summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Young <chris@unsatisfactorysoftware.co.uk>2018-01-08 21:25:33 +0000
committerChris Young <chris@unsatisfactorysoftware.co.uk>2018-01-08 21:25:33 +0000
commitf8aad68778cdb783c3e3afb9732ae611e0a3d22f (patch)
tree9b7c8234fcdc6bda9dc429383e7d66f08d6db553
parent1224526c4ceb0c9936f2ebd45f64871505b3259a (diff)
downloadtoolchains-f8aad68778cdb783c3e3afb9732ae611e0a3d22f.tar.gz
toolchains-f8aad68778cdb783c3e3afb9732ae611e0a3d22f.tar.bz2
Update with latest binutils patches from github.com/sba1/adtools
-rw-r--r--ppc-amigaos/recipes/patches/binutils/0001-Changes-for-various-Amiga-targets.p1601
-rw-r--r--ppc-amigaos/recipes/patches/binutils/0002-Fixed-errors-occuring-with-more-recent-versions-of-t.p40
-rw-r--r--ppc-amigaos/recipes/patches/binutils/0003-Disabled-some-stuff-such-that-68k-vtarget-builds-aga.p8
-rw-r--r--ppc-amigaos/recipes/patches/binutils/0004-Print-symbol-name-when-an-unexpected-type-was-encoun.p8
-rw-r--r--ppc-amigaos/recipes/patches/binutils/0005-Bind-in-the-ld-unwind-options.p8
-rw-r--r--ppc-amigaos/recipes/patches/binutils/0006-Introduced-strip-unneeded-rel-relocs.p8
-rw-r--r--ppc-amigaos/recipes/patches/binutils/0007-Keep-symbols-for-stripped-sections.-This-is-importan.p8
-rw-r--r--ppc-amigaos/recipes/patches/binutils/0008-Fix-undefined-behaviour.p113
-rw-r--r--ppc-amigaos/recipes/patches/binutils/missing-files.p12492
9 files changed, 1573 insertions, 12713 deletions
diff --git a/ppc-amigaos/recipes/patches/binutils/0001-Changes-for-various-Amiga-targets.p b/ppc-amigaos/recipes/patches/binutils/0001-Changes-for-various-Amiga-targets.p
index ccc8a07..06d746a 100644
--- a/ppc-amigaos/recipes/patches/binutils/0001-Changes-for-various-Amiga-targets.p
+++ b/ppc-amigaos/recipes/patches/binutils/0001-Changes-for-various-Amiga-targets.p
@@ -1,7 +1,7 @@
From 1678a95339b8893195b307a953a0053ceeca0133 Mon Sep 17 00:00:00 2001
From: Sebastian Bauer <mail@sebastianbauer.info>
Date: Sat, 14 Feb 2015 14:54:44 +0100
-Subject: [PATCH 1/7] Changes for various Amiga targets.
+Subject: [PATCH 1/8] Changes for various Amiga targets.
---
bfd/ChangeLog-9697 | 64 +
@@ -156,8 +156,8 @@ Subject: [PATCH 1/7] Changes for various Amiga targets.
diff --git a/bfd/ChangeLog-9697 b/bfd/ChangeLog-9697
index e9a5c1d60a313aaf09d1a8add619022cfdf575fa..1c2bb3f3c91d32e8b95f8b0cf16b98c58cde454b 100644
---- bfd/ChangeLog-9697
-+++ bfd/ChangeLog-9697
+--- a/bfd/ChangeLog-9697
++++ b/bfd/ChangeLog-9697
@@ -46,12 +46,19 @@ Mon Dec 22 13:20:57 1997 Ian Lance Taylor <ian@cygnus.com>
Mon Dec 22 13:04:33 1997 Joel Sherrill <joel@oarcorp.com>
@@ -341,8 +341,8 @@ index e9a5c1d60a313aaf09d1a8add619022cfdf575fa..1c2bb3f3c91d32e8b95f8b0cf16b98c5
(h8300_symbol_address_p): New function.
diff --git a/bfd/ChangeLog-9899 b/bfd/ChangeLog-9899
index 6d7f5cd616db22097b8238d8686f60484c9e6ee6..6e25901995a73646a13037d32c14563df20f74b3 100644
---- bfd/ChangeLog-9899
-+++ bfd/ChangeLog-9899
+--- a/bfd/ChangeLog-9899
++++ b/bfd/ChangeLog-9899
@@ -5570,12 +5570,17 @@ Wed Jan 21 21:16:06 1998 Manfred Hollstein <manfred@s-direktnet.de>
(GET_SCNDHR_NLNNO): Likewise.
@@ -363,8 +363,8 @@ index 6d7f5cd616db22097b8238d8686f60484c9e6ee6..6e25901995a73646a13037d32c14563d
diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 9ab2aa947a0a96ba5a469652c579a4d181793646..c224a3cecc392df96a6bc20c8dc73eb81c677269 100644
---- bfd/Makefile.am
-+++ bfd/Makefile.am
+--- a/bfd/Makefile.am
++++ b/bfd/Makefile.am
@@ -232,13 +232,16 @@ ALL_MACHINES_CFILES = \
cpu-z80.c \
cpu-z8k.c
@@ -485,8 +485,8 @@ index 9ab2aa947a0a96ba5a469652c579a4d181793646..c224a3cecc392df96a6bc20c8dc73eb8
-@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< $(NO_WERROR)
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index 99902757111d8011447cde1dda030e5a9c817ff2..bcdf435a15eb144bca66d8bfe04122a45e647446 100644
---- bfd/Makefile.in
-+++ bfd/Makefile.in
+--- a/bfd/Makefile.in
++++ b/bfd/Makefile.in
@@ -532,13 +532,16 @@ ALL_MACHINES_CFILES = \
cpu-z8k.c
@@ -658,7 +658,7 @@ diff --git a/bfd/amigaos.c b/bfd/amigaos.c
new file mode 100644
index 0000000000000000000000000000000000000000..9d715d64d458e6599c19ed65fbb61c253d2ab208
--- /dev/null
-+++ bfd/amigaos.c
++++ b/bfd/amigaos.c
@@ -0,0 +1,3189 @@
+/* BFD back-end for Commodore-Amiga AmigaOS binaries.
+ Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
@@ -3853,7 +3853,7 @@ diff --git a/bfd/amigaoslink.c b/bfd/amigaoslink.c
new file mode 100644
index 0000000000000000000000000000000000000000..9067a0a06b933c67bfd3542b299d1adb281182c3
--- /dev/null
-+++ bfd/amigaoslink.c
++++ b/bfd/amigaoslink.c
@@ -0,0 +1,1032 @@
+/* BFD back-end for Commodore-Amiga AmigaOS binaries. Linker routines.
+ Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
@@ -4891,7 +4891,7 @@ diff --git a/bfd/aout-amiga.c b/bfd/aout-amiga.c
new file mode 100644
index 0000000000000000000000000000000000000000..ced7584521b89943b1636d2b4c9b884242cd81c6
--- /dev/null
-+++ bfd/aout-amiga.c
++++ b/bfd/aout-amiga.c
@@ -0,0 +1,152 @@
+/* BFD back-end for Amiga style m68k a.out binaries.
+ Copyright (C) 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
@@ -5047,8 +5047,8 @@ index 0000000000000000000000000000000000000000..ced7584521b89943b1636d2b4c9b8842
+}
diff --git a/bfd/aoutx.h b/bfd/aoutx.h
index 1e0ad38f95bcf990a9ffd4cfb89eae3f6496740c..2641f975fd575d0a651540dc886eeee68cf4b173 100644
---- bfd/aoutx.h
-+++ bfd/aoutx.h
+--- a/bfd/aoutx.h
++++ b/bfd/aoutx.h
@@ -127,12 +127,16 @@ DESCRIPTION
#include "libaout.h"
#include "libbfd.h"
@@ -5135,8 +5135,8 @@ index 1e0ad38f95bcf990a9ffd4cfb89eae3f6496740c..2641f975fd575d0a651540dc886eeee6
r_extern = 0;
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index e496083d6ebb0842cfe0a7777dc76cdbd18c7134..8a4d566298f86c56c4a2d21895a39e0d7c5002d7 100644
---- bfd/bfd-in2.h
-+++ bfd/bfd-in2.h
+--- a/bfd/bfd-in2.h
++++ b/bfd/bfd-in2.h
@@ -3128,12 +3128,16 @@ instruction. */
BFD_RELOC_PPC_EMB_RELSEC16,
BFD_RELOC_PPC_EMB_RELST_LO,
@@ -5203,8 +5203,8 @@ index e496083d6ebb0842cfe0a7777dc76cdbd18c7134..8a4d566298f86c56c4a2d21895a39e0d
bfd_target_ieee_flavour,
diff --git a/bfd/bfd.c b/bfd/bfd.c
index eed18960855bdc51be8b57ddba27975afb6b02ef..3487694a541417ec20453ca9116bbb86c383f979 100644
---- bfd/bfd.c
-+++ bfd/bfd.c
+--- a/bfd/bfd.c
++++ b/bfd/bfd.c
@@ -261,12 +261,13 @@ CODE_FRAGMENT
. struct mach_o_data_struct *mach_o_data;
. struct mach_o_fat_data_struct *mach_o_fat_data;
@@ -5221,8 +5221,8 @@ index eed18960855bdc51be8b57ddba27975afb6b02ef..3487694a541417ec20453ca9116bbb86
. void *usrdata;
diff --git a/bfd/bfdio.c b/bfd/bfdio.c
index be05581aeb4026addd3f4caf2b185ae73d893a24..a15208b16635c7174592b6ccf26685c4b1d05bc8 100644
---- bfd/bfdio.c
-+++ bfd/bfdio.c
+--- a/bfd/bfdio.c
++++ b/bfd/bfdio.c
@@ -325,12 +325,37 @@ bfd_seek (bfd *abfd, file_ptr position, int direction)
if (abfd->iovec)
@@ -5263,8 +5263,8 @@ index be05581aeb4026addd3f4caf2b185ae73d893a24..a15208b16635c7174592b6ccf26685c4
bfd_tell (abfd);
diff --git a/bfd/config.bfd b/bfd/config.bfd
index 6025f2641b47915c79a7d643963e9d9080e0ed5c..fcbbce847bc65a44ee68deedd93b2943aac9f77f 100644
---- bfd/config.bfd
-+++ bfd/config.bfd
+--- a/bfd/config.bfd
++++ b/bfd/config.bfd
@@ -78,15 +78,17 @@ c30*) targ_archs=bfd_tic30_arch ;;
c4x*) targ_archs=bfd_tic4x_arch ;;
c54x*) targ_archs=bfd_tic54x_arch ;;
@@ -5362,8 +5362,8 @@ index 6025f2641b47915c79a7d643963e9d9080e0ed5c..fcbbce847bc65a44ee68deedd93b2943
;;
diff --git a/bfd/configure b/bfd/configure
index e965796ef43d9346cd917bf20243707633fc632e..018a5913f1d96081342c66a64f0167b11cdb1add 100755
---- bfd/configure
-+++ bfd/configure
+--- a/bfd/configure
++++ b/bfd/configure
@@ -15172,13 +15172,15 @@ do
case "$vec" in
# This list is alphabetized to make it easy to compare
@@ -5424,8 +5424,8 @@ index e965796ef43d9346cd917bf20243707633fc632e..018a5913f1d96081342c66a64f0167b1
tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
diff --git a/bfd/configure.host b/bfd/configure.host
index 7c63de58397426d08501dd7a0fd527cb59a9809c..afa7c909a787d9121d01e4e99d8047cf7f11f0b7 100644
---- bfd/configure.host
-+++ bfd/configure.host
+--- a/bfd/configure.host
++++ b/bfd/configure.host
@@ -53,12 +53,13 @@ mips64*-*-linux*) host64=true;;
mips64*-*-freebsd* | mips64*-*-kfreebsd*-gnu) host64=true;;
mips*-*-sysv4*) ;;
@@ -5442,8 +5442,8 @@ index 7c63de58397426d08501dd7a0fd527cb59a9809c..afa7c909a787d9121d01e4e99d8047cf
*-*-solaris2.11) HDEFINES=-DCP_ACP=1 ;;
diff --git a/bfd/configure.in b/bfd/configure.in
index 4b4cb617ef74f5fb33e4de13856d685f5ffba025..5d882b3701b6e0d93f97be655123a2bb2728d63a 100644
---- bfd/configure.in
-+++ bfd/configure.in
+--- a/bfd/configure.in
++++ b/bfd/configure.in
@@ -664,13 +664,15 @@ do
case "$vec" in
# This list is alphabetized to make it easy to compare
@@ -5504,8 +5504,8 @@ index 4b4cb617ef74f5fb33e4de13856d685f5ffba025..5d882b3701b6e0d93f97be655123a2bb
tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
diff --git a/bfd/doc/Makefile.am b/bfd/doc/Makefile.am
index 7476ee5bab710b6b418072124b473cf0d340b247..1ddc9e3d2153b55f6f26645e5fc584074bb369fd 100644
---- bfd/doc/Makefile.am
-+++ bfd/doc/Makefile.am
+--- a/bfd/doc/Makefile.am
++++ b/bfd/doc/Makefile.am
@@ -1,11 +1,11 @@
## Process this file with automake to generate Makefile.in
@@ -5560,8 +5560,8 @@ index 7476ee5bab710b6b418072124b473cf0d340b247..1ddc9e3d2153b55f6f26645e5fc58407
$(srcdir)/../bfdwin.c \
diff --git a/bfd/doc/Makefile.in b/bfd/doc/Makefile.in
index 7ba351d742bf53f9e5f51ad7ef74150295519f1a..67db3caf9886839b8d8f52a2a1878de878bb2f6a 100644
---- bfd/doc/Makefile.in
-+++ bfd/doc/Makefile.in
+--- a/bfd/doc/Makefile.in
++++ b/bfd/doc/Makefile.in
@@ -268,13 +268,13 @@ target_vendor = @target_vendor@
tdefaults = @tdefaults@
top_build_prefix = @top_build_prefix@
@@ -5618,8 +5618,8 @@ index 7ba351d742bf53f9e5f51ad7ef74150295519f1a..67db3caf9886839b8d8f52a2a1878de8
*/header.sed) break ;; \
diff --git a/bfd/doc/bfd.texinfo b/bfd/doc/bfd.texinfo
index 45ffa73240ea22a74debe916fcd7e068a947a7dc..7b9774b71a3cb9b3c154c8c75a41de29a6813146 100644
---- bfd/doc/bfd.texinfo
-+++ bfd/doc/bfd.texinfo
+--- a/bfd/doc/bfd.texinfo
++++ b/bfd/doc/bfd.texinfo
@@ -286,12 +286,13 @@ structures.
@chapter BFD back ends
@menu
@@ -5663,7 +5663,7 @@ diff --git a/bfd/elf32-amiga.c b/bfd/elf32-amiga.c
new file mode 100644
index 0000000000000000000000000000000000000000..cf6c6cb9efdd15c786932adedd2476ec3a4bc08d
--- /dev/null
-+++ bfd/elf32-amiga.c
++++ b/bfd/elf32-amiga.c
@@ -0,0 +1,3844 @@
+/* PowerPC-specific support for 32-bit ELF
+ Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
@@ -9509,11 +9509,790 @@ index 0000000000000000000000000000000000000000..cf6c6cb9efdd15c786932adedd2476ec
+#define elf_backend_reloc_type_class ppc_elf_reloc_type_class
+
+#include "elf32-target.h"
+diff --git a/bfd/elf32-ppc.c b/bfd/elf32-amigaos.c
+similarity index 97%
+copy from bfd/elf32-ppc.c
+copy to bfd/elf32-amigaos.c
+index 6454a8350da35adf6ed1e2209d9e4774ab7c50e3..9bf9535888f2345d60a8f802680ae03f41f67a5f 100644
+--- a/bfd/elf32-ppc.c
++++ b/bfd/elf32-amigaos.c
+@@ -31,32 +31,50 @@
+ #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
+@@ -1381,12 +1399,74 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
+ /* 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) */
+@@ -1935,12 +2015,16 @@ ppc_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+ 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];
+ };
+@@ -2268,13 +2352,13 @@ ppc_elf_lookup_section_flags (char *flag_name)
+ return 0;
+ }
+
+ /* Add the VLE flag if required. */
+
+ bfd_boolean
+-ppc_elf_section_processing (bfd *abfd, Elf_Internal_Shdr *shdr)
++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;
+@@ -2285,12 +2369,15 @@ ppc_elf_section_processing (bfd *abfd, Elf_Internal_Shdr *shdr)
+
+ 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. */
+@@ -2337,13 +2424,14 @@ ppc_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
+
+ static int
+ ppc_elf_additional_program_headers (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+ {
+ asection *s;
+- int ret = 0;
++// 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");
+@@ -2353,13 +2441,13 @@ ppc_elf_additional_program_headers (bfd *abfd,
+ return ret;
+ }
+
+ /* Modify the segment map for VLE executables. */
+
+ bfd_boolean
+-ppc_elf_modify_segment_map (bfd *abfd,
++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;
+@@ -2546,13 +2634,13 @@ apuinfo_list_finish (void)
+ #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_begin_write_processing (bfd *abfd, struct bfd_link_info *link_info)
++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;
+@@ -2646,24 +2734,24 @@ ppc_elf_begin_write_processing (bfd *abfd, struct bfd_link_info *link_info)
+ }
+
+ /* 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_write_section (bfd *abfd ATTRIBUTE_UNUSED,
++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_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
++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;
+@@ -3232,13 +3320,13 @@ ppc_elf_create_got (bfd *abfd, struct bfd_link_info *info)
+ abort ();
+ }
+ else
+ {
+ /* The powerpc .got has a blrl instruction in it. Mark it
+ executable. */
+- flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS
++ 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");
+@@ -3340,13 +3428,13 @@ ppc_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+
+ 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;
++ 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);
+ }
+
+@@ -3410,13 +3498,13 @@ ppc_elf_copy_indirect_symbol (struct bfd_link_info *info,
+ 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
++ 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;
+
+@@ -4186,12 +4274,19 @@ ppc_elf_check_relocs (bfd *abfd,
+ 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;
+@@ -4679,13 +4774,13 @@ ppc_elf_vle_split16 (bfd *output_bfd, bfd_byte *contents,
+ }
+
+
+ /* 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_select_plt_layout (bfd *output_bfd ATTRIBUTE_UNUSED,
++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;
+@@ -4976,13 +5071,13 @@ ppc_elf_gc_sweep_hook (bfd *abfd,
+ }
+
+ /* Set plt output section type, htab->tls_get_addr, and call the
+ generic ELF tls_setup function. */
+
+ asection *
+-ppc_elf_tls_setup (bfd *obfd,
++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);
+@@ -5075,13 +5170,13 @@ branch_reloc_hash_match (const bfd *ibfd,
+ }
+
+ /* Run through all the TLS relocs looking for optimization
+ opportunities. */
+
+ bfd_boolean
+-ppc_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED,
++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;
+@@ -6008,12 +6103,16 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ 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");
+@@ -6037,12 +6136,16 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ 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;
+@@ -6400,12 +6503,16 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+ 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)
+ {
+@@ -7172,13 +7279,13 @@ is_static_defined (struct elf_link_hash_entry *h)
+
+ /* 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_ppc_at_tls_transform (unsigned int insn, unsigned int reg)
++_bfd_elf_amigaos_ppc_at_tls_transform (unsigned int insn, unsigned int reg)
+ {
+ unsigned int rtra;
+
+ if ((insn & (0x3f << 26)) != 31 << 26)
+ return 0;
+
+@@ -7212,13 +7319,13 @@ _bfd_elf_ppc_at_tls_transform (unsigned int insn, unsigned int reg)
+
+ /* 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_ppc_at_tprel_transform (unsigned int insn, unsigned int reg)
++_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 */
+@@ -8076,13 +8183,13 @@ ppc_elf_relocate_section (bfd *output_bfd,
+ /* 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_ppc_at_tprel_transform (insn, 2);
++ 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
+@@ -8502,13 +8609,47 @@ ppc_elf_relocate_section (bfd *output_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;
+
+@@ -8899,12 +9040,15 @@ ppc_elf_relocate_section (bfd *output_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;
+@@ -9124,18 +9268,24 @@ ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
+ || 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);
+@@ -9166,24 +9316,34 @@ ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
+ * 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)
+- sym->st_value = 0;
++ {
++ /* 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;
+@@ -9275,12 +9435,15 @@ ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
+ 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;
+ }
+
+@@ -9735,16 +9898,14 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
+ return FALSE;
+ }
+
+ return ret;
+ }
+
+-#define TARGET_LITTLE_SYM bfd_elf32_powerpcle_vec
+-#define TARGET_LITTLE_NAME "elf32-powerpcle"
+-#define TARGET_BIG_SYM bfd_elf32_powerpc_vec
+-#define TARGET_BIG_NAME "elf32-powerpc"
++#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
+@@ -9789,153 +9950,23 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
+ #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_modify_segment_map
++#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_begin_write_processing
+-#define elf_backend_final_write_processing ppc_elf_final_write_processing
+-#define elf_backend_write_section ppc_elf_write_section
++#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_section_processing
+-
+-#include "elf32-target.h"
+-
+-/* FreeBSD Target */
+-
+-#undef TARGET_LITTLE_SYM
+-#undef TARGET_LITTLE_NAME
+-
+-#undef TARGET_BIG_SYM
+-#define TARGET_BIG_SYM bfd_elf32_powerpc_freebsd_vec
+-#undef TARGET_BIG_NAME
+-#define TARGET_BIG_NAME "elf32-powerpc-freebsd"
+-
+-#undef ELF_OSABI
+-#define ELF_OSABI ELFOSABI_FREEBSD
+-
+-#undef elf32_bed
+-#define elf32_bed elf32_powerpc_fbsd_bed
+-
+-#include "elf32-target.h"
+-
+-/* VxWorks Target */
+-
+-#undef TARGET_LITTLE_SYM
+-#undef TARGET_LITTLE_NAME
+-
+-#undef TARGET_BIG_SYM
+-#define TARGET_BIG_SYM bfd_elf32_powerpc_vxworks_vec
+-#undef TARGET_BIG_NAME
+-#define TARGET_BIG_NAME "elf32-powerpc-vxworks"
+-
+-#undef ELF_OSABI
+-
+-/* VxWorks uses the elf default section flags for .plt. */
+-static const struct bfd_elf_special_section *
+-ppc_elf_vxworks_get_sec_type_attr (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
+-{
+- if (sec->name == NULL)
+- return NULL;
+-
+- if (strcmp (sec->name, ".plt") == 0)
+- return _bfd_elf_get_sec_type_attr (abfd, sec);
+-
+- return ppc_elf_get_sec_type_attr (abfd, sec);
+-}
+-
+-/* Like ppc_elf_link_hash_table_create, but overrides
+- appropriately for VxWorks. */
+-static struct bfd_link_hash_table *
+-ppc_elf_vxworks_link_hash_table_create (bfd *abfd)
+-{
+- struct bfd_link_hash_table *ret;
+-
+- ret = ppc_elf_link_hash_table_create (abfd);
+- if (ret)
+- {
+- struct ppc_elf_link_hash_table *htab
+- = (struct ppc_elf_link_hash_table *)ret;
+- htab->is_vxworks = 1;
+- htab->plt_type = PLT_VXWORKS;
+- htab->plt_entry_size = VXWORKS_PLT_ENTRY_SIZE;
+- htab->plt_slot_size = VXWORKS_PLT_ENTRY_SIZE;
+- htab->plt_initial_entry_size = VXWORKS_PLT_INITIAL_ENTRY_SIZE;
+- }
+- return ret;
+-}
+-
+-/* Tweak magic VxWorks symbols as they are loaded. */
+-static bfd_boolean
+-ppc_elf_vxworks_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 (!elf_vxworks_add_symbol_hook(abfd, info, sym,namep, flagsp, secp,
+- valp))
+- return FALSE;
+-
+- return ppc_elf_add_symbol_hook(abfd, info, sym,namep, flagsp, secp, valp);
+-}
+-
+-static void
+-ppc_elf_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
+-{
+- ppc_elf_final_write_processing(abfd, linker);
+- elf_vxworks_final_write_processing(abfd, linker);
+-}
+-
+-/* On VxWorks, we emit relocations against _PROCEDURE_LINKAGE_TABLE_, so
+- define it. */
+-#undef elf_backend_want_plt_sym
+-#define elf_backend_want_plt_sym 1
+-#undef elf_backend_want_got_plt
+-#define elf_backend_want_got_plt 1
+-#undef elf_backend_got_symbol_offset
+-#define elf_backend_got_symbol_offset 0
+-#undef elf_backend_plt_not_loaded
+-#define elf_backend_plt_not_loaded 0
+-#undef elf_backend_plt_readonly
+-#define elf_backend_plt_readonly 1
+-#undef elf_backend_got_header_size
+-#define elf_backend_got_header_size 12
+-
+-#undef bfd_elf32_get_synthetic_symtab
+-
+-#undef bfd_elf32_bfd_link_hash_table_create
+-#define bfd_elf32_bfd_link_hash_table_create \
+- ppc_elf_vxworks_link_hash_table_create
+-#undef elf_backend_add_symbol_hook
+-#define elf_backend_add_symbol_hook \
+- ppc_elf_vxworks_add_symbol_hook
+-#undef elf_backend_link_output_symbol_hook
+-#define elf_backend_link_output_symbol_hook \
+- elf_vxworks_link_output_symbol_hook
+-#undef elf_backend_final_write_processing
+-#define elf_backend_final_write_processing \
+- ppc_elf_vxworks_final_write_processing
+-#undef elf_backend_get_sec_type_attr
+-#define elf_backend_get_sec_type_attr \
+- ppc_elf_vxworks_get_sec_type_attr
+-#undef elf_backend_emit_relocs
+-#define elf_backend_emit_relocs \
+- elf_vxworks_emit_relocs
+-
+-#undef elf32_bed
+-#define elf32_bed ppc_elf_vxworks_bed
+-#undef elf_backend_post_process_headers
++#define elf_backend_section_processing ppc_elf_amigaos_section_processing
+
+ #include "elf32-target.h"
diff --git a/bfd/elf32-i386-amithlon.c b/bfd/elf32-i386-amithlon.c
new file mode 100644
index 0000000000000000000000000000000000000000..4e029a5e90187a96013ed97e078fba920d95db28
--- /dev/null
-+++ bfd/elf32-i386-amithlon.c
++++ b/bfd/elf32-i386-amithlon.c
@@ -0,0 +1,198 @@
+/* Intel IA-32 specific support for 32-bit big endian ELF on Amithlon.
+ Copyright 2002 Free Software Foundation, Inc.
@@ -9715,8 +10494,8 @@ index 0000000000000000000000000000000000000000..4e029a5e90187a96013ed97e078fba92
+#include "elf32-i386.c"
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 0a6b22ec19ec9daee29e49c64c5d3ba2299e99c1..46396c83d45bab97de1470ee44ffa21f9d03e4b4 100644
---- bfd/elf32-i386.c
-+++ bfd/elf32-i386.c
+--- a/bfd/elf32-i386.c
++++ b/bfd/elf32-i386.c
@@ -29,12 +29,16 @@
#include "elf-vxworks.h"
#include "bfd_stdint.h"
@@ -9824,7 +10603,7 @@ diff --git a/bfd/elf32-morphos.c b/bfd/elf32-morphos.c
new file mode 100644
index 0000000000000000000000000000000000000000..accc2d426bede6c9441313115fcd5ab5f99630f9
--- /dev/null
-+++ bfd/elf32-morphos.c
++++ b/bfd/elf32-morphos.c
@@ -0,0 +1,7137 @@
+/* PowerPC-specific support for 32-bit ELF
+ Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
@@ -16965,8 +17744,8 @@ index 0000000000000000000000000000000000000000..accc2d426bede6c9441313115fcd5ab5
+#include "elf32-target.h"
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 6454a8350da35adf6ed1e2209d9e4774ab7c50e3..5c92c53da7b3dec8f85a0a0b930190635f89dcfb 100644
---- bfd/elf32-ppc.c
-+++ bfd/elf32-ppc.c
+--- a/bfd/elf32-ppc.c
++++ b/bfd/elf32-ppc.c
@@ -4412,12 +4412,16 @@ ppc_elf_check_relocs (bfd *abfd,
p->count += 1;
if (!must_be_dyn_reloc (info, r_type))
@@ -16988,7 +17767,7 @@ diff --git a/bfd/hosts/amigaos.h b/bfd/hosts/amigaos.h
new file mode 100644
index 0000000000000000000000000000000000000000..dc62d7f837f333ae8d2c5b47d01144cb0d3625f2
--- /dev/null
-+++ bfd/hosts/amigaos.h
++++ b/bfd/hosts/amigaos.h
@@ -0,0 +1,5 @@
+/* Host configuration for AmigaOS */
+#ifndef hosts_amigaos_h
@@ -16999,7 +17778,7 @@ diff --git a/bfd/hosts/morphos.h b/bfd/hosts/morphos.h
new file mode 100644
index 0000000000000000000000000000000000000000..d3c60ea9f5767ad0bfa22ba2c8c1e5ed9d94d481
--- /dev/null
-+++ bfd/hosts/morphos.h
++++ b/bfd/hosts/morphos.h
@@ -0,0 +1,5 @@
+/* Host configuration for MorphOS */
+#ifndef hosts_morphos_h
@@ -17010,7 +17789,7 @@ diff --git a/bfd/libamiga.h b/bfd/libamiga.h
new file mode 100644
index 0000000000000000000000000000000000000000..351f0fa16a45680982f5b5807c8ba756defe1764
--- /dev/null
-+++ bfd/libamiga.h
++++ b/bfd/libamiga.h
@@ -0,0 +1,187 @@
+/* BFD back-end for Commodore-Amiga AmigaOS binaries. Data structures.
+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998
@@ -17201,8 +17980,8 @@ index 0000000000000000000000000000000000000000..351f0fa16a45680982f5b5807c8ba756
+#endif /* MEMF_ANY */
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 6c48d641f606b9ed6158b4567021769bacfbd54a..3cb9b36fe2379a5d7f118472e106c151d6153aea 100644
---- bfd/libbfd.h
-+++ bfd/libbfd.h
+--- a/bfd/libbfd.h
++++ b/bfd/libbfd.h
@@ -1345,12 +1345,16 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_PPC_EMB_RELSEC16",
"BFD_RELOC_PPC_EMB_RELST_LO",
@@ -17239,8 +18018,8 @@ index 6c48d641f606b9ed6158b4567021769bacfbd54a..3cb9b36fe2379a5d7f118472e106c151
"BFD_RELOC_ARM_PCREL_CALL",
diff --git a/bfd/linker.c b/bfd/linker.c
index d3ef9a43a5bca8096221870248daf58007c6ef78..4f0aa188f5017ea68023530f6ae9eaa6b98b5b11 100644
---- bfd/linker.c
-+++ bfd/linker.c
+--- a/bfd/linker.c
++++ b/bfd/linker.c
@@ -430,13 +430,14 @@ static bfd_boolean generic_link_add_symbol_list
(bfd *, struct bfd_link_info *, bfd_size_type count, asymbol **,
bfd_boolean);
@@ -17334,8 +18113,8 @@ index d3ef9a43a5bca8096221870248daf58007c6ef78..4f0aa188f5017ea68023530f6ae9eaa6
{
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 47d052d1345847a7178f4c7ebe4f529396ae0a4f..6c3bb68f2da65b201b6288b8709fd60d9b0d5b2c 100644
---- bfd/reloc.c
-+++ bfd/reloc.c
+--- a/bfd/reloc.c
++++ b/bfd/reloc.c
@@ -2803,12 +2803,20 @@ ENUMX
BFD_RELOC_PPC_EMB_RELST_HA
ENUMX
@@ -17383,8 +18162,8 @@ index 47d052d1345847a7178f4c7ebe4f529396ae0a4f..6c3bb68f2da65b201b6288b8709fd60d
BFD_RELOC_CTOR
diff --git a/bfd/targets.c b/bfd/targets.c
index fa206d24bef3a22255f6be42221647db3142eb06..9df24504bab564048f724fbbb641ca13c5805602 100644
---- bfd/targets.c
-+++ bfd/targets.c
+--- a/bfd/targets.c
++++ b/bfd/targets.c
@@ -144,12 +144,13 @@ DESCRIPTION
the entry points which call them. Too bad we can't have one
macro to define them both!
@@ -17515,8 +18294,8 @@ index fa206d24bef3a22255f6be42221647db3142eb06..9df24504bab564048f724fbbb641ca13
&bfd_elf32_ntradbigmips_vec,
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 020d54d6fbe27a5c90600e1d034a93e8fade0ff6..88bd071eefa8b5426eaadfd6431e9de5d4a4591b 100644
---- binutils/objcopy.c
-+++ binutils/objcopy.c
+--- a/binutils/objcopy.c
++++ b/binutils/objcopy.c
@@ -1101,12 +1101,17 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
bfd_boolean undefined;
bfd_boolean rem_leading_char;
@@ -17659,8 +18438,8 @@ index 020d54d6fbe27a5c90600e1d034a93e8fade0ff6..88bd071eefa8b5426eaadfd6431e9de5
diff --git a/binutils/readelf.c b/binutils/readelf.c
index d9ec436af6fbea0bbc3dfa8e9cd40fcf9be140cf..f52d7168af3bc6559bd2483ff1fc126da385b38d 100644
---- binutils/readelf.c
-+++ binutils/readelf.c
+--- a/binutils/readelf.c
++++ b/binutils/readelf.c
@@ -150,12 +150,13 @@
#include "elf/vax.h"
#include "elf/x86-64.h"
@@ -17707,8 +18486,8 @@ index d9ec436af6fbea0bbc3dfa8e9cd40fcf9be140cf..f52d7168af3bc6559bd2483ff1fc126d
break;
diff --git a/binutils/rename.c b/binutils/rename.c
index 5923a3f4ce2b2b5b0da96ff8225bf3c7750563bc..354b6fd1eab7f632995fed27698c76826ee8e753 100644
---- binutils/rename.c
-+++ binutils/rename.c
+--- a/binutils/rename.c
++++ b/binutils/rename.c
@@ -27,13 +27,13 @@
#else /* ! HAVE_GOOD_UTIME_H */
#ifdef HAVE_UTIMES
@@ -17741,8 +18520,8 @@ index 5923a3f4ce2b2b5b0da96ff8225bf3c7750563bc..354b6fd1eab7f632995fed27698c7682
diff --git a/config.sub b/config.sub
index 59bb593f109c8d795df4cbb96b015222eed91c07..88ccfd90050ad0d8d341c091b9920f62fc5996f8 100755
---- config.sub
-+++ config.sub
+--- a/config.sub
++++ b/config.sub
@@ -353,13 +353,13 @@ case $basic_machine in
basic_machine=armel-unknown
;;
@@ -17797,7 +18576,7 @@ diff --git a/config/mh-amigaos b/config/mh-amigaos
new file mode 100644
index 0000000000000000000000000000000000000000..4889ea41c6889e2e15c06c8f355c30b5eb2aa5f4
--- /dev/null
-+++ config/mh-amigaos
++++ b/config/mh-amigaos
@@ -0,0 +1,13 @@
+# Host makefile fragment for Commodore Amiga running AmigaOS.
+
@@ -17816,7 +18595,7 @@ diff --git a/config/mh-morphos b/config/mh-morphos
new file mode 100644
index 0000000000000000000000000000000000000000..c00202aec0389eaa067ea48818a7d8fa4fd5fc6b
--- /dev/null
-+++ config/mh-morphos
++++ b/config/mh-morphos
@@ -0,0 +1,13 @@
+# Host makefile fragment for Commodore Amiga running AmigaOS.
+
@@ -17833,8 +18612,8 @@ index 0000000000000000000000000000000000000000..c00202aec0389eaa067ea48818a7d8fa
+HARDLINK = cp
diff --git a/configure b/configure
index 6079e6c07511e12bb51ae5197e7110d79c36b098..9667d72a79baf032fa22e054b88fb03e64673b63 100755
---- configure
-+++ configure
+--- a/configure
++++ b/configure
@@ -3630,12 +3630,15 @@ case "${noconfigdirs}" in
esac
@@ -17869,8 +18648,8 @@ index 6079e6c07511e12bb51ae5197e7110d79c36b098..9667d72a79baf032fa22e054b88fb03e
;;
diff --git a/configure.ac b/configure.ac
index 5efb4a32f114f23b90f838a5108f5016dc01bf43..fea7239acf315d982587796d8b93de4c894a14d8 100644
---- configure.ac
-+++ configure.ac
+--- a/configure.ac
++++ b/configure.ac
@@ -1056,12 +1056,15 @@ case "${noconfigdirs}" in
esac
@@ -17905,8 +18684,8 @@ index 5efb4a32f114f23b90f838a5108f5016dc01bf43..fea7239acf315d982587796d8b93de4c
;;
diff --git a/gas/ChangeLog-9697 b/gas/ChangeLog-9697
index f39e99554e87446d7eb8f0869701984c5df2137d..08dbfbc1d36608ec8e553593d445431cb1792cc5 100644
---- gas/ChangeLog-9697
-+++ gas/ChangeLog-9697
+--- a/gas/ChangeLog-9697
++++ b/gas/ChangeLog-9697
@@ -874,12 +874,18 @@ Tue Aug 26 12:23:25 1997 Ian Lance Taylor <ian@cygnus.com>
Gabriel Paubert <paubert@iram.es>.
@@ -17947,8 +18726,8 @@ index f39e99554e87446d7eb8f0869701984c5df2137d..08dbfbc1d36608ec8e553593d445431c
Fri Nov 8 13:55:03 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
diff --git a/gas/ChangeLog-9899 b/gas/ChangeLog-9899
index ae38e5dd9223cf4e26355263197ea9f2cd0296c0..76861df24938b7ec7a3051da5cf20c44465b145e 100644
---- gas/ChangeLog-9899
-+++ gas/ChangeLog-9899
+--- a/gas/ChangeLog-9899
++++ b/gas/ChangeLog-9899
@@ -3574,12 +3574,16 @@ Wed Jun 3 14:10:36 1998 Ian Lance Taylor <ian@cygnus.com>
Wed Jun 3 09:16:00 1998 Catherine Moore <clm@cygnus.com>
@@ -17968,8 +18747,8 @@ index ae38e5dd9223cf4e26355263197ea9f2cd0296c0..76861df24938b7ec7a3051da5cf20c44
Tue Jun 2 15:36:13 1998 Ian Lance Taylor <ian@cygnus.com>
diff --git a/gas/Makefile.am b/gas/Makefile.am
index 256e2322fd80f84d8fa8fab735c85446dff4f506..851de3dc36be1138ad52026f7ace0ebd49da94b6 100644
---- gas/Makefile.am
-+++ gas/Makefile.am
+--- a/gas/Makefile.am
++++ b/gas/Makefile.am
@@ -245,23 +245,25 @@ TARGET_CPU_HFILES = \
config/tc-z8k.h \
config/xtensa-relax.h
@@ -18027,8 +18806,8 @@ index 256e2322fd80f84d8fa8fab735c85446dff4f506..851de3dc36be1138ad52026f7ace0ebd
BASEDIR = $(srcdir)/..
diff --git a/gas/Makefile.in b/gas/Makefile.in
index 94812d96db9cb13bdbdd0243a6b9a021e95e0a0b..c04f7d53feacb96ac3a82109375c3c94bcb15d56 100644
---- gas/Makefile.in
-+++ gas/Makefile.in
+--- a/gas/Makefile.in
++++ b/gas/Makefile.in
@@ -513,23 +513,25 @@ TARGET_CPU_HFILES = \
config/tc-z8k.h \
config/xtensa-relax.h
@@ -18127,8 +18906,8 @@ index 94812d96db9cb13bdbdd0243a6b9a021e95e0a0b..c04f7d53feacb96ac3a82109375c3c94
mkdir testsuite; \
diff --git a/gas/as.c b/gas/as.c
index fa4141f92bc887cfd403ec3eb93a7a20f26b642a..7b35f0e3f23662e09e8ce56c525239cf68b5dd3a 100644
---- gas/as.c
-+++ gas/as.c
+--- a/gas/as.c
++++ b/gas/as.c
@@ -105,12 +105,17 @@ int keep_it = 0;
segT reg_section;
segT expr_section;
@@ -18181,8 +18960,8 @@ index fa4141f92bc887cfd403ec3eb93a7a20f26b642a..7b35f0e3f23662e09e8ce56c525239cf
expr_section = subseg_new ("*GAS `expr' section*", 0);
diff --git a/gas/config/m68k-parse.h b/gas/config/m68k-parse.h
index 4f91385f9222dc52c8cc9f490860729c2183e445..08e766c5523b90ac3cd2d685b239c0a7ed4d8230 100644
---- gas/config/m68k-parse.h
-+++ gas/config/m68k-parse.h
+--- a/gas/config/m68k-parse.h
++++ b/gas/config/m68k-parse.h
@@ -293,12 +293,15 @@ struct m68k_exp
/* The type of pic relocation if any. */
enum pic_relocation pic_reloc;
@@ -18201,8 +18980,8 @@ index 4f91385f9222dc52c8cc9f490860729c2183e445..08e766c5523b90ac3cd2d685b239c0a7
{
diff --git a/gas/config/m68k-parse.y b/gas/config/m68k-parse.y
index 2c58266fb8e6bd8d57515fe5200daaf9a1e450a2..742cbf2eeaaa15766a4d44de76a9d58d56993367 100644
---- gas/config/m68k-parse.y
-+++ gas/config/m68k-parse.y
+--- a/gas/config/m68k-parse.y
++++ b/gas/config/m68k-parse.y
@@ -972,31 +972,35 @@ yylex ()
else if (parens == 0
&& (*s == ',' || *s == ']'))
@@ -18246,7 +19025,7 @@ diff --git a/gas/config/obj-amigahunk.c b/gas/config/obj-amigahunk.c
new file mode 100644
index 0000000000000000000000000000000000000000..8755475ecfdfd5aafbf876ed1f87c9d343b560e9
--- /dev/null
-+++ gas/config/obj-amigahunk.c
++++ b/gas/config/obj-amigahunk.c
@@ -0,0 +1,212 @@
+/* AmigaOS object file format
+ Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
@@ -18464,7 +19243,7 @@ diff --git a/gas/config/obj-amigahunk.h b/gas/config/obj-amigahunk.h
new file mode 100644
index 0000000000000000000000000000000000000000..0b7d80eeb291878dc871ce0591b2223bf6cb1de2
--- /dev/null
-+++ gas/config/obj-amigahunk.h
++++ b/gas/config/obj-amigahunk.h
@@ -0,0 +1,54 @@
+/* obj-amigahunk.h, AmigaOS object file format for gas, the assembler.
+ Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
@@ -18522,8 +19301,8 @@ index 0000000000000000000000000000000000000000..0b7d80eeb291878dc871ce0591b2223b
+#define AOUT_STABS
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index d7c766513ccc4111f51904a7e01904b7ebe96a03..bb8d9d1ebee6b76deee86848202fd06d5b1a4dfa 100644
---- gas/config/obj-elf.c
-+++ gas/config/obj-elf.c
+--- a/gas/config/obj-elf.c
++++ b/gas/config/obj-elf.c
@@ -1390,13 +1390,13 @@ obj_elf_vtable_inherit (int ignore ATTRIBUTE_UNUSED)
if (bad)
return NULL;
@@ -18556,8 +19335,8 @@ index d7c766513ccc4111f51904a7e01904b7ebe96a03..bb8d9d1ebee6b76deee86848202fd06d
#ifdef NEED_ECOFF_DEBUG
diff --git a/gas/config/tc-i386.h b/gas/config/tc-i386.h
index de132d69d7ac3f854ea517a15267e8c75365714d..14b67f0506eacf6d3dbb11dbd08689fa69354678 100644
---- gas/config/tc-i386.h
-+++ gas/config/tc-i386.h
+--- a/gas/config/tc-i386.h
++++ b/gas/config/tc-i386.h
@@ -24,13 +24,20 @@
#define TC_I386 1
@@ -18628,8 +19407,8 @@ index de132d69d7ac3f854ea517a15267e8c75365714d..14b67f0506eacf6d3dbb11dbd08689fa
PROCESSOR_I486,
diff --git a/gas/config/tc-m68k.c b/gas/config/tc-m68k.c
index 21accf605b22ebc5af491e173faeef93888b6667..8b5f6c60f2141ee91d6e9d1d639815abdf4e5042 100644
---- gas/config/tc-m68k.c
-+++ gas/config/tc-m68k.c
+--- a/gas/config/tc-m68k.c
++++ b/gas/config/tc-m68k.c
@@ -35,12 +35,22 @@
#endif
@@ -19589,8 +20368,8 @@ index 21accf605b22ebc5af491e173faeef93888b6667..8b5f6c60f2141ee91d6e9d1d639815ab
m68k_elf_final_processing (void)
diff --git a/gas/config/tc-m68k.h b/gas/config/tc-m68k.h
index bcf4607ebebe16d575166d666a536fb1fbdfeaee..144b7c7d783bab80bd84fa0e57cfce9f349a528f 100644
---- gas/config/tc-m68k.h
-+++ gas/config/tc-m68k.h
+--- a/gas/config/tc-m68k.h
++++ b/gas/config/tc-m68k.h
@@ -30,20 +30,27 @@ struct fix;
#ifdef TE_SUN3
#define TARGET_FORMAT "a.out-sunos-big"
@@ -19655,8 +20434,8 @@ index bcf4607ebebe16d575166d666a536fb1fbdfeaee..144b7c7d783bab80bd84fa0e57cfce9f
if (aim == 0 && this_type->rlx_forward == 127) \
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index 208d76d847128c833f73713eff2b78deb610a764..11949323d80802138ec23fb8174727c0a7c4fd45 100644
---- gas/config/tc-ppc.c
-+++ gas/config/tc-ppc.c
+--- a/gas/config/tc-ppc.c
++++ b/gas/config/tc-ppc.c
@@ -1421,22 +1421,28 @@ ppc_target_format (void)
# else
return (ppc_obj64 ? "aixcoff64-rs6000" : "aixcoff-rs6000");
@@ -19794,8 +20573,8 @@ index 208d76d847128c833f73713eff2b78deb610a764..11949323d80802138ec23fb8174727c0
size = 2;
diff --git a/gas/config/tc-sh.c b/gas/config/tc-sh.c
index 4db1a0913602aaf18d1390cc315f6db0fbdef649..ba0ed8e89e44a9ab8411662047e6f85b4f28d5d9 100644
---- gas/config/tc-sh.c
-+++ gas/config/tc-sh.c
+--- a/gas/config/tc-sh.c
++++ b/gas/config/tc-sh.c
@@ -800,13 +800,13 @@ sh_cons_fix_new (fragS *frag, int off, int size, expressionS *exp)
{
error:
@@ -19993,7 +20772,7 @@ diff --git a/gas/config/te-amiga.h b/gas/config/te-amiga.h
new file mode 100644
index 0000000000000000000000000000000000000000..a7b93727031092cdeb4bf66e3813663d66d79c3b
--- /dev/null
-+++ gas/config/te-amiga.h
++++ b/gas/config/te-amiga.h
@@ -0,0 +1,24 @@
+/*
+ * te-amiga.h -- Amiga target environment declarations.
@@ -20023,7 +20802,7 @@ diff --git a/gas/config/te-amigaos.h b/gas/config/te-amigaos.h
new file mode 100644
index 0000000000000000000000000000000000000000..8bd15a3d19b3f383e6756d6e307bd10dc4dcfb6f
--- /dev/null
-+++ gas/config/te-amigaos.h
++++ b/gas/config/te-amigaos.h
@@ -0,0 +1,14 @@
+/*
+ * te-amigaos.h -- Amiga target environment declarations.
@@ -20044,8 +20823,8 @@ similarity index 65%
copy from gas/config/te-nbsd.h
copy to gas/config/te-amithlon.h
index ce291014824771b2081438766002c479eeb60d9b..2fbd88551330d46e5cd585d142d67e6b7efe1624 100644
---- gas/config/te-nbsd.h
-+++ gas/config/te-amithlon.h
+--- a/gas/config/te-nbsd.h
++++ b/gas/config/te-amithlon.h
@@ -1,24 +1,26 @@
-/* te-nbsd.h -- NetBSD target environment declarations.
- Copyright 1987, 1990, 1991, 1992, 1994, 1998, 2000, 2005, 2007
@@ -20084,7 +20863,7 @@ diff --git a/gas/config/te-morphos.h b/gas/config/te-morphos.h
new file mode 100644
index 0000000000000000000000000000000000000000..43b0826fa79d9e9c97485cc6dd7d919771defbf9
--- /dev/null
-+++ gas/config/te-morphos.h
++++ b/gas/config/te-morphos.h
@@ -0,0 +1,14 @@
+/*
+ * te-amiga.h -- Amiga target environment declarations.
@@ -20102,8 +20881,8 @@ index 0000000000000000000000000000000000000000..43b0826fa79d9e9c97485cc6dd7d9197
+#endif
diff --git a/gas/configure b/gas/configure
index 2e674491f392b756186c52f7b0d28de8a20398c5..6eabef030df837c80ab009e12ad99a3086df5e43 100755
---- gas/configure
-+++ gas/configure
+--- a/gas/configure
++++ b/gas/configure
@@ -12500,12 +12500,19 @@ _ACEOF
cat >>confdefs.h <<_ACEOF
@@ -20152,8 +20931,8 @@ index 2e674491f392b756186c52f7b0d28de8a20398c5..6eabef030df837c80ab009e12ad99a30
$as_echo_n "checking for $ac_word... " >&6; }
diff --git a/gas/configure.in b/gas/configure.in
index 14f6edfe5deb041e968454931c451e1da226e0d1..183d98e8a4ac56e2e8a7a87f7b824f302bbb04f4 100644
---- gas/configure.in
-+++ gas/configure.in
+--- a/gas/configure.in
++++ b/gas/configure.in
@@ -598,12 +598,19 @@ if test `set . $emfiles ; shift ; echo $#` -gt 0 ; then
fi
AC_SUBST(extra_objects)
@@ -20200,8 +20979,8 @@ index 14f6edfe5deb041e968454931c451e1da226e0d1..183d98e8a4ac56e2e8a7a87f7b824f30
AM_PO_SUBDIRS
diff --git a/gas/configure.tgt b/gas/configure.tgt
index 9e44de000145c39abfd3ea325656a4d4bc066198..61f24acdb98484f43ac0c08d3cacfd38b1c1fb8b 100644
---- gas/configure.tgt
-+++ gas/configure.tgt
+--- a/gas/configure.tgt
++++ b/gas/configure.tgt
@@ -40,13 +40,14 @@ case ${cpu} in
cr16*) cpu_type=cr16 endian=little ;;
crisv32) cpu_type=cris arch=crisv32 ;;
@@ -20264,8 +21043,8 @@ index 9e44de000145c39abfd3ea325656a4d4bc066198..61f24acdb98484f43ac0c08d3cacfd38
ppc-*-beos*) fmt=coff ;;
diff --git a/gas/read.c b/gas/read.c
index 21c42b27342fb8e2c687417bcdacc4c16e3905b7..9de62b9c512025212d52a19833ffe28004944dd1 100644
---- gas/read.c
-+++ gas/read.c
+--- a/gas/read.c
++++ b/gas/read.c
@@ -43,12 +43,16 @@
#include "wchar.h"
@@ -20354,8 +21133,8 @@ index 21c42b27342fb8e2c687417bcdacc4c16e3905b7..9de62b9c512025212d52a19833ffe280
diff --git a/gas/read.h b/gas/read.h
index 4e5d1bbd2dc7b0724a2fc047db01f97aec8a4bac..59e787e754a14e11195607d382f81992423584cb 100644
---- gas/read.h
-+++ gas/read.h
+--- a/gas/read.h
++++ b/gas/read.h
@@ -130,12 +130,16 @@ extern void do_repeat (int,const char *,const char *);
extern void do_repeat_with_expander (int, const char *, const char *, const char *);
extern void end_repeat (int);
@@ -20375,8 +21154,8 @@ index 4e5d1bbd2dc7b0724a2fc047db01f97aec8a4bac..59e787e754a14e11195607d382f81992
extern symbolS *s_comm_internal (int, symbolS *(*) (int, symbolS *, addressT));
diff --git a/gas/write.c b/gas/write.c
index 56ebb6c565bea35df43565b53206156270a41b66..8a9746c927a3e8b7007cdec9c7f16e47509b5f45 100644
---- gas/write.c
-+++ gas/write.c
+--- a/gas/write.c
++++ b/gas/write.c
@@ -149,13 +149,14 @@ fix_new_internal (fragS *frag, /* Which frag? */
int size, /* 1, 2, or 4 usually. */
symbolS *add_symbol, /* X_add_symbol. */
@@ -20530,8 +21309,8 @@ index 56ebb6c565bea35df43565b53206156270a41b66..8a9746c927a3e8b7007cdec9c7f16e47
diff --git a/gas/write.h b/gas/write.h
index 8303f1be98b6548e4e30a326f042f78e07aed7f5..5f3598655b2665fa86d7b5291643f563536e2f31 100644
---- gas/write.h
-+++ gas/write.h
+--- a/gas/write.h
++++ b/gas/write.h
@@ -172,16 +172,16 @@ extern void write_object_file (void);
extern long relax_frag (segT, fragS *, long);
extern int relax_segment (struct frag *, segT, int);
@@ -20553,8 +21332,8 @@ index 8303f1be98b6548e4e30a326f042f78e07aed7f5..5f3598655b2665fa86d7b5291643f563
#endif /* __write_h__ */
diff --git a/gprof/Makefile.am b/gprof/Makefile.am
index edd100ac924458a1e69da65cab55ddb6a3b61555..286d29546ecdfa6cfafbfc7f7fb83a0fdeadfb83 100644
---- gprof/Makefile.am
-+++ gprof/Makefile.am
+--- a/gprof/Makefile.am
++++ b/gprof/Makefile.am
@@ -36,13 +36,13 @@ noinst_HEADERS = \
corefile.h gmon.h gmon_io.h gmon_out.h gprof.h hertz.h hist.h \
search_list.h source.h sym_ids.h symtab.h utils.h
@@ -20572,8 +21351,8 @@ index edd100ac924458a1e69da65cab55ddb6a3b61555..286d29546ecdfa6cfafbfc7f7fb83a0f
# This empty rule is a hack against gmake patched by Apple.
diff --git a/gprof/Makefile.in b/gprof/Makefile.in
index a9d7073c799863dc3b39124f83dbcba73bf8bf85..4d487c22a56406d567643a6bd53310e501fa99aa 100644
---- gprof/Makefile.in
-+++ gprof/Makefile.in
+--- a/gprof/Makefile.in
++++ b/gprof/Makefile.in
@@ -1013,13 +1013,13 @@ uninstall-man: uninstall-man1
mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
uninstall uninstall-am uninstall-binPROGRAMS uninstall-dvi-am \
@@ -20591,8 +21370,8 @@ index a9d7073c799863dc3b39124f83dbcba73bf8bf85..4d487c22a56406d567643a6bd53310e5
awk -f $(srcdir)/gen-c-prog.awk > ./$*.c \
diff --git a/gprof/configure b/gprof/configure
index 6ffdbe30cef942eb7e28f26674b03c8ff5907711..665d5009457e7e17d7acc0c8bfb81301cd546b32 100755
---- gprof/configure
-+++ gprof/configure
+--- a/gprof/configure
++++ b/gprof/configure
@@ -11850,12 +11850,25 @@ $as_echo "found xgettext program is not GNU xgettext; ignore it" >&6; }
fi
@@ -20621,8 +21400,8 @@ index 6ffdbe30cef942eb7e28f26674b03c8ff5907711..665d5009457e7e17d7acc0c8bfb81301
enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
diff --git a/gprof/configure.in b/gprof/configure.in
index 631e3e467314f3740c737f1534537c7532a00d08..7b4586b0aeee56169f321af15214054feec0c349 100644
---- gprof/configure.in
-+++ gprof/configure.in
+--- a/gprof/configure.in
++++ b/gprof/configure.in
@@ -28,12 +28,23 @@ LT_INIT
AC_CHECK_FUNCS(setmode)
@@ -20649,8 +21428,8 @@ index 631e3e467314f3740c737f1534537c7532a00d08..7b4586b0aeee56169f321af15214054f
diff --git a/gprof/gconfig.in b/gprof/gconfig.in
index 25679910ee73fb2ae8f1c3f7b1cb2951166da71f..4ad8775fd559a1c06b6f572b4af24ca46f7f7f3e 100644
---- gprof/gconfig.in
-+++ gprof/gconfig.in
+--- a/gprof/gconfig.in
++++ b/gprof/gconfig.in
@@ -1,12 +1,8 @@
/* gconfig.in. Generated from configure.in by autoheader. */
@@ -20668,7 +21447,7 @@ diff --git a/include/elf/amigaos.h b/include/elf/amigaos.h
new file mode 100644
index 0000000000000000000000000000000000000000..2cbcd490a300f0248aecf2ca6d50865181a3c1f0
--- /dev/null
-+++ include/elf/amigaos.h
++++ b/include/elf/amigaos.h
@@ -0,0 +1,27 @@
+/* AmigaOS ELF support for BFD.
+ Copyright 2001 Free Software Foundation, Inc.
@@ -20699,15 +21478,21 @@ index 0000000000000000000000000000000000000000..2cbcd490a300f0248aecf2ca6d508651
+#endif /* _ELF_AMIGAOS_H */
diff --git a/include/elf/ppc.h b/include/elf/ppc.h
index f80a1e8a3e9c5852902beaafbb6a2a9e36d815c3..9893a88d96a77d730d91ef2bfe89a18d75029dd1 100644
---- include/elf/ppc.h
-+++ include/elf/ppc.h
-@@ -128,12 +128,18 @@ START_RELOC_NUMBERS (elf_ppc_reloc_type)
+--- a/include/elf/ppc.h
++++ b/include/elf/ppc.h
+@@ -128,12 +128,24 @@ START_RELOC_NUMBERS (elf_ppc_reloc_type)
RELOC_NUMBER (R_PPC_EMB_RELST_LO, 112)
RELOC_NUMBER (R_PPC_EMB_RELST_HI, 113)
RELOC_NUMBER (R_PPC_EMB_RELST_HA, 114)
RELOC_NUMBER (R_PPC_EMB_BIT_FLD, 115)
RELOC_NUMBER (R_PPC_EMB_RELSDA, 116)
++/* Special MorphOS relocs. */
++ RELOC_NUMBER (R_PPC_MORPHOS_DREL, 200)
++ RELOC_NUMBER (R_PPC_MORPHOS_DREL_LO, 201)
++ RELOC_NUMBER (R_PPC_MORPHOS_DREL_HI, 202)
++ RELOC_NUMBER (R_PPC_MORPHOS_DREL_HA, 203)
++
+/* AmigaOS4 relocs */
+ RELOC_NUMBER (R_PPC_AMIGAOS_BREL, 210)
+ RELOC_NUMBER (R_PPC_AMIGAOS_BREL_LO, 211)
@@ -20722,8 +21507,8 @@ index f80a1e8a3e9c5852902beaafbb6a2a9e36d815c3..9893a88d96a77d730d91ef2bfe89a18d
RELOC_NUMBER (R_PPC_VLE_LO16D, 220)
diff --git a/include/libiberty.h b/include/libiberty.h
index cacde800ea3dda438ea8292ab4b9354a63ad048b..595ecf48242a2067dd71c4dda07a57994bdb4981 100644
---- include/libiberty.h
-+++ include/libiberty.h
+--- a/include/libiberty.h
++++ b/include/libiberty.h
@@ -103,13 +103,13 @@ extern int countargv (char**);
/* HAVE_DECL_* is a three-state macro: undefined, 0 or 1. If it is
undefined, we haven't run the autoconf check so provide the
@@ -20741,8 +21526,8 @@ index cacde800ea3dda438ea8292ab4b9354a63ad048b..595ecf48242a2067dd71c4dda07a5799
#define basename basename_cannot_be_used_without_a_prototype
diff --git a/ld/ChangeLog-9197 b/ld/ChangeLog-9197
index 9307f333e3b156758598c19ff0873c21fc1dad29..0f0e189765f0438cd3bbd7a04f36c8e006cef91c 100644
---- ld/ChangeLog-9197
-+++ ld/ChangeLog-9197
+--- a/ld/ChangeLog-9197
++++ b/ld/ChangeLog-9197
@@ -144,12 +144,17 @@ Wed Oct 22 11:29:25 1997 Ian Lance Taylor <ian@cygnus.com>
Fri Oct 17 00:00:13 1997 Richard Henderson <rth@cygnus.com>
@@ -20799,8 +21584,8 @@ index 9307f333e3b156758598c19ff0873c21fc1dad29..0f0e189765f0438cd3bbd7a04f36c8e0
diff --git a/ld/ChangeLog-9899 b/ld/ChangeLog-9899
index 866e4a0cfbb8a086ae01716e4a806e3386914cab..de288123cb7b80422bfc2973640bbdd16c6af900 100644
---- ld/ChangeLog-9899
-+++ ld/ChangeLog-9899
+--- a/ld/ChangeLog-9899
++++ b/ld/ChangeLog-9899
@@ -1881,12 +1881,17 @@ Wed Mar 18 09:42:24 1998 Nick Clifton <nickc@cygnus.com>
* configure.tgt (targ_extra_emuls): Add thumb-pe target.
@@ -20821,8 +21606,8 @@ index 866e4a0cfbb8a086ae01716e4a806e3386914cab..de288123cb7b80422bfc2973640bbdd1
Thu Feb 26 17:09:53 1998 Michael Meissner <meissner@cygnus.com>
diff --git a/ld/Makefile.am b/ld/Makefile.am
index e343ab06531054392ae09d67ecb2dc3022053c07..cbaa4c736f8e87f05a60d8580174e207069872fd 100644
---- ld/Makefile.am
-+++ ld/Makefile.am
+--- a/ld/Makefile.am
++++ b/ld/Makefile.am
@@ -128,12 +128,16 @@ LIBIBERTY = ../libiberty/libiberty.a
ALL_EMULATION_SOURCES = \
@@ -20941,8 +21726,8 @@ index e343ab06531054392ae09d67ecb2dc3022053c07..cbaa4c736f8e87f05a60d8580174e207
${GENSCRIPTS} ppcmacos "$(tdir_ppcmacos)"
diff --git a/ld/Makefile.in b/ld/Makefile.in
index 7da93b46501b8f8aa076134b903e1cdf34025941..43947832717c60ff3a89a8fcea838f5151afd56e 100644
---- ld/Makefile.in
-+++ ld/Makefile.in
+--- a/ld/Makefile.in
++++ b/ld/Makefile.in
@@ -435,12 +435,16 @@ BFDLIB = ../bfd/libbfd.la
LIBIBERTY = ../libiberty/libiberty.a
ALL_EMULATION_SOURCES = \
@@ -21108,8 +21893,8 @@ index 7da93b46501b8f8aa076134b903e1cdf34025941..43947832717c60ff3a89a8fcea838f51
${GENSCRIPTS} ppcmacos "$(tdir_ppcmacos)"
diff --git a/ld/configure.host b/ld/configure.host
index f47b961176fa37c2786aa9ff322b21b06081cdfd..c7e1e700c24e48e783d07023b678dbd59bee0b11 100644
---- ld/configure.host
-+++ ld/configure.host
+--- a/ld/configure.host
++++ b/ld/configure.host
@@ -170,12 +170,16 @@ mips*-sgi-irix4* | mips*-sgi-irix5*)
mips*-sgi-irix6*)
@@ -21129,8 +21914,8 @@ index f47b961176fa37c2786aa9ff322b21b06081cdfd..c7e1e700c24e48e783d07023b678dbd5
;;
diff --git a/ld/configure.tgt b/ld/configure.tgt
index 72bc5bca48d7c93f838de826a0685c13ef1db3c2..ddba96d6da87eb2f033eae77509639b6a630ec2a 100644
---- ld/configure.tgt
-+++ ld/configure.tgt
+--- a/ld/configure.tgt
++++ b/ld/configure.tgt
@@ -298,12 +298,13 @@ x86_64-*-pe | x86_64-*-pep) targ_emul=i386pep ;
targ_extra_ofiles="deffilep.o pep-dll.o pe-dll.o" ;;
x86_64-*-mingw*) targ_emul=i386pep ;
@@ -21195,7 +21980,7 @@ diff --git a/ld/emulparams/amiga.sh b/ld/emulparams/amiga.sh
new file mode 100644
index 0000000000000000000000000000000000000000..c2915d47d7964c6406eae9079ce90d695ecdbfda
--- /dev/null
-+++ ld/emulparams/amiga.sh
++++ b/ld/emulparams/amiga.sh
@@ -0,0 +1,6 @@
+SCRIPT_NAME=amiga
+OUTPUT_FORMAT="amiga"
@@ -21207,7 +21992,7 @@ diff --git a/ld/emulparams/amiga_bss.sh b/ld/emulparams/amiga_bss.sh
new file mode 100644
index 0000000000000000000000000000000000000000..5405d737448875ea39e5d9c4edfd59ee32c8a7b4
--- /dev/null
-+++ ld/emulparams/amiga_bss.sh
++++ b/ld/emulparams/amiga_bss.sh
@@ -0,0 +1,6 @@
+SCRIPT_NAME=amiga_bss
+OUTPUT_FORMAT="amiga"
@@ -21219,7 +22004,7 @@ diff --git a/ld/emulparams/amigaos.sh b/ld/emulparams/amigaos.sh
new file mode 100644
index 0000000000000000000000000000000000000000..605b81e76bcbbd2322561d7d9502190dc7c00674
--- /dev/null
-+++ ld/emulparams/amigaos.sh
++++ b/ld/emulparams/amigaos.sh
@@ -0,0 +1,26 @@
+#. ${srcdir}/emulparams/elf32ppccommon.sh
+TEMPLATE_NAME=amigaos
@@ -21251,7 +22036,7 @@ diff --git a/ld/emulparams/amithlon.sh b/ld/emulparams/amithlon.sh
new file mode 100644
index 0000000000000000000000000000000000000000..14b1c776396e2424af51c9b409e2d05f2881a84d
--- /dev/null
-+++ ld/emulparams/amithlon.sh
++++ b/ld/emulparams/amithlon.sh
@@ -0,0 +1,11 @@
+SCRIPT_NAME=amithlon
+OUTPUT_FORMAT="elf32-i386be-amithlon"
@@ -21268,7 +22053,7 @@ diff --git a/ld/emulparams/morphos.sh b/ld/emulparams/morphos.sh
new file mode 100644
index 0000000000000000000000000000000000000000..45908c662f9b6085877dd39621e813da45a9f5f7
--- /dev/null
-+++ ld/emulparams/morphos.sh
++++ b/ld/emulparams/morphos.sh
@@ -0,0 +1,6 @@
+TEMPLATE_NAME=morphos
+SCRIPT_NAME=morphos
@@ -21280,7 +22065,7 @@ diff --git a/ld/emulparams/morphos_baserel.sh b/ld/emulparams/morphos_baserel.sh
new file mode 100644
index 0000000000000000000000000000000000000000..46c483484813395904772673d1ae1eed0bc9109f
--- /dev/null
-+++ ld/emulparams/morphos_baserel.sh
++++ b/ld/emulparams/morphos_baserel.sh
@@ -0,0 +1,6 @@
+TEMPLATE_NAME=morphos
+SCRIPT_NAME=morphos_baserel
@@ -21292,7 +22077,7 @@ diff --git a/ld/emulparams/ppcamiga.sh b/ld/emulparams/ppcamiga.sh
new file mode 100644
index 0000000000000000000000000000000000000000..3f266cf5265f13748eeb78f67dd93227ade92de5
--- /dev/null
-+++ ld/emulparams/ppcamiga.sh
++++ b/ld/emulparams/ppcamiga.sh
@@ -0,0 +1,8 @@
+SCRIPT_NAME=amiga
+OUTPUT_FORMAT="amiga"
@@ -21306,7 +22091,7 @@ diff --git a/ld/emulparams/ppcamiga_bss.sh b/ld/emulparams/ppcamiga_bss.sh
new file mode 100644
index 0000000000000000000000000000000000000000..8d1720fb17c876d55b75f0885eb9f6eb0c7e9f1e
--- /dev/null
-+++ ld/emulparams/ppcamiga_bss.sh
++++ b/ld/emulparams/ppcamiga_bss.sh
@@ -0,0 +1,8 @@
+SCRIPT_NAME=amiga_bss
+OUTPUT_FORMAT="amiga"
@@ -21320,7 +22105,7 @@ diff --git a/ld/emultempl/amiga.em b/ld/emultempl/amiga.em
new file mode 100644
index 0000000000000000000000000000000000000000..c6abc5c644d3d93609d66972752e6cd3d474d70e
--- /dev/null
-+++ ld/emultempl/amiga.em
++++ b/ld/emultempl/amiga.em
@@ -0,0 +1,288 @@
+# This shell script emits a C file. -*- C -*-
+# It does some substitutions.
@@ -21618,7 +22403,7 @@ diff --git a/ld/emultempl/amithlon.em b/ld/emultempl/amithlon.em
new file mode 100644
index 0000000000000000000000000000000000000000..5e453a72f8c01e621d110d505b83d1abbcd19831
--- /dev/null
-+++ ld/emultempl/amithlon.em
++++ b/ld/emultempl/amithlon.em
@@ -0,0 +1,1698 @@
+# This shell script emits a C file. -*- C -*-
+# It does some substitutions.
@@ -23322,7 +24107,7 @@ diff --git a/ld/emultempl/morphos.em b/ld/emultempl/morphos.em
new file mode 100644
index 0000000000000000000000000000000000000000..cd3b9a790fb286187d8fa3e11af9382f1603d16b
--- /dev/null
-+++ ld/emultempl/morphos.em
++++ b/ld/emultempl/morphos.em
@@ -0,0 +1,1104 @@
+# This shell script emits a C file. -*- C -*-
+# It does some substitutions.
@@ -24430,8 +25215,8 @@ index 0000000000000000000000000000000000000000..cd3b9a790fb286187d8fa3e11af9382f
+EOF
diff --git a/ld/emultempl/ppc32elf.em b/ld/emultempl/ppc32elf.em
index 6843770ca9431d7a4b698bfda7060082b215c41f..801d1d6424bc1f61bb0e7171de9f9b5178bc8100 100644
---- ld/emultempl/ppc32elf.em
-+++ ld/emultempl/ppc32elf.em
+--- a/ld/emultempl/ppc32elf.em
++++ b/ld/emultempl/ppc32elf.em
@@ -26,12 +26,15 @@
fragment <<EOF
@@ -24487,8 +25272,8 @@ index 6843770ca9431d7a4b698bfda7060082b215c41f..801d1d6424bc1f61bb0e7171de9f9b51
{ "secure-plt", no_argument, NULL, OPTION_NEW_PLT },
diff --git a/ld/ldctor.c b/ld/ldctor.c
index b29c1e0cbb13463f58989042722775698365cf9a..18d5f9370c7a0e9b009c74fdff48a4c45659245f 100644
---- ld/ldctor.c
-+++ ld/ldctor.c
+--- a/ld/ldctor.c
++++ b/ld/ldctor.c
@@ -256,14 +256,18 @@ ldctor_build_sets (void)
reloc_howto_type *howto;
int reloc_size, size;
@@ -24542,8 +25327,8 @@ index b29c1e0cbb13463f58989042722775698365cf9a..18d5f9370c7a0e9b009c74fdff48a4c4
diff --git a/ld/ldfile.c b/ld/ldfile.c
index e9091e9fa9ab0cb1182a102de48096ac13215a39..034eb2a7e452623f8c2571f4d6186b981c10c11d 100644
---- ld/ldfile.c
-+++ ld/ldfile.c
+--- a/ld/ldfile.c
++++ b/ld/ldfile.c
@@ -63,12 +63,46 @@ typedef struct search_arch
} search_arch_type;
@@ -24660,8 +25445,8 @@ index e9091e9fa9ab0cb1182a102de48096ac13215a39..034eb2a7e452623f8c2571f4d6186b98
continue processing other input files in case there
diff --git a/ld/ldfile.h b/ld/ldfile.h
index 945609250afc6fede2985dbdd59bf035cb835843..530fb0f3b78f7ce54421b074bea4fcd5ae28022d 100644
---- ld/ldfile.h
-+++ ld/ldfile.h
+--- a/ld/ldfile.h
++++ b/ld/ldfile.h
@@ -56,7 +56,12 @@ extern bfd_boolean ldfile_try_open_bfd
extern void ldfile_set_output_arch
(const char *, enum bfd_architecture);
@@ -24677,8 +25462,8 @@ index 945609250afc6fede2985dbdd59bf035cb835843..530fb0f3b78f7ce54421b074bea4fcd5
#endif
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 459f277a3ea5baa2f38e7b95db0ac9ef67d648b8..d199cda1fd9bd4d8bfa12fe72a44501861ffe1ff 100644
---- ld/ldlang.c
-+++ ld/ldlang.c
+--- a/ld/ldlang.c
++++ b/ld/ldlang.c
@@ -3389,12 +3389,19 @@ typedef struct bfd_sym_chain ldlang_undef_chain_list_type;
#define ldlang_undef_chain_list_head entry_symbol.next
@@ -24701,8 +25486,8 @@ index 459f277a3ea5baa2f38e7b95db0ac9ef67d648b8..d199cda1fd9bd4d8bfa12fe72a445018
ldlang_undef_chain_list_head = new_undef;
diff --git a/ld/ldlang.h b/ld/ldlang.h
index d5ea8d20e34c9c4697d0aa14b4af09d2df8f0d20..f6f061dfe6e92cdb3a5097baf644773cc402ad3f 100644
---- ld/ldlang.h
-+++ ld/ldlang.h
+--- a/ld/ldlang.h
++++ b/ld/ldlang.h
@@ -302,12 +302,14 @@ typedef struct lang_input_statement_struct
/* Point to the next file, but skips archive contents. */
union lang_statement_union *next_real_file;
@@ -24720,8 +25505,8 @@ index d5ea8d20e34c9c4697d0aa14b4af09d2df8f0d20..f6f061dfe6e92cdb3a5097baf644773c
asection *section;
diff --git a/ld/ldlex.c b/ld/ldlex.c
index 50bb3b1e14133555e524ad059d7b578cfaac6b24..eb7e21a7741a0fc82b72f2c7e3d88d1888998db8 100644
---- ld/ldlex.c
-+++ ld/ldlex.c
+--- a/ld/ldlex.c
++++ b/ld/ldlex.c
@@ -1,17 +1,17 @@
-#line 3 "ldlex.c"
@@ -25236,8 +26021,8 @@ index 50bb3b1e14133555e524ad059d7b578cfaac6b24..eb7e21a7741a0fc82b72f2c7e3d88d18
saving the current input info on the include stack. */
diff --git a/ld/ldmain.c b/ld/ldmain.c
index 73353309c3595a2e53e160cbf2bcfd215a92aab2..8b7513d8e83264c0cb236781cdb753181612fb14 100644
---- ld/ldmain.c
-+++ ld/ldmain.c
+--- a/ld/ldmain.c
++++ b/ld/ldmain.c
@@ -408,16 +408,23 @@ main (int argc, char **argv)
}
@@ -25266,7 +26051,7 @@ diff --git a/ld/scripttempl/amiga.sc b/ld/scripttempl/amiga.sc
new file mode 100644
index 0000000000000000000000000000000000000000..f5c9d694742ecabb3a2a9c6b85e8f2aaf23e78f1
--- /dev/null
-+++ ld/scripttempl/amiga.sc
++++ b/ld/scripttempl/amiga.sc
@@ -0,0 +1,49 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
@@ -25321,7 +26106,7 @@ diff --git a/ld/scripttempl/amiga_bss.sc b/ld/scripttempl/amiga_bss.sc
new file mode 100644
index 0000000000000000000000000000000000000000..668ce7c0dee923dd0d4643a379bf24f4b352cef0
--- /dev/null
-+++ ld/scripttempl/amiga_bss.sc
++++ b/ld/scripttempl/amiga_bss.sc
@@ -0,0 +1,41 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
@@ -25369,8 +26154,8 @@ similarity index 88%
copy from ld/scripttempl/elf64hppa.sc
copy to ld/scripttempl/amigaos.sc
index 18090e6b9b73969ba6c33ccb272d88fc125be19d..865c9ba63ca1746c6bc6b66153557a10da677e58 100644
---- ld/scripttempl/elf64hppa.sc
-+++ ld/scripttempl/amigaos.sc
+--- a/ld/scripttempl/elf64hppa.sc
++++ b/ld/scripttempl/amigaos.sc
@@ -33,17 +33,14 @@
# OTHER_SDATA_SECTIONS - sections just after .sdata.
# OTHER_BSS_SYMBOLS - symbols that appear at the start of the
@@ -25740,8 +26525,8 @@ similarity index 76%
copy from ld/scripttempl/mep.sc
copy to ld/scripttempl/amithlon.sc
index 3fc1352e19184c0319302e809cccf7cc861ec8d7..b8248cd4966e34e95c8b262e515ace1802c6db35 100644
---- ld/scripttempl/mep.sc
-+++ ld/scripttempl/amithlon.sc
+--- a/ld/scripttempl/mep.sc
++++ b/ld/scripttempl/amithlon.sc
@@ -1,57 +1,45 @@
#
# Unusual variables checked by this code:
@@ -26110,11 +26895,465 @@ index 3fc1352e19184c0319302e809cccf7cc861ec8d7..b8248cd4966e34e95c8b262e515ace18
+ .libnix___LIB_LIST__ ${RELOCATING-0} : { *(.libnix___LIB_LIST__) }
}
EOF
+diff --git a/ld/scripttempl/elfi370.sc b/ld/scripttempl/morphos.sc
+similarity index 88%
+copy from ld/scripttempl/elfi370.sc
+copy to ld/scripttempl/morphos.sc
+index a845b2980105fa8504b5bf8a83aeb6fc086caa6e..469a8f5f2cad237c9317faf5d23db7f2b7a63eee 100644
+--- a/ld/scripttempl/elfi370.sc
++++ b/ld/scripttempl/morphos.sc
+@@ -1,17 +1,14 @@
+ #
+-# This is just a raw copy of elfppc.sc and has not been otherwise modified
+-#
+ # Unusual variables checked by this code:
+-# NOP - four byte opcode for no-op (defaults to 0)
++# NOP - two byte opcode for no-op (defaults to 0)
+ # DATA_ADDR - if end-of-text-plus-one-page isn't right for data start
+ # OTHER_READONLY_SECTIONS - other than .text .init .rodata ...
+ # (e.g., .PARISC.milli)
+ # OTHER_READWRITE_SECTIONS - other than .data .bss .ctors .sdata ...
+ # (e.g., .PARISC.global)
+-# ATTRS_SECTIONS - at the end
+ # OTHER_SECTIONS - at the end
+ # EXECUTABLE_SYMBOLS - symbols that must be defined for an
+ # executable (e.g., _DYNAMIC_LINK)
+ # TEXT_START_SYMBOLS - symbols that appear at the start of the
+ # .text section.
+ # DATA_START_SYMBOLS - symbols that appear at the start of the
+@@ -19,37 +16,35 @@
+ # OTHER_BSS_SYMBOLS - symbols that appear at the start of the
+ # .bss section besides __bss_start.
+ #
+ # When adding sections, do note that the names of some sections are used
+ # when specifying the start address of the next.
+ #
+-test -z "$ENTRY" && ENTRY=_start
+ test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT}
+ test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT}
+-test -z "$ATTRS_SECTIONS" && ATTRS_SECTIONS=".gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }"
+ test "$LD_FLAG" = "N" && DATA_ADDR=.
+ SBSS2=".sbss2 ${RELOCATING-0} : { *(.sbss2) }"
+ SDATA2=".sdata2 ${RELOCATING-0} : { *(.sdata2) }"
+ INTERP=".interp ${RELOCATING-0} : { *(.interp) }"
+ PLT=".plt ${RELOCATING-0} : { *(.plt) }"
+ cat <<EOF
+ OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}",
+ "${LITTLE_OUTPUT_FORMAT}")
+ OUTPUT_ARCH(${ARCH})
+-${RELOCATING+ENTRY(${ENTRY})}
+
+ ${RELOCATING+${LIB_SEARCH_DIRS}}
+ ${RELOCATING+/* Do we need any of these for elf?
+ __DYNAMIC = 0; ${STACKZERO+${STACKZERO}} ${SHLIB_PATH+${SHLIB_PATH}} */}
+ ${RELOCATING+${EXECUTABLE_SYMBOLS}}
+ ${RELOCATING- /* For some reason, the Solaris linker makes bad executables
+ if gld -r is used and the intermediate file has sections starting
+ at non-zero addresses. Could be a Solaris ld bug, could be a GNU ld
+ bug. But for now assigning the zero vmas works. */}
+
+ ${RELOCATING+PROVIDE (__stack = 0);}
++PROVIDE (__machtype = 0x1);
+ SECTIONS
+ {
+ /* Read-only sections, merged into text segment: */
+ ${CREATE_SHLIB-${RELOCATING+. = ${TEXT_START_ADDR} + SIZEOF_HEADERS;}}
+ ${CREATE_SHLIB+${RELOCATING+. = SIZEOF_HEADERS;}}
+ ${CREATE_SHLIB-${INTERP}}
+@@ -77,27 +72,30 @@ SECTIONS
+ .rela.sdata ${RELOCATING-0} : { *(.rela.sdata) }
+ .rela.sbss ${RELOCATING-0} : { *(.rela.sbss) }
+ .rela.sdata2 ${RELOCATING-0} : { *(.rela.sdata2) }
+ .rela.sbss2 ${RELOCATING-0} : { *(.rela.sbss2) }
+ .text ${RELOCATING-0} :
+ {
++ PROVIDE (__text_start = .);
+ ${RELOCATING+${TEXT_START_SYMBOLS}}
+ *(.text)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.gnu.linkonce.t*)
++ PROVIDE (__text_end = .);
+ } =${NOP-0}
++ PROVIDE (__text_size = SIZEOF(.text));
+ .init ${RELOCATING-0} : { *(.init) } =${NOP-0}
+ .fini ${RELOCATING-0} : { *(.fini) } =${NOP-0}
+ .rodata ${RELOCATING-0} : { *(.rodata) *(.gnu.linkonce.r*) }
+ .rodata1 ${RELOCATING-0} : { *(.rodata1) }
+ ${RELOCATING+_etext = .;}
+ ${RELOCATING+PROVIDE (etext = .);}
+ ${CREATE_SHLIB-${SDATA2}}
+ ${CREATE_SHLIB-${SBSS2}}
+- ${OTHER_READONLY_SECTIONS}
++ ${RELOCATING+${OTHER_READONLY_SECTIONS}}
+
+ /* Adjust the address for the data segment. We want to adjust up to
+ the same address within the page on the next page up. It would
+ be more correct to do this:
+ ${RELOCATING+. = ${DATA_ADDR-ALIGN(${MAXPAGESIZE}) + (ALIGN(8) & (${MAXPAGESIZE} - 1))};}
+ The current expression does not correctly handle the case of a
+@@ -111,19 +109,22 @@ SECTIONS
+ that no actual memory is lost; the page which is skipped can not
+ be referenced). */
+ ${RELOCATING+. = ${DATA_ADDR- ALIGN(8) + ${MAXPAGESIZE}};}
+
+ .data ${RELOCATING-0} :
+ {
++ PROVIDE (__data_start = .);
+ ${RELOCATING+${DATA_START_SYMBOLS}}
+ *(.data)
+ *(.gnu.linkonce.d*)
+ ${CONSTRUCTING+CONSTRUCTORS}
++ PROVIDE (__data_end = .);
+ }
++ PROVIDE (__data_size = SIZEOF(.data));
+ .data1 ${RELOCATING-0} : { *(.data1) }
+- ${OTHER_READWRITE_SECTIONS}
++ ${RELOCATING+${OTHER_READWRITE_SECTIONS}}
+
+ .got1 ${RELOCATING-0} : { *(.got1) }
+ .dynamic ${RELOCATING-0} : { *(.dynamic) }
+
+ /* Put .ctors and .dtors next to the .got2 section, so that the pointers
+ get relocated with -mrelocatable. Also put in the .fixup pointers.
+@@ -152,32 +153,43 @@ SECTIONS
+ ${CREATE_SHLIB+${SBSS2}}
+ ${RELOCATING+PROVIDE (_GOT_END_ = .);}
+
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+- .sdata ${RELOCATING-0} : { *(.sdata) }
++ .sdata ${RELOCATING-0} :
++ {
++ PROVIDE (__sdata_start = .);
++ *(.sdata)
++ PROVIDE (__r13_init = 0x8000);
++ PROVIDE (__sdata_end = .);
++ }
++ PROVIDE (__sdata_size = SIZEOF(.sdata));
+ ${RELOCATING+_edata = .;}
+ ${RELOCATING+PROVIDE (edata = .);}
+ .sbss ${RELOCATING-0} :
+ {
+- ${RELOCATING+PROVIDE (__sbss_start = .);}
++ PROVIDE (__sbss_start = .);
+ *(.sbss)
+ *(.scommon)
+ *(.dynsbss)
+- ${RELOCATING+PROVIDE (__sbss_end = .);}
++ PROVIDE (__sbss_end = .);
+ }
++ PROVIDE (__sbss_size = SIZEOF(.sbss));
+ ${PLT}
+ .bss ${RELOCATING-0} :
+ {
+- ${RELOCATING+${OTHER_BSS_SYMBOLS}}
+- ${RELOCATING+PROVIDE (__bss_start = .);}
+- *(.dynbss)
+- *(.bss)
+- *(COMMON)
++ PROVIDE (__bss_start = .);
++ ${RELOCATING+${OTHER_BSS_SYMBOLS}}
++ ${RELOCATING+PROVIDE (__bss_start = .);}
++ *(.dynbss)
++ *(.bss)
++ *(COMMON)
++ PROVIDE (__bss_end = .);
+ }
++ PROVIDE (__bss_size = SIZEOF(.bss));
+ ${RELOCATING+_end = . ;}
+ ${RELOCATING+PROVIDE (end = .);}
+
+ /* These are needed for ELF backends which have not yet been
+ converted to the new style linker. */
+ .stab 0 : { *(.stab) }
+@@ -197,13 +209,13 @@ SECTIONS
+
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+
+ /* DWARF 2 */
+- .debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) }
++ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+@@ -211,17 +223,10 @@ SECTIONS
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+
+- /* DWARF 3 */
+- .debug_pubtypes 0 : { *(.debug_pubtypes) }
+- .debug_ranges 0 : { *(.debug_ranges) }
+-
+- /* DWARF Extension. */
+- .debug_macro 0 : { *(.debug_macro) }
+-
+- ${ATTRS_SECTIONS}
++ /* These must appear regardless of ${RELOCATING}. */
+ ${OTHER_SECTIONS}
+ }
+ EOF
+diff --git a/ld/scripttempl/elfi370.sc b/ld/scripttempl/morphos_baserel.sc
+similarity index 69%
+copy from ld/scripttempl/elfi370.sc
+copy to ld/scripttempl/morphos_baserel.sc
+index a845b2980105fa8504b5bf8a83aeb6fc086caa6e..4f0f4aba86bddb4e76a9405c0da04df4c0091d9e 100644
+--- a/ld/scripttempl/elfi370.sc
++++ b/ld/scripttempl/morphos_baserel.sc
+@@ -1,17 +1,14 @@
+ #
+-# This is just a raw copy of elfppc.sc and has not been otherwise modified
+-#
+ # Unusual variables checked by this code:
+-# NOP - four byte opcode for no-op (defaults to 0)
++# NOP - two byte opcode for no-op (defaults to 0)
+ # DATA_ADDR - if end-of-text-plus-one-page isn't right for data start
+ # OTHER_READONLY_SECTIONS - other than .text .init .rodata ...
+ # (e.g., .PARISC.milli)
+ # OTHER_READWRITE_SECTIONS - other than .data .bss .ctors .sdata ...
+ # (e.g., .PARISC.global)
+-# ATTRS_SECTIONS - at the end
+ # OTHER_SECTIONS - at the end
+ # EXECUTABLE_SYMBOLS - symbols that must be defined for an
+ # executable (e.g., _DYNAMIC_LINK)
+ # TEXT_START_SYMBOLS - symbols that appear at the start of the
+ # .text section.
+ # DATA_START_SYMBOLS - symbols that appear at the start of the
+@@ -19,37 +16,35 @@
+ # OTHER_BSS_SYMBOLS - symbols that appear at the start of the
+ # .bss section besides __bss_start.
+ #
+ # When adding sections, do note that the names of some sections are used
+ # when specifying the start address of the next.
+ #
+-test -z "$ENTRY" && ENTRY=_start
+ test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT}
+ test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT}
+-test -z "$ATTRS_SECTIONS" && ATTRS_SECTIONS=".gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }"
+ test "$LD_FLAG" = "N" && DATA_ADDR=.
+ SBSS2=".sbss2 ${RELOCATING-0} : { *(.sbss2) }"
+ SDATA2=".sdata2 ${RELOCATING-0} : { *(.sdata2) }"
+ INTERP=".interp ${RELOCATING-0} : { *(.interp) }"
+ PLT=".plt ${RELOCATING-0} : { *(.plt) }"
+ cat <<EOF
+ OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}",
+ "${LITTLE_OUTPUT_FORMAT}")
+ OUTPUT_ARCH(${ARCH})
+-${RELOCATING+ENTRY(${ENTRY})}
+
+ ${RELOCATING+${LIB_SEARCH_DIRS}}
+ ${RELOCATING+/* Do we need any of these for elf?
+ __DYNAMIC = 0; ${STACKZERO+${STACKZERO}} ${SHLIB_PATH+${SHLIB_PATH}} */}
+ ${RELOCATING+${EXECUTABLE_SYMBOLS}}
+ ${RELOCATING- /* For some reason, the Solaris linker makes bad executables
+ if gld -r is used and the intermediate file has sections starting
+ at non-zero addresses. Could be a Solaris ld bug, could be a GNU ld
+ bug. But for now assigning the zero vmas works. */}
+
+ ${RELOCATING+PROVIDE (__stack = 0);}
++PROVIDE (__machtype = 0x1);
+ SECTIONS
+ {
+ /* Read-only sections, merged into text segment: */
+ ${CREATE_SHLIB-${RELOCATING+. = ${TEXT_START_ADDR} + SIZEOF_HEADERS;}}
+ ${CREATE_SHLIB+${RELOCATING+. = SIZEOF_HEADERS;}}
+ ${CREATE_SHLIB-${INTERP}}
+@@ -58,72 +53,53 @@ SECTIONS
+ .dynstr ${RELOCATING-0} : { *(.dynstr) }
+ .gnu.version ${RELOCATING-0} : { *(.gnu.version) }
+ .gnu.version_d ${RELOCATING-0} : { *(.gnu.version_d) }
+ .gnu.version_r ${RELOCATING-0} : { *(.gnu.version_r) }
+ .rela.text ${RELOCATING-0} :
+ { *(.rela.text) *(.rela.gnu.linkonce.t*) }
+- .rela.data ${RELOCATING-0} :
+- { *(.rela.data) *(.rela.gnu.linkonce.d*) }
+- .rela.rodata ${RELOCATING-0} :
+- { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
+ .rela.got ${RELOCATING-0} : { *(.rela.got) }
+ .rela.got1 ${RELOCATING-0} : { *(.rela.got1) }
+ .rela.got2 ${RELOCATING-0} : { *(.rela.got2) }
+ .rela.ctors ${RELOCATING-0} : { *(.rela.ctors) }
+ .rela.dtors ${RELOCATING-0} : { *(.rela.dtors) }
+ .rela.init ${RELOCATING-0} : { *(.rela.init) }
+ .rela.fini ${RELOCATING-0} : { *(.rela.fini) }
+- .rela.bss ${RELOCATING-0} : { *(.rela.bss) }
+ .rela.plt ${RELOCATING-0} : { *(.rela.plt) }
+- .rela.sdata ${RELOCATING-0} : { *(.rela.sdata) }
+- .rela.sbss ${RELOCATING-0} : { *(.rela.sbss) }
++ .rela.rodata ${RELOCATING-0} :
++ { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
++ .rela.sdata ${RELOCATING-0} :
++ {
++ *(.rela.data)
++ *(.rela.gnu.linkonce.d*)
++ *(.rela.sdata)
++ }
++ .rela.sbss ${RELOCATING-0} :
++ {
++ *(.rela.sbss)
++ *(.rela.bss)
++ }
+ .rela.sdata2 ${RELOCATING-0} : { *(.rela.sdata2) }
+ .rela.sbss2 ${RELOCATING-0} : { *(.rela.sbss2) }
+ .text ${RELOCATING-0} :
+ {
++ PROVIDE (__text_start = .);
+ ${RELOCATING+${TEXT_START_SYMBOLS}}
+ *(.text)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.gnu.linkonce.t*)
++ PROVIDE (__text_end = .);
+ } =${NOP-0}
++ PROVIDE (__text_size = SIZEOF(.text));
+ .init ${RELOCATING-0} : { *(.init) } =${NOP-0}
+ .fini ${RELOCATING-0} : { *(.fini) } =${NOP-0}
+- .rodata ${RELOCATING-0} : { *(.rodata) *(.gnu.linkonce.r*) }
+- .rodata1 ${RELOCATING-0} : { *(.rodata1) }
+ ${RELOCATING+_etext = .;}
+ ${RELOCATING+PROVIDE (etext = .);}
+ ${CREATE_SHLIB-${SDATA2}}
+ ${CREATE_SHLIB-${SBSS2}}
+- ${OTHER_READONLY_SECTIONS}
+-
+- /* Adjust the address for the data segment. We want to adjust up to
+- the same address within the page on the next page up. It would
+- be more correct to do this:
+- ${RELOCATING+. = ${DATA_ADDR-ALIGN(${MAXPAGESIZE}) + (ALIGN(8) & (${MAXPAGESIZE} - 1))};}
+- The current expression does not correctly handle the case of a
+- text segment ending precisely at the end of a page; it causes the
+- data segment to skip a page. The above expression does not have
+- this problem, but it will currently (2/95) cause BFD to allocate
+- a single segment, combining both text and data, for this case.
+- This will prevent the text segment from being shared among
+- multiple executions of the program; I think that is more
+- important than losing a page of the virtual address space (note
+- that no actual memory is lost; the page which is skipped can not
+- be referenced). */
+- ${RELOCATING+. = ${DATA_ADDR- ALIGN(8) + ${MAXPAGESIZE}};}
+-
+- .data ${RELOCATING-0} :
+- {
+- ${RELOCATING+${DATA_START_SYMBOLS}}
+- *(.data)
+- *(.gnu.linkonce.d*)
+- ${CONSTRUCTING+CONSTRUCTORS}
+- }
+- .data1 ${RELOCATING-0} : { *(.data1) }
+- ${OTHER_READWRITE_SECTIONS}
++ ${RELOCATING+${OTHER_READONLY_SECTIONS}}
+
+ .got1 ${RELOCATING-0} : { *(.got1) }
+ .dynamic ${RELOCATING-0} : { *(.dynamic) }
+
+ /* Put .ctors and .dtors next to the .got2 section, so that the pointers
+ get relocated with -mrelocatable. Also put in the .fixup pointers.
+@@ -148,38 +124,41 @@ SECTIONS
+ ${RELOCATING+PROVIDE (_GOT_START_ = .);}
+ .got ${RELOCATING-0} : { *(.got) }
+ .got.plt ${RELOCATING-0} : { *(.got.plt) }
+ ${CREATE_SHLIB+${SDATA2}}
+ ${CREATE_SHLIB+${SBSS2}}
+ ${RELOCATING+PROVIDE (_GOT_END_ = .);}
+-
+- /* We want the small data sections together, so single-instruction offsets
++ .rodata ${RELOCATING-0} : { *(.rodata) }
++ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+- .sdata ${RELOCATING-0} : { *(.sdata) }
++ .sdata ${RELOCATING-0} :
++ {
++ /*PROVIDE (__sdata_start = .);*/
++ __sdata_start = .;
++ *(.data)
++ *(.data1)
++ __small_start = .;
++ *(.sdata)
++ PROVIDE (__r13_init = /*__small_start*/ __sdata_start + 0x8000);
++ PROVIDE (__sdata_end = .);
++ }
++ PROVIDE (__sdata_size = SIZEOF(.sdata));
+ ${RELOCATING+_edata = .;}
+ ${RELOCATING+PROVIDE (edata = .);}
+ .sbss ${RELOCATING-0} :
+ {
+- ${RELOCATING+PROVIDE (__sbss_start = .);}
++ PROVIDE (__sbss_start = .);
+ *(.sbss)
+ *(.scommon)
+ *(.dynsbss)
+- ${RELOCATING+PROVIDE (__sbss_end = .);}
+- }
+- ${PLT}
+- .bss ${RELOCATING-0} :
+- {
+- ${RELOCATING+${OTHER_BSS_SYMBOLS}}
+- ${RELOCATING+PROVIDE (__bss_start = .);}
+- *(.dynbss)
+- *(.bss)
+- *(COMMON)
++ *(.bss)
++ *(COMMON)
++ PROVIDE (__sbss_end = .);
+ }
+- ${RELOCATING+_end = . ;}
+- ${RELOCATING+PROVIDE (end = .);}
++ PROVIDE (__sbss_size = SIZEOF(.sbss));
+
+ /* These are needed for ELF backends which have not yet been
+ converted to the new style linker. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+
+@@ -197,13 +176,13 @@ SECTIONS
+
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+
+ /* DWARF 2 */
+- .debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) }
++ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+@@ -211,17 +190,10 @@ SECTIONS
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+
+- /* DWARF 3 */
+- .debug_pubtypes 0 : { *(.debug_pubtypes) }
+- .debug_ranges 0 : { *(.debug_ranges) }
+-
+- /* DWARF Extension. */
+- .debug_macro 0 : { *(.debug_macro) }
+-
+- ${ATTRS_SECTIONS}
++ /* These must appear regardless of ${RELOCATING}. */
+ ${OTHER_SECTIONS}
+ }
+ EOF
diff --git a/libiberty/config/mh-amigaos b/libiberty/config/mh-amigaos
new file mode 100644
index 0000000000000000000000000000000000000000..495fa7e35897000efe600c9f1dd844b086731fcd
--- /dev/null
-+++ libiberty/config/mh-amigaos
++++ b/libiberty/config/mh-amigaos
@@ -0,0 +1,12 @@
+# Host makefile fragment for Commodore Amiga running AmigaOS.
+
@@ -26132,7 +27371,7 @@ diff --git a/libiberty/config/mh-morphos b/libiberty/config/mh-morphos
new file mode 100644
index 0000000000000000000000000000000000000000..064647ab3397b088317905a47cce0171e25a4bae
--- /dev/null
-+++ libiberty/config/mh-morphos
++++ b/libiberty/config/mh-morphos
@@ -0,0 +1,12 @@
+# Host makefile fragment for Commodore Amiga running AmigaOS.
+
@@ -26148,8 +27387,8 @@ index 0000000000000000000000000000000000000000..064647ab3397b088317905a47cce0171
+HDEFINES =
diff --git a/libiberty/lrealpath.c b/libiberty/lrealpath.c
index b27c8de990e974c7294dfc4024ef44fbd3844a52..e94add4802d830aa3e04c9a784a8d081938ae0d5 100644
---- libiberty/lrealpath.c
-+++ libiberty/lrealpath.c
+--- a/libiberty/lrealpath.c
++++ b/libiberty/lrealpath.c
@@ -69,12 +69,18 @@ extern char *canonicalize_file_name (const char *);
# if defined (_WIN32)
# define WIN32_LEAN_AND_MEAN
@@ -26171,8 +27410,8 @@ index b27c8de990e974c7294dfc4024ef44fbd3844a52..e94add4802d830aa3e04c9a784a8d081
the most common case. Note that, if there isn't a compile time
diff --git a/opcodes/m68k-dis.c b/opcodes/m68k-dis.c
index bc2dd491592e56fb664cdf96fc32491c08e1e075..bc40541b7c5aecc30a7a74fd61f29225acd21fcd 100644
---- opcodes/m68k-dis.c
-+++ opcodes/m68k-dis.c
+--- a/opcodes/m68k-dis.c
++++ b/opcodes/m68k-dis.c
@@ -36,13 +36,13 @@ const char * const fpcr_names[] =
"%fpiar/%fpcr", "%fpsr/%fpcr", "%fpiar/%fpsr/%fpcr"
};
@@ -26189,5 +27428,5 @@ index bc2dd491592e56fb664cdf96fc32491c08e1e075..bc40541b7c5aecc30a7a74fd61f29225
Seperate from reg_names since 'spu', 'fpl' look weird. */
static char *const reg_half_names[] =
--
-2.1.4
+2.11.0
diff --git a/ppc-amigaos/recipes/patches/binutils/0002-Fixed-errors-occuring-with-more-recent-versions-of-t.p b/ppc-amigaos/recipes/patches/binutils/0002-Fixed-errors-occuring-with-more-recent-versions-of-t.p
index eb82ebf..0e2bf0f 100644
--- a/ppc-amigaos/recipes/patches/binutils/0002-Fixed-errors-occuring-with-more-recent-versions-of-t.p
+++ b/ppc-amigaos/recipes/patches/binutils/0002-Fixed-errors-occuring-with-more-recent-versions-of-t.p
@@ -1,7 +1,7 @@
From e5811195ee1007420de6150b593fd6b3654c4921 Mon Sep 17 00:00:00 2001
From: Sebastian Bauer <mail@sebastianbauer.info>
Date: Sat, 29 Nov 2014 11:32:22 +0100
-Subject: [PATCH 2/7] Fixed errors occuring with more recent versions of
+Subject: [PATCH 2/8] Fixed errors occuring with more recent versions of
texinfo.
---
@@ -18,8 +18,8 @@ Subject: [PATCH 2/7] Fixed errors occuring with more recent versions of
diff --git a/bfd/doc/bfd.texinfo b/bfd/doc/bfd.texinfo
index 7b9774b71a3cb9b3c154c8c75a41de29a6813146..d3b14c56449321b5dfe33206b2c5cfcd87eb0b91 100644
---- bfd/doc/bfd.texinfo
-+++ bfd/doc/bfd.texinfo
+--- a/bfd/doc/bfd.texinfo
++++ b/bfd/doc/bfd.texinfo
@@ -324,21 +324,21 @@ All of BFD lives in one directory.
@node BFD Index, , GNU Free Documentation License, Top
@@ -46,8 +46,8 @@ index 7b9774b71a3cb9b3c154c8c75a41de29a6813146..d3b14c56449321b5dfe33206b2c5cfcd
@bye
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index 45174b739e568d8f7f01fc373035e010ffeced3d..ce7746c103d9f6a5770b43a850a2e26b68b4b58d 100644
---- binutils/doc/binutils.texi
-+++ binutils/doc/binutils.texi
+--- a/binutils/doc/binutils.texi
++++ b/binutils/doc/binutils.texi
@@ -4410,45 +4410,45 @@ which fields in the ELF header should be updated.
The long and short forms of options, shown here as alternatives, are
equivalent. At least one of the @option{--output-mach},
@@ -102,8 +102,8 @@ index 45174b739e568d8f7f01fc373035e010ffeced3d..ce7746c103d9f6a5770b43a850a2e26b
Display the version number of @command{elfedit}.
diff --git a/gas/doc/c-arc.texi b/gas/doc/c-arc.texi
index ea0fa4eb522c265700bdc3b6712894ec2ad61d7c..f27b3270abce6c40a7ff1b068313a14572c79b56 100644
---- gas/doc/c-arc.texi
-+++ gas/doc/c-arc.texi
+--- a/gas/doc/c-arc.texi
++++ b/gas/doc/c-arc.texi
@@ -217,13 +217,13 @@ can shortcut the pipeline.
@item .extInstruction @var{name},@var{opcode},@var{subopcode},@var{suffixclass},@var{syntaxclass}
The ARCtangent A4 allows the user to specify extension instructions.
@@ -136,8 +136,8 @@ index ea0fa4eb522c265700bdc3b6712894ec2ad61d7c..f27b3270abce6c40a7ff1b068313a145
SYNTAX_3OP|OP1_MUST_BE_IMM
diff --git a/gas/doc/c-arm.texi b/gas/doc/c-arm.texi
index a46e08f4400ef64851828be4ab4df1046678699e..1944862d1caeb8f2aca57902f4ec1be55b68eb7e 100644
---- gas/doc/c-arm.texi
-+++ gas/doc/c-arm.texi
+--- a/gas/doc/c-arm.texi
++++ b/gas/doc/c-arm.texi
@@ -387,13 +387,13 @@ features. The default is to warn.
Two slightly different syntaxes are support for ARM and THUMB
instructions. The default, @code{divided}, uses the old style where
@@ -210,8 +210,8 @@ index a46e08f4400ef64851828be4ab4df1046678699e..1944862d1caeb8f2aca57902f4ec1be5
@table @code
diff --git a/gas/doc/c-cr16.texi b/gas/doc/c-cr16.texi
index 19f859f71d8f8712e8250fda07ee5b148d2d13ac..592dc5a5459d0e48ba1ca2e2846dc5e380f18e63 100644
---- gas/doc/c-cr16.texi
-+++ gas/doc/c-cr16.texi
+--- a/gas/doc/c-cr16.texi
++++ b/gas/doc/c-cr16.texi
@@ -41,32 +41,39 @@ Operand expression type qualifier is an optional field in the instruction operan
- @code{Specifies the CompactRISC Assembler generates a relocation entry for the operand, where pc has implied bit, the expression is adjusted accordingly. The linker uses the relocation entry to update the operand address at link time.}
@end table
@@ -274,8 +274,8 @@ index 19f859f71d8f8712e8250fda07ee5b148d2d13ac..592dc5a5459d0e48ba1ca2e2846dc5e3
diff --git a/gas/doc/c-mips.texi b/gas/doc/c-mips.texi
index 9ed0420549220079a9c44d2eed0b9daca7805af5..6054ab90442b3de4622743ef73720b5c891334e4 100644
---- gas/doc/c-mips.texi
-+++ gas/doc/c-mips.texi
+--- a/gas/doc/c-mips.texi
++++ b/gas/doc/c-mips.texi
@@ -231,13 +231,13 @@ option.
@itemx -no-m4650
Generate code for the MIPS @sc{r4650} chip. This tells the assembler to accept
@@ -293,8 +293,8 @@ index 9ed0420549220079a9c44d2eed0b9daca7805af5..6054ab90442b3de4622743ef73720b5c
specific to that chip, and to schedule for that chip's hazards.
diff --git a/gas/doc/c-score.texi b/gas/doc/c-score.texi
index 3af20a381dccc9738b4e6f5152a0f83edba9892e..40959f5b9cb2aef21b5e55289b6b9c981d57ce79 100644
---- gas/doc/c-score.texi
-+++ gas/doc/c-score.texi
+--- a/gas/doc/c-score.texi
++++ b/gas/doc/c-score.texi
@@ -34,31 +34,31 @@ The following table lists all available SCORE options.
This option sets the largest size of an object that can be referenced
implicitly with the @code{gp} register. The default value is 8.
@@ -333,8 +333,8 @@ index 3af20a381dccc9738b4e6f5152a0f83edba9892e..40959f5b9cb2aef21b5e55289b6b9c98
@item -march=score3
diff --git a/gas/doc/c-tic54x.texi b/gas/doc/c-tic54x.texi
index d61ec3af1a7de0b52e9a8230e65d8b55992c8540..2c3b0f2c111461debe9d4ea20d0219a04764c734 100644
---- gas/doc/c-tic54x.texi
-+++ gas/doc/c-tic54x.texi
+--- a/gas/doc/c-tic54x.texi
++++ b/gas/doc/c-tic54x.texi
@@ -106,13 +106,13 @@ Expansion is recursive until a previously encountered symbol is seen, at
which point substitution stops.
@@ -405,8 +405,8 @@ index d61ec3af1a7de0b52e9a8230e65d8b55992c8540..2c3b0f2c111461debe9d4ea20d0219a0
@item .bss @var{symbol}, @var{size} [, [@var{blocking_flag}] [,@var{alignment_flag}]]
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 71e909e4b61606d4ca8d1f855d9cd10a3ae1947b..81d538bad91eee08ae24dc88f589b6d07719fff0 100644
---- ld/ld.texinfo
-+++ ld/ld.texinfo
+--- a/ld/ld.texinfo
++++ b/ld/ld.texinfo
@@ -7860,21 +7860,21 @@ If you have more than one @code{SECT} statement for the same
@node LD Index
@unnumbered LD Index
@@ -432,5 +432,5 @@ index 71e909e4b61606d4ca8d1f855d9cd10a3ae1947b..81d538bad91eee08ae24dc88f589b6d0
@bye
--
-2.1.4
+2.11.0
diff --git a/ppc-amigaos/recipes/patches/binutils/0003-Disabled-some-stuff-such-that-68k-vtarget-builds-aga.p b/ppc-amigaos/recipes/patches/binutils/0003-Disabled-some-stuff-such-that-68k-vtarget-builds-aga.p
index f3b89fd..9ddeb6b 100644
--- a/ppc-amigaos/recipes/patches/binutils/0003-Disabled-some-stuff-such-that-68k-vtarget-builds-aga.p
+++ b/ppc-amigaos/recipes/patches/binutils/0003-Disabled-some-stuff-such-that-68k-vtarget-builds-aga.p
@@ -1,7 +1,7 @@
From be1c62376ea16552979036768972be85ca66c9ed Mon Sep 17 00:00:00 2001
From: Sebastian Bauer <mail@sebastianbauer.info>
Date: Tue, 17 Mar 2015 19:30:24 +0100
-Subject: [PATCH 3/7] Disabled some stuff such that 68k vtarget builds again.
+Subject: [PATCH 3/8] Disabled some stuff such that 68k vtarget builds again.
This doesn't imply that it is working.
---
@@ -10,8 +10,8 @@ This doesn't imply that it is working.
diff --git a/gas/config/tc-m68k.c b/gas/config/tc-m68k.c
index 8b5f6c60f2141ee91d6e9d1d639815abdf4e5042..9070a862b9c1266e84a8cea8da697f333227fa98 100644
---- gas/config/tc-m68k.c
-+++ gas/config/tc-m68k.c
+--- a/gas/config/tc-m68k.c
++++ b/gas/config/tc-m68k.c
@@ -5158,22 +5158,22 @@ md_convert_frag_1 (fragS *fragP)
case TAB (BRANCHBWPL, LONG):
/* Here we are converting an unconditional branch into a pair of
@@ -106,5 +106,5 @@ index 8b5f6c60f2141ee91d6e9d1d639815abdf4e5042..9070a862b9c1266e84a8cea8da697f33
}
while (*input_line_pointer++ == ',');
--
-2.1.4
+2.11.0
diff --git a/ppc-amigaos/recipes/patches/binutils/0004-Print-symbol-name-when-an-unexpected-type-was-encoun.p b/ppc-amigaos/recipes/patches/binutils/0004-Print-symbol-name-when-an-unexpected-type-was-encoun.p
index 7c4f7a6..913b50e 100644
--- a/ppc-amigaos/recipes/patches/binutils/0004-Print-symbol-name-when-an-unexpected-type-was-encoun.p
+++ b/ppc-amigaos/recipes/patches/binutils/0004-Print-symbol-name-when-an-unexpected-type-was-encoun.p
@@ -1,7 +1,7 @@
From 5e5e0a5505d8e5fc67697f3ab397fa5a39e085cc Mon Sep 17 00:00:00 2001
From: Sebastian Bauer <mail@sebastianbauer.info>
Date: Sat, 12 Sep 2015 11:29:01 +0200
-Subject: [PATCH 4/7] Print symbol name when an unexpected type was
+Subject: [PATCH 4/8] Print symbol name when an unexpected type was
encountered.
---
@@ -10,8 +10,8 @@ Subject: [PATCH 4/7] Print symbol name when an unexpected type was
diff --git a/bfd/elflink.c b/bfd/elflink.c
index bcd3add478ab13addffee21b54919afd5cdcd7d6..f10801b99e366ad956faf039401cfcbf0c42aaa1 100644
---- bfd/elflink.c
-+++ bfd/elflink.c
+--- a/bfd/elflink.c
++++ b/bfd/elflink.c
@@ -8801,12 +8801,13 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data)
switch (h->root.type)
@@ -27,5 +27,5 @@ index bcd3add478ab13addffee21b54919afd5cdcd7d6..f10801b99e366ad956faf039401cfcbf
case bfd_link_hash_undefweak:
input_sec = bfd_und_section_ptr;
--
-2.1.4
+2.11.0
diff --git a/ppc-amigaos/recipes/patches/binutils/0005-Bind-in-the-ld-unwind-options.p b/ppc-amigaos/recipes/patches/binutils/0005-Bind-in-the-ld-unwind-options.p
index f82d880..0ecd59a 100644
--- a/ppc-amigaos/recipes/patches/binutils/0005-Bind-in-the-ld-unwind-options.p
+++ b/ppc-amigaos/recipes/patches/binutils/0005-Bind-in-the-ld-unwind-options.p
@@ -1,7 +1,7 @@
From ce074fe73deeb899bf1cd863092c174034f56e67 Mon Sep 17 00:00:00 2001
From: Sebastian Bauer <mail@sebastianbauer.info>
Date: Thu, 22 Oct 2015 09:48:26 +0200
-Subject: [PATCH 5/7] Bind in the ld unwind options.
+Subject: [PATCH 5/8] Bind in the ld unwind options.
---
ld/emulparams/amigaos.sh | 4 +++-
@@ -9,8 +9,8 @@ Subject: [PATCH 5/7] Bind in the ld unwind options.
diff --git a/ld/emulparams/amigaos.sh b/ld/emulparams/amigaos.sh
index 605b81e76bcbbd2322561d7d9502190dc7c00674..2661d4ddcd1c5ecab9adea84af7f7d0ba054aa95 100644
---- ld/emulparams/amigaos.sh
-+++ ld/emulparams/amigaos.sh
+--- a/ld/emulparams/amigaos.sh
++++ b/ld/emulparams/amigaos.sh
@@ -1,7 +1,9 @@
-#. ${srcdir}/emulparams/elf32ppccommon.sh
+. ${srcdir}/emulparams/elf32ppccommon.sh
@@ -23,5 +23,5 @@ index 605b81e76bcbbd2322561d7d9502190dc7c00674..2661d4ddcd1c5ecab9adea84af7f7d0b
COMMONPAGESIZE="CONSTANT (COMMONPAGESIZE)"
ALIGNMENT=16
--
-2.1.4
+2.11.0
diff --git a/ppc-amigaos/recipes/patches/binutils/0006-Introduced-strip-unneeded-rel-relocs.p b/ppc-amigaos/recipes/patches/binutils/0006-Introduced-strip-unneeded-rel-relocs.p
index db15c54..9cb51d1 100644
--- a/ppc-amigaos/recipes/patches/binutils/0006-Introduced-strip-unneeded-rel-relocs.p
+++ b/ppc-amigaos/recipes/patches/binutils/0006-Introduced-strip-unneeded-rel-relocs.p
@@ -1,7 +1,7 @@
From 6b64c328f239a146c1ce5a85c27b0ff1636f3987 Mon Sep 17 00:00:00 2001
From: Sebastian Bauer <mail@sebastianbauer.info>
Date: Tue, 1 Dec 2015 13:51:20 +0100
-Subject: [PATCH 6/7] Introduced strip-unneeded-rel-relocs.
+Subject: [PATCH 6/8] Introduced strip-unneeded-rel-relocs.
Normally, on AmigaOS we keep all relocs for executables as we don't have
an isolated address space. However, not all relative relocs are necessary
@@ -14,8 +14,8 @@ can be removed now.
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 88bd071eefa8b5426eaadfd6431e9de5d4a4591b..4beee77179b85479d5b43507d9eb2a6e0caf384e 100644
---- binutils/objcopy.c
-+++ binutils/objcopy.c
+--- a/binutils/objcopy.c
++++ b/binutils/objcopy.c
@@ -101,12 +101,15 @@ enum strip_action
STRIP_ALL /* Strip all symbols. */
};
@@ -124,5 +124,5 @@ index 88bd071eefa8b5426eaadfd6431e9de5d4a4591b..4beee77179b85479d5b43507d9eb2a6e
add_specific_symbol (optarg, strip_specific_htab);
break;
--
-2.1.4
+2.11.0
diff --git a/ppc-amigaos/recipes/patches/binutils/0007-Keep-symbols-for-stripped-sections.-This-is-importan.p b/ppc-amigaos/recipes/patches/binutils/0007-Keep-symbols-for-stripped-sections.-This-is-importan.p
index 7681051..30319d5 100644
--- a/ppc-amigaos/recipes/patches/binutils/0007-Keep-symbols-for-stripped-sections.-This-is-importan.p
+++ b/ppc-amigaos/recipes/patches/binutils/0007-Keep-symbols-for-stripped-sections.-This-is-importan.p
@@ -1,7 +1,7 @@
From 035f3afce47e01ee70c7972a71a9dccea2b61e6f Mon Sep 17 00:00:00 2001
From: Sebastian Bauer <mail@sebastianbauer.info>
Date: Thu, 3 Dec 2015 23:48:21 +0100
-Subject: [PATCH 7/7] Keep symbols for stripped sections. This is important for
+Subject: [PATCH 7/8] Keep symbols for stripped sections. This is important for
_SDA_BASE_,
---
@@ -10,8 +10,8 @@ Subject: [PATCH 7/7] Keep symbols for stripped sections. This is important for
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 4beee77179b85479d5b43507d9eb2a6e0caf384e..8750db51279ec56080aba114cd61780d061b168f 100644
---- binutils/objcopy.c
-+++ binutils/objcopy.c
+--- a/binutils/objcopy.c
++++ b/binutils/objcopy.c
@@ -1239,13 +1239,23 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
if (!keep
&& ((keep_file_symbols && (flags & BSF_FILE))
@@ -38,5 +38,5 @@ index 4beee77179b85479d5b43507d9eb2a6e0caf384e..8750db51279ec56080aba114cd61780d
&& (weaken || is_specified_symbol (name, weaken_specific_htab)))
{
--
-2.1.4
+2.11.0
diff --git a/ppc-amigaos/recipes/patches/binutils/0008-Fix-undefined-behaviour.p b/ppc-amigaos/recipes/patches/binutils/0008-Fix-undefined-behaviour.p
new file mode 100644
index 0000000..ebfe1e8
--- /dev/null
+++ b/ppc-amigaos/recipes/patches/binutils/0008-Fix-undefined-behaviour.p
@@ -0,0 +1,113 @@
+From 9592197f4e9723b6a435318b9c39521beab07c7b Mon Sep 17 00:00:00 2001
+From: Sebastian Bauer <mail@sebastianbauer.info>
+Date: Wed, 15 Feb 2017 22:12:54 +0100
+Subject: [PATCH 8/8] Fix undefined behaviour.
+
+This should ensure that the code compiles with more recent version of GCC.
+Changes have been backported from more recent version of binutils.
+---
+ binutils/dwarf.c | 2 +-
+ gas/config/tc-ppc.c | 2 +-
+ gas/read.c | 2 +-
+ gas/write.c | 2 +-
+ include/opcode/ppc.h | 2 +-
+ 5 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/binutils/dwarf.c b/binutils/dwarf.c
+index 6e93906af385ff3dd0f8785792a1e8cc3d04a774..9fc4a594cfe83693f44f686fc752987b3e2a5653 100644
+--- a/binutils/dwarf.c
++++ b/binutils/dwarf.c
+@@ -214,13 +214,13 @@ read_leb128 (unsigned char *data, unsigned int *length_return, int sign)
+ while (byte & 0x80);
+
+ if (length_return != NULL)
+ *length_return = num_read;
+
+ if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40))
+- result |= -1L << shift;
++ result |= -((dwarf_vma) 1 << shift);
+
+ return result;
+ }
+
+ /* Create a signed version to avoid painful typecasts. */
+ static dwarf_signed_vma
+diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
+index 11949323d80802138ec23fb8174727c0a7c4fd45..14346e30661d408d5dba4d456cc274f2f4dc3820 100644
+--- a/gas/config/tc-ppc.c
++++ b/gas/config/tc-ppc.c
+@@ -1466,13 +1466,13 @@ insn_validate (const struct powerpc_opcode *op)
+ as_bad (_("operand index error for %s"), op->name);
+ return TRUE;
+ }
+ else
+ {
+ const struct powerpc_operand *operand = &powerpc_operands[*o];
+- if (operand->shift != PPC_OPSHIFT_INV)
++ if (operand->shift != (int) PPC_OPSHIFT_INV)
+ {
+ unsigned long mask;
+
+ if (operand->shift >= 0)
+ mask = operand->bitm << operand->shift;
+ else
+diff --git a/gas/read.c b/gas/read.c
+index 9de62b9c512025212d52a19833ffe28004944dd1..dfd466be7934cfd379b2a0c99f08c7ea877fdbe0 100644
+--- a/gas/read.c
++++ b/gas/read.c
+@@ -5172,13 +5172,13 @@ output_big_sleb128 (char *p, LITTLENUM_TYPE *bignum, int size)
+
+ /* Mop up any left-over bits (of which there will be less than 7). */
+ if ((byte & 0x80) != 0)
+ {
+ /* Sign-extend VAL. */
+ if (val & (1 << (loaded - 1)))
+- val |= ~0 << loaded;
++ val |= ~0U << loaded;
+ if (orig)
+ *p = val & 0x7f;
+ p++;
+ }
+
+ return p - orig;
+diff --git a/gas/write.c b/gas/write.c
+index 8a9746c927a3e8b7007cdec9c7f16e47509b5f45..be6969865f7373cdeb396df44506ef537206fbd8 100644
+--- a/gas/write.c
++++ b/gas/write.c
+@@ -2310,13 +2310,13 @@ static relax_addressT
+ relax_align (register relax_addressT address, /* Address now. */
+ register int alignment /* Alignment (binary). */)
+ {
+ relax_addressT mask;
+ relax_addressT new_address;
+
+- mask = ~((~0) << alignment);
++ mask = ~((relax_addressT) ~0 << alignment);
+ new_address = (address + mask) & (~mask);
+ #ifdef LINKER_RELAXING_SHRINKS_ONLY
+ if (linkrelax)
+ /* We must provide lots of padding, so the linker can discard it
+ when needed. The linker will not add extra space, ever. */
+ new_address += (1 << alignment);
+diff --git a/include/opcode/ppc.h b/include/opcode/ppc.h
+index e57b118b02e5a2faba62f5dbd524f03827f719c0..40a1262ecd17944de229f6b192f8c6e078f70728 100644
+--- a/include/opcode/ppc.h
++++ b/include/opcode/ppc.h
+@@ -267,13 +267,13 @@ struct powerpc_operand
+ extern const struct powerpc_operand powerpc_operands[];
+ extern const unsigned int num_powerpc_operands;
+
+ /* Use with the shift field of a struct powerpc_operand to indicate
+ that BITM and SHIFT cannot be used to determine where the operand
+ goes in the insn. */
+-#define PPC_OPSHIFT_INV (-1 << 31)
++#define PPC_OPSHIFT_INV (-1U << 31)
+
+ /* Values defined for the flags field of a struct powerpc_operand. */
+
+ /* This operand takes signed values. */
+ #define PPC_OPERAND_SIGNED (0x1)
+
+--
+2.11.0
+
diff --git a/ppc-amigaos/recipes/patches/binutils/missing-files.p b/ppc-amigaos/recipes/patches/binutils/missing-files.p
deleted file mode 100644
index 7911090..0000000
--- a/ppc-amigaos/recipes/patches/binutils/missing-files.p
+++ /dev/null
@@ -1,12492 +0,0 @@
---- /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 -*-
-+# It does some substitutions.
-+# This file is now misnamed, because it supports both 32 bit and 64 bit
-+# ELF emulations.
-+test -z "${ELFSIZE}" && ELFSIZE=32
-+if [ -z "$MACHINE" ]; then
-+ OUTPUT_ARCH=${ARCH}
-+else
-+ OUTPUT_ARCH=${ARCH}:${MACHINE}
-+fi
-+fragment <<EOF
-+/* This file is is generated by a shell script. DO NOT EDIT! */
-+
-+/* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME}
-+ Copyright 1991, 1993, 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 Steve Chamberlain <sac@cygnus.com>
-+ ELF support by Ian Lance Taylor <ian@cygnus.com>
-+
-+ This file is part of the GNU Binutils.
-+
-+ 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. */
-+
-+#define TARGET_IS_${EMULATION_NAME}
-+
-+#include "sysdep.h"
-+#include "bfd.h"
-+#include "libiberty.h"
-+#include "filenames.h"
-+#include "safe-ctype.h"
-+#include "getopt.h"
-+#include "md5.h"
-+#include "sha1.h"
-+#include <fcntl.h>
-+
-+#include "bfdlink.h"
-+
-+#include "ld.h"
-+#include "ldmain.h"
-+#include "ldmisc.h"
-+#include "ldexp.h"
-+#include "ldlang.h"
-+#include "ldfile.h"
-+#include "ldemul.h"
-+#include <ldgram.h>
-+#include "elf/common.h"
-+#include "elf-bfd.h"
-+#include "filenames.h"
-+
-+/* Declare functions used by various EXTRA_EM_FILEs. */
-+static void gld${EMULATION_NAME}_before_parse (void);
-+static void gld${EMULATION_NAME}_after_open (void);
-+static void gld${EMULATION_NAME}_before_allocation (void);
-+static void gld${EMULATION_NAME}_after_allocation (void);
-+static lang_output_section_statement_type *gld${EMULATION_NAME}_place_orphan
-+ (asection *, const char *, int);
-+EOF
-+
-+if [ "x${USE_LIBPATH}" = xyes ] ; then
-+ case ${target} in
-+ *-*-linux-* | *-*-k*bsd*-* | *-*-gnu*)
-+ fragment <<EOF
-+#ifdef HAVE_GLOB
-+#include <glob.h>
-+#endif
-+EOF
-+ ;;
-+ esac
-+fi
-+
-+# Import any needed special functions and/or overrides.
-+#
-+source_em ${srcdir}/emultempl/elf-generic.em
-+if test -n "$EXTRA_EM_FILE" ; then
-+ source_em ${srcdir}/emultempl/${EXTRA_EM_FILE}.em
-+fi
-+
-+# Functions in this file can be overridden by setting the LDEMUL_* shell
-+# variables. If the name of the overriding function is the same as is
-+# defined in this file, then don't output this file's version.
-+# If a different overriding name is given then output the standard function
-+# as presumably it is called from the overriding function.
-+#
-+if test x"$LDEMUL_BEFORE_PARSE" != xgld"$EMULATION_NAME"_before_parse; then
-+fragment <<EOF
-+
-+static void
-+gld${EMULATION_NAME}_before_parse (void)
-+{
-+ ldfile_set_output_arch ("${OUTPUT_ARCH}", bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`);
-+ input_flags.dynamic = ${DYNAMIC_LINK-TRUE};
-+ config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo TRUE ; else echo FALSE ; fi`;
-+ config.separate_code = `if test "x${SEPARATE_CODE}" = xyes ; then echo TRUE ; else echo FALSE ; fi`;
-+}
-+
-+EOF
-+fi
-+
-+if test x"$LDEMUL_RECOGNIZED_FILE" != xgld"${EMULATION_NAME}"_load_symbols; then
-+fragment <<EOF
-+/* Handle the generation of DT_NEEDED tags. */
-+
-+static bfd_boolean
-+gld${EMULATION_NAME}_load_symbols (lang_input_statement_type *entry)
-+{
-+ int link_class = 0;
-+
-+ /* Tell the ELF linker that we don't want the output file to have a
-+ DT_NEEDED entry for this file, unless it is used to resolve
-+ references in a regular object. */
-+ if (entry->flags.add_DT_NEEDED_for_regular)
-+ link_class = DYN_AS_NEEDED;
-+
-+ /* Tell the ELF linker that we don't want the output file to have a
-+ DT_NEEDED entry for any dynamic library in DT_NEEDED tags from
-+ this file at all. */
-+ if (!entry->flags.add_DT_NEEDED_for_dynamic)
-+ link_class |= DYN_NO_ADD_NEEDED;
-+
-+ if (entry->flags.just_syms
-+ && (bfd_get_file_flags (entry->the_bfd) & DYNAMIC) != 0)
-+ einfo (_("%P%F: --just-symbols may not be used on DSO: %B\n"),
-+ entry->the_bfd);
-+
-+ if (link_class == 0
-+ || (bfd_get_file_flags (entry->the_bfd) & DYNAMIC) == 0)
-+ return FALSE;
-+
-+ bfd_elf_set_dyn_lib_class (entry->the_bfd,
-+ (enum dynamic_lib_link_class) link_class);
-+
-+ /* Continue on with normal load_symbols processing. */
-+ return FALSE;
-+}
-+EOF
-+fi
-+
-+fragment <<EOF
-+
-+/* These variables are required to pass information back and forth
-+ between after_open and check_needed and stat_needed and vercheck. */
-+
-+static struct bfd_link_needed_list *global_needed;
-+static struct stat global_stat;
-+static lang_input_statement_type *global_found;
-+static struct bfd_link_needed_list *global_vercheck_needed;
-+static bfd_boolean global_vercheck_failed;
-+
-+/* These variables are used to implement target options */
-+
-+static char *audit; /* colon (typically) separated list of libs */
-+static char *depaudit; /* colon (typically) separated list of libs */
-+
-+/* On Linux, it's possible to have different versions of the same
-+ shared library linked against different versions of libc. The
-+ dynamic linker somehow tags which libc version to use in
-+ /etc/ld.so.cache, and, based on the libc that it sees in the
-+ executable, chooses which version of the shared library to use.
-+
-+ We try to do a similar check here by checking whether this shared
-+ library needs any other shared libraries which may conflict with
-+ libraries we have already included in the link. If it does, we
-+ skip it, and try to find another shared library farther on down the
-+ link path.
-+
-+ This is called via lang_for_each_input_file.
-+ GLOBAL_VERCHECK_NEEDED is the list of objects needed by the object
-+ which we are checking. This sets GLOBAL_VERCHECK_FAILED if we find
-+ a conflicting version. */
-+
-+static void
-+gld${EMULATION_NAME}_vercheck (lang_input_statement_type *s)
-+{
-+ const char *soname;
-+ struct bfd_link_needed_list *l;
-+
-+ if (global_vercheck_failed)
-+ return;
-+ if (s->the_bfd == NULL
-+ || (bfd_get_file_flags (s->the_bfd) & DYNAMIC) == 0)
-+ return;
-+
-+ soname = bfd_elf_get_dt_soname (s->the_bfd);
-+ if (soname == NULL)
-+ soname = lbasename (bfd_get_filename (s->the_bfd));
-+
-+ for (l = global_vercheck_needed; l != NULL; l = l->next)
-+ {
-+ const char *suffix;
-+
-+ if (filename_cmp (soname, l->name) == 0)
-+ {
-+ /* Probably can't happen, but it's an easy check. */
-+ continue;
-+ }
-+
-+ if (strchr (l->name, '/') != NULL)
-+ continue;
-+
-+ suffix = strstr (l->name, ".so.");
-+ if (suffix == NULL)
-+ continue;
-+
-+ suffix += sizeof ".so." - 1;
-+
-+ if (filename_ncmp (soname, l->name, suffix - l->name) == 0)
-+ {
-+ /* Here we know that S is a dynamic object FOO.SO.VER1, and
-+ the object we are considering needs a dynamic object
-+ FOO.SO.VER2, and VER1 and VER2 are different. This
-+ appears to be a version mismatch, so we tell the caller
-+ to try a different version of this library. */
-+ global_vercheck_failed = TRUE;
-+ return;
-+ }
-+ }
-+}
-+
-+
-+/* See if an input file matches a DT_NEEDED entry by running stat on
-+ the file. */
-+
-+static void
-+gld${EMULATION_NAME}_stat_needed (lang_input_statement_type *s)
-+{
-+ struct stat st;
-+ const char *suffix;
-+ const char *soname;
-+
-+ if (global_found != NULL)
-+ return;
-+ if (s->the_bfd == NULL)
-+ return;
-+
-+ /* If this input file was an as-needed entry, and wasn't found to be
-+ needed at the stage it was linked, then don't say we have loaded it. */
-+ if ((bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0)
-+ return;
-+
-+ if (bfd_stat (s->the_bfd, &st) != 0)
-+ {
-+ einfo ("%P:%B: bfd_stat failed: %E\n", s->the_bfd);
-+ return;
-+ }
-+
-+ /* Some operating systems, e.g. Windows, do not provide a meaningful
-+ st_ino; they always set it to zero. (Windows does provide a
-+ meaningful st_dev.) Do not indicate a duplicate library in that
-+ case. While there is no guarantee that a system that provides
-+ meaningful inode numbers will never set st_ino to zero, this is
-+ merely an optimization, so we do not need to worry about false
-+ negatives. */
-+ if (st.st_dev == global_stat.st_dev
-+ && st.st_ino == global_stat.st_ino
-+ && st.st_ino != 0)
-+ {
-+ global_found = s;
-+ return;
-+ }
-+
-+ /* We issue a warning if it looks like we are including two
-+ different versions of the same shared library. For example,
-+ there may be a problem if -lc picks up libc.so.6 but some other
-+ shared library has a DT_NEEDED entry of libc.so.5. This is a
-+ heuristic test, and it will only work if the name looks like
-+ NAME.so.VERSION. FIXME: Depending on file names is error-prone.
-+ If we really want to issue warnings about mixing version numbers
-+ of shared libraries, we need to find a better way. */
-+
-+ if (strchr (global_needed->name, '/') != NULL)
-+ return;
-+ suffix = strstr (global_needed->name, ".so.");
-+ if (suffix == NULL)
-+ return;
-+ suffix += sizeof ".so." - 1;
-+
-+ soname = bfd_elf_get_dt_soname (s->the_bfd);
-+ if (soname == NULL)
-+ soname = lbasename (s->filename);
-+
-+ if (filename_ncmp (soname, global_needed->name, suffix - global_needed->name) == 0)
-+ einfo ("%P: warning: %s, needed by %B, may conflict with %s\n",
-+ global_needed->name, global_needed->by, soname);
-+}
-+
-+struct dt_needed
-+{
-+ bfd *by;
-+ const char *name;
-+};
-+
-+/* This function is called for each possible name for a dynamic object
-+ named by a DT_NEEDED entry. The FORCE parameter indicates whether
-+ to skip the check for a conflicting version. */
-+
-+static bfd_boolean
-+gld${EMULATION_NAME}_try_needed (struct dt_needed *needed,
-+ int force)
-+{
-+ bfd *abfd;
-+ const char *name = needed->name;
-+ const char *soname;
-+ int link_class;
-+
-+ abfd = bfd_openr (name, bfd_get_target (link_info.output_bfd));
-+ if (abfd == NULL)
-+ return FALSE;
-+
-+ /* Linker needs to decompress sections. */
-+ abfd->flags |= BFD_DECOMPRESS;
-+
-+ if (! bfd_check_format (abfd, bfd_object))
-+ {
-+ bfd_close (abfd);
-+ return FALSE;
-+ }
-+ if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0)
-+ {
-+ bfd_close (abfd);
-+ return FALSE;
-+ }
-+
-+ /* For DT_NEEDED, they have to match. */
-+ if (abfd->xvec != link_info.output_bfd->xvec)
-+ {
-+ bfd_close (abfd);
-+ return FALSE;
-+ }
-+
-+ /* Check whether this object would include any conflicting library
-+ versions. If FORCE is set, then we skip this check; we use this
-+ the second time around, if we couldn't find any compatible
-+ instance of the shared library. */
-+
-+ if (! force)
-+ {
-+ struct bfd_link_needed_list *needs;
-+
-+ if (! bfd_elf_get_bfd_needed_list (abfd, &needs))
-+ einfo ("%F%P:%B: bfd_elf_get_bfd_needed_list failed: %E\n", abfd);
-+
-+ if (needs != NULL)
-+ {
-+ global_vercheck_needed = needs;
-+ global_vercheck_failed = FALSE;
-+ lang_for_each_input_file (gld${EMULATION_NAME}_vercheck);
-+ if (global_vercheck_failed)
-+ {
-+ bfd_close (abfd);
-+ /* Return FALSE to force the caller to move on to try
-+ another file on the search path. */
-+ return FALSE;
-+ }
-+
-+ /* But wait! It gets much worse. On Linux, if a shared
-+ library does not use libc at all, we are supposed to skip
-+ it the first time around in case we encounter a shared
-+ library later on with the same name which does use the
-+ version of libc that we want. This is much too horrible
-+ to use on any system other than Linux. */
-+
-+EOF
-+case ${target} in
-+ *-*-linux-* | *-*-k*bsd*-* | *-*-gnu*)
-+ fragment <<EOF
-+ {
-+ struct bfd_link_needed_list *l;
-+
-+ for (l = needs; l != NULL; l = l->next)
-+ if (CONST_STRNEQ (l->name, "libc.so"))
-+ break;
-+ if (l == NULL)
-+ {
-+ bfd_close (abfd);
-+ return FALSE;
-+ }
-+ }
-+
-+EOF
-+ ;;
-+esac
-+fragment <<EOF
-+ }
-+ }
-+
-+ /* We've found a dynamic object matching the DT_NEEDED entry. */
-+
-+ /* We have already checked that there is no other input file of the
-+ same name. We must now check again that we are not including the
-+ same file twice. We need to do this because on many systems
-+ libc.so is a symlink to, e.g., libc.so.1. The SONAME entry will
-+ reference libc.so.1. If we have already included libc.so, we
-+ don't want to include libc.so.1 if they are the same file, and we
-+ can only check that using stat. */
-+
-+ if (bfd_stat (abfd, &global_stat) != 0)
-+ einfo ("%F%P:%B: bfd_stat failed: %E\n", abfd);
-+
-+ /* First strip off everything before the last '/'. */
-+ soname = lbasename (abfd->filename);
-+
-+ if (verbose)
-+ info_msg (_("found %s at %s\n"), soname, name);
-+
-+ global_found = NULL;
-+ lang_for_each_input_file (gld${EMULATION_NAME}_stat_needed);
-+ if (global_found != NULL)
-+ {
-+ /* Return TRUE to indicate that we found the file, even though
-+ we aren't going to do anything with it. */
-+ return TRUE;
-+ }
-+
-+ /* Specify the soname to use. */
-+ bfd_elf_set_dt_needed_name (abfd, soname);
-+
-+ /* Tell the ELF linker that we don't want the output file to have a
-+ DT_NEEDED entry for this file, unless it is used to resolve
-+ references in a regular object. */
-+ link_class = DYN_DT_NEEDED;
-+
-+ /* Tell the ELF linker that we don't want the output file to have a
-+ DT_NEEDED entry for this file at all if the entry is from a file
-+ with DYN_NO_ADD_NEEDED. */
-+ if (needed->by != NULL
-+ && (bfd_elf_get_dyn_lib_class (needed->by) & DYN_NO_ADD_NEEDED) != 0)
-+ link_class |= DYN_NO_NEEDED | DYN_NO_ADD_NEEDED;
-+
-+ bfd_elf_set_dyn_lib_class (abfd, (enum dynamic_lib_link_class) link_class);
-+
-+ /* Add this file into the symbol table. */
-+ if (! bfd_link_add_symbols (abfd, &link_info))
-+ einfo ("%F%B: could not read symbols: %E\n", abfd);
-+
-+ return TRUE;
-+}
-+
-+
-+/* Search for a needed file in a path. */
-+
-+static bfd_boolean
-+gld${EMULATION_NAME}_search_needed (const char *path,
-+ struct dt_needed *n, int force)
-+{
-+ const char *s;
-+ const char *name = n->name;
-+ size_t len;
-+ struct dt_needed needed;
-+
-+ if (name[0] == '/')
-+ return gld${EMULATION_NAME}_try_needed (n, force);
-+
-+ if (path == NULL || *path == '\0')
-+ return FALSE;
-+
-+ needed.by = n->by;
-+ needed.name = n->name;
-+
-+ len = strlen (name);
-+ while (1)
-+ {
-+ char *filename, *sset;
-+
-+ s = strchr (path, config.rpath_separator);
-+ if (s == NULL)
-+ s = path + strlen (path);
-+
-+#if HAVE_DOS_BASED_FILE_SYSTEM
-+ /* Assume a match on the second char is part of drive specifier. */
-+ else if (config.rpath_separator == ':'
-+ && s == path + 1
-+ && ISALPHA (*path))
-+ {
-+ s = strchr (s + 1, config.rpath_separator);
-+ if (s == NULL)
-+ s = path + strlen (path);
-+ }
-+#endif
-+ filename = (char *) xmalloc (s - path + len + 2);
-+ if (s == path)
-+ sset = filename;
-+ else
-+ {
-+ memcpy (filename, path, s - path);
-+ filename[s - path] = '/';
-+ sset = filename + (s - path) + 1;
-+ }
-+ strcpy (sset, name);
-+
-+ needed.name = filename;
-+ if (gld${EMULATION_NAME}_try_needed (&needed, force))
-+ return TRUE;
-+
-+ free (filename);
-+
-+ if (*s == '\0')
-+ break;
-+ path = s + 1;
-+ }
-+
-+ return FALSE;
-+}
-+
-+EOF
-+if [ "x${USE_LIBPATH}" = xyes ] ; then
-+ fragment <<EOF
-+
-+/* Add the sysroot to every entry in a path separated by
-+ config.rpath_separator. */
-+
-+static char *
-+gld${EMULATION_NAME}_add_sysroot (const char *path)
-+{
-+ int len, colons, i;
-+ char *ret, *p;
-+
-+ len = strlen (path);
-+ colons = 0;
-+ i = 0;
-+ while (path[i])
-+ if (path[i++] == config.rpath_separator)
-+ colons++;
-+
-+ if (path[i])
-+ colons++;
-+
-+ len = len + (colons + 1) * strlen (ld_sysroot);
-+ ret = xmalloc (len + 1);
-+ strcpy (ret, ld_sysroot);
-+ p = ret + strlen (ret);
-+ i = 0;
-+ while (path[i])
-+ if (path[i] == config.rpath_separator)
-+ {
-+ *p++ = path[i++];
-+ strcpy (p, ld_sysroot);
-+ p = p + strlen (p);
-+ }
-+ else
-+ *p++ = path[i++];
-+
-+ *p = 0;
-+ return ret;
-+}
-+
-+EOF
-+ case ${target} in
-+ *-*-freebsd* | *-*-dragonfly*)
-+ fragment <<EOF
-+/* Read the system search path the FreeBSD way rather than the Linux way. */
-+#ifdef HAVE_ELF_HINTS_H
-+#include <elf-hints.h>
-+#else
-+#include "elf-hints-local.h"
-+#endif
-+
-+static bfd_boolean
-+gld${EMULATION_NAME}_check_ld_elf_hints (const struct bfd_link_needed_list *l,
-+ int force)
-+{
-+ static bfd_boolean initialized;
-+ static char *ld_elf_hints;
-+ struct dt_needed needed;
-+
-+ if (!initialized)
-+ {
-+ FILE *f;
-+ char *tmppath;
-+
-+ tmppath = concat (ld_sysroot, _PATH_ELF_HINTS, (const char *) NULL);
-+ f = fopen (tmppath, FOPEN_RB);
-+ free (tmppath);
-+ if (f != NULL)
-+ {
-+ struct elfhints_hdr hdr;
-+
-+ if (fread (&hdr, 1, sizeof (hdr), f) == sizeof (hdr)
-+ && hdr.magic == ELFHINTS_MAGIC
-+ && hdr.version == 1)
-+ {
-+ if (fseek (f, hdr.strtab + hdr.dirlist, SEEK_SET) != -1)
-+ {
-+ char *b;
-+
-+ b = xmalloc (hdr.dirlistlen + 1);
-+ if (fread (b, 1, hdr.dirlistlen + 1, f) ==
-+ hdr.dirlistlen + 1)
-+ ld_elf_hints = gld${EMULATION_NAME}_add_sysroot (b);
-+
-+ free (b);
-+ }
-+ }
-+ fclose (f);
-+ }
-+
-+ initialized = TRUE;
-+ }
-+
-+ if (ld_elf_hints == NULL)
-+ return FALSE;
-+
-+ needed.by = l->by;
-+ needed.name = l->name;
-+ return gld${EMULATION_NAME}_search_needed (ld_elf_hints, &needed, force);
-+}
-+EOF
-+ # FreeBSD
-+ ;;
-+
-+ *-*-linux-* | *-*-k*bsd*-* | *-*-gnu*)
-+ fragment <<EOF
-+/* For a native linker, check the file /etc/ld.so.conf for directories
-+ in which we may find shared libraries. /etc/ld.so.conf is really
-+ only meaningful on Linux. */
-+
-+struct gld${EMULATION_NAME}_ld_so_conf
-+{
-+ char *path;
-+ size_t len, alloc;
-+};
-+
-+static bfd_boolean
-+gld${EMULATION_NAME}_parse_ld_so_conf
-+ (struct gld${EMULATION_NAME}_ld_so_conf *info, const char *filename);
-+
-+static void
-+gld${EMULATION_NAME}_parse_ld_so_conf_include
-+ (struct gld${EMULATION_NAME}_ld_so_conf *info, const char *filename,
-+ const char *pattern)
-+{
-+ char *newp = NULL;
-+#ifdef HAVE_GLOB
-+ glob_t gl;
-+#endif
-+
-+ if (pattern[0] != '/')
-+ {
-+ char *p = strrchr (filename, '/');
-+ size_t patlen = strlen (pattern) + 1;
-+
-+ newp = xmalloc (p - filename + 1 + patlen);
-+ memcpy (newp, filename, p - filename + 1);
-+ memcpy (newp + (p - filename + 1), pattern, patlen);
-+ pattern = newp;
-+ }
-+
-+#ifdef HAVE_GLOB
-+ if (glob (pattern, 0, NULL, &gl) == 0)
-+ {
-+ size_t i;
-+
-+ for (i = 0; i < gl.gl_pathc; ++i)
-+ gld${EMULATION_NAME}_parse_ld_so_conf (info, gl.gl_pathv[i]);
-+ globfree (&gl);
-+ }
-+#else
-+ /* If we do not have glob, treat the pattern as a literal filename. */
-+ gld${EMULATION_NAME}_parse_ld_so_conf (info, pattern);
-+#endif
-+
-+ if (newp)
-+ free (newp);
-+}
-+
-+static bfd_boolean
-+gld${EMULATION_NAME}_parse_ld_so_conf
-+ (struct gld${EMULATION_NAME}_ld_so_conf *info, const char *filename)
-+{
-+ FILE *f = fopen (filename, FOPEN_RT);
-+ char *line;
-+ size_t linelen;
-+
-+ if (f == NULL)
-+ return FALSE;
-+
-+ linelen = 256;
-+ line = xmalloc (linelen);
-+ do
-+ {
-+ char *p = line, *q;
-+
-+ /* Normally this would use getline(3), but we need to be portable. */
-+ while ((q = fgets (p, linelen - (p - line), f)) != NULL
-+ && strlen (q) == linelen - (p - line) - 1
-+ && line[linelen - 2] != '\n')
-+ {
-+ line = xrealloc (line, 2 * linelen);
-+ p = line + linelen - 1;
-+ linelen += linelen;
-+ }
-+
-+ if (q == NULL && p == line)
-+ break;
-+
-+ p = strchr (line, '\n');
-+ if (p)
-+ *p = '\0';
-+
-+ /* Because the file format does not know any form of quoting we
-+ can search forward for the next '#' character and if found
-+ make it terminating the line. */
-+ p = strchr (line, '#');
-+ if (p)
-+ *p = '\0';
-+
-+ /* Remove leading whitespace. NUL is no whitespace character. */
-+ p = line;
-+ while (*p == ' ' || *p == '\f' || *p == '\r' || *p == '\t' || *p == '\v')
-+ ++p;
-+
-+ /* If the line is blank it is ignored. */
-+ if (p[0] == '\0')
-+ continue;
-+
-+ if (CONST_STRNEQ (p, "include") && (p[7] == ' ' || p[7] == '\t'))
-+ {
-+ char *dir, c;
-+ p += 8;
-+ do
-+ {
-+ while (*p == ' ' || *p == '\t')
-+ ++p;
-+
-+ if (*p == '\0')
-+ break;
-+
-+ dir = p;
-+
-+ while (*p != ' ' && *p != '\t' && *p)
-+ ++p;
-+
-+ c = *p;
-+ *p++ = '\0';
-+ if (dir[0] != '\0')
-+ gld${EMULATION_NAME}_parse_ld_so_conf_include (info, filename,
-+ dir);
-+ }
-+ while (c != '\0');
-+ }
-+ else
-+ {
-+ char *dir = p;
-+ while (*p && *p != '=' && *p != ' ' && *p != '\t' && *p != '\f'
-+ && *p != '\r' && *p != '\v')
-+ ++p;
-+
-+ while (p != dir && p[-1] == '/')
-+ --p;
-+ if (info->path == NULL)
-+ {
-+ info->alloc = p - dir + 1 + 256;
-+ info->path = xmalloc (info->alloc);
-+ info->len = 0;
-+ }
-+ else
-+ {
-+ if (info->len + 1 + (p - dir) >= info->alloc)
-+ {
-+ info->alloc += p - dir + 256;
-+ info->path = xrealloc (info->path, info->alloc);
-+ }
-+ info->path[info->len++] = config.rpath_separator;
-+ }
-+ memcpy (info->path + info->len, dir, p - dir);
-+ info->len += p - dir;
-+ info->path[info->len] = '\0';
-+ }
-+ }
-+ while (! feof (f));
-+ free (line);
-+ fclose (f);
-+ return TRUE;
-+}
-+
-+static bfd_boolean
-+gld${EMULATION_NAME}_check_ld_so_conf (const struct bfd_link_needed_list *l,
-+ int force)
-+{
-+ static bfd_boolean initialized;
-+ static char *ld_so_conf;
-+ struct dt_needed needed;
-+
-+ if (! initialized)
-+ {
-+ char *tmppath;
-+ struct gld${EMULATION_NAME}_ld_so_conf info;
-+
-+ info.path = NULL;
-+ info.len = info.alloc = 0;
-+ tmppath = concat (ld_sysroot, "${prefix}/etc/ld.so.conf",
-+ (const char *) NULL);
-+ if (!gld${EMULATION_NAME}_parse_ld_so_conf (&info, tmppath))
-+ {
-+ free (tmppath);
-+ tmppath = concat (ld_sysroot, "/etc/ld.so.conf",
-+ (const char *) NULL);
-+ gld${EMULATION_NAME}_parse_ld_so_conf (&info, tmppath);
-+ }
-+ free (tmppath);
-+
-+ if (info.path)
-+ {
-+ char *d = gld${EMULATION_NAME}_add_sysroot (info.path);
-+ free (info.path);
-+ ld_so_conf = d;
-+ }
-+ initialized = TRUE;
-+ }
-+
-+ if (ld_so_conf == NULL)
-+ return FALSE;
-+
-+
-+ needed.by = l->by;
-+ needed.name = l->name;
-+ return gld${EMULATION_NAME}_search_needed (ld_so_conf, &needed, force);
-+}
-+
-+EOF
-+ # Linux
-+ ;;
-+ esac
-+fi
-+fragment <<EOF
-+
-+/* See if an input file matches a DT_NEEDED entry by name. */
-+
-+static void
-+gld${EMULATION_NAME}_check_needed (lang_input_statement_type *s)
-+{
-+ const char *soname;
-+
-+ /* Stop looking if we've found a loaded lib. */
-+ if (global_found != NULL
-+ && (bfd_elf_get_dyn_lib_class (global_found->the_bfd)
-+ & DYN_AS_NEEDED) == 0)
-+ return;
-+
-+ if (s->filename == NULL || s->the_bfd == NULL)
-+ return;
-+
-+ /* Don't look for a second non-loaded as-needed lib. */
-+ if (global_found != NULL
-+ && (bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0)
-+ return;
-+
-+ if (filename_cmp (s->filename, global_needed->name) == 0)
-+ {
-+ global_found = s;
-+ return;
-+ }
-+
-+ if (s->flags.search_dirs)
-+ {
-+ const char *f = strrchr (s->filename, '/');
-+ if (f != NULL
-+ && filename_cmp (f + 1, global_needed->name) == 0)
-+ {
-+ global_found = s;
-+ return;
-+ }
-+ }
-+
-+ soname = bfd_elf_get_dt_soname (s->the_bfd);
-+ if (soname != NULL
-+ && filename_cmp (soname, global_needed->name) == 0)
-+ {
-+ global_found = s;
-+ return;
-+ }
-+}
-+
-+EOF
-+
-+if test x"$LDEMUL_AFTER_OPEN" != xgld"$EMULATION_NAME"_after_open; then
-+fragment <<EOF
-+
-+static bfd_size_type
-+gld${EMULATION_NAME}_id_note_section_size (bfd *abfd,
-+ struct bfd_link_info *linfo)
-+{
-+ const char *style = linfo->emit_note_gnu_build_id;
-+ bfd_size_type size;
-+
-+ abfd = abfd;
-+
-+ size = offsetof (Elf_External_Note, name[sizeof "GNU"]);
-+ size = (size + 3) & -(bfd_size_type) 4;
-+
-+ if (!strcmp (style, "md5") || !strcmp (style, "uuid"))
-+ size += 128 / 8;
-+ else if (!strcmp (style, "sha1"))
-+ size += 160 / 8;
-+ else if (!strncmp (style, "0x", 2))
-+ {
-+ /* ID is in string form (hex). Convert to bits. */
-+ const char *id = style + 2;
-+ do
-+ {
-+ if (ISXDIGIT (id[0]) && ISXDIGIT (id[1]))
-+ {
-+ ++size;
-+ id += 2;
-+ }
-+ else if (*id == '-' || *id == ':')
-+ ++id;
-+ else
-+ {
-+ size = 0;
-+ break;
-+ }
-+ } while (*id != '\0');
-+ }
-+ else
-+ size = 0;
-+
-+ return size;
-+}
-+
-+static unsigned char
-+read_hex (const char xdigit)
-+{
-+ if (ISDIGIT (xdigit))
-+ return xdigit - '0';
-+ if (ISUPPER (xdigit))
-+ return xdigit - 'A' + 0xa;
-+ if (ISLOWER (xdigit))
-+ return xdigit - 'a' + 0xa;
-+ abort ();
-+ return 0;
-+}
-+
-+struct build_id_info
-+{
-+ const char *style;
-+ asection *sec;
-+};
-+
-+static bfd_boolean
-+gld${EMULATION_NAME}_write_build_id_section (bfd *abfd)
-+{
-+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
-+ struct build_id_info *info = (struct build_id_info *)
-+ elf_tdata (abfd)->after_write_object_contents_info;
-+ asection *asec;
-+ Elf_Internal_Shdr *i_shdr;
-+ unsigned char *contents, *id_bits;
-+ bfd_size_type size;
-+ Elf_External_Note *e_note;
-+
-+ asec = info->sec;
-+ if (bfd_is_abs_section (asec->output_section))
-+ {
-+ einfo (_("%P: warning: .note.gnu.build-id section discarded,"
-+ " --build-id ignored.\n"));
-+ return TRUE;
-+ }
-+ i_shdr = &elf_section_data (asec->output_section)->this_hdr;
-+
-+ if (i_shdr->contents == NULL)
-+ {
-+ if (asec->contents == NULL)
-+ asec->contents = (unsigned char *) xmalloc (asec->size);
-+ contents = asec->contents;
-+ }
-+ else
-+ contents = i_shdr->contents + asec->output_offset;
-+
-+ e_note = (Elf_External_Note *) contents;
-+ size = offsetof (Elf_External_Note, name[sizeof "GNU"]);
-+ size = (size + 3) & -(bfd_size_type) 4;
-+ id_bits = contents + size;
-+ size = asec->size - size;
-+
-+ bfd_h_put_32 (abfd, sizeof "GNU", &e_note->namesz);
-+ bfd_h_put_32 (abfd, size, &e_note->descsz);
-+ bfd_h_put_32 (abfd, NT_GNU_BUILD_ID, &e_note->type);
-+ memcpy (e_note->name, "GNU", sizeof "GNU");
-+
-+ if (!strcmp (info->style, "md5"))
-+ {
-+ struct md5_ctx ctx;
-+ md5_init_ctx (&ctx);
-+ if (bed->s->checksum_contents (abfd,
-+ (void (*) (const void *, size_t, void *))
-+ &md5_process_bytes,
-+ &ctx))
-+ md5_finish_ctx (&ctx, id_bits);
-+ else
-+ return FALSE;
-+ }
-+ else if (!strcmp (info->style, "sha1"))
-+ {
-+ struct sha1_ctx ctx;
-+ sha1_init_ctx (&ctx);
-+ if (bed->s->checksum_contents (abfd,
-+ (void (*) (const void *, size_t, void *))
-+ &sha1_process_bytes,
-+ &ctx))
-+ sha1_finish_ctx (&ctx, id_bits);
-+ else
-+ return FALSE;
-+ }
-+ else if (!strcmp (info->style, "uuid"))
-+ {
-+ int n;
-+ int fd = open ("/dev/urandom", O_RDONLY);
-+ if (fd < 0)
-+ return FALSE;
-+ n = read (fd, id_bits, size);
-+ close (fd);
-+ if (n < (int) size)
-+ return FALSE;
-+ }
-+ else if (!strncmp (info->style, "0x", 2))
-+ {
-+ /* ID is in string form (hex). Convert to bits. */
-+ const char *id = info->style + 2;
-+ size_t n = 0;
-+ do
-+ {
-+ if (ISXDIGIT (id[0]) && ISXDIGIT (id[1]))
-+ {
-+ id_bits[n] = read_hex (*id++) << 4;
-+ id_bits[n++] |= read_hex (*id++);
-+ }
-+ else if (*id == '-' || *id == ':')
-+ ++id;
-+ else
-+ abort (); /* Should have been validated earlier. */
-+ } while (*id != '\0');
-+ }
-+ else
-+ abort (); /* Should have been validated earlier. */
-+
-+ size = asec->size;
-+ return (bfd_seek (abfd,
-+ i_shdr->sh_offset + asec->output_offset, SEEK_SET) == 0
-+ && bfd_bwrite (contents, size, abfd) == size);
-+}
-+
-+
-+/* This is called after all the input files have been opened. */
-+
-+static void
-+gld${EMULATION_NAME}_after_open (void)
-+{
-+ struct bfd_link_needed_list *needed, *l;
-+ struct elf_link_hash_table *htab;
-+
-+ after_open_default ();
-+
-+ htab = elf_hash_table (&link_info);
-+ if (!is_elf_hash_table (htab))
-+ return;
-+
-+ if (link_info.emit_note_gnu_build_id)
-+ {
-+ bfd *abfd;
-+ asection *s;
-+ bfd_size_type size;
-+
-+ /* Find an ELF input. */
-+ for (abfd = link_info.input_bfds;
-+ abfd != (bfd *) NULL; abfd = abfd->link_next)
-+ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
-+ break;
-+
-+ if (abfd == NULL)
-+ {
-+ /* PR 10555: If there are no input files do not
-+ try to create a .note.gnu-build-id section. */
-+ free (link_info.emit_note_gnu_build_id);
-+ link_info.emit_note_gnu_build_id = NULL;
-+ }
-+ else
-+ {
-+ size = gld${EMULATION_NAME}_id_note_section_size (abfd, &link_info);
-+ if (size == 0)
-+ {
-+ einfo ("%P: warning: unrecognized --build-id style ignored.\n");
-+ free (link_info.emit_note_gnu_build_id);
-+ link_info.emit_note_gnu_build_id = NULL;
-+ }
-+ else
-+ {
-+ s = bfd_make_section_with_flags (abfd, ".note.gnu.build-id",
-+ SEC_ALLOC | SEC_LOAD
-+ | SEC_IN_MEMORY | SEC_LINKER_CREATED
-+ | SEC_READONLY | SEC_DATA);
-+ if (s != NULL && bfd_set_section_alignment (abfd, s, 2))
-+ {
-+ struct elf_obj_tdata *t = elf_tdata (link_info.output_bfd);
-+ struct build_id_info *b =
-+ (struct build_id_info *) xmalloc (sizeof *b);
-+
-+ b->style = link_info.emit_note_gnu_build_id;
-+ b->sec = s;
-+ elf_section_type (s) = SHT_NOTE;
-+ s->size = size;
-+ t->after_write_object_contents
-+ = &gld${EMULATION_NAME}_write_build_id_section;
-+ t->after_write_object_contents_info = b;
-+ }
-+ else
-+ {
-+ einfo ("%P: warning: Cannot create .note.gnu.build-id section,"
-+ " --build-id ignored.\n");
-+ free (link_info.emit_note_gnu_build_id);
-+ link_info.emit_note_gnu_build_id = NULL;
-+ }
-+ }
-+ }
-+ }
-+
-+ if (link_info.relocatable)
-+ return;
-+
-+ if (link_info.eh_frame_hdr
-+ && !link_info.traditional_format)
-+ {
-+ bfd *abfd, *elfbfd = NULL;
-+ bfd_boolean warn_eh_frame = FALSE;
-+ asection *s;
-+
-+ for (abfd = link_info.input_bfds; abfd; abfd = abfd->link_next)
-+ {
-+ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
-+ elfbfd = abfd;
-+ if (!warn_eh_frame)
-+ {
-+ s = bfd_get_section_by_name (abfd, ".eh_frame");
-+ while (s != NULL
-+ && (s->size <= 8
-+ || bfd_is_abs_section (s->output_section)))
-+ s = bfd_get_next_section_by_name (s);
-+ warn_eh_frame = s != NULL;
-+ }
-+ if (elfbfd && warn_eh_frame)
-+ break;
-+ }
-+ if (elfbfd)
-+ {
-+ const struct elf_backend_data *bed;
-+
-+ bed = get_elf_backend_data (elfbfd);
-+ s = bfd_make_section_with_flags (elfbfd, ".eh_frame_hdr",
-+ bed->dynamic_sec_flags
-+ | SEC_READONLY);
-+ if (s != NULL
-+ && bfd_set_section_alignment (elfbfd, s, 2))
-+ {
-+ htab->eh_info.hdr_sec = s;
-+ warn_eh_frame = FALSE;
-+ }
-+ }
-+ if (warn_eh_frame)
-+ einfo ("%P: warning: Cannot create .eh_frame_hdr section,"
-+ " --eh-frame-hdr ignored.\n");
-+ }
-+
-+ /* Get the list of files which appear in DT_NEEDED entries in
-+ dynamic objects included in the link (often there will be none).
-+ For each such file, we want to track down the corresponding
-+ library, and include the symbol table in the link. This is what
-+ the runtime dynamic linker will do. Tracking the files down here
-+ permits one dynamic object to include another without requiring
-+ special action by the person doing the link. Note that the
-+ needed list can actually grow while we are stepping through this
-+ loop. */
-+ needed = bfd_elf_get_needed_list (link_info.output_bfd, &link_info);
-+ for (l = needed; l != NULL; l = l->next)
-+ {
-+ struct bfd_link_needed_list *ll;
-+ struct dt_needed n, nn;
-+ int force;
-+
-+ /* If the lib that needs this one was --as-needed and wasn't
-+ found to be needed, then this lib isn't needed either. Skip
-+ the lib when creating a shared object unless we are copying
-+ DT_NEEDED entres. */
-+ if (l->by != NULL
-+ && ((bfd_elf_get_dyn_lib_class (l->by) & DYN_AS_NEEDED) != 0
-+ || (!link_info.executable
-+ && bfd_elf_get_dyn_lib_class (l->by) & DYN_NO_ADD_NEEDED) != 0))
-+ continue;
-+
-+ /* If we've already seen this file, skip it. */
-+ for (ll = needed; ll != l; ll = ll->next)
-+ if ((ll->by == NULL
-+ || (bfd_elf_get_dyn_lib_class (ll->by) & DYN_AS_NEEDED) == 0)
-+ && strcmp (ll->name, l->name) == 0)
-+ break;
-+ if (ll != l)
-+ continue;
-+
-+ /* See if this file was included in the link explicitly. */
-+ global_needed = l;
-+ global_found = NULL;
-+ lang_for_each_input_file (gld${EMULATION_NAME}_check_needed);
-+ if (global_found != NULL
-+ && (bfd_elf_get_dyn_lib_class (global_found->the_bfd)
-+ & DYN_AS_NEEDED) == 0)
-+ continue;
-+
-+ n.by = l->by;
-+ n.name = l->name;
-+ nn.by = l->by;
-+ if (verbose)
-+ info_msg (_("%s needed by %B\n"), l->name, l->by);
-+
-+ /* As-needed libs specified on the command line (or linker script)
-+ take priority over libs found in search dirs. */
-+ if (global_found != NULL)
-+ {
-+ nn.name = global_found->filename;
-+ if (gld${EMULATION_NAME}_try_needed (&nn, TRUE))
-+ continue;
-+ }
-+
-+ /* We need to find this file and include the symbol table. We
-+ want to search for the file in the same way that the dynamic
-+ linker will search. That means that we want to use
-+ rpath_link, rpath, then the environment variable
-+ LD_LIBRARY_PATH (native only), then the DT_RPATH/DT_RUNPATH
-+ entries (native only), then the linker script LIB_SEARCH_DIRS.
-+ We do not search using the -L arguments.
-+
-+ We search twice. The first time, we skip objects which may
-+ introduce version mismatches. The second time, we force
-+ their use. See gld${EMULATION_NAME}_vercheck comment. */
-+ for (force = 0; force < 2; force++)
-+ {
-+ size_t len;
-+ search_dirs_type *search;
-+EOF
-+if [ "x${NATIVE}" = xyes ] ; then
-+fragment <<EOF
-+ const char *lib_path;
-+EOF
-+fi
-+if [ "x${USE_LIBPATH}" = xyes ] ; then
-+fragment <<EOF
-+ struct bfd_link_needed_list *rp;
-+ int found;
-+EOF
-+fi
-+fragment <<EOF
-+
-+ if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link,
-+ &n, force))
-+ break;
-+EOF
-+if [ "x${USE_LIBPATH}" = xyes ] ; then
-+fragment <<EOF
-+ if (gld${EMULATION_NAME}_search_needed (command_line.rpath,
-+ &n, force))
-+ break;
-+EOF
-+fi
-+if [ "x${NATIVE}" = xyes ] ; then
-+fragment <<EOF
-+ if (command_line.rpath_link == NULL
-+ && command_line.rpath == NULL)
-+ {
-+ lib_path = (const char *) getenv ("LD_RUN_PATH");
-+ if (gld${EMULATION_NAME}_search_needed (lib_path, &n,
-+ force))
-+ break;
-+ }
-+ lib_path = (const char *) getenv ("LD_LIBRARY_PATH");
-+ if (gld${EMULATION_NAME}_search_needed (lib_path, &n, force))
-+ break;
-+EOF
-+fi
-+if [ "x${USE_LIBPATH}" = xyes ] ; then
-+fragment <<EOF
-+ found = 0;
-+ rp = bfd_elf_get_runpath_list (link_info.output_bfd, &link_info);
-+ for (; !found && rp != NULL; rp = rp->next)
-+ {
-+ char *tmpname = gld${EMULATION_NAME}_add_sysroot (rp->name);
-+ found = (rp->by == l->by
-+ && gld${EMULATION_NAME}_search_needed (tmpname,
-+ &n,
-+ force));
-+ free (tmpname);
-+ }
-+ if (found)
-+ break;
-+
-+EOF
-+fi
-+if [ "x${USE_LIBPATH}" = xyes ] ; then
-+ case ${target} in
-+ *-*-freebsd* | *-*-dragonfly*)
-+ fragment <<EOF
-+ if (gld${EMULATION_NAME}_check_ld_elf_hints (l, force))
-+ break;
-+EOF
-+ # FreeBSD
-+ ;;
-+
-+ *-*-linux-* | *-*-k*bsd*-* | *-*-gnu*)
-+ # Linux
-+ fragment <<EOF
-+ if (gld${EMULATION_NAME}_check_ld_so_conf (l, force))
-+ break;
-+
-+EOF
-+ ;;
-+ esac
-+fi
-+fragment <<EOF
-+ len = strlen (l->name);
-+ for (search = search_head; search != NULL; search = search->next)
-+ {
-+ char *filename;
-+
-+ if (search->cmdline)
-+ continue;
-+ filename = (char *) xmalloc (strlen (search->name) + len + 2);
-+ sprintf (filename, "%s/%s", search->name, l->name);
-+ nn.name = filename;
-+ if (gld${EMULATION_NAME}_try_needed (&nn, force))
-+ break;
-+ free (filename);
-+ }
-+ if (search != NULL)
-+ break;
-+EOF
-+fragment <<EOF
-+ }
-+
-+ if (force < 2)
-+ continue;
-+
-+ einfo ("%P: warning: %s, needed by %B, not found (try using -rpath or -rpath-link)\n",
-+ l->name, l->by);
-+ }
-+}
-+
-+EOF
-+fi
-+
-+fragment <<EOF
-+
-+/* Look through an expression for an assignment statement. */
-+
-+static void
-+gld${EMULATION_NAME}_find_exp_assignment (etree_type *exp)
-+{
-+ bfd_boolean provide = FALSE;
-+
-+ switch (exp->type.node_class)
-+ {
-+ case etree_provide:
-+ case etree_provided:
-+ provide = TRUE;
-+ /* Fall thru */
-+ case etree_assign:
-+ /* We call record_link_assignment even if the symbol is defined.
-+ This is because if it is defined by a dynamic object, we
-+ actually want to use the value defined by the linker script,
-+ not the value from the dynamic object (because we are setting
-+ symbols like etext). If the symbol is defined by a regular
-+ object, then, as it happens, calling record_link_assignment
-+ will do no harm. */
-+ if (strcmp (exp->assign.dst, ".") != 0)
-+ {
-+ if (!bfd_elf_record_link_assignment (link_info.output_bfd,
-+ &link_info,
-+ exp->assign.dst, provide,
-+ exp->assign.hidden))
-+ einfo ("%P%F: failed to record assignment to %s: %E\n",
-+ exp->assign.dst);
-+ }
-+ gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src);
-+ break;
-+
-+ case etree_binary:
-+ gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs);
-+ gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs);
-+ break;
-+
-+ case etree_trinary:
-+ gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond);
-+ gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
-+ gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs);
-+ break;
-+
-+ case etree_unary:
-+ gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child);
-+ break;
-+
-+ default:
-+ break;
-+ }
-+}
-+
-+
-+/* This is called by the before_allocation routine via
-+ lang_for_each_statement. It locates any assignment statements, and
-+ tells the ELF backend about them, in case they are assignments to
-+ symbols which are referred to by dynamic objects. */
-+
-+static void
-+gld${EMULATION_NAME}_find_statement_assignment (lang_statement_union_type *s)
-+{
-+ if (s->header.type == lang_assignment_statement_enum)
-+ gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
-+}
-+
-+EOF
-+
-+if test x"$LDEMUL_BEFORE_ALLOCATION" != xgld"$EMULATION_NAME"_before_allocation; then
-+ if test x"${ELF_INTERPRETER_NAME+set}" = xset; then
-+ ELF_INTERPRETER_SET_DEFAULT="
-+ if (sinterp != NULL)
-+ {
-+ sinterp->contents = (unsigned char *) ${ELF_INTERPRETER_NAME};
-+ sinterp->size = strlen ((char *) sinterp->contents) + 1;
-+ }
-+
-+"
-+ else
-+ ELF_INTERPRETER_SET_DEFAULT=
-+ fi
-+fragment <<EOF
-+
-+/* used by before_allocation and handle_option. */
-+static void
-+gld${EMULATION_NAME}_append_to_separated_string (char **to, char *op_arg)
-+{
-+ if (*to == NULL)
-+ *to = xstrdup (op_arg);
-+ else
-+ {
-+ size_t to_len = strlen (*to);
-+ size_t op_arg_len = strlen (op_arg);
-+ char *buf;
-+ char *cp = *to;
-+
-+ /* First see whether OPTARG is already in the path. */
-+ do
-+ {
-+ if (strncmp (op_arg, cp, op_arg_len) == 0
-+ && (cp[op_arg_len] == 0
-+ || cp[op_arg_len] == config.rpath_separator))
-+ /* We found it. */
-+ break;
-+
-+ /* Not yet found. */
-+ cp = strchr (cp, config.rpath_separator);
-+ if (cp != NULL)
-+ ++cp;
-+ }
-+ while (cp != NULL);
-+
-+ if (cp == NULL)
-+ {
-+ buf = xmalloc (to_len + op_arg_len + 2);
-+ sprintf (buf, "%s%c%s", *to,
-+ config.rpath_separator, op_arg);
-+ free (*to);
-+ *to = buf;
-+ }
-+ }
-+}
-+
-+/* This is called after the sections have been attached to output
-+ sections, but before any sizes or addresses have been set. */
-+
-+static void
-+gld${EMULATION_NAME}_before_allocation (void)
-+{
-+ const char *rpath;
-+ asection *sinterp;
-+ bfd *abfd;
-+
-+ if (link_info.hash->type == bfd_link_elf_hash_table)
-+ _bfd_elf_tls_setup (link_info.output_bfd, &link_info);
-+
-+ /* If we are going to make any variable assignments, we need to let
-+ the ELF backend know about them in case the variables are
-+ referred to by dynamic objects. */
-+ lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment);
-+
-+ /* Let the ELF backend work out the sizes of any sections required
-+ by dynamic linking. */
-+ rpath = command_line.rpath;
-+ if (rpath == NULL)
-+ rpath = (const char *) getenv ("LD_RUN_PATH");
-+
-+ for (abfd = link_info.input_bfds; abfd; abfd = abfd->link_next)
-+ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
-+ {
-+ const char *audit_libs = elf_dt_audit (abfd);
-+
-+ /* If the input bfd contains an audit entry, we need to add it as
-+ a dep audit entry. */
-+ if (audit_libs && *audit_libs != '\0')
-+ {
-+ char *cp = xstrdup (audit_libs);
-+ do
-+ {
-+ int more = 0;
-+ char *cp2 = strchr (cp, config.rpath_separator);
-+
-+ if (cp2)
-+ {
-+ *cp2 = '\0';
-+ more = 1;
-+ }
-+
-+ if (cp != NULL && *cp != '\0')
-+ gld${EMULATION_NAME}_append_to_separated_string (&depaudit, cp);
-+
-+ cp = more ? ++cp2 : NULL;
-+ }
-+ while (cp != NULL);
-+ }
-+ }
-+
-+ if (! (bfd_elf_size_dynamic_sections
-+ (link_info.output_bfd, command_line.soname, rpath,
-+ command_line.filter_shlib, audit, depaudit,
-+ (const char * const *) command_line.auxiliary_filters,
-+ &link_info, &sinterp)))
-+ einfo ("%P%F: failed to set dynamic section sizes: %E\n");
-+
-+${ELF_INTERPRETER_SET_DEFAULT}
-+ /* Let the user override the dynamic linker we are using. */
-+ if (command_line.interpreter != NULL
-+ && sinterp != NULL)
-+ {
-+ sinterp->contents = (bfd_byte *) command_line.interpreter;
-+ sinterp->size = strlen (command_line.interpreter) + 1;
-+ }
-+
-+ /* Look for any sections named .gnu.warning. As a GNU extensions,
-+ we treat such sections as containing warning messages. We print
-+ out the warning message, and then zero out the section size so
-+ that it does not get copied into the output file. */
-+
-+ {
-+ LANG_FOR_EACH_INPUT_STATEMENT (is)
-+ {
-+ asection *s;
-+ bfd_size_type sz;
-+ char *msg;
-+ bfd_boolean ret;
-+
-+ if (is->flags.just_syms)
-+ continue;
-+
-+ s = bfd_get_section_by_name (is->the_bfd, ".gnu.warning");
-+ if (s == NULL)
-+ continue;
-+
-+ sz = s->size;
-+ msg = (char *) xmalloc ((size_t) (sz + 1));
-+ if (! bfd_get_section_contents (is->the_bfd, s, msg,
-+ (file_ptr) 0, sz))
-+ einfo ("%F%B: Can't read contents of section .gnu.warning: %E\n",
-+ is->the_bfd);
-+ msg[sz] = '\0';
-+ ret = link_info.callbacks->warning (&link_info, msg,
-+ (const char *) NULL,
-+ is->the_bfd, (asection *) NULL,
-+ (bfd_vma) 0);
-+ ASSERT (ret);
-+ free (msg);
-+
-+ /* Clobber the section size, so that we don't waste space
-+ copying the warning into the output file. If we've already
-+ sized the output section, adjust its size. The adjustment
-+ is on rawsize because targets that size sections early will
-+ have called lang_reset_memory_regions after sizing. */
-+ if (s->output_section != NULL
-+ && s->output_section->rawsize >= s->size)
-+ s->output_section->rawsize -= s->size;
-+
-+ s->size = 0;
-+
-+ /* Also set SEC_EXCLUDE, so that local symbols defined in the
-+ warning section don't get copied to the output. */
-+ s->flags |= SEC_EXCLUDE | SEC_KEEP;
-+ }
-+ }
-+
-+ before_allocation_default ();
-+
-+ if (!bfd_elf_size_dynsym_hash_dynstr (link_info.output_bfd, &link_info))
-+ einfo ("%P%F: failed to set dynamic section sizes: %E\n");
-+}
-+
-+EOF
-+fi
-+
-+if test x"$LDEMUL_OPEN_DYNAMIC_ARCHIVE" != xgld"$EMULATION_NAME"_open_dynamic_archive; then
-+fragment <<EOF
-+
-+/* Try to open a dynamic archive. This is where we know that ELF
-+ dynamic libraries have an extension of .so (or .sl on oddball systems
-+ like hpux). */
-+
-+static bfd_boolean
-+gld${EMULATION_NAME}_open_dynamic_archive
-+ (const char *arch, search_dirs_type *search, lang_input_statement_type *entry)
-+{
-+ const char *filename;
-+ char *string;
-+
-+ if (! entry->flags.maybe_archive)
-+ return FALSE;
-+
-+ filename = entry->filename;
-+
-+ /* This allocates a few bytes too many when EXTRA_SHLIB_EXTENSION
-+ is defined, but it does not seem worth the headache to optimize
-+ away those two bytes of space. */
-+ string = (char *) xmalloc (strlen (search->name)
-+ + strlen (filename)
-+ + strlen (arch)
-+#ifdef EXTRA_SHLIB_EXTENSION
-+ + strlen (EXTRA_SHLIB_EXTENSION)
-+#endif
-+ + sizeof "/lib.so");
-+
-+ sprintf (string, "%s/lib%s%s.so", search->name, filename, arch);
-+
-+#ifdef EXTRA_SHLIB_EXTENSION
-+ /* Try the .so extension first. If that fails build a new filename
-+ using EXTRA_SHLIB_EXTENSION. */
-+ if (! ldfile_try_open_bfd (string, entry))
-+ {
-+ sprintf (string, "%s/lib%s%s%s", search->name,
-+ filename, arch, EXTRA_SHLIB_EXTENSION);
-+#endif
-+
-+ if (! ldfile_try_open_bfd (string, entry))
-+ {
-+ free (string);
-+ return FALSE;
-+ }
-+#ifdef EXTRA_SHLIB_EXTENSION
-+ }
-+#endif
-+
-+ entry->filename = string;
-+
-+ /* We have found a dynamic object to include in the link. The ELF
-+ backend linker will create a DT_NEEDED entry in the .dynamic
-+ section naming this file. If this file includes a DT_SONAME
-+ entry, it will be used. Otherwise, the ELF linker will just use
-+ the name of the file. For an archive found by searching, like
-+ this one, the DT_NEEDED entry should consist of just the name of
-+ the file, without the path information used to find it. Note
-+ that we only need to do this if we have a dynamic object; an
-+ archive will never be referenced by a DT_NEEDED entry.
-+
-+ FIXME: This approach--using bfd_elf_set_dt_needed_name--is not
-+ very pretty. I haven't been able to think of anything that is
-+ pretty, though. */
-+ if (bfd_check_format (entry->the_bfd, bfd_object)
-+ && (entry->the_bfd->flags & DYNAMIC) != 0)
-+ {
-+ ASSERT (entry->flags.maybe_archive && entry->flags.search_dirs);
-+
-+ /* Rather than duplicating the logic above. Just use the
-+ filename we recorded earlier. */
-+
-+ filename = lbasename (entry->filename);
-+ bfd_elf_set_dt_needed_name (entry->the_bfd, filename);
-+ }
-+
-+ return TRUE;
-+}
-+
-+EOF
-+fi
-+
-+if test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then
-+fragment <<EOF
-+
-+/* A variant of lang_output_section_find used by place_orphan. */
-+
-+static lang_output_section_statement_type *
-+output_rel_find (asection *sec, int isdyn)
-+{
-+ lang_output_section_statement_type *lookup;
-+ lang_output_section_statement_type *last = NULL;
-+ lang_output_section_statement_type *last_alloc = NULL;
-+ lang_output_section_statement_type *last_ro_alloc = NULL;
-+ lang_output_section_statement_type *last_rel = NULL;
-+ lang_output_section_statement_type *last_rel_alloc = NULL;
-+ int rela = sec->name[4] == 'a';
-+
-+ for (lookup = &lang_output_section_statement.head->output_section_statement;
-+ lookup != NULL;
-+ lookup = lookup->next)
-+ {
-+ if (lookup->constraint >= 0
-+ && CONST_STRNEQ (lookup->name, ".rel"))
-+ {
-+ int lookrela = lookup->name[4] == 'a';
-+
-+ /* .rel.dyn must come before all other reloc sections, to suit
-+ GNU ld.so. */
-+ if (isdyn)
-+ break;
-+
-+ /* Don't place after .rel.plt as doing so results in wrong
-+ dynamic tags. */
-+ if (strcmp (".plt", lookup->name + 4 + lookrela) == 0)
-+ break;
-+
-+ if (rela == lookrela || last_rel == NULL)
-+ last_rel = lookup;
-+ if ((rela == lookrela || last_rel_alloc == NULL)
-+ && lookup->bfd_section != NULL
-+ && (lookup->bfd_section->flags & SEC_ALLOC) != 0)
-+ last_rel_alloc = lookup;
-+ }
-+
-+ last = lookup;
-+ if (lookup->bfd_section != NULL
-+ && (lookup->bfd_section->flags & SEC_ALLOC) != 0)
-+ {
-+ last_alloc = lookup;
-+ if ((lookup->bfd_section->flags & SEC_READONLY) != 0)
-+ last_ro_alloc = lookup;
-+ }
-+ }
-+
-+ if (last_rel_alloc)
-+ return last_rel_alloc;
-+
-+ if (last_rel)
-+ return last_rel;
-+
-+ if (last_ro_alloc)
-+ return last_ro_alloc;
-+
-+ if (last_alloc)
-+ return last_alloc;
-+
-+ return last;
-+}
-+
-+/* Place an orphan section. We use this to put random SHF_ALLOC
-+ sections in the right segment. */
-+
-+static lang_output_section_statement_type *
-+gld${EMULATION_NAME}_place_orphan (asection *s,
-+ const char *secname,
-+ int constraint)
-+{
-+ static struct orphan_save hold[] =
-+ {
-+ { ".text",
-+ SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE,
-+ 0, 0, 0, 0 },
-+ { ".rodata",
-+ SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA,
-+ 0, 0, 0, 0 },
-+ { ".data",
-+ SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA,
-+ 0, 0, 0, 0 },
-+ { ".bss",
-+ SEC_ALLOC,
-+ 0, 0, 0, 0 },
-+ { 0,
-+ SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA,
-+ 0, 0, 0, 0 },
-+ { ".interp",
-+ SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA,
-+ 0, 0, 0, 0 },
-+ { ".sdata",
-+ SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_SMALL_DATA,
-+ 0, 0, 0, 0 },
-+ { ".comment",
-+ SEC_HAS_CONTENTS,
-+ 0, 0, 0, 0 },
-+ };
-+ enum orphan_save_index
-+ {
-+ orphan_text = 0,
-+ orphan_rodata,
-+ orphan_data,
-+ orphan_bss,
-+ orphan_rel,
-+ orphan_interp,
-+ orphan_sdata,
-+ orphan_nonalloc
-+ };
-+ static int orphan_init_done = 0;
-+ struct orphan_save *place;
-+ lang_output_section_statement_type *after;
-+ lang_output_section_statement_type *os;
-+ lang_output_section_statement_type *match_by_name = NULL;
-+ int isdyn = 0;
-+ int iself = s->owner->xvec->flavour == bfd_target_elf_flavour;
-+ unsigned int sh_type = iself ? elf_section_type (s) : SHT_NULL;
-+
-+ if (! link_info.relocatable
-+ && link_info.combreloc
-+ && (s->flags & SEC_ALLOC))
-+ {
-+ if (iself)
-+ switch (sh_type)
-+ {
-+ case SHT_RELA:
-+ secname = ".rela.dyn";
-+ isdyn = 1;
-+ break;
-+ case SHT_REL:
-+ secname = ".rel.dyn";
-+ isdyn = 1;
-+ break;
-+ default:
-+ break;
-+ }
-+ else if (CONST_STRNEQ (secname, ".rel"))
-+ {
-+ secname = secname[4] == 'a' ? ".rela.dyn" : ".rel.dyn";
-+ isdyn = 1;
-+ }
-+ }
-+
-+ /* Look through the script to see where to place this section. */
-+ if (constraint == 0)
-+ for (os = lang_output_section_find (secname);
-+ os != NULL;
-+ os = next_matching_output_section_statement (os, 0))
-+ {
-+ /* If we don't match an existing output section, tell
-+ lang_insert_orphan to create a new output section. */
-+ constraint = SPECIAL;
-+
-+ if (os->bfd_section != NULL
-+ && (os->bfd_section->flags == 0
-+ || (_bfd_elf_match_sections_by_type (link_info.output_bfd,
-+ os->bfd_section,
-+ s->owner, s)
-+ && ((s->flags ^ os->bfd_section->flags)
-+ & (SEC_LOAD | SEC_ALLOC)) == 0)))
-+ {
-+ /* We already have an output section statement with this
-+ name, and its bfd section has compatible flags.
-+ If the section already exists but does not have any flags
-+ set, then it has been created by the linker, probably as a
-+ result of a --section-start command line switch. */
-+ lang_add_section (&os->children, s, NULL, os);
-+ return os;
-+ }
-+
-+ /* Save unused output sections in case we can match them
-+ against orphans later. */
-+ if (os->bfd_section == NULL)
-+ match_by_name = os;
-+ }
-+
-+ /* If we didn't match an active output section, see if we matched an
-+ unused one and use that. */
-+ if (match_by_name)
-+ {
-+ lang_add_section (&match_by_name->children, s, NULL, match_by_name);
-+ return match_by_name;
-+ }
-+
-+ if (!orphan_init_done)
-+ {
-+ struct orphan_save *ho;
-+
-+ for (ho = hold; ho < hold + sizeof (hold) / sizeof (hold[0]); ++ho)
-+ if (ho->name != NULL)
-+ {
-+ ho->os = lang_output_section_find (ho->name);
-+ if (ho->os != NULL && ho->os->flags == 0)
-+ ho->os->flags = ho->flags;
-+ }
-+ orphan_init_done = 1;
-+ }
-+
-+ /* If this is a final link, then always put .gnu.warning.SYMBOL
-+ sections into the .text section to get them out of the way. */
-+ if (link_info.executable
-+ && ! link_info.relocatable
-+ && CONST_STRNEQ (s->name, ".gnu.warning.")
-+ && hold[orphan_text].os != NULL)
-+ {
-+ os = hold[orphan_text].os;
-+ lang_add_section (&os->children, s, NULL, os);
-+ return os;
-+ }
-+
-+ /* Decide which segment the section should go in based on the
-+ section name and section flags. We put loadable .note sections
-+ right after the .interp section, so that the PT_NOTE segment is
-+ stored right after the program headers where the OS can read it
-+ in the first page. */
-+
-+ place = NULL;
-+ if ((s->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
-+ place = &hold[orphan_nonalloc];
-+ else if ((s->flags & SEC_ALLOC) == 0)
-+ ;
-+ else if ((s->flags & SEC_LOAD) != 0
-+ && ((iself && sh_type == SHT_NOTE)
-+ || (!iself && CONST_STRNEQ (secname, ".note"))))
-+ place = &hold[orphan_interp];
-+ else if ((s->flags & (SEC_LOAD | SEC_HAS_CONTENTS | SEC_THREAD_LOCAL)) == 0)
-+ place = &hold[orphan_bss];
-+ else if ((s->flags & SEC_SMALL_DATA) != 0)
-+ place = &hold[orphan_sdata];
-+ else if ((s->flags & SEC_READONLY) == 0)
-+ place = &hold[orphan_data];
-+ else if (((iself && (sh_type == SHT_RELA || sh_type == SHT_REL))
-+ || (!iself && CONST_STRNEQ (secname, ".rel")))
-+ && (s->flags & SEC_LOAD) != 0)
-+ place = &hold[orphan_rel];
-+ else if ((s->flags & SEC_CODE) == 0)
-+ place = &hold[orphan_rodata];
-+ else
-+ place = &hold[orphan_text];
-+
-+ after = NULL;
-+ if (place != NULL)
-+ {
-+ if (place->os == NULL)
-+ {
-+ if (place->name != NULL)
-+ place->os = lang_output_section_find (place->name);
-+ else
-+ place->os = output_rel_find (s, isdyn);
-+ }
-+ after = place->os;
-+ if (after == NULL)
-+ after = lang_output_section_find_by_flags
-+ (s, &place->os, _bfd_elf_match_sections_by_type);
-+ if (after == NULL)
-+ /* *ABS* is always the first output section statement. */
-+ after = &lang_output_section_statement.head->output_section_statement;
-+ }
-+
-+ return lang_insert_orphan (s, secname, constraint, after, place, NULL, NULL);
-+}
-+EOF
-+fi
-+
-+if test x"$LDEMUL_AFTER_ALLOCATION" != xgld"$EMULATION_NAME"_after_allocation; then
-+fragment <<EOF
-+
-+static void
-+gld${EMULATION_NAME}_after_allocation (void)
-+{
-+ bfd_boolean need_layout = bfd_elf_discard_info (link_info.output_bfd,
-+ &link_info);
-+ gld${EMULATION_NAME}_map_segments (need_layout);
-+}
-+EOF
-+fi
-+
-+if test x"$LDEMUL_GET_SCRIPT" != xgld"$EMULATION_NAME"_get_script; then
-+fragment <<EOF
-+
-+static char *
-+gld${EMULATION_NAME}_get_script (int *isfile)
-+EOF
-+
-+if test -n "$COMPILE_IN"
-+then
-+# Scripts compiled in.
-+
-+# sed commands to quote an ld script as a C string.
-+sc="-f stringify.sed"
-+
-+fragment <<EOF
-+{
-+ *isfile = 0;
-+
-+ if (link_info.relocatable && config.build_constructors)
-+ return
-+EOF
-+sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
-+echo ' ; else if (link_info.relocatable) return' >> e${EMULATION_NAME}.c
-+sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
-+echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
-+sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
-+if cmp -s ldscripts/${EMULATION_NAME}.x ldscripts/${EMULATION_NAME}.xn; then : ; else
-+echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
-+sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
-+fi
-+if test -n "$GENERATE_PIE_SCRIPT" ; then
-+if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
-+echo ' ; else if (link_info.pie && link_info.combreloc' >> e${EMULATION_NAME}.c
-+echo ' && link_info.relro' >> e${EMULATION_NAME}.c
-+echo ' && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
-+sed $sc ldscripts/${EMULATION_NAME}.xdw >> e${EMULATION_NAME}.c
-+echo ' ; else if (link_info.pie && link_info.combreloc) return' >> e${EMULATION_NAME}.c
-+sed $sc ldscripts/${EMULATION_NAME}.xdc >> e${EMULATION_NAME}.c
-+fi
-+echo ' ; else if (link_info.pie) return' >> e${EMULATION_NAME}.c
-+sed $sc ldscripts/${EMULATION_NAME}.xd >> e${EMULATION_NAME}.c
-+fi
-+if test -n "$GENERATE_SHLIB_SCRIPT" ; then
-+if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
-+echo ' ; else if (link_info.shared && link_info.combreloc' >> e${EMULATION_NAME}.c
-+echo ' && link_info.relro' >> e${EMULATION_NAME}.c
-+echo ' && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
-+sed $sc ldscripts/${EMULATION_NAME}.xsw >> e${EMULATION_NAME}.c
-+echo ' ; else if (link_info.shared && link_info.combreloc) return' >> e${EMULATION_NAME}.c
-+sed $sc ldscripts/${EMULATION_NAME}.xsc >> e${EMULATION_NAME}.c
-+fi
-+echo ' ; else if (link_info.shared) return' >> e${EMULATION_NAME}.c
-+sed $sc ldscripts/${EMULATION_NAME}.xs >> e${EMULATION_NAME}.c
-+fi
-+if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
-+echo ' ; else if (link_info.combreloc && link_info.relro' >> e${EMULATION_NAME}.c
-+echo ' && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
-+sed $sc ldscripts/${EMULATION_NAME}.xw >> e${EMULATION_NAME}.c
-+echo ' ; else if (link_info.combreloc) return' >> e${EMULATION_NAME}.c
-+sed $sc ldscripts/${EMULATION_NAME}.xc >> e${EMULATION_NAME}.c
-+fi
-+echo ' ; else return' >> e${EMULATION_NAME}.c
-+sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
-+echo '; }' >> e${EMULATION_NAME}.c
-+
-+else
-+# Scripts read from the filesystem.
-+
-+fragment <<EOF
-+{
-+ *isfile = 1;
-+
-+ if (link_info.relocatable && config.build_constructors)
-+ return "ldscripts/${EMULATION_NAME}.xu";
-+ else if (link_info.relocatable)
-+ return "ldscripts/${EMULATION_NAME}.xr";
-+ else if (!config.text_read_only)
-+ return "ldscripts/${EMULATION_NAME}.xbn";
-+EOF
-+if cmp -s ldscripts/${EMULATION_NAME}.x ldscripts/${EMULATION_NAME}.xn; then :
-+else
-+fragment <<EOF
-+ else if (!config.magic_demand_paged)
-+ return "ldscripts/${EMULATION_NAME}.xn";
-+EOF
-+fi
-+if test -n "$GENERATE_PIE_SCRIPT" ; then
-+if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
-+fragment <<EOF
-+ else if (link_info.pie && link_info.combreloc
-+ && link_info.relro && (link_info.flags & DF_BIND_NOW))
-+ return "ldscripts/${EMULATION_NAME}.xdw";
-+ else if (link_info.pie && link_info.combreloc)
-+ return "ldscripts/${EMULATION_NAME}.xdc";
-+EOF
-+fi
-+fragment <<EOF
-+ else if (link_info.pie)
-+ return "ldscripts/${EMULATION_NAME}.xd";
-+EOF
-+fi
-+if test -n "$GENERATE_SHLIB_SCRIPT" ; then
-+if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
-+fragment <<EOF
-+ else if (link_info.shared && link_info.combreloc
-+ && link_info.relro && (link_info.flags & DF_BIND_NOW))
-+ return "ldscripts/${EMULATION_NAME}.xsw";
-+ else if (link_info.shared && link_info.combreloc)
-+ return "ldscripts/${EMULATION_NAME}.xsc";
-+EOF
-+fi
-+fragment <<EOF
-+ else if (link_info.shared)
-+ return "ldscripts/${EMULATION_NAME}.xs";
-+EOF
-+fi
-+if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
-+fragment <<EOF
-+ else if (link_info.combreloc && link_info.relro
-+ && (link_info.flags & DF_BIND_NOW))
-+ return "ldscripts/${EMULATION_NAME}.xw";
-+ else if (link_info.combreloc)
-+ return "ldscripts/${EMULATION_NAME}.xc";
-+EOF
-+fi
-+fragment <<EOF
-+ else
-+ return "ldscripts/${EMULATION_NAME}.x";
-+}
-+
-+EOF
-+fi
-+fi
-+
-+if test -n "$PARSE_AND_LIST_PROLOGUE" ; then
-+fragment <<EOF
-+ $PARSE_AND_LIST_PROLOGUE
-+EOF
-+fi
-+
-+fragment <<EOF
-+
-+#define OPTION_DISABLE_NEW_DTAGS (400)
-+#define OPTION_ENABLE_NEW_DTAGS (OPTION_DISABLE_NEW_DTAGS + 1)
-+#define OPTION_GROUP (OPTION_ENABLE_NEW_DTAGS + 1)
-+#define OPTION_EH_FRAME_HDR (OPTION_GROUP + 1)
-+#define OPTION_EXCLUDE_LIBS (OPTION_EH_FRAME_HDR + 1)
-+#define OPTION_HASH_STYLE (OPTION_EXCLUDE_LIBS + 1)
-+#define OPTION_BUILD_ID (OPTION_HASH_STYLE + 1)
-+#define OPTION_AUDIT (OPTION_BUILD_ID + 1)
-+
-+static void
-+gld${EMULATION_NAME}_add_options
-+ (int ns, char **shortopts, int nl, struct option **longopts,
-+ int nrl ATTRIBUTE_UNUSED, struct option **really_longopts ATTRIBUTE_UNUSED)
-+{
-+EOF
-+if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
-+fragment <<EOF
-+ static const char xtra_short[] = "${PARSE_AND_LIST_SHORTOPTS}z:P:";
-+EOF
-+else
-+fragment <<EOF
-+ static const char xtra_short[] = "${PARSE_AND_LIST_SHORTOPTS}z:";
-+EOF
-+fi
-+fragment <<EOF
-+ static const struct option xtra_long[] = {
-+EOF
-+if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
-+fragment <<EOF
-+ {"audit", required_argument, NULL, OPTION_AUDIT},
-+ {"Bgroup", no_argument, NULL, OPTION_GROUP},
-+EOF
-+fi
-+fragment <<EOF
-+ {"build-id", optional_argument, NULL, OPTION_BUILD_ID},
-+EOF
-+if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
-+fragment <<EOF
-+ {"depaudit", required_argument, NULL, 'P'},
-+ {"disable-new-dtags", no_argument, NULL, OPTION_DISABLE_NEW_DTAGS},
-+ {"enable-new-dtags", no_argument, NULL, OPTION_ENABLE_NEW_DTAGS},
-+ {"eh-frame-hdr", no_argument, NULL, OPTION_EH_FRAME_HDR},
-+ {"exclude-libs", required_argument, NULL, OPTION_EXCLUDE_LIBS},
-+ {"hash-style", required_argument, NULL, OPTION_HASH_STYLE},
-+EOF
-+fi
-+if test -n "$PARSE_AND_LIST_LONGOPTS" ; then
-+fragment <<EOF
-+ $PARSE_AND_LIST_LONGOPTS
-+EOF
-+fi
-+fragment <<EOF
-+ {NULL, no_argument, NULL, 0}
-+ };
-+
-+ *shortopts = (char *) xrealloc (*shortopts, ns + sizeof (xtra_short));
-+ memcpy (*shortopts + ns, &xtra_short, sizeof (xtra_short));
-+ *longopts = (struct option *)
-+ xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long));
-+ memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long));
-+}
-+
-+#define DEFAULT_BUILD_ID_STYLE "sha1"
-+
-+static bfd_boolean
-+gld${EMULATION_NAME}_handle_option (int optc)
-+{
-+ switch (optc)
-+ {
-+ default:
-+ return FALSE;
-+
-+ case OPTION_BUILD_ID:
-+ if (link_info.emit_note_gnu_build_id != NULL)
-+ {
-+ free (link_info.emit_note_gnu_build_id);
-+ link_info.emit_note_gnu_build_id = NULL;
-+ }
-+ if (optarg == NULL)
-+ optarg = DEFAULT_BUILD_ID_STYLE;
-+ if (strcmp (optarg, "none"))
-+ link_info.emit_note_gnu_build_id = xstrdup (optarg);
-+ break;
-+
-+EOF
-+
-+if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
-+fragment <<EOF
-+ case OPTION_AUDIT:
-+ gld${EMULATION_NAME}_append_to_separated_string (&audit, optarg);
-+ break;
-+
-+ case 'P':
-+ gld${EMULATION_NAME}_append_to_separated_string (&depaudit, optarg);
-+ break;
-+
-+ case OPTION_DISABLE_NEW_DTAGS:
-+ link_info.new_dtags = FALSE;
-+ break;
-+
-+ case OPTION_ENABLE_NEW_DTAGS:
-+ link_info.new_dtags = TRUE;
-+ break;
-+
-+ case OPTION_EH_FRAME_HDR:
-+ link_info.eh_frame_hdr = TRUE;
-+ break;
-+
-+ case OPTION_GROUP:
-+ link_info.flags_1 |= (bfd_vma) DF_1_GROUP;
-+ /* Groups must be self-contained. */
-+ link_info.unresolved_syms_in_objects = RM_GENERATE_ERROR;
-+ link_info.unresolved_syms_in_shared_libs = RM_GENERATE_ERROR;
-+ break;
-+
-+ case OPTION_EXCLUDE_LIBS:
-+ add_excluded_libs (optarg);
-+ break;
-+
-+ case OPTION_HASH_STYLE:
-+ link_info.emit_hash = FALSE;
-+ link_info.emit_gnu_hash = FALSE;
-+ if (strcmp (optarg, "sysv") == 0)
-+ link_info.emit_hash = TRUE;
-+ else if (strcmp (optarg, "gnu") == 0)
-+ link_info.emit_gnu_hash = TRUE;
-+ else if (strcmp (optarg, "both") == 0)
-+ {
-+ link_info.emit_hash = TRUE;
-+ link_info.emit_gnu_hash = TRUE;
-+ }
-+ else
-+ einfo (_("%P%F: invalid hash style \`%s'\n"), optarg);
-+ break;
-+
-+EOF
-+fi
-+fragment <<EOF
-+ case 'z':
-+ if (strcmp (optarg, "defs") == 0)
-+ link_info.unresolved_syms_in_objects = RM_GENERATE_ERROR;
-+ else if (strcmp (optarg, "muldefs") == 0)
-+ link_info.allow_multiple_definition = TRUE;
-+ else if (CONST_STRNEQ (optarg, "max-page-size="))
-+ {
-+ char *end;
-+
-+ config.maxpagesize = strtoul (optarg + 14, &end, 0);
-+ if (*end || (config.maxpagesize & (config.maxpagesize - 1)) != 0)
-+ einfo (_("%P%F: invalid maxium page size \`%s'\n"),
-+ optarg + 14);
-+ }
-+ else if (CONST_STRNEQ (optarg, "common-page-size="))
-+ {
-+ char *end;
-+ config.commonpagesize = strtoul (optarg + 17, &end, 0);
-+ if (*end
-+ || (config.commonpagesize & (config.commonpagesize - 1)) != 0)
-+ einfo (_("%P%F: invalid common page size \`%s'\n"),
-+ optarg + 17);
-+ }
-+ else if (strcmp (optarg, "execstack") == 0)
-+ {
-+ link_info.execstack = TRUE;
-+ link_info.noexecstack = FALSE;
-+ }
-+ else if (strcmp (optarg, "noexecstack") == 0)
-+ {
-+ link_info.noexecstack = TRUE;
-+ link_info.execstack = FALSE;
-+ }
-+EOF
-+if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
-+fragment <<EOF
-+ else if (strcmp (optarg, "initfirst") == 0)
-+ link_info.flags_1 |= (bfd_vma) DF_1_INITFIRST;
-+ else if (strcmp (optarg, "interpose") == 0)
-+ link_info.flags_1 |= (bfd_vma) DF_1_INTERPOSE;
-+ else if (strcmp (optarg, "loadfltr") == 0)
-+ link_info.flags_1 |= (bfd_vma) DF_1_LOADFLTR;
-+ else if (strcmp (optarg, "nodefaultlib") == 0)
-+ link_info.flags_1 |= (bfd_vma) DF_1_NODEFLIB;
-+ else if (strcmp (optarg, "nodelete") == 0)
-+ link_info.flags_1 |= (bfd_vma) DF_1_NODELETE;
-+ else if (strcmp (optarg, "nodlopen") == 0)
-+ link_info.flags_1 |= (bfd_vma) DF_1_NOOPEN;
-+ else if (strcmp (optarg, "nodump") == 0)
-+ link_info.flags_1 |= (bfd_vma) DF_1_NODUMP;
-+ else if (strcmp (optarg, "now") == 0)
-+ {
-+ link_info.flags |= (bfd_vma) DF_BIND_NOW;
-+ link_info.flags_1 |= (bfd_vma) DF_1_NOW;
-+ }
-+ else if (strcmp (optarg, "lazy") == 0)
-+ {
-+ link_info.flags &= ~(bfd_vma) DF_BIND_NOW;
-+ link_info.flags_1 &= ~(bfd_vma) DF_1_NOW;
-+ }
-+ else if (strcmp (optarg, "origin") == 0)
-+ {
-+ link_info.flags |= (bfd_vma) DF_ORIGIN;
-+ link_info.flags_1 |= (bfd_vma) DF_1_ORIGIN;
-+ }
-+ else if (strcmp (optarg, "combreloc") == 0)
-+ link_info.combreloc = TRUE;
-+ else if (strcmp (optarg, "nocombreloc") == 0)
-+ link_info.combreloc = FALSE;
-+ else if (strcmp (optarg, "nocopyreloc") == 0)
-+ link_info.nocopyreloc = TRUE;
-+ else if (strcmp (optarg, "relro") == 0)
-+ link_info.relro = TRUE;
-+ else if (strcmp (optarg, "norelro") == 0)
-+ link_info.relro = FALSE;
-+ else if (strcmp (optarg, "text") == 0)
-+ link_info.error_textrel = TRUE;
-+ else if (strcmp (optarg, "notext") == 0)
-+ link_info.error_textrel = FALSE;
-+ else if (strcmp (optarg, "textoff") == 0)
-+ link_info.error_textrel = FALSE;
-+EOF
-+fi
-+
-+fragment <<EOF
-+ else
-+ einfo (_("%P: warning: -z %s ignored.\n"), optarg);
-+ break;
-+EOF
-+
-+if test -n "$PARSE_AND_LIST_ARGS_CASES" ; then
-+fragment <<EOF
-+ $PARSE_AND_LIST_ARGS_CASES
-+EOF
-+fi
-+
-+fragment <<EOF
-+ }
-+
-+ return TRUE;
-+}
-+
-+EOF
-+
-+if test x"$LDEMUL_LIST_OPTIONS" != xgld"$EMULATION_NAME"_list_options; then
-+fragment <<EOF
-+
-+static void
-+gld${EMULATION_NAME}_list_options (FILE * file)
-+{
-+EOF
-+if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
-+fragment <<EOF
-+ fprintf (file, _("\
-+ --audit=AUDITLIB Specify a library to use for auditing\n"));
-+ fprintf (file, _("\
-+ -Bgroup Selects group name lookup rules for DSO\n"));
-+EOF
-+fi
-+fragment <<EOF
-+ fprintf (file, _("\
-+ --build-id[=STYLE] Generate build ID note\n"));
-+EOF
-+if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
-+fragment <<EOF
-+ fprintf (file, _("\
-+ -P AUDITLIB, --depaudit=AUDITLIB\n" "\
-+ Specify a library to use for auditing dependencies\n"));
-+ fprintf (file, _("\
-+ --disable-new-dtags Disable new dynamic tags\n"));
-+ fprintf (file, _("\
-+ --enable-new-dtags Enable new dynamic tags\n"));
-+ fprintf (file, _("\
-+ --eh-frame-hdr Create .eh_frame_hdr section\n"));
-+ fprintf (file, _("\
-+ --exclude-libs=LIBS Make all symbols in LIBS hidden\n"));
-+ fprintf (file, _("\
-+ --hash-style=STYLE Set hash style to sysv, gnu or both\n"));
-+ fprintf (file, _("\
-+ -z combreloc Merge dynamic relocs into one section and sort\n"));
-+EOF
-+fi
-+
-+fragment <<EOF
-+ fprintf (file, _("\
-+ -z common-page-size=SIZE Set common page size to SIZE\n"));
-+ fprintf (file, _("\
-+ -z defs Report unresolved symbols in object files.\n"));
-+ fprintf (file, _("\
-+ -z execstack Mark executable as requiring executable stack\n"));
-+EOF
-+
-+if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
-+fragment <<EOF
-+ fprintf (file, _("\
-+ -z initfirst Mark DSO to be initialized first at runtime\n"));
-+ fprintf (file, _("\
-+ -z interpose Mark object to interpose all DSOs but executable\n"));
-+ fprintf (file, _("\
-+ -z lazy Mark object lazy runtime binding (default)\n"));
-+ fprintf (file, _("\
-+ -z loadfltr Mark object requiring immediate process\n"));
-+EOF
-+fi
-+
-+fragment <<EOF
-+ fprintf (file, _("\
-+ -z max-page-size=SIZE Set maximum page size to SIZE\n"));
-+ fprintf (file, _("\
-+ -z muldefs Allow multiple definitions\n"));
-+EOF
-+
-+if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
-+fragment <<EOF
-+ fprintf (file, _("\
-+ -z nocombreloc Don't merge dynamic relocs into one section\n"));
-+ fprintf (file, _("\
-+ -z nocopyreloc Don't create copy relocs\n"));
-+ fprintf (file, _("\
-+ -z nodefaultlib Mark object not to use default search paths\n"));
-+ fprintf (file, _("\
-+ -z nodelete Mark DSO non-deletable at runtime\n"));
-+ fprintf (file, _("\
-+ -z nodlopen Mark DSO not available to dlopen\n"));
-+ fprintf (file, _("\
-+ -z nodump Mark DSO not available to dldump\n"));
-+EOF
-+fi
-+fragment <<EOF
-+ fprintf (file, _("\
-+ -z noexecstack Mark executable as not requiring executable stack\n"));
-+EOF
-+if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
-+fragment <<EOF
-+ fprintf (file, _("\
-+ -z norelro Don't create RELRO program header\n"));
-+ fprintf (file, _("\
-+ -z now Mark object non-lazy runtime binding\n"));
-+ fprintf (file, _("\
-+ -z origin Mark object requiring immediate \$ORIGIN\n\
-+ processing at runtime\n"));
-+ fprintf (file, _("\
-+ -z relro Create RELRO program header\n"));
-+EOF
-+fi
-+
-+if test -n "$PARSE_AND_LIST_OPTIONS" ; then
-+fragment <<EOF
-+ $PARSE_AND_LIST_OPTIONS
-+EOF
-+fi
-+
-+fragment <<EOF
-+}
-+EOF
-+
-+if test -n "$PARSE_AND_LIST_EPILOGUE" ; then
-+fragment <<EOF
-+ $PARSE_AND_LIST_EPILOGUE
-+EOF
-+fi
-+fi
-+
-+fragment <<EOF
-+
-+struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
-+{
-+ ${LDEMUL_BEFORE_PARSE-gld${EMULATION_NAME}_before_parse},
-+ ${LDEMUL_SYSLIB-syslib_default},
-+ ${LDEMUL_HLL-hll_default},
-+ ${LDEMUL_AFTER_PARSE-after_parse_default},
-+ ${LDEMUL_AFTER_OPEN-gld${EMULATION_NAME}_after_open},
-+ ${LDEMUL_AFTER_ALLOCATION-gld${EMULATION_NAME}_after_allocation},
-+ ${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default},
-+ ${LDEMUL_CHOOSE_TARGET-ldemul_default_target},
-+ ${LDEMUL_BEFORE_ALLOCATION-gld${EMULATION_NAME}_before_allocation},
-+ ${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script},
-+ "${EMULATION_NAME}",
-+ "${OUTPUT_FORMAT}",
-+ ${LDEMUL_FINISH-finish_default},
-+ ${LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS-NULL},
-+ ${LDEMUL_OPEN_DYNAMIC_ARCHIVE-gld${EMULATION_NAME}_open_dynamic_archive},
-+ ${LDEMUL_PLACE_ORPHAN-gld${EMULATION_NAME}_place_orphan},
-+ ${LDEMUL_SET_SYMBOLS-NULL},
-+ ${LDEMUL_PARSE_ARGS-NULL},
-+ gld${EMULATION_NAME}_add_options,
-+ gld${EMULATION_NAME}_handle_option,
-+ ${LDEMUL_UNRECOGNIZED_FILE-NULL},
-+ ${LDEMUL_LIST_OPTIONS-gld${EMULATION_NAME}_list_options},
-+ ${LDEMUL_RECOGNIZED_FILE-gld${EMULATION_NAME}_load_symbols},
-+ ${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL},
-+ ${LDEMUL_NEW_VERS_PATTERN-NULL}
-+};
-+EOF
-