summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Young <chris@unsatisfactorysoftware.co.uk>2018-01-08 22:36:56 +0000
committerChris Young <chris@unsatisfactorysoftware.co.uk>2018-01-08 22:36:56 +0000
commit8c54b1f726591a91e1002e3d219688bcb5fa9447 (patch)
treec3e19d3be53b420b69f1e4c1566b4e306698f40e
parent17496c103b69193a7c03cb737d841a6906390bb2 (diff)
downloadtoolchains-8c54b1f726591a91e1002e3d219688bcb5fa9447.tar.gz
toolchains-8c54b1f726591a91e1002e3d219688bcb5fa9447.tar.bz2
Only one of the previously missing files is still missing
-rw-r--r--ppc-amigaos/recipes/patches/binutils/missing-files.p9975
1 files changed, 0 insertions, 9975 deletions
diff --git a/ppc-amigaos/recipes/patches/binutils/missing-files.p b/ppc-amigaos/recipes/patches/binutils/missing-files.p
index 7911090..a0650ca 100644
--- a/ppc-amigaos/recipes/patches/binutils/missing-files.p
+++ b/ppc-amigaos/recipes/patches/binutils/missing-files.p
@@ -1,9979 +1,4 @@
--- /dev/null 2015-09-06 08:42:34.091999986 +0100
-+++ bfd/elf32-amigaos.c 2016-01-03 01:46:50.503001072 +0000
-@@ -0,0 +1,9972 @@
-+/* PowerPC-specific support for 32-bit ELF
-+ Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-+ 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
-+ Free Software Foundation, Inc.
-+ Written by Ian Lance Taylor, Cygnus Support.
-+
-+ This file is part of BFD, the Binary File Descriptor library.
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 3 of the License, or
-+ (at your option) any later version.
-+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program; if not, write to the
-+ Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
-+ Boston, MA 02110-1301, USA. */
-+
-+
-+/* This file is based on a preliminary PowerPC ELF ABI. The
-+ information may not match the final PowerPC ELF ABI. It includes
-+ suggestions from the in-progress Embedded PowerPC ABI, and that
-+ information may also not match. */
-+
-+#include "sysdep.h"
-+#include <stdarg.h>
-+#include "bfd.h"
-+#include "bfdlink.h"
-+#include "libbfd.h"
-+#include "elf-bfd.h"
-+#include "elf/ppc.h"
-+#include "elf/amigaos.h"
-+#include "elf32-ppc.h"
-+#include "elf-vxworks.h"
-+#include "dwarf2.h"
-+
-+#undef DEBUG
-+
-+typedef enum split16_format_type
-+{
-+ split16a_type = 0,
-+ split16d_type
-+}
-+split16_format_type;
-+
-+/* RELA relocations are used here. */
-+#define USE_RELA
-+#define USE_REL 0
-+
-+static bfd_reloc_status_type ppc_elf_addr16_ha_reloc
-+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
-+static bfd_reloc_status_type ppc_elf_unhandled_reloc
-+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
-+static void ppc_elf_vle_split16
-+ (bfd *, bfd_byte *, bfd_vma, bfd_vma, split16_format_type);
-+
-+int ppc_elf_amigaos_select_plt_layout (bfd *, struct bfd_link_info *,
-+ enum ppc_elf_plt_type, int);
-+
-+bfd_boolean ppc_elf_amigaos_section_processing (bfd *abfd, Elf_Internal_Shdr *shdr);
-+bfd_boolean ppc_elf_amigaos_modify_segment_map (bfd *abfd,
-+ struct bfd_link_info *info ATTRIBUTE_UNUSED);
-+asection *ppc_elf_amigaos_tls_setup (bfd *obfd, struct bfd_link_info *info,
-+ int no_tls_get_addr_opt);
-+bfd_boolean ppc_elf_amigaos_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED,
-+ struct bfd_link_info *info);
-+unsigned int _bfd_elf_amigaos_ppc_at_tls_transform (unsigned int insn, unsigned int reg);
-+unsigned int _bfd_elf_amigaos_ppc_at_tprel_transform (unsigned int insn, unsigned int reg);
-+
-+/* Branch prediction bit for branch taken relocs. */
-+#define BRANCH_PREDICT_BIT 0x200000
-+/* Mask to set RA in memory instructions. */
-+#define RA_REGISTER_MASK 0x001f0000
-+/* Value to shift register by to insert RA. */
-+#define RA_REGISTER_SHIFT 16
-+
-+/* The name of the dynamic interpreter. This is put in the .interp
-+ section. */
-+#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
-+
-+/* For old-style PLT. */
-+/* The number of single-slot PLT entries (the rest use two slots). */
-+#define PLT_NUM_SINGLE_ENTRIES 8192
-+
-+/* For new-style .glink and .plt. */
-+#define GLINK_PLTRESOLVE 16*4
-+#define GLINK_ENTRY_SIZE 4*4
-+#define TLS_GET_ADDR_GLINK_SIZE 12*4
-+
-+/* VxWorks uses its own plt layout, filled in by the static linker. */
-+
-+/* The standard VxWorks PLT entry. */
-+#define VXWORKS_PLT_ENTRY_SIZE 32
-+static const bfd_vma ppc_elf_vxworks_plt_entry
-+ [VXWORKS_PLT_ENTRY_SIZE / 4] =
-+ {
-+ 0x3d800000, /* lis r12,0 */
-+ 0x818c0000, /* lwz r12,0(r12) */
-+ 0x7d8903a6, /* mtctr r12 */
-+ 0x4e800420, /* bctr */
-+ 0x39600000, /* li r11,0 */
-+ 0x48000000, /* b 14 <.PLT0resolve+0x4> */
-+ 0x60000000, /* nop */
-+ 0x60000000, /* nop */
-+ };
-+static const bfd_vma ppc_elf_vxworks_pic_plt_entry
-+ [VXWORKS_PLT_ENTRY_SIZE / 4] =
-+ {
-+ 0x3d9e0000, /* addis r12,r30,0 */
-+ 0x818c0000, /* lwz r12,0(r12) */
-+ 0x7d8903a6, /* mtctr r12 */
-+ 0x4e800420, /* bctr */
-+ 0x39600000, /* li r11,0 */
-+ 0x48000000, /* b 14 <.PLT0resolve+0x4> 14: R_PPC_REL24 .PLTresolve */
-+ 0x60000000, /* nop */
-+ 0x60000000, /* nop */
-+ };
-+
-+/* The initial VxWorks PLT entry. */
-+#define VXWORKS_PLT_INITIAL_ENTRY_SIZE 32
-+static const bfd_vma ppc_elf_vxworks_plt0_entry
-+ [VXWORKS_PLT_INITIAL_ENTRY_SIZE / 4] =
-+ {
-+ 0x3d800000, /* lis r12,0 */
-+ 0x398c0000, /* addi r12,r12,0 */
-+ 0x800c0008, /* lwz r0,8(r12) */
-+ 0x7c0903a6, /* mtctr r0 */
-+ 0x818c0004, /* lwz r12,4(r12) */
-+ 0x4e800420, /* bctr */
-+ 0x60000000, /* nop */
-+ 0x60000000, /* nop */
-+ };
-+static const bfd_vma ppc_elf_vxworks_pic_plt0_entry
-+ [VXWORKS_PLT_INITIAL_ENTRY_SIZE / 4] =
-+ {
-+ 0x819e0008, /* lwz r12,8(r30) */
-+ 0x7d8903a6, /* mtctr r12 */
-+ 0x819e0004, /* lwz r12,4(r30) */
-+ 0x4e800420, /* bctr */
-+ 0x60000000, /* nop */
-+ 0x60000000, /* nop */
-+ 0x60000000, /* nop */
-+ 0x60000000, /* nop */
-+ };
-+
-+/* For executables, we have some additional relocations in
-+ .rela.plt.unloaded, for the kernel loader. */
-+
-+/* The number of non-JMP_SLOT relocations per PLT0 slot. */
-+#define VXWORKS_PLT_NON_JMP_SLOT_RELOCS 3
-+/* The number of relocations in the PLTResolve slot. */
-+#define VXWORKS_PLTRESOLVE_RELOCS 2
-+/* The number of relocations in the PLTResolve slot when when creating
-+ a shared library. */
-+#define VXWORKS_PLTRESOLVE_RELOCS_SHLIB 0
-+
-+/* Some instructions. */
-+#define ADDIS_11_11 0x3d6b0000
-+#define ADDIS_11_30 0x3d7e0000
-+#define ADDIS_12_12 0x3d8c0000
-+#define ADDI_11_11 0x396b0000
-+#define ADD_0_11_11 0x7c0b5a14
-+#define ADD_3_12_2 0x7c6c1214
-+#define ADD_11_0_11 0x7d605a14
-+#define B 0x48000000
-+#define BCL_20_31 0x429f0005
-+#define BCTR 0x4e800420
-+#define BEQLR 0x4d820020
-+#define CMPWI_11_0 0x2c0b0000
-+#define LIS_11 0x3d600000
-+#define LIS_12 0x3d800000
-+#define LWZU_0_12 0x840c0000
-+#define LWZ_0_12 0x800c0000
-+#define LWZ_11_3 0x81630000
-+#define LWZ_11_11 0x816b0000
-+#define LWZ_11_30 0x817e0000
-+#define LWZ_12_3 0x81830000
-+#define LWZ_12_12 0x818c0000
-+#define MR_0_3 0x7c601b78
-+#define MR_3_0 0x7c030378
-+#define MFLR_0 0x7c0802a6
-+#define MFLR_12 0x7d8802a6
-+#define MTCTR_0 0x7c0903a6
-+#define MTCTR_11 0x7d6903a6
-+#define MTLR_0 0x7c0803a6
-+#define NOP 0x60000000
-+#define SUB_11_11_12 0x7d6c5850
-+
-+/* Offset of tp and dtp pointers from start of TLS block. */
-+#define TP_OFFSET 0x7000
-+#define DTP_OFFSET 0x8000
-+
-+/* The value of a defined global symbol. */
-+#define SYM_VAL(SYM) \
-+ ((SYM)->root.u.def.section->output_section->vma \
-+ + (SYM)->root.u.def.section->output_offset \
-+ + (SYM)->root.u.def.value)
-+
-+static reloc_howto_type *ppc_elf_howto_table[R_PPC_max];
-+
-+static reloc_howto_type ppc_elf_howto_raw[] = {
-+ /* This reloc does nothing. */
-+ HOWTO (R_PPC_NONE, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_NONE", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* A standard 32 bit relocation. */
-+ HOWTO (R_PPC_ADDR32, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_ADDR32", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffffffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* An absolute 26 bit branch; the lower two bits must be zero.
-+ FIXME: we don't check that, we just clear them. */
-+ HOWTO (R_PPC_ADDR24, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 26, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_ADDR24", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0x3fffffc, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* A standard 16 bit relocation. */
-+ HOWTO (R_PPC_ADDR16, /* type */
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_ADDR16", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* A 16 bit relocation without overflow. */
-+ HOWTO (R_PPC_ADDR16_LO, /* type */
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont,/* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_ADDR16_LO", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* The high order 16 bits of an address. */
-+ HOWTO (R_PPC_ADDR16_HI, /* type */
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_ADDR16_HI", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* The high order 16 bits of an address, plus 1 if the contents of
-+ the low 16 bits, treated as a signed number, is negative. */
-+ HOWTO (R_PPC_ADDR16_HA, /* type */
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_addr16_ha_reloc, /* special_function */
-+ "R_PPC_ADDR16_HA", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* An absolute 16 bit branch; the lower two bits must be zero.
-+ FIXME: we don't check that, we just clear them. */
-+ HOWTO (R_PPC_ADDR14, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_ADDR14", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xfffc, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* An absolute 16 bit branch, for which bit 10 should be set to
-+ indicate that the branch is expected to be taken. The lower two
-+ bits must be zero. */
-+ HOWTO (R_PPC_ADDR14_BRTAKEN, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_ADDR14_BRTAKEN",/* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xfffc, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* An absolute 16 bit branch, for which bit 10 should be set to
-+ indicate that the branch is not expected to be taken. The lower
-+ two bits must be zero. */
-+ HOWTO (R_PPC_ADDR14_BRNTAKEN, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_ADDR14_BRNTAKEN",/* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xfffc, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* A relative 26 bit branch; the lower two bits must be zero. */
-+ HOWTO (R_PPC_REL24, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 26, /* bitsize */
-+ TRUE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_signed, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_REL24", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0x3fffffc, /* dst_mask */
-+ TRUE), /* pcrel_offset */
-+
-+ /* A relative 16 bit branch; the lower two bits must be zero. */
-+ HOWTO (R_PPC_REL14, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ TRUE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_signed, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_REL14", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xfffc, /* dst_mask */
-+ TRUE), /* pcrel_offset */
-+
-+ /* A relative 16 bit branch. Bit 10 should be set to indicate that
-+ the branch is expected to be taken. The lower two bits must be
-+ zero. */
-+ HOWTO (R_PPC_REL14_BRTAKEN, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ TRUE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_signed, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_REL14_BRTAKEN", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xfffc, /* dst_mask */
-+ TRUE), /* pcrel_offset */
-+
-+ /* A relative 16 bit branch. Bit 10 should be set to indicate that
-+ the branch is not expected to be taken. The lower two bits must
-+ be zero. */
-+ HOWTO (R_PPC_REL14_BRNTAKEN, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ TRUE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_signed, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_REL14_BRNTAKEN",/* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xfffc, /* dst_mask */
-+ TRUE), /* pcrel_offset */
-+
-+ /* Like R_PPC_ADDR16, but referring to the GOT table entry for the
-+ symbol. */
-+ HOWTO (R_PPC_GOT16, /* type */
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_signed, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_GOT16", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like R_PPC_ADDR16_LO, but referring to the GOT table entry for
-+ the symbol. */
-+ HOWTO (R_PPC_GOT16_LO, /* type */
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_GOT16_LO", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like R_PPC_ADDR16_HI, but referring to the GOT table entry for
-+ the symbol. */
-+ HOWTO (R_PPC_GOT16_HI, /* type */
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_GOT16_HI", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like R_PPC_ADDR16_HA, but referring to the GOT table entry for
-+ the symbol. */
-+ HOWTO (R_PPC_GOT16_HA, /* type */
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ ppc_elf_addr16_ha_reloc, /* special_function */
-+ "R_PPC_GOT16_HA", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like R_PPC_REL24, but referring to the procedure linkage table
-+ entry for the symbol. */
-+ HOWTO (R_PPC_PLTREL24, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 26, /* bitsize */
-+ TRUE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_signed, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_PLTREL24", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0x3fffffc, /* dst_mask */
-+ TRUE), /* pcrel_offset */
-+
-+ /* This is used only by the dynamic linker. The symbol should exist
-+ both in the object being run and in some shared library. The
-+ dynamic linker copies the data addressed by the symbol from the
-+ shared library into the object, because the object being
-+ run has to have the data at some particular address. */
-+ HOWTO (R_PPC_COPY, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_COPY", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like R_PPC_ADDR32, but used when setting global offset table
-+ entries. */
-+ HOWTO (R_PPC_GLOB_DAT, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_GLOB_DAT", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffffffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Marks a procedure linkage table entry for a symbol. */
-+ HOWTO (R_PPC_JMP_SLOT, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_JMP_SLOT", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Used only by the dynamic linker. When the object is run, this
-+ longword is set to the load address of the object, plus the
-+ addend. */
-+ HOWTO (R_PPC_RELATIVE, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_RELATIVE", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffffffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like R_PPC_REL24, but uses the value of the symbol within the
-+ object rather than the final value. Normally used for
-+ _GLOBAL_OFFSET_TABLE_. */
-+ HOWTO (R_PPC_LOCAL24PC, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 26, /* bitsize */
-+ TRUE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_signed, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_LOCAL24PC", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0x3fffffc, /* dst_mask */
-+ TRUE), /* pcrel_offset */
-+
-+ /* Like R_PPC_ADDR32, but may be unaligned. */
-+ HOWTO (R_PPC_UADDR32, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_UADDR32", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffffffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like R_PPC_ADDR16, but may be unaligned. */
-+ HOWTO (R_PPC_UADDR16, /* type */
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_UADDR16", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* 32-bit PC relative */
-+ HOWTO (R_PPC_REL32, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ TRUE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_REL32", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffffffff, /* dst_mask */
-+ TRUE), /* pcrel_offset */
-+
-+ /* 32-bit relocation to the symbol's procedure linkage table.
-+ FIXME: not supported. */
-+ HOWTO (R_PPC_PLT32, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_PLT32", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* 32-bit PC relative relocation to the symbol's procedure linkage table.
-+ FIXME: not supported. */
-+ HOWTO (R_PPC_PLTREL32, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ TRUE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_PLTREL32", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0, /* dst_mask */
-+ TRUE), /* pcrel_offset */
-+
-+ /* Like R_PPC_ADDR16_LO, but referring to the PLT table entry for
-+ the symbol. */
-+ HOWTO (R_PPC_PLT16_LO, /* type */
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_PLT16_LO", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like R_PPC_ADDR16_HI, but referring to the PLT table entry for
-+ the symbol. */
-+ HOWTO (R_PPC_PLT16_HI, /* type */
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_PLT16_HI", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like R_PPC_ADDR16_HA, but referring to the PLT table entry for
-+ the symbol. */
-+ HOWTO (R_PPC_PLT16_HA, /* type */
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ ppc_elf_addr16_ha_reloc, /* special_function */
-+ "R_PPC_PLT16_HA", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* A sign-extended 16 bit value relative to _SDA_BASE_, for use with
-+ small data items. */
-+ HOWTO (R_PPC_SDAREL16, /* type */
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_signed, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_SDAREL16", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* 16-bit section relative relocation. */
-+ HOWTO (R_PPC_SECTOFF, /* type */
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_SECTOFF", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* 16-bit lower half section relative relocation. */
-+ HOWTO (R_PPC_SECTOFF_LO, /* type */
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_SECTOFF_LO", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* 16-bit upper half section relative relocation. */
-+ HOWTO (R_PPC_SECTOFF_HI, /* type */
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_SECTOFF_HI", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* 16-bit upper half adjusted section relative relocation. */
-+ HOWTO (R_PPC_SECTOFF_HA, /* type */
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ ppc_elf_addr16_ha_reloc, /* special_function */
-+ "R_PPC_SECTOFF_HA", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Marker relocs for TLS. */
-+ HOWTO (R_PPC_TLS,
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_TLS", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ HOWTO (R_PPC_TLSGD,
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_TLSGD", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ HOWTO (R_PPC_TLSLD,
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_TLSLD", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Computes the load module index of the load module that contains the
-+ definition of its TLS sym. */
-+ HOWTO (R_PPC_DTPMOD32,
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_DTPMOD32", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffffffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Computes a dtv-relative displacement, the difference between the value
-+ of sym+add and the base address of the thread-local storage block that
-+ contains the definition of sym, minus 0x8000. */
-+ HOWTO (R_PPC_DTPREL32,
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_DTPREL32", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffffffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* A 16 bit dtprel reloc. */
-+ HOWTO (R_PPC_DTPREL16,
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_signed, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_DTPREL16", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like DTPREL16, but no overflow. */
-+ HOWTO (R_PPC_DTPREL16_LO,
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_DTPREL16_LO", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like DTPREL16_LO, but next higher group of 16 bits. */
-+ HOWTO (R_PPC_DTPREL16_HI,
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_DTPREL16_HI", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like DTPREL16_HI, but adjust for low 16 bits. */
-+ HOWTO (R_PPC_DTPREL16_HA,
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_DTPREL16_HA", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Computes a tp-relative displacement, the difference between the value of
-+ sym+add and the value of the thread pointer (r13). */
-+ HOWTO (R_PPC_TPREL32,
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_TPREL32", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffffffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* A 16 bit tprel reloc. */
-+ HOWTO (R_PPC_TPREL16,
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_signed, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_TPREL16", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like TPREL16, but no overflow. */
-+ HOWTO (R_PPC_TPREL16_LO,
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_TPREL16_LO", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like TPREL16_LO, but next higher group of 16 bits. */
-+ HOWTO (R_PPC_TPREL16_HI,
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_TPREL16_HI", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like TPREL16_HI, but adjust for low 16 bits. */
-+ HOWTO (R_PPC_TPREL16_HA,
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_TPREL16_HA", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Allocates two contiguous entries in the GOT to hold a tls_index structure,
-+ with values (sym+add)@dtpmod and (sym+add)@dtprel, and computes the offset
-+ to the first entry. */
-+ HOWTO (R_PPC_GOT_TLSGD16,
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_signed, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_GOT_TLSGD16", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like GOT_TLSGD16, but no overflow. */
-+ HOWTO (R_PPC_GOT_TLSGD16_LO,
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_GOT_TLSGD16_LO", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like GOT_TLSGD16_LO, but next higher group of 16 bits. */
-+ HOWTO (R_PPC_GOT_TLSGD16_HI,
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_GOT_TLSGD16_HI", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like GOT_TLSGD16_HI, but adjust for low 16 bits. */
-+ HOWTO (R_PPC_GOT_TLSGD16_HA,
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_GOT_TLSGD16_HA", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Allocates two contiguous entries in the GOT to hold a tls_index structure,
-+ with values (sym+add)@dtpmod and zero, and computes the offset to the
-+ first entry. */
-+ HOWTO (R_PPC_GOT_TLSLD16,
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_signed, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_GOT_TLSLD16", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like GOT_TLSLD16, but no overflow. */
-+ HOWTO (R_PPC_GOT_TLSLD16_LO,
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_GOT_TLSLD16_LO", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like GOT_TLSLD16_LO, but next higher group of 16 bits. */
-+ HOWTO (R_PPC_GOT_TLSLD16_HI,
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_GOT_TLSLD16_HI", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like GOT_TLSLD16_HI, but adjust for low 16 bits. */
-+ HOWTO (R_PPC_GOT_TLSLD16_HA,
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_GOT_TLSLD16_HA", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Allocates an entry in the GOT with value (sym+add)@dtprel, and computes
-+ the offset to the entry. */
-+ HOWTO (R_PPC_GOT_DTPREL16,
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_signed, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_GOT_DTPREL16", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like GOT_DTPREL16, but no overflow. */
-+ HOWTO (R_PPC_GOT_DTPREL16_LO,
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_GOT_DTPREL16_LO", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like GOT_DTPREL16_LO, but next higher group of 16 bits. */
-+ HOWTO (R_PPC_GOT_DTPREL16_HI,
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_GOT_DTPREL16_HI", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like GOT_DTPREL16_HI, but adjust for low 16 bits. */
-+ HOWTO (R_PPC_GOT_DTPREL16_HA,
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_GOT_DTPREL16_HA", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Allocates an entry in the GOT with value (sym+add)@tprel, and computes the
-+ offset to the entry. */
-+ HOWTO (R_PPC_GOT_TPREL16,
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_signed, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_GOT_TPREL16", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like GOT_TPREL16, but no overflow. */
-+ HOWTO (R_PPC_GOT_TPREL16_LO,
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_GOT_TPREL16_LO", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like GOT_TPREL16_LO, but next higher group of 16 bits. */
-+ HOWTO (R_PPC_GOT_TPREL16_HI,
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_GOT_TPREL16_HI", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Like GOT_TPREL16_HI, but adjust for low 16 bits. */
-+ HOWTO (R_PPC_GOT_TPREL16_HA,
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_unhandled_reloc, /* special_function */
-+ "R_PPC_GOT_TPREL16_HA", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* The remaining relocs are from the Embedded ELF ABI, and are not
-+ in the SVR4 ELF ABI. */
-+
-+ /* 32 bit value resulting from the addend minus the symbol. */
-+ HOWTO (R_PPC_EMB_NADDR32, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_EMB_NADDR32", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffffffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* 16 bit value resulting from the addend minus the symbol. */
-+ HOWTO (R_PPC_EMB_NADDR16, /* type */
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_EMB_NADDR16", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* 16 bit value resulting from the addend minus the symbol. */
-+ HOWTO (R_PPC_EMB_NADDR16_LO, /* type */
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont,/* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_EMB_ADDR16_LO", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* The high order 16 bits of the addend minus the symbol. */
-+ HOWTO (R_PPC_EMB_NADDR16_HI, /* type */
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_EMB_NADDR16_HI", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* The high order 16 bits of the result of the addend minus the address,
-+ plus 1 if the contents of the low 16 bits, treated as a signed number,
-+ is negative. */
-+ HOWTO (R_PPC_EMB_NADDR16_HA, /* type */
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_addr16_ha_reloc, /* special_function */
-+ "R_PPC_EMB_NADDR16_HA", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* 16 bit value resulting from allocating a 4 byte word to hold an
-+ address in the .sdata section, and returning the offset from
-+ _SDA_BASE_ for that relocation. */
-+ HOWTO (R_PPC_EMB_SDAI16, /* type */
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_signed, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_EMB_SDAI16", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* 16 bit value resulting from allocating a 4 byte word to hold an
-+ address in the .sdata2 section, and returning the offset from
-+ _SDA2_BASE_ for that relocation. */
-+ HOWTO (R_PPC_EMB_SDA2I16, /* type */
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_signed, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_EMB_SDA2I16", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* A sign-extended 16 bit value relative to _SDA2_BASE_, for use with
-+ small data items. */
-+ HOWTO (R_PPC_EMB_SDA2REL, /* type */
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_signed, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_EMB_SDA2REL", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Relocate against either _SDA_BASE_ or _SDA2_BASE_, filling in the 16 bit
-+ signed offset from the appropriate base, and filling in the register
-+ field with the appropriate register (0, 2, or 13). */
-+ HOWTO (R_PPC_EMB_SDA21, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_signed, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_EMB_SDA21", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Relocation not handled: R_PPC_EMB_MRKREF */
-+ /* Relocation not handled: R_PPC_EMB_RELSEC16 */
-+ /* Relocation not handled: R_PPC_EMB_RELST_LO */
-+ /* Relocation not handled: R_PPC_EMB_RELST_HI */
-+ /* Relocation not handled: R_PPC_EMB_RELST_HA */
-+ /* Relocation not handled: R_PPC_EMB_BIT_FLD */
-+
-+
-+ /* A standard 32 bit base relative relocation. */
-+ HOWTO (R_PPC_AMIGAOS_BREL, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_AMIGAOS_BREL", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffffffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* A 16 bit base relative relocation without overflow. */
-+ HOWTO (R_PPC_AMIGAOS_BREL_LO, /* type */
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont,/* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_AMIGAOS_BREL_LO",/* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* The high order 16 bits of a base relative address. */
-+ HOWTO (R_PPC_AMIGAOS_BREL_HI, /* type */
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_AMIGAOS_BREL_HI",/* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* The high order 16 bits of a base relative address, plus 1 if the contents
-+ of the low 16 bits, treated as a signed number, is negative. */
-+ HOWTO (R_PPC_AMIGAOS_BREL_HA, /* type */
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_addr16_ha_reloc, /* special_function */
-+ "R_PPC_AMIGAOS_BREL_HA",/* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* PC relative relocation against either _SDA_BASE_ or _SDA2_BASE_, filling
-+ in the 16 bit signed offset from the appropriate base, and filling in the
-+ register field with the appropriate register (0, 2, or 13). */
-+ HOWTO (R_PPC_EMB_RELSDA, /* type */
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_signed, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_EMB_RELSDA", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* A relative 8 bit branch. */
-+ HOWTO (R_PPC_VLE_REL8, /* type */
-+ 1, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 8, /* bitsize */
-+ TRUE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_signed, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_VLE_REL8", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xff, /* dst_mask */
-+ TRUE), /* pcrel_offset */
-+
-+ /* A relative 15 bit branch. */
-+ HOWTO (R_PPC_VLE_REL15, /* type */
-+ 1, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 15, /* bitsize */
-+ TRUE, /* pc_relative */
-+ 1, /* bitpos */
-+ complain_overflow_signed, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_VLE_REL15", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xfe, /* dst_mask */
-+ TRUE), /* pcrel_offset */
-+
-+ /* A relative 24 bit branch. */
-+ HOWTO (R_PPC_VLE_REL24, /* type */
-+ 1, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 24, /* bitsize */
-+ TRUE, /* pc_relative */
-+ 1, /* bitpos */
-+ complain_overflow_signed, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_VLE_REL24", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0x1fffffe, /* dst_mask */
-+ TRUE), /* pcrel_offset */
-+
-+ /* The 16 LSBS in split16a format. */
-+ HOWTO (R_PPC_VLE_LO16A, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_VLE_LO16A", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0x1f007ff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* The 16 LSBS in split16d format. */
-+ HOWTO (R_PPC_VLE_LO16D, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_VLE_LO16D", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0x1f07ff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Bits 16-31 split16a format. */
-+ HOWTO (R_PPC_VLE_HI16A, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_VLE_HI16A", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0x1f007ff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Bits 16-31 split16d format. */
-+ HOWTO (R_PPC_VLE_HI16D, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_VLE_HI16D", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0x1f07ff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Bits 16-31 (High Adjusted) in split16a format. */
-+ HOWTO (R_PPC_VLE_HA16A, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_VLE_HA16A", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0x1f007ff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Bits 16-31 (High Adjusted) in split16d format. */
-+ HOWTO (R_PPC_VLE_HA16D, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_VLE_HA16D", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0x1f07ff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* This reloc does nothing. */
-+ HOWTO (R_PPC_VLE_SDA21, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_VLE_SDA21", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* This reloc does nothing. */
-+ HOWTO (R_PPC_VLE_SDA21_LO, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_VLE_SDA21_LO", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* The 16 LSBS relative to _SDA_BASE_ in split16a format. */
-+ HOWTO (R_PPC_VLE_SDAREL_LO16A,/* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_VLE_SDAREL_LO16A", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0x1f007ff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* The 16 LSBS relative to _SDA_BASE_ in split16d format. */
-+ /* This reloc does nothing. */
-+ HOWTO (R_PPC_VLE_SDAREL_LO16D, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_VLE_SDAREL_LO16D", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0x1f07ff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Bits 16-31 relative to _SDA_BASE_ in split16a format. */
-+ HOWTO (R_PPC_VLE_SDAREL_HI16A, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_VLE_SDAREL_HI16A", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0x1f007ff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Bits 16-31 relative to _SDA_BASE_ in split16d format. */
-+ HOWTO (R_PPC_VLE_SDAREL_HI16D, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_VLE_SDAREL_HI16D", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0x1f07ff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Bits 16-31 (HA) relative to _SDA_BASE split16a format. */
-+ HOWTO (R_PPC_VLE_SDAREL_HA16A, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_VLE_SDAREL_HA16A", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0x1f007ff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Bits 16-31 (HA) relative to _SDA_BASE split16d format. */
-+ HOWTO (R_PPC_VLE_SDAREL_HA16D, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_VLE_SDAREL_HA16D", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0x1f07ff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ HOWTO (R_PPC_IRELATIVE, /* type */
-+ 0, /* rightshift */
-+ 2, /* size (0 = byte, 1 = short, 2 = long) */
-+ 32, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_IRELATIVE", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffffffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* A 16 bit relative relocation. */
-+ HOWTO (R_PPC_REL16, /* type */
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ TRUE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_bitfield, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_REL16", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ TRUE), /* pcrel_offset */
-+
-+ /* A 16 bit relative relocation without overflow. */
-+ HOWTO (R_PPC_REL16_LO, /* type */
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ TRUE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont,/* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_REL16_LO", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ TRUE), /* pcrel_offset */
-+
-+ /* The high order 16 bits of a relative address. */
-+ HOWTO (R_PPC_REL16_HI, /* type */
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ TRUE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_REL16_HI", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ TRUE), /* pcrel_offset */
-+
-+ /* The high order 16 bits of a relative address, plus 1 if the contents of
-+ the low 16 bits, treated as a signed number, is negative. */
-+ HOWTO (R_PPC_REL16_HA, /* type */
-+ 16, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ TRUE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ ppc_elf_addr16_ha_reloc, /* special_function */
-+ "R_PPC_REL16_HA", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ TRUE), /* pcrel_offset */
-+
-+ /* GNU extension to record C++ vtable hierarchy. */
-+ HOWTO (R_PPC_GNU_VTINHERIT, /* type */
-+ 0, /* rightshift */
-+ 0, /* size (0 = byte, 1 = short, 2 = long) */
-+ 0, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ NULL, /* special_function */
-+ "R_PPC_GNU_VTINHERIT", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* GNU extension to record C++ vtable member usage. */
-+ HOWTO (R_PPC_GNU_VTENTRY, /* type */
-+ 0, /* rightshift */
-+ 0, /* size (0 = byte, 1 = short, 2 = long) */
-+ 0, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_dont, /* complain_on_overflow */
-+ NULL, /* special_function */
-+ "R_PPC_GNU_VTENTRY", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+
-+ /* Phony reloc to handle AIX style TOC entries. */
-+ HOWTO (R_PPC_TOC16, /* type */
-+ 0, /* rightshift */
-+ 1, /* size (0 = byte, 1 = short, 2 = long) */
-+ 16, /* bitsize */
-+ FALSE, /* pc_relative */
-+ 0, /* bitpos */
-+ complain_overflow_signed, /* complain_on_overflow */
-+ bfd_elf_generic_reloc, /* special_function */
-+ "R_PPC_TOC16", /* name */
-+ FALSE, /* partial_inplace */
-+ 0, /* src_mask */
-+ 0xffff, /* dst_mask */
-+ FALSE), /* pcrel_offset */
-+};
-+
-+/* Initialize the ppc_elf_howto_table, so that linear accesses can be done. */
-+
-+static void
-+ppc_elf_howto_init (void)
-+{
-+ unsigned int i, type;
-+
-+ for (i = 0;
-+ i < sizeof (ppc_elf_howto_raw) / sizeof (ppc_elf_howto_raw[0]);
-+ i++)
-+ {
-+ type = ppc_elf_howto_raw[i].type;
-+ if (type >= (sizeof (ppc_elf_howto_table)
-+ / sizeof (ppc_elf_howto_table[0])))
-+ abort ();
-+ ppc_elf_howto_table[type] = &ppc_elf_howto_raw[i];
-+ }
-+}
-+
-+static reloc_howto_type *
-+ppc_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
-+ bfd_reloc_code_real_type code)
-+{
-+ enum elf_ppc_reloc_type r;
-+
-+ /* Initialize howto table if not already done. */
-+ if (!ppc_elf_howto_table[R_PPC_ADDR32])
-+ ppc_elf_howto_init ();
-+
-+ switch (code)
-+ {
-+ default:
-+ return NULL;
-+
-+ case BFD_RELOC_NONE: r = R_PPC_NONE; break;
-+ case BFD_RELOC_32: r = R_PPC_ADDR32; break;
-+ case BFD_RELOC_PPC_BA26: r = R_PPC_ADDR24; break;
-+ case BFD_RELOC_PPC64_ADDR16_DS:
-+ case BFD_RELOC_16: r = R_PPC_ADDR16; break;
-+ case BFD_RELOC_PPC64_ADDR16_LO_DS:
-+ case BFD_RELOC_LO16: r = R_PPC_ADDR16_LO; break;
-+ case BFD_RELOC_HI16: r = R_PPC_ADDR16_HI; break;
-+ case BFD_RELOC_HI16_S: r = R_PPC_ADDR16_HA; break;
-+ case BFD_RELOC_PPC_BA16: r = R_PPC_ADDR14; break;
-+ case BFD_RELOC_PPC_BA16_BRTAKEN: r = R_PPC_ADDR14_BRTAKEN; break;
-+ case BFD_RELOC_PPC_BA16_BRNTAKEN: r = R_PPC_ADDR14_BRNTAKEN; break;
-+ case BFD_RELOC_PPC_B26: r = R_PPC_REL24; break;
-+ case BFD_RELOC_PPC_B16: r = R_PPC_REL14; break;
-+ case BFD_RELOC_PPC_B16_BRTAKEN: r = R_PPC_REL14_BRTAKEN; break;
-+ case BFD_RELOC_PPC_B16_BRNTAKEN: r = R_PPC_REL14_BRNTAKEN; break;
-+ case BFD_RELOC_PPC64_GOT16_DS:
-+ case BFD_RELOC_16_GOTOFF: r = R_PPC_GOT16; break;
-+ case BFD_RELOC_PPC64_GOT16_LO_DS:
-+ case BFD_RELOC_LO16_GOTOFF: r = R_PPC_GOT16_LO; break;
-+ case BFD_RELOC_HI16_GOTOFF: r = R_PPC_GOT16_HI; break;
-+ case BFD_RELOC_HI16_S_GOTOFF: r = R_PPC_GOT16_HA; break;
-+ case BFD_RELOC_24_PLT_PCREL: r = R_PPC_PLTREL24; break;
-+ case BFD_RELOC_PPC_COPY: r = R_PPC_COPY; break;
-+ case BFD_RELOC_PPC_GLOB_DAT: r = R_PPC_GLOB_DAT; break;
-+ case BFD_RELOC_PPC_LOCAL24PC: r = R_PPC_LOCAL24PC; break;
-+ case BFD_RELOC_32_PCREL: r = R_PPC_REL32; break;
-+ case BFD_RELOC_32_PLTOFF: r = R_PPC_PLT32; break;
-+ case BFD_RELOC_32_PLT_PCREL: r = R_PPC_PLTREL32; break;
-+ case BFD_RELOC_PPC64_PLT16_LO_DS:
-+ case BFD_RELOC_LO16_PLTOFF: r = R_PPC_PLT16_LO; break;
-+ case BFD_RELOC_HI16_PLTOFF: r = R_PPC_PLT16_HI; break;
-+ case BFD_RELOC_HI16_S_PLTOFF: r = R_PPC_PLT16_HA; break;
-+ case BFD_RELOC_GPREL16: r = R_PPC_SDAREL16; break;
-+ case BFD_RELOC_PPC64_SECTOFF_DS:
-+ case BFD_RELOC_16_BASEREL: r = R_PPC_SECTOFF; break;
-+ case BFD_RELOC_PPC64_SECTOFF_LO_DS:
-+ case BFD_RELOC_LO16_BASEREL: r = R_PPC_SECTOFF_LO; break;
-+ case BFD_RELOC_HI16_BASEREL: r = R_PPC_SECTOFF_HI; break;
-+ case BFD_RELOC_HI16_S_BASEREL: r = R_PPC_SECTOFF_HA; break;
-+ case BFD_RELOC_CTOR: r = R_PPC_ADDR32; break;
-+ case BFD_RELOC_PPC64_TOC16_DS:
-+ case BFD_RELOC_PPC_TOC16: r = R_PPC_TOC16; break;
-+ case BFD_RELOC_PPC_TLS: r = R_PPC_TLS; break;
-+ case BFD_RELOC_PPC_TLSGD: r = R_PPC_TLSGD; break;
-+ case BFD_RELOC_PPC_TLSLD: r = R_PPC_TLSLD; break;
-+ case BFD_RELOC_PPC_DTPMOD: r = R_PPC_DTPMOD32; break;
-+ case BFD_RELOC_PPC64_TPREL16_DS:
-+ case BFD_RELOC_PPC_TPREL16: r = R_PPC_TPREL16; break;
-+ case BFD_RELOC_PPC64_TPREL16_LO_DS:
-+ case BFD_RELOC_PPC_TPREL16_LO: r = R_PPC_TPREL16_LO; break;
-+ case BFD_RELOC_PPC_TPREL16_HI: r = R_PPC_TPREL16_HI; break;
-+ case BFD_RELOC_PPC_TPREL16_HA: r = R_PPC_TPREL16_HA; break;
-+ case BFD_RELOC_PPC_TPREL: r = R_PPC_TPREL32; break;
-+ case BFD_RELOC_PPC64_DTPREL16_DS:
-+ case BFD_RELOC_PPC_DTPREL16: r = R_PPC_DTPREL16; break;
-+ case BFD_RELOC_PPC64_DTPREL16_LO_DS:
-+ case BFD_RELOC_PPC_DTPREL16_LO: r = R_PPC_DTPREL16_LO; break;
-+ case BFD_RELOC_PPC_DTPREL16_HI: r = R_PPC_DTPREL16_HI; break;
-+ case BFD_RELOC_PPC_DTPREL16_HA: r = R_PPC_DTPREL16_HA; break;
-+ case BFD_RELOC_PPC_DTPREL: r = R_PPC_DTPREL32; break;
-+ case BFD_RELOC_PPC_GOT_TLSGD16: r = R_PPC_GOT_TLSGD16; break;
-+ case BFD_RELOC_PPC_GOT_TLSGD16_LO: r = R_PPC_GOT_TLSGD16_LO; break;
-+ case BFD_RELOC_PPC_GOT_TLSGD16_HI: r = R_PPC_GOT_TLSGD16_HI; break;
-+ case BFD_RELOC_PPC_GOT_TLSGD16_HA: r = R_PPC_GOT_TLSGD16_HA; break;
-+ case BFD_RELOC_PPC_GOT_TLSLD16: r = R_PPC_GOT_TLSLD16; break;
-+ case BFD_RELOC_PPC_GOT_TLSLD16_LO: r = R_PPC_GOT_TLSLD16_LO; break;
-+ case BFD_RELOC_PPC_GOT_TLSLD16_HI: r = R_PPC_GOT_TLSLD16_HI; break;
-+ case BFD_RELOC_PPC_GOT_TLSLD16_HA: r = R_PPC_GOT_TLSLD16_HA; break;
-+ case BFD_RELOC_PPC_GOT_TPREL16: r = R_PPC_GOT_TPREL16; break;
-+ case BFD_RELOC_PPC_GOT_TPREL16_LO: r = R_PPC_GOT_TPREL16_LO; break;
-+ case BFD_RELOC_PPC_GOT_TPREL16_HI: r = R_PPC_GOT_TPREL16_HI; break;
-+ case BFD_RELOC_PPC_GOT_TPREL16_HA: r = R_PPC_GOT_TPREL16_HA; break;
-+ case BFD_RELOC_PPC_GOT_DTPREL16: r = R_PPC_GOT_DTPREL16; break;
-+ case BFD_RELOC_PPC_GOT_DTPREL16_LO: r = R_PPC_GOT_DTPREL16_LO; break;
-+ case BFD_RELOC_PPC_GOT_DTPREL16_HI: r = R_PPC_GOT_DTPREL16_HI; break;
-+ case BFD_RELOC_PPC_GOT_DTPREL16_HA: r = R_PPC_GOT_DTPREL16_HA; break;
-+ case BFD_RELOC_PPC_EMB_NADDR32: r = R_PPC_EMB_NADDR32; break;
-+ case BFD_RELOC_PPC_EMB_NADDR16: r = R_PPC_EMB_NADDR16; break;
-+ case BFD_RELOC_PPC_EMB_NADDR16_LO: r = R_PPC_EMB_NADDR16_LO; break;
-+ case BFD_RELOC_PPC_EMB_NADDR16_HI: r = R_PPC_EMB_NADDR16_HI; break;
-+ case BFD_RELOC_PPC_EMB_NADDR16_HA: r = R_PPC_EMB_NADDR16_HA; break;
-+ case BFD_RELOC_PPC_EMB_SDAI16: r = R_PPC_EMB_SDAI16; break;
-+ case BFD_RELOC_PPC_EMB_SDA2I16: r = R_PPC_EMB_SDA2I16; break;
-+ case BFD_RELOC_PPC_EMB_SDA2REL: r = R_PPC_EMB_SDA2REL; break;
-+ case BFD_RELOC_PPC_EMB_SDA21: r = R_PPC_EMB_SDA21; break;
-+ case BFD_RELOC_PPC_EMB_MRKREF: r = R_PPC_EMB_MRKREF; break;
-+ case BFD_RELOC_PPC_EMB_RELSEC16: r = R_PPC_EMB_RELSEC16; break;
-+ case BFD_RELOC_PPC_EMB_RELST_LO: r = R_PPC_EMB_RELST_LO; break;
-+ case BFD_RELOC_PPC_EMB_RELST_HI: r = R_PPC_EMB_RELST_HI; break;
-+ case BFD_RELOC_PPC_EMB_RELST_HA: r = R_PPC_EMB_RELST_HA; break;
-+ case BFD_RELOC_PPC_EMB_BIT_FLD: r = R_PPC_EMB_BIT_FLD; break;
-+ case BFD_RELOC_PPC_EMB_RELSDA: r = R_PPC_EMB_RELSDA; break;
-+ case BFD_RELOC_PPC_VLE_REL8: r = R_PPC_VLE_REL8; break;
-+ case BFD_RELOC_PPC_VLE_REL15: r = R_PPC_VLE_REL15; break;
-+ case BFD_RELOC_PPC_VLE_REL24: r = R_PPC_VLE_REL24; break;
-+ case BFD_RELOC_PPC_VLE_LO16A: r = R_PPC_VLE_LO16A; break;
-+ case BFD_RELOC_PPC_VLE_LO16D: r = R_PPC_VLE_LO16D; break;
-+ case BFD_RELOC_PPC_VLE_HI16A: r = R_PPC_VLE_HI16A; break;
-+ case BFD_RELOC_PPC_VLE_HI16D: r = R_PPC_VLE_HI16D; break;
-+ case BFD_RELOC_PPC_VLE_HA16A: r = R_PPC_VLE_HA16A; break;
-+ case BFD_RELOC_PPC_VLE_HA16D: r = R_PPC_VLE_HA16D; break;
-+ case BFD_RELOC_PPC_VLE_SDA21: r = R_PPC_VLE_SDA21; break;
-+ case BFD_RELOC_PPC_VLE_SDA21_LO: r = R_PPC_VLE_SDA21_LO; break;
-+ case BFD_RELOC_PPC_VLE_SDAREL_LO16A:
-+ r = R_PPC_VLE_SDAREL_LO16A;
-+ break;
-+ case BFD_RELOC_PPC_VLE_SDAREL_LO16D:
-+ r = R_PPC_VLE_SDAREL_LO16D;
-+ break;
-+ case BFD_RELOC_PPC_VLE_SDAREL_HI16A:
-+ r = R_PPC_VLE_SDAREL_HI16A;
-+ break;
-+ case BFD_RELOC_PPC_VLE_SDAREL_HI16D:
-+ r = R_PPC_VLE_SDAREL_HI16D;
-+ break;
-+ case BFD_RELOC_PPC_VLE_SDAREL_HA16A:
-+ r = R_PPC_VLE_SDAREL_HA16A;
-+ break;
-+ case BFD_RELOC_PPC_VLE_SDAREL_HA16D:
-+ r = R_PPC_VLE_SDAREL_HA16D;
-+ break;
-+ case BFD_RELOC_16_PCREL: r = R_PPC_REL16; break;
-+ case BFD_RELOC_LO16_PCREL: r = R_PPC_REL16_LO; break;
-+ case BFD_RELOC_HI16_PCREL: r = R_PPC_REL16_HI; break;
-+ case BFD_RELOC_HI16_S_PCREL: r = R_PPC_REL16_HA; break;
-+ case BFD_RELOC_PPC_AMIGAOS_BREL: r = R_PPC_AMIGAOS_BREL; break;
-+ case BFD_RELOC_PPC_AMIGAOS_BREL_LO: r = R_PPC_AMIGAOS_BREL_LO; break;
-+ case BFD_RELOC_PPC_AMIGAOS_BREL_HI: r = R_PPC_AMIGAOS_BREL_HI; break;
-+ case BFD_RELOC_PPC_AMIGAOS_BREL_HA: r = R_PPC_AMIGAOS_BREL_HA; break;
-+ case BFD_RELOC_VTABLE_INHERIT: r = R_PPC_GNU_VTINHERIT; break;
-+ case BFD_RELOC_VTABLE_ENTRY: r = R_PPC_GNU_VTENTRY; break;
-+ }
-+
-+ return ppc_elf_howto_table[r];
-+};
-+
-+static reloc_howto_type *
-+ppc_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
-+ const char *r_name)
-+{
-+ unsigned int i;
-+
-+ for (i = 0;
-+ i < sizeof (ppc_elf_howto_raw) / sizeof (ppc_elf_howto_raw[0]);
-+ i++)
-+ if (ppc_elf_howto_raw[i].name != NULL
-+ && strcasecmp (ppc_elf_howto_raw[i].name, r_name) == 0)
-+ return &ppc_elf_howto_raw[i];
-+
-+ return NULL;
-+}
-+
-+/* Set the howto pointer for a PowerPC ELF reloc. */
-+
-+static void
-+ppc_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
-+ arelent *cache_ptr,
-+ Elf_Internal_Rela *dst)
-+{
-+ /* Initialize howto table if not already done. */
-+ if (!ppc_elf_howto_table[R_PPC_ADDR32])
-+ ppc_elf_howto_init ();
-+
-+ BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_PPC_max);
-+ cache_ptr->howto = ppc_elf_howto_table[ELF32_R_TYPE (dst->r_info)];
-+
-+ /* Just because the above assert didn't trigger doesn't mean that
-+ ELF32_R_TYPE (dst->r_info) is necessarily a valid relocation. */
-+ if (!cache_ptr->howto)
-+ {
-+ (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
-+ abfd, ELF32_R_TYPE (dst->r_info));
-+ bfd_set_error (bfd_error_bad_value);
-+
-+ cache_ptr->howto = ppc_elf_howto_table[R_PPC_NONE];
-+ }
-+}
-+
-+/* Handle the R_PPC_ADDR16_HA and R_PPC_REL16_HA relocs. */
-+
-+static bfd_reloc_status_type
-+ppc_elf_addr16_ha_reloc (bfd *abfd ATTRIBUTE_UNUSED,
-+ arelent *reloc_entry,
-+ asymbol *symbol,
-+ void *data ATTRIBUTE_UNUSED,
-+ asection *input_section,
-+ bfd *output_bfd,
-+ char **error_message ATTRIBUTE_UNUSED)
-+{
-+ bfd_vma relocation;
-+
-+ if (output_bfd != NULL)
-+ {
-+ reloc_entry->address += input_section->output_offset;
-+ return bfd_reloc_ok;
-+ }
-+
-+ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
-+ return bfd_reloc_outofrange;
-+
-+ if (bfd_is_com_section (symbol->section))
-+ relocation = 0;
-+ else
-+ relocation = symbol->value;
-+
-+ relocation += symbol->section->output_section->vma;
-+ relocation += symbol->section->output_offset;
-+ relocation += reloc_entry->addend;
-+ if (reloc_entry->howto->pc_relative)
-+ relocation -= reloc_entry->address;
-+
-+ reloc_entry->addend += (relocation & 0x8000) << 1;
-+
-+ return bfd_reloc_continue;
-+}
-+
-+static bfd_reloc_status_type
-+ppc_elf_unhandled_reloc (bfd *abfd,
-+ arelent *reloc_entry,
-+ asymbol *symbol,
-+ void *data,
-+ asection *input_section,
-+ bfd *output_bfd,
-+ char **error_message)
-+{
-+ /* If this is a relocatable link (output_bfd test tells us), just
-+ call the generic function. Any adjustment will be done at final
-+ link time. */
-+ if (output_bfd != NULL)
-+ return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
-+ input_section, output_bfd, error_message);
-+
-+ if (error_message != NULL)
-+ {
-+ static char buf[60];
-+ sprintf (buf, _("generic linker can't handle %s"),
-+ reloc_entry->howto->name);
-+ *error_message = buf;
-+ }
-+ return bfd_reloc_dangerous;
-+}
-+
-+/* Sections created by the linker. */
-+
-+typedef struct elf_linker_section
-+{
-+ /* Pointer to the bfd section. */
-+ asection *section;
-+ /* Section name. */
-+ const char *name;
-+ /* Associated bss section name. */
-+ const char *bss_name;
-+ /* Associated symbol name. */
-+ const char *sym_name;
-+ /* Associated symbol. */
-+ struct elf_link_hash_entry *sym;
-+} elf_linker_section_t;
-+
-+/* Linked list of allocated pointer entries. This hangs off of the
-+ symbol lists, and provides allows us to return different pointers,
-+ based on different addend's. */
-+
-+typedef struct elf_linker_section_pointers
-+{
-+ /* next allocated pointer for this symbol */
-+ struct elf_linker_section_pointers *next;
-+ /* offset of pointer from beginning of section */
-+ bfd_vma offset;
-+ /* addend used */
-+ bfd_vma addend;
-+ /* which linker section this is */
-+ elf_linker_section_t *lsect;
-+} elf_linker_section_pointers_t;
-+
-+struct ppc_elf_obj_tdata
-+{
-+ struct elf_obj_tdata elf;
-+
-+ /* A mapping from local symbols to offsets into the various linker
-+ sections added. This is index by the symbol index. */
-+ elf_linker_section_pointers_t **linker_section_pointers;
-+
-+ /* Flags used to auto-detect plt type. */
-+ unsigned int makes_plt_call : 1;
-+ unsigned int has_rel16 : 1;
-+};
-+
-+#define ppc_elf_tdata(bfd) \
-+ ((struct ppc_elf_obj_tdata *) (bfd)->tdata.any)
-+
-+#define elf_local_ptr_offsets(bfd) \
-+ (ppc_elf_tdata (bfd)->linker_section_pointers)
-+
-+#define is_ppc_elf(bfd) \
-+ (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
-+ && elf_object_id (bfd) == PPC32_ELF_DATA)
-+
-+/* Override the generic function because we store some extras. */
-+
-+static bfd_boolean
-+ppc_elf_mkobject (bfd *abfd)
-+{
-+ return bfd_elf_allocate_object (abfd, sizeof (struct ppc_elf_obj_tdata),
-+ PPC32_ELF_DATA);
-+}
-+
-+/* Fix bad default arch selected for a 32 bit input bfd when the
-+ default is 64 bit. */
-+
-+static bfd_boolean
-+ppc_elf_object_p (bfd *abfd)
-+{
-+ if (abfd->arch_info->the_default && abfd->arch_info->bits_per_word == 64)
-+ {
-+ Elf_Internal_Ehdr *i_ehdr = elf_elfheader (abfd);
-+
-+ if (i_ehdr->e_ident[EI_CLASS] == ELFCLASS32)
-+ {
-+ /* Relies on arch after 64 bit default being 32 bit default. */
-+ abfd->arch_info = abfd->arch_info->next;
-+ BFD_ASSERT (abfd->arch_info->bits_per_word == 32);
-+ }
-+ }
-+ return TRUE;
-+}
-+
-+/* Function to set whether a module needs the -mrelocatable bit set. */
-+
-+static bfd_boolean
-+ppc_elf_set_private_flags (bfd *abfd, flagword flags)
-+{
-+ BFD_ASSERT (!elf_flags_init (abfd)
-+ || elf_elfheader (abfd)->e_flags == flags);
-+
-+ elf_elfheader (abfd)->e_flags = flags;
-+ elf_flags_init (abfd) = TRUE;
-+ return TRUE;
-+}
-+
-+/* Support for core dump NOTE sections. */
-+
-+static bfd_boolean
-+ppc_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
-+{
-+ int offset;
-+ unsigned int size;
-+
-+ switch (note->descsz)
-+ {
-+ default:
-+ return FALSE;
-+
-+ case 268: /* Linux/PPC. */
-+ /* pr_cursig */
-+ elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
-+
-+ /* pr_pid */
-+ elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, note->descdata + 24);
-+
-+ /* pr_reg */
-+ offset = 72;
-+ size = 192;
-+
-+ break;
-+ }
-+
-+ /* Make a ".reg/999" section. */
-+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
-+ size, note->descpos + offset);
-+}
-+
-+static bfd_boolean
-+ppc_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
-+{
-+ switch (note->descsz)
-+ {
-+ default:
-+ return FALSE;
-+
-+ case 128: /* Linux/PPC elf_prpsinfo. */
-+ elf_tdata (abfd)->core_pid
-+ = bfd_get_32 (abfd, note->descdata + 16);
-+ elf_tdata (abfd)->core_program
-+ = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
-+ elf_tdata (abfd)->core_command
-+ = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
-+ }
-+
-+ /* Note that for some reason, a spurious space is tacked
-+ onto the end of the args in some (at least one anyway)
-+ implementations, so strip it off if it exists. */
-+
-+ {
-+ char *command = elf_tdata (abfd)->core_command;
-+ int n = strlen (command);
-+
-+ if (0 < n && command[n - 1] == ' ')
-+ command[n - 1] = '\0';
-+ }
-+
-+ return TRUE;
-+}
-+
-+static char *
-+ppc_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type, ...)
-+{
-+ switch (note_type)
-+ {
-+ default:
-+ return NULL;
-+
-+ case NT_PRPSINFO:
-+ {
-+ char data[128];
-+ va_list ap;
-+
-+ va_start (ap, note_type);
-+ memset (data, 0, sizeof (data));
-+ strncpy (data + 32, va_arg (ap, const char *), 16);
-+ strncpy (data + 48, va_arg (ap, const char *), 80);
-+ va_end (ap);
-+ return elfcore_write_note (abfd, buf, bufsiz,
-+ "CORE", note_type, data, sizeof (data));
-+ }
-+
-+ case NT_PRSTATUS:
-+ {
-+ char data[268];
-+ va_list ap;
-+ long pid;
-+ int cursig;
-+ const void *greg;
-+
-+ va_start (ap, note_type);
-+ memset (data, 0, 72);
-+ pid = va_arg (ap, long);
-+ bfd_put_32 (abfd, pid, data + 24);
-+ cursig = va_arg (ap, int);
-+ bfd_put_16 (abfd, cursig, data + 12);
-+ greg = va_arg (ap, const void *);
-+ memcpy (data + 72, greg, 192);
-+ memset (data + 264, 0, 4);
-+ va_end (ap);
-+ return elfcore_write_note (abfd, buf, bufsiz,
-+ "CORE", note_type, data, sizeof (data));
-+ }
-+ }
-+}
-+
-+static flagword
-+ppc_elf_lookup_section_flags (char *flag_name)
-+{
-+
-+ if (!strcmp (flag_name, "SHF_PPC_VLE"))
-+ return SHF_PPC_VLE;
-+
-+ return 0;
-+}
-+
-+/* Add the VLE flag if required. */
-+
-+bfd_boolean
-+ppc_elf_amigaos_section_processing (bfd *abfd, Elf_Internal_Shdr *shdr)
-+{
-+ if (bfd_get_mach (abfd) == bfd_mach_ppc_vle
-+ && (shdr->sh_flags & SHF_EXECINSTR) != 0)
-+ shdr->sh_flags |= SHF_PPC_VLE;
-+
-+ return TRUE;
-+}
-+
-+/* Return address for Ith PLT stub in section PLT, for relocation REL
-+ or (bfd_vma) -1 if it should not be included. */
-+
-+static bfd_vma
-+ppc_elf_plt_sym_val (bfd_vma i ATTRIBUTE_UNUSED,
-+ const asection *plt ATTRIBUTE_UNUSED,
-+ const arelent *rel)
-+{
-+#ifdef DEBUG
-+ fprintf (stderr, "ppc_elf_plt_sym_cal (0x%08x)\n", (unsigned int)rel->address);
-+#endif
-+ return rel->address;
-+}
-+
-+/* Handle a PowerPC specific section when reading an object file. This
-+ is called when bfd_section_from_shdr finds a section with an unknown
-+ type. */
-+
-+static bfd_boolean
-+ppc_elf_section_from_shdr (bfd *abfd,
-+ Elf_Internal_Shdr *hdr,
-+ const char *name,
-+ int shindex)
-+{
-+ asection *newsect;
-+ flagword flags;
-+
-+ if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
-+ return FALSE;
-+
-+ newsect = hdr->bfd_section;
-+ flags = bfd_get_section_flags (abfd, newsect);
-+ if (hdr->sh_flags & SHF_EXCLUDE)
-+ flags |= SEC_EXCLUDE;
-+
-+ if (hdr->sh_type == SHT_ORDERED)
-+ flags |= SEC_SORT_ENTRIES;
-+
-+ bfd_set_section_flags (abfd, newsect, flags);
-+ return TRUE;
-+}
-+
-+/* Set up any other section flags and such that may be necessary. */
-+
-+static bfd_boolean
-+ppc_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
-+ Elf_Internal_Shdr *shdr,
-+ asection *asect)
-+{
-+ if ((asect->flags & SEC_SORT_ENTRIES) != 0)
-+ shdr->sh_type = SHT_ORDERED;
-+
-+ return TRUE;
-+}
-+
-+/* If we have .sbss2 or .PPC.EMB.sbss0 output sections, we
-+ need to bump up the number of section headers. */
-+
-+static int
-+ppc_elf_additional_program_headers (bfd *abfd,
-+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
-+{
-+ asection *s;
-+// int ret = 0;
-+ int ret = 1;
-+
-+ s = bfd_get_section_by_name (abfd, ".sbss2");
-+ if (s != NULL && (s->flags & SEC_ALLOC) != 0)
-+ ++ret;
-+
-+ s = bfd_get_section_by_name (abfd, ".PPC.EMB.sbss0");
-+ if (s != NULL && (s->flags & SEC_ALLOC) != 0)
-+ ++ret;
-+
-+ return ret;
-+}
-+
-+/* Modify the segment map for VLE executables. */
-+
-+bfd_boolean
-+ppc_elf_amigaos_modify_segment_map (bfd *abfd,
-+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
-+{
-+ struct elf_segment_map *m, *n;
-+ bfd_size_type amt;
-+ unsigned int j, k;
-+ bfd_boolean sect0_vle, sectj_vle;
-+
-+ /* At this point in the link, output sections have already been sorted by
-+ LMA and assigned to segments. All that is left to do is to ensure
-+ there is no mixing of VLE & non-VLE sections in a text segment.
-+ If we find that case, we split the segment.
-+ We maintain the original output section order. */
-+
-+ for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
-+ {
-+ if (m->count == 0)
-+ continue;
-+
-+ sect0_vle = (elf_section_flags (m->sections[0]) & SHF_PPC_VLE) != 0;
-+ for (j = 1; j < m->count; ++j)
-+ {
-+ sectj_vle = (elf_section_flags (m->sections[j]) & SHF_PPC_VLE) != 0;
-+
-+ if (sectj_vle != sect0_vle)
-+ break;
-+ }
-+ if (j >= m->count)
-+ continue;
-+
-+ /* sections 0..j-1 stay in this (current) segment,
-+ the remainder are put in a new segment.
-+ The scan resumes with the new segment. */
-+
-+ /* Fix the new segment. */
-+ amt = sizeof (struct elf_segment_map);
-+ amt += (m->count - j - 1) * sizeof (asection *);
-+ n = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
-+ if (n == NULL)
-+ return FALSE;
-+
-+ n->p_type = PT_LOAD;
-+ n->p_flags = PF_X | PF_R;
-+ if (sectj_vle)
-+ n->p_flags |= PF_PPC_VLE;
-+ n->count = m->count - j;
-+ for (k = 0; k < n->count; ++k)
-+ {
-+ n->sections[k] = m->sections[j+k];
-+ m->sections[j+k] = NULL;
-+ }
-+ n->next = m->next;
-+ m->next = n;
-+
-+ /* Fix the current segment */
-+ m->count = j;
-+ }
-+
-+ return TRUE;
-+}
-+
-+/* Add extra PPC sections -- Note, for now, make .sbss2 and
-+ .PPC.EMB.sbss0 a normal section, and not a bss section so
-+ that the linker doesn't crater when trying to make more than
-+ 2 sections. */
-+
-+static const struct bfd_elf_special_section ppc_elf_special_sections[] =
-+{
-+ { STRING_COMMA_LEN (".plt"), 0, SHT_NOBITS, SHF_ALLOC + SHF_EXECINSTR },
-+ { STRING_COMMA_LEN (".sbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
-+ { STRING_COMMA_LEN (".sbss2"), -2, SHT_PROGBITS, SHF_ALLOC },
-+ { STRING_COMMA_LEN (".sdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
-+ { STRING_COMMA_LEN (".sdata2"), -2, SHT_PROGBITS, SHF_ALLOC },
-+ { STRING_COMMA_LEN (".tags"), 0, SHT_ORDERED, SHF_ALLOC },
-+ { STRING_COMMA_LEN (".PPC.EMB.apuinfo"), 0, SHT_NOTE, 0 },
-+ { STRING_COMMA_LEN (".PPC.EMB.sbss0"), 0, SHT_PROGBITS, SHF_ALLOC },
-+ { STRING_COMMA_LEN (".PPC.EMB.sdata0"), 0, SHT_PROGBITS, SHF_ALLOC },
-+ { NULL, 0, 0, 0, 0 }
-+};
-+
-+/* This is what we want for new plt/got. */
-+static struct bfd_elf_special_section ppc_alt_plt =
-+ { STRING_COMMA_LEN (".plt"), 0, SHT_PROGBITS, SHF_ALLOC };
-+
-+static const struct bfd_elf_special_section *
-+ppc_elf_get_sec_type_attr (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
-+{
-+ const struct bfd_elf_special_section *ssect;
-+
-+ /* See if this is one of the special sections. */
-+ if (sec->name == NULL)
-+ return NULL;
-+
-+ ssect = _bfd_elf_get_special_section (sec->name, ppc_elf_special_sections,
-+ sec->use_rela_p);
-+ if (ssect != NULL)
-+ {
-+ if (ssect == ppc_elf_special_sections && (sec->flags & SEC_LOAD) != 0)
-+ ssect = &ppc_alt_plt;
-+ return ssect;
-+ }
-+
-+ return _bfd_elf_get_sec_type_attr (abfd, sec);
-+}
-+
-+/* Very simple linked list structure for recording apuinfo values. */
-+typedef struct apuinfo_list
-+{
-+ struct apuinfo_list *next;
-+ unsigned long value;
-+}
-+apuinfo_list;
-+
-+static apuinfo_list *head;
-+static bfd_boolean apuinfo_set;
-+
-+static void
-+apuinfo_list_init (void)
-+{
-+ head = NULL;
-+ apuinfo_set = FALSE;
-+}
-+
-+static void
-+apuinfo_list_add (unsigned long value)
-+{
-+ apuinfo_list *entry = head;
-+
-+ while (entry != NULL)
-+ {
-+ if (entry->value == value)
-+ return;
-+ entry = entry->next;
-+ }
-+
-+ entry = bfd_malloc (sizeof (* entry));
-+ if (entry == NULL)
-+ return;
-+
-+ entry->value = value;
-+ entry->next = head;
-+ head = entry;
-+}
-+
-+static unsigned
-+apuinfo_list_length (void)
-+{
-+ apuinfo_list *entry;
-+ unsigned long count;
-+
-+ for (entry = head, count = 0;
-+ entry;
-+ entry = entry->next)
-+ ++ count;
-+
-+ return count;
-+}
-+
-+static inline unsigned long
-+apuinfo_list_element (unsigned long number)
-+{
-+ apuinfo_list * entry;
-+
-+ for (entry = head;
-+ entry && number --;
-+ entry = entry->next)
-+ ;
-+
-+ return entry ? entry->value : 0;
-+}
-+
-+static void
-+apuinfo_list_finish (void)
-+{
-+ apuinfo_list *entry;
-+
-+ for (entry = head; entry;)
-+ {
-+ apuinfo_list *next = entry->next;
-+ free (entry);
-+ entry = next;
-+ }
-+
-+ head = NULL;
-+}
-+
-+#define APUINFO_SECTION_NAME ".PPC.EMB.apuinfo"
-+#define APUINFO_LABEL "APUinfo"
-+
-+/* Scan the input BFDs and create a linked list of
-+ the APUinfo values that will need to be emitted. */
-+
-+static void
-+ppc_elf_amigaos_begin_write_processing (bfd *abfd, struct bfd_link_info *link_info)
-+{
-+ bfd *ibfd;
-+ asection *asec;
-+ char *buffer = NULL;
-+ bfd_size_type largest_input_size = 0;
-+ unsigned i;
-+ unsigned long length;
-+ const char *error_message = NULL;
-+
-+ if (link_info == NULL)
-+ return;
-+
-+ apuinfo_list_init ();
-+
-+ /* Read in the input sections contents. */
-+ for (ibfd = link_info->input_bfds; ibfd; ibfd = ibfd->link_next)
-+ {
-+ unsigned long datum;
-+
-+ asec = bfd_get_section_by_name (ibfd, APUINFO_SECTION_NAME);
-+ if (asec == NULL)
-+ continue;
-+
-+ error_message = _("corrupt %s section in %B");
-+ length = asec->size;
-+ if (length < 20)
-+ goto fail;
-+
-+ apuinfo_set = TRUE;
-+ if (largest_input_size < asec->size)
-+ {
-+ if (buffer)
-+ free (buffer);
-+ largest_input_size = asec->size;
-+ buffer = bfd_malloc (largest_input_size);
-+ if (!buffer)
-+ return;
-+ }
-+
-+ if (bfd_seek (ibfd, asec->filepos, SEEK_SET) != 0
-+ || (bfd_bread (buffer, length, ibfd) != length))
-+ {
-+ error_message = _("unable to read in %s section from %B");
-+ goto fail;
-+ }
-+
-+ /* Verify the contents of the header. Note - we have to
-+ extract the values this way in order to allow for a
-+ host whose endian-ness is different from the target. */
-+ datum = bfd_get_32 (ibfd, buffer);
-+ if (datum != sizeof APUINFO_LABEL)
-+ goto fail;
-+
-+ datum = bfd_get_32 (ibfd, buffer + 8);
-+ if (datum != 0x2)
-+ goto fail;
-+
-+ if (strcmp (buffer + 12, APUINFO_LABEL) != 0)
-+ goto fail;
-+
-+ /* Get the number of bytes used for apuinfo entries. */
-+ datum = bfd_get_32 (ibfd, buffer + 4);
-+ if (datum + 20 != length)
-+ goto fail;
-+
-+ /* Scan the apuinfo section, building a list of apuinfo numbers. */
-+ for (i = 0; i < datum; i += 4)
-+ apuinfo_list_add (bfd_get_32 (ibfd, buffer + 20 + i));
-+ }
-+
-+ error_message = NULL;
-+
-+ if (apuinfo_set)
-+ {
-+ /* Compute the size of the output section. */
-+ unsigned num_entries = apuinfo_list_length ();
-+
-+ /* Set the output section size, if it exists. */
-+ asec = bfd_get_section_by_name (abfd, APUINFO_SECTION_NAME);
-+
-+ if (asec && ! bfd_set_section_size (abfd, asec, 20 + num_entries * 4))
-+ {
-+ ibfd = abfd;
-+ error_message = _("warning: unable to set size of %s section in %B");
-+ }
-+ }
-+
-+ fail:
-+ if (buffer)
-+ free (buffer);
-+
-+ if (error_message)
-+ (*_bfd_error_handler) (error_message, ibfd, APUINFO_SECTION_NAME);
-+}
-+
-+/* Prevent the output section from accumulating the input sections'
-+ contents. We have already stored this in our linked list structure. */
-+
-+static bfd_boolean
-+ppc_elf_amigaos_write_section (bfd *abfd ATTRIBUTE_UNUSED,
-+ struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
-+ asection *asec,
-+ bfd_byte *contents ATTRIBUTE_UNUSED)
-+{
-+ return apuinfo_set && strcmp (asec->name, APUINFO_SECTION_NAME) == 0;
-+}
-+
-+/* Finally we can generate the output section. */
-+
-+static void
-+ppc_elf_amigaos_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
-+{
-+ bfd_byte *buffer;
-+ asection *asec;
-+ unsigned i;
-+ unsigned num_entries;
-+ bfd_size_type length;
-+
-+ asec = bfd_get_section_by_name (abfd, APUINFO_SECTION_NAME);
-+ if (asec == NULL)
-+ return;
-+
-+ if (!apuinfo_set)
-+ return;
-+
-+ length = asec->size;
-+ if (length < 20)
-+ return;
-+
-+ buffer = bfd_malloc (length);
-+ if (buffer == NULL)
-+ {
-+ (*_bfd_error_handler)
-+ (_("failed to allocate space for new APUinfo section."));
-+ return;
-+ }
-+
-+ /* Create the apuinfo header. */
-+ num_entries = apuinfo_list_length ();
-+ bfd_put_32 (abfd, sizeof APUINFO_LABEL, buffer);
-+ bfd_put_32 (abfd, num_entries * 4, buffer + 4);
-+ bfd_put_32 (abfd, 0x2, buffer + 8);
-+ strcpy ((char *) buffer + 12, APUINFO_LABEL);
-+
-+ length = 20;
-+ for (i = 0; i < num_entries; i++)
-+ {
-+ bfd_put_32 (abfd, apuinfo_list_element (i), buffer + length);
-+ length += 4;
-+ }
-+
-+ if (length != asec->size)
-+ (*_bfd_error_handler) (_("failed to compute new APUinfo section."));
-+
-+ if (! bfd_set_section_contents (abfd, asec, buffer, (file_ptr) 0, length))
-+ (*_bfd_error_handler) (_("failed to install new APUinfo section."));
-+
-+ free (buffer);
-+
-+ apuinfo_list_finish ();
-+}
-+
-+static bfd_boolean
-+is_nonpic_glink_stub (bfd *abfd, asection *glink, bfd_vma off)
-+{
-+ bfd_byte buf[GLINK_ENTRY_SIZE];
-+
-+ if (!bfd_get_section_contents (abfd, glink, buf, off, GLINK_ENTRY_SIZE))
-+ return FALSE;
-+
-+ return ((bfd_get_32 (abfd, buf + 0) & 0xffff0000) == LIS_11
-+ && (bfd_get_32 (abfd, buf + 4) & 0xffff0000) == LWZ_11_11
-+ && bfd_get_32 (abfd, buf + 8) == MTCTR_11
-+ && bfd_get_32 (abfd, buf + 12) == BCTR);
-+}
-+
-+static bfd_boolean
-+section_covers_vma (bfd *abfd ATTRIBUTE_UNUSED, asection *section, void *ptr)
-+{
-+ bfd_vma vma = *(bfd_vma *) ptr;
-+ return ((section->flags & SEC_ALLOC) != 0
-+ && section->vma <= vma
-+ && vma < section->vma + section->size);
-+}
-+
-+static long
-+ppc_elf_get_synthetic_symtab (bfd *abfd, long symcount, asymbol **syms,
-+ long dynsymcount, asymbol **dynsyms,
-+ asymbol **ret)
-+{
-+ bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
-+ asection *plt, *relplt, *dynamic, *glink;
-+ bfd_vma glink_vma = 0;
-+ bfd_vma resolv_vma = 0;
-+ bfd_vma stub_vma;
-+ asymbol *s;
-+ arelent *p;
-+ long count, i;
-+ size_t size;
-+ char *names;
-+ bfd_byte buf[4];
-+
-+ *ret = NULL;
-+
-+ if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0)
-+ return 0;
-+
-+ if (dynsymcount <= 0)
-+ return 0;
-+
-+ relplt = bfd_get_section_by_name (abfd, ".rela.plt");
-+ if (relplt == NULL)
-+ return 0;
-+
-+ plt = bfd_get_section_by_name (abfd, ".plt");
-+ if (plt == NULL)
-+ return 0;
-+
-+ /* Call common code to handle old-style executable PLTs. */
-+ if (elf_section_flags (plt) & SHF_EXECINSTR)
-+ return _bfd_elf_get_synthetic_symtab (abfd, symcount, syms,
-+ dynsymcount, dynsyms, ret);
-+
-+ /* If this object was prelinked, the prelinker stored the address
-+ of .glink at got[1]. If it wasn't prelinked, got[1] will be zero. */
-+ dynamic = bfd_get_section_by_name (abfd, ".dynamic");
-+ if (dynamic != NULL)
-+ {
-+ bfd_byte *dynbuf, *extdyn, *extdynend;
-+ size_t extdynsize;
-+ void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);
-+
-+ if (!bfd_malloc_and_get_section (abfd, dynamic, &dynbuf))
-+ return -1;
-+
-+ extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
-+ swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;
-+
-+ extdyn = dynbuf;
-+ extdynend = extdyn + dynamic->size;
-+ for (; extdyn < extdynend; extdyn += extdynsize)
-+ {
-+ Elf_Internal_Dyn dyn;
-+ (*swap_dyn_in) (abfd, extdyn, &dyn);
-+
-+ if (dyn.d_tag == DT_NULL)
-+ break;
-+
-+ if (dyn.d_tag == DT_PPC_GOT)
-+ {
-+ unsigned int g_o_t = dyn.d_un.d_val;
-+ asection *got = bfd_get_section_by_name (abfd, ".got");
-+ if (got != NULL
-+ && bfd_get_section_contents (abfd, got, buf,
-+ g_o_t - got->vma + 4, 4))
-+ glink_vma = bfd_get_32 (abfd, buf);
-+ break;
-+ }
-+ }
-+ free (dynbuf);
-+ }
-+
-+ /* Otherwise we read the first plt entry. */
-+ if (glink_vma == 0)
-+ {
-+ if (bfd_get_section_contents (abfd, plt, buf, 0, 4))
-+ glink_vma = bfd_get_32 (abfd, buf);
-+ }
-+
-+ if (glink_vma == 0)
-+ return 0;
-+
-+ /* The .glink section usually does not survive the final
-+ link; search for the section (usually .text) where the
-+ glink stubs now reside. */
-+ glink = bfd_sections_find_if (abfd, section_covers_vma, &glink_vma);
-+ if (glink == NULL)
-+ return 0;
-+
-+ /* Determine glink PLT resolver by reading the relative branch
-+ from the first glink stub. */
-+ if (bfd_get_section_contents (abfd, glink, buf,
-+ glink_vma - glink->vma, 4))
-+ {
-+ unsigned int insn = bfd_get_32 (abfd, buf);
-+
-+ /* The first glink stub may either branch to the resolver ... */
-+ insn ^= B;
-+ if ((insn & ~0x3fffffc) == 0)
-+ resolv_vma = glink_vma + (insn ^ 0x2000000) - 0x2000000;
-+
-+ /* ... or fall through a bunch of NOPs. */
-+ else if ((insn ^ B ^ NOP) == 0)
-+ for (i = 4;
-+ bfd_get_section_contents (abfd, glink, buf,
-+ glink_vma - glink->vma + i, 4);
-+ i += 4)
-+ if (bfd_get_32 (abfd, buf) != NOP)
-+ {
-+ resolv_vma = glink_vma + i;
-+ break;
-+ }
-+ }
-+
-+ count = relplt->size / sizeof (Elf32_External_Rela);
-+ stub_vma = glink_vma - (bfd_vma) count * 16;
-+ /* If the stubs are those for -shared/-pie then we might have
-+ multiple stubs for each plt entry. If that is the case then
-+ there is no way to associate stubs with their plt entries short
-+ of figuring out the GOT pointer value used in the stub. */
-+ if (!is_nonpic_glink_stub (abfd, glink,
-+ glink_vma - GLINK_ENTRY_SIZE - glink->vma))
-+ return 0;
-+
-+ slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
-+ if (! (*slurp_relocs) (abfd, relplt, dynsyms, TRUE))
-+ return -1;
-+
-+ size = count * sizeof (asymbol);
-+ p = relplt->relocation;
-+ for (i = 0; i < count; i++, p++)
-+ {
-+ size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
-+ if (p->addend != 0)
-+ size += sizeof ("+0x") - 1 + 8;
-+ }
-+
-+ size += sizeof (asymbol) + sizeof ("__glink");
-+
-+ if (resolv_vma)
-+ size += sizeof (asymbol) + sizeof ("__glink_PLTresolve");
-+
-+ s = *ret = bfd_malloc (size);
-+ if (s == NULL)
-+ return -1;
-+
-+ names = (char *) (s + count + 1 + (resolv_vma != 0));
-+ p = relplt->relocation;
-+ for (i = 0; i < count; i++, p++)
-+ {
-+ size_t len;
-+
-+ *s = **p->sym_ptr_ptr;
-+ /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set. Since
-+ we are defining a symbol, ensure one of them is set. */
-+ if ((s->flags & BSF_LOCAL) == 0)
-+ s->flags |= BSF_GLOBAL;
-+ s->flags |= BSF_SYNTHETIC;
-+ s->section = glink;
-+ s->value = stub_vma - glink->vma;
-+ s->name = names;
-+ s->udata.p = NULL;
-+ len = strlen ((*p->sym_ptr_ptr)->name);
-+ memcpy (names, (*p->sym_ptr_ptr)->name, len);
-+ names += len;
-+ if (p->addend != 0)
-+ {
-+ memcpy (names, "+0x", sizeof ("+0x") - 1);
-+ names += sizeof ("+0x") - 1;
-+ bfd_sprintf_vma (abfd, names, p->addend);
-+ names += strlen (names);
-+ }
-+ memcpy (names, "@plt", sizeof ("@plt"));
-+ names += sizeof ("@plt");
-+ ++s;
-+ stub_vma += 16;
-+ }
-+
-+ /* Add a symbol at the start of the glink branch table. */
-+ memset (s, 0, sizeof *s);
-+ s->the_bfd = abfd;
-+ s->flags = BSF_GLOBAL | BSF_SYNTHETIC;
-+ s->section = glink;
-+ s->value = glink_vma - glink->vma;
-+ s->name = names;
-+ memcpy (names, "__glink", sizeof ("__glink"));
-+ names += sizeof ("__glink");
-+ s++;
-+ count++;
-+
-+ if (resolv_vma)
-+ {
-+ /* Add a symbol for the glink PLT resolver. */
-+ memset (s, 0, sizeof *s);
-+ s->the_bfd = abfd;
-+ s->flags = BSF_GLOBAL | BSF_SYNTHETIC;
-+ s->section = glink;
-+ s->value = resolv_vma - glink->vma;
-+ s->name = names;
-+ memcpy (names, "__glink_PLTresolve", sizeof ("__glink_PLTresolve"));
-+ names += sizeof ("__glink_PLTresolve");
-+ s++;
-+ count++;
-+ }
-+
-+ return count;
-+}
-+
-+/* The following functions are specific to the ELF linker, while
-+ functions above are used generally. They appear in this file more
-+ or less in the order in which they are called. eg.
-+ ppc_elf_check_relocs is called early in the link process,
-+ ppc_elf_finish_dynamic_sections is one of the last functions
-+ called. */
-+
-+/* Track PLT entries needed for a given symbol. We might need more
-+ than one glink entry per symbol when generating a pic binary. */
-+struct plt_entry
-+{
-+ struct plt_entry *next;
-+
-+ /* -fPIC uses multiple GOT sections, one per file, called ".got2".
-+ This field stores the offset into .got2 used to initialise the
-+ GOT pointer reg. It will always be at least 32768. (Current
-+ gcc always uses an offset of 32768, but ld -r will pack .got2
-+ sections together resulting in larger offsets). */
-+ bfd_vma addend;
-+
-+ /* The .got2 section. */
-+ asection *sec;
-+
-+ /* PLT refcount or offset. */
-+ union
-+ {
-+ bfd_signed_vma refcount;
-+ bfd_vma offset;
-+ } plt;
-+
-+ /* .glink stub offset. */
-+ bfd_vma glink_offset;
-+};
-+
-+/* Of those relocs that might be copied as dynamic relocs, this function
-+ selects those that must be copied when linking a shared library,
-+ even when the symbol is local. */
-+
-+static int
-+must_be_dyn_reloc (struct bfd_link_info *info,
-+ enum elf_ppc_reloc_type r_type)
-+{
-+ switch (r_type)
-+ {
-+ default:
-+ return 1;
-+
-+ case R_PPC_REL24:
-+ case R_PPC_REL14:
-+ case R_PPC_REL14_BRTAKEN:
-+ case R_PPC_REL14_BRNTAKEN:
-+ case R_PPC_REL32:
-+ return 0;
-+
-+ case R_PPC_TPREL32:
-+ case R_PPC_TPREL16:
-+ case R_PPC_TPREL16_LO:
-+ case R_PPC_TPREL16_HI:
-+ case R_PPC_TPREL16_HA:
-+ return !info->executable;
-+ }
-+}
-+
-+/* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
-+ copying dynamic variables from a shared lib into an app's dynbss
-+ section, and instead use a dynamic relocation to point into the
-+ shared lib. */
-+#define ELIMINATE_COPY_RELOCS 1
-+
-+/* PPC ELF linker hash entry. */
-+
-+struct ppc_elf_link_hash_entry
-+{
-+ struct elf_link_hash_entry elf;
-+
-+ /* If this symbol is used in the linker created sections, the processor
-+ specific backend uses this field to map the field into the offset
-+ from the beginning of the section. */
-+ elf_linker_section_pointers_t *linker_section_pointer;
-+
-+ /* Track dynamic relocs copied for this symbol. */
-+ struct elf_dyn_relocs *dyn_relocs;
-+
-+ /* Contexts in which symbol is used in the GOT (or TOC).
-+ TLS_GD .. TLS_TLS bits are or'd into the mask as the
-+ corresponding relocs are encountered during check_relocs.
-+ tls_optimize clears TLS_GD .. TLS_TPREL when optimizing to
-+ indicate the corresponding GOT entry type is not needed. */
-+#define TLS_GD 1 /* GD reloc. */
-+#define TLS_LD 2 /* LD reloc. */
-+#define TLS_TPREL 4 /* TPREL reloc, => IE. */
-+#define TLS_DTPREL 8 /* DTPREL reloc, => LD. */
-+#define TLS_TLS 16 /* Any TLS reloc. */
-+#define TLS_TPRELGD 32 /* TPREL reloc resulting from GD->IE. */
-+#define PLT_IFUNC 64 /* STT_GNU_IFUNC. */
-+ char tls_mask;
-+
-+ /* Nonzero if we have seen a small data relocation referring to this
-+ symbol. */
-+ unsigned char has_sda_refs;
-+};
-+
-+#define ppc_elf_hash_entry(ent) ((struct ppc_elf_link_hash_entry *) (ent))
-+
-+/* PPC ELF linker hash table. */
-+
-+struct ppc_elf_link_hash_table
-+{
-+ struct elf_link_hash_table elf;
-+
-+ /* Short-cuts to get to dynamic linker sections. */
-+ asection *got;
-+ asection *relgot;
-+ asection *glink;
-+ asection *plt;
-+ asection *relplt;
-+ asection *iplt;
-+ asection *reliplt;
-+ asection *dynbss;
-+ asection *relbss;
-+ asection *dynsbss;
-+ asection *relsbss;
-+ elf_linker_section_t sdata[2];
-+ asection *sbss;
-+ asection *glink_eh_frame;
-+
-+ /* The (unloaded but important) .rela.plt.unloaded on VxWorks. */
-+ asection *srelplt2;
-+
-+ /* The .got.plt section (VxWorks only)*/
-+ asection *sgotplt;
-+
-+ /* Shortcut to __tls_get_addr. */
-+ struct elf_link_hash_entry *tls_get_addr;
-+
-+ /* The bfd that forced an old-style PLT. */
-+ bfd *old_bfd;
-+
-+ /* TLS local dynamic got entry handling. */
-+ union {
-+ bfd_signed_vma refcount;
-+ bfd_vma offset;
-+ } tlsld_got;
-+
-+ /* Offset of branch table to PltResolve function in glink. */
-+ bfd_vma glink_pltresolve;
-+
-+ /* Size of reserved GOT entries. */
-+ unsigned int got_header_size;
-+ /* Non-zero if allocating the header left a gap. */
-+ unsigned int got_gap;
-+
-+ /* The type of PLT we have chosen to use. */
-+ enum ppc_elf_plt_type plt_type;
-+
-+ /* Set if we should emit symbols for stubs. */
-+ unsigned int emit_stub_syms:1;
-+
-+ /* Set if __tls_get_addr optimization should not be done. */
-+ unsigned int no_tls_get_addr_opt:1;
-+
-+ /* True if the target system is VxWorks. */
-+ unsigned int is_vxworks:1;
-+
-+ /* The size of PLT entries. */
-+ int plt_entry_size;
-+ /* The distance between adjacent PLT slots. */
-+ int plt_slot_size;
-+ /* The size of the first PLT entry. */
-+ int plt_initial_entry_size;
-+
-+ /* Small local sym cache. */
-+ struct sym_cache sym_cache;
-+};
-+
-+/* Rename some of the generic section flags to better document how they
-+ are used for ppc32. The flags are only valid for ppc32 elf objects. */
-+
-+/* Nonzero if this section has TLS related relocations. */
-+#define has_tls_reloc sec_flg0
-+
-+/* Nonzero if this section has a call to __tls_get_addr. */
-+#define has_tls_get_addr_call sec_flg1
-+
-+/* Get the PPC ELF linker hash table from a link_info structure. */
-+
-+#define ppc_elf_hash_table(p) \
-+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
-+ == PPC32_ELF_DATA ? ((struct ppc_elf_link_hash_table *) ((p)->hash)) : NULL)
-+
-+/* Create an entry in a PPC ELF linker hash table. */
-+
-+static struct bfd_hash_entry *
-+ppc_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
-+ struct bfd_hash_table *table,
-+ const char *string)
-+{
-+ /* Allocate the structure if it has not already been allocated by a
-+ subclass. */
-+ if (entry == NULL)
-+ {
-+ entry = bfd_hash_allocate (table,
-+ sizeof (struct ppc_elf_link_hash_entry));
-+ if (entry == NULL)
-+ return entry;
-+ }
-+
-+ /* Call the allocation method of the superclass. */
-+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
-+ if (entry != NULL)
-+ {
-+ ppc_elf_hash_entry (entry)->linker_section_pointer = NULL;
-+ ppc_elf_hash_entry (entry)->dyn_relocs = NULL;
-+ ppc_elf_hash_entry (entry)->tls_mask = 0;
-+ ppc_elf_hash_entry (entry)->has_sda_refs = 0;
-+ }
-+
-+ return entry;
-+}
-+
-+/* Create a PPC ELF linker hash table. */
-+
-+static struct bfd_link_hash_table *
-+ppc_elf_link_hash_table_create (bfd *abfd)
-+{
-+ struct ppc_elf_link_hash_table *ret;
-+
-+ ret = bfd_zmalloc (sizeof (struct ppc_elf_link_hash_table));
-+ if (ret == NULL)
-+ return NULL;
-+
-+ if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
-+ ppc_elf_link_hash_newfunc,
-+ sizeof (struct ppc_elf_link_hash_entry),
-+ PPC32_ELF_DATA))
-+ {
-+ free (ret);
-+ return NULL;
-+ }
-+
-+ ret->elf.init_plt_refcount.refcount = 0;
-+ ret->elf.init_plt_refcount.glist = NULL;
-+ ret->elf.init_plt_offset.offset = 0;
-+ ret->elf.init_plt_offset.glist = NULL;
-+
-+ ret->sdata[0].name = ".sdata";
-+ ret->sdata[0].sym_name = "_SDA_BASE_";
-+ ret->sdata[0].bss_name = ".sbss";
-+
-+ ret->sdata[1].name = ".sdata2";
-+ ret->sdata[1].sym_name = "_SDA2_BASE_";
-+ ret->sdata[1].bss_name = ".sbss2";
-+
-+ ret->plt_entry_size = 12;
-+ ret->plt_slot_size = 8;
-+ ret->plt_initial_entry_size = 72;
-+
-+ return &ret->elf.root;
-+}
-+
-+/* Create .got and the related sections. */
-+
-+static bfd_boolean
-+ppc_elf_create_got (bfd *abfd, struct bfd_link_info *info)
-+{
-+ struct ppc_elf_link_hash_table *htab;
-+ asection *s;
-+ flagword flags;
-+
-+ if (!_bfd_elf_create_got_section (abfd, info))
-+ return FALSE;
-+
-+ htab = ppc_elf_hash_table (info);
-+ htab->got = s = bfd_get_linker_section (abfd, ".got");
-+ if (s == NULL)
-+ abort ();
-+
-+ if (htab->is_vxworks)
-+ {
-+ htab->sgotplt = bfd_get_linker_section (abfd, ".got.plt");
-+ if (!htab->sgotplt)
-+ abort ();
-+ }
-+ else
-+ {
-+ /* The powerpc .got has a blrl instruction in it. Mark it
-+ executable. */
-+ flags = (SEC_ALLOC | SEC_LOAD | /*SEC_CODE |*/ SEC_HAS_CONTENTS
-+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
-+ if (!bfd_set_section_flags (abfd, s, flags))
-+ return FALSE;
-+ }
-+
-+ htab->relgot = bfd_get_linker_section (abfd, ".rela.got");
-+ if (!htab->relgot)
-+ abort ();
-+
-+ return TRUE;
-+}
-+
-+static bfd_boolean
-+ppc_elf_create_glink (bfd *abfd, struct bfd_link_info *info)
-+{
-+ struct ppc_elf_link_hash_table *htab = ppc_elf_hash_table (info);
-+ asection *s;
-+ flagword flags;
-+
-+ flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY | SEC_HAS_CONTENTS
-+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
-+ s = bfd_make_section_anyway_with_flags (abfd, ".glink", flags);
-+ htab->glink = s;
-+ if (s == NULL
-+ || !bfd_set_section_alignment (abfd, s, 4))
-+ return FALSE;
-+
-+ if (!info->no_ld_generated_unwind_info)
-+ {
-+ flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_HAS_CONTENTS
-+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
-+ s = bfd_make_section_anyway_with_flags (abfd, ".eh_frame", flags);
-+ htab->glink_eh_frame = s;
-+ if (s == NULL
-+ || !bfd_set_section_alignment (abfd, s, 2))
-+ return FALSE;
-+ }
-+
-+ flags = SEC_ALLOC | SEC_LINKER_CREATED;
-+ s = bfd_make_section_anyway_with_flags (abfd, ".iplt", flags);
-+ htab->iplt = s;
-+ if (s == NULL
-+ || !bfd_set_section_alignment (abfd, s, 4))
-+ return FALSE;
-+
-+ flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_HAS_CONTENTS
-+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
-+ s = bfd_make_section_anyway_with_flags (abfd, ".rela.iplt", flags);
-+ htab->reliplt = s;
-+ if (s == NULL
-+ || ! bfd_set_section_alignment (abfd, s, 2))
-+ return FALSE;
-+ return TRUE;
-+}
-+
-+/* We have to create .dynsbss and .rela.sbss here so that they get mapped
-+ to output sections (just like _bfd_elf_create_dynamic_sections has
-+ to create .dynbss and .rela.bss). */
-+
-+static bfd_boolean
-+ppc_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
-+{
-+ struct ppc_elf_link_hash_table *htab;
-+ asection *s;
-+ flagword flags;
-+
-+ htab = ppc_elf_hash_table (info);
-+
-+ if (htab->got == NULL
-+ && !ppc_elf_create_got (abfd, info))
-+ return FALSE;
-+
-+ if (!_bfd_elf_create_dynamic_sections (abfd, info))
-+ return FALSE;
-+
-+ if (htab->glink == NULL
-+ && !ppc_elf_create_glink (abfd, info))
-+ return FALSE;
-+
-+ htab->dynbss = bfd_get_linker_section (abfd, ".dynbss");
-+ s = bfd_make_section_anyway_with_flags (abfd, ".dynsbss",
-+ SEC_ALLOC | SEC_LINKER_CREATED);
-+ htab->dynsbss = s;
-+ if (s == NULL)
-+ return FALSE;
-+
-+ if (! info->shared)
-+ {
-+ htab->relbss = bfd_get_linker_section (abfd, ".rela.bss");
-+ flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_HAS_CONTENTS
-+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
-+ s = bfd_make_section_anyway_with_flags (abfd, ".rela.sbss", flags);
-+ htab->relsbss = s;
-+ if (s == NULL
-+ || ! bfd_set_section_alignment (abfd, s, 2))
-+ return FALSE;
-+ }
-+
-+ if (htab->is_vxworks
-+ && !elf_vxworks_create_dynamic_sections (abfd, info, &htab->srelplt2))
-+ return FALSE;
-+
-+ htab->relplt = bfd_get_linker_section (abfd, ".rela.plt");
-+ htab->plt = s = bfd_get_linker_section (abfd, ".plt");
-+ if (s == NULL)
-+ abort ();
-+
-+ flags = SEC_ALLOC | SEC_CODE | SEC_LINKER_CREATED | SEC_READONLY;
-+ if (htab->plt_type == PLT_VXWORKS)
-+ /* The VxWorks PLT is a loaded section with contents. */
-+ flags |= SEC_HAS_CONTENTS | SEC_LOAD | SEC_READONLY;
-+ return bfd_set_section_flags (abfd, s, flags);
-+}
-+
-+/* Copy the extra info we tack onto an elf_link_hash_entry. */
-+
-+static void
-+ppc_elf_copy_indirect_symbol (struct bfd_link_info *info,
-+ struct elf_link_hash_entry *dir,
-+ struct elf_link_hash_entry *ind)
-+{
-+ struct ppc_elf_link_hash_entry *edir, *eind;
-+
-+ edir = (struct ppc_elf_link_hash_entry *) dir;
-+ eind = (struct ppc_elf_link_hash_entry *) ind;
-+
-+ edir->tls_mask |= eind->tls_mask;
-+ edir->has_sda_refs |= eind->has_sda_refs;
-+
-+ /* If called to transfer flags for a weakdef during processing
-+ of elf_adjust_dynamic_symbol, don't copy non_got_ref.
-+ We clear it ourselves for ELIMINATE_COPY_RELOCS. */
-+ if (!(ELIMINATE_COPY_RELOCS
-+ && eind->elf.root.type != bfd_link_hash_indirect
-+ && edir->elf.dynamic_adjusted))
-+ edir->elf.non_got_ref |= eind->elf.non_got_ref;
-+
-+ edir->elf.ref_dynamic |= eind->elf.ref_dynamic;
-+ edir->elf.ref_regular |= eind->elf.ref_regular;
-+ edir->elf.ref_regular_nonweak |= eind->elf.ref_regular_nonweak;
-+ edir->elf.needs_plt |= eind->elf.needs_plt;
-+ edir->elf.pointer_equality_needed |= eind->elf.pointer_equality_needed;
-+
-+ if (eind->dyn_relocs != NULL)
-+ {
-+ if (edir->dyn_relocs != NULL)
-+ {
-+ struct elf_dyn_relocs **pp;
-+ struct elf_dyn_relocs *p;
-+
-+ /* Add reloc counts against the indirect sym to the direct sym
-+ list. Merge any entries against the same section. */
-+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
-+ {
-+ struct elf_dyn_relocs *q;
-+
-+ for (q = edir->dyn_relocs; q != NULL; q = q->next)
-+ if (q->sec == p->sec)
-+ {
-+ q->pc_count += p->pc_count;
-+ q->count += p->count;
-+ *pp = p->next;
-+ break;
-+ }
-+ if (q == NULL)
-+ pp = &p->next;
-+ }
-+ *pp = edir->dyn_relocs;
-+ }
-+
-+ edir->dyn_relocs = eind->dyn_relocs;
-+ eind->dyn_relocs = NULL;
-+ }
-+
-+ /* If we were called to copy over info for a weak sym, that's all.
-+ You might think dyn_relocs need not be copied over; After all,
-+ both syms will be dynamic or both non-dynamic so we're just
-+ moving reloc accounting around. However, ELIMINATE_COPY_RELOCS
-+ code in ppc_elf_adjust_dynamic_symbol needs to check for
-+ dyn_relocs in read-only sections, and it does so on what is the
-+ DIR sym here. */
-+ if (eind->elf.root.type != bfd_link_hash_indirect)
-+ return;
-+
-+ /* Copy over the GOT refcount entries that we may have already seen to
-+ the symbol which just became indirect. */
-+ edir->elf.got.refcount += eind->elf.got.refcount;
-+ eind->elf.got.refcount = 0;
-+
-+ /* And plt entries. */
-+ if (eind->elf.plt.plist != NULL)
-+ {
-+ if (edir->elf.plt.plist != NULL)
-+ {
-+ struct plt_entry **entp;
-+ struct plt_entry *ent;
-+
-+ for (entp = &eind->elf.plt.plist; (ent = *entp) != NULL; )
-+ {
-+ struct plt_entry *dent;
-+
-+ for (dent = edir->elf.plt.plist; dent != NULL; dent = dent->next)
-+ if (dent->sec == ent->sec && dent->addend == ent->addend)
-+ {
-+ dent->plt.refcount += ent->plt.refcount;
-+ *entp = ent->next;
-+ break;
-+ }
-+ if (dent == NULL)
-+ entp = &ent->next;
-+ }
-+ *entp = edir->elf.plt.plist;
-+ }
-+
-+ edir->elf.plt.plist = eind->elf.plt.plist;
-+ eind->elf.plt.plist = NULL;
-+ }
-+
-+ if (eind->elf.dynindx != -1)
-+ {
-+ if (edir->elf.dynindx != -1)
-+ _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
-+ edir->elf.dynstr_index);
-+ edir->elf.dynindx = eind->elf.dynindx;
-+ edir->elf.dynstr_index = eind->elf.dynstr_index;
-+ eind->elf.dynindx = -1;
-+ eind->elf.dynstr_index = 0;
-+ }
-+}
-+
-+/* Hook called by the linker routine which adds symbols from an object
-+ file. We use it to put .comm items in .sbss, and not .bss. */
-+
-+static bfd_boolean
-+ppc_elf_add_symbol_hook (bfd *abfd,
-+ struct bfd_link_info *info,
-+ Elf_Internal_Sym *sym,
-+ const char **namep ATTRIBUTE_UNUSED,
-+ flagword *flagsp ATTRIBUTE_UNUSED,
-+ asection **secp,
-+ bfd_vma *valp)
-+{
-+ if (sym->st_shndx == SHN_COMMON
-+ && !info->relocatable
-+ && is_ppc_elf (info->output_bfd)
-+ && sym->st_size <= elf_gp_size (abfd))
-+ {
-+ /* Common symbols less than or equal to -G nn bytes are automatically
-+ put into .sbss. */
-+ struct ppc_elf_link_hash_table *htab;
-+
-+ htab = ppc_elf_hash_table (info);
-+ if (htab->sbss == NULL)
-+ {
-+ flagword flags = SEC_IS_COMMON | SEC_LINKER_CREATED;
-+
-+ if (!htab->elf.dynobj)
-+ htab->elf.dynobj = abfd;
-+
-+ htab->sbss = bfd_make_section_anyway_with_flags (htab->elf.dynobj,
-+ ".sbss",
-+ flags);
-+ if (htab->sbss == NULL)
-+ return FALSE;
-+ }
-+
-+ *secp = htab->sbss;
-+ *valp = sym->st_size;
-+ }
-+
-+ if ((abfd->flags & DYNAMIC) == 0
-+ && (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
-+ || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE))
-+ elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
-+
-+ return TRUE;
-+}
-+
-+static bfd_boolean
-+create_sdata_sym (struct bfd_link_info *info, elf_linker_section_t *lsect)
-+{
-+ struct ppc_elf_link_hash_table *htab = ppc_elf_hash_table (info);
-+
-+ lsect->sym = elf_link_hash_lookup (&htab->elf, lsect->sym_name,
-+ TRUE, FALSE, TRUE);
-+ if (lsect->sym == NULL)
-+ return FALSE;
-+ if (lsect->sym->root.type == bfd_link_hash_new)
-+ lsect->sym->non_elf = 0;
-+ lsect->sym->ref_regular = 1;
-+ _bfd_elf_link_hash_hide_symbol (info, lsect->sym, TRUE);
-+ return TRUE;
-+}
-+
-+/* Create a special linker section. */
-+
-+static bfd_boolean
-+ppc_elf_create_linker_section (bfd *abfd,
-+ struct bfd_link_info *info,
-+ flagword flags,
-+ elf_linker_section_t *lsect)
-+{
-+ struct ppc_elf_link_hash_table *htab = ppc_elf_hash_table (info);
-+ asection *s;
-+
-+ flags |= (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
-+ | SEC_LINKER_CREATED);
-+
-+ /* Record the first bfd that needs the special sections. */
-+ if (!htab->elf.dynobj)
-+ htab->elf.dynobj = abfd;
-+
-+ s = bfd_make_section_anyway_with_flags (htab->elf.dynobj,
-+ lsect->name,
-+ flags);
-+ if (s == NULL
-+ || !bfd_set_section_alignment (htab->elf.dynobj, s, 2))
-+ return FALSE;
-+ lsect->section = s;
-+
-+ return create_sdata_sym (info, lsect);
-+}
-+
-+/* Find a linker generated pointer with a given addend and type. */
-+
-+static elf_linker_section_pointers_t *
-+elf_find_pointer_linker_section
-+ (elf_linker_section_pointers_t *linker_pointers,
-+ bfd_vma addend,
-+ elf_linker_section_t *lsect)
-+{
-+ for ( ; linker_pointers != NULL; linker_pointers = linker_pointers->next)
-+ if (lsect == linker_pointers->lsect && addend == linker_pointers->addend)
-+ return linker_pointers;
-+
-+ return NULL;
-+}
-+
-+/* Allocate a pointer to live in a linker created section. */
-+
-+static bfd_boolean
-+elf_create_pointer_linker_section (bfd *abfd,
-+ elf_linker_section_t *lsect,
-+ struct elf_link_hash_entry *h,
-+ const Elf_Internal_Rela *rel)
-+{
-+ elf_linker_section_pointers_t **ptr_linker_section_ptr = NULL;
-+ elf_linker_section_pointers_t *linker_section_ptr;
-+ unsigned long r_symndx = ELF32_R_SYM (rel->r_info);
-+ bfd_size_type amt;
-+
-+ BFD_ASSERT (lsect != NULL);
-+
-+ /* Is this a global symbol? */
-+ if (h != NULL)
-+ {
-+ struct ppc_elf_link_hash_entry *eh;
-+
-+ /* Has this symbol already been allocated? If so, our work is done. */
-+ eh = (struct ppc_elf_link_hash_entry *) h;
-+ if (elf_find_pointer_linker_section (eh->linker_section_pointer,
-+ rel->r_addend,
-+ lsect))
-+ return TRUE;
-+
-+ ptr_linker_section_ptr = &eh->linker_section_pointer;
-+ }
-+ else
-+ {
-+ BFD_ASSERT (is_ppc_elf (abfd));
-+
-+ /* Allocation of a pointer to a local symbol. */
-+ elf_linker_section_pointers_t **ptr = elf_local_ptr_offsets (abfd);
-+
-+ /* Allocate a table to hold the local symbols if first time. */
-+ if (!ptr)
-+ {
-+ unsigned int num_symbols = elf_symtab_hdr (abfd).sh_info;
-+
-+ amt = num_symbols;
-+ amt *= sizeof (elf_linker_section_pointers_t *);
-+ ptr = bfd_zalloc (abfd, amt);
-+
-+ if (!ptr)
-+ return FALSE;
-+
-+ elf_local_ptr_offsets (abfd) = ptr;
-+ }
-+
-+ /* Has this symbol already been allocated? If so, our work is done. */
-+ if (elf_find_pointer_linker_section (ptr[r_symndx],
-+ rel->r_addend,
-+ lsect))
-+ return TRUE;
-+
-+ ptr_linker_section_ptr = &ptr[r_symndx];
-+ }
-+
-+ /* Allocate space for a pointer in the linker section, and allocate
-+ a new pointer record from internal memory. */
-+ BFD_ASSERT (ptr_linker_section_ptr != NULL);
-+ amt = sizeof (elf_linker_section_pointers_t);
-+ linker_section_ptr = bfd_alloc (abfd, amt);
-+
-+ if (!linker_section_ptr)
-+ return FALSE;
-+
-+ linker_section_ptr->next = *ptr_linker_section_ptr;
-+ linker_section_ptr->addend = rel->r_addend;
-+ linker_section_ptr->lsect = lsect;
-+ *ptr_linker_section_ptr = linker_section_ptr;
-+
-+ linker_section_ptr->offset = lsect->section->size;
-+ lsect->section->size += 4;
-+
-+#ifdef DEBUG
-+ fprintf (stderr,
-+ "Create pointer in linker section %s, offset = %ld, section size = %ld\n",
-+ lsect->name, (long) linker_section_ptr->offset,
-+ (long) lsect->section->size);
-+#endif
-+
-+ return TRUE;
-+}
-+
-+static struct plt_entry **
-+update_local_sym_info (bfd *abfd,
-+ Elf_Internal_Shdr *symtab_hdr,
-+ unsigned long r_symndx,
-+ int tls_type)
-+{
-+ bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd);
-+ struct plt_entry **local_plt;
-+ char *local_got_tls_masks;
-+
-+ if (local_got_refcounts == NULL)
-+ {
-+ bfd_size_type size = symtab_hdr->sh_info;
-+
-+ size *= (sizeof (*local_got_refcounts)
-+ + sizeof (*local_plt)
-+ + sizeof (*local_got_tls_masks));
-+ local_got_refcounts = bfd_zalloc (abfd, size);
-+ if (local_got_refcounts == NULL)
-+ return NULL;
-+ elf_local_got_refcounts (abfd) = local_got_refcounts;
-+ }
-+
-+ local_plt = (struct plt_entry **) (local_got_refcounts + symtab_hdr->sh_info);
-+ local_got_tls_masks = (char *) (local_plt + symtab_hdr->sh_info);
-+ local_got_tls_masks[r_symndx] |= tls_type;
-+ if (tls_type != PLT_IFUNC)
-+ local_got_refcounts[r_symndx] += 1;
-+ return local_plt + r_symndx;
-+}
-+
-+static bfd_boolean
-+update_plt_info (bfd *abfd, struct plt_entry **plist,
-+ asection *sec, bfd_vma addend)
-+{
-+ struct plt_entry *ent;
-+
-+ if (addend < 32768)
-+ sec = NULL;
-+ for (ent = *plist; ent != NULL; ent = ent->next)
-+ if (ent->sec == sec && ent->addend == addend)
-+ break;
-+ if (ent == NULL)
-+ {
-+ bfd_size_type amt = sizeof (*ent);
-+ ent = bfd_alloc (abfd, amt);
-+ if (ent == NULL)
-+ return FALSE;
-+ ent->next = *plist;
-+ ent->sec = sec;
-+ ent->addend = addend;
-+ ent->plt.refcount = 0;
-+ *plist = ent;
-+ }
-+ ent->plt.refcount += 1;
-+ return TRUE;
-+}
-+
-+static struct plt_entry *
-+find_plt_ent (struct plt_entry **plist, asection *sec, bfd_vma addend)
-+{
-+ struct plt_entry *ent;
-+
-+ if (addend < 32768)
-+ sec = NULL;
-+ for (ent = *plist; ent != NULL; ent = ent->next)
-+ if (ent->sec == sec && ent->addend == addend)
-+ break;
-+ return ent;
-+}
-+
-+static bfd_boolean
-+is_branch_reloc (enum elf_ppc_reloc_type r_type)
-+{
-+ return (r_type == R_PPC_PLTREL24
-+ || r_type == R_PPC_LOCAL24PC
-+ || r_type == R_PPC_REL24
-+ || r_type == R_PPC_REL14
-+ || r_type == R_PPC_REL14_BRTAKEN
-+ || r_type == R_PPC_REL14_BRNTAKEN
-+ || r_type == R_PPC_ADDR24
-+ || r_type == R_PPC_ADDR14
-+ || r_type == R_PPC_ADDR14_BRTAKEN
-+ || r_type == R_PPC_ADDR14_BRNTAKEN);
-+}
-+
-+static void
-+bad_shared_reloc (bfd *abfd, enum elf_ppc_reloc_type r_type)
-+{
-+ (*_bfd_error_handler)
-+ (_("%B: relocation %s cannot be used when making a shared object"),
-+ abfd,
-+ ppc_elf_howto_table[r_type]->name);
-+ bfd_set_error (bfd_error_bad_value);
-+}
-+
-+/* Look through the relocs for a section during the first phase, and
-+ allocate space in the global offset table or procedure linkage
-+ table. */
-+
-+static bfd_boolean
-+ppc_elf_check_relocs (bfd *abfd,
-+ struct bfd_link_info *info,
-+ asection *sec,
-+ const Elf_Internal_Rela *relocs)
-+{
-+ struct ppc_elf_link_hash_table *htab;
-+ Elf_Internal_Shdr *symtab_hdr;
-+ struct elf_link_hash_entry **sym_hashes;
-+ const Elf_Internal_Rela *rel;
-+ const Elf_Internal_Rela *rel_end;
-+ asection *got2, *sreloc;
-+ struct elf_link_hash_entry *tga;
-+
-+ if (info->relocatable)
-+ return TRUE;
-+
-+ /* Don't do anything special with non-loaded, non-alloced sections.
-+ In particular, any relocs in such sections should not affect GOT
-+ and PLT reference counting (ie. we don't allow them to create GOT
-+ or PLT entries), there's no possibility or desire to optimize TLS
-+ relocs, and there's not much point in propagating relocs to shared
-+ libs that the dynamic linker won't relocate. */
-+ if ((sec->flags & SEC_ALLOC) == 0)
-+ return TRUE;
-+
-+#ifdef DEBUG
-+ _bfd_error_handler ("ppc_elf_check_relocs called for section %A in %B",
-+ sec, abfd);
-+#endif
-+
-+ BFD_ASSERT (is_ppc_elf (abfd));
-+
-+ /* Initialize howto table if not already done. */
-+ if (!ppc_elf_howto_table[R_PPC_ADDR32])
-+ ppc_elf_howto_init ();
-+
-+ htab = ppc_elf_hash_table (info);
-+ if (htab->glink == NULL)
-+ {
-+ if (htab->elf.dynobj == NULL)
-+ htab->elf.dynobj = abfd;
-+ if (!ppc_elf_create_glink (htab->elf.dynobj, info))
-+ return FALSE;
-+ }
-+ tga = elf_link_hash_lookup (&htab->elf, "__tls_get_addr",
-+ FALSE, FALSE, TRUE);
-+ symtab_hdr = &elf_symtab_hdr (abfd);
-+ sym_hashes = elf_sym_hashes (abfd);
-+ got2 = bfd_get_section_by_name (abfd, ".got2");
-+ sreloc = NULL;
-+
-+ rel_end = relocs + sec->reloc_count;
-+ for (rel = relocs; rel < rel_end; rel++)
-+ {
-+ unsigned long r_symndx;
-+ enum elf_ppc_reloc_type r_type;
-+ struct elf_link_hash_entry *h;
-+ int tls_type;
-+
-+ r_symndx = ELF32_R_SYM (rel->r_info);
-+ if (r_symndx < symtab_hdr->sh_info)
-+ h = NULL;
-+ else
-+ {
-+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-+ while (h->root.type == bfd_link_hash_indirect
-+ || h->root.type == bfd_link_hash_warning)
-+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
-+ }
-+
-+ /* If a relocation refers to _GLOBAL_OFFSET_TABLE_, create the .got.
-+ This shows up in particular in an R_PPC_ADDR32 in the eabi
-+ startup code. */
-+ if (h != NULL
-+ && htab->got == NULL
-+ && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
-+ {
-+ if (htab->elf.dynobj == NULL)
-+ htab->elf.dynobj = abfd;
-+ if (!ppc_elf_create_got (htab->elf.dynobj, info))
-+ return FALSE;
-+ BFD_ASSERT (h == htab->elf.hgot);
-+ }
-+
-+ tls_type = 0;
-+ r_type = ELF32_R_TYPE (rel->r_info);
-+ if (h == NULL && !htab->is_vxworks)
-+ {
-+ Elf_Internal_Sym *isym = bfd_sym_from_r_symndx (&htab->sym_cache,
-+ abfd, r_symndx);
-+ if (isym == NULL)
-+ return FALSE;
-+
-+ if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC
-+ && (!info->shared
-+ || is_branch_reloc (r_type)))
-+ {
-+ struct plt_entry **ifunc;
-+ bfd_vma addend;
-+
-+ ifunc = update_local_sym_info (abfd, symtab_hdr, r_symndx,
-+ PLT_IFUNC);
-+ if (ifunc == NULL)
-+ return FALSE;
-+
-+ /* STT_GNU_IFUNC symbols must have a PLT entry;
-+ In a non-pie executable even when there are
-+ no plt calls. */
-+ addend = 0;
-+ if (r_type == R_PPC_PLTREL24)
-+ {
-+ ppc_elf_tdata (abfd)->makes_plt_call = 1;
-+ if (info->shared)
-+ addend = rel->r_addend;
-+ }
-+ if (!update_plt_info (abfd, ifunc, got2, addend))
-+ return FALSE;
-+ }
-+ }
-+
-+ if (!htab->is_vxworks
-+ && is_branch_reloc (r_type)
-+ && h != NULL
-+ && h == tga)
-+ {
-+ if (rel != relocs
-+ && (ELF32_R_TYPE (rel[-1].r_info) == R_PPC_TLSGD
-+ || ELF32_R_TYPE (rel[-1].r_info) == R_PPC_TLSLD))
-+ /* We have a new-style __tls_get_addr call with a marker
-+ reloc. */
-+ ;
-+ else
-+ /* Mark this section as having an old-style call. */
-+ sec->has_tls_get_addr_call = 1;
-+ }
-+
-+ switch (r_type)
-+ {
-+ case R_PPC_TLSGD:
-+ case R_PPC_TLSLD:
-+ /* These special tls relocs tie a call to __tls_get_addr with
-+ its parameter symbol. */
-+ break;
-+
-+ case R_PPC_GOT_TLSLD16:
-+ case R_PPC_GOT_TLSLD16_LO:
-+ case R_PPC_GOT_TLSLD16_HI:
-+ case R_PPC_GOT_TLSLD16_HA:
-+ tls_type = TLS_TLS | TLS_LD;
-+ goto dogottls;
-+
-+ case R_PPC_GOT_TLSGD16:
-+ case R_PPC_GOT_TLSGD16_LO:
-+ case R_PPC_GOT_TLSGD16_HI:
-+ case R_PPC_GOT_TLSGD16_HA:
-+ tls_type = TLS_TLS | TLS_GD;
-+ goto dogottls;
-+
-+ case R_PPC_GOT_TPREL16:
-+ case R_PPC_GOT_TPREL16_LO:
-+ case R_PPC_GOT_TPREL16_HI:
-+ case R_PPC_GOT_TPREL16_HA:
-+ if (!info->executable)
-+ info->flags |= DF_STATIC_TLS;
-+ tls_type = TLS_TLS | TLS_TPREL;
-+ goto dogottls;
-+
-+ case R_PPC_GOT_DTPREL16:
-+ case R_PPC_GOT_DTPREL16_LO:
-+ case R_PPC_GOT_DTPREL16_HI:
-+ case R_PPC_GOT_DTPREL16_HA:
-+ tls_type = TLS_TLS | TLS_DTPREL;
-+ dogottls:
-+ sec->has_tls_reloc = 1;
-+ /* Fall thru */
-+
-+ /* GOT16 relocations */
-+ case R_PPC_GOT16:
-+ case R_PPC_GOT16_LO:
-+ case R_PPC_GOT16_HI:
-+ case R_PPC_GOT16_HA:
-+ /* This symbol requires a global offset table entry. */
-+ if (htab->got == NULL)
-+ {
-+ if (htab->elf.dynobj == NULL)
-+ htab->elf.dynobj = abfd;
-+ if (!ppc_elf_create_got (htab->elf.dynobj, info))
-+ return FALSE;
-+ }
-+ if (h != NULL)
-+ {
-+ h->got.refcount += 1;
-+ ppc_elf_hash_entry (h)->tls_mask |= tls_type;
-+ }
-+ else
-+ /* This is a global offset table entry for a local symbol. */
-+ if (!update_local_sym_info (abfd, symtab_hdr, r_symndx, tls_type))
-+ return FALSE;
-+
-+ /* We may also need a plt entry if the symbol turns out to be
-+ an ifunc. */
-+ if (h != NULL && !info->shared)
-+ {
-+ if (!update_plt_info (abfd, &h->plt.plist, NULL, 0))
-+ return FALSE;
-+ }
-+ break;
-+
-+ /* Indirect .sdata relocation. */
-+ case R_PPC_EMB_SDAI16:
-+ if (info->shared)
-+ {
-+ bad_shared_reloc (abfd, r_type);
-+ return FALSE;
-+ }
-+ if (htab->sdata[0].section == NULL
-+ && !ppc_elf_create_linker_section (abfd, info, 0,
-+ &htab->sdata[0]))
-+ return FALSE;
-+ if (!elf_create_pointer_linker_section (abfd, &htab->sdata[0],
-+ h, rel))
-+ return FALSE;
-+ if (h != NULL)
-+ {
-+ ppc_elf_hash_entry (h)->has_sda_refs = TRUE;
-+ h->non_got_ref = TRUE;
-+ }
-+ break;
-+
-+ /* Indirect .sdata2 relocation. */
-+ case R_PPC_EMB_SDA2I16:
-+ if (info->shared)
-+ {
-+ bad_shared_reloc (abfd, r_type);
-+ return FALSE;
-+ }
-+ if (htab->sdata[1].section == NULL
-+ && !ppc_elf_create_linker_section (abfd, info, SEC_READONLY,
-+ &htab->sdata[1]))
-+ return FALSE;
-+ if (!elf_create_pointer_linker_section (abfd, &htab->sdata[1],
-+ h, rel))
-+ return FALSE;
-+ if (h != NULL)
-+ {
-+ ppc_elf_hash_entry (h)->has_sda_refs = TRUE;
-+ h->non_got_ref = TRUE;
-+ }
-+ break;
-+
-+ case R_PPC_VLE_SDAREL_LO16A:
-+ case R_PPC_VLE_SDAREL_LO16D:
-+ case R_PPC_VLE_SDAREL_HI16A:
-+ case R_PPC_VLE_SDAREL_HI16D:
-+ case R_PPC_VLE_SDAREL_HA16A:
-+ case R_PPC_VLE_SDAREL_HA16D:
-+ case R_PPC_SDAREL16:
-+ if (htab->sdata[0].sym == NULL
-+ && !create_sdata_sym (info, &htab->sdata[0]))
-+ return FALSE;
-+
-+ if (htab->sdata[1].sym == NULL
-+ && !create_sdata_sym (info, &htab->sdata[1]))
-+ return FALSE;
-+
-+ if (h != NULL)
-+ {
-+ ppc_elf_hash_entry (h)->has_sda_refs = TRUE;
-+ h->non_got_ref = TRUE;
-+ }
-+ break;
-+
-+ case R_PPC_VLE_REL8:
-+ case R_PPC_VLE_REL15:
-+ case R_PPC_VLE_REL24:
-+ case R_PPC_VLE_LO16A:
-+ case R_PPC_VLE_LO16D:
-+ case R_PPC_VLE_HI16A:
-+ case R_PPC_VLE_HI16D:
-+ case R_PPC_VLE_HA16A:
-+ case R_PPC_VLE_HA16D:
-+ break;
-+
-+ case R_PPC_EMB_SDA2REL:
-+ if (info->shared)
-+ {
-+ bad_shared_reloc (abfd, r_type);
-+ return FALSE;
-+ }
-+ if (htab->sdata[1].sym == NULL
-+ && !create_sdata_sym (info, &htab->sdata[1]))
-+ return FALSE;
-+ if (h != NULL)
-+ {
-+ ppc_elf_hash_entry (h)->has_sda_refs = TRUE;
-+ h->non_got_ref = TRUE;
-+ }
-+ break;
-+
-+ case R_PPC_VLE_SDA21_LO:
-+ case R_PPC_VLE_SDA21:
-+ case R_PPC_EMB_SDA21:
-+ case R_PPC_EMB_RELSDA:
-+ if (info->shared)
-+ {
-+ bad_shared_reloc (abfd, r_type);
-+ return FALSE;
-+ }
-+ if (htab->sdata[0].sym == NULL
-+ && !create_sdata_sym (info, &htab->sdata[0]))
-+ return FALSE;
-+ if (htab->sdata[1].sym == NULL
-+ && !create_sdata_sym (info, &htab->sdata[1]))
-+ return FALSE;
-+ if (h != NULL)
-+ {
-+ ppc_elf_hash_entry (h)->has_sda_refs = TRUE;
-+ h->non_got_ref = TRUE;
-+ }
-+ break;
-+
-+ case R_PPC_EMB_NADDR32:
-+ case R_PPC_EMB_NADDR16:
-+ case R_PPC_EMB_NADDR16_LO:
-+ case R_PPC_EMB_NADDR16_HI:
-+ case R_PPC_EMB_NADDR16_HA:
-+ if (info->shared)
-+ {
-+ bad_shared_reloc (abfd, r_type);
-+ return FALSE;
-+ }
-+ if (h != NULL)
-+ h->non_got_ref = TRUE;
-+ break;
-+
-+ case R_PPC_PLTREL24:
-+ if (h == NULL)
-+ break;
-+ /* Fall through */
-+ case R_PPC_PLT32:
-+ case R_PPC_PLTREL32:
-+ case R_PPC_PLT16_LO:
-+ case R_PPC_PLT16_HI:
-+ case R_PPC_PLT16_HA:
-+#ifdef DEBUG
-+ fprintf (stderr, "Reloc requires a PLT entry\n");
-+#endif
-+ /* This symbol requires a procedure linkage table entry. We
-+ actually build the entry in finish_dynamic_symbol,
-+ because this might be a case of linking PIC code without
-+ linking in any dynamic objects, in which case we don't
-+ need to generate a procedure linkage table after all. */
-+
-+ if (h == NULL)
-+ {
-+ /* It does not make sense to have a procedure linkage
-+ table entry for a local symbol. */
-+ info->callbacks->einfo (_("%P: %H: %s reloc against local symbol\n"),
-+ abfd, sec, rel->r_offset,
-+ ppc_elf_howto_table[r_type]->name);
-+ bfd_set_error (bfd_error_bad_value);
-+ return FALSE;
-+ }
-+ else
-+ {
-+ bfd_vma addend = 0;
-+
-+ if (r_type == R_PPC_PLTREL24)
-+ {
-+ ppc_elf_tdata (abfd)->makes_plt_call = 1;
-+ if (info->shared)
-+ addend = rel->r_addend;
-+ }
-+ h->needs_plt = 1;
-+ if (!update_plt_info (abfd, &h->plt.plist, got2, addend))
-+ return FALSE;
-+ }
-+ break;
-+
-+ /* The following relocations don't need to propagate the
-+ relocation if linking a shared object since they are
-+ section relative. */
-+ case R_PPC_SECTOFF:
-+ case R_PPC_SECTOFF_LO:
-+ case R_PPC_SECTOFF_HI:
-+ case R_PPC_SECTOFF_HA:
-+ case R_PPC_DTPREL16:
-+ case R_PPC_DTPREL16_LO:
-+ case R_PPC_DTPREL16_HI:
-+ case R_PPC_DTPREL16_HA:
-+ case R_PPC_TOC16:
-+ break;
-+
-+ case R_PPC_REL16:
-+ case R_PPC_REL16_LO:
-+ case R_PPC_REL16_HI:
-+ case R_PPC_REL16_HA:
-+ ppc_elf_tdata (abfd)->has_rel16 = 1;
-+ break;
-+
-+ /* These are just markers. */
-+ case R_PPC_TLS:
-+ case R_PPC_EMB_MRKREF:
-+ case R_PPC_NONE:
-+ case R_PPC_max:
-+ case R_PPC_RELAX:
-+ case R_PPC_RELAX_PLT:
-+ case R_PPC_RELAX_PLTREL24:
-+ break;
-+
-+ /* These should only appear in dynamic objects. */
-+ case R_PPC_COPY:
-+ case R_PPC_GLOB_DAT:
-+ case R_PPC_JMP_SLOT:
-+ case R_PPC_RELATIVE:
-+ case R_PPC_IRELATIVE:
-+ break;
-+
-+ /* These aren't handled yet. We'll report an error later. */
-+ case R_PPC_ADDR30:
-+ case R_PPC_EMB_RELSEC16:
-+ case R_PPC_EMB_RELST_LO:
-+ case R_PPC_EMB_RELST_HI:
-+ case R_PPC_EMB_RELST_HA:
-+ case R_PPC_EMB_BIT_FLD:
-+ break;
-+
-+ /* These don't work with a GOT */
-+ case R_PPC_AMIGAOS_BREL:
-+ case R_PPC_AMIGAOS_BREL_HI:
-+ case R_PPC_AMIGAOS_BREL_LO:
-+ case R_PPC_AMIGAOS_BREL_HA:
-+ break;
-+
-+ /* This refers only to functions defined in the shared library. */
-+ case R_PPC_LOCAL24PC:
-+ if (h != NULL && h == htab->elf.hgot && htab->plt_type == PLT_UNSET)
-+ {
-+ htab->plt_type = PLT_OLD;
-+ htab->old_bfd = abfd;
-+ }
-+ break;
-+
-+ /* This relocation describes the C++ object vtable hierarchy.
-+ Reconstruct it for later use during GC. */
-+ case R_PPC_GNU_VTINHERIT:
-+ if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
-+ return FALSE;
-+ break;
-+
-+ /* This relocation describes which C++ vtable entries are actually
-+ used. Record for later use during GC. */
-+ case R_PPC_GNU_VTENTRY:
-+ BFD_ASSERT (h != NULL);
-+ if (h != NULL
-+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
-+ return FALSE;
-+ break;
-+
-+ /* We shouldn't really be seeing these. */
-+ case R_PPC_TPREL32:
-+ case R_PPC_TPREL16:
-+ case R_PPC_TPREL16_LO:
-+ case R_PPC_TPREL16_HI:
-+ case R_PPC_TPREL16_HA:
-+ if (!info->executable)
-+ info->flags |= DF_STATIC_TLS;
-+ goto dodyn;
-+
-+ /* Nor these. */
-+ case R_PPC_DTPMOD32:
-+ case R_PPC_DTPREL32:
-+ goto dodyn;
-+
-+ case R_PPC_REL32:
-+ if (h == NULL
-+ && got2 != NULL
-+ && (sec->flags & SEC_CODE) != 0
-+ && info->shared
-+ && htab->plt_type == PLT_UNSET)
-+ {
-+ /* Old -fPIC gcc code has .long LCTOC1-LCFx just before
-+ the start of a function, which assembles to a REL32
-+ reference to .got2. If we detect one of these, then
-+ force the old PLT layout because the linker cannot
-+ reliably deduce the GOT pointer value needed for
-+ PLT call stubs. */
-+ asection *s;
-+ Elf_Internal_Sym *isym;
-+
-+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
-+ abfd, r_symndx);
-+ if (isym == NULL)
-+ return FALSE;
-+
-+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
-+ if (s == got2)
-+ {
-+ htab->plt_type = PLT_OLD;
-+ htab->old_bfd = abfd;
-+ }
-+ }
-+ if (h == NULL || h == htab->elf.hgot)
-+ break;
-+ /* fall through */
-+
-+ case R_PPC_ADDR32:
-+ case R_PPC_ADDR16:
-+ case R_PPC_ADDR16_LO:
-+ case R_PPC_ADDR16_HI:
-+ case R_PPC_ADDR16_HA:
-+ case R_PPC_UADDR32:
-+ case R_PPC_UADDR16:
-+ if (h != NULL && !info->shared)
-+ {
-+ /* We may need a plt entry if the symbol turns out to be
-+ a function defined in a dynamic object. */
-+ if (!update_plt_info (abfd, &h->plt.plist, NULL, 0))
-+ return FALSE;
-+
-+ /* We may need a copy reloc too. */
-+ h->non_got_ref = 1;
-+ h->pointer_equality_needed = 1;
-+ }
-+ goto dodyn;
-+
-+ case R_PPC_REL24:
-+ case R_PPC_REL14:
-+ case R_PPC_REL14_BRTAKEN:
-+ case R_PPC_REL14_BRNTAKEN:
-+ if (h == NULL)
-+ break;
-+ if (h == htab->elf.hgot)
-+ {
-+ if (htab->plt_type == PLT_UNSET)
-+ {
-+ htab->plt_type = PLT_OLD;
-+ htab->old_bfd = abfd;
-+ }
-+ break;
-+ }
-+ /* fall through */
-+
-+ case R_PPC_ADDR24:
-+ case R_PPC_ADDR14:
-+ case R_PPC_ADDR14_BRTAKEN:
-+ case R_PPC_ADDR14_BRNTAKEN:
-+ if (h != NULL && !info->shared)
-+ {
-+ /* We may need a plt entry if the symbol turns out to be
-+ a function defined in a dynamic object. */
-+ h->needs_plt = 1;
-+ if (!update_plt_info (abfd, &h->plt.plist, NULL, 0))
-+ return FALSE;
-+ break;
-+ }
-+
-+ dodyn:
-+ /* If we are creating a shared library, and this is a reloc
-+ against a global symbol, or a non PC relative reloc
-+ against a local symbol, then we need to copy the reloc
-+ into the shared library. However, if we are linking with
-+ -Bsymbolic, we do not need to copy a reloc against a
-+ global symbol which is defined in an object we are
-+ including in the link (i.e., DEF_REGULAR is set). At
-+ this point we have not seen all the input files, so it is
-+ possible that DEF_REGULAR is not set now but will be set
-+ later (it is never cleared). In case of a weak definition,
-+ DEF_REGULAR may be cleared later by a strong definition in
-+ a shared library. We account for that possibility below by
-+ storing information in the dyn_relocs field of the hash
-+ table entry. A similar situation occurs when creating
-+ shared libraries and symbol visibility changes render the
-+ symbol local.
-+
-+ If on the other hand, we are creating an executable, we
-+ may need to keep relocations for symbols satisfied by a
-+ dynamic library if we manage to avoid copy relocs for the
-+ symbol. */
-+ if ((info->shared
-+ && (must_be_dyn_reloc (info, r_type)
-+ || (h != NULL
-+ && (! info->symbolic
-+ || h->root.type == bfd_link_hash_defweak
-+ || !h->def_regular))))
-+ || (ELIMINATE_COPY_RELOCS
-+ && !info->shared
-+ && h != NULL
-+ && (h->root.type == bfd_link_hash_defweak
-+ || !h->def_regular)))
-+ {
-+ struct elf_dyn_relocs *p;
-+ struct elf_dyn_relocs **rel_head;
-+
-+#ifdef DEBUG
-+ fprintf (stderr,
-+ "ppc_elf_check_relocs needs to "
-+ "create relocation for %s\n",
-+ (h && h->root.root.string
-+ ? h->root.root.string : "<unknown>"));
-+#endif
-+ if (sreloc == NULL)
-+ {
-+ if (htab->elf.dynobj == NULL)
-+ htab->elf.dynobj = abfd;
-+
-+ sreloc = _bfd_elf_make_dynamic_reloc_section
-+ (sec, htab->elf.dynobj, 2, abfd, /*rela?*/ TRUE);
-+
-+ if (sreloc == NULL)
-+ return FALSE;
-+ }
-+
-+ /* If this is a global symbol, we count the number of
-+ relocations we need for this symbol. */
-+ if (h != NULL)
-+ {
-+ rel_head = &ppc_elf_hash_entry (h)->dyn_relocs;
-+ }
-+ else
-+ {
-+ /* Track dynamic relocs needed for local syms too.
-+ We really need local syms available to do this
-+ easily. Oh well. */
-+ asection *s;
-+ void *vpp;
-+ Elf_Internal_Sym *isym;
-+
-+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
-+ abfd, r_symndx);
-+ if (isym == NULL)
-+ return FALSE;
-+
-+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
-+ if (s == NULL)
-+ s = sec;
-+
-+ vpp = &elf_section_data (s)->local_dynrel;
-+ rel_head = (struct elf_dyn_relocs **) vpp;
-+ }
-+
-+ p = *rel_head;
-+ if (p == NULL || p->sec != sec)
-+ {
-+ p = bfd_alloc (htab->elf.dynobj, sizeof *p);
-+ if (p == NULL)
-+ return FALSE;
-+ p->next = *rel_head;
-+ *rel_head = p;
-+ p->sec = sec;
-+ p->count = 0;
-+ p->pc_count = 0;
-+ }
-+
-+ p->count += 1;
-+ if (!must_be_dyn_reloc (info, r_type))
-+ p->pc_count += 1;
-+ }
-+
-+ break;
-+ }
-+ }
-+
-+ return TRUE;
-+}
-+
-+
-+/* Merge object attributes from IBFD into OBFD. Raise an error if
-+ there are conflicting attributes. */
-+static bfd_boolean
-+ppc_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
-+{
-+ obj_attribute *in_attr, *in_attrs;
-+ obj_attribute *out_attr, *out_attrs;
-+
-+ if (!elf_known_obj_attributes_proc (obfd)[0].i)
-+ {
-+ /* This is the first object. Copy the attributes. */
-+ _bfd_elf_copy_obj_attributes (ibfd, obfd);
-+
-+ /* Use the Tag_null value to indicate the attributes have been
-+ initialized. */
-+ elf_known_obj_attributes_proc (obfd)[0].i = 1;
-+
-+ return TRUE;
-+ }
-+
-+ in_attrs = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
-+ out_attrs = elf_known_obj_attributes (obfd)[OBJ_ATTR_GNU];
-+
-+ /* Check for conflicting Tag_GNU_Power_ABI_FP attributes and merge
-+ non-conflicting ones. */
-+ in_attr = &in_attrs[Tag_GNU_Power_ABI_FP];
-+ out_attr = &out_attrs[Tag_GNU_Power_ABI_FP];
-+ if (in_attr->i != out_attr->i)
-+ {
-+ out_attr->type = 1;
-+ if (out_attr->i == 0)
-+ out_attr->i = in_attr->i;
-+ else if (in_attr->i == 0)
-+ ;
-+ else if (out_attr->i == 1 && in_attr->i == 2)
-+ _bfd_error_handler
-+ (_("Warning: %B uses hard float, %B uses soft float"), obfd, ibfd);
-+ else if (out_attr->i == 1 && in_attr->i == 3)
-+ _bfd_error_handler
-+ (_("Warning: %B uses double-precision hard float, %B uses single-precision hard float"),
-+ obfd, ibfd);
-+ else if (out_attr->i == 3 && in_attr->i == 1)
-+ _bfd_error_handler
-+ (_("Warning: %B uses double-precision hard float, %B uses single-precision hard float"),
-+ ibfd, obfd);
-+ else if (out_attr->i == 3 && in_attr->i == 2)
-+ _bfd_error_handler
-+ (_("Warning: %B uses soft float, %B uses single-precision hard float"),
-+ ibfd, obfd);
-+ else if (out_attr->i == 2 && (in_attr->i == 1 || in_attr->i == 3))
-+ _bfd_error_handler
-+ (_("Warning: %B uses hard float, %B uses soft float"), ibfd, obfd);
-+ else if (in_attr->i > 3)
-+ _bfd_error_handler
-+ (_("Warning: %B uses unknown floating point ABI %d"), ibfd,
-+ in_attr->i);
-+ else
-+ _bfd_error_handler
-+ (_("Warning: %B uses unknown floating point ABI %d"), obfd,
-+ out_attr->i);
-+ }
-+
-+ /* Check for conflicting Tag_GNU_Power_ABI_Vector attributes and
-+ merge non-conflicting ones. */
-+ in_attr = &in_attrs[Tag_GNU_Power_ABI_Vector];
-+ out_attr = &out_attrs[Tag_GNU_Power_ABI_Vector];
-+ if (in_attr->i != out_attr->i)
-+ {
-+ const char *in_abi = NULL, *out_abi = NULL;
-+
-+ switch (in_attr->i)
-+ {
-+ case 1: in_abi = "generic"; break;
-+ case 2: in_abi = "AltiVec"; break;
-+ case 3: in_abi = "SPE"; break;
-+ }
-+
-+ switch (out_attr->i)
-+ {
-+ case 1: out_abi = "generic"; break;
-+ case 2: out_abi = "AltiVec"; break;
-+ case 3: out_abi = "SPE"; break;
-+ }
-+
-+ out_attr->type = 1;
-+ if (out_attr->i == 0)
-+ out_attr->i = in_attr->i;
-+ else if (in_attr->i == 0)
-+ ;
-+ /* For now, allow generic to transition to AltiVec or SPE
-+ without a warning. If GCC marked files with their stack
-+ alignment and used don't-care markings for files which are
-+ not affected by the vector ABI, we could warn about this
-+ case too. */
-+ else if (out_attr->i == 1)
-+ out_attr->i = in_attr->i;
-+ else if (in_attr->i == 1)
-+ ;
-+ else if (in_abi == NULL)
-+ _bfd_error_handler
-+ (_("Warning: %B uses unknown vector ABI %d"), ibfd,
-+ in_attr->i);
-+ else if (out_abi == NULL)
-+ _bfd_error_handler
-+ (_("Warning: %B uses unknown vector ABI %d"), obfd,
-+ in_attr->i);
-+ else
-+ _bfd_error_handler
-+ (_("Warning: %B uses vector ABI \"%s\", %B uses \"%s\""),
-+ ibfd, obfd, in_abi, out_abi);
-+ }
-+
-+ /* Check for conflicting Tag_GNU_Power_ABI_Struct_Return attributes
-+ and merge non-conflicting ones. */
-+ in_attr = &in_attrs[Tag_GNU_Power_ABI_Struct_Return];
-+ out_attr = &out_attrs[Tag_GNU_Power_ABI_Struct_Return];
-+ if (in_attr->i != out_attr->i)
-+ {
-+ out_attr->type = 1;
-+ if (out_attr->i == 0)
-+ out_attr->i = in_attr->i;
-+ else if (in_attr->i == 0)
-+ ;
-+ else if (out_attr->i == 1 && in_attr->i == 2)
-+ _bfd_error_handler
-+ (_("Warning: %B uses r3/r4 for small structure returns, %B uses memory"), obfd, ibfd);
-+ else if (out_attr->i == 2 && in_attr->i == 1)
-+ _bfd_error_handler
-+ (_("Warning: %B uses r3/r4 for small structure returns, %B uses memory"), ibfd, obfd);
-+ else if (in_attr->i > 2)
-+ _bfd_error_handler
-+ (_("Warning: %B uses unknown small structure return convention %d"), ibfd,
-+ in_attr->i);
-+ else
-+ _bfd_error_handler
-+ (_("Warning: %B uses unknown small structure return convention %d"), obfd,
-+ out_attr->i);
-+ }
-+
-+ /* Merge Tag_compatibility attributes and any common GNU ones. */
-+ _bfd_elf_merge_object_attributes (ibfd, obfd);
-+
-+ return TRUE;
-+}
-+
-+/* Merge backend specific data from an object file to the output
-+ object file when linking. */
-+
-+static bfd_boolean
-+ppc_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
-+{
-+ flagword old_flags;
-+ flagword new_flags;
-+ bfd_boolean error;
-+
-+ if (!is_ppc_elf (ibfd) || !is_ppc_elf (obfd))
-+ return TRUE;
-+
-+ /* Check if we have the same endianness. */
-+ if (! _bfd_generic_verify_endian_match (ibfd, obfd))
-+ return FALSE;
-+
-+ if (!ppc_elf_merge_obj_attributes (ibfd, obfd))
-+ return FALSE;
-+
-+ new_flags = elf_elfheader (ibfd)->e_flags;
-+ old_flags = elf_elfheader (obfd)->e_flags;
-+ if (!elf_flags_init (obfd))
-+ {
-+ /* First call, no flags set. */
-+ elf_flags_init (obfd) = TRUE;
-+ elf_elfheader (obfd)->e_flags = new_flags;
-+ }
-+
-+ /* Compatible flags are ok. */
-+ else if (new_flags == old_flags)
-+ ;
-+
-+ /* Incompatible flags. */
-+ else
-+ {
-+ /* Warn about -mrelocatable mismatch. Allow -mrelocatable-lib
-+ to be linked with either. */
-+ error = FALSE;
-+ if ((new_flags & EF_PPC_RELOCATABLE) != 0
-+ && (old_flags & (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB)) == 0)
-+ {
-+ error = TRUE;
-+ (*_bfd_error_handler)
-+ (_("%B: compiled with -mrelocatable and linked with "
-+ "modules compiled normally"), ibfd);
-+ }
-+ else if ((new_flags & (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB)) == 0
-+ && (old_flags & EF_PPC_RELOCATABLE) != 0)
-+ {
-+ error = TRUE;
-+ (*_bfd_error_handler)
-+ (_("%B: compiled normally and linked with "
-+ "modules compiled with -mrelocatable"), ibfd);
-+ }
-+
-+ /* The output is -mrelocatable-lib iff both the input files are. */
-+ if (! (new_flags & EF_PPC_RELOCATABLE_LIB))
-+ elf_elfheader (obfd)->e_flags &= ~EF_PPC_RELOCATABLE_LIB;
-+
-+ /* The output is -mrelocatable iff it can't be -mrelocatable-lib,
-+ but each input file is either -mrelocatable or -mrelocatable-lib. */
-+ if (! (elf_elfheader (obfd)->e_flags & EF_PPC_RELOCATABLE_LIB)
-+ && (new_flags & (EF_PPC_RELOCATABLE_LIB | EF_PPC_RELOCATABLE))
-+ && (old_flags & (EF_PPC_RELOCATABLE_LIB | EF_PPC_RELOCATABLE)))
-+ elf_elfheader (obfd)->e_flags |= EF_PPC_RELOCATABLE;
-+
-+ /* Do not warn about eabi vs. V.4 mismatch, just or in the bit if
-+ any module uses it. */
-+ elf_elfheader (obfd)->e_flags |= (new_flags & EF_PPC_EMB);
-+
-+ new_flags &= ~(EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB | EF_PPC_EMB);
-+ old_flags &= ~(EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB | EF_PPC_EMB);
-+
-+ /* Warn about any other mismatches. */
-+ if (new_flags != old_flags)
-+ {
-+ error = TRUE;
-+ (*_bfd_error_handler)
-+ (_("%B: uses different e_flags (0x%lx) fields "
-+ "than previous modules (0x%lx)"),
-+ ibfd, (long) new_flags, (long) old_flags);
-+ }
-+
-+ if (error)
-+ {
-+ bfd_set_error (bfd_error_bad_value);
-+ return FALSE;
-+ }
-+ }
-+
-+ return TRUE;
-+}
-+
-+static void
-+ppc_elf_vle_split16 (bfd *output_bfd, bfd_byte *contents,
-+ bfd_vma offset, bfd_vma relocation,
-+ split16_format_type split16_format)
-+
-+{
-+ bfd_vma insn, top5, bottom11;
-+
-+ insn = bfd_get_32 (output_bfd, contents + offset);
-+ top5 = relocation >> 11;
-+ top5 = top5 << (split16_format == split16a_type ? 20 : 16);
-+ bottom11 = relocation & 0x7ff;
-+ insn |= top5;
-+ insn |= bottom11;
-+ bfd_put_32 (output_bfd, insn, contents + offset);
-+}
-+
-+
-+/* Choose which PLT scheme to use, and set .plt flags appropriately.
-+ Returns -1 on error, 0 for old PLT, 1 for new PLT. */
-+int
-+ppc_elf_amigaos_select_plt_layout (bfd *output_bfd ATTRIBUTE_UNUSED,
-+ struct bfd_link_info *info,
-+ enum ppc_elf_plt_type plt_style,
-+ int emit_stub_syms)
-+{
-+ struct ppc_elf_link_hash_table *htab;
-+ flagword flags;
-+
-+ htab = ppc_elf_hash_table (info);
-+
-+ htab->emit_stub_syms = emit_stub_syms;
-+
-+ if (htab->plt_type == PLT_UNSET)
-+ {
-+ struct elf_link_hash_entry *h;
-+
-+ if (plt_style == PLT_OLD)
-+ htab->plt_type = PLT_OLD;
-+ else if (info->shared
-+ && htab->elf.dynamic_sections_created
-+ && (h = elf_link_hash_lookup (&htab->elf, "_mcount",
-+ FALSE, FALSE, TRUE)) != NULL
-+ && (h->type == STT_FUNC
-+ || h->needs_plt)
-+ && h->ref_regular
-+ && !(SYMBOL_CALLS_LOCAL (info, h)
-+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
-+ && h->root.type == bfd_link_hash_undefweak)))
-+ {
-+ /* Profiling of shared libs (and pies) is not supported with
-+ secure plt, because ppc32 does profiling before a
-+ function prologue and a secure plt pic call stubs needs
-+ r30 to be set up. */
-+ htab->plt_type = PLT_OLD;
-+ }
-+ else
-+ {
-+ bfd *ibfd;
-+ enum ppc_elf_plt_type plt_type = plt_style;
-+
-+ /* Look through the reloc flags left by ppc_elf_check_relocs.
-+ Use the old style bss plt if a file makes plt calls
-+ without using the new relocs, and if ld isn't given
-+ --secure-plt and we never see REL16 relocs. */
-+ if (plt_type == PLT_UNSET)
-+ plt_type = PLT_OLD;
-+ for (ibfd = info->input_bfds; ibfd; ibfd = ibfd->link_next)
-+ if (is_ppc_elf (ibfd))
-+ {
-+ if (ppc_elf_tdata (ibfd)->has_rel16)
-+ plt_type = PLT_NEW;
-+ else if (ppc_elf_tdata (ibfd)->makes_plt_call)
-+ {
-+ plt_type = PLT_OLD;
-+ htab->old_bfd = ibfd;
-+ break;
-+ }
-+ }
-+ htab->plt_type = plt_type;
-+ }
-+ }
-+ if (htab->plt_type == PLT_OLD && plt_style == PLT_NEW)
-+ {
-+ if (htab->old_bfd != NULL)
-+ info->callbacks->einfo (_("%P: bss-plt forced due to %B\n"),
-+ htab->old_bfd);
-+ else
-+ info->callbacks->einfo (_("%P: bss-plt forced by profiling\n"));
-+ }
-+
-+ BFD_ASSERT (htab->plt_type != PLT_VXWORKS);
-+
-+ if (htab->plt_type == PLT_NEW)
-+ {
-+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
-+ | SEC_IN_MEMORY | SEC_LINKER_CREATED);
-+
-+ /* The new PLT is a loaded section. */
-+ if (htab->plt != NULL
-+ && !bfd_set_section_flags (htab->elf.dynobj, htab->plt, flags))
-+ return -1;
-+
-+ /* The new GOT is not executable. */
-+ if (htab->got != NULL
-+ && !bfd_set_section_flags (htab->elf.dynobj, htab->got, flags))
-+ return -1;
-+ }
-+ else
-+ {
-+ /* Stop an unused .glink section from affecting .text alignment. */
-+ if (htab->glink != NULL
-+ && !bfd_set_section_alignment (htab->elf.dynobj, htab->glink, 0))
-+ return -1;
-+ }
-+ return htab->plt_type == PLT_NEW;
-+}
-+
-+/* Return the section that should be marked against GC for a given
-+ relocation. */
-+
-+static asection *
-+ppc_elf_gc_mark_hook (asection *sec,
-+ struct bfd_link_info *info,
-+ Elf_Internal_Rela *rel,
-+ struct elf_link_hash_entry *h,
-+ Elf_Internal_Sym *sym)
-+{
-+ if (h != NULL)
-+ switch (ELF32_R_TYPE (rel->r_info))
-+ {
-+ case R_PPC_GNU_VTINHERIT:
-+ case R_PPC_GNU_VTENTRY:
-+ return NULL;
-+ }
-+
-+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
-+}
-+
-+/* Update the got, plt and dynamic reloc reference counts for the
-+ section being removed. */
-+
-+static bfd_boolean
-+ppc_elf_gc_sweep_hook (bfd *abfd,
-+ struct bfd_link_info *info,
-+ asection *sec,
-+ const Elf_Internal_Rela *relocs)
-+{
-+ struct ppc_elf_link_hash_table *htab;
-+ Elf_Internal_Shdr *symtab_hdr;
-+ struct elf_link_hash_entry **sym_hashes;
-+ bfd_signed_vma *local_got_refcounts;
-+ const Elf_Internal_Rela *rel, *relend;
-+ asection *got2;
-+
-+ if (info->relocatable)
-+ return TRUE;
-+
-+ if ((sec->flags & SEC_ALLOC) == 0)
-+ return TRUE;
-+
-+ elf_section_data (sec)->local_dynrel = NULL;
-+
-+ htab = ppc_elf_hash_table (info);
-+ symtab_hdr = &elf_symtab_hdr (abfd);
-+ sym_hashes = elf_sym_hashes (abfd);
-+ local_got_refcounts = elf_local_got_refcounts (abfd);
-+ got2 = bfd_get_section_by_name (abfd, ".got2");
-+
-+ relend = relocs + sec->reloc_count;
-+ for (rel = relocs; rel < relend; rel++)
-+ {
-+ unsigned long r_symndx;
-+ enum elf_ppc_reloc_type r_type;
-+ struct elf_link_hash_entry *h = NULL;
-+
-+ r_symndx = ELF32_R_SYM (rel->r_info);
-+ if (r_symndx >= symtab_hdr->sh_info)
-+ {
-+ struct elf_dyn_relocs **pp, *p;
-+ struct ppc_elf_link_hash_entry *eh;
-+
-+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-+ while (h->root.type == bfd_link_hash_indirect
-+ || h->root.type == bfd_link_hash_warning)
-+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
-+ eh = (struct ppc_elf_link_hash_entry *) h;
-+
-+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
-+ if (p->sec == sec)
-+ {
-+ /* Everything must go for SEC. */
-+ *pp = p->next;
-+ break;
-+ }
-+ }
-+
-+ r_type = ELF32_R_TYPE (rel->r_info);
-+ if (!htab->is_vxworks
-+ && h == NULL
-+ && local_got_refcounts != NULL
-+ && (!info->shared
-+ || is_branch_reloc (r_type)))
-+ {
-+ struct plt_entry **local_plt = (struct plt_entry **)
-+ (local_got_refcounts + symtab_hdr->sh_info);
-+ char *local_got_tls_masks = (char *)
-+ (local_plt + symtab_hdr->sh_info);
-+ if ((local_got_tls_masks[r_symndx] & PLT_IFUNC) != 0)
-+ {
-+ struct plt_entry **ifunc = local_plt + r_symndx;
-+ bfd_vma addend = 0;
-+ struct plt_entry *ent;
-+
-+ if (r_type == R_PPC_PLTREL24 && info->shared)
-+ addend = rel->r_addend;
-+ ent = find_plt_ent (ifunc, got2, addend);
-+ if (ent->plt.refcount > 0)
-+ ent->plt.refcount -= 1;
-+ continue;
-+ }
-+ }
-+
-+ switch (r_type)
-+ {
-+ case R_PPC_GOT_TLSLD16:
-+ case R_PPC_GOT_TLSLD16_LO:
-+ case R_PPC_GOT_TLSLD16_HI:
-+ case R_PPC_GOT_TLSLD16_HA:
-+ case R_PPC_GOT_TLSGD16:
-+ case R_PPC_GOT_TLSGD16_LO:
-+ case R_PPC_GOT_TLSGD16_HI:
-+ case R_PPC_GOT_TLSGD16_HA:
-+ case R_PPC_GOT_TPREL16:
-+ case R_PPC_GOT_TPREL16_LO:
-+ case R_PPC_GOT_TPREL16_HI:
-+ case R_PPC_GOT_TPREL16_HA:
-+ case R_PPC_GOT_DTPREL16:
-+ case R_PPC_GOT_DTPREL16_LO:
-+ case R_PPC_GOT_DTPREL16_HI:
-+ case R_PPC_GOT_DTPREL16_HA:
-+ case R_PPC_GOT16:
-+ case R_PPC_GOT16_LO:
-+ case R_PPC_GOT16_HI:
-+ case R_PPC_GOT16_HA:
-+ if (h != NULL)
-+ {
-+ if (h->got.refcount > 0)
-+ h->got.refcount--;
-+ if (!info->shared)
-+ {
-+ struct plt_entry *ent;
-+
-+ ent = find_plt_ent (&h->plt.plist, NULL, 0);
-+ if (ent != NULL && ent->plt.refcount > 0)
-+ ent->plt.refcount -= 1;
-+ }
-+ }
-+ else if (local_got_refcounts != NULL)
-+ {
-+ if (local_got_refcounts[r_symndx] > 0)
-+ local_got_refcounts[r_symndx]--;
-+ }
-+ break;
-+
-+ case R_PPC_REL24:
-+ case R_PPC_REL14:
-+ case R_PPC_REL14_BRTAKEN:
-+ case R_PPC_REL14_BRNTAKEN:
-+ case R_PPC_REL32:
-+ if (h == NULL || h == htab->elf.hgot)
-+ break;
-+ /* Fall thru */
-+
-+ case R_PPC_ADDR32:
-+ case R_PPC_ADDR24:
-+ case R_PPC_ADDR16:
-+ case R_PPC_ADDR16_LO:
-+ case R_PPC_ADDR16_HI:
-+ case R_PPC_ADDR16_HA:
-+ case R_PPC_ADDR14:
-+ case R_PPC_ADDR14_BRTAKEN:
-+ case R_PPC_ADDR14_BRNTAKEN:
-+ case R_PPC_UADDR32:
-+ case R_PPC_UADDR16:
-+ if (info->shared)
-+ break;
-+
-+ case R_PPC_PLT32:
-+ case R_PPC_PLTREL24:
-+ case R_PPC_PLTREL32:
-+ case R_PPC_PLT16_LO:
-+ case R_PPC_PLT16_HI:
-+ case R_PPC_PLT16_HA:
-+ if (h != NULL)
-+ {
-+ bfd_vma addend = 0;
-+ struct plt_entry *ent;
-+
-+ if (r_type == R_PPC_PLTREL24 && info->shared)
-+ addend = rel->r_addend;
-+ ent = find_plt_ent (&h->plt.plist, got2, addend);
-+ if (ent != NULL && ent->plt.refcount > 0)
-+ ent->plt.refcount -= 1;
-+ }
-+ break;
-+
-+ default:
-+ break;
-+ }
-+ }
-+ return TRUE;
-+}
-+
-+/* Set plt output section type, htab->tls_get_addr, and call the
-+ generic ELF tls_setup function. */
-+
-+asection *
-+ppc_elf_amigaos_tls_setup (bfd *obfd,
-+ struct bfd_link_info *info,
-+ int no_tls_get_addr_opt)
-+{
-+ struct ppc_elf_link_hash_table *htab;
-+
-+ htab = ppc_elf_hash_table (info);
-+ htab->tls_get_addr = elf_link_hash_lookup (&htab->elf, "__tls_get_addr",
-+ FALSE, FALSE, TRUE);
-+ if (!no_tls_get_addr_opt)
-+ {
-+ struct elf_link_hash_entry *opt, *tga;
-+ opt = elf_link_hash_lookup (&htab->elf, "__tls_get_addr_opt",
-+ FALSE, FALSE, TRUE);
-+ if (opt != NULL
-+ && (opt->root.type == bfd_link_hash_defined
-+ || opt->root.type == bfd_link_hash_defweak))
-+ {
-+ /* If glibc supports an optimized __tls_get_addr call stub,
-+ signalled by the presence of __tls_get_addr_opt, and we'll
-+ be calling __tls_get_addr via a plt call stub, then
-+ make __tls_get_addr point to __tls_get_addr_opt. */
-+ tga = htab->tls_get_addr;
-+ if (htab->elf.dynamic_sections_created
-+ && tga != NULL
-+ && (tga->type == STT_FUNC
-+ || tga->needs_plt)
-+ && !(SYMBOL_CALLS_LOCAL (info, tga)
-+ || (ELF_ST_VISIBILITY (tga->other) != STV_DEFAULT
-+ && tga->root.type == bfd_link_hash_undefweak)))
-+ {
-+ struct plt_entry *ent;
-+ for (ent = tga->plt.plist; ent != NULL; ent = ent->next)
-+ if (ent->plt.refcount > 0)
-+ break;
-+ if (ent != NULL)
-+ {
-+ tga->root.type = bfd_link_hash_indirect;
-+ tga->root.u.i.link = &opt->root;
-+ ppc_elf_copy_indirect_symbol (info, opt, tga);
-+ if (opt->dynindx != -1)
-+ {
-+ /* Use __tls_get_addr_opt in dynamic relocations. */
-+ opt->dynindx = -1;
-+ _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
-+ opt->dynstr_index);
-+ if (!bfd_elf_link_record_dynamic_symbol (info, opt))
-+ return FALSE;
-+ }
-+ htab->tls_get_addr = opt;
-+ }
-+ }
-+ }
-+ else
-+ no_tls_get_addr_opt = TRUE;
-+ }
-+ htab->no_tls_get_addr_opt = no_tls_get_addr_opt;
-+ if (htab->plt_type == PLT_NEW
-+ && htab->plt != NULL
-+ && htab->plt->output_section != NULL)
-+ {
-+ elf_section_type (htab->plt->output_section) = SHT_PROGBITS;
-+ elf_section_flags (htab->plt->output_section) = SHF_ALLOC + SHF_WRITE;
-+ }
-+
-+ return _bfd_elf_tls_setup (obfd, info);
-+}
-+
-+/* Return TRUE iff REL is a branch reloc with a global symbol matching
-+ HASH. */
-+
-+static bfd_boolean
-+branch_reloc_hash_match (const bfd *ibfd,
-+ const Elf_Internal_Rela *rel,
-+ const struct elf_link_hash_entry *hash)
-+{
-+ Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (ibfd);
-+ enum elf_ppc_reloc_type r_type = ELF32_R_TYPE (rel->r_info);
-+ unsigned int r_symndx = ELF32_R_SYM (rel->r_info);
-+
-+ if (r_symndx >= symtab_hdr->sh_info && is_branch_reloc (r_type))
-+ {
-+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (ibfd);
-+ struct elf_link_hash_entry *h;
-+
-+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-+ while (h->root.type == bfd_link_hash_indirect
-+ || h->root.type == bfd_link_hash_warning)
-+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
-+ if (h == hash)
-+ return TRUE;
-+ }
-+ return FALSE;
-+}
-+
-+/* Run through all the TLS relocs looking for optimization
-+ opportunities. */
-+
-+bfd_boolean
-+ppc_elf_amigaos_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED,
-+ struct bfd_link_info *info)
-+{
-+ bfd *ibfd;
-+ asection *sec;
-+ struct ppc_elf_link_hash_table *htab;
-+ int pass;
-+
-+ if (info->relocatable || !info->executable)
-+ return TRUE;
-+
-+ htab = ppc_elf_hash_table (info);
-+ if (htab == NULL)
-+ return FALSE;
-+
-+ /* Make two passes through the relocs. First time check that tls
-+ relocs involved in setting up a tls_get_addr call are indeed
-+ followed by such a call. If they are not, don't do any tls
-+ optimization. On the second pass twiddle tls_mask flags to
-+ notify relocate_section that optimization can be done, and
-+ adjust got and plt refcounts. */
-+ for (pass = 0; pass < 2; ++pass)
-+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
-+ {
-+ Elf_Internal_Sym *locsyms = NULL;
-+ Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (ibfd);
-+ asection *got2 = bfd_get_section_by_name (ibfd, ".got2");
-+
-+ for (sec = ibfd->sections; sec != NULL; sec = sec->next)
-+ if (sec->has_tls_reloc && !bfd_is_abs_section (sec->output_section))
-+ {
-+ Elf_Internal_Rela *relstart, *rel, *relend;
-+ int expecting_tls_get_addr = 0;
-+
-+ /* Read the relocations. */
-+ relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL,
-+ info->keep_memory);
-+ if (relstart == NULL)
-+ return FALSE;
-+
-+ relend = relstart + sec->reloc_count;
-+ for (rel = relstart; rel < relend; rel++)
-+ {
-+ enum elf_ppc_reloc_type r_type;
-+ unsigned long r_symndx;
-+ struct elf_link_hash_entry *h = NULL;
-+ char *tls_mask;
-+ char tls_set, tls_clear;
-+ bfd_boolean is_local;
-+ bfd_signed_vma *got_count;
-+
-+ r_symndx = ELF32_R_SYM (rel->r_info);
-+ if (r_symndx >= symtab_hdr->sh_info)
-+ {
-+ struct elf_link_hash_entry **sym_hashes;
-+
-+ sym_hashes = elf_sym_hashes (ibfd);
-+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-+ while (h->root.type == bfd_link_hash_indirect
-+ || h->root.type == bfd_link_hash_warning)
-+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
-+ }
-+
-+ is_local = FALSE;
-+ if (h == NULL
-+ || !h->def_dynamic)
-+ is_local = TRUE;
-+
-+ r_type = ELF32_R_TYPE (rel->r_info);
-+ /* If this section has old-style __tls_get_addr calls
-+ without marker relocs, then check that each
-+ __tls_get_addr call reloc is preceded by a reloc
-+ that conceivably belongs to the __tls_get_addr arg
-+ setup insn. If we don't find matching arg setup
-+ relocs, don't do any tls optimization. */
-+ if (pass == 0
-+ && sec->has_tls_get_addr_call
-+ && h != NULL
-+ && h == htab->tls_get_addr
-+ && !expecting_tls_get_addr
-+ && is_branch_reloc (r_type))
-+ {
-+ info->callbacks->minfo ("%H __tls_get_addr lost arg, "
-+ "TLS optimization disabled\n",
-+ ibfd, sec, rel->r_offset);
-+ if (elf_section_data (sec)->relocs != relstart)
-+ free (relstart);
-+ return TRUE;
-+ }
-+
-+ expecting_tls_get_addr = 0;
-+ switch (r_type)
-+ {
-+ case R_PPC_GOT_TLSLD16:
-+ case R_PPC_GOT_TLSLD16_LO:
-+ expecting_tls_get_addr = 1;
-+ /* Fall thru */
-+
-+ case R_PPC_GOT_TLSLD16_HI:
-+ case R_PPC_GOT_TLSLD16_HA:
-+ /* These relocs should never be against a symbol
-+ defined in a shared lib. Leave them alone if
-+ that turns out to be the case. */
-+ if (!is_local)
-+ continue;
-+
-+ /* LD -> LE */
-+ tls_set = 0;
-+ tls_clear = TLS_LD;
-+ break;
-+
-+ case R_PPC_GOT_TLSGD16:
-+ case R_PPC_GOT_TLSGD16_LO:
-+ expecting_tls_get_addr = 1;
-+ /* Fall thru */
-+
-+ case R_PPC_GOT_TLSGD16_HI:
-+ case R_PPC_GOT_TLSGD16_HA:
-+ if (is_local)
-+ /* GD -> LE */
-+ tls_set = 0;
-+ else
-+ /* GD -> IE */
-+ tls_set = TLS_TLS | TLS_TPRELGD;
-+ tls_clear = TLS_GD;
-+ break;
-+
-+ case R_PPC_GOT_TPREL16:
-+ case R_PPC_GOT_TPREL16_LO:
-+ case R_PPC_GOT_TPREL16_HI:
-+ case R_PPC_GOT_TPREL16_HA:
-+ if (is_local)
-+ {
-+ /* IE -> LE */
-+ tls_set = 0;
-+ tls_clear = TLS_TPREL;
-+ break;
-+ }
-+ else
-+ continue;
-+
-+ case R_PPC_TLSGD:
-+ case R_PPC_TLSLD:
-+ expecting_tls_get_addr = 2;
-+ tls_set = 0;
-+ tls_clear = 0;
-+ break;
-+
-+ default:
-+ continue;
-+ }
-+
-+ if (pass == 0)
-+ {
-+ if (!expecting_tls_get_addr
-+ || (expecting_tls_get_addr == 1
-+ && !sec->has_tls_get_addr_call))
-+ continue;
-+
-+ if (rel + 1 < relend
-+ && branch_reloc_hash_match (ibfd, rel + 1,
-+ htab->tls_get_addr))
-+ continue;
-+
-+ /* Uh oh, we didn't find the expected call. We
-+ could just mark this symbol to exclude it
-+ from tls optimization but it's safer to skip
-+ the entire optimization. */
-+ info->callbacks->minfo (_("%H arg lost __tls_get_addr, "
-+ "TLS optimization disabled\n"),
-+ ibfd, sec, rel->r_offset);
-+ if (elf_section_data (sec)->relocs != relstart)
-+ free (relstart);
-+ return TRUE;
-+ }
-+
-+ if (expecting_tls_get_addr)
-+ {
-+ struct plt_entry *ent;
-+ bfd_vma addend = 0;
-+
-+ if (info->shared
-+ && ELF32_R_TYPE (rel[1].r_info) == R_PPC_PLTREL24)
-+ addend = rel[1].r_addend;
-+ ent = find_plt_ent (&htab->tls_get_addr->plt.plist,
-+ got2, addend);
-+ if (ent != NULL && ent->plt.refcount > 0)
-+ ent->plt.refcount -= 1;
-+
-+ if (expecting_tls_get_addr == 2)
-+ continue;
-+ }
-+
-+ if (h != NULL)
-+ {
-+ tls_mask = &ppc_elf_hash_entry (h)->tls_mask;
-+ got_count = &h->got.refcount;
-+ }
-+ else
-+ {
-+ bfd_signed_vma *lgot_refs;
-+ struct plt_entry **local_plt;
-+ char *lgot_masks;
-+
-+ if (locsyms == NULL)
-+ {
-+ locsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
-+ if (locsyms == NULL)
-+ locsyms = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
-+ symtab_hdr->sh_info,
-+ 0, NULL, NULL, NULL);
-+ if (locsyms == NULL)
-+ {
-+ if (elf_section_data (sec)->relocs != relstart)
-+ free (relstart);
-+ return FALSE;
-+ }
-+ }
-+ lgot_refs = elf_local_got_refcounts (ibfd);
-+ if (lgot_refs == NULL)
-+ abort ();
-+ local_plt = (struct plt_entry **)
-+ (lgot_refs + symtab_hdr->sh_info);
-+ lgot_masks = (char *) (local_plt + symtab_hdr->sh_info);
-+ tls_mask = &lgot_masks[r_symndx];
-+ got_count = &lgot_refs[r_symndx];
-+ }
-+
-+ if (tls_set == 0)
-+ {
-+ /* We managed to get rid of a got entry. */
-+ if (*got_count > 0)
-+ *got_count -= 1;
-+ }
-+
-+ *tls_mask |= tls_set;
-+ *tls_mask &= ~tls_clear;
-+ }
-+
-+ if (elf_section_data (sec)->relocs != relstart)
-+ free (relstart);
-+ }
-+
-+ if (locsyms != NULL
-+ && (symtab_hdr->contents != (unsigned char *) locsyms))
-+ {
-+ if (!info->keep_memory)
-+ free (locsyms);
-+ else
-+ symtab_hdr->contents = (unsigned char *) locsyms;
-+ }
-+ }
-+ return TRUE;
-+}
-+
-+/* Return true if we have dynamic relocs that apply to read-only sections. */
-+
-+static bfd_boolean
-+readonly_dynrelocs (struct elf_link_hash_entry *h)
-+{
-+ struct elf_dyn_relocs *p;
-+
-+ for (p = ppc_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
-+ {
-+ asection *s = p->sec->output_section;
-+
-+ if (s != NULL
-+ && ((s->flags & (SEC_READONLY | SEC_ALLOC))
-+ == (SEC_READONLY | SEC_ALLOC)))
-+ return TRUE;
-+ }
-+ return FALSE;
-+}
-+
-+/* Adjust a symbol defined by a dynamic object and referenced by a
-+ regular object. The current definition is in some section of the
-+ dynamic object, but we're not including those sections. We have to
-+ change the definition to something the rest of the link can
-+ understand. */
-+
-+static bfd_boolean
-+ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
-+ struct elf_link_hash_entry *h)
-+{
-+ struct ppc_elf_link_hash_table *htab;
-+ asection *s;
-+
-+#ifdef DEBUG
-+ fprintf (stderr, "ppc_elf_adjust_dynamic_symbol called for %s\n",
-+ h->root.root.string);
-+#endif
-+
-+ /* Make sure we know what is going on here. */
-+ htab = ppc_elf_hash_table (info);
-+ BFD_ASSERT (htab->elf.dynobj != NULL
-+ && (h->needs_plt
-+ || h->type == STT_GNU_IFUNC
-+ || h->u.weakdef != NULL
-+ || (h->def_dynamic
-+ && h->ref_regular
-+ && !h->def_regular)));
-+
-+ /* Deal with function syms. */
-+ if (h->type == STT_FUNC
-+ || h->type == STT_GNU_IFUNC
-+ || h->needs_plt)
-+ {
-+ /* Clear procedure linkage table information for any symbol that
-+ won't need a .plt entry. */
-+ struct plt_entry *ent;
-+ for (ent = h->plt.plist; ent != NULL; ent = ent->next)
-+ if (ent->plt.refcount > 0)
-+ break;
-+ if (ent == NULL
-+ || (h->type != STT_GNU_IFUNC
-+ && (SYMBOL_CALLS_LOCAL (info, h)
-+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
-+ && h->root.type == bfd_link_hash_undefweak))))
-+ {
-+ /* A PLT entry is not required/allowed when:
-+
-+ 1. We are not using ld.so; because then the PLT entry
-+ can't be set up, so we can't use one. In this case,
-+ ppc_elf_adjust_dynamic_symbol won't even be called.
-+
-+ 2. GC has rendered the entry unused.
-+
-+ 3. We know for certain that a call to this symbol
-+ will go to this object, or will remain undefined. */
-+ h->plt.plist = NULL;
-+ h->needs_plt = 0;
-+ }
-+ else
-+ {
-+ /* After adjust_dynamic_symbol, non_got_ref set in the
-+ non-shared case means that we have allocated space in
-+ .dynbss for the symbol and thus dyn_relocs for this
-+ symbol should be discarded.
-+ If we get here we know we are making a PLT entry for this
-+ symbol, and in an executable we'd normally resolve
-+ relocations against this symbol to the PLT entry. Allow
-+ dynamic relocs if the reference is weak, and the dynamic
-+ relocs will not cause text relocation. */
-+ if (!h->ref_regular_nonweak
-+ && h->non_got_ref
-+ && h->type != STT_GNU_IFUNC
-+ && !htab->is_vxworks
-+ && !ppc_elf_hash_entry (h)->has_sda_refs
-+ && !readonly_dynrelocs (h))
-+ h->non_got_ref = 0;
-+ }
-+ return TRUE;
-+ }
-+ else
-+ h->plt.plist = NULL;
-+
-+ /* If this is a weak symbol, and there is a real definition, the
-+ processor independent code will have arranged for us to see the
-+ real definition first, and we can just use the same value. */
-+ if (h->u.weakdef != NULL)
-+ {
-+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
-+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
-+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
-+ h->root.u.def.value = h->u.weakdef->root.u.def.value;
-+ if (ELIMINATE_COPY_RELOCS)
-+ h->non_got_ref = h->u.weakdef->non_got_ref;
-+ return TRUE;
-+ }
-+
-+ /* This is a reference to a symbol defined by a dynamic object which
-+ is not a function. */
-+
-+ /* If we are creating a shared library, we must presume that the
-+ only references to the symbol are via the global offset table.
-+ For such cases we need not do anything here; the relocations will
-+ be handled correctly by relocate_section. */
-+ if (info->shared)
-+ return TRUE;
-+
-+ /* If there are no references to this symbol that do not use the
-+ GOT, we don't need to generate a copy reloc. */
-+ if (!h->non_got_ref)
-+ return TRUE;
-+
-+ /* If we didn't find any dynamic relocs in read-only sections, then
-+ we'll be keeping the dynamic relocs and avoiding the copy reloc.
-+ We can't do this if there are any small data relocations. This
-+ doesn't work on VxWorks, where we can not have dynamic
-+ relocations (other than copy and jump slot relocations) in an
-+ executable. */
-+ if (ELIMINATE_COPY_RELOCS
-+ && !ppc_elf_hash_entry (h)->has_sda_refs
-+ && !htab->is_vxworks
-+ && !h->def_regular
-+ && !readonly_dynrelocs (h))
-+ {
-+ h->non_got_ref = 0;
-+ return TRUE;
-+ }
-+
-+ /* We must allocate the symbol in our .dynbss section, which will
-+ become part of the .bss section of the executable. There will be
-+ an entry for this symbol in the .dynsym section. The dynamic
-+ object will contain position independent code, so all references
-+ from the dynamic object to this symbol will go through the global
-+ offset table. The dynamic linker will use the .dynsym entry to
-+ determine the address it must put in the global offset table, so
-+ both the dynamic object and the regular object will refer to the
-+ same memory location for the variable.
-+
-+ Of course, if the symbol is referenced using SDAREL relocs, we
-+ must instead allocate it in .sbss. */
-+
-+ if (ppc_elf_hash_entry (h)->has_sda_refs)
-+ s = htab->dynsbss;
-+ else
-+ s = htab->dynbss;
-+ BFD_ASSERT (s != NULL);
-+
-+ /* We must generate a R_PPC_COPY reloc to tell the dynamic linker to
-+ copy the initial value out of the dynamic object and into the
-+ runtime process image. We need to remember the offset into the
-+ .rela.bss section we are going to use. */
-+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
-+ {
-+ asection *srel;
-+
-+ if (ppc_elf_hash_entry (h)->has_sda_refs)
-+ srel = htab->relsbss;
-+ else
-+ srel = htab->relbss;
-+ BFD_ASSERT (srel != NULL);
-+ srel->size += sizeof (Elf32_External_Rela);
-+ h->needs_copy = 1;
-+ }
-+
-+ return _bfd_elf_adjust_dynamic_copy (h, s);
-+}
-+
-+/* Generate a symbol to mark plt call stubs. For non-PIC code the sym is
-+ xxxxxxxx.plt_call32.<callee> where xxxxxxxx is a hex number, usually 0,
-+ specifying the addend on the plt relocation. For -fpic code, the sym
-+ is xxxxxxxx.plt_pic32.<callee>, and for -fPIC
-+ xxxxxxxx.got2.plt_pic32.<callee>. */
-+
-+static bfd_boolean
-+add_stub_sym (struct plt_entry *ent,
-+ struct elf_link_hash_entry *h,
-+ struct bfd_link_info *info)
-+{
-+ struct elf_link_hash_entry *sh;
-+ size_t len1, len2, len3;
-+ char *name;
-+ const char *stub;
-+ struct ppc_elf_link_hash_table *htab = ppc_elf_hash_table (info);
-+
-+ if (info->shared)
-+ stub = ".plt_pic32.";
-+ else
-+ stub = ".plt_call32.";
-+
-+ len1 = strlen (h->root.root.string);
-+ len2 = strlen (stub);
-+ len3 = 0;
-+ if (ent->sec)
-+ len3 = strlen (ent->sec->name);
-+ name = bfd_malloc (len1 + len2 + len3 + 9);
-+ if (name == NULL)
-+ return FALSE;
-+ sprintf (name, "%08x", (unsigned) ent->addend & 0xffffffff);
-+ if (ent->sec)
-+ memcpy (name + 8, ent->sec->name, len3);
-+ memcpy (name + 8 + len3, stub, len2);
-+ memcpy (name + 8 + len3 + len2, h->root.root.string, len1 + 1);
-+ sh = elf_link_hash_lookup (&htab->elf, name, TRUE, FALSE, FALSE);
-+ if (sh == NULL)
-+ return FALSE;
-+ if (sh->root.type == bfd_link_hash_new)
-+ {
-+ sh->root.type = bfd_link_hash_defined;
-+ sh->root.u.def.section = htab->glink;
-+ sh->root.u.def.value = ent->glink_offset;
-+ sh->ref_regular = 1;
-+ sh->def_regular = 1;
-+ sh->ref_regular_nonweak = 1;
-+ sh->forced_local = 1;
-+ sh->non_elf = 0;
-+ }
-+ return TRUE;
-+}
-+
-+/* Allocate NEED contiguous space in .got, and return the offset.
-+ Handles allocation of the got header when crossing 32k. */
-+
-+static bfd_vma
-+allocate_got (struct ppc_elf_link_hash_table *htab, unsigned int need)
-+{
-+ bfd_vma where;
-+ unsigned int max_before_header;
-+
-+ if (htab->plt_type == PLT_VXWORKS)
-+ {
-+ where = htab->got->size;
-+ htab->got->size += need;
-+ }
-+ else
-+ {
-+ max_before_header = htab->plt_type == PLT_NEW ? 32768 : 32764;
-+ if (need <= htab->got_gap)
-+ {
-+ where = max_before_header - htab->got_gap;
-+ htab->got_gap -= need;
-+ }
-+ else
-+ {
-+ if (htab->got->size + need > max_before_header
-+ && htab->got->size <= max_before_header)
-+ {
-+ htab->got_gap = max_before_header - htab->got->size;
-+ htab->got->size = max_before_header + htab->got_header_size;
-+ }
-+ where = htab->got->size;
-+ htab->got->size += need;
-+ }
-+ }
-+ return where;
-+}
-+
-+/* Allocate space in associated reloc sections for dynamic relocs. */
-+
-+static bfd_boolean
-+allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
-+{
-+ struct bfd_link_info *info = inf;
-+ struct ppc_elf_link_hash_entry *eh;
-+ struct ppc_elf_link_hash_table *htab;
-+ struct elf_dyn_relocs *p;
-+
-+ if (h->root.type == bfd_link_hash_indirect)
-+ return TRUE;
-+
-+ htab = ppc_elf_hash_table (info);
-+ if (htab->elf.dynamic_sections_created
-+ || h->type == STT_GNU_IFUNC)
-+ {
-+ struct plt_entry *ent;
-+ bfd_boolean doneone = FALSE;
-+ bfd_vma plt_offset = 0, glink_offset = 0;
-+ bfd_boolean dyn;
-+
-+ for (ent = h->plt.plist; ent != NULL; ent = ent->next)
-+ if (ent->plt.refcount > 0)
-+ {
-+ /* Make sure this symbol is output as a dynamic symbol. */
-+ if (h->dynindx == -1
-+ && !h->forced_local
-+ && !h->def_regular
-+ && htab->elf.dynamic_sections_created)
-+ {
-+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
-+ return FALSE;
-+ }
-+
-+ dyn = htab->elf.dynamic_sections_created;
-+ if (info->shared
-+ || h->type == STT_GNU_IFUNC
-+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))
-+ {
-+ asection *s = htab->plt;
-+ if (!dyn || h->dynindx == -1)
-+ s = htab->iplt;
-+
-+ if (htab->plt_type == PLT_NEW || !dyn || h->dynindx == -1)
-+ {
-+ if (!doneone)
-+ {
-+ plt_offset = s->size;
-+ s->size += 4;
-+ }
-+ ent->plt.offset = plt_offset;
-+
-+ s = htab->glink;
-+ if (!doneone || info->shared)
-+ {
-+ glink_offset = s->size;
-+ s->size += GLINK_ENTRY_SIZE;
-+ if (h == htab->tls_get_addr
-+ && !htab->no_tls_get_addr_opt)
-+ s->size += TLS_GET_ADDR_GLINK_SIZE - GLINK_ENTRY_SIZE;
-+ }
-+ if (!doneone
-+ && !info->shared
-+ && h->def_dynamic
-+ && !h->def_regular)
-+ {
-+ h->root.u.def.section = s;
-+ h->root.u.def.value = glink_offset;
-+ }
-+ ent->glink_offset = glink_offset;
-+
-+ if (htab->emit_stub_syms
-+ && !add_stub_sym (ent, h, info))
-+ return FALSE;
-+ }
-+ else
-+ {
-+ if (!doneone)
-+ {
-+ /* If this is the first .plt entry, make room
-+ for the special first entry. */
-+ if (s->size == 0)
-+ s->size += htab->plt_initial_entry_size;
-+
-+ /* The PowerPC PLT is actually composed of two
-+ parts, the first part is 2 words (for a load
-+ and a jump), and then there is a remaining
-+ word available at the end. */
-+ plt_offset = (htab->plt_initial_entry_size
-+ + (htab->plt_slot_size
-+ * ((s->size
-+ - htab->plt_initial_entry_size)
-+ / htab->plt_entry_size)));
-+
-+ /* If this symbol is not defined in a regular
-+ file, and we are not generating a shared
-+ library, then set the symbol to this location
-+ in the .plt. This is to avoid text
-+ relocations, and is required to make
-+ function pointers compare as equal between
-+ the normal executable and the shared library. */
-+ if (! info->shared
-+ && h->def_dynamic
-+ && !h->def_regular)
-+ {
-+ h->root.u.def.section = s;
-+ h->root.u.def.value = plt_offset;
-+ }
-+
-+ /* Make room for this entry. */
-+ s->size += htab->plt_entry_size;
-+ /* After the 8192nd entry, room for two entries
-+ is allocated. */
-+ if (htab->plt_type == PLT_OLD
-+ && (s->size - htab->plt_initial_entry_size)
-+ / htab->plt_entry_size
-+ > PLT_NUM_SINGLE_ENTRIES)
-+ s->size += htab->plt_entry_size;
-+ }
-+ ent->plt.offset = plt_offset;
-+ }
-+
-+ /* We also need to make an entry in the .rela.plt section. */
-+ if (!doneone)
-+ {
-+ if (!htab->elf.dynamic_sections_created
-+ || h->dynindx == -1)
-+ htab->reliplt->size += sizeof (Elf32_External_Rela);
-+ else
-+ {
-+ htab->relplt->size += sizeof (Elf32_External_Rela);
-+
-+ if (htab->plt_type == PLT_VXWORKS)
-+ {
-+ /* Allocate space for the unloaded relocations. */
-+ if (!info->shared
-+ && htab->elf.dynamic_sections_created)
-+ {
-+ if (ent->plt.offset
-+ == (bfd_vma) htab->plt_initial_entry_size)
-+ {
-+ htab->srelplt2->size
-+ += (sizeof (Elf32_External_Rela)
-+ * VXWORKS_PLTRESOLVE_RELOCS);
-+ }
-+
-+ htab->srelplt2->size
-+ += (sizeof (Elf32_External_Rela)
-+ * VXWORKS_PLT_NON_JMP_SLOT_RELOCS);
-+ }
-+
-+ /* Every PLT entry has an associated GOT entry in
-+ .got.plt. */
-+ htab->sgotplt->size += 4;
-+ }
-+ }
-+ doneone = TRUE;
-+ }
-+ }
-+ else
-+ ent->plt.offset = (bfd_vma) -1;
-+ }
-+ else
-+ ent->plt.offset = (bfd_vma) -1;
-+
-+ if (!doneone)
-+ {
-+ h->plt.plist = NULL;
-+ h->needs_plt = 0;
-+ }
-+ }
-+ else
-+ {
-+ h->plt.plist = NULL;
-+ h->needs_plt = 0;
-+ }
-+
-+ eh = (struct ppc_elf_link_hash_entry *) h;
-+ if (eh->elf.got.refcount > 0)
-+ {
-+ bfd_boolean dyn;
-+ unsigned int need;
-+
-+ /* Make sure this symbol is output as a dynamic symbol. */
-+ if (eh->elf.dynindx == -1
-+ && !eh->elf.forced_local
-+ && eh->elf.type != STT_GNU_IFUNC
-+ && htab->elf.dynamic_sections_created)
-+ {
-+ if (!bfd_elf_link_record_dynamic_symbol (info, &eh->elf))
-+ return FALSE;
-+ }
-+
-+ need = 0;
-+ if ((eh->tls_mask & TLS_TLS) != 0)
-+ {
-+ if ((eh->tls_mask & TLS_LD) != 0)
-+ {
-+ if (!eh->elf.def_dynamic)
-+ /* We'll just use htab->tlsld_got.offset. This should
-+ always be the case. It's a little odd if we have
-+ a local dynamic reloc against a non-local symbol. */
-+ htab->tlsld_got.refcount += 1;
-+ else
-+ need += 8;
-+ }
-+ if ((eh->tls_mask & TLS_GD) != 0)
-+ need += 8;
-+ if ((eh->tls_mask & (TLS_TPREL | TLS_TPRELGD)) != 0)
-+ need += 4;
-+ if ((eh->tls_mask & TLS_DTPREL) != 0)
-+ need += 4;
-+ }
-+ else
-+ need += 4;
-+ if (need == 0)
-+ eh->elf.got.offset = (bfd_vma) -1;
-+ else
-+ {
-+ eh->elf.got.offset = allocate_got (htab, need);
-+ dyn = htab->elf.dynamic_sections_created;
-+ if ((info->shared
-+ || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, &eh->elf))
-+ && (ELF_ST_VISIBILITY (eh->elf.other) == STV_DEFAULT
-+ || eh->elf.root.type != bfd_link_hash_undefweak))
-+ {
-+ asection *rsec = htab->relgot;
-+ /* All the entries we allocated need relocs.
-+ Except LD only needs one. */
-+ if ((eh->tls_mask & TLS_LD) != 0
-+ && eh->elf.def_dynamic)
-+ need -= 4;
-+ rsec->size += need * (sizeof (Elf32_External_Rela) / 4);
-+ }
-+ }
-+ }
-+ else
-+ eh->elf.got.offset = (bfd_vma) -1;
-+
-+ if (eh->dyn_relocs == NULL
-+ || !htab->elf.dynamic_sections_created)
-+ return TRUE;
-+
-+ /* In the shared -Bsymbolic case, discard space allocated for
-+ dynamic pc-relative relocs against symbols which turn out to be
-+ defined in regular objects. For the normal shared case, discard
-+ space for relocs that have become local due to symbol visibility
-+ changes. */
-+
-+ if (info->shared)
-+ {
-+ /* Relocs that use pc_count are those that appear on a call insn,
-+ or certain REL relocs (see must_be_dyn_reloc) that can be
-+ generated via assembly. We want calls to protected symbols to
-+ resolve directly to the function rather than going via the plt.
-+ If people want function pointer comparisons to work as expected
-+ then they should avoid writing weird assembly. */
-+ if (SYMBOL_CALLS_LOCAL (info, h))
-+ {
-+ struct elf_dyn_relocs **pp;
-+
-+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
-+ {
-+ p->count -= p->pc_count;
-+ p->pc_count = 0;
-+ if (p->count == 0)
-+ *pp = p->next;
-+ else
-+ pp = &p->next;
-+ }
-+ }
-+
-+ if (htab->is_vxworks)
-+ {
-+ struct elf_dyn_relocs **pp;
-+
-+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
-+ {
-+ if (strcmp (p->sec->output_section->name, ".tls_vars") == 0)
-+ *pp = p->next;
-+ else
-+ pp = &p->next;
-+ }
-+ }
-+
-+ /* Discard relocs on undefined symbols that must be local. */
-+ if (eh->dyn_relocs != NULL
-+ && h->root.type == bfd_link_hash_undefined
-+ && (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
-+ || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL))
-+ eh->dyn_relocs = NULL;
-+
-+ /* Also discard relocs on undefined weak syms with non-default
-+ visibility. */
-+ if (eh->dyn_relocs != NULL
-+ && h->root.type == bfd_link_hash_undefweak)
-+ {
-+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
-+ eh->dyn_relocs = NULL;
-+
-+ /* Make sure undefined weak symbols are output as a dynamic
-+ symbol in PIEs. */
-+ else if (h->dynindx == -1
-+ && !h->forced_local
-+ && !h->def_regular)
-+ {
-+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
-+ return FALSE;
-+ }
-+ }
-+ }
-+ else if (ELIMINATE_COPY_RELOCS)
-+ {
-+ /* For the non-shared case, discard space for relocs against
-+ symbols which turn out to need copy relocs or are not
-+ dynamic. */
-+
-+ if (!h->non_got_ref
-+ && !h->def_regular)
-+ {
-+ /* Make sure this symbol is output as a dynamic symbol.
-+ Undefined weak syms won't yet be marked as dynamic. */
-+ if (h->dynindx == -1
-+ && !h->forced_local)
-+ {
-+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
-+ return FALSE;
-+ }
-+
-+ /* If that succeeded, we know we'll be keeping all the
-+ relocs. */
-+ if (h->dynindx != -1)
-+ goto keep;
-+ }
-+
-+ eh->dyn_relocs = NULL;
-+
-+ keep: ;
-+ }
-+
-+ /* Finally, allocate space. */
-+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
-+ {
-+ asection *sreloc = elf_section_data (p->sec)->sreloc;
-+ if (!htab->elf.dynamic_sections_created)
-+ sreloc = htab->reliplt;
-+ sreloc->size += p->count * sizeof (Elf32_External_Rela);
-+ }
-+
-+ return TRUE;
-+}
-+
-+/* Set DF_TEXTREL if we find any dynamic relocs that apply to
-+ read-only sections. */
-+
-+static bfd_boolean
-+maybe_set_textrel (struct elf_link_hash_entry *h, void *info)
-+{
-+ if (h->root.type == bfd_link_hash_indirect)
-+ return TRUE;
-+
-+ if (readonly_dynrelocs (h))
-+ {
-+ ((struct bfd_link_info *) info)->flags |= DF_TEXTREL;
-+
-+ /* Not an error, just cut short the traversal. */
-+ return FALSE;
-+ }
-+ return TRUE;
-+}
-+
-+static const unsigned char glink_eh_frame_cie[] =
-+{
-+ 0, 0, 0, 16, /* length. */
-+ 0, 0, 0, 0, /* id. */
-+ 1, /* CIE version. */
-+ 'z', 'R', 0, /* Augmentation string. */
-+ 4, /* Code alignment. */
-+ 0x7c, /* Data alignment. */
-+ 65, /* RA reg. */
-+ 1, /* Augmentation size. */
-+ DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding. */
-+ DW_CFA_def_cfa, 1, 0 /* def_cfa: r1 offset 0. */
-+};
-+
-+/* Set the sizes of the dynamic sections. */
-+
-+static bfd_boolean
-+ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
-+ struct bfd_link_info *info)
-+{
-+ struct ppc_elf_link_hash_table *htab;
-+ asection *s;
-+ bfd_boolean relocs;
-+ bfd *ibfd;
-+
-+#ifdef DEBUG
-+ fprintf (stderr, "ppc_elf_size_dynamic_sections called\n");
-+#endif
-+
-+ htab = ppc_elf_hash_table (info);
-+ BFD_ASSERT (htab->elf.dynobj != NULL);
-+
-+#ifdef DEBUG
-+ fprintf (stderr, "ppc_elf_size_dynamic_sections: dynamic_sections_created = %d\n", elf_hash_table (info)->dynamic_sections_created);
-+#endif
-+
-+ if (elf_hash_table (info)->dynamic_sections_created)
-+ {
-+ /* Set the contents of the .interp section to the interpreter. */
-+ if (info->executable)
-+ {
-+ s = bfd_get_linker_section (htab->elf.dynobj, ".interp");
-+ BFD_ASSERT (s != NULL);
-+ s->size = sizeof ELF_DYNAMIC_INTERPRETER;
-+ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
-+ }
-+ }
-+
-+ if (htab->plt_type == PLT_OLD)
-+ htab->got_header_size = 16;
-+ else if (htab->plt_type == PLT_NEW)
-+ htab->got_header_size = 12;
-+
-+ /* Set up .got offsets for local syms, and space for local dynamic
-+ relocs. */
-+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
-+ {
-+ bfd_signed_vma *local_got;
-+ bfd_signed_vma *end_local_got;
-+ struct plt_entry **local_plt;
-+ struct plt_entry **end_local_plt;
-+ char *lgot_masks;
-+ bfd_size_type locsymcount;
-+ Elf_Internal_Shdr *symtab_hdr;
-+
-+#ifdef DEBUG
-+ fprintf (stderr, "ppc_elf_size_dynamic_sections: is_ppc_elf() = %d (flavour = %d)\n", is_ppc_elf (ibfd), bfd_get_flavour (ibfd));
-+#endif
-+
-+ if (!is_ppc_elf (ibfd))
-+ continue;
-+
-+ for (s = ibfd->sections; s != NULL; s = s->next)
-+ {
-+ struct elf_dyn_relocs *p;
-+
-+ for (p = ((struct elf_dyn_relocs *)
-+ elf_section_data (s)->local_dynrel);
-+ p != NULL;
-+ p = p->next)
-+ {
-+ if (!bfd_is_abs_section (p->sec)
-+ && bfd_is_abs_section (p->sec->output_section))
-+ {
-+ /* Input section has been discarded, either because
-+ it is a copy of a linkonce section or due to
-+ linker script /DISCARD/, so we'll be discarding
-+ the relocs too. */
-+ }
-+ else if (htab->is_vxworks
-+ && strcmp (p->sec->output_section->name,
-+ ".tls_vars") == 0)
-+ {
-+ /* Relocations in vxworks .tls_vars sections are
-+ handled specially by the loader. */
-+ }
-+ else if (p->count != 0)
-+ {
-+ asection *sreloc = elf_section_data (p->sec)->sreloc;
-+ if (!htab->elf.dynamic_sections_created)
-+ sreloc = htab->reliplt;
-+ sreloc->size += p->count * sizeof (Elf32_External_Rela);
-+ if ((p->sec->output_section->flags
-+ & (SEC_READONLY | SEC_ALLOC))
-+ == (SEC_READONLY | SEC_ALLOC))
-+ info->flags |= DF_TEXTREL;
-+ }
-+ }
-+ }
-+
-+ local_got = elf_local_got_refcounts (ibfd);
-+ if (!local_got)
-+ continue;
-+
-+ symtab_hdr = &elf_symtab_hdr (ibfd);
-+ locsymcount = symtab_hdr->sh_info;
-+ end_local_got = local_got + locsymcount;
-+ local_plt = (struct plt_entry **) end_local_got;
-+ end_local_plt = local_plt + locsymcount;
-+ lgot_masks = (char *) end_local_plt;
-+
-+ for (; local_got < end_local_got; ++local_got, ++lgot_masks)
-+ if (*local_got > 0)
-+ {
-+ unsigned int need = 0;
-+ if ((*lgot_masks & TLS_TLS) != 0)
-+ {
-+ if ((*lgot_masks & TLS_GD) != 0)
-+ need += 8;
-+ if ((*lgot_masks & TLS_LD) != 0)
-+ htab->tlsld_got.refcount += 1;
-+ if ((*lgot_masks & (TLS_TPREL | TLS_TPRELGD)) != 0)
-+ need += 4;
-+ if ((*lgot_masks & TLS_DTPREL) != 0)
-+ need += 4;
-+ }
-+ else
-+ need += 4;
-+ if (need == 0)
-+ *local_got = (bfd_vma) -1;
-+ else
-+ {
-+ *local_got = allocate_got (htab, need);
-+ if (info->shared)
-+ htab->relgot->size += (need
-+ * (sizeof (Elf32_External_Rela) / 4));
-+ }
-+ }
-+ else
-+ *local_got = (bfd_vma) -1;
-+
-+ if (htab->is_vxworks)
-+ continue;
-+
-+ /* Allocate space for calls to local STT_GNU_IFUNC syms in .iplt. */
-+ for (; local_plt < end_local_plt; ++local_plt)
-+ {
-+ struct plt_entry *ent;
-+ bfd_boolean doneone = FALSE;
-+ bfd_vma plt_offset = 0, glink_offset = 0;
-+
-+ for (ent = *local_plt; ent != NULL; ent = ent->next)
-+ if (ent->plt.refcount > 0)
-+ {
-+ s = htab->iplt;
-+
-+ if (!doneone)
-+ {
-+ plt_offset = s->size;
-+ s->size += 4;
-+ }
-+ ent->plt.offset = plt_offset;
-+
-+ s = htab->glink;
-+ if (!doneone || info->shared)
-+ {
-+ glink_offset = s->size;
-+ s->size += GLINK_ENTRY_SIZE;
-+ }
-+ ent->glink_offset = glink_offset;
-+
-+ if (!doneone)
-+ {
-+ htab->reliplt->size += sizeof (Elf32_External_Rela);
-+ doneone = TRUE;
-+ }
-+ }
-+ else
-+ ent->plt.offset = (bfd_vma) -1;
-+ }
-+ }
-+
-+ /* Allocate space for global sym dynamic relocs. */
-+ elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info);
-+
-+ if (htab->tlsld_got.refcount > 0)
-+ {
-+ htab->tlsld_got.offset = allocate_got (htab, 8);
-+ if (info->shared)
-+ htab->relgot->size += sizeof (Elf32_External_Rela);
-+ }
-+ else
-+ htab->tlsld_got.offset = (bfd_vma) -1;
-+
-+ if (htab->got != NULL && htab->plt_type != PLT_VXWORKS)
-+ {
-+ unsigned int g_o_t = 32768;
-+
-+ /* If we haven't allocated the header, do so now. When we get here,
-+ for old plt/got the got size will be 0 to 32764 (not allocated),
-+ or 32780 to 65536 (header allocated). For new plt/got, the
-+ corresponding ranges are 0 to 32768 and 32780 to 65536. */
-+ if (htab->got->size <= 32768)
-+ {
-+ g_o_t = htab->got->size;
-+ if (htab->plt_type == PLT_OLD)
-+ g_o_t += 4;
-+ htab->got->size += htab->got_header_size;
-+ }
-+
-+ htab->elf.hgot->root.u.def.value = g_o_t;
-+ }
-+ if (info->shared)
-+ {
-+ struct elf_link_hash_entry *sda = htab->sdata[0].sym;
-+ if (sda != NULL
-+ && !(sda->root.type == bfd_link_hash_defined
-+ || sda->root.type == bfd_link_hash_defweak))
-+ {
-+ sda->root.type = bfd_link_hash_defined;
-+ sda->root.u.def.section = htab->elf.hgot->root.u.def.section;
-+ sda->root.u.def.value = htab->elf.hgot->root.u.def.value;
-+ }
-+ }
-+
-+ if (htab->glink != NULL
-+ && htab->glink->size != 0
-+ && htab->elf.dynamic_sections_created)
-+ {
-+ htab->glink_pltresolve = htab->glink->size;
-+ /* Space for the branch table. */
-+ htab->glink->size += htab->glink->size / (GLINK_ENTRY_SIZE / 4) - 4;
-+ /* Pad out to align the start of PLTresolve. */
-+ htab->glink->size += -htab->glink->size & 15;
-+ htab->glink->size += GLINK_PLTRESOLVE;
-+
-+ if (htab->emit_stub_syms)
-+ {
-+ struct elf_link_hash_entry *sh;
-+ sh = elf_link_hash_lookup (&htab->elf, "__glink",
-+ TRUE, FALSE, FALSE);
-+ if (sh == NULL)
-+ return FALSE;
-+ if (sh->root.type == bfd_link_hash_new)
-+ {
-+ sh->root.type = bfd_link_hash_defined;
-+ sh->root.u.def.section = htab->glink;
-+ sh->root.u.def.value = htab->glink_pltresolve;
-+ sh->ref_regular = 1;
-+ sh->def_regular = 1;
-+ sh->ref_regular_nonweak = 1;
-+ sh->forced_local = 1;
-+ sh->non_elf = 0;
-+ }
-+ sh = elf_link_hash_lookup (&htab->elf, "__glink_PLTresolve",
-+ TRUE, FALSE, FALSE);
-+ if (sh == NULL)
-+ return FALSE;
-+ if (sh->root.type == bfd_link_hash_new)
-+ {
-+ sh->root.type = bfd_link_hash_defined;
-+ sh->root.u.def.section = htab->glink;
-+ sh->root.u.def.value = htab->glink->size - GLINK_PLTRESOLVE;
-+ sh->ref_regular = 1;
-+ sh->def_regular = 1;
-+ sh->ref_regular_nonweak = 1;
-+ sh->forced_local = 1;
-+ sh->non_elf = 0;
-+ }
-+ }
-+ }
-+
-+ if (htab->glink != NULL
-+ && htab->glink->size != 0
-+ && htab->glink_eh_frame != NULL
-+ && !bfd_is_abs_section (htab->glink_eh_frame->output_section)
-+ && _bfd_elf_eh_frame_present (info))
-+ {
-+ s = htab->glink_eh_frame;
-+ s->size = sizeof (glink_eh_frame_cie) + 20;
-+ if (info->shared)
-+ {
-+ s->size += 4;
-+ if (htab->glink->size - GLINK_PLTRESOLVE + 8 >= 256)
-+ s->size += 4;
-+ }
-+ }
-+
-+ /* We've now determined the sizes of the various dynamic sections.
-+ Allocate memory for them. */
-+ relocs = FALSE;
-+ for (s = htab->elf.dynobj->sections; s != NULL; s = s->next)
-+ {
-+ bfd_boolean strip_section = TRUE;
-+
-+ if ((s->flags & SEC_LINKER_CREATED) == 0)
-+ continue;
-+
-+ if (s == htab->plt
-+ || s == htab->got)
-+ {
-+ /* We'd like to strip these sections if they aren't needed, but if
-+ we've exported dynamic symbols from them we must leave them.
-+ It's too late to tell BFD to get rid of the symbols. */
-+ if (htab->elf.hplt != NULL)
-+ strip_section = FALSE;
-+ /* Strip this section if we don't need it; see the
-+ comment below. */
-+ }
-+ else if (s == htab->iplt
-+ || s == htab->glink
-+ || s == htab->glink_eh_frame
-+ || s == htab->sgotplt
-+ || s == htab->sbss
-+ || s == htab->dynbss
-+ || s == htab->dynsbss
-+ || s == htab->sdata[0].section
-+ || s == htab->sdata[1].section)
-+ {
-+ /* Strip these too. */
-+ }
-+ else if (CONST_STRNEQ (bfd_get_section_name (htab->elf.dynobj, s),
-+ ".rela"))
-+ {
-+ if (s->size != 0)
-+ {
-+ /* Remember whether there are any relocation sections. */
-+ relocs = TRUE;
-+
-+ /* We use the reloc_count field as a counter if we need
-+ to copy relocs into the output file. */
-+ s->reloc_count = 0;
-+ }
-+ }
-+ else
-+ {
-+ /* It's not one of our sections, so don't allocate space. */
-+ continue;
-+ }
-+
-+ if (s->size == 0 && strip_section)
-+ {
-+ /* If we don't need this section, strip it from the
-+ output file. This is mostly to handle .rela.bss and
-+ .rela.plt. We must create both sections in
-+ create_dynamic_sections, because they must be created
-+ before the linker maps input sections to output
-+ sections. The linker does that before
-+ adjust_dynamic_symbol is called, and it is that
-+ function which decides whether anything needs to go
-+ into these sections. */
-+ s->flags |= SEC_EXCLUDE;
-+ continue;
-+ }
-+
-+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
-+ continue;
-+
-+ /* Allocate memory for the section contents. */
-+ s->contents = bfd_zalloc (htab->elf.dynobj, s->size);
-+ if (s->contents == NULL)
-+ return FALSE;
-+ }
-+
-+ if (htab->elf.dynamic_sections_created)
-+ {
-+ /* Add some entries to the .dynamic section. We fill in the
-+ values later, in ppc_elf_finish_dynamic_sections, but we
-+ must add the entries now so that we get the correct size for
-+ the .dynamic section. The DT_DEBUG entry is filled in by the
-+ dynamic linker and used by the debugger. */
-+#define add_dynamic_entry(TAG, VAL) \
-+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
-+
-+ if (info->executable)
-+ {
-+ if (!add_dynamic_entry (DT_DEBUG, 0))
-+ return FALSE;
-+ }
-+
-+ if (htab->plt != NULL && htab->plt->size != 0)
-+ {
-+ if (!add_dynamic_entry (DT_PLTGOT, 0)
-+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
-+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
-+ || !add_dynamic_entry (DT_JMPREL, 0))
-+ return FALSE;
-+ }
-+
-+ if (htab->glink != NULL && htab->glink->size != 0)
-+ {
-+ if (!add_dynamic_entry (DT_PPC_GOT, 0))
-+ return FALSE;
-+ if (!htab->no_tls_get_addr_opt
-+ && htab->tls_get_addr != NULL
-+ && htab->tls_get_addr->plt.plist != NULL
-+ && !add_dynamic_entry (DT_PPC_TLSOPT, 0))
-+ return FALSE;
-+ }
-+
-+ if (relocs)
-+ {
-+ if (!add_dynamic_entry (DT_RELA, 0)
-+ || !add_dynamic_entry (DT_RELASZ, 0)
-+ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
-+ return FALSE;
-+ }
-+
-+ /* If any dynamic relocs apply to a read-only section, then we
-+ need a DT_TEXTREL entry. */
-+ if ((info->flags & DF_TEXTREL) == 0)
-+ elf_link_hash_traverse (elf_hash_table (info), maybe_set_textrel,
-+ info);
-+
-+ if ((info->flags & DF_TEXTREL) != 0)
-+ {
-+ if (!add_dynamic_entry (DT_TEXTREL, 0))
-+ return FALSE;
-+ }
-+ if (htab->is_vxworks
-+ && !elf_vxworks_add_dynamic_entries (output_bfd, info))
-+ return FALSE;
-+
-+ /* Flag it as a version 2 dynamic binary */
-+ if (!add_dynamic_entry(DT_AMIGAOS_DYNVERSION, 2))
-+ return FALSE;
-+ }
-+#undef add_dynamic_entry
-+
-+ if (htab->glink_eh_frame != NULL
-+ && htab->glink_eh_frame->contents != NULL)
-+ {
-+ unsigned char *p = htab->glink_eh_frame->contents;
-+ bfd_vma val;
-+
-+ memcpy (p, glink_eh_frame_cie, sizeof (glink_eh_frame_cie));
-+ /* CIE length (rewrite in case little-endian). */
-+ bfd_put_32 (htab->elf.dynobj, sizeof (glink_eh_frame_cie) - 4, p);
-+ p += sizeof (glink_eh_frame_cie);
-+ /* FDE length. */
-+ val = htab->glink_eh_frame->size - 4 - sizeof (glink_eh_frame_cie);
-+ bfd_put_32 (htab->elf.dynobj, val, p);
-+ p += 4;
-+ /* CIE pointer. */
-+ val = p - htab->glink_eh_frame->contents;
-+ bfd_put_32 (htab->elf.dynobj, val, p);
-+ p += 4;
-+ /* Offset to .glink. Set later. */
-+ p += 4;
-+ /* .glink size. */
-+ bfd_put_32 (htab->elf.dynobj, htab->glink->size, p);
-+ p += 4;
-+ /* Augmentation. */
-+ p += 1;
-+
-+ if (info->shared
-+ && htab->elf.dynamic_sections_created)
-+ {
-+ bfd_vma adv = (htab->glink->size - GLINK_PLTRESOLVE + 8) >> 2;
-+ if (adv < 64)
-+ *p++ = DW_CFA_advance_loc + adv;
-+ else if (adv < 256)
-+ {
-+ *p++ = DW_CFA_advance_loc1;
-+ *p++ = adv;
-+ }
-+ else if (adv < 65536)
-+ {
-+ *p++ = DW_CFA_advance_loc2;
-+ bfd_put_16 (htab->elf.dynobj, adv, p);
-+ p += 2;
-+ }
-+ else
-+ {
-+ *p++ = DW_CFA_advance_loc4;
-+ bfd_put_32 (htab->elf.dynobj, adv, p);
-+ p += 4;
-+ }
-+ *p++ = DW_CFA_register;
-+ *p++ = 65;
-+ p++;
-+ *p++ = DW_CFA_advance_loc + 4;
-+ *p++ = DW_CFA_restore_extended;
-+ *p++ = 65;
-+ }
-+ BFD_ASSERT ((bfd_vma) ((p + 3 - htab->glink_eh_frame->contents) & -4)
-+ == htab->glink_eh_frame->size);
-+ }
-+
-+ return TRUE;
-+}
-+
-+/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */
-+
-+static bfd_boolean
-+ppc_elf_hash_symbol (struct elf_link_hash_entry *h)
-+{
-+ if (h->plt.plist != NULL
-+ && !h->def_regular
-+ && (!h->pointer_equality_needed
-+ || !h->ref_regular_nonweak))
-+ return FALSE;
-+
-+ return _bfd_elf_hash_symbol (h);
-+}
-+
-+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
-+
-+/* Relaxation trampolines. r12 is available for clobbering (r11, is
-+ used for some functions that are allowed to break the ABI). */
-+static const int shared_stub_entry[] =
-+ {
-+ 0x7c0802a6, /* mflr 0 */
-+ 0x429f0005, /* bcl 20, 31, .Lxxx */
-+ 0x7d8802a6, /* mflr 12 */
-+ 0x3d8c0000, /* addis 12, 12, (xxx-.Lxxx)@ha */
-+ 0x398c0008, /* addi 12, 12, (xxx-.Lxxx)@l */
-+ 0x7c0803a6, /* mtlr 0 */
-+ 0x7d8903a6, /* mtctr 12 */
-+ 0x4e800420, /* bctr */
-+ };
-+
-+static const int stub_entry[] =
-+ {
-+ 0x3d800000, /* lis 12,xxx@ha */
-+ 0x398c0000, /* addi 12,12,xxx@l */
-+ 0x7d8903a6, /* mtctr 12 */
-+ 0x4e800420, /* bctr */
-+ };
-+
-+static bfd_boolean
-+ppc_elf_relax_section (bfd *abfd,
-+ asection *isec,
-+ struct bfd_link_info *link_info,
-+ bfd_boolean *again)
-+{
-+ struct one_fixup
-+ {
-+ struct one_fixup *next;
-+ asection *tsec;
-+ /* Final link, can use the symbol offset. For a
-+ relocatable link we use the symbol's index. */
-+ bfd_vma toff;
-+ bfd_vma trampoff;
-+ };
-+
-+ Elf_Internal_Shdr *symtab_hdr;
-+ bfd_byte *contents = NULL;
-+ Elf_Internal_Sym *isymbuf = NULL;
-+ Elf_Internal_Rela *internal_relocs = NULL;
-+ Elf_Internal_Rela *irel, *irelend;
-+ struct one_fixup *fixups = NULL;
-+ unsigned changes = 0;
-+ struct ppc_elf_link_hash_table *htab;
-+ bfd_size_type trampoff;
-+ asection *got2;
-+ bfd_boolean maybe_pasted;
-+
-+ *again = FALSE;
-+
-+ /* Nothing to do if there are no relocations, and no need to do
-+ anything with non-alloc or non-code sections. */
-+ if ((isec->flags & SEC_ALLOC) == 0
-+ || (isec->flags & SEC_CODE) == 0
-+ || (isec->flags & SEC_RELOC) == 0
-+ || isec->reloc_count == 0)
-+ return TRUE;
-+
-+ /* We cannot represent the required PIC relocs in the output, so don't
-+ do anything. The linker doesn't support mixing -shared and -r
-+ anyway. */
-+ if (link_info->relocatable && link_info->shared)
-+ return TRUE;
-+
-+ trampoff = (isec->size + 3) & (bfd_vma) -4;
-+ maybe_pasted = (strcmp (isec->output_section->name, ".init") == 0
-+ || strcmp (isec->output_section->name, ".fini") == 0);
-+ /* Space for a branch around any trampolines. */
-+ if (maybe_pasted)
-+ trampoff += 4;
-+
-+ symtab_hdr = &elf_symtab_hdr (abfd);
-+
-+ /* Get a copy of the native relocations. */
-+ internal_relocs = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL,
-+ link_info->keep_memory);
-+ if (internal_relocs == NULL)
-+ goto error_return;
-+
-+ htab = ppc_elf_hash_table (link_info);
-+ got2 = bfd_get_section_by_name (abfd, ".got2");
-+
-+ irelend = internal_relocs + isec->reloc_count;
-+ for (irel = internal_relocs; irel < irelend; irel++)
-+ {
-+ unsigned long r_type = ELF32_R_TYPE (irel->r_info);
-+ bfd_vma toff, roff;
-+ asection *tsec;
-+ struct one_fixup *f;
-+ size_t insn_offset = 0;
-+ bfd_vma max_branch_offset, val;
-+ bfd_byte *hit_addr;
-+ unsigned long t0;
-+ struct elf_link_hash_entry *h;
-+ struct plt_entry **plist;
-+ unsigned char sym_type;
-+
-+ switch (r_type)
-+ {
-+ case R_PPC_REL24:
-+ case R_PPC_LOCAL24PC:
-+ case R_PPC_PLTREL24:
-+ max_branch_offset = 1 << 25;
-+ break;
-+
-+ case R_PPC_REL14:
-+ case R_PPC_REL14_BRTAKEN:
-+ case R_PPC_REL14_BRNTAKEN:
-+ max_branch_offset = 1 << 15;
-+ break;
-+
-+ default:
-+ continue;
-+ }
-+
-+ /* Get the value of the symbol referred to by the reloc. */
-+ h = NULL;
-+ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
-+ {
-+ /* A local symbol. */
-+ Elf_Internal_Sym *isym;
-+
-+ /* Read this BFD's local symbols. */
-+ if (isymbuf == NULL)
-+ {
-+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
-+ if (isymbuf == NULL)
-+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
-+ symtab_hdr->sh_info, 0,
-+ NULL, NULL, NULL);
-+ if (isymbuf == 0)
-+ goto error_return;
-+ }
-+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
-+ if (isym->st_shndx == SHN_UNDEF)
-+ tsec = bfd_und_section_ptr;
-+ else if (isym->st_shndx == SHN_ABS)
-+ tsec = bfd_abs_section_ptr;
-+ else if (isym->st_shndx == SHN_COMMON)
-+ tsec = bfd_com_section_ptr;
-+ else
-+ tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
-+
-+ toff = isym->st_value;
-+ sym_type = ELF_ST_TYPE (isym->st_info);
-+ }
-+ else
-+ {
-+ /* Global symbol handling. */
-+ unsigned long indx;
-+
-+ indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
-+ h = elf_sym_hashes (abfd)[indx];
-+
-+ while (h->root.type == bfd_link_hash_indirect
-+ || h->root.type == bfd_link_hash_warning)
-+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
-+
-+ if (h->root.type == bfd_link_hash_defined
-+ || h->root.type == bfd_link_hash_defweak)
-+ {
-+ tsec = h->root.u.def.section;
-+ toff = h->root.u.def.value;
-+ }
-+ else if (h->root.type == bfd_link_hash_undefined
-+ || h->root.type == bfd_link_hash_undefweak)
-+ {
-+ tsec = bfd_und_section_ptr;
-+ toff = link_info->relocatable ? indx : 0;
-+ }
-+ else
-+ continue;
-+
-+ sym_type = h->type;
-+ }
-+
-+ /* The condition here under which we call find_plt_ent must
-+ match that in relocate_section. If we call find_plt_ent here
-+ but not in relocate_section, or vice versa, then the branch
-+ destination used here may be incorrect. */
-+ plist = NULL;
-+ if (h != NULL)
-+ {
-+ /* We know is_branch_reloc (r_type) is true. */
-+ if (h->type == STT_GNU_IFUNC
-+ || r_type == R_PPC_PLTREL24)
-+ plist = &h->plt.plist;
-+ }
-+ else if (sym_type == STT_GNU_IFUNC
-+ && elf_local_got_offsets (abfd) != NULL)
-+ {
-+ bfd_vma *local_got_offsets = elf_local_got_offsets (abfd);
-+ struct plt_entry **local_plt = (struct plt_entry **)
-+ (local_got_offsets + symtab_hdr->sh_info);
-+ plist = local_plt + ELF32_R_SYM (irel->r_info);
-+ }
-+ if (plist != NULL)
-+ {
-+ bfd_vma addend = 0;
-+ struct plt_entry *ent;
-+
-+ if (r_type == R_PPC_PLTREL24 && link_info->shared)
-+ addend = irel->r_addend;
-+ ent = find_plt_ent (plist, got2, addend);
-+ if (ent != NULL)
-+ {
-+ if (htab->plt_type == PLT_NEW
-+ || h == NULL
-+ || !htab->elf.dynamic_sections_created
-+ || h->dynindx == -1)
-+ {
-+ tsec = htab->glink;
-+ toff = ent->glink_offset;
-+ }
-+ else
-+ {
-+ tsec = htab->plt;
-+ toff = ent->plt.offset;
-+ }
-+ }
-+ }
-+
-+ /* If the branch and target are in the same section, you have
-+ no hope of adding stubs. We'll error out later should the
-+ branch overflow. */
-+ if (tsec == isec)
-+ continue;
-+
-+ /* There probably isn't any reason to handle symbols in
-+ SEC_MERGE sections; SEC_MERGE doesn't seem a likely
-+ attribute for a code section, and we are only looking at
-+ branches. However, implement it correctly here as a
-+ reference for other target relax_section functions. */
-+ if (0 && tsec->sec_info_type == SEC_INFO_TYPE_MERGE)
-+ {
-+ /* At this stage in linking, no SEC_MERGE symbol has been
-+ adjusted, so all references to such symbols need to be
-+ passed through _bfd_merged_section_offset. (Later, in
-+ relocate_section, all SEC_MERGE symbols *except* for
-+ section symbols have been adjusted.)
-+
-+ gas may reduce relocations against symbols in SEC_MERGE
-+ sections to a relocation against the section symbol when
-+ the original addend was zero. When the reloc is against
-+ a section symbol we should include the addend in the
-+ offset passed to _bfd_merged_section_offset, since the
-+ location of interest is the original symbol. On the
-+ other hand, an access to "sym+addend" where "sym" is not
-+ a section symbol should not include the addend; Such an
-+ access is presumed to be an offset from "sym"; The
-+ location of interest is just "sym". */
-+ if (sym_type == STT_SECTION)
-+ toff += irel->r_addend;
-+
-+ toff = _bfd_merged_section_offset (abfd, &tsec,
-+ elf_section_data (tsec)->sec_info,
-+ toff);
-+
-+ if (sym_type != STT_SECTION)
-+ toff += irel->r_addend;
-+ }
-+ /* PLTREL24 addends are special. */
-+ else if (r_type != R_PPC_PLTREL24)
-+ toff += irel->r_addend;
-+
-+ /* Attempted -shared link of non-pic code loses. */
-+ if (tsec->output_section == NULL)
-+ continue;
-+
-+ roff = irel->r_offset;
-+
-+ /* If the branch is in range, no need to do anything. */
-+ if (tsec != bfd_und_section_ptr
-+ && (!link_info->relocatable
-+ /* A relocatable link may have sections moved during
-+ final link, so do not presume they remain in range. */
-+ || tsec->output_section == isec->output_section))
-+ {
-+ bfd_vma symaddr, reladdr;
-+
-+ symaddr = tsec->output_section->vma + tsec->output_offset + toff;
-+ reladdr = isec->output_section->vma + isec->output_offset + roff;
-+ if (symaddr - reladdr + max_branch_offset < 2 * max_branch_offset)
-+ continue;
-+ }
-+
-+ /* Look for an existing fixup to this address. */
-+ for (f = fixups; f ; f = f->next)
-+ if (f->tsec == tsec && f->toff == toff)
-+ break;
-+
-+ if (f == NULL)
-+ {
-+ size_t size;
-+ unsigned long stub_rtype;
-+
-+ val = trampoff - roff;
-+ if (val >= max_branch_offset)
-+ /* Oh dear, we can't reach a trampoline. Don't try to add
-+ one. We'll report an error later. */
-+ continue;
-+
-+ if (link_info->shared)
-+ {
-+ size = 4 * ARRAY_SIZE (shared_stub_entry);
-+ insn_offset = 12;
-+ }
-+ else
-+ {
-+ size = 4 * ARRAY_SIZE (stub_entry);
-+ insn_offset = 0;
-+ }
-+ stub_rtype = R_PPC_RELAX;
-+ if (tsec == htab->plt
-+ || tsec == htab->glink)
-+ {
-+ stub_rtype = R_PPC_RELAX_PLT;
-+ if (r_type == R_PPC_PLTREL24)
-+ stub_rtype = R_PPC_RELAX_PLTREL24;
-+ }
-+
-+ /* Hijack the old relocation. Since we need two
-+ relocations for this use a "composite" reloc. */
-+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
-+ stub_rtype);
-+ irel->r_offset = trampoff + insn_offset;
-+ if (r_type == R_PPC_PLTREL24
-+ && stub_rtype != R_PPC_RELAX_PLTREL24)
-+ irel->r_addend = 0;
-+
-+ /* Record the fixup so we don't do it again this section. */
-+ f = bfd_malloc (sizeof (*f));
-+ f->next = fixups;
-+ f->tsec = tsec;
-+ f->toff = toff;
-+ f->trampoff = trampoff;
-+ fixups = f;
-+
-+ trampoff += size;
-+ changes++;
-+ }
-+ else
-+ {
-+ val = f->trampoff - roff;
-+ if (val >= max_branch_offset)
-+ continue;
-+
-+ /* Nop out the reloc, since we're finalizing things here. */
-+ irel->r_info = ELF32_R_INFO (0, R_PPC_NONE);
-+ }
-+
-+ /* Get the section contents. */
-+ if (contents == NULL)
-+ {
-+ /* Get cached copy if it exists. */
-+ if (elf_section_data (isec)->this_hdr.contents != NULL)
-+ contents = elf_section_data (isec)->this_hdr.contents;
-+ else
-+ {
-+ /* Go get them off disk. */
-+ if (!bfd_malloc_and_get_section (abfd, isec, &contents))
-+ goto error_return;
-+ }
-+ }
-+
-+ /* Fix up the existing branch to hit the trampoline. */
-+ hit_addr = contents + roff;
-+ switch (r_type)
-+ {
-+ case R_PPC_REL24:
-+ case R_PPC_LOCAL24PC:
-+ case R_PPC_PLTREL24:
-+ t0 = bfd_get_32 (abfd, hit_addr);
-+ t0 &= ~0x3fffffc;
-+ t0 |= val & 0x3fffffc;
-+ bfd_put_32 (abfd, t0, hit_addr);
-+ break;
-+
-+ case R_PPC_REL14:
-+ case R_PPC_REL14_BRTAKEN:
-+ case R_PPC_REL14_BRNTAKEN:
-+ t0 = bfd_get_32 (abfd, hit_addr);
-+ t0 &= ~0xfffc;
-+ t0 |= val & 0xfffc;
-+ bfd_put_32 (abfd, t0, hit_addr);
-+ break;
-+ }
-+ }
-+
-+ /* Write out the trampolines. */
-+ if (fixups != NULL)
-+ {
-+ const int *stub;
-+ bfd_byte *dest;
-+ int i, size;
-+
-+ do
-+ {
-+ struct one_fixup *f = fixups;
-+ fixups = fixups->next;
-+ free (f);
-+ }
-+ while (fixups);
-+
-+ contents = bfd_realloc_or_free (contents, trampoff);
-+ if (contents == NULL)
-+ goto error_return;
-+
-+ isec->size = (isec->size + 3) & (bfd_vma) -4;
-+ dest = contents + isec->size;
-+ /* Branch around the trampolines. */
-+ if (maybe_pasted)
-+ {
-+ bfd_vma val = B + trampoff - isec->size;
-+ bfd_put_32 (abfd, val, dest);
-+ dest += 4;
-+ }
-+ isec->size = trampoff;
-+
-+ if (link_info->shared)
-+ {
-+ stub = shared_stub_entry;
-+ size = ARRAY_SIZE (shared_stub_entry);
-+ }
-+ else
-+ {
-+ stub = stub_entry;
-+ size = ARRAY_SIZE (stub_entry);
-+ }
-+
-+ i = 0;
-+ while (dest < contents + trampoff)
-+ {
-+ bfd_put_32 (abfd, stub[i], dest);
-+ i++;
-+ if (i == size)
-+ i = 0;
-+ dest += 4;
-+ }
-+ BFD_ASSERT (i == 0);
-+ }
-+
-+ if (isymbuf != NULL
-+ && symtab_hdr->contents != (unsigned char *) isymbuf)
-+ {
-+ if (! link_info->keep_memory)
-+ free (isymbuf);
-+ else
-+ {
-+ /* Cache the symbols for elf_link_input_bfd. */
-+ symtab_hdr->contents = (unsigned char *) isymbuf;
-+ }
-+ }
-+
-+ if (contents != NULL
-+ && elf_section_data (isec)->this_hdr.contents != contents)
-+ {
-+ if (!changes && !link_info->keep_memory)
-+ free (contents);
-+ else
-+ {
-+ /* Cache the section contents for elf_link_input_bfd. */
-+ elf_section_data (isec)->this_hdr.contents = contents;
-+ }
-+ }
-+
-+ if (changes != 0)
-+ {
-+ /* Append sufficient NOP relocs so we can write out relocation
-+ information for the trampolines. */
-+ Elf_Internal_Shdr *rel_hdr;
-+ Elf_Internal_Rela *new_relocs = bfd_malloc ((changes + isec->reloc_count)
-+ * sizeof (*new_relocs));
-+ unsigned ix;
-+
-+ if (!new_relocs)
-+ goto error_return;
-+ memcpy (new_relocs, internal_relocs,
-+ isec->reloc_count * sizeof (*new_relocs));
-+ for (ix = changes; ix--;)
-+ {
-+ irel = new_relocs + ix + isec->reloc_count;
-+
-+ irel->r_info = ELF32_R_INFO (0, R_PPC_NONE);
-+ }
-+ if (internal_relocs != elf_section_data (isec)->relocs)
-+ free (internal_relocs);
-+ elf_section_data (isec)->relocs = new_relocs;
-+ isec->reloc_count += changes;
-+ rel_hdr = _bfd_elf_single_rel_hdr (isec);
-+ rel_hdr->sh_size += changes * rel_hdr->sh_entsize;
-+ }
-+ else if (elf_section_data (isec)->relocs != internal_relocs)
-+ free (internal_relocs);
-+
-+ *again = changes != 0;
-+ if (!*again && link_info->relocatable)
-+ {
-+ /* Convert the internal relax relocs to external form. */
-+ for (irel = internal_relocs; irel < irelend; irel++)
-+ if (ELF32_R_TYPE (irel->r_info) == R_PPC_RELAX)
-+ {
-+ unsigned long r_symndx = ELF32_R_SYM (irel->r_info);
-+
-+ /* Rewrite the reloc and convert one of the trailing nop
-+ relocs to describe this relocation. */
-+ BFD_ASSERT (ELF32_R_TYPE (irelend[-1].r_info) == R_PPC_NONE);
-+ /* The relocs are at the bottom 2 bytes */
-+ irel[0].r_offset += 2;
-+ memmove (irel + 1, irel, (irelend - irel - 1) * sizeof (*irel));
-+ irel[0].r_info = ELF32_R_INFO (r_symndx, R_PPC_ADDR16_HA);
-+ irel[1].r_offset += 4;
-+ irel[1].r_info = ELF32_R_INFO (r_symndx, R_PPC_ADDR16_LO);
-+ irel++;
-+ }
-+ }
-+
-+ return TRUE;
-+
-+ error_return:
-+ if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
-+ free (isymbuf);
-+ if (contents != NULL
-+ && elf_section_data (isec)->this_hdr.contents != contents)
-+ free (contents);
-+ if (internal_relocs != NULL
-+ && elf_section_data (isec)->relocs != internal_relocs)
-+ free (internal_relocs);
-+ return FALSE;
-+}
-+
-+/* What to do when ld finds relocations against symbols defined in
-+ discarded sections. */
-+
-+static unsigned int
-+ppc_elf_action_discarded (asection *sec)
-+{
-+ if (strcmp (".fixup", sec->name) == 0)
-+ return 0;
-+
-+ if (strcmp (".got2", sec->name) == 0)
-+ return 0;
-+
-+ return _bfd_elf_default_action_discarded (sec);
-+}
-+
-+/* Fill in the address for a pointer generated in a linker section. */
-+
-+static bfd_vma
-+elf_finish_pointer_linker_section (bfd *input_bfd,
-+ elf_linker_section_t *lsect,
-+ struct elf_link_hash_entry *h,
-+ bfd_vma relocation,
-+ const Elf_Internal_Rela *rel)
-+{
-+ elf_linker_section_pointers_t *linker_section_ptr;
-+
-+ BFD_ASSERT (lsect != NULL);
-+
-+ if (h != NULL)
-+ {
-+ /* Handle global symbol. */
-+ struct ppc_elf_link_hash_entry *eh;
-+
-+ eh = (struct ppc_elf_link_hash_entry *) h;
-+ BFD_ASSERT (eh->elf.def_regular);
-+ linker_section_ptr = eh->linker_section_pointer;
-+ }
-+ else
-+ {
-+ /* Handle local symbol. */
-+ unsigned long r_symndx = ELF32_R_SYM (rel->r_info);
-+
-+ BFD_ASSERT (is_ppc_elf (input_bfd));
-+ BFD_ASSERT (elf_local_ptr_offsets (input_bfd) != NULL);
-+ linker_section_ptr = elf_local_ptr_offsets (input_bfd)[r_symndx];
-+ }
-+
-+ linker_section_ptr = elf_find_pointer_linker_section (linker_section_ptr,
-+ rel->r_addend,
-+ lsect);
-+ BFD_ASSERT (linker_section_ptr != NULL);
-+
-+ /* Offset will always be a multiple of four, so use the bottom bit
-+ as a "written" flag. */
-+ if ((linker_section_ptr->offset & 1) == 0)
-+ {
-+ bfd_put_32 (lsect->section->owner,
-+ relocation + linker_section_ptr->addend,
-+ lsect->section->contents + linker_section_ptr->offset);
-+ linker_section_ptr->offset += 1;
-+ }
-+
-+ relocation = (lsect->section->output_section->vma
-+ + lsect->section->output_offset
-+ + linker_section_ptr->offset - 1
-+ - SYM_VAL (lsect->sym));
-+
-+#ifdef DEBUG
-+ fprintf (stderr,
-+ "Finish pointer in linker section %s, offset = %ld (0x%lx)\n",
-+ lsect->name, (long) relocation, (long) relocation);
-+#endif
-+
-+ return relocation;
-+}
-+
-+#define PPC_LO(v) ((v) & 0xffff)
-+#define PPC_HI(v) (((v) >> 16) & 0xffff)
-+#define PPC_HA(v) PPC_HI ((v) + 0x8000)
-+
-+static void
-+write_glink_stub (struct plt_entry *ent, asection *plt_sec, unsigned char *p,
-+ struct bfd_link_info *info)
-+{
-+ struct ppc_elf_link_hash_table *htab = ppc_elf_hash_table (info);
-+ bfd *output_bfd = info->output_bfd;
-+ bfd_vma plt;
-+
-+ plt = ((ent->plt.offset & ~1)
-+ + plt_sec->output_section->vma
-+ + plt_sec->output_offset);
-+
-+ if (info->shared)
-+ {
-+ bfd_vma got = 0;
-+
-+ if (ent->addend >= 32768)
-+ got = (ent->addend
-+ + ent->sec->output_section->vma
-+ + ent->sec->output_offset);
-+ else if (htab->elf.hgot != NULL)
-+ got = SYM_VAL (htab->elf.hgot);
-+
-+ plt -= got;
-+
-+ if (plt + 0x8000 < 0x10000)
-+ {
-+ bfd_put_32 (output_bfd, LWZ_11_30 + PPC_LO (plt), p);
-+ p += 4;
-+ bfd_put_32 (output_bfd, MTCTR_11, p);
-+ p += 4;
-+ bfd_put_32 (output_bfd, BCTR, p);
-+ p += 4;
-+ bfd_put_32 (output_bfd, NOP, p);
-+ p += 4;
-+ }
-+ else
-+ {
-+ bfd_put_32 (output_bfd, ADDIS_11_30 + PPC_HA (plt), p);
-+ p += 4;
-+ bfd_put_32 (output_bfd, LWZ_11_11 + PPC_LO (plt), p);
-+ p += 4;
-+ bfd_put_32 (output_bfd, MTCTR_11, p);
-+ p += 4;
-+ bfd_put_32 (output_bfd, BCTR, p);
-+ p += 4;
-+ }
-+ }
-+ else
-+ {
-+ bfd_put_32 (output_bfd, LIS_11 + PPC_HA (plt), p);
-+ p += 4;
-+ bfd_put_32 (output_bfd, LWZ_11_11 + PPC_LO (plt), p);
-+ p += 4;
-+ bfd_put_32 (output_bfd, MTCTR_11, p);
-+ p += 4;
-+ bfd_put_32 (output_bfd, BCTR, p);
-+ p += 4;
-+ }
-+}
-+
-+/* Return true if symbol is defined statically. */
-+
-+static bfd_boolean
-+is_static_defined (struct elf_link_hash_entry *h)
-+{
-+ return ((h->root.type == bfd_link_hash_defined
-+ || h->root.type == bfd_link_hash_defweak)
-+ && h->root.u.def.section != NULL
-+ && h->root.u.def.section->output_section != NULL);
-+}
-+
-+/* If INSN is an opcode that may be used with an @tls operand, return
-+ the transformed insn for TLS optimisation, otherwise return 0. If
-+ REG is non-zero only match an insn with RB or RA equal to REG. */
-+
-+unsigned int
-+_bfd_elf_amigaos_ppc_at_tls_transform (unsigned int insn, unsigned int reg)
-+{
-+ unsigned int rtra;
-+
-+ if ((insn & (0x3f << 26)) != 31 << 26)
-+ return 0;
-+
-+ if (reg == 0 || ((insn >> 11) & 0x1f) == reg)
-+ rtra = insn & ((1 << 26) - (1 << 16));
-+ else if (((insn >> 16) & 0x1f) == reg)
-+ rtra = (insn & (0x1f << 21)) | ((insn & (0x1f << 11)) << 5);
-+ else
-+ return 0;
-+
-+ if ((insn & (0x3ff << 1)) == 266 << 1)
-+ /* add -> addi. */
-+ insn = 14 << 26;
-+ else if ((insn & (0x1f << 1)) == 23 << 1
-+ && ((insn & (0x1f << 6)) < 14 << 6
-+ || ((insn & (0x1f << 6)) >= 16 << 6
-+ && (insn & (0x1f << 6)) < 24 << 6)))
-+ /* load and store indexed -> dform. */
-+ insn = (32 | ((insn >> 6) & 0x1f)) << 26;
-+ else if ((insn & (((0x1a << 5) | 0x1f) << 1)) == 21 << 1)
-+ /* ldx, ldux, stdx, stdux -> ld, ldu, std, stdu. */
-+ insn = ((58 | ((insn >> 6) & 4)) << 26) | ((insn >> 6) & 1);
-+ else if ((insn & (((0x1f << 5) | 0x1f) << 1)) == 341 << 1)
-+ /* lwax -> lwa. */
-+ insn = (58 << 26) | 2;
-+ else
-+ return 0;
-+ insn |= rtra;
-+ return insn;
-+}
-+
-+/* If INSN is an opcode that may be used with an @tprel operand, return
-+ the transformed insn for an undefined weak symbol, ie. with the
-+ thread pointer REG operand removed. Otherwise return 0. */
-+
-+unsigned int
-+_bfd_elf_amigaos_ppc_at_tprel_transform (unsigned int insn, unsigned int reg)
-+{
-+ if ((insn & (0x1f << 16)) == reg << 16
-+ && ((insn & (0x3f << 26)) == 14u << 26 /* addi */
-+ || (insn & (0x3f << 26)) == 15u << 26 /* addis */
-+ || (insn & (0x3f << 26)) == 32u << 26 /* lwz */
-+ || (insn & (0x3f << 26)) == 34u << 26 /* lbz */
-+ || (insn & (0x3f << 26)) == 36u << 26 /* stw */
-+ || (insn & (0x3f << 26)) == 38u << 26 /* stb */
-+ || (insn & (0x3f << 26)) == 40u << 26 /* lhz */
-+ || (insn & (0x3f << 26)) == 42u << 26 /* lha */
-+ || (insn & (0x3f << 26)) == 44u << 26 /* sth */
-+ || (insn & (0x3f << 26)) == 46u << 26 /* lmw */
-+ || (insn & (0x3f << 26)) == 47u << 26 /* stmw */
-+ || (insn & (0x3f << 26)) == 48u << 26 /* lfs */
-+ || (insn & (0x3f << 26)) == 50u << 26 /* lfd */
-+ || (insn & (0x3f << 26)) == 52u << 26 /* stfs */
-+ || (insn & (0x3f << 26)) == 54u << 26 /* stfd */
-+ || ((insn & (0x3f << 26)) == 58u << 26 /* lwa,ld,lmd */
-+ && (insn & 3) != 1)
-+ || ((insn & (0x3f << 26)) == 62u << 26 /* std, stmd */
-+ && ((insn & 3) == 0 || (insn & 3) == 3))))
-+ {
-+ insn &= ~(0x1f << 16);
-+ }
-+ else if ((insn & (0x1f << 21)) == reg << 21
-+ && ((insn & (0x3e << 26)) == 24u << 26 /* ori, oris */
-+ || (insn & (0x3e << 26)) == 26u << 26 /* xori,xoris */
-+ || (insn & (0x3e << 26)) == 28u << 26 /* andi,andis */))
-+ {
-+ insn &= ~(0x1f << 21);
-+ insn |= (insn & (0x1f << 16)) << 5;
-+ if ((insn & (0x3e << 26)) == 26 << 26 /* xori,xoris */)
-+ insn -= 2 >> 26; /* convert to ori,oris */
-+ }
-+ else
-+ insn = 0;
-+ return insn;
-+}
-+
-+static bfd_boolean
-+is_insn_ds_form (unsigned int insn)
-+{
-+ return ((insn & (0x3f << 26)) == 58u << 26 /* ld,ldu,lwa */
-+ || (insn & (0x3f << 26)) == 62u << 26 /* std,stdu,stq */
-+ || (insn & (0x3f << 26)) == 57u << 26 /* lfdp */
-+ || (insn & (0x3f << 26)) == 61u << 26 /* stfdp */);
-+}
-+
-+static bfd_boolean
-+is_insn_dq_form (unsigned int insn)
-+{
-+ return (insn & (0x3f << 26)) == 56u << 26; /* lq */
-+}
-+
-+/* The RELOCATE_SECTION function is called by the ELF backend linker
-+ to handle the relocations for a section.
-+
-+ The relocs are always passed as Rela structures; if the section
-+ actually uses Rel structures, the r_addend field will always be
-+ zero.
-+
-+ This function is responsible for adjust the section contents as
-+ necessary, and (if using Rela relocs and generating a
-+ relocatable output file) adjusting the reloc addend as
-+ necessary.
-+
-+ This function does not have to worry about setting the reloc
-+ address or the reloc symbol index.
-+
-+ LOCAL_SYMS is a pointer to the swapped in local symbols.
-+
-+ LOCAL_SECTIONS is an array giving the section in the input file
-+ corresponding to the st_shndx field of each local symbol.
-+
-+ The global hash table entry for the global symbols can be found
-+ via elf_sym_hashes (input_bfd).
-+
-+ When generating relocatable output, this function must handle
-+ STB_LOCAL/STT_SECTION symbols specially. The output symbol is
-+ going to be the section symbol corresponding to the output
-+ section, which means that the addend must be adjusted
-+ accordingly. */
-+
-+static bfd_boolean
-+ppc_elf_relocate_section (bfd *output_bfd,
-+ struct bfd_link_info *info,
-+ bfd *input_bfd,
-+ asection *input_section,
-+ bfd_byte *contents,
-+ Elf_Internal_Rela *relocs,
-+ Elf_Internal_Sym *local_syms,
-+ asection **local_sections)
-+{
-+ Elf_Internal_Shdr *symtab_hdr;
-+ struct elf_link_hash_entry **sym_hashes;
-+ struct ppc_elf_link_hash_table *htab;
-+ Elf_Internal_Rela *rel;
-+ Elf_Internal_Rela *relend;
-+ Elf_Internal_Rela outrel;
-+ asection *got2, *sreloc = NULL;
-+ bfd_vma *local_got_offsets;
-+ bfd_boolean ret = TRUE;
-+ bfd_vma d_offset = (bfd_big_endian (output_bfd) ? 2 : 0);
-+ bfd_boolean is_vxworks_tls;
-+
-+#ifdef DEBUG
-+ _bfd_error_handler ("ppc_elf_relocate_section called for %B section %A, "
-+ "%ld relocations%s",
-+ input_bfd, input_section,
-+ (long) input_section->reloc_count,
-+ (info->relocatable) ? " (relocatable)" : "");
-+#endif
-+
-+ got2 = bfd_get_section_by_name (input_bfd, ".got2");
-+
-+ /* Initialize howto table if not already done. */
-+ if (!ppc_elf_howto_table[R_PPC_ADDR32])
-+ ppc_elf_howto_init ();
-+
-+ htab = ppc_elf_hash_table (info);
-+ local_got_offsets = elf_local_got_offsets (input_bfd);
-+ symtab_hdr = &elf_symtab_hdr (input_bfd);
-+ sym_hashes = elf_sym_hashes (input_bfd);
-+ /* We have to handle relocations in vxworks .tls_vars sections
-+ specially, because the dynamic loader is 'weird'. */
-+ is_vxworks_tls = (htab->is_vxworks && info->shared
-+ && !strcmp (input_section->output_section->name,
-+ ".tls_vars"));
-+ rel = relocs;
-+ relend = relocs + input_section->reloc_count;
-+ for (; rel < relend; rel++)
-+ {
-+ enum elf_ppc_reloc_type r_type;
-+ bfd_vma addend;
-+ bfd_reloc_status_type r;
-+ Elf_Internal_Sym *sym;
-+ asection *sec;
-+ struct elf_link_hash_entry *h;
-+ const char *sym_name;
-+ reloc_howto_type *howto;
-+ unsigned long r_symndx;
-+ bfd_vma relocation;
-+ bfd_vma branch_bit, from;
-+ bfd_boolean unresolved_reloc;
-+ bfd_boolean warned;
-+ unsigned int tls_type, tls_mask, tls_gd;
-+ struct plt_entry **ifunc;
-+
-+ r_type = ELF32_R_TYPE (rel->r_info);
-+ sym = NULL;
-+ sec = NULL;
-+ h = NULL;
-+ unresolved_reloc = FALSE;
-+ warned = FALSE;
-+ r_symndx = ELF32_R_SYM (rel->r_info);
-+
-+ if (r_symndx < symtab_hdr->sh_info)
-+ {
-+ sym = local_syms + r_symndx;
-+ sec = local_sections[r_symndx];
-+ sym_name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec);
-+
-+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
-+ }
-+ else
-+ {
-+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
-+ r_symndx, symtab_hdr, sym_hashes,
-+ h, sec, relocation,
-+ unresolved_reloc, warned);
-+
-+ sym_name = h->root.root.string;
-+ }
-+
-+ if (sec != NULL && discarded_section (sec))
-+ {
-+ /* For relocs against symbols from removed linkonce sections,
-+ or sections discarded by a linker script, we just want the
-+ section contents zeroed. Avoid any special processing. */
-+ howto = NULL;
-+ if (r_type < R_PPC_max)
-+ howto = ppc_elf_howto_table[r_type];
-+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
-+ rel, 1, relend, howto, 0, contents);
-+ }
-+
-+ if (info->relocatable)
-+ {
-+ if (got2 != NULL
-+ && r_type == R_PPC_PLTREL24
-+ && rel->r_addend != 0)
-+ {
-+ /* R_PPC_PLTREL24 is rather special. If non-zero, the
-+ addend specifies the GOT pointer offset within .got2. */
-+ rel->r_addend += got2->output_offset;
-+ }
-+ continue;
-+ }
-+
-+ /* TLS optimizations. Replace instruction sequences and relocs
-+ based on information we collected in tls_optimize. We edit
-+ RELOCS so that --emit-relocs will output something sensible
-+ for the final instruction stream. */
-+ tls_mask = 0;
-+ tls_gd = 0;
-+ if (h != NULL)
-+ tls_mask = ((struct ppc_elf_link_hash_entry *) h)->tls_mask;
-+ else if (local_got_offsets != NULL)
-+ {
-+ struct plt_entry **local_plt;
-+ char *lgot_masks;
-+ local_plt
-+ = (struct plt_entry **) (local_got_offsets + symtab_hdr->sh_info);
-+ lgot_masks = (char *) (local_plt + symtab_hdr->sh_info);
-+ tls_mask = lgot_masks[r_symndx];
-+ }
-+
-+ /* Ensure reloc mapping code below stays sane. */
-+ if ((R_PPC_GOT_TLSLD16 & 3) != (R_PPC_GOT_TLSGD16 & 3)
-+ || (R_PPC_GOT_TLSLD16_LO & 3) != (R_PPC_GOT_TLSGD16_LO & 3)
-+ || (R_PPC_GOT_TLSLD16_HI & 3) != (R_PPC_GOT_TLSGD16_HI & 3)
-+ || (R_PPC_GOT_TLSLD16_HA & 3) != (R_PPC_GOT_TLSGD16_HA & 3)
-+ || (R_PPC_GOT_TLSLD16 & 3) != (R_PPC_GOT_TPREL16 & 3)
-+ || (R_PPC_GOT_TLSLD16_LO & 3) != (R_PPC_GOT_TPREL16_LO & 3)
-+ || (R_PPC_GOT_TLSLD16_HI & 3) != (R_PPC_GOT_TPREL16_HI & 3)
-+ || (R_PPC_GOT_TLSLD16_HA & 3) != (R_PPC_GOT_TPREL16_HA & 3))
-+ abort ();
-+ switch (r_type)
-+ {
-+ default:
-+ break;
-+
-+ case R_PPC_GOT_TPREL16:
-+ case R_PPC_GOT_TPREL16_LO:
-+ if ((tls_mask & TLS_TLS) != 0
-+ && (tls_mask & TLS_TPREL) == 0)
-+ {
-+ bfd_vma insn;
-+
-+ insn = bfd_get_32 (output_bfd, contents + rel->r_offset - d_offset);
-+ insn &= 31 << 21;
-+ insn |= 0x3c020000; /* addis 0,2,0 */
-+ bfd_put_32 (output_bfd, insn, contents + rel->r_offset - d_offset);
-+ r_type = R_PPC_TPREL16_HA;
-+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
-+ }
-+ break;
-+
-+ case R_PPC_TLS:
-+ if ((tls_mask & TLS_TLS) != 0
-+ && (tls_mask & TLS_TPREL) == 0)
-+ {
-+ bfd_vma insn;
-+
-+ insn = bfd_get_32 (output_bfd, contents + rel->r_offset);
-+ insn = _bfd_elf_ppc_at_tls_transform (insn, 2);
-+ if (insn == 0)
-+ abort ();
-+ bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
-+ r_type = R_PPC_TPREL16_LO;
-+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
-+
-+ /* Was PPC_TLS which sits on insn boundary, now
-+ PPC_TPREL16_LO which is at low-order half-word. */
-+ rel->r_offset += d_offset;
-+ }
-+ break;
-+
-+ case R_PPC_GOT_TLSGD16_HI:
-+ case R_PPC_GOT_TLSGD16_HA:
-+ tls_gd = TLS_TPRELGD;
-+ if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_GD) == 0)
-+ goto tls_gdld_hi;
-+ break;
-+
-+ case R_PPC_GOT_TLSLD16_HI:
-+ case R_PPC_GOT_TLSLD16_HA:
-+ if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_LD) == 0)
-+ {
-+ tls_gdld_hi:
-+ if ((tls_mask & tls_gd) != 0)
-+ r_type = (((r_type - (R_PPC_GOT_TLSGD16 & 3)) & 3)
-+ + R_PPC_GOT_TPREL16);
-+ else
-+ {
-+ bfd_put_32 (output_bfd, NOP, contents + rel->r_offset);
-+ rel->r_offset -= d_offset;
-+ r_type = R_PPC_NONE;
-+ }
-+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
-+ }
-+ break;
-+
-+ case R_PPC_GOT_TLSGD16:
-+ case R_PPC_GOT_TLSGD16_LO:
-+ tls_gd = TLS_TPRELGD;
-+ if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_GD) == 0)
-+ goto tls_ldgd_opt;
-+ break;
-+
-+ case R_PPC_GOT_TLSLD16:
-+ case R_PPC_GOT_TLSLD16_LO:
-+ if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_LD) == 0)
-+ {
-+ unsigned int insn1, insn2;
-+ bfd_vma offset;
-+
-+ tls_ldgd_opt:
-+ offset = (bfd_vma) -1;
-+ /* If not using the newer R_PPC_TLSGD/LD to mark
-+ __tls_get_addr calls, we must trust that the call
-+ stays with its arg setup insns, ie. that the next
-+ reloc is the __tls_get_addr call associated with
-+ the current reloc. Edit both insns. */
-+ if (input_section->has_tls_get_addr_call
-+ && rel + 1 < relend
-+ && branch_reloc_hash_match (input_bfd, rel + 1,
-+ htab->tls_get_addr))
-+ offset = rel[1].r_offset;
-+ if ((tls_mask & tls_gd) != 0)
-+ {
-+ /* IE */
-+ insn1 = bfd_get_32 (output_bfd,
-+ contents + rel->r_offset - d_offset);
-+ insn1 &= (1 << 26) - 1;
-+ insn1 |= 32 << 26; /* lwz */
-+ if (offset != (bfd_vma) -1)
-+ {
-+ rel[1].r_info = ELF32_R_INFO (STN_UNDEF, R_PPC_NONE);
-+ insn2 = 0x7c631214; /* add 3,3,2 */
-+ bfd_put_32 (output_bfd, insn2, contents + offset);
-+ }
-+ r_type = (((r_type - (R_PPC_GOT_TLSGD16 & 3)) & 3)
-+ + R_PPC_GOT_TPREL16);
-+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
-+ }
-+ else
-+ {
-+ /* LE */
-+ insn1 = 0x3c620000; /* addis 3,2,0 */
-+ if (tls_gd == 0)
-+ {
-+ /* Was an LD reloc. */
-+ for (r_symndx = 0;
-+ r_symndx < symtab_hdr->sh_info;
-+ r_symndx++)
-+ if (local_sections[r_symndx] == sec)
-+ break;
-+ if (r_symndx >= symtab_hdr->sh_info)
-+ r_symndx = STN_UNDEF;
-+ rel->r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
-+ if (r_symndx != STN_UNDEF)
-+ rel->r_addend -= (local_syms[r_symndx].st_value
-+ + sec->output_offset
-+ + sec->output_section->vma);
-+ }
-+ r_type = R_PPC_TPREL16_HA;
-+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
-+ if (offset != (bfd_vma) -1)
-+ {
-+ rel[1].r_info = ELF32_R_INFO (r_symndx, R_PPC_TPREL16_LO);
-+ rel[1].r_offset = offset + d_offset;
-+ rel[1].r_addend = rel->r_addend;
-+ insn2 = 0x38630000; /* addi 3,3,0 */
-+ bfd_put_32 (output_bfd, insn2, contents + offset);
-+ }
-+ }
-+ bfd_put_32 (output_bfd, insn1,
-+ contents + rel->r_offset - d_offset);
-+ if (tls_gd == 0)
-+ {
-+ /* We changed the symbol on an LD reloc. Start over
-+ in order to get h, sym, sec etc. right. */
-+ rel--;
-+ continue;
-+ }
-+ }
-+ break;
-+
-+ case R_PPC_TLSGD:
-+ if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_GD) == 0)
-+ {
-+ unsigned int insn2;
-+ bfd_vma offset = rel->r_offset;
-+
-+ if ((tls_mask & TLS_TPRELGD) != 0)
-+ {
-+ /* IE */
-+ r_type = R_PPC_NONE;
-+ insn2 = 0x7c631214; /* add 3,3,2 */
-+ }
-+ else
-+ {
-+ /* LE */
-+ r_type = R_PPC_TPREL16_LO;
-+ rel->r_offset += d_offset;
-+ insn2 = 0x38630000; /* addi 3,3,0 */
-+ }
-+ rel->r_info = ELF32_R_INFO (r_symndx, r_type);
-+ bfd_put_32 (output_bfd, insn2, contents + offset);
-+ /* Zap the reloc on the _tls_get_addr call too. */
-+ BFD_ASSERT (offset == rel[1].r_offset);
-+ rel[1].r_info = ELF32_R_INFO (STN_UNDEF, R_PPC_NONE);
-+ }
-+ break;
-+
-+ case R_PPC_TLSLD:
-+ if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_LD) == 0)
-+ {
-+ unsigned int insn2;
-+
-+ for (r_symndx = 0;
-+ r_symndx < symtab_hdr->sh_info;
-+ r_symndx++)
-+ if (local_sections[r_symndx] == sec)
-+ break;
-+ if (r_symndx >= symtab_hdr->sh_info)
-+ r_symndx = STN_UNDEF;
-+ rel->r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
-+ if (r_symndx != STN_UNDEF)
-+ rel->r_addend -= (local_syms[r_symndx].st_value
-+ + sec->output_offset
-+ + sec->output_section->vma);
-+
-+ rel->r_info = ELF32_R_INFO (r_symndx, R_PPC_TPREL16_LO);
-+ rel->r_offset += d_offset;
-+ insn2 = 0x38630000; /* addi 3,3,0 */
-+ bfd_put_32 (output_bfd, insn2,
-+ contents + rel->r_offset - d_offset);
-+ /* Zap the reloc on the _tls_get_addr call too. */
-+ BFD_ASSERT (rel->r_offset - d_offset == rel[1].r_offset);
-+ rel[1].r_info = ELF32_R_INFO (STN_UNDEF, R_PPC_NONE);
-+ rel--;
-+ continue;
-+ }
-+ break;
-+ }
-+
-+ /* Handle other relocations that tweak non-addend part of insn. */
-+ branch_bit = 0;
-+ switch (r_type)
-+ {
-+ default:
-+ break;
-+
-+ /* Branch taken prediction relocations. */
-+ case R_PPC_ADDR14_BRTAKEN:
-+ case R_PPC_REL14_BRTAKEN:
-+ branch_bit = BRANCH_PREDICT_BIT;
-+ /* Fall thru */
-+
-+ /* Branch not taken prediction relocations. */
-+ case R_PPC_ADDR14_BRNTAKEN:
-+ case R_PPC_REL14_BRNTAKEN:
-+ {
-+ bfd_vma insn;
-+
-+ insn = bfd_get_32 (output_bfd, contents + rel->r_offset);
-+ insn &= ~BRANCH_PREDICT_BIT;
-+ insn |= branch_bit;
-+
-+ from = (rel->r_offset
-+ + input_section->output_offset
-+ + input_section->output_section->vma);
-+
-+ /* Invert 'y' bit if not the default. */
-+ if ((bfd_signed_vma) (relocation + rel->r_addend - from) < 0)
-+ insn ^= BRANCH_PREDICT_BIT;
-+
-+ bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
-+ break;
-+ }
-+ }
-+
-+ ifunc = NULL;
-+ if (!htab->is_vxworks)
-+ {
-+ struct plt_entry *ent;
-+
-+ if (h != NULL)
-+ {
-+ if (h->type == STT_GNU_IFUNC)
-+ ifunc = &h->plt.plist;
-+ }
-+ else if (local_got_offsets != NULL
-+ && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
-+ {
-+ struct plt_entry **local_plt;
-+
-+ local_plt = (struct plt_entry **) (local_got_offsets
-+ + symtab_hdr->sh_info);
-+ ifunc = local_plt + r_symndx;
-+ }
-+
-+ ent = NULL;
-+ if (ifunc != NULL
-+ && (!info->shared
-+ || is_branch_reloc (r_type)))
-+ {
-+ addend = 0;
-+ if (r_type == R_PPC_PLTREL24 && info->shared)
-+ addend = rel->r_addend;
-+ ent = find_plt_ent (ifunc, got2, addend);
-+ }
-+ if (ent != NULL)
-+ {
-+ if (h == NULL && (ent->plt.offset & 1) == 0)
-+ {
-+ Elf_Internal_Rela rela;
-+ bfd_byte *loc;
-+
-+ rela.r_offset = (htab->iplt->output_section->vma
-+ + htab->iplt->output_offset
-+ + ent->plt.offset);
-+ rela.r_info = ELF32_R_INFO (0, R_PPC_IRELATIVE);
-+ rela.r_addend = relocation;
-+ loc = htab->reliplt->contents;
-+ loc += (htab->reliplt->reloc_count++
-+ * sizeof (Elf32_External_Rela));
-+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
-+
-+ ent->plt.offset |= 1;
-+ }
-+ if (h == NULL && (ent->glink_offset & 1) == 0)
-+ {
-+ unsigned char *p = ((unsigned char *) htab->glink->contents
-+ + ent->glink_offset);
-+ write_glink_stub (ent, htab->iplt, p, info);
-+ ent->glink_offset |= 1;
-+ }
-+
-+ unresolved_reloc = FALSE;
-+ if (htab->plt_type == PLT_NEW
-+ || !htab->elf.dynamic_sections_created
-+ || h == NULL)
-+ relocation = (htab->glink->output_section->vma
-+ + htab->glink->output_offset
-+ + (ent->glink_offset & ~1));
-+ else
-+ relocation = (htab->plt->output_section->vma
-+ + htab->plt->output_offset
-+ + ent->plt.offset);
-+ }
-+ }
-+
-+ addend = rel->r_addend;
-+ tls_type = 0;
-+ howto = NULL;
-+ if (r_type < R_PPC_max)
-+ howto = ppc_elf_howto_table[r_type];
-+ switch (r_type)
-+ {
-+ default:
-+ info->callbacks->einfo
-+ (_("%P: %B: unknown relocation type %d for symbol %s\n"),
-+ input_bfd, (int) r_type, sym_name);
-+
-+ bfd_set_error (bfd_error_bad_value);
-+ ret = FALSE;
-+ continue;
-+
-+ case R_PPC_NONE:
-+ case R_PPC_TLS:
-+ case R_PPC_TLSGD:
-+ case R_PPC_TLSLD:
-+ case R_PPC_EMB_MRKREF:
-+ case R_PPC_GNU_VTINHERIT:
-+ case R_PPC_GNU_VTENTRY:
-+ continue;
-+
-+ /* GOT16 relocations. Like an ADDR16 using the symbol's
-+ address in the GOT as relocation value instead of the
-+ symbol's value itself. Also, create a GOT entry for the
-+ symbol and put the symbol value there. */
-+ case R_PPC_GOT_TLSGD16:
-+ case R_PPC_GOT_TLSGD16_LO:
-+ case R_PPC_GOT_TLSGD16_HI:
-+ case R_PPC_GOT_TLSGD16_HA:
-+ tls_type = TLS_TLS | TLS_GD;
-+ goto dogot;
-+
-+ case R_PPC_GOT_TLSLD16:
-+ case R_PPC_GOT_TLSLD16_LO:
-+ case R_PPC_GOT_TLSLD16_HI:
-+ case R_PPC_GOT_TLSLD16_HA:
-+ tls_type = TLS_TLS | TLS_LD;
-+ goto dogot;
-+
-+ case R_PPC_GOT_TPREL16:
-+ case R_PPC_GOT_TPREL16_LO:
-+ case R_PPC_GOT_TPREL16_HI:
-+ case R_PPC_GOT_TPREL16_HA:
-+ tls_type = TLS_TLS | TLS_TPREL;
-+ goto dogot;
-+
-+ case R_PPC_GOT_DTPREL16:
-+ case R_PPC_GOT_DTPREL16_LO:
-+ case R_PPC_GOT_DTPREL16_HI:
-+ case R_PPC_GOT_DTPREL16_HA:
-+ tls_type = TLS_TLS | TLS_DTPREL;
-+ goto dogot;
-+
-+ case R_PPC_GOT16:
-+ case R_PPC_GOT16_LO:
-+ case R_PPC_GOT16_HI:
-+ case R_PPC_GOT16_HA:
-+ tls_mask = 0;
-+ dogot:
-+ {
-+ /* Relocation is to the entry for this symbol in the global
-+ offset table. */
-+ bfd_vma off;
-+ bfd_vma *offp;
-+ unsigned long indx;
-+
-+ if (htab->got == NULL)
-+ abort ();
-+
-+ indx = 0;
-+ if (tls_type == (TLS_TLS | TLS_LD)
-+ && (h == NULL
-+ || !h->def_dynamic))
-+ offp = &htab->tlsld_got.offset;
-+ else if (h != NULL)
-+ {
-+ bfd_boolean dyn;
-+ dyn = htab->elf.dynamic_sections_created;
-+ if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
-+ || (info->shared
-+ && SYMBOL_REFERENCES_LOCAL (info, h)))
-+ /* This is actually a static link, or it is a
-+ -Bsymbolic link and the symbol is defined
-+ locally, or the symbol was forced to be local
-+ because of a version file. */
-+ ;
-+ else
-+ {
-+ BFD_ASSERT (h->dynindx != -1);
-+ indx = h->dynindx;
-+ unresolved_reloc = FALSE;
-+ }
-+ offp = &h->got.offset;
-+ }
-+ else
-+ {
-+ if (local_got_offsets == NULL)
-+ abort ();
-+ offp = &local_got_offsets[r_symndx];
-+ }
-+
-+ /* The offset must always be a multiple of 4. We use the
-+ least significant bit to record whether we have already
-+ processed this entry. */
-+ off = *offp;
-+ if ((off & 1) != 0)
-+ off &= ~1;
-+ else
-+ {
-+ unsigned int tls_m = (tls_mask
-+ & (TLS_LD | TLS_GD | TLS_DTPREL
-+ | TLS_TPREL | TLS_TPRELGD));
-+
-+ if (offp == &htab->tlsld_got.offset)
-+ tls_m = TLS_LD;
-+ else if (h == NULL
-+ || !h->def_dynamic)
-+ tls_m &= ~TLS_LD;
-+
-+ /* We might have multiple got entries for this sym.
-+ Initialize them all. */
-+ do
-+ {
-+ int tls_ty = 0;
-+
-+ if ((tls_m & TLS_LD) != 0)
-+ {
-+ tls_ty = TLS_TLS | TLS_LD;
-+ tls_m &= ~TLS_LD;
-+ }
-+ else if ((tls_m & TLS_GD) != 0)
-+ {
-+ tls_ty = TLS_TLS | TLS_GD;
-+ tls_m &= ~TLS_GD;
-+ }
-+ else if ((tls_m & TLS_DTPREL) != 0)
-+ {
-+ tls_ty = TLS_TLS | TLS_DTPREL;
-+ tls_m &= ~TLS_DTPREL;
-+ }
-+ else if ((tls_m & (TLS_TPREL | TLS_TPRELGD)) != 0)
-+ {
-+ tls_ty = TLS_TLS | TLS_TPREL;
-+ tls_m = 0;
-+ }
-+
-+ /* Generate relocs for the dynamic linker. */
-+ if ((info->shared || indx != 0)
-+ && (offp == &htab->tlsld_got.offset
-+ || h == NULL
-+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
-+ || h->root.type != bfd_link_hash_undefweak))
-+ {
-+ asection *rsec = htab->relgot;
-+ bfd_byte * loc;
-+
-+ outrel.r_offset = (htab->got->output_section->vma
-+ + htab->got->output_offset
-+ + off);
-+ outrel.r_addend = 0;
-+ if (tls_ty & (TLS_LD | TLS_GD))
-+ {
-+ outrel.r_info = ELF32_R_INFO (indx, R_PPC_DTPMOD32);
-+ if (tls_ty == (TLS_TLS | TLS_GD))
-+ {
-+ loc = rsec->contents;
-+ loc += (rsec->reloc_count++
-+ * sizeof (Elf32_External_Rela));
-+ bfd_elf32_swap_reloca_out (output_bfd,
-+ &outrel, loc);
-+ outrel.r_offset += 4;
-+ outrel.r_info
-+ = ELF32_R_INFO (indx, R_PPC_DTPREL32);
-+ }
-+ }
-+ else if (tls_ty == (TLS_TLS | TLS_DTPREL))
-+ outrel.r_info = ELF32_R_INFO (indx, R_PPC_DTPREL32);
-+ else if (tls_ty == (TLS_TLS | TLS_TPREL))
-+ outrel.r_info = ELF32_R_INFO (indx, R_PPC_TPREL32);
-+ else if (indx != 0)
-+ outrel.r_info = ELF32_R_INFO (indx, R_PPC_GLOB_DAT);
-+ else if (ifunc != NULL)
-+ outrel.r_info = ELF32_R_INFO (0, R_PPC_IRELATIVE);
-+ else
-+ outrel.r_info = ELF32_R_INFO (0, R_PPC_RELATIVE);
-+ if (indx == 0 && tls_ty != (TLS_TLS | TLS_LD))
-+ {
-+ outrel.r_addend += relocation;
-+ if (tls_ty & (TLS_GD | TLS_DTPREL | TLS_TPREL))
-+ outrel.r_addend -= htab->elf.tls_sec->vma;
-+ }
-+ loc = rsec->contents;
-+ loc += (rsec->reloc_count++
-+ * sizeof (Elf32_External_Rela));
-+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
-+ }
-+
-+ /* Init the .got section contents if we're not
-+ emitting a reloc. */
-+ else
-+ {
-+ bfd_vma value = relocation;
-+
-+ if (tls_ty == (TLS_TLS | TLS_LD))
-+ value = 1;
-+ else if (tls_ty != 0)
-+ {
-+ value -= htab->elf.tls_sec->vma + DTP_OFFSET;
-+ if (tls_ty == (TLS_TLS | TLS_TPREL))
-+ value += DTP_OFFSET - TP_OFFSET;
-+
-+ if (tls_ty == (TLS_TLS | TLS_GD))
-+ {
-+ bfd_put_32 (output_bfd, value,
-+ htab->got->contents + off + 4);
-+ value = 1;
-+ }
-+ }
-+ bfd_put_32 (output_bfd, value,
-+ htab->got->contents + off);
-+ }
-+
-+ off += 4;
-+ if (tls_ty & (TLS_LD | TLS_GD))
-+ off += 4;
-+ }
-+ while (tls_m != 0);
-+
-+ off = *offp;
-+ *offp = off | 1;
-+ }
-+
-+ if (off >= (bfd_vma) -2)
-+ abort ();
-+
-+ if ((tls_type & TLS_TLS) != 0)
-+ {
-+ if (tls_type != (TLS_TLS | TLS_LD))
-+ {
-+ if ((tls_mask & TLS_LD) != 0
-+ && !(h == NULL
-+ || !h->def_dynamic))
-+ off += 8;
-+ if (tls_type != (TLS_TLS | TLS_GD))
-+ {
-+ if ((tls_mask & TLS_GD) != 0)
-+ off += 8;
-+ if (tls_type != (TLS_TLS | TLS_DTPREL))
-+ {
-+ if ((tls_mask & TLS_DTPREL) != 0)
-+ off += 4;
-+ }
-+ }
-+ }
-+ }
-+
-+ relocation = (htab->got->output_section->vma
-+ + htab->got->output_offset
-+ + off
-+ - SYM_VAL (htab->elf.hgot));
-+
-+ /* Addends on got relocations don't make much sense.
-+ x+off@got is actually x@got+off, and since the got is
-+ generated by a hash table traversal, the value in the
-+ got at entry m+n bears little relation to the entry m. */
-+ if (addend != 0)
-+ info->callbacks->einfo
-+ (_("%P: %H: non-zero addend on %s reloc against `%s'\n"),
-+ input_bfd, input_section, rel->r_offset,
-+ howto->name,
-+ sym_name);
-+ }
-+ break;
-+
-+ /* Relocations that need no special processing. */
-+ case R_PPC_LOCAL24PC:
-+ /* It makes no sense to point a local relocation
-+ at a symbol not in this object. */
-+ if (unresolved_reloc)
-+ {
-+ if (! (*info->callbacks->undefined_symbol) (info,
-+ h->root.root.string,
-+ input_bfd,
-+ input_section,
-+ rel->r_offset,
-+ TRUE))
-+ return FALSE;
-+ continue;
-+ }
-+ break;
-+
-+ case R_PPC_DTPREL16:
-+ case R_PPC_DTPREL16_LO:
-+ case R_PPC_DTPREL16_HI:
-+ case R_PPC_DTPREL16_HA:
-+ addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
-+ break;
-+
-+ /* Relocations that may need to be propagated if this is a shared
-+ object. */
-+ case R_PPC_TPREL16:
-+ case R_PPC_TPREL16_LO:
-+ case R_PPC_TPREL16_HI:
-+ case R_PPC_TPREL16_HA:
-+ if (h != NULL
-+ && h->root.type == bfd_link_hash_undefweak
-+ && h->dynindx == -1)
-+ {
-+ /* Make this relocation against an undefined weak symbol
-+ resolve to zero. This is really just a tweak, since
-+ code using weak externs ought to check that they are
-+ defined before using them. */
-+ bfd_byte *p = contents + rel->r_offset - d_offset;
-+ unsigned int insn = bfd_get_32 (output_bfd, p);
-+ insn = _bfd_elf_amigaos_ppc_at_tprel_transform (insn, 2);
-+ if (insn != 0)
-+ bfd_put_32 (output_bfd, insn, p);
-+ break;
-+ }
-+ addend -= htab->elf.tls_sec->vma + TP_OFFSET;
-+ /* The TPREL16 relocs shouldn't really be used in shared
-+ libs as they will result in DT_TEXTREL being set, but
-+ support them anyway. */
-+ goto dodyn;
-+
-+ case R_PPC_TPREL32:
-+ addend -= htab->elf.tls_sec->vma + TP_OFFSET;
-+ goto dodyn;
-+
-+ case R_PPC_DTPREL32:
-+ addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
-+ goto dodyn;
-+
-+ case R_PPC_DTPMOD32:
-+ relocation = 1;
-+ addend = 0;
-+ goto dodyn;
-+
-+ case R_PPC_REL16:
-+ case R_PPC_REL16_LO:
-+ case R_PPC_REL16_HI:
-+ case R_PPC_REL16_HA:
-+ break;
-+
-+ case R_PPC_REL32:
-+ if (h == NULL || h == htab->elf.hgot)
-+ break;
-+ /* fall through */
-+
-+ case R_PPC_ADDR32:
-+ case R_PPC_ADDR16:
-+ case R_PPC_ADDR16_LO:
-+ case R_PPC_ADDR16_HI:
-+ case R_PPC_ADDR16_HA:
-+ case R_PPC_UADDR32:
-+ case R_PPC_UADDR16:
-+ goto dodyn;
-+
-+ case R_PPC_VLE_REL8:
-+ case R_PPC_VLE_REL15:
-+ case R_PPC_VLE_REL24:
-+ case R_PPC_REL24:
-+ case R_PPC_REL14:
-+ case R_PPC_REL14_BRTAKEN:
-+ case R_PPC_REL14_BRNTAKEN:
-+ /* If these relocations are not to a named symbol, they can be
-+ handled right here, no need to bother the dynamic linker. */
-+ if (SYMBOL_CALLS_LOCAL (info, h)
-+ || h == htab->elf.hgot)
-+ break;
-+ /* fall through */
-+
-+ case R_PPC_ADDR24:
-+ case R_PPC_ADDR14:
-+ case R_PPC_ADDR14_BRTAKEN:
-+ case R_PPC_ADDR14_BRNTAKEN:
-+ if (h != NULL && !info->shared)
-+ break;
-+ /* fall through */
-+
-+ dodyn:
-+ if ((input_section->flags & SEC_ALLOC) == 0
-+ || is_vxworks_tls)
-+ break;
-+
-+ if ((info->shared
-+ && !(h != NULL
-+ && ((h->root.type == bfd_link_hash_undefined
-+ && (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
-+ || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL))
-+ || (h->root.type == bfd_link_hash_undefweak
-+ && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)))
-+ && (must_be_dyn_reloc (info, r_type)
-+ || !SYMBOL_CALLS_LOCAL (info, h)))
-+ || (ELIMINATE_COPY_RELOCS
-+ && !info->shared
-+ && h != NULL
-+ && h->dynindx != -1
-+ && !h->non_got_ref
-+ && !h->def_regular))
-+ {
-+ int skip;
-+ bfd_byte * loc;
-+#ifdef DEBUG
-+ fprintf (stderr, "ppc_elf_relocate_section needs to "
-+ "create relocation for %s\n",
-+ (h && h->root.root.string
-+ ? h->root.root.string : "<unknown>"));
-+#endif
-+
-+ /* When generating a shared object, these relocations
-+ are copied into the output file to be resolved at run
-+ time. */
-+ if (sreloc == NULL)
-+ {
-+ sreloc = elf_section_data (input_section)->sreloc;
-+ if (!htab->elf.dynamic_sections_created)
-+ sreloc = htab->reliplt;
-+ if (sreloc == NULL)
-+ return FALSE;
-+ }
-+
-+ skip = 0;
-+ outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
-+ input_section,
-+ rel->r_offset);
-+ if (outrel.r_offset == (bfd_vma) -1
-+ || outrel.r_offset == (bfd_vma) -2)
-+ skip = (int) outrel.r_offset;
-+ outrel.r_offset += (input_section->output_section->vma
-+ + input_section->output_offset);
-+
-+ if (skip)
-+ memset (&outrel, 0, sizeof outrel);
-+ else if ((h != NULL
-+ && (h->root.type == bfd_link_hash_undefined
-+ || h->root.type == bfd_link_hash_undefweak))
-+ || !SYMBOL_REFERENCES_LOCAL (info, h))
-+ {
-+ BFD_ASSERT (h->dynindx != -1);
-+ unresolved_reloc = FALSE;
-+ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
-+ outrel.r_addend = rel->r_addend;
-+ }
-+ else
-+ {
-+ outrel.r_addend = relocation + rel->r_addend;
-+
-+ if (r_type != R_PPC_ADDR32)
-+ {
-+ long indx = 0;
-+
-+ if (ifunc != NULL)
-+ {
-+ /* If we get here when building a static
-+ executable, then the libc startup function
-+ responsible for applying indirect function
-+ relocations is going to complain about
-+ the reloc type.
-+ If we get here when building a dynamic
-+ executable, it will be because we have
-+ a text relocation. The dynamic loader
-+ will set the text segment writable and
-+ non-executable to apply text relocations.
-+ So we'll segfault when trying to run the
-+ indirection function to resolve the reloc. */
-+ info->callbacks->einfo
-+ (_("%P: %H: relocation %s for indirect "
-+ "function %s unsupported\n"),
-+ input_bfd, input_section, rel->r_offset,
-+ howto->name,
-+ sym_name);
-+ ret = FALSE;
-+ }
-+ else if (r_symndx == STN_UNDEF || bfd_is_abs_section (sec))
-+ ;
-+ else if (sec == NULL || sec->owner == NULL)
-+ {
-+ bfd_set_error (bfd_error_bad_value);
-+ ret = FALSE;
-+ }
-+ else
-+ {
-+ asection *osec;
-+
-+ /* We are turning this relocation into one
-+ against a section symbol. It would be
-+ proper to subtract the symbol's value,
-+ osec->vma, from the emitted reloc addend,
-+ but ld.so expects buggy relocs.
-+ FIXME: Why not always use a zero index? */
-+ osec = sec->output_section;
-+ indx = elf_section_data (osec)->dynindx;
-+ if (indx == 0)
-+ {
-+ osec = htab->elf.text_index_section;
-+ indx = elf_section_data (osec)->dynindx;
-+ }
-+ BFD_ASSERT (indx != 0);
-+#ifdef DEBUG
-+ if (indx == 0)
-+ printf ("indx=%ld section=%s flags=%08x name=%s\n",
-+ indx, osec->name, osec->flags,
-+ h->root.root.string);
-+#endif
-+ }
-+
-+ outrel.r_info = ELF32_R_INFO (indx, r_type);
-+ }
-+ else if (ifunc != NULL)
-+ outrel.r_info = ELF32_R_INFO (0, R_PPC_IRELATIVE);
-+ else
-+ outrel.r_info = ELF32_R_INFO (0, R_PPC_RELATIVE);
-+ }
-+
-+ loc = sreloc->contents;
-+ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
-+ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
-+
-+ if (skip == -1)
-+ continue;
-+
-+ /* This reloc will be computed at runtime. We clear the memory
-+ so that it contains predictable value. */
-+ if (! skip
-+ && ((input_section->flags & SEC_ALLOC) != 0
-+ || ELF32_R_TYPE (outrel.r_info) != R_PPC_RELATIVE))
-+ {
-+ relocation = howto->pc_relative ? outrel.r_offset : 0;
-+ addend = 0;
-+ break;
-+ }
-+ }
-+ break;
-+
-+ case R_PPC_RELAX_PLT:
-+ case R_PPC_RELAX_PLTREL24:
-+ if (h != NULL)
-+ {
-+ struct plt_entry *ent;
-+ bfd_vma got2_addend = 0;
-+
-+ if (r_type == R_PPC_RELAX_PLTREL24)
-+ {
-+ if (info->shared)
-+ got2_addend = addend;
-+ addend = 0;
-+ }
-+ ent = find_plt_ent (&h->plt.plist, got2, got2_addend);
-+ if (htab->plt_type == PLT_NEW)
-+ relocation = (htab->glink->output_section->vma
-+ + htab->glink->output_offset
-+ + ent->glink_offset);
-+ else
-+ relocation = (htab->plt->output_section->vma
-+ + htab->plt->output_offset
-+ + ent->plt.offset);
-+ }
-+ /* Fall thru */
-+
-+ case R_PPC_RELAX:
-+ if (info->shared)
-+ relocation -= (input_section->output_section->vma
-+ + input_section->output_offset
-+ + rel->r_offset - 4);
-+
-+ {
-+ unsigned long t0;
-+ unsigned long t1;
-+
-+ t0 = bfd_get_32 (output_bfd, contents + rel->r_offset);
-+ t1 = bfd_get_32 (output_bfd, contents + rel->r_offset + 4);
-+
-+ /* We're clearing the bits for R_PPC_ADDR16_HA
-+ and R_PPC_ADDR16_LO here. */
-+ t0 &= ~0xffff;
-+ t1 &= ~0xffff;
-+
-+ /* t0 is HA, t1 is LO */
-+ relocation += addend;
-+ t0 |= ((relocation + 0x8000) >> 16) & 0xffff;
-+ t1 |= relocation & 0xffff;
-+
-+ bfd_put_32 (output_bfd, t0, contents + rel->r_offset);
-+ bfd_put_32 (output_bfd, t1, contents + rel->r_offset + 4);
-+
-+ /* Rewrite the reloc and convert one of the trailing nop
-+ relocs to describe this relocation. */
-+ BFD_ASSERT (ELF32_R_TYPE (relend[-1].r_info) == R_PPC_NONE);
-+ /* The relocs are at the bottom 2 bytes */
-+ rel[0].r_offset += 2;
-+ memmove (rel + 1, rel, (relend - rel - 1) * sizeof (*rel));
-+ rel[0].r_info = ELF32_R_INFO (r_symndx, R_PPC_ADDR16_HA);
-+ rel[1].r_offset += 4;
-+ rel[1].r_info = ELF32_R_INFO (r_symndx, R_PPC_ADDR16_LO);
-+ rel++;
-+ }
-+ continue;
-+
-+ /* Indirect .sdata relocation. */
-+ case R_PPC_EMB_SDAI16:
-+ BFD_ASSERT (htab->sdata[0].section != NULL);
-+ if (!is_static_defined (htab->sdata[0].sym))
-+ {
-+ unresolved_reloc = TRUE;
-+ break;
-+ }
-+ relocation
-+ = elf_finish_pointer_linker_section (input_bfd, &htab->sdata[0],
-+ h, relocation, rel);
-+ addend = 0;
-+ break;
-+
-+ /* Indirect .sdata2 relocation. */
-+ case R_PPC_EMB_SDA2I16:
-+ BFD_ASSERT (htab->sdata[1].section != NULL);
-+ if (!is_static_defined (htab->sdata[1].sym))
-+ {
-+ unresolved_reloc = TRUE;
-+ break;
-+ }
-+ relocation
-+ = elf_finish_pointer_linker_section (input_bfd, &htab->sdata[1],
-+ h, relocation, rel);
-+ addend = 0;
-+ break;
-+
-+ /* Handle the TOC16 reloc. We want to use the offset within the .got
-+ section, not the actual VMA. This is appropriate when generating
-+ an embedded ELF object, for which the .got section acts like the
-+ AIX .toc section. */
-+ case R_PPC_TOC16: /* phony GOT16 relocations */
-+ if (sec == NULL || sec->output_section == NULL)
-+ {
-+ unresolved_reloc = TRUE;
-+ break;
-+ }
-+ BFD_ASSERT (strcmp (bfd_get_section_name (sec->owner, sec),
-+ ".got") == 0
-+ || strcmp (bfd_get_section_name (sec->owner, sec),
-+ ".cgot") == 0);
-+
-+ addend -= sec->output_section->vma + sec->output_offset + 0x8000;
-+ break;
-+
-+ case R_PPC_PLTREL24:
-+ if (h != NULL && ifunc == NULL)
-+ {
-+ struct plt_entry *ent = find_plt_ent (&h->plt.plist, got2,
-+ info->shared ? addend : 0);
-+ if (ent == NULL
-+ || htab->plt == NULL)
-+ {
-+ /* We didn't make a PLT entry for this symbol. This
-+ happens when statically linking PIC code, or when
-+ using -Bsymbolic. */
-+ }
-+ else
-+ {
-+ /* Relocation is to the entry for this symbol in the
-+ procedure linkage table. */
-+ unresolved_reloc = FALSE;
-+ if (htab->plt_type == PLT_NEW)
-+ relocation = (htab->glink->output_section->vma
-+ + htab->glink->output_offset
-+ + ent->glink_offset);
-+ else
-+ relocation = (htab->plt->output_section->vma
-+ + htab->plt->output_offset
-+ + ent->plt.offset);
-+ }
-+ }
-+
-+ /* R_PPC_PLTREL24 is rather special. If non-zero, the
-+ addend specifies the GOT pointer offset within .got2.
-+ Don't apply it to the relocation field. */
-+ addend = 0;
-+ break;
-+
-+ /* Relocate against _SDA_BASE_. */
-+ case R_PPC_SDAREL16:
-+ {
-+ const char *name;
-+ struct elf_link_hash_entry *sda = htab->sdata[0].sym;
-+
-+ if (sec == NULL
-+ || sec->output_section == NULL
-+ || !is_static_defined (sda))
-+ {
-+ unresolved_reloc = TRUE;
-+ break;
-+ }
-+ addend -= SYM_VAL (sda);
-+
-+ name = bfd_get_section_name (output_bfd, sec->output_section);
-+ if (! ((CONST_STRNEQ (name, ".sdata")
-+ && (name[6] == 0 || name[6] == '.'))
-+ || (CONST_STRNEQ (name, ".sbss")
-+ && (name[5] == 0 || name[5] == '.'))))
-+ {
-+ info->callbacks->einfo
-+ (_("%P: %B: the target (%s) of a %s relocation is "
-+ "in the wrong output section (%s)\n"),
-+ input_bfd,
-+ sym_name,
-+ howto->name,
-+ name);
-+ }
-+ }
-+ break;
-+
-+ /* Relocate against _SDA2_BASE_. */
-+ case R_PPC_EMB_SDA2REL:
-+ {
-+ const char *name;
-+ struct elf_link_hash_entry *sda = htab->sdata[1].sym;
-+
-+ if (sec == NULL
-+ || sec->output_section == NULL
-+ || !is_static_defined (sda))
-+ {
-+ unresolved_reloc = TRUE;
-+ break;
-+ }
-+ addend -= SYM_VAL (sda);
-+
-+ name = bfd_get_section_name (output_bfd, sec->output_section);
-+ if (! (CONST_STRNEQ (name, ".sdata2")
-+ || CONST_STRNEQ (name, ".sbss2")))
-+ {
-+ info->callbacks->einfo
-+ (_("%P: %B: the target (%s) of a %s relocation is "
-+ "in the wrong output section (%s)\n"),
-+ input_bfd,
-+ sym_name,
-+ howto->name,
-+ name);
-+ }
-+ }
-+ break;
-+#if 0
-+ case R_PPC_AMIGAOS_BREL:
-+ case R_PPC_AMIGAOS_BREL_HI:
-+ case R_PPC_AMIGAOS_BREL_LO:
-+ case R_PPC_AMIGAOS_BREL_HA:
-+ {
-+ if (data_section == NULL)
-+ data_section = bfd_get_section_by_name (output_bfd, ".data");
-+
-+ if (sec)
-+ {
-+ const char *name = bfd_get_section_name (abfd, sec->output_section);
-+ if (strcmp (name, ".sdata") != 0
-+ && strcmp (name, ".sbss") != 0
-+ && strcmp (name, ".data") != 0
-+ && strcmp (name, ".bss") != 0
-+ && strncmp (name, ".ctors", 6) != 0
-+ && strncmp (name, ".dtors", 6) != 0)
-+ {
-+ (*_bfd_error_handler) (_("%s: The target (%s) of a %s relocation is in the wrong output section (%s)"),
-+ input_bfd,
-+ sym_name,
-+ howto->name,
-+ name);
-+ }
-+ }
-+
-+ addend = addend - data_section->vma;
-+
-+ if (r_type == R_PPC_AMIGAOS_BREL_HA)
-+ addend += ((relocation + addend) & 0x8000) << 1;
-+
-+ }
-+ break;
-+#endif
-+ case R_PPC_VLE_LO16A:
-+ relocation = (relocation + addend) & 0xffff;
-+ ppc_elf_vle_split16 (output_bfd, contents, rel->r_offset,
-+ relocation, split16a_type);
-+ continue;
-+
-+ case R_PPC_VLE_LO16D:
-+ relocation = (relocation + addend) & 0xffff;
-+ ppc_elf_vle_split16 (output_bfd, contents, rel->r_offset,
-+ relocation, split16d_type);
-+ continue;
-+
-+ case R_PPC_VLE_HI16A:
-+ relocation = ((relocation + addend) >> 16) & 0xffff;
-+ ppc_elf_vle_split16 (output_bfd, contents, rel->r_offset,
-+ relocation, split16a_type);
-+ continue;
-+
-+ case R_PPC_VLE_HI16D:
-+ relocation = ((relocation + addend) >> 16) & 0xffff;
-+ ppc_elf_vle_split16 (output_bfd, contents, rel->r_offset,
-+ relocation, split16d_type);
-+ continue;
-+
-+ case R_PPC_VLE_HA16A:
-+ {
-+ bfd_vma value = relocation + addend;
-+ value = (((value >> 16) + ((value & 0x8000) ? 1 : 0)) & 0xffff);
-+ ppc_elf_vle_split16 (output_bfd, contents, rel->r_offset,
-+ value, split16a_type);
-+ }
-+ continue;
-+
-+ case R_PPC_VLE_HA16D:
-+ {
-+ bfd_vma value = relocation + addend;
-+ value = (((value >> 16) + ((value & 0x8000) ? 1 : 0)) & 0xffff);
-+ ppc_elf_vle_split16 (output_bfd, contents, rel->r_offset,
-+ value, split16d_type);
-+ }
-+ continue;
-+
-+ /* Relocate against either _SDA_BASE_, _SDA2_BASE_, or 0. */
-+ case R_PPC_EMB_SDA21:
-+ case R_PPC_VLE_SDA21:
-+ case R_PPC_EMB_RELSDA:
-+ case R_PPC_VLE_SDA21_LO:
-+ {
-+ const char *name;
-+ int reg;
-+ struct elf_link_hash_entry *sda = NULL;
-+
-+ if (sec == NULL || sec->output_section == NULL)
-+ {
-+ unresolved_reloc = TRUE;
-+ break;
-+ }
-+
-+ name = bfd_get_section_name (output_bfd, sec->output_section);
-+ if (((CONST_STRNEQ (name, ".sdata")
-+ && (name[6] == 0 || name[6] == '.'))
-+ || (CONST_STRNEQ (name, ".sbss")
-+ && (name[5] == 0 || name[5] == '.'))))
-+ {
-+ reg = 13;
-+ sda = htab->sdata[0].sym;
-+ }
-+ else if (CONST_STRNEQ (name, ".sdata2")
-+ || CONST_STRNEQ (name, ".sbss2"))
-+ {
-+ reg = 2;
-+ sda = htab->sdata[1].sym;
-+ }
-+ else if (strcmp (name, ".PPC.EMB.sdata0") == 0
-+ || strcmp (name, ".PPC.EMB.sbss0") == 0)
-+ {
-+ reg = 0;
-+ }
-+ else
-+ {
-+ info->callbacks->einfo
-+ (_("%P: %B: the target (%s) of a %s relocation is "
-+ "in the wrong output section (%s)\n"),
-+ input_bfd,
-+ sym_name,
-+ howto->name,
-+ name);
-+
-+ bfd_set_error (bfd_error_bad_value);
-+ ret = FALSE;
-+ continue;
-+ }
-+
-+ if (sda != NULL)
-+ {
-+ if (!is_static_defined (sda))
-+ {
-+ unresolved_reloc = TRUE;
-+ break;
-+ }
-+ addend -= SYM_VAL (sda);
-+ }
-+
-+ if (reg == 0
-+ && (r_type == R_PPC_VLE_SDA21
-+ || r_type == R_PPC_VLE_SDA21_LO))
-+ {
-+ /* Use the split20 format. */
-+ bfd_vma insn, bits12to15, bits21to31;
-+ bfd_vma value = (relocation + rel->r_offset) & 0xffff;
-+ /* Propagate sign bit, if necessary. */
-+ insn = (value & 0x8000) ? 0x70107800 : 0x70000000;
-+ bits12to15 = value & 0x700;
-+ bits21to31 = value & 0x7ff;
-+ insn |= bits12to15;
-+ insn |= bits21to31;
-+ bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
-+ continue;
-+ }
-+ else if (r_type == R_PPC_EMB_SDA21
-+ || r_type == R_PPC_VLE_SDA21
-+ || r_type == R_PPC_VLE_SDA21_LO)
-+ {
-+ bfd_vma insn; /* Fill in register field. */
-+
-+ insn = bfd_get_32 (output_bfd, contents + rel->r_offset);
-+ insn = (insn & ~RA_REGISTER_MASK) | (reg << RA_REGISTER_SHIFT);
-+ bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
-+ }
-+ }
-+ break;
-+
-+ case R_PPC_VLE_SDAREL_LO16A:
-+ case R_PPC_VLE_SDAREL_LO16D:
-+ case R_PPC_VLE_SDAREL_HI16A:
-+ case R_PPC_VLE_SDAREL_HI16D:
-+ case R_PPC_VLE_SDAREL_HA16A:
-+ case R_PPC_VLE_SDAREL_HA16D:
-+ {
-+ bfd_vma value;
-+ const char *name;
-+ //int reg;
-+ struct elf_link_hash_entry *sda = NULL;
-+
-+ if (sec == NULL || sec->output_section == NULL)
-+ {
-+ unresolved_reloc = TRUE;
-+ break;
-+ }
-+
-+ name = bfd_get_section_name (output_bfd, sec->output_section);
-+ if (((CONST_STRNEQ (name, ".sdata")
-+ && (name[6] == 0 || name[6] == '.'))
-+ || (CONST_STRNEQ (name, ".sbss")
-+ && (name[5] == 0 || name[5] == '.'))))
-+ {
-+ //reg = 13;
-+ sda = htab->sdata[0].sym;
-+ }
-+ else if (CONST_STRNEQ (name, ".sdata2")
-+ || CONST_STRNEQ (name, ".sbss2"))
-+ {
-+ //reg = 2;
-+ sda = htab->sdata[1].sym;
-+ }
-+ else
-+ {
-+ (*_bfd_error_handler)
-+ (_("%B: the target (%s) of a %s relocation is "
-+ "in the wrong output section (%s)"),
-+ input_bfd,
-+ sym_name,
-+ howto->name,
-+ name);
-+
-+ bfd_set_error (bfd_error_bad_value);
-+ ret = FALSE;
-+ continue;
-+ }
-+
-+ if (sda != NULL)
-+ {
-+ if (!is_static_defined (sda))
-+ {
-+ unresolved_reloc = TRUE;
-+ break;
-+ }
-+ }
-+
-+ value = sda->root.u.def.section->output_section->vma
-+ + sda->root.u.def.section->output_offset;
-+
-+ if (r_type == R_PPC_VLE_SDAREL_LO16A)
-+ {
-+ value = (value + addend) & 0xffff;
-+ ppc_elf_vle_split16 (output_bfd, contents, rel->r_offset,
-+ value, split16a_type);
-+ }
-+ else if (r_type == R_PPC_VLE_SDAREL_LO16D)
-+ {
-+ value = (value + addend) & 0xffff;
-+ ppc_elf_vle_split16 (output_bfd, contents, rel->r_offset,
-+ value, split16d_type);
-+ }
-+ else if (r_type == R_PPC_VLE_SDAREL_HI16A)
-+ {
-+ value = ((value + addend) >> 16) & 0xffff;
-+ ppc_elf_vle_split16 (output_bfd, contents, rel->r_offset,
-+ value, split16a_type);
-+ }
-+ else if (r_type == R_PPC_VLE_SDAREL_HI16D)
-+ {
-+ value = ((value + addend) >> 16) & 0xffff;
-+ ppc_elf_vle_split16 (output_bfd, contents, rel->r_offset,
-+ value, split16d_type);
-+ }
-+ else if (r_type == R_PPC_VLE_SDAREL_HA16A)
-+ {
-+ value += addend;
-+ value = (((value >> 16) + ((value & 0x8000) ? 1 : 0)) & 0xffff);
-+ ppc_elf_vle_split16 (output_bfd, contents, rel->r_offset,
-+ value, split16a_type);
-+ }
-+ else if (r_type == R_PPC_VLE_SDAREL_HA16D)
-+ {
-+ value += addend;
-+ value = (((value >> 16) + ((value & 0x8000) ? 1 : 0)) & 0xffff);
-+ ppc_elf_vle_split16 (output_bfd, contents, rel->r_offset,
-+ value, split16d_type);
-+ }
-+ }
-+ continue;
-+
-+ /* Relocate against the beginning of the section. */
-+ case R_PPC_SECTOFF:
-+ case R_PPC_SECTOFF_LO:
-+ case R_PPC_SECTOFF_HI:
-+ case R_PPC_SECTOFF_HA:
-+ if (sec == NULL || sec->output_section == NULL)
-+ {
-+ unresolved_reloc = TRUE;
-+ break;
-+ }
-+ addend -= sec->output_section->vma;
-+ break;
-+
-+ /* Negative relocations. */
-+ case R_PPC_EMB_NADDR32:
-+ case R_PPC_EMB_NADDR16:
-+ case R_PPC_EMB_NADDR16_LO:
-+ case R_PPC_EMB_NADDR16_HI:
-+ case R_PPC_EMB_NADDR16_HA:
-+ addend -= 2 * relocation;
-+ break;
-+
-+ case R_PPC_COPY:
-+ case R_PPC_GLOB_DAT:
-+ case R_PPC_JMP_SLOT:
-+ case R_PPC_RELATIVE:
-+ case R_PPC_IRELATIVE:
-+ case R_PPC_PLT32:
-+ case R_PPC_PLTREL32:
-+ case R_PPC_PLT16_LO:
-+ case R_PPC_PLT16_HI:
-+ case R_PPC_PLT16_HA:
-+ case R_PPC_ADDR30:
-+ case R_PPC_EMB_RELSEC16:
-+ case R_PPC_EMB_RELST_LO:
-+ case R_PPC_EMB_RELST_HI:
-+ case R_PPC_EMB_RELST_HA:
-+ case R_PPC_EMB_BIT_FLD:
-+ info->callbacks->einfo
-+ (_("%P: %B: relocation %s is not yet supported for symbol %s\n"),
-+ input_bfd,
-+ howto->name,
-+ sym_name);
-+
-+ bfd_set_error (bfd_error_invalid_operation);
-+ ret = FALSE;
-+ continue;
-+ }
-+
-+ /* Do any further special processing. */
-+ switch (r_type)
-+ {
-+ default:
-+ break;
-+
-+ case R_PPC_ADDR16_HA:
-+ case R_PPC_REL16_HA:
-+ case R_PPC_SECTOFF_HA:
-+ case R_PPC_TPREL16_HA:
-+ case R_PPC_DTPREL16_HA:
-+ case R_PPC_EMB_NADDR16_HA:
-+ case R_PPC_EMB_RELST_HA:
-+ /* It's just possible that this symbol is a weak symbol
-+ that's not actually defined anywhere. In that case,
-+ 'sec' would be NULL, and we should leave the symbol
-+ alone (it will be set to zero elsewhere in the link). */
-+ if (sec == NULL)
-+ break;
-+ /* Fall thru */
-+
-+ case R_PPC_PLT16_HA:
-+ case R_PPC_GOT16_HA:
-+ case R_PPC_GOT_TLSGD16_HA:
-+ case R_PPC_GOT_TLSLD16_HA:
-+ case R_PPC_GOT_TPREL16_HA:
-+ case R_PPC_GOT_DTPREL16_HA:
-+ /* Add 0x10000 if sign bit in 0:15 is set.
-+ Bits 0:15 are not used. */
-+ addend += 0x8000;
-+ break;
-+
-+ case R_PPC_ADDR16:
-+ case R_PPC_ADDR16_LO:
-+ case R_PPC_GOT16:
-+ case R_PPC_GOT16_LO:
-+ case R_PPC_SDAREL16:
-+ case R_PPC_SECTOFF:
-+ case R_PPC_SECTOFF_LO:
-+ case R_PPC_DTPREL16:
-+ case R_PPC_DTPREL16_LO:
-+ case R_PPC_TPREL16:
-+ case R_PPC_TPREL16_LO:
-+ case R_PPC_GOT_TLSGD16:
-+ case R_PPC_GOT_TLSGD16_LO:
-+ case R_PPC_GOT_TLSLD16:
-+ case R_PPC_GOT_TLSLD16_LO:
-+ case R_PPC_GOT_DTPREL16:
-+ case R_PPC_GOT_DTPREL16_LO:
-+ case R_PPC_GOT_TPREL16:
-+ case R_PPC_GOT_TPREL16_LO:
-+ {
-+ /* The 32-bit ABI lacks proper relocations to deal with
-+ certain 64-bit instructions. Prevent damage to bits
-+ that make up part of the insn opcode. */
-+ unsigned int insn, mask, lobit;
-+
-+ insn = bfd_get_32 (output_bfd, contents + rel->r_offset - d_offset);
-+ mask = 0;
-+ if (is_insn_ds_form (insn))
-+ mask = 3;
-+ else if (is_insn_dq_form (insn))
-+ mask = 15;
-+ else
-+ break;
-+ lobit = mask & (relocation + addend);
-+ if (lobit != 0)
-+ {
-+ addend -= lobit;
-+ info->callbacks->einfo
-+ (_("%P: %H: error: %s against `%s' not a multiple of %u\n"),
-+ input_bfd, input_section, rel->r_offset,
-+ howto->name, sym_name, mask + 1);
-+ bfd_set_error (bfd_error_bad_value);
-+ ret = FALSE;
-+ }
-+ addend += insn & mask;
-+ }
-+ break;
-+ }
-+
-+#ifdef DEBUG
-+ fprintf (stderr, "\ttype = %s (%d), name = %s, symbol index = %ld, "
-+ "offset = %ld, addend = %ld\n",
-+ howto->name,
-+ (int) r_type,
-+ sym_name,
-+ r_symndx,
-+ (long) rel->r_offset,
-+ (long) addend);
-+#endif
-+
-+ if (unresolved_reloc
-+ && !((input_section->flags & SEC_DEBUGGING) != 0
-+ && h->def_dynamic)
-+ && _bfd_elf_section_offset (output_bfd, info, input_section,
-+ rel->r_offset) != (bfd_vma) -1)
-+ {
-+ info->callbacks->einfo
-+ (_("%P: %H: unresolvable %s relocation against symbol `%s'\n"),
-+ input_bfd, input_section, rel->r_offset,
-+ howto->name,
-+ sym_name);
-+ ret = FALSE;
-+ }
-+
-+ r = _bfd_final_link_relocate (howto,
-+ input_bfd,
-+ input_section,
-+ contents,
-+ rel->r_offset,
-+ relocation,
-+ addend);
-+
-+#ifdef DEBUG
-+ fprintf (stderr, "%p %p %p\n", (void *)rel->r_offset, (void *)relocation, (void *)addend);
-+#endif
-+ if (r != bfd_reloc_ok)
-+ {
-+ if (r == bfd_reloc_overflow)
-+ {
-+ if (warned)
-+ continue;
-+ if (h != NULL
-+ && h->root.type == bfd_link_hash_undefweak
-+ && howto->pc_relative)
-+ {
-+ /* Assume this is a call protected by other code that
-+ detect the symbol is undefined. If this is the case,
-+ we can safely ignore the overflow. If not, the
-+ program is hosed anyway, and a little warning isn't
-+ going to help. */
-+
-+ continue;
-+ }
-+
-+ if (! (*info->callbacks->reloc_overflow) (info,
-+ (h ? &h->root : NULL),
-+ sym_name,
-+ howto->name,
-+ rel->r_addend,
-+ input_bfd,
-+ input_section,
-+ rel->r_offset))
-+ return FALSE;
-+ }
-+ else
-+ {
-+ info->callbacks->einfo
-+ (_("%P: %H: %s reloc against `%s': error %d\n"),
-+ input_bfd, input_section, rel->r_offset,
-+ howto->name, sym_name, (int) r);
-+ ret = FALSE;
-+ }
-+ }
-+ }
-+
-+#ifdef DEBUG
-+ fprintf (stderr, "\n");
-+#endif
-+
-+ return ret;
-+}
-+
-+/* Finish up dynamic symbol handling. We set the contents of various
-+ dynamic sections here. */
-+
-+static bfd_boolean
-+ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
-+ struct bfd_link_info *info,
-+ struct elf_link_hash_entry *h,
-+ Elf_Internal_Sym *sym)
-+{
-+ struct ppc_elf_link_hash_table *htab;
-+ struct plt_entry *ent;
-+ bfd_boolean doneone;
-+
-+#ifdef DEBUG
-+ fprintf (stderr, "ppc_elf_finish_dynamic_symbol called for %s",
-+ h->root.root.string);
-+#endif
-+
-+ htab = ppc_elf_hash_table (info);
-+ BFD_ASSERT (htab->elf.dynobj != NULL);
-+
-+ doneone = FALSE;
-+ for (ent = h->plt.plist; ent != NULL; ent = ent->next)
-+ if (ent->plt.offset != (bfd_vma) -1)
-+ {
-+ if (!doneone)
-+ {
-+ Elf_Internal_Rela rela;
-+ bfd_byte *loc;
-+ bfd_vma reloc_index;
-+
-+ if (htab->plt_type == PLT_NEW
-+ || !htab->elf.dynamic_sections_created
-+ || h->dynindx == -1)
-+ reloc_index = ent->plt.offset / 4;
-+ else
-+ {
-+ reloc_index = ((ent->plt.offset - htab->plt_initial_entry_size)
-+ / htab->plt_slot_size);
-+ if (reloc_index > PLT_NUM_SINGLE_ENTRIES
-+ && htab->plt_type == PLT_OLD)
-+ reloc_index -= (reloc_index - PLT_NUM_SINGLE_ENTRIES) / 2;
-+ }
-+
-+ /* This symbol has an entry in the procedure linkage table.
-+ Set it up. */
-+ if (htab->plt_type == PLT_VXWORKS
-+ && htab->elf.dynamic_sections_created
-+ && h->dynindx != -1)
-+ {
-+ bfd_vma got_offset;
-+ const bfd_vma *plt_entry;
-+
-+ /* The first three entries in .got.plt are reserved. */
-+ got_offset = (reloc_index + 3) * 4;
-+
-+ /* Use the right PLT. */
-+ plt_entry = info->shared ? ppc_elf_vxworks_pic_plt_entry
-+ : ppc_elf_vxworks_plt_entry;
-+
-+ /* Fill in the .plt on VxWorks. */
-+ if (info->shared)
-+ {
-+ bfd_put_32 (output_bfd,
-+ plt_entry[0] | PPC_HA (got_offset),
-+ htab->plt->contents + ent->plt.offset + 0);
-+ bfd_put_32 (output_bfd,
-+ plt_entry[1] | PPC_LO (got_offset),
-+ htab->plt->contents + ent->plt.offset + 4);
-+ }
-+ else
-+ {
-+ bfd_vma got_loc = got_offset + SYM_VAL (htab->elf.hgot);
-+
-+ bfd_put_32 (output_bfd,
-+ plt_entry[0] | PPC_HA (got_loc),
-+ htab->plt->contents + ent->plt.offset + 0);
-+ bfd_put_32 (output_bfd,
-+ plt_entry[1] | PPC_LO (got_loc),
-+ htab->plt->contents + ent->plt.offset + 4);
-+ }
-+
-+ bfd_put_32 (output_bfd, plt_entry[2],
-+ htab->plt->contents + ent->plt.offset + 8);
-+ bfd_put_32 (output_bfd, plt_entry[3],
-+ htab->plt->contents + ent->plt.offset + 12);
-+
-+ /* This instruction is an immediate load. The value loaded is
-+ the byte offset of the R_PPC_JMP_SLOT relocation from the
-+ start of the .rela.plt section. The value is stored in the
-+ low-order 16 bits of the load instruction. */
-+ /* NOTE: It appears that this is now an index rather than a
-+ prescaled offset. */
-+ bfd_put_32 (output_bfd,
-+ plt_entry[4] | reloc_index,
-+ htab->plt->contents + ent->plt.offset + 16);
-+ /* This instruction is a PC-relative branch whose target is
-+ the start of the PLT section. The address of this branch
-+ instruction is 20 bytes beyond the start of this PLT entry.
-+ The address is encoded in bits 6-29, inclusive. The value
-+ stored is right-shifted by two bits, permitting a 26-bit
-+ offset. */
-+ bfd_put_32 (output_bfd,
-+ (plt_entry[5]
-+ | (-(ent->plt.offset + 20) & 0x03fffffc)),
-+ htab->plt->contents + ent->plt.offset + 20);
-+ bfd_put_32 (output_bfd, plt_entry[6],
-+ htab->plt->contents + ent->plt.offset + 24);
-+ bfd_put_32 (output_bfd, plt_entry[7],
-+ htab->plt->contents + ent->plt.offset + 28);
-+
-+ /* Fill in the GOT entry corresponding to this PLT slot with
-+ the address immediately after the "bctr" instruction
-+ in this PLT entry. */
-+ bfd_put_32 (output_bfd, (htab->plt->output_section->vma
-+ + htab->plt->output_offset
-+ + ent->plt.offset + 16),
-+ htab->sgotplt->contents + got_offset);
-+
-+ if (!info->shared)
-+ {
-+ /* Fill in a couple of entries in .rela.plt.unloaded. */
-+ loc = htab->srelplt2->contents
-+ + ((VXWORKS_PLTRESOLVE_RELOCS + reloc_index
-+ * VXWORKS_PLT_NON_JMP_SLOT_RELOCS)
-+ * sizeof (Elf32_External_Rela));
-+
-+ /* Provide the @ha relocation for the first instruction. */
-+ rela.r_offset = (htab->plt->output_section->vma
-+ + htab->plt->output_offset
-+ + ent->plt.offset + 2);
-+ rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx,
-+ R_PPC_ADDR16_HA);
-+ rela.r_addend = got_offset;
-+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
-+ loc += sizeof (Elf32_External_Rela);
-+
-+ /* Provide the @l relocation for the second instruction. */
-+ rela.r_offset = (htab->plt->output_section->vma
-+ + htab->plt->output_offset
-+ + ent->plt.offset + 6);
-+ rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx,
-+ R_PPC_ADDR16_LO);
-+ rela.r_addend = got_offset;
-+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
-+ loc += sizeof (Elf32_External_Rela);
-+
-+ /* Provide a relocation for the GOT entry corresponding to this
-+ PLT slot. Point it at the middle of the .plt entry. */
-+ rela.r_offset = (htab->sgotplt->output_section->vma
-+ + htab->sgotplt->output_offset
-+ + got_offset);
-+ rela.r_info = ELF32_R_INFO (htab->elf.hplt->indx,
-+ R_PPC_ADDR32);
-+ rela.r_addend = ent->plt.offset + 16;
-+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
-+ }
-+
-+ /* VxWorks uses non-standard semantics for R_PPC_JMP_SLOT.
-+ In particular, the offset for the relocation is not the
-+ address of the PLT entry for this function, as specified
-+ by the ABI. Instead, the offset is set to the address of
-+ the GOT slot for this function. See EABI 4.4.4.1. */
-+ rela.r_offset = (htab->sgotplt->output_section->vma
-+ + htab->sgotplt->output_offset
-+ + got_offset);
-+
-+ }
-+ else
-+ {
-+ asection *splt = htab->plt;
-+ if (!htab->elf.dynamic_sections_created
-+ || h->dynindx == -1)
-+ splt = htab->iplt;
-+
-+ rela.r_offset = (splt->output_section->vma
-+ + splt->output_offset
-+ + ent->plt.offset);
-+#ifdef DEBUG
-+ fprintf (stderr, " r_offset = %p ", (void *)rela.r_offset);
-+#endif
-+ if (htab->plt_type == PLT_OLD
-+ || !htab->elf.dynamic_sections_created
-+ || h->dynindx == -1)
-+ {
-+ /* We don't need to fill in the .plt. The ppc dynamic
-+ linker will fill it in. */
-+#ifdef DEBUG
-+ fprintf (stderr, " not filling in .plt ");
-+#endif
-+ }
-+ else
-+ {
-+ bfd_vma val = (htab->glink_pltresolve + ent->plt.offset
-+ + htab->glink->output_section->vma
-+ + htab->glink->output_offset);
-+ bfd_put_32 (output_bfd, val,
-+ splt->contents + ent->plt.offset);
-+ }
-+ }
-+
-+ /* Fill in the entry in the .rela.plt section. */
-+ rela.r_addend = 0;
-+ if (!htab->elf.dynamic_sections_created
-+ || h->dynindx == -1)
-+ {
-+ BFD_ASSERT (h->type == STT_GNU_IFUNC
-+ && h->def_regular
-+ && (h->root.type == bfd_link_hash_defined
-+ || h->root.type == bfd_link_hash_defweak));
-+ rela.r_info = ELF32_R_INFO (0, R_PPC_IRELATIVE);
-+ rela.r_addend = SYM_VAL (h);
-+ }
-+ else
-+ rela.r_info = ELF32_R_INFO (h->dynindx, R_PPC_JMP_SLOT);
-+
-+ if (!htab->elf.dynamic_sections_created
-+ || h->dynindx == -1)
-+ loc = (htab->reliplt->contents
-+ + (htab->reliplt->reloc_count++
-+ * sizeof (Elf32_External_Rela)));
-+ else
-+ loc = (htab->relplt->contents
-+ + reloc_index * sizeof (Elf32_External_Rela));
-+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
-+
-+#ifdef DEBUG
-+ fprintf (stderr, " r_offset = %p r_addednd = %p, r_info = 0x%08x, h->def_regular = %d", (void *)rela.r_offset, (void *)rela.r_addend, (unsigned int)rela.r_info, (int)h->def_regular);
-+#endif
-+ if (!h->def_regular)
-+ {
-+ /* Mark the symbol as undefined, rather than as
-+ defined in the .plt section. Leave the value if
-+ there were any relocations where pointer equality
-+ matters (this is a clue for the dynamic linker, to
-+ make function pointer comparisons work between an
-+ application and shared library), otherwise set it
-+ to zero. */
-+ sym->st_shndx = SHN_UNDEF;
-+ if (!h->pointer_equality_needed)
-+ {
-+ /* THF: This is peculiar. The compiler generates a R_PPC_REL24 for externally referenced
-+ * symbols impoted from libc.so. Relocation in elf.library requires the symbol to have it's .plt
-+ * stub value, but the linker specifically clears the value to 0, resulting in run-time
-+ * errors when the binary tries to call libc functions.
-+ */
-+ // sym->st_value = 0;
-+ }
-+ else if (!h->ref_regular_nonweak)
-+ {
-+ /* This breaks function pointer comparisons, but
-+ that is better than breaking tests for a NULL
-+ function pointer. */
-+ sym->st_value = 0;
-+ }
-+ }
-+ else if (h->type == STT_GNU_IFUNC
-+ && !info->shared)
-+ {
-+ /* Set the value of ifunc symbols in a non-pie
-+ executable to the glink entry. This is to avoid
-+ text relocations. We can't do this for ifunc in
-+ allocate_dynrelocs, as we do for normal dynamic
-+ function symbols with plt entries, because we need
-+ to keep the original value around for the ifunc
-+ relocation. */
-+ sym->st_shndx = (_bfd_elf_section_from_bfd_section
-+ (output_bfd, htab->glink->output_section));
-+ sym->st_value = (ent->glink_offset
-+ + htab->glink->output_offset
-+ + htab->glink->output_section->vma);
-+ }
-+ doneone = TRUE;
-+ }
-+
-+ if (htab->plt_type == PLT_NEW
-+ || !htab->elf.dynamic_sections_created
-+ || h->dynindx == -1)
-+ {
-+ unsigned char *p;
-+ asection *splt = htab->plt;
-+ if (!htab->elf.dynamic_sections_created
-+ || h->dynindx == -1)
-+ splt = htab->iplt;
-+
-+ p = (unsigned char *) htab->glink->contents + ent->glink_offset;
-+
-+ if (h == htab->tls_get_addr && !htab->no_tls_get_addr_opt)
-+ {
-+ bfd_put_32 (output_bfd, LWZ_11_3, p);
-+ p += 4;
-+ bfd_put_32 (output_bfd, LWZ_12_3 + 4, p);
-+ p += 4;
-+ bfd_put_32 (output_bfd, MR_0_3, p);
-+ p += 4;
-+ bfd_put_32 (output_bfd, CMPWI_11_0, p);
-+ p += 4;
-+ bfd_put_32 (output_bfd, ADD_3_12_2, p);
-+ p += 4;
-+ bfd_put_32 (output_bfd, BEQLR, p);
-+ p += 4;
-+ bfd_put_32 (output_bfd, MR_3_0, p);
-+ p += 4;
-+ bfd_put_32 (output_bfd, NOP, p);
-+ p += 4;
-+ }
-+
-+ write_glink_stub (ent, splt, p, info);
-+
-+ if (!info->shared)
-+ /* We only need one non-PIC glink stub. */
-+ break;
-+ }
-+ else
-+ break;
-+ }
-+
-+ if (h->needs_copy)
-+ {
-+ asection *s;
-+ Elf_Internal_Rela rela;
-+ bfd_byte *loc;
-+
-+ /* This symbols needs a copy reloc. Set it up. */
-+
-+#ifdef DEBUG
-+ fprintf (stderr, ", copy");
-+#endif
-+
-+ BFD_ASSERT (h->dynindx != -1);
-+
-+ if (ppc_elf_hash_entry (h)->has_sda_refs)
-+ s = htab->relsbss;
-+ else
-+ s = htab->relbss;
-+ BFD_ASSERT (s != NULL);
-+
-+ rela.r_offset = SYM_VAL (h);
-+ rela.r_info = ELF32_R_INFO (h->dynindx, R_PPC_COPY);
-+ rela.r_addend = 0;
-+ loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
-+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
-+ }
-+
-+#ifdef DEBUG
-+ fprintf (stderr, " SYM_VAL(%p) ", (void *)SYM_VAL(h));
-+#endif
-+#ifdef DEBUG
-+ fprintf (stderr, "\n");
-+#endif
-+
-+ return TRUE;
-+}
-+
-+static enum elf_reloc_type_class
-+ppc_elf_reloc_type_class (const Elf_Internal_Rela *rela)
-+{
-+ switch (ELF32_R_TYPE (rela->r_info))
-+ {
-+ case R_PPC_RELATIVE:
-+ return reloc_class_relative;
-+ case R_PPC_REL24:
-+ case R_PPC_ADDR24:
-+ case R_PPC_JMP_SLOT:
-+ return reloc_class_plt;
-+ case R_PPC_COPY:
-+ return reloc_class_copy;
-+ default:
-+ return reloc_class_normal;
-+ }
-+}
-+
-+/* Finish up the dynamic sections. */
-+
-+static bfd_boolean
-+ppc_elf_finish_dynamic_sections (bfd *output_bfd,
-+ struct bfd_link_info *info)
-+{
-+ asection *sdyn;
-+ asection *splt;
-+ struct ppc_elf_link_hash_table *htab;
-+ bfd_vma got;
-+ bfd *dynobj;
-+ bfd_boolean ret = TRUE;
-+
-+#ifdef DEBUG
-+ fprintf (stderr, "ppc_elf_finish_dynamic_sections called\n");
-+#endif
-+
-+ htab = ppc_elf_hash_table (info);
-+ dynobj = elf_hash_table (info)->dynobj;
-+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
-+ if (htab->is_vxworks)
-+ splt = bfd_get_linker_section (dynobj, ".plt");
-+ else
-+ splt = NULL;
-+
-+ got = 0;
-+ if (htab->elf.hgot != NULL)
-+ got = SYM_VAL (htab->elf.hgot);
-+
-+ if (htab->elf.dynamic_sections_created)
-+ {
-+ Elf32_External_Dyn *dyncon, *dynconend;
-+
-+ BFD_ASSERT (htab->plt != NULL && sdyn != NULL);
-+
-+ dyncon = (Elf32_External_Dyn *) sdyn->contents;
-+ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
-+ for (; dyncon < dynconend; dyncon++)
-+ {
-+ Elf_Internal_Dyn dyn;
-+ asection *s;
-+
-+ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
-+
-+ switch (dyn.d_tag)
-+ {
-+ case DT_PLTGOT:
-+ if (htab->is_vxworks)
-+ s = htab->sgotplt;
-+ else
-+ s = htab->plt;
-+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
-+ break;
-+
-+ case DT_PLTRELSZ:
-+ dyn.d_un.d_val = htab->relplt->size;
-+ break;
-+
-+ case DT_JMPREL:
-+ s = htab->relplt;
-+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
-+ break;
-+
-+ case DT_PPC_GOT:
-+ dyn.d_un.d_ptr = got;
-+ break;
-+
-+ case DT_RELASZ:
-+ if (htab->is_vxworks)
-+ {
-+ if (htab->relplt)
-+ dyn.d_un.d_ptr -= htab->relplt->size;
-+ break;
-+ }
-+ continue;
-+
-+ default:
-+ if (htab->is_vxworks
-+ && elf_vxworks_finish_dynamic_entry (output_bfd, &dyn))
-+ break;
-+ continue;
-+ }
-+
-+ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
-+ }
-+ }
-+
-+ if (htab->got != NULL)
-+ {
-+ if (htab->elf.hgot->root.u.def.section == htab->got
-+ || htab->elf.hgot->root.u.def.section == htab->sgotplt)
-+ {
-+ unsigned char *p = htab->elf.hgot->root.u.def.section->contents;
-+
-+ p += htab->elf.hgot->root.u.def.value;
-+ if (htab->plt_type == PLT_OLD)
-+ {
-+ /* Add a blrl instruction at _GLOBAL_OFFSET_TABLE_-4
-+ so that a function can easily find the address of
-+ _GLOBAL_OFFSET_TABLE_. */
-+ BFD_ASSERT (htab->elf.hgot->root.u.def.value - 4
-+ < htab->elf.hgot->root.u.def.section->size);
-+ bfd_put_32 (output_bfd, 0x4e800021, p - 4);
-+ }
-+
-+ if (sdyn != NULL)
-+ {
-+ bfd_vma val = sdyn->output_section->vma + sdyn->output_offset;
-+ BFD_ASSERT (htab->elf.hgot->root.u.def.value
-+ < htab->elf.hgot->root.u.def.section->size);
-+ bfd_put_32 (output_bfd, val, p);
-+ }
-+ }
-+ else
-+ {
-+ info->callbacks->einfo (_("%P: %s not defined in linker created %s\n"),
-+ htab->elf.hgot->root.root.string,
-+ (htab->sgotplt != NULL
-+ ? htab->sgotplt->name : htab->got->name));
-+ bfd_set_error (bfd_error_bad_value);
-+ ret = FALSE;
-+ }
-+
-+ elf_section_data (htab->got->output_section)->this_hdr.sh_entsize = 4;
-+ }
-+
-+ /* Fill in the first entry in the VxWorks procedure linkage table. */
-+ if (splt && splt->size > 0)
-+ {
-+ /* Use the right PLT. */
-+ const bfd_vma *plt_entry = (info->shared
-+ ? ppc_elf_vxworks_pic_plt0_entry
-+ : ppc_elf_vxworks_plt0_entry);
-+
-+ if (!info->shared)
-+ {
-+ bfd_vma got_value = SYM_VAL (htab->elf.hgot);
-+
-+ bfd_put_32 (output_bfd, plt_entry[0] | PPC_HA (got_value),
-+ splt->contents + 0);
-+ bfd_put_32 (output_bfd, plt_entry[1] | PPC_LO (got_value),
-+ splt->contents + 4);
-+ }
-+ else
-+ {
-+ bfd_put_32 (output_bfd, plt_entry[0], splt->contents + 0);
-+ bfd_put_32 (output_bfd, plt_entry[1], splt->contents + 4);
-+ }
-+ bfd_put_32 (output_bfd, plt_entry[2], splt->contents + 8);
-+ bfd_put_32 (output_bfd, plt_entry[3], splt->contents + 12);
-+ bfd_put_32 (output_bfd, plt_entry[4], splt->contents + 16);
-+ bfd_put_32 (output_bfd, plt_entry[5], splt->contents + 20);
-+ bfd_put_32 (output_bfd, plt_entry[6], splt->contents + 24);
-+ bfd_put_32 (output_bfd, plt_entry[7], splt->contents + 28);
-+
-+ if (! info->shared)
-+ {
-+ Elf_Internal_Rela rela;
-+ bfd_byte *loc;
-+
-+ loc = htab->srelplt2->contents;
-+
-+ /* Output the @ha relocation for the first instruction. */
-+ rela.r_offset = (htab->plt->output_section->vma
-+ + htab->plt->output_offset
-+ + 2);
-+ rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_PPC_ADDR16_HA);
-+ rela.r_addend = 0;
-+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
-+ loc += sizeof (Elf32_External_Rela);
-+
-+ /* Output the @l relocation for the second instruction. */
-+ rela.r_offset = (htab->plt->output_section->vma
-+ + htab->plt->output_offset
-+ + 6);
-+ rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_PPC_ADDR16_LO);
-+ rela.r_addend = 0;
-+ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
-+ loc += sizeof (Elf32_External_Rela);
-+
-+ /* Fix up the remaining relocations. They may have the wrong
-+ symbol index for _G_O_T_ or _P_L_T_ depending on the order
-+ in which symbols were output. */
-+ while (loc < htab->srelplt2->contents + htab->srelplt2->size)
-+ {
-+ Elf_Internal_Rela rel;
-+
-+ bfd_elf32_swap_reloc_in (output_bfd, loc, &rel);
-+ rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_PPC_ADDR16_HA);
-+ bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
-+ loc += sizeof (Elf32_External_Rela);
-+
-+ bfd_elf32_swap_reloc_in (output_bfd, loc, &rel);
-+ rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_PPC_ADDR16_LO);
-+ bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
-+ loc += sizeof (Elf32_External_Rela);
-+
-+ bfd_elf32_swap_reloc_in (output_bfd, loc, &rel);
-+ rel.r_info = ELF32_R_INFO (htab->elf.hplt->indx, R_PPC_ADDR32);
-+ bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
-+ loc += sizeof (Elf32_External_Rela);
-+ }
-+ }
-+ }
-+
-+ if (htab->glink != NULL
-+ && htab->glink->contents != NULL
-+ && htab->elf.dynamic_sections_created)
-+ {
-+ unsigned char *p;
-+ unsigned char *endp;
-+ bfd_vma res0;
-+ unsigned int i;
-+
-+ /*
-+ * PIC glink code is the following:
-+ *
-+ * # ith PLT code stub.
-+ * addis 11,30,(plt+(i-1)*4-got)@ha
-+ * lwz 11,(plt+(i-1)*4-got)@l(11)
-+ * mtctr 11
-+ * bctr
-+ *
-+ * # A table of branches, one for each plt entry.
-+ * # The idea is that the plt call stub loads ctr and r11 with these
-+ * # addresses, so (r11 - res_0) gives the plt index * 4.
-+ * res_0: b PLTresolve
-+ * res_1: b PLTresolve
-+ * .
-+ * # Some number of entries towards the end can be nops
-+ * res_n_m3: nop
-+ * res_n_m2: nop
-+ * res_n_m1:
-+ *
-+ * PLTresolve:
-+ * addis 11,11,(1f-res_0)@ha
-+ * mflr 0
-+ * bcl 20,31,1f
-+ * 1: addi 11,11,(1b-res_0)@l
-+ * mflr 12
-+ * mtlr 0
-+ * sub 11,11,12 # r11 = index * 4
-+ * addis 12,12,(got+4-1b)@ha
-+ * lwz 0,(got+4-1b)@l(12) # got[1] address of dl_runtime_resolve
-+ * lwz 12,(got+8-1b)@l(12) # got[2] contains the map address
-+ * mtctr 0
-+ * add 0,11,11
-+ * add 11,0,11 # r11 = index * 12 = reloc offset.
-+ * bctr
-+ */
-+ static const unsigned int pic_plt_resolve[] =
-+ {
-+ ADDIS_11_11,
-+ MFLR_0,
-+ BCL_20_31,
-+ ADDI_11_11,
-+ MFLR_12,
-+ MTLR_0,
-+ SUB_11_11_12,
-+ ADDIS_12_12,
-+ LWZ_0_12,
-+ LWZ_12_12,
-+ MTCTR_0,
-+ ADD_0_11_11,
-+ ADD_11_0_11,
-+ BCTR,
-+ NOP,
-+ NOP
-+ };
-+
-+ /*
-+ * Non-PIC glink code is a little simpler.
-+ *
-+ * # ith PLT code stub.
-+ * lis 11,(plt+(i-1)*4)@ha
-+ * lwz 11,(plt+(i-1)*4)@l(11)
-+ * mtctr 11
-+ * bctr
-+ *
-+ * The branch table is the same, then comes
-+ *
-+ * PLTresolve:
-+ * lis 12,(got+4)@ha
-+ * addis 11,11,(-res_0)@ha
-+ * lwz 0,(got+4)@l(12) # got[1] address of dl_runtime_resolve
-+ * addi 11,11,(-res_0)@l # r11 = index * 4
-+ * mtctr 0
-+ * add 0,11,11
-+ * lwz 12,(got+8)@l(12) # got[2] contains the map address
-+ * add 11,0,11 # r11 = index * 12 = reloc offset.
-+ * bctr
-+ */
-+ static const unsigned int plt_resolve[] =
-+ {
-+ LIS_12,
-+ ADDIS_11_11,
-+ LWZ_0_12,
-+ ADDI_11_11,
-+ MTCTR_0,
-+ ADD_0_11_11,
-+ LWZ_12_12,
-+ ADD_11_0_11,
-+ BCTR,
-+ NOP,
-+ NOP,
-+ NOP,
-+ NOP,
-+ NOP,
-+ NOP,
-+ NOP
-+ };
-+
-+ if (ARRAY_SIZE (pic_plt_resolve) != GLINK_PLTRESOLVE / 4)
-+ abort ();
-+ if (ARRAY_SIZE (plt_resolve) != GLINK_PLTRESOLVE / 4)
-+ abort ();
-+
-+ /* Build the branch table, one for each plt entry (less one),
-+ and perhaps some padding. */
-+ p = htab->glink->contents;
-+ p += htab->glink_pltresolve;
-+ endp = htab->glink->contents;
-+ endp += htab->glink->size - GLINK_PLTRESOLVE;
-+ while (p < endp - 8 * 4)
-+ {
-+ bfd_put_32 (output_bfd, B + endp - p, p);
-+ p += 4;
-+ }
-+ while (p < endp)
-+ {
-+ bfd_put_32 (output_bfd, NOP, p);
-+ p += 4;
-+ }
-+
-+ res0 = (htab->glink_pltresolve
-+ + htab->glink->output_section->vma
-+ + htab->glink->output_offset);
-+
-+ /* Last comes the PLTresolve stub. */
-+ if (info->shared)
-+ {
-+ bfd_vma bcl;
-+
-+ for (i = 0; i < ARRAY_SIZE (pic_plt_resolve); i++)
-+ {
-+ bfd_put_32 (output_bfd, pic_plt_resolve[i], p);
-+ p += 4;
-+ }
-+ p -= 4 * ARRAY_SIZE (pic_plt_resolve);
-+
-+ bcl = (htab->glink->size - GLINK_PLTRESOLVE + 3*4
-+ + htab->glink->output_section->vma
-+ + htab->glink->output_offset);
-+
-+ bfd_put_32 (output_bfd,
-+ ADDIS_11_11 + PPC_HA (bcl - res0), p + 0*4);
-+ bfd_put_32 (output_bfd,
-+ ADDI_11_11 + PPC_LO (bcl - res0), p + 3*4);
-+ bfd_put_32 (output_bfd,
-+ ADDIS_12_12 + PPC_HA (got + 4 - bcl), p + 7*4);
-+ if (PPC_HA (got + 4 - bcl) == PPC_HA (got + 8 - bcl))
-+ {
-+ bfd_put_32 (output_bfd,
-+ LWZ_0_12 + PPC_LO (got + 4 - bcl), p + 8*4);
-+ bfd_put_32 (output_bfd,
-+ LWZ_12_12 + PPC_LO (got + 8 - bcl), p + 9*4);
-+ }
-+ else
-+ {
-+ bfd_put_32 (output_bfd,
-+ LWZU_0_12 + PPC_LO (got + 4 - bcl), p + 8*4);
-+ bfd_put_32 (output_bfd,
-+ LWZ_12_12 + 4, p + 9*4);
-+ }
-+ }
-+ else
-+ {
-+ for (i = 0; i < ARRAY_SIZE (plt_resolve); i++)
-+ {
-+ bfd_put_32 (output_bfd, plt_resolve[i], p);
-+ p += 4;
-+ }
-+ p -= 4 * ARRAY_SIZE (plt_resolve);
-+
-+ bfd_put_32 (output_bfd,
-+ LIS_12 + PPC_HA (got + 4), p + 0*4);
-+ bfd_put_32 (output_bfd,
-+ ADDIS_11_11 + PPC_HA (-res0), p + 1*4);
-+ bfd_put_32 (output_bfd,
-+ ADDI_11_11 + PPC_LO (-res0), p + 3*4);
-+ if (PPC_HA (got + 4) == PPC_HA (got + 8))
-+ {
-+ bfd_put_32 (output_bfd,
-+ LWZ_0_12 + PPC_LO (got + 4), p + 2*4);
-+ bfd_put_32 (output_bfd,
-+ LWZ_12_12 + PPC_LO (got + 8), p + 6*4);
-+ }
-+ else
-+ {
-+ bfd_put_32 (output_bfd,
-+ LWZU_0_12 + PPC_LO (got + 4), p + 2*4);
-+ bfd_put_32 (output_bfd,
-+ LWZ_12_12 + 4, p + 6*4);
-+ }
-+ }
-+ }
-+
-+ if (htab->glink_eh_frame != NULL
-+ && htab->glink_eh_frame->contents != NULL)
-+ {
-+ unsigned char *p = htab->glink_eh_frame->contents;
-+ bfd_vma val;
-+
-+ p += sizeof (glink_eh_frame_cie);
-+ /* FDE length. */
-+ p += 4;
-+ /* CIE pointer. */
-+ p += 4;
-+ /* Offset to .glink. */
-+ val = (htab->glink->output_section->vma
-+ + htab->glink->output_offset);
-+ val -= (htab->glink_eh_frame->output_section->vma
-+ + htab->glink_eh_frame->output_offset);
-+ val -= p - htab->glink_eh_frame->contents;
-+ bfd_put_32 (htab->elf.dynobj, val, p);
-+
-+ if (htab->glink_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME
-+ && !_bfd_elf_write_section_eh_frame (output_bfd, info,
-+ htab->glink_eh_frame,
-+ htab->glink_eh_frame->contents))
-+ return FALSE;
-+ }
-+
-+ return ret;
-+}
-+
-+#define TARGET_BIG_SYM bfd_elf32_amigaos_vec
-+#define TARGET_BIG_NAME "elf32-amigaos"
-+#define ELF_ARCH bfd_arch_powerpc
-+#define ELF_TARGET_ID PPC32_ELF_DATA
-+#define ELF_MACHINE_CODE EM_PPC
-+#ifdef __QNXTARGET__
-+#define ELF_MAXPAGESIZE 0x1000
-+#else
-+#define ELF_MAXPAGESIZE 0x10000
-+#endif
-+#define ELF_MINPAGESIZE 0x1000
-+#define ELF_COMMONPAGESIZE 0x1000
-+#define elf_info_to_howto ppc_elf_info_to_howto
-+
-+#ifdef EM_CYGNUS_POWERPC
-+#define ELF_MACHINE_ALT1 EM_CYGNUS_POWERPC
-+#endif
-+
-+#ifdef EM_PPC_OLD
-+#define ELF_MACHINE_ALT2 EM_PPC_OLD
-+#endif
-+
-+#define elf_backend_plt_not_loaded 1
-+#define elf_backend_can_gc_sections 1
-+#define elf_backend_can_refcount 1
-+#define elf_backend_rela_normal 1
-+
-+#define bfd_elf32_mkobject ppc_elf_mkobject
-+#define bfd_elf32_bfd_merge_private_bfd_data ppc_elf_merge_private_bfd_data
-+#define bfd_elf32_bfd_relax_section ppc_elf_relax_section
-+#define bfd_elf32_bfd_reloc_type_lookup ppc_elf_reloc_type_lookup
-+#define bfd_elf32_bfd_reloc_name_lookup ppc_elf_reloc_name_lookup
-+#define bfd_elf32_bfd_set_private_flags ppc_elf_set_private_flags
-+#define bfd_elf32_bfd_link_hash_table_create ppc_elf_link_hash_table_create
-+#define bfd_elf32_get_synthetic_symtab ppc_elf_get_synthetic_symtab
-+
-+#define elf_backend_object_p ppc_elf_object_p
-+#define elf_backend_gc_mark_hook ppc_elf_gc_mark_hook
-+#define elf_backend_gc_sweep_hook ppc_elf_gc_sweep_hook
-+#define elf_backend_section_from_shdr ppc_elf_section_from_shdr
-+#define elf_backend_relocate_section ppc_elf_relocate_section
-+#define elf_backend_create_dynamic_sections ppc_elf_create_dynamic_sections
-+#define elf_backend_check_relocs ppc_elf_check_relocs
-+#define elf_backend_copy_indirect_symbol ppc_elf_copy_indirect_symbol
-+#define elf_backend_adjust_dynamic_symbol ppc_elf_adjust_dynamic_symbol
-+#define elf_backend_add_symbol_hook ppc_elf_add_symbol_hook
-+#define elf_backend_size_dynamic_sections ppc_elf_size_dynamic_sections
-+#define elf_backend_hash_symbol ppc_elf_hash_symbol
-+#define elf_backend_finish_dynamic_symbol ppc_elf_finish_dynamic_symbol
-+#define elf_backend_finish_dynamic_sections ppc_elf_finish_dynamic_sections
-+#define elf_backend_fake_sections ppc_elf_fake_sections
-+#define elf_backend_additional_program_headers ppc_elf_additional_program_headers
-+#define elf_backend_modify_segment_map ppc_elf_amigaos_modify_segment_map
-+#define elf_backend_grok_prstatus ppc_elf_grok_prstatus
-+#define elf_backend_grok_psinfo ppc_elf_grok_psinfo
-+#define elf_backend_write_core_note ppc_elf_write_core_note
-+#define elf_backend_reloc_type_class ppc_elf_reloc_type_class
-+#define elf_backend_begin_write_processing ppc_elf_amigaos_begin_write_processing
-+#define elf_backend_final_write_processing ppc_elf_amigaos_final_write_processing
-+#define elf_backend_write_section ppc_elf_amigaos_write_section
-+#define elf_backend_get_sec_type_attr ppc_elf_get_sec_type_attr
-+#define elf_backend_plt_sym_val ppc_elf_plt_sym_val
-+#define elf_backend_action_discarded ppc_elf_action_discarded
-+#define elf_backend_init_index_section _bfd_elf_init_1_index_section
-+#define elf_backend_post_process_headers _bfd_elf_set_osabi
-+#define elf_backend_lookup_section_flags_hook ppc_elf_lookup_section_flags
-+#define elf_backend_section_processing ppc_elf_amigaos_section_processing
-+
-+#include "elf32-target.h"
---- /dev/null 2015-09-06 08:42:34.091999986 +0100
+++ ld/emultempl/amigaos.em 2016-01-03 01:46:50.647001071 +0000
@@ -0,0 +1,2513 @@
+# This shell script emits a C file. -*- C -*-