Nios2 dynobj handling fixes
[deliverable/binutils-gdb.git] / bfd / elf32-nios2.c
index d07ef67a85e17d55e398f4af5dd3c2526b975217..a2045bf366747e70f9d8df01fe1357d0e7ba9e64 100644 (file)
@@ -3713,10 +3713,10 @@ nios2_elf32_relocate_section (bfd *output_bfd,
   splt = htab->root.splt;
   local_got_offsets = elf_local_got_offsets (input_bfd);
 
-  if (elf32_nios2_hash_table (info)->h_gp_got == NULL)
+  if (htab->h_gp_got == NULL)
     got_base = 0;
   else
-    got_base = elf32_nios2_hash_table (info)->h_gp_got->root.u.def.value;
+    got_base = htab->h_gp_got->root.u.def.value;
 
   for (rel = relocs; rel < relend; rel++)
     {
@@ -3998,7 +3998,7 @@ nios2_elf32_relocate_section (bfd *output_bfd,
 
                  off = h->got.offset;
                  BFD_ASSERT (off != (bfd_vma) -1);
-                 dyn = elf_hash_table (info)->dynamic_sections_created;
+                 dyn = htab->root.dynamic_sections_created;
                  if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
                                                         bfd_link_pic (info),
                                                         h)
@@ -4580,7 +4580,7 @@ create_got_section (bfd *dynobj, struct bfd_link_info *info)
      points to the base of the GOT while _gp_got may include a bias.  */
   h = _bfd_elf_define_linkage_sym (dynobj, info, htab->root.sgotplt,
                                   "_gp_got");
-  elf32_nios2_hash_table (info)->h_gp_got = h;
+  htab->h_gp_got = h;
   if (h == NULL)
     return FALSE;
 
@@ -4694,21 +4694,17 @@ static bfd_boolean
 nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
                          asection *sec, const Elf_Internal_Rela *relocs)
 {
-  bfd *dynobj;
   Elf_Internal_Shdr *symtab_hdr;
   struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
   const Elf_Internal_Rela *rel;
   const Elf_Internal_Rela *rel_end;
   struct elf32_nios2_link_hash_table *htab;
-  asection *sgot;
-  asection *srelgot;
   asection *sreloc = NULL;
   bfd_signed_vma *local_got_refcounts;
 
   if (bfd_link_relocatable (info))
     return TRUE;
 
-  dynobj = elf_hash_table (info)->dynobj;
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
   sym_hashes_end = (sym_hashes
@@ -4718,8 +4714,6 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
   local_got_refcounts = elf_local_got_refcounts (abfd);
 
   htab = elf32_nios2_hash_table (info);
-  sgot = htab->root.sgot;
-  srelgot = htab->root.srelgot;
 
   rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; rel++)
@@ -4778,26 +4772,6 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
                break;
              }
 
-           if (dynobj == NULL)
-             {
-               /* Create the .got section.  */
-               elf_hash_table (info)->dynobj = dynobj = abfd;
-               nios2_elf32_create_dynamic_sections (dynobj, info);
-             }
-
-           if (sgot == NULL)
-             {
-               sgot = htab->root.sgot;
-               BFD_ASSERT (sgot != NULL);
-             }
-
-           if (srelgot == NULL
-               && (h != NULL || bfd_link_pic (info)))
-             {
-               srelgot = htab->root.srelgot;
-               BFD_ASSERT (srelgot != NULL);
-             }
-
            if (h != NULL)
              {
                struct elf32_nios2_link_hash_entry *eh
@@ -4856,11 +4830,7 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
                  elf32_nios2_local_got_tls_type (abfd) [r_symndx] = tls_type;
              }
          }
-         /* Fall through */
-       case R_NIOS2_TLS_LDM16:
-         if (r_type == R_NIOS2_TLS_LDM16)
-           htab->tls_ldm_got.refcount++;
-
+       make_got:
          if (htab->root.sgot == NULL)
            {
              if (htab->root.dynobj == NULL)
@@ -4870,6 +4840,10 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
            }
          break;
 
+       case R_NIOS2_TLS_LDM16:
+         htab->tls_ldm_got.refcount++;
+         goto make_got;
+
          /* This relocation describes the C++ object vtable hierarchy.
             Reconstruct it for later use during GC.  */
        case R_NIOS2_GNU_VTINHERIT:
@@ -4925,8 +4899,11 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
                 section in dynobj and make room for this reloc.  */
              if (sreloc == NULL)
                {
+                 if (htab->root.dynobj == NULL)
+                   htab->root.dynobj = abfd;
+
                  sreloc = _bfd_elf_make_dynamic_reloc_section
-                   (sec, dynobj, 2, abfd, TRUE);
+                   (sec, htab->root.dynobj, 2, abfd, TRUE);
                  if (sreloc == NULL)
                    return FALSE;
                }
