Setting sh_link for SHT_REL/SHT_RELA
authorAlan Modra <amodra@gmail.com>
Thu, 30 Mar 2023 01:40:16 +0000 (12:10 +1030)
committerAlan Modra <amodra@gmail.com>
Thu, 30 Mar 2023 04:48:02 +0000 (15:18 +1030)
It's wrong to have an alloc reloc section trying to use a non-alloc
symbol table.

* elf.c (assign_section_numbers <SHT_REL, SHT_RELA>): Correct
comment.  Always set sh_link to .dynsym for alloc reloc
sections and to .symtab for non-alloc.

bfd/elf.c

index 45e53640e8f817407ee43f04c9adb572a976b5d1..027d01437352555bc4ac0717cb0486c751a7775d 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -3870,21 +3870,23 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
        {
        case SHT_REL:
        case SHT_RELA:
-         /* A reloc section which we are treating as a normal BFD
-            section.  sh_link is the section index of the symbol
-            table.  sh_info is the section index of the section to
-            which the relocation entries apply.  We assume that an
-            allocated reloc section uses the dynamic symbol table
-            if there is one.  Otherwise we guess the normal symbol
-            table.  FIXME: How can we be sure?  */
-         if (d->this_hdr.sh_link == 0 && (sec->flags & SEC_ALLOC) != 0)
-           {
-             s = bfd_get_section_by_name (abfd, ".dynsym");
-             if (s != NULL)
-               d->this_hdr.sh_link = elf_section_data (s)->this_idx;
-           }
+         /* sh_link is the section index of the symbol table.
+            sh_info is the section index of the section to which the
+            relocation entries apply.  */
          if (d->this_hdr.sh_link == 0)
-           d->this_hdr.sh_link = elf_onesymtab (abfd);
+           {
+             /* FIXME maybe: If this is a reloc section which we are
+                treating as a normal section then we likely should
+                not be assuming its sh_link is .dynsym or .symtab.  */
+             if ((sec->flags & SEC_ALLOC) != 0)
+               {
+                 s = bfd_get_section_by_name (abfd, ".dynsym");
+                 if (s != NULL)
+                   d->this_hdr.sh_link = elf_section_data (s)->this_idx;
+               }
+             else
+               d->this_hdr.sh_link = elf_onesymtab (abfd);
+           }
 
          s = elf_get_reloc_section (sec);
          if (s != NULL)