powerpc gold, work around pr17670
[platform/upstream/binutils.git] / bfd / elf32-bfin.c
index 647087a..692875b 100644 (file)
@@ -1,5 +1,5 @@
 /* ADI Blackfin BFD support for 32-bit ELF.
-   Copyright 2005, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2005-2014 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -23,7 +23,7 @@
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "elf/bfin.h"
-#include "elf/dwarf2.h"
+#include "dwarf2.h"
 #include "hashtab.h"
 
 /* FUNCTION : bfin_pltpc_reloc
@@ -33,7 +33,7 @@ bfin_pltpc_reloc (
      bfd *abfd ATTRIBUTE_UNUSED,
      arelent *reloc_entry ATTRIBUTE_UNUSED,
      asymbol *symbol ATTRIBUTE_UNUSED,
-     PTR data ATTRIBUTE_UNUSED,
+     void * data ATTRIBUTE_UNUSED,
      asection *input_section ATTRIBUTE_UNUSED,
      bfd *output_bfd ATTRIBUTE_UNUSED,
      char **error_message ATTRIBUTE_UNUSED)
@@ -47,7 +47,7 @@ static bfd_reloc_status_type
 bfin_pcrel24_reloc (bfd *abfd,
                     arelent *reloc_entry,
                     asymbol *symbol,
-                    PTR data,
+                    void * data,
                     asection *input_section,
                     bfd *output_bfd,
                     char **error_message ATTRIBUTE_UNUSED)
@@ -103,7 +103,7 @@ bfin_pcrel24_reloc (bfd *abfd,
   /* if rightshift is 1 and the number odd, return error.  */
   if (howto->rightshift && (relocation & 0x01))
     {
-      fprintf(stderr, "relocation should be even number\n");
+      (*_bfd_error_handler) (_("relocation should be even number"));
       return bfd_reloc_overflow;
     }
 
@@ -144,7 +144,7 @@ static bfd_reloc_status_type
 bfin_imm16_reloc (bfd *abfd,
                  arelent *reloc_entry,
                  asymbol *symbol,
-                 PTR data,
+                 void * data,
                  asection *input_section,
                  bfd *output_bfd,
                  char **error_message ATTRIBUTE_UNUSED)
@@ -216,7 +216,7 @@ static bfd_reloc_status_type
 bfin_byte4_reloc (bfd *abfd,
                   arelent *reloc_entry,
                   asymbol *symbol,
-                  PTR data,
+                  void * data,
                   asection *input_section,
                   bfd *output_bfd,
                   char **error_message ATTRIBUTE_UNUSED)
@@ -282,7 +282,7 @@ static bfd_reloc_status_type
 bfin_bfd_reloc (bfd *abfd,
                arelent *reloc_entry,
                asymbol *symbol,
-               PTR data,
+               void * data,
                asection *input_section,
                bfd *output_bfd,
                char **error_message ATTRIBUTE_UNUSED)
