|
6 | 6 | // |
7 | 7 | //===----------------------------------------------------------------------===// |
8 | 8 |
|
| 9 | +#include "include/llvm-libc-macros/offsetof-macro.h" |
9 | 10 | #include "src/__support/common.h" |
10 | 11 | #include "src/setjmp/setjmp_impl.h" |
11 | 12 |
|
|
15 | 16 |
|
16 | 17 | namespace LIBC_NAMESPACE { |
17 | 18 |
|
| 19 | +__attribute__((naked)) |
18 | 20 | LLVM_LIBC_FUNCTION(int, setjmp, (__jmp_buf * buf)) { |
19 | | - asm("mov %%rbx, %[rbx]\n\t" |
20 | | - "mov %%r12, %[r12]\n\t" |
21 | | - "mov %%r13, %[r13]\n\t" |
22 | | - "mov %%r14, %[r14]\n\t" |
23 | | - "mov %%r15, %[r15]" |
24 | | - : [rbx] "=m"(buf->rbx), [r12] "=m"(buf->r12), [r13] "=m"(buf->r13), |
25 | | - [r14] "=m"(buf->r14), [r15] "=m"(buf->r15)); |
26 | | - |
27 | | - // We want the rbp of the caller, which is what __builtin_frame_address(1) |
28 | | - // should return. But, compilers generate a warning that calling |
29 | | - // __builtin_frame_address with non-zero argument is unsafe. So, we use |
30 | | - // the knowledge of the x86_64 ABI to fetch the callers rbp. As per the ABI, |
31 | | - // the rbp of the caller is pushed on to the stack and then new top is saved |
32 | | - // in this function's rbp. So, we fetch it from location at which this |
33 | | - // functions's rbp is pointing. |
34 | | - buf->rbp = *reinterpret_cast<__UINTPTR_TYPE__ *>(__builtin_frame_address(0)); |
35 | | - |
36 | | - // The callers stack address is exactly 2 pointer widths ahead of the current |
37 | | - // frame pointer - between the current frame pointer and the rsp of the caller |
38 | | - // are the return address (pushed by the x86_64 call instruction) and the |
39 | | - // previous stack pointer as required by the x86_64 ABI. |
40 | | - // The stack pointer is ahead because the stack grows down on x86_64. |
41 | | - buf->rsp = reinterpret_cast<__UINTPTR_TYPE__>(__builtin_frame_address(0)) + |
42 | | - sizeof(__UINTPTR_TYPE__) * 2; |
43 | | - buf->rip = reinterpret_cast<__UINTPTR_TYPE__>(__builtin_return_address(0)); |
44 | | - return 0; |
| 21 | + asm("mov %%rbx, %c[rbx](%%rdi)\n\t" |
| 22 | + "mov %%rbp, %c[rbp](%%rdi)\n\t" |
| 23 | + "mov %%r12, %c[r12](%%rdi)\n\t" |
| 24 | + "mov %%r13, %c[r13](%%rdi)\n\t" |
| 25 | + "mov %%r14, %c[r14](%%rdi)\n\t" |
| 26 | + "mov %%r15, %c[r15](%%rdi)\n\t" |
| 27 | + |
| 28 | + "lea 8(%%rsp), %%rax\n\t" |
| 29 | + "mov %%rax, %c[rsp](%%rdi)\n\t" |
| 30 | + |
| 31 | + "mov %[read_rip], %c[rip](%%rdi)\n\t" |
| 32 | + |
| 33 | + "xorl %%eax, %%eax\n\t" |
| 34 | + "retq" |
| 35 | + :: |
| 36 | + [rbx] "i"(offsetof(__jmp_buf, rbx)), [r12] "i"(offsetof(__jmp_buf, r12)), |
| 37 | + [r13] "i"(offsetof(__jmp_buf, r13)), [r14] "i"(offsetof(__jmp_buf, r14)), |
| 38 | + [r15] "i"(offsetof(__jmp_buf, r15)), [rbp] "i"(offsetof(__jmp_buf, rbp)), |
| 39 | + [rsp] "i"(offsetof(__jmp_buf, rsp)), [rip] "i"(offsetof(__jmp_buf, rip)), |
| 40 | + [read_rip] "r" (reinterpret_cast<__UINTPTR_TYPE__>(__builtin_return_address(0))) |
| 41 | + : "rax"); |
45 | 42 | } |
46 | 43 |
|
47 | 44 | } // namespace LIBC_NAMESPACE |
0 commit comments