• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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