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-exception
6//
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#endif
19namespace LIBC_NAMESPACE_DECL {
20#ifdef __i386__
21[[gnu::naked]]
22LLVM_LIBC_FUNCTION(int, sigsetjmp, (sigjmp_buf buf)) {
23 asm(R"(
24 mov 8(%%esp), %%ecx
25 jecxz .Lnosave
26
27 mov 4(%%esp), %%eax
28 pop %c[retaddr](%%eax)
29 mov %%ebx, %c[extra](%%eax)
30 mov %%eax, %%ebx
31 call %P[setjmp]
32 push %c[retaddr](%%ebx)
33 mov %%ebx,4(%%esp)
34 mov %%eax,8(%%esp)
35 mov %c[extra](%%ebx), %%ebx
36 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#endif
45[[gnu::naked]]
46LLVM_LIBC_FUNCTION(int, sigsetjmp, (sigjmp_buf, int)) {
47 asm(R"(
48 test %%esi, %%esi
49 jz .Lnosave
50
51 pop %c[retaddr](%%rdi)
52 mov %%rbx, %c[extra](%%rdi)
53 mov %%rdi, %%rbx
54 call %P[setjmp]
55 push %c[retaddr](%%rbx)
56 mov %%rbx, %%rdi
57 mov %%eax, %%esi
58 mov %c[extra](%%rdi), %%rbx
59 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
68} // namespace LIBC_NAMESPACE_DECL
69

source code of libc/src/setjmp/x86_64/sigsetjmp.cpp