[llvm] [BOLT] Fix order of R_*_IRELATIVE in .rela.plt (PR #106515)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 23 03:38:33 PDT 2024
https://github.com/linsinan1995 updated https://github.com/llvm/llvm-project/pull/106515
>From 7d731c204747963b5a13f4f617697c01fdd0c86a Mon Sep 17 00:00:00 2001
From: Sinan Lin <sinan.lin at linux.alibaba.com>
Date: Wed, 28 Aug 2024 20:37:52 +0800
Subject: [PATCH] [BOLT] Fix order of R_*_IRELATIVE in .rela.plt
GNU ld might place R_*_IRELATIVE in .rela.plt, and have a layout like
Relocation section '.rela.plt' ...
Offset Type
cc9040 R_X86_64_JUMP_SLOT
cc9048 R_X86_64_JUMP_SLOT
cc9060 R_X86_64_JUMP_SLOT
cc9050 R_X86_64_IRELATIVE
R_*_IRELATIVE entries all come after JUMP_SLOT entries. This patch will
change the allocatable rela patching order to keep this layout if we
find R_*_IRELATIVE is in .rela.plt section.
---
bolt/include/bolt/Core/Relocation.h | 3 +
bolt/lib/Core/Relocation.cpp | 15 +-
bolt/lib/Rewrite/RewriteInstance.cpp | 19 +-
bolt/test/X86/Inputs/ifunc-ld.yaml | 424 +++++++++++++++++++++++++++
bolt/test/X86/ifunc-ld.test | 13 +
5 files changed, 470 insertions(+), 4 deletions(-)
create mode 100644 bolt/test/X86/Inputs/ifunc-ld.yaml
create mode 100644 bolt/test/X86/ifunc-ld.test
diff --git a/bolt/include/bolt/Core/Relocation.h b/bolt/include/bolt/Core/Relocation.h
index 933f62a31f8fd7..d925f87f762b30 100644
--- a/bolt/include/bolt/Core/Relocation.h
+++ b/bolt/include/bolt/Core/Relocation.h
@@ -117,6 +117,9 @@ struct Relocation {
/// Return code for a RELATIVE relocation
static uint64_t getRelative();
+ /// Return code for a IRELATIVE relocation
+ static uint64_t getIRelative();
+
/// Return true if this relocation is PC-relative. Return false otherwise.
bool isPCRelative() const { return isPCRelative(Type); }
diff --git a/bolt/lib/Core/Relocation.cpp b/bolt/lib/Core/Relocation.cpp
index 4e888a5b147aca..49064bb4e49b75 100644
--- a/bolt/lib/Core/Relocation.cpp
+++ b/bolt/lib/Core/Relocation.cpp
@@ -899,7 +899,7 @@ bool Relocation::isIRelative(uint64_t Type) {
case Triple::aarch64:
return Type == ELF::R_AARCH64_IRELATIVE;
case Triple::riscv64:
- llvm_unreachable("not implemented");
+ return Type == ELF::R_RISCV_IRELATIVE;
case Triple::x86_64:
return Type == ELF::R_X86_64_IRELATIVE;
}
@@ -1009,6 +1009,19 @@ uint64_t Relocation::getRelative() {
}
}
+uint64_t Relocation::getIRelative() {
+ switch (Arch) {
+ default:
+ llvm_unreachable("Unsupported architecture");
+ case Triple::aarch64:
+ return ELF::R_AARCH64_IRELATIVE;
+ case Triple::riscv64:
+ return ELF::R_RISCV_IRELATIVE;
+ case Triple::x86_64:
+ return ELF::R_X86_64_IRELATIVE;
+ }
+}
+
size_t Relocation::emit(MCStreamer *Streamer) const {
const size_t Size = getSizeForType(Type);
const auto *Value = createExpr(Streamer);
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index adacb50dc167c8..71c92d616c6915 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -5185,12 +5185,15 @@ RewriteInstance::patchELFAllocatableRelaSections(ELFObjectFile<ELFT> *File) {
DynamicRelativeRelocationsCount = 0;
+ const bool HasIRelativeInPLT =
+ IsJmpRelocation.contains(Relocation::getIRelative());
+
auto writeRela = [&OS](const Elf_Rela *RelA, uint64_t &Offset) {
OS.pwrite(reinterpret_cast<const char *>(RelA), sizeof(*RelA), Offset);
Offset += sizeof(*RelA);
};
- auto writeRelocations = [&](bool PatchRelative) {
+ auto writeRelocations = [&](bool PatchRelative, bool PatchIRelativeInPLT) {
for (BinarySection &Section : BC->allocatableSections()) {
const uint64_t SectionInputAddress = Section.getAddress();
uint64_t SectionAddress = Section.getOutputAddress();
@@ -5199,9 +5202,14 @@ RewriteInstance::patchELFAllocatableRelaSections(ELFObjectFile<ELFT> *File) {
for (const Relocation &Rel : Section.dynamicRelocations()) {
const bool IsRelative = Rel.isRelative();
+ const bool IsIRelativeInPLT = HasIRelativeInPLT && Rel.isIRelative();
+
if (PatchRelative != IsRelative)
continue;
+ if (PatchIRelativeInPLT != IsIRelativeInPLT)
+ continue;
+
if (IsRelative)
++DynamicRelativeRelocationsCount;
@@ -5249,8 +5257,13 @@ RewriteInstance::patchELFAllocatableRelaSections(ELFObjectFile<ELFT> *File) {
// The dynamic linker expects all R_*_RELATIVE relocations in RELA
// to be emitted first.
if (!DynamicRelrAddress)
- writeRelocations(/* PatchRelative */ true);
- writeRelocations(/* PatchRelative */ false);
+ writeRelocations(/* PatchRelative */ true, /* PatchIRelativeInPLT */ false);
+ writeRelocations(/* PatchRelative */ false, /* PatchIRelativeInPLT */ false);
+
+ // Place R_*_IRELATIVE after all R_*_JUMP_SLOT relocations emitted if
+ // R_*_IRELATIVE is presented at .rela.plt
+ if (HasIRelativeInPLT)
+ writeRelocations(/* PatchRelative */ false, /* PatchIRelativeInPLT */ true);
auto fillNone = [&](uint64_t &Offset, uint64_t EndOffset) {
if (!Offset)
diff --git a/bolt/test/X86/Inputs/ifunc-ld.yaml b/bolt/test/X86/Inputs/ifunc-ld.yaml
new file mode 100644
index 00000000000000..18032397e107e8
--- /dev/null
+++ b/bolt/test/X86/Inputs/ifunc-ld.yaml
@@ -0,0 +1,424 @@
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ OSABI: ELFOSABI_GNU
+ Type: ET_EXEC
+ Machine: EM_X86_64
+ Entry: 0x401050
+ProgramHeaders:
+ - Type: PT_PHDR
+ Flags: [ PF_R ]
+ VAddr: 0x400040
+ Align: 0x8
+ Offset: 0x40
+ - Type: PT_INTERP
+ Flags: [ PF_R ]
+ FirstSec: .interp
+ LastSec: .interp
+ VAddr: 0x400270
+ Offset: 0x270
+ - Type: PT_LOAD
+ Flags: [ PF_R ]
+ FirstSec: .interp
+ LastSec: .rela.plt
+ VAddr: 0x400000
+ Align: 0x1000
+ Offset: 0x0
+ - Type: PT_LOAD
+ Flags: [ PF_X, PF_R ]
+ FirstSec: .plt
+ LastSec: .text
+ VAddr: 0x401000
+ Align: 0x1000
+ Offset: 0x1000
+ - Type: PT_LOAD
+ Flags: [ PF_R ]
+ FirstSec: .rodata
+ LastSec: .eh_frame
+ VAddr: 0x402000
+ Align: 0x1000
+ Offset: 0x2000
+ - Type: PT_LOAD
+ Flags: [ PF_W, PF_R ]
+ FirstSec: .dynamic
+ LastSec: .got.plt
+ VAddr: 0x403EB8
+ Align: 0x1000
+ Offset: 0x2EB8
+ - Type: PT_DYNAMIC
+ Flags: [ PF_W, PF_R ]
+ FirstSec: .dynamic
+ LastSec: .dynamic
+ VAddr: 0x403EB8
+ Align: 0x8
+ Offset: 0x2EB8
+ - Type: PT_GNU_EH_FRAME
+ Flags: [ PF_R ]
+ FirstSec: .eh_frame_hdr
+ LastSec: .eh_frame_hdr
+ VAddr: 0x402004
+ Align: 0x4
+ Offset: 0x2004
+ - Type: PT_GNU_STACK
+ Flags: [ PF_W, PF_R ]
+ Align: 0x10
+ Offset: 0x0
+ - Type: PT_GNU_RELRO
+ Flags: [ PF_R ]
+ FirstSec: .dynamic
+ LastSec: .got
+ VAddr: 0x403EB8
+ Offset: 0x2EB8
+Sections:
+ - Name: .interp
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x400270
+ AddressAlign: 0x1
+ Content: 2F6C696236342F6C642D6C696E75782D7838362D36342E736F2E3200
+ - Name: .gnu.hash
+ Type: SHT_GNU_HASH
+ Flags: [ SHF_ALLOC ]
+ Address: 0x400290
+ Link: .dynsym
+ AddressAlign: 0x8
+ Header:
+ SymNdx: 0x1
+ Shift2: 0x0
+ BloomFilter: [ 0x0 ]
+ HashBuckets: [ 0x0 ]
+ HashValues: [ ]
+ - Name: .dynsym
+ Type: SHT_DYNSYM
+ Flags: [ SHF_ALLOC ]
+ Address: 0x4002B0
+ Link: .dynstr
+ AddressAlign: 0x8
+ - Name: .dynstr
+ Type: SHT_STRTAB
+ Flags: [ SHF_ALLOC ]
+ Address: 0x400310
+ AddressAlign: 0x1
+ - Name: .rela.dyn
+ Type: SHT_RELA
+ Flags: [ SHF_ALLOC ]
+ Address: 0x400330
+ Link: .dynsym
+ AddressAlign: 0x8
+ Relocations:
+ - Offset: 0x403FF8
+ Symbol: memcpy
+ Type: R_X86_64_GLOB_DAT
+ - Name: .rela.plt
+ Type: SHT_RELA
+ Flags: [ SHF_ALLOC, SHF_INFO_LINK ]
+ Address: 0x400348
+ Link: .dynsym
+ AddressAlign: 0x8
+ Info: .got.plt
+ Relocations:
+ - Offset: 0x404018
+ Symbol: printf
+ Type: R_X86_64_JUMP_SLOT
+ - Offset: 0x404028
+ Symbol: rand
+ Type: R_X86_64_JUMP_SLOT
+ - Offset: 0x404030
+ Type: R_X86_64_IRELATIVE
+ Addend: 4198480
+ - Offset: 0x404020
+ Type: R_X86_64_IRELATIVE
+ Addend: 4198496
+ - Name: .plt
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x401000
+ AddressAlign: 0x10
+ EntSize: 0x10
+ Offset: 0x1000
+ Content: FF3502300000FF25043000000F1F4000FF25023000006800000000E9E0FFFFFFFF25FA2F00006803000000E9D0FFFFFFFF25F22F00006801000000E9C0FFFFFFFF25EA2F00006802000000E9B0FFFFFF
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x401050
+ AddressAlign: 0x10
+ Content: 488D0579000000C30F1F840000000000488B05912F0000C30F1F840000000000554889E54883EC10C745FC00000000C745F8EFBEADDEC745F400000000488D7DF4488D75F8BA04000000E881FFFFFF8B45F83B45F40F840C000000C745FCFFFFFFFFE907000000B000E882FFFFFF8B45FC4883C4105DC3660F1F840000000000554889E54883EC10E853FFFFFF8945FC8B75FC488D3D160F0000B000E81FFFFFFF4883C4105DC3
+ - Name: .rodata
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_MERGE, SHF_STRINGS ]
+ Address: 0x402000
+ AddressAlign: 0x1
+ EntSize: 0x1
+ Offset: 0x2000
+ Content: '256400'
+ - Name: .eh_frame_hdr
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x402004
+ AddressAlign: 0x4
+ Content: 011B033B3000000005000000FCEFFFFFB40000004CF0FFFF4C0000005CF0FFFF600000006CF0FFFF74000000CCF0FFFF94000000
+ - Name: .eh_frame
+ Type: SHT_X86_64_UNWIND
+ Flags: [ SHF_ALLOC ]
+ Address: 0x402038
+ AddressAlign: 0x8
+ Content: 1400000000000000017A5200017810011B0C070890010000100000001C000000F8EFFFFF08000000000000001000000030000000F4EFFFFF08000000000000001C00000044000000F0EFFFFF5700000000410E108602430D0602520C070800001C0000006400000030F0FFFF2700000000410E108602430D06620C0708000000200000008400000040EFFFFF50000000000E10460E184A0F0B770880003F1A3B2A332422
+ - Name: .dynamic
+ Type: SHT_DYNAMIC
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x403EB8
+ Link: .dynstr
+ AddressAlign: 0x8
+ Offset: 0x2EB8
+ Entries:
+ - Tag: DT_NEEDED
+ Value: 0x1
+ - Tag: DT_GNU_HASH
+ Value: 0x400290
+ - Tag: DT_STRTAB
+ Value: 0x400310
+ - Tag: DT_SYMTAB
+ Value: 0x4002B0
+ - Tag: DT_STRSZ
+ Value: 0x1F
+ - Tag: DT_SYMENT
+ Value: 0x18
+ - Tag: DT_DEBUG
+ Value: 0x0
+ - Tag: DT_PLTGOT
+ Value: 0x404000
+ - Tag: DT_PLTRELSZ
+ Value: 0x60
+ - Tag: DT_PLTREL
+ Value: 0x7
+ - Tag: DT_JMPREL
+ Value: 0x400348
+ - Tag: DT_RELA
+ Value: 0x400330
+ - Tag: DT_RELASZ
+ Value: 0x18
+ - Tag: DT_RELAENT
+ Value: 0x18
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Name: .got
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x403FF8
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Content: '0000000000000000'
+ - Name: .got.plt
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x404000
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Content: B83E400000000000000000000000000000000000000000001610400000000000261040000000000036104000000000004610400000000000
+ - Name: .comment
+ Type: SHT_PROGBITS
+ Flags: [ SHF_MERGE, SHF_STRINGS ]
+ AddressAlign: 0x1
+ EntSize: 0x1
+ Content: 636C616E672076657273696F6E2031372E302E362028416C696261626120436C6F756420436F6D70696C65722031372E302E362E312D32342E30352E31302E616C696F73372900
+ - Name: .rela.text
+ Type: SHT_RELA
+ Flags: [ SHF_INFO_LINK ]
+ Link: .symtab
+ AddressAlign: 0x8
+ Info: .text
+ Relocations:
+ - Offset: 0x401063
+ Symbol: memcpy
+ Type: R_X86_64_REX_GOTPCRELX
+ Addend: -4
+ - Offset: 0x40109B
+ Symbol: imemcpy
+ Type: R_X86_64_PLT32
+ Addend: -4
+ - Offset: 0x4010BA
+ Symbol: ifoo
+ Type: R_X86_64_PLT32
+ Addend: -4
+ - Offset: 0x4010D9
+ Symbol: rand
+ Type: R_X86_64_PLT32
+ Addend: -4
+ - Offset: 0x4010E6
+ Symbol: .L.str
+ Type: R_X86_64_PC32
+ Addend: -4
+ - Offset: 0x4010ED
+ Symbol: printf
+ Type: R_X86_64_PLT32
+ Addend: -4
+ - Name: .rela.eh_frame
+ Type: SHT_RELA
+ Flags: [ SHF_INFO_LINK ]
+ Link: .symtab
+ AddressAlign: 0x8
+ Info: .eh_frame
+ Relocations:
+ - Offset: 0x402058
+ Symbol: .text
+ Type: R_X86_64_PC32
+ - Offset: 0x40206C
+ Symbol: .text
+ Type: R_X86_64_PC32
+ Addend: 16
+ - Offset: 0x402080
+ Symbol: .text
+ Type: R_X86_64_PC32
+ Addend: 32
+ - Offset: 0x4020A0
+ Symbol: .text
+ Type: R_X86_64_PC32
+ Addend: 128
+ - Type: SectionHeaderTable
+ Sections:
+ - Name: .interp
+ - Name: .gnu.hash
+ - Name: .dynsym
+ - Name: .dynstr
+ - Name: .rela.dyn
+ - Name: .rela.plt
+ - Name: .plt
+ - Name: .text
+ - Name: .rela.text
+ - Name: .rodata
+ - Name: .eh_frame_hdr
+ - Name: .eh_frame
+ - Name: .rela.eh_frame
+ - Name: .dynamic
+ - Name: .got
+ - Name: .got.plt
+ - Name: .comment
+ - Name: .symtab
+ - Name: .strtab
+ - Name: .shstrtab
+Symbols:
+ - Name: .interp
+ Type: STT_SECTION
+ Section: .interp
+ Value: 0x400270
+ - Name: .gnu.hash
+ Type: STT_SECTION
+ Section: .gnu.hash
+ Value: 0x400290
+ - Name: .dynsym
+ Type: STT_SECTION
+ Section: .dynsym
+ Value: 0x4002B0
+ - Name: .dynstr
+ Type: STT_SECTION
+ Section: .dynstr
+ Value: 0x400310
+ - Name: .rela.dyn
+ Type: STT_SECTION
+ Section: .rela.dyn
+ Value: 0x400330
+ - Name: .rela.plt
+ Type: STT_SECTION
+ Section: .rela.plt
+ Value: 0x400348
+ - Name: .plt
+ Type: STT_SECTION
+ Section: .plt
+ Value: 0x401000
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ Value: 0x401050
+ - Name: .rodata
+ Type: STT_SECTION
+ Section: .rodata
+ Value: 0x402000
+ - Name: .eh_frame_hdr
+ Type: STT_SECTION
+ Section: .eh_frame_hdr
+ Value: 0x402004
+ - Name: .eh_frame
+ Type: STT_SECTION
+ Section: .eh_frame
+ Value: 0x402038
+ - Name: .dynamic
+ Type: STT_SECTION
+ Section: .dynamic
+ Value: 0x403EB8
+ - Name: .got
+ Type: STT_SECTION
+ Section: .got
+ Value: 0x403FF8
+ - Name: .got.plt
+ Type: STT_SECTION
+ Section: .got.plt
+ Value: 0x404000
+ - Name: .comment
+ Type: STT_SECTION
+ Section: .comment
+ - Name: .L.str
+ Type: STT_OBJECT
+ Section: .rodata
+ Value: 0x402000
+ Size: 0x3
+ - Name: printf
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: imemcpy
+ Type: STT_GNU_IFUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x401060
+ Size: 0x8
+ - Name: memcpy
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: rand
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: __bss_start
+ Section: .got.plt
+ Binding: STB_GLOBAL
+ Value: 0x404038
+ - Name: main
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x401070
+ Size: 0x57
+ - Name: _edata
+ Section: .got.plt
+ Binding: STB_GLOBAL
+ Value: 0x404038
+ - Name: _end
+ Section: .got.plt
+ Binding: STB_GLOBAL
+ Value: 0x404038
+ - Name: ifoo
+ Type: STT_GNU_IFUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x401050
+ Size: 0x8
+DynamicSymbols:
+ - Name: printf
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: memcpy
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: rand
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+...
diff --git a/bolt/test/X86/ifunc-ld.test b/bolt/test/X86/ifunc-ld.test
new file mode 100644
index 00000000000000..64cbd6d758fed7
--- /dev/null
+++ b/bolt/test/X86/ifunc-ld.test
@@ -0,0 +1,13 @@
+// This test checks R_X86_64_IRELATIVE in .rela.plt can be properly
+// placed after R_X86_64_JUMP_SLOT entries by BOLT
+
+RUN: yaml2obj %p/Inputs/ifunc-ld.yaml &> %t.exe
+RUN: llvm-bolt %t.exe -o %t.bolt
+RUN: llvm-readelf -aW %t.bolt | FileCheck %s
+
+# CHECK: Relocation section '.rela.plt'
+# CHECK-NEXT: Offset
+# CHECK-NEXT: R_X86_64_JUMP_SLOT
+# CHECK-NEXT: R_X86_64_JUMP_SLOT
+# CHECK-NEXT: R_X86_64_IRELATIVE
+# CHECK-NEXT: R_X86_64_IRELATIVE
More information about the llvm-commits
mailing list