Skip to content

Commit cf18f14

Browse files
authored
[BOLT] Read .rela.dyn in static non-pie binary (#71635)
Static non-pie binary doesn't have DYNAMIC segment and BOLT skips reading .rela.dyn section because of it. But such binaries might have this section for example to store IFUNC relocation which is resolved by linked-in startup files, so force reading this section for static executables.
1 parent abec50c commit cf18f14

File tree

3 files changed

+37
-0
lines changed

3 files changed

+37
-0
lines changed

bolt/include/bolt/Rewrite/RewriteInstance.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,7 @@ class RewriteInstance {
430430

431431
/// Common section names.
432432
static StringRef getEHFrameSectionName() { return ".eh_frame"; }
433+
static StringRef getRelaDynSectionName() { return ".rela.dyn"; }
433434

434435
/// An instance of the input binary we are processing, externally owned.
435436
llvm::object::ELFObjectFileBase *InputFile;

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2217,6 +2217,19 @@ void RewriteInstance::processDynamicRelocations() {
22172217
}
22182218

22192219
// The rest of dynamic relocations - DT_RELA.
2220+
// The static executable might have .rela.dyn secion and not have PT_DYNAMIC
2221+
if (!DynamicRelocationsSize && BC->IsStaticExecutable) {
2222+
ErrorOr<BinarySection &> DynamicRelSectionOrErr =
2223+
BC->getUniqueSectionByName(getRelaDynSectionName());
2224+
if (DynamicRelSectionOrErr) {
2225+
DynamicRelocationsAddress = DynamicRelSectionOrErr->getAddress();
2226+
DynamicRelocationsSize = DynamicRelSectionOrErr->getSize();
2227+
const SectionRef &SectionRef = DynamicRelSectionOrErr->getSectionRef();
2228+
DynamicRelativeRelocationsCount = std::distance(
2229+
SectionRef.relocation_begin(), SectionRef.relocation_end());
2230+
}
2231+
}
2232+
22202233
if (DynamicRelocationsSize > 0) {
22212234
ErrorOr<BinarySection &> DynamicRelSectionOrErr =
22222235
BC->getSectionForAddress(*DynamicRelocationsAddress);

bolt/test/AArch64/ifunc.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,20 @@
77
// RUN: llvm-bolt %t.O0.exe -o %t.O0.bolt.exe \
88
// RUN: --print-disasm --print-only=_start | \
99
// RUN: FileCheck --check-prefix=O0_CHECK %s
10+
// RUN: llvm-readelf -aW %t.O0.bolt.exe | \
11+
// RUN: FileCheck --check-prefix=REL_CHECK %s
12+
13+
// Non-pie static executable doesn't generate PT_DYNAMIC, check relocation
14+
// is readed successfully and IPLT trampoline has been identified by bolt.
15+
// RUN: %clang %cflags -nostdlib -O3 %s -fuse-ld=lld -no-pie \
16+
// RUN: -o %t.O3_nopie.exe -Wl,-q
17+
// RUN: llvm-readelf -l %t.O3_nopie.exe | \
18+
// RUN: FileCheck --check-prefix=NON_DYN_CHECK %s
19+
// RUN: llvm-bolt %t.O3_nopie.exe -o %t.O3_nopie.bolt.exe \
20+
// RUN: --print-disasm --print-only=_start | \
21+
// RUN: FileCheck --check-prefix=O3_CHECK %s
22+
// RUN: llvm-readelf -aW %t.O3_nopie.bolt.exe | \
23+
// RUN: FileCheck --check-prefix=REL_CHECK %s
1024

1125
// With -O3 direct call is performed on IPLT trampoline. IPLT trampoline
1226
// doesn't have associated symbol. The ifunc symbol has the same address as
@@ -16,6 +30,8 @@
1630
// RUN: llvm-bolt %t.O3_pie.exe -o %t.O3_pie.bolt.exe \
1731
// RUN: --print-disasm --print-only=_start | \
1832
// RUN: FileCheck --check-prefix=O3_CHECK %s
33+
// RUN: llvm-readelf -aW %t.O3_pie.bolt.exe | \
34+
// RUN: FileCheck --check-prefix=REL_CHECK %s
1935

2036
// Check that IPLT trampoline located in .plt section are normally handled by
2137
// BOLT. The gnu-ld linker doesn't use separate .iplt section.
@@ -24,10 +40,17 @@
2440
// RUN: llvm-bolt %t.iplt_O3_pie.exe -o %t.iplt_O3_pie.bolt.exe \
2541
// RUN: --print-disasm --print-only=_start | \
2642
// RUN: FileCheck --check-prefix=O3_CHECK %s
43+
// RUN: llvm-readelf -aW %t.iplt_O3_pie.bolt.exe | \
44+
// RUN: FileCheck --check-prefix=REL_CHECK %s
45+
46+
// NON_DYN_CHECK-NOT: DYNAMIC
2747

2848
// O0_CHECK: adr x{{[0-9]+}}, ifoo
2949
// O3_CHECK: b "{{resolver_foo|ifoo}}{{.*}}@PLT"
3050

51+
// REL_CHECK: R_AARCH64_IRELATIVE [[#%x,REL_SYMB_ADDR:]]
52+
// REL_CHECK: [[#REL_SYMB_ADDR]] {{.*}} FUNC {{.*}} resolver_foo
53+
3154
static void foo() {}
3255

3356
static void *resolver_foo(void) { return foo; }

0 commit comments

Comments
 (0)