From 2d93788ce36be0b05c7bb0af0058da80378bb586 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Fri, 5 Jan 2024 15:11:37 -0800 Subject: [PATCH] Fix --ftrace with cosmo_dlopen() This change ensures function call logging won't crash the process when cosmo_dlopen() is called. --- libc/dlopen/dlopen.c | 2 +- libc/nexgen32e/longjmp.S | 3 ++- libc/runtime/set_tls-sysv.S | 26 ++++++++++++++++++++++++++ libc/runtime/set_tls.c | 5 +++-- libc/sysv/calls/sys_set_tls.S | 2 -- libc/sysv/consts.sh | 1 + libc/sysv/consts/__NR_set_tls.S | 2 ++ libc/sysv/syscalls.sh | 1 - 8 files changed, 35 insertions(+), 7 deletions(-) create mode 100644 libc/runtime/set_tls-sysv.S delete mode 100644 libc/sysv/calls/sys_set_tls.S create mode 100644 libc/sysv/consts/__NR_set_tls.S diff --git a/libc/dlopen/dlopen.c b/libc/dlopen/dlopen.c index 1a0bdf143..9be0c1f56 100644 --- a/libc/dlopen/dlopen.c +++ b/libc/dlopen/dlopen.c @@ -291,7 +291,7 @@ static wontreturn dontinstrument void foreign_helper(void **p) { __foreign.dlsym = p[1]; __foreign.dlclose = p[2]; __foreign.dlerror = p[3]; - longjmp(__foreign.jb, 1); + _longjmp(__foreign.jb, 1); } static dontinline void elf_exec(const char *file, char **envp) { diff --git a/libc/nexgen32e/longjmp.S b/libc/nexgen32e/longjmp.S index f0aad78e9..643c599d6 100644 --- a/libc/nexgen32e/longjmp.S +++ b/libc/nexgen32e/longjmp.S @@ -28,6 +28,7 @@ .ftrace1 longjmp: .ftrace2 +_longjmp: #ifdef __x86_64__ mov %esi,%eax test %eax,%eax @@ -61,5 +62,5 @@ longjmp: #error "unsupported architecture" #endif .endfn longjmp,globl - .alias longjmp,_longjmp + .endfn _longjmp,globl .alias longjmp,siglongjmp diff --git a/libc/runtime/set_tls-sysv.S b/libc/runtime/set_tls-sysv.S new file mode 100644 index 000000000..e013014b5 --- /dev/null +++ b/libc/runtime/set_tls-sysv.S @@ -0,0 +1,26 @@ +/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│ vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi │ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2024 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.internal.h" + +// we can't allow ftrace here since ftrace needs tls +sys_set_tls: + mov __NR_set_tls(%rip),%eax + syscall + ret + .endfn sys_set_tls,globl diff --git a/libc/runtime/set_tls.c b/libc/runtime/set_tls.c index 3a2a3e3cc..3e87f0764 100644 --- a/libc/runtime/set_tls.c +++ b/libc/runtime/set_tls.c @@ -28,12 +28,13 @@ int sys_set_tls(); -textstartup void __set_tls(struct CosmoTib *tib) { +// we can't allow --ftrace here because cosmo_dlopen() calls this +// function to fix the tls register, and ftrace needs it unbroken +dontinstrument textstartup void __set_tls(struct CosmoTib *tib) { tib = __adj_tls(tib); #ifdef __x86_64__ // ask the operating system to change the x86 segment register if (IsWindows()) { - npassert(0 <= __tls_index && __tls_index < 64); asm("mov\t%1,%%gs:%0" : "=m"(*((long *)0x1480 + __tls_index)) : "r"(tib)); } else if (IsFreebsd()) { sys_set_tls(129 /*AMD64_SET_FSBASE*/, tib); diff --git a/libc/sysv/calls/sys_set_tls.S b/libc/sysv/calls/sys_set_tls.S deleted file mode 100644 index ad10da93c..000000000 --- a/libc/sysv/calls/sys_set_tls.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/macros.internal.h" -.scall sys_set_tls,0x13d1490a5300309e,4095,3,165,globl,hidden diff --git a/libc/sysv/consts.sh b/libc/sysv/consts.sh index 5b767cdc5..2a7a5cf22 100755 --- a/libc/sysv/consts.sh +++ b/libc/sysv/consts.sh @@ -1725,6 +1725,7 @@ syscon nr __NR_ioperm 0x00ad 0x0fff 0xfff 0xfff 0xfff 0xfff 0xfff syscon nr __NR_init_module 0x00af 0x0069 0xfff 0xfff 0xfff 0xfff 0xfff 0xfff syscon nr __NR_delete_module 0x00b0 0x006a 0xfff 0xfff 0xfff 0xfff 0xfff 0xfff syscon nr __NR_gettid 0x00ba 0x00b2 0x100001b 0xfff 432 299 311 0xfff # TODO(jart): thread_self_trap vs. gettid? +syscon nr __NR_set_tls 0x009e 0xfff 0x3000003 0xfff 0x00a5 0x0149 0x13d 0xfff syscon nr __NR_readahead 0x00bb 0x00d5 0xfff 0xfff 0xfff 0xfff 0xfff 0xfff syscon nr __NR_setxattr 0x00bc 0x0005 0x20000ec 0x00ec 0xfff 0xfff 0x177 0xfff syscon nr __NR_fsetxattr 0x00be 0x0007 0x20000ed 0x00ed 0xfff 0xfff 0x179 0xfff diff --git a/libc/sysv/consts/__NR_set_tls.S b/libc/sysv/consts/__NR_set_tls.S new file mode 100644 index 000000000..064a54ce6 --- /dev/null +++ b/libc/sysv/consts/__NR_set_tls.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon nr,__NR_set_tls,0x009e,0xfff,0x3000003,0xfff,0x00a5,0x0149,0x13d,0xfff diff --git a/libc/sysv/syscalls.sh b/libc/sysv/syscalls.sh index c7cdb79b5..7f465b163 100755 --- a/libc/sysv/syscalls.sh +++ b/libc/sysv/syscalls.sh @@ -201,7 +201,6 @@ scall sys_modify_ldt 0xfffffffffffff09a 0xfff globl # no wrapper scall sys_pivot_root 0xfffffffffffff09b 0x029 globl hidden #scall prctl 0xfffffffffffff09d 0x0a7 globl # wrapped manually scall sys_arch_prctl 0x0a50a50a5ffff09e 0xfff globl hidden # sysarch() on bsd -scall sys_set_tls 0x13d1490a5300309e 0xfff globl hidden # arch_prctl on linux, sysarch on freebsd, _lwp_setprivate on netbsd, __set_tcb on openbsd, _lwp_setprivate on netbsd, thread_fast_set_cthread_self on xnu scall sys_adjtimex 0xfffffffffffff09f 0x0ab globl # no wrapper scall sys_swapon 0xffffff05520550a7 0x0e0 globl # no wrapper scall sys_swapoff 0xffffff1a8ffff0a8 0x0e1 globl # no wrapper