@@ -5291,8 +5268,8 @@ nios2_elf32_finish_dynamic_symbol (bfd *output_bfd,
 
   /* Mark _DYNAMIC, _GLOBAL_OFFSET_TABLE_, and _gp_got as absolute.  */
   if (strcmp (h->root.root.string, "_DYNAMIC") == 0
-      || h == elf_hash_table (info)->hgot
-      || h == elf32_nios2_hash_table (info)->h_gp_got)
+      || h == htab->root.hgot
+      || h == htab->h_gp_got)
     sym->st_shndx = SHN_ABS;
 
   return TRUE;
@@ -5303,24 +5280,22 @@ static bfd_boolean
 nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
                                     struct bfd_link_info *info)
 {
-  bfd *dynobj;
   asection *sgotplt;
   asection *sdyn;
   struct elf32_nios2_link_hash_table *htab;
 
   htab = elf32_nios2_hash_table (info);
-  dynobj = elf_hash_table (info)->dynobj;
   sgotplt = htab->root.sgotplt;
-  BFD_ASSERT (sgotplt != NULL);
-  sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+  sdyn = NULL;
 
-  if (elf_hash_table (info)->dynamic_sections_created)
+  if (htab->root.dynamic_sections_created)
     {
       asection *splt;
       Elf32_External_Dyn *dyncon, *dynconend;
 
       splt = htab->root.splt;
-      BFD_ASSERT (splt != NULL && sdyn != NULL);
+      sdyn = bfd_get_linker_section (htab->root.dynobj, ".dynamic");
+      BFD_ASSERT (splt != NULL && sdyn != NULL && sgotplt != NULL);
 
       dyncon = (Elf32_External_Dyn *) sdyn->contents;
       dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
@@ -5329,7 +5304,7 @@ nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
          Elf_Internal_Dyn dyn;
          asection *s;
 
-         bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+         bfd_elf32_swap_dyn_in (htab->root.dynobj, dyncon, &dyn);
 
          switch (dyn.d_tag)
            {
@@ -5413,8 +5388,9 @@ nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
            }
        }
     }
+
   /* Fill in the first three entries in the global offset table.  */
-  if (sgotplt->size > 0)
+  if (sgotplt != NULL && sgotplt->size > 0)
     {
       if (sdyn == NULL)
        bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents);
@@ -5424,9 +5400,10 @@ nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
                    sgotplt->contents);
       bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 4);
       bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 8);
-    }
 
-  elf_section_data (sgotplt->output_section)->this_hdr.sh_entsize = 4;
+      if (sgotplt->output_section != bfd_abs_section_ptr)
+       elf_section_data (sgotplt->output_section)->this_hdr.sh_entsize = 4;
+    }
 
   return TRUE;
 }
