mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-03 11:12:27 +00:00
Fix bugs with recent change
This change makes further effort towards improving our poll() implementation on the New Technology. The stdin worker didn't work out so well for Python so it's not being used for now. System call tracing with the --strace flag should now be less noisy now on Windows unless you modify the strace.internal.h defines to turn on some optional ones that are most useful for debugging the system call wrappers.
This commit is contained in:
parent
933411ba99
commit
dc0ea6640e
127 changed files with 1354 additions and 866 deletions
|
@ -90,11 +90,14 @@ cosmo: push %rbp
|
|||
#if IsModeDbg()
|
||||
#ifdef SYSDEBUG
|
||||
.init.start 307,_init_printargs
|
||||
cmpl $0,__strace(%rip)
|
||||
jz 1f
|
||||
push %rdi
|
||||
push %rsi
|
||||
loadstr STRACE_PROLOGUE,di
|
||||
call __printargs
|
||||
pop %rsi
|
||||
pop %rdi
|
||||
.init.end 307,_init_printargs
|
||||
1: .init.end 307,_init_printargs
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
STATIC_YOINK("_check_sigchld");
|
||||
|
||||
extern int __pid;
|
||||
extern int64_t __wincrashearly;
|
||||
extern unsigned long long __kbirth;
|
||||
extern unsigned char __data_start[]; /* αpε */
|
||||
extern unsigned char __data_end[]; /* αpε */
|
||||
|
@ -59,6 +60,11 @@ extern unsigned char __bss_start[]; /* αpε */
|
|||
extern unsigned char __bss_end[]; /* αpε */
|
||||
bool32 __onntconsoleevent_nt(uint32_t);
|
||||
|
||||
static textwindows wontreturn void KillForkChild(const char *func) {
|
||||
STRACE("fork() %s() failed %d", func, GetLastError());
|
||||
ExitProcess(177);
|
||||
}
|
||||
|
||||
static textwindows char16_t *ParseInt(char16_t *p, int64_t *x) {
|
||||
*x = 0;
|
||||
while (*p == ' ') p++;
|
||||
|
@ -84,7 +90,7 @@ static inline textwindows ssize_t ForkIo(int64_t h, char *p, size_t n,
|
|||
static dontinline textwindows bool ForkIo2(int64_t h, void *buf, size_t n,
|
||||
bool32 (*fn)(), const char *sf) {
|
||||
ssize_t rc = ForkIo(h, buf, n, fn);
|
||||
// STRACE("%s(%ld, %'zu) → %'zd% m", sf, h, n, rc);
|
||||
NTTRACE("%s(%ld, %'zu) → %'zd% m", sf, h, n, rc);
|
||||
return rc != -1;
|
||||
}
|
||||
|
||||
|
@ -92,8 +98,10 @@ static dontinline textwindows bool WriteAll(int64_t h, void *buf, size_t n) {
|
|||
return ForkIo2(h, buf, n, WriteFile, "WriteFile");
|
||||
}
|
||||
|
||||
static textwindows dontinline bool ReadAll(int64_t h, void *buf, size_t n) {
|
||||
return ForkIo2(h, buf, n, ReadFile, "ReadFile");
|
||||
static textwindows dontinline void ReadOrDie(int64_t h, void *buf, size_t n) {
|
||||
if (!ForkIo2(h, buf, n, ReadFile, "ReadFile")) {
|
||||
KillForkChild("ReadFile");
|
||||
}
|
||||
}
|
||||
|
||||
textwindows void WinMainForked(void) {
|
||||
|
@ -114,7 +122,7 @@ textwindows void WinMainForked(void) {
|
|||
// this variable should have the pipe handle numba
|
||||
varlen = GetEnvironmentVariable(u"_FORK", fvar, ARRAYLEN(fvar));
|
||||
if (!varlen || varlen >= ARRAYLEN(fvar)) return;
|
||||
STRACE("WinMainForked()");
|
||||
NTTRACE("WinMainForked()");
|
||||
SetEnvironmentVariable(u"_FORK", NULL);
|
||||
ParseInt(fvar, &reader);
|
||||
|
||||
|
@ -123,21 +131,21 @@ textwindows void WinMainForked(void) {
|
|||
// this is stored in a special secretive memory map!
|
||||
// read ExtendMemoryIntervals for further details :|
|
||||
maps = (void *)kMemtrackStart;
|
||||
ReadAll(reader, jb, sizeof(jb));
|
||||
ReadAll(reader, &mapcount, sizeof(_mmi.i));
|
||||
ReadAll(reader, &mapcapacity, sizeof(_mmi.n));
|
||||
ReadOrDie(reader, jb, sizeof(jb));
|
||||
ReadOrDie(reader, &mapcount, sizeof(_mmi.i));
|
||||
ReadOrDie(reader, &mapcapacity, sizeof(_mmi.n));
|
||||
specialz = ROUNDUP(mapcapacity * sizeof(_mmi.p[0]), kMemtrackGran);
|
||||
MapViewOfFileEx(
|
||||
CreateFileMapping(-1, 0, kNtPageReadwrite, specialz >> 32, specialz, 0),
|
||||
kNtFileMapWrite, 0, 0, specialz, maps);
|
||||
ReadAll(reader, maps, mapcount * sizeof(_mmi.p[0]));
|
||||
ReadOrDie(reader, maps, mapcount * sizeof(_mmi.p[0]));
|
||||
if (IsAsan()) {
|
||||
shad = (char *)(((intptr_t)maps >> 3) + 0x7fff8000);
|
||||
size = ROUNDUP(specialz >> 3, FRAMESIZE);
|
||||
MapViewOfFileEx(
|
||||
CreateFileMapping(-1, 0, kNtPageReadwrite, size >> 32, size, 0),
|
||||
kNtFileMapWrite, 0, 0, size, maps);
|
||||
ReadAll(reader, shad, (mapcount * sizeof(_mmi.p[0])) >> 3);
|
||||
ReadOrDie(reader, shad, (mapcount * sizeof(_mmi.p[0])) >> 3);
|
||||
}
|
||||
|
||||
// read the heap mappings from the parent process
|
||||
|
@ -152,7 +160,7 @@ textwindows void WinMainForked(void) {
|
|||
upsize >> 32, upsize, 0);
|
||||
MapViewOfFileEx(maps[i].h, kNtFileMapWrite | kNtFileMapExecute, 0, 0,
|
||||
upsize, addr);
|
||||
ReadAll(reader, addr, size);
|
||||
ReadOrDie(reader, addr, size);
|
||||
} else {
|
||||
// we can however safely inherit MAP_SHARED with zero copy
|
||||
MapViewOfFileEx(maps[i].h,
|
||||
|
@ -167,8 +175,8 @@ textwindows void WinMainForked(void) {
|
|||
savepid = __pid;
|
||||
savebir = __kbirth;
|
||||
savetsc = ts;
|
||||
ReadAll(reader, __data_start, __data_end - __data_start);
|
||||
ReadAll(reader, __bss_start, __bss_end - __bss_start);
|
||||
ReadOrDie(reader, __data_start, __data_end - __data_start);
|
||||
ReadOrDie(reader, __bss_start, __bss_end - __bss_start);
|
||||
__pid = savepid;
|
||||
__kbirth = savebir;
|
||||
ts = savetsc;
|
||||
|
@ -177,23 +185,28 @@ textwindows void WinMainForked(void) {
|
|||
_mmi.p = maps;
|
||||
_mmi.n = specialz / sizeof(_mmi.p[0]);
|
||||
for (i = 0; i < mapcount; ++i) {
|
||||
VirtualProtect((void *)((uint64_t)maps[i].x << 16), maps[i].size,
|
||||
__prot2nt(maps[i].prot, maps[i].iscow), &oldprot);
|
||||
if (!VirtualProtect((void *)((uint64_t)maps[i].x << 16), maps[i].size,
|
||||
__prot2nt(maps[i].prot, maps[i].iscow), &oldprot)) {
|
||||
KillForkChild("VirtualProtect");
|
||||
}
|
||||
}
|
||||
|
||||
// mitosis complete
|
||||
CloseHandle(reader);
|
||||
if (!CloseHandle(reader)) {
|
||||
KillForkChild("CloseHandle");
|
||||
}
|
||||
|
||||
// rewrap the stdin named pipe hack
|
||||
// since the handles closed on fork
|
||||
if (weaken(ForkNtStdinWorker)) weaken(ForkNtStdinWorker)();
|
||||
struct Fds *fds = VEIL("r", &g_fds);
|
||||
fds->__init_p[0].handle = GetStdHandle(kNtStdInputHandle); // just in case
|
||||
fds->__init_p[1].handle = GetStdHandle(kNtStdOutputHandle); // just in case
|
||||
fds->__init_p[2].handle = GetStdHandle(kNtStdErrorHandle); // just in case
|
||||
fds->__init_p[0].handle = GetStdHandle(kNtStdInputHandle);
|
||||
fds->__init_p[1].handle = GetStdHandle(kNtStdOutputHandle);
|
||||
fds->__init_p[2].handle = GetStdHandle(kNtStdErrorHandle);
|
||||
|
||||
// restore the crash reporting stuff
|
||||
if (weaken(__wincrash_nt)) {
|
||||
RemoveVectoredExceptionHandler(__wincrashearly);
|
||||
AddVectoredExceptionHandler(1, (void *)weaken(__wincrash_nt));
|
||||
}
|
||||
if (weaken(__onntconsoleevent_nt)) {
|
||||
|
|
|
@ -48,9 +48,8 @@ void ftrace_hook(void);
|
|||
|
||||
bool ftrace_enabled;
|
||||
static int g_skew;
|
||||
static int g_lastsymbol;
|
||||
static uint64_t laststamp;
|
||||
static struct SymbolTable *g_symbols;
|
||||
static int64_t g_lastaddr;
|
||||
static uint64_t g_laststamp;
|
||||
|
||||
static privileged noinstrument noasan noubsan int GetNestingLevelImpl(
|
||||
struct StackFrame *frame) {
|
||||
|
@ -80,34 +79,31 @@ static privileged noinstrument noasan noubsan int GetNestingLevel(
|
|||
*/
|
||||
privileged noinstrument noasan noubsan void ftracer(void) {
|
||||
/* asan runtime depends on this function */
|
||||
int symbol;
|
||||
uint64_t stamp;
|
||||
static bool noreentry;
|
||||
struct StackFrame *frame;
|
||||
if (!_cmpxchg(&noreentry, 0, 1)) return;
|
||||
if (ftrace_enabled && g_symbols) {
|
||||
if (ftrace_enabled) {
|
||||
stamp = rdtsc();
|
||||
frame = __builtin_frame_address(0);
|
||||
frame = frame->next;
|
||||
if ((symbol = __get_symbol(g_symbols, frame->addr)) != -1 &&
|
||||
symbol != g_lastsymbol) {
|
||||
g_lastsymbol = symbol;
|
||||
kprintf("+ %*s%s %d\r\n", GetNestingLevel(frame) * 2, "",
|
||||
__get_symbol_name(g_symbols, symbol),
|
||||
(long)(unsignedsubtract(stamp, laststamp) / 3.3));
|
||||
laststamp = X86_HAVE(RDTSCP) ? rdtscp(0) : rdtsc();
|
||||
if (frame->addr != g_lastaddr) {
|
||||
kprintf("+ %*s%t %d\r\n", GetNestingLevel(frame) * 2, "", frame->addr,
|
||||
(long)(unsignedsubtract(stamp, g_laststamp) / 3.3));
|
||||
g_laststamp = X86_HAVE(RDTSCP) ? rdtscp(0) : rdtsc();
|
||||
g_lastaddr = frame->addr;
|
||||
}
|
||||
}
|
||||
noreentry = 0;
|
||||
}
|
||||
|
||||
textstartup void ftrace_install(void) {
|
||||
if ((g_symbols = GetSymbolTable())) {
|
||||
laststamp = kStartTsc;
|
||||
g_lastsymbol = -1;
|
||||
if (GetSymbolTable()) {
|
||||
g_lastaddr = -1;
|
||||
g_laststamp = kStartTsc;
|
||||
g_skew = GetNestingLevelImpl(__builtin_frame_address(0));
|
||||
ftrace_enabled = 1;
|
||||
__hook(ftrace_hook, g_symbols);
|
||||
__hook(ftrace_hook, GetSymbolTable());
|
||||
} else {
|
||||
kprintf("error: --ftrace failed to open symbol table\r\n");
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ char *GetInterpreterExecutableName(char *p, size_t n) {
|
|||
e = errno;
|
||||
if (n < 2) {
|
||||
errno = ENAMETOOLONG;
|
||||
} else if (IsWindows()) {
|
||||
} else if (IsWindows() || IsXnu()) {
|
||||
if (strlen(GetProgramExecutableName()) < n) {
|
||||
strcpy(p, GetProgramExecutableName());
|
||||
return p;
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 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/runtime/symbols.internal.h"
|
||||
|
||||
privileged noinstrument noasan noubsan int __get_symbol(struct SymbolTable *t,
|
||||
intptr_t a) {
|
||||
/* asan runtime depends on this function */
|
||||
unsigned l, m, r, n, k;
|
||||
if (t) {
|
||||
l = 0;
|
||||
r = n = t->count;
|
||||
k = a - t->addr_base;
|
||||
while (l < r) {
|
||||
m = (l + r) >> 1;
|
||||
if (t->symbols[m].y < k) {
|
||||
l = m + 1;
|
||||
} else {
|
||||
r = m;
|
||||
}
|
||||
}
|
||||
if (l < n && t->symbols[l].x <= k && k <= t->symbols[l].y) {
|
||||
return l;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
|
@ -29,10 +29,12 @@
|
|||
#include "libc/zip.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
static struct SymbolTable *g_symtab;
|
||||
|
||||
/**
|
||||
* Looks for `.symtab` in zip central directory.
|
||||
*/
|
||||
noasan static ssize_t FindSymtabInZip(struct Zipos *zipos) {
|
||||
static ssize_t FindSymtabInZip(struct Zipos *zipos) {
|
||||
size_t i, n, c;
|
||||
c = GetZipCdirOffset(zipos->cdir);
|
||||
n = GetZipCdirRecords(zipos->cdir);
|
||||
|
@ -51,7 +53,7 @@ noasan static ssize_t FindSymtabInZip(struct Zipos *zipos) {
|
|||
* Reads symbol table from zip directory.
|
||||
* @note This code can't depend on dlmalloc()
|
||||
*/
|
||||
noasan static struct SymbolTable *GetSymbolTableFromZip(struct Zipos *zipos) {
|
||||
static struct SymbolTable *GetSymbolTableFromZip(struct Zipos *zipos) {
|
||||
ssize_t cf, lf;
|
||||
size_t size, size2;
|
||||
struct DeflateState ds;
|
||||
|
@ -88,7 +90,7 @@ noasan static struct SymbolTable *GetSymbolTableFromZip(struct Zipos *zipos) {
|
|||
* Reads symbol table from .com.dbg file.
|
||||
* @note This code can't depend on dlmalloc()
|
||||
*/
|
||||
noasan static struct SymbolTable *GetSymbolTableFromElf(void) {
|
||||
static struct SymbolTable *GetSymbolTableFromElf(void) {
|
||||
return OpenSymbolTable(FindDebugBinary());
|
||||
}
|
||||
|
||||
|
@ -112,24 +114,56 @@ noasan static struct SymbolTable *GetSymbolTableFromElf(void) {
|
|||
*
|
||||
* @return symbol table, or NULL w/ errno on first call
|
||||
*/
|
||||
noasan struct SymbolTable *GetSymbolTable(void) {
|
||||
struct SymbolTable *GetSymbolTable(void) {
|
||||
int ft, st;
|
||||
struct Zipos *z;
|
||||
static struct SymbolTable *t;
|
||||
if (!t) {
|
||||
if (!g_symtab) {
|
||||
ft = g_ftrace, g_ftrace = 0;
|
||||
st = __strace, __strace = 0;
|
||||
if (weaken(__zipos_get) && (z = weaken(__zipos_get)())) {
|
||||
if ((t = GetSymbolTableFromZip(z))) {
|
||||
t->names = (uint32_t *)((char *)t + t->names_offset);
|
||||
t->name_base = (char *)((char *)t + t->name_base_offset);
|
||||
if ((g_symtab = GetSymbolTableFromZip(z))) {
|
||||
g_symtab->names =
|
||||
(uint32_t *)((char *)g_symtab + g_symtab->names_offset);
|
||||
g_symtab->name_base =
|
||||
(char *)((char *)g_symtab + g_symtab->name_base_offset);
|
||||
}
|
||||
}
|
||||
if (!t) {
|
||||
t = GetSymbolTableFromElf();
|
||||
if (!g_symtab) {
|
||||
g_symtab = GetSymbolTableFromElf();
|
||||
}
|
||||
g_ftrace = ft;
|
||||
__strace = st;
|
||||
}
|
||||
return t;
|
||||
return g_symtab;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns low index into symbol table for address.
|
||||
*
|
||||
* @param t if null will be auto-populated only if already open
|
||||
* @return index or -1 if nothing found
|
||||
*/
|
||||
privileged int __get_symbol(struct SymbolTable *t, intptr_t a) {
|
||||
/* asan runtime depends on this function */
|
||||
unsigned l, m, r, n, k;
|
||||
if (!t && g_symtab) {
|
||||
t = g_symtab;
|
||||
}
|
||||
if (t) {
|
||||
l = 0;
|
||||
r = n = t->count;
|
||||
k = a - t->addr_base;
|
||||
while (l < r) {
|
||||
m = (l + r) >> 1;
|
||||
if (t->symbols[m].y < k) {
|
||||
l = m + 1;
|
||||
} else {
|
||||
r = m;
|
||||
}
|
||||
}
|
||||
if (l < n && t->symbols[l].x <= k && k <= t->symbols[l].y) {
|
||||
return l;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -180,7 +180,7 @@ void *mremap(void *p, size_t n, size_t m, int f, ... /* void *q */) {
|
|||
}
|
||||
q = sys_mremap((void *)p, n, m, MREMAP_MAYMOVE | MREMAP_FIXED,
|
||||
(void *)ADDR(a));
|
||||
STRACE("sys_mremap(%p, %'zu, %'zu, %#b, %p) → %p", p, n, m,
|
||||
KERNTRACE("sys_mremap(%p, %'zu, %'zu, %#b, %p) → %p", p, n, m,
|
||||
MREMAP_MAYMOVE | MREMAP_FIXED, ADDR(a), q);
|
||||
if (q == MAP_FAILED) return 0;
|
||||
if (ReleaseMemoryIntervals(&_mmi, (uintptr_t)p >> 16,
|
||||
|
|
|
@ -1,245 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 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/calls/calls.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/enum/startf.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/startupinfo.h"
|
||||
#include "libc/nt/struct/ldrdatatableentry.h"
|
||||
#include "libc/nt/struct/startupinfo.h"
|
||||
#include "libc/nt/struct/teb.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/stack.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/sysv/consts/auxv.h"
|
||||
#include "libc/sysv/consts/f.h"
|
||||
#include "libc/sysv/consts/poll.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
|
||||
#define PRINT(FMT, ...) kprintf(STRACE_PROLOGUE FMT "%n", ##__VA_ARGS__)
|
||||
|
||||
static const struct AuxiliaryValue {
|
||||
const char *fmt;
|
||||
long *id;
|
||||
const char *name;
|
||||
} kAuxiliaryValues[] = {
|
||||
{"%-14p", &AT_EXECFD, "AT_EXECFD"},
|
||||
{"%-14p", &AT_PHDR, "AT_PHDR"},
|
||||
{"%-14p", &AT_PHENT, "AT_PHENT"},
|
||||
{"%-14p", &AT_PHNUM, "AT_PHNUM"},
|
||||
{"%-14p", &AT_PAGESZ, "AT_PAGESZ"},
|
||||
{"%-14p", &AT_BASE, "AT_BASE"},
|
||||
{"%-14p", &AT_ENTRY, "AT_ENTRY"},
|
||||
{"%-14p", &AT_NOTELF, "AT_NOTELF"},
|
||||
{"%-14d", &AT_UID, "AT_UID"},
|
||||
{"%-14d", &AT_EUID, "AT_EUID"},
|
||||
{"%-14d", &AT_GID, "AT_GID"},
|
||||
{"%-14d", &AT_EGID, "AT_EGID"},
|
||||
{"%-14d", &AT_CLKTCK, "AT_CLKTCK"},
|
||||
{"%-14d", &AT_OSRELDATE, "AT_OSRELDATE"},
|
||||
{"%-14p", &AT_PLATFORM, "AT_PLATFORM"},
|
||||
{"%-14p", &AT_DCACHEBSIZE, "AT_DCACHEBSIZE"},
|
||||
{"%-14p", &AT_ICACHEBSIZE, "AT_ICACHEBSIZE"},
|
||||
{"%-14p", &AT_UCACHEBSIZE, "AT_UCACHEBSIZE"},
|
||||
{"%-14p", &AT_SECURE, "AT_SECURE"},
|
||||
{"%-14s", &AT_BASE_PLATFORM, "AT_BASE_PLATFORM"},
|
||||
{"%-14p", &AT_RANDOM, "AT_RANDOM"},
|
||||
{"%-14s", &AT_EXECFN, "AT_EXECFN"},
|
||||
{"%-14p", &AT_SYSINFO_EHDR, "AT_SYSINFO_EHDR"},
|
||||
{"%-14p", &AT_FLAGS, "AT_FLAGS"},
|
||||
{"%-14p", &AT_HWCAP, "AT_HWCAP"},
|
||||
{"%-14p", &AT_HWCAP2, "AT_HWCAP2"},
|
||||
{"%-14p", &AT_STACKBASE, "AT_STACKBASE"},
|
||||
{"%-14p", &AT_CANARY, "AT_CANARY"},
|
||||
{"%-14p", &AT_CANARYLEN, "AT_CANARYLEN"},
|
||||
{"%-14ld", &AT_NCPUS, "AT_NCPUS"},
|
||||
{"%-14p", &AT_PAGESIZES, "AT_PAGESIZES"},
|
||||
{"%-14d", &AT_PAGESIZESLEN, "AT_PAGESIZESLEN"},
|
||||
{"%-14p", &AT_TIMEKEEP, "AT_TIMEKEEP"},
|
||||
{"%-14p", &AT_STACKPROT, "AT_STACKPROT"},
|
||||
{"%-14p", &AT_EHDRFLAGS, "AT_EHDRFLAGS"},
|
||||
};
|
||||
|
||||
static const struct AuxiliaryValue *DescribeAuxv(unsigned long x) {
|
||||
int i;
|
||||
for (i = 0; i < ARRAYLEN(kAuxiliaryValues); ++i) {
|
||||
if (*kAuxiliaryValues[i].id && x == *kAuxiliaryValues[i].id) {
|
||||
return kAuxiliaryValues + i;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
noasan textstartup void __printargs(void) {
|
||||
#ifdef SYSDEBUG
|
||||
int st;
|
||||
long key;
|
||||
char **env;
|
||||
unsigned i;
|
||||
sigset_t ss;
|
||||
uintptr_t *auxp;
|
||||
char path[PATH_MAX];
|
||||
struct pollfd pfds[128];
|
||||
struct AuxiliaryValue *auxinfo;
|
||||
if (__strace <= 0) return;
|
||||
st = __strace;
|
||||
__strace = 0;
|
||||
|
||||
PRINT("");
|
||||
PRINT("ARGUMENTS (%p)", __argv);
|
||||
for (i = 0; i < __argc; ++i) {
|
||||
PRINT(" ☼ %s", __argv[i]);
|
||||
}
|
||||
|
||||
PRINT("");
|
||||
PRINT("ENVIRONMENT (%p)", __envp);
|
||||
for (env = __envp; *env; ++env) {
|
||||
PRINT(" ☼ %s", *env);
|
||||
}
|
||||
|
||||
PRINT("");
|
||||
PRINT("AUXILIARY (%p)", __auxv);
|
||||
for (auxp = __auxv; *auxp; auxp += 2) {
|
||||
if ((auxinfo = DescribeAuxv(auxp[0]))) {
|
||||
ksnprintf(path, sizeof(path), auxinfo->fmt, auxp[1]);
|
||||
PRINT(" ☼ %16s[%4ld] = %s", auxinfo->name, auxp[0], path);
|
||||
} else {
|
||||
PRINT(" ☼ %16s[%4ld] = %014p", "unknown", auxp[0], auxp[1]);
|
||||
}
|
||||
}
|
||||
|
||||
PRINT("");
|
||||
PRINT("SPECIALS");
|
||||
PRINT(" ☼ %s = %#s", "kTmpPath", kTmpPath);
|
||||
PRINT(" ☼ %s = %#s", "kNtSystemDirectory", kNtSystemDirectory);
|
||||
PRINT(" ☼ %s = %#s", "kNtWindowsDirectory", kNtWindowsDirectory);
|
||||
PRINT(" ☼ %s = %#s", "program_executable_name", GetProgramExecutableName());
|
||||
PRINT(" ☼ %s = %#s", "GetInterpreterExecutableName()",
|
||||
GetInterpreterExecutableName(path, sizeof(path)));
|
||||
PRINT(" ☼ %s = %p", "RSP", __builtin_frame_address(0));
|
||||
PRINT(" ☼ %s = %p", "GetStackAddr()", GetStackAddr(0));
|
||||
PRINT(" ☼ %s = %p", "GetStaticStackAddr(0)", GetStaticStackAddr(0));
|
||||
PRINT(" ☼ %s = %p", "GetStackSize()", GetStackSize());
|
||||
|
||||
if (!IsWindows()) {
|
||||
PRINT("");
|
||||
PRINT("OPEN FILE DESCRIPTORS");
|
||||
for (i = 0; i < ARRAYLEN(pfds); ++i) {
|
||||
pfds[i].fd = i;
|
||||
pfds[i].events = 0;
|
||||
}
|
||||
if (sys_poll(pfds, ARRAYLEN(pfds), 0) != -1) {
|
||||
for (i = 0; i < ARRAYLEN(pfds); ++i) {
|
||||
if (~pfds[i].revents & POLLNVAL) {
|
||||
PRINT(" ☼ %d (F_GETFL=%#x)", i, fcntl(i, F_GETFL));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!sigprocmask(SIG_BLOCK, 0, &ss) && (ss.__bits[0] || ss.__bits[1])) {
|
||||
PRINT("");
|
||||
PRINT("BLOCKED SIGNALS {%#lx, %#lx}", ss.__bits[0], ss.__bits[1]);
|
||||
for (i = 0; i < 32; ++i) {
|
||||
if (ss.__bits[0] & (1u << i)) {
|
||||
PRINT(" ☼ %G (%d)", i + 1, i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IsWindows()) {
|
||||
struct NtStartupInfo startinfo;
|
||||
GetStartupInfo(&startinfo);
|
||||
|
||||
PRINT("");
|
||||
PRINT("GETSTARTUPINFO");
|
||||
if (startinfo.lpDesktop)
|
||||
PRINT(" ☼ %s = %#!hs", "lpDesktop", startinfo.lpDesktop);
|
||||
if (startinfo.lpTitle) PRINT(" ☼ %s = %#!hs", "lpTitle", startinfo.lpTitle);
|
||||
if (startinfo.dwX) PRINT(" ☼ %s = %u", "dwX", startinfo.dwX);
|
||||
if (startinfo.dwY) PRINT(" ☼ %s = %u", "dwY", startinfo.dwY);
|
||||
if (startinfo.dwXSize) PRINT(" ☼ %s = %u", "dwXSize", startinfo.dwXSize);
|
||||
if (startinfo.dwYSize) PRINT(" ☼ %s = %u", "dwYSize", startinfo.dwYSize);
|
||||
if (startinfo.dwXCountChars)
|
||||
PRINT(" ☼ %s = %u", "dwXCountChars", startinfo.dwXCountChars);
|
||||
if (startinfo.dwYCountChars)
|
||||
PRINT(" ☼ %s = %u", "dwYCountChars", startinfo.dwYCountChars);
|
||||
if (startinfo.dwFillAttribute)
|
||||
PRINT(" ☼ %s = %u", "dwFillAttribute", startinfo.dwFillAttribute);
|
||||
if (startinfo.dwFlags)
|
||||
PRINT(" ☼ %s = %s", "dwFlags", DescribeNtStartFlags(startinfo.dwFlags));
|
||||
if (startinfo.wShowWindow)
|
||||
PRINT(" ☼ %s = %hu", "wShowWindow", startinfo.wShowWindow);
|
||||
if (startinfo.cbReserved2)
|
||||
PRINT(" ☼ %s = %hu", "cbReserved2", startinfo.cbReserved2);
|
||||
if (startinfo.hStdInput)
|
||||
PRINT(" ☼ %s = %ld", "hStdInput", startinfo.hStdInput);
|
||||
if (startinfo.hStdOutput)
|
||||
PRINT(" ☼ %s = %ld", "hStdOutput", startinfo.hStdOutput);
|
||||
if (startinfo.hStdError)
|
||||
PRINT(" ☼ %s = %ld", "hStdError", startinfo.hStdError);
|
||||
|
||||
PRINT("");
|
||||
PRINT("STANDARD HANDLES");
|
||||
PRINT(" ☼ %s = %ld", "GetStdHandle(kNtStdInputHandle)",
|
||||
GetStdHandle(kNtStdInputHandle));
|
||||
PRINT(" ☼ %s = %ld", "GetStdHandle(kNtStdOutputHandle)",
|
||||
GetStdHandle(kNtStdOutputHandle));
|
||||
PRINT(" ☼ %s = %ld", "GetStdHandle(kNtStdErrorHandle)",
|
||||
GetStdHandle(kNtStdErrorHandle));
|
||||
|
||||
PRINT("");
|
||||
PRINT("TEB");
|
||||
PRINT(" ☼ gs:0x%02x %s = %p", 0x00, "NtGetSeh()", _NtGetSeh());
|
||||
PRINT(" ☼ gs:0x%02x %s = %p", 0x08, "NtGetStackHigh()", _NtGetStackHigh());
|
||||
PRINT(" ☼ gs:0x%02x %s = %p", 0x10, "NtGetStackLow()", _NtGetStackLow());
|
||||
PRINT(" ☼ gs:0x%02x %s = %p", 0x18, "_NtGetSubsystemTib()",
|
||||
_NtGetSubsystemTib());
|
||||
PRINT(" ☼ gs:0x%02x %s = %p", 0x20, "NtGetFib()", _NtGetFib());
|
||||
PRINT(" ☼ gs:0x%02x %s = %p", 0x30, "NtGetTeb()", NtGetTeb());
|
||||
PRINT(" ☼ gs:0x%02x %s = %p", 0x38, "NtGetEnv()", _NtGetEnv());
|
||||
PRINT(" ☼ gs:0x%02x %s = %p", 0x40, "NtGetPid()", NtGetPid());
|
||||
PRINT(" ☼ gs:0x%02x %s = %p", 0x48, "NtGetTid()", NtGetTid());
|
||||
PRINT(" ☼ gs:0x%02x %s = %p", 0x50, "NtGetRpc()", _NtGetRpc());
|
||||
PRINT(" ☼ gs:0x%02x %s = %p", 0x58, "NtGetTls()", _NtGetTls());
|
||||
PRINT(" ☼ gs:0x%02x %s = %p", 0x60, "NtGetPeb()", NtGetPeb());
|
||||
PRINT(" ☼ gs:0x%02x %s = %p", 0x68, "NtGetErr()", NtGetErr());
|
||||
|
||||
PRINT("");
|
||||
PRINT("DEPENDENCIES");
|
||||
struct NtLinkedList *head = &NtGetPeb()->Ldr->InLoadOrderModuleList;
|
||||
struct NtLinkedList *ldr = head->Next;
|
||||
do {
|
||||
const struct NtLdrDataTableEntry *dll =
|
||||
(const struct NtLdrDataTableEntry *)ldr;
|
||||
PRINT(" ☼ %.*!hs\t\t%'zu bytes", dll->FullDllName.Length,
|
||||
dll->FullDllName.Data, dll->SizeOfImage);
|
||||
} while ((ldr = ldr->Next) && ldr != head);
|
||||
}
|
||||
|
||||
PRINT("");
|
||||
__strace = st;
|
||||
#endif
|
||||
}
|
|
@ -100,6 +100,7 @@ long GetResourceLimit(int);
|
|||
long GetMaxFd(void);
|
||||
char *GetProgramExecutableName(void);
|
||||
char *GetInterpreterExecutableName(char *, size_t);
|
||||
void __printargs(const char *);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -75,11 +75,13 @@ o/$(MODE)/libc/runtime/hook.greg.o \
|
|||
o/$(MODE)/libc/runtime/isheap.o \
|
||||
o/$(MODE)/libc/runtime/memtrack.o \
|
||||
o/$(MODE)/libc/runtime/memtracknt.o \
|
||||
o/$(MODE)/libc/runtime/printargs.greg.o \
|
||||
o/$(MODE)/libc/runtime/mman.greg.o \
|
||||
o/$(MODE)/libc/runtime/print.greg.o \
|
||||
o/$(MODE)/libc/runtime/stackchkfail.o \
|
||||
o/$(MODE)/libc/runtime/stackchkfaillocal.o \
|
||||
o/$(MODE)/libc/runtime/winmain.greg.o: \
|
||||
o/$(MODE)/libc/runtime/winmain.greg.o \
|
||||
o/$(MODE)/libc/runtime/getsymboltable.greg.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-ffreestanding \
|
||||
$(NO_MAGIC)
|
||||
|
@ -90,13 +92,6 @@ o/$(MODE)/libc/runtime/fork-nt.o: \
|
|||
OVERRIDE_CPPFLAGS += \
|
||||
-DSTACK_FRAME_UNLIMITED
|
||||
|
||||
o/$(MODE)/libc/runtime/printf.o \
|
||||
o/$(MODE)/libc/runtime/memtrack.o \
|
||||
o/$(MODE)/libc/runtime/mman.greg.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-ffreestanding \
|
||||
-mgeneral-regs-only
|
||||
|
||||
o/$(MODE)/libc/runtime/qsort.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-Og
|
||||
|
|
|
@ -120,7 +120,7 @@ forceinline void MakeLongDoubleLongAgain(void) {
|
|||
asm volatile("fldcw\t%0" : /* no outputs */ : "m"(x87cw));
|
||||
}
|
||||
|
||||
__msabi static textwindows int WinCrashEarly(struct NtExceptionPointers *ep) {
|
||||
__msabi static textwindows int OnEarlyWinCrash(struct NtExceptionPointers *ep) {
|
||||
uint32_t wrote;
|
||||
char buf[64], *p = buf;
|
||||
*p++ = 'c';
|
||||
|
@ -158,15 +158,16 @@ __msabi static textwindows wontreturn void WinMainNew(const char16_t *cmdline) {
|
|||
if ((intptr_t)v_ntsubsystem == kNtImageSubsystemWindowsCui && version >= 10) {
|
||||
__winmainpid = __pid;
|
||||
rc = SetConsoleCP(kNtCpUtf8);
|
||||
STRACE("SetConsoleCP(kNtCpUtf8) → %hhhd", rc);
|
||||
NTTRACE("SetConsoleCP(kNtCpUtf8) → %hhhd", rc);
|
||||
rc = SetConsoleOutputCP(kNtCpUtf8);
|
||||
STRACE("SetConsoleOutputCP(kNtCpUtf8) → %hhhd", rc);
|
||||
NTTRACE("SetConsoleOutputCP(kNtCpUtf8) → %hhhd", rc);
|
||||
for (i = 0; i < 3; ++i) {
|
||||
hand = GetStdHandle(kConsoleHandles[i]);
|
||||
rc = GetConsoleMode(hand, __ntconsolemode + i);
|
||||
STRACE("GetConsoleMode(%p, [%#x]) → %hhhd", hand, __ntconsolemode[i], rc);
|
||||
NTTRACE("GetConsoleMode(%p, [%#x]) → %hhhd", hand, __ntconsolemode[i],
|
||||
rc);
|
||||
rc = SetConsoleMode(hand, kConsoleModes[i]);
|
||||
STRACE("SetConsoleMode(%p, %#x) → %hhhd", hand, kConsoleModes[i], rc);
|
||||
NTTRACE("SetConsoleMode(%p, %#x) → %hhhd", hand, kConsoleModes[i], rc);
|
||||
}
|
||||
}
|
||||
_mmi.p = _mmi.s;
|
||||
|
@ -176,8 +177,8 @@ __msabi static textwindows wontreturn void WinMainNew(const char16_t *cmdline) {
|
|||
stacksize = GetStackSize();
|
||||
allocsize = argsize + stacksize;
|
||||
allocaddr = stackaddr - argsize;
|
||||
STRACE("WinMainNew() mapping %'zu byte arg block + stack at %p", allocsize,
|
||||
allocaddr);
|
||||
NTTRACE("WinMainNew() mapping %'zu byte arg block + stack at %p", allocsize,
|
||||
allocaddr);
|
||||
MapViewOfFileEx(
|
||||
(_mmi.p[0].h =
|
||||
CreateFileMapping(-1, &kNtIsInheritable, kNtPageExecuteReadwrite,
|
||||
|
@ -194,7 +195,7 @@ __msabi static textwindows wontreturn void WinMainNew(const char16_t *cmdline) {
|
|||
_mmi.p[0].size = allocsize;
|
||||
_mmi.i = 1;
|
||||
wa = (struct WinArgs *)allocaddr;
|
||||
STRACE("WinMainNew() loading arg block");
|
||||
NTTRACE("WinMainNew() loading arg block");
|
||||
count = GetDosArgv(cmdline, wa->argblock, ARRAYLEN(wa->argblock), wa->argv,
|
||||
ARRAYLEN(wa->argv));
|
||||
for (i = 0; wa->argv[0][i]; ++i) {
|
||||
|
@ -203,13 +204,11 @@ __msabi static textwindows wontreturn void WinMainNew(const char16_t *cmdline) {
|
|||
}
|
||||
}
|
||||
env16 = GetEnvironmentStrings();
|
||||
STRACE("WinMainNew() loading environment");
|
||||
NTTRACE("WinMainNew() loading environment");
|
||||
GetDosEnviron(env16, wa->envblock, ARRAYLEN(wa->envblock) - 8, wa->envp,
|
||||
ARRAYLEN(wa->envp) - 1);
|
||||
FreeEnvironmentStrings(env16);
|
||||
wa->auxv[0][0] = pushpop(AT_EXECFN);
|
||||
wa->auxv[0][1] = (intptr_t)wa->argv[0];
|
||||
STRACE("WinMainNew() switching stacks");
|
||||
NTTRACE("WinMainNew() switching stacks");
|
||||
_jmpstack((char *)(stackaddr + stacksize - (intptr_t)ape_stack_align), cosmo,
|
||||
count, wa->argv, wa->envp, wa->auxv);
|
||||
}
|
||||
|
@ -255,13 +254,13 @@ __msabi textwindows int64_t WinMain(int64_t hInstance, int64_t hPrevInstance,
|
|||
ts = rdtsc();
|
||||
__nomultics = true;
|
||||
__pid = GetCurrentProcessId();
|
||||
__wincrashearly = AddVectoredExceptionHandler(1, (void *)WinCrashEarly);
|
||||
__wincrashearly = AddVectoredExceptionHandler(1, (void *)OnEarlyWinCrash);
|
||||
cmdline = GetCommandLine();
|
||||
#ifdef SYSDEBUG
|
||||
/* sloppy flag-only check for early initialization */
|
||||
if (__strstr16(cmdline, u"--strace")) ++__strace;
|
||||
#endif
|
||||
STRACE("WinMain()");
|
||||
NTTRACE("WinMain()");
|
||||
MakeLongDoubleLongAgain();
|
||||
if (weaken(WinSockInit)) weaken(WinSockInit)();
|
||||
if (weaken(WinMainForked)) weaken(WinMainForked)();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue