1 // Copyright 2020 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Push all callee-saved registers to get them on the stack for conservative 6 // stack scanning. 7 // 8 // We cannot rely on clang generating the function and right symbol mangling 9 // as `__attribite__((naked))` does not prevent clang from generating TSAN 10 // function entry stubs (`__tsan_func_entry`). Even with 11 // `__attribute__((no_sanitize_thread)` annotation clang generates the entry 12 // stub. 13 // See https://bugs.llvm.org/show_bug.cgi?id=45400. 14 15 // Do not depend on V8_TARGET_OS_* defines as some embedders may override the 16 // GN toolchain (e.g. ChromeOS) and not provide them. 17 // _WIN64 Defined as 1 when the compilation target is 64-bit ARM or x64. 18 // Otherwise, undefined. 19 #ifdef _WIN64 20 21 // We maintain 16-byte alignment at calls. There is an 8-byte return address 22 // on the stack and we push 72 bytes which maintains 16-byte stack alignment 23 // at the call. 24 // Source: https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention 25 asm(".globl PushAllRegistersAndIterateStack \n" 26 "PushAllRegistersAndIterateStack: \n" 27 // rbp is callee-saved. Maintain proper frame pointer for debugging. 28 " push %rbp \n" 29 " mov %rsp, %rbp \n" 30 // Dummy for alignment. 31 " push $0xCDCDCD \n" 32 " push %rsi \n" 33 " push %rdi \n" 34 " push %rbx \n" 35 " push %r12 \n" 36 " push %r13 \n" 37 " push %r14 \n" 38 " push %r15 \n" 39 // Pass 1st parameter (rcx) unchanged (Stack*). 40 // Pass 2nd parameter (rdx) unchanged (StackVisitor*). 41 // Save 3rd parameter (r8; IterateStackCallback) 42 " mov %r8, %r9 \n" 43 // Pass 3rd parameter as rsp (stack pointer). 44 " mov %rsp, %r8 \n" 45 // Call the callback. 46 " call *%r9 \n" 47 // Pop the callee-saved registers. 48 " add $64, %rsp \n" 49 // Restore rbp as it was used as frame pointer. 50 " pop %rbp \n" 51 " ret \n"); 52 53 #else // !_WIN64 54 55 // We maintain 16-byte alignment at calls. There is an 8-byte return address 56 // on the stack and we push 56 bytes which maintains 16-byte stack alignment 57 // at the call. 58 // Source: https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf 59 asm( 60 #ifdef __APPLE__ 61 ".globl _PushAllRegistersAndIterateStack \n" 62 ".private_extern _PushAllRegistersAndIterateStack \n" 63 "_PushAllRegistersAndIterateStack: \n" 64 #else // !__APPLE__ 65 ".globl PushAllRegistersAndIterateStack \n" 66 ".type PushAllRegistersAndIterateStack, %function \n" 67 ".hidden PushAllRegistersAndIterateStack \n" 68 "PushAllRegistersAndIterateStack: \n" 69 #endif // !__APPLE__ 70 // rbp is callee-saved. Maintain proper frame pointer for debugging. 71 " push %rbp \n" 72 " mov %rsp, %rbp \n" 73 // Dummy for alignment. 74 " push $0xCDCDCD \n" 75 " push %rbx \n" 76 " push %r12 \n" 77 " push %r13 \n" 78 " push %r14 \n" 79 " push %r15 \n" 80 // Pass 1st parameter (rdi) unchanged (Stack*). 81 // Pass 2nd parameter (rsi) unchanged (StackVisitor*). 82 // Save 3rd parameter (rdx; IterateStackCallback) 83 " mov %rdx, %r8 \n" 84 // Pass 3rd parameter as rsp (stack pointer). 85 " mov %rsp, %rdx \n" 86 // Call the callback. 87 " call *%r8 \n" 88 // Pop the callee-saved registers. 89 " add $48, %rsp \n" 90 // Restore rbp as it was used as frame pointer. 91 " pop %rbp \n" 92 " ret \n"); 93 94 #endif // !_WIN64 95