[ELF] Set SHF_INFO_LINK for .rel[a].plt and .rel[a].dyn
authorFangrui Song <i@maskray.me>
Thu, 22 Oct 2020 16:48:04 +0000 (09:48 -0700)
committerFangrui Song <i@maskray.me>
Thu, 22 Oct 2020 16:48:19 +0000 (09:48 -0700)
The ELF spec says

> If the sh_flags field for this section header includes the attribute SHF_INFO_LINK, then this member represents a section header table index.

Set SHF_INFO_LINK so that binary manipulation tools know that sh_info is
a section header table index instead of (the number of local symbols in the case of SHT_SYMTAB/SHT_DYNSYM).
We have already added SHF_INFO_LINK for --emit-relocs retained SHT_REL[A].

For example, we can teach llvm-objcopy to preserve the section index of the sh_info referenced section if
SHF_INFO_LINK is set. (GNU objcopy recognizes .rel[a].plt and updates
sh_info even if SHF_INFO_LINK is not set).

Reviewed By: grimar, psmith

Differential Revision: https://reviews.llvm.org/D89828

lld/ELF/SyntheticSections.cpp
lld/test/ELF/aarch64-gnu-ifunc.s
lld/test/ELF/arm-combined-dynrel-ifunc.s
lld/test/ELF/arm-gnu-ifunc.s
lld/test/ELF/dynamic-reloc.s
lld/test/ELF/gnu-ifunc-i386.s
lld/test/ELF/gnu-ifunc.s
lld/test/ELF/x86-64-combined-dynrel.s

index 7769848..0ffd6bf 100644 (file)
@@ -1610,10 +1610,14 @@ void RelocationBaseSection::finalizeContents() {
   else
     getParent()->link = 0;
 
-  if (in.relaPlt == this)
+  if (in.relaPlt == this) {
+    getParent()->flags |= ELF::SHF_INFO_LINK;
     getParent()->info = in.gotPlt->getParent()->sectionIndex;
-  if (in.relaIplt == this)
+  }
+  if (in.relaIplt == this) {
+    getParent()->flags |= ELF::SHF_INFO_LINK;
     getParent()->info = in.igotPlt->getParent()->sectionIndex;
+  }
 }
 
 RelrBaseSection::RelrBaseSection()
index daa7873..e036517 100644 (file)
@@ -11,6 +11,7 @@
 // CHECK-NEXT:  Type: SHT_RELA
 // CHECK-NEXT:  Flags [
 // CHECK-NEXT:    SHF_ALLOC
+// CHECK-NEXT:    SHF_INFO_LINK
 // CHECK-NEXT:  ]
 // CHECK-NEXT:  Address: [[RELA:.*]]
 // CHECK-NEXT:  Offset: 0x158
index 2761357..8471182 100644 (file)
@@ -40,6 +40,7 @@ main:
 // CHECK-NEXT:     Type: SHT_REL
 // CHECK-NEXT:     Flags [
 // CHECK-NEXT:       SHF_ALLOC
+// CHECK-NEXT:       SHF_INFO_LINK
 // CHECK-NEXT:     ]
 // CHECK-NEXT:     Address:
 // CHECK-NEXT:     Offset:
index 71b80a1..9a410aa 100644 (file)
@@ -31,6 +31,7 @@ _start:
 // CHECK-NEXT:     Type: SHT_REL
 // CHECK-NEXT:     Flags [
 // CHECK-NEXT:       SHF_ALLOC
+// CHECK-NEXT:       SHF_INFO_LINK
 // CHECK-NEXT:     ]
 // CHECK-NEXT:     Address: 0x100F4
 // CHECK-NEXT:     Offset: 0xF4
index f6cb15e..0df38b5 100644 (file)
@@ -13,6 +13,7 @@
 // CHECK-NEXT: Type: SHT_RELA
 // CHECK-NEXT: Flags [
 // CHECK-NEXT:   SHF_ALLOC
+// CHECK-NEXT:   SHF_INFO_LINK
 // CHECK-NEXT: ]
 // CHECK-NEXT: Address: [[RELAADDR:.*]]
 // CHECK-NEXT: Offset:
index 60c16f5..41fcd79 100644 (file)
@@ -11,6 +11,7 @@
 // CHECK-NEXT:  Type: SHT_REL
 // CHECK-NEXT:  Flags [
 // CHECK-NEXT:    SHF_ALLOC
+// CHECK-NEXT:    SHF_INFO_LINK
 // CHECK-NEXT:  ]
 // CHECK-NEXT:  Address: [[RELA:.*]]
 // CHECK-NEXT:  Offset: 0xD4
index c43bef2..dc7a851 100644 (file)
@@ -11,6 +11,7 @@
 // CHECK-NEXT:  Type: SHT_RELA
 // CHECK-NEXT:  Flags [
 // CHECK-NEXT:    SHF_ALLOC
+// CHECK-NEXT:    SHF_INFO_LINK
 // CHECK-NEXT:  ]
 // CHECK-NEXT:  Address: [[RELA:.*]]
 // CHECK-NEXT:  Offset: 0x158
index b1bc697..9b3ed75 100644 (file)
@@ -31,6 +31,7 @@ _start:
 # CHECK-NEXT:         Type: SHT_RELA
 # CHECK-NEXT:     Flags [
 # CHECK-NEXT:       SHF_ALLOC
+# CHECK-NEXT:       SHF_INFO_LINK
 # CHECK-NEXT:     ]
 # CHECK-NEXT:     Address:
 # CHECK-NEXT:     Offset: