Skip to content

Commit def6174

Browse files
authored
[BOLT] Emit empty FDE for injected functions
This fixes an issue where `PatchEntries` overwrites function body but keeps CFI untouched. Existing FDEs thus become invalid. This doesn't affect unwinding because patched functions are transparent from EH/unwinding perspective, but it breaks BOLT during disassembling those functions. Emit empty FDE for injected functions (emitted to the same address as .org functions) that take precedence over the original FDE. This adds eh_frame overhead, but restores the ability to disassemble .org functions. Note that the overhead is avoided in `-use-old-text` mode. Test Plan: updated bolt/test/X86/patch-entries.test Reviewers: rafaelauler, maksfb, dcci, ayermolo Reviewed By: maksfb, dcci Pull Request: #87967
1 parent cd14e71 commit def6174

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

bolt/include/bolt/Core/BinaryFunction.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1402,7 +1402,8 @@ class BinaryFunction {
14021402

14031403
/// Return true if the function has CFI instructions
14041404
bool hasCFI() const {
1405-
return !FrameInstructions.empty() || !CIEFrameInstructions.empty();
1405+
return !FrameInstructions.empty() || !CIEFrameInstructions.empty() ||
1406+
IsInjected;
14061407
}
14071408

14081409
/// Return unique number associated with the function.

bolt/test/X86/patch-entries.test

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,25 @@ REQUIRES: system-linux
77

88
RUN: %clang %cflags -no-pie -g %p/Inputs/patch-entries.c -fuse-ld=lld -o %t.exe \
99
RUN: -Wl,-q -I%p/../Inputs
10-
RUN: llvm-bolt -relocs %t.exe -o %t.out --update-debug-sections --force-patch
10+
RUN: llvm-bolt -relocs %t.exe -o %t.out --update-debug-sections --force-patch \
11+
RUN: --enable-bat
12+
13+
# Check that patched functions can be disassembled (override FDE from the
14+
# original function)
15+
# PREAGG: B X:0 #foo.org.0# 1 0
16+
RUN: link_fdata %s %t.out %t.preagg PREAGG
17+
RUN: perf2bolt %t.out -p %t.preagg --pa -o %t.yaml --profile-format=yaml \
18+
RUN: -print-disasm -print-only=foo.org.0/1 2>&1 | FileCheck %s
19+
CHECK-NOT: BOLT-WARNING: sizes differ for function foo.org.0/1
20+
CHECK: Binary Function "foo.org.0/1(*2)" after disassembly {
21+
22+
# Check the expected eh_frame contents
23+
RUN: llvm-nm --print-size %t.out > %t.foo
24+
RUN: llvm-objdump %t.out --dwarf=frames >> %t.foo
25+
RUN: FileCheck %s --input-file %t.foo --check-prefix=CHECK-FOO
26+
CHECK-FOO: 0000000000[[#%x,FOO:]] [[#%x,OPTSIZE:]] t foo
27+
CHECK-FOO: 0000000000[[#%x,ORG:]] [[#%x,ORGSIZE:]] t foo.org.0
28+
# patched FDE comes first
29+
CHECK-FOO: FDE {{.*}} pc=00[[#%x,ORG]]...00[[#%x,ORG+ORGSIZE]]
30+
# original FDE comes second
31+
CHECK-FOO: FDE {{.*}} pc=00[[#%x,ORG]]...00[[#%x,ORG+OPTSIZE]]

0 commit comments

Comments
 (0)