From a8f9f0801816953e9cf792448dcffd9000227b27 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 22 Oct 2020 09:48:04 -0700 Subject: [PATCH] [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 --- lld/ELF/SyntheticSections.cpp | 8 ++++++-- lld/test/ELF/aarch64-gnu-ifunc.s | 1 + lld/test/ELF/arm-combined-dynrel-ifunc.s | 1 + lld/test/ELF/arm-gnu-ifunc.s | 1 + lld/test/ELF/dynamic-reloc.s | 1 + lld/test/ELF/gnu-ifunc-i386.s | 1 + lld/test/ELF/gnu-ifunc.s | 1 + lld/test/ELF/x86-64-combined-dynrel.s | 1 + 8 files changed, 13 insertions(+), 2 deletions(-) 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: