Home | History | Annotate | Line # | Download | only in xray
      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
    105 ASM_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
    133 ASM_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
    173 ASM_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
    199 ASM_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
    238 ASM_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
    263 ASM_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 
    284 NO_EXEC_STACK_DIRECTIVE
    285