Don't strip section defining _SDA_BASE_
authorAlan Modra <amodra@gmail.com>
Tue, 24 Jun 2014 03:53:04 +0000 (13:23 +0930)
committerAlan Modra <amodra@gmail.com>
Tue, 24 Jun 2014 04:09:04 +0000 (13:39 +0930)
Prior to 93d1b056 _SDA_BASE_ used to be defined in a linker script
output section.  Now _SDA_BASE_ is defined in an input section that is
subject to being stripped.  If the section is stripped we don't output
the symbol, which results in --emit-relocs trying to emit relocs with
dangling references to _SDA_BASE_.

* elf32-ppc.c (ppc_elf_size_dynamic_sections): Arrange to keep
.sdata/.sdata2 when _SDA_BASE_/_SDA2_BASE_ should be output
for --emit-relocs.

bfd/ChangeLog
bfd/elf32-ppc.c

index fcf2cd3..9cd00df 100644 (file)
@@ -1,3 +1,9 @@
+2014-06-24  Alan Modra  <amodra@gmail.com>
+
+       * elf32-ppc.c (ppc_elf_size_dynamic_sections): Arrange to keep
+       .sdata/.sdata2 when _SDA_BASE_/_SDA2_BASE_ should be output
+       for --emit-relocs.
+
 2014-06-21  Philippe De Muyter  <phdm@macqel.be>
 
        * targets.c (_bfd_target_vector): Add missing #ifdef BFD64 for
index bc793d7..c4a9543 100644 (file)
@@ -6304,6 +6304,16 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd,
       sda->root.u.def.section = htab->elf.hgot->root.u.def.section;
       sda->root.u.def.value = htab->elf.hgot->root.u.def.value;
     }
+  if (info->emitrelocations)
+    {
+      struct elf_link_hash_entry *sda = htab->sdata[0].sym;
+
+      if (sda != NULL && sda->ref_regular)
+       sda->root.u.def.section->flags |= SEC_KEEP;
+      sda = htab->sdata[1].sym;
+      if (sda != NULL && sda->ref_regular)
+       sda->root.u.def.section->flags |= SEC_KEEP;
+    }
 
   if (htab->glink != NULL
       && htab->glink->size != 0
@@ -6396,12 +6406,15 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd,
               || s == htab->sgotplt
               || s == htab->sbss
               || s == htab->dynbss
-              || s == htab->dynsbss
-              || s == htab->sdata[0].section
-              || s == htab->sdata[1].section)
+              || s == htab->dynsbss)
        {
          /* Strip these too.  */
        }
+      else if (s == htab->sdata[0].section
+              || s == htab->sdata[1].section)
+       {
+         strip_section = (s->flags & SEC_KEEP) == 0;
+       }
       else if (CONST_STRNEQ (bfd_get_section_name (htab->elf.dynobj, s),
                             ".rela"))
        {