@@ -359,7 +359,7 @@ bfin_bfd_reloc (bfd *abfd,
   /* If rightshift is 1 and the number odd, return error.  */
   if (howto->rightshift && (relocation & 0x01))
     {
-      fprintf(stderr, "relocation should be even number\n");
+      (*_bfd_error_handler) (_("relocation should be even number"));
       return bfd_reloc_overflow;
     }
 
@@ -421,7 +421,7 @@ bfin_bfd_reloc (bfd *abfd,
 static reloc_howto_type bfin_howto_table [] =
 {
   /* This reloc does nothing. .  */
-  HOWTO (R_unused0,            /* type.  */
+  HOWTO (R_BFIN_UNUSED0,       /* type.  */
         0,                     /* rightshift.  */
         2,                     /* size (0 = byte, 1 = short, 2 = long).  */
         32,                    /* bitsize.  */
@@ -429,13 +429,13 @@ static reloc_howto_type bfin_howto_table [] =
         0,                     /* bitpos.  */
         complain_overflow_bitfield, /* complain_on_overflow.  */
         bfd_elf_generic_reloc, /* special_function.  */
-        "R_unused0",           /* name.  */
+        "R_BFIN_UNUSED0",      /* name.  */
         FALSE,                 /* partial_inplace.  */
         0,                     /* src_mask.  */
         0,                     /* dst_mask.  */
         FALSE),                /* pcrel_offset.  */
 
-  HOWTO (R_pcrel5m2,           /* type.  */
+  HOWTO (R_BFIN_PCREL5M2,      /* type.  */
         1,                     /* rightshift.  */
         1,                     /* size (0 = byte, 1 = short, 2 = long)..  */
         4,                     /* bitsize.  */
@@ -443,13 +443,13 @@ static reloc_howto_type bfin_howto_table [] =
         0,                     /* bitpos.  */
         complain_overflow_unsigned, /* complain_on_overflow.  */
         bfin_bfd_reloc,        /* special_function.  */
-        "R_pcrel5m2",          /* name.  */
+        "R_BFIN_PCREL5M2",     /* name.  */
         FALSE,                 /* partial_inplace.  */
         0,                     /* src_mask.  */
         0x0000000F,            /* dst_mask.  */
         FALSE),                /* pcrel_offset.  */
 
-  HOWTO (R_unused1,            /* type.  */
+  HOWTO (R_BFIN_UNUSED1,       /* type.  */
         0,                     /* rightshift.  */
         2,                     /* size (0 = byte, 1 = short, 2 = long).  */
         32,                    /* bitsize.  */
@@ -457,13 +457,13 @@ static reloc_howto_type bfin_howto_table [] =
         0,                     /* bitpos.  */
         complain_overflow_bitfield, /* complain_on_overflow.  */
         bfd_elf_generic_reloc, /* special_function.  */
-        "R_unused1",           /* name.  */
+        "R_BFIN_UNUSED1",      /* name.  */
         FALSE,                 /* partial_inplace.  */
         0,                     /* src_mask.  */
         0,                     /* dst_mask.  */
         FALSE),                /* pcrel_offset.  */
 
-  HOWTO (R_pcrel10,            /* type.  */
+  HOWTO (R_BFIN_PCREL10,       /* type.  */
         1,                     /* rightshift.  */
         1,                     /* size (0 = byte, 1 = short, 2 = long).  */
         10,                    /* bitsize.  */
@@ -471,13 +471,13 @@ static reloc_howto_type bfin_howto_table [] =
         0,                     /* bitpos.  */
         complain_overflow_signed, /* complain_on_overflow.  */
         bfin_bfd_reloc,        /* special_function.  */
-        "R_pcrel10",           /* name.  */
+        "R_BFIN_PCREL10",      /* name.  */
         FALSE,                 /* partial_inplace.  */
         0,                     /* src_mask.  */
         0x000003FF,            /* dst_mask.  */
         TRUE),                 /* pcrel_offset.  */
 
-  HOWTO (R_pcrel12_jump,       /* type.  */
+  HOWTO (R_BFIN_PCREL12_JUMP,  /* type.  */
         1,                     /* rightshift.  */
                                /* the offset is actually 13 bit
                                   aligned on a word boundary so
@@ -489,13 +489,13 @@ static reloc_howto_type bfin_howto_table [] =
         0,                     /* bitpos.  */
         complain_overflow_signed, /* complain_on_overflow.  */
         bfin_bfd_reloc,        /* special_function.  */
-        "R_pcrel12_jump",      /* name.  */
+        "R_BFIN_PCREL12_JUMP", /* name.  */
         FALSE,                 /* partial_inplace.  */
         0,                     /* src_mask.  */
         0x0FFF,                /* dst_mask.  */
         TRUE),                 /* pcrel_offset.  */
 
-  HOWTO (R_rimm16,             /* type.  */
+  HOWTO (R_BFIN_RIMM16,                /* type.  */
         0,                     /* rightshift.  */
         1,                     /* size (0 = byte, 1 = short, 2 = long).  */
         16,                    /* bitsize.  */
@@ -503,13 +503,13 @@ static reloc_howto_type bfin_howto_table [] =
         0,                     /* bitpos.  */
         complain_overflow_signed, /* complain_on_overflow.  */
         bfin_imm16_reloc,      /* special_function.  */
-        "R_rimm16",            /* name.  */
+        "R_BFIN_RIMM16",       /* name.  */
         FALSE,                 /* partial_inplace.  */
         0,                     /* src_mask.  */
         0x0000FFFF,            /* dst_mask.  */
         TRUE),                 /* pcrel_offset.  */
 
-  HOWTO (R_luimm16,            /* type.  */
+  HOWTO (R_BFIN_LUIMM16,       /* type.  */
         0,                     /* rightshift.  */
         1,                     /* size (0 = byte, 1 = short, 2 = long).  */
         16,                    /* bitsize.  */
@@ -517,13 +517,13 @@ static reloc_howto_type bfin_howto_table [] =
         0,                     /* bitpos.  */
         complain_overflow_dont, /* complain_on_overflow.  */
         bfin_imm16_reloc,      /* special_function.  */
-        "R_luimm16",           /* name.  */
+        "R_BFIN_LUIMM16",      /* name.  */
         FALSE,                 /* partial_inplace.  */
         0,                     /* src_mask.  */
         0x0000FFFF,            /* dst_mask.  */
         TRUE),                 /* pcrel_offset.  */
 
-  HOWTO (R_huimm16,            /* type.  */
+  HOWTO (R_BFIN_HUIMM16,       /* type.  */
         16,                    /* rightshift.  */
         1,                     /* size (0 = byte, 1 = short, 2 = long).  */
         16,                    /* bitsize.  */
@@ -531,13 +531,13 @@ static reloc_howto_type bfin_howto_table [] =
         0,                     /* bitpos.  */
         complain_overflow_unsigned, /* complain_on_overflow.  */
         bfin_imm16_reloc,      /* special_function.  */
-        "R_huimm16",           /* name.  */
+        "R_BFIN_HUIMM16",      /* name.  */
         FALSE,                 /* partial_inplace.  */
         0,                     /* src_mask.  */
         0x0000FFFF,            /* dst_mask.  */
         TRUE),                 /* pcrel_offset.  */
 
-  HOWTO (R_pcrel12_jump_s,     /* type.  */
+  HOWTO (R_BFIN_PCREL12_JUMP_S,        /* type.  */
         1,                     /* rightshift.  */
         1,                     /* size (0 = byte, 1 = short, 2 = long).  */
         12,                    /* bitsize.  */
@@ -545,13 +545,13 @@ static reloc_howto_type bfin_howto_table [] =
         0,                     /* bitpos.  */
         complain_overflow_signed, /* complain_on_overflow.  */
         bfin_bfd_reloc,        /* special_function.  */
-        "R_pcrel12_jump_s",    /* name.  */
+        "R_BFIN_PCREL12_JUMP_S", /* name.  */
         FALSE,                 /* partial_inplace.  */
         0,                     /* src_mask.  */
         0x00000FFF,            /* dst_mask.  */
         TRUE),                 /* pcrel_offset.  */
 
-  HOWTO (R_pcrel24_jump_x,     /* type.  */
+  HOWTO (R_BFIN_PCREL24_JUMP_X,        /* type.  */
          1,                    /* rightshift.  */
          2,                    /* size (0 = byte, 1 = short, 2 = long).  */
          24,                   /* bitsize.  */
@@ -559,13 +559,13 @@ static reloc_howto_type bfin_howto_table [] =
          0,                    /* bitpos.  */
          complain_overflow_signed, /* complain_on_overflow.  */
          bfin_pcrel24_reloc,   /* special_function.  */
-         "R_pcrel24_jump_x",   /* name.  */
+       "R_BFIN_PCREL24_JUMP_X", /* name.  */
         FALSE,                 /* partial_inplace.  */
         0,                     /* src_mask.  */
         0x00FFFFFF,            /* dst_mask.  */
         TRUE),                 /* pcrel_offset.  */
 
-  HOWTO (R_pcrel24,            /* type.  */
+  HOWTO (R_BFIN_PCREL24,       /* type.  */
         1,                     /* rightshift.  */
         2,                     /* size (0 = byte, 1 = short, 2 = long).  */
         24,                    /* bitsize.  */
@@ -573,13 +573,13 @@ static reloc_howto_type bfin_howto_table [] =
         0,                     /* bitpos.  */
         complain_overflow_signed, /* complain_on_overflow.  */
         bfin_pcrel24_reloc,    /* special_function.  */
-        "R_pcrel24",           /* name.  */
+        "R_BFIN_PCREL24",      /* name.  */
         FALSE,                 /* partial_inplace.  */
         0,                     /* src_mask.  */
         0x00FFFFFF,            /* dst_mask.  */
         TRUE),                 /* pcrel_offset.  */
 
-  HOWTO (R_unusedb,            /* type.  */
+  HOWTO (R_BFIN_UNUSEDB,       /* type.  */
         0,                     /* rightshift.  */
         2,                     /* size (0 = byte, 1 = short, 2 = long).  */
         32,                    /* bitsize.  */
@@ -587,13 +587,13 @@ static reloc_howto_type bfin_howto_table [] =
         0,                     /* bitpos.  */
         complain_overflow_dont, /* complain_on_overflow.  */
         bfd_elf_generic_reloc, /* special_function.  */
-        "R_unusedb",           /* name.  */
+        "R_BFIN_UNUSEDB",      /* name.  */
         FALSE,                 /* partial_inplace.  */
         0,                     /* src_mask.  */
         0,                     /* dst_mask.  */
         FALSE),                /* pcrel_offset.  */
 
-  HOWTO (R_unusedc,            /* type.  */
+  HOWTO (R_BFIN_UNUSEDC,       /* type.  */
         0,                     /* rightshift.  */
         2,                     /* size (0 = byte, 1 = short, 2 = long).  */
         32,                    /* bitsize.  */
@@ -601,13 +601,13 @@ static reloc_howto_type bfin_howto_table [] =
         0,                     /* bitpos.  */
         complain_overflow_dont, /* complain_on_overflow.  */
         bfd_elf_generic_reloc, /* special_function.  */
-        "R_unusedc",           /* name.  */
+        "R_BFIN_UNUSEDC",      /* name.  */
         FALSE,                 /* partial_inplace.  */
         0,                     /* src_mask.  */
         0,                     /* dst_mask.  */
         FALSE),                /* pcrel_offset.  */
 
-  HOWTO (R_pcrel24_jump_l,     /* type.  */
+  HOWTO (R_BFIN_PCREL24_JUMP_L,        /* type.  */
         1,                     /* rightshift.  */
         2,                     /* size (0 = byte, 1 = short, 2 = long).  */
         24,                    /* bitsize.  */
@@ -615,13 +615,13 @@ static reloc_howto_type bfin_howto_table [] =
         0,                     /* bitpos.  */
         complain_overflow_signed, /* complain_on_overflow.  */
         bfin_pcrel24_reloc,    /* special_function.  */
-        "R_pcrel24_jump_l",    /* name.  */
+        "R_BFIN_PCREL24_JUMP_L", /* name.  */
         FALSE,                 /* partial_inplace.  */
         0,                     /* src_mask.  */
         0x00FFFFFF,            /* dst_mask.  */
         TRUE),                 /* pcrel_offset.  */
 
-  HOWTO (R_pcrel24_call_x,     /* type.  */
+  HOWTO (R_BFIN_PCREL24_CALL_X,        /* type.  */
         1,                     /* rightshift.  */
         2,                     /* size (0 = byte, 1 = short, 2 = long).  */
         24,                    /* bitsize.  */
@@ -629,13 +629,13 @@ static reloc_howto_type bfin_howto_table [] =
         0,                     /* bitpos.  */
         complain_overflow_signed, /* complain_on_overflow.  */
         bfin_pcrel24_reloc,    /* special_function.  */
-        "R_pcrel24_call_x",    /* name.  */
+        "R_BFIN_PCREL24_CALL_X", /* name.  */
         FALSE,                 /* partial_inplace.  */
         0,                     /* src_mask.  */
         0x00FFFFFF,            /* dst_mask.  */
         TRUE),                 /* pcrel_offset.  */
 
-  HOWTO (R_var_eq_symb,                /* type.  */
+  HOWTO (R_BFIN_VAR_EQ_SYMB,   /* type.  */
         0,                     /* rightshift.  */
         2,                     /* size (0 = byte, 1 = short, 2 = long).  */
         32,                    /* bitsize.  */
@@ -643,13 +643,13 @@ static reloc_howto_type bfin_howto_table [] =
         0,                     /* bitpos.  */
         complain_overflow_bitfield, /* complain_on_overflow.  */
         bfin_bfd_reloc,        /* special_function.  */
-        "R_var_eq_symb",               /* name.  */
+        "R_BFIN_VAR_EQ_SYMB",  /* name.  */
         FALSE,                 /* partial_inplace.  */
         0,                     /* src_mask.  */
         0,                     /* dst_mask.  */
         FALSE),                /* pcrel_offset.  */
 
-  HOWTO (R_byte_data,          /* type.  */
+  HOWTO (R_BFIN_BYTE_DATA,     /* type.  */
         0,                     /* rightshift.  */
         0,                     /* size (0 = byte, 1 = short, 2 = long).  */
         8,                     /* bitsize.  */
@@ -657,13 +657,13 @@ static reloc_howto_type bfin_howto_table [] =
         0,                     /* bitpos.  */
         complain_overflow_unsigned, /* complain_on_overflow.  */
         bfin_bfd_reloc,        /* special_function.  */
-        "R_byte_data",         /* name.  */
+        "R_BFIN_BYTE_DATA",    /* name.  */
         FALSE,                 /* partial_inplace.  */
         0,                     /* src_mask.  */
         0xFF,                  /* dst_mask.  */
         TRUE),                 /* pcrel_offset.  */
 
-  HOWTO (R_byte2_data,         /* type.  */
+  HOWTO (R_BFIN_BYTE2_DATA,    /* type.  */
         0,                     /* rightshift.  */
         1,                     /* size (0 = byte, 1 = short, 2 = long).  */
         16,                    /* bitsize.  */
@@ -671,13 +671,13 @@ static reloc_howto_type bfin_howto_table [] =
         0,                     /* bitpos.  */
         complain_overflow_signed, /* complain_on_overflow.  */
         bfin_bfd_reloc,        /* special_function.  */
-        "R_byte2_data",        /* name.  */
+        "R_BFIN_BYTE2_DATA",   /* name.  */
         FALSE,                 /* partial_inplace.  */
         0,                     /* src_mask.  */
         0xFFFF,                /* dst_mask.  */
         TRUE),                 /* pcrel_offset.  */
 
-  HOWTO (R_byte4_data,         /* type.  */
+  HOWTO (R_BFIN_BYTE4_DATA,    /* type.  */
         0,                     /* rightshift.  */
         2,                     /* size (0 = byte, 1 = short, 2 = long).  */
         32,                    /* bitsize.  */
@@ -685,13 +685,13 @@ static reloc_howto_type bfin_howto_table [] =
         0,                     /* bitpos.  */
         complain_overflow_unsigned, /* complain_on_overflow.  */
         bfin_byte4_reloc,      /* special_function.  */
-        "R_byte4_data",        /* name.  */
+        "R_BFIN_BYTE4_DATA",   /* name.  */
         FALSE,                 /* partial_inplace.  */
         0,                     /* src_mask.  */
         0xFFFFFFFF,            /* dst_mask.  */
         TRUE),                 /* pcrel_offset.  */
 
-  HOWTO (R_pcrel11,            /* type.  */
+  HOWTO (R_BFIN_PCREL11,       /* type.  */
         1,                     /* rightshift.  */
         1,                     /* size (0 = byte, 1 = short, 2 = long).  */
         10,                    /* bitsize.  */
@@ -699,7 +699,7 @@ static reloc_howto_type bfin_howto_table [] =
         0,                     /* bitpos.  */
         complain_overflow_unsigned, /* complain_on_overflow.  */
         bfin_bfd_reloc,        /* special_function.  */
-        "R_pcrel11",           /* name.  */
+        "R_BFIN_PCREL11",      /* name.  */
         FALSE,                 /* partial_inplace.  */
         0,                     /* src_mask.  */
         0x000003FF,            /* dst_mask.  */
@@ -931,7 +931,7 @@ static reloc_howto_type bfin_howto_table [] =
 
 static reloc_howto_type bfin_gnuext_howto_table [] =
 {
-  HOWTO (R_pltpc,              /* type.  */
+  HOWTO (R_BFIN_PLTPC,         /* type.  */
         0,                     /* rightshift.  */
         1,                     /* size (0 = byte, 1 = short, 2 = long).  */
         16,                    /* bitsize.  */
@@ -939,13 +939,13 @@ static reloc_howto_type bfin_gnuext_howto_table [] =
         0,                     /* bitpos.  */
         complain_overflow_bitfield, /* complain_on_overflow.  */
         bfin_pltpc_reloc,      /* special_function.  */
-        "R_pltpc",             /* name.  */
+        "R_BFIN_PLTPC",        /* name.  */
         FALSE,                 /* partial_inplace.  */
         0xffff,                /* src_mask.  */
         0xffff,                /* dst_mask.  */
         FALSE),                /* pcrel_offset.  */
 
-  HOWTO (R_got,                        /* type.  */
+  HOWTO (R_BFIN_GOT,           /* type.  */
         0,                     /* rightshift.  */
         1,                     /* size (0 = byte, 1 = short, 2 = long).  */
         16,                    /* bitsize.  */
@@ -953,7 +953,7 @@ static reloc_howto_type bfin_gnuext_howto_table [] =
         0,                     /* bitpos.  */
         complain_overflow_bitfield, /* complain_on_overflow.  */
         bfd_elf_generic_reloc, /* special_function.  */
-        "R_got",               /* name.  */
+        "R_BFIN_GOT",          /* name.  */
         FALSE,                 /* partial_inplace.  */
         0x7fff,                /* src_mask.  */
         0x7fff,                /* dst_mask.  */
@@ -998,27 +998,27 @@ struct bfin_reloc_map
 
 static const struct bfin_reloc_map bfin_reloc_map [] =
 {
-  { BFD_RELOC_NONE,                    R_unused0 },
-  { BFD_RELOC_BFIN_5_PCREL,            R_pcrel5m2 },
-  { BFD_RELOC_NONE,                    R_unused1 },
-  { BFD_RELOC_BFIN_10_PCREL,           R_pcrel10 },
-  { BFD_RELOC_BFIN_12_PCREL_JUMP,      R_pcrel12_jump },
-  { BFD_RELOC_BFIN_16_IMM,             R_rimm16 },
-  { BFD_RELOC_BFIN_16_LOW,             R_luimm16 },
-  { BFD_RELOC_BFIN_16_HIGH,            R_huimm16 },
-  { BFD_RELOC_BFIN_12_PCREL_JUMP_S,    R_pcrel12_jump_s },
-  { BFD_RELOC_24_PCREL,                        R_pcrel24 },
-  { BFD_RELOC_24_PCREL,                        R_pcrel24 },
-  { BFD_RELOC_BFIN_24_PCREL_JUMP_L,    R_pcrel24_jump_l },
-  { BFD_RELOC_NONE,                    R_unusedb },
-  { BFD_RELOC_NONE,                    R_unusedc },
-  { BFD_RELOC_BFIN_24_PCREL_CALL_X,    R_pcrel24_call_x },
-  { BFD_RELOC_8,                       R_byte_data },
-  { BFD_RELOC_16,                      R_byte2_data },
-  { BFD_RELOC_32,                      R_byte4_data },
-  { BFD_RELOC_BFIN_11_PCREL,           R_pcrel11 },
-  { BFD_RELOC_BFIN_GOT,                        R_got },
-  { BFD_RELOC_BFIN_PLTPC,              R_pltpc },
+  { BFD_RELOC_NONE,                    R_BFIN_UNUSED0 },
+  { BFD_RELOC_BFIN_5_PCREL,            R_BFIN_PCREL5M2 },
+  { BFD_RELOC_NONE,                    R_BFIN_UNUSED1 },
+  { BFD_RELOC_BFIN_10_PCREL,           R_BFIN_PCREL10 },
+  { BFD_RELOC_BFIN_12_PCREL_JUMP,      R_BFIN_PCREL12_JUMP },
+  { BFD_RELOC_BFIN_16_IMM,             R_BFIN_RIMM16 },
+  { BFD_RELOC_BFIN_16_LOW,             R_BFIN_LUIMM16 },
+  { BFD_RELOC_BFIN_16_HIGH,            R_BFIN_HUIMM16 },
+  { BFD_RELOC_BFIN_12_PCREL_JUMP_S,    R_BFIN_PCREL12_JUMP_S },
+  { BFD_RELOC_24_PCREL,                        R_BFIN_PCREL24 },
+  { BFD_RELOC_24_PCREL,                        R_BFIN_PCREL24 },
+  { BFD_RELOC_BFIN_24_PCREL_JUMP_L,    R_BFIN_PCREL24_JUMP_L },
+  { BFD_RELOC_NONE,                    R_BFIN_UNUSEDB },
+  { BFD_RELOC_NONE,                    R_BFIN_UNUSEDC },
+  { BFD_RELOC_BFIN_24_PCREL_CALL_X,    R_BFIN_PCREL24_CALL_X },
+  { BFD_RELOC_8,                       R_BFIN_BYTE_DATA },
+  { BFD_RELOC_16,                      R_BFIN_BYTE2_DATA },
+  { BFD_RELOC_32,                      R_BFIN_BYTE4_DATA },
+  { BFD_RELOC_BFIN_11_PCREL,           R_BFIN_PCREL11 },
+  { BFD_RELOC_BFIN_GOT,                        R_BFIN_GOT },
+  { BFD_RELOC_BFIN_PLTPC,              R_BFIN_PLTPC },
 
   { BFD_RELOC_BFIN_GOT17M4,      R_BFIN_GOT17M4 },
   { BFD_RELOC_BFIN_GOTHI,      R_BFIN_GOTHI },
@@ -1108,7 +1108,7 @@ bfin_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
 /* Given a bfin relocation type, return the howto.  */
 static reloc_howto_type *
 bfin_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
-                           unsigned int r_type)
+                       unsigned int r_type)
 {
   if (r_type <= BFIN_RELOC_MAX)
     return &bfin_howto_table [r_type];
@@ -1119,12 +1119,26 @@ bfin_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
   return (reloc_howto_type *) NULL;
 }
 
+/* Set by ld emulation if --code-in-l1.  */
+bfd_boolean elf32_bfin_code_in_l1 = 0;
+
+/* Set by ld emulation if --data-in-l1.  */
+bfd_boolean elf32_bfin_data_in_l1 = 0;
+
+static void
+elf32_bfin_final_write_processing (bfd *abfd,
+                                  bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+  if (elf32_bfin_code_in_l1)
+    elf_elfheader (abfd)->e_flags |= EF_BFIN_CODE_IN_L1;
+  if (elf32_bfin_data_in_l1)
+    elf_elfheader (abfd)->e_flags |= EF_BFIN_DATA_IN_L1;
+}
+
 /* Return TRUE if the name is a local label.
    bfin local labels begin with L$.  */
 static bfd_boolean
-bfin_is_local_label_name (
-     bfd *abfd,
-     const char *label)
+bfin_is_local_label_name (bfd *abfd, const char *label)
 {
   if (label[0] == 'L' && label[1] == '$' )
     return TRUE;
@@ -1150,6 +1164,7 @@ bfin_check_relocs (bfd * abfd,
   const Elf_Internal_Rela *rel_end;
   asection *sgot;
   asection *srelgot;
+
   if (info->relocatable)
     return TRUE;
 
@@ -1171,7 +1186,13 @@ bfin_check_relocs (bfd * abfd,
       if (r_symndx < symtab_hdr->sh_info)
        h = NULL;
       else
-       h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+       {
+         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
+         /* PR15323, ref flags aren't set for references in the same
+            object.  */
+         h->root.non_ir_ref = 1;
+       }
 
       switch (ELF32_R_TYPE (rel->r_info))
        {
@@ -1191,7 +1212,7 @@ bfin_check_relocs (bfd * abfd,
             return FALSE;
           break;
 
-       case R_got:
+       case R_BFIN_GOT:
          if (h != NULL
              && strcmp (h->root.root.string, "__GLOBAL_OFFSET_TABLE_") == 0)
            break;
@@ -1207,20 +1228,21 @@ bfin_check_relocs (bfd * abfd,
 
          if (sgot == NULL)
            {
-             sgot = bfd_get_section_by_name (dynobj, ".got");
+             sgot = bfd_get_linker_section (dynobj, ".got");
              BFD_ASSERT (sgot != NULL);
            }
 
          if (srelgot == NULL && (h != NULL || info->shared))
            {
-             srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+             srelgot = bfd_get_linker_section (dynobj, ".rela.got");
              if (srelgot == NULL)
                {
                  flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
                                    | SEC_IN_MEMORY | SEC_LINKER_CREATED
                                    | SEC_READONLY);
-                 srelgot = bfd_make_section_with_flags (dynobj, ".rela.got",
-                                                        flags);
+                 srelgot = bfd_make_section_anyway_with_flags (dynobj,
+                                                               ".rela.got",
+                                                               flags);
                  if (srelgot == NULL
                      || !bfd_set_section_alignment (dynobj, srelgot, 2))
                    return FALSE;
@@ -1284,7 +1306,9 @@ bfin_check_relocs (bfd * abfd,
 }
 
 static enum elf_reloc_type_class
-elf32_bfin_reloc_type_class (const Elf_Internal_Rela * rela)
+elf32_bfin_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                            const asection *rel_sec ATTRIBUTE_UNUSED,
+                            const Elf_Internal_Rela * rela)
 {
   switch ((int) ELF32_R_TYPE (rela->r_info))
     {
@@ -1301,7 +1325,7 @@ bfin_final_link_relocate (Elf_Internal_Rela *rel, reloc_howto_type *howto,
 {
   int r_type = ELF32_R_TYPE (rel->r_info);
 
-  if (r_type == R_pcrel24 || r_type == R_pcrel24_jump_l)
+  if (r_type == R_BFIN_PCREL24 || r_type == R_BFIN_PCREL24_JUMP_L)
     {
       bfd_reloc_status_type r = bfd_reloc_ok;
       bfd_vma x;
@@ -1419,24 +1443,17 @@ bfin_relocate_section (bfd * output_bfd,
        }
       else
        {
-         bfd_boolean warned;
+         bfd_boolean warned, ignored;
 
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
                                   r_symndx, symtab_hdr, sym_hashes,
                                   h, sec, relocation,
-                                  unresolved_reloc, warned);
+                                  unresolved_reloc, warned, ignored);
        }
 
-      if (sec != NULL && elf_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.  */
-         _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
-         rel->r_info = 0;
-         rel->r_addend = 0;
-         continue;
-       }
+      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, 1, relend, howto, 0, contents);
 
       if (info->relocatable)
        continue;
@@ -1450,7 +1467,7 @@ bfin_relocate_section (bfd * output_bfd,
        case R_BFIN_GNU_VTENTRY:
          return bfd_reloc_ok;
 
-       case R_got:
+       case R_BFIN_GOT:
          /* Relocation is to the address of the entry for this symbol
             in the global offset table.  */
          if (h != NULL
@@ -1473,7 +1490,7 @@ bfin_relocate_section (bfd * output_bfd,
 
            if (sgot == NULL)
              {
-               sgot = bfd_get_section_by_name (dynobj, ".got");
+               sgot = bfd_get_linker_section (dynobj, ".got");
                BFD_ASSERT (sgot != NULL);
              }
 
@@ -1537,13 +1554,13 @@ bfin_relocate_section (bfd * output_bfd,
                        Elf_Internal_Rela outrel;
                        bfd_byte *loc;
 
-                       s = bfd_get_section_by_name (dynobj, ".rela.got");
+                       s = bfd_get_linker_section (dynobj, ".rela.got");
                        BFD_ASSERT (s != NULL);
 
                        outrel.r_offset = (sgot->output_section->vma
                                           + sgot->output_offset + off);
                        outrel.r_info =
-                         ELF32_R_INFO (0, R_pcrel24);
+                         ELF32_R_INFO (0, R_BFIN_PCREL24);
                        outrel.r_addend = relocation;
                        loc = s->contents;
                        loc +=
@@ -1575,7 +1592,9 @@ bfin_relocate_section (bfd * output_bfd,
          because such sections are not SEC_ALLOC and thus ld.so will
          not process them.  */
       if (unresolved_reloc
-         && !((input_section->flags & SEC_DEBUGGING) != 0 && h->def_dynamic))
+         && !((input_section->flags & SEC_DEBUGGING) != 0 && h->def_dynamic)
+         && _bfd_elf_section_offset (output_bfd, info, input_section,
+                                     rel->r_offset) != (bfd_vma) -1)
        {
          (*_bfd_error_handler)
            (_("%B(%A+0x%lx): unresolvable relocation against symbol `%s'"),
@@ -1664,8 +1683,8 @@ bfin_gc_sweep_hook (bfd * abfd,
   sym_hashes = elf_sym_hashes (abfd);
   local_got_refcounts = elf_local_got_refcounts (abfd);
 
-  sgot = bfd_get_section_by_name (dynobj, ".got");
-  srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+  sgot = bfd_get_linker_section (dynobj, ".got");
+  srelgot = bfd_get_linker_section (dynobj, ".rela.got");
 
   relend = relocs + sec->reloc_count;
   for (rel = relocs; rel < relend; rel++)
@@ -1675,7 +1694,7 @@ bfin_gc_sweep_hook (bfd * abfd,
 
       switch (ELF32_R_TYPE (rel->r_info))
        {
-       case R_got:
+       case R_BFIN_GOT:
          r_symndx = ELF32_R_SYM (rel->r_info);
          if (r_symndx >= symtab_hdr->sh_info)
            {
@@ -1713,11 +1732,11 @@ bfin_gc_sweep_hook (bfd * abfd,
   return TRUE;
 }
 \f
-extern const bfd_target bfd_elf32_bfinfdpic_vec;
-#define IS_FDPIC(bfd) ((bfd)->xvec == &bfd_elf32_bfinfdpic_vec)
+extern const bfd_target bfin_elf32_fdpic_vec;
+#define IS_FDPIC(bfd) ((bfd)->xvec == &bfin_elf32_fdpic_vec)
 
-/* An extension of the elf hash table data structure, containing some
-   additional Blackfin-specific data.  */
+/* An extension of the elf hash table data structure,
+   containing some additional Blackfin-specific data.  */
 struct bfinfdpic_elf_link_hash_table
 {
   struct elf_link_hash_table elf;
@@ -1740,12 +1759,16 @@ struct bfinfdpic_elf_link_hash_table
   /* A hash table holding information about which symbols were
      referenced with which PIC-related relocations.  */
   struct htab *relocs_info;
+  /* Summary reloc information collected by
+     _bfinfdpic_count_got_plt_entries.  */
+  struct _bfinfdpic_dynamic_got_info *g;
 };
 
 /* Get the Blackfin ELF linker hash table from a link_info structure.  */
 
 #define bfinfdpic_hash_table(info) \
-  ((struct bfinfdpic_elf_link_hash_table *) ((info)->hash))
+  (elf_hash_table_id ((struct elf_link_hash_table *) ((info)->hash)) \
+  == BFIN_ELF_DATA ? ((struct bfinfdpic_elf_link_hash_table *) ((info)->hash)) : NULL)
 
 #define bfinfdpic_got_section(info) \
   (bfinfdpic_hash_table (info)->sgot)
@@ -1763,6 +1786,8 @@ struct bfinfdpic_elf_link_hash_table
   (bfinfdpic_hash_table (info)->got0)
 #define bfinfdpic_plt_initial_offset(info) \
   (bfinfdpic_hash_table (info)->plt0)
+#define bfinfdpic_dynamic_got_plt_info(info) \
+  (bfinfdpic_hash_table (info)->g)
 
 /* The name of the dynamic interpreter.  This is put in the .interp
    section.  */
@@ -1803,13 +1828,14 @@ bfinfdpic_elf_link_hash_table_create (bfd *abfd)
   struct bfinfdpic_elf_link_hash_table *ret;
   bfd_size_type amt = sizeof (struct bfinfdpic_elf_link_hash_table);
 
-  ret = bfd_zalloc (abfd, amt);
+  ret = bfd_zmalloc (amt);
   if (ret == NULL)
     return NULL;
 
   if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
                                      _bfd_elf_link_hash_newfunc,
-                                     sizeof (struct elf_link_hash_entry)))
+                                     sizeof (struct elf_link_hash_entry),
+                                     BFIN_ELF_DATA))
     {
       free (ret);
       return NULL;
@@ -1893,7 +1919,7 @@ struct bfinfdpic_relocs_info
      needed for this symbol.  */
   unsigned done:1;
 
-  /* The number of R_byte4_data, R_BFIN_FUNCDESC and R_BFIN_FUNCDESC_VALUE
+  /* The number of R_BFIN_BYTE4_DATA, R_BFIN_FUNCDESC and R_BFIN_FUNCDESC_VALUE
      relocations referencing the symbol.  */
   unsigned relocs32, relocsfd, relocsfdv;
 
@@ -1945,8 +1971,12 @@ bfinfdpic_relocs_info_find (struct htab *ht,
                           const struct bfinfdpic_relocs_info *entry,
                           enum insert_option insert)
 {
-  struct bfinfdpic_relocs_info **loc =
-    (struct bfinfdpic_relocs_info **) htab_find_slot (ht, entry, insert);
+  struct bfinfdpic_relocs_info **loc;
+
+  if (!ht)
+    return NULL;
+
+  loc = (struct bfinfdpic_relocs_info **) htab_find_slot (ht, entry, insert);
 
   if (! loc)
     return NULL;
@@ -1973,10 +2003,10 @@ bfinfdpic_relocs_info_find (struct htab *ht,
    for memory allocation purposes.  */
 inline static struct bfinfdpic_relocs_info *
 bfinfdpic_relocs_info_for_global (struct htab *ht,
-                                bfd *abfd,
-                                struct elf_link_hash_entry *h,
-                                bfd_vma addend,
-                                enum insert_option insert)
+                                 bfd *abfd,
+                                 struct elf_link_hash_entry *h,
+                                 bfd_vma addend,
+                                 enum insert_option insert)
 {
   struct bfinfdpic_relocs_info entry;
 
@@ -2011,7 +2041,7 @@ bfinfdpic_relocs_info_for_local (struct htab *ht,
 
 inline static void
 bfinfdpic_pic_merge_early_relocs_info (struct bfinfdpic_relocs_info *e2,
-                                     struct bfinfdpic_relocs_info const *e1)
+                                      struct bfinfdpic_relocs_info const *e1)
 {
   e2->got17m4 |= e1->got17m4;
   e2->gothilo |= e1->gothilo;
@@ -2077,7 +2107,7 @@ _bfinfdpic_add_dyn_reloc (bfd *output_bfd, asection *sreloc, bfd_vma offset,
 
 static bfd_vma
 _bfinfdpic_add_rofixup (bfd *output_bfd, asection *rofixup, bfd_vma offset,
-                      struct bfinfdpic_relocs_info *entry)
+                       struct bfinfdpic_relocs_info *entry)
 {
   bfd_vma fixup_offset;
 
@@ -2132,9 +2162,8 @@ _bfinfdpic_emit_got_relocs_plt_entries (struct bfinfdpic_relocs_info *entry,
                                        asection *sec,
                                        Elf_Internal_Sym *sym,
                                        bfd_vma addend)
-
 {
-  bfd_vma fd_lazy_rel_offset = (bfd_vma)-1;
+  bfd_vma fd_lazy_rel_offset = (bfd_vma) -1;
   int dynindx = -1;
 
   if (entry->done)
@@ -2149,7 +2178,8 @@ _bfinfdpic_emit_got_relocs_plt_entries (struct bfinfdpic_relocs_info *entry,
        dynindx = entry->d.h->dynindx;
       else
        {
-         if (sec->output_section
+         if (sec
+             && sec->output_section
              && ! bfd_is_abs_section (sec->output_section)
              && ! bfd_is_und_section (sec->output_section))
            dynindx = elf_section_data (sec->output_section)->dynindx;
@@ -2209,7 +2239,7 @@ _bfinfdpic_emit_got_relocs_plt_entries (struct bfinfdpic_relocs_info *entry,
                                 + bfinfdpic_got_section (info)
                                 ->output_section->vma
                                 + bfinfdpic_got_section (info)->output_offset,
-                                R_byte4_data, idx, ad, entry);
+                                R_BFIN_BYTE4_DATA, idx, ad, entry);
 
       bfd_put_32 (output_bfd, ad,
                  bfinfdpic_got_section (info)->contents
@@ -2261,7 +2291,7 @@ _bfinfdpic_emit_got_relocs_plt_entries (struct bfinfdpic_relocs_info *entry,
                 so reference it directly.  */
              if (elf_hash_table (info)->dynamic_sections_created)
                BFD_ASSERT (entry->privfd);
-             reloc = R_byte4_data;
+             reloc = R_BFIN_BYTE4_DATA;
              idx = elf_section_data (bfinfdpic_got_section (info)
                                      ->output_section)->dynindx;
              ad = bfinfdpic_got_section (info)->output_offset
@@ -2417,8 +2447,9 @@ _bfinfdpic_emit_got_relocs_plt_entries (struct bfinfdpic_relocs_info *entry,
             of the section.  For a non-local function, it's
             disregarded.  */
          lowword = ad;
-         if (entry->symndx == -1 && entry->d.h->dynindx != -1
-             && entry->d.h->dynindx == idx)
+         if (sec == NULL
+             || (entry->symndx == -1 && entry->d.h->dynindx != -1
+                 && entry->d.h->dynindx == idx))
            highword = 0;
          else
            highword = _bfinfdpic_osec_to_segment
@@ -2630,26 +2661,19 @@ bfinfdpic_relocate_section (bfd * output_bfd,
        }
       else
        {
-         bfd_boolean warned;
+         bfd_boolean warned, ignored;
          bfd_boolean unresolved_reloc;
 
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
                                   r_symndx, symtab_hdr, sym_hashes,
                                   h, sec, relocation,
-                                  unresolved_reloc, warned);
+                                  unresolved_reloc, warned, ignored);
          osec = sec;
        }
 
-      if (sec != NULL && elf_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.  */
-         _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
-         rel->r_info = 0;
-         rel->r_addend = 0;
-         continue;
-       }
+      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, 1, relend, howto, 0, contents);
 
       if (info->relocatable)
        continue;
@@ -2665,9 +2689,9 @@ bfinfdpic_relocate_section (bfd * output_bfd,
 
       switch (r_type)
        {
-       case R_pcrel24:
-       case R_pcrel24_jump_l:
-       case R_byte4_data:
+       case R_BFIN_PCREL24:
+       case R_BFIN_PCREL24_JUMP_L:
+       case R_BFIN_BYTE4_DATA:
          if (! IS_FDPIC (output_bfd))
            goto non_fdpic;
 
@@ -2715,7 +2739,9 @@ bfinfdpic_relocate_section (bfd * output_bfd,
        default:
        non_fdpic:
          picrel = NULL;
-         if (h && ! BFINFDPIC_SYM_LOCAL (info, h))
+         if (h && ! BFINFDPIC_SYM_LOCAL (info, h)
+             && _bfd_elf_section_offset (output_bfd, info, input_section,
+                                         rel->r_offset) != (bfd_vma) -1)
            {
              info->callbacks->warning
                (info, _("relocation references symbol not defined in the module"),
@@ -2727,8 +2753,8 @@ bfinfdpic_relocate_section (bfd * output_bfd,
 
       switch (r_type)
        {
-       case R_pcrel24:
-       case R_pcrel24_jump_l:
+       case R_BFIN_PCREL24:
+       case R_BFIN_PCREL24_JUMP_L:
          check_segment[0] = isec_segment;
          if (! IS_FDPIC (output_bfd))
            check_segment[1] = isec_segment;
@@ -2826,7 +2852,7 @@ bfinfdpic_relocate_section (bfd * output_bfd,
                    /* Otherwise, we know we have a private function
                       descriptor, so reference it directly.  */
                    BFD_ASSERT (picrel->privfd);
-                   r_type = R_byte4_data;
+                   r_type = R_BFIN_BYTE4_DATA;
                    dynindx = elf_section_data (bfinfdpic_got_section (info)
                                                ->output_section)->dynindx;
                    addend = bfinfdpic_got_section (info)->output_offset
@@ -2843,6 +2869,8 @@ bfinfdpic_relocate_section (bfd * output_bfd,
                if (info->executable && !info->pie
                    && (!h || BFINFDPIC_FUNCDESC_LOCAL (info, h)))
                  {
+                   bfd_vma offset;
+
                    addend += bfinfdpic_got_section (info)->output_section->vma;
                    if ((bfd_get_section_flags (output_bfd,
                                                input_section->output_section)
@@ -2858,16 +2886,19 @@ bfinfdpic_relocate_section (bfd * output_bfd,
                               name, input_bfd, input_section, rel->r_offset);
                            return FALSE;
                          }
-                       _bfinfdpic_add_rofixup (output_bfd,
-                                              bfinfdpic_gotfixup_section
-                                              (info),
-                                              _bfd_elf_section_offset
-                                              (output_bfd, info,
-                                               input_section, rel->r_offset)
-                                              + input_section
-                                              ->output_section->vma
-                                              + input_section->output_offset,
-                                              picrel);
+
+                       offset = _bfd_elf_section_offset
+                         (output_bfd, info,
+                          input_section, rel->r_offset);
+
+                       if (offset != (bfd_vma)-1)
+                         _bfinfdpic_add_rofixup (output_bfd,
+                                                 bfinfdpic_gotfixup_section
+                                                 (info),
+                                                 offset + input_section
+                                                 ->output_section->vma
+                                                 + input_section->output_offset,
+                                                 picrel);
                      }
                  }
                else if ((bfd_get_section_flags (output_bfd,
@@ -2888,14 +2919,8 @@ bfinfdpic_relocate_section (bfd * output_bfd,
                      }
                    offset = _bfd_elf_section_offset (output_bfd, info,
                                                      input_section, rel->r_offset);
-                   /* Only output a reloc for a not deleted entry.  */
-                   if (offset >= (bfd_vma) -2)
-                     _bfinfdpic_add_dyn_reloc (output_bfd,
-                                               bfinfdpic_gotrel_section (info),
-                                               0,
-                                               R_unused0,
-                                               dynindx, addend, picrel);
-                   else
+
+                   if (offset != (bfd_vma)-1)
                      _bfinfdpic_add_dyn_reloc (output_bfd,
                                                bfinfdpic_gotrel_section (info),
                                                offset + input_section
@@ -2916,7 +2941,7 @@ bfinfdpic_relocate_section (bfd * output_bfd,
          check_segment[0] = check_segment[1] = got_segment;
          break;
 
-       case R_byte4_data:
+       case R_BFIN_BYTE4_DATA:
          if (! IS_FDPIC (output_bfd))
            {
              check_segment[0] = check_segment[1] = -1;
@@ -2986,28 +3011,17 @@ bfinfdpic_relocate_section (bfd * output_bfd,
                      }
                    if (!h || h->root.type != bfd_link_hash_undefweak)
                      {
-                       /* Only output a reloc for a not deleted entry.  */
-                       if (offset >= (bfd_vma)-2)
-                         _bfinfdpic_add_rofixup (output_bfd,
-                                                 bfinfdpic_gotfixup_section
-                                                 (info), -1, picrel);
-                       else
-                         _bfinfdpic_add_rofixup (output_bfd,
-                                                 bfinfdpic_gotfixup_section
-                                                 (info),
-                                                 offset + input_section
-                                                 ->output_section->vma
-                                                 + input_section->output_offset,
-                                                 picrel);
-
-                       if (r_type == R_BFIN_FUNCDESC_VALUE)
+                       if (offset != (bfd_vma)-1)
                          {
-                           if (offset >= (bfd_vma)-2)
-                             _bfinfdpic_add_rofixup
-                               (output_bfd,
-                                bfinfdpic_gotfixup_section (info),
-                                -1, picrel);
-                           else
+                           _bfinfdpic_add_rofixup (output_bfd,
+                                                   bfinfdpic_gotfixup_section
+                                                   (info),
+                                                   offset + input_section
+                                                   ->output_section->vma
+                                                   + input_section->output_offset,
+                                                   picrel);
+
+                           if (r_type == R_BFIN_FUNCDESC_VALUE)
                              _bfinfdpic_add_rofixup
                                (output_bfd,
                                 bfinfdpic_gotfixup_section (info),
@@ -3033,17 +3047,12 @@ bfinfdpic_relocate_section (bfd * output_bfd,
                           name, input_bfd, input_section, rel->r_offset);
                        return FALSE;
                      }
-                   /* Only output a reloc for a not deleted entry.  */
-                   if (offset >= (bfd_vma)-2)
-                     _bfinfdpic_add_dyn_reloc (output_bfd,
-                                               bfinfdpic_gotrel_section (info),
-                                               0, R_unused0, dynindx, addend, picrel);
-                   else
+
+                   if (offset != (bfd_vma)-1)
                      _bfinfdpic_add_dyn_reloc (output_bfd,
                                                bfinfdpic_gotrel_section (info),
                                                offset
-                                               + input_section
-                                               ->output_section->vma
+                                               + input_section->output_section->vma
                                                + input_section->output_offset,
                                                r_type, dynindx, addend, picrel);
                  }
@@ -3055,7 +3064,7 @@ bfinfdpic_relocate_section (bfd * output_bfd,
                relocation = addend - rel->r_addend;
              }
 
-           if (r_type == R_BFIN_FUNCDESC_VALUE && offset < (bfd_vma)-2)
+           if (r_type == R_BFIN_FUNCDESC_VALUE)
              {
                /* If we've omitted the dynamic relocation, just emit
                   the fixed addresses of the symbol and of the local
@@ -3104,10 +3113,10 @@ bfinfdpic_relocate_section (bfd * output_bfd,
          if (silence_segment_error == 1)
            silence_segment_error =
              (strlen (input_bfd->filename) == 6
-              && strcmp (input_bfd->filename, "crt0.o") == 0)
+              && filename_cmp (input_bfd->filename, "crt0.o") == 0)
              || (strlen (input_bfd->filename) > 6
-                 && strcmp (input_bfd->filename
-                            + strlen (input_bfd->filename) - 7,
+                 && filename_cmp (input_bfd->filename
+                                  + strlen (input_bfd->filename) - 7,
                             "/crt0.o") == 0)
              ? -1 : 0;
 #endif
@@ -3153,8 +3162,8 @@ bfinfdpic_relocate_section (bfd * output_bfd,
 
       switch (r_type)
        {
-       case R_pcrel24:
-       case R_pcrel24_jump_l:
+       case R_BFIN_PCREL24:
+       case R_BFIN_PCREL24_JUMP_L:
          if (! IS_FDPIC (output_bfd) || ! picrel->plt)
            break;
          /* Fall through.  */
@@ -3284,8 +3293,8 @@ bfinfdpic_gc_sweep_hook (bfd *abfd,
 
       switch (ELF32_R_TYPE (rel->r_info))
         {
-       case R_pcrel24:
-       case R_pcrel24_jump_l:
+       case R_BFIN_PCREL24:
+       case R_BFIN_PCREL24_JUMP_L:
          picrel->call--;
          break;
 
@@ -3295,7 +3304,7 @@ bfinfdpic_gc_sweep_hook (bfd *abfd,
            picrel->relocs32++;
          /* Fall through.  */
 
-       case R_byte4_data:
+       case R_BFIN_BYTE4_DATA:
          picrel->sym--;
          if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
            picrel->relocs32--;
@@ -3382,11 +3391,10 @@ _bfin_create_got_section (bfd *abfd, struct bfd_link_info *info)
   struct elf_link_hash_entry *h;
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   int ptralign;
-  int offset;
 
   /* This function may be called more than once.  */
-  s = bfd_get_section_by_name (abfd, ".got");
-  if (s != NULL && (s->flags & SEC_LINKER_CREATED) != 0)
+  s = bfd_get_linker_section (abfd, ".got");
+  if (s != NULL)
     return TRUE;
 
   /* Machine specific: although pointers are 32-bits wide, we want the
@@ -3399,14 +3407,14 @@ _bfin_create_got_section (bfd *abfd, struct bfd_link_info *info)
           | SEC_LINKER_CREATED);
   pltflags = flags;
 
-  s = bfd_make_section_with_flags (abfd, ".got", flags);
+  s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
   if (s == NULL
       || !bfd_set_section_alignment (abfd, s, ptralign))
     return FALSE;
 
   if (bed->want_got_plt)
     {
-      s = bfd_make_section_with_flags (abfd, ".got.plt", flags);
+      s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
       if (s == NULL
          || !bfd_set_section_alignment (abfd, s, ptralign))
        return FALSE;
@@ -3444,8 +3452,8 @@ _bfin_create_got_section (bfd *abfd, struct bfd_link_info *info)
       if (! bfinfdpic_relocs_info (info))
        return FALSE;
 
-      s = bfd_make_section_with_flags (abfd, ".rel.got",
-                                      (flags | SEC_READONLY));
+      s = bfd_make_section_anyway_with_flags (abfd, ".rel.got",
+                                             (flags | SEC_READONLY));
       if (s == NULL
          || ! bfd_set_section_alignment (abfd, s, 2))
        return FALSE;
@@ -3453,51 +3461,22 @@ _bfin_create_got_section (bfd *abfd, struct bfd_link_info *info)
       bfinfdpic_gotrel_section (info) = s;
 
       /* Machine-specific.  */
-      s = bfd_make_section_with_flags (abfd, ".rofixup",
-                                      (flags | SEC_READONLY));
+      s = bfd_make_section_anyway_with_flags (abfd, ".rofixup",
+                                             (flags | SEC_READONLY));
       if (s == NULL
          || ! bfd_set_section_alignment (abfd, s, 2))
        return FALSE;
 
       bfinfdpic_gotfixup_section (info) = s;
-      offset = -2048;
-      flags = BSF_GLOBAL;
-    }
-  else
-    {
-      offset = 2048;
-      flags = BSF_GLOBAL | BSF_WEAK;
     }
 
-  return TRUE;
-}
-
-/* Make sure the got and plt sections exist, and that our pointers in
-   the link hash table point to them.  */
-
-static bfd_boolean
-elf32_bfinfdpic_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
-{
-  /* This is mostly copied from
-     elflink.c:_bfd_elf_create_dynamic_sections().  */
-  flagword flags, pltflags;
-  asection *s;
-  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
-
-  /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
-     .rel[a].bss sections.  */
-
-  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
-          | SEC_LINKER_CREATED);
-
-  pltflags = flags;
   pltflags |= SEC_CODE;
   if (bed->plt_not_loaded)
     pltflags &= ~ (SEC_CODE | SEC_LOAD | SEC_HAS_CONTENTS);
   if (bed->plt_readonly)
     pltflags |= SEC_READONLY;
 
-  s = bfd_make_section_with_flags (abfd, ".plt", pltflags);
+  s = bfd_make_section_anyway_with_flags (abfd, ".plt", pltflags);
   if (s == NULL
       || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
     return FALSE;
@@ -3508,7 +3487,6 @@ elf32_bfinfdpic_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
     {
       /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
         .plt section.  */
-      struct elf_link_hash_entry *h;
       struct bfd_link_hash_entry *bh = NULL;
 
       if (! (_bfd_generic_link_add_one_symbol
@@ -3525,13 +3503,35 @@ elf32_bfinfdpic_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
     }
 
   /* Blackfin-specific: we want rel relocations for the plt.  */
-  s = bfd_make_section_with_flags (abfd, ".rel.plt", flags | SEC_READONLY);
+  s = bfd_make_section_anyway_with_flags (abfd, ".rel.plt",
+                                         flags | SEC_READONLY);
   if (s == NULL
       || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
     return FALSE;
   /* Blackfin-specific: remember it.  */
   bfinfdpic_pltrel_section (info) = s;
 
+  return TRUE;
+}
+
+/* Make sure the got and plt sections exist, and that our pointers in
+   the link hash table point to them.  */
+
+static bfd_boolean
+elf32_bfinfdpic_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+{
+  /* This is mostly copied from
+     elflink.c:_bfd_elf_create_dynamic_sections().  */
+  flagword flags;
+  asection *s;
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+          | SEC_LINKER_CREATED);
+
+  /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
+     .rel[a].bss sections.  */
+
   /* Blackfin-specific: we want to create the GOT in the Blackfin way.  */
   if (! _bfin_create_got_section (abfd, info))
     return FALSE;
@@ -3550,28 +3550,27 @@ elf32_bfinfdpic_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
         image and use a R_*_COPY reloc to tell the dynamic linker to
         initialize them at run time.  The linker script puts the .dynbss
         section into the .bss section of the final image.  */
-      s = bfd_make_section_with_flags (abfd, ".dynbss",
-                                      SEC_ALLOC | SEC_LINKER_CREATED);
+      s = bfd_make_section_anyway_with_flags (abfd, ".dynbss",
+                                             SEC_ALLOC | SEC_LINKER_CREATED);
       if (s == NULL)
        return FALSE;
 
       /* The .rel[a].bss section holds copy relocs.  This section is not
-     normally needed.  We need to create it here, though, so that the
-     linker will map it to an output section.  We can't just create it
-     only if we need it, because we will not know whether we need it
-     until we have seen all the input files, and the first time the
-     main linker code calls BFD after examining all the input files
-     (size_dynamic_sections) the input sections have already been
-     mapped to the output sections.  If the section turns out not to
-     be needed, we can discard it later.  We will never need this
-     section when generating a shared object, since they do not use
-     copy relocs.  */
+        normally needed.  We need to create it here, though, so that the
+        linker will map it to an output section.  We can't just create it
+        only if we need it, because we will not know whether we need it
+        until we have seen all the input files, and the first time the
+        main linker code calls BFD after examining all the input files
+        (size_dynamic_sections) the input sections have already been
+        mapped to the output sections.  If the section turns out not to
+        be needed, we can discard it later.  We will never need this
+        section when generating a shared object, since they do not use
+        copy relocs.  */
       if (! info->shared)
        {
-         s = bfd_make_section_with_flags (abfd,
-                                          (bed->default_use_rela_p
-                                           ? ".rela.bss" : ".rel.bss"),
-                                          flags | SEC_READONLY);
+         s = bfd_make_section_anyway_with_flags (abfd,
+                                                 ".rela.bss",
+                                                 flags | SEC_READONLY);
          if (s == NULL
              || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
            return FALSE;
@@ -3586,13 +3585,10 @@ elf32_bfinfdpic_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
    the symbol, an entry pointing to its function descriptor, and a
    private function descriptors taking two words.  */
 
-static int
-_bfinfdpic_count_got_plt_entries (void **entryp, void *dinfo_)
+static void
+_bfinfdpic_count_nontls_entries (struct bfinfdpic_relocs_info *entry,
+                                struct _bfinfdpic_dynamic_got_info *dinfo)
 {
-  struct bfinfdpic_relocs_info *entry = *entryp;
-  struct _bfinfdpic_dynamic_got_info *dinfo = dinfo_;
-  unsigned relocs = 0, fixups = 0;
-
   /* Allocate space for a GOT entry pointing to the symbol.  */
   if (entry->got17m4)
     dinfo->got17m4 += 4;
@@ -3640,6 +3636,18 @@ _bfinfdpic_count_got_plt_entries (void **entryp, void *dinfo_)
 
   if (entry->lazyplt)
     dinfo->lzplt += LZPLT_NORMAL_SIZE;
+}
+
+/* Compute the number of dynamic relocations and fixups that a symbol
+   requires, and add (or subtract) from the grand and per-symbol
+   totals.  */
+
+static void
+_bfinfdpic_count_relocs_fixups (struct bfinfdpic_relocs_info *entry,
+                               struct _bfinfdpic_dynamic_got_info *dinfo,
+                               bfd_boolean subtract)
+{
+  bfd_vma relocs = 0, fixups = 0;
 
   if (!dinfo->info->executable || dinfo->info->pie)
     relocs = entry->relocs32 + entry->relocsfd + entry->relocsfdv;
@@ -3665,10 +3673,32 @@ _bfinfdpic_count_got_plt_entries (void **entryp, void *dinfo_)
        relocs += entry->relocsfd;
     }
 
+  if (subtract)
+    {
+      relocs = - relocs;
+      fixups = - fixups;
+    }
+
   entry->dynrelocs += relocs;
   entry->fixups += fixups;
   dinfo->relocs += relocs;
   dinfo->fixups += fixups;
+}
+
+/* Compute the total GOT and PLT size required by each symbol in each range. *
+   Symbols may require up to 4 words in the GOT: an entry pointing to
+   the symbol, an entry pointing to its function descriptor, and a
+   private function descriptors taking two words.  */
+
+static int
+_bfinfdpic_count_got_plt_entries (void **entryp, void *dinfo_)
+{
+  struct bfinfdpic_relocs_info *entry = *entryp;
+  struct _bfinfdpic_dynamic_got_info *dinfo = dinfo_;
+
+  _bfinfdpic_count_nontls_entries (entry, dinfo);
+
+  _bfinfdpic_count_relocs_fixups (entry, dinfo, FALSE);
 
   return 1;
 }
@@ -3964,6 +3994,23 @@ _bfinfdpic_assign_plt_entries (void **entryp, void *info_)
   return 1;
 }
 
+/* Cancel out any effects of calling _bfinfdpic_assign_got_entries and
+   _bfinfdpic_assign_plt_entries.  */
+
+static int
+_bfinfdpic_reset_got_plt_entries (void **entryp, void *ignore ATTRIBUTE_UNUSED)
+{
+  struct bfinfdpic_relocs_info *entry = *entryp;
+
+  entry->got_entry = 0;
+  entry->fdgot_entry = 0;
+  entry->fd_entry = 0;
+  entry->plt_entry = (bfd_vma)-1;
+  entry->lzplt_entry = (bfd_vma)-1;
+
+  return 1;
+}
+
 /* Follow indirect and warning hash entries so that each got entry
    points to the final symbol definition.  P must point to a pointer
    to the hash table we're traversing.  Since this traversal may
@@ -4020,89 +4067,62 @@ _bfinfdpic_resolve_final_relocs_info (void **entryp, void *p)
   return 1;
 }
 
-/* Set the sizes of the dynamic sections.  */
+/* Compute the total size of the GOT, the PLT, the dynamic relocations
+   section and the rofixup section.  Assign locations for GOT and PLT
+   entries.  */
 
 static bfd_boolean
-elf32_bfinfdpic_size_dynamic_sections (bfd *output_bfd,
-                                     struct bfd_link_info *info)
+_bfinfdpic_size_got_plt (bfd *output_bfd,
+                        struct _bfinfdpic_dynamic_got_plt_info *gpinfop)
 {
-  bfd *dynobj;
-  asection *s;
-  struct _bfinfdpic_dynamic_got_plt_info gpinfo;
   bfd_signed_vma odd;
   bfd_vma limit;
+  struct bfd_link_info *info = gpinfop->g.info;
+  bfd *dynobj = elf_hash_table (info)->dynobj;
 
-  dynobj = elf_hash_table (info)->dynobj;
-  BFD_ASSERT (dynobj != NULL);
-
-  if (elf_hash_table (info)->dynamic_sections_created)
-    {
-      /* Set the contents of the .interp section to the interpreter.  */
-      if (info->executable)
-       {
-         s = bfd_get_section_by_name (dynobj, ".interp");
-         BFD_ASSERT (s != NULL);
-         s->size = sizeof ELF_DYNAMIC_INTERPRETER;
-         s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
-       }
-    }
-
-  memset (&gpinfo, 0, sizeof (gpinfo));
-  gpinfo.g.info = info;
-
-  for (;;)
-    {
-      htab_t relocs = bfinfdpic_relocs_info (info);
-
-      htab_traverse (relocs, _bfinfdpic_resolve_final_relocs_info, &relocs);
-
-      if (relocs == bfinfdpic_relocs_info (info))
-       break;
-    }
-
-  htab_traverse (bfinfdpic_relocs_info (info), _bfinfdpic_count_got_plt_entries,
-                &gpinfo.g);
+  memcpy (bfinfdpic_dynamic_got_plt_info (info), &gpinfop->g,
+         sizeof (gpinfop->g));
 
   odd = 12;
   /* Compute the total size taken by entries in the 18-bit range,
      to tell how many PLT function descriptors we can bring into it
      without causing it to overflow.  */
-  limit = odd + gpinfo.g.got17m4 + gpinfo.g.fd17m4;
+  limit = odd + gpinfop->g.got17m4 + gpinfop->g.fd17m4;
   if (limit < (bfd_vma)1 << 18)
     limit = ((bfd_vma)1 << 18) - limit;
   else
     limit = 0;
-  if (gpinfo.g.fdplt < limit)
-    limit = gpinfo.g.fdplt;
+  if (gpinfop->g.fdplt < limit)
+    limit = gpinfop->g.fdplt;
 
   /* Determine the ranges of GOT offsets that we can use for each
      range of addressing modes.  */
-  odd = _bfinfdpic_compute_got_alloc_data (&gpinfo.got17m4,
+  odd = _bfinfdpic_compute_got_alloc_data (&gpinfop->got17m4,
                                          0,
                                          odd,
                                          16,
-                                         gpinfo.g.got17m4,
-                                         gpinfo.g.fd17m4,
+                                         gpinfop->g.got17m4,
+                                         gpinfop->g.fd17m4,
                                          limit,
                                          (bfd_vma)1 << (18-1));
-  odd = _bfinfdpic_compute_got_alloc_data (&gpinfo.gothilo,
-                                         gpinfo.got17m4.min,
+  odd = _bfinfdpic_compute_got_alloc_data (&gpinfop->gothilo,
+                                         gpinfop->got17m4.min,
                                          odd,
-                                         gpinfo.got17m4.max,
-                                         gpinfo.g.gothilo,
-                                         gpinfo.g.fdhilo,
-                                         gpinfo.g.fdplt - gpinfo.got17m4.fdplt,
+                                         gpinfop->got17m4.max,
+                                         gpinfop->g.gothilo,
+                                         gpinfop->g.fdhilo,
+                                         gpinfop->g.fdplt - gpinfop->got17m4.fdplt,
                                          (bfd_vma)1 << (32-1));
 
   /* Now assign (most) GOT offsets.  */
   htab_traverse (bfinfdpic_relocs_info (info), _bfinfdpic_assign_got_entries,
-                &gpinfo);
+                gpinfop);
 
-  bfinfdpic_got_section (info)->size = gpinfo.gothilo.max
-    - gpinfo.gothilo.min
+  bfinfdpic_got_section (info)->size = gpinfop->gothilo.max
+    - gpinfop->gothilo.min
     /* If an odd word is the last word of the GOT, we don't need this
        word to be part of the GOT.  */
-    - (odd + 4 == gpinfo.gothilo.max ? 4 : 0);
+    - (odd + 4 == gpinfop->gothilo.max ? 4 : 0);
   if (bfinfdpic_got_section (info)->size == 0)
     bfinfdpic_got_section (info)->flags |= SEC_EXCLUDE;
   else if (bfinfdpic_got_section (info)->size == 12
@@ -4124,10 +4144,10 @@ elf32_bfinfdpic_size_dynamic_sections (bfd *output_bfd,
     /* Subtract the number of lzplt entries, since those will generate
        relocations in the pltrel section.  */
     bfinfdpic_gotrel_section (info)->size =
-      (gpinfo.g.relocs - gpinfo.g.lzplt / LZPLT_NORMAL_SIZE)
+      (gpinfop->g.relocs - gpinfop->g.lzplt / LZPLT_NORMAL_SIZE)
       * get_elf_backend_data (output_bfd)->s->sizeof_rel;
   else
-    BFD_ASSERT (gpinfo.g.relocs == 0);
+    BFD_ASSERT (gpinfop->g.relocs == 0);
   if (bfinfdpic_gotrel_section (info)->size == 0)
     bfinfdpic_gotrel_section (info)->flags |= SEC_EXCLUDE;
   else
@@ -4139,7 +4159,7 @@ elf32_bfinfdpic_size_dynamic_sections (bfd *output_bfd,
        return FALSE;
     }
 
-  bfinfdpic_gotfixup_section (info)->size = (gpinfo.g.fixups + 1) * 4;
+  bfinfdpic_gotfixup_section (info)->size = (gpinfop->g.fixups + 1) * 4;
   if (bfinfdpic_gotfixup_section (info)->size == 0)
     bfinfdpic_gotfixup_section (info)->flags |= SEC_EXCLUDE;
   else
@@ -4152,19 +4172,17 @@ elf32_bfinfdpic_size_dynamic_sections (bfd *output_bfd,
     }
 
   if (elf_hash_table (info)->dynamic_sections_created)
+    bfinfdpic_pltrel_section (info)->size =
+      gpinfop->g.lzplt / LZPLT_NORMAL_SIZE * get_elf_backend_data (output_bfd)->s->sizeof_rel;
+  if (bfinfdpic_pltrel_section (info)->size == 0)
+    bfinfdpic_pltrel_section (info)->flags |= SEC_EXCLUDE;
+  else
     {
-      bfinfdpic_pltrel_section (info)->size =
-       gpinfo.g.lzplt / LZPLT_NORMAL_SIZE * get_elf_backend_data (output_bfd)->s->sizeof_rel;
-      if (bfinfdpic_pltrel_section (info)->size == 0)
-       bfinfdpic_pltrel_section (info)->flags |= SEC_EXCLUDE;
-      else
-       {
-         bfinfdpic_pltrel_section (info)->contents =
-           (bfd_byte *) bfd_zalloc (dynobj,
-                                    bfinfdpic_pltrel_section (info)->size);
-         if (bfinfdpic_pltrel_section (info)->contents == NULL)
-           return FALSE;
-       }
+      bfinfdpic_pltrel_section (info)->contents =
+       (bfd_byte *) bfd_zalloc (dynobj,
+                                bfinfdpic_pltrel_section (info)->size);
+      if (bfinfdpic_pltrel_section (info)->contents == NULL)
+       return FALSE;
     }
 
   /* Add 4 bytes for every block of at most 65535 lazy PLT entries,
@@ -4174,47 +4192,97 @@ elf32_bfinfdpic_size_dynamic_sections (bfd *output_bfd,
      block size.  */
   if (elf_hash_table (info)->dynamic_sections_created)
     {
-      bfinfdpic_plt_section (info)->size = gpinfo.g.lzplt
-       + ((gpinfo.g.lzplt + (BFINFDPIC_LZPLT_BLOCK_SIZE - 4) - LZPLT_NORMAL_SIZE)
+      bfinfdpic_plt_section (info)->size = gpinfop->g.lzplt
+       + ((gpinfop->g.lzplt + (BFINFDPIC_LZPLT_BLOCK_SIZE - 4) - LZPLT_NORMAL_SIZE)
           / (BFINFDPIC_LZPLT_BLOCK_SIZE - 4) * LZPLT_RESOLVER_EXTRA);
     }
 
   /* Reset it, such that _bfinfdpic_assign_plt_entries() can use it to
      actually assign lazy PLT entries addresses.  */
-  gpinfo.g.lzplt = 0;
+  gpinfop->g.lzplt = 0;
 
   /* Save information that we're going to need to generate GOT and PLT
      entries.  */
-  bfinfdpic_got_initial_offset (info) = -gpinfo.gothilo.min;
+  bfinfdpic_got_initial_offset (info) = -gpinfop->gothilo.min;
 
   if (get_elf_backend_data (output_bfd)->want_got_sym)
     elf_hash_table (info)->hgot->root.u.def.value
-      += bfinfdpic_got_initial_offset (info);
+      = bfinfdpic_got_initial_offset (info);
 
   if (elf_hash_table (info)->dynamic_sections_created)
     bfinfdpic_plt_initial_offset (info) =
       bfinfdpic_plt_section (info)->size;
 
   htab_traverse (bfinfdpic_relocs_info (info), _bfinfdpic_assign_plt_entries,
-                &gpinfo);
+                gpinfop);
 
   /* Allocate the PLT section contents only after
      _bfinfdpic_assign_plt_entries has a chance to add the size of the
      non-lazy PLT entries.  */
-  if (elf_hash_table (info)->dynamic_sections_created)
+  if (bfinfdpic_plt_section (info)->size == 0)
+    bfinfdpic_plt_section (info)->flags |= SEC_EXCLUDE;
+  else
     {
-      if (bfinfdpic_plt_section (info)->size == 0)
-       bfinfdpic_plt_section (info)->flags |= SEC_EXCLUDE;
-      else
+      bfinfdpic_plt_section (info)->contents =
+       (bfd_byte *) bfd_zalloc (dynobj,
+                                bfinfdpic_plt_section (info)->size);
+      if (bfinfdpic_plt_section (info)->contents == NULL)
+       return FALSE;
+    }
+
+  return TRUE;
+}
+
+/* Set the sizes of the dynamic sections.  */
+
+static bfd_boolean
+elf32_bfinfdpic_size_dynamic_sections (bfd *output_bfd,
+                                     struct bfd_link_info *info)
+{
+  struct elf_link_hash_table *htab;
+  bfd *dynobj;
+  asection *s;
+  struct _bfinfdpic_dynamic_got_plt_info gpinfo;
+
+  htab = elf_hash_table (info);
+  dynobj = htab->dynobj;
+  BFD_ASSERT (dynobj != NULL);
+
+  if (htab->dynamic_sections_created)
+    {
+      /* Set the contents of the .interp section to the interpreter.  */
+      if (info->executable)
        {
-         bfinfdpic_plt_section (info)->contents =
-           (bfd_byte *) bfd_zalloc (dynobj,
-                                    bfinfdpic_plt_section (info)->size);
-         if (bfinfdpic_plt_section (info)->contents == NULL)
-           return FALSE;
+         s = bfd_get_linker_section (dynobj, ".interp");
+         BFD_ASSERT (s != NULL);
+         s->size = sizeof ELF_DYNAMIC_INTERPRETER;
+         s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
        }
     }
 
+  memset (&gpinfo, 0, sizeof (gpinfo));
+  gpinfo.g.info = info;
+
+  for (;;)
+    {
+      htab_t relocs = bfinfdpic_relocs_info (info);
+
+      htab_traverse (relocs, _bfinfdpic_resolve_final_relocs_info, &relocs);
+
+      if (relocs == bfinfdpic_relocs_info (info))
+       break;
+    }
+
+  htab_traverse (bfinfdpic_relocs_info (info), _bfinfdpic_count_got_plt_entries,
+                &gpinfo.g);
+
+  /* Allocate space to save the summary information, we're going to
+     use it if we're doing relaxations.  */
+  bfinfdpic_dynamic_got_plt_info (info) = bfd_alloc (dynobj, sizeof (gpinfo.g));
+
+  if (!_bfinfdpic_size_got_plt (output_bfd, &gpinfo))
+      return FALSE;
+
   if (elf_hash_table (info)->dynamic_sections_created)
     {
       if (bfinfdpic_got_section (info)->size)
@@ -4235,6 +4303,14 @@ elf32_bfinfdpic_size_dynamic_sections (bfd *output_bfd,
          return FALSE;
     }
 
+  s = bfd_get_linker_section (dynobj, ".dynbss");
+  if (s && s->size == 0)
+    s->flags |= SEC_EXCLUDE;
+
+  s = bfd_get_linker_section (dynobj, ".rela.bss");
+  if (s && s->size == 0)
+    s->flags |= SEC_EXCLUDE;
+
   return TRUE;
 }
 
@@ -4242,79 +4318,124 @@ static bfd_boolean
 elf32_bfinfdpic_always_size_sections (bfd *output_bfd,
                                     struct bfd_link_info *info)
 {
-  if (!info->relocatable)
-    {
-      struct elf_link_hash_entry *h;
-
-      /* Force a PT_GNU_STACK segment to be created.  */
-      if (! elf_tdata (output_bfd)->stack_flags)
-       elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X;
-
-      /* Define __stacksize if it's not defined yet.  */
-      h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize",
-                               FALSE, FALSE, FALSE);
-      if (! h || h->root.type != bfd_link_hash_defined
-         || h->type != STT_OBJECT
-         || !h->def_regular)
-       {
-         struct bfd_link_hash_entry *bh = NULL;
-
-         if (!(_bfd_generic_link_add_one_symbol
-               (info, output_bfd, "__stacksize",
-                BSF_GLOBAL, bfd_abs_section_ptr, DEFAULT_STACK_SIZE,
-                (const char *) NULL, FALSE,
-                get_elf_backend_data (output_bfd)->collect, &bh)))
-           return FALSE;
-
-         h = (struct elf_link_hash_entry *) bh;
-         h->def_regular = 1;
-         h->type = STT_OBJECT;
-       }
-    }
+  if (!info->relocatable
+      && !bfd_elf_stack_segment_size (output_bfd, info,
+                                     "__stacksize", DEFAULT_STACK_SIZE))
+    return FALSE;
 
   return TRUE;
 }
 
+/* Check whether any of the relocations was optimized away, and
+   subtract it from the relocation or fixup count.  */
 static bfd_boolean
-elf32_bfinfdpic_modify_program_headers (bfd *output_bfd,
-                                       struct bfd_link_info *info)
+_bfinfdpic_check_discarded_relocs (bfd *abfd, asection *sec,
+                                  struct bfd_link_info *info,
+                                  bfd_boolean *changed)
 {
-  struct elf_obj_tdata *tdata = elf_tdata (output_bfd);
-  struct elf_segment_map *m;
-  Elf_Internal_Phdr *p;
+  Elf_Internal_Shdr *symtab_hdr;
+  struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
+  Elf_Internal_Rela *rel, *erel;
 
-  /* objcopy and strip preserve what's already there using
-     elf32_bfinfdpic_copy_private_bfd_data ().  */
-  if (! info)
+  if ((sec->flags & SEC_RELOC) == 0
+      || sec->reloc_count == 0)
     return TRUE;
 
-  for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++)
-    if (m->p_type == PT_GNU_STACK)
-      break;
+  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+  sym_hashes = elf_sym_hashes (abfd);
+  sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
+  if (!elf_bad_symtab (abfd))
+    sym_hashes_end -= symtab_hdr->sh_info;
 
-  if (m)
+  rel = elf_section_data (sec)->relocs;
+
+  /* Now examine each relocation.  */
+  for (erel = rel + sec->reloc_count; rel < erel; rel++)
     {
       struct elf_link_hash_entry *h;
+      unsigned long r_symndx;
+      struct bfinfdpic_relocs_info *picrel;
+      struct _bfinfdpic_dynamic_got_info *dinfo;
+
+      if (ELF32_R_TYPE (rel->r_info) != R_BFIN_BYTE4_DATA
+         && ELF32_R_TYPE (rel->r_info) != R_BFIN_FUNCDESC)
+       continue;
 
-      /* Obtain the pointer to the __stacksize symbol.  */
-      h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize",
-                               FALSE, FALSE, FALSE);
-      if (h)
+      if (_bfd_elf_section_offset (sec->output_section->owner,
+                                  info, sec, rel->r_offset)
+         != (bfd_vma)-1)
+       continue;
+
+      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;
-         BFD_ASSERT (h->root.type == bfd_link_hash_defined);
+           h = (struct elf_link_hash_entry *)h->root.u.i.link;
        }
 
-      /* Set the header p_memsz from the symbol value.  We
-        intentionally ignore the symbol section.  */
-      if (h && h->root.type == bfd_link_hash_defined)
-       p->p_memsz = h->root.u.def.value;
+      if (h != NULL)
+       picrel = bfinfdpic_relocs_info_for_global (bfinfdpic_relocs_info (info),
+                                                 abfd, h,
+                                                 rel->r_addend, NO_INSERT);
       else
-       p->p_memsz = DEFAULT_STACK_SIZE;
+       picrel = bfinfdpic_relocs_info_for_local (bfinfdpic_relocs_info (info),
+                                                abfd, r_symndx,
+                                                rel->r_addend, NO_INSERT);
 
-      p->p_align = 8;
+      if (! picrel)
+       return FALSE;
+
+      *changed = TRUE;
+      dinfo = bfinfdpic_dynamic_got_plt_info (info);
+
+      _bfinfdpic_count_relocs_fixups (picrel, dinfo, TRUE);
+      if (ELF32_R_TYPE (rel->r_info) == R_BFIN_BYTE4_DATA)
+       picrel->relocs32--;
+      else /* we know (ELF32_R_TYPE (rel->r_info) == R_BFIN_FUNCDESC) */
+       picrel->relocsfd--;
+      _bfinfdpic_count_relocs_fixups (picrel, dinfo, FALSE);
+    }
+
+  return TRUE;
+}
+
+static bfd_boolean
+bfinfdpic_elf_discard_info (bfd *ibfd,
+                          struct elf_reloc_cookie *cookie ATTRIBUTE_UNUSED,
+                          struct bfd_link_info *info)
+{
+  bfd_boolean changed = FALSE;
+  asection *s;
+  bfd *obfd = NULL;
+
+  /* Account for relaxation of .eh_frame section.  */
+  for (s = ibfd->sections; s; s = s->next)
+    if (s->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
+      {
+       if (!_bfinfdpic_check_discarded_relocs (ibfd, s, info, &changed))
+         return FALSE;
+       obfd = s->output_section->owner;
+      }
+
+  if (changed)
+    {
+      struct _bfinfdpic_dynamic_got_plt_info gpinfo;
+
+      memset (&gpinfo, 0, sizeof (gpinfo));
+      memcpy (&gpinfo.g, bfinfdpic_dynamic_got_plt_info (info),
+             sizeof (gpinfo.g));
+
+      /* Clear GOT and PLT assignments.  */
+      htab_traverse (bfinfdpic_relocs_info (info),
+                    _bfinfdpic_reset_got_plt_entries,
+                    NULL);
+
+      if (!_bfinfdpic_size_got_plt (obfd, &gpinfo))
+       return FALSE;
     }
 
   return TRUE;
@@ -4361,7 +4482,7 @@ elf32_bfinfdpic_finish_dynamic_sections (bfd *output_bfd,
                      * sizeof (Elf32_External_Rel)));
     }
 
-  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+  sdyn = bfd_get_linker_section (dynobj, ".dynamic");
 
   if (elf_hash_table (info)->dynamic_sections_created)
     {
@@ -4413,9 +4534,8 @@ elf32_bfinfdpic_finish_dynamic_sections (bfd *output_bfd,
    regular object.  */
 
 static bfd_boolean
-elf32_bfinfdpic_adjust_dynamic_symbol
-(struct bfd_link_info *info,
- struct elf_link_hash_entry *h)
+elf32_bfinfdpic_adjust_dynamic_symbol (struct bfd_link_info *info,
+                                      struct elf_link_hash_entry *h)
 {
   bfd * dynobj;
 
@@ -4653,9 +4773,9 @@ bfinfdpic_check_relocs (bfd *abfd, struct bfd_link_info *info,
          if (! IS_FDPIC (abfd))
            goto bad_reloc;
          /* Fall through.  */
-       case R_pcrel24:
-       case R_pcrel24_jump_l:
-       case R_byte4_data:
+       case R_BFIN_PCREL24:
+       case R_BFIN_PCREL24_JUMP_L:
+       case R_BFIN_BYTE4_DATA:
          if (IS_FDPIC (abfd) && ! dynobj)
            {
              elf_hash_table (info)->dynobj = dynobj = abfd;
@@ -4699,8 +4819,8 @@ bfinfdpic_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
       switch (ELF32_R_TYPE (rel->r_info))
         {
-       case R_pcrel24:
-       case R_pcrel24_jump_l:
+       case R_BFIN_PCREL24:
+       case R_BFIN_PCREL24_JUMP_L:
          if (IS_FDPIC (abfd))
            picrel->call++;
          break;
@@ -4711,7 +4831,7 @@ bfinfdpic_check_relocs (bfd *abfd, struct bfd_link_info *info,
            picrel->relocs32--;
          /* Fall through.  */
 
-       case R_byte4_data:
+       case R_BFIN_BYTE4_DATA:
          if (! IS_FDPIC (abfd))
            break;
 
@@ -4774,10 +4894,10 @@ bfinfdpic_check_relocs (bfd *abfd, struct bfd_link_info *info,
             return FALSE;
           break;
 
-       case R_huimm16:
-       case R_luimm16:
-       case R_pcrel12_jump_s:
-       case R_pcrel10:
+       case R_BFIN_HUIMM16:
+       case R_BFIN_LUIMM16:
+       case R_BFIN_PCREL12_JUMP_S:
+       case R_BFIN_PCREL10:
          break;
 
        default:
@@ -4810,75 +4930,9 @@ elf32_bfin_set_private_flags (bfd * abfd, flagword flags)
   return TRUE;
 }
 
-/* Copy backend specific data from one object module to another.  */
-
-static bfd_boolean
-bfin_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
-{
-  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
-      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
-    return TRUE;
-
-  BFD_ASSERT (!elf_flags_init (obfd)
-             || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
-
-  elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
-  elf_flags_init (obfd) = TRUE;
-
-  /* Copy object attributes.  */
-  _bfd_elf_copy_obj_attributes (ibfd, obfd);
-
-  return TRUE;
-}
-
-static bfd_boolean
-elf32_bfinfdpic_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
-{
-  unsigned i;
-
-  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
-      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
-    return TRUE;
-
-  if (! bfin_elf_copy_private_bfd_data (ibfd, obfd))
-    return FALSE;
-
-  if (! elf_tdata (ibfd) || ! elf_tdata (ibfd)->phdr
-      || ! elf_tdata (obfd) || ! elf_tdata (obfd)->phdr)
-    return TRUE;
-
-  /* Copy the stack size.  */
-  for (i = 0; i < elf_elfheader (ibfd)->e_phnum; i++)
-    if (elf_tdata (ibfd)->phdr[i].p_type == PT_GNU_STACK)
-      {
-       Elf_Internal_Phdr *iphdr = &elf_tdata (ibfd)->phdr[i];
-
-       for (i = 0; i < elf_elfheader (obfd)->e_phnum; i++)
-         if (elf_tdata (obfd)->phdr[i].p_type == PT_GNU_STACK)
-           {
-             memcpy (&elf_tdata (obfd)->phdr[i], iphdr, sizeof (*iphdr));
-
-             /* Rewrite the phdrs, since we're only called after they
-                were first written.  */
-             if (bfd_seek (obfd, (bfd_signed_vma) get_elf_backend_data (obfd)
-                           ->s->sizeof_ehdr, SEEK_SET) != 0
-                 || get_elf_backend_data (obfd)->s
-                 ->write_out_phdrs (obfd, elf_tdata (obfd)->phdr,
-                                    elf_elfheader (obfd)->e_phnum) != 0)
-               return FALSE;
-             break;
-           }
-
-       break;
-      }
-
-  return TRUE;
-}
-
-
 /* Display the flags field.  */
 static bfd_boolean
-elf32_bfin_print_private_bfd_data (bfd * abfd, PTR ptr)
+elf32_bfin_print_private_bfd_data (bfd * abfd, void * ptr)
 {
   FILE *file = (FILE *) ptr;
   flagword flags;
@@ -4919,11 +4973,12 @@ elf32_bfin_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
   if (new_flags & EF_BFIN_FDPIC)
     new_flags &= ~EF_BFIN_PIC;
 
-#ifdef DEBUG
+#ifndef DEBUG
+  if (0)
+#endif
   (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
                         old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
                         bfd_get_filename (ibfd));
-#endif
 
   if (!elf_flags_init (obfd))                  /* First call, no flags set.  */
     {
@@ -5001,13 +5056,14 @@ bfin_link_hash_table_create (bfd * abfd)
   struct bfin_link_hash_table *ret;
   bfd_size_type amt = sizeof (struct bfin_link_hash_table);
 
-  ret = bfd_zalloc (abfd, amt);
+  ret = bfd_zmalloc (amt);
   if (ret == NULL)
     return NULL;
 
   if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
                                      bfin_link_hash_newfunc,
-                                     sizeof (struct elf_link_hash_entry)))
+                                     sizeof (struct elf_link_hash_entry),
+                                     BFIN_ELF_DATA))
     {
       free (ret);
       return NULL;
@@ -5024,14 +5080,14 @@ bfin_link_hash_table_create (bfd * abfd)
 
 static bfd_boolean
 bfin_finish_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
-                                 struct bfd_link_info *info)
+                             struct bfd_link_info *info)
 {
   bfd *dynobj;
   asection *sdyn;
 
   dynobj = elf_hash_table (info)->dynobj;
 
-  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+  sdyn = bfd_get_linker_section (dynobj, ".dynamic");
 
   if (elf_hash_table (info)->dynamic_sections_created)
     {
@@ -5058,9 +5114,9 @@ bfin_finish_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
 
 static bfd_boolean
 bfin_finish_dynamic_symbol (bfd * output_bfd,
-                               struct bfd_link_info *info,
-                               struct elf_link_hash_entry *h,
-                               Elf_Internal_Sym * sym)
+                           struct bfd_link_info *info,
+                           struct elf_link_hash_entry *h,
+                           Elf_Internal_Sym * sym)
 {
   bfd *dynobj;
 
@@ -5076,8 +5132,8 @@ bfin_finish_dynamic_symbol (bfd * output_bfd,
       /* This symbol has an entry in the global offset table.
          Set it up.  */
 
-      sgot = bfd_get_section_by_name (dynobj, ".got");
-      srela = bfd_get_section_by_name (dynobj, ".rela.got");
+      sgot = bfd_get_linker_section (dynobj, ".got");
+      srela = bfd_get_linker_section (dynobj, ".rela.got");
       BFD_ASSERT (sgot != NULL && srela != NULL);
 
       rela.r_offset = (sgot->output_section->vma
@@ -5093,8 +5149,9 @@ bfin_finish_dynamic_symbol (bfd * output_bfd,
          && (info->symbolic
              || h->dynindx == -1 || h->forced_local) && h->def_regular)
        {
-         fprintf(stderr, "*** check this relocation %s\n", __FUNCTION__);
-         rela.r_info = ELF32_R_INFO (0, R_pcrel24);
+         (*_bfd_error_handler) (_("*** check this relocation %s"),
+                                __FUNCTION__);
+         rela.r_info = ELF32_R_INFO (0, R_BFIN_PCREL24);
          rela.r_addend = bfd_get_signed_32 (output_bfd,
                                             (sgot->contents
                                              +
@@ -5105,7 +5162,7 @@ bfin_finish_dynamic_symbol (bfd * output_bfd,
        {
          bfd_put_32 (output_bfd, (bfd_vma) 0,
                      sgot->contents + (h->got.offset & ~(bfd_vma) 1));
-         rela.r_info = ELF32_R_INFO (h->dynindx, R_got);
+         rela.r_info = ELF32_R_INFO (h->dynindx, R_BFIN_GOT);
          rela.r_addend = 0;
        }
 
@@ -5134,7 +5191,7 @@ bfin_finish_dynamic_symbol (bfd * output_bfd,
 
 static bfd_boolean
 bfin_adjust_dynamic_symbol (struct bfd_link_info *info,
-                               struct elf_link_hash_entry *h)
+                           struct elf_link_hash_entry *h)
 {
   bfd *dynobj;
   asection *s;
@@ -5188,7 +5245,7 @@ bfin_adjust_dynamic_symbol (struct bfd_link_info *info,
      both the dynamic object and the regular object will refer to the
      same memory location for the variable.  */
 
-  s = bfd_get_section_by_name (dynobj, ".dynbss");
+  s = bfd_get_linker_section (dynobj, ".dynbss");
   BFD_ASSERT (s != NULL);
 
   /* We must generate a R_68K_COPY reloc to tell the dynamic linker to
@@ -5199,7 +5256,7 @@ bfin_adjust_dynamic_symbol (struct bfd_link_info *info,
     {
       asection *srel;
 
-      srel = bfd_get_section_by_name (dynobj, ".rela.bss");
+      srel = bfd_get_linker_section (dynobj, ".rela.bss");
       BFD_ASSERT (srel != NULL);
       srel->size += sizeof (Elf32_External_Rela);
       h->needs_copy = 1;
@@ -5262,14 +5319,11 @@ struct bfin_pcrel_relocs_copied
    case.  */
 
 static bfd_boolean
-bfin_discard_copies (struct elf_link_hash_entry *h, PTR inf)
+bfin_discard_copies (struct elf_link_hash_entry *h, void * inf)
 {
   struct bfd_link_info *info = (struct bfd_link_info *) inf;
   struct bfin_pcrel_relocs_copied *s;
 
-  if (h->root.type == bfd_link_hash_warning)
-    h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
   if (!h->def_regular || (!info->symbolic && !h->forced_local))
     {
       if ((info->flags & DF_TEXTREL) == 0)
@@ -5296,7 +5350,7 @@ bfin_discard_copies (struct elf_link_hash_entry *h, PTR inf)
 
 static bfd_boolean
 bfin_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
-                               struct bfd_link_info *info)
+                           struct bfd_link_info *info)
 {
   bfd *dynobj;
   asection *s;
@@ -5310,7 +5364,7 @@ bfin_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
       /* Set the contents of the .interp section to the interpreter.  */
       if (info->executable)
        {
-         s = bfd_get_section_by_name (dynobj, ".interp");
+         s = bfd_get_linker_section (dynobj, ".interp");
          BFD_ASSERT (s != NULL);
          s->size = sizeof ELF_DYNAMIC_INTERPRETER;
          s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
@@ -5323,7 +5377,7 @@ bfin_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
          not actually use these entries.  Reset the size of .rela.got,
          which will cause it to get stripped from the output file
          below.  */
-      s = bfd_get_section_by_name (dynobj, ".rela.got");
+      s = bfd_get_linker_section (dynobj, ".rela.got");
       if (s != NULL)
        s->size = 0;
     }
@@ -5336,7 +5390,7 @@ bfin_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
      will not fill them in in the relocate_section routine.  */
   if (info->shared)
     elf_link_hash_traverse (elf_hash_table (info),
-                           bfin_discard_copies, (PTR) info);
+                           bfin_discard_copies, info);
 
   /* The check_relocs and adjust_dynamic_symbol entry points have
      determined the sizes of the various dynamic sections.  Allocate
@@ -5447,16 +5501,12 @@ bfin_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
    after the add_symbols entry point has been called for all the
    objects, and before the final_link entry point is called.  */
 
-bfd_boolean bfd_bfin_elf32_create_embedded_relocs
-  PARAMS ((bfd *, struct bfd_link_info *, asection *, asection *, char **));
-
 bfd_boolean
-bfd_bfin_elf32_create_embedded_relocs (
-     bfd *abfd,
-     struct bfd_link_info *info,
-     asection *datasec,
-     asection *relsec,
-     char **errmsg)
+bfd_bfin_elf32_create_embedded_relocs (bfd *abfd,
+                                      struct bfd_link_info *info,
+                                      asection *datasec,
+                                      asection *relsec,
+                                      char **errmsg)
 {
   Elf_Internal_Shdr *symtab_hdr;
   Elf_Internal_Sym *isymbuf = NULL;
@@ -5476,7 +5526,7 @@ bfd_bfin_elf32_create_embedded_relocs (
 
   /* Get a copy of the native relocations.  */
   internal_relocs = (_bfd_elf_link_read_relocs
-                    (abfd, datasec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
+                    (abfd, datasec, NULL, (Elf_Internal_Rela *) NULL,
                      info->keep_memory));
   if (internal_relocs == NULL)
     goto error_return;
@@ -5500,7 +5550,7 @@ bfd_bfin_elf32_create_embedded_relocs (
        characters.  */
 
       /* We can only relocate absolute longword relocs at run time.  */
-      if (ELF32_R_TYPE (irel->r_info) != (int) R_byte4_data)
+      if (ELF32_R_TYPE (irel->r_info) != (int) R_BFIN_BYTE4_DATA)
        {
          *errmsg = _("unsupported reloc type");
          bfd_set_error (bfd_error_bad_value);
@@ -5574,9 +5624,10 @@ struct bfd_elf_special_section const elf32_bfin_special_sections[] =
 };
 
 \f
-#define TARGET_LITTLE_SYM              bfd_elf32_bfin_vec
+#define TARGET_LITTLE_SYM              bfin_elf32_vec
 #define TARGET_LITTLE_NAME             "elf32-bfin"
 #define ELF_ARCH                       bfd_arch_bfin
+#define ELF_TARGET_ID                  BFIN_ELF_DATA
 #define ELF_MACHINE_CODE               EM_BLACKFIN
 #define ELF_MAXPAGESIZE                        0x1000
 #define elf_symbol_leading_char                '_'
@@ -5619,7 +5670,10 @@ struct bfd_elf_special_section const elf32_bfin_special_sections[] =
                                         elf32_bfin_set_private_flags
 #define bfd_elf32_bfd_print_private_bfd_data \
                                         elf32_bfin_print_private_bfd_data
+#define elf_backend_final_write_processing \
+                                        elf32_bfin_final_write_processing
 #define elf_backend_reloc_type_class    elf32_bfin_reloc_type_class
+#define elf_backend_stack_align                8
 #define elf_backend_can_gc_sections 1
 #define elf_backend_special_sections   elf32_bfin_special_sections
 #define elf_backend_can_refcount 1
@@ -5632,7 +5686,7 @@ struct bfd_elf_special_section const elf32_bfin_special_sections[] =
 #include "elf32-target.h"
 
 #undef TARGET_LITTLE_SYM
-#define TARGET_LITTLE_SYM          bfd_elf32_bfinfdpic_vec
+#define TARGET_LITTLE_SYM          bfin_elf32_fdpic_vec
 #undef TARGET_LITTLE_NAME
 #define TARGET_LITTLE_NAME             "elf32-bfinfdpic"
 #undef elf32_bed
@@ -5655,12 +5709,6 @@ struct bfd_elf_special_section const elf32_bfin_special_sections[] =
 #undef elf_backend_always_size_sections
 #define elf_backend_always_size_sections \
                elf32_bfinfdpic_always_size_sections
-#undef elf_backend_modify_program_headers
-#define elf_backend_modify_program_headers \
-               elf32_bfinfdpic_modify_program_headers
-#undef bfd_elf32_bfd_copy_private_bfd_data
-#define bfd_elf32_bfd_copy_private_bfd_data \
-               elf32_bfinfdpic_copy_private_bfd_data
 
 #undef elf_backend_create_dynamic_sections
 #define elf_backend_create_dynamic_sections \
@@ -5678,6 +5726,9 @@ struct bfd_elf_special_section const elf32_bfin_special_sections[] =
 #define elf_backend_finish_dynamic_sections \
                elf32_bfinfdpic_finish_dynamic_sections
 
+#undef elf_backend_discard_info
+#define elf_backend_discard_info \
+               bfinfdpic_elf_discard_info
 #undef elf_backend_can_make_relative_eh_frame
 #define elf_backend_can_make_relative_eh_frame \
                bfinfdpic_elf_use_relative_eh_frame