forked from OSchip/llvm-project
[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
This commit is contained in:
parent
0b460e6bf8
commit
0d86810158
|
@ -61,6 +61,7 @@ extern "C" {
|
|||
// basis. See xray_trampoline_*.S files for implementations.
|
||||
extern void __xray_FunctionEntry();
|
||||
extern void __xray_FunctionExit();
|
||||
extern void __xray_FunctionTailExit();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -110,3 +110,63 @@ __xray_FunctionExit:
|
|||
.Ltmp3:
|
||||
.size __xray_FunctionExit, .Ltmp3-__xray_FunctionExit
|
||||
.cfi_endproc
|
||||
|
||||
.global __xray_FunctionTailExit
|
||||
.align 16, 0x90
|
||||
.type __xray_FunctionTailExit,@function
|
||||
__xray_FunctionTailExit:
|
||||
.cfi_startproc
|
||||
// Save the important registers as in the entry trampoline, but indicate that
|
||||
// this is an exit. In the future, we will introduce a new entry type that
|
||||
// differentiates between a normal exit and a tail exit, but we'd have to do
|
||||
// this and increment the version number for the header.
|
||||
pushq %rbp
|
||||
.cfi_def_cfa_offset 16
|
||||
subq $200, %rsp
|
||||
movupd %xmm0, 184(%rsp)
|
||||
movupd %xmm1, 168(%rsp)
|
||||
movupd %xmm2, 152(%rsp)
|
||||
movupd %xmm3, 136(%rsp)
|
||||
movupd %xmm4, 120(%rsp)
|
||||
movupd %xmm5, 104(%rsp)
|
||||
movupd %xmm6, 88(%rsp)
|
||||
movupd %xmm7, 72(%rsp)
|
||||
movq %rdi, 64(%rsp)
|
||||
movq %rax, 56(%rsp)
|
||||
movq %rdx, 48(%rsp)
|
||||
movq %rsi, 40(%rsp)
|
||||
movq %rcx, 32(%rsp)
|
||||
movq %r8, 24(%rsp)
|
||||
movq %r9, 16(%rsp)
|
||||
|
||||
movq _ZN6__xray19XRayPatchedFunctionE(%rip), %rax
|
||||
testq %rax,%rax
|
||||
je .Ltmp4
|
||||
|
||||
movl %r10d, %edi
|
||||
movl $1, %esi
|
||||
callq *%rax
|
||||
|
||||
.Ltmp4:
|
||||
// Restore the registers.
|
||||
movupd 184(%rsp), %xmm0
|
||||
movupd 168(%rsp), %xmm1
|
||||
movupd 152(%rsp), %xmm2
|
||||
movupd 136(%rsp), %xmm3
|
||||
movupd 120(%rsp), %xmm4
|
||||
movupd 104(%rsp), %xmm5
|
||||
movupd 88(%rsp) , %xmm6
|
||||
movupd 72(%rsp) , %xmm7
|
||||
movq 64(%rsp), %rdi
|
||||
movq 56(%rsp), %rax
|
||||
movq 48(%rsp), %rdx
|
||||
movq 40(%rsp), %rsi
|
||||
movq 32(%rsp), %rcx
|
||||
movq 24(%rsp), %r8
|
||||
movq 16(%rsp), %r9
|
||||
addq $200, %rsp
|
||||
popq %rbp
|
||||
retq
|
||||
.Ltmp5:
|
||||
.size __xray_FunctionTailExit, .Ltmp5-__xray_FunctionTailExit
|
||||
.cfi_endproc
|
||||
|
|
|
@ -114,13 +114,10 @@ bool patchFunctionExit(const bool Enable, const uint32_t FuncId,
|
|||
bool patchFunctionTailExit(const bool Enable, const uint32_t FuncId,
|
||||
const XRaySledEntry &Sled) {
|
||||
// Here we do the dance of replacing the tail call sled with a similar
|
||||
// sequence as the entry sled, but calls the exit sled instead, so we can
|
||||
// treat tail call exits as if they were normal exits.
|
||||
//
|
||||
// FIXME: In the future we'd need to distinguish between non-tail exits and
|
||||
// tail exits for better information preservation.
|
||||
int64_t TrampolineOffset = reinterpret_cast<int64_t>(__xray_FunctionExit) -
|
||||
(static_cast<int64_t>(Sled.Address) + 11);
|
||||
// sequence as the entry sled, but calls the tail exit sled instead.
|
||||
int64_t TrampolineOffset =
|
||||
reinterpret_cast<int64_t>(__xray_FunctionTailExit) -
|
||||
(static_cast<int64_t>(Sled.Address) + 11);
|
||||
if (TrampolineOffset < MinOffset || TrampolineOffset > MaxOffset) {
|
||||
Report("XRay Exit trampoline (%p) too far from sled (%p); distance = "
|
||||
"%ld\n",
|
||||
|
|
Loading…
Reference in New Issue