* bfd/elf.c (INCLUDE_SECTION_IN_SEGMENT): Don't put empty sections into
[deliverable/binutils-gdb.git] / bfd / elf32-frv.c
index eedc55d6e7dfc8bae17c3341e71e5386e6c6e84d..9564671af7bb7a0419576afc5a46529b03fe8ddb 100644 (file)
@@ -1,5 +1,5 @@
 /* FRV-specific support for 32-bit ELF.
-   Copyright 2002, 2003 Free Software Foundation, Inc.
+   Copyright 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of BFD, the Binary File Descriptor library.
 
@@ -52,7 +52,7 @@ static bfd_boolean elf32_frv_relocate_section
   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
           Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
 static bfd_boolean elf32_frv_add_symbol_hook
-  PARAMS (( bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
+  PARAMS (( bfd *, struct bfd_link_info *, Elf_Internal_Sym *,
            const char **, flagword *, asection **, bfd_vma *));
 static bfd_reloc_status_type frv_final_link_relocate
   PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,
@@ -583,10 +583,12 @@ static const struct frv_reloc_map frv_reloc_map [] =
 };
 #endif
 
+extern const bfd_target bfd_elf32_frvfdpic_vec;
+#define IS_FDPIC(bfd) ((bfd)->xvec == &bfd_elf32_frvfdpic_vec)
 
 /* An extension of the elf hash table data structure, containing some
    additional FRV-specific data.  */
-struct frv_elf_link_hash_table
+struct frvfdpic_elf_link_hash_table
 {
   struct elf_link_hash_table elf;
 
@@ -612,33 +614,33 @@ struct frv_elf_link_hash_table
 
 /* Get the FRV ELF linker hash table from a link_info structure.  */
 
-#define frv_hash_table(info) \
-  ((struct frv_elf_link_hash_table *) ((info)->hash))
-
-#define frv_got_section(info) \
-  (frv_hash_table (info)->sgot)
-#define frv_gotrel_section(info) \
-  (frv_hash_table (info)->sgotrel)
-#define frv_gotfixup_section(info) \
-  (frv_hash_table (info)->sgotfixup)
-#define frv_plt_section(info) \
-  (frv_hash_table (info)->splt)
-#define frv_pltrel_section(info) \
-  (frv_hash_table (info)->spltrel)
-#define frv_relocs_info(info) \
-  (frv_hash_table (info)->relocs_info)
-#define frv_got_initial_offset(info) \
-  (frv_hash_table (info)->got0)
-#define frv_plt_initial_offset(info) \
-  (frv_hash_table (info)->plt0)
+#define frvfdpic_hash_table(info) \
+  ((struct frvfdpic_elf_link_hash_table *) ((info)->hash))
+
+#define frvfdpic_got_section(info) \
+  (frvfdpic_hash_table (info)->sgot)
+#define frvfdpic_gotrel_section(info) \
+  (frvfdpic_hash_table (info)->sgotrel)
+#define frvfdpic_gotfixup_section(info) \
+  (frvfdpic_hash_table (info)->sgotfixup)
+#define frvfdpic_plt_section(info) \
+  (frvfdpic_hash_table (info)->splt)
+#define frvfdpic_pltrel_section(info) \
+  (frvfdpic_hash_table (info)->spltrel)
+#define frvfdpic_relocs_info(info) \
+  (frvfdpic_hash_table (info)->relocs_info)
+#define frvfdpic_got_initial_offset(info) \
+  (frvfdpic_hash_table (info)->got0)
+#define frvfdpic_plt_initial_offset(info) \
+  (frvfdpic_hash_table (info)->plt0)
 
 /* Create an FRV ELF linker hash table.  */
 
 static struct bfd_link_hash_table *
-frv_elf_link_hash_table_create (bfd *abfd)
+frvfdpic_elf_link_hash_table_create (bfd *abfd)
 {
-  struct frv_elf_link_hash_table *ret;
-  bfd_size_type amt = sizeof (struct frv_elf_link_hash_table);
+  struct frvfdpic_elf_link_hash_table *ret;
+  bfd_size_type amt = sizeof (struct frvfdpic_elf_link_hash_table);
 
   ret = bfd_zalloc (abfd, amt);
   if (ret == NULL)
@@ -657,26 +659,16 @@ frv_elf_link_hash_table_create (bfd *abfd)
 /* Decide whether a reference to a symbol can be resolved locally or
    not.  If the symbol is protected, we want the local address, but
    its function descriptor must be assigned by the dynamic linker.  */
-#define FRV_SYM_LOCAL(INFO, H) \
+#define FRVFDPIC_SYM_LOCAL(INFO, H) \
   (_bfd_elf_symbol_refs_local_p ((H), (INFO), 1) \
-   || ! elf_hash_table (INFO)->dynamic_sections_created \
-   || (/* The condition below is an ugly hack to get .scommon data to
-         be regarded as local.  For some reason the
-         ELF_LINK_HASH_DEF_REGULAR bit is not set on such common
-         symbols, and the SEC_IS_COMMON bit is not set any longer
-         when we need to perform this test.  Hopefully this
-         approximation is good enough.  */ \
-       ((H)->root.type == bfd_link_hash_defined \
-       || (H)->root.type == bfd_link_hash_defweak) \
-       && (H)->root.u.def.section->output_section \
-       && ((H)->root.u.def.section->flags & SEC_LINKER_CREATED)))
-#define FRV_FUNCDESC_LOCAL(INFO, H) \
+   || ! elf_hash_table (INFO)->dynamic_sections_created)
+#define FRVFDPIC_FUNCDESC_LOCAL(INFO, H) \
   ((H)->dynindx == -1 || ! elf_hash_table (INFO)->dynamic_sections_created)
 
 /* This structure collects information on what kind of GOT, PLT or
    function descriptors are required by relocations that reference a
    certain symbol.  */
-struct frv_pic_relocs_info
+struct frvfdpic_relocs_info
 {
   /* The index of the symbol, as stored in the relocation r_info, if
      we have a local symbol; -1 otherwise.  */
@@ -727,17 +719,17 @@ struct frv_pic_relocs_info
   unsigned sym:1;
   /* Whether we need a PLT entry for a symbol.  Should be implied by
      something like:
-     (call && symndx == -1 && ! FRV_SYM_LOCAL (info, d.h))  */
+     (call && symndx == -1 && ! FRVFDPIC_SYM_LOCAL (info, d.h))  */
   unsigned plt:1;
   /* Whether a function descriptor should be created in this link unit
      for symbol+addend.  Should be implied by something like:
      (plt || fdgotoff12 || fdgotofflos || fdgotofflohi
       || ((fd || fdgot12 || fdgotlos || fdgothilo)
-          && (symndx != -1 || FRV_FUNCDESC_LOCAL (info, d.h))))  */
+          && (symndx != -1 || FRVFDPIC_FUNCDESC_LOCAL (info, d.h))))  */
   unsigned privfd:1;
   /* Whether a lazy PLT entry is needed for this symbol+addend.
      Should be implied by something like:
-     (privfd && symndx == -1 && ! FRV_SYM_LOCAL (info, d.h)
+     (privfd && symndx == -1 && ! FRVFDPIC_SYM_LOCAL (info, d.h)
       && ! (info->flags & DF_BIND_NOW))  */
   unsigned lazyplt:1;
   /* Whether we've already emitted GOT relocations and PLT entries as
@@ -764,24 +756,24 @@ struct frv_pic_relocs_info
   bfd_vma plt_entry, lzplt_entry;
 };
 
-/* Compute a hash with the key fields of an frv_pic_relocs_info entry.  */
+/* Compute a hash with the key fields of an frvfdpic_relocs_info entry.  */
 static hashval_t
-frv_pic_relocs_info_hash (const void *entry_)
+frvfdpic_relocs_info_hash (const void *entry_)
 {
-  const struct frv_pic_relocs_info *entry = entry_;
+  const struct frvfdpic_relocs_info *entry = entry_;
 
   return (entry->symndx == -1
          ? entry->d.h->root.root.hash
          : entry->symndx + entry->d.abfd->id * 257) + entry->addend;
 }
 
-/* Test whether the key fields of two frv_pic_relocs_info entries are
+/* Test whether the key fields of two frvfdpic_relocs_info entries are
    identical.  */
 static int
