From 93e9c0d6bf1f204f2fcc7059ab03c570394d8ef7 Mon Sep 17 00:00:00 2001 From: Domagoj Stolfa Date: Thu, 21 Mar 2024 21:51:24 +0000 Subject: [PATCH] c18n: Allow _rtld_unw_resume to resume purecap binaries. --- libexec/rtld-elf/aarch64/rtld_c18n_asm.S | 10 ++++++++++ libexec/rtld-elf/rtld_c18n.c | 15 +++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/libexec/rtld-elf/aarch64/rtld_c18n_asm.S b/libexec/rtld-elf/aarch64/rtld_c18n_asm.S index 9085042b49b9..a6110c0b4dfa 100644 --- a/libexec/rtld-elf/aarch64/rtld_c18n_asm.S +++ b/libexec/rtld-elf/aarch64/rtld_c18n_asm.S @@ -127,6 +127,16 @@ ENTRY(_rtld_dispatch_signal) b dispatch_signal_end END(_rtld_dispatch_signal) +ENTRY(_rtld_unw_setcontext_epilogue) + /* + * FIXME: llvm-libunwind specific ABI. This should be better specified. + */ + mov c16, c2 + ldp c2, c3, [c0, #(-0x210 + 0x20)] + mov csp, c16 + ret +END(_rtld_unw_setcontext_epilogue) + ENTRY(allocate_rstk) /* * NON-STANDARD CALLING CONVENTION diff --git a/libexec/rtld-elf/rtld_c18n.c b/libexec/rtld-elf/rtld_c18n.c index 88ee5d50502a..0120cb427d33 100644 --- a/libexec/rtld-elf/rtld_c18n.c +++ b/libexec/rtld-elf/rtld_c18n.c @@ -858,9 +858,18 @@ _rtld_longjmp(struct jmp_args ret, void *rcsp, void **buf) get_trusted_frame())); } +struct jmp_args _rtld_unw_setcontext_epilogue(struct jmp_args ret, void *rcsp, + void **buf); + struct jmp_args _rtld_unw_setcontext(struct jmp_args ret, void *rcsp, void **buf) { +#ifdef C18N_ENABLED + if (!C18N_ENABLED) { + __attribute__((musttail)) + return (_rtld_unw_setcontext_epilogue(ret, rcsp, buf)); + } +#endif return (unwind_stack(ret, rcsp, cheri_unseal(*buf, sealer_unwbuf), get_trusted_frame())); } @@ -868,6 +877,12 @@ _rtld_unw_setcontext(struct jmp_args ret, void *rcsp, void **buf) struct jmp_args _rtld_unw_setcontext_unsealed(struct jmp_args ret, void *rcsp, void **buf) { +#ifdef C18N_ENABLED + if (!C18N_ENABLED) { + __attribute__((musttail)) + return (_rtld_unw_setcontext_epilogue(ret, rcsp, buf)); + } +#endif return (unwind_stack(ret, rcsp, *buf, get_trusted_frame())); }