Skip to content

Commit 0d86810

Browse files
committedNov 2, 2016
[XRay][x86_64] Define a tail exit trampoline.
Summary: We define a new trampoline that's a hybrid between the exit and entry trampolines with the following properties: - Saves all of the callee-saved registers according to the x86_64 calling conventions. - Indicate to the log handler function being called that this is a function exit event. This fixes a bug that is a result of not saving enough of the register states, and that the log handler is clobbering registers that would be used by the function being tail-exited into manifesting as runtime errors. Reviewers: rSerge, echristo, majnemer Subscribers: mehdi_amini, llvm-commits Differential Revision: https://reviews.llvm.org/D26020 llvm-svn: 285787
1 parent 0b460e6 commit 0d86810

File tree

3 files changed

+65
-7
lines changed

3 files changed

+65
-7
lines changed
 

‎compiler-rt/lib/xray/xray_interface_internal.h

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ extern "C" {
6161
// basis. See xray_trampoline_*.S files for implementations.
6262
extern void __xray_FunctionEntry();
6363
extern void __xray_FunctionExit();
64+
extern void __xray_FunctionTailExit();
6465
}
6566

6667
#endif

‎compiler-rt/lib/xray/xray_trampoline_x86_64.S

+60
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,63 @@ __xray_FunctionExit:
110110
.Ltmp3:
111111
.size __xray_FunctionExit, .Ltmp3-__xray_FunctionExit
112112
.cfi_endproc
113+
114+
.global __xray_FunctionTailExit
115+
.align 16, 0x90
116+
.type __xray_FunctionTailExit,@function
117+
__xray_FunctionTailExit:
118+
.cfi_startproc
119+
// Save the important registers as in the entry trampoline, but indicate that
120+
// this is an exit. In the future, we will introduce a new entry type that
121+
// differentiates between a normal exit and a tail exit, but we'd have to do
122+
// this and increment the version number for the header.
123+
pushq %rbp
124+
.cfi_def_cfa_offset 16
125+
subq $200, %rsp
126+
movupd %xmm0, 184(%rsp)
127+
movupd %xmm1, 168(%rsp)
128+
movupd %xmm2, 152(%rsp)
129+
movupd %xmm3, 136(%rsp)
130+
movupd %xmm4, 120(%rsp)
131+
movupd %xmm5, 104(%rsp)
132+
movupd %xmm6, 88(%rsp)
133+
movupd %xmm7, 72(%rsp)
134+
movq %rdi, 64(%rsp)
135+
movq %rax, 56(%rsp)
136+
movq %rdx, 48(%rsp)
137+
movq %rsi, 40(%rsp)
138+
movq %rcx, 32(%rsp)
139+
movq %r8, 24(%rsp)
140+
movq %r9, 16(%rsp)
141+
142+
movq _ZN6__xray19XRayPatchedFunctionE(%rip), %rax
143+
testq %rax,%rax
144+
je .Ltmp4
145+
146+
movl %r10d, %edi
147+
movl $1, %esi
148+
callq *%rax
149+
150+
.Ltmp4:
151+
// Restore the registers.
152+
movupd 184(%rsp), %xmm0
153+
movupd 168(%rsp), %xmm1
154+
movupd 152(%rsp), %xmm2
155+
movupd 136(%rsp), %xmm3
156+
movupd 120(%rsp), %xmm4
157+
movupd 104(%rsp), %xmm5
158+
movupd 88(%rsp) , %xmm6
159+
movupd 72(%rsp) , %xmm7
160+
movq 64(%rsp), %rdi
161+
movq 56(%rsp), %rax
162+
movq 48(%rsp), %rdx
163+
movq 40(%rsp), %rsi
164+
movq 32(%rsp), %rcx
165+
movq 24(%rsp), %r8
166+
movq 16(%rsp), %r9
167+
addq $200, %rsp
168+
popq %rbp
169+
retq
170+
.Ltmp5:
171+
.size __xray_FunctionTailExit, .Ltmp5-__xray_FunctionTailExit
172+
.cfi_endproc

‎compiler-rt/lib/xray/xray_x86_64.cc

+4-7
Original file line numberDiff line numberDiff line change
@@ -114,13 +114,10 @@ bool patchFunctionExit(const bool Enable, const uint32_t FuncId,
114114
bool patchFunctionTailExit(const bool Enable, const uint32_t FuncId,
115115
const XRaySledEntry &Sled) {
116116
// Here we do the dance of replacing the tail call sled with a similar
117-
// sequence as the entry sled, but calls the exit sled instead, so we can
118-
// treat tail call exits as if they were normal exits.
119-
//
120-
// FIXME: In the future we'd need to distinguish between non-tail exits and
121-
// tail exits for better information preservation.
122-
int64_t TrampolineOffset = reinterpret_cast<int64_t>(__xray_FunctionExit) -
123-
(static_cast<int64_t>(Sled.Address) + 11);
117+
// sequence as the entry sled, but calls the tail exit sled instead.
118+
int64_t TrampolineOffset =
119+
reinterpret_cast<int64_t>(__xray_FunctionTailExit) -
120+
(static_cast<int64_t>(Sled.Address) + 11);
124121
if (TrampolineOffset < MinOffset || TrampolineOffset > MaxOffset) {
125122
Report("XRay Exit trampoline (%p) too far from sled (%p); distance = "
126123
"%ld\n",

0 commit comments

Comments
 (0)
Please sign in to comment.