[libc-commits] [libc] [libc] add checksum for jmpbuf (PR #101110)
Schrodinger ZHU Yifan via libc-commits
libc-commits at lists.llvm.org
Tue Jul 30 10:48:05 PDT 2024
================
@@ -7,39 +7,63 @@
//===----------------------------------------------------------------------===//
#include "src/setjmp/longjmp.h"
+#include "include/llvm-libc-types/jmp_buf.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
+#include "src/setjmp/checksum.h"
#if !defined(LIBC_TARGET_ARCH_IS_X86_64)
#error "Invalid file include"
#endif
namespace LIBC_NAMESPACE_DECL {
+[[gnu::naked]]
LLVM_LIBC_FUNCTION(void, longjmp, (__jmp_buf * buf, int val)) {
- register __UINT64_TYPE__ rbx __asm__("rbx");
- register __UINT64_TYPE__ rbp __asm__("rbp");
- register __UINT64_TYPE__ r12 __asm__("r12");
- register __UINT64_TYPE__ r13 __asm__("r13");
- register __UINT64_TYPE__ r14 __asm__("r14");
- register __UINT64_TYPE__ r15 __asm__("r15");
- register __UINT64_TYPE__ rsp __asm__("rsp");
- register __UINT64_TYPE__ rax __asm__("rax");
-
- // ABI requires that the return value should be stored in rax. So, we store
- // |val| in rax. Note that this has to happen before we restore the registers
- // from values in |buf|. Otherwise, once rsp and rbp are updated, we cannot
- // read |val|.
- val = val == 0 ? 1 : val;
- LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(rax) : "m"(val) :);
- LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(rbx) : "m"(buf->rbx) :);
- LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(rbp) : "m"(buf->rbp) :);
- LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(r12) : "m"(buf->r12) :);
- LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(r13) : "m"(buf->r13) :);
- LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(r14) : "m"(buf->r14) :);
- LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(r15) : "m"(buf->r15) :);
- LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(rsp) : "m"(buf->rsp) :);
- LIBC_INLINE_ASM("jmp *%0\n\t" : : "m"(buf->rip));
+ asm(R"(
+ pushq %%rbp
+ pushq %%rbx
+ mov %%rdi, %%rbp
+ mov %%esi, %%ebx
+ subq $8, %%rsp
+ call %P0
+ addq $8, %%rsp
+ mov %%ebx, %%esi
+ mov %%rbp, %%rdi
+ popq %%rbx
+ popq %%rbp
+ )" ::"i"(jmpbuf::verify)
+ : "rax", "rcx", "rdx", "r8", "r9", "r10", "r11");
+
+ register __UINT64_TYPE__ rcx __asm__("rcx");
+ // Load cookie
+ asm("mov %1, %0\n\t" : "=r"(rcx) : "m"(jmpbuf::register_mangle_cookie));
+
+ // load registers from buffer
+ // do not pass any invalid values into registers
+#define RECOVER(REG) \
+ asm("mov %c[" #REG "](%%rdi), %%rdx\n\t" \
+ "xor %%rdx, %%rcx\n\t" \
+ "mov %%rdx, %%" #REG "\n\t" ::[REG] "i"(offsetof(__jmp_buf, REG)) \
+ : "rdx");
----------------
SchrodingerZhu wrote:
You are right. It should be an output register.
https://github.com/llvm/llvm-project/pull/101110
More information about the libc-commits
mailing list