Skip to content

Commit 9d5411f

Browse files
authored
[BOLT] Avoid reference updates for non-JT symbol operands (#88838)
Skip updating references for operands that do not directly refer to jump table symbols but fall within a jump table's address range to prevent unintended modifications.
1 parent b329179 commit 9d5411f

File tree

2 files changed

+64
-4
lines changed

2 files changed

+64
-4
lines changed

bolt/lib/Passes/ValidateMemRefs.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ bool ValidateMemRefs::checkAndFixJTReference(BinaryFunction &BF, MCInst &Inst,
2929
if (!BD)
3030
return false;
3131

32-
const uint64_t TargetAddress = BD->getAddress() + Offset;
33-
JumpTable *JT = BC.getJumpTableContainingAddress(TargetAddress);
32+
JumpTable *JT = BC.getJumpTableContainingAddress(BD->getAddress());
3433
if (!JT)
3534
return false;
3635

@@ -43,8 +42,9 @@ bool ValidateMemRefs::checkAndFixJTReference(BinaryFunction &BF, MCInst &Inst,
4342
// the jump table label with a regular rodata reference. Get a
4443
// non-JT reference by fetching the symbol 1 byte before the JT
4544
// label.
46-
MCSymbol *NewSym = BC.getOrCreateGlobalSymbol(TargetAddress - 1, "DATAat");
47-
BC.MIB->setOperandToSymbolRef(Inst, OperandNum, NewSym, 1, &*BC.Ctx, 0);
45+
MCSymbol *NewSym = BC.getOrCreateGlobalSymbol(BD->getAddress() - 1, "DATAat");
46+
BC.MIB->setOperandToSymbolRef(Inst, OperandNum, NewSym, Offset + 1, &*BC.Ctx,
47+
0);
4848
LLVM_DEBUG(dbgs() << "BOLT-DEBUG: replaced reference @" << BF.getPrintName()
4949
<< " from " << BD->getName() << " to " << NewSym->getName()
5050
<< " + 1\n");
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# If the operand references a symbol that differs from the jump table label,
2+
# no reference updating is required even if its target address resides within
3+
# the jump table's range.
4+
# In this test case, consider the second instruction within the main function,
5+
# where the address resulting from 'c + 17' corresponds to one byte beyond the
6+
# address of the .LJTI2_0 jump table label. However, this operand represents
7+
# an offset calculation related to the global variable 'c' and should remain
8+
# unaffected by the jump table.
9+
10+
# REQUIRES: system-linux
11+
12+
13+
# RUN: %clang -no-pie %s -o %t.exe -Wl,-q
14+
15+
# RUN: %t.exe
16+
# RUN: llvm-bolt -funcs=main,foo/1 %t.exe -o %t.exe.bolt -jump-tables=move
17+
# RUN: %t.exe.bolt
18+
19+
.text
20+
.globl main
21+
.type main,@function
22+
main:
23+
pushq %rbp
24+
movq %rsp, %rbp
25+
movq $-16, %rax
26+
movl c+17(%rax), %edx
27+
cmpl $255, %edx
28+
je .LCorrect
29+
movl $1, %eax
30+
popq %rbp
31+
ret
32+
.LCorrect:
33+
movl $0, %eax
34+
popq %rbp
35+
ret
36+
.p2align 4, 0x90
37+
.type foo,@function
38+
foo:
39+
movq $0, %rax
40+
jmpq *.LJTI2_0(,%rax,8)
41+
addl $-36, %eax
42+
.LBB2_2:
43+
addl $-16, %eax
44+
retq
45+
.section .rodata,"a",@progbits
46+
.type c,@object
47+
.data
48+
.globl c
49+
.p2align 4, 0x0
50+
c:
51+
.byte 1
52+
.byte 0xff
53+
.zero 14
54+
.size c, 16
55+
.LJTI2_0:
56+
.quad .LBB2_2
57+
.quad .LBB2_2
58+
.quad .LBB2_2
59+
.quad .LBB2_2
60+

0 commit comments

Comments
 (0)