[lld] a8f9f08 - [ELF] Set SHF_INFO_LINK for .rel[a].plt and .rel[a].dyn

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 22 09:48:25 PDT 2020


Author: Fangrui Song
Date: 2020-10-22T09:48:19-07:00
New Revision: a8f9f0801816953e9cf792448dcffd9000227b27

URL: https://github.com/llvm/llvm-project/commit/a8f9f0801816953e9cf792448dcffd9000227b27
DIFF: https://github.com/llvm/llvm-project/commit/a8f9f0801816953e9cf792448dcffd9000227b27.diff

LOG: [ELF] Set SHF_INFO_LINK for .rel[a].plt and .rel[a].dyn

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

Added: 
    

Modified: 
    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

Removed: 
    


################################################################################
diff  --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 776984874a78..0ffd6bfa81dd 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -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()

diff  --git a/lld/test/ELF/aarch64-gnu-ifunc.s b/lld/test/ELF/aarch64-gnu-ifunc.s
index daa7873eb71d..e03651788b6a 100644
--- a/lld/test/ELF/aarch64-gnu-ifunc.s
+++ b/lld/test/ELF/aarch64-gnu-ifunc.s
@@ -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

diff  --git a/lld/test/ELF/arm-combined-dynrel-ifunc.s b/lld/test/ELF/arm-combined-dynrel-ifunc.s
index 2761357fd98d..84711827b8e5 100644
--- a/lld/test/ELF/arm-combined-dynrel-ifunc.s
+++ b/lld/test/ELF/arm-combined-dynrel-ifunc.s
@@ -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:

diff  --git a/lld/test/ELF/arm-gnu-ifunc.s b/lld/test/ELF/arm-gnu-ifunc.s
index 71b80a1840be..9a410aaa27d6 100644
--- a/lld/test/ELF/arm-gnu-ifunc.s
+++ b/lld/test/ELF/arm-gnu-ifunc.s
@@ -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

diff  --git a/lld/test/ELF/dynamic-reloc.s b/lld/test/ELF/dynamic-reloc.s
index f6cb15e493dc..0df38b565ddf 100644
--- a/lld/test/ELF/dynamic-reloc.s
+++ b/lld/test/ELF/dynamic-reloc.s
@@ -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:

diff  --git a/lld/test/ELF/gnu-ifunc-i386.s b/lld/test/ELF/gnu-ifunc-i386.s
index 60c16f54e4f1..41fcd79b5c42 100644
--- a/lld/test/ELF/gnu-ifunc-i386.s
+++ b/lld/test/ELF/gnu-ifunc-i386.s
@@ -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

diff  --git a/lld/test/ELF/gnu-ifunc.s b/lld/test/ELF/gnu-ifunc.s
index c43bef28b2e2..dc7a851a57ab 100644
--- a/lld/test/ELF/gnu-ifunc.s
+++ b/lld/test/ELF/gnu-ifunc.s
@@ -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

diff  --git a/lld/test/ELF/x86-64-combined-dynrel.s b/lld/test/ELF/x86-64-combined-dynrel.s
index b1bc697d148b..9b3ed75a67d0 100644
--- a/lld/test/ELF/x86-64-combined-dynrel.s
+++ b/lld/test/ELF/x86-64-combined-dynrel.s
@@ -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:


        


More information about the llvm-commits mailing list