1 //===-- Implementation of longjmp -----------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "src/setjmp/longjmp.h" 10 #include "include/llvm-libc-macros/offsetof-macro.h" 11 #include "src/__support/common.h" 12 #include "src/__support/macros/config.h" 13 14 #if !defined(LIBC_TARGET_ARCH_IS_X86) 15 #error "Invalid file include" 16 #endif 17 18 namespace LIBC_NAMESPACE_DECL { 19 20 #ifdef __i386__ 21 [[gnu::naked]] 22 LLVM_LIBC_FUNCTION(void, longjmp, (jmp_buf, int)) { 23 asm(R"( 24 mov 0x4(%%esp), %%ecx 25 mov 0x8(%%esp), %%eax 26 cmpl $0x1, %%eax 27 adcl $0x0, %%eax 28 29 mov %c[ebx](%%ecx), %%ebx 30 mov %c[esi](%%ecx), %%esi 31 mov %c[edi](%%ecx), %%edi 32 mov %c[ebp](%%ecx), %%ebp 33 mov %c[esp](%%ecx), %%esp 34 35 jmp *%c[eip](%%ecx) 36 )" ::[ebx] "i"(offsetof(__jmp_buf, ebx)), 37 [esi] "i"(offsetof(__jmp_buf, esi)), [edi] "i"(offsetof(__jmp_buf, edi)), 38 [ebp] "i"(offsetof(__jmp_buf, ebp)), [esp] "i"(offsetof(__jmp_buf, esp)), 39 [eip] "i"(offsetof(__jmp_buf, eip))); 40 } 41 #else 42 [[gnu::naked]] 43 LLVM_LIBC_FUNCTION(void, longjmp, (jmp_buf, int)) { 44 asm(R"( 45 cmpl $0x1, %%esi 46 adcl $0x0, %%esi 47 movq %%rsi, %%rax 48 49 movq %c[rbx](%%rdi), %%rbx 50 movq %c[rbp](%%rdi), %%rbp 51 movq %c[r12](%%rdi), %%r12 52 movq %c[r13](%%rdi), %%r13 53 movq %c[r14](%%rdi), %%r14 54 movq %c[r15](%%rdi), %%r15 55 movq %c[rsp](%%rdi), %%rsp 56 jmpq *%c[rip](%%rdi) 57 )" ::[rbx] "i"(offsetof(__jmp_buf, rbx)), 58 [rbp] "i"(offsetof(__jmp_buf, rbp)), [r12] "i"(offsetof(__jmp_buf, r12)), 59 [r13] "i"(offsetof(__jmp_buf, r13)), [r14] "i"(offsetof(__jmp_buf, r14)), 60 [r15] "i"(offsetof(__jmp_buf, r15)), [rsp] "i"(offsetof(__jmp_buf, rsp)), 61 [rip] "i"(offsetof(__jmp_buf, rip))); 62 } 63 #endif 64 65 } // namespace LIBC_NAMESPACE_DECL 66