mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-03 07:29:23 +00:00
Add support for symbol table in .com files
This change fixes minor bugs and adds a feature, which lets us store the ELF symbol table, inside the ZIP directory. We use the path /zip/.symtab which can be safely removed using a zip editing tool, to make the binary smaller after compilation. This supplements the existing method of using a separate .com.dbg file, which is still supported. The intent is people don't always know that it's a good idea to download the debug file. It's not great having someone's first experience be a crash report, that only has numbers rather than symbols. This will help fix that!
This commit is contained in:
parent
393ca4be40
commit
23b72eb617
61 changed files with 963 additions and 510 deletions
|
@ -133,6 +133,16 @@ o/$(MODE)/examples/nesemu1.com.dbg: \
|
|||
$(APE)
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/examples/nesemu1.com: \
|
||||
o/$(MODE)/examples/nesemu1.com.dbg \
|
||||
o/$(MODE)/third_party/infozip/zip.com \
|
||||
o/$(MODE)/tool/build/symtab.com
|
||||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/examples/.nesemu1/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/infozip/zip.com -9qj $@ \
|
||||
o/$(MODE)/examples/.nesemu1/.symtab
|
||||
|
||||
o/$(MODE)/examples/hello.com.dbg: \
|
||||
$(EXAMPLES_DEPS) \
|
||||
o/$(MODE)/examples/hello.o \
|
||||
|
|
|
@ -109,8 +109,8 @@ int main(int argc, char *argv[], char **envp) {
|
|||
kprintf(" ☼ kTmpPath = %#s%n", kTmpPath);
|
||||
kprintf(" ☼ kNtSystemDirectory = %#s%n", kNtSystemDirectory);
|
||||
kprintf(" ☼ kNtWindowsDirectory = %#s%n", kNtWindowsDirectory);
|
||||
kprintf(" ☼ program_executable_name = %#s (%p)%n", program_executable_name,
|
||||
program_executable_name);
|
||||
kprintf(" ☼ program_executable_name = %#s (%p)%n", GetProgramExecutableName(),
|
||||
GetProgramExecutableName());
|
||||
kprintf(" ☼ GetInterpreterExecutableName() → %#s%n",
|
||||
GetInterpreterExecutableName(_gc(malloc(1024)), 1024));
|
||||
kprintf(" ☼ RSP → %p%n", __builtin_frame_address(0));
|
||||
|
|
|
@ -41,8 +41,8 @@ textwindows int sys_getrusage_nt(int who, struct rusage *usage) {
|
|||
if ((who == RUSAGE_SELF ? GetProcessTimes : GetThreadTimes)(
|
||||
(who == RUSAGE_SELF ? GetCurrentProcess : GetCurrentThread)(),
|
||||
&CreationFileTime, &ExitFileTime, &KernelFileTime, &UserFileTime)) {
|
||||
usage->ru_utime = FileTimeToTimeVal(UserFileTime);
|
||||
usage->ru_stime = FileTimeToTimeVal(KernelFileTime);
|
||||
usage->ru_utime = WindowsDurationToTimeVal(ReadFileTime(UserFileTime));
|
||||
usage->ru_stime = WindowsDurationToTimeVal(ReadFileTime(KernelFileTime));
|
||||
} else {
|
||||
return __winerr();
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
@ -29,11 +30,16 @@
|
|||
* @return 0 on success, or -1 w/ errno
|
||||
*/
|
||||
int getrusage(int who, struct rusage *usage) {
|
||||
if (who == 99) return einval();
|
||||
if (IsAsan() && !__asan_is_valid(usage, sizeof(*usage))) return efault();
|
||||
if (!IsWindows()) {
|
||||
return sys_getrusage(who, usage);
|
||||
int rc;
|
||||
if (who == 99) {
|
||||
rc = einval();
|
||||
} else if (IsAsan() && !__asan_is_valid(usage, sizeof(*usage))) {
|
||||
rc = efault();
|
||||
} else if (!IsWindows()) {
|
||||
rc = sys_getrusage(who, usage);
|
||||
} else {
|
||||
return sys_getrusage_nt(who, usage);
|
||||
rc = sys_getrusage_nt(who, usage);
|
||||
}
|
||||
STRACE("getrusage(%d, %p) → %d% m", who, usage, rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -31,12 +31,13 @@
|
|||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int ioctl_tiocgwinsz_nt(struct Fd *fd, struct winsize *ws) {
|
||||
int i;
|
||||
int i, e;
|
||||
uint32_t mode;
|
||||
struct Fd *fds[3];
|
||||
struct NtStartupInfo startinfo;
|
||||
struct NtConsoleScreenBufferInfoEx sbinfo;
|
||||
if (!ws) return efault();
|
||||
e = errno;
|
||||
if (ws) {
|
||||
fds[0] = fd, fds[1] = g_fds.p + 1, fds[2] = g_fds.p + 0;
|
||||
GetStartupInfo(&startinfo);
|
||||
for (i = 0; i < ARRAYLEN(fds); ++i) {
|
||||
|
@ -49,12 +50,14 @@ textwindows int ioctl_tiocgwinsz_nt(struct Fd *fd, struct winsize *ws) {
|
|||
ws->ws_row = sbinfo.srWindow.Bottom - sbinfo.srWindow.Top + 1;
|
||||
ws->ws_xpixel = 0;
|
||||
ws->ws_ypixel = 0;
|
||||
errno = e;
|
||||
return 0;
|
||||
} else if (startinfo.dwFlags & kNtStartfUsecountchars) {
|
||||
ws->ws_col = startinfo.dwXCountChars;
|
||||
ws->ws_row = startinfo.dwYCountChars;
|
||||
ws->ws_xpixel = 0;
|
||||
ws->ws_ypixel = 0;
|
||||
errno = e;
|
||||
return 0;
|
||||
} else {
|
||||
__winerr();
|
||||
|
@ -67,5 +70,8 @@ textwindows int ioctl_tiocgwinsz_nt(struct Fd *fd, struct winsize *ws) {
|
|||
ebadf();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
efault();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/alloca.h"
|
||||
|
@ -42,22 +43,6 @@
|
|||
#define KERN_PROC_PATHNAME_FREEBSD 12
|
||||
#define KERN_PROC_PATHNAME_NETBSD 5
|
||||
|
||||
/**
|
||||
* Absolute path of executable.
|
||||
*
|
||||
* This variable is initialized automatically at startup. The path is
|
||||
* basically `argv[0]` except some extra vetting is done to provide
|
||||
* stronger assurance that the path can be counted upon to exist.
|
||||
*
|
||||
* For example, if your program is executed as a relative path and then
|
||||
* your program calls `chdir()`, then `argv[0]` will be incorrect; but
|
||||
* `program_executable_name` will work, because it prefixed `getcwd()`
|
||||
* early in the initialization phase.
|
||||
*
|
||||
* @see GetInterpreterExecutableName()
|
||||
* @see program_invocation_short_name
|
||||
* @see program_invocation_name
|
||||
*/
|
||||
char program_executable_name[SIZE];
|
||||
|
||||
static textwindows bool GetNtExePath(char executable[SIZE]) {
|
||||
|
@ -88,13 +73,15 @@ static textwindows bool GetNtExePath(char executable[SIZE]) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static textstartup void GetProgramExecutableName(char executable[SIZE],
|
||||
char *argv0, intptr_t *auxv) {
|
||||
static void ReadProgramExecutableName(char executable[SIZE], char *argv0,
|
||||
uintptr_t *auxv) {
|
||||
size_t m;
|
||||
ssize_t n;
|
||||
int cmd[4];
|
||||
char *p, *t;
|
||||
if (IsWindows() && GetNtExePath(executable)) return;
|
||||
if (IsWindows() && GetNtExePath(executable)) {
|
||||
return;
|
||||
}
|
||||
for (p = 0; *auxv; auxv += 2) {
|
||||
if (*auxv == AT_EXECFN) {
|
||||
p = (char *)auxv[1];
|
||||
|
@ -119,19 +106,37 @@ static textstartup void GetProgramExecutableName(char executable[SIZE],
|
|||
executable[n] = 0;
|
||||
}
|
||||
|
||||
textstartup void program_executable_name_init(int argc, char **argv,
|
||||
char **envp, intptr_t *auxv) {
|
||||
/**
|
||||
* Returns absolute path of executable.
|
||||
*
|
||||
* This variable is initialized automatically at startup. The path is
|
||||
* basically `argv[0]` except some extra vetting is done to provide
|
||||
* stronger assurance that the path can be counted upon to exist.
|
||||
*
|
||||
* For example, if your program is executed as a relative path and then
|
||||
* your program calls `chdir()`, then `argv[0]` will be incorrect; but
|
||||
* `program_executable_name` will work, because it prefixed `getcwd()`
|
||||
* early in the initialization phase.
|
||||
*
|
||||
* @see GetInterpreterExecutableName()
|
||||
* @see program_invocation_short_name
|
||||
* @see program_invocation_name
|
||||
*/
|
||||
char *GetProgramExecutableName(void) {
|
||||
int e;
|
||||
static bool once;
|
||||
char executable[SIZE];
|
||||
if (!cmpxchg(&once, 0, 1)) return;
|
||||
if (!once) {
|
||||
e = errno;
|
||||
GetProgramExecutableName(executable, argv[0], auxv);
|
||||
ReadProgramExecutableName(executable, __argv[0], __auxv);
|
||||
errno = e;
|
||||
__stpcpy(program_executable_name, executable);
|
||||
STRACE("program_executable_name → %#s", program_executable_name);
|
||||
once = true;
|
||||
}
|
||||
return program_executable_name;
|
||||
}
|
||||
|
||||
// try our best to memoize it before a chdir() happens
|
||||
const void *const program_executable_name_init_ctor[] initarray = {
|
||||
program_executable_name_init,
|
||||
GetProgramExecutableName,
|
||||
};
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
|
@ -39,22 +40,26 @@
|
|||
* @asyncsignalsafe
|
||||
*/
|
||||
ssize_t read(int fd, void *buf, size_t size) {
|
||||
ssize_t rc;
|
||||
if (fd >= 0) {
|
||||
if (IsAsan() && !__asan_is_valid(buf, size)) return efault();
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
return weaken(__zipos_read)(
|
||||
if (IsAsan() && !__asan_is_valid(buf, size)) {
|
||||
rc = efault();
|
||||
} else if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
rc = weaken(__zipos_read)(
|
||||
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle,
|
||||
&(struct iovec){buf, size}, 1, -1);
|
||||
} else if (!IsWindows() && !IsMetal()) {
|
||||
return sys_read(fd, buf, size);
|
||||
rc = sys_read(fd, buf, size);
|
||||
} else if (fd >= g_fds.n) {
|
||||
return ebadf();
|
||||
rc = ebadf();
|
||||
} else if (IsMetal()) {
|
||||
return sys_readv_metal(g_fds.p + fd, &(struct iovec){buf, size}, 1);
|
||||
rc = sys_readv_metal(g_fds.p + fd, &(struct iovec){buf, size}, 1);
|
||||
} else {
|
||||
return sys_readv_nt(g_fds.p + fd, &(struct iovec){buf, size}, 1);
|
||||
rc = sys_readv_nt(g_fds.p + fd, &(struct iovec){buf, size}, 1);
|
||||
}
|
||||
} else {
|
||||
return einval();
|
||||
rc = einval();
|
||||
}
|
||||
STRACE("read(%d, %p, %'zu) → %'zd% m", fd, buf, size, rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sock/internal.h"
|
||||
|
@ -32,21 +33,25 @@
|
|||
* @asyncsignalsafe
|
||||
*/
|
||||
ssize_t readv(int fd, const struct iovec *iov, int iovlen) {
|
||||
ssize_t rc;
|
||||
if (fd >= 0 && iovlen >= 0) {
|
||||
if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) return efault();
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
return weaken(__zipos_read)(
|
||||
if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) {
|
||||
rc = efault();
|
||||
} else if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
rc = weaken(__zipos_read)(
|
||||
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1);
|
||||
} else if (!IsWindows() && !IsMetal()) {
|
||||
return sys_readv(fd, iov, iovlen);
|
||||
rc = sys_readv(fd, iov, iovlen);
|
||||
} else if (fd >= g_fds.n) {
|
||||
return ebadf();
|
||||
rc = ebadf();
|
||||
} else if (IsMetal()) {
|
||||
return sys_readv_metal(g_fds.p + fd, iov, iovlen);
|
||||
rc = sys_readv_metal(g_fds.p + fd, iov, iovlen);
|
||||
} else {
|
||||
return sys_readv_nt(g_fds.p + fd, iov, iovlen);
|
||||
rc = sys_readv_nt(g_fds.p + fd, iov, iovlen);
|
||||
}
|
||||
} else {
|
||||
return einval();
|
||||
rc = einval();
|
||||
}
|
||||
STRACE("readv(%d, %p, %d) → %'zd% m", fd, iov, iovlen, rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
|
@ -37,22 +38,26 @@
|
|||
* @asyncsignalsafe
|
||||
*/
|
||||
ssize_t write(int fd, const void *buf, size_t size) {
|
||||
ssize_t rc;
|
||||
if (fd >= 0) {
|
||||
if (IsAsan() && !__asan_is_valid(buf, size)) return efault();
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
return weaken(__zipos_write)(
|
||||
if (IsAsan() && !__asan_is_valid(buf, size)) {
|
||||
rc = efault();
|
||||
} else if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
rc = weaken(__zipos_write)(
|
||||
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle,
|
||||
&(struct iovec){buf, size}, 1, -1);
|
||||
} else if (!IsWindows() && !IsMetal()) {
|
||||
return sys_write(fd, buf, size);
|
||||
rc = sys_write(fd, buf, size);
|
||||
} else if (fd >= g_fds.n) {
|
||||
return ebadf();
|
||||
rc = ebadf();
|
||||
} else if (IsMetal()) {
|
||||
return sys_writev_metal(g_fds.p + fd, &(struct iovec){buf, size}, 1);
|
||||
rc = sys_writev_metal(g_fds.p + fd, &(struct iovec){buf, size}, 1);
|
||||
} else {
|
||||
return sys_writev_nt(fd, &(struct iovec){buf, size}, 1);
|
||||
rc = sys_writev_nt(fd, &(struct iovec){buf, size}, 1);
|
||||
}
|
||||
} else {
|
||||
return einval();
|
||||
rc = einval();
|
||||
}
|
||||
STRACE("write(%d, %p, %'zu) → %'zd% m", fd, buf, size, rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
@ -35,21 +36,25 @@
|
|||
* @return number of bytes actually handed off, or -1 w/ errno
|
||||
*/
|
||||
ssize_t writev(int fd, const struct iovec *iov, int iovlen) {
|
||||
ssize_t rc;
|
||||
if (fd >= 0 && iovlen >= 0) {
|
||||
if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) return efault();
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
return weaken(__zipos_write)(
|
||||
if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) {
|
||||
rc = efault();
|
||||
} else if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
rc = weaken(__zipos_write)(
|
||||
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1);
|
||||
} else if (!IsWindows() && !IsMetal()) {
|
||||
return sys_writev(fd, iov, iovlen);
|
||||
rc = sys_writev(fd, iov, iovlen);
|
||||
} else if (fd >= g_fds.n) {
|
||||
return ebadf();
|
||||
rc = ebadf();
|
||||
} else if (IsMetal()) {
|
||||
return sys_writev_metal(g_fds.p + fd, iov, iovlen);
|
||||
rc = sys_writev_metal(g_fds.p + fd, iov, iovlen);
|
||||
} else {
|
||||
return sys_writev_nt(fd, iov, iovlen);
|
||||
rc = sys_writev_nt(fd, iov, iovlen);
|
||||
}
|
||||
} else {
|
||||
return einval();
|
||||
rc = einval();
|
||||
}
|
||||
STRACE("writev(%d, %p, %d) → %'zd% m", fd, iov, iovlen, rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "libc/nt/enum/version.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/runtime/directmap.internal.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/symbols.internal.h"
|
||||
|
@ -321,6 +322,7 @@ static void __asan_exit(void) {
|
|||
kprintf("your asan runtime needs%n"
|
||||
"\tSTATIC_YOINK(\"__die\");%n"
|
||||
"in order to show you backtraces%n");
|
||||
__restorewintty();
|
||||
_Exit(99);
|
||||
}
|
||||
|
||||
|
@ -1366,6 +1368,7 @@ textstartup void __asan_init(int argc, char **argv, char **envp,
|
|||
if (!cmpxchg(&once, false, true)) return;
|
||||
if (IsWindows() && NtGetVersion() < kNtVersionWindows10) {
|
||||
__write_str("error: asan binaries require windows10\r\n");
|
||||
__restorewintty();
|
||||
_Exit(0); /* So `make MODE=dbg test` passes w/ Windows7 */
|
||||
}
|
||||
REQUIRE(_mmi);
|
||||
|
@ -1389,6 +1392,11 @@ textstartup void __asan_init(int argc, char **argv, char **envp,
|
|||
__asan_shadow_string_list(envp);
|
||||
__asan_shadow_auxv(auxv);
|
||||
__asan_install_malloc_hooks();
|
||||
STRACE(" _ ____ _ _ _ ");
|
||||
STRACE(" / \\ / ___| / \\ | \\ | |");
|
||||
STRACE(" / _ \\ \\___ \\ / _ \\ | \\| |");
|
||||
STRACE(" / ___ \\ ___) / ___ \\| |\\ |");
|
||||
STRACE("/_/ \\_\\____/_/ \\_\\_| \\_|");
|
||||
STRACE("cosmopolitan memory safety module initialized");
|
||||
}
|
||||
|
||||
|
|
|
@ -26,9 +26,6 @@
|
|||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
uint32_t __winmainpid;
|
||||
const char kConsoleHandles[2] = {kNtStdInputHandle, kNtStdOutputHandle};
|
||||
|
||||
/**
|
||||
* Exits process faster.
|
||||
*
|
||||
|
@ -36,14 +33,9 @@ const char kConsoleHandles[2] = {kNtStdInputHandle, kNtStdOutputHandle};
|
|||
* @noreturn
|
||||
*/
|
||||
wontreturn void quick_exit(int exitcode) {
|
||||
int i;
|
||||
const uintptr_t *p;
|
||||
STRACE("quick_exit(%d)", exitcode);
|
||||
if (SupportsWindows() && GetCurrentProcessId() == __winmainpid) {
|
||||
for (i = 0; i < 2; ++i) {
|
||||
SetConsoleMode(GetStdHandle(kConsoleHandles[i]), __ntconsolemode[i]);
|
||||
}
|
||||
}
|
||||
__restorewintty();
|
||||
if (weaken(fflush)) {
|
||||
weaken(fflush)(0);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*-*- 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 │
|
||||
│ Copyright 2022 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 │
|
||||
|
@ -16,20 +16,24 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/symbols.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/nt/console.h"
|
||||
#include "libc/nt/process.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
|
||||
uint32_t __winmainpid;
|
||||
const char kConsoleHandles[2] = {kNtStdInputHandle, kNtStdOutputHandle};
|
||||
|
||||
/**
|
||||
* Returns debug binary symbol table, as global singleton.
|
||||
* @return symbol table, or NULL w/ errno on first call
|
||||
* Puts cmd.exe gui back the way it was.
|
||||
*/
|
||||
noasan struct SymbolTable *GetSymbolTable(void) {
|
||||
static struct SymbolTable *singleton;
|
||||
if (!singleton) {
|
||||
++g_ftrace;
|
||||
singleton = OpenSymbolTable(FindDebugBinary());
|
||||
--g_ftrace;
|
||||
noasan void __restorewintty(void) {
|
||||
int i;
|
||||
if (IsWindows() && GetCurrentProcessId() == __winmainpid) {
|
||||
for (i = 0; i < 2; ++i) {
|
||||
SetConsoleMode(GetStdHandle(kConsoleHandles[i]), __ntconsolemode[i]);
|
||||
}
|
||||
__winmainpid = 0;
|
||||
}
|
||||
return singleton;
|
||||
}
|
|
@ -20,6 +20,7 @@
|
|||
#include "libc/bits/pushpop.h"
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/log/color.internal.h"
|
||||
|
@ -199,6 +200,7 @@ static void __ubsan_exit(void) {
|
|||
kprintf("your ubsan runtime needs%n"
|
||||
"\tSTATIC_YOINK(\"__die\");%n"
|
||||
"in order to show you backtraces%n");
|
||||
__restorewintty();
|
||||
_Exit(99);
|
||||
}
|
||||
|
||||
|
@ -594,3 +596,16 @@ void __ubsan_on_report(void) {
|
|||
void *__ubsan_get_current_report_data(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static textstartup void ubsan_init() {
|
||||
STRACE(" _ _ ____ ____ _ _ _");
|
||||
STRACE("| | | | __ ) ___| / \\ | \\ | |");
|
||||
STRACE("| | | | _ \\___ \\ / _ \\ | \\| |");
|
||||
STRACE("| |_| | |_) |__) / ___ \\| |\\ |");
|
||||
STRACE(" \\___/|____/____/_/ \\_\\_| \\_|");
|
||||
STRACE("cosmopolitan behavior module initialized");
|
||||
}
|
||||
|
||||
const void *const ubsan_ctor[] initarray = {
|
||||
ubsan_init,
|
||||
};
|
||||
|
|
|
@ -65,7 +65,6 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) {
|
|||
char buf[kBacktraceBufSize], *argv[kBacktraceMaxFrames];
|
||||
|
||||
if (!(debugbin = FindDebugBinary())) {
|
||||
ShowHint("can't find .com.dbg file try setting COMDBG");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "libc/log/internal.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
/**
|
||||
|
@ -38,8 +39,10 @@ relegated wontreturn void __die(void) {
|
|||
DebugBreak();
|
||||
}
|
||||
ShowBacktrace(2, NULL);
|
||||
__restorewintty();
|
||||
_Exit(77);
|
||||
}
|
||||
__write_str("PANIC: __DIE() DIED\r\n");
|
||||
__restorewintty();
|
||||
_Exit(78);
|
||||
}
|
||||
|
|
|
@ -103,6 +103,7 @@ noasan void CheckForMemoryLeaks(void) {
|
|||
PrintMemoryIntervals(2, &_mmi);
|
||||
/* PrintSystemMappings(2); */
|
||||
/* PrintGarbage(); */
|
||||
__restorewintty();
|
||||
_Exit(78);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nexgen32e/stackframe.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/pc.internal.h"
|
||||
|
||||
/**
|
||||
|
@ -275,7 +276,8 @@ static wontreturn relegated noinstrument void __minicrash(int sig,
|
|||
"%n",
|
||||
kind, TinyStrSignal(sig), __argv[0], ctx ? ctx->uc_mcontext.rip : 0,
|
||||
ctx ? ctx->uc_mcontext.rsp : 0, ctx ? ctx->uc_mcontext.rbp : 0);
|
||||
quick_exit(119);
|
||||
__restorewintty();
|
||||
_Exit(119);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -316,6 +318,7 @@ relegated noinstrument void __oncrash(int sig, struct siginfo *si,
|
|||
if (!(gdbpid > 0 && (sig == SIGTRAP || sig == SIGQUIT))) {
|
||||
__restore_tty(1);
|
||||
ShowCrashReport(err, sig, si, ctx);
|
||||
__restorewintty();
|
||||
_Exit(128 + sig);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "libc/errno.h"
|
||||
#include "libc/log/color.internal.h"
|
||||
#include "libc/log/internal.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
|
||||
/**
|
||||
|
|
|
@ -80,13 +80,6 @@ cosmo: push %rbp
|
|||
.init.start 306,_init_ftrace
|
||||
push %rdi
|
||||
push %rsi
|
||||
mov %r12d,%edi
|
||||
mov %r13,%rsi
|
||||
mov %r14,%rdx
|
||||
mov %r15,%rcx
|
||||
call program_executable_name_init
|
||||
mov %r12d,%edi
|
||||
mov %r13,%rsi
|
||||
call ftrace_init
|
||||
mov %eax,%r12d
|
||||
pop %rsi
|
||||
|
@ -99,10 +92,6 @@ cosmo: push %rbp
|
|||
.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
|
||||
|
|
|
@ -39,7 +39,7 @@ const char *FindComBinary(void) {
|
|||
const char *p;
|
||||
if (!g_findcombinary.once) {
|
||||
g_findcombinary.once = true;
|
||||
if ((p = program_executable_name) &&
|
||||
if ((p = GetProgramExecutableName()) &&
|
||||
(len = strlen(p)) < ARRAYLEN(g_findcombinary.buf)) {
|
||||
g_findcombinary.res = memcpy(g_findcombinary.buf, p, len + 1);
|
||||
if (len > 4 && memcmp(&g_findcombinary.buf[len - 4], ".dbg", 4) == 0) {
|
||||
|
|
|
@ -35,7 +35,7 @@ const char *FindDebugBinary(void) {
|
|||
size_t n;
|
||||
if (!once) {
|
||||
if (!(res = getenv("COMDBG"))) {
|
||||
p = program_executable_name;
|
||||
p = GetProgramExecutableName();
|
||||
n = strlen(p);
|
||||
if (n > 4 && READ32LE(p + n - 4) == READ32LE(".dbg")) {
|
||||
res = p;
|
||||
|
|
|
@ -291,7 +291,7 @@ textwindows int sys_fork_nt(void) {
|
|||
args = args2;
|
||||
}
|
||||
#endif
|
||||
if (ntspawn(program_executable_name, args, environ, forkvar,
|
||||
if (ntspawn(GetProgramExecutableName(), args, environ, forkvar,
|
||||
&kNtIsInheritable, NULL, true, 0, NULL, &startinfo,
|
||||
&procinfo) != -1) {
|
||||
CloseHandle(reader);
|
||||
|
|
|
@ -102,9 +102,7 @@ privileged noinstrument noasan noubsan void ftracer(void) {
|
|||
}
|
||||
|
||||
textstartup void ftrace_install(void) {
|
||||
const char *path;
|
||||
if ((path = FindDebugBinary())) {
|
||||
if ((g_symbols = OpenSymbolTable(path))) {
|
||||
if ((g_symbols = GetSymbolTable())) {
|
||||
laststamp = kStartTsc;
|
||||
g_lastsymbol = -1;
|
||||
g_skew = GetNestingLevelImpl(__builtin_frame_address(0));
|
||||
|
@ -113,7 +111,4 @@ textstartup void ftrace_install(void) {
|
|||
} else {
|
||||
kprintf("error: --ftrace failed to open symbol table\r\n");
|
||||
}
|
||||
} else {
|
||||
kprintf("error: --ftrace needs concomitant .com.dbg binary\r\n");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,8 +52,8 @@ char *GetInterpreterExecutableName(char *p, size_t n) {
|
|||
if (n < 2) {
|
||||
errno = ENAMETOOLONG;
|
||||
} else if (IsWindows()) {
|
||||
if (strlen(program_executable_name) < n) {
|
||||
strcpy(p, program_executable_name);
|
||||
if (strlen(GetProgramExecutableName()) < n) {
|
||||
strcpy(p, GetProgramExecutableName());
|
||||
return p;
|
||||
}
|
||||
errno = ENAMETOOLONG;
|
||||
|
|
133
libc/runtime/getsymboltable.c
Normal file
133
libc/runtime/getsymboltable.c
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*-*- 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/assert.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/symbols.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/undeflate.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "libc/zip.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
/**
|
||||
* Looks for `.symtab` in zip central directory.
|
||||
*/
|
||||
noasan static ssize_t FindSymtabInZip(struct Zipos *zipos) {
|
||||
size_t i, n, c;
|
||||
c = GetZipCdirOffset(zipos->cdir);
|
||||
n = GetZipCdirRecords(zipos->cdir);
|
||||
for (i = 0; i < n; ++i, c += ZIP_CFILE_HDRSIZE(zipos->map + c)) {
|
||||
if (ZIP_CFILE_NAMESIZE(zipos->map + c) == 7 &&
|
||||
READ32LE(ZIP_CFILE_NAME(zipos->map + c + 0)) == READ32LE(".sym") &&
|
||||
READ16LE(ZIP_CFILE_NAME(zipos->map + c + 4)) == READ16LE("ta") &&
|
||||
*ZIP_CFILE_NAME(zipos->map + c + 6) == 'b') {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads symbol table from zip directory.
|
||||
* @note This code can't depend on dlmalloc()
|
||||
*/
|
||||
noasan static struct SymbolTable *GetSymbolTableFromZip(struct Zipos *zipos) {
|
||||
ssize_t cf, lf;
|
||||
size_t size, size2;
|
||||
struct DeflateState ds;
|
||||
struct SymbolTable *res = 0;
|
||||
if ((cf = FindSymtabInZip(zipos)) != -1) {
|
||||
lf = GetZipCfileOffset(zipos->map + cf);
|
||||
size = GetZipLfileUncompressedSize(zipos->map + lf);
|
||||
size2 = ROUNDUP(size, FRAMESIZE);
|
||||
if ((res = mapanon(size2))) {
|
||||
switch (ZIP_LFILE_COMPRESSIONMETHOD(zipos->map + lf)) {
|
||||
case kZipCompressionNone:
|
||||
memcpy(res, (void *)ZIP_LFILE_CONTENT(zipos->map + lf), size);
|
||||
break;
|
||||
case kZipCompressionDeflate:
|
||||
if (undeflate(res, size, (void *)ZIP_LFILE_CONTENT(zipos->map + lf),
|
||||
GetZipLfileCompressedSize(zipos->map + lf),
|
||||
&ds) == -1) {
|
||||
munmap(res, size2);
|
||||
res = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
munmap(res, size2);
|
||||
res = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
STRACE("GetSymbolTableFromZip() → %p", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads symbol table from .com.dbg file.
|
||||
* @note This code can't depend on dlmalloc()
|
||||
*/
|
||||
noasan static struct SymbolTable *GetSymbolTableFromElf(void) {
|
||||
return OpenSymbolTable(FindDebugBinary());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns symbol table singleton.
|
||||
*
|
||||
* This uses multiple strategies to find the symbol table. The first
|
||||
* strategy, depends on whether or not the following is linked:
|
||||
*
|
||||
* STATIC_YOINK("__zipos_get");
|
||||
*
|
||||
* In that case, the symbol table may be read from `/zip/.symtab` which
|
||||
* is generated by `o//tool/build/symtab.com`. The second strategy is to
|
||||
* look for the concomitant `.com.dbg` executable, which may very well
|
||||
* be the one currently executing, or it could be placed in the same
|
||||
* folder as your `.com` binary, or lastly, it could be explicitly
|
||||
* specified via the `COMDBG` environment variable.
|
||||
*
|
||||
* Function tracing is disabled throughout the duration of this call.
|
||||
* Backtraces and other core runtime functionality depend on this.
|
||||
*
|
||||
* @return symbol table, or NULL w/ errno on first call
|
||||
*/
|
||||
noasan struct SymbolTable *GetSymbolTable(void) {
|
||||
struct Zipos *z;
|
||||
static struct SymbolTable *t;
|
||||
if (!t) {
|
||||
++g_ftrace;
|
||||
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 (!t) {
|
||||
t = GetSymbolTableFromElf();
|
||||
}
|
||||
--g_ftrace;
|
||||
}
|
||||
return t;
|
||||
}
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
|
|
@ -18,6 +18,7 @@ extern const uintptr_t __fini_array_end[] __attribute__((__weak__));
|
|||
extern const uintptr_t __fini_array_start[] __attribute__((__weak__));
|
||||
|
||||
void _init(void) hidden;
|
||||
void __restorewintty(void) hidden;
|
||||
void *__cxa_finalize(void *) hidden;
|
||||
void cosmo(int, char **, char **, long (*)[2]) hidden wontreturn;
|
||||
void __stack_chk_fail(void) wontreturn relegated;
|
||||
|
|
|
@ -110,11 +110,11 @@ noasan struct SymbolTable *OpenSymbolTable(const char *filename) {
|
|||
void *map;
|
||||
long *stp;
|
||||
struct stat st;
|
||||
size_t n, m, tsz;
|
||||
unsigned i, j, x;
|
||||
const Elf64_Ehdr *elf;
|
||||
const char *name_base;
|
||||
struct SymbolTable *t;
|
||||
size_t n, m, tsz, size;
|
||||
const Elf64_Sym *symtab, *sym;
|
||||
ptrdiff_t names_offset, name_base_offset, stp_offset;
|
||||
map = MAP_FAILED;
|
||||
|
@ -136,13 +136,19 @@ noasan struct SymbolTable *OpenSymbolTable(const char *filename) {
|
|||
tsz += m;
|
||||
tsz = ROUNDUP(tsz, FRAMESIZE);
|
||||
stp_offset = tsz;
|
||||
size = tsz;
|
||||
tsz += sizeof(const Elf64_Sym *) * n;
|
||||
tsz = ROUNDUP(tsz, FRAMESIZE);
|
||||
t = mmap(0, tsz, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||
if (t == MAP_FAILED) goto SystemError;
|
||||
t->mapsize = tsz;
|
||||
t->names = (unsigned *)((char *)t + names_offset);
|
||||
t->name_base = (char *)((char *)t + name_base_offset);
|
||||
t->magic = SYMBOLS_MAGIC;
|
||||
t->abi = SYMBOLS_ABI;
|
||||
t->size = size;
|
||||
t->mapsize = size;
|
||||
t->names_offset = names_offset;
|
||||
t->name_base_offset = name_base_offset;
|
||||
t->names = (uint32_t *)((char *)t + t->names_offset);
|
||||
t->name_base = (char *)((char *)t + t->name_base_offset);
|
||||
GetImageRange(elf, &t->addr_base, &t->addr_end);
|
||||
memcpy(t->name_base, name_base, m);
|
||||
--t->addr_end;
|
||||
|
|
|
@ -75,25 +75,24 @@ static const struct AuxiliaryValue *DescribeAuxv(unsigned long x) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
textstartup void __printargs(int argc, char **argv, char **envp,
|
||||
intptr_t *auxv) {
|
||||
textstartup void __printargs(void) {
|
||||
#ifdef SYSDEBUG
|
||||
long key;
|
||||
char **env;
|
||||
unsigned i;
|
||||
intptr_t *auxp;
|
||||
uintptr_t *auxp;
|
||||
char path[PATH_MAX];
|
||||
struct AuxiliaryValue *auxinfo;
|
||||
STRACE("ARGUMENTS (%p)", argv);
|
||||
for (i = 0; i < argc; ++i) {
|
||||
STRACE(" ☼ %s", argv[i]);
|
||||
STRACE("ARGUMENTS (%p)", __argv);
|
||||
for (i = 0; i < __argc; ++i) {
|
||||
STRACE(" ☼ %s", __argv[i]);
|
||||
}
|
||||
STRACE("ENVIRONMENT (%p)", envp);
|
||||
for (env = envp; *env; ++env) {
|
||||
STRACE("ENVIRONMENT (%p)", __envp);
|
||||
for (env = __envp; *env; ++env) {
|
||||
STRACE(" ☼ %s", *env);
|
||||
}
|
||||
STRACE("AUXILIARY (%p)", auxv);
|
||||
for (auxp = auxv; *auxp; auxp += 2) {
|
||||
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);
|
||||
|
@ -105,7 +104,8 @@ textstartup void __printargs(int argc, char **argv, char **envp,
|
|||
STRACE(" ☼ %30s = %#s", "kTmpPath", kTmpPath);
|
||||
STRACE(" ☼ %30s = %#s", "kNtSystemDirectory", kNtSystemDirectory);
|
||||
STRACE(" ☼ %30s = %#s", "kNtWindowsDirectory", kNtWindowsDirectory);
|
||||
STRACE(" ☼ %30s = %#s", "program_executable_name", program_executable_name);
|
||||
STRACE(" ☼ %30s = %#s", "program_executable_name",
|
||||
GetProgramExecutableName());
|
||||
STRACE(" ☼ %30s = %#s", "GetInterpreterExecutableName()",
|
||||
GetInterpreterExecutableName(path, sizeof(path)));
|
||||
STRACE(" ☼ %30s = %p", "RSP", __builtin_frame_address(0));
|
||||
|
|
|
@ -9,10 +9,10 @@ COSMOPOLITAN_C_START_
|
|||
typedef long jmp_buf[8] forcealign(CACHELINE);
|
||||
|
||||
extern char **environ; /* CRT */
|
||||
extern const int __argc; /* CRT */
|
||||
extern char **const __argv; /* CRT */
|
||||
extern char **const __envp; /* CRT */
|
||||
extern unsigned long *const __auxv; /* CRT */
|
||||
extern int __argc; /* CRT */
|
||||
extern char **__argv; /* CRT */
|
||||
extern char **__envp; /* CRT */
|
||||
extern unsigned long *__auxv; /* CRT */
|
||||
extern intptr_t __oldstack; /* CRT */
|
||||
extern char program_executable_name[]; /* RII */
|
||||
extern char *program_invocation_name; /* RII */
|
||||
|
@ -98,6 +98,7 @@ int OpenExecutable(void);
|
|||
void ftrace_install(void);
|
||||
long GetResourceLimit(int);
|
||||
long GetMaxFd(void);
|
||||
char *GetProgramExecutableName(void);
|
||||
char *GetInterpreterExecutableName(char *, size_t);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
|
|
|
@ -18,11 +18,9 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#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"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
/**
|
||||
* Enables plaintext system call logging if `--strace` flag is passed.
|
||||
|
@ -33,5 +31,5 @@ textstartup int __strace_init(int argc, char **argv, char **envp, long *auxv) {
|
|||
__atoul(nulltoempty(__getenv(envp, "STRACE")))) {
|
||||
++__strace;
|
||||
}
|
||||
return argc;
|
||||
return (__argc = argc);
|
||||
}
|
||||
|
|
|
@ -1,20 +1,29 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_SYMBOLS_H_
|
||||
#define COSMOPOLITAN_LIBC_SYMBOLS_H_
|
||||
#include "libc/bits/bits.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#define SYMBOLS_MAGIC READ32LE("SYMT")
|
||||
#define SYMBOLS_ABI 1
|
||||
|
||||
struct Symbol {
|
||||
unsigned x; /* start (relative to addr_base) */
|
||||
unsigned y; /* start + size - 1 (inclusive) */
|
||||
};
|
||||
|
||||
struct SymbolTable {
|
||||
size_t count; /* of `symbols` */
|
||||
size_t mapsize; /* of this object */
|
||||
intptr_t addr_base; /* IMAGE_BASE_VIRTUAL */
|
||||
intptr_t addr_end; /* _end - 1 */
|
||||
unsigned *names; /* relative to `name_base` */
|
||||
uint32_t magic; /* 0xFEEDABEE little endian */
|
||||
uint32_t abi; /* 1 */
|
||||
uint64_t count; /* of `symbols` */
|
||||
uint64_t size; /* file size */
|
||||
uint64_t mapsize; /* of this object */
|
||||
int64_t addr_base; /* IMAGE_BASE_VIRTUAL */
|
||||
int64_t addr_end; /* _end - 1 */
|
||||
uint32_t *names; /* relative to `name_base` */
|
||||
char *name_base; /* double-nul terminated w/ empty first */
|
||||
uint32_t names_offset; /* for file loading */
|
||||
uint32_t name_base_offset; /* for file loading */
|
||||
struct Symbol symbols[]; /* sorted and non-overlapping intervals */
|
||||
};
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
|
@ -34,14 +35,20 @@
|
|||
*/
|
||||
int getsockopt(int fd, int level, int optname, void *out_opt_optval,
|
||||
uint32_t *out_optlen) {
|
||||
if (!level || !optname) return enoprotoopt(); /* our sysvconsts definition */
|
||||
if (optname == -1) return 0; /* our sysvconsts definition */
|
||||
if (!IsWindows()) {
|
||||
return sys_getsockopt(fd, level, optname, out_opt_optval, out_optlen);
|
||||
int rc;
|
||||
if (!level || !optname) {
|
||||
rc = enoprotoopt(); /* our sysvconsts definition */
|
||||
} else if (optname == -1) {
|
||||
rc = 0; /* our sysvconsts definition */
|
||||
} else if (!IsWindows()) {
|
||||
rc = sys_getsockopt(fd, level, optname, out_opt_optval, out_optlen);
|
||||
} else if (__isfdkind(fd, kFdSocket)) {
|
||||
return sys_getsockopt_nt(&g_fds.p[fd], level, optname, out_opt_optval,
|
||||
rc = sys_getsockopt_nt(&g_fds.p[fd], level, optname, out_opt_optval,
|
||||
out_optlen);
|
||||
} else {
|
||||
return ebadf();
|
||||
rc = ebadf();
|
||||
}
|
||||
STRACE("getsockopt(%d, %#x, %#x, %p, %p) → %d% m", fd, level, optname,
|
||||
out_opt_optval, out_optlen, rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/nt/winsock.h"
|
||||
|
@ -50,19 +51,29 @@ static bool setsockopt_polyfill(int *optname) {
|
|||
*/
|
||||
int setsockopt(int fd, int level, int optname, const void *optval,
|
||||
uint32_t optlen) {
|
||||
if (!optval) return efault();
|
||||
if (!level || !optname) return enoprotoopt(); /* our sysvconsts definition */
|
||||
if (optname == -1) return 0; /* our sysvconsts definition */
|
||||
if (!IsWindows()) {
|
||||
int e, rc;
|
||||
if (!optval) {
|
||||
rc = efault();
|
||||
} else if (!level || !optname) {
|
||||
rc = enoprotoopt(); /* our sysvconsts definition */
|
||||
} else if (optname == -1) {
|
||||
rc = 0; /* our sysvconsts definition */
|
||||
} else if (!IsWindows()) {
|
||||
rc = -1;
|
||||
e = errno;
|
||||
do {
|
||||
if (sys_setsockopt(fd, level, optname, optval, optlen) != -1) {
|
||||
return 0;
|
||||
errno = e;
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
} while (setsockopt_polyfill(&optname));
|
||||
return -1;
|
||||
} else if (__isfdkind(fd, kFdSocket)) {
|
||||
return sys_setsockopt_nt(&g_fds.p[fd], level, optname, optval, optlen);
|
||||
rc = sys_setsockopt_nt(&g_fds.p[fd], level, optname, optval, optlen);
|
||||
} else {
|
||||
return ebadf();
|
||||
rc = ebadf();
|
||||
}
|
||||
STRACE("setsockopt(%d, %#x, %#x, %p, %'u) → %d% m", fd, level, optname,
|
||||
optval, optlen, rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ int socket(int family, int type, int protocol) {
|
|||
} else {
|
||||
rc = sys_socket_nt(family, type, protocol);
|
||||
}
|
||||
STRACE("socket(%s, %s, %s) -> %d% m", __describe_socket_family(family),
|
||||
STRACE("socket(%s, %s, %s) → %d% m", __describe_socket_family(family),
|
||||
__describe_socket_type(type), __describe_socket_protocol(protocol),
|
||||
rc);
|
||||
return rc;
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
}
|
||||
|
||||
struct DeflateHold {
|
||||
size_t word;
|
||||
uint64_t word;
|
||||
size_t bits;
|
||||
};
|
||||
|
||||
|
|
|
@ -626,16 +626,16 @@ syscon clock CLOCK_TAI 11 -1 -1 -1 -1 -1 # bsd consensus
|
|||
# poll()
|
||||
#
|
||||
# group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology Commentary
|
||||
syscon poll POLLIN 1 1 1 1 1 0x300 # unix consensus
|
||||
syscon poll POLLIN 1 1 1 1 1 0x0300 # unix consensus; POLLRDNORM|POLLRDBAND on Windows
|
||||
syscon poll POLLPRI 2 2 2 2 2 0x0400 # unix consensus
|
||||
syscon poll POLLOUT 4 4 4 4 4 0x10 # unix consensus
|
||||
syscon poll POLLERR 8 8 8 8 8 1 # unix consensus
|
||||
syscon poll POLLHUP 0x10 0x10 0x10 0x10 0x10 2 # unix consensus
|
||||
syscon poll POLLNVAL 0x20 0x20 0x20 0x20 0x20 4 # unix consensus
|
||||
syscon poll POLLOUT 4 4 4 4 4 0x0010 # unix consensus; POLLWRNORM on Windows
|
||||
syscon poll POLLERR 8 8 8 8 8 0x0001 # unix consensus
|
||||
syscon poll POLLHUP 0x10 0x10 0x10 0x10 0x10 0x0002 # unix consensus
|
||||
syscon poll POLLNVAL 0x20 0x20 0x20 0x20 0x20 0x0004 # unix consensus
|
||||
syscon poll POLLRDBAND 0x80 0x80 0x80 0x80 0x80 0x0200 # unix consensus
|
||||
syscon poll POLLRDNORM 0x40 0x40 0x40 0x40 0x40 0x0100 # unix consensus
|
||||
syscon poll POLLWRBAND 0x0200 0x0100 0x0100 0x0100 0x0100 0x20 # bsd consensus
|
||||
syscon poll POLLWRNORM 0x0100 4 4 4 4 0x10 # bsd consensus
|
||||
syscon poll POLLWRBAND 0x0200 0x0100 0x0100 0x0100 0x0100 0x0020 # bsd consensus
|
||||
syscon poll POLLWRNORM 0x0100 4 4 4 4 0x0010 # bsd consensus
|
||||
syscon poll POLLRDHUP 0x2000 0x10 0x10 0x10 0x10 2 # bsd consensus (POLLHUP on non-Linux)
|
||||
|
||||
# epoll
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon poll,POLLERR,8,8,8,8,8,1
|
||||
.syscon poll,POLLERR,8,8,8,8,8,0x0001
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon poll,POLLHUP,0x10,0x10,0x10,0x10,0x10,2
|
||||
.syscon poll,POLLHUP,0x10,0x10,0x10,0x10,0x10,0x0002
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon poll,POLLIN,1,1,1,1,1,0x300
|
||||
.syscon poll,POLLIN,1,1,1,1,1,0x0300
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon poll,POLLNVAL,0x20,0x20,0x20,0x20,0x20,4
|
||||
.syscon poll,POLLNVAL,0x20,0x20,0x20,0x20,0x20,0x0004
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon poll,POLLOUT,4,4,4,4,4,0x10
|
||||
.syscon poll,POLLOUT,4,4,4,4,4,0x0010
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon poll,POLLWRBAND,0x0200,0x0100,0x0100,0x0100,0x0100,0x20
|
||||
.syscon poll,POLLWRBAND,0x0200,0x0100,0x0100,0x0100,0x0100,0x0020
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon poll,POLLWRNORM,0x0100,4,4,4,4,0x10
|
||||
.syscon poll,POLLWRNORM,0x0100,4,4,4,4,0x0010
|
||||
|
|
|
@ -46,7 +46,7 @@ testonly void testlib_showerror(const char *file, int line, const char *func,
|
|||
"\t%s%s\n",
|
||||
RED2, UNBOLD, BLUE1, file, (long)line, RESET, method, func,
|
||||
g_fixturename, code, v1, symbol, v2, SUBTLE, strerror(errno),
|
||||
program_executable_name, RESET);
|
||||
GetProgramExecutableName(), RESET);
|
||||
free_s(&v1);
|
||||
free_s(&v2);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/alloca.h"
|
||||
|
@ -71,7 +72,7 @@ struct Zipos *__zipos_get(void) {
|
|||
if (!once) {
|
||||
sigfillset(&neu);
|
||||
sigprocmask(SIG_BLOCK, &neu, &old);
|
||||
if ((fd = open(program_executable_name, O_RDONLY)) != -1) {
|
||||
if ((fd = open(GetProgramExecutableName(), O_RDONLY)) != -1) {
|
||||
if ((size = getfiledescriptorsize(fd)) != SIZE_MAX &&
|
||||
(map = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0)) != MAP_FAILED) {
|
||||
if ((base = FindEmbeddedApe(map, size))) {
|
||||
|
@ -83,12 +84,18 @@ struct Zipos *__zipos_get(void) {
|
|||
__zipos_munmap_unneeded(base, cdir, map);
|
||||
zipos.map = base;
|
||||
zipos.cdir = cdir;
|
||||
STRACE("__zipos_get(%#s)", program_executable_name);
|
||||
} else {
|
||||
munmap(map, size);
|
||||
kprintf("__zipos_get(%#s) → eocd not found%n",
|
||||
program_executable_name);
|
||||
STRACE("__zipos_get(%#s) → eocd not found", program_executable_name);
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
} else {
|
||||
kprintf("__zipos_get(%#s) → open failed %m%n", program_executable_name);
|
||||
STRACE("__zipos_get(%#s) → open failed %m", program_executable_name);
|
||||
}
|
||||
once = true;
|
||||
sigprocmask(SIG_SETMASK, &old, 0);
|
||||
|
|
10
third_party/chibicc/chibicc.mk
vendored
10
third_party/chibicc/chibicc.mk
vendored
|
@ -109,6 +109,16 @@ o/$(MODE)/third_party/chibicc/chibicc2.com.dbg: \
|
|||
$(THIRD_PARTY_CHIBICC2_A).pkg
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/third_party/chibicc/chibicc.com: \
|
||||
o/$(MODE)/third_party/chibicc/chibicc.com.dbg \
|
||||
o/$(MODE)/third_party/infozip/zip.com \
|
||||
o/$(MODE)/tool/build/symtab.com
|
||||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/third_party/chibicc/.chibicc/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/infozip/zip.com -9qj $@ \
|
||||
o/$(MODE)/third_party/chibicc/.chibicc/.symtab
|
||||
|
||||
o/$(MODE)/third_party/chibicc/as.com.dbg: \
|
||||
$(THIRD_PARTY_CHIBICC_A_DEPS) \
|
||||
$(THIRD_PARTY_CHIBICC_A) \
|
||||
|
|
10
third_party/lua/lua.mk
vendored
10
third_party/lua/lua.mk
vendored
|
@ -69,6 +69,16 @@ o/$(MODE)/third_party/lua/luac.com.dbg: \
|
|||
$(APE)
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/third_party/lua/lua.com: \
|
||||
o/$(MODE)/third_party/lua/lua.com.dbg \
|
||||
o/$(MODE)/third_party/infozip/zip.com \
|
||||
o/$(MODE)/tool/build/symtab.com
|
||||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/third_party/lua/.lua/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/infozip/zip.com -9qj $@ \
|
||||
o/$(MODE)/third_party/lua/.lua/.symtab
|
||||
|
||||
o/$(MODE)/third_party/lua/lauxlib.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-DSTACK_FRAME_UNLIMITED
|
||||
|
|
10
third_party/make/make.mk
vendored
10
third_party/make/make.mk
vendored
|
@ -114,6 +114,16 @@ o/$(MODE)/third_party/make/make.com.dbg: \
|
|||
$(APE_NO_MODIFY_SELF)
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/third_party/make/make.com: \
|
||||
o/$(MODE)/third_party/make/make.com.dbg \
|
||||
o/$(MODE)/third_party/infozip/zip.com \
|
||||
o/$(MODE)/tool/build/symtab.com
|
||||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/third_party/make/.make/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/infozip/zip.com -9qj $@ \
|
||||
o/$(MODE)/third_party/make/.make/.symtab
|
||||
|
||||
$(THIRD_PARTY_MAKE_OBJS): \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-DSTACK_FRAME_UNLIMITED \
|
||||
|
|
10
third_party/python/python.mk
vendored
10
third_party/python/python.mk
vendored
|
@ -4190,6 +4190,16 @@ o/$(MODE)/third_party/python/python.com.dbg: \
|
|||
$(APE_NO_MODIFY_SELF)
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/third_party/python/python.com: \
|
||||
o/$(MODE)/third_party/python/python.com.dbg \
|
||||
o/$(MODE)/third_party/infozip/zip.com \
|
||||
o/$(MODE)/tool/build/symtab.com
|
||||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/third_party/python/.python/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/infozip/zip.com -9qj $@ \
|
||||
o/$(MODE)/third_party/python/.python/.symtab
|
||||
|
||||
################################################################################
|
||||
# FREEZE.COM
|
||||
|
||||
|
|
10
third_party/quickjs/quickjs.mk
vendored
10
third_party/quickjs/quickjs.mk
vendored
|
@ -147,6 +147,16 @@ o/$(MODE)/third_party/quickjs/qjs.com.dbg: \
|
|||
$(APE)
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/third_party/quickjs/qjs.com: \
|
||||
o/$(MODE)/third_party/quickjs/qjs.com.dbg \
|
||||
o/$(MODE)/third_party/infozip/zip.com \
|
||||
o/$(MODE)/tool/build/symtab.com
|
||||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/third_party/quickjs/.qjs/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/infozip/zip.com -9qj $@ \
|
||||
o/$(MODE)/third_party/quickjs/.qjs/.symtab
|
||||
|
||||
o/$(MODE)/third_party/quickjs/qjsc.com.dbg: \
|
||||
$(THIRD_PARTY_QUICKJS) \
|
||||
o/$(MODE)/third_party/quickjs/qjsc.o \
|
||||
|
|
10
third_party/sqlite3/sqlite3.mk
vendored
10
third_party/sqlite3/sqlite3.mk
vendored
|
@ -76,6 +76,16 @@ o/$(MODE)/third_party/sqlite3/sqlite3.com.dbg: \
|
|||
$(APE_NO_MODIFY_SELF)
|
||||
-@$(APELINK)
|
||||
|
||||
o/$(MODE)/third_party/sqlite3/sqlite3.com: \
|
||||
o/$(MODE)/third_party/sqlite3/sqlite3.com.dbg \
|
||||
o/$(MODE)/third_party/infozip/zip.com \
|
||||
o/$(MODE)/tool/build/symtab.com
|
||||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/third_party/sqlite3/.sqlite3/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/infozip/zip.com -9qj $@ \
|
||||
o/$(MODE)/third_party/sqlite3/.sqlite3/.symtab
|
||||
|
||||
$(THIRD_PARTY_SQLITE3_A): \
|
||||
third_party/sqlite3/ \
|
||||
$(THIRD_PARTY_SQLITE3_A).pkg \
|
||||
|
|
|
@ -3105,7 +3105,9 @@ static void OnlyRunOnFirstCpu(void) {
|
|||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (!NoDebug()) ShowCrashReports();
|
||||
if (!NoDebug()) {
|
||||
ShowCrashReports();
|
||||
}
|
||||
pty = NewPty();
|
||||
pty->conf |= kPtyNocanon;
|
||||
m = NewMachine();
|
||||
|
|
|
@ -50,6 +50,7 @@ TOOL_BUILD_DIRECTDEPS = \
|
|||
LIBC_TINYMATH \
|
||||
LIBC_UNICODE \
|
||||
LIBC_X \
|
||||
LIBC_ZIPOS \
|
||||
NET_HTTPS \
|
||||
THIRD_PARTY_COMPILER_RT \
|
||||
THIRD_PARTY_GDTOA \
|
||||
|
@ -78,7 +79,7 @@ o/$(MODE)/tool/build/%.com.dbg: \
|
|||
o/$(MODE)/tool/build/%.o \
|
||||
$(CRT) \
|
||||
$(APE)
|
||||
-@$(APELINK)
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/tool/build/blinkenlights.com.dbg: \
|
||||
$(TOOL_BUILD_DEPS) \
|
||||
|
@ -88,13 +89,23 @@ o/$(MODE)/tool/build/blinkenlights.com.dbg: \
|
|||
$(APE_NO_MODIFY_SELF)
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/tool/build/blinkenlights.com: \
|
||||
o/$(MODE)/tool/build/blinkenlights.com.dbg \
|
||||
o/$(MODE)/third_party/infozip/zip.com \
|
||||
o/$(MODE)/tool/build/symtab.com
|
||||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/tool/build/.blinkenlights/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/infozip/zip.com -9qj $@ \
|
||||
o/$(MODE)/tool/build/.blinkenlights/.symtab
|
||||
|
||||
o/$(MODE)/tool/build/ar.com.dbg: \
|
||||
$(TOOL_BUILD_DEPS) \
|
||||
o/$(MODE)/tool/build/build.pkg \
|
||||
o/$(MODE)/tool/build/ar.o \
|
||||
$(CRT) \
|
||||
$(APE)
|
||||
-@$(APELINK)
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/tool/build/package.com.dbg: \
|
||||
$(TOOL_BUILD_DEPS) \
|
||||
|
@ -102,7 +113,7 @@ o/$(MODE)/tool/build/package.com.dbg: \
|
|||
o/$(MODE)/tool/build/package.o \
|
||||
$(CRT) \
|
||||
$(APE)
|
||||
-@$(APELINK)
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/tool/build/mkdeps.com.dbg: \
|
||||
$(TOOL_BUILD_DEPS) \
|
||||
|
@ -118,7 +129,7 @@ o/$(MODE)/tool/build/compile.com.dbg: \
|
|||
o/$(MODE)/tool/build/compile.o \
|
||||
$(CRT) \
|
||||
$(APE)
|
||||
-@$(APELINK)
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/tool/build/zipobj.com.dbg: \
|
||||
$(TOOL_BUILD_DEPS) \
|
||||
|
@ -126,7 +137,7 @@ o/$(MODE)/tool/build/zipobj.com.dbg: \
|
|||
o/$(MODE)/tool/build/zipobj.o \
|
||||
$(CRT) \
|
||||
$(APE)
|
||||
-@$(APELINK)
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/tool/build/emulator.o: \
|
||||
OVERRIDE_COPTS += \
|
||||
|
|
99
tool/build/symtab.c
Normal file
99
tool/build/symtab.c
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*-*- 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 2022 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/errno.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/symbols.internal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/ex.h"
|
||||
#include "libc/sysv/consts/exit.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "third_party/getopt/getopt.h"
|
||||
|
||||
/**
|
||||
* @fileoverview elf to symbol table file dump tool
|
||||
*/
|
||||
|
||||
void PrintUsage(FILE *f) {
|
||||
fprintf(f, "%s%s%s\n", "usage: ", program_invocation_name,
|
||||
" [-?h] -o PATH COMDBG");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int fd, opt;
|
||||
const char *outpath;
|
||||
struct SymbolTable *tab;
|
||||
|
||||
outpath = 0;
|
||||
|
||||
while ((opt = getopt(argc, argv, "?ho:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'o':
|
||||
outpath = optarg;
|
||||
break;
|
||||
case '?':
|
||||
case 'h':
|
||||
PrintUsage(stdout);
|
||||
return 0;
|
||||
default:
|
||||
PrintUsage(stderr);
|
||||
return EX_USAGE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!outpath) {
|
||||
fprintf(stderr, "error: need output path\n");
|
||||
PrintUsage(stderr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (optind + 1 != argc) {
|
||||
fprintf(stderr, "error: need exactly one input path\n");
|
||||
PrintUsage(stderr);
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (!(tab = OpenSymbolTable(argv[optind]))) {
|
||||
fprintf(stderr, "error: %s(%`'s) failed %m\n", "OpenSymbolTable",
|
||||
argv[optind]);
|
||||
return 3;
|
||||
}
|
||||
|
||||
tab->names = 0;
|
||||
tab->name_base = 0;
|
||||
|
||||
if ((fd = open(outpath, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) {
|
||||
fprintf(stderr, "error: %s(%`'s) failed %m\n", "open", outpath);
|
||||
return 4;
|
||||
}
|
||||
|
||||
if (write(fd, (const char *)tab, tab->size) != tab->size) {
|
||||
fprintf(stderr, "error: %s(%`'s) failed %m\n", "write", outpath);
|
||||
return 5;
|
||||
}
|
||||
|
||||
if (close(fd) == -1) {
|
||||
fprintf(stderr, "error: %s(%`'s) failed %m\n", "close", outpath);
|
||||
return 6;
|
||||
}
|
||||
|
||||
CloseSymbolTable(&tab);
|
||||
return 0;
|
||||
}
|
|
@ -52,7 +52,7 @@ struct timespec timestamp;
|
|||
wontreturn void PrintUsage(int rc, FILE *f) {
|
||||
fprintf(f, "%s%s%s\n", "Usage: ", program_invocation_name,
|
||||
" [-n] [-B] [-C INT] [-P PREFIX] [-o FILE] [-s SYMBOL] [-y YOINK] "
|
||||
"[FILE...]\n");
|
||||
"[FILE...]");
|
||||
exit(rc);
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,8 @@ FLAGS
|
|||
-P PATH pid file location
|
||||
-U INT daemon set user id
|
||||
-G INT daemon set group id
|
||||
--strace enables system call tracing
|
||||
--ftrace enables function call tracing
|
||||
|
||||
FEATURES
|
||||
|
||||
|
|
|
@ -98,14 +98,23 @@ o/$(MODE)/tool/net/redbean.com.dbg: \
|
|||
o/$(MODE)/tool/net/redbean.com: \
|
||||
o/$(MODE)/tool/net/redbean.com.dbg \
|
||||
o/$(MODE)/third_party/infozip/zip.com \
|
||||
o/$(MODE)/tool/build/symtab.com \
|
||||
tool/net/net.mk \
|
||||
tool/net/help.txt \
|
||||
tool/net/.init.lua \
|
||||
tool/net/favicon.ico \
|
||||
tool/net/redbean.png
|
||||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -ADD -T$@ dd if=$@ of=o/$(MODE)/tool/net/.ape bs=64 count=11 conv=notrunc 2>/dev/null
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/infozip/zip.com -qj $@ o/$(MODE)/tool/net/.ape tool/net/help.txt tool/net/.init.lua tool/net/favicon.ico tool/net/redbean.png
|
||||
@$(COMPILE) -AMKDIR -T$@ mkdir -p o/$(MODE)/tool/net/.redbean
|
||||
@$(COMPILE) -ADD -T$@ dd if=$@ of=o/$(MODE)/tool/net/.redbean/.ape bs=64 count=11 conv=notrunc 2>/dev/null
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com -o o/$(MODE)/tool/net/.redbean/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/infozip/zip.com -9qj $@ \
|
||||
o/$(MODE)/tool/net/.redbean/.ape \
|
||||
o/$(MODE)/tool/net/.redbean/.symtab \
|
||||
tool/net/help.txt \
|
||||
tool/net/.init.lua \
|
||||
tool/net/favicon.ico \
|
||||
tool/net/redbean.png
|
||||
|
||||
# REDBEAN-DEMO.COM
|
||||
#
|
||||
|
@ -184,11 +193,16 @@ o/$(MODE)/tool/net/redbean-demo.com.dbg: \
|
|||
|
||||
o/$(MODE)/tool/net/redbean-demo.com: \
|
||||
o/$(MODE)/tool/net/redbean-demo.com.dbg \
|
||||
o/$(MODE)/tool/build/symtab.com \
|
||||
o/$(MODE)/third_party/infozip/zip.com
|
||||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -AMKDIR -T$@ mkdir -p o/$(MODE)/tool/net/.redbean-demo
|
||||
@$(COMPILE) -ADD -T$@ dd if=$@ of=o/$(MODE)/tool/net/.redbean-demo/.ape bs=64 count=11 conv=notrunc 2>/dev/null
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/infozip/zip.com -qj $@ o/$(MODE)/tool/net/.redbean-demo/.ape
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/tool/net/.redbean-demo/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/infozip/zip.com -9qj $@ \
|
||||
o/$(MODE)/tool/net/.redbean-demo/.ape \
|
||||
o/$(MODE)/tool/net/.redbean-demo/.symtab
|
||||
|
||||
# REDBEAN-STATIC.COM
|
||||
#
|
||||
|
@ -198,13 +212,21 @@ o/$(MODE)/tool/net/redbean-demo.com: \
|
|||
o/$(MODE)/tool/net/redbean-static.com: \
|
||||
o/$(MODE)/tool/net/redbean-static.com.dbg \
|
||||
o/$(MODE)/third_party/infozip/zip.com \
|
||||
o/$(MODE)/tool/build/symtab.com \
|
||||
tool/net/help.txt \
|
||||
tool/net/favicon.ico \
|
||||
tool/net/redbean.png
|
||||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -AMKDIR -T$@ mkdir -p o/$(MODE)/tool/net/.redbean-static
|
||||
@$(COMPILE) -ADD -T$@ dd if=$@ of=o/$(MODE)/tool/net/.redbean-static/.ape bs=64 count=11 conv=notrunc 2>/dev/null
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/infozip/zip.com -qj $@ o/$(MODE)/tool/net/.redbean-static/.ape tool/net/help.txt tool/net/favicon.ico tool/net/redbean.png
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/tool/net/.redbean-static/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/infozip/zip.com -9qj $@ \
|
||||
o/$(MODE)/tool/net/.redbean-static/.ape \
|
||||
o/$(MODE)/tool/net/.redbean-static/.symtab \
|
||||
tool/net/help.txt \
|
||||
tool/net/favicon.ico \
|
||||
tool/net/redbean.png
|
||||
|
||||
o/$(MODE)/tool/net/redbean-static.com.dbg: \
|
||||
$(TOOL_NET_DEPS) \
|
||||
|
@ -226,13 +248,21 @@ o/$(MODE)/tool/net/redbean-static.o: tool/net/redbean.c o/$(MODE)/tool/net/redbe
|
|||
o/$(MODE)/tool/net/redbean-unsecure.com: \
|
||||
o/$(MODE)/tool/net/redbean-unsecure.com.dbg \
|
||||
o/$(MODE)/third_party/infozip/zip.com \
|
||||
o/$(MODE)/tool/build/symtab.com \
|
||||
tool/net/help.txt \
|
||||
tool/net/favicon.ico \
|
||||
tool/net/redbean.png
|
||||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -AMKDIR -T$@ mkdir -p o/$(MODE)/tool/net/.redbean-unsecure
|
||||
@$(COMPILE) -ADD -T$@ dd if=$@ of=o/$(MODE)/tool/net/.redbean-unsecure/.ape bs=64 count=11 conv=notrunc 2>/dev/null
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/infozip/zip.com -qj $@ o/$(MODE)/tool/net/.redbean-unsecure/.ape tool/net/help.txt tool/net/favicon.ico tool/net/redbean.png
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/tool/net/.redbean-unsecure/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/infozip/zip.com -9qj $@ \
|
||||
o/$(MODE)/tool/net/.redbean-unsecure/.ape \
|
||||
o/$(MODE)/tool/net/.redbean-unsecure/.symtab \
|
||||
tool/net/help.txt \
|
||||
tool/net/favicon.ico \
|
||||
tool/net/redbean.png
|
||||
|
||||
o/$(MODE)/tool/net/redbean-unsecure.com.dbg: \
|
||||
$(TOOL_NET_DEPS) \
|
||||
|
@ -257,13 +287,21 @@ o/$(MODE)/tool/net/redbean-unsecure.o: tool/net/redbean.c o/$(MODE)/tool/net/red
|
|||
o/$(MODE)/tool/net/redbean-original.com: \
|
||||
o/$(MODE)/tool/net/redbean-original.com.dbg \
|
||||
o/$(MODE)/third_party/infozip/zip.com \
|
||||
o/$(MODE)/tool/build/symtab.com \
|
||||
tool/net/help.txt \
|
||||
tool/net/favicon.ico \
|
||||
tool/net/redbean.png
|
||||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -AMKDIR -T$@ mkdir -p o/$(MODE)/tool/net/.redbean-original
|
||||
@$(COMPILE) -ADD -T$@ dd if=$@ of=o/$(MODE)/tool/net/.redbean-original/.ape bs=64 count=11 conv=notrunc 2>/dev/null
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/infozip/zip.com -qj $@ o/$(MODE)/tool/net/.redbean-original/.ape tool/net/help.txt tool/net/favicon.ico tool/net/redbean.png
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/tool/net/.redbean-original/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/infozip/zip.com -9qj $@ \
|
||||
o/$(MODE)/tool/net/.redbean-original/.ape \
|
||||
o/$(MODE)/tool/net/.redbean-original/.symtab \
|
||||
tool/net/help.txt \
|
||||
tool/net/favicon.ico \
|
||||
tool/net/redbean.png
|
||||
|
||||
o/$(MODE)/tool/net/redbean-original.com.dbg: \
|
||||
$(TOOL_NET_DEPS) \
|
||||
|
|
|
@ -1232,7 +1232,7 @@ static void ReapZombies(void) {
|
|||
} while (!terminated);
|
||||
}
|
||||
|
||||
static ssize_t ReadAll(int fd, const char *p, size_t n) {
|
||||
static ssize_t ReadAll(int fd, char *p, size_t n) {
|
||||
ssize_t rc;
|
||||
size_t i, got;
|
||||
for (i = 0; i < n;) {
|
||||
|
|
|
@ -71,6 +71,16 @@ o/$(MODE)/tool/viz/%.com.dbg: \
|
|||
$(APE)
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/tool/viz/printvideo.com: \
|
||||
o/$(MODE)/tool/viz/printvideo.com.dbg \
|
||||
o/$(MODE)/third_party/infozip/zip.com \
|
||||
o/$(MODE)/tool/build/symtab.com
|
||||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/tool/viz/.printvideo/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/infozip/zip.com -9qj $@ \
|
||||
o/$(MODE)/tool/viz/.printvideo/.symtab
|
||||
|
||||
o/$(MODE)/tool/viz/derasterize.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-DSTACK_FRAME_UNLIMITED \
|
||||
|
|
Loading…
Add table
Reference in a new issue