-frv_pic_relocs_info_eq (const void *entry1, const void *entry2)
+frvfdpic_relocs_info_eq (const void *entry1, const void *entry2)
 {
-  const struct frv_pic_relocs_info *e1 = entry1;
-  const struct frv_pic_relocs_info *e2 = entry2;
+  const struct frvfdpic_relocs_info *e1 = entry1;
+  const struct frvfdpic_relocs_info *e2 = entry2;
 
   return e1->symndx == e2->symndx && e1->addend == e2->addend
     && (e1->symndx == -1 ? e1->d.h == e2->d.h : e1->d.abfd == e2->d.abfd);
@@ -790,14 +782,14 @@ frv_pic_relocs_info_eq (const void *entry1, const void *entry2)
 /* Find or create an entry in a hash table HT that matches the key
    fields of the given ENTRY.  If it's not found, memory for a new
    entry is allocated in ABFD's obstack.  */
-static struct frv_pic_relocs_info *
-frv_pic_relocs_info_find (struct htab *ht,
-                         bfd *abfd,
-                         const struct frv_pic_relocs_info *entry,
-                         enum insert_option insert)
+static struct frvfdpic_relocs_info *
+frvfdpic_relocs_info_find (struct htab *ht,
+                          bfd *abfd,
+                          const struct frvfdpic_relocs_info *entry,
+                          enum insert_option insert)
 {
-  struct frv_pic_relocs_info **loc =
-    (struct frv_pic_relocs_info **) htab_find_slot (ht, entry, insert);
+  struct frvfdpic_relocs_info **loc =
+    (struct frvfdpic_relocs_info **) htab_find_slot (ht, entry, insert);
 
   if (! loc)
     return NULL;
@@ -822,47 +814,47 @@ frv_pic_relocs_info_find (struct htab *ht,
 /* Obtain the address of the entry in HT associated with H's symbol +
    addend, creating a new entry if none existed.  ABFD is only used
    for memory allocation purposes.  */
-inline static struct frv_pic_relocs_info *
-frv_pic_relocs_info_for_global (struct htab *ht,
-                               bfd *abfd,
-                               struct elf_link_hash_entry *h,
-                               bfd_vma addend,
-                               enum insert_option insert)
+inline static struct frvfdpic_relocs_info *
+frvfdpic_relocs_info_for_global (struct htab *ht,
+                                bfd *abfd,
+                                struct elf_link_hash_entry *h,
+                                bfd_vma addend,
+                                enum insert_option insert)
 {
-  struct frv_pic_relocs_info entry;
+  struct frvfdpic_relocs_info entry;
 
   entry.symndx = -1;
   entry.d.h = h;
   entry.addend = addend;
 
-  return frv_pic_relocs_info_find (ht, abfd, &entry, insert);
+  return frvfdpic_relocs_info_find (ht, abfd, &entry, insert);
 }
 
 /* Obtain the address of the entry in HT associated with the SYMNDXth
    local symbol of the input bfd ABFD, plus the addend, creating a new
-   entry if none existed.  */  
-inline static struct frv_pic_relocs_info *
-frv_pic_relocs_info_for_local (struct htab *ht,
-                              bfd *abfd,
-                              long symndx,
-                              bfd_vma addend,
-                              enum insert_option insert)
+   entry if none existed.  */
+inline static struct frvfdpic_relocs_info *
+frvfdpic_relocs_info_for_local (struct htab *ht,
+                               bfd *abfd,
+                               long symndx,
+                               bfd_vma addend,
+                               enum insert_option insert)
 {
-  struct frv_pic_relocs_info entry;
+  struct frvfdpic_relocs_info entry;
 
   entry.symndx = symndx;
   entry.d.abfd = abfd;
   entry.addend = addend;
 
-  return frv_pic_relocs_info_find (ht, abfd, &entry, insert);
+  return frvfdpic_relocs_info_find (ht, abfd, &entry, insert);
 }
 
 /* Merge fields set by check_relocs() of two entries that end up being
    mapped to the same (presumably global) symbol.  */
 
 inline static void
-frv_pic_merge_early_relocs_info (struct frv_pic_relocs_info *e2,
-                                struct frv_pic_relocs_info const *e1)
+frvfdpic_pic_merge_early_relocs_info (struct frvfdpic_relocs_info *e2,
+                                     struct frvfdpic_relocs_info const *e1)
 {
   e2->got12 |= e1->got12;
   e2->gotlos |= e1->gotlos;
@@ -879,8 +871,8 @@ frv_pic_merge_early_relocs_info (struct frv_pic_relocs_info *e2,
   e2->sym |= e1->sym;
 
 #if 0
-  /* These are set in _frv_count_got_plt_entries() or later, and this
-     function is only called in _frv_resolve_final_relocs_info(), that
+  /* These are set in _frvfdpic_count_got_plt_entries() or later, and this
+     function is only called in _frvfdpic_resolve_final_relocs_info(), that
      runs just before it, so we don't have to worry about the fields
      below.  */
 
@@ -914,15 +906,15 @@ frv_pic_merge_early_relocs_info (struct frv_pic_relocs_info *e2,
    32767, counting from 0).  All other lazy PLT entries branch to it
    in a single instruction.  */
 
-#define FRV_LZPLT_BLOCK_SIZE ((bfd_vma) 8 * 65535 + 4)
-#define FRV_LZPLT_RESOLV_LOC (8 * 32767)
+#define FRVFDPIC_LZPLT_BLOCK_SIZE ((bfd_vma) 8 * 65535 + 4)
+#define FRVFDPIC_LZPLT_RESOLV_LOC (8 * 32767)
 
 /* Add a dynamic relocation to the SRELOC section.  */
 
 inline static bfd_vma
-_frv_add_dyn_reloc (bfd *output_bfd, asection *sreloc, bfd_vma offset,
-                   int reloc_type, long dynindx, bfd_vma addend,
-                   struct frv_pic_relocs_info *entry)
+_frvfdpic_add_dyn_reloc (bfd *output_bfd, asection *sreloc, bfd_vma offset,
+                        int reloc_type, long dynindx, bfd_vma addend,
+                        struct frvfdpic_relocs_info *entry)
 {
   Elf_Internal_Rela outrel;
   bfd_vma reloc_offset;
@@ -932,13 +924,23 @@ _frv_add_dyn_reloc (bfd *output_bfd, asection *sreloc, bfd_vma offset,
   outrel.r_addend = addend;
 
   reloc_offset = sreloc->reloc_count * sizeof (Elf32_External_Rel);
-  BFD_ASSERT (reloc_offset < sreloc->_raw_size);
+  BFD_ASSERT (reloc_offset < sreloc->size);
   bfd_elf32_swap_reloc_out (output_bfd, &outrel,
                            sreloc->contents + reloc_offset);
   sreloc->reloc_count++;
 
-  BFD_ASSERT (entry->dynrelocs > 0);
-  entry->dynrelocs--;
+  /* If the entry's index is zero, this relocation was probably to a
+     linkonce section that got discarded.  We reserved a dynamic
+     relocation, but it was for another entry than the one we got at
+     the time of emitting the relocation.  Unfortunately there's no
+     simple way for us to catch this situation, since the relocation
+     is cleared right before calling relocate_section, at which point
+     we no longer know what the relocation used to point to.  */
+  if (entry->symndx)
+    {
+      BFD_ASSERT (entry->dynrelocs > 0);
+      entry->dynrelocs--;
+    }
 
   return reloc_offset;
 }
@@ -946,8 +948,8 @@ _frv_add_dyn_reloc (bfd *output_bfd, asection *sreloc, bfd_vma offset,
 /* Add a fixup to the ROFIXUP section.  */
 
 static bfd_vma
-_frv_add_rofixup (bfd *output_bfd, asection *rofixup, bfd_vma offset,
-                 struct frv_pic_relocs_info *entry)
+_frvfdpic_add_rofixup (bfd *output_bfd, asection *rofixup, bfd_vma offset,
+                      struct frvfdpic_relocs_info *entry)
 {
   bfd_vma fixup_offset;
 
@@ -957,13 +959,15 @@ _frv_add_rofixup (bfd *output_bfd, asection *rofixup, bfd_vma offset,
   fixup_offset = rofixup->reloc_count * 4;
   if (rofixup->contents)
     {
-      BFD_ASSERT (fixup_offset < rofixup->_raw_size);
+      BFD_ASSERT (fixup_offset < rofixup->size);
       bfd_put_32 (output_bfd, offset, rofixup->contents + fixup_offset);
     }
   rofixup->reloc_count++;
 
-  if (entry)
+  if (entry && entry->symndx)
     {
+      /* See discussion about symndx == 0 in _frvfdpic_add_dyn_reloc
+        above.  */
       BFD_ASSERT (entry->fixups > 0);
       entry->fixups--;
     }
@@ -975,7 +979,7 @@ _frv_add_rofixup (bfd *output_bfd, asection *rofixup, bfd_vma offset,
    located.  */
 
 static unsigned
-_frv_osec_to_segment (bfd *output_bfd, asection *osec)
+_frvfdpic_osec_to_segment (bfd *output_bfd, asection *osec)
 {
   struct elf_segment_map *m;
   Elf_Internal_Phdr *p;
@@ -1000,9 +1004,9 @@ _frv_osec_to_segment (bfd *output_bfd, asection *osec)
 }
 
 inline static bfd_boolean
-_frv_osec_readonly_p (bfd *output_bfd, asection *osec)
+_frvfdpic_osec_readonly_p (bfd *output_bfd, asection *osec)
 {
-  unsigned seg = _frv_osec_to_segment (output_bfd, osec);
+  unsigned seg = _frvfdpic_osec_to_segment (output_bfd, osec);
 
   return ! (elf_tdata (output_bfd)->phdr[seg].p_flags & PF_W);
 }
@@ -1011,13 +1015,13 @@ _frv_osec_readonly_p (bfd *output_bfd, asection *osec)
    code for PLT and lazy PLT entries.  */
 
 inline static bfd_boolean
-_frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
-                                 bfd *output_bfd,
-                                 struct bfd_link_info *info,
-                                 asection *sec,
-                                 Elf_Internal_Sym *sym,
-                                 bfd_vma addend)
-                                 
+_frvfdpic_emit_got_relocs_plt_entries (struct frvfdpic_relocs_info *entry,
+                                      bfd *output_bfd,
+                                      struct bfd_link_info *info,
+                                      asection *sec,
+                                      Elf_Internal_Sym *sym,
+                                      bfd_vma addend)
+
 {
   bfd_vma fd_lazy_rel_offset = (bfd_vma)-1;
   int dynindx = -1;
@@ -1051,7 +1055,8 @@ _frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
 
       /* If the symbol is dynamic but binds locally, use
         section+offset.  */
-      if (sec && (entry->symndx != -1 || FRV_SYM_LOCAL (info, entry->d.h)))
+      if (sec && (entry->symndx != -1
+                 || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
        {
          if (entry->symndx == -1)
            ad += entry->d.h->root.u.def.value;
@@ -1068,32 +1073,36 @@ _frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
         omit the dynamic relocation as long as the symbol is local to
         this module.  */
       if (info->executable && !info->pie
-         && (entry->symndx != -1 || FRV_SYM_LOCAL (info, entry->d.h)))
+         && (entry->symndx != -1
+             || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
        {
          if (sec)
            ad += sec->output_section->vma;
          if (entry->symndx != -1
              || entry->d.h->root.type != bfd_link_hash_undefweak)
-           _frv_add_rofixup (output_bfd, frv_gotfixup_section (info),
-                             frv_got_section (info)->output_section->vma
-                             + frv_got_section (info)->output_offset
-                             + frv_got_initial_offset (info)
-                             + entry->got_entry, entry);
+           _frvfdpic_add_rofixup (output_bfd,
+                                  frvfdpic_gotfixup_section (info),
+                                  frvfdpic_got_section (info)->output_section
+                                  ->vma
+                                  + frvfdpic_got_section (info)->output_offset
+                                  + frvfdpic_got_initial_offset (info)
+                                  + entry->got_entry, entry);
        }
       else
-       _frv_add_dyn_reloc (output_bfd, frv_gotrel_section (info),
-                           _bfd_elf_section_offset
-                           (output_bfd, info,
-                            frv_got_section (info),
-                            frv_got_initial_offset (info)
-                            + entry->got_entry)
-                           + frv_got_section (info)->output_section->vma
-                           + frv_got_section (info)->output_offset,
-                           R_FRV_32, idx, ad, entry);
-       
+       _frvfdpic_add_dyn_reloc (output_bfd, frvfdpic_gotrel_section (info),
+                                _bfd_elf_section_offset
+                                (output_bfd, info,
+                                 frvfdpic_got_section (info),
+                                 frvfdpic_got_initial_offset (info)
+                                 + entry->got_entry)
+                                + frvfdpic_got_section (info)
+                                ->output_section->vma
+                                + frvfdpic_got_section (info)->output_offset,
+                                R_FRV_32, idx, ad, entry);
+
       bfd_put_32 (output_bfd, ad,
-                 frv_got_section (info)->contents
-                 + frv_got_initial_offset (info)
+                 frvfdpic_got_section (info)->contents
+                 + frvfdpic_got_initial_offset (info)
                  + entry->got_entry);
     }
 
@@ -1103,10 +1112,10 @@ _frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
     {
       int reloc, idx;
       bfd_vma ad = 0;
-      
+
       if (! (entry->symndx == -1
             && entry->d.h->root.type == bfd_link_hash_undefweak
-            && FRV_SYM_LOCAL (info, entry->d.h)))
+            && FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
        {
          /* If the symbol is dynamic and there may be dynamic symbol
             resolution because we are, or are linked with, a shared
@@ -1115,8 +1124,9 @@ _frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
             symbol needs a non-local function descriptor but binds
             locally (e.g., its visibility is protected, emit a
             dynamic relocation decayed to section+offset.  */
-         if (entry->symndx == -1 && ! FRV_FUNCDESC_LOCAL (info, entry->d.h)
-             && FRV_SYM_LOCAL (info, entry->d.h)
+         if (entry->symndx == -1
+             && ! FRVFDPIC_FUNCDESC_LOCAL (info, entry->d.h)
+             && FRVFDPIC_SYM_LOCAL (info, entry->d.h)
              && !(info->executable && !info->pie))
            {
              reloc = R_FRV_FUNCDESC;
@@ -1126,7 +1136,7 @@ _frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
                + entry->d.h->root.u.def.value;
            }
          else if (entry->symndx == -1
-                  && ! FRV_FUNCDESC_LOCAL (info, entry->d.h))
+                  && ! FRVFDPIC_FUNCDESC_LOCAL (info, entry->d.h))
            {
              reloc = R_FRV_FUNCDESC;
              idx = dynindx;
@@ -1141,10 +1151,10 @@ _frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
              if (elf_hash_table (info)->dynamic_sections_created)
                BFD_ASSERT (entry->privfd);
              reloc = R_FRV_32;
-             idx = elf_section_data (frv_got_section (info)
+             idx = elf_section_data (frvfdpic_got_section (info)
                                      ->output_section)->dynindx;
-             ad = frv_got_section (info)->output_offset
-               + frv_got_initial_offset (info) + entry->fd_entry;
+             ad = frvfdpic_got_section (info)->output_offset
+               + frvfdpic_got_initial_offset (info) + entry->fd_entry;
            }
 
          /* If there is room for dynamic symbol resolution, emit the
@@ -1155,30 +1165,36 @@ _frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
             of the private descriptor ourselves.  */
          if (info->executable && !info->pie
              && (entry->symndx != -1
-                 || FRV_FUNCDESC_LOCAL (info, entry->d.h)))
+                 || FRVFDPIC_FUNCDESC_LOCAL (info, entry->d.h)))
            {
-             ad += frv_got_section (info)->output_section->vma;
-             _frv_add_rofixup (output_bfd, frv_gotfixup_section (info),
-                               frv_got_section (info)->output_section->vma
-                               + frv_got_section (info)->output_offset
-                               + frv_got_initial_offset (info)
-                               + entry->fdgot_entry, entry);
+             ad += frvfdpic_got_section (info)->output_section->vma;
+             _frvfdpic_add_rofixup (output_bfd,
+                                    frvfdpic_gotfixup_section (info),
+                                    frvfdpic_got_section (info)
+                                    ->output_section->vma
+                                    + frvfdpic_got_section (info)
+                                    ->output_offset
+                                    + frvfdpic_got_initial_offset (info)
+                                    + entry->fdgot_entry, entry);
            }
          else
-           _frv_add_dyn_reloc (output_bfd, frv_gotrel_section (info),
-                               _bfd_elf_section_offset
-                               (output_bfd, info,
-                                frv_got_section (info),
-                                frv_got_initial_offset (info)
-                                + entry->fdgot_entry)
-                               + frv_got_section (info)->output_section->vma
-                               + frv_got_section (info)->output_offset,
-                               reloc, idx, ad, entry);
+           _frvfdpic_add_dyn_reloc (output_bfd,
+                                    frvfdpic_gotrel_section (info),
+                                    _bfd_elf_section_offset
+                                    (output_bfd, info,
+                                     frvfdpic_got_section (info),
+                                     frvfdpic_got_initial_offset (info)
+                                     + entry->fdgot_entry)
+                                    + frvfdpic_got_section (info)
+                                    ->output_section->vma
+                                    + frvfdpic_got_section (info)
+                                    ->output_offset,
+                                    reloc, idx, ad, entry);
        }
 
       bfd_put_32 (output_bfd, ad,
-                 frv_got_section (info)->contents
-                 + frv_got_initial_offset (info)
+                 frvfdpic_got_section (info)->contents
+                 + frvfdpic_got_initial_offset (info)
                  + entry->fdgot_entry);
     }
 
@@ -1193,7 +1209,8 @@ _frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
 
       /* If the symbol is dynamic but binds locally, use
         section+offset.  */
-      if (sec && (entry->symndx != -1 || FRV_SYM_LOCAL (info, entry->d.h)))
+      if (sec && (entry->symndx != -1
+                 || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
        {
          if (entry->symndx == -1)
            ad += entry->d.h->root.u.def.value;
@@ -1210,7 +1227,7 @@ _frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
         omit the dynamic relocation as long as the symbol is local to
         this module.  */
       if (info->executable && !info->pie
-         && (entry->symndx != -1 || FRV_SYM_LOCAL (info, entry->d.h)))
+         && (entry->symndx != -1 || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
        {
          if (sec)
            ad += sec->output_section->vma;
@@ -1218,32 +1235,41 @@ _frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
          if (entry->symndx != -1
              || entry->d.h->root.type != bfd_link_hash_undefweak)
            {
-             _frv_add_rofixup (output_bfd, frv_gotfixup_section (info),
-                               frv_got_section (info)->output_section->vma
-                               + frv_got_section (info)->output_offset
-                               + frv_got_initial_offset (info)
-                               + entry->fd_entry, entry);
-             _frv_add_rofixup (output_bfd, frv_gotfixup_section (info),
-                               frv_got_section (info)->output_section->vma
-                               + frv_got_section (info)->output_offset
-                               + frv_got_initial_offset (info)
-                               + entry->fd_entry + 4, entry);
+             _frvfdpic_add_rofixup (output_bfd,
+                                    frvfdpic_gotfixup_section (info),
+                                    frvfdpic_got_section (info)
+                                    ->output_section->vma
+                                    + frvfdpic_got_section (info)
+                                    ->output_offset
+                                    + frvfdpic_got_initial_offset (info)
+                                    + entry->fd_entry, entry);
+             _frvfdpic_add_rofixup (output_bfd,
+                                    frvfdpic_gotfixup_section (info),
+                                    frvfdpic_got_section (info)
+                                    ->output_section->vma
+                                    + frvfdpic_got_section (info)
+                                    ->output_offset
+                                    + frvfdpic_got_initial_offset (info)
+                                    + entry->fd_entry + 4, entry);
            }
        }
       else
        {
          ofst =
-           _frv_add_dyn_reloc (output_bfd,
-                               entry->lazyplt ? frv_pltrel_section (info)
-                               : frv_gotrel_section (info),
-                               _bfd_elf_section_offset
-                               (output_bfd, info,
-                                frv_got_section (info),
-                                frv_got_initial_offset (info)
-                                + entry->fd_entry)
-                               + frv_got_section (info)->output_section->vma
-                               + frv_got_section (info)->output_offset,
-                               R_FRV_FUNCDESC_VALUE, idx, ad, entry);
+           _frvfdpic_add_dyn_reloc (output_bfd,
+                                    entry->lazyplt
+                                    ? frvfdpic_pltrel_section (info)
+                                    : frvfdpic_gotrel_section (info),
+                                    _bfd_elf_section_offset
+                                    (output_bfd, info,
+                                     frvfdpic_got_section (info),
+                                     frvfdpic_got_initial_offset (info)
+                                     + entry->fd_entry)
+                                    + frvfdpic_got_section (info)
+                                    ->output_section->vma
+                                    + frvfdpic_got_section (info)
+                                    ->output_offset,
+                                    R_FRV_FUNCDESC_VALUE, idx, ad, entry);
        }
 
       /* If we've omitted the dynamic relocation, just emit the fixed
@@ -1251,15 +1277,15 @@ _frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
       if (info->executable && !info->pie && sec && sec->output_section)
        {
          lowword = ad;
-         highword = frv_got_section (info)->output_section->vma
-           + frv_got_section (info)->output_offset
-           + frv_got_initial_offset (info);
+         highword = frvfdpic_got_section (info)->output_section->vma
+           + frvfdpic_got_section (info)->output_offset
+           + frvfdpic_got_initial_offset (info);
        }
       else if (entry->lazyplt)
        {
          if (ad)
            return FALSE;
-         
+
          fd_lazy_rel_offset = ofst;
 
          /* A function descriptor used for lazy or local resolving is
@@ -1269,10 +1295,10 @@ _frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
             entry point, that must be within the memory region
             assigned to that section.  */
          lowword = entry->lzplt_entry + 4
-           + frv_plt_section (info)->output_offset
-           + frv_plt_section (info)->output_section->vma;
-         highword = _frv_osec_to_segment 
-           (output_bfd, frv_plt_section (info)->output_section);
+           + frvfdpic_plt_section (info)->output_offset
+           + frvfdpic_plt_section (info)->output_section->vma;
+         highword = _frvfdpic_osec_to_segment
+           (output_bfd, frvfdpic_plt_section (info)->output_section);
        }
       else
        {
@@ -1284,23 +1310,25 @@ _frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
              && entry->d.h->dynindx == idx)
            highword = 0;
          else
-           highword = _frv_osec_to_segment (output_bfd, sec->output_section);
+           highword = _frvfdpic_osec_to_segment
+             (output_bfd, sec->output_section);
        }
 
       bfd_put_32 (output_bfd, lowword,
-                 frv_got_section (info)->contents
-                 + frv_got_initial_offset (info)
+                 frvfdpic_got_section (info)->contents
+                 + frvfdpic_got_initial_offset (info)
                  + entry->fd_entry);
       bfd_put_32 (output_bfd, highword,
-                 frv_got_section (info)->contents
-                 + frv_got_initial_offset (info)
+                 frvfdpic_got_section (info)->contents
+                 + frvfdpic_got_initial_offset (info)
                  + entry->fd_entry + 4);
     }
 
   /* Generate code for the PLT entry.  */
   if (entry->plt_entry != (bfd_vma) -1)
     {
-      bfd_byte *plt_code = frv_plt_section (info)->contents + entry->plt_entry;
+      bfd_byte *plt_code = frvfdpic_plt_section (info)->contents
+       + entry->plt_entry;
 
       BFD_ASSERT (entry->fd_entry);
 
@@ -1353,17 +1381,17 @@ _frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
   /* Generate code for the lazy PLT entry.  */
   if (entry->lzplt_entry != (bfd_vma) -1)
     {
-      bfd_byte *lzplt_code = frv_plt_section (info)->contents
+      bfd_byte *lzplt_code = frvfdpic_plt_section (info)->contents
        + entry->lzplt_entry;
       bfd_vma resolverStub_addr;
 
       bfd_put_32 (output_bfd, fd_lazy_rel_offset, lzplt_code);
       lzplt_code += 4;
 
-      resolverStub_addr = entry->lzplt_entry / FRV_LZPLT_BLOCK_SIZE
-       * FRV_LZPLT_BLOCK_SIZE + FRV_LZPLT_RESOLV_LOC;
-      if (resolverStub_addr >= frv_plt_initial_offset (info))
-       resolverStub_addr = frv_plt_initial_offset (info) - 12;
+      resolverStub_addr = entry->lzplt_entry / FRVFDPIC_LZPLT_BLOCK_SIZE
+       * FRVFDPIC_LZPLT_BLOCK_SIZE + FRVFDPIC_LZPLT_RESOLV_LOC;
+      if (resolverStub_addr >= frvfdpic_plt_initial_offset (info))
+       resolverStub_addr = frvfdpic_plt_initial_offset (info) - 12;
 
       if (entry->lzplt_entry == resolverStub_addr)
        {
@@ -1767,8 +1795,8 @@ frv_info_to_howto_rela (abfd, cache_ptr, dst)
 
 /* Set the howto pointer for an FRV ELF REL reloc.  */
 static void
-frv_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
-                      arelent *cache_ptr, Elf_Internal_Rela *dst)
+frvfdpic_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
+                           arelent *cache_ptr, Elf_Internal_Rela *dst)
 {
   unsigned int r_type;
 
@@ -1869,24 +1897,24 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
   sym_hashes = elf_sym_hashes (input_bfd);
   relend     = relocs + input_section->reloc_count;
 
-  isec_segment = _frv_osec_to_segment (output_bfd,
-                                      input_section->output_section);
-  if (frv_got_section (info))
-    got_segment = _frv_osec_to_segment (output_bfd,
-                                       frv_got_section (info)
-                                       ->output_section);
+  isec_segment = _frvfdpic_osec_to_segment (output_bfd,
+                                           input_section->output_section);
+  if (IS_FDPIC (output_bfd) && frvfdpic_got_section (info))
+    got_segment = _frvfdpic_osec_to_segment (output_bfd,
+                                            frvfdpic_got_section (info)
+                                            ->output_section);
   else
     got_segment = -1;
-  if (frv_gotfixup_section (info))
-    gprel_segment = _frv_osec_to_segment (output_bfd,
-                                         frv_gotfixup_section (info)
-                                         ->output_section);
+  if (IS_FDPIC (output_bfd) && frvfdpic_gotfixup_section (info))
+    gprel_segment = _frvfdpic_osec_to_segment (output_bfd,
+                                              frvfdpic_gotfixup_section (info)
+                                              ->output_section);
   else
     gprel_segment = -1;
-  if (elf_hash_table (info)->dynamic_sections_created)
-    plt_segment = _frv_osec_to_segment (output_bfd,
-                                       frv_plt_section (info)
-                                       ->output_section);
+  if (IS_FDPIC (output_bfd) && elf_hash_table (info)->dynamic_sections_created)
+    plt_segment = _frvfdpic_osec_to_segment (output_bfd,
+                                            frvfdpic_plt_section (info)
+                                            ->output_section);
   else
     plt_segment = -1;
 
@@ -1902,7 +1930,7 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
       const char * name = NULL;
       int r_type;
       asection *osec;
-      struct frv_pic_relocs_info *picrel;
+      struct frvfdpic_relocs_info *picrel;
       bfd_vma orig_addend = rel->r_addend;
 
       r_type = ELF32_R_TYPE (rel->r_info);
@@ -1940,7 +1968,7 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
 
          if ((h->root.type == bfd_link_hash_defined
               || h->root.type == bfd_link_hash_defweak)
-             && ! FRV_SYM_LOCAL (info, h))
+             && ! FRVFDPIC_SYM_LOCAL (info, h))
            {
              sec = NULL;
              relocation = 0;
@@ -1978,6 +2006,9 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
        {
        case R_FRV_LABEL24:
        case R_FRV_32:
+         if (! IS_FDPIC (output_bfd))
+           goto non_fdpic;
+
        case R_FRV_GOT12:
        case R_FRV_GOTHI:
        case R_FRV_GOTLO:
@@ -1993,25 +2024,26 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
        case R_FRV_FUNCDESC:
        case R_FRV_FUNCDESC_VALUE:
          if (h != NULL)
-           picrel = frv_pic_relocs_info_for_global (frv_relocs_info (info),
-                                                    input_bfd, h,
-                                                    orig_addend, INSERT);
+           picrel = frvfdpic_relocs_info_for_global (frvfdpic_relocs_info
+                                                     (info), input_bfd, h,
+                                                     orig_addend, INSERT);
          else
            /* In order to find the entry we created before, we must
               use the original addend, not the one that may have been
               modified by _bfd_elf_rela_local_sym().  */
-           picrel = frv_pic_relocs_info_for_local (frv_relocs_info (info),
-                                                   input_bfd, r_symndx,
-                                                   orig_addend, INSERT);
+           picrel = frvfdpic_relocs_info_for_local (frvfdpic_relocs_info
+                                                    (info), input_bfd, r_symndx,
+                                                    orig_addend, INSERT);
          if (! picrel)
            return FALSE;
 
-         if (!_frv_emit_got_relocs_plt_entries (picrel, output_bfd, info,
-                                                osec, sym, rel->r_addend))
+         if (!_frvfdpic_emit_got_relocs_plt_entries (picrel, output_bfd, info,
+                                                     osec, sym,
+                                                     rel->r_addend))
            {
-             info->callbacks->warning
-               (info, _("Dynamic relocation references symbol with nonzero addend"),
-                name, input_bfd, input_section, rel->r_offset);
+             (*_bfd_error_handler)
+               (_("%B: relocation at `%A+0x%x' references symbol `%s' with nonzero addend"),
+                input_bfd, input_section, rel->r_offset, name);
              return FALSE;
 
            }
@@ -2019,8 +2051,9 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
          break;
 
        default:
+       non_fdpic:
          picrel = NULL;
-         if (h && ! FRV_SYM_LOCAL (info, h))
+         if (h && ! FRVFDPIC_SYM_LOCAL (info, h))
            {
              info->callbacks->warning
                (info, _("relocation references symbol not defined in the module"),
@@ -2034,10 +2067,12 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
        {
        case R_FRV_LABEL24:
          check_segment[0] = isec_segment;
-         if (picrel->plt)
+         if (! IS_FDPIC (output_bfd))
+           check_segment[1] = isec_segment;
+         else if (picrel->plt)
            {
-             relocation = frv_plt_section (info)->output_section->vma
-               + frv_plt_section (info)->output_offset
+             relocation = frvfdpic_plt_section (info)->output_section->vma
+               + frvfdpic_plt_section (info)->output_offset
                + picrel->plt_entry;
              check_segment[1] = plt_segment;
            }
@@ -2050,7 +2085,7 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
            check_segment[1] = check_segment[0];
          else
            check_segment[1] = sec
-             ? _frv_osec_to_segment (output_bfd, sec->output_section)
+             ? _frvfdpic_osec_to_segment (output_bfd, sec->output_section)
              : (unsigned)-1;
          break;
 
@@ -2060,23 +2095,23 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
          relocation = picrel->got_entry;
          check_segment[0] = check_segment[1] = got_segment;
          break;
-         
+
        case R_FRV_FUNCDESC_GOT12:
        case R_FRV_FUNCDESC_GOTHI:
        case R_FRV_FUNCDESC_GOTLO:
          relocation = picrel->fdgot_entry;
          check_segment[0] = check_segment[1] = got_segment;
          break;
-         
+
        case R_FRV_GOTOFFHI:
        case R_FRV_GOTOFF12:
        case R_FRV_GOTOFFLO:
-         relocation -= frv_got_section (info)->output_section->vma
-           + frv_got_section (info)->output_offset
-           + frv_got_initial_offset (info);
+         relocation -= frvfdpic_got_section (info)->output_section->vma
+           + frvfdpic_got_section (info)->output_offset
+           + frvfdpic_got_initial_offset (info);
          check_segment[0] = got_segment;
          check_segment[1] = sec
-           ? _frv_osec_to_segment (output_bfd, sec->output_section)
+           ? _frvfdpic_osec_to_segment (output_bfd, sec->output_section)
            : (unsigned)-1;
          break;
 
@@ -2093,7 +2128,7 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
            bfd_vma addend = rel->r_addend;
 
            if (! (h && h->root.type == bfd_link_hash_undefweak
-                  && FRV_SYM_LOCAL (info, h)))
+                  && FRVFDPIC_SYM_LOCAL (info, h)))
              {
                /* If the symbol is dynamic and there may be dynamic
                   symbol resolution because we are or are linked with a
@@ -2103,8 +2138,8 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
                   descriptor but binds locally (e.g., its visibility is
                   protected, emit a dynamic relocation decayed to
                   section+offset.  */
-               if (h && ! FRV_FUNCDESC_LOCAL (info, h)
-                   && FRV_SYM_LOCAL (info, h)
+               if (h && ! FRVFDPIC_FUNCDESC_LOCAL (info, h)
+                   && FRVFDPIC_SYM_LOCAL (info, h)
                    && !(info->executable && !info->pie))
                  {
                    dynindx = elf_section_data (h->root.u.def.section
@@ -2112,7 +2147,7 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
                    addend += h->root.u.def.section->output_offset
                      + h->root.u.def.value;
                  }
-               else if (h && ! FRV_FUNCDESC_LOCAL (info, h))
+               else if (h && ! FRVFDPIC_FUNCDESC_LOCAL (info, h))
                  {
                    if (addend)
                      {
@@ -2129,10 +2164,10 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
                       descriptor, so reference it directly.  */
                    BFD_ASSERT (picrel->privfd);
                    r_type = R_FRV_32;
-                   dynindx = elf_section_data (frv_got_section (info)
+                   dynindx = elf_section_data (frvfdpic_got_section (info)
                                                ->output_section)->dynindx;
-                   addend = frv_got_section (info)->output_offset
-                     + frv_got_initial_offset (info)
+                   addend = frvfdpic_got_section (info)->output_offset
+                     + frvfdpic_got_initial_offset (info)
                      + picrel->fd_entry;
                  }
 
@@ -2143,15 +2178,16 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
                   be zero, which means we can and should compute the
                   address of the private descriptor ourselves.  */
                if (info->executable && !info->pie
-                   && (!h || FRV_FUNCDESC_LOCAL (info, h)))
+                   && (!h || FRVFDPIC_FUNCDESC_LOCAL (info, h)))
                  {
-                   addend += frv_got_section (info)->output_section->vma;
+                   addend += frvfdpic_got_section (info)->output_section->vma;
                    if ((bfd_get_section_flags (output_bfd,
                                                input_section->output_section)
                         & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
                      {
-                       if (_frv_osec_readonly_p (output_bfd,
-                                                 input_section->output_section))
+                       if (_frvfdpic_osec_readonly_p (output_bfd,
+                                                      input_section
+                                                      ->output_section))
                          {
                            info->callbacks->warning
                              (info,
@@ -2159,22 +2195,25 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
                               name, input_bfd, input_section, rel->r_offset);
                            return FALSE;
                          }
-                       _frv_add_rofixup (output_bfd,
-                                         frv_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);
+                       _frvfdpic_add_rofixup (output_bfd,
+                                              frvfdpic_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);
                      }
                  }
                else if ((bfd_get_section_flags (output_bfd,
                                                 input_section->output_section)
                          & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
                  {
-                   if (_frv_osec_readonly_p (output_bfd,
-                                             input_section->output_section))
+                   if (_frvfdpic_osec_readonly_p (output_bfd,
+                                                  input_section
+                                                  ->output_section))
                      {
                        info->callbacks->warning
                          (info,
@@ -2182,14 +2221,18 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
                           name, input_bfd, input_section, rel->r_offset);
                        return FALSE;
                      }
-                   _frv_add_dyn_reloc (output_bfd, frv_gotrel_section (info),
-                                       _bfd_elf_section_offset
-                                       (output_bfd, info,
-                                        input_section, rel->r_offset)
-                                       + input_section->output_section->vma
-                                       + input_section->output_offset,
-                                       r_type, dynindx, addend, picrel);
+                   _frvfdpic_add_dyn_reloc (output_bfd,
+                                            frvfdpic_gotrel_section (info),
+                                            _bfd_elf_section_offset
+                                            (output_bfd, info,
+                                             input_section, rel->r_offset)
+                                            + input_section
+                                            ->output_section->vma
+                                            + input_section->output_offset,
+                                            r_type, dynindx, addend, picrel);
                  }
+               else
+                 addend += frvfdpic_got_section (info)->output_section->vma;
              }
 
            /* We want the addend in-place because dynamic
@@ -2201,6 +2244,12 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
          break;
 
        case R_FRV_32:
+         if (! IS_FDPIC (output_bfd))
+           {
+             check_segment[0] = check_segment[1] = -1;
+             break;
+           }
+         /* Fall through.  */
        case R_FRV_FUNCDESC_VALUE:
          {
            int dynindx;
@@ -2208,7 +2257,7 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
 
            /* If the symbol is dynamic but binds locally, use
               section+offset.  */
-           if (h && ! FRV_SYM_LOCAL (info, h))
+           if (h && ! FRVFDPIC_SYM_LOCAL (info, h))
              {
                if (addend && r_type == R_FRV_FUNCDESC_VALUE)
                  {
@@ -2240,17 +2289,18 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
               is defined in the current link unit (which is implied
               by its output section not being NULL).  */
            if (info->executable && !info->pie
-               && (!h || FRV_SYM_LOCAL (info, h)))
+               && (!h || FRVFDPIC_SYM_LOCAL (info, h)))
              {
                if (osec)
                  addend += osec->output_section->vma;
-               if ((elf_elfheader (input_bfd)->e_flags & EF_FRV_FDPIC)
+               if (IS_FDPIC (input_bfd)
                    && (bfd_get_section_flags (output_bfd,
                                               input_section->output_section)
                        & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
                  {
-                   if (_frv_osec_readonly_p (output_bfd,
-                                             input_section->output_section))
+                   if (_frvfdpic_osec_readonly_p (output_bfd,
+                                                  input_section
+                                                  ->output_section))
                      {
                        info->callbacks->warning
                          (info,
@@ -2260,18 +2310,20 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
                      }
                    if (!h || h->root.type != bfd_link_hash_undefweak)
                      {
-                       _frv_add_rofixup (output_bfd,
-                                         frv_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);
+                       _frvfdpic_add_rofixup (output_bfd,
+                                              frvfdpic_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);
                        if (r_type == R_FRV_FUNCDESC_VALUE)
-                         _frv_add_rofixup
+                         _frvfdpic_add_rofixup
                            (output_bfd,
-                            frv_gotfixup_section (info),
+                            frvfdpic_gotfixup_section (info),
                             _bfd_elf_section_offset
                             (output_bfd, info,
                              input_section, rel->r_offset)
@@ -2286,8 +2338,9 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
                                            input_section->output_section)
                     & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
                  {
-                   if (_frv_osec_readonly_p (output_bfd,
-                                             input_section->output_section))
+                   if (_frvfdpic_osec_readonly_p (output_bfd,
+                                                  input_section
+                                                  ->output_section))
                      {
                        info->callbacks->warning
                          (info,
@@ -2295,14 +2348,18 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
                           name, input_bfd, input_section, rel->r_offset);
                        return FALSE;
                      }
-                   _frv_add_dyn_reloc (output_bfd, frv_gotrel_section (info),
-                                       _bfd_elf_section_offset
-                                       (output_bfd, info,
-                                        input_section, rel->r_offset)
-                                       + input_section->output_section->vma
-                                       + input_section->output_offset,
-                                       r_type, dynindx, addend, picrel);
+                   _frvfdpic_add_dyn_reloc (output_bfd,
+                                            frvfdpic_gotrel_section (info),
+                                            _bfd_elf_section_offset
+                                            (output_bfd, info,
+                                             input_section, rel->r_offset)
+                                            + input_section
+                                            ->output_section->vma
+                                            + input_section->output_offset,
+                                            r_type, dynindx, addend, picrel);
                  }
+               else if (osec)
+                 addend += osec->output_section->vma;
                /* We want the addend in-place because dynamic
                   relocations are REL.  Setting relocation to it
                   should arrange for it to be installed.  */
@@ -2315,11 +2372,11 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
                   the fixed addresses of the symbol and of the local
                   GOT base offset.  */
                if (info->executable && !info->pie
-                   && (!h || FRV_SYM_LOCAL (info, h)))
+                   && (!h || FRVFDPIC_SYM_LOCAL (info, h)))
                  bfd_put_32 (output_bfd,
-                             frv_got_section (info)->output_section->vma
-                             + frv_got_section (info)->output_offset
-                             + frv_got_initial_offset (info),
+                             frvfdpic_got_section (info)->output_section->vma
+                             + frvfdpic_got_section (info)->output_offset
+                             + frvfdpic_got_initial_offset (info),
                              contents + rel->r_offset + 4);
                else
                  /* A function descriptor used for lazy or local
@@ -2329,10 +2386,11 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
                     contains the offset of the lazy PLT entry entry
                     point into that section.  */
                  bfd_put_32 (output_bfd,
-                             h && ! FRV_SYM_LOCAL (info, h)
+                             h && ! FRVFDPIC_SYM_LOCAL (info, h)
                              ? 0
-                             : _frv_osec_to_segment (output_bfd,
-                                                     sec->output_section),
+                             : _frvfdpic_osec_to_segment (output_bfd,
+                                                          sec
+                                                          ->output_section),
                              contents + rel->r_offset + 4);
              }
          }
@@ -2346,22 +2404,22 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
        case R_FRV_GPRELLO:
          check_segment[0] = gprel_segment;
          check_segment[1] = sec
-           ? _frv_osec_to_segment (output_bfd, sec->output_section)
+           ? _frvfdpic_osec_to_segment (output_bfd, sec->output_section)
            : (unsigned)-1;
          break;
 
        default:
          check_segment[0] = isec_segment;
          check_segment[1] = sec
-           ? _frv_osec_to_segment (output_bfd, sec->output_section)
+           ? _frvfdpic_osec_to_segment (output_bfd, sec->output_section)
            : (unsigned)-1;
          break;
        }
 
-      if (check_segment[0] != check_segment[1]
-         && (elf_elfheader (output_bfd)->e_flags & EF_FRV_FDPIC))
+      if (check_segment[0] != check_segment[1] && IS_FDPIC (output_bfd))
        {
-#if 1
+#if 1 /* If you take this out, remove the #error from fdpic-static-6.d
+        in the ld testsuite.  */
          /* This helps catch problems in GCC while we can't do more
             than static linking.  The idea is to test whether the
             input file basename is crt0.o only once.  */
@@ -2418,10 +2476,10 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
       switch (r_type)
        {
        case R_FRV_LABEL24:
-         if (! picrel->plt)
+         if (! IS_FDPIC (output_bfd) || ! picrel->plt)
            break;
          /* Fall through.  */
-         
+
          /* When referencing a GOT entry, a function descriptor or a
             PLT, we don't want the addend to apply to the reference,
             but rather to the referenced symbol.  The actual entry
@@ -2439,7 +2497,7 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
          /* Note that we only want GOTOFFHI, not GOTOFFLO or GOTOFF12
             here, since we do want to apply the addend to the others.
             Note that we've applied the addend to GOTOFFHI before we
-            shifted it right.  */ 
+            shifted it right.  */
        case R_FRV_GOTOFFHI:
          relocation -= rel->r_addend;
          break;
@@ -2486,8 +2544,8 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
            {
            case bfd_reloc_overflow:
              r = info->callbacks->reloc_overflow
-               (info, name, howto->name, (bfd_vma) 0,
-                input_bfd, input_section, rel->r_offset);
+               (info, (h ? &h->root : NULL), name, howto->name,
+                (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
              break;
 
            case bfd_reloc_undefined:
@@ -2584,7 +2642,7 @@ static bfd_boolean
 elf32_frv_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
      bfd *abfd;
      struct bfd_link_info *info;
-     const Elf_Internal_Sym *sym;
+     Elf_Internal_Sym *sym;
      const char **namep ATTRIBUTE_UNUSED;
      flagword *flagsp ATTRIBUTE_UNUSED;
      asection **secp;
@@ -2615,7 +2673,32 @@ elf32_frv_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
 
   return TRUE;
 }
-/* Create a .got section, as well as its additional info field.  This
+
+/* We need dynamic symbols for every section, since segments can
+   relocate independently.  */
+static bfd_boolean
+_frvfdpic_link_omit_section_dynsym (bfd *output_bfd ATTRIBUTE_UNUSED,
+                                   struct bfd_link_info *info
+                                   ATTRIBUTE_UNUSED,
+                                   asection *p ATTRIBUTE_UNUSED)
+{
+  switch (elf_section_data (p)->this_hdr.sh_type)
+    {
+    case SHT_PROGBITS:
+    case SHT_NOBITS:
+      /* If sh_type is yet undecided, assume it could be
+        SHT_PROGBITS/SHT_NOBITS.  */
+    case SHT_NULL:
+      return FALSE;
+
+      /* There shouldn't be section relative relocations
+        against any other section.  */
+    default:
+      return TRUE;
+    }
+}
+
+/* Create  a .got section, as well as its additional info field.  This
    is almost entirely copied from
    elflink.c:_bfd_elf_create_got_section().  */
 
@@ -2628,6 +2711,7 @@ _frv_create_got_section (bfd *abfd, struct bfd_link_info *info)
   struct bfd_link_hash_entry *bh;
   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");
@@ -2671,62 +2755,72 @@ _frv_create_got_section (bfd *abfd, struct bfd_link_info *info)
             bed->collect, &bh)))
        return FALSE;
       h = (struct elf_link_hash_entry *) bh;
-      h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+      h->def_regular = 1;
       h->type = STT_OBJECT;
 
       /* Machine-specific: we want the symbol for executables as
         well.  */
-      if (! _bfd_elf_link_record_dynamic_symbol (info, h))
+      if (! bfd_elf_link_record_dynamic_symbol (info, h))
        return FALSE;
 
       elf_hash_table (info)->hgot = h;
     }
 
   /* The first bit of the global offset table is the header.  */
-  s->_raw_size += bed->got_header_size + bed->got_symbol_offset;
+  s->size += bed->got_header_size + bed->got_symbol_offset;
 
   /* This is the machine-specific part.  Create and initialize section
      data for the got.  */
-  frv_got_section (info) = s;
-  frv_relocs_info (info) = htab_try_create (1, frv_pic_relocs_info_hash,
-                                           frv_pic_relocs_info_eq,
-                                           (htab_del) NULL);
-  if (! frv_relocs_info (info))
-    return FALSE;
+  if (IS_FDPIC (abfd))
+    {
+      frvfdpic_got_section (info) = s;
+      frvfdpic_relocs_info (info) = htab_try_create (1, frvfdpic_relocs_info_hash,
+                                                    frvfdpic_relocs_info_eq,
+                                                    (htab_del) NULL);
+      if (! frvfdpic_relocs_info (info))
+       return FALSE;
 
-  s = bfd_make_section (abfd, ".rel.got");
-  if (s == NULL
-      || ! bfd_set_section_flags (abfd, s, (flags | SEC_READONLY))
-      || ! bfd_set_section_alignment (abfd, s, 2))
-    return FALSE;
+      s = bfd_make_section (abfd, ".rel.got");
+      if (s == NULL
+         || ! bfd_set_section_flags (abfd, s, (flags | SEC_READONLY))
+         || ! bfd_set_section_alignment (abfd, s, 2))
+       return FALSE;
 
-  frv_gotrel_section (info) = s;
+      frvfdpic_gotrel_section (info) = s;
 
-  /* Machine-specific.  */
-  s = bfd_make_section (abfd, ".rofixup");
-  if (s == NULL
-      || ! bfd_set_section_flags (abfd, s, (flags | SEC_READONLY))
-      || ! bfd_set_section_alignment (abfd, s, 2))
-    return FALSE;
+      /* Machine-specific.  */
+      s = bfd_make_section (abfd, ".rofixup");
+      if (s == NULL
+         || ! bfd_set_section_flags (abfd, s, (flags | SEC_READONLY))
+         || ! bfd_set_section_alignment (abfd, s, 2))
+       return FALSE;
 
-  frv_gotfixup_section (info) = s;
+      frvfdpic_gotfixup_section (info) = s;
+      offset = -2048;
+      flags = BSF_GLOBAL;
+    }
+  else
+    {
+      offset = 2048;
+      flags = BSF_GLOBAL | BSF_WEAK;
+    }
 
-  /* Define _gp in .rofixup, for FDPIC.  If it turns out that
-     we're linking with a different linker script, the linker script
-     will override it.  */
+  /* Define _gp in .rofixup, for FDPIC, or .got otherwise.  If it
+     turns out that we're linking with a different linker script, the
+     linker script will override it.  */
   bh = NULL;
   if (!(_bfd_generic_link_add_one_symbol
-       (info, abfd, "_gp", BSF_GLOBAL, s, -2048, (const char *) NULL, FALSE,
+       (info, abfd, "_gp", flags, s, offset, (const char *) NULL, FALSE,
         bed->collect, &bh)))
     return FALSE;
   h = (struct elf_link_hash_entry *) bh;
-  h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+  h->def_regular = 1;
   h->type = STT_OBJECT;
 
   /* Machine-specific: we want the symbol for executables as well.  */
-  if (! _bfd_elf_link_record_dynamic_symbol (info, h))
+  if (IS_FDPIC (abfd) && ! bfd_elf_link_record_dynamic_symbol (info, h))
     return FALSE;
-  
+
   return TRUE;
 }
 
@@ -2734,7 +2828,7 @@ _frv_create_got_section (bfd *abfd, struct bfd_link_info *info)
    the link hash table point to them.  */
 
 static bfd_boolean
-elf32_frv_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
+elf32_frvfdpic_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
 {
   /* This is mostly copied from
      elflink.c:_bfd_elf_create_dynamic_sections().  */
@@ -2761,7 +2855,7 @@ elf32_frv_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
       || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
     return FALSE;
   /* FRV-specific: remember it.  */
-  frv_plt_section (info) = s;
+  frvfdpic_plt_section (info) = s;
 
   if (bed->want_plt_sym)
     {
@@ -2775,11 +2869,11 @@ elf32_frv_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
              FALSE, get_elf_backend_data (abfd)->collect, &bh)))
        return FALSE;
       h = (struct elf_link_hash_entry *) bh;
-      h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+      h->def_regular = 1;
       h->type = STT_OBJECT;
 
       if (! info->executable
-         && ! _bfd_elf_link_record_dynamic_symbol (info, h))
+         && ! bfd_elf_link_record_dynamic_symbol (info, h))
        return FALSE;
     }
 
@@ -2790,16 +2884,17 @@ elf32_frv_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
       || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
     return FALSE;
   /* FRV-specific: remember it.  */
-  frv_pltrel_section (info) = s;
+  frvfdpic_pltrel_section (info) = s;
 
   /* FRV-specific: we want to create the GOT in the FRV way.  */
   if (! _frv_create_got_section (abfd, info))
     return FALSE;
 
   /* FRV-specific: make sure we created everything we wanted.  */
-  BFD_ASSERT (frv_got_section (info) && frv_gotrel_section (info)
-             && frv_gotfixup_section (info)
-             && frv_plt_section (info) && frv_pltrel_section (info));
+  BFD_ASSERT (frvfdpic_got_section (info) && frvfdpic_gotrel_section (info)
+             && frvfdpic_gotfixup_section (info)
+             && frvfdpic_plt_section (info)
+             && frvfdpic_pltrel_section (info));
 
   if (bed->want_dynbss)
     {
@@ -2849,7 +2944,7 @@ elf32_frv_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
 
 /* This structure is used to collect the number of entries present in
    each addressable range of the got.  */
-struct _frv_dynamic_got_info
+struct _frvfdpic_dynamic_got_info
 {
   /* Several bits of information about the current link.  */
   struct bfd_link_info *info;
@@ -2877,10 +2972,10 @@ struct _frv_dynamic_got_info
    private function descriptors taking two words.  */
 
 static int
-_frv_count_got_plt_entries (void **entryp, void *dinfo_)
+_frvfdpic_count_got_plt_entries (void **entryp, void *dinfo_)
 {
-  struct frv_pic_relocs_info *entry = *entryp;
-  struct _frv_dynamic_got_info *dinfo = dinfo_;
+  struct frvfdpic_relocs_info *entry = *entryp;
+  struct _frvfdpic_dynamic_got_info *dinfo = dinfo_;
   unsigned relocs = 0, fixups = 0;
 
   /* Allocate space for a GOT entry pointing to the symbol.  */
@@ -2909,15 +3004,15 @@ _frv_count_got_plt_entries (void **entryp, void *dinfo_)
   /* Decide whether we need a PLT entry, a function descriptor in the
      GOT, and a lazy PLT entry for this symbol.  */
   entry->plt = entry->call
-    && entry->symndx == -1 && ! FRV_SYM_LOCAL (dinfo->info, entry->d.h)
+    && entry->symndx == -1 && ! FRVFDPIC_SYM_LOCAL (dinfo->info, entry->d.h)
     && elf_hash_table (dinfo->info)->dynamic_sections_created;
   entry->privfd = entry->plt
     || entry->fdgoff12 || entry->fdgofflos || entry->fdgoffhilo
     || ((entry->fd || entry->fdgot12 || entry->fdgotlos || entry->fdgothilo)
        && (entry->symndx != -1
-           || FRV_FUNCDESC_LOCAL (dinfo->info, entry->d.h)));
+           || FRVFDPIC_FUNCDESC_LOCAL (dinfo->info, entry->d.h)));
   entry->lazyplt = entry->privfd
-    && entry->symndx == -1 && ! FRV_SYM_LOCAL (dinfo->info, entry->d.h)
+    && entry->symndx == -1 && ! FRVFDPIC_SYM_LOCAL (dinfo->info, entry->d.h)
     && ! (dinfo->info->flags & DF_BIND_NOW)
     && elf_hash_table (dinfo->info)->dynamic_sections_created;
 
@@ -2941,7 +3036,7 @@ _frv_count_got_plt_entries (void **entryp, void *dinfo_)
     relocs = entry->relocs32 + entry->relocsfd + entry->relocsfdv;
   else
     {
-      if (entry->symndx != -1 || FRV_SYM_LOCAL (dinfo->info, entry->d.h))
+      if (entry->symndx != -1 || FRVFDPIC_SYM_LOCAL (dinfo->info, entry->d.h))
        {
          if (entry->symndx != -1
              || entry->d.h->root.type != bfd_link_hash_undefweak)
@@ -2950,7 +3045,8 @@ _frv_count_got_plt_entries (void **entryp, void *dinfo_)
       else
        relocs += entry->relocs32 + entry->relocsfdv;
 
-      if (entry->symndx != -1 || FRV_FUNCDESC_LOCAL (dinfo->info, entry->d.h))
+      if (entry->symndx != -1
+         || FRVFDPIC_FUNCDESC_LOCAL (dinfo->info, entry->d.h))
        {
          if (entry->symndx != -1
              || entry->d.h->root.type != bfd_link_hash_undefweak)
@@ -2971,10 +3067,10 @@ _frv_count_got_plt_entries (void **entryp, void *dinfo_)
 /* This structure is used to assign offsets to got entries, function
    descriptors, plt entries and lazy plt entries.  */
 
-struct _frv_dynamic_got_plt_info
+struct _frvfdpic_dynamic_got_plt_info
 {
-  /* Summary information collected with _frv_count_got_plt_entries.  */
-  struct _frv_dynamic_got_info g;
+  /* Summary information collected with _frvfdpic_count_got_plt_entries.  */
+  struct _frvfdpic_dynamic_got_info g;
 
   /* For each addressable range, we record a MAX (positive) and MIN
      (negative) value.  CUR is used to assign got entries, and it's
@@ -2990,7 +3086,7 @@ struct _frv_dynamic_got_plt_info
      descriptor is chosen.  FDPLT indicates the number of remaining
      slots that can be used for function descriptors used only by PLT
      entries.  */
-  struct _frv_dynamic_got_alloc_data
+  struct _frvfdpic_dynamic_got_alloc_data
   {
     bfd_signed_vma max, cur, odd, fdcur, min;
     bfd_vma fdplt;
@@ -3008,14 +3104,14 @@ struct _frv_dynamic_got_plt_info
    descriptors.  */
 
 inline static bfd_signed_vma
-_frv_compute_got_alloc_data (struct _frv_dynamic_got_alloc_data *gad,
-                            bfd_signed_vma fdcur,
-                            bfd_signed_vma odd,
-                            bfd_signed_vma cur,
-                            bfd_vma got,
-                            bfd_vma fd,
-                            bfd_vma fdplt,
-                            bfd_vma wrap)
+_frvfdpic_compute_got_alloc_data (struct _frvfdpic_dynamic_got_alloc_data *gad,
+                                 bfd_signed_vma fdcur,
+                                 bfd_signed_vma odd,
+                                 bfd_signed_vma cur,
+                                 bfd_vma got,
+                                 bfd_vma fd,
+                                 bfd_vma fdplt,
+                                 bfd_vma wrap)
 {
   bfd_signed_vma wrapmin = -wrap;
 
@@ -3051,7 +3147,7 @@ _frv_compute_got_alloc_data (struct _frv_dynamic_got_alloc_data *gad,
       odd = cur + got;
       got += 4;
     }
-  
+
   /* Compute the tentative boundaries of this range.  */
   gad->max = cur + got;
   gad->min = fdcur - fd;
@@ -3109,7 +3205,7 @@ _frv_compute_got_alloc_data (struct _frv_dynamic_got_alloc_data *gad,
   if (odd > gad->max)
     odd = gad->min + odd - gad->max;
 
-  /* _frv_get_got_entry() below will always wrap gad->cur if needed
+  /* _frvfdpic_get_got_entry() below will always wrap gad->cur if needed
      before returning, so do it here too.  This guarantees that,
      should cur and fdcur meet at the wrap point, they'll both be
      equal to min.  */
@@ -3123,10 +3219,10 @@ _frv_compute_got_alloc_data (struct _frv_dynamic_got_alloc_data *gad,
    data for a range.  */
 
 inline static bfd_signed_vma
-_frv_get_got_entry (struct _frv_dynamic_got_alloc_data *gad)
+_frvfdpic_get_got_entry (struct _frvfdpic_dynamic_got_alloc_data *gad)
 {
   bfd_signed_vma ret;
-  
+
   if (gad->odd)
     {
       /* If there was an odd word left behind, use it.  */
@@ -3152,7 +3248,7 @@ _frv_get_got_entry (struct _frv_dynamic_got_alloc_data *gad)
    GOT, given the allocation data for a range.  */
 
 inline static bfd_signed_vma
-_frv_get_fd_entry (struct _frv_dynamic_got_alloc_data *gad)
+_frvfdpic_get_fd_entry (struct _frvfdpic_dynamic_got_alloc_data *gad)
 {
   /* If we're at the bottom, wrap around, and only then allocate the
      next pair of words.  */
@@ -3165,47 +3261,47 @@ _frv_get_fd_entry (struct _frv_dynamic_got_alloc_data *gad)
    Doing everything in a single pass is tricky.  */
 
 static int
-_frv_assign_got_entries (void **entryp, void *info_)
+_frvfdpic_assign_got_entries (void **entryp, void *info_)
 {
-  struct frv_pic_relocs_info *entry = *entryp;
-  struct _frv_dynamic_got_plt_info *dinfo = info_;
+  struct frvfdpic_relocs_info *entry = *entryp;
+  struct _frvfdpic_dynamic_got_plt_info *dinfo = info_;
 
   if (entry->got12)
-    entry->got_entry = _frv_get_got_entry (&dinfo->got12);
+    entry->got_entry = _frvfdpic_get_got_entry (&dinfo->got12);
   else if (entry->gotlos)
-    entry->got_entry = _frv_get_got_entry (&dinfo->gotlos);
+    entry->got_entry = _frvfdpic_get_got_entry (&dinfo->gotlos);
   else if (entry->gothilo)
-    entry->got_entry = _frv_get_got_entry (&dinfo->gothilo);
+    entry->got_entry = _frvfdpic_get_got_entry (&dinfo->gothilo);
 
   if (entry->fdgot12)
-    entry->fdgot_entry = _frv_get_got_entry (&dinfo->got12);
+    entry->fdgot_entry = _frvfdpic_get_got_entry (&dinfo->got12);
   else if (entry->fdgotlos)
-    entry->fdgot_entry = _frv_get_got_entry (&dinfo->gotlos);
+    entry->fdgot_entry = _frvfdpic_get_got_entry (&dinfo->gotlos);
   else if (entry->fdgothilo)
-    entry->fdgot_entry = _frv_get_got_entry (&dinfo->gothilo);
+    entry->fdgot_entry = _frvfdpic_get_got_entry (&dinfo->gothilo);
 
   if (entry->fdgoff12)
-    entry->fd_entry = _frv_get_fd_entry (&dinfo->got12);
+    entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->got12);
   else if (entry->plt && dinfo->got12.fdplt)
     {
       dinfo->got12.fdplt -= 8;
-      entry->fd_entry = _frv_get_fd_entry (&dinfo->got12);
+      entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->got12);
     }
   else if (entry->fdgofflos)
-    entry->fd_entry = _frv_get_fd_entry (&dinfo->gotlos);
+    entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->gotlos);
   else if (entry->plt && dinfo->gotlos.fdplt)
     {
       dinfo->gotlos.fdplt -= 8;
-      entry->fd_entry = _frv_get_fd_entry (&dinfo->gotlos);
+      entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->gotlos);
     }
   else if (entry->plt)
     {
       dinfo->gothilo.fdplt -= 8;
-      entry->fd_entry = _frv_get_fd_entry (&dinfo->gothilo);
+      entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->gothilo);
     }
   else if (entry->privfd)
-    entry->fd_entry = _frv_get_fd_entry (&dinfo->gothilo);
-  
+    entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->gothilo);
+
   return 1;
 }
 
@@ -3214,10 +3310,10 @@ _frv_assign_got_entries (void **entryp, void *info_)
    and lazy PLT entries.  */
 
 static int
-_frv_assign_plt_entries (void **entryp, void *info_)
+_frvfdpic_assign_plt_entries (void **entryp, void *info_)
 {
-  struct frv_pic_relocs_info *entry = *entryp;
-  struct _frv_dynamic_got_plt_info *dinfo = info_;
+  struct frvfdpic_relocs_info *entry = *entryp;
+  struct _frvfdpic_dynamic_got_plt_info *dinfo = info_;
 
   /* If this symbol requires a local function descriptor, allocate
      one.  */
@@ -3225,18 +3321,18 @@ _frv_assign_plt_entries (void **entryp, void *info_)
     {
       if (dinfo->got12.fdplt)
        {
-         entry->fd_entry = _frv_get_fd_entry (&dinfo->got12);
+         entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->got12);
          dinfo->got12.fdplt -= 8;
        }
       else if (dinfo->gotlos.fdplt)
        {
-         entry->fd_entry = _frv_get_fd_entry (&dinfo->gotlos);
+         entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->gotlos);
          dinfo->gotlos.fdplt -= 8;
        }
       else
        {
-         BFD_ASSERT (dinfo->gothilo.fdplt)
-         entry->fd_entry = _frv_get_fd_entry (&dinfo->gothilo);
+         BFD_ASSERT (dinfo->gothilo.fdplt);
+         entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->gothilo);
          dinfo->gothilo.fdplt -= 8;
        }
     }
@@ -3247,7 +3343,7 @@ _frv_assign_plt_entries (void **entryp, void *info_)
 
       /* We use the section's raw size to mark the location of the
         next PLT entry.  */
-      entry->plt_entry = frv_plt_section (dinfo->g.info)->_raw_size;
+      entry->plt_entry = frvfdpic_plt_section (dinfo->g.info)->size;
 
       /* Figure out the length of this PLT entry based on the
         addressing mode we need to reach the function descriptor.  */
@@ -3261,7 +3357,7 @@ _frv_assign_plt_entries (void **entryp, void *info_)
       else
        size = 16;
 
-      frv_plt_section (dinfo->g.info)->_raw_size += size;
+      frvfdpic_plt_section (dinfo->g.info)->size += size;
     }
 
   if (entry->lazyplt)
@@ -3270,12 +3366,13 @@ _frv_assign_plt_entries (void **entryp, void *info_)
       dinfo->g.lzplt += 8;
       /* If this entry is the one that gets the resolver stub, account
         for the additional instruction.  */
-      if (entry->lzplt_entry % FRV_LZPLT_BLOCK_SIZE == FRV_LZPLT_RESOLV_LOC)
+      if (entry->lzplt_entry % FRVFDPIC_LZPLT_BLOCK_SIZE
+         == FRVFDPIC_LZPLT_RESOLV_LOC)
        dinfo->g.lzplt += 4;
     }
-      
+
   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
@@ -3284,15 +3381,15 @@ _frv_assign_plt_entries (void **entryp, void *info_)
    we've made a potentially-destructive change to the hash table, so
    the traversal must be restarted.  */
 static int
-_frv_resolve_final_relocs_info (void **entryp, void *p)
+_frvfdpic_resolve_final_relocs_info (void **entryp, void *p)
 {
-  struct frv_pic_relocs_info *entry = *entryp;
+  struct frvfdpic_relocs_info *entry = *entryp;
   htab_t *htab = p;
 
   if (entry->symndx == -1)
     {
       struct elf_link_hash_entry *h = entry->d.h;
-      struct frv_pic_relocs_info *oentry;
+      struct frvfdpic_relocs_info *oentry;
 
       while (h->root.type == bfd_link_hash_indirect
             || h->root.type == bfd_link_hash_warning)
@@ -3301,13 +3398,13 @@ _frv_resolve_final_relocs_info (void **entryp, void *p)
       if (entry->d.h == h)
        return 1;
 
-      oentry = frv_pic_relocs_info_for_global (*htab, 0, h, entry->addend,
-                                              NO_INSERT);
+      oentry = frvfdpic_relocs_info_for_global (*htab, 0, h, entry->addend,
+                                               NO_INSERT);
 
       if (oentry)
        {
          /* Merge the two entries.  */
-         frv_pic_merge_early_relocs_info (oentry, entry);
+         frvfdpic_pic_merge_early_relocs_info (oentry, entry);
          htab_clear_slot (*htab, entryp);
          return 1;
        }
@@ -3336,12 +3433,12 @@ _frv_resolve_final_relocs_info (void **entryp, void *p)
 /* Set the sizes of the dynamic sections.  */
 
 static bfd_boolean
-elf32_frv_size_dynamic_sections (bfd *output_bfd,
-                                struct bfd_link_info *info)
+elf32_frvfdpic_size_dynamic_sections (bfd *output_bfd,
+                                     struct bfd_link_info *info)
 {
   bfd *dynobj;
   asection *s;
-  struct _frv_dynamic_got_plt_info gpinfo;
+  struct _frvfdpic_dynamic_got_plt_info gpinfo;
   bfd_signed_vma odd;
   bfd_vma limit;
 
@@ -3355,7 +3452,7 @@ elf32_frv_size_dynamic_sections (bfd *output_bfd,
        {
          s = bfd_get_section_by_name (dynobj, ".interp");
          BFD_ASSERT (s != NULL);
-         s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
+         s->size = sizeof ELF_DYNAMIC_INTERPRETER;
          s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
        }
     }
@@ -3365,15 +3462,15 @@ elf32_frv_size_dynamic_sections (bfd *output_bfd,
 
   for (;;)
     {
-      htab_t relocs = frv_relocs_info (info);
+      htab_t relocs = frvfdpic_relocs_info (info);
 
-      htab_traverse (relocs, _frv_resolve_final_relocs_info, &relocs);
+      htab_traverse (relocs, _frvfdpic_resolve_final_relocs_info, &relocs);
 
-      if (relocs == frv_relocs_info (info))
+      if (relocs == frvfdpic_relocs_info (info))
        break;
     }
 
-  htab_traverse (frv_relocs_info (info), _frv_count_got_plt_entries,
+  htab_traverse (frvfdpic_relocs_info (info), _frvfdpic_count_got_plt_entries,
                 &gpinfo.g);
 
   odd = 12;
@@ -3392,164 +3489,170 @@ elf32_frv_size_dynamic_sections (bfd *output_bfd,
 
   /* Determine the ranges of GOT offsets that we can use for each
      range of addressing modes.  */
-  odd = _frv_compute_got_alloc_data (&gpinfo.got12,
-                                    0,
-                                    odd,
-                                    16,
-                                    gpinfo.g.got12,
-                                    gpinfo.g.fd12,
-                                    limit,
-                                    (bfd_vma)1 << (12-1));
-  odd = _frv_compute_got_alloc_data (&gpinfo.gotlos,
-                                    gpinfo.got12.min,
-                                    odd,
-                                    gpinfo.got12.max,
-                                    gpinfo.g.gotlos,
-                                    gpinfo.g.fdlos,
-                                    gpinfo.g.fdplt - gpinfo.got12.fdplt,
-                                    (bfd_vma)1 << (16-1));
-  odd = _frv_compute_got_alloc_data (&gpinfo.gothilo,
-                                    gpinfo.gotlos.min,
-                                    odd,
-                                    gpinfo.gotlos.max,
-                                    gpinfo.g.gothilo,
-                                    gpinfo.g.fdhilo,
-                                    gpinfo.g.fdplt - gpinfo.got12.fdplt
-                                    - gpinfo.gotlos.fdplt,
-                                    (bfd_vma)1 << (32-1));
+  odd = _frvfdpic_compute_got_alloc_data (&gpinfo.got12,
+                                         0,
+                                         odd,
+                                         16,
+                                         gpinfo.g.got12,
+                                         gpinfo.g.fd12,
+                                         limit,
+                                         (bfd_vma)1 << (12-1));
+  odd = _frvfdpic_compute_got_alloc_data (&gpinfo.gotlos,
+                                         gpinfo.got12.min,
+                                         odd,
+                                         gpinfo.got12.max,
+                                         gpinfo.g.gotlos,
+                                         gpinfo.g.fdlos,
+                                         gpinfo.g.fdplt - gpinfo.got12.fdplt,
+                                         (bfd_vma)1 << (16-1));
+  odd = _frvfdpic_compute_got_alloc_data (&gpinfo.gothilo,
+                                         gpinfo.gotlos.min,
+                                         odd,
+                                         gpinfo.gotlos.max,
+                                         gpinfo.g.gothilo,
+                                         gpinfo.g.fdhilo,
+                                         gpinfo.g.fdplt - gpinfo.got12.fdplt
+                                         - gpinfo.gotlos.fdplt,
+                                         (bfd_vma)1 << (32-1));
 
   /* Now assign (most) GOT offsets.  */
-  htab_traverse (frv_relocs_info (info), _frv_assign_got_entries, &gpinfo);
+  htab_traverse (frvfdpic_relocs_info (info), _frvfdpic_assign_got_entries,
+                &gpinfo);
 
-  frv_got_section (info)->_raw_size = gpinfo.gothilo.max - gpinfo.gothilo.min
+  frvfdpic_got_section (info)->size = gpinfo.gothilo.max
+    - gpinfo.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);
-  if (frv_got_section (info)->_raw_size == 0)
-    frv_got_section (info)->flags |= SEC_EXCLUDE;
-  else if (frv_got_section (info)->_raw_size == 12
+  if (frvfdpic_got_section (info)->size == 0)
+    frvfdpic_got_section (info)->flags |= SEC_EXCLUDE;
+  else if (frvfdpic_got_section (info)->size == 12
           && ! elf_hash_table (info)->dynamic_sections_created)
     {
-      frv_got_section (info)->flags |= SEC_EXCLUDE;
-      frv_got_section (info)->_raw_size = 0;
+      frvfdpic_got_section (info)->flags |= SEC_EXCLUDE;
+      frvfdpic_got_section (info)->size = 0;
     }
   else
     {
-      frv_got_section (info)->contents =
-       (bfd_byte *) bfd_zalloc (dynobj, frv_got_section (info)->_raw_size);
-      if (frv_got_section (info)->contents == NULL)
+      frvfdpic_got_section (info)->contents =
+       (bfd_byte *) bfd_zalloc (dynobj,
+                                frvfdpic_got_section (info)->size);
+      if (frvfdpic_got_section (info)->contents == NULL)
        return FALSE;
     }
-  
+
   if (elf_hash_table (info)->dynamic_sections_created)
     /* Subtract the number of lzplt entries, since those will generate
        relocations in the pltrel section.  */
-    frv_gotrel_section (info)->_raw_size =
+    frvfdpic_gotrel_section (info)->size =
       (gpinfo.g.relocs - gpinfo.g.lzplt / 8)
       * get_elf_backend_data (output_bfd)->s->sizeof_rel;
   else
     BFD_ASSERT (gpinfo.g.relocs == 0);
-  if (frv_gotrel_section (info)->_raw_size == 0)
-    frv_gotrel_section (info)->flags |= SEC_EXCLUDE;
+  if (frvfdpic_gotrel_section (info)->size == 0)
+    frvfdpic_gotrel_section (info)->flags |= SEC_EXCLUDE;
   else
     {
-      frv_gotrel_section (info)->contents =
-       (bfd_byte *) bfd_zalloc (dynobj, frv_gotrel_section (info)->_raw_size);
-      if (frv_gotrel_section (info)->contents == NULL)
+      frvfdpic_gotrel_section (info)->contents =
+       (bfd_byte *) bfd_zalloc (dynobj,
+                                frvfdpic_gotrel_section (info)->size);
+      if (frvfdpic_gotrel_section (info)->contents == NULL)
        return FALSE;
     }
 
-  if (elf_elfheader (output_bfd)->e_flags & EF_FRV_FDPIC)
-    frv_gotfixup_section (info)->_raw_size = (gpinfo.g.fixups + 1) * 4;
-  if (frv_gotfixup_section (info)->_raw_size == 0)
-    frv_gotfixup_section (info)->flags |= SEC_EXCLUDE;
+  frvfdpic_gotfixup_section (info)->size = (gpinfo.g.fixups + 1) * 4;
+  if (frvfdpic_gotfixup_section (info)->size == 0)
+    frvfdpic_gotfixup_section (info)->flags |= SEC_EXCLUDE;
   else
     {
-      frv_gotfixup_section (info)->contents =
+      frvfdpic_gotfixup_section (info)->contents =
        (bfd_byte *) bfd_zalloc (dynobj,
-                                frv_gotfixup_section (info)->_raw_size);
-      if (frv_gotfixup_section (info)->contents == NULL)
+                                frvfdpic_gotfixup_section (info)->size);
+      if (frvfdpic_gotfixup_section (info)->contents == NULL)
        return FALSE;
     }
-  
+
   if (elf_hash_table (info)->dynamic_sections_created)
     {
-      frv_pltrel_section (info)->_raw_size =
+      frvfdpic_pltrel_section (info)->size =
        gpinfo.g.lzplt / 8 * get_elf_backend_data (output_bfd)->s->sizeof_rel;
-      if (frv_pltrel_section (info)->_raw_size == 0)
-       frv_pltrel_section (info)->flags |= SEC_EXCLUDE;
+      if (frvfdpic_pltrel_section (info)->size == 0)
+       frvfdpic_pltrel_section (info)->flags |= SEC_EXCLUDE;
       else
        {
-         frv_pltrel_section (info)->contents =
+         frvfdpic_pltrel_section (info)->contents =
            (bfd_byte *) bfd_zalloc (dynobj,
-                                    frv_pltrel_section (info)->_raw_size);
-         if (frv_pltrel_section (info)->contents == NULL)
+                                    frvfdpic_pltrel_section (info)->size);
+         if (frvfdpic_pltrel_section (info)->contents == NULL)
            return FALSE;
        }
     }
-  
+
   /* Add 4 bytes for every block of at most 65535 lazy PLT entries,
      such that there's room for the additional instruction needed to
-     call the resolver.  Since _frv_assign_got_entries didn't account
-     for them, our block size is 4 bytes smaller than the real block
-     size.  */
+     call the resolver.  Since _frvfdpic_assign_got_entries didn't
+     account for them, our block size is 4 bytes smaller than the real
+     block size.  */
   if (elf_hash_table (info)->dynamic_sections_created)
     {
-      frv_plt_section (info)->_raw_size = gpinfo.g.lzplt
-       + ((gpinfo.g.lzplt + (FRV_LZPLT_BLOCK_SIZE - 4) - 8)
-          / (FRV_LZPLT_BLOCK_SIZE - 4) * 4);
+      frvfdpic_plt_section (info)->size = gpinfo.g.lzplt
+       + ((gpinfo.g.lzplt + (FRVFDPIC_LZPLT_BLOCK_SIZE - 4) - 8)
+          / (FRVFDPIC_LZPLT_BLOCK_SIZE - 4) * 4);
     }
 
-  /* Reset it, such that _frv_assign_plt_entries() can use it to
+  /* Reset it, such that _frvfdpic_assign_plt_entries() can use it to
      actually assign lazy PLT entries addresses.  */
   gpinfo.g.lzplt = 0;
 
   /* Save information that we're going to need to generate GOT and PLT
      entries.  */
-  frv_got_initial_offset (info) = -gpinfo.gothilo.min;
+  frvfdpic_got_initial_offset (info) = -gpinfo.gothilo.min;
 
   if (get_elf_backend_data (output_bfd)->want_got_sym)
     elf_hash_table (info)->hgot->root.u.def.value
-      += frv_got_initial_offset (info);
+      += frvfdpic_got_initial_offset (info);
 
   if (elf_hash_table (info)->dynamic_sections_created)
-    frv_plt_initial_offset (info) = frv_plt_section (info)->_raw_size;
+    frvfdpic_plt_initial_offset (info) =
+      frvfdpic_plt_section (info)->size;
 
-  htab_traverse (frv_relocs_info (info), _frv_assign_plt_entries, &gpinfo);
+  htab_traverse (frvfdpic_relocs_info (info), _frvfdpic_assign_plt_entries,
+                &gpinfo);
 
   /* Allocate the PLT section contents only after
-     _frv_assign_plt_entries has a chance to add the size of the
+     _frvfdpic_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 (frv_plt_section (info)->_raw_size == 0)
-       frv_plt_section (info)->flags |= SEC_EXCLUDE;
+      if (frvfdpic_plt_section (info)->size == 0)
+       frvfdpic_plt_section (info)->flags |= SEC_EXCLUDE;
       else
        {
-         frv_plt_section (info)->contents =
-           (bfd_byte *) bfd_zalloc (dynobj, frv_plt_section (info)->_raw_size);
-         if (frv_plt_section (info)->contents == NULL)
+         frvfdpic_plt_section (info)->contents =
+           (bfd_byte *) bfd_zalloc (dynobj,
+                                    frvfdpic_plt_section (info)->size);
+         if (frvfdpic_plt_section (info)->contents == NULL)
            return FALSE;
        }
     }
 
   if (elf_hash_table (info)->dynamic_sections_created)
     {
-      if (frv_got_section (info)->_raw_size)
-       if (! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0))
+      if (frvfdpic_got_section (info)->size)
+       if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0))
          return FALSE;
 
-      if (frv_pltrel_section (info)->_raw_size)
-       if (! bfd_elf32_add_dynamic_entry (info, DT_PLTRELSZ, 0)
-           || ! bfd_elf32_add_dynamic_entry (info, DT_PLTREL, DT_REL)
-           || ! bfd_elf32_add_dynamic_entry (info, DT_JMPREL, 0))
+      if (frvfdpic_pltrel_section (info)->size)
+       if (!_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
+           || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_REL)
+           || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
          return FALSE;
 
-      if (frv_gotrel_section (info)->_raw_size)
-       if (! bfd_elf32_add_dynamic_entry (info, DT_REL, 0)
-           || ! bfd_elf32_add_dynamic_entry (info, DT_RELSZ, 0)
-           || ! bfd_elf32_add_dynamic_entry (info, DT_RELENT,
-                                             sizeof (Elf32_External_Rel)))
+      if (frvfdpic_gotrel_section (info)->size)
+       if (!_bfd_elf_add_dynamic_entry (info, DT_REL, 0)
+           || !_bfd_elf_add_dynamic_entry (info, DT_RELSZ, 0)
+           || !_bfd_elf_add_dynamic_entry (info, DT_RELENT,
+                                           sizeof (Elf32_External_Rel)))
          return FALSE;
     }
 
@@ -3557,11 +3660,10 @@ elf32_frv_size_dynamic_sections (bfd *output_bfd,
 }
 
 static bfd_boolean
-elf32_frv_always_size_sections (bfd *output_bfd,
-                               struct bfd_link_info *info)
+elf32_frvfdpic_always_size_sections (bfd *output_bfd,
+                                    struct bfd_link_info *info)
 {
-  if (!info->relocatable
-      && elf_elfheader (output_bfd)->e_flags & EF_FRV_FDPIC)
+  if (!info->relocatable)
     {
       struct elf_link_hash_entry *h;
       asection *sec;
@@ -3575,7 +3677,7 @@ elf32_frv_always_size_sections (bfd *output_bfd,
                                FALSE, FALSE, FALSE);
       if (! h || h->root.type != bfd_link_hash_defined
          || h->type != STT_OBJECT
-         || !(h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
+         || !h->def_regular)
        {
          struct bfd_link_hash_entry *bh = NULL;
 
@@ -3587,7 +3689,7 @@ elf32_frv_always_size_sections (bfd *output_bfd,
            return FALSE;
 
          h = (struct elf_link_hash_entry *) bh;
-         h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+         h->def_regular = 1;
          h->type = STT_OBJECT;
        }
 
@@ -3603,45 +3705,47 @@ elf32_frv_always_size_sections (bfd *output_bfd,
 }
 
 static bfd_boolean
-elf32_frv_modify_segment_map (bfd *output_bfd,
-                             struct bfd_link_info *info)
+elf32_frvfdpic_modify_segment_map (bfd *output_bfd,
+                                  struct bfd_link_info *info)
 {
-  if (elf_elfheader (output_bfd)->e_flags & EF_FRV_FDPIC)
-    {
-      struct elf_segment_map *m;
+  struct elf_segment_map *m;
 
-      for (m = elf_tdata (output_bfd)->segment_map; m != NULL; m = m->next)
-       if (m->p_type == PT_GNU_STACK)
-         break;
+  /* objcopy and strip preserve what's already there using
+     elf32_frvfdpic_copy_private_bfd_data ().  */
+  if (! info)
+    return TRUE;
 
-      if (m)
+  for (m = elf_tdata (output_bfd)->segment_map; m != NULL; m = m->next)
+    if (m->p_type == PT_GNU_STACK)
+      break;
+
+  if (m)
+    {
+      asection *sec = bfd_get_section_by_name (output_bfd, ".stack");
+      struct elf_link_hash_entry *h;
+
+      if (sec)
        {
-         asection *sec = bfd_get_section_by_name (output_bfd, ".stack");
-         struct elf_link_hash_entry *h;
+         /* Obtain the pointer to the __stacksize symbol.  */
+         h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize",
+                                   FALSE, FALSE, FALSE);
+         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);
 
-         if (sec)
-           {
-             /* Obtain the pointer to the __stacksize symbol.  */
-             h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize",
-                                       FALSE, FALSE, FALSE);
-             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);
-
-             /* Set the section size from the symbol value.  We
-                intentionally ignore the symbol section.  */
-             if (h->root.type == bfd_link_hash_defined)
-               sec->_raw_size = h->root.u.def.value;
-             else
-               sec->_raw_size = DEFAULT_STACK_SIZE;
-
-             /* Add the stack section to the PT_GNU_STACK segment,
-                such that its size and alignment requirements make it
-                to the segment.  */
-             m->sections[m->count] = sec;
-             m->count++;
-           }
+         /* Set the section size from the symbol value.  We
+            intentionally ignore the symbol section.  */
+         if (h->root.type == bfd_link_hash_defined)
+           sec->size = h->root.u.def.value;
+         else
+           sec->size = DEFAULT_STACK_SIZE;
+
+         /* Add the stack section to the PT_GNU_STACK segment,
+            such that its size and alignment requirements make it
+            to the segment.  */
+         m->sections[m->count] = sec;
+         m->count++;
        }
     }
 
@@ -3651,60 +3755,51 @@ elf32_frv_modify_segment_map (bfd *output_bfd,
 /* Fill in code and data in dynamic sections.  */
 
 static bfd_boolean
-elf32_frv_finish_dynamic_sections (bfd *output_bfd,
-                                  struct bfd_link_info *info)
+elf32_frv_finish_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
+                                  struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+  /* Nothing to be done for non-FDPIC.  */
+  return TRUE;
+}
+
+static bfd_boolean
+elf32_frvfdpic_finish_dynamic_sections (bfd *output_bfd,
+                                       struct bfd_link_info *info)
 {
   bfd *dynobj;
   asection *sdyn;
 
   dynobj = elf_hash_table (info)->dynobj;
 
-  if (frv_got_section (info))
+  if (frvfdpic_got_section (info))
     {
-      BFD_ASSERT (frv_gotrel_section (info)->_raw_size
-                 == (frv_gotrel_section (info)->reloc_count
+      BFD_ASSERT (frvfdpic_gotrel_section (info)->size
+                 == (frvfdpic_gotrel_section (info)->reloc_count
                      * sizeof (Elf32_External_Rel)));
 
-      if (frv_gotfixup_section (info))
+      if (frvfdpic_gotfixup_section (info))
        {
-         if (elf_elfheader (output_bfd)->e_flags & EF_FRV_FDPIC)
-           {
-             struct elf_link_hash_entry *hgot = elf_hash_table (info)->hgot;
-             bfd_vma got_value = hgot->root.u.def.value
-               + hgot->root.u.def.section->output_section->vma
-               + hgot->root.u.def.section->output_offset;
+         struct elf_link_hash_entry *hgot = elf_hash_table (info)->hgot;
+         bfd_vma got_value = hgot->root.u.def.value
+           + hgot->root.u.def.section->output_section->vma
+           + hgot->root.u.def.section->output_offset;
 
-             _frv_add_rofixup (output_bfd, frv_gotfixup_section (info),
-                               got_value, 0);
-           }
+         _frvfdpic_add_rofixup (output_bfd, frvfdpic_gotfixup_section (info),
+                                got_value, 0);
 
-         if (frv_gotfixup_section (info)->_raw_size
-             != (frv_gotfixup_section (info)->reloc_count * 4))
+         if (frvfdpic_gotfixup_section (info)->size
+             != (frvfdpic_gotfixup_section (info)->reloc_count * 4))
            {
-             if (frv_gotfixup_section (info)->_raw_size
-                 < frv_gotfixup_section (info)->reloc_count * 4)
-               {
-                 info->callbacks->warning
-                   (info, "LINKER BUG: .rofixup section size mismatch",
-                    ".rofixup", NULL, NULL, 0);
-                 abort ();
-                 return FALSE;
-               }
-             else if (!elf_hash_table (info)->dynamic_sections_created)
-               {
-                 info->callbacks->warning
-                   (info, "no dynamic sections, missing -melf32frvfd?",
-                    ".rofixup", NULL, NULL, 0);
-                 return FALSE;
-               }
-             BFD_ASSERT (0);
+             (*_bfd_error_handler)
+               ("LINKER BUG: .rofixup section size mismatch");
+             return FALSE;
            }
        }
     }
   if (elf_hash_table (info)->dynamic_sections_created)
     {
-      BFD_ASSERT (frv_pltrel_section (info)->_raw_size
-                 == (frv_pltrel_section (info)->reloc_count
+      BFD_ASSERT (frvfdpic_pltrel_section (info)->size
+                 == (frvfdpic_pltrel_section (info)->reloc_count
                      * sizeof (Elf32_External_Rel)));
     }
 
@@ -3718,7 +3813,7 @@ elf32_frv_finish_dynamic_sections (bfd *output_bfd,
       BFD_ASSERT (sdyn != NULL);
 
       dyncon = (Elf32_External_Dyn *) sdyn->contents;
-      dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
+      dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
 
       for (; dyncon < dynconend; dyncon++)
        {
@@ -3732,23 +3827,21 @@ elf32_frv_finish_dynamic_sections (bfd *output_bfd,
              break;
 
            case DT_PLTGOT:
-             dyn.d_un.d_ptr = frv_got_section (info)->output_section->vma
-               + frv_got_section (info)->output_offset
-               + frv_got_initial_offset (info);
+             dyn.d_un.d_ptr = frvfdpic_got_section (info)->output_section->vma
+               + frvfdpic_got_section (info)->output_offset
+               + frvfdpic_got_initial_offset (info);
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
              break;
 
            case DT_JMPREL:
-             dyn.d_un.d_ptr = frv_pltrel_section (info)->output_section->vma
-               + frv_pltrel_section (info)->output_offset;
+             dyn.d_un.d_ptr = frvfdpic_pltrel_section (info)
+               ->output_section->vma
+               + frvfdpic_pltrel_section (info)->output_offset;
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
              break;
 
            case DT_PLTRELSZ:
-             if (frv_pltrel_section (info)->_cooked_size != 0)
-               dyn.d_un.d_val = frv_pltrel_section (info)->_cooked_size;
-             else
-               dyn.d_un.d_val = frv_pltrel_section (info)->_raw_size;
+             dyn.d_un.d_val = frvfdpic_pltrel_section (info)->size;
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
              break;
            }
@@ -3762,8 +3855,9 @@ elf32_frv_finish_dynamic_sections (bfd *output_bfd,
    regular object.  */
 
 static bfd_boolean
-elf32_frv_adjust_dynamic_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
-                                struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
+elf32_frvfdpic_adjust_dynamic_symbol
+(struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
 {
   bfd * dynobj;
 
@@ -3771,23 +3865,20 @@ elf32_frv_adjust_dynamic_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
 
   /* Make sure we know what is going on here.  */
   BFD_ASSERT (dynobj != NULL
-             && (h->weakdef != NULL
-                 || ((h->elf_link_hash_flags
-                      & ELF_LINK_HASH_DEF_DYNAMIC) != 0
-                     && (h->elf_link_hash_flags
-                         & ELF_LINK_HASH_REF_REGULAR) != 0
-                     && (h->elf_link_hash_flags
-                         & ELF_LINK_HASH_DEF_REGULAR) == 0)));
+             && (h->u.weakdef != NULL
+                 || (h->def_dynamic
+                     && h->ref_regular
+                     && !h->def_regular)));
 
   /* If this is a weak symbol, and there is a real definition, the
      processor independent code will have arranged for us to see the
      real definition first, and we can just use the same value.  */
-  if (h->weakdef != NULL)
+  if (h->u.weakdef != NULL)
     {
-      BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
-                 || h->weakdef->root.type == bfd_link_hash_defweak);
-      h->root.u.def.section = h->weakdef->root.u.def.section;
-      h->root.u.def.value = h->weakdef->root.u.def.value;
+      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
+                 || h->u.weakdef->root.type == bfd_link_hash_defweak);
+      h->root.u.def.section = h->u.weakdef->root.u.def.section;
+      h->root.u.def.value = h->u.weakdef->root.u.def.value;
     }
 
   return TRUE;
@@ -3796,10 +3887,11 @@ elf32_frv_adjust_dynamic_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
 /* Perform any actions needed for dynamic symbols.  */
 
 static bfd_boolean
-elf32_frv_finish_dynamic_symbol (bfd *output_bfd ATTRIBUTE_UNUSED,
-                                struct bfd_link_info *info ATTRIBUTE_UNUSED,
-                                struct elf_link_hash_entry *h ATTRIBUTE_UNUSED,
-                                Elf_Internal_Sym *sym ATTRIBUTE_UNUSED)
+elf32_frvfdpic_finish_dynamic_symbol
+(bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym ATTRIBUTE_UNUSED)
 {
   return TRUE;
 }
@@ -3808,44 +3900,37 @@ elf32_frv_finish_dynamic_symbol (bfd *output_bfd ATTRIBUTE_UNUSED,
    shared libraries into pcrel within the given input section.  */
 
 static bfd_boolean
-frv_elf_use_relative_eh_frame (bfd *input_bfd,
-                              struct bfd_link_info *info ATTRIBUTE_UNUSED,
-                              asection *eh_frame_section ATTRIBUTE_UNUSED)
+frvfdpic_elf_use_relative_eh_frame
+(bfd *input_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *eh_frame_section ATTRIBUTE_UNUSED)
 {
   /* We can't use PC-relative encodings in FDPIC binaries, in general.  */
-  if (elf_elfheader (input_bfd)->e_flags & EF_FRV_FDPIC)
-    return FALSE;
-
-  return TRUE;
+  return FALSE;
 }
 
 /* Adjust the contents of an eh_frame_hdr section before they're output.  */
 
 static bfd_byte
-frv_elf_encode_eh_address (bfd *abfd,
-                          struct bfd_link_info *info,
-                          asection *osec, bfd_vma offset,
-                          asection *loc_sec, bfd_vma loc_offset,
-                          bfd_vma *encoded)
+frvfdpic_elf_encode_eh_address (bfd *abfd,
+                               struct bfd_link_info *info,
+                               asection *osec, bfd_vma offset,
+                               asection *loc_sec, bfd_vma loc_offset,
+                               bfd_vma *encoded)
 {
   struct elf_link_hash_entry *h;
 
-  /* Non-FDPIC binaries can use PC-relative encodings.  */
-  if (! (elf_elfheader (abfd)->e_flags & EF_FRV_FDPIC))
-    return _bfd_elf_encode_eh_address (abfd, info, osec, offset,
-                                      loc_sec, loc_offset, encoded);
-
   h = elf_hash_table (info)->hgot;
   BFD_ASSERT (h && h->root.type == bfd_link_hash_defined);
 
-  if (! h || (_frv_osec_to_segment (abfd, osec)
-             == _frv_osec_to_segment (abfd, loc_sec->output_section)))
+  if (! h || (_frvfdpic_osec_to_segment (abfd, osec)
+             == _frvfdpic_osec_to_segment (abfd, loc_sec->output_section)))
     return _bfd_elf_encode_eh_address (abfd, info, osec, offset,
                                       loc_sec, loc_offset, encoded);
 
-  BFD_ASSERT (_frv_osec_to_segment (abfd, osec)
-             == _frv_osec_to_segment (abfd,
-                                      h->root.u.def.section->output_section));
+  BFD_ASSERT (_frvfdpic_osec_to_segment (abfd, osec)
+             == (_frvfdpic_osec_to_segment
+                 (abfd, h->root.u.def.section->output_section)));
 
   *encoded = osec->vma + offset
     - (h->root.u.def.value
@@ -3971,7 +4056,7 @@ elf32_frv_check_relocs (abfd, info, sec, relocs)
   const Elf_Internal_Rela *rel;
   const Elf_Internal_Rela *rel_end;
   bfd *dynobj;
-  struct frv_pic_relocs_info *picrel;
+  struct frvfdpic_relocs_info *picrel;
 
   if (info->relocatable)
     return TRUE;
@@ -3997,8 +4082,6 @@ elf32_frv_check_relocs (abfd, info, sec, relocs)
 
       switch (ELF32_R_TYPE (rel->r_info))
        {
-       case R_FRV_LABEL24:
-       case R_FRV_32:
        case R_FRV_GOT12:
        case R_FRV_GOTHI:
        case R_FRV_GOTLO:
@@ -4013,12 +4096,26 @@ elf32_frv_check_relocs (abfd, info, sec, relocs)
        case R_FRV_FUNCDESC_GOTOFFLO:
        case R_FRV_FUNCDESC:
        case R_FRV_FUNCDESC_VALUE:
+         if (! IS_FDPIC (abfd))
+           goto bad_reloc;
+         /* Fall through.  */
+       case R_FRV_GPREL12:
+       case R_FRV_GPRELU12:
+       case R_FRV_GPRELHI:
+       case R_FRV_GPRELLO:
+       case R_FRV_LABEL24:
+       case R_FRV_32:
          if (! dynobj)
            {
              elf_hash_table (info)->dynobj = dynobj = abfd;
              if (! _frv_create_got_section (abfd, info))
                return FALSE;
            }
+         if (! IS_FDPIC (abfd))
+           {
+             picrel = NULL;
+             break;
+           }
          if (h != NULL)
            {
              if (h->dynindx == -1)
@@ -4028,18 +4125,18 @@ elf32_frv_check_relocs (abfd, info, sec, relocs)
                  case STV_HIDDEN:
                    break;
                  default:
-                   bfd_elf32_link_record_dynamic_symbol (info, h);
+                   bfd_elf_link_record_dynamic_symbol (info, h);
                    break;
                  }
              picrel
-               = frv_pic_relocs_info_for_global (frv_relocs_info (info),
-                                                 abfd, h,
-                                                 rel->r_addend, INSERT);
+               = frvfdpic_relocs_info_for_global (frvfdpic_relocs_info (info),
+                                                  abfd, h,
+                                                  rel->r_addend, INSERT);
            }
          else
-           picrel = frv_pic_relocs_info_for_local (frv_relocs_info (info),
-                                                   abfd, r_symndx,
-                                                   rel->r_addend, INSERT);
+           picrel = frvfdpic_relocs_info_for_local (frvfdpic_relocs_info
+                                                    (info), abfd, r_symndx,
+                                                    rel->r_addend, INSERT);
          if (! picrel)
            return FALSE;
          break;
@@ -4048,28 +4145,33 @@ elf32_frv_check_relocs (abfd, info, sec, relocs)
          picrel = NULL;
          break;
        }
-      
+
       switch (ELF32_R_TYPE (rel->r_info))
         {
        case R_FRV_LABEL24:
-         picrel->call = 1;
+         if (IS_FDPIC (abfd))
+           picrel->call = 1;
          break;
-               
+
        case R_FRV_FUNCDESC_VALUE:
          picrel->relocsfdv++;
          if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
            picrel->relocs32--;
          /* Fall through.  */
+
        case R_FRV_32:
+         if (! IS_FDPIC (abfd))
+           break;
+
          picrel->sym = 1;
          if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
            picrel->relocs32++;
          break;
-           
+
        case R_FRV_GOT12:
          picrel->got12 = 1;
          break;
-           
+
        case R_FRV_GOTHI:
        case R_FRV_GOTLO:
          picrel->gothilo = 1;
@@ -4078,45 +4180,62 @@ elf32_frv_check_relocs (abfd, info, sec, relocs)
        case R_FRV_FUNCDESC_GOT12:
          picrel->fdgot12 = 1;
          break;
-           
+
        case R_FRV_FUNCDESC_GOTHI:
        case R_FRV_FUNCDESC_GOTLO:
          picrel->fdgothilo = 1;
          break;
-           
+
        case R_FRV_GOTOFF12:
        case R_FRV_GOTOFFHI:
        case R_FRV_GOTOFFLO:
          picrel->gotoff = 1;
          break;
-           
+
        case R_FRV_FUNCDESC_GOTOFF12:
          picrel->fdgoff12 = 1;
          break;
-           
+
        case R_FRV_FUNCDESC_GOTOFFHI:
        case R_FRV_FUNCDESC_GOTOFFLO:
          picrel->fdgoffhilo = 1;
          break;
-           
+
        case R_FRV_FUNCDESC:
          picrel->fd = 1;
          picrel->relocsfd++;
          break;
-         
+
         /* This relocation describes the C++ object vtable hierarchy.
            Reconstruct it for later use during GC.  */
         case R_FRV_GNU_VTINHERIT:
-          if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
             return FALSE;
           break;
 
         /* This relocation describes which C++ vtable entries are actually
            used.  Record for later use during GC.  */
         case R_FRV_GNU_VTENTRY:
-          if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+          if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
             return FALSE;
           break;
+
+       case R_FRV_LABEL16:
+       case R_FRV_LO16:
+       case R_FRV_HI16:
+       case R_FRV_GPREL12:
+       case R_FRV_GPRELU12:
+       case R_FRV_GPREL32:
+       case R_FRV_GPRELHI:
+       case R_FRV_GPRELLO:
+         break;
+
+       default:
+       bad_reloc:
+         (*_bfd_error_handler)
+           (_("%B: unsupported relocation type %i"),
+            abfd, ELF32_R_TYPE (rel->r_info));
+         return FALSE;
         }
     }
 
@@ -4153,7 +4272,8 @@ elf32_frv_object_p (abfd)
      bfd *abfd;
 {
   bfd_default_set_arch_mach (abfd, bfd_arch_frv, elf32_frv_machine (abfd));
-  return TRUE;
+  return (((elf_elfheader (abfd)->e_flags & EF_FRV_FDPIC) != 0)
+         == (IS_FDPIC (abfd)));
 }
 \f
 /* Function to set the ELF flag bits.  */
@@ -4214,6 +4334,50 @@ frv_elf_arch_extension_p (flagword base, flagword extension)
   return FALSE;
 }
 
+static bfd_boolean
+elf32_frvfdpic_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 (! frv_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;
+}
+
 /* Merge backend specific data from an object file to the output
    object file when linking.  */
 
@@ -4467,6 +4631,20 @@ frv_elf_merge_private_bfd_data (ibfd, obfd)
   if (old_partial != (old_flags & EF_FRV_CPU_MASK))
     bfd_default_set_arch_mach (obfd, bfd_arch_frv, elf32_frv_machine (obfd));
 
+  if (((new_flags & EF_FRV_FDPIC) == 0)
+      != (! IS_FDPIC (ibfd)))
+    {
+      error = TRUE;
+      if (IS_FDPIC (obfd))
+       (*_bfd_error_handler)
+         (_("%s: cannot link non-fdpic object file into fdpic executable"),
+          bfd_get_filename (ibfd));
+      else
+       (*_bfd_error_handler)
+         (_("%s: cannot link fdpic object file into non-fdpic executable"),
+          bfd_get_filename (ibfd));
+    }
+
   if (error)
     bfd_set_error (bfd_error_bad_value);
 
@@ -4545,7 +4723,7 @@ frv_elf_print_private_bfd_data (abfd, ptr)
 
   if (flags & EF_FRV_FDPIC)
     fprintf (file, " -mfdpic");
-  
+
   if (flags & EF_FRV_NON_PIC_RELOCS)
     fprintf (file, " non-pic relocations");
 
@@ -4564,7 +4742,6 @@ frv_elf_print_private_bfd_data (abfd, ptr)
 #define TARGET_BIG_SYM          bfd_elf32_frv_vec
 #define TARGET_BIG_NAME                "elf32-frv"
 
-#define elf_info_to_howto_rel                  frv_info_to_howto_rel
 #define elf_info_to_howto                      frv_info_to_howto_rela
 #define elf_backend_relocate_section           elf32_frv_relocate_section
 #define elf_backend_gc_mark_hook               elf32_frv_gc_mark_hook
@@ -4582,39 +4759,79 @@ frv_elf_print_private_bfd_data (abfd, ptr)
 #define bfd_elf32_bfd_merge_private_bfd_data   frv_elf_merge_private_bfd_data
 #define bfd_elf32_bfd_print_private_bfd_data   frv_elf_print_private_bfd_data
 
-#define bfd_elf32_bfd_link_hash_table_create  frv_elf_link_hash_table_create
+#define elf_backend_want_got_sym       1
+#define elf_backend_got_header_size    0
+#define elf_backend_want_got_plt       0
+#define elf_backend_plt_readonly       1
+#define elf_backend_want_plt_sym       0
+#define elf_backend_plt_header_size    0
+
+#define elf_backend_finish_dynamic_sections \
+               elf32_frv_finish_dynamic_sections
+
+#include "elf32-target.h"
+
+#undef ELF_MAXPAGESIZE
+#define ELF_MAXPAGESIZE                0x4000
+
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM          bfd_elf32_frvfdpic_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME                "elf32-frvfdpic"
+#undef elf32_bed
+#define        elf32_bed               elf32_frvfdpic_bed
+
+#undef elf_info_to_howto_rel
+#define elf_info_to_howto_rel  frvfdpic_info_to_howto_rel
+
+#undef bfd_elf32_bfd_link_hash_table_create
+#define bfd_elf32_bfd_link_hash_table_create \
+               frvfdpic_elf_link_hash_table_create
+#undef elf_backend_always_size_sections
 #define elf_backend_always_size_sections \
-               elf32_frv_always_size_sections
+               elf32_frvfdpic_always_size_sections
+#undef elf_backend_modify_segment_map
 #define elf_backend_modify_segment_map \
-               elf32_frv_modify_segment_map
+               elf32_frvfdpic_modify_segment_map
+#undef bfd_elf32_bfd_copy_private_bfd_data
+#define bfd_elf32_bfd_copy_private_bfd_data \
+               elf32_frvfdpic_copy_private_bfd_data
 
+#undef elf_backend_create_dynamic_sections
 #define elf_backend_create_dynamic_sections \
-               elf32_frv_create_dynamic_sections
+               elf32_frvfdpic_create_dynamic_sections
+#undef elf_backend_adjust_dynamic_symbol
 #define elf_backend_adjust_dynamic_symbol \
-               elf32_frv_adjust_dynamic_symbol
+               elf32_frvfdpic_adjust_dynamic_symbol
+#undef elf_backend_size_dynamic_sections
 #define elf_backend_size_dynamic_sections \
-               elf32_frv_size_dynamic_sections
+               elf32_frvfdpic_size_dynamic_sections
+#undef elf_backend_finish_dynamic_symbol
 #define elf_backend_finish_dynamic_symbol \
-               elf32_frv_finish_dynamic_symbol
+               elf32_frvfdpic_finish_dynamic_symbol
+#undef elf_backend_finish_dynamic_sections
 #define elf_backend_finish_dynamic_sections \
-               elf32_frv_finish_dynamic_sections
-
-#define elf_backend_want_got_sym       1
-#define elf_backend_got_header_size    0
-#define elf_backend_want_got_plt       0
-#define elf_backend_plt_readonly       1
-#define elf_backend_want_plt_sym       0
-#define elf_backend_plt_header_size    0
+               elf32_frvfdpic_finish_dynamic_sections
 
+#undef elf_backend_can_make_relative_eh_frame
 #define elf_backend_can_make_relative_eh_frame \
-               frv_elf_use_relative_eh_frame
+               frvfdpic_elf_use_relative_eh_frame
+#undef elf_backend_can_make_lsda_relative_eh_frame
 #define elf_backend_can_make_lsda_relative_eh_frame \
-               frv_elf_use_relative_eh_frame
-#define elf_backend_encode_eh_address  frv_elf_encode_eh_address
+               frvfdpic_elf_use_relative_eh_frame
+#undef elf_backend_encode_eh_address
+#define elf_backend_encode_eh_address \
+               frvfdpic_elf_encode_eh_address
 
+#undef elf_backend_may_use_rel_p
 #define elf_backend_may_use_rel_p       1
+#undef elf_backend_may_use_rela_p
 #define elf_backend_may_use_rela_p      1
 /* We use REL for dynamic relocations only.  */
+#undef elf_backend_default_use_rela_p
 #define elf_backend_default_use_rela_p  1
 
+#undef elf_backend_omit_section_dynsym
+#define elf_backend_omit_section_dynsym _frvfdpic_link_omit_section_dynsym
+
 #include "elf32-target.h"
This page took 0.06685 seconds and 4 git commands to generate.