70 lines · cpp
1//===-- Implementation of sigsetjmp ---------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "src/setjmp/sigsetjmp.h"10#include "hdr/offsetof_macros.h"11#include "src/__support/common.h"12#include "src/__support/macros/config.h"13#include "src/setjmp/setjmp_impl.h"14#include "src/setjmp/sigsetjmp_epilogue.h"15 16#if !defined(LIBC_TARGET_ARCH_IS_X86)17#error "Invalid file include"18#endif19namespace LIBC_NAMESPACE_DECL {20#ifdef __i386__21[[gnu::naked]]22LLVM_LIBC_FUNCTION(int, sigsetjmp, (sigjmp_buf buf)) {23 asm(R"(24 mov 8(%%esp), %%ecx25 jecxz .Lnosave26 27 mov 4(%%esp), %%eax28 pop %c[retaddr](%%eax)29 mov %%ebx, %c[extra](%%eax)30 mov %%eax, %%ebx31 call %P[setjmp]32 push %c[retaddr](%%ebx)33 mov %%ebx,4(%%esp)34 mov %%eax,8(%%esp)35 mov %c[extra](%%ebx), %%ebx36 jmp %P[epilogue]37 38.Lnosave:39 jmp %P[setjmp])" ::[retaddr] "i"(offsetof(__jmp_buf, sig_retaddr)),40 [extra] "i"(offsetof(__jmp_buf, sig_extra)), [setjmp] "X"(setjmp),41 [epilogue] "X"(sigsetjmp_epilogue)42 : "eax", "ebx", "ecx");43}44#else45[[gnu::naked]]46LLVM_LIBC_FUNCTION(int, sigsetjmp, (sigjmp_buf, int)) {47 asm(R"(48 test %%esi, %%esi49 jz .Lnosave50 51 pop %c[retaddr](%%rdi)52 mov %%rbx, %c[extra](%%rdi)53 mov %%rdi, %%rbx54 call %P[setjmp]55 push %c[retaddr](%%rbx)56 mov %%rbx, %%rdi57 mov %%eax, %%esi58 mov %c[extra](%%rdi), %%rbx59 jmp %P[epilogue]60 61.Lnosave:62 jmp %P[setjmp])" ::[retaddr] "i"(offsetof(__jmp_buf, sig_retaddr)),63 [extra] "i"(offsetof(__jmp_buf, sig_extra)), [setjmp] "X"(setjmp),64 [epilogue] "X"(sigsetjmp_epilogue)65 : "rax", "rbx");66}67#endif68 69} // namespace LIBC_NAMESPACE_DECL70