mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-02 09:18:31 +00:00
Introduce --strace flag for system call tracing
This is similar to the --ftrace (c function call trace) flag, except it's less noisy since it only logs system calls to stderr. Having this flag is valuable because (1) system call tracing tells us a lot about the behavior of complex programs and (2) it's usually very hard to get system call tracing on various operating systems, e.g. strace, ktrace, dtruss, truss, nttrace, etc. Especially on Apple platforms where even with the special boot trick, debuggers still aren't guaranteed to work. make -j8 o//examples o//examples/hello.com --strace This is enabled by default in MODE=, MODE=opt, and MODE=dbg. In MODE=dbg extra information will be printed. make -j8 MODE=dbg o/dbg/examples o/dbg/examples/hello.com --strace |& less This change also changes: - Rename IsText() → _istext() - Rename IsUtf8() → _isutf8() - Fix madvise() on Windows NT - Fix empty string case of inet_ntop() - vfork() wrapper now saves and restores errno - Update xsigaction() to yoink syscall support
This commit is contained in:
parent
c541225af0
commit
14e192e5ba
138 changed files with 1519 additions and 631 deletions
|
@ -16,7 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/sysdebug.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
|
||||
noasan bool AreMemoryIntervalsOk(const struct MemoryIntervals *mm) {
|
||||
|
@ -24,7 +24,7 @@ noasan bool AreMemoryIntervalsOk(const struct MemoryIntervals *mm) {
|
|||
int i;
|
||||
for (i = 0; i < mm->i; ++i) {
|
||||
if (mm->p[i].y < mm->p[i].x) {
|
||||
SYSDEBUG("AreMemoryIntervalsOk() y should be >= x!");
|
||||
STRACE("AreMemoryIntervalsOk() y should be >= x!");
|
||||
return false;
|
||||
}
|
||||
if (i) {
|
||||
|
@ -34,7 +34,7 @@ noasan bool AreMemoryIntervalsOk(const struct MemoryIntervals *mm) {
|
|||
}
|
||||
} else {
|
||||
if (!(mm->p[i - 1].y + 1 <= mm->p[i].x)) {
|
||||
SYSDEBUG("AreMemoryIntervalsOk() out of order or overlap!");
|
||||
STRACE("AreMemoryIntervalsOk() out of order or overlap!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,12 +16,14 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
/**
|
||||
* Removes all environment variables.
|
||||
*/
|
||||
int clearenv(void) {
|
||||
STRACE("clearenv() → 0");
|
||||
environ = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "libc/notice.inc"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
.text.startup
|
||||
|
||||
|
@ -37,6 +38,10 @@ cosmo: push %rbp
|
|||
mov %rsi,%r13
|
||||
mov %rdx,%r14
|
||||
mov %rcx,%r15
|
||||
#ifdef SYSDEBUG
|
||||
call __strace_init
|
||||
mov %eax,%r12d
|
||||
#endif /* SYSDEBUG */
|
||||
#ifdef __FAST_MATH__
|
||||
push %rax
|
||||
stmxcsr (%rsp)
|
||||
|
@ -72,7 +77,7 @@ cosmo: push %rbp
|
|||
.endfn cosmo,weak
|
||||
|
||||
#ifdef __PG__
|
||||
.init.start 800,_init_ftrace
|
||||
.init.start 306,_init_ftrace
|
||||
push %rdi
|
||||
push %rsi
|
||||
mov %r12d,%edi
|
||||
|
@ -86,5 +91,21 @@ cosmo: push %rbp
|
|||
mov %eax,%r12d
|
||||
pop %rsi
|
||||
pop %rdi
|
||||
.init.end 800,_init_ftrace
|
||||
.init.end 306,_init_ftrace
|
||||
#endif
|
||||
|
||||
#if IsModeDbg()
|
||||
#ifdef SYSDEBUG
|
||||
.init.start 307,_init_printargs
|
||||
push %rdi
|
||||
push %rsi
|
||||
mov %r12d,%edi
|
||||
mov %r13,%rsi
|
||||
mov %r14,%rdx
|
||||
mov %r15,%rcx
|
||||
call __printargs
|
||||
pop %rsi
|
||||
pop %rdi
|
||||
.init.end 307,_init_printargs
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1,49 +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/log/libfatal.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
#define ADDR(x) ((int64_t)((uint64_t)(x) << 32) >> 16)
|
||||
#define UNSHADOW(x) ((int64_t)(MAX(0, (x)-0x7fff8000)) << 3)
|
||||
#define FRAME(x) ((int)((x) >> 16))
|
||||
|
||||
noasan const char *DescribeFrame(int x) {
|
||||
/* asan runtime depends on this function */
|
||||
char *p;
|
||||
static char buf[128];
|
||||
if (IsShadowFrame(x)) {
|
||||
p = buf;
|
||||
p = __stpcpy(p, " shadow of ");
|
||||
p = __fixcpy(p, UNSHADOW(ADDR(x)), 48);
|
||||
return buf;
|
||||
return " shadow ";
|
||||
} else if (IsAutoFrame(x)) {
|
||||
return " automap";
|
||||
} else if (IsFixedFrame(x)) {
|
||||
return " fixed ";
|
||||
} else if (IsArenaFrame(x)) {
|
||||
return " arena ";
|
||||
} else if (IsStaticStackFrame(x)) {
|
||||
return " stack ";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
|
@ -1,39 +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 2020 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/dce.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
char *describeos(char *buf, size_t size) {
|
||||
const char *s;
|
||||
if (IsLinux()) {
|
||||
s = "gnu/systemd";
|
||||
} else if (IsXnu()) {
|
||||
s = "xnu's not unix";
|
||||
} else if (IsFreebsd()) {
|
||||
s = "freebesiyatadishmaya";
|
||||
} else if (IsOpenbsd()) {
|
||||
s = "openbsd";
|
||||
} else if (IsWindows()) {
|
||||
s = "the new technology";
|
||||
} else {
|
||||
s = "wut";
|
||||
}
|
||||
return memccpy(buf, s, '\0', size);
|
||||
}
|
|
@ -1,65 +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/macros.internal.h"
|
||||
#include "libc/runtime/directmap.internal.h"
|
||||
#include "libc/runtime/pc.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
static uint64_t sys_mmap_metal_break;
|
||||
|
||||
noasan struct DirectMap sys_mmap_metal(void *paddr, size_t size, int prot,
|
||||
int flags, int fd, int64_t off) {
|
||||
/* asan runtime depends on this function */
|
||||
size_t i;
|
||||
struct mman *mm;
|
||||
struct DirectMap res;
|
||||
uint64_t addr, page, *pte, *pml4t;
|
||||
mm = (struct mman *)(BANE + 0x0500);
|
||||
pml4t = __get_pml4t();
|
||||
size = ROUNDUP(size, 4096);
|
||||
addr = (uint64_t)paddr;
|
||||
if (!(flags & MAP_FIXED)) {
|
||||
for (i = 0; i < size; i += 4096) {
|
||||
pte = __get_virtual(mm, pml4t, addr, false);
|
||||
if (pte && (*pte & PAGE_V)) {
|
||||
addr = MAX(addr, sys_mmap_metal_break) + i + 4096;
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
sys_mmap_metal_break = MAX(addr + size, sys_mmap_metal_break);
|
||||
}
|
||||
for (i = 0; i < size; i += 4096) {
|
||||
page = __new_page(mm);
|
||||
pte = __get_virtual(mm, pml4t, addr + i, true);
|
||||
if (pte && page) {
|
||||
__clear_page(BANE + page);
|
||||
*pte = page | ((prot & PROT_WRITE) ? PAGE_RW : 0) | PAGE_U | PAGE_V;
|
||||
} else {
|
||||
addr = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
res.addr = (void *)addr;
|
||||
res.maphandle = -1;
|
||||
return res;
|
||||
}
|
|
@ -1,105 +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 2020 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/internal.h"
|
||||
#include "libc/calls/sysdebug.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/enum/filemapflags.h"
|
||||
#include "libc/nt/enum/pageflags.h"
|
||||
#include "libc/nt/memory.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/overlapped.h"
|
||||
#include "libc/runtime/directmap.internal.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
|
||||
textwindows noasan struct DirectMap sys_mmap_nt(void *addr, size_t size,
|
||||
int prot, int flags,
|
||||
int64_t handle, int64_t off) {
|
||||
/* asan runtime depends on this function */
|
||||
uint32_t got;
|
||||
size_t i, upsize;
|
||||
struct DirectMap dm;
|
||||
struct NtOverlapped op;
|
||||
if ((prot & PROT_WRITE) && (flags & MAP_PRIVATE) && handle != -1) {
|
||||
/*
|
||||
* WIN32 claims it can do COW mappings but we still haven't found a
|
||||
* combination of flags, that'll cause Windows to actually do this!
|
||||
*/
|
||||
upsize = ROUNDUP(size, FRAMESIZE);
|
||||
dm.maphandle = CreateFileMappingNuma(-1, &kNtIsInheritable,
|
||||
kNtPageExecuteReadwrite, upsize >> 32,
|
||||
upsize, NULL, kNtNumaNoPreferredNode);
|
||||
SYSDEBUG("CreateFileMappingNuma(-1, kNtPageExecuteReadwrite, 0x%x/0x%x) -> "
|
||||
"0x%x",
|
||||
upsize, size, dm.maphandle);
|
||||
if (dm.maphandle) {
|
||||
dm.addr =
|
||||
MapViewOfFileExNuma(dm.maphandle, kNtFileMapWrite | kNtFileMapExecute,
|
||||
0, 0, upsize, addr, kNtNumaNoPreferredNode);
|
||||
SYSDEBUG("MapViewOfFileExNuma(WX, 0x%x) -> addr:0x%x", addr, dm.addr);
|
||||
if (dm.addr) {
|
||||
for (i = 0; i < size; i += got) {
|
||||
got = 0;
|
||||
op.Internal = 0;
|
||||
op.InternalHigh = 0;
|
||||
op.Pointer = (void *)(uintptr_t)i;
|
||||
op.hEvent = 0;
|
||||
if (!ReadFile(handle, (char *)dm.addr + i, size - i, &got, &op)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == size) {
|
||||
return dm;
|
||||
}
|
||||
UnmapViewOfFile(dm.addr);
|
||||
}
|
||||
CloseHandle(dm.maphandle);
|
||||
}
|
||||
} else {
|
||||
dm.maphandle = CreateFileMappingNuma(
|
||||
handle, &kNtIsInheritable,
|
||||
(prot & PROT_WRITE) ? kNtPageExecuteReadwrite : kNtPageExecuteRead,
|
||||
handle != -1 ? 0 : size >> 32, handle != -1 ? 0 : size, NULL,
|
||||
kNtNumaNoPreferredNode);
|
||||
SYSDEBUG("CreateFileMappingNuma(fhand:%d, prot:%s, size:0x%x) -> "
|
||||
"handle:0x%x",
|
||||
handle, (prot & PROT_WRITE) ? "XRW" : "XR",
|
||||
handle != -1 ? 0 : size);
|
||||
if (dm.maphandle) {
|
||||
dm.addr = MapViewOfFileExNuma(
|
||||
dm.maphandle,
|
||||
(prot & PROT_WRITE) ? kNtFileMapWrite | kNtFileMapExecute
|
||||
: kNtFileMapRead | kNtFileMapExecute,
|
||||
off >> 32, off, size, addr, kNtNumaNoPreferredNode);
|
||||
SYSDEBUG(
|
||||
"MapViewOfFileExNuma(prot:%s, off:0x%x, size:0x%x, addr:0x%x) -> "
|
||||
"addr:0x%x",
|
||||
(prot & PROT_WRITE) ? "WX" : "RX", off, size, addr, dm.addr);
|
||||
if (dm.addr) {
|
||||
return dm;
|
||||
} else {
|
||||
CloseHandle(dm.maphandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
dm.maphandle = kNtInvalidHandleValue;
|
||||
dm.addr = (void *)(intptr_t)__winerr();
|
||||
return dm;
|
||||
}
|
|
@ -1,55 +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 2020 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/internal.h"
|
||||
#include "libc/calls/sysdebug.internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/runtime/directmap.internal.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Obtains memory mapping directly from system.
|
||||
*
|
||||
* The mmap() function needs to track memory mappings in order to
|
||||
* support Windows NT and Address Sanitizer. That memory tracking can be
|
||||
* bypassed by calling this function. However the caller is responsible
|
||||
* for passing the magic memory handle on Windows NT to CloseHandle().
|
||||
*/
|
||||
noasan struct DirectMap sys_mmap(void *addr, size_t size, int prot, int flags,
|
||||
int fd, int64_t off) {
|
||||
/* asan runtime depends on this function */
|
||||
char mode[8];
|
||||
struct DirectMap dm;
|
||||
if (!IsWindows() && !IsMetal()) {
|
||||
dm.addr = __sys_mmap(addr, size, prot, flags, fd, off, off);
|
||||
SYSDEBUG("sys_mmap(0x%p%s, 0x%x, %s, %d, %d) -> 0x%p %s", addr,
|
||||
DescribeFrame((intptr_t)addr >> 16), size,
|
||||
DescribeMapping(prot, flags, mode), (long)fd, off, dm.addr,
|
||||
dm.addr != MAP_FAILED ? "" : strerror(errno));
|
||||
dm.maphandle = kNtInvalidHandleValue;
|
||||
return dm;
|
||||
} else if (IsMetal()) {
|
||||
return sys_mmap_metal(addr, size, prot, flags, fd, off);
|
||||
} else {
|
||||
return sys_mmap_nt(addr, size, prot, flags,
|
||||
fd != -1 ? g_fds.p[fd].handle : kNtInvalidHandleValue,
|
||||
off);
|
||||
}
|
||||
}
|
|
@ -19,7 +19,9 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/notice.inc"
|
||||
|
||||
.underrun
|
||||
// Uniquely identifies each artifact linked in an address space.
|
||||
__dso_handle:
|
||||
.quad __dso_handle
|
||||
.endobj __dso_handle,globl,hidden
|
||||
.overrun
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
|
@ -32,6 +33,7 @@
|
|||
* @noreturn
|
||||
*/
|
||||
wontreturn void exit(int exitcode) {
|
||||
STRACE("exit(%d)", exitcode);
|
||||
if (weaken(__cxa_finalize)) {
|
||||
weaken(__cxa_finalize)(NULL);
|
||||
}
|
||||
|
|
|
@ -22,46 +22,37 @@
|
|||
#include "libc/runtime/symbols.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
static char *g_comdbg;
|
||||
static char g_comdbg_buf[PATH_MAX + 1];
|
||||
|
||||
static optimizesize textstartup void g_comdbg_init() {
|
||||
char *p;
|
||||
size_t n;
|
||||
static bool once;
|
||||
if (!once) {
|
||||
if (!(g_comdbg = getenv("COMDBG"))) {
|
||||
p = program_executable_name;
|
||||
n = strlen(p);
|
||||
if (n > 4 && READ32LE(p + n - 4) == READ32LE(".dbg")) {
|
||||
g_comdbg = p;
|
||||
} else if (n > 4 && READ32LE(p + n - 4) == READ32LE(".com") &&
|
||||
n + 4 <= PATH_MAX) {
|
||||
mempcpy(mempcpy(g_comdbg_buf, p, n), ".dbg", 5);
|
||||
if (fileexists(g_comdbg_buf)) {
|
||||
g_comdbg = g_comdbg_buf;
|
||||
}
|
||||
} else if (n + 8 <= PATH_MAX) {
|
||||
mempcpy(mempcpy(g_comdbg_buf, p, n), ".com.dbg", 9);
|
||||
if (fileexists(g_comdbg_buf)) {
|
||||
g_comdbg = g_comdbg_buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
once = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns path of binary with the debug information, or null.
|
||||
*
|
||||
* @return path to debug binary, or NULL
|
||||
*/
|
||||
const char *FindDebugBinary(void) {
|
||||
g_comdbg_init();
|
||||
return g_comdbg;
|
||||
static bool once;
|
||||
static char *res;
|
||||
static char buf[PATH_MAX + 1];
|
||||
char *p;
|
||||
size_t n;
|
||||
if (!once) {
|
||||
if (!(res = getenv("COMDBG"))) {
|
||||
p = program_executable_name;
|
||||
n = strlen(p);
|
||||
if (n > 4 && READ32LE(p + n - 4) == READ32LE(".dbg")) {
|
||||
res = p;
|
||||
} else if (n > 4 && READ32LE(p + n - 4) == READ32LE(".com") &&
|
||||
n + 4 <= PATH_MAX) {
|
||||
mempcpy(mempcpy(buf, p, n), ".dbg", 5);
|
||||
if (fileexists(buf)) {
|
||||
res = buf;
|
||||
}
|
||||
} else if (n + 8 <= PATH_MAX) {
|
||||
mempcpy(mempcpy(buf, p, n), ".com.dbg", 9);
|
||||
if (fileexists(buf)) {
|
||||
res = buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
once = true;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
const void *const g_comdbg_ctor[] initarray = {
|
||||
g_comdbg_init,
|
||||
};
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/ntspawn.h"
|
||||
#include "libc/calls/sysdebug.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nexgen32e/nt2sysv.h"
|
||||
|
@ -60,7 +60,7 @@ static textwindows noasan char16_t *ParseInt(char16_t *p, int64_t *x) {
|
|||
}
|
||||
|
||||
static dontinline textwindows noasan bool ForkIo(int64_t h, void *buf, size_t n,
|
||||
bool32 (*f)()) {
|
||||
bool32 (*f)()) {
|
||||
char *p;
|
||||
size_t i;
|
||||
uint32_t x;
|
||||
|
@ -73,17 +73,15 @@ static dontinline textwindows noasan bool ForkIo(int64_t h, void *buf, size_t n,
|
|||
}
|
||||
|
||||
static dontinline textwindows noasan void WriteAll(int64_t h, void *buf,
|
||||
size_t n) {
|
||||
if (!ForkIo(h, buf, n, WriteFile)) {
|
||||
SYSDEBUG("fork() WriteFile(%zu) failed %d\n", n, GetLastError());
|
||||
}
|
||||
size_t n) {
|
||||
bool rc = ForkIo(h, buf, n, WriteFile);
|
||||
STRACE("%s(%ld, %'zu) %d% m", "WriteFile", h, n);
|
||||
}
|
||||
|
||||
static textwindows dontinline noasan void ReadAll(int64_t h, void *buf,
|
||||
size_t n) {
|
||||
if (!ForkIo(h, buf, n, ReadFile)) {
|
||||
SYSDEBUG("fork() ReadFile(%zu) failed %d\n", n, GetLastError());
|
||||
}
|
||||
size_t n) {
|
||||
bool rc = ForkIo(h, buf, n, ReadFile);
|
||||
STRACE("%s(%ld, %'zu) %d% m", "ReadFile", h, n);
|
||||
}
|
||||
|
||||
textwindows noasan noinstrument void WinMainForked(void) {
|
||||
|
@ -99,6 +97,7 @@ textwindows noasan noinstrument void WinMainForked(void) {
|
|||
varlen = GetEnvironmentVariable(u"_FORK", var, ARRAYLEN(var));
|
||||
if (!varlen) return;
|
||||
if (varlen >= ARRAYLEN(var)) ExitProcess(123);
|
||||
STRACE("WinMainForked()");
|
||||
SetEnvironmentVariable(u"_FORK", NULL);
|
||||
ParseInt(ParseInt(var, &reader), &writer);
|
||||
ReadAll(reader, jb, sizeof(jb));
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sysdebug.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/nt/process.h"
|
||||
|
||||
|
@ -55,12 +55,12 @@ int fork(void) {
|
|||
}
|
||||
parent = __pid;
|
||||
__pid = dx;
|
||||
SYSDEBUG("fork() → 0 (child of %d)", parent);
|
||||
STRACE("fork() → 0 (child of %d)", parent);
|
||||
if (weaken(__onfork)) {
|
||||
weaken(__onfork)();
|
||||
}
|
||||
} else {
|
||||
SYSDEBUG("fork() → %d% m", ax);
|
||||
STRACE("fork() → %d% m", ax);
|
||||
}
|
||||
return ax;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
ftrace_hook:
|
||||
cmp $0,g_ftrace(%rip)
|
||||
je 1f
|
||||
jg 1f
|
||||
ret
|
||||
1: push %rbp
|
||||
mov %rsp,%rbp
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
|
@ -31,26 +32,10 @@
|
|||
*
|
||||
* @see libc/runtime/_init.S for documentation
|
||||
*/
|
||||
textstartup int ftrace_init(int argc, char *argv[]) {
|
||||
int i;
|
||||
bool foundflag;
|
||||
foundflag = false;
|
||||
for (i = 1; i <= argc; ++i) {
|
||||
if (!foundflag) {
|
||||
if (argv[i]) {
|
||||
if (strcmp(argv[i], "--ftrace") == 0) {
|
||||
foundflag = true;
|
||||
} else if (strcmp(argv[i], "----ftrace") == 0) {
|
||||
strcpy(argv[i], "--ftrace");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
argv[i - 1] = argv[i];
|
||||
}
|
||||
}
|
||||
if (foundflag) {
|
||||
--argc;
|
||||
textstartup int ftrace_init(void) {
|
||||
if (__intercept_flag(&__argc, __argv, "--ftrace")) {
|
||||
ftrace_install();
|
||||
++g_ftrace;
|
||||
}
|
||||
return argc;
|
||||
return __argc;
|
||||
}
|
|
@ -16,25 +16,31 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
noasan char *DescribeMapping(int prot, int flags, char p[hasatleast 8]) {
|
||||
/* asan runtime depends on this function */
|
||||
p[0] = (prot & PROT_READ) ? 'r' : '-';
|
||||
p[1] = (prot & PROT_WRITE) ? 'w' : '-';
|
||||
p[2] = (prot & PROT_EXEC) ? 'x' : '-';
|
||||
if (flags & MAP_PRIVATE) {
|
||||
p[3] = 'p';
|
||||
} else if (flags & MAP_SHARED) {
|
||||
p[3] = 's';
|
||||
} else {
|
||||
p[3] = '?';
|
||||
textstartup bool __intercept_flag(int *argc, char *argv[], const char *flag) {
|
||||
/* asan isn't initialized yet at runlevel 300 */
|
||||
char *a;
|
||||
int i, j;
|
||||
bool found;
|
||||
found = false;
|
||||
for (j = i = 1; i <= *argc;) {
|
||||
a = argv[j++];
|
||||
if (a && !__strcmp(a, flag)) {
|
||||
found = true;
|
||||
--*argc;
|
||||
} else {
|
||||
/*
|
||||
* e.g. turns ----strace → --strace for execve.
|
||||
* todo: update this to allow ------strace etc.
|
||||
*/
|
||||
if (a && a[0] == '-' && a[1] == '-' && !__strcmp(a + 2, flag)) {
|
||||
a = flag;
|
||||
}
|
||||
argv[i++] = a;
|
||||
}
|
||||
}
|
||||
p[4] = (flags & MAP_ANONYMOUS) ? 'a' : 'f';
|
||||
p[5] = (flags & MAP_GROWSDOWN) ? 'S' : '-';
|
||||
p[6] = (flags & MAP_FIXED) ? 'F' : '-';
|
||||
p[7] = 0;
|
||||
return p;
|
||||
return found;
|
||||
}
|
|
@ -27,6 +27,7 @@ long _setstack(void *, void *, ...) hidden;
|
|||
int GetDosArgv(const char16_t *, char *, size_t, char **, size_t) hidden;
|
||||
Elf64_Ehdr *MapElfRead(const char *, struct MappedFile *) hidden;
|
||||
int GetDosEnviron(const char16_t *, char *, size_t, char **, size_t) hidden;
|
||||
bool __intercept_flag(int *, char *[], const char *);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "libc/bits/likely.h"
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/sysdebug.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
|
@ -76,13 +76,13 @@ static noasan bool ExtendMemoryIntervals(struct MemoryIntervals *mm) {
|
|||
shad = (char *)(((intptr_t)base >> 3) + 0x7fff8000);
|
||||
dm = sys_mmap(shad, gran >> 3, prot, flags, -1, 0);
|
||||
if (!dm.addr) {
|
||||
SYSDEBUG("ExtendMemoryIntervals() fail #1");
|
||||
STRACE("ExtendMemoryIntervals() fail #1");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
dm = sys_mmap(base, gran, prot, flags, -1, 0);
|
||||
if (!dm.addr) {
|
||||
SYSDEBUG("ExtendMemoryIntervals() fail #2");
|
||||
STRACE("ExtendMemoryIntervals() fail #2");
|
||||
return false;
|
||||
}
|
||||
MoveMemoryIntervals(dm.addr, mm->p, mm->i);
|
||||
|
@ -95,13 +95,13 @@ static noasan bool ExtendMemoryIntervals(struct MemoryIntervals *mm) {
|
|||
shad = (char *)(((intptr_t)base >> 3) + 0x7fff8000);
|
||||
dm = sys_mmap(shad, gran >> 3, prot, flags, -1, 0);
|
||||
if (!dm.addr) {
|
||||
SYSDEBUG("ExtendMemoryIntervals() fail #3");
|
||||
STRACE("ExtendMemoryIntervals() fail #3");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
dm = sys_mmap(base, gran, prot, flags, -1, 0);
|
||||
if (!dm.addr) {
|
||||
SYSDEBUG("ExtendMemoryIntervals() fail #4");
|
||||
STRACE("ExtendMemoryIntervals() fail #4");
|
||||
return false;
|
||||
}
|
||||
mm->n = (size + gran) / sizeof(*mm->p);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_
|
||||
#define COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_
|
||||
#include "libc/assert.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/enum/version.h"
|
||||
|
@ -164,6 +165,7 @@ forceinline unsigned FindMemoryInterval(const struct MemoryIntervals *mm,
|
|||
r = m;
|
||||
}
|
||||
}
|
||||
assert(l == mm->i || x <= mm->p[l].y);
|
||||
return l;
|
||||
}
|
||||
|
||||
|
@ -171,7 +173,7 @@ forceinline bool IsMemtracked(int x, int y) {
|
|||
unsigned i;
|
||||
i = FindMemoryInterval(&_mmi, x);
|
||||
if (i == _mmi.i) return false;
|
||||
if (!(_mmi.p[i].x <= x && x <= _mmi.p[i].y)) return false;
|
||||
if (x < _mmi.p[i].x) return false;
|
||||
for (;;) {
|
||||
if (y <= _mmi.p[i].y) return true;
|
||||
if (++i == _mmi.i) return false;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/sysdebug.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/nt/memory.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
|
@ -37,8 +37,8 @@ noasan void ReleaseMemoryNt(struct MemoryIntervals *mm, int l, int r) {
|
|||
for (i = l; i <= r; ++i) {
|
||||
addr = GetFrameAddr(mm->p[i].x);
|
||||
last = GetFrameAddr(mm->p[i].y);
|
||||
SYSDEBUG("UnmapViewOfFile(addr:0x%x, size:0x%x, hand:0x%x)", addr,
|
||||
last - addr + FRAMESIZE, mm->p[i].h);
|
||||
STRACE("UnmapViewOfFile(%p, size:%'zu, hand:%ld)", addr,
|
||||
last - addr + FRAMESIZE, mm->p[i].h);
|
||||
ok = UnmapViewOfFile(addr);
|
||||
assert(ok);
|
||||
ok = CloseHandle(mm->p[i].h);
|
||||
|
|
|
@ -1,160 +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 2020 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. │
|
||||
╠──────────────────────────────────────────────────────────────────────────────╣
|
||||
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░█▀█░█▀█░▀█▀░█░█░█▀█░█░░░█░░░█░█░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░█▀█░█░▄░░█░░█░█░█▀█░█░░░█░░░▀█▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░▀░▀░▀▀▀░░▀░░▀▀▀░▀░▀░▀▀▀░▀▀▀░░▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░█▀█░█▀█░█▀█░▀█▀░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░█▀▀░█ █░██▀░░█░░█▀█░█▀█░█░░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░▀░░░▀▀▀░▀░▀░░▀░░▀░▀░▀▀▀░▀▀▀░▀▀▀░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
|
||||
│░░░░░░░█▀▀░█░█░█▀▀░█▀█░█░█░▀█▀░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░░░░░░░░░░░░░▄▄░░░▐█░░│
|
||||
│░░░░░░░█▀▀░▄▀▄░█▀▀░█░▄░█░█░░█░░█▀█░█▀█░█░░█▀▀░░░░░░░░░░░░▄▄▄░░░▄██▄░░█▀░░░█░▄░│
|
||||
│░░░░░░░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀░░▀░░▀░▀░▀▀▀░▀▀░▀▀▀░░░░░░░░░░▄██▀█▌░██▄▄░░▐█▀▄░▐█▀░░│
|
||||
│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▐█▀▀▌░░░▄▀▌░▌░█░▌░░▌░▌░░│
|
||||
╠──────────────────────────────────────────────────────▌▀▄─▐──▀▄─▐▄─▐▄▐▄─▐▄─▐▄─│
|
||||
│ αcτµαlly pδrταblε εxεcµταblε § no-frills virtual memory management │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "ape/relocations.h"
|
||||
#include "libc/elf/def.h"
|
||||
#include "libc/elf/struct/phdr.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nexgen32e/uart.internal.h"
|
||||
#include "libc/runtime/e820.internal.h"
|
||||
#include "libc/runtime/metalprintf.internal.h"
|
||||
#include "libc/runtime/pc.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
/**
|
||||
* Allocates new page of physical memory.
|
||||
*/
|
||||
noasan texthead uint64_t __new_page(struct mman *mm) {
|
||||
uint64_t p;
|
||||
if (mm->pdpi == mm->e820n) {
|
||||
/* TODO: reclaim free pages */
|
||||
return 0;
|
||||
}
|
||||
while (mm->pdp >= mm->e820[mm->pdpi].addr + mm->e820[mm->pdpi].size) {
|
||||
if (++mm->pdpi == mm->e820n) return 0;
|
||||
mm->pdp = mm->e820[mm->pdpi].addr;
|
||||
}
|
||||
p = mm->pdp;
|
||||
mm->pdp += 4096;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns pointer to page table entry for page at virtual address.
|
||||
* Additional page tables are allocated if needed as a side-effect.
|
||||
*/
|
||||
noasan texthead uint64_t *__get_virtual(struct mman *mm, uint64_t *t,
|
||||
int64_t vaddr, bool maketables) {
|
||||
uint64_t *e, p;
|
||||
unsigned char h;
|
||||
for (h = 39;; h -= 9) {
|
||||
e = t + ((vaddr >> h) & 511);
|
||||
if (h == 12) return e;
|
||||
if (!(*e & PAGE_V)) {
|
||||
if (!maketables) return NULL;
|
||||
if (!(p = __new_page(mm))) return NULL;
|
||||
*e = p | PAGE_V | PAGE_RW;
|
||||
}
|
||||
t = (uint64_t *)(BANE + (*e & PAGE_TA));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts, rounds, and filters BIOS memory map.
|
||||
*/
|
||||
static noasan texthead void __normalize_e820(struct mman *mm) {
|
||||
uint64_t a, b;
|
||||
uint64_t x, y;
|
||||
unsigned i, j, n;
|
||||
for (n = i = 0; mm->e820[i].size; ++i) {
|
||||
mm->e820[n] = mm->e820[i];
|
||||
x = mm->e820[n].addr;
|
||||
y = mm->e820[n].addr + mm->e820[n].size;
|
||||
a = ROUNDUP(x, 4096);
|
||||
b = ROUNDDOWN(y, 4096) - a;
|
||||
if (b > 0 && mm->e820[i].type == kMemoryUsable) {
|
||||
mm->e820[n].addr = a;
|
||||
mm->e820[n].size = b;
|
||||
++n;
|
||||
}
|
||||
}
|
||||
for (i = 1; i < n; ++i) {
|
||||
for (j = i; j > 0 && mm->e820[i].addr < mm->e820[j - 1].addr; --j) {
|
||||
mm->e820[j] = mm->e820[j - 1];
|
||||
}
|
||||
mm->e820[j] = mm->e820[i];
|
||||
}
|
||||
mm->pdp = MAX(0x80000, mm->e820[0].addr);
|
||||
mm->pdpi = 0;
|
||||
mm->e820n = n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Identity maps all usable physical memory to its negative address.
|
||||
*/
|
||||
static noasan texthead void __invert_memory(struct mman *mm, uint64_t *pml4t) {
|
||||
uint64_t i, j, *m, p, pe;
|
||||
for (i = 0; i < mm->e820n; ++i) {
|
||||
for (p = mm->e820[i].addr, pe = mm->e820[i].addr + mm->e820[i].size;
|
||||
p + 0x200000 < pe; p += 4096) {
|
||||
m = __get_virtual(mm, pml4t, BANE + p, true);
|
||||
if (m && !(*m & PAGE_V)) {
|
||||
*m = p | PAGE_V | PAGE_RW;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
noasan texthead void __setup_mman(struct mman *mm, uint64_t *pml4t) {
|
||||
__normalize_e820(mm);
|
||||
__invert_memory(mm, pml4t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps APE-defined ELF program headers into memory and clears BSS.
|
||||
*/
|
||||
noasan textreal void __map_phdrs(struct mman *mm, uint64_t *pml4t, uint64_t b) {
|
||||
struct Elf64_Phdr *p;
|
||||
uint64_t i, f, v, m, *e;
|
||||
extern char ape_phdrs[] __attribute__((__weak__));
|
||||
extern char ape_phdrs_end[] __attribute__((__weak__));
|
||||
__setup_mman(mm, pml4t);
|
||||
for (p = (struct Elf64_Phdr *)REAL(ape_phdrs), m = 0;
|
||||
p < (struct Elf64_Phdr *)REAL(ape_phdrs_end); ++p) {
|
||||
if (p->p_type == PT_LOAD || p->p_type == PT_GNU_STACK) {
|
||||
f = PAGE_V | PAGE_U;
|
||||
if (p->p_flags & PF_W) f |= PAGE_RW;
|
||||
for (i = 0; i < p->p_memsz; i += 4096) {
|
||||
if (i < p->p_filesz) {
|
||||
v = b + p->p_offset + i;
|
||||
m = MAX(m, v);
|
||||
} else {
|
||||
v = __clear_page(__new_page(mm));
|
||||
}
|
||||
*__get_virtual(mm, pml4t, p->p_vaddr + i, true) = (v & PAGE_TA) | f;
|
||||
}
|
||||
}
|
||||
}
|
||||
mm->pdp = MAX(mm->pdp, m);
|
||||
}
|
|
@ -21,7 +21,7 @@
|
|||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sysdebug.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
|
@ -40,7 +40,6 @@
|
|||
|
||||
#define IP(X) (intptr_t)(X)
|
||||
#define VIP(X) (void *)IP(X)
|
||||
#define SMALL(n) ((n) <= 0xffffffffffff)
|
||||
#define ALIGNED(p) (!(IP(p) & (FRAMESIZE - 1)))
|
||||
#define ADDR(x) ((int64_t)((uint64_t)(x) << 32) >> 16)
|
||||
#define SHADE(x) (((intptr_t)(x) >> 3) + 0x7fff8000)
|
||||
|
@ -60,7 +59,7 @@ noasan static bool NeedAutomap(char *p, size_t n) {
|
|||
IsMapped(p, n);
|
||||
}
|
||||
|
||||
noasan static bool ChooseInterval(int x, int n, int *res) {
|
||||
noasan static bool ChooseMemoryInterval(int x, int n, int *res) {
|
||||
int i;
|
||||
if (_mmi.i) {
|
||||
i = FindMemoryInterval(&_mmi, x);
|
||||
|
@ -89,18 +88,17 @@ noasan static bool ChooseInterval(int x, int n, int *res) {
|
|||
|
||||
noasan static bool Automap(int n, int *res) {
|
||||
*res = -1;
|
||||
if (ChooseInterval(FRAME(kAutomapStart), n, res)) {
|
||||
if (ChooseMemoryInterval(FRAME(kAutomapStart), n, res)) {
|
||||
assert(*res >= FRAME(kAutomapStart));
|
||||
if (*res + n <= FRAME(kAutomapStart + (kAutomapStart - 1))) {
|
||||
return true;
|
||||
} else {
|
||||
SYSDEBUG("mmap(0x%p, 0x%x) ENOMEM (automap interval exhausted)",
|
||||
ADDR(*res), ADDR(n + 1));
|
||||
STRACE("mmap(%.12p, %p) ENOMEM (automap interval exhausted)", ADDR(*res),
|
||||
ADDR(n + 1));
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
SYSDEBUG("mmap(0x%p, 0x%x) ENOMEM (automap failed)", ADDR(*res),
|
||||
ADDR(n + 1));
|
||||
STRACE("mmap(%.12p, %p) ENOMEM (automap failed)", ADDR(*res), ADDR(n + 1));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -111,28 +109,28 @@ static noasan void *MapMemory(void *addr, size_t size, int prot, int flags,
|
|||
dm = sys_mmap(addr, size, prot, f, fd, off);
|
||||
if (UNLIKELY(dm.addr == MAP_FAILED)) {
|
||||
if (IsWindows() && (flags & MAP_FIXED)) {
|
||||
SYSDEBUG("mmap(0x%p, 0x%x) -> %s (%s)", addr, size, strerror(errno),
|
||||
"can't recover from MAP_FIXED errors on Windows");
|
||||
STRACE("mmap(%.12p, %'ld) → %s (%s)", addr, size, strerror(errno),
|
||||
"can't recover from MAP_FIXED errors on Windows");
|
||||
assert(!"MapMemory() failed");
|
||||
Die();
|
||||
}
|
||||
return MAP_FAILED;
|
||||
}
|
||||
if (UNLIKELY(dm.addr != addr)) {
|
||||
SYSDEBUG("KERNEL DIDN'T RESPECT MAP_FIXED");
|
||||
STRACE("KERNEL DIDN'T RESPECT MAP_FIXED");
|
||||
assert(!"MapMemory() failed");
|
||||
Die();
|
||||
}
|
||||
if (!IsWindows() && (flags & MAP_FIXED)) {
|
||||
if (UntrackMemoryIntervals(addr, size)) {
|
||||
SYSDEBUG("FIXED UNTRACK FAILED %s", strerror(errno));
|
||||
STRACE("FIXED UNTRACK FAILED %s", strerror(errno));
|
||||
assert(!"MapMemory() failed");
|
||||
Die();
|
||||
}
|
||||
}
|
||||
if (TrackMemoryInterval(&_mmi, x, x + (n - 1), dm.maphandle, prot, flags)) {
|
||||
if (sys_munmap(addr, n) == -1) {
|
||||
SYSDEBUG("TRACK MUNMAP FAILED %s", strerror(errno));
|
||||
STRACE("TRACK MUNMAP FAILED %s", strerror(errno));
|
||||
assert(!"MapMemory() failed");
|
||||
Die();
|
||||
}
|
||||
|
@ -151,21 +149,21 @@ static noasan void *MapMemory(void *addr, size_t size, int prot, int flags,
|
|||
* punch holes into existing mappings.
|
||||
*/
|
||||
static textwindows dontinline noasan void *MapMemories(char *addr, size_t size,
|
||||
int prot, int flags,
|
||||
int fd, int64_t off, int f,
|
||||
int x, size_t n) {
|
||||
int prot, int flags,
|
||||
int fd, int64_t off,
|
||||
int f, int x, size_t n) {
|
||||
struct DirectMap dm;
|
||||
size_t i, m = (n - 1) * FRAMESIZE;
|
||||
assert(m < size && m + FRAMESIZE >= size);
|
||||
dm = sys_mmap(addr + m, size - m, prot, f, fd, fd == -1 ? 0 : off + m);
|
||||
if (dm.addr == MAP_FAILED) {
|
||||
SYSDEBUG("MapMemories(%p+%x/%x) %s", addr, m, size, strerror(errno));
|
||||
STRACE("MapMemories(%.12p+%lx/%lx) %m", addr, m, size);
|
||||
return MAP_FAILED;
|
||||
}
|
||||
if (TrackMemoryInterval(&_mmi, x + (n - 1), x + (n - 1), dm.maphandle, prot,
|
||||
flags) == -1) {
|
||||
SYSDEBUG("MapMemories(%p+%x/%x) unrecoverable failure #1 %s", addr, m, size,
|
||||
strerror(errno));
|
||||
STRACE("MapMemories(%.12p+%lx/%lx) unrecoverable failure #1 %m", addr, m,
|
||||
size);
|
||||
assert(!"MapMemories() failed");
|
||||
Die();
|
||||
}
|
||||
|
@ -174,8 +172,8 @@ static textwindows dontinline noasan void *MapMemories(char *addr, size_t size,
|
|||
if (dm.addr == MAP_FAILED ||
|
||||
TrackMemoryInterval(&_mmi, x + i / FRAMESIZE, x + i / FRAMESIZE,
|
||||
dm.maphandle, prot, flags) == -1) {
|
||||
SYSDEBUG("MapMemories(%p+%x/%x) unrecoverable failure #2 %s", addr, i,
|
||||
size, strerror(errno));
|
||||
STRACE("MapMemories(%p+%x/%x) unrecoverable failure #2 %m", addr, i,
|
||||
size);
|
||||
assert(!"MapMemories() failed");
|
||||
Die();
|
||||
}
|
||||
|
@ -221,56 +219,56 @@ noasan void *mmap(void *addr, size_t size, int prot, int flags, int fd,
|
|||
int a, b, i, f, m, n, x;
|
||||
char mode[8], *p = addr;
|
||||
if (UNLIKELY(!size)) {
|
||||
SYSDEBUG("mmap(0x%p, 0x%x) EINVAL (size=0)", p, size);
|
||||
STRACE("mmap(%.12p, %'zu) EINVAL (size=0)", p, size);
|
||||
return VIP(einval());
|
||||
}
|
||||
if (UNLIKELY(!SMALL(size))) {
|
||||
SYSDEBUG("mmap(0x%p, 0x%x) EINVAL (size isn't 48-bit)", p, size);
|
||||
if (UNLIKELY(!IsLegalSize(size))) {
|
||||
STRACE("mmap(%.12p, %'zu) EINVAL (size isn't 48-bit)", p, size);
|
||||
return VIP(einval());
|
||||
}
|
||||
if (UNLIKELY(!IsLegalPointer(p))) {
|
||||
SYSDEBUG("mmap(0x%p, 0x%x) EINVAL (p isn't 48-bit)", p, size);
|
||||
STRACE("mmap(%.12p, %'zu) EINVAL (p isn't 48-bit)", p, size);
|
||||
return VIP(einval());
|
||||
}
|
||||
if (UNLIKELY(!ALIGNED(p))) {
|
||||
SYSDEBUG("mmap(0x%p, 0x%x) EINVAL (p isn't 64kb aligned)", p, size);
|
||||
STRACE("mmap(%.12p, %'zu) EINVAL (p isn't 64kb aligned)", p, size);
|
||||
return VIP(einval());
|
||||
}
|
||||
if (UNLIKELY(fd < -1)) {
|
||||
SYSDEBUG("mmap(0x%p, 0x%x, fd=%d) EBADF", p, size, (long)fd);
|
||||
STRACE("mmap(%.12p, %'zu, fd=%d) EBADF", p, size, fd);
|
||||
return VIP(ebadf());
|
||||
}
|
||||
if (UNLIKELY(!((fd != -1) ^ !!(flags & MAP_ANONYMOUS)))) {
|
||||
SYSDEBUG("mmap(0x%p, 0x%x, %s, %d, %d) EINVAL (fd anonymous mismatch)", p,
|
||||
size, DescribeMapping(prot, flags, mode), (long)fd, off);
|
||||
STRACE("mmap(%.12p, %'zu, %s, %d, %'ld) EINVAL (fd anonymous mismatch)", p,
|
||||
size, DescribeMapping(prot, flags, mode), fd, off);
|
||||
return VIP(einval());
|
||||
}
|
||||
if (UNLIKELY(!(!!(flags & MAP_PRIVATE) ^ !!(flags & MAP_SHARED)))) {
|
||||
SYSDEBUG("mmap(0x%p, 0x%x) EINVAL (MAP_SHARED ^ MAP_PRIVATE)", p, size);
|
||||
STRACE("mmap(%.12p, %'zu) EINVAL (MAP_SHARED ^ MAP_PRIVATE)", p, size);
|
||||
return VIP(einval());
|
||||
}
|
||||
if (UNLIKELY(off < 0)) {
|
||||
SYSDEBUG("mmap(0x%p, 0x%x, off=%d) EINVAL (neg off)", p, size, off);
|
||||
STRACE("mmap(%.12p, %'zu, off=%'ld) EINVAL (neg off)", p, size, off);
|
||||
return VIP(einval());
|
||||
}
|
||||
if (UNLIKELY(INT64_MAX - size < off)) {
|
||||
SYSDEBUG("mmap(0x%p, 0x%x, off=%d) EINVAL (too large)", p, size, off);
|
||||
STRACE("mmap(%.12p, %'zu, off=%'ld) EINVAL (too large)", p, size, off);
|
||||
return VIP(einval());
|
||||
}
|
||||
if (UNLIKELY(!ALIGNED(off))) {
|
||||
SYSDEBUG("mmap(0x%p, 0x%x) EINVAL (p isn't 64kb aligned)", p, size);
|
||||
STRACE("mmap(%.12p, %'zu) EINVAL (p isn't 64kb aligned)", p, size);
|
||||
return VIP(einval());
|
||||
}
|
||||
if ((flags & MAP_FIXED_NOREPLACE) && IsMapped(p, size)) {
|
||||
if (OverlapsImageSpace(p, size)) {
|
||||
SYSDEBUG("mmap(0x%p, 0x%x) EFAULT (overlaps image)", p, size);
|
||||
STRACE("mmap(%.12p, %'zu) EFAULT (overlaps image)", p, size);
|
||||
} else {
|
||||
SYSDEBUG("mmap(0x%p, 0x%x) EFAULT (overlaps existing)", p, size);
|
||||
STRACE("mmap(%.12p, %'zu) EFAULT (overlaps existing)", p, size);
|
||||
}
|
||||
return VIP(efault());
|
||||
}
|
||||
SYSDEBUG("mmap(0x%p, 0x%x, %s, %d, %d)", p, size,
|
||||
DescribeMapping(prot, flags, mode), (long)fd, off);
|
||||
STRACE("mmap(%.12p, %'zu, %s, %d, %'ld)% m", p, size,
|
||||
DescribeMapping(prot, flags, mode), fd, off);
|
||||
if (fd == -1) {
|
||||
size = ROUNDUP(size, FRAMESIZE);
|
||||
if (IsWindows()) {
|
||||
|
@ -283,7 +281,7 @@ noasan void *mmap(void *addr, size_t size, int prot, int flags, int fd,
|
|||
x = FRAME(p);
|
||||
if (IsWindows()) {
|
||||
if (UntrackMemoryIntervals(p, size)) {
|
||||
SYSDEBUG("FIXED UNTRACK FAILED %s", strerror(errno));
|
||||
STRACE("FIXED UNTRACK FAILED %m");
|
||||
assert(!"mmap() failed");
|
||||
Die();
|
||||
}
|
||||
|
|
|
@ -1,55 +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/bits/bits.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/mremap.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
privileged void *sys_mremap(void *p, size_t n, size_t m, int f, void *q) {
|
||||
bool cf;
|
||||
uintptr_t rax, rdi, rsi, rdx;
|
||||
register uintptr_t r8 asm("r8");
|
||||
register uintptr_t r10 asm("r10");
|
||||
if (IsLinux()) {
|
||||
r10 = f;
|
||||
r8 = (uintptr_t)q;
|
||||
asm("syscall"
|
||||
: "=a"(rax)
|
||||
: "0"(0x019), "D"(p), "S"(n), "d"(m), "r"(r10), "r"(r8)
|
||||
: "rcx", "r11", "memory", "cc");
|
||||
if (rax > -4096ul) errno = -rax, rax = -1;
|
||||
} else if (IsNetbsd()) {
|
||||
if (f & MREMAP_MAYMOVE) {
|
||||
rax = 0x19B;
|
||||
r10 = m;
|
||||
r8 = (f & MREMAP_FIXED) ? MAP_FIXED : 0;
|
||||
asm(CFLAG_ASM("syscall")
|
||||
: CFLAG_CONSTRAINT(cf), "+a"(rax)
|
||||
: "D"(p), "S"(n), "d"(q), "r"(r10), "r"(r8)
|
||||
: "rcx", "r11", "memory", "cc");
|
||||
if (cf) errno = rax, rax = -1;
|
||||
} else {
|
||||
rax = einval();
|
||||
}
|
||||
} else {
|
||||
rax = enosys();
|
||||
}
|
||||
return (void *)rax;
|
||||
}
|
|
@ -21,10 +21,9 @@
|
|||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sysdebug.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/runtime/directmap.internal.h"
|
||||
|
@ -36,7 +35,6 @@
|
|||
|
||||
#define IP(X) (intptr_t)(X)
|
||||
#define VIP(X) (void *)IP(X)
|
||||
#define SMALL(n) ((n) <= 0xffffffffffff)
|
||||
#define ALIGNED(p) (!(IP(p) & (FRAMESIZE - 1)))
|
||||
#define ADDR(x) ((int64_t)((uint64_t)(x) << 32) >> 16)
|
||||
#define SHADE(x) (((intptr_t)(x) >> 3) + 0x7fff8000)
|
||||
|
@ -76,43 +74,44 @@ void *mremap(void *p, size_t n, size_t m, int f, ... /* void *q */) {
|
|||
size_t i, j, k;
|
||||
struct DirectMap dm;
|
||||
int a, b, prot, flags;
|
||||
assert(!__vforked);
|
||||
if (UNLIKELY(!m)) {
|
||||
SYSDEBUG("mremap(0x%p, 0x%x, 0x%x, 0x%x) EINVAL (m=0)", p, n, m, f);
|
||||
STRACE("mremap(%p, %'zu, %'zu, %#b) EINVAL (m=0)", p, n, m, f);
|
||||
return VIP(einval());
|
||||
}
|
||||
if (UNLIKELY(!n)) {
|
||||
SYSDEBUG("mremap(0x%p, 0x%x, 0x%x, 0x%x) EOPNOTSUPP (n=0)", p, n, m, f);
|
||||
STRACE("mremap(%p, %'zu, %'zu, %#b) EOPNOTSUPP (n=0)", p, n, m, f);
|
||||
return VIP(eopnotsupp());
|
||||
}
|
||||
if (UNLIKELY(!ALIGNED(n))) {
|
||||
SYSDEBUG("mremap(0x%p, 0x%x, 0x%x, 0x%x) EOPNOTSUPP (n align)", p, n, m, f);
|
||||
STRACE("mremap(%p, %'zu, %'zu, %#b) EOPNOTSUPP (n align)", p, n, m, f);
|
||||
return VIP(eopnotsupp());
|
||||
}
|
||||
if (UNLIKELY(!ALIGNED(m))) {
|
||||
SYSDEBUG("mremap(0x%p, 0x%x, 0x%x, 0x%x) EOPNOTSUPP (n align)", p, n, m, f);
|
||||
STRACE("mremap(%p, %'zu, %'zu, %#b) EOPNOTSUPP (n align)", p, n, m, f);
|
||||
return VIP(eopnotsupp());
|
||||
}
|
||||
if (UNLIKELY(!ALIGNED(p))) {
|
||||
SYSDEBUG("mremap(0x%p, 0x%x, 0x%x, 0x%x) EINVAL (64kb align)", p, n, m, f);
|
||||
STRACE("mremap(%p, %'zu, %'zu, %#b) EINVAL (64kb align)", p, n, m, f);
|
||||
return VIP(einval());
|
||||
}
|
||||
if (UNLIKELY(!SMALL(n))) {
|
||||
SYSDEBUG("mremap(0x%p, 0x%x, 0x%x, 0x%x) EINVAL (n too big)", p, n, m, f);
|
||||
if (UNLIKELY(!IsLegalSize(n))) {
|
||||
STRACE("mremap(%p, %'zu, %'zu, %#b) EINVAL (n too big)", p, n, m, f);
|
||||
return VIP(enomem());
|
||||
}
|
||||
if (UNLIKELY(!SMALL(m))) {
|
||||
SYSDEBUG("mremap(0x%p, 0x%x, 0x%x, 0x%x) EINVAL (m too big)", p, n, m, f);
|
||||
if (UNLIKELY(!IsLegalSize(m))) {
|
||||
STRACE("mremap(%p, %'zu, %'zu, %#b) EINVAL (m too big)", p, n, m, f);
|
||||
return VIP(enomem());
|
||||
}
|
||||
if (f & ~(MREMAP_MAYMOVE | MREMAP_FIXED)) {
|
||||
SYSDEBUG("mremap(0x%p, 0x%x, 0x%x, 0x%x) EINVAL (bad flag)", p, n, m, f);
|
||||
STRACE("mremap(%p, %'zu, %'zu, %#b) EINVAL (bad flag)", p, n, m, f);
|
||||
return VIP(einval());
|
||||
}
|
||||
if (!IsMemtracked(FRAME(p), FRAME((intptr_t)p + (n - 1)))) {
|
||||
SYSDEBUG("munmap(0x%x, 0x%x) EFAULT (interval not tracked)", p, n);
|
||||
STRACE("munmap(%p, %'zu) EFAULT (interval not tracked)", p, n);
|
||||
return VIP(efault());
|
||||
}
|
||||
SYSDEBUG("mremap(0x%p, 0x%x, 0x%x, 0x%x)", p, n, m, f);
|
||||
STRACE("mremap(%p, %'zu, %'zu, %#b)", p, n, m, f);
|
||||
i = FindMemoryInterval(&_mmi, FRAME(p));
|
||||
if (i >= _mmi.i) return VIP(efault());
|
||||
flags = _mmi.p[i].flags;
|
||||
|
@ -174,8 +173,8 @@ 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));
|
||||
SYSDEBUG("sys_mremap(0x%p, 0x%x, 0x%x, 0x%x, 0x%x) -> 0x%p", p, n, m,
|
||||
MREMAP_MAYMOVE | MREMAP_FIXED, ADDR(a));
|
||||
STRACE("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,
|
||||
((uintptr_t)p + n - FRAMESIZE) >> 16, 0) != -1 &&
|
||||
|
|
|
@ -1,33 +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/directmap.internal.h"
|
||||
#include "libc/runtime/pc.internal.h"
|
||||
|
||||
noasan int sys_munmap_metal(void *addr, size_t size) {
|
||||
size_t i;
|
||||
uint64_t *e;
|
||||
struct mman *mm;
|
||||
mm = (struct mman *)(BANE + 0x0500);
|
||||
for (i = 0; i < size; i += 4096) {
|
||||
e = __get_virtual(mm, __get_pml4t(), (uint64_t)addr + i, false);
|
||||
if (e) *e = ~PAGE_V;
|
||||
invlpg(e);
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -18,7 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/likely.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sysdebug.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
|
@ -31,10 +31,8 @@
|
|||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
#define IP(X) (intptr_t)(X)
|
||||
#define SMALL(n) ((n) <= 0xffffffffffff)
|
||||
#define ALIGNED(p) (!(IP(p) & (FRAMESIZE - 1)))
|
||||
#define ADDR(x) ((int64_t)((uint64_t)(x) << 32) >> 16)
|
||||
#define SHADE(x) (((intptr_t)(x) >> 3) + 0x7fff8000)
|
||||
#define FRAME(x) ((int)((intptr_t)(x) >> 16))
|
||||
|
||||
/**
|
||||
|
@ -56,28 +54,29 @@ noasan int munmap(void *v, size_t n) {
|
|||
int rc;
|
||||
char poison, *p = v;
|
||||
intptr_t a, b, x, y;
|
||||
assert(!__vforked);
|
||||
if (UNLIKELY(!n)) {
|
||||
SYSDEBUG("munmap(0x%p, 0x%x) %s (n=0)", p, n);
|
||||
STRACE("munmap(%.12p, %'zu) %s (n=0)", p, n);
|
||||
return einval();
|
||||
}
|
||||
if (UNLIKELY(!SMALL(n))) {
|
||||
SYSDEBUG("munmap(0x%p, 0x%x) EINVAL (n isn't 48-bit)", p, n);
|
||||
if (UNLIKELY(!IsLegalSize(n))) {
|
||||
STRACE("munmap(%.12p, %'zu) EINVAL (n isn't 48-bit)", p, n);
|
||||
return einval();
|
||||
}
|
||||
if (UNLIKELY(!IsLegalPointer(p))) {
|
||||
SYSDEBUG("munmap(0x%p, 0x%x) EINVAL (p isn't 48-bit)", p, n);
|
||||
STRACE("munmap(%.12p, %'zu) EINVAL (p isn't 48-bit)", p, n);
|
||||
return einval();
|
||||
}
|
||||
if (UNLIKELY(!IsLegalPointer(p + (n - 1)))) {
|
||||
SYSDEBUG("munmap(0x%p, 0x%x) EINVAL (p+(n-1) isn't 48-bit)", p, n);
|
||||
STRACE("munmap(%.12p, %'zu) EINVAL (p+(n-1) isn't 48-bit)", p, n);
|
||||
return einval();
|
||||
}
|
||||
if (UNLIKELY(!ALIGNED(p))) {
|
||||
SYSDEBUG("munmap(0x%p, 0x%x) EINVAL (p isn't 64kb aligned)", p, n);
|
||||
STRACE("munmap(%.12p, %'zu) EINVAL (p isn't 64kb aligned)", p, n);
|
||||
return einval();
|
||||
}
|
||||
if (!IsMemtracked(FRAME(p), FRAME(p + (n - 1)))) {
|
||||
SYSDEBUG("munmap(0x%p, 0x%x) EFAULT (interval not tracked)", p, n);
|
||||
STRACE("munmap(%.12p, %'zu) EFAULT (interval not tracked)", p, n);
|
||||
return efault();
|
||||
}
|
||||
if (UntrackMemoryIntervals(p, n) != -1) {
|
||||
|
@ -85,7 +84,7 @@ noasan int munmap(void *v, size_t n) {
|
|||
rc = sys_munmap(p, n);
|
||||
if (rc != -1) {
|
||||
if (IsAsan() && !OverlapsShadowSpace(p, n)) {
|
||||
a = SHADE(p);
|
||||
a = ((intptr_t)p >> 3) + 0x7fff8000;
|
||||
b = a + (n >> 3);
|
||||
if (IsMemtracked(FRAME(a), FRAME(b - 1))) {
|
||||
x = ROUNDUP(a, FRAMESIZE);
|
||||
|
@ -100,7 +99,7 @@ noasan int munmap(void *v, size_t n) {
|
|||
__repstosb((void *)a, kAsanUnmapped, b - a);
|
||||
}
|
||||
} else {
|
||||
SYSDEBUG("unshadow(0x%x, 0x%x) EFAULT", a, b - a);
|
||||
STRACE("unshadow(%.12p, %p) EFAULT", a, b - a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -110,7 +109,7 @@ noasan int munmap(void *v, size_t n) {
|
|||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
SYSDEBUG("munmap(0x%p, 0x%x) -> %d %s", p, n, (long)rc,
|
||||
rc == -1 ? strerror(errno) : "");
|
||||
STRACE("munmap(%.12p, %'zu) → %d %s", p, n, rc,
|
||||
rc == -1 ? strerror(errno) : "");
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "libc/assert.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/sysdebug.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/elf/def.h"
|
||||
#include "libc/elf/scalar.h"
|
||||
|
@ -187,7 +187,7 @@ RaiseEnobufs:
|
|||
RaiseEnoexec:
|
||||
errno = ENOEXEC;
|
||||
SystemError:
|
||||
SYSDEBUG("OpenSymbolTable() %s", strerror(errno));
|
||||
STRACE("OpenSymbolTable() %m");
|
||||
if (map != MAP_FAILED) {
|
||||
munmap(map, st.st_size);
|
||||
}
|
||||
|
|
116
libc/runtime/printargs.c
Normal file
116
libc/runtime/printargs.c
Normal file
|
@ -0,0 +1,116 @@
|
|||
/*-*- 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/strace.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/stack.h"
|
||||
#include "libc/sysv/consts/auxv.h"
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
textstartup void __printargs(int argc, char **argv, char **envp,
|
||||
intptr_t *auxv) {
|
||||
#ifdef SYSDEBUG
|
||||
long key;
|
||||
char **env;
|
||||
unsigned i;
|
||||
intptr_t *auxp;
|
||||
char path[PATH_MAX];
|
||||
struct AuxiliaryValue *auxinfo;
|
||||
STRACE("ARGUMENTS (%p)", argv);
|
||||
for (i = 0; i < argc; ++i) {
|
||||
STRACE(" ☼ %s", argv[i]);
|
||||
}
|
||||
STRACE("ENVIRONMENT (%p)", envp);
|
||||
for (env = envp; *env; ++env) {
|
||||
STRACE(" ☼ %s", *env);
|
||||
}
|
||||
STRACE("AUXILIARY (%p)", auxv);
|
||||
for (auxp = auxv; *auxp; auxp += 2) {
|
||||
if ((auxinfo = DescribeAuxv(auxp[0]))) {
|
||||
ksnprintf(path, sizeof(path), auxinfo->fmt, auxp[1]);
|
||||
STRACE(" ☼ %16s[%4ld] = %s", auxinfo->name, auxp[0], path);
|
||||
} else {
|
||||
STRACE(" ☼ %16s[%4ld] = %014p", "unknown", auxp[0], auxp[1]);
|
||||
}
|
||||
}
|
||||
STRACE("SPECIALS");
|
||||
STRACE(" ☼ %21s = %#s", "kTmpPath", kTmpPath);
|
||||
STRACE(" ☼ %21s = %#s", "kNtSystemDirectory", kNtSystemDirectory);
|
||||
STRACE(" ☼ %21s = %#s", "kNtWindowsDirectory", kNtWindowsDirectory);
|
||||
STRACE(" ☼ %21s = %#s", "program_executable_name", program_executable_name);
|
||||
STRACE(" ☼ %21s = %#s", "GetInterpreterExecutableName()",
|
||||
GetInterpreterExecutableName(path, sizeof(path)));
|
||||
STRACE(" ☼ %21s = %p", "RSP", __builtin_frame_address(0));
|
||||
STRACE(" ☼ %21s = %p", "GetStackAddr()", GetStackAddr(0));
|
||||
STRACE(" ☼ %21s = %p", "GetStaticStackAddr(0)", GetStaticStackAddr(0));
|
||||
STRACE(" ☼ %21s = %p", "GetStackSize()", GetStackSize());
|
||||
#endif
|
||||
}
|
|
@ -16,19 +16,22 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sysdebug.internal.h"
|
||||
#include "libc/runtime/directmap.internal.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/bits/safemacros.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
int sys_munmap(void *p, size_t n) {
|
||||
int rc;
|
||||
if (!IsMetal()) {
|
||||
rc = __sys_munmap(p, n);
|
||||
} else {
|
||||
rc = sys_munmap_metal(p, n);
|
||||
/**
|
||||
* Enables plaintext system call logging if `--strace` flag is passed.
|
||||
*/
|
||||
textstartup int __strace_init(int argc, char **argv, char **envp, long *auxv) {
|
||||
/* asan isn't initialized yet at runlevel 300 */
|
||||
if (__intercept_flag(&argc, argv, "--strace") ||
|
||||
__atoul(nulltoempty(__getenv(envp, "STRACE")))) {
|
||||
++__strace;
|
||||
}
|
||||
SYSDEBUG("sys_munmap(0x%p%s, 0x%x) -> %d", p,
|
||||
DescribeFrame((intptr_t)p >> 16), n, (long)rc);
|
||||
return rc;
|
||||
return argc;
|
||||
}
|
|
@ -17,14 +17,10 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dce.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
.privileged
|
||||
|
||||
#ifdef __FSANITIZE_ADDRESS__
|
||||
vfork: jmp fork # TODO: asan and vfork don't mix?
|
||||
.endfn vfork,globl
|
||||
#else
|
||||
|
||||
// Forks process without copying page tables.
|
||||
//
|
||||
// This is the same as fork() except it's optimized for the case
|
||||
|
@ -40,11 +36,24 @@ vfork: jmp fork # TODO: asan and vfork don't mix?
|
|||
// @returnstwice
|
||||
// @vforksafe
|
||||
vfork:
|
||||
#ifdef __FSANITIZE_ADDRESS__
|
||||
jmp fork # TODO: asan and vfork don't mix?
|
||||
.endfn vfork,globl
|
||||
#else
|
||||
#if SupportsWindows()
|
||||
testb IsWindows()
|
||||
jnz sys_fork_nt
|
||||
jnz sys_fork_nt # and we're lucky to have that
|
||||
#endif
|
||||
#if SupportsOpenbsd()
|
||||
testb IsOpenbsd()
|
||||
jnz fork # fake vfork plus msyscall issues
|
||||
#endif
|
||||
#ifdef SYSDEBUG
|
||||
ezlea .Llog,di
|
||||
call __stracef
|
||||
#endif /* SYSDEBUG */
|
||||
mov __NR_vfork(%rip),%eax
|
||||
mov errno(%rip),%r8d # avoid question of @vforksafe errno
|
||||
pop %rsi # saves return address in a register
|
||||
#if SupportsBsd()
|
||||
testb IsBsd()
|
||||
|
@ -56,7 +65,8 @@ vfork:
|
|||
cmp $-4095,%eax
|
||||
jae systemfive_error
|
||||
#endif
|
||||
0: ezlea __vforked,di
|
||||
0: mov %r8d,errno(%rip)
|
||||
ezlea __vforked,di
|
||||
test %eax,%eax
|
||||
jz 1f
|
||||
decl (%rdi)
|
||||
|
@ -81,4 +91,11 @@ vfork.bsd:
|
|||
.endfn vfork.bsd
|
||||
#endif /* BSD */
|
||||
|
||||
#ifdef SYSDEBUG
|
||||
.rodata.str1.1
|
||||
.Llog: .ascii STRACE_PROLOGUE
|
||||
.asciz "vfork()%n"
|
||||
.previous
|
||||
#endif /* DEBUGSYS */
|
||||
|
||||
#endif /* __FSANITIZE_ADDRESS__ */
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "libc/bits/pushpop.h"
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
|
@ -127,6 +128,7 @@ static noasan textwindows wontreturn noinstrument void WinMainNew(void) {
|
|||
stacksize = GetStackSize();
|
||||
allocsize = argsize + stacksize;
|
||||
allocaddr = stackaddr - argsize;
|
||||
STRACE("WinMainNew() mapping arg block / stack");
|
||||
MapViewOfFileExNuma(
|
||||
(_mmi.p[0].h = CreateFileMappingNuma(
|
||||
-1, &kNtIsInheritable, kNtPageExecuteReadwrite, allocsize >> 32,
|
||||
|
@ -139,6 +141,7 @@ static noasan textwindows wontreturn noinstrument void WinMainNew(void) {
|
|||
_mmi.p[0].flags = MAP_PRIVATE | MAP_ANONYMOUS;
|
||||
_mmi.i = 1;
|
||||
wa = (struct WinArgs *)allocaddr;
|
||||
STRACE("WinMainNew() loading arg block");
|
||||
count = GetDosArgv(GetCommandLine(), wa->argblock, ARRAYLEN(wa->argblock),
|
||||
wa->argv, ARRAYLEN(wa->argv));
|
||||
for (i = 0; wa->argv[0][i]; ++i) {
|
||||
|
@ -147,11 +150,13 @@ static noasan textwindows wontreturn noinstrument void WinMainNew(void) {
|
|||
}
|
||||
}
|
||||
env16 = GetEnvironmentStrings();
|
||||
STRACE("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");
|
||||
_jmpstack((char *)stackaddr + stacksize, cosmo, count, wa->argv, wa->envp,
|
||||
wa->auxv);
|
||||
}
|
||||
|
@ -198,6 +203,7 @@ noasan textwindows noinstrument int64_t WinMain(int64_t hInstance,
|
|||
ts = rdtsc();
|
||||
__nomultics = true;
|
||||
__pid = GetCurrentProcessId();
|
||||
STRACE("WinMain()");
|
||||
MakeLongDoubleLongAgain();
|
||||
if (weaken(WinSockInit)) weaken(WinSockInit)();
|
||||
if (weaken(WinMainForked)) weaken(WinMainForked)();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue