Set dynobj to a normal input file if possible
authorH.J. Lu <hjl.tools@gmail.com>
Fri, 22 Apr 2016 02:14:10 +0000 (19:14 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 22 Apr 2016 02:14:28 +0000 (19:14 -0700)
When check_relocs is called after gc-sections has run,
_bfd_elf_link_create_dynstrtab may be called with an dynamic object
and hash_table->dynobj may be NULL.  We may not set dynobj, an input
file holding linker created dynamic sections to the dynamic object,
which has its own dynamic sections.  We need to find a normal input
file to hold linker created sections if possible.  Otherwise ld will
crash during LTO input rescan when linker created dynamic section
overrides input dynamic section.

* elflink.c (_bfd_elf_link_create_dynstrtab): Set dynobj to a
normal input file if possible.

bfd/ChangeLog
bfd/elflink.c

index 979322522b1d910fcb34b0be67f9af7b972d7acf..d668652e4b8fd9ce1d1407b00b03b7572c7b1a9c 100644 (file)
@@ -1,3 +1,8 @@
+2016-04-21  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * elflink.c (_bfd_elf_link_create_dynstrtab): Set dynobj to a
+       normal input file if possible.
+
 2016-04-21  Nick Clifton  <nickc@redhat.com>
 
        * aout-adobe.c: Use _bfd_generic_link_check_relocs.
index b432384bd7d93a2f442269506a15a3f440a189dc..13233cb50be2a86a9a6e789da2b0593125180c51 100644 (file)
@@ -204,7 +204,23 @@ _bfd_elf_link_create_dynstrtab (bfd *abfd, struct bfd_link_info *info)
 
   hash_table = elf_hash_table (info);
   if (hash_table->dynobj == NULL)
-    hash_table->dynobj = abfd;
+    {
+      /* We may not set dynobj, an input file holding linker created
+        dynamic sections to abfd, which may be a dynamic object with
+        its own dynamic sections.  We need to find a normal input file
+        to hold linker created sections if possible.  */
+      if ((abfd->flags & (DYNAMIC | BFD_PLUGIN)) != 0)
+       {
+         bfd *ibfd;
+         for (ibfd = info->input_bfds; ibfd; ibfd = ibfd->link.next)
+           if ((ibfd->flags & (DYNAMIC | BFD_PLUGIN)) == 0)
+             {
+               abfd = ibfd;
+               break;
+             }
+       }
+      hash_table->dynobj = abfd;
+    }
 
   if (hash_table->dynstr == NULL)
     {