Fix AArch32 build attributes for Armv8.4-A.
[deliverable/binutils-gdb.git] / bfd / elf32-nds32.c
index 2b63024c9c35be1fadb77f8d2e242adb3cedd5aa..541ec5d55d287f5f29eae146a457baa6797ef36e 100644 (file)
@@ -1,5 +1,5 @@
 /* NDS32-specific support for 32-bit ELF.
-   Copyright (C) 2012-2014 Free Software Foundation, Inc.
+   Copyright (C) 2012-2018 Free Software Foundation, Inc.
    Contributed by Andes Technology Corporation.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -56,62 +56,14 @@ static bfd_reloc_status_type nds32_elf_sda15_reloc
 static bfd_reloc_status_type nds32_elf_do_9_pcrel_reloc
   (bfd *, reloc_howto_type *, asection *, bfd_byte *, bfd_vma,
    asection *, bfd_vma, bfd_vma);
-static void nds32_elf_relocate_hi20
-  (bfd *, int, Elf_Internal_Rela *, Elf_Internal_Rela *, bfd_byte *, bfd_vma);
-static reloc_howto_type *bfd_elf32_bfd_reloc_type_table_lookup
-  (enum elf_nds32_reloc_type);
-static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
-  (bfd *, bfd_reloc_code_real_type);
-
-/* Target hooks.  */
-static void nds32_info_to_howto_rel
-  (bfd *, arelent *, Elf_Internal_Rela *dst);
-static void nds32_info_to_howto
-  (bfd *, arelent *, Elf_Internal_Rela *dst);
-static bfd_boolean nds32_elf_add_symbol_hook
-  (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **,
-   flagword *, asection **, bfd_vma *);
-static bfd_boolean nds32_elf_relocate_section
-  (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
-   Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
-static bfd_boolean nds32_elf_object_p (bfd *);
-static void nds32_elf_final_write_processing (bfd *, bfd_boolean);
-static bfd_boolean nds32_elf_set_private_flags (bfd *, flagword);
-static bfd_boolean nds32_elf_merge_private_bfd_data (bfd *, bfd *);
-static bfd_boolean nds32_elf_print_private_bfd_data (bfd *, void *);
-static bfd_boolean nds32_elf_gc_sweep_hook
-  (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
-static bfd_boolean nds32_elf_check_relocs
-  (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
-static asection *nds32_elf_gc_mark_hook
-  (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
-   struct elf_link_hash_entry *, Elf_Internal_Sym *);
-static bfd_boolean nds32_elf_adjust_dynamic_symbol
-  (struct bfd_link_info *, struct elf_link_hash_entry *);
-static bfd_boolean nds32_elf_size_dynamic_sections
-  (bfd *, struct bfd_link_info *);
-static bfd_boolean nds32_elf_create_dynamic_sections
-  (bfd *, struct bfd_link_info *);
-static bfd_boolean nds32_elf_finish_dynamic_sections
-  (bfd *, struct bfd_link_info *info);
-static bfd_boolean nds32_elf_finish_dynamic_symbol
-  (bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
-   Elf_Internal_Sym *);
-static bfd_boolean nds32_elf_mkobject (bfd *);
 
 /* Nds32 helper functions.  */
-static bfd_reloc_status_type nds32_elf_final_sda_base
-  (bfd *, struct bfd_link_info *, bfd_vma *, bfd_boolean);
-static bfd_boolean allocate_dynrelocs (struct elf_link_hash_entry *, void *);
-static bfd_boolean readonly_dynrelocs (struct elf_link_hash_entry *, void *);
-static Elf_Internal_Rela *find_relocs_at_address
-  (Elf_Internal_Rela *, Elf_Internal_Rela *,
-   Elf_Internal_Rela *, enum elf_nds32_reloc_type);
 static bfd_vma calculate_memory_address
-  (bfd *, Elf_Internal_Rela *, Elf_Internal_Sym *, Elf_Internal_Shdr *);
-static int nds32_get_section_contents (bfd *, asection *, bfd_byte **);
+(bfd *, Elf_Internal_Rela *, Elf_Internal_Sym *, Elf_Internal_Shdr *);
+static int nds32_get_section_contents (bfd *, asection *,
+                                      bfd_byte **, bfd_boolean);
 static bfd_boolean nds32_elf_ex9_build_hash_table
-  (bfd *, asection *, struct bfd_link_info *);
+(bfd *, asection *, struct bfd_link_info *);
 static bfd_boolean nds32_elf_ex9_itb_base (struct bfd_link_info *);
 static void nds32_elf_ex9_import_table (struct bfd_link_info *);
 static void nds32_elf_ex9_finish (struct bfd_link_info *);
@@ -134,13 +86,6 @@ static bfd_boolean  nds32_relax_fp_as_gp
 static bfd_boolean nds32_fag_remove_unused_fpbase
   (bfd *abfd, asection *sec, Elf_Internal_Rela *internal_relocs,
    Elf_Internal_Rela *irelend);
-static bfd_byte *
-nds32_elf_get_relocated_section_contents (bfd *abfd,
-                                         struct bfd_link_info *link_info,
-                                         struct bfd_link_order *link_order,
-                                         bfd_byte *data,
-                                         bfd_boolean relocatable,
-                                         asymbol **symbols);
 
 enum
 {
@@ -168,32 +113,32 @@ enum
 /* The first entry in a procedure linkage table are reserved,
    and the initial contents are unimportant (we zero them out).
    Subsequent entries look like this.  */
-#define PLT0_ENTRY_WORD0  0x46f00000           /* sethi   r15, HI20(.got+4)      */
-#define PLT0_ENTRY_WORD1  0x58f78000           /* ori     r15, r25, LO12(.got+4) */
-#define PLT0_ENTRY_WORD2  0x05178000           /* lwi     r17, [r15+0]           */
-#define PLT0_ENTRY_WORD3  0x04f78001           /* lwi     r15, [r15+4]           */
-#define PLT0_ENTRY_WORD4  0x4a003c00           /* jr      r15                    */
+#define PLT0_ENTRY_WORD0  0x46f00000           /* sethi   r15, HI20(.got+4)      */
+#define PLT0_ENTRY_WORD1  0x58f78000           /* ori     r15, r25, LO12(.got+4) */
+#define PLT0_ENTRY_WORD2  0x05178000           /* lwi     r17, [r15+0]           */
+#define PLT0_ENTRY_WORD3  0x04f78001           /* lwi     r15, [r15+4]           */
+#define PLT0_ENTRY_WORD4  0x4a003c00           /* jr      r15                    */
 
 /* $ta is change to $r15 (from $r25).  */
 #define PLT0_PIC_ENTRY_WORD0  0x46f00000       /* sethi   r15, HI20(got[1]@GOT)  */
-#define PLT0_PIC_ENTRY_WORD1  0x58f78000       /* ori     r15, r15, LO12(got[1]@GOT) */
-#define PLT0_PIC_ENTRY_WORD2  0x40f7f400       /* add     r15, gp, r15           */
-#define PLT0_PIC_ENTRY_WORD3  0x05178000       /* lwi     r17, [r15+0]           */
-#define PLT0_PIC_ENTRY_WORD4  0x04f78001       /* lwi     r15, [r15+4]           */
-#define PLT0_PIC_ENTRY_WORD5  0x4a003c00       /* jr      r15                    */
-
-#define PLT_ENTRY_WORD0  0x46f00000            /* sethi   r15, HI20(&got[n+3])      */
-#define PLT_ENTRY_WORD1  0x04f78000            /* lwi     r15, r15, LO12(&got[n+3]) */
-#define PLT_ENTRY_WORD2  0x4a003c00            /* jr      r15                       */
-#define PLT_ENTRY_WORD3  0x45000000            /* movi    r16, sizeof(RELA) * n     */
-#define PLT_ENTRY_WORD4  0x48000000            /* j      .plt0.                     */
+#define PLT0_PIC_ENTRY_WORD1  0x58f78000       /* ori     r15, r15, LO12(got[1]@GOT) */
+#define PLT0_PIC_ENTRY_WORD2  0x40f7f400       /* add     r15, gp, r15           */
+#define PLT0_PIC_ENTRY_WORD3  0x05178000       /* lwi     r17, [r15+0]           */
+#define PLT0_PIC_ENTRY_WORD4  0x04f78001       /* lwi     r15, [r15+4]           */
+#define PLT0_PIC_ENTRY_WORD5  0x4a003c00       /* jr      r15                    */
+
+#define PLT_ENTRY_WORD0         0x46f00000             /* sethi   r15, HI20(&got[n+3])      */
+#define PLT_ENTRY_WORD1         0x04f78000             /* lwi     r15, r15, LO12(&got[n+3]) */
+#define PLT_ENTRY_WORD2         0x4a003c00             /* jr      r15                       */
+#define PLT_ENTRY_WORD3         0x45000000             /* movi    r16, sizeof(RELA) * n     */
+#define PLT_ENTRY_WORD4         0x48000000             /* j      .plt0.                     */
 
 #define PLT_PIC_ENTRY_WORD0  0x46f00000                /* sethi  r15, HI20(got[n+3]@GOT)    */
-#define PLT_PIC_ENTRY_WORD1  0x58f78000                /* ori    r15, r15,    LO12(got[n+3]@GOT) */
-#define PLT_PIC_ENTRY_WORD2  0x38febc02                /* lw     r15, [gp+r15]              */
-#define PLT_PIC_ENTRY_WORD3  0x4a003c00                /* jr     r15                        */
-#define PLT_PIC_ENTRY_WORD4  0x45000000                /* movi   r16, sizeof(RELA) * n      */
-#define PLT_PIC_ENTRY_WORD5  0x48000000                /* j      .plt0                      */
+#define PLT_PIC_ENTRY_WORD1  0x58f78000                /* ori    r15, r15,    LO12(got[n+3]@GOT) */
+#define PLT_PIC_ENTRY_WORD2  0x38febc02                /* lw     r15, [gp+r15]              */
+#define PLT_PIC_ENTRY_WORD3  0x4a003c00                /* jr     r15                        */
+#define PLT_PIC_ENTRY_WORD4  0x45000000                /* movi   r16, sizeof(RELA) * n      */
+#define PLT_PIC_ENTRY_WORD5  0x48000000                /* j      .plt0                      */
 
 /* These are macros used to get the relocation accurate value.  */
 #define ACCURATE_8BIT_S1       (0x100)
@@ -247,26 +192,6 @@ struct elf_nds32_pcrel_relocs_copied
   bfd_size_type count;
 };
 
-/* The sh linker needs to keep track of the number of relocs that it
-   decides to copy as dynamic relocs in check_relocs for each symbol.
-   This is so that it can later discard them if they are found to be
-   unnecessary.  We store the information in a field extending the
-   regular ELF linker hash table.  */
-
-struct elf_nds32_dyn_relocs
-{
-  struct elf_nds32_dyn_relocs *next;
-
-  /* The input section of the reloc.  */
-  asection *sec;
-
-  /* Total number of relocs copied for the input section.  */
-  bfd_size_type count;
-
-  /* Number of pc-relative relocs copied for the input section.  */
-  bfd_size_type pc_count;
-};
-
 /* Nds32 ELF linker hash entry.  */
 
 struct elf_nds32_link_hash_entry
@@ -274,7 +199,7 @@ struct elf_nds32_link_hash_entry
   struct elf_link_hash_entry root;
 
   /* Track dynamic relocs copied for this symbol.  */
-  struct elf_nds32_dyn_relocs *dyn_relocs;
+  struct elf_dyn_relocs *dyn_relocs;
 
   /* For checking relocation type.  */
 #define GOT_UNKNOWN     0
@@ -321,11 +246,11 @@ static reloc_howto_type nds32_elf_howto_table[] =
   /* This reloc does nothing.  */
   HOWTO (R_NDS32_NONE,         /* type */
         0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
+        3,                     /* size (0 = byte, 1 = short, 2 = long) */
+        0,                     /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield,    /* complain_on_overflow */
+        complain_overflow_dont,        /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_NDS32_NONE",        /* name */
         FALSE,                 /* partial_inplace */
@@ -2299,7 +2224,7 @@ nds32_insertion_sort (void *base, size_t nmemb, size_t size,
 {
   char *ptr = (char *) base;
   int i, j;
-  char *tmp = alloca (size);
+  char *tmp = xmalloc (size);
 
   /* If i is less than j, i is inserted before j.
 
@@ -2323,6 +2248,7 @@ nds32_insertion_sort (void *base, size_t nmemb, size_t size,
       memmove (ptr + (j + 1) * size, ptr + j * size, (i - j) * size);
       memcpy (ptr + j * size, tmp, size);
     }
+  free (tmp);
 }
 
 /* Sort relocation by r_offset.
@@ -2965,7 +2891,12 @@ nds32_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
   enum elf_nds32_reloc_type r_type;
 
   r_type = ELF32_R_TYPE (dst->r_info);
-  BFD_ASSERT (ELF32_R_TYPE (dst->r_info) <= R_NDS32_GNU_VTENTRY);
+  if (r_type > R_NDS32_GNU_VTENTRY)
+    {
+      /* xgettext:c-format */
+      _bfd_error_handler (_("%B: invalid NDS32 reloc number: %d"), abfd, r_type);
+      r_type = 0;
+    }
   cache_ptr->howto = bfd_elf32_bfd_reloc_type_table_lookup (r_type);
 }
 
@@ -3040,6 +2971,7 @@ nds32_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
        _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
       elf_tdata (abfd)->core->command =
        _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
+      break;
 
     default:
       return FALSE;
@@ -3286,7 +3218,7 @@ nds32_elf_final_sda_base (bfd *output_bfd, struct bfd_link_info *info,
        }
     }
 
-  if (add_symbol == TRUE)
+  if (add_symbol)
     {
       if (h)
        {
@@ -3297,7 +3229,7 @@ nds32_elf_final_sda_base (bfd *output_bfd, struct bfd_link_info *info,
        }
       else
        {
-         (*_bfd_error_handler) (_("error: Can't find symbol: _SDA_BASE_."));
+         _bfd_error_handler (_("error: Can't find symbol: _SDA_BASE_."));
          return bfd_reloc_dangerous;
        }
     }
@@ -3371,50 +3303,9 @@ nds32_elf_link_hash_table_create (bfd *abfd)
       return NULL;
     }
 
-  ret->sgot = NULL;
-  ret->sgotplt = NULL;
-  ret->srelgot = NULL;
-  ret->splt = NULL;
-  ret->srelplt = NULL;
-  ret->sdynbss = NULL;
-  ret->srelbss = NULL;
-  ret->sym_ld_script = NULL;
-  ret->ex9_export_file = NULL;
-  ret->ex9_import_file = NULL;
-
   return &ret->root.root;
 }
 
-/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
-   shortcuts to them in our hash table.  */
-
-static bfd_boolean
-create_got_section (bfd *dynobj, struct bfd_link_info *info)
-{
-  struct elf_nds32_link_hash_table *htab;
-
-  if (!_bfd_elf_create_got_section (dynobj, info))
-    return FALSE;
-
-  htab = nds32_elf_hash_table (info);
-  htab->sgot = bfd_get_section_by_name (dynobj, ".got");
-  htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
-  if (!htab->sgot || !htab->sgotplt)
-    abort ();
-
-  /* _bfd_elf_create_got_section will create it for us.  */
-  htab->srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
-  if (htab->srelgot == NULL
-      || !bfd_set_section_flags (dynobj, htab->srelgot,
-                                (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
-                                 | SEC_IN_MEMORY | SEC_LINKER_CREATED
-                                 | SEC_READONLY))
-      || !bfd_set_section_alignment (dynobj, htab->srelgot, 2))
-    return FALSE;
-
-  return TRUE;
-}
-
 /* Create dynamic sections when linking against a dynamic object.  */
 
 static bfd_boolean
@@ -3444,7 +3335,7 @@ nds32_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
     pltflags |= SEC_READONLY;
 
   s = bfd_make_section (abfd, ".plt");
-  htab->splt = s;
+  htab->root.splt = s;
   if (s == NULL
       || !bfd_set_section_flags (abfd, s, pltflags)
       || !bfd_set_section_alignment (abfd, s, bed->plt_alignment))
@@ -3467,19 +3358,19 @@ nds32_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
       h->def_regular = 1;
       h->type = STT_OBJECT;
 
-      if (info->shared && !bfd_elf_link_record_dynamic_symbol (info, h))
+      if (bfd_link_pic (info) && !bfd_elf_link_record_dynamic_symbol (info, h))
        return FALSE;
     }
 
   s = bfd_make_section (abfd,
                        bed->default_use_rela_p ? ".rela.plt" : ".rel.plt");
-  htab->srelplt = s;
+  htab->root.srelplt = s;
   if (s == NULL
       || !bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
       || !bfd_set_section_alignment (abfd, s, ptralign))
     return FALSE;
 
-  if (htab->sgot == NULL && !create_got_section (abfd, info))
+  if (htab->root.sgot == NULL && !_bfd_elf_create_got_section (abfd, info))
     return FALSE;
 
   {
@@ -3532,7 +3423,7 @@ nds32_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
         be needed, we can discard it later.  We will never need this
         section when generating a shared object, since they do not use
         copy relocs.  */
-      if (!info->shared)
+      if (!bfd_link_pic (info))
        {
          s = bfd_make_section (abfd, (bed->default_use_rela_p
                                       ? ".rela.bss" : ".rel.bss"));
@@ -3562,8 +3453,8 @@ nds32_elf_copy_indirect_symbol (struct bfd_link_info *info,
     {
       if (edir->dyn_relocs != NULL)
        {
-         struct elf_nds32_dyn_relocs **pp;
-         struct elf_nds32_dyn_relocs *p;
+         struct elf_dyn_relocs **pp;
+         struct elf_dyn_relocs *p;
 
          if (ind->root.type == bfd_link_hash_indirect)
            abort ();
@@ -3572,7 +3463,7 @@ nds32_elf_copy_indirect_symbol (struct bfd_link_info *info,
             list.  Merge any entries against the same section.  */
          for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
            {
-             struct elf_nds32_dyn_relocs *q;
+             struct elf_dyn_relocs *q;
 
              for (q = edir->dyn_relocs; q != NULL; q = q->next)
                if (q->sec == p->sec)
@@ -3595,6 +3486,22 @@ nds32_elf_copy_indirect_symbol (struct bfd_link_info *info,
   _bfd_elf_link_hash_copy_indirect (info, dir, ind);
 }
 \f
+/* Find dynamic relocs for H that apply to read-only sections.  */
+
+static asection *
+readonly_dynrelocs (struct elf_link_hash_entry *h)
+{
+  struct elf_dyn_relocs *p;
+
+  for (p = elf32_nds32_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
+    {
+      asection *s = p->sec->output_section;
+
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
+       return p->sec;
+    }
+  return NULL;
+}
 
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
@@ -3607,8 +3514,6 @@ nds32_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
                                 struct elf_link_hash_entry *h)
 {
   struct elf_nds32_link_hash_table *htab;
-  struct elf_nds32_link_hash_entry *eh;
-  struct elf_nds32_dyn_relocs *p;
   bfd *dynobj;
   asection *s;
   unsigned int power_of_two;
@@ -3618,7 +3523,7 @@ nds32_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   /* Make sure we know what is going on here.  */
   BFD_ASSERT (dynobj != NULL
              && (h->needs_plt
-                 || h->u.weakdef != NULL
+                 || h->is_weakalias
                  || (h->def_dynamic && h->ref_regular && !h->def_regular)));
 
 
@@ -3627,7 +3532,7 @@ nds32_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
      when we know the address of the .got section.  */
   if (h->type == STT_FUNC || h->needs_plt)
     {
-      if (!info->shared
+      if (!bfd_link_pic (info)
          && !h->def_dynamic
          && !h->ref_dynamic
          && h->root.type != bfd_link_hash_undefweak
@@ -3650,12 +3555,12 @@ nds32_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   /* If this is a weak symbol, and there is a real definition, the
      processor independent code will have arranged for us to see the
      real definition first, and we can just use the same value.  */
-  if (h->u.weakdef != NULL)
+  if (h->is_weakalias)
     {
-      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;
+      struct elf_link_hash_entry *def = weakdef (h);
+      BFD_ASSERT (def->root.type == bfd_link_hash_defined);
+      h->root.u.def.section = def->root.u.def.section;
+      h->root.u.def.value = def->root.u.def.value;
       return TRUE;
     }
 
@@ -3666,7 +3571,7 @@ nds32_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
      only references to the symbol are via the global offset table.
      For such cases we need not do anything here; the relocations will
      be handled correctly by relocate_section.  */
-  if (info->shared)
+  if (bfd_link_pic (info))
     return TRUE;
 
   /* If there are no references to this symbol that do not use the
@@ -3675,24 +3580,15 @@ nds32_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
     return TRUE;
 
   /* If -z nocopyreloc was given, we won't generate them either.  */
-  if (info->nocopyreloc)
+  if (0 && info->nocopyreloc)
     {
       h->non_got_ref = 0;
       return TRUE;
     }
 
-  eh = (struct elf_nds32_link_hash_entry *) h;
-  for (p = eh->dyn_relocs; p != NULL; p = p->next)
-    {
-      s = p->sec->output_section;
-      if (s != NULL && (s->flags & (SEC_READONLY | SEC_HAS_CONTENTS)) != 0)
-       break;
-    }
-
-  /* If we didn't find any dynamic relocs in sections which needs the
-     copy reloc, then we'll be keeping the dynamic relocs and avoiding
-     the copy reloc.  */
-  if (p == NULL)
+  /* If we don't find any dynamic relocs in read-only sections, then
+     we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
+  if (0 && !readonly_dynrelocs (h))
     {
       h->non_got_ref = 0;
       return TRUE;
@@ -3759,7 +3655,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
   struct bfd_link_info *info;
   struct elf_nds32_link_hash_table *htab;
   struct elf_nds32_link_hash_entry *eh;
-  struct elf_nds32_dyn_relocs *p;
+  struct elf_dyn_relocs *p;
 
   if (h->root.type == bfd_link_hash_indirect)
     return TRUE;
@@ -3785,9 +3681,9 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
            return FALSE;
        }
 
-      if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h))
+      if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h))
        {
-         asection *s = htab->splt;
+         asection *s = htab->root.splt;
 
          /* If this is the first .plt entry, make room for the special
             first entry.  */
@@ -3801,7 +3697,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
             location in the .plt.  This is required to make function
             pointers compare as equal between the normal executable and
             the shared library.  */
-         if (!info->shared && !h->def_regular)
+         if (!bfd_link_pic (info) && !h->def_regular)
            {
              h->root.u.def.section = s;
              h->root.u.def.value = h->plt.offset;
@@ -3812,10 +3708,10 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 
          /* We also need to make an entry in the .got.plt section, which
             will be placed in the .got section by the linker script.  */
-         htab->sgotplt->size += 4;
+         htab->root.sgotplt->size += 4;
 
          /* We also need to make an entry in the .rel.plt section.  */
-         htab->srelplt->size += sizeof (Elf32_External_Rela);
+         htab->root.srelplt->size += sizeof (Elf32_External_Rela);
        }
       else
        {
@@ -3843,7 +3739,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
            return FALSE;
        }
 
-      s = htab->sgot;
+      s = htab->root.sgot;
       h->got.offset = s->size;
 
       if (tls_type == GOT_UNKNOWN)
@@ -3854,8 +3750,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
        s->size += 4;
 
       dyn = htab->root.dynamic_sections_created;
-      if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h))
-       htab->srelgot->size += sizeof (Elf32_External_Rela);
+      if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h))
+       htab->root.srelgot->size += sizeof (Elf32_External_Rela);
     }
   else
     h->got.offset = (bfd_vma) - 1;
@@ -3869,11 +3765,11 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
      space for pc-relative relocs that have become local due to symbol
      visibility changes.  */
 
-  if (info->shared)
+  if (bfd_link_pic (info))
     {
       if (h->def_regular && (h->forced_local || info->symbolic))
        {
-         struct elf_nds32_dyn_relocs **pp;
+         struct elf_dyn_relocs **pp;
 
          for (pp = &eh->dyn_relocs; (p = *pp) != NULL;)
            {
@@ -3927,31 +3823,29 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
   return TRUE;
 }
 
-/* Find any dynamic relocs that apply to read-only sections.  */
+/* Set DF_TEXTREL if we find any dynamic relocs that apply to
+   read-only sections.  */
 
 static bfd_boolean
-readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
+maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
 {
-  struct elf_nds32_link_hash_entry *eh;
-  struct elf_nds32_dyn_relocs *p;
+  asection *sec;
 
-  if (h->root.type == bfd_link_hash_warning)
-    h = (struct elf_link_hash_entry *) h->root.u.i.link;
+  if (h->root.type == bfd_link_hash_indirect)
+    return TRUE;
 
-  eh = (struct elf_nds32_link_hash_entry *) h;
-  for (p = eh->dyn_relocs; p != NULL; p = p->next)
+  sec = readonly_dynrelocs (h);
+  if (sec != NULL)
     {
-      asection *s = p->sec->output_section;
-
-      if (s != NULL && (s->flags & SEC_READONLY) != 0)
-       {
-         struct bfd_link_info *info = (struct bfd_link_info *) inf;
+      struct bfd_link_info *info = (struct bfd_link_info *) info_p;
 
-         info->flags |= DF_TEXTREL;
+      info->flags |= DF_TEXTREL;
+      info->callbacks->minfo
+       (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"),
+        sec->owner, h->root.root.string, sec);
 
-         /* Not an error, just cut short the traversal.  */
-         return FALSE;
-       }
+      /* Not an error, just cut short the traversal.  */
+      return FALSE;
     }
   return TRUE;
 }
@@ -3975,7 +3869,7 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
   if (htab->root.dynamic_sections_created)
     {
       /* Set the contents of the .interp section to the interpreter.  */
-      if (!info->shared)
+      if (bfd_link_executable (info) && !info->nointerp)
        {
          s = bfd_get_section_by_name (dynobj, ".interp");
          BFD_ASSERT (s != NULL);
@@ -3999,9 +3893,9 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 
       for (s = ibfd->sections; s != NULL; s = s->next)
        {
-         struct elf_nds32_dyn_relocs *p;
+         struct elf_dyn_relocs *p;
 
-         for (p = ((struct elf_nds32_dyn_relocs *)
+         for (p = ((struct elf_dyn_relocs *)
                    elf_section_data (s)->local_dynrel);
               p != NULL; p = p->next)
            {
@@ -4030,15 +3924,15 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
       symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
       locsymcount = symtab_hdr->sh_info;
       end_local_got = local_got + locsymcount;
-      s = htab->sgot;
-      srel = htab->srelgot;
+      s = htab->root.sgot;
+      srel = htab->root.srelgot;
       for (; local_got < end_local_got; ++local_got)
        {
          if (*local_got > 0)
            {
              *local_got = s->size;
              s->size += 4;
-             if (info->shared)
+             if (bfd_link_pic (info))
                srel->size += sizeof (Elf32_External_Rela);
            }
          else
@@ -4058,22 +3952,22 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
       if ((s->flags & SEC_LINKER_CREATED) == 0)
        continue;
 
-      if (s == htab->splt)
+      if (s == htab->root.splt)
        {
          /* Strip this section if we don't need it; see the
             comment below.  */
        }
-      else if (s == htab->sgot)
+      else if (s == htab->root.sgot)
        {
          got_size += s->size;
        }
-      else if (s == htab->sgotplt)
+      else if (s == htab->root.sgotplt)
        {
          got_size += s->size;
        }
       else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0)
        {
-         if (s->size != 0 && s != htab->srelplt)
+         if (s->size != 0 && s != htab->root.srelplt)
            relocs = TRUE;
 
          /* We use the reloc_count field as a counter if we need
@@ -4122,13 +4016,13 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 #define add_dynamic_entry(TAG, VAL) \
   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
 
-      if (!info->shared)
+      if (!bfd_link_pic (info))
        {
          if (!add_dynamic_entry (DT_DEBUG, 0))
            return FALSE;
        }
 
-      if (htab->splt->size != 0)
+      if (htab->root.splt->size != 0)
        {
          if (!add_dynamic_entry (DT_PLTGOT, 0)
              || !add_dynamic_entry (DT_PLTRELSZ, 0)
@@ -4147,7 +4041,7 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
          /* If any dynamic relocs apply to a read-only section,
             then we need a DT_TEXTREL entry.  */
          if ((info->flags & DF_TEXTREL) == 0)
-           elf_link_hash_traverse (&htab->root, readonly_dynrelocs,
+           elf_link_hash_traverse (&htab->root, maybe_set_textrel,
                                    (void *) info);
 
          if ((info->flags & DF_TEXTREL) != 0)
@@ -4182,11 +4076,10 @@ nds32_relocate_contents (reloc_howto_type *howto, bfd *input_bfd,
   switch (size)
     {
     default:
-    case 0:
-    case 1:
-    case 8:
       abort ();
       break;
+    case 0:
+      return bfd_reloc_ok;
     case 2:
       x = bfd_getb16 (location);
       break;
@@ -4457,14 +4350,14 @@ dtpoff_base (struct bfd_link_info *info)
 }
 
 static bfd_boolean
-nds32_elf_relocate_section (bfd *                  output_bfd ATTRIBUTE_UNUSED,
+nds32_elf_relocate_section (bfd *                 output_bfd ATTRIBUTE_UNUSED,
                            struct bfd_link_info * info,
-                           bfd *                  input_bfd,
-                           asection *             input_section,
-                           bfd_byte *             contents,
-                           Elf_Internal_Rela *    relocs,
-                           Elf_Internal_Sym *     local_syms,
-                           asection **            local_sections)
+                           bfd *                  input_bfd,
+                           asection *             input_section,
+                           bfd_byte *             contents,
+                           Elf_Internal_Rela *    relocs,
+                           Elf_Internal_Sym *     local_syms,
+                           asection **            local_sections)
 {
   Elf_Internal_Shdr *symtab_hdr;
   struct elf_link_hash_entry **sym_hashes;
@@ -4491,8 +4384,8 @@ nds32_elf_relocate_section (bfd *                  output_bfd ATTRIBUTE_UNUSED,
   dynobj = htab->root.dynobj;
   local_got_offsets = elf_local_got_offsets (input_bfd);
 
-  sgot = htab->sgot;
-  splt = htab->splt;
+  sgot = htab->root.sgot;
+  splt = htab->root.splt;
   sreloc = NULL;
 
   rel = relocs;
@@ -4501,7 +4394,7 @@ nds32_elf_relocate_section (bfd *                  output_bfd ATTRIBUTE_UNUSED,
   table = nds32_elf_hash_table (info);
   eliminate_gc_relocs = table->eliminate_gc_relocs;
   /* By this time, we can adjust the value of _SDA_BASE_.  */
-  if ((!info->relocatable))
+  if ((!bfd_link_relocatable (info)))
     {
       is_SDA_BASE_set = 1;
       r = nds32_elf_final_sda_base (output_bfd, info, &gp, TRUE);
@@ -4509,9 +4402,20 @@ nds32_elf_relocate_section (bfd *                  output_bfd ATTRIBUTE_UNUSED,
        return FALSE;
     }
 
+  if (is_ITB_BASE_set == 0)
+    {
+      /* Set the _ITB_BASE_.  */
+      if (!nds32_elf_ex9_itb_base (info))
+       {
+         _bfd_error_handler (_("%B: error: Cannot set _ITB_BASE_"),
+                             output_bfd);
+         bfd_set_error (bfd_error_bad_value);
+       }
+    }
+
   if (table->target_optimize & NDS32_RELAX_JUMP_IFC_ON)
     if (!nds32_elf_ifc_reloc ())
-      (*_bfd_error_handler) (_("error: IFC relocation error."));
+      _bfd_error_handler (_("error: IFC relocation error."));
 
  /* Relocation for .ex9.itable.  */
   if (table->target_optimize & NDS32_RELAX_EX9_ON
@@ -4544,8 +4448,9 @@ nds32_elf_relocate_section (bfd *                  output_bfd ATTRIBUTE_UNUSED,
       r_type = ELF32_R_TYPE (rel->r_info);
       if (r_type >= R_NDS32_max)
        {
-         (*_bfd_error_handler) (_("%B: error: unknown relocation type %d."),
-                                input_bfd, r_type);
+         /* xgettext:c-format */
+         _bfd_error_handler (_("%B: error: unknown relocation type %d."),
+                             input_bfd, r_type);
          bfd_set_error (bfd_error_bad_value);
          ret = FALSE;
          continue;
@@ -4559,10 +4464,11 @@ nds32_elf_relocate_section (bfd *                  output_bfd ATTRIBUTE_UNUSED,
          || (r_type >= R_NDS32_INSN16 && r_type <= R_NDS32_25_FIXED_RELA)
          || r_type == R_NDS32_DATA
          || r_type == R_NDS32_TRAN
-         || (r_type >= R_NDS32_LONGCALL4 && r_type <= R_NDS32_LONGJUMP6))
+         || (r_type >= R_NDS32_LONGCALL4 && r_type <= R_NDS32_LONGJUMP7))
        continue;
 
-      /* If we enter the fp-as-gp region.  Resolve the address of best fp-base.  */
+      /* If we enter the fp-as-gp region.  Resolve the address
+        of best fp-base.  */
       if (ELF32_R_TYPE (rel->r_info) == R_NDS32_RELAX_REGION_BEGIN
          && (rel->r_addend & R_NDS32_RELAX_REGION_OMIT_FP_FLAG))
        {
@@ -4581,7 +4487,7 @@ nds32_elf_relocate_section (bfd *                  output_bfd ATTRIBUTE_UNUSED,
 
       if (((r_type >= R_NDS32_DWARF2_OP1_RELA
            && r_type <= R_NDS32_DWARF2_LEB_RELA)
-          || r_type >= R_NDS32_RELAX_ENTRY) && !info->relocatable)
+          || r_type >= R_NDS32_RELAX_ENTRY) && !bfd_link_relocatable (info))
        continue;
 
       howto = bfd_elf32_bfd_reloc_type_table_lookup (r_type);
@@ -4629,7 +4535,7 @@ nds32_elf_relocate_section (bfd *                  output_bfd ATTRIBUTE_UNUSED,
 
        }
 
-      if (info->relocatable)
+      if (bfd_link_relocatable (info))
        {
          /* This is a relocatable link.  We don't have to change
             anything, unless the reloc is against a section symbol,
@@ -4789,8 +4695,10 @@ nds32_elf_relocate_section (bfd *                  output_bfd ATTRIBUTE_UNUSED,
              off = h->got.offset;
              BFD_ASSERT (off != (bfd_vma) - 1);
              dyn = htab->root.dynamic_sections_created;
-             if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
-                 || (info->shared
+             if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
+                                                   bfd_link_pic (info),
+                                                   h)
+                 || (bfd_link_pic (info)
                      && (info->symbolic
                          || h->dynindx == -1
                          || h->forced_local) && h->def_regular))
@@ -4837,14 +4745,14 @@ nds32_elf_relocate_section (bfd *                  output_bfd ATTRIBUTE_UNUSED,
                {
                  bfd_put_32 (output_bfd, relocation, sgot->contents + off);
 
-                 if (info->shared)
+                 if (bfd_link_pic (info))
                    {
                      asection *srelgot;
                      Elf_Internal_Rela outrel;
 
                      /* We need to generate a R_NDS32_RELATIVE reloc
                         for the dynamic linker.  */
-                     srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+                     srelgot = htab->root.srelgot;
                      BFD_ASSERT (srelgot != NULL);
 
                      outrel.r_offset = (elf_gp (output_bfd)
@@ -4883,7 +4791,7 @@ nds32_elf_relocate_section (bfd *                  output_bfd ATTRIBUTE_UNUSED,
        case R_NDS32_LO12S1_RELA:
        case R_NDS32_LO12S0_RELA:
        case R_NDS32_LO12S0_ORI_RELA:
-         if (info->shared && r_symndx != 0
+         if (bfd_link_pic (info) && r_symndx != 0
              && (input_section->flags & SEC_ALLOC) != 0
              && (eliminate_gc_relocs == 0
                  || (sec && (sec->flags & SEC_EXCLUDE) == 0))
@@ -4984,11 +4892,11 @@ nds32_elf_relocate_section (bfd *                  output_bfd ATTRIBUTE_UNUSED,
          break;
 
        case R_NDS32_25_ABS_RELA:
-         if (info->shared)
+         if (bfd_link_pic (info))
            {
-             (*_bfd_error_handler)
-               (_("%s: warning: cannot deal R_NDS32_25_ABS_RELA in shared "
-                  "mode."), bfd_get_filename (input_bfd));
+             _bfd_error_handler
+               (_("%B: warning: cannot deal R_NDS32_25_ABS_RELA in shared "
+                  "mode."), input_bfd);
              return FALSE;
            }
          break;
@@ -5044,11 +4952,12 @@ nds32_elf_relocate_section (bfd *                  output_bfd ATTRIBUTE_UNUSED,
 
                  dyn = htab->root.dynamic_sections_created;
                  if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL
-                     (dyn, info->shared, h) || (info->shared
-                                                && (info->symbolic
-                                                    || h->dynindx == -1
-                                                    || h->forced_local)
-                                                && h->def_regular))
+                     (dyn, bfd_link_pic (info), h)
+                     || (bfd_link_pic (info)
+                         && (info->symbolic
+                             || h->dynindx == -1
+                             || h->forced_local)
+                         && h->def_regular))
                    {
                      /* This is actually a static link, or it is a
                         -Bsymbolic link and the symbol is defined
@@ -5090,14 +4999,14 @@ nds32_elf_relocate_section (bfd *                  output_bfd ATTRIBUTE_UNUSED,
                    {
                      bfd_put_32 (output_bfd, relocation, sgot->contents + off);
 
-                     if (info->shared)
+                     if (bfd_link_pic (info))
                        {
                          asection *srelgot;
                          Elf_Internal_Rela outrel;
 
                          /* We need to generate a R_NDS32_RELATIVE reloc
                             for the dynamic linker.  */
-                         srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
+                         srelgot = htab->root.srelgot;
                          BFD_ASSERT (srelgot != NULL);
 
                          outrel.r_offset = (elf_gp (output_bfd)
@@ -5119,7 +5028,7 @@ nds32_elf_relocate_section (bfd *                  output_bfd ATTRIBUTE_UNUSED,
          if (relocation & align)
            {
              /* Incorrect alignment.  */
-             (*_bfd_error_handler)
+             _bfd_error_handler
                (_("%B: warning: unaligned access to GOT entry."), input_bfd);
              ret = FALSE;
              r = bfd_reloc_dangerous;
@@ -5161,7 +5070,7 @@ handle_sda:
              r = nds32_elf_final_sda_base (output_bfd, info, &gp, FALSE);
              if (r != bfd_reloc_ok)
                {
-                 (*_bfd_error_handler)
+                 _bfd_error_handler
                    (_("%B: warning: relocate SDA_BASE failed."), input_bfd);
                  ret = FALSE;
                  goto check_reloc;
@@ -5182,7 +5091,8 @@ handle_sda:
              if (relocation & align)
                {
                  /* Incorrect alignment.  */
-                 (*_bfd_error_handler)
+                 _bfd_error_handler
+                   /* xgettext:c-format */
                    (_("%B(%A): warning: unaligned small data access of type %d."),
                     input_bfd, input_section, r_type);
                  ret = FALSE;
@@ -5226,8 +5136,8 @@ handle_sda:
                BFD_ASSERT (off != (bfd_vma) - 1);
                dyn = htab->root.dynamic_sections_created;
                tls_type = ((struct elf_nds32_link_hash_entry *) h)->tls_type;
-               if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
-                   && (!info->shared
+               if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
+                   && (!bfd_link_pic (info)
                        || !SYMBOL_REFERENCES_LOCAL (info, h)))
                  indx = h->dynindx;
              }
@@ -5254,8 +5164,8 @@ handle_sda:
            else
              {
                bfd_boolean need_relocs = FALSE;
-               srelgot = htab->srelgot;
-               if ((info->shared || indx != 0)
+               srelgot = htab->root.srelgot;
+               if ((bfd_link_pic (info) || indx != 0)
                    && (h == NULL
                        || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
                        || h->root.type != bfd_link_hash_undefweak))
@@ -5404,16 +5314,14 @@ check_reloc:
          switch (r)
            {
            case bfd_reloc_overflow:
-             if (!((*info->callbacks->reloc_overflow)
-                   (info, (h ? &h->root : NULL), name, howto->name,
-                    (bfd_vma) 0, input_bfd, input_section, offset)))
-               return FALSE;
+             (*info->callbacks->reloc_overflow)
+               (info, (h ? &h->root : NULL), name, howto->name,
+                (bfd_vma) 0, input_bfd, input_section, offset);
              break;
 
            case bfd_reloc_undefined:
-             if (!((*info->callbacks->undefined_symbol)
-                   (info, name, input_bfd, input_section, offset, TRUE)))
-               return FALSE;
+             (*info->callbacks->undefined_symbol)
+               (info, name, input_bfd, input_section, offset, TRUE);
              break;
 
            case bfd_reloc_outofrange:
@@ -5432,10 +5340,9 @@ check_reloc:
              errmsg = _("internal error: unknown error");
              /* Fall through.  */
 
-common_error:
-             if (!((*info->callbacks->warning)
-                   (info, errmsg, name, input_bfd, input_section, offset)))
-               return FALSE;
+           common_error:
+             (*info->callbacks->warning) (info, errmsg, name, input_bfd,
+                                          input_section, offset);
              break;
            }
        }
@@ -5472,9 +5379,9 @@ nds32_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
 
       BFD_ASSERT (h->dynindx != -1);
 
-      splt = htab->splt;
-      sgot = htab->sgotplt;
-      srela = htab->srelplt;
+      splt = htab->root.splt;
+      sgot = htab->root.sgotplt;
+      srela = htab->root.srelplt;
       BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL);
 
       /* Get the index in the procedure linkage table which
@@ -5489,7 +5396,7 @@ nds32_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
       got_offset = (plt_index + 3) * 4;
 
       /* Fill in the entry in the procedure linkage table.  */
-      if (!info->shared)
+      if (!bfd_link_pic (info))
        {
          unsigned long insn;
 
@@ -5581,8 +5488,8 @@ nds32_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
       /* This symbol has an entry in the global offset table.
         Set it up.  */
 
-      sgot = htab->sgot;
-      srela = htab->srelgot;
+      sgot = htab->root.sgot;
+      srela = htab->root.srelgot;
       BFD_ASSERT (sgot != NULL && srela != NULL);
 
       rela.r_offset = (sgot->output_section->vma
@@ -5593,7 +5500,7 @@ nds32_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
         the symbol was forced to be local because of a version file.
         The entry in the global offset table will already have been
         initialized in the relocate_section function.  */
-      if (info->shared
+      if (bfd_link_pic (info)
          && (info->symbolic
              || h->dynindx == -1 || h->forced_local) && h->def_regular)
        {
@@ -5664,7 +5571,7 @@ nds32_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
   htab = nds32_elf_hash_table (info);
   dynobj = htab->root.dynobj;
 
-  sgot = htab->sgotplt;
+  sgot = htab->root.sgotplt;
   sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
 
   if (htab->root.dynamic_sections_created)
@@ -5690,49 +5597,28 @@ nds32_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
              break;
 
            case DT_PLTGOT:
-             /* name = ".got"; */
-             s = htab->sgot->output_section;
+             s = htab->root.sgotplt;
              goto get_vma;
            case DT_JMPREL:
-             s = htab->srelplt->output_section;
+             s = htab->root.srelplt;
            get_vma:
-             BFD_ASSERT (s != NULL);
-             dyn.d_un.d_ptr = s->vma;
+             dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
              break;
 
            case DT_PLTRELSZ:
-             s = htab->srelplt->output_section;
-             BFD_ASSERT (s != NULL);
+             s = htab->root.srelplt;
              dyn.d_un.d_val = s->size;
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
              break;
-
-           case DT_RELASZ:
-             /* My reading of the SVR4 ABI indicates that the
-                procedure linkage table relocs (DT_JMPREL) should be
-                included in the overall relocs (DT_RELA).  This is
-                what Solaris does.  However, UnixWare can not handle
-                that case.  Therefore, we override the DT_RELASZ entry
-                here to make it not include the JMPREL relocs.  Since
-                the linker script arranges for .rela.plt to follow all
-                other relocation sections, we don't have to worry
-                about changing the DT_RELA entry.  */
-             if (htab->srelplt != NULL)
-               {
-                 s = htab->srelplt->output_section;
-                 dyn.d_un.d_val -= s->size;
-               }
-             bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
-             break;
            }
        }
 
       /* Fill in the first entry in the procedure linkage table.  */
-      splt = htab->splt;
+      splt = htab->root.splt;
       if (splt && splt->size > 0)
        {
-         if (info->shared)
+         if (bfd_link_pic (info))
            {
              unsigned long insn;
              long offset;
@@ -5943,7 +5829,7 @@ nds32_check_vec_size (bfd *ibfd)
       /* Get vec_size in file.  */
       unsigned int flag_t;
 
-      nds32_get_section_contents (ibfd, sec_t, &contents);
+      nds32_get_section_contents (ibfd, sec_t, &contents, TRUE);
       flag_t = bfd_get_32 (ibfd, contents);
 
       /* The value could only be 4 or 16.  */
@@ -5953,11 +5839,13 @@ nds32_check_vec_size (bfd *ibfd)
        nds32_vec_size = (flag_t & 0x3);
       else if (nds32_vec_size != (flag_t & 0x3))
        {
-         (*_bfd_error_handler) (_("%B: ISR vector size mismatch"
-                                  " with previous modules, previous %u-byte, current %u-byte"),
-                                ibfd,
-                                nds32_vec_size == 1 ? 4 : nds32_vec_size == 2 ? 16 : 0xffffffff,
-                                (flag_t & 0x3) == 1 ? 4 : (flag_t & 0x3) == 2 ? 16 : 0xffffffff);
+         _bfd_error_handler
+           /* xgettext:c-format */
+           (_("%B: ISR vector size mismatch"
+              " with previous modules, previous %u-byte, current %u-byte"),
+            ibfd,
+            nds32_vec_size == 1 ? 4 : nds32_vec_size == 2 ? 16 : 0xffffffff,
+            (flag_t & 0x3) == 1 ? 4 : (flag_t & 0x3) == 2 ? 16 : 0xffffffff);
          return FALSE;
        }
       else
@@ -5972,8 +5860,9 @@ nds32_check_vec_size (bfd *ibfd)
    object file when linking.  */
 
 static bfd_boolean
-nds32_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+nds32_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
 {
+  bfd *obfd = info->output_bfd;
   flagword out_flags;
   flagword in_flags;
   flagword out_16regs;
@@ -5995,7 +5884,7 @@ nds32_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
 
   if (bfd_little_endian (ibfd) != bfd_little_endian (obfd))
     {
-      (*_bfd_error_handler)
+      _bfd_error_handler
        (_("%B: warning: Endian mismatch with previous modules."), ibfd);
 
       bfd_set_error (bfd_error_bad_value);
@@ -6005,7 +5894,7 @@ nds32_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
   in_version = elf_elfheader (ibfd)->e_flags & EF_NDS32_ELF_VERSION;
   if (in_version == E_NDS32_ELF_VER_1_2)
     {
-      (*_bfd_error_handler)
+      _bfd_error_handler
        (_("%B: warning: Older version of object file encountered, "
           "Please recompile with current tool chain."), ibfd);
     }
@@ -6083,7 +5972,7 @@ nds32_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
   /* Check flag compatibility.  */
   if ((in_flags & EF_NDS_ABI) != (out_flags & EF_NDS_ABI))
     {
-      (*_bfd_error_handler)
+      _bfd_error_handler
        (_("%B: error: ABI mismatch with previous modules."), ibfd);
 
       bfd_set_error (bfd_error_bad_value);
@@ -6094,7 +5983,7 @@ nds32_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
     {
       if (((in_flags & EF_NDS_ARCH) != E_N1_ARCH))
        {
-         (*_bfd_error_handler)
+         _bfd_error_handler
            (_("%B: error: Instruction set mismatch with previous modules."), ibfd);
 
          bfd_set_error (bfd_error_bad_value);
@@ -6119,9 +6008,11 @@ nds32_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
   else
     {
       if (in_version != out_version)
-       (*_bfd_error_handler) (_("%B: warning: Incompatible elf-versions %s and  %s."),
-                                ibfd, nds32_elfver_strtab[out_version],
-                                nds32_elfver_strtab[in_version]);
+       _bfd_error_handler
+         /* xgettext:c-format */
+         (_("%B: warning: Incompatible elf-versions %s and  %s."),
+          ibfd, nds32_elfver_strtab[out_version],
+          nds32_elfver_strtab[in_version]);
 
       elf_elfheader (obfd)->e_flags = in_flags | out_flags
        | (in_16regs & out_16regs) | (in_no_mac & out_no_mac)
@@ -6190,136 +6081,6 @@ nds32_elf_gc_mark_hook (asection *sec, struct bfd_link_info *info,
   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
 }
 
-static bfd_boolean
-nds32_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info, asection *sec,
-                        const Elf_Internal_Rela *relocs)
-{
-  /* Update the got entry reference counts for the section being removed.  */
-  Elf_Internal_Shdr *symtab_hdr;
-  struct elf_link_hash_entry **sym_hashes;
-  bfd_signed_vma *local_got_refcounts;
-  const Elf_Internal_Rela *rel, *relend;
-
-  elf_section_data (sec)->local_dynrel = NULL;
-
-  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
-  sym_hashes = elf_sym_hashes (abfd);
-  local_got_refcounts = elf_local_got_refcounts (abfd);
-
-  relend = relocs + sec->reloc_count;
-  for (rel = relocs; rel < relend; rel++)
-    {
-      unsigned long r_symndx;
-      struct elf_link_hash_entry *h = NULL;
-
-      r_symndx = ELF32_R_SYM (rel->r_info);
-      if (r_symndx >= symtab_hdr->sh_info)
-       {
-         /* External symbol.  */
-         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-         while (h->root.type == bfd_link_hash_indirect
-                || h->root.type == bfd_link_hash_warning)
-           h = (struct elf_link_hash_entry *) h->root.u.i.link;
-       }
-
-      switch (ELF32_R_TYPE (rel->r_info))
-       {
-       case R_NDS32_GOT_HI20:
-       case R_NDS32_GOT_LO12:
-       case R_NDS32_GOT_LO15:
-       case R_NDS32_GOT_LO19:
-       case R_NDS32_GOT17S2_RELA:
-       case R_NDS32_GOT15S2_RELA:
-       case R_NDS32_GOTOFF:
-       case R_NDS32_GOTOFF_HI20:
-       case R_NDS32_GOTOFF_LO12:
-       case R_NDS32_GOTOFF_LO15:
-       case R_NDS32_GOTOFF_LO19:
-       case R_NDS32_GOT20:
-       case R_NDS32_GOTPC_HI20:
-       case R_NDS32_GOTPC_LO12:
-       case R_NDS32_GOTPC20:
-         if (h != NULL)
-           {
-             if (h->got.refcount > 0)
-               h->got.refcount--;
-           }
-         else
-           {
-             if (local_got_refcounts && local_got_refcounts[r_symndx] > 0)
-               local_got_refcounts[r_symndx]--;
-           }
-         break;
-
-       case R_NDS32_16_RELA:
-       case R_NDS32_20_RELA:
-       case R_NDS32_5_RELA:
-       case R_NDS32_32_RELA:
-       case R_NDS32_HI20_RELA:
-       case R_NDS32_LO12S3_RELA:
-       case R_NDS32_LO12S2_RELA:
-       case R_NDS32_LO12S2_DP_RELA:
-       case R_NDS32_LO12S2_SP_RELA:
-       case R_NDS32_LO12S1_RELA:
-       case R_NDS32_LO12S0_RELA:
-       case R_NDS32_LO12S0_ORI_RELA:
-       case R_NDS32_SDA16S3_RELA:
-       case R_NDS32_SDA17S2_RELA:
-       case R_NDS32_SDA18S1_RELA:
-       case R_NDS32_SDA19S0_RELA:
-       case R_NDS32_SDA15S3_RELA:
-       case R_NDS32_SDA15S2_RELA:
-       case R_NDS32_SDA12S2_DP_RELA:
-       case R_NDS32_SDA12S2_SP_RELA:
-       case R_NDS32_SDA15S1_RELA:
-       case R_NDS32_SDA15S0_RELA:
-       case R_NDS32_SDA_FP7U2_RELA:
-       case R_NDS32_15_PCREL_RELA:
-       case R_NDS32_17_PCREL_RELA:
-       case R_NDS32_25_PCREL_RELA:
-         if (h != NULL)
-           {
-             struct elf_nds32_link_hash_entry *eh;
-             struct elf_nds32_dyn_relocs **pp;
-             struct elf_nds32_dyn_relocs *p;
-
-             if (!info->shared && h->plt.refcount > 0)
-               h->plt.refcount -= 1;
-
-             eh = (struct elf_nds32_link_hash_entry *) h;
-
-             for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
-               if (p->sec == sec)
-                 {
-                   if (ELF32_R_TYPE (rel->r_info) == R_NDS32_15_PCREL_RELA
-                       || ELF32_R_TYPE (rel->r_info) == R_NDS32_17_PCREL_RELA
-                       || ELF32_R_TYPE (rel->r_info) == R_NDS32_25_PCREL_RELA)
-                     p->pc_count -= 1;
-                   p->count -= 1;
-                   if (p->count == 0)
-                     *pp = p->next;
-                   break;
-                 }
-           }
-         break;
-
-       case R_NDS32_9_PLTREL:
-       case R_NDS32_25_PLTREL:
-         if (h != NULL)
-           {
-             if (h->plt.refcount > 0)
-               h->plt.refcount--;
-           }
-         break;
-
-       default:
-         break;
-       }
-    }
-
-  return TRUE;
-}
-
 /* Look through the relocs for a section during the first phase.
    Since we don't do .gots or .plts, we just need to consider the
    virtual table relocs for gc.  */
@@ -6336,7 +6097,16 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
   bfd *dynobj;
   asection *sreloc = NULL;
 
-  if (info->relocatable)
+  if (bfd_link_relocatable (info))
+    return TRUE;
+
+  /* Don't do anything special with non-loaded, non-alloced sections.
+     In particular, any relocs in such sections should not affect GOT
+     and PLT reference counting (ie. we don't allow them to create GOT
+     or PLT entries), there's no possibility or desire to optimize TLS
+     relocs, and there's not much point in propagating relocs to shared
+     libs that the dynamic linker won't relocate.  */
+  if ((sec->flags & SEC_ALLOC) == 0)
     return TRUE;
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
@@ -6372,7 +6142,7 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
       /* Some relocs require a global offset table.  We create
         got section here, since these relocation need got section
         and it is not created yet.  */
-      if (htab->sgot == NULL)
+      if (htab->root.sgot == NULL)
        {
          switch (r_type)
            {
@@ -6395,7 +6165,7 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
            case R_NDS32_TLS_IE_LO12S2:
              if (dynobj == NULL)
                htab->root.dynobj = dynobj = abfd;
-             if (!create_got_section (dynobj, info))
+             if (!_bfd_elf_create_got_section (dynobj, info))
                return FALSE;
              break;
 
@@ -6521,7 +6291,7 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
        case R_NDS32_17_PCREL_RELA:
        case R_NDS32_25_PCREL_RELA:
 
-         if (h != NULL && !info->shared)
+         if (h != NULL && !bfd_link_pic (info))
            {
              h->non_got_ref = 1;
              h->plt.refcount += 1;
@@ -6543,7 +6313,7 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
             If on the other hand, we are creating an executable, we may need
             to keep relocations for symbols satisfied by a dynamic library
             if we manage to avoid copy relocs for the symbol.  */
-         if ((info->shared
+         if ((bfd_link_pic (info)
               && (sec->flags & SEC_ALLOC) != 0
               && ((r_type != R_NDS32_25_PCREL_RELA
                    && r_type != R_NDS32_15_PCREL_RELA
@@ -6554,14 +6324,14 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
                       && (!info->symbolic
                           || h->root.type == bfd_link_hash_defweak
                           || !h->def_regular))))
-             || (!info->shared
+             || (!bfd_link_pic (info)
                  && (sec->flags & SEC_ALLOC) != 0
                  && h != NULL
                  && (h->root.type == bfd_link_hash_defweak
                      || !h->def_regular)))
            {
-             struct elf_nds32_dyn_relocs *p;
-             struct elf_nds32_dyn_relocs **head;
+             struct elf_dyn_relocs *p;
+             struct elf_dyn_relocs **head;
 
              if (dynobj == NULL)
                htab->root.dynobj = dynobj = abfd;
@@ -6610,6 +6380,7 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
              else
                {
                  asection *s;
+                 void *vpp;
 
                  Elf_Internal_Sym *isym;
                  isym = bfd_sym_from_r_symndx (&htab->sym_cache, abfd, r_symndx);
@@ -6621,15 +6392,15 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
                  if (s == NULL)
                    return FALSE;
 
-                 head = ((struct elf_nds32_dyn_relocs **)
-                       &elf_section_data (s)->local_dynrel);
+                 vpp = &elf_section_data (s)->local_dynrel;
+                 head = (struct elf_dyn_relocs **) vpp;
                }
 
              p = *head;
              if (p == NULL || p->sec != sec)
                {
                  bfd_size_type amt = sizeof (*p);
-                 p = (struct elf_nds32_dyn_relocs *) bfd_alloc (dynobj, amt);
+                 p = (struct elf_dyn_relocs *) bfd_alloc (dynobj, amt);
                  if (p == NULL)
                    return FALSE;
                  p->next = *head;
@@ -6800,7 +6571,7 @@ calculate_plt_memory_address (bfd *abfd, struct bfd_link_info *link_info,
       h = elf_sym_hashes (abfd)[indx];
       BFD_ASSERT (h != NULL);
       htab = nds32_elf_hash_table (link_info);
-      splt = htab->splt;
+      splt = htab->root.splt;
 
       while (h->root.type == bfd_link_hash_indirect
             || h->root.type == bfd_link_hash_warning)
@@ -6849,7 +6620,7 @@ nds32_convert_32_to_16_alu1 (bfd *abfd, uint32_t insn, uint16_t *pinsn16,
                             int *pinsn_type)
 {
   uint16_t insn16 = 0;
-  int insn_type;
+  int insn_type = 0;
   unsigned long mach = bfd_get_mach (abfd);
 
   if (N32_SH5 (insn) != 0)
@@ -7377,7 +7148,7 @@ nds32_convert_32_to_16 (bfd *abfd, uint32_t insn, uint16_t *pinsn16,
       if (!IS_WITHIN_S (N32_IMM14S (insn), 8))
        goto done;
 
-      if ((insn & __BIT (14)) == 0)
+      if ((insn & N32_BIT (14)) == 0)
        {
          /* N32_BR1_BEQ */
          if (N32_IS_RT3 (insn) && N32_RA5 (insn) == REG_R5
@@ -7445,7 +7216,7 @@ nds32_convert_32_to_16 (bfd *abfd, uint32_t insn, uint16_t *pinsn16,
       break;
 
     case N32_OP6_JI:
-      if ((insn & __BIT (24)) == 0)
+      if ((insn & N32_BIT (24)) == 0)
        {
          /* N32_JI_J */
          if (IS_WITHIN_S (N32_IMM24S (insn), 8))
@@ -7681,7 +7452,7 @@ nds32_convert_16_to_32 (bfd *abfd, uint16_t insn16, uint32_t *pinsn)
       insn = N32_TYPE2 (SLTI, REG_TA, N16_RT4 (insn16), N16_IMM5U (insn16));
       goto done;
     case 0x34:                 /* beqzs8, bnezs8 */
-      if (insn16 & __BIT (8))
+      if (insn16 & N32_BIT (8))
        insn = N32_BR2 (BNEZ, REG_TA, N16_IMM8S (insn16));
       else
        insn = N32_BR2 (BEQZ, REG_TA, N16_IMM8S (insn16));
@@ -7781,7 +7552,7 @@ nds32_convert_16_to_32 (bfd *abfd, uint16_t insn16, uint32_t *pinsn)
   switch (__GF (insn16, 11, 4))
     {
     case 0x7:                  /* lwi37.fp/swi37.fp */
-      if (insn16 & __BIT (7))  /* swi37.fp */
+      if (insn16 & N32_BIT (7))        /* swi37.fp */
        insn = N32_TYPE2 (SWI, N16_RT38 (insn16), REG_FP, N16_IMM7U (insn16));
       else                     /* lwi37.fp */
        insn = N32_TYPE2 (LWI, N16_RT38 (insn16), REG_FP, N16_IMM7U (insn16));
@@ -7884,7 +7655,7 @@ turn_insn_to_sda_access (uint32_t insn, bfd_signed_vma type, uint32_t *pinsn)
          break;
        case N32_OP6_LBSI:
          /* lbsi.gp */
-         oinsn = N32_TYPE1 (LBGP, N32_RT5 (insn), __BIT (19));
+         oinsn = N32_TYPE1 (LBGP, N32_RT5 (insn), N32_BIT (19));
          break;
        case N32_OP6_SBI:
          /* sbi.gp */
@@ -7892,7 +7663,7 @@ turn_insn_to_sda_access (uint32_t insn, bfd_signed_vma type, uint32_t *pinsn)
          break;
        case N32_OP6_ORI:
          /* addi.gp */
-         oinsn = N32_TYPE1 (SBGP, N32_RT5 (insn), __BIT (19));
+         oinsn = N32_TYPE1 (SBGP, N32_RT5 (insn), N32_BIT (19));
          break;
        }
       break;
@@ -7906,11 +7677,11 @@ turn_insn_to_sda_access (uint32_t insn, bfd_signed_vma type, uint32_t *pinsn)
          break;
        case N32_OP6_LHSI:
          /* lhsi.gp */
-         oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), __BIT (18));
+         oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), N32_BIT (18));
          break;
        case N32_OP6_SHI:
          /* shi.gp */
-         oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), __BIT (19));
+         oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), N32_BIT (19));
          break;
        }
       break;
@@ -8076,15 +7847,17 @@ calculate_got_memory_address (bfd *abfd, struct bfd_link_info *link_info,
   if (symndx >= 0)
     {
       BFD_ASSERT (h != NULL);
-      return htab->sgot->output_section->vma + htab->sgot->output_offset
-            + h->got.offset;
+      return (htab->root.sgot->output_section->vma
+             + htab->root.sgot->output_offset
+             + h->got.offset);
     }
   else
     {
       local_got_offsets = elf_local_got_offsets (abfd);
       BFD_ASSERT (local_got_offsets != NULL);
-      return htab->sgot->output_section->vma + htab->sgot->output_offset
-            + local_got_offsets[ELF32_R_SYM (irel->r_info)];
+      return (htab->root.sgot->output_section->vma
+             + htab->root.sgot->output_offset
+             + local_got_offsets[ELF32_R_SYM (irel->r_info)]);
     }
 
   /* The _GLOBAL_OFFSET_TABLE_ may be undefweak(or should be?).  */
@@ -8137,7 +7910,7 @@ is_convert_32_to_16 (bfd *abfd, asection *sec,
 
   offset = reloc->r_offset;
 
-  if (!nds32_get_section_contents (abfd, sec, &contents))
+  if (!nds32_get_section_contents (abfd, sec, &contents, TRUE))
     return FALSE;
   insn = bfd_getb32 (contents + offset);
 
@@ -8312,7 +8085,7 @@ static Elf_Internal_Rela *
 find_relocs_at_address_addr (Elf_Internal_Rela *reloc,
                             Elf_Internal_Rela *relocs,
                             Elf_Internal_Rela *irelend,
-                            unsigned char reloc_type,
+                            enum elf_nds32_reloc_type reloc_type,
                             bfd_vma offset_p)
 {
   Elf_Internal_Rela *rel_t = NULL;
@@ -8650,7 +8423,7 @@ nds32_elf_relax_delete_blanks (bfd *abfd, asection *sec,
       if (!(sect->flags & SEC_RELOC))
        continue;
 
-      nds32_get_section_contents (abfd, sect, &contents);
+      nds32_get_section_contents (abfd, sect, &contents, TRUE);
 
       for (irel = internal_relocs; irel < irelend; irel++)
        {
@@ -8663,7 +8436,7 @@ nds32_elf_relax_delete_blanks (bfd *abfd, asection *sec,
              unsigned long val = 0;
              unsigned long mask;
              long before, between;
-             long offset;
+             long offset = 0;
 
              switch (ELF32_R_TYPE (irel->r_info))
                {
@@ -8728,8 +8501,8 @@ nds32_elf_relax_delete_blanks (bfd *abfd, asection *sec,
              unsigned long before, between;
              bfd_byte *endp, *p;
 
-             val = read_unsigned_leb128 (abfd, contents + irel->r_offset,
-                                         &len);
+             val = _bfd_read_unsigned_leb128 (abfd, contents + irel->r_offset,
+                                              &len);
 
              before = get_nds32_elf_blank_total (&blank_t, irel->r_addend, 0);
              between = get_nds32_elf_blank_total (&blank_t,
@@ -8758,9 +8531,8 @@ done_adjust_diff:
              if (blank_t2 && blank_t2->next
                  && (blank_t2->offset > raddr
                      || blank_t2->next->offset <= raddr))
-               (*_bfd_error_handler)
-                 (_("%B: %s\n"), abfd,
-                  "Error: search_nds32_elf_blank reports wrong node");
+               _bfd_error_handler
+                 (_("%B: Error: search_nds32_elf_blank reports wrong node\n"), abfd);
 
              /* Mark reloc in deleted portion as NONE.
                 For some relocs like R_NDS32_LABEL that doesn't modify the
@@ -8898,7 +8670,8 @@ done_adjust_diff:
 /* Get the contents of a section.  */
 
 static int
-nds32_get_section_contents (bfd *abfd, asection *sec, bfd_byte **contents_p)
+nds32_get_section_contents (bfd *abfd, asection *sec,
+                           bfd_byte **contents_p, bfd_boolean cache)
 {
   /* Get the section contents.  */
   if (elf_section_data (sec)->this_hdr.contents != NULL)
@@ -8907,7 +8680,8 @@ nds32_get_section_contents (bfd *abfd, asection *sec, bfd_byte **contents_p)
     {
       if (!bfd_malloc_and_get_section (abfd, sec, contents_p))
        return FALSE;
-      elf_section_data (sec)->this_hdr.contents = *contents_p;
+      if (cache)
+       elf_section_data (sec)->this_hdr.contents = *contents_p;
     }
 
   return TRUE;
@@ -9015,6 +8789,10 @@ relax_range_measurement (bfd *abfd)
 #define IS_OPTIMIZE(addend)     ((addend) & 0x40000000)
 #define IS_16BIT_ON(addend)     ((addend) & 0x20000000)
 
+static const char * unrecognized_reloc_msg =
+  /* xgettext:c-format */
+  N_("%B: warning: %s points to unrecognized reloc at %#Lx");
+
 /* Relax LONGCALL1 relocation for nds32_elf_relax_section.  */
 
 static bfd_boolean
@@ -9025,19 +8803,19 @@ nds32_elf_relax_longcall1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
 {
   /* There are 3 variations for LONGCALL1
      case 4-4-2; 16-bit on, optimize off or optimize for space
-     sethi ta, hi20(symbol)     ; LONGCALL1/HI20
+     sethi ta, hi20(symbol)    ; LONGCALL1/HI20
      ori   ta, ta, lo12(symbol) ; LO12S0
-     jral5 ta                   ;
+     jral5 ta                  ;
 
      case 4-4-4; 16-bit off, optimize don't care
-     sethi ta, hi20(symbol)     ; LONGCALL1/HI20
+     sethi ta, hi20(symbol)    ; LONGCALL1/HI20
      ori   ta, ta, lo12(symbol) ; LO12S0
-     jral  ta                   ;
+     jral  ta                  ;
 
      case 4-4-4; 16-bit on, optimize for speed
-     sethi ta, hi20(symbol)     ; LONGCALL1/HI20
+     sethi ta, hi20(symbol)    ; LONGCALL1/HI20
      ori   ta, ta, lo12(symbol) ; LO12S0
-     jral  ta                   ;
+     jral  ta                  ;
      Check code for -mlong-calls output.  */
 
   /* Get the reloc for the address from which the register is
@@ -9065,9 +8843,8 @@ nds32_elf_relax_longcall1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
 
   if (hi_irelfn == irelend || lo_irelfn == irelend)
     {
-      (*_bfd_error_handler)
-       ("%B: warning: R_NDS32_LONGCALL1 points to unrecognized"
-        "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+      _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGCALL1",
+                         irel->r_offset);
       return FALSE;
     }
 
@@ -9147,9 +8924,8 @@ nds32_elf_relax_longcall2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
 
   if (i1_irelfn == irelend)
     {
-      (*_bfd_error_handler)
-       ("%B: warning: R_NDS32_LONGCALL2 points to unrecognized"
-        "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+      _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGCALL2",
+                         irel->r_offset);
       return FALSE;
     }
 
@@ -9208,24 +8984,24 @@ nds32_elf_relax_longcall3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
 {
   /* There are 3 variations for LONGCALL3
      case 4-4-4-2; 16-bit on, optimize off or optimize for space
-     bltz  rt,   $1                ; LONGCALL3
-     sethi ta,   hi20(symbol)      ; HI20
+     bltz  rt,  $1                ; LONGCALL3
+     sethi ta,  hi20(symbol)      ; HI20
      ori   ta, ta,  lo12(symbol)   ; LO12S0
-     jral5 ta                      ;
+     jral5 ta                     ;
      $1
 
      case 4-4-4-4; 16-bit off, optimize don't care
-     bltz  rt,   $1                ; LONGCALL3
-     sethi ta,   hi20(symbol)      ; HI20
+     bltz  rt,  $1                ; LONGCALL3
+     sethi ta,  hi20(symbol)      ; HI20
      ori   ta, ta,  lo12(symbol)   ; LO12S0
-     jral  ta                      ;
+     jral  ta                     ;
      $1
 
      case 4-4-4-4; 16-bit on, optimize for speed
-     bltz  rt,   $1                ; LONGCALL3
-     sethi ta,   hi20(symbol)      ; HI20
+     bltz  rt,  $1                ; LONGCALL3
+     sethi ta,  hi20(symbol)      ; HI20
      ori   ta, ta,  lo12(symbol)   ; LO12S0
-     jral  ta                      ;
+     jral  ta                     ;
      $1 */
 
   /* Get the reloc for the address from which the register is
@@ -9254,9 +9030,8 @@ nds32_elf_relax_longcall3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
 
   if (hi_irelfn == irelend || lo_irelfn == irelend)
     {
-      (*_bfd_error_handler)
-       ("%B: warning: R_NDS32_LONGCALL3 points to unrecognized"
-        "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+      _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGCALL3",
+                         irel->r_offset);
       return FALSE;
     }
 
@@ -9347,19 +9122,19 @@ nds32_elf_relax_longjump1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
 {
   /* There are 3 variations for LONGJUMP1
      case 4-4-2; 16-bit bit on, optimize off or optimize for space
-     sethi ta, hi20(symbol)      ; LONGJUMP1/HI20
-     ori   ta, ta, lo12(symbol)  ; LO12S0
-     jr5   ta                    ;
+     sethi ta, hi20(symbol)     ; LONGJUMP1/HI20
+     ori   ta, ta, lo12(symbol)         ; LO12S0
+     jr5   ta                   ;
 
      case 4-4-4; 16-bit off, optimize don't care
-     sethi ta, hi20(symbol)      ; LONGJUMP1/HI20
-     ori   ta, ta, lo12(symbol)  ; LO12S0
-     jr    ta                    ;
+     sethi ta, hi20(symbol)     ; LONGJUMP1/HI20
+     ori   ta, ta, lo12(symbol)         ; LO12S0
+     jr           ta                    ;
 
      case 4-4-4; 16-bit on, optimize for speed
-     sethi ta, hi20(symbol)      ; LONGJUMP1/HI20
-     ori   ta, ta, lo12(symbol)  ; LO12S0
-     jr    ta                    ;     */
+     sethi ta, hi20(symbol)     ; LONGJUMP1/HI20
+     ori   ta, ta, lo12(symbol)         ; LO12S0
+     jr           ta                    ;      */
 
   /* Get the reloc for the address from which the register is
      being loaded.  This reloc will tell us which function is
@@ -9389,9 +9164,8 @@ nds32_elf_relax_longjump1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
                                 R_NDS32_LO12S0_ORI_RELA, laddr + 4);
   if (hi_irelfn == irelend || lo_irelfn == irelend)
     {
-      (*_bfd_error_handler)
-       ("%B: warning: R_NDS32_LONGJUMP1 points to unrecognized"
-        "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+      _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP1",
+                         irel->r_offset);
       return FALSE;
     }
 
@@ -9596,9 +9370,8 @@ nds32_elf_relax_longjump2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
 
   if (i2_irelfn == irelend || cond_irelfn == irelend)
     {
-      (*_bfd_error_handler)
-       ("%B: warning: R_NDS32_LONGJUMP2 points to unrecognized"
-        "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+      _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP2",
+                         irel->r_offset);
       return FALSE;
     }
 
@@ -9703,42 +9476,42 @@ nds32_elf_relax_longjump3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
   /* There are 5 variations for LONGJUMP3
      case 1: 2-4-4-2; 1st insn convertible, 16-bit on,
      optimize off or optimize for space
-     bnes38   rt, ra, $1            ; LONGJUMP3
-     sethi    ta, hi20(symbol)      ; HI20
+     bnes38   rt, ra, $1           ; LONGJUMP3
+     sethi    ta, hi20(symbol)     ; HI20
      ori      ta, ta, lo12(symbol)  ; LO12S0
-     jr5      ta                    ;
-     $1:                            ;
+     jr5      ta                   ;
+     $1:                           ;
 
      case 2: 2-4-4-2; 1st insn convertible, 16-bit on, optimize for speed
-     bnes38   rt, ra, $1           ; LONGJUMP3
-     sethi    ta, hi20(symbol)     ; HI20
+     bnes38   rt, ra, $1          ; LONGJUMP3
+     sethi    ta, hi20(symbol)    ; HI20
      ori      ta, ta, lo12(symbol) ; LO12S0
-     jr5      ta                   ;
-     $1:                           ; LABEL
+     jr5      ta                  ;
+     $1:                          ; LABEL
 
      case 3: 4-4-4-2; 1st insn not convertible, 16-bit on,
      optimize off or optimize for space
-     bne   rt, ra, $1           ; LONGJUMP3
-     sethi ta, hi20(symbol)     ; HI20
+     bne   rt, ra, $1          ; LONGJUMP3
+     sethi ta, hi20(symbol)    ; HI20
      ori   ta, ta, lo12(symbol) ; LO12S0
-     jr5   ta                   ;
-     $1:                        ;
+     jr5   ta                  ;
+     $1:                       ;
 
      case 4: 4-4-4-4; 1st insn don't care, 16-bit off, optimize don't care
      16-bit off if no INSN16
-     bne   rt, ra, $1           ; LONGJUMP3
-     sethi ta, hi20(symbol)     ; HI20
+     bne   rt, ra, $1          ; LONGJUMP3
+     sethi ta, hi20(symbol)    ; HI20
      ori   ta, ta, lo12(symbol) ; LO12S0
-     jr    ta                   ;
-     $1:                        ;
+     jr           ta                   ;
+     $1:                       ;
 
      case 5: 4-4-4-4; 1st insn not convertible, 16-bit on, optimize for speed
      16-bit off if no INSN16
-     bne   rt, ra, $1           ; LONGJUMP3
-     sethi ta, hi20(symbol)     ; HI20
+     bne   rt, ra, $1          ; LONGJUMP3
+     sethi ta, hi20(symbol)    ; HI20
      ori   ta, ta, lo12(symbol) ; LO12S0
-     jr    ta                   ;
-     $1:                        ; LABEL */
+     jr           ta                   ;
+     $1:                       ; LABEL */
 
   /* Get the reloc for the address from which the register is
      being loaded.  This reloc will tell us which function is
@@ -9789,9 +9562,8 @@ nds32_elf_relax_longjump3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
 
   if (hi_irelfn == irelend || lo_irelfn == irelend || cond_irelfn == irelend)
     {
-      (*_bfd_error_handler)
-       ("%B: warning: R_NDS32_LONGJUMP3 points to unrecognized"
-        "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+      _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP3",
+                         irel->r_offset);
       return FALSE;
     }
 
@@ -9918,7 +9690,6 @@ nds32_elf_relax_longjump3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
     else
       {
        irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), reloc);
-       irel->r_addend = irel->r_addend;
        hi_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info),
                                          cond_reloc);
       }
@@ -9970,9 +9741,8 @@ nds32_elf_relax_longcall4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
 
   if (hi_irel == irelend)
     {
-      (*_bfd_error_handler)
-       ("%B: warning: R_NDS32_LONGCALL4 points to unrecognized"
-        "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+      _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGCALL4",
+                         irel->r_offset);
       return FALSE;
     }
 
@@ -10001,9 +9771,8 @@ nds32_elf_relax_longcall4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
 
   if (ptr_irel == irelend || em_irel == irelend)
     {
-      (*_bfd_error_handler)
-       ("%B: warning: R_NDS32_LONGCALL4 points to unrecognized"
-        "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+      _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGCALL4",
+                         irel->r_offset);
       return FALSE;
     }
   /* Check these is enough space to insert jal in R_NDS32_EMPTY.  */
@@ -10073,9 +9842,8 @@ nds32_elf_relax_longcall5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
                                 R_NDS32_25_PCREL_RELA, irel->r_addend);
   if (cond_irel == irelend)
     {
-      (*_bfd_error_handler)
-       ("%B: warning: R_NDS32_LONGCALL5 points to unrecognized"
-        "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+      _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGCALL5",
+                         irel->r_offset);
       return FALSE;
     }
 
@@ -10152,9 +9920,8 @@ nds32_elf_relax_longcall6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
 
   if (em_irel == irelend)
     {
-      (*_bfd_error_handler)
-       ("%B: warning: R_NDS32_LONGCALL6 points to unrecognized"
-        "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+      _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGCALL6",
+                         irel->r_offset);
       return FALSE;
     }
 
@@ -10191,9 +9958,8 @@ nds32_elf_relax_longcall6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
                                     R_NDS32_PTR_RESOLVED, irel->r_addend);
       if (cond_irel == irelend)
        {
-         (*_bfd_error_handler)
-           ("%B: warning: R_NDS32_LONGCALL6 points to unrecognized"
-            "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+         _bfd_error_handler (unrecognized_reloc_msg, abfd,
+                             "R_NDS32_LONGCALL6", irel->r_offset);
          return FALSE;
        }
       cond_irel->r_addend = 1;
@@ -10241,9 +10007,8 @@ nds32_elf_relax_longcall6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
                                     R_NDS32_PTR_RESOLVED, irel->r_addend);
       if (cond_irel == irelend)
        {
-         (*_bfd_error_handler)
-           ("%B: warning: R_NDS32_LONGCALL6 points to unrecognized"
-            "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+         _bfd_error_handler (unrecognized_reloc_msg, abfd,
+                             "R_NDS32_LONGCALL6", irel->r_offset);
          return FALSE;
        }
       cond_irel->r_addend = 1;
@@ -10292,9 +10057,8 @@ nds32_elf_relax_longjump4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
 
   if (hi_irel == irelend)
     {
-      (*_bfd_error_handler)
-       ("%B: warning: R_NDS32_LONGJUMP4 points to unrecognized"
-        "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+      _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP4",
+                         irel->r_offset);
       return FALSE;
     }
 
@@ -10315,9 +10079,8 @@ nds32_elf_relax_longjump4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
 
   if (ptr_irel == irelend || em_irel == irelend)
     {
-      (*_bfd_error_handler)
-       ("%B: warning: R_NDS32_LONGJUMP4 points to unrecognized"
-        "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+      _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP4",
+                         irel->r_offset);
       return FALSE;
     }
 
@@ -10390,9 +10153,8 @@ nds32_elf_relax_longjump5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
                                 R_NDS32_25_PCREL_RELA, irel->r_addend);
   if (cond_irel == irelend)
     {
-      (*_bfd_error_handler)
-       ("%B: warning: R_NDS32_LONGJUMP5 points to unrecognized"
-        "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+      _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP5",
+                         irel->r_offset);
       return FALSE;
     }
 
@@ -10520,9 +10282,8 @@ nds32_elf_relax_longjump6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
 
   if (em_irel == irelend)
     {
-      (*_bfd_error_handler)
-       ("%B: warning: R_NDS32_LONGJUMP6 points to unrecognized"
-        "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+      _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP6",
+                         irel->r_offset);
       return FALSE;
     }
 
@@ -10691,9 +10452,8 @@ nds32_elf_relax_longjump7 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
                                 R_NDS32_15_PCREL_RELA, irel->r_addend);
   if (cond_irel == irelend)
     {
-      (*_bfd_error_handler)
-       ("%B: warning: R_NDS32_LONGJUMP7 points to unrecognized"
-        "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+      _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LONGJUMP7",
+                         irel->r_offset);
       return FALSE;
     }
 
@@ -10766,7 +10526,8 @@ nds32_elf_relax_loadstore (struct bfd_link_info *link_info, bfd *abfd,
                           bfd_byte *contents, Elf_Internal_Sym *isymbuf,
                           Elf_Internal_Shdr *symtab_hdr, int load_store_relax)
 {
-  int eliminate_sethi = 0, range_type, i;
+  int eliminate_sethi = 0, range_type;
+  unsigned int i;
   bfd_vma local_sda, laddr;
   int seq_len; /* Original length of instruction sequence.  */
   uint32_t insn;
@@ -10786,7 +10547,7 @@ nds32_elf_relax_loadstore (struct bfd_link_info *link_info, bfd *abfd,
   *insn_len = seq_len;
 
   /* Get the high part relocation.  */
-  for (i = 0; (unsigned) i < sizeof (checked_types); i++)
+  for (i = 0; i < ARRAY_SIZE (checked_types); i++)
     {
       hi_irelfn = find_relocs_at_address_addr (irel, internal_relocs, irelend,
                                               checked_types[i], laddr);
@@ -10796,9 +10557,8 @@ nds32_elf_relax_loadstore (struct bfd_link_info *link_info, bfd *abfd,
 
   if (hi_irelfn == irelend)
     {
-      (*_bfd_error_handler)
-       ("%B: warning: R_NDS32_LOADSTORE points to unrecognized"
-        "reloc at 0x%lx.", abfd, (long) irel->r_offset);
+      _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_LOADSTORE",
+                         irel->r_offset);
        return FALSE;
     }
 
@@ -10845,7 +10605,7 @@ nds32_elf_relax_loadstore (struct bfd_link_info *link_info, bfd *abfd,
        break;
 
       if (range_type == NDS32_LOADSTORE_FLOAT_S
-         || range_type == NDS32_LOADSTORE_FLOAT_S)
+         || range_type == NDS32_LOADSTORE_FLOAT_D)
        {
          range_l = sdata_range[0][0];
          range_h = sdata_range[0][1];
@@ -11132,9 +10892,9 @@ nds32_elf_relax_letlsadd (struct bfd_link_info *link_info, bfd *abfd,
                          Elf_Internal_Shdr *symtab_hdr, bfd_boolean *again)
 {
   /* Local TLS non-pic
-     sethi    ta, hi20(symbol@tpoff)      ; TLS_LE_HI20
+     sethi    ta, hi20(symbol@tpoff)     ; TLS_LE_HI20
      ori      ta, ta, lo12(symbol@tpoff)  ; TLS_LE_LO12
-     add      ra, ta, tp                  ; TLS_LE_ADD */
+     add      ra, ta, tp                 ; TLS_LE_ADD */
 
   uint32_t insn;
   bfd_vma laddr;
@@ -11209,6 +10969,7 @@ nds32_elf_relax_letlsls (struct bfd_link_info *link_info, bfd *abfd,
          success = 1;
          break;
        }
+      /* Fall through.  */
     case (N32_OP6_MEM << 8) | N32_MEM_LH:
     case (N32_OP6_MEM << 8) | N32_MEM_SH:
     case (N32_OP6_MEM << 8) | N32_MEM_LHS:
@@ -11223,6 +10984,7 @@ nds32_elf_relax_letlsls (struct bfd_link_info *link_info, bfd *abfd,
          success = 1;
          break;
        }
+      /* Fall through.  */
     case (N32_OP6_MEM << 8) | N32_MEM_LW:
     case (N32_OP6_MEM << 8) | N32_MEM_SW:
       /* The range is +/-64k.  */
@@ -11236,6 +10998,7 @@ nds32_elf_relax_letlsls (struct bfd_link_info *link_info, bfd *abfd,
          success = 1;
          break;
        }
+      /* Fall through.  */
     default:
       break;
     }
@@ -11268,9 +11031,8 @@ nds32_elf_relax_ptr (bfd *abfd, asection *sec, Elf_Internal_Rela *irel,
 
   if (re_irel == irelend)
     {
-      (*_bfd_error_handler)
-       ("%B: warning: R_NDS32_PTR points to unrecognized reloc at 0x%lx.",
-        abfd, (long) irel->r_offset);
+      _bfd_error_handler (unrecognized_reloc_msg, abfd, "R_NDS32_PTR",
+                         irel->r_offset);
       return FALSE;
     }
 
@@ -11361,7 +11123,7 @@ nds32_elf_relax_pltgot_suff (struct bfd_link_info *link_info, bfd *abfd,
       irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
                                   R_NDS32_PLT_GOTREL_LO19);
       /* addi.gp */
-      insn = N32_TYPE1 (SBGP, N32_RT5 (insn), __BIT (19));
+      insn = N32_TYPE1 (SBGP, N32_RT5 (insn), N32_BIT (19));
     }
   else if (N32_OP6 (insn) == N32_OP6_JREG
           && N32_SUB5 (insn) == N32_JREG_JRAL)
@@ -11494,12 +11256,12 @@ nds32_elf_relax_gotoff_suff (struct bfd_link_info *link_info, bfd *abfd,
        ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA18S1_RELA);
       break;
     case (N32_OP6_MEM << 8) | N32_MEM_LHS:
-      insn = N32_TYPE1 (HWGP, N32_RT5 (insn), __BIT (18));
+      insn = N32_TYPE1 (HWGP, N32_RT5 (insn), N32_BIT (18));
       irel->r_info =
        ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA18S1_RELA);
       break;
     case (N32_OP6_MEM << 8) | N32_MEM_SH:
-      insn = N32_TYPE1 (HWGP, N32_RT5 (insn), __BIT (19));
+      insn = N32_TYPE1 (HWGP, N32_RT5 (insn), N32_BIT (19));
       irel->r_info =
        ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA18S1_RELA);
       break;
@@ -11510,7 +11272,7 @@ nds32_elf_relax_gotoff_suff (struct bfd_link_info *link_info, bfd *abfd,
        ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA19S0_RELA);
       break;
     case (N32_OP6_MEM << 8) | N32_MEM_LBS:
-      insn = N32_TYPE1 (LBGP, N32_RT5 (insn), __BIT (19));
+      insn = N32_TYPE1 (LBGP, N32_RT5 (insn), N32_BIT (19));
       irel->r_info =
        ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA19S0_RELA);
       break;
@@ -11520,7 +11282,7 @@ nds32_elf_relax_gotoff_suff (struct bfd_link_info *link_info, bfd *abfd,
        ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA19S0_RELA);
       break;
     case (N32_OP6_ALU1 << 8) | N32_ALU1_ADD:
-      insn = N32_TYPE1 (SBGP, N32_RT5 (insn), __BIT (19));
+      insn = N32_TYPE1 (SBGP, N32_RT5 (insn), N32_BIT (19));
       irel->r_info =
        ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA19S0_RELA);
       break;
@@ -11551,12 +11313,12 @@ nds32_relax_adjust_label (bfd *abfd, asection *sec,
      of instruction a time.
 
      It recognizes three types of relocations.
-     1. R_NDS32_LABEL - a aligment.
+     1. R_NDS32_LABEL - a alignment.
      2. R_NDS32_INSN16 - relax a 32-bit instruction to 16-bit.
      3. is_16bit_NOP () - remove a 16-bit instruction.  */
 
-  /* TODO: It seems currently implementation only support 4-byte aligment.
-     We should handle any-aligment.  */
+  /* TODO: It seems currently implementation only support 4-byte alignment.
+     We should handle any-alignment.  */
 
   Elf_Internal_Rela *insn_rel = NULL, *label_rel = NULL, *irel;
   Elf_Internal_Rela *tmp_rel, *tmp2_rel = NULL;
@@ -11812,7 +11574,8 @@ nds32_elf_pick_relax (bfd_boolean init, asection *sec, bfd_boolean *again,
                      struct elf_nds32_link_hash_table *table,
                      struct bfd_link_info *link_info)
 {
-  static asection *final_sec;
+  static asection *final_sec, *first_sec = NULL;
+  static bfd_boolean normal_again = FALSE;
   static bfd_boolean set = FALSE;
   static bfd_boolean first = TRUE;
   int round_table[] = {
@@ -11824,6 +11587,13 @@ nds32_elf_pick_relax (bfd_boolean init, asection *sec, bfd_boolean *again,
   static int pass = 0;
   static int relax_round;
 
+  /* The new round.  */
+  if (init && first_sec == sec)
+    {
+      set = TRUE;
+      normal_again = FALSE;
+    }
+
   if (first)
     {
       /* Run an empty run to get the final section.  */
@@ -11832,27 +11602,29 @@ nds32_elf_pick_relax (bfd_boolean init, asection *sec, bfd_boolean *again,
       /* It has to enter relax again because we can
         not make sure what the final turn is.  */
       *again = TRUE;
+
       first = FALSE;
+      first_sec = sec;
     }
 
-  if (!set && *again)
+  if (!set)
     {
-      /* It is reentered when again is FALSE.  */
+      /* Not reenter yet.  */
       final_sec = sec;
       return relax_round;
     }
 
-  /* The second round begins.  */
-  set = TRUE;
-
   relax_round = round_table[pass];
 
+  if (!init && relax_round == NDS32_RELAX_NORMAL_ROUND && *again)
+    normal_again = TRUE;
+
   if (!init && final_sec == sec)
     {
       switch (relax_round)
        {
        case NDS32_RELAX_NORMAL_ROUND:
-         if (!*again)
+         if (!normal_again)
            {
              /* Normal relaxation done.  */
              if (table->target_optimize & NDS32_RELAX_JUMP_IFC_ON)
@@ -11879,7 +11651,7 @@ nds32_elf_pick_relax (bfd_boolean init, asection *sec, bfd_boolean *again,
          break;
        case NDS32_RELAX_JUMP_IFC_ROUND:
          if (!nds32_elf_ifc_finish (link_info))
-           (*_bfd_error_handler) (_("error: Jump IFC Fail."));
+           _bfd_error_handler (_("error: Jump IFC Fail."));
          if (table->target_optimize & NDS32_RELAX_EX9_ON)
            {
              pass++;
@@ -11896,7 +11668,7 @@ nds32_elf_pick_relax (bfd_boolean init, asection *sec, bfd_boolean *again,
            {
              /* Do jump IFC optimization again.  */
              if (!nds32_elf_ifc_finish (link_info))
-               (*_bfd_error_handler) (_("error: Jump IFC Fail."));
+               _bfd_error_handler (_("error: Jump IFC Fail."));
            }
          break;
        default:
@@ -11939,9 +11711,9 @@ nds32_elf_relax_section (bfd *abfd, asection *sec,
    * non-code section or
    * empty content or
    * no reloc entry.  */
-  if (link_info->relocatable
+  if (bfd_link_relocatable (link_info)
       || (sec->flags & SEC_RELOC) == 0
-      || (sec->flags & SEC_EXCLUDE) == 1
+      || (sec->flags & SEC_EXCLUDE) != 0
       || (sec->flags & SEC_CODE) == 0
       || sec->size == 0)
     return TRUE;
@@ -12007,7 +11779,7 @@ nds32_elf_relax_section (bfd *abfd, asection *sec,
       /* Set the _ITB_BASE_.  */
       if (!nds32_elf_ex9_itb_base (link_info))
        {
-         (*_bfd_error_handler) (_("%B: error: Cannot set _ITB_BASE_"), abfd);
+         _bfd_error_handler (_("%B: error: Cannot set _ITB_BASE_"), abfd);
          bfd_set_error (bfd_error_bad_value);
        }
     }
@@ -12029,7 +11801,10 @@ nds32_elf_relax_section (bfd *abfd, asection *sec,
   if (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_ENTRY)
     {
       if (irel->r_addend & R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG)
-       return TRUE;
+       {
+         nds32_elf_pick_relax (FALSE, sec, again, table, link_info);
+         return TRUE;
+       }
 
       if (irel->r_addend & R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG)
        optimize = 1;
@@ -12041,7 +11816,7 @@ nds32_elf_relax_section (bfd *abfd, asection *sec,
   load_store_relax = table->load_store_relax;
 
   /* Get symbol table and section content.  */
-  if (!nds32_get_section_contents (abfd, sec, &contents)
+  if (!nds32_get_section_contents (abfd, sec, &contents, TRUE)
       || !nds32_get_local_syms (abfd, sec, &isymbuf))
     goto error_return;
 
@@ -12275,7 +12050,7 @@ nds32_elf_relax_section (bfd *abfd, asection *sec,
                                 irelend, isymbuf))
        goto error_return;
 
-      if (*again == FALSE)
+      if (!*again)
        {
          if (!nds32_fag_remove_unused_fpbase (abfd, sec, internal_relocs,
                                               irelend))
@@ -12285,7 +12060,7 @@ nds32_elf_relax_section (bfd *abfd, asection *sec,
 
   nds32_elf_pick_relax (FALSE, sec, again, table, link_info);
 
-  if (*again == FALSE)
+  if (!*again)
     {
       if (!nds32_relax_adjust_label (abfd, sec, internal_relocs, contents,
                                     &relax_blank_list, optimize, opt_size))
@@ -12302,15 +12077,15 @@ nds32_elf_relax_section (bfd *abfd, asection *sec,
       relax_blank_list = NULL;
     }
 
-  if (*again == FALSE)
+  if (!*again)
     {
       /* Closing the section, so we don't relax it anymore.  */
       bfd_vma sec_size_align;
       Elf_Internal_Rela *tmp_rel;
 
       /* Pad to alignment boundary.  Only handle current section alignment.  */
-      sec_size_align = (sec->size + (~((-1) << sec->alignment_power)))
-                      & ((-1) << sec->alignment_power);
+      sec_size_align = (sec->size + (~((-1U) << sec->alignment_power)))
+                      & ((-1U) << sec->alignment_power);
       if ((sec_size_align - sec->size) & 0x2)
        {
          insn16 = NDS32_NOP16;
@@ -12727,7 +12502,7 @@ nds32_relax_fp_as_gp (struct bfd_link_info *link_info,
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
 
-  if (!nds32_get_section_contents (abfd, sec, &contents)
+  if (!nds32_get_section_contents (abfd, sec, &contents, TRUE)
       || !nds32_get_local_syms (abfd, sec, &isymbuf))
     return FALSE;
 
@@ -12749,7 +12524,8 @@ nds32_relax_fp_as_gp (struct bfd_link_info *link_info,
        {
          /* Begin of the region.  */
          if (begin_rel)
-           (*_bfd_error_handler) (_("%B: Nested OMIT_FP in %A."), abfd, sec);
+           /* xgettext:c-format */
+           _bfd_error_handler (_("%B: Nested OMIT_FP in %A."), abfd, sec);
 
          begin_rel = irel;
          nds32_fag_init (&fag_head);
@@ -12767,7 +12543,8 @@ nds32_relax_fp_as_gp (struct bfd_link_info *link_info,
 
          if (begin_rel == NULL)
            {
-             (*_bfd_error_handler) (_("%B: Unmatched OMIT_FP in %A."), abfd, sec);
+             /* xgettext:c-format */
+             _bfd_error_handler (_("%B: Unmatched OMIT_FP in %A."), abfd, sec);
              continue;
            }
 
@@ -12864,7 +12641,7 @@ nds32_fag_remove_unused_fpbase (bfd *abfd, asection *sec,
   */
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
-  nds32_get_section_contents (abfd, sec, &contents);
+  nds32_get_section_contents (abfd, sec, &contents, TRUE);
 
   for (irel = internal_relocs; irel < irelend; irel++)
     {
@@ -12966,7 +12743,7 @@ nds32_elf_get_relocated_section_contents (bfd *abfd,
     return NULL;
 
   /* Read in the section.  */
-  if (!nds32_get_section_contents (input_bfd, input_section, &data))
+  if (!nds32_get_section_contents (input_bfd, input_section, &data, FALSE))
     return NULL;
 
   if (reloc_size == 0)
@@ -13026,25 +12803,22 @@ nds32_elf_get_relocated_section_contents (bfd *abfd,
              switch (r)
                {
                case bfd_reloc_undefined:
-                 if (!((*link_info->callbacks->undefined_symbol)
-                       (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
-                        input_bfd, input_section, (*parent)->address, TRUE)))
-                   goto error_return;
+                 (*link_info->callbacks->undefined_symbol)
+                   (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
+                    input_bfd, input_section, (*parent)->address, TRUE);
                  break;
                case bfd_reloc_dangerous:
                  BFD_ASSERT (error_message != NULL);
-                 if (!((*link_info->callbacks->reloc_dangerous)
-                       (link_info, error_message, input_bfd, input_section,
-                        (*parent)->address)))
-                   goto error_return;
+                 (*link_info->callbacks->reloc_dangerous)
+                   (link_info, error_message,
+                    input_bfd, input_section, (*parent)->address);
                  break;
                case bfd_reloc_overflow:
-                 if (!((*link_info->callbacks->reloc_overflow)
-                       (link_info, NULL,
-                        bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
-                        (*parent)->howto->name, (*parent)->addend,
-                        input_bfd, input_section, (*parent)->address)))
-                   goto error_return;
+                 (*link_info->callbacks->reloc_overflow)
+                   (link_info, NULL,
+                    bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
+                    (*parent)->howto->name, (*parent)->addend,
+                    input_bfd, input_section, (*parent)->address);
                  break;
                case bfd_reloc_outofrange:
                  /* PR ld/13730:
@@ -13052,6 +12826,7 @@ nds32_elf_get_relocated_section_contents (bfd *abfd,
                     complete binaries.  Do not abort, but issue an error
                     message instead.  */
                  link_info->callbacks->einfo
+                   /* xgettext:c-format */
                    (_("%X%P: %B(%A): relocation \"%R\" goes out of range\n"),
                     abfd, input_section, * parent);
                  goto error_return;
@@ -13217,7 +12992,7 @@ nds32_elf_ifc_calc (struct bfd_link_info *info,
          && !(irel->r_addend & R_NDS32_RELAX_ENTRY_IFC_FLAG)))
     return TRUE;
 
-  if (!nds32_get_section_contents (abfd, sec, &contents))
+  if (!nds32_get_section_contents (abfd, sec, &contents, TRUE))
     return FALSE;
 
   table = nds32_elf_hash_table (info);
@@ -13459,7 +13234,7 @@ nds32_elf_ifc_replace (struct bfd_link_info *info)
              irelend = internal_relocs + ptr->sec->reloc_count;
 
              if (!nds32_get_section_contents (ptr->sec->owner, ptr->sec,
-                                              &contents))
+                                              &contents, TRUE))
                return FALSE;
 
              while (irel_ptr)
@@ -13516,8 +13291,9 @@ nds32_elf_ifc_replace (struct bfd_link_info *info)
                        (irel_ptr->sec->owner, irel_ptr->sec, NULL, NULL,
                         TRUE /* keep_memory */);
                      irelend = internal_relocs + irel_ptr->sec->reloc_count;
-                     if (!nds32_get_section_contents
-                            (irel_ptr->sec->owner, irel_ptr->sec, &contents))
+                     if (!nds32_get_section_contents (irel_ptr->sec->owner,
+                                                      irel_ptr->sec, &contents,
+                                                      TRUE))
                        return FALSE;
 
                      irel = irel_ptr->irel;
@@ -13603,7 +13379,8 @@ nds32_elf_ifc_reloc (void)
          if (ptr->h == NULL)
            {
              /* Local symbol.  */
-             if (!nds32_get_section_contents (ptr->sec->owner, ptr->sec, &contents))
+             if (!nds32_get_section_contents (ptr->sec->owner, ptr->sec,
+                                              &contents, TRUE))
                return FALSE;
 
              while (irel_ptr)
@@ -13701,7 +13478,7 @@ nds32_elf_ifc_reloc (void)
                            return FALSE;
                        }
                      if (!nds32_get_section_contents
-                         (irel_ptr->sec->owner, irel_ptr->sec, &contents))
+                         (irel_ptr->sec->owner, irel_ptr->sec, &contents, TRUE))
                        return FALSE;
                      insn16 = INSN_IFCALL9 | (relocation >> 1);
                      bfd_putb16 (insn16, contents + irel_ptr->irel->r_offset);
@@ -14156,7 +13933,7 @@ nds32_elf_ex9_build_itable (struct bfd_link_info *link_info)
       table_sec = bfd_get_section_by_name (it_abfd, ".ex9.itable");
       if (table_sec != NULL)
        {
-         if (!nds32_get_section_contents (it_abfd, table_sec, &contents))
+         if (!nds32_get_section_contents (it_abfd, table_sec, &contents, TRUE))
            return;
 
          for (ptr = ex9_insn_head; ptr !=NULL ; ptr = ptr->next)
@@ -14502,7 +14279,7 @@ nds32_elf_ex9_replace_instruction (struct bfd_link_info *info, bfd *abfd, asecti
 
 
   /* Load section instructions, relocations, and symbol table.  */
-  if (!nds32_get_section_contents (abfd, sec, &contents)
+  if (!nds32_get_section_contents (abfd, sec, &contents, TRUE)
       || !nds32_get_local_syms (abfd, sec, &isym))
     return FALSE;
   internal_relocs =
@@ -14826,7 +14603,7 @@ nds32_elf_ex9_init (void)
                              sizeof (struct elf_nds32_code_hash_entry),
                              1023))
     {
-      (*_bfd_error_handler) (_("Linker: cannot init ex9 hash table error \n"));
+      _bfd_error_handler (_("Linker: cannot init ex9 hash table error \n"));
       return FALSE;
     }
   return TRUE;
@@ -14976,7 +14753,6 @@ nds32_elf_ex9_import_table (struct bfd_link_info *info)
 {
   int num = 0;
   bfd_byte *contents;
-  unsigned long insn;
   FILE *ex9_import_file;
   int update_ex9_table;
   struct elf_nds32_link_hash_table *table;
@@ -14990,6 +14766,7 @@ nds32_elf_ex9_import_table (struct bfd_link_info *info)
   /* Read instructions from the input file and build the list.  */
   while (!feof (ex9_import_file))
     {
+      unsigned long insn;
       char *code;
       struct elf_nds32_insn_times_entry *ptr;
       size_t nread;
@@ -15000,7 +14777,7 @@ nds32_elf_ex9_import_table (struct bfd_link_info *info)
        break;
       insn = bfd_getb32 (contents);
       code = bfd_malloc (sizeof (char) * 9);
-      snprintf (code, 9, "%08lx", insn);
+      snprintf (code, 9, "%08lx", (insn & 0xffffffff));
       ptr = bfd_malloc (sizeof (struct elf_nds32_insn_times_entry));
       ptr->string = code;
       ptr->order = num;
@@ -15094,7 +14871,7 @@ nds32_elf_ex9_reloc_jmp (struct bfd_link_info *link_info)
          if (table_sec->size == 0)
            return;
 
-         if (!nds32_get_section_contents (it_abfd, table_sec, &contents))
+         if (!nds32_get_section_contents (it_abfd, table_sec, &contents, TRUE))
            return;
        }
     }
@@ -15233,8 +15010,8 @@ nds32_elf_ex9_reloc_jmp (struct bfd_link_info *link_info)
                                {
                                  if (!nds32_get_section_contents
                                         (fix_ptr->sec->owner, fix_ptr->sec,
-                                         &source_contents))
-                                   (*_bfd_error_handler)
+                                         &source_contents, TRUE))
+                                   _bfd_error_handler
                                      (_("Linker: error cannot fixed ex9 relocation \n"));
                                  if (temp_ptr->order < 32)
                                    insn_ex9 = INSN_EX9_IT_2;
@@ -15248,7 +15025,7 @@ nds32_elf_ex9_reloc_jmp (struct bfd_link_info *link_info)
                          else
                            {
                              if (!temp_ptr->next || temp_ptr->m_list != temp_ptr->next->m_list)
-                               (*_bfd_error_handler)
+                               _bfd_error_handler
                                  (_("Linker: error cannot fixed ex9 relocation \n"));
                              else
                                temp_ptr = temp_ptr->next;
@@ -15315,7 +15092,7 @@ nds32_elf_ex9_build_hash_table (bfd *abfd, asection *sec,
 
   sym_hashes = elf_sym_hashes (abfd);
   /* Load section instructions, relocations, and symbol table.  */
-  if (!nds32_get_section_contents (abfd, sec, &contents))
+  if (!nds32_get_section_contents (abfd, sec, &contents, TRUE))
     return FALSE;
 
   internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
@@ -15458,10 +15235,11 @@ nds32_elf_ex9_build_hash_table (bfd *abfd, asection *sec,
                      if (relocation & align)
                        {
                          /* Incorrect alignment.  */
-                         (*_bfd_error_handler)
-                           (_("%s: warning: unaligned small data access. "
-                              "For entry: {%d, %d, %d}, addr = 0x%x, align = 0x%x."),
-                            bfd_get_filename (abfd), irel->r_offset,
+                         _bfd_error_handler
+                           /* xgettext:c-format */
+                           (_("%B: warning: unaligned small data access "
+                              "for entry: {%Ld, %Ld, %Ld}, addr = %#Lx, align = %#x"),
+                            abfd, irel->r_offset,
                             irel->r_info, irel->r_addend, relocation, align);
                          off += 4;
                          continue;
@@ -15491,8 +15269,8 @@ nds32_elf_ex9_build_hash_table (bfd *abfd, asection *sec,
            bfd_hash_lookup (&ex9_code_table, code, TRUE, TRUE);
          if (entry == NULL)
            {
-             (*_bfd_error_handler)
-               (_("%P%F: failed creating ex9.it %s hash table: %E\n"), code);
+             _bfd_error_handler
+               (_("failed creating ex9.it %s hash table entry"), code);
              return FALSE;
            }
          if (h)
@@ -15653,7 +15431,7 @@ nds32_elf_ex9_itb_base (struct bfd_link_info *link_info)
 #define ELF_ARCH                               bfd_arch_nds32
 #define ELF_MACHINE_CODE                       EM_NDS32
 #define ELF_MAXPAGESIZE                                0x1000
-#define ELF_TARGET_ID                           NDS32_ELF_DATA
+#define ELF_TARGET_ID                          NDS32_ELF_DATA
 
 #define TARGET_BIG_SYM                         nds32_elf32_be_vec
 #define TARGET_BIG_NAME                                "elf32-nds32be"
@@ -15669,7 +15447,7 @@ nds32_elf_ex9_itb_base (struct bfd_link_info *link_info)
 #define bfd_elf32_bfd_relax_section            nds32_elf_relax_section
 #define bfd_elf32_bfd_set_private_flags                nds32_elf_set_private_flags
 
-#define bfd_elf32_mkobject                     nds32_elf_mkobject
+#define bfd_elf32_mkobject                     nds32_elf_mkobject
 #define elf_backend_action_discarded           nds32_elf_action_discarded
 #define elf_backend_add_symbol_hook            nds32_elf_add_symbol_hook
 #define elf_backend_check_relocs               nds32_elf_check_relocs
@@ -15680,7 +15458,6 @@ nds32_elf_ex9_itb_base (struct bfd_link_info *link_info)
 #define elf_backend_size_dynamic_sections      nds32_elf_size_dynamic_sections
 #define elf_backend_relocate_section           nds32_elf_relocate_section
 #define elf_backend_gc_mark_hook               nds32_elf_gc_mark_hook
-#define elf_backend_gc_sweep_hook              nds32_elf_gc_sweep_hook
 #define elf_backend_grok_prstatus              nds32_elf_grok_prstatus
 #define elf_backend_grok_psinfo                        nds32_elf_grok_psinfo
 #define elf_backend_reloc_type_class           nds32_elf_reloc_type_class
@@ -15691,7 +15468,7 @@ nds32_elf_ex9_itb_base (struct bfd_link_info *link_info)
 #define elf_backend_final_write_processing     nds32_elf_final_write_processing
 #define elf_backend_special_sections           nds32_elf_special_sections
 #define bfd_elf32_bfd_get_relocated_section_contents \
-                                nds32_elf_get_relocated_section_contents
+                               nds32_elf_get_relocated_section_contents
 
 #define elf_backend_can_gc_sections            1
 #define elf_backend_can_refcount               1
@@ -15702,6 +15479,7 @@ nds32_elf_ex9_itb_base (struct bfd_link_info *link_info)
 #define elf_backend_may_use_rel_p              1
 #define elf_backend_default_use_rela_p         1
 #define elf_backend_may_use_rela_p             1
+#define elf_backend_dtrel_excludes_plt         1
 
 #include "elf32-target.h"
 
This page took 0.066437 seconds and 4 git commands to generate.