Skip to content

Commit 1de305d

Browse files
aaupovtru
authored andcommitted
[BOLT][Instrumentation] Preserve red zone for functions with tail calls only
Allow a function with tail calls only to clobber its red zone. Fixes #61114. Reviewed By: #bolt, yota9 Differential Revision: https://reviews.llvm.org/D145202 (cherry picked from commit 1e1dfbb)
1 parent 5cdefb4 commit 1de305d

File tree

2 files changed

+58
-6
lines changed

2 files changed

+58
-6
lines changed

bolt/lib/Passes/Instrumentation.cpp

+7-6
Original file line numberDiff line numberDiff line change
@@ -360,12 +360,13 @@ void Instrumentation::instrumentFunction(BinaryFunction &Function,
360360
// instructions to protect the red zone
361361
bool IsLeafFunction = true;
362362
DenseSet<const BinaryBasicBlock *> InvokeBlocks;
363-
for (auto BBI = Function.begin(), BBE = Function.end(); BBI != BBE; ++BBI) {
364-
for (auto I = BBI->begin(), E = BBI->end(); I != E; ++I) {
365-
if (BC.MIB->isCall(*I)) {
366-
if (BC.MIB->isInvoke(*I))
367-
InvokeBlocks.insert(&*BBI);
368-
IsLeafFunction = false;
363+
for (const BinaryBasicBlock &BB : Function) {
364+
for (const MCInst &Inst : BB) {
365+
if (BC.MIB->isCall(Inst)) {
366+
if (BC.MIB->isInvoke(Inst))
367+
InvokeBlocks.insert(&BB);
368+
if (!BC.MIB->isTailCall(Inst))
369+
IsLeafFunction = false;
369370
}
370371
}
371372
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# This reproduces a bug with instrumentation when trying to instrument
2+
# a function with only tail calls. Such functions can clobber red zone,
3+
# see https://github.com/llvm/llvm-project/issues/61114.
4+
5+
# REQUIRES: system-linux,bolt-runtime
6+
7+
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o
8+
# RUN: %clang %cflags -no-pie %t.o -o %t.exe -Wl,-q
9+
10+
# RUN: llvm-bolt %t.exe --instrument --instrumentation-file=%t.fdata \
11+
# RUN: -o %t.instrumented
12+
# RUN: %t.instrumented arg1 arg2
13+
# RUN: llvm-objdump %t.instrumented --disassemble-symbols=main | FileCheck %s
14+
15+
# CHECK: leaq 0x80(%rsp), %rsp
16+
17+
.text
18+
.globl main
19+
.type main, %function
20+
.p2align 4
21+
main:
22+
pushq %rbp
23+
movq %rsp, %rbp
24+
mov %rax,-0x10(%rsp)
25+
leaq targetFunc, %rax
26+
pushq %rax # We save the target function address in the stack
27+
subq $0x18, %rsp # Set up a dummy stack frame
28+
cmpl $0x2, %edi
29+
jb .LBBerror # Add control flow so we don't have a trivial case
30+
.LBB2:
31+
addq $0x20, %rsp
32+
movq %rbp, %rsp
33+
pop %rbp
34+
mov -0x10(%rsp),%rax
35+
jmp targetFunc
36+
37+
.LBBerror:
38+
addq $0x20, %rsp
39+
movq %rbp, %rsp
40+
pop %rbp
41+
movq $1, %rax # Finish with an error if we go this path
42+
retq
43+
.size main, .-main
44+
45+
.globl targetFunc
46+
.type targetFunc, %function
47+
.p2align 4
48+
targetFunc:
49+
xorq %rax, %rax
50+
retq
51+
.size targetFunc, .-targetFunc

0 commit comments

Comments
 (0)