1//===-- xray_trampoline_x86.s -----------------------------------*- ASM -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file is a part of XRay, a dynamic runtime instrumentation system. 11// 12// This implements the X86-specific assembler for the trampolines. 13// 14//===----------------------------------------------------------------------===// 15 16#include "../builtins/assembly.h" 17#include "../sanitizer_common/sanitizer_asm.h" 18 19 20 21.macro SAVE_REGISTERS 22 pushfq 23 subq $240, %rsp 24 CFI_DEF_CFA_OFFSET(248) 25 movq %rbp, 232(%rsp) 26 movupd %xmm0, 216(%rsp) 27 movupd %xmm1, 200(%rsp) 28 movupd %xmm2, 184(%rsp) 29 movupd %xmm3, 168(%rsp) 30 movupd %xmm4, 152(%rsp) 31 movupd %xmm5, 136(%rsp) 32 movupd %xmm6, 120(%rsp) 33 movupd %xmm7, 104(%rsp) 34 movq %rdi, 96(%rsp) 35 movq %rax, 88(%rsp) 36 movq %rdx, 80(%rsp) 37 movq %rsi, 72(%rsp) 38 movq %rcx, 64(%rsp) 39 movq %r8, 56(%rsp) 40 movq %r9, 48(%rsp) 41 movq %r10, 40(%rsp) 42 movq %r11, 32(%rsp) 43 movq %r12, 24(%rsp) 44 movq %r13, 16(%rsp) 45 movq %r14, 8(%rsp) 46 movq %r15, 0(%rsp) 47.endm 48 49.macro RESTORE_REGISTERS 50 movq 232(%rsp), %rbp 51 movupd 216(%rsp), %xmm0 52 movupd 200(%rsp), %xmm1 53 movupd 184(%rsp), %xmm2 54 movupd 168(%rsp), %xmm3 55 movupd 152(%rsp), %xmm4 56 movupd 136(%rsp), %xmm5 57 movupd 120(%rsp) , %xmm6 58 movupd 104(%rsp) , %xmm7 59 movq 96(%rsp), %rdi 60 movq 88(%rsp), %rax 61 movq 80(%rsp), %rdx 62 movq 72(%rsp), %rsi 63 movq 64(%rsp), %rcx 64 movq 56(%rsp), %r8 65 movq 48(%rsp), %r9 66 movq 40(%rsp), %r10 67 movq 32(%rsp), %r11 68 movq 24(%rsp), %r12 69 movq 16(%rsp), %r13 70 movq 8(%rsp), %r14 71 movq 0(%rsp), %r15 72 addq $240, %rsp 73 popfq 74 CFI_DEF_CFA_OFFSET(8) 75.endm 76 77.macro ALIGNED_CALL_RAX 78 // Call the logging handler, after aligning the stack to a 16-byte boundary. 79 // The approach we're taking here uses additional stack space to stash the 80 // stack pointer twice before aligning the pointer to 16-bytes. If the stack 81 // was 8-byte aligned, it will become 16-byte aligned -- when restoring the 82 // pointer, we can always look -8 bytes from the current position to get 83 // either of the values we've stashed in the first place. 84 pushq %rsp 85 pushq (%rsp) 86 andq $-0x10, %rsp 87 callq *%rax 88 movq 8(%rsp), %rsp 89.endm 90 91 .text 92#if !defined(__APPLE__) 93 .section .text 94 .file "xray_trampoline_x86.S" 95#else 96 .section __TEXT,__text 97#endif 98 99//===----------------------------------------------------------------------===// 100 101 .globl ASM_SYMBOL(__xray_FunctionEntry) 102 .align 16, 0x90 103 ASM_TYPE_FUNCTION(__xray_FunctionEntry) 104# LLVM-MCA-BEGIN __xray_FunctionEntry 105ASM_SYMBOL(__xray_FunctionEntry): 106 CFI_STARTPROC 107 SAVE_REGISTERS 108 109 // This load has to be atomic, it's concurrent with __xray_patch(). 110 // On x86/amd64, a simple (type-aligned) MOV instruction is enough. 111 movq ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax 112 testq %rax, %rax 113 je .Ltmp0 114 115 // The patched function prologue puts its xray_instr_map index into %r10d. 116 movl %r10d, %edi 117 xor %esi,%esi 118 ALIGNED_CALL_RAX 119 120.Ltmp0: 121 RESTORE_REGISTERS 122 retq 123# LLVM-MCA-END 124 ASM_SIZE(__xray_FunctionEntry) 125 CFI_ENDPROC 126 127//===----------------------------------------------------------------------===// 128 129 .globl ASM_SYMBOL(__xray_FunctionExit) 130 .align 16, 0x90 131 ASM_TYPE_FUNCTION(__xray_FunctionExit) 132# LLVM-MCA-BEGIN __xray_FunctionExit 133ASM_SYMBOL(__xray_FunctionExit): 134 CFI_STARTPROC 135 // Save the important registers first. Since we're assuming that this 136 // function is only jumped into, we only preserve the registers for 137 // returning. 138 subq $56, %rsp 139 CFI_DEF_CFA_OFFSET(64) 140 movq %rbp, 48(%rsp) 141 movupd %xmm0, 32(%rsp) 142 movupd %xmm1, 16(%rsp) 143 movq %rax, 8(%rsp) 144 movq %rdx, 0(%rsp) 145 movq ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax 146 testq %rax,%rax 147 je .Ltmp2 148 149 movl %r10d, %edi 150 movl $1, %esi 151 ALIGNED_CALL_RAX 152 153.Ltmp2: 154 // Restore the important registers. 155 movq 48(%rsp), %rbp 156 movupd 32(%rsp), %xmm0 157 movupd 16(%rsp), %xmm1 158 movq 8(%rsp), %rax 159 movq 0(%rsp), %rdx 160 addq $56, %rsp 161 CFI_DEF_CFA_OFFSET(8) 162 retq 163# LLVM-MCA-END 164 ASM_SIZE(__xray_FunctionExit) 165 CFI_ENDPROC 166 167//===----------------------------------------------------------------------===// 168 169 .globl ASM_SYMBOL(__xray_FunctionTailExit) 170 .align 16, 0x90 171 ASM_TYPE_FUNCTION(__xray_FunctionTailExit) 172# LLVM-MCA-BEGIN __xray_FunctionTailExit 173ASM_SYMBOL(__xray_FunctionTailExit): 174 CFI_STARTPROC 175 SAVE_REGISTERS 176 177 movq ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax 178 testq %rax,%rax 179 je .Ltmp4 180 181 movl %r10d, %edi 182 movl $2, %esi 183 184 ALIGNED_CALL_RAX 185 186.Ltmp4: 187 RESTORE_REGISTERS 188 retq 189# LLVM-MCA-END 190 ASM_SIZE(__xray_FunctionTailExit) 191 CFI_ENDPROC 192 193//===----------------------------------------------------------------------===// 194 195 .globl ASM_SYMBOL(__xray_ArgLoggerEntry) 196 .align 16, 0x90 197 ASM_TYPE_FUNCTION(__xray_ArgLoggerEntry) 198# LLVM-MCA-BEGIN __xray_ArgLoggerEntry 199ASM_SYMBOL(__xray_ArgLoggerEntry): 200 CFI_STARTPROC 201 SAVE_REGISTERS 202 203 // Again, these function pointer loads must be atomic; MOV is fine. 204 movq ASM_SYMBOL(_ZN6__xray13XRayArgLoggerE)(%rip), %rax 205 testq %rax, %rax 206 jne .Larg1entryLog 207 208 // If [arg1 logging handler] not set, defer to no-arg logging. 209 movq ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE)(%rip), %rax 210 testq %rax, %rax 211 je .Larg1entryFail 212 213.Larg1entryLog: 214 215 // First argument will become the third 216 movq %rdi, %rdx 217 218 // XRayEntryType::LOG_ARGS_ENTRY into the second 219 mov $0x3, %esi 220 221 // 32-bit function ID becomes the first 222 movl %r10d, %edi 223 ALIGNED_CALL_RAX 224 225.Larg1entryFail: 226 RESTORE_REGISTERS 227 retq 228# LLVM-MCA-END 229 ASM_SIZE(__xray_ArgLoggerEntry) 230 CFI_ENDPROC 231 232//===----------------------------------------------------------------------===// 233 234 .global ASM_SYMBOL(__xray_CustomEvent) 235 .align 16, 0x90 236 ASM_TYPE_FUNCTION(__xray_CustomEvent) 237# LLVM-MCA-BEGIN __xray_CustomEvent 238ASM_SYMBOL(__xray_CustomEvent): 239 CFI_STARTPROC 240 SAVE_REGISTERS 241 242 // We take two arguments to this trampoline, which should be in rdi and rsi 243 // already. 244 movq ASM_SYMBOL(_ZN6__xray22XRayPatchedCustomEventE)(%rip), %rax 245 testq %rax,%rax 246 je .LcustomEventCleanup 247 248 ALIGNED_CALL_RAX 249 250.LcustomEventCleanup: 251 RESTORE_REGISTERS 252 retq 253# LLVM-MCA-END 254 ASM_SIZE(__xray_CustomEvent) 255 CFI_ENDPROC 256 257//===----------------------------------------------------------------------===// 258 259 .global ASM_SYMBOL(__xray_TypedEvent) 260 .align 16, 0x90 261 ASM_TYPE_FUNCTION(__xray_TypedEvent) 262# LLVM-MCA-BEGIN __xray_TypedEvent 263ASM_SYMBOL(__xray_TypedEvent): 264 CFI_STARTPROC 265 SAVE_REGISTERS 266 267 // We pass three arguments to this trampoline, which should be in rdi, rsi 268 // and rdx without our intervention. 269 movq ASM_SYMBOL(_ZN6__xray21XRayPatchedTypedEventE)(%rip), %rax 270 testq %rax,%rax 271 je .LtypedEventCleanup 272 273 ALIGNED_CALL_RAX 274 275.LtypedEventCleanup: 276 RESTORE_REGISTERS 277 retq 278# LLVM-MCA-END 279 ASM_SIZE(__xray_TypedEvent) 280 CFI_ENDPROC 281 282//===----------------------------------------------------------------------===// 283 284NO_EXEC_STACK_DIRECTIVE 285