Mint APE Loader v1.4

This change also incorporates more bug fixes and improvements to a wide
variety of small things. For example this fixes #860 so Windows console
doesn't get corrupted after exit. An system stack memory map issue with
aarch64 has been fixed. We no longer use O_NONBLOCK on AF_UNIX sockets.
Crash reports on Arm64 will now demangle C++ symbols, even when c++filt
isn't available. Most importantly the Apple M1 version of APE Loader is
brought up to date by this change. A prebuilt unsigned binary for it is
being included in build/bootstrap/. One more thing: retrieving the term
dimensions under --strace was causing the stack to become corrupted and
now that's been solved too. PSS: We're now including an ELF PT_NOTE for
APE in the binaries we build, that has the APE Loader version.
This commit is contained in:
Justine Tunney 2023-07-25 05:43:04 -07:00
parent 53d3f9d9c5
commit 6843150e0c
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
25 changed files with 524 additions and 226 deletions

View file

@ -85,8 +85,8 @@ int sys_execve(const char *prog, char *const argv[], char *const envp[]) {
(CanExecute((ape = "/usr/bin/ape")) ||
CanExecute((ape = Join(firstnonnull(getenv("TMPDIR"),
firstnonnull(getenv("HOME"), ".")),
".ape-1.3", buf))) ||
CanExecute((ape = Join(firstnonnull(getenv("HOME"), "."), ".ape-1.3",
".ape-1.4", buf))) ||
CanExecute((ape = Join(firstnonnull(getenv("HOME"), "."), ".ape-1.4",
buf))))) {
shargs[0] = ape;
shargs[1] = "-";

View file

@ -48,8 +48,6 @@
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/errfuns.h"
#undef sigaction
#ifdef SYSDEBUG
STATIC_YOINK("strsignal"); // for kprintf()
#endif

View file

@ -8,7 +8,7 @@ COSMOPOLITAN_C_START_
int tcgetwinsize_nt(struct Fd *, struct winsize *);
const char *DescribeWinsize(char[64], int, struct winsize *);
#define DescribeWinsize(rc, ws) DescribeWinsize(alloca(12), rc, ws)
#define DescribeWinsize(rc, ws) DescribeWinsize(alloca(64), rc, ws)
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -33,11 +33,13 @@ Elf64_Shdr *FindElfSectionByName(Elf64_Ehdr *elf, size_t mapsize,
long i;
Elf64_Shdr *shdr;
const char *secname;
for (i = 0; i < elf->e_shnum; ++i) {
if ((shdr = GetElfSectionHeaderAddress(elf, mapsize, i)) &&
(secname = GetElfString(elf, mapsize, shdrstrtab, shdr->sh_name)) &&
!strcmp(name, secname)) {
return shdr;
if (shdrstrtab) {
for (i = 0; i < elf->e_shnum; ++i) {
if ((shdr = GetElfSectionHeaderAddress(elf, mapsize, i)) &&
(secname = GetElfString(elf, mapsize, shdrstrtab, shdr->sh_name)) &&
!strcmp(name, secname)) {
return shdr;
}
}
}
return 0;

View file

@ -20,6 +20,7 @@
#include "libc/nt/console.h"
#include "libc/nt/process.h"
#include "libc/nt/runtime.h"
#include "libc/nt/thunk/msabi.h"
#include "libc/runtime/internal.h"
__msabi extern typeof(GetCurrentProcessId) *const __imp_GetCurrentProcessId;
@ -28,17 +29,18 @@ __msabi extern typeof(GetStdHandle) *const __imp_GetStdHandle;
extern uint32_t __pid_exec;
const unsigned char kConsoleHandles[3] = {
const signed char kConsoleHandles[3] = {
kNtStdInputHandle,
kNtStdOutputHandle,
kNtStdErrorHandle,
};
// Puts cmd.exe gui back the way it was.
privileged dontinstrument void _restorewintty(void) {
void _restorewintty(void) {
int i;
if (!IsWindows()) return;
if (__imp_GetCurrentProcessId() != __pid_exec) return;
for (int i = 0; i < 3; ++i) {
for (i = 0; i < 3; ++i) {
__imp_SetConsoleMode(__imp_GetStdHandle(kConsoleHandles[i]),
__ntconsolemode[i]);
}

View file

@ -32,10 +32,12 @@
#include "libc/log/internal.h"
#include "libc/log/log.h"
#include "libc/macros.internal.h"
#include "libc/mem/mem.h"
#include "libc/nexgen32e/stackframe.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/stack.h"
#include "libc/runtime/symbols.internal.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/sig.h"
#include "libc/thread/thread.h"
@ -162,6 +164,17 @@ static bool AppendFileLine(struct Buffer *b, const char *addr2line,
}
}
static char *GetSymbolName(struct SymbolTable *st, int symbol, char **mem,
size_t *memsz) {
char *s, *t;
if ((s = __get_symbol_name(st, symbol)) && //
s[0] == '_' && s[1] == 'Z' && //
(t = __cxa_demangle(s, *mem, memsz, 0))) {
*mem = s = t;
}
return s;
}
relegated void __oncrash_arm64(int sig, struct siginfo *si, void *arg) {
char buf[10000];
ucontext_t *ctx = arg;
@ -200,6 +213,8 @@ relegated void __oncrash_arm64(int sig, struct siginfo *si, void *arg) {
if (ctx) {
long pc;
char line[256];
char *mem = 0;
size_t memsz = 0;
int addend, symbol;
const char *debugbin;
const char *addr2line;
@ -253,8 +268,7 @@ relegated void __oncrash_arm64(int sig, struct siginfo *si, void *arg) {
if (pc && st && (symbol = __get_symbol(st, pc))) {
addend = pc - st->addr_base;
addend -= st->symbols[symbol].x;
Append(b, " ");
Append(b, "%s", __get_symbol_name(st, symbol));
Append(b, " %s", GetSymbolName(st, symbol, &mem, &memsz));
if (addend) Append(b, "%+d", addend);
}
Append(b, "\n");
@ -274,7 +288,7 @@ relegated void __oncrash_arm64(int sig, struct siginfo *si, void *arg) {
addend -= st->symbols[symbol].x;
Append(b, " ");
if (!AppendFileLine(b, addr2line, debugbin, pc)) {
Append(b, "%s", __get_symbol_name(st, symbol));
Append(b, "%s", GetSymbolName(st, symbol, &mem, &memsz));
if (addend) Append(b, "%+d", addend);
}
}
@ -313,11 +327,12 @@ relegated void __oncrash_arm64(int sig, struct siginfo *si, void *arg) {
}
Append(b, " %016lx fp %lx lr ", fp, pc);
if (!AppendFileLine(b, addr2line, debugbin, pc) && st) {
Append(b, "%s", __get_symbol_name(st, symbol));
Append(b, "%s", GetSymbolName(st, symbol, &mem, &memsz));
if (addend) Append(b, "%+d", addend);
}
Append(b, "\n");
}
free(mem);
}
} else {
Append(b, "got %G while crashing! pc %lx lr %lx\n", sig,

View file

@ -4,8 +4,20 @@
#include "libc/nt/struct/imagedatadirectory.internal.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
/**
* Portable Executable Optional Header.
*
* @see NtImageNtHeaders which encloses this
* @see NtImageFileHeader which precedes this
* @see NtImageSectionHeader which follows this
*/
struct NtImageOptionalHeader {
/*
* Must be kNtPe64bit.
*/
uint16_t Magic;
uint8_t MajorLinkerVersion;
uint8_t MinorLinkerVersion;
uint32_t SizeOfCode;
@ -55,8 +67,20 @@ struct NtImageOptionalHeader {
uint16_t MajorSubsystemVersion;
uint16_t MinorSubsystemVersion;
uint32_t Win32VersionValue;
/*
* The size (in bytes) of the image, including all headers, as the
* image is loaded in memory. It must be a multiple of
* SectionAlignment.
*/
uint32_t SizeOfImage;
/*
* The combined size of an MS-DOS stub, PE header, and section headers
* rounded up to a multiple of FileAlignment.
*/
uint32_t SizeOfHeaders;
uint32_t CheckSum;
uint16_t Subsystem;
uint16_t DllCharacteristics;

View file

@ -21,6 +21,7 @@
#include "libc/dce.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/strace.internal.h"
#include "libc/limits.h"
#include "libc/macros.internal.h"
#include "libc/nexgen32e/rdtsc.h"
#include "libc/runtime/internal.h"
@ -32,6 +33,7 @@
#include "libc/sysv/consts/sig.h"
#include "libc/thread/thread.h"
#include "libc/thread/tls.h"
#include "third_party/lua/lunix.h"
#ifndef __x86_64__
/**
@ -128,11 +130,13 @@ textstartup void cosmo(long *sp, struct Syslib *m1) {
_mmi.p = _mmi.s;
__mmi_lock_obj._type = PTHREAD_MUTEX_RECURSIVE;
// record provided stack to memory manager
// record system provided stack to memory manager
uintptr_t s = (uintptr_t)sp;
uintptr_t z = GetStackSize() << 1;
_mmi.i = 1;
_mmi.p->x = (uintptr_t)GetStackAddr() >> 16;
_mmi.p->y = (uintptr_t)(GetStackAddr() + (GetStackSize() - FRAMESIZE)) >> 16;
_mmi.p->size = GetStackSize();
_mmi.p->x = (s & -z) >> 16;
_mmi.p->y = MIN(((s & -z) + (z - 1)) >> 16, INT_MAX);
_mmi.p->size = z;
_mmi.p->prot = PROT_READ | PROT_WRITE;
__virtualmax = -1;

View file

@ -66,7 +66,7 @@ __msabi extern typeof(VirtualProtect) *const __imp_VirtualProtect;
*/
extern int64_t __wincrashearly;
extern const char kConsoleHandles[3];
extern const signed char kConsoleHandles[3];
extern void cosmo(int, char **, char **, long (*)[2]) wontreturn;
static const short kConsoleModes[3] = {

View file

@ -17,6 +17,7 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/struct/timeval.h"
#include "libc/errno.h"
#include "libc/sock/goodsocket.internal.h"
#include "libc/sock/sock.h"
#include "libc/sysv/consts/so.h"
@ -33,18 +34,23 @@ static bool Tune(int fd, int a, int b, int x) {
*/
int GoodSocket(int family, int type, int protocol, bool isserver,
const struct timeval *timeout) {
int fd;
int e, fd;
if ((fd = socket(family, type, protocol)) != -1) {
e = errno;
if (isserver) {
Tune(fd, SOL_TCP, TCP_FASTOPEN, 100);
Tune(fd, SOL_SOCKET, SO_REUSEADDR, 1);
} else {
Tune(fd, SOL_TCP, TCP_FASTOPEN_CONNECT, 1);
}
errno = e;
if (!Tune(fd, SOL_TCP, TCP_QUICKACK, 1)) {
e = errno;
Tune(fd, SOL_TCP, TCP_NODELAY, 1);
errno = e;
}
if (timeout) {
e = errno;
if (timeout->tv_sec < 0) {
Tune(fd, SOL_SOCKET, SO_KEEPALIVE, 1);
Tune(fd, SOL_TCP, TCP_KEEPIDLE, -timeout->tv_sec);
@ -53,6 +59,7 @@ int GoodSocket(int family, int type, int protocol, bool isserver,
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, timeout, sizeof(*timeout));
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, timeout, sizeof(*timeout));
}
errno = e;
}
}
return fd;

View file

@ -45,7 +45,6 @@ extern const unsigned RLIMIT_VMEM;
#define RLIMIT_SWAP RLIMIT_SWAP
#define RLIMIT_VMEM RLIMIT_VMEM
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_RLIMIT_H_ */