mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-06 19:28:29 +00:00
Support thread local storage
This commit is contained in:
parent
91ee2b19d4
commit
55de4ca6b5
197 changed files with 1483 additions and 874 deletions
|
@ -65,10 +65,21 @@ $(LIBC_CALLS_A).pkg: \
|
|||
$(LIBC_CALLS_A_OBJS) \
|
||||
$(foreach x,$(LIBC_CALLS_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
o/$(MODE)/libc/calls/sigenter-freebsd.o \
|
||||
o/$(MODE)/libc/calls/sigenter-netbsd.o \
|
||||
o/$(MODE)/libc/calls/sigenter-openbsd.o \
|
||||
o/$(MODE)/libc/calls/sigenter-xnu.o: \
|
||||
OVERRIDE_COPTS += \
|
||||
-mno-fentry \
|
||||
-fno-stack-protector \
|
||||
-fno-sanitize=all
|
||||
|
||||
o/$(MODE)/libc/calls/sys_mprotect.greg.o \
|
||||
o/$(MODE)/libc/calls/vdsofunc.greg.o \
|
||||
o/$(MODE)/libc/calls/directmap.o \
|
||||
o/$(MODE)/libc/calls/directmap-nt.o \
|
||||
o/$(MODE)/libc/calls/mapstack.greg.o \
|
||||
o/$(MODE)/libc/calls/execve-nt.greg.o \
|
||||
o/$(MODE)/libc/calls/getcwd.greg.o \
|
||||
o/$(MODE)/libc/calls/getcwd-xnu.greg.o \
|
||||
o/$(MODE)/libc/calls/getprogramexecutablename.greg.o \
|
||||
|
@ -114,7 +125,7 @@ o/$(MODE)/libc/calls/execl.o \
|
|||
o/$(MODE)/libc/calls/execle.o \
|
||||
o/$(MODE)/libc/calls/execlp.o \
|
||||
o/$(MODE)/libc/calls/copyfile.o \
|
||||
o/$(MODE)/libc/calls/execve-nt.o \
|
||||
o/$(MODE)/libc/calls/execve-nt.greg.o \
|
||||
o/$(MODE)/libc/calls/linkat-nt.o \
|
||||
o/$(MODE)/libc/calls/renameat-nt.o \
|
||||
o/$(MODE)/libc/calls/execve-sysv.o \
|
||||
|
|
|
@ -16,44 +16,95 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#define ShouldUseMsabiAttribute() 1
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/ntspawn.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/mem/alloca.h"
|
||||
#include "libc/nt/accounting.h"
|
||||
#include "libc/nt/console.h"
|
||||
#include "libc/nt/enum/startf.h"
|
||||
#include "libc/nt/enum/status.h"
|
||||
#include "libc/nt/memory.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/processinformation.h"
|
||||
#include "libc/nt/struct/startupinfo.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
#include "libc/nt/thunk/msabi.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/ok.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
__msabi extern typeof(CloseHandle) *const __imp_CloseHandle;
|
||||
__msabi extern typeof(WaitForSingleObject) *const __imp_WaitForSingleObject;
|
||||
__msabi extern typeof(GetExitCodeProcess) *const __imp_GetExitCodeProcess;
|
||||
__msabi extern typeof(UnmapViewOfFile) *const __imp_UnmapViewOfFile;
|
||||
|
||||
static noinstrument __msabi bool32
|
||||
BlockExecveConsoleEvent(uint32_t dwCtrlType) {
|
||||
// block SIGINT and SIGQUIT in execve() parent process
|
||||
return true;
|
||||
}
|
||||
|
||||
textwindows int sys_execve_nt(const char *program, char *const argv[],
|
||||
char *const envp[]) {
|
||||
int rc;
|
||||
size_t i;
|
||||
uint32_t dwExitCode;
|
||||
struct MemoryIntervals *mm;
|
||||
struct NtStartupInfo startinfo;
|
||||
struct NtProcessInformation procinfo;
|
||||
|
||||
// this is a non-recoverable operation, so do some manual validation
|
||||
if (sys_faccessat_nt(AT_FDCWD, program, X_OK, 0) == -1) {
|
||||
return eacces();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// execve operation is unrecoverable from this point
|
||||
|
||||
// close cloexec handles
|
||||
for (i = 3; i < g_fds.n; ++i) {
|
||||
if (g_fds.p[i].kind != kFdEmpty && (g_fds.p[i].flags & O_CLOEXEC)) {
|
||||
__imp_CloseHandle(g_fds.p[i].handle);
|
||||
}
|
||||
}
|
||||
|
||||
bzero(&startinfo, sizeof(startinfo));
|
||||
startinfo.cb = sizeof(struct NtStartupInfo);
|
||||
startinfo.dwFlags = kNtStartfUsestdhandles;
|
||||
startinfo.hStdInput = __getfdhandleactual(0);
|
||||
startinfo.hStdOutput = __getfdhandleactual(1);
|
||||
startinfo.hStdError = __getfdhandleactual(2);
|
||||
|
||||
// spawn the process
|
||||
rc = ntspawn(program, argv, envp, 0, 0, 0, 1, 0, 0, &startinfo, &procinfo);
|
||||
if (rc == -1) return -1;
|
||||
CloseHandle(g_fds.p[0].handle);
|
||||
CloseHandle(g_fds.p[1].handle);
|
||||
CloseHandle(procinfo.hThread);
|
||||
if (rc == -1) {
|
||||
STRACE("panic: unrecoverable ntspawn(%#s) error: %m", program);
|
||||
__imp_ExitProcess(6543);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// zombie shell process remains, to wait for child and propagate its exit
|
||||
// code
|
||||
|
||||
__imp_CloseHandle(g_fds.p[0].handle);
|
||||
__imp_CloseHandle(g_fds.p[1].handle);
|
||||
__imp_CloseHandle(procinfo.hThread);
|
||||
__imp_SetConsoleCtrlHandler((void *)BlockExecveConsoleEvent, 1);
|
||||
do {
|
||||
WaitForSingleObject(procinfo.hProcess, -1);
|
||||
__imp_WaitForSingleObject(procinfo.hProcess, -1);
|
||||
dwExitCode = kNtStillActive;
|
||||
GetExitCodeProcess(procinfo.hProcess, &dwExitCode);
|
||||
__imp_GetExitCodeProcess(procinfo.hProcess, &dwExitCode);
|
||||
} while (dwExitCode == kNtStillActive);
|
||||
CloseHandle(procinfo.hProcess);
|
||||
_Exit(dwExitCode);
|
||||
__imp_CloseHandle(procinfo.hProcess);
|
||||
__imp_ExitProcess(dwExitCode);
|
||||
unreachable;
|
||||
}
|
|
@ -63,11 +63,6 @@ int execve(const char *prog, char *const argv[], char *const envp[]) {
|
|||
kprintf("})\n");
|
||||
}
|
||||
#endif
|
||||
for (i = 3; i < g_fds.n; ++i) {
|
||||
if (g_fds.p[i].kind != kFdEmpty && (g_fds.p[i].flags & O_CLOEXEC)) {
|
||||
close(i);
|
||||
}
|
||||
}
|
||||
if (!IsWindows()) {
|
||||
rc = sys_execve(prog, argv, envp);
|
||||
} else {
|
||||
|
|
|
@ -134,6 +134,7 @@ i32 __sys_pipe2(i32[hasatleast 2], u32) hidden;
|
|||
i32 __sys_sigprocmask(i32, const sigset *, sigset *, u64) hidden;
|
||||
i32 __sys_utimensat(i32, const char *, const struct timespec *, i32) hidden;
|
||||
i32 __sys_wait4(i32, i32 *, i32, struct rusage *) hidden;
|
||||
i32 sys_arch_prctl(i32, i64) hidden;
|
||||
i32 sys_chdir(const char *) hidden;
|
||||
i32 sys_chroot(const char *) hidden;
|
||||
i32 sys_clock_gettime(i32, struct timespec *) hidden;
|
||||
|
|
|
@ -18,10 +18,11 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/nt/struct/context.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
textwindows void _ntcontext2linux(ucontext_t *ctx, const struct NtContext *cr) {
|
||||
privileged void _ntcontext2linux(ucontext_t *ctx, const struct NtContext *cr) {
|
||||
if (!cr) return;
|
||||
ctx->uc_flags = cr->EFlags;
|
||||
ctx->uc_mcontext.eflags = cr->EFlags;
|
||||
|
@ -46,10 +47,10 @@ textwindows void _ntcontext2linux(ucontext_t *ctx, const struct NtContext *cr) {
|
|||
ctx->uc_mcontext.gs = cr->SegGs;
|
||||
ctx->uc_mcontext.fs = cr->SegFs;
|
||||
ctx->uc_mcontext.fpregs = &ctx->__fpustate;
|
||||
memcpy(&ctx->__fpustate, &cr->FltSave, sizeof(ctx->__fpustate));
|
||||
__repmovsb(&ctx->__fpustate, &cr->FltSave, sizeof(ctx->__fpustate));
|
||||
}
|
||||
|
||||
textwindows void _ntlinux2context(struct NtContext *cr, const ucontext_t *ctx) {
|
||||
privileged void _ntlinux2context(struct NtContext *cr, const ucontext_t *ctx) {
|
||||
if (!cr) return;
|
||||
cr->EFlags = ctx->uc_flags;
|
||||
cr->EFlags = ctx->uc_mcontext.eflags;
|
||||
|
@ -73,5 +74,5 @@ textwindows void _ntlinux2context(struct NtContext *cr, const ucontext_t *ctx) {
|
|||
cr->SegCs = ctx->uc_mcontext.cs;
|
||||
cr->SegGs = ctx->uc_mcontext.gs;
|
||||
cr->SegFs = ctx->uc_mcontext.fs;
|
||||
memcpy(&cr->FltSave, &ctx->__fpustate, sizeof(ctx->__fpustate));
|
||||
__repmovsb(&cr->FltSave, &ctx->__fpustate, sizeof(ctx->__fpustate));
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/intrin/cmpxchg.h"
|
||||
#include "libc/intrin/spinlock.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
@ -90,8 +91,8 @@ static textwindows struct Signal *__sig_remove(void) {
|
|||
* @note called from main thread
|
||||
* @return true if EINTR should be returned by caller
|
||||
*/
|
||||
static textwindows bool __sig_deliver(bool restartable, int sig, int si_code,
|
||||
ucontext_t *ctx) {
|
||||
static privileged bool __sig_deliver(bool restartable, int sig, int si_code,
|
||||
ucontext_t *ctx) {
|
||||
unsigned rva, flags;
|
||||
siginfo_t info, *infop;
|
||||
STRACE("delivering %G", sig);
|
||||
|
@ -113,7 +114,7 @@ static textwindows bool __sig_deliver(bool restartable, int sig, int si_code,
|
|||
// setup the somewhat expensive information args
|
||||
// only if they're requested by the user in sigaction()
|
||||
if (flags & SA_SIGINFO) {
|
||||
bzero(&info, sizeof(info));
|
||||
__repstosb(&info, 0, sizeof(info));
|
||||
info.si_signo = sig;
|
||||
info.si_code = si_code;
|
||||
infop = &info;
|
||||
|
@ -162,8 +163,8 @@ static textwindows bool __sig_isfatal(int sig) {
|
|||
* @param restartable can be used to suppress true return if SA_RESTART
|
||||
* @return true if signal was delivered
|
||||
*/
|
||||
textwindows bool __sig_handle(bool restartable, int sig, int si_code,
|
||||
ucontext_t *ctx) {
|
||||
privileged bool __sig_handle(bool restartable, int sig, int si_code,
|
||||
ucontext_t *ctx) {
|
||||
bool delivered;
|
||||
switch (__sighandrvas[sig]) {
|
||||
case (intptr_t)SIG_DFL:
|
||||
|
|
|
@ -25,13 +25,13 @@
|
|||
#include "libc/calls/typedef/sigaction_f.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/repstosb.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sa.h"
|
||||
|
||||
void __sigenter_freebsd(int sig, struct siginfo_freebsd *freebsdinfo,
|
||||
struct ucontext_freebsd *ctx) {
|
||||
privileged void __sigenter_freebsd(int sig, struct siginfo_freebsd *freebsdinfo,
|
||||
struct ucontext_freebsd *ctx) {
|
||||
int rva, flags;
|
||||
struct Goodies {
|
||||
ucontext_t uc;
|
||||
|
@ -43,14 +43,14 @@ void __sigenter_freebsd(int sig, struct siginfo_freebsd *freebsdinfo,
|
|||
if (~flags & SA_SIGINFO) {
|
||||
((sigaction_f)(_base + rva))(sig, 0, 0);
|
||||
} else {
|
||||
repstosb(&g, 0, sizeof(g));
|
||||
__repstosb(&g, 0, sizeof(g));
|
||||
g.uc.uc_mcontext.fpregs = &g.uc.__fpustate;
|
||||
g.uc.uc_stack.ss_sp = ctx->uc_stack.ss_sp;
|
||||
g.uc.uc_stack.ss_size = ctx->uc_stack.ss_size;
|
||||
g.uc.uc_stack.ss_flags = ctx->uc_stack.ss_flags;
|
||||
g.uc.uc_flags = ctx->uc_flags;
|
||||
memcpy(&g.uc.uc_sigmask, &ctx->uc_sigmask,
|
||||
MIN(sizeof(g.uc.uc_sigmask), sizeof(ctx->uc_sigmask)));
|
||||
__repmovsb(&g.uc.uc_sigmask, &ctx->uc_sigmask,
|
||||
MIN(sizeof(g.uc.uc_sigmask), sizeof(ctx->uc_sigmask)));
|
||||
g.uc.uc_mcontext.r8 = ctx->uc_mcontext.mc_r8;
|
||||
g.uc.uc_mcontext.r9 = ctx->uc_mcontext.mc_r9;
|
||||
g.uc.uc_mcontext.r10 = ctx->uc_mcontext.mc_r10;
|
||||
|
@ -73,7 +73,7 @@ void __sigenter_freebsd(int sig, struct siginfo_freebsd *freebsdinfo,
|
|||
g.uc.uc_mcontext.gs = ctx->uc_mcontext.mc_gs;
|
||||
g.uc.uc_mcontext.err = ctx->uc_mcontext.mc_err;
|
||||
g.uc.uc_mcontext.trapno = ctx->uc_mcontext.mc_trapno;
|
||||
memcpy(&g.uc.__fpustate, &ctx->uc_mcontext.mc_fpstate, 512);
|
||||
__repmovsb(&g.uc.__fpustate, &ctx->uc_mcontext.mc_fpstate, 512);
|
||||
g.si.si_signo = freebsdinfo->si_signo;
|
||||
g.si.si_errno = freebsdinfo->si_errno;
|
||||
g.si.si_code = freebsdinfo->si_code;
|
||||
|
@ -89,8 +89,8 @@ void __sigenter_freebsd(int sig, struct siginfo_freebsd *freebsdinfo,
|
|||
ctx->uc_stack.ss_size = g.uc.uc_stack.ss_size;
|
||||
ctx->uc_stack.ss_flags = g.uc.uc_stack.ss_flags;
|
||||
ctx->uc_flags = g.uc.uc_flags;
|
||||
memcpy(&ctx->uc_sigmask, &g.uc.uc_sigmask,
|
||||
MIN(sizeof(g.uc.uc_sigmask), sizeof(ctx->uc_sigmask)));
|
||||
__repmovsb(&ctx->uc_sigmask, &g.uc.uc_sigmask,
|
||||
MIN(sizeof(g.uc.uc_sigmask), sizeof(ctx->uc_sigmask)));
|
||||
ctx->uc_mcontext.mc_rdi = g.uc.uc_mcontext.rdi;
|
||||
ctx->uc_mcontext.mc_rsi = g.uc.uc_mcontext.rsi;
|
||||
ctx->uc_mcontext.mc_rdx = g.uc.uc_mcontext.rdx;
|
||||
|
@ -113,7 +113,7 @@ void __sigenter_freebsd(int sig, struct siginfo_freebsd *freebsdinfo,
|
|||
ctx->uc_mcontext.mc_err = g.uc.uc_mcontext.err;
|
||||
ctx->uc_mcontext.mc_rip = g.uc.uc_mcontext.rip;
|
||||
ctx->uc_mcontext.mc_rsp = g.uc.uc_mcontext.rsp;
|
||||
memcpy(&ctx->uc_mcontext.mc_fpstate, &g.uc.__fpustate, 512);
|
||||
__repmovsb(&ctx->uc_mcontext.mc_fpstate, &g.uc.__fpustate, 512);
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
|
|
@ -24,12 +24,13 @@
|
|||
#include "libc/calls/struct/ucontext-netbsd.internal.h"
|
||||
#include "libc/calls/typedef/sigaction_f.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sa.h"
|
||||
|
||||
void __sigenter_netbsd(int sig, struct siginfo_netbsd *si,
|
||||
struct ucontext_netbsd *ctx) {
|
||||
privileged void __sigenter_netbsd(int sig, struct siginfo_netbsd *si,
|
||||
struct ucontext_netbsd *ctx) {
|
||||
int rva, flags;
|
||||
ucontext_t uc;
|
||||
struct siginfo si2;
|
||||
|
@ -39,8 +40,8 @@ void __sigenter_netbsd(int sig, struct siginfo_netbsd *si,
|
|||
if (~flags & SA_SIGINFO) {
|
||||
((sigaction_f)(_base + rva))(sig, 0, 0);
|
||||
} else {
|
||||
bzero(&uc, sizeof(uc));
|
||||
bzero(&si2, sizeof(si2));
|
||||
__repstosb(&uc, 0, sizeof(uc));
|
||||
__repstosb(&si2, 0, sizeof(si2));
|
||||
si2.si_signo = si->si_signo;
|
||||
si2.si_code = si->si_code;
|
||||
si2.si_errno = si->si_errno;
|
||||
|
@ -52,8 +53,8 @@ void __sigenter_netbsd(int sig, struct siginfo_netbsd *si,
|
|||
uc.uc_stack.ss_sp = ctx->uc_stack.ss_sp;
|
||||
uc.uc_stack.ss_size = ctx->uc_stack.ss_size;
|
||||
uc.uc_stack.ss_flags = ctx->uc_stack.ss_flags;
|
||||
memcpy(&uc.uc_sigmask, &ctx->uc_sigmask,
|
||||
MIN(sizeof(uc.uc_sigmask), sizeof(ctx->uc_sigmask)));
|
||||
__repmovsb(&uc.uc_sigmask, &ctx->uc_sigmask,
|
||||
MIN(sizeof(uc.uc_sigmask), sizeof(ctx->uc_sigmask)));
|
||||
uc.uc_mcontext.rdi = ctx->uc_mcontext.rdi;
|
||||
uc.uc_mcontext.rsi = ctx->uc_mcontext.rsi;
|
||||
uc.uc_mcontext.rdx = ctx->uc_mcontext.rdx;
|
||||
|
|
|
@ -24,13 +24,13 @@
|
|||
#include "libc/calls/struct/ucontext-openbsd.internal.h"
|
||||
#include "libc/calls/typedef/sigaction_f.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/intrin/repstosb.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sa.h"
|
||||
|
||||
void __sigenter_openbsd(int sig, struct siginfo_openbsd *openbsdinfo,
|
||||
struct ucontext_openbsd *ctx) {
|
||||
privileged void __sigenter_openbsd(int sig, struct siginfo_openbsd *openbsdinfo,
|
||||
struct ucontext_openbsd *ctx) {
|
||||
int rva, flags;
|
||||
struct Goodies {
|
||||
ucontext_t uc;
|
||||
|
@ -42,7 +42,7 @@ void __sigenter_openbsd(int sig, struct siginfo_openbsd *openbsdinfo,
|
|||
if (~flags & SA_SIGINFO) {
|
||||
((sigaction_f)(_base + rva))(sig, 0, 0);
|
||||
} else {
|
||||
repstosb(&g, 0, sizeof(g));
|
||||
__repstosb(&g, 0, sizeof(g));
|
||||
g.si.si_signo = openbsdinfo->si_signo;
|
||||
g.si.si_code = openbsdinfo->si_code;
|
||||
g.si.si_errno = openbsdinfo->si_errno;
|
||||
|
@ -54,8 +54,8 @@ void __sigenter_openbsd(int sig, struct siginfo_openbsd *openbsdinfo,
|
|||
}
|
||||
g.si.si_value = openbsdinfo->si_value;
|
||||
g.uc.uc_mcontext.fpregs = &g.uc.__fpustate;
|
||||
memcpy(&g.uc.uc_sigmask, &ctx->sc_mask,
|
||||
MIN(sizeof(g.uc.uc_sigmask), sizeof(ctx->sc_mask)));
|
||||
__repmovsb(&g.uc.uc_sigmask, &ctx->sc_mask,
|
||||
MIN(sizeof(g.uc.uc_sigmask), sizeof(ctx->sc_mask)));
|
||||
g.uc.uc_mcontext.rdi = ctx->sc_rdi;
|
||||
g.uc.uc_mcontext.rsi = ctx->sc_rsi;
|
||||
g.uc.uc_mcontext.rdx = ctx->sc_rdx;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/repstosb.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sa.h"
|
||||
|
||||
|
@ -355,19 +356,19 @@ struct __darwin_ucontext {
|
|||
struct __darwin_mcontext64 *uc_mcontext;
|
||||
};
|
||||
|
||||
noasan static void xnuexceptionstate2linux(
|
||||
static privileged void xnuexceptionstate2linux(
|
||||
mcontext_t *mc, struct __darwin_x86_exception_state64 *xnues) {
|
||||
mc->trapno = xnues->__trapno;
|
||||
mc->err = xnues->__err;
|
||||
}
|
||||
|
||||
noasan static void linuxexceptionstate2xnu(
|
||||
static privileged void linuxexceptionstate2xnu(
|
||||
struct __darwin_x86_exception_state64 *xnues, mcontext_t *mc) {
|
||||
xnues->__trapno = mc->trapno;
|
||||
xnues->__err = mc->err;
|
||||
}
|
||||
|
||||
noasan static void xnuthreadstate2linux(
|
||||
static privileged void xnuthreadstate2linux(
|
||||
mcontext_t *mc, struct __darwin_x86_thread_state64 *xnuss) {
|
||||
mc->rdi = xnuss->__rdi;
|
||||
mc->rsi = xnuss->__rsi;
|
||||
|
@ -392,7 +393,7 @@ noasan static void xnuthreadstate2linux(
|
|||
mc->r15 = xnuss->__r15;
|
||||
}
|
||||
|
||||
noasan static void linuxthreadstate2xnu(
|
||||
static privileged void linuxthreadstate2xnu(
|
||||
struct __darwin_x86_thread_state64 *xnuss, ucontext_t *uc, mcontext_t *mc) {
|
||||
xnuss->__rdi = mc->rdi;
|
||||
xnuss->__rsi = mc->rsi;
|
||||
|
@ -417,14 +418,14 @@ noasan static void linuxthreadstate2xnu(
|
|||
xnuss->__r15 = mc->r15;
|
||||
}
|
||||
|
||||
noasan static void CopyFpXmmRegs(void *d, const void *s) {
|
||||
static privileged void CopyFpXmmRegs(void *d, const void *s) {
|
||||
size_t i;
|
||||
for (i = 0; i < (8 + 16) * 16; i += 16) {
|
||||
__builtin_memcpy((char *)d + i, (const char *)s + i, 16);
|
||||
}
|
||||
}
|
||||
|
||||
noasan static void xnussefpustate2linux(
|
||||
static privileged void xnussefpustate2linux(
|
||||
struct FpuState *fs, struct __darwin_x86_float_state64 *xnufs) {
|
||||
fs->cwd = xnufs->__fpu_fcw;
|
||||
fs->swd = xnufs->__fpu_fsw;
|
||||
|
@ -437,7 +438,7 @@ noasan static void xnussefpustate2linux(
|
|||
CopyFpXmmRegs(fs->st, &xnufs->__fpu_stmm0);
|
||||
}
|
||||
|
||||
noasan static void linuxssefpustate2xnu(
|
||||
static privileged void linuxssefpustate2xnu(
|
||||
struct __darwin_x86_float_state64 *xnufs, struct FpuState *fs) {
|
||||
xnufs->__fpu_fcw = fs->cwd;
|
||||
xnufs->__fpu_fsw = fs->swd;
|
||||
|
@ -450,9 +451,9 @@ noasan static void linuxssefpustate2xnu(
|
|||
CopyFpXmmRegs(&xnufs->__fpu_stmm0, fs->st);
|
||||
}
|
||||
|
||||
noasan void __sigenter_xnu(void *fn, int infostyle, int sig,
|
||||
struct siginfo_xnu *xnuinfo,
|
||||
struct __darwin_ucontext *xnuctx) {
|
||||
privileged void __sigenter_xnu(void *fn, int infostyle, int sig,
|
||||
struct siginfo_xnu *xnuinfo,
|
||||
struct __darwin_ucontext *xnuctx) {
|
||||
intptr_t ax;
|
||||
int rva, flags;
|
||||
struct Goodies {
|
||||
|
@ -465,7 +466,7 @@ noasan void __sigenter_xnu(void *fn, int infostyle, int sig,
|
|||
if (~flags & SA_SIGINFO) {
|
||||
((sigaction_f)(_base + rva))(sig, 0, 0);
|
||||
} else {
|
||||
repstosb(&g, 0, sizeof(g));
|
||||
__repstosb(&g, 0, sizeof(g));
|
||||
if (xnuctx) {
|
||||
g.uc.uc_flags = xnuctx->uc_onstack ? SA_ONSTACK : 0;
|
||||
g.uc.uc_sigmask.__bits[0] = xnuctx->uc_sigmask;
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include "libc/sysv/consts/sicode.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
|
||||
textwindows unsigned __wincrash(struct NtExceptionPointers *ep) {
|
||||
privileged unsigned __wincrash(struct NtExceptionPointers *ep) {
|
||||
int64_t rip;
|
||||
int sig, code;
|
||||
ucontext_t ctx;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue