Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Conservatively handle jump tables in split functions
Summary: - Allow jump table entries to point to locations inside the function and its fragments. Reasoning behind this is that jump table identification has the logic of stopping at entry which belongs to a function different from the one originally referencing jump table. This assumption is invalid for jump tables with entries pointing to both parent function and cold fragments, leading to "unclaimed PC-relative relocations" assertion. - Add fragment identification heuristic based on function name regex and contiguous jump table entries. Currently, parent-to-fragment relationship is set up based on interprocedural references – direct references from the parent function. These references don't include references through jump table. Additionally, some fragments are only reachable through jump table. In that case, in order to fully consume jump table, add parent-to-fragment relationship during `analyzeJumpTable` using the following heuristics: 1. Fragment is identified as such based on name (contains `.cold.` part), but 2. Parent function is not set – no direct interprocedural references to that fragment, and 3. Fragment has the name of the form <parent>.cold(.\d+) * For split functions with jump table entries spanning parent and fragments, mark parent and all fragments as ignored. (cherry picked from FBD24456904)
- Loading branch information
Showing
5 changed files
with
189 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# This reproduces a bug with jump table identification where jump table has | ||
# entries pointing to code in function and its cold fragment. | ||
|
||
# REQUIRES: system-linux | ||
|
||
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o | ||
# RUN: strip --strip-unneeded %t.o | ||
# RUN: %host_cc %t.o -o %t.exe -Wl,-q | ||
# RUN: llvm-bolt %t.exe -o %t.out -lite=0 -v=1 2>&1 | FileCheck %s | ||
|
||
# CHECK-NOT: unclaimed PC-relative relocations left in data | ||
# CHECK: BOLT-INFO: marking main.cold.1 as a fragment of main | ||
.text | ||
.globl main | ||
.type main, %function | ||
.p2align 2 | ||
main: | ||
LBB0: | ||
andl $0xf, %ecx | ||
cmpb $0x4, %cl | ||
# exit through abort in main.cold.1, registers cold fragment the regular way | ||
ja main.cold.1 | ||
|
||
# jump table dispatch, jumping to label indexed by val in %ecx | ||
LBB1: | ||
leaq JUMP_TABLE(%rip), %r8 | ||
movzbl %cl, %ecx | ||
movq (%r8,%rcx,8), %rax | ||
addq %r8, %rax | ||
jmpq *%rax | ||
|
||
LBB2: | ||
xorq %rax, %rax | ||
LBB3: | ||
addq $0x8, %rsp | ||
ret | ||
.size main, .-main | ||
|
||
.globl main.cold.1 | ||
.type main.cold.1, %function | ||
.p2align 2 | ||
main.cold.1: | ||
# load bearing nop: pad LBB4 so that it can't be treated | ||
# as __builtin_unreachable by analyzeJumpTable | ||
nop | ||
LBB4: | ||
callq abort | ||
.size main.cold.1, .-main.cold.1 | ||
|
||
.rodata | ||
# jmp table, entries must be R_X86_64_PC32 relocs | ||
.globl JUMP_TABLE | ||
JUMP_TABLE: | ||
.quad LBB2-JUMP_TABLE | ||
.quad LBB3-JUMP_TABLE | ||
.quad LBB4-JUMP_TABLE | ||
.quad LBB3-JUMP_TABLE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# This reproduces a bug with jump table identification where jump table has | ||
# entries pointing to code in function and its cold fragment. | ||
# The fragment is only reachable through jump table. | ||
|
||
# REQUIRES: system-linux | ||
|
||
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o | ||
# RUN: strip --strip-unneeded %t.o | ||
# RUN: %host_cc %t.o -o %t.exe -Wl,-q | ||
# RUN: llvm-bolt %t.exe -o %t.out -lite=0 -v=1 2>&1 | FileCheck %s | ||
|
||
# CHECK-NOT: unclaimed PC-relative relocations left in data | ||
# CHECK: BOLT-INFO: marking main.cold.1 as a fragment of main | ||
.text | ||
.globl main | ||
.type main, %function | ||
.p2align 2 | ||
main: | ||
LBB0: | ||
andl $0xf, %ecx | ||
cmpb $0x4, %cl | ||
# exit through ret | ||
ja LBB3 | ||
|
||
# jump table dispatch, jumping to label indexed by val in %ecx | ||
LBB1: | ||
leaq JUMP_TABLE(%rip), %r8 | ||
movzbl %cl, %ecx | ||
movslq (%r8,%rcx,4), %rax | ||
addq %rax, %r8 | ||
jmpq *%r8 | ||
|
||
LBB2: | ||
xorq %rax, %rax | ||
LBB3: | ||
addq $0x8, %rsp | ||
ret | ||
.size main, .-main | ||
|
||
# cold fragment is only reachable through jump table | ||
.globl main.cold.1 | ||
.type main.cold.1, %function | ||
.p2align 2 | ||
main.cold.1: | ||
# load bearing nop: pad LBB4 so that it can't be treated | ||
# as __builtin_unreachable by analyzeJumpTable | ||
nop | ||
LBB4: | ||
callq abort | ||
.size main.cold.1, .-main.cold.1 | ||
|
||
.rodata | ||
# jmp table, entries must be R_X86_64_PC32 relocs | ||
.globl JUMP_TABLE | ||
JUMP_TABLE: | ||
.long LBB2-JUMP_TABLE | ||
.long LBB3-JUMP_TABLE | ||
.long LBB4-JUMP_TABLE | ||
.long LBB3-JUMP_TABLE |