Automatic date update in version.in
[deliverable/binutils-gdb.git] / bfd / elf32-nios2.c
index 1c54320e53de6e509346b72d6ee568b7b38420e3..3e4706f35f09aac50bfac1d7ee6be4d01809de4e 100644 (file)
@@ -1,5 +1,5 @@
 /* 32-bit ELF support for Nios II.
-   Copyright (C) 2012-2015 Free Software Foundation, Inc.
+   Copyright (C) 2012-2017 Free Software Foundation, Inc.
    Contributed by Nigel Gray (ngray@altera.com).
    Contributed by Mentor Graphics, Inc.
 
@@ -1820,8 +1820,6 @@ struct elf32_nios2_link_hash_table
     Elf_Internal_Sym **all_local_syms;
 
     /* Short-cuts to get to dynamic linker sections.  */
-    asection *sdynbss;
-    asection *srelbss;
     asection *sbss;
 
     /* GOT pointer symbol _gp_got.  */
@@ -1905,7 +1903,7 @@ nios2_elf32_install_imm16 (asection *sec, bfd_vma offset, bfd_vma value)
 {
   bfd_vma word = bfd_get_32 (sec->owner, sec->contents + offset);
 
-  BFD_ASSERT(value <= 0xffff);
+  BFD_ASSERT (value <= 0xffff || ((bfd_signed_vma) value) >= -0xffff);
 
   bfd_put_32 (sec->owner, word | ((value & 0xffff) << 6),
              sec->contents + offset);
@@ -2225,9 +2223,10 @@ nios2_add_stub (const char *stub_name,
                                TRUE, FALSE);
   if (hsh == NULL)
     {
-      (*_bfd_error_handler) (_("%B: cannot create stub entry %s"),
-                            section->owner,
-                            stub_name);
+      /* xgettext:c-format */
+      _bfd_error_handler (_("%B: cannot create stub entry %s"),
+                         section->owner,
+                         stub_name);
       return NULL;
     }
 
@@ -2916,8 +2915,9 @@ nios2_elf32_build_stubs (struct bfd_link_info *info)
    object file when linking.  */
 
 static bfd_boolean
-nios2_elf32_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+nios2_elf32_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
 {
+  bfd *obfd = info->output_bfd;
   flagword old_flags;
   flagword new_flags;
 
@@ -2925,7 +2925,7 @@ nios2_elf32_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
     return TRUE;
 
   /* Check if we have the same endianness.  */
-  if (! _bfd_generic_verify_endian_match (ibfd, obfd))
+  if (! _bfd_generic_verify_endian_match (ibfd, info))
     return FALSE;
 
   new_flags = elf_elfheader (ibfd)->e_flags;
@@ -2945,7 +2945,7 @@ nios2_elf32_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
        case EF_NIOS2_ARCH_R2:
          if (bfd_big_endian (ibfd))
            {
-             (*_bfd_error_handler)
+             _bfd_error_handler
                (_("error: %B: Big-endian R2 is not supported."), ibfd);
              bfd_set_error (bfd_error_bad_value);
              return FALSE;
@@ -2960,7 +2960,8 @@ nios2_elf32_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
     {
       /* So far, the only incompatible flags denote incompatible
         architectures.  */
-      (*_bfd_error_handler)
+      _bfd_error_handler
+       /* xgettext:c-format */
        (_("error: %B: Conflicting CPU architectures %d/%d"),
         ibfd, new_flags, old_flags);
       bfd_set_error (bfd_error_bad_value);
@@ -2968,7 +2969,7 @@ nios2_elf32_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
     }
 
   /* Merge Tag_compatibility attributes and any common GNU ones.  */
-  _bfd_elf_merge_object_attributes (ibfd, obfd);
+  _bfd_elf_merge_object_attributes (ibfd, info);
 
   return TRUE;
 }
@@ -3086,7 +3087,15 @@ lookup:
        case bfd_link_hash_defined:
        case bfd_link_hash_defweak:
          gp_found = TRUE;
-         *pgp = lh->u.def.value;
+         {
+           asection *sym_sec = lh->u.def.section;
+           bfd_vma sym_value = lh->u.def.value;
+
+           if (sym_sec->output_section)
+             sym_value = (sym_value + sym_sec->output_offset
+                          + sym_sec->output_section->vma);
+           *pgp = sym_value;
+         }
          break;
        case bfd_link_hash_indirect:
        case bfd_link_hash_warning:
@@ -3719,7 +3728,6 @@ nios2_elf32_relocate_section (bfd *output_bfd,
       struct elf32_nios2_link_hash_entry *eh;
       bfd_vma relocation;
       bfd_vma gp;
-      bfd_vma reloc_address;
       bfd_reloc_status_type r = bfd_reloc_ok;
       const char *name = NULL;
       int r_type;
@@ -3762,12 +3770,6 @@ nios2_elf32_relocate_section (bfd *output_bfd,
       if (bfd_link_relocatable (info))
        continue;
 
-      if (sec && sec->output_section)
-       reloc_address = (sec->output_section->vma + sec->output_offset
-                        + rel->r_offset);
-      else
-       reloc_address = 0;
-
       if (howto)
        {
          switch (howto->type)
@@ -3816,6 +3818,15 @@ nios2_elf32_relocate_section (bfd *output_bfd,
              /* Turns an absolute address into a gp-relative address.  */
              if (!nios2_elf_assign_gp (output_bfd, &gp, info))
                {
+                 bfd_vma reloc_address;
+
+                 if (sec && sec->output_section)
+                   reloc_address = (sec->output_section->vma
+                                    + sec->output_offset
+                                    + rel->r_offset);
+                 else
+                   reloc_address = 0;
+
                  format = _("global pointer relative relocation at address "
                             "0x%08x when _gp not defined\n");
                  sprintf (msgbuf, format, reloc_address);
@@ -3825,7 +3836,7 @@ nios2_elf32_relocate_section (bfd *output_bfd,
              else
                {
                  bfd_vma symbol_address = rel->r_addend + relocation;
-                 relocation = relocation + rel->r_addend - gp;
+                 relocation = symbol_address - gp;
                  rel->r_addend = 0;
                  if (((signed) relocation < -32768
                       || (signed) relocation > 32767)
@@ -3833,6 +3844,9 @@ nios2_elf32_relocate_section (bfd *output_bfd,
                          || h->root.type == bfd_link_hash_defined
                          || h->root.type == bfd_link_hash_defweak))
                    {
+                     if (h)
+                       name = h->root.root.string;
+                     /* xgettext:c-format */
                      format = _("Unable to reach %s (at 0x%08x) from the "
                                 "global pointer (at 0x%08x) because the "
                                 "offset (%d) is out of the allowed range, "
@@ -3848,7 +3862,6 @@ nios2_elf32_relocate_section (bfd *output_bfd,
                                                  rel->r_offset, relocation,
                                                  rel->r_addend);
                }
-
              break;
            case R_NIOS2_UJMP:
              r = nios2_elf32_do_ujmp_relocate (input_bfd, howto,
@@ -4354,7 +4367,8 @@ nios2_elf32_relocate_section (bfd *output_bfd,
            case R_NIOS2_TLS_LE16:
              if (bfd_link_dll (info))
                {
-                 (*_bfd_error_handler)
+                 _bfd_error_handler
+                   /* xgettext:c-format */
                    (_("%B(%A+0x%lx): R_NIOS2_TLS_LE16 relocation not "
                       "permitted in shared object"),
                     input_bfd, input_section,
@@ -4469,16 +4483,16 @@ nios2_elf32_relocate_section (bfd *output_bfd,
          switch (r)
            {
            case bfd_reloc_overflow:
-             r = info->callbacks->reloc_overflow (info, NULL, name,
-                                                  howto->name, (bfd_vma) 0,
-                                                  input_bfd, input_section,
-                                                  rel->r_offset);
+             (*info->callbacks->reloc_overflow) (info, NULL, name,
+                                                 howto->name, (bfd_vma) 0,
+                                                 input_bfd, input_section,
+                                                 rel->r_offset);
              break;
 
            case bfd_reloc_undefined:
-             r = info->callbacks->undefined_symbol (info, name, input_bfd,
-                                                    input_section,
-                                                    rel->r_offset, TRUE);
+             (*info->callbacks->undefined_symbol) (info, name, input_bfd,
+                                                   input_section,
+                                                   rel->r_offset, TRUE);
              break;
 
            case bfd_reloc_outofrange:
@@ -4504,8 +4518,8 @@ nios2_elf32_relocate_section (bfd *output_bfd,
 
          if (msg)
            {
-             r = info->callbacks->warning
-               (info, msg, name, input_bfd, input_section, rel->r_offset);
+             (*info->callbacks->warning) (info, msg, name, input_bfd,
+                                          input_section, rel->r_offset);
              return FALSE;
            }
        }
@@ -4586,26 +4600,14 @@ nios2_elf32_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
   if (!htab->root.sgot && !create_got_section (dynobj, info))
     return FALSE;
 
-  _bfd_elf_create_dynamic_sections (dynobj, info);
+  if (!_bfd_elf_create_dynamic_sections (dynobj, info))
+    return FALSE;
 
   /* In order for the two loads in a shared object .PLTresolve to share the
      same %hiadj, the start of the PLT (as well as the GOT) must be aligned
      to a 16-byte boundary.  This is because the addresses for these loads
      include the -(.plt+4) PIC correction.  */
-  if (!bfd_set_section_alignment (dynobj, htab->root.splt, 4))
-    return FALSE;
-
-  htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
-  if (!htab->sdynbss)
-    return FALSE;
-  if (!bfd_link_pic (info))
-    {
-      htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
-      if (!htab->srelbss)
-       return FALSE;
-    }
-
-  return TRUE;
+  return bfd_set_section_alignment (dynobj, htab->root.splt, 4);
 }
 
 /* Implement elf_backend_copy_indirect_symbol:
@@ -5273,14 +5275,16 @@ nios2_elf32_finish_dynamic_symbol (bfd *output_bfd,
                  && (h->root.type == bfd_link_hash_defined
                      || h->root.type == bfd_link_hash_defweak));
 
-      s = htab->srelbss;
-      BFD_ASSERT (s != NULL);
-
       rela.r_offset = (h->root.u.def.value
                       + h->root.u.def.section->output_section->vma
                       + h->root.u.def.section->output_offset);
       rela.r_info = ELF32_R_INFO (h->dynindx, R_NIOS2_COPY);
       rela.r_addend = 0;
+      if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+       s = htab->root.sreldynrelro;
+      else
+       s = htab->root.srelbss;
+      BFD_ASSERT (s != NULL);
       loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
     }
@@ -5333,44 +5337,27 @@ nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
              break;
 
            case DT_PLTGOT:
-             s = htab->root.sgot;
-             BFD_ASSERT (s != NULL);
-             dyn.d_un.d_ptr = s->output_section->vma;
+             s = htab->root.sgotplt;
+             dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
              break;
 
            case DT_JMPREL:
              s = htab->root.srelplt;
-             BFD_ASSERT (s != NULL);
-             dyn.d_un.d_ptr = s->output_section->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->root.srelplt;
-             BFD_ASSERT (s != NULL);
              dyn.d_un.d_val = s->size;
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
              break;
 
-           case DT_RELASZ:
-             /* The procedure linkage table relocs (DT_JMPREL) should
-                not be included in the overall relocs (DT_RELA).
-                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.  */
-             s = htab->root.srelplt;
-             if (s != NULL)
-               dyn.d_un.d_val -= s->size;
-             bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
-             break;
-
            case DT_NIOS2_GP:
-             s = htab->root.sgot;
-             BFD_ASSERT (s != NULL);
-             dyn.d_un.d_ptr = s->output_section->vma + 0x7ff0;
+             s = htab->root.sgotplt;
+             dyn.d_un.d_ptr
+               = s->output_section->vma + s->output_offset + 0x7ff0;
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
              break;
            }
@@ -5456,7 +5443,7 @@ nios2_elf32_adjust_dynamic_symbol (struct bfd_link_info *info,
 {
   struct elf32_nios2_link_hash_table *htab;
   bfd *dynobj;
-  asection *s;
+  asection *s, *srel;
   unsigned align2;
 
   htab = elf32_nios2_hash_table (info);
@@ -5524,8 +5511,8 @@ nios2_elf32_adjust_dynamic_symbol (struct bfd_link_info *info,
 
   if (h->size == 0)
     {
-      (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"),
-                            h->root.root.string);
+      _bfd_error_handler (_("dynamic variable `%s' is zero size"),
+                         h->root.root.string);
       return TRUE;
     }
 
@@ -5538,19 +5525,22 @@ nios2_elf32_adjust_dynamic_symbol (struct bfd_link_info *info,
      determine the address it must put in the global offset table, so
      both the dynamic object and the regular object will refer to the
      same memory location for the variable.  */
-  s = htab->sdynbss;
-  BFD_ASSERT (s != NULL);
-
   /* We must generate a R_NIOS2_COPY reloc to tell the dynamic linker to
      copy the initial value out of the dynamic object and into the
      runtime process image.  We need to remember the offset into the
      .rela.bss section we are going to use.  */
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = htab->root.sdynrelro;
+      srel = htab->root.sreldynrelro;
+    }
+  else
+    {
+      s = htab->root.sdynbss;
+      srel = htab->root.srelbss;
+    }
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
     {
-      asection *srel;
-
-      srel = htab->srelbss;
-      BFD_ASSERT (srel != NULL);
       srel->size += sizeof (Elf32_External_Rela);
       h->needs_copy = 1;
     }
@@ -5990,7 +5980,7 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
         of the dynobj section names depend upon the input files.  */
       name = bfd_get_section_name (dynobj, s);
 
-      if (strcmp (name, ".plt") == 0)
+      if (s == htab->root.splt)
        {
          /* Remember whether there is a PLT.  */
          plt = s->size != 0;
@@ -6013,9 +6003,14 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
              s->reloc_count = 0;
            }
        }
-      else if (CONST_STRNEQ (name, ".got"))
-       got = s->size != 0;
-      else if (strcmp (name, ".dynbss") != 0)
+      else if (s == htab->root.sgot
+              || s == htab->root.sgotplt)
+       {
+         if (s->size != 0)
+           got = TRUE;
+       }
+      else if (s != htab->root.sdynbss
+              && s != htab->root.sdynrelro)
        /* It's not one of our sections, so don't allocate space.  */
        continue;
 
@@ -6264,7 +6259,9 @@ const struct bfd_elf_special_section elf32_nios2_special_sections[] =
 #define elf_backend_can_refcount       1
 #define elf_backend_plt_readonly       1
 #define elf_backend_want_got_plt       1
+#define elf_backend_want_dynrelro      1
 #define elf_backend_rela_normal                1
+#define elf_backend_dtrel_excludes_plt 1
 
 #define elf_backend_relocate_section     nios2_elf32_relocate_section
 #define elf_backend_section_flags        nios2_elf32_section_flags
This page took 0.02911 seconds and 4 git commands to generate.