-
Notifications
You must be signed in to change notification settings - Fork 14.1k
[libc][setjmp][x86] implement setjmp in terms of out of line asm #88157
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
a449c60
fa3e817
913e955
ea7f70c
327e64b
8d48548
9182f1c
221ef63
81a2396
e39c288
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
//===-- assembly.h - libc assembler support macros based on compiler-rt's -===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
#ifndef LLVM_LIBC_SRC___SUPPORT_ASSEMBLY_H | ||
#define LLVM_LIBC_SRC___SUPPORT_ASSEMBLY_H | ||
|
||
#ifndef __ASSEMBLER__ | ||
#error "No not include assembly.h in non-asm sources" | ||
#endif | ||
|
||
#define GLUE2_(a, b) a##b | ||
#define GLUE(a, b) GLUE2_(a, b) | ||
#define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name) | ||
|
||
#if defined(__ELF__) && (defined(__GNU__) || defined(__FreeBSD__) || \ | ||
defined(__Fuchsia__) || defined(__linux__)) | ||
|
||
// clang-format off | ||
#define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack, "", @progbits | ||
#define SYMBOL_IS_FUNC(name) .type SYMBOL_NAME(name), %function | ||
#define END_FUNC(name) .size SYMBOL_NAME(name), . - SYMBOL_NAME(name) | ||
// clang-format on | ||
|
||
#else // !ELF | ||
#define NO_EXEC_STACK_DIRECTIVE | ||
#define SYMBOL_IS_FUNC(name) | ||
#define END_FUNC(name) | ||
#endif // ELF | ||
|
||
#endif // LLVM_LIBC_SRC___SUPPORT_ASSEMBLY_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
//===-- Implementation of setjmp --------------------------------*- ASM -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "src/__support/assembly.h" | ||
#include "src/setjmp/x86_64/setjmp.h" | ||
|
||
#define paste(ns) _ZN22 ## ns ## 6setjmpEP9__jmp_buf | ||
#define expand(x) paste(x) | ||
#define LIBC_NAMESPACE_setjmp expand(LIBC_NAMESPACE) | ||
// aka _ZN22__llvm_libc_19_0_0_git6setjmpEP9__jmp_buf | ||
// aka __llvm_libc_19_0_0_git::setjmp(__jmp_buf*) | ||
|
||
.global SYMBOL_NAME(setjmp) | ||
.global SYMBOL_NAME(LIBC_NAMESPACE_setjmp) | ||
|
||
SYMBOL_IS_FUNC(setjmp) | ||
SYMBOL_IS_FUNC(LIBC_NAMESPACE_setjmp) | ||
|
||
SYMBOL_NAME(setjmp): | ||
SYMBOL_NAME(LIBC_NAMESPACE_setjmp): | ||
|
||
mov %rbx, RBX_OFFSET(%rdi) | ||
mov %rbp, RBP_OFFSET(%rdi) | ||
mov %r12, R12_OFFSET(%rdi) | ||
mov %r13, R13_OFFSET(%rdi) | ||
mov %r14, R14_OFFSET(%rdi) | ||
mov %r15, R15_OFFSET(%rdi) | ||
lea 8(%rsp), %rax | ||
mov %rax, RSP_OFFSET(%rdi) | ||
mov (%rsp), %rax | ||
mov %rax, RIP_OFFSET(%rdi) | ||
xor %eax, %eax | ||
ret | ||
END_FUNC(setjmp) | ||
END_FUNC(LIBC_NAMESPACE_setjmp) | ||
|
||
NO_EXEC_STACK_DIRECTIVE |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
//===-- setjmp.h - shared constants between C++ and asm sources (x86_64) --===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_LIBC_SRC_SETJMP_X86_64_SETJMP_H | ||
#define LLVM_LIBC_SRC_SETJMP_X86_64_SETJMP_H | ||
|
||
#ifdef __ASSEMBLER__ | ||
#define UL(x) x | ||
#else | ||
#define UL(x) x##UL | ||
#endif | ||
Comment on lines
+12
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will be useful again, move to assembly.h There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm...maybe not. I do have a:
in assembly.h. Maybe I should change that so that it can be included in either sources. Or create yet another new header. |
||
|
||
// Brittle! Changing the layout of __jmp_buf will break this! | ||
#define RBX_OFFSET UL(0) | ||
#define RBP_OFFSET UL(8) | ||
#define R12_OFFSET UL(16) | ||
#define R13_OFFSET UL(24) | ||
#define R14_OFFSET UL(32) | ||
#define R15_OFFSET UL(40) | ||
#define RSP_OFFSET UL(48) | ||
#define RIP_OFFSET UL(56) | ||
|
||
#endif // LLVM_LIBC_SRC_SETJMP_X86_64_SETJMP_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
//===-- Unittests for setjmp ----------------------------------------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDSList-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "include/llvm-libc-macros/offsetof-macro.h" | ||
#include "include/llvm-libc-types/jmp_buf.h" | ||
#include "src/setjmp/x86_64/setjmp.h" | ||
#include "test/UnitTest/Test.h" | ||
|
||
// If this test fails, then *_OFFSET macro definitions in | ||
// libc/src/setjmp/x86_64/setjmp.S need to be fixed. This is a simple change | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. libc/src/setjmp/x86_64/setjmp.h is the updated source location |
||
// detector. | ||
TEST(LlvmLibcSetjmpTest, JmpBufLayout) { | ||
#ifdef __x86_64__ | ||
ASSERT_EQ(offsetof(__jmp_buf, rbx), RBX_OFFSET); | ||
ASSERT_EQ(offsetof(__jmp_buf, rbp), RBP_OFFSET); | ||
ASSERT_EQ(offsetof(__jmp_buf, r12), R12_OFFSET); | ||
ASSERT_EQ(offsetof(__jmp_buf, r13), R13_OFFSET); | ||
ASSERT_EQ(offsetof(__jmp_buf, r14), R14_OFFSET); | ||
ASSERT_EQ(offsetof(__jmp_buf, r15), R15_OFFSET); | ||
ASSERT_EQ(offsetof(__jmp_buf, rsp), RSP_OFFSET); | ||
ASSERT_EQ(offsetof(__jmp_buf, rip), RIP_OFFSET); | ||
ASSERT_EQ(sizeof(__jmp_buf), 64UL); | ||
ASSERT_EQ(alignof(__jmp_buf), 8UL); | ||
#endif // __x86_64__ | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest an extern C name which includes the expansion of LIBC_NAMESPACE in the name, rather than manual C++ name-mangling. If you want to do C++ name-mangling you'll need to figure out how to generate the "22" since that needs to be the length of the namespace.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sorry I don't follow the suggestion. Can you please "break out the crayons" for me?