|
7 | 7 | //===----------------------------------------------------------------------===// |
8 | 8 |
|
9 | 9 | #include "src/setjmp/longjmp.h" |
| 10 | +#include "include/llvm-libc-macros/offsetof-macro.h" |
10 | 11 | #include "src/__support/common.h" |
11 | 12 | #include "src/__support/macros/config.h" |
12 | 13 |
|
|
16 | 17 |
|
17 | 18 | namespace LIBC_NAMESPACE_DECL { |
18 | 19 |
|
19 | | -LLVM_LIBC_FUNCTION(void, longjmp, (jmp_buf buf, int val)) { |
20 | | - register __UINT64_TYPE__ rbx __asm__("rbx"); |
21 | | - register __UINT64_TYPE__ rbp __asm__("rbp"); |
22 | | - register __UINT64_TYPE__ r12 __asm__("r12"); |
23 | | - register __UINT64_TYPE__ r13 __asm__("r13"); |
24 | | - register __UINT64_TYPE__ r14 __asm__("r14"); |
25 | | - register __UINT64_TYPE__ r15 __asm__("r15"); |
26 | | - register __UINT64_TYPE__ rsp __asm__("rsp"); |
27 | | - register __UINT64_TYPE__ rax __asm__("rax"); |
| 20 | +[[gnu::naked]] |
| 21 | +LLVM_LIBC_FUNCTION(void, longjmp, (jmp_buf, int)) { |
| 22 | + asm(R"( |
| 23 | + cmpl $0x1, %%esi |
| 24 | + adcl $0x0, %%esi |
| 25 | + movq %%rsi, %%rax |
28 | 26 |
|
29 | | - // ABI requires that the return value should be stored in rax. So, we store |
30 | | - // |val| in rax. Note that this has to happen before we restore the registers |
31 | | - // from values in |buf|. Otherwise, once rsp and rbp are updated, we cannot |
32 | | - // read |val|. |
33 | | - val = val == 0 ? 1 : val; |
34 | | - LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(rax) : "m"(val) :); |
35 | | - LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(rbx) : "m"(buf->rbx) :); |
36 | | - LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(rbp) : "m"(buf->rbp) :); |
37 | | - LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(r12) : "m"(buf->r12) :); |
38 | | - LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(r13) : "m"(buf->r13) :); |
39 | | - LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(r14) : "m"(buf->r14) :); |
40 | | - LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(r15) : "m"(buf->r15) :); |
41 | | - LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(rsp) : "m"(buf->rsp) :); |
42 | | - LIBC_INLINE_ASM("jmp *%0\n\t" : : "m"(buf->rip)); |
| 27 | + movq %c[rbx](%%rdi), %%rbx |
| 28 | + movq %c[rbp](%%rdi), %%rbp |
| 29 | + movq %c[r12](%%rdi), %%r12 |
| 30 | + movq %c[r13](%%rdi), %%r13 |
| 31 | + movq %c[r14](%%rdi), %%r14 |
| 32 | + movq %c[r15](%%rdi), %%r15 |
| 33 | + movq %c[rsp](%%rdi), %%rsp |
| 34 | + jmpq *%c[rip](%%rdi) |
| 35 | + )" :: |
| 36 | + [rbx] "i"(offsetof(__jmp_buf, rbx)), |
| 37 | + [rbp] "i"(offsetof(__jmp_buf, rbp)), |
| 38 | + [r12] "i"(offsetof(__jmp_buf, r12)), |
| 39 | + [r13] "i"(offsetof(__jmp_buf, r13)), |
| 40 | + [r14] "i"(offsetof(__jmp_buf, r14)), |
| 41 | + [r15] "i"(offsetof(__jmp_buf, r15)), |
| 42 | + [rsp] "i"(offsetof(__jmp_buf, rsp)), |
| 43 | + [rip] "i"(offsetof(__jmp_buf, rip)) |
| 44 | +); |
43 | 45 | } |
44 | 46 |
|
45 | 47 | } // namespace LIBC_NAMESPACE_DECL |
0 commit comments