@@ -5447,7 +5424,7 @@ nios2_elf32_adjust_dynamic_symbol (struct bfd_link_info *info,
   unsigned align2;
 
   htab = elf32_nios2_hash_table (info);
-  dynobj = elf_hash_table (info)->dynobj;
+  dynobj = htab->root.dynobj;
 
   /* Make sure we know what is going on here.  */
   BFD_ASSERT (dynobj != NULL
@@ -5834,18 +5811,16 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 {
   bfd *dynobj;
   asection *s;
-  bfd_boolean plt;
-  bfd_boolean got;
   bfd_boolean relocs;
   bfd *ibfd;
   struct elf32_nios2_link_hash_table *htab;
 
   htab = elf32_nios2_hash_table (info);
-  dynobj = elf_hash_table (info)->dynobj;
+  dynobj = htab->root.dynobj;
   BFD_ASSERT (dynobj != NULL);
 
   htab->res_n_size = 0;
-  if (elf_hash_table (info)->dynamic_sections_created)
+  if (htab->root.dynamic_sections_created)
     {
       /* Set the contents of the .interp section to the interpreter.  */
       if (bfd_link_executable (info) && !info->nointerp)
@@ -5953,21 +5928,19 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
      sym dynamic relocs.  */
   elf_link_hash_traverse (& htab->root, allocate_dynrelocs, info);
 
-  if (elf_hash_table (info)->dynamic_sections_created)
+  if (htab->root.dynamic_sections_created)
     {
       /* If the .got section is more than 0x8000 bytes, we add
         0x8000 to the value of _gp_got, so that 16-bit relocations
         have a greater chance of working. */
       if (htab->root.sgot->size >= 0x8000
-         && elf32_nios2_hash_table (info)->h_gp_got->root.u.def.value == 0)
-       elf32_nios2_hash_table (info)->h_gp_got->root.u.def.value = 0x8000;
+         && htab->h_gp_got->root.u.def.value == 0)
+       htab->h_gp_got->root.u.def.value = 0x8000;
     }
 
   /* The check_relocs and adjust_dynamic_symbol entry points have
      determined the sizes of the various dynamic sections.  Allocate
      memory for them.  */
-  plt = FALSE;
-  got = FALSE;
   relocs = FALSE;
   for (s = dynobj->sections; s != NULL; s = s->next)
     {
@@ -5980,51 +5953,37 @@ 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 (s == htab->root.splt)
-       {
-         /* Remember whether there is a PLT.  */
-         plt = s->size != 0;
-
-         /* Correct for the number of res_N branches.  */
-         if (plt && !bfd_link_pic (info))
-           {
-             htab->res_n_size = (s->size-28) / 3;
-             s->size += htab->res_n_size;
-           }
-       }
-      else if (CONST_STRNEQ (name, ".rela"))
+      if (CONST_STRNEQ (name, ".rela"))
        {
          if (s->size != 0)
            {
-             relocs = TRUE;
+             if (s != htab->root.srelplt)
+               relocs = TRUE;
 
              /* We use the reloc_count field as a counter if we need
                 to copy relocs into the output file.  */
              s->reloc_count = 0;
            }
        }
-      else if (s == htab->root.sgot
-              || s == htab->root.sgotplt)
+      else if (s == htab->root.splt)
        {
-         if (s->size != 0)
-           got = TRUE;
+         /* Correct for the number of res_N branches.  */
+         if (s->size != 0 && !bfd_link_pic (info))
+           {
+             htab->res_n_size = (s->size - 28) / 3;
+             s->size += htab->res_n_size;
+           }
        }
-      else if (s != htab->root.sdynbss
+      else if (s != htab->sbss
+              && s != htab->root.sgot
+              && s != htab->root.sgotplt
+              && s != htab->root.sdynbss
               && s != htab->root.sdynrelro)
        /* It's not one of our sections, so don't allocate space.  */
        continue;
 
       if (s->size == 0)
        {
-         /* If we don't need this section, strip it from the
-            output file.  This is mostly to handle .rela.bss and
-            .rela.plt.  We must create both sections in
-            create_dynamic_sections, because they must be created
-            before the linker maps input sections to output
-            sections.  The linker does that before
-            adjust_dynamic_symbol is called, and it is that
-            function which decides whether anything needs to go
-            into these sections.  */
          s->flags |= SEC_EXCLUDE;
          continue;
        }
@@ -6033,11 +5992,6 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
        continue;
 
       /* Allocate memory for the section contents.  */
-      /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
-        Unused entries should be reclaimed before the section's contents
-        are written out, but at the moment this does not happen.  Thus in
-        order to prevent writing out garbage, we initialize the section's
-        contents to zero.  */
       s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
       if (s->contents == NULL)
        return FALSE;
@@ -6048,7 +6002,7 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
   if (htab->res_n_size)
     elf_link_hash_traverse (& htab->root, adjust_dynrelocs, info);
 
-  if (elf_hash_table (info)->dynamic_sections_created)
+  if (htab->root.dynamic_sections_created)
     {
       /* Add some entries to the .dynamic section.  We fill in the
         values later, in elf_nios2_finish_dynamic_sections, but we
@@ -6061,10 +6015,11 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
       if (!bfd_link_pic (info) && !add_dynamic_entry (DT_DEBUG, 0))
        return FALSE;
 
-      if (got && !add_dynamic_entry (DT_PLTGOT, 0))
+      if (htab->root.sgotplt->size != 0
+         && !add_dynamic_entry (DT_PLTGOT, 0))
        return FALSE;
 
-      if (plt
+      if (htab->root.splt->size != 0
          && (!add_dynamic_entry (DT_PLTRELSZ, 0)
              || !add_dynamic_entry (DT_PLTREL, DT_RELA)
              || !add_dynamic_entry (DT_JMPREL, 0)))
@@ -6171,8 +6126,6 @@ nios2_elf_add_symbol_hook (bfd *abfd,
                           asection **secp,
                           bfd_vma *valp)
 {
-  bfd *dynobj;
-
   if (sym->st_shndx == SHN_COMMON
       && !bfd_link_relocatable (info)
       && sym->st_size <= elf_gp_size (abfd)
@@ -6187,12 +6140,11 @@ nios2_elf_add_symbol_hook (bfd *abfd,
        {
          flagword flags = SEC_IS_COMMON | SEC_LINKER_CREATED;
 
-         dynobj = elf_hash_table (info)->dynobj;
-         if (!dynobj)
-           dynobj = abfd;
+         if (htab->root.dynobj == NULL)
+           htab->root.dynobj = abfd;
 
-         htab->sbss = bfd_make_section_anyway_with_flags (dynobj, ".sbss",
-                                                          flags);
+         htab->sbss = bfd_make_section_anyway_with_flags (htab->root.dynobj,
+                                                          ".sbss", flags);
          if (htab->sbss == NULL)
            return FALSE;
        }
This page took 0.035612 seconds and 4 git commands to generate.