mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-30 08:18:30 +00:00
Write more runtime tests and fix bugs
This change adds tests for the new memory manager code particularly with its windows support. Function call tracing now works reliably on Silicon since our function hooker was missing new Apple self-modifying code APIs Many tests that were disabled a long time ago on aarch64 are reactivated by this change, now that arm support is on equal terms with x86. There's been a lot of places where ftrace could cause deadlocks, which have been hunted down across all platforms thanks to new tests. A bug in Windows's kill() function has been identified.
This commit is contained in:
parent
0b3c81dd4e
commit
f24c854b28
45 changed files with 550 additions and 872 deletions
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/proc/ntspawn.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/calls/struct/sigset.internal.h"
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/intrin/strace.h"
|
||||
|
|
|
@ -190,7 +190,9 @@ textstartup void __init_fds(int argc, char **argv, char **envp) {
|
|||
map->prot = PROT_READ | PROT_WRITE;
|
||||
map->flags = MAP_SHARED | MAP_ANONYMOUS;
|
||||
map->hand = shand;
|
||||
__maps_lock();
|
||||
__maps_insert(map);
|
||||
__maps_unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,6 +112,13 @@ void __maps_init(void) {
|
|||
}
|
||||
|
||||
bool __maps_held(void) {
|
||||
return !__tls_enabled || (__get_tls()->tib_flags & TIB_FLAG_VFORKED) ||
|
||||
MUTEX_OWNER(
|
||||
atomic_load_explicit(&__maps.lock.word, memory_order_relaxed)) ==
|
||||
atomic_load_explicit(&__get_tls()->tib_ptid, memory_order_relaxed);
|
||||
}
|
||||
|
||||
bool __maps_reentrant(void) {
|
||||
return __tls_enabled && !(__get_tls()->tib_flags & TIB_FLAG_VFORKED) &&
|
||||
MUTEX_OWNER(
|
||||
atomic_load_explicit(&__maps.lock.word, memory_order_relaxed)) ==
|
||||
|
|
|
@ -84,6 +84,7 @@ void __maps_init(void);
|
|||
void __maps_lock(void);
|
||||
void __maps_check(void);
|
||||
void __maps_unlock(void);
|
||||
bool __maps_reentrant(void);
|
||||
void *__maps_randaddr(void);
|
||||
void __maps_add(struct Map *);
|
||||
void __maps_free(struct Map *);
|
||||
|
@ -103,28 +104,28 @@ forceinline optimizespeed int __maps_search(const void *key,
|
|||
return (addr > map->addr) - (addr < map->addr);
|
||||
}
|
||||
|
||||
dontinstrument static inline struct Map *__maps_next(struct Map *map) {
|
||||
static inline struct Map *__maps_next(struct Map *map) {
|
||||
struct Tree *node;
|
||||
if ((node = tree_next(&map->tree)))
|
||||
return MAP_TREE_CONTAINER(node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dontinstrument static inline struct Map *__maps_prev(struct Map *map) {
|
||||
static inline struct Map *__maps_prev(struct Map *map) {
|
||||
struct Tree *node;
|
||||
if ((node = tree_prev(&map->tree)))
|
||||
return MAP_TREE_CONTAINER(node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dontinstrument static inline struct Map *__maps_first(void) {
|
||||
static inline struct Map *__maps_first(void) {
|
||||
struct Tree *node;
|
||||
if ((node = tree_first(__maps.maps)))
|
||||
return MAP_TREE_CONTAINER(node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dontinstrument static inline struct Map *__maps_last(void) {
|
||||
static inline struct Map *__maps_last(void) {
|
||||
struct Tree *node;
|
||||
if ((node = tree_last(__maps.maps)))
|
||||
return MAP_TREE_CONTAINER(node);
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
#include "libc/thread/thread.h"
|
||||
#include "libc/thread/tls.h"
|
||||
|
||||
#define MMDEBUG 1
|
||||
#define MMDEBUG 0
|
||||
#define MAX_SIZE 0x0ff800000000ul
|
||||
|
||||
#define MAP_FIXED_NOREPLACE_linux 0x100000
|
||||
|
@ -94,8 +94,11 @@ privileged optimizespeed struct Map *__maps_floor(const char *addr) {
|
|||
}
|
||||
|
||||
static bool __maps_overlaps(const char *addr, size_t size) {
|
||||
struct Map *map, *floor = __maps_floor(addr);
|
||||
for (map = floor; map && map->addr <= addr + size; map = __maps_next(map))
|
||||
struct Map *map;
|
||||
ASSERT(__maps_held());
|
||||
if (!(map = __maps_floor(addr)))
|
||||
map = __maps_first();
|
||||
for (; map && map->addr <= addr + size; map = __maps_next(map))
|
||||
if (MAX(addr, map->addr) <
|
||||
MIN(addr + PGUP(size), map->addr + PGUP(map->size)))
|
||||
return true;
|
||||
|
@ -105,30 +108,33 @@ static bool __maps_overlaps(const char *addr, size_t size) {
|
|||
// returns true if all fragments of all allocations which overlap
|
||||
// [addr,addr+size) are completely contained by [addr,addr+size).
|
||||
textwindows static bool __maps_envelops(const char *addr, size_t size) {
|
||||
struct Map *map, *next;
|
||||
struct Map *map;
|
||||
size = PGUP(size);
|
||||
ASSERT(__maps_held());
|
||||
if (!(map = __maps_floor(addr)))
|
||||
if (!(map = __maps_first()))
|
||||
return true;
|
||||
do {
|
||||
if (MAX(addr, map->addr) >= MIN(addr + size, map->addr + map->size))
|
||||
break; // didn't overlap mapping
|
||||
if (!__maps_isalloc(map))
|
||||
return false; // didn't include first fragment of alloc
|
||||
if (addr > map->addr)
|
||||
return false; // excluded leading pages of first fragment
|
||||
// set map to last fragment in allocation
|
||||
for (; (next = __maps_next(map)) && !__maps_isalloc(next); map = next)
|
||||
// fragments within an allocation must be perfectly contiguous
|
||||
ASSERT(map->addr + map->size == next->addr);
|
||||
if (addr + size < map->addr + PGUP(map->size))
|
||||
return false; // excluded trailing pages of allocation
|
||||
} while ((map = next));
|
||||
map = __maps_first();
|
||||
while (map && map->addr <= addr + size) {
|
||||
if (MAX(addr, map->addr) < MIN(addr + size, map->addr + map->size)) {
|
||||
if (!__maps_isalloc(map))
|
||||
return false; // didn't include first fragment of alloc
|
||||
if (addr > map->addr)
|
||||
return false; // excluded leading pages of first fragment
|
||||
struct Map *next; // set map to last fragment in allocation
|
||||
for (; (next = __maps_next(map)) && !__maps_isalloc(next); map = next)
|
||||
ASSERT(map->addr + map->size == next->addr); // contiguous
|
||||
if (addr + size < map->addr + PGUP(map->size))
|
||||
return false; // excluded trailing pages of allocation
|
||||
map = next;
|
||||
} else {
|
||||
map = __maps_next(map);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void __maps_check(void) {
|
||||
#if MMDEBUG
|
||||
ASSERT(__maps_held());
|
||||
size_t maps = 0;
|
||||
size_t pages = 0;
|
||||
static unsigned mono;
|
||||
|
@ -152,6 +158,22 @@ void __maps_check(void) {
|
|||
#endif
|
||||
}
|
||||
|
||||
#if MMDEBUG
|
||||
static void __maps_ok(void) {
|
||||
ASSERT(!__maps_reentrant());
|
||||
__maps_lock();
|
||||
__maps_check();
|
||||
__maps_unlock();
|
||||
}
|
||||
__attribute__((__constructor__)) static void __maps_ctor(void) {
|
||||
atexit(__maps_ok);
|
||||
__maps_ok();
|
||||
}
|
||||
__attribute__((__destructor__)) static void __maps_dtor(void) {
|
||||
__maps_ok();
|
||||
}
|
||||
#endif
|
||||
|
||||
static int __muntrack(char *addr, size_t size, struct Map **deleted,
|
||||
struct Map **untracked, struct Map temp[2]) {
|
||||
int rc = 0;
|
||||
|
@ -159,13 +181,14 @@ static int __muntrack(char *addr, size_t size, struct Map **deleted,
|
|||
struct Map *map;
|
||||
struct Map *next;
|
||||
size = PGUP(size);
|
||||
ASSERT(__maps_held());
|
||||
if (!(map = __maps_floor(addr)))
|
||||
map = __maps_first();
|
||||
for (; map && map->addr <= addr + size; map = next) {
|
||||
next = __maps_next(map);
|
||||
char *map_addr = map->addr;
|
||||
size_t map_size = map->size;
|
||||
if (!(MAX(addr, map_addr) < MIN(addr + size, map_addr + PGUP(map_size))))
|
||||
if (MAX(addr, map_addr) >= MIN(addr + size, map_addr + PGUP(map_size)))
|
||||
continue;
|
||||
if (addr <= map_addr && addr + size >= map_addr + PGUP(map_size)) {
|
||||
if (map->hand == MAPS_RESERVATION)
|
||||
|
@ -350,6 +373,7 @@ static bool __maps_mergeable(const struct Map *x, const struct Map *y) {
|
|||
void __maps_insert(struct Map *map) {
|
||||
struct Map *left, *right;
|
||||
ASSERT(map->size);
|
||||
ASSERT(__maps_held());
|
||||
ASSERT(!__maps_overlaps(map->addr, map->size));
|
||||
__maps.pages += (map->size + __pagesize - 1) / __pagesize;
|
||||
|
||||
|
@ -460,7 +484,7 @@ static int __munmap(char *addr, size_t size) {
|
|||
return einval();
|
||||
|
||||
// test for signal handler tragedy
|
||||
if (__maps_held())
|
||||
if (__maps_reentrant())
|
||||
return edeadlk();
|
||||
|
||||
// lock the memory manager
|
||||
|
@ -469,8 +493,10 @@ static int __munmap(char *addr, size_t size) {
|
|||
|
||||
// on windows we can only unmap whole allocations
|
||||
if (IsWindows())
|
||||
if (!__maps_envelops(addr, size))
|
||||
if (!__maps_envelops(addr, size)) {
|
||||
__maps_unlock();
|
||||
return enotsup();
|
||||
}
|
||||
|
||||
// untrack mappings
|
||||
int rc;
|
||||
|
@ -500,6 +526,7 @@ void *__maps_randaddr(void) {
|
|||
}
|
||||
|
||||
static void *__maps_pickaddr(size_t size) {
|
||||
ASSERT(__maps_held());
|
||||
char *addr = 0;
|
||||
struct Map *map, *prev;
|
||||
size = GRUP(size);
|
||||
|
@ -569,11 +596,15 @@ static void *__mmap_impl(char *addr, size_t size, int prot, int flags, int fd,
|
|||
noreplace = true;
|
||||
sysflags |= MAP_FIXED_NOREPLACE_linux;
|
||||
} else if (IsFreebsd() || IsNetbsd()) {
|
||||
// todo: insert a reservation like windows
|
||||
sysflags |= MAP_FIXED;
|
||||
__maps_lock();
|
||||
if (__maps_overlaps(addr, size)) {
|
||||
__maps_unlock();
|
||||
__maps_free(map);
|
||||
return (void *)eexist();
|
||||
}
|
||||
__maps_unlock();
|
||||
} else {
|
||||
noreplace = true;
|
||||
}
|
||||
|
@ -729,7 +760,7 @@ static void *__mmap(char *addr, size_t size, int prot, int flags, int fd,
|
|||
return (void *)enomem();
|
||||
|
||||
// test for signal handler reentry
|
||||
if (__maps_held())
|
||||
if (__maps_reentrant())
|
||||
return (void *)edeadlk();
|
||||
|
||||
// create memory mappping
|
||||
|
@ -874,7 +905,7 @@ static void *__mremap(char *old_addr, size_t old_size, size_t new_size,
|
|||
return (void *)enomem();
|
||||
|
||||
// test for signal handler reentry
|
||||
if (__maps_held())
|
||||
if (__maps_reentrant())
|
||||
return (void *)edeadlk();
|
||||
|
||||
// lock the memory manager
|
||||
|
|
|
@ -67,16 +67,17 @@ int __mprotect(char *addr, size_t size, int prot) {
|
|||
size = (size + pagesz - 1) & -pagesz;
|
||||
|
||||
// test for signal handler reentry
|
||||
if (__maps_held())
|
||||
if (__maps_reentrant())
|
||||
return edeadlk();
|
||||
|
||||
// change mappings
|
||||
int rc = 0;
|
||||
bool found = false;
|
||||
__maps_lock();
|
||||
struct Map *map, *floor;
|
||||
floor = __maps_floor(addr);
|
||||
for (map = floor; map && map->addr <= addr + size; map = __maps_next(map)) {
|
||||
struct Map *map;
|
||||
if (!(map = __maps_floor(addr)))
|
||||
map = __maps_first();
|
||||
for (; map && map->addr <= addr + size; map = __maps_next(map)) {
|
||||
char *map_addr = map->addr;
|
||||
size_t map_size = map->size;
|
||||
char *beg = MAX(addr, map_addr);
|
||||
|
@ -85,7 +86,7 @@ int __mprotect(char *addr, size_t size, int prot) {
|
|||
continue;
|
||||
found = true;
|
||||
if (addr <= map_addr && addr + size >= map_addr + PGUP(map_size)) {
|
||||
// change protection of entire mapping
|
||||
// change protection status of pages
|
||||
if (!__mprotect_chunk(map_addr, map_size, prot, map->iscow)) {
|
||||
map->prot = prot;
|
||||
} else {
|
||||
|
|
|
@ -31,32 +31,29 @@ textwindows int sys_msync_nt(char *addr, size_t size, int flags) {
|
|||
|
||||
if ((uintptr_t)addr & (__pagesize - 1))
|
||||
return einval();
|
||||
if (__maps_held())
|
||||
if (__maps_reentrant())
|
||||
return edeadlk();
|
||||
|
||||
int rc = 0;
|
||||
__maps_lock();
|
||||
struct Map *map, *next;
|
||||
struct Map *next, *map;
|
||||
if (!(map = __maps_floor(addr)))
|
||||
if (!(map = __maps_first()))
|
||||
return true;
|
||||
for (; map; map = next) {
|
||||
map = __maps_first();
|
||||
for (; map && map->addr <= addr + size; map = next) {
|
||||
next = __maps_next(map);
|
||||
if (!__maps_isalloc(map))
|
||||
continue;
|
||||
if (map->flags & MAP_ANONYMOUS)
|
||||
continue;
|
||||
if (MAX(addr, map->addr) >= MIN(addr + size, map->addr + map->size))
|
||||
break; // didn't overlap mapping
|
||||
continue; // didn't overlap mapping
|
||||
|
||||
// get true size of win32 allocation
|
||||
size_t allocsize = map->size;
|
||||
for (struct Map *map2 = next; map2; map2 = __maps_next(map2)) {
|
||||
if (!__maps_isalloc(map2) && map->addr + allocsize == map2->addr) {
|
||||
allocsize += map2->size;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
while (next && !__maps_isalloc(next) &&
|
||||
next->addr + allocsize == next->addr) {
|
||||
allocsize += next->size;
|
||||
next = __maps_next(next);
|
||||
}
|
||||
|
||||
// perform the flush
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/stack.h"
|
||||
#include "libc/runtime/symbols.internal.h"
|
||||
#include "libc/runtime/syslib.internal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/auxv.h"
|
||||
|
|
|
@ -82,11 +82,7 @@ void ShowCrashReports(void) {
|
|||
ss.ss_sp = crashstack;
|
||||
unassert(!sigaltstack(&ss, 0));
|
||||
InstallCrashHandler(SIGQUIT, 0);
|
||||
#ifdef __x86_64__
|
||||
InstallCrashHandler(SIGTRAP, 0);
|
||||
#else
|
||||
InstallCrashHandler(SIGTRAP, 0);
|
||||
#endif
|
||||
InstallCrashHandler(SIGFPE, 0);
|
||||
InstallCrashHandler(SIGILL, 0);
|
||||
InstallCrashHandler(SIGBUS, 0);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sig.internal.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/directmap.h"
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "libc/errno.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/intrin/dll.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/strace.h"
|
||||
#include "libc/nt/console.h"
|
||||
#include "libc/nt/enum/creationdisposition.h"
|
||||
|
@ -84,6 +83,23 @@ textwindows int sys_kill_nt(int pid, int sig) {
|
|||
}
|
||||
}
|
||||
|
||||
// attempt to signal via shared memory file
|
||||
//
|
||||
// now that we know the process exists, if it has a shared memory file
|
||||
// then we can be reasonably certain it's a cosmo process which should
|
||||
// be trusted to deliver its signal, unless it's a nine exterminations
|
||||
if (pid > 0 && sig != 9) {
|
||||
atomic_ulong *sigproc;
|
||||
if ((sigproc = __sig_map_process(pid, kNtOpenExisting))) {
|
||||
if (sig > 0)
|
||||
atomic_fetch_or_explicit(sigproc, 1ull << (sig - 1),
|
||||
memory_order_release);
|
||||
UnmapViewOfFile(sigproc);
|
||||
if (sig != 9)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// find existing handle we own for process
|
||||
//
|
||||
// this step should come first to verify process existence. this is
|
||||
|
@ -91,31 +107,9 @@ textwindows int sys_kill_nt(int pid, int sig) {
|
|||
// file exists, the process actually exists.
|
||||
int64_t handle, closeme = 0;
|
||||
if (!(handle = __proc_handle(pid))) {
|
||||
if ((handle = OpenProcess(kNtProcessTerminate, false, pid))) {
|
||||
STRACE("warning: kill() using raw win32 pid");
|
||||
closeme = handle;
|
||||
} else {
|
||||
goto OnError;
|
||||
}
|
||||
}
|
||||
|
||||
// attempt to signal via shared memory file
|
||||
//
|
||||
// now that we know the process exists, if it has a shared memory file
|
||||
// then we can be reasonably certain it's a cosmo process which should
|
||||
// be trusted to deliver its signal, unless it's a nine exterminations
|
||||
if (pid > 0) {
|
||||
atomic_ulong *sigproc;
|
||||
if ((sigproc = __sig_map_process(pid, kNtOpenExisting))) {
|
||||
if (sig > 0)
|
||||
atomic_fetch_or_explicit(sigproc, 1ull << (sig - 1),
|
||||
memory_order_release);
|
||||
UnmapViewOfFile(sigproc);
|
||||
if (closeme)
|
||||
CloseHandle(closeme);
|
||||
if (sig != 9)
|
||||
return 0;
|
||||
}
|
||||
if (!(handle = OpenProcess(kNtProcessTerminate, false, pid)))
|
||||
return eperm();
|
||||
closeme = handle;
|
||||
}
|
||||
|
||||
// perform actual kill
|
||||
|
@ -127,16 +121,7 @@ textwindows int sys_kill_nt(int pid, int sig) {
|
|||
CloseHandle(closeme);
|
||||
if (ok)
|
||||
return 0;
|
||||
|
||||
// handle error
|
||||
OnError:
|
||||
switch (GetLastError()) {
|
||||
case kNtErrorInvalidHandle:
|
||||
case kNtErrorInvalidParameter:
|
||||
return esrch();
|
||||
default:
|
||||
return eperm();
|
||||
}
|
||||
return esrch();
|
||||
}
|
||||
|
||||
#endif /* __x86_64__ */
|
||||
|
|
|
@ -112,7 +112,7 @@ __msabi extern typeof(GetCurrentThreadId) *const __imp_GetCurrentThreadId;
|
|||
__msabi extern typeof(TlsSetValue) *const __imp_TlsSetValue;
|
||||
__msabi extern typeof(WakeByAddressAll) *const __imp_WakeByAddressAll;
|
||||
|
||||
static textwindows dontinstrument wontreturn void //
|
||||
textwindows dontinstrument wontreturn static void //
|
||||
WinThreadEntry(int rdi, // rcx
|
||||
int rsi, // rdx
|
||||
int rdx, // r8
|
||||
|
@ -185,7 +185,7 @@ asm("XnuThreadThunk:\n\t"
|
|||
".size\tXnuThreadThunk,.-XnuThreadThunk");
|
||||
__attribute__((__used__))
|
||||
|
||||
static wontreturn void
|
||||
static dontinstrument wontreturn void
|
||||
XnuThreadMain(void *pthread, // rdi
|
||||
int tid, // rsi
|
||||
int (*func)(void *arg, int tid), // rdx
|
||||
|
@ -265,7 +265,7 @@ static errno_t CloneXnu(int (*fn)(void *), char *stk, size_t stksz, int flags,
|
|||
|
||||
// we can't use address sanitizer because:
|
||||
// 1. __asan_handle_no_return wipes stack [todo?]
|
||||
relegated static wontreturn void OpenbsdThreadMain(void *p) {
|
||||
relegated dontinstrument wontreturn static void OpenbsdThreadMain(void *p) {
|
||||
struct CloneArgs *wt = p;
|
||||
atomic_init(wt->ptid, wt->tid);
|
||||
atomic_init(wt->ctid, wt->tid);
|
||||
|
@ -318,11 +318,12 @@ relegated errno_t CloneOpenbsd(int (*func)(void *, int), char *stk,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NET BESIYATA DISHMAYA
|
||||
|
||||
static wontreturn void NetbsdThreadMain(void *arg, // rdi
|
||||
int (*func)(void *, int), // rsi
|
||||
int flags, // rdx
|
||||
atomic_int *ctid, // rcx
|
||||
atomic_int *ptid) { // r8
|
||||
wontreturn dontinstrument static void NetbsdThreadMain(
|
||||
void *arg, // rdi
|
||||
int (*func)(void *, int), // rsi
|
||||
int flags, // rdx
|
||||
atomic_int *ctid, // rcx
|
||||
atomic_int *ptid) { // r8
|
||||
int ax, dx;
|
||||
static atomic_int clobber;
|
||||
atomic_int *ztid = &clobber;
|
||||
|
@ -420,7 +421,7 @@ static int CloneNetbsd(int (*func)(void *, int), char *stk, size_t stksz,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// FREE BESIYATA DISHMAYA
|
||||
|
||||
static wontreturn void FreebsdThreadMain(void *p) {
|
||||
wontreturn dontinstrument static void FreebsdThreadMain(void *p) {
|
||||
struct CloneArgs *wt = p;
|
||||
#ifdef __aarch64__
|
||||
asm volatile("mov\tx28,%0" : /* no outputs */ : "r"(wt->tls));
|
||||
|
@ -519,7 +520,7 @@ static errno_t CloneFreebsd(int (*func)(void *, int), char *stk, size_t stksz,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// APPLE SILICON
|
||||
|
||||
static void *SiliconThreadMain(void *arg) {
|
||||
dontinstrument static void *SiliconThreadMain(void *arg) {
|
||||
struct CloneArgs *wt = arg;
|
||||
asm volatile("mov\tx28,%0" : /* no outputs */ : "r"(wt->tls));
|
||||
atomic_init(wt->ctid, wt->this);
|
||||
|
@ -595,7 +596,7 @@ int sys_clone_linux(int flags, // rdi
|
|||
void *func, // r9
|
||||
void *arg); // 8(rsp)
|
||||
|
||||
static int LinuxThreadEntry(void *arg, int tid) {
|
||||
dontinstrument static int LinuxThreadEntry(void *arg, int tid) {
|
||||
struct LinuxCloneArgs *wt = arg;
|
||||
#if defined(__x86_64__)
|
||||
sys_set_tls(ARCH_SET_GS, wt->tls);
|
||||
|
|
|
@ -119,6 +119,7 @@ privileged int __hook(void *dest, struct SymbolTable *st) {
|
|||
if (!st)
|
||||
return -1;
|
||||
__morph_begin();
|
||||
__jit_begin();
|
||||
lowest = MAX((intptr_t)__executable_start, (intptr_t)_ereal);
|
||||
for (i = 0; i < st->count; ++i) {
|
||||
if (st->symbols[i].x < 9)
|
||||
|
@ -138,6 +139,9 @@ privileged int __hook(void *dest, struct SymbolTable *st) {
|
|||
// kprintf("can't hook %t at %lx\n", p, p);
|
||||
}
|
||||
}
|
||||
__clear_cache(MAX((char *)__executable_start, (char *)_ereal),
|
||||
MIN((char *)__privileged_start, (char *)_etext));
|
||||
__jit_end();
|
||||
__morph_end();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/syslib.internal.h"
|
||||
|
||||
void __jit_begin(void) {
|
||||
privileged void __jit_begin(void) {
|
||||
if (IsXnuSilicon()) {
|
||||
if (__syslib->__pthread_jit_write_protect_supported_np()) {
|
||||
__syslib->__pthread_jit_write_protect_np(false);
|
||||
|
@ -28,7 +28,7 @@ void __jit_begin(void) {
|
|||
}
|
||||
}
|
||||
|
||||
void __jit_end(void) {
|
||||
privileged void __jit_end(void) {
|
||||
if (IsXnuSilicon()) {
|
||||
if (__syslib->__pthread_jit_write_protect_supported_np()) {
|
||||
__syslib->__pthread_jit_write_protect_np(true);
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/runtime/zipos.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
@ -44,9 +43,8 @@ ssize_t __zipos_scan(struct Zipos *zipos, struct ZiposUri *name) {
|
|||
|
||||
// strip trailing slash from search name
|
||||
int len = name->len;
|
||||
if (len && name->path[len - 1] == '/') {
|
||||
if (len && name->path[len - 1] == '/')
|
||||
--len;
|
||||
}
|
||||
|
||||
// empty string means the /zip root directory
|
||||
if (!len) {
|
||||
|
@ -91,9 +89,8 @@ ssize_t __zipos_scan(struct Zipos *zipos, struct ZiposUri *name) {
|
|||
dx = dx < -1 ? -1 : dx;
|
||||
for (l += dx; 0 <= l && l < zipos->records; l += dx) {
|
||||
ssize_t cf;
|
||||
if ((cf = __zipos_match(zipos, name, len, l)) != -1) {
|
||||
if ((cf = __zipos_match(zipos, name, len, l)) != -1)
|
||||
return cf;
|
||||
}
|
||||
cfile = zipos->index[l];
|
||||
zname = ZIP_CFILE_NAME(zipos->map + cfile);
|
||||
zsize = ZIP_CFILE_NAMESIZE(zipos->map + cfile);
|
||||
|
|
|
@ -118,9 +118,10 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
GetOpts(argc, argv);
|
||||
|
||||
for (fd = 3; fd < 100; ++fd) {
|
||||
int oe = errno;
|
||||
for (fd = 3; fd < 100; ++fd)
|
||||
close(fd);
|
||||
}
|
||||
errno = oe;
|
||||
|
||||
#ifndef TINY
|
||||
setenv("GDB", "", true);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue