mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-01 16:58:30 +00:00
Mint APE Loader v1.7
This change reduces the memory requirements of your APE Loader by 10x, in terms of virtual memory size, thanks to the help of alloca(). We're also now creating argument blocks with the same layout across systems.
This commit is contained in:
parent
d967a94c9a
commit
1d8937d528
31 changed files with 367 additions and 656 deletions
|
@ -180,6 +180,7 @@ textwindows bool __sig_handle(int sigops, int sig, int si_code,
|
|||
case (intptr_t)SIG_DFL:
|
||||
if (__sig_is_fatal(sig)) {
|
||||
STRACE("terminating on %G", sig);
|
||||
_restorewintty();
|
||||
ExitProcess(sig);
|
||||
}
|
||||
// fallthrough
|
||||
|
|
|
@ -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.6", buf))) ||
|
||||
CanExecute((ape = Join(firstnonnull(getenv("HOME"), "."), ".ape-1.6",
|
||||
".ape-1.7", buf))) ||
|
||||
CanExecute((ape = Join(firstnonnull(getenv("HOME"), "."), ".ape-1.7",
|
||||
buf))))) {
|
||||
shargs[0] = ape;
|
||||
shargs[1] = "-";
|
||||
|
|
|
@ -43,8 +43,8 @@ int getrlimit(int resource, struct rlimit *rlim) {
|
|||
} else if (!IsWindows()) {
|
||||
rc = sys_getrlimit(resource, rlim);
|
||||
} else if (resource == RLIMIT_STACK) {
|
||||
rlim->rlim_cur = (uintptr_t)ape_stack_memsz;
|
||||
rlim->rlim_max = (uintptr_t)ape_stack_memsz;
|
||||
rlim->rlim_cur = GetStaticStackSize();
|
||||
rlim->rlim_max = GetStaticStackSize();
|
||||
rc = 0;
|
||||
} else if (resource == RLIMIT_AS) {
|
||||
rlim->rlim_cur = __virtualmax;
|
||||
|
|
|
@ -26,10 +26,10 @@
|
|||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/runtime/zipos.internal.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/runtime/zipos.internal.h"
|
||||
|
||||
/**
|
||||
* Reads data from file descriptor.
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/sysv/consts/rlimit.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
|
@ -31,6 +32,12 @@
|
|||
*
|
||||
* The following resources are recommended:
|
||||
*
|
||||
* - `RLIMIT_STACK` controls how much stack memory is available to the
|
||||
* main thread. This setting is inherited across fork() and execve()
|
||||
* Please note it's only safe for Cosmopolitan programs, to set this
|
||||
* value to at least `PTHREAD_STACK_MIN * 2`. On Windows this cannot
|
||||
* be used to extend the stack, which is currently hard-coded.
|
||||
*
|
||||
* - `RLIMIT_AS` limits the size of the virtual address space. This will
|
||||
* work on all platforms except WSL. It is emulated on XNU and Windows
|
||||
* which means it won't propagate across execve() currently.
|
||||
|
|
|
@ -278,7 +278,7 @@ void statfs2cosmo(struct statfs *f, const union statfs_meta *m) {
|
|||
f_files = m->netbsd.f_files;
|
||||
f_ffree = m->netbsd.f_ffree;
|
||||
f_fsid = m->netbsd.f_fsid;
|
||||
f_namelen = f->f_namelen;
|
||||
f_namelen = 511;
|
||||
f_frsize = m->netbsd.f_bsize;
|
||||
f_flags = m->netbsd.f_flags;
|
||||
f_owner = m->netbsd.f_owner;
|
||||
|
|
|
@ -48,13 +48,10 @@ static const char *GetFrameName(int x) {
|
|||
} else if (IsMemtrackFrame(x)) {
|
||||
return "memtrack";
|
||||
} else if (IsOldStackFrame(x)) {
|
||||
return "oldstack";
|
||||
} else if (IsWindows() &&
|
||||
(((GetStaticStackAddr(0) + GetStackSize()) >> 16) <= x &&
|
||||
x <= ((GetStaticStackAddr(0) + GetStackSize() +
|
||||
sizeof(struct WinArgs) - 1) >>
|
||||
16))) {
|
||||
return "mainstack";
|
||||
return "system stack";
|
||||
} else if (((GetStaticStackAddr(0) + GetStackSize()) >> 16) <= x &&
|
||||
x <= ((GetStaticStackAddr(0) + GetStackSize() - 1) >> 16)) {
|
||||
return "static stack";
|
||||
} else if ((int)((intptr_t)__executable_start >> 16) <= x &&
|
||||
x <= (int)(((intptr_t)_end - 1) >> 16)) {
|
||||
return "image";
|
||||
|
|
|
@ -110,9 +110,9 @@ wontreturn textstartup void cosmo(long *sp, struct Syslib *m1) {
|
|||
|
||||
// get page size
|
||||
unsigned long pagesz = 4096;
|
||||
for (int i = 0; auxv[i]; auxv += 2) {
|
||||
if (auxv[0] == AT_PAGESZ) {
|
||||
pagesz = auxv[1];
|
||||
for (int i = 0; auxv[i]; i += 2) {
|
||||
if (auxv[i] == AT_PAGESZ) {
|
||||
pagesz = auxv[i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,6 +83,7 @@ extern char kTmpPath[];
|
|||
extern const char kNtSystemDirectory[];
|
||||
extern const char kNtWindowsDirectory[];
|
||||
extern size_t __virtualmax;
|
||||
extern size_t __stackmax;
|
||||
extern bool __isworker;
|
||||
/* utilities */
|
||||
void _intsort(int *, size_t);
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "libc/nt/thunk/msabi.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/stack.h"
|
||||
#include "libc/runtime/winargs.internal.h"
|
||||
#include "libc/sock/internal.h"
|
||||
|
@ -119,9 +120,9 @@ __msabi static textwindows void DeduplicateStdioHandles(void) {
|
|||
}
|
||||
|
||||
__msabi static textwindows wontreturn void WinMainNew(const char16_t *cmdline) {
|
||||
size_t stacksize;
|
||||
struct WinArgs *wa;
|
||||
size_t allocsize, stacksize;
|
||||
uintptr_t stackaddr, allocaddr;
|
||||
uintptr_t stackaddr;
|
||||
__oldstack = (intptr_t)__builtin_frame_address(0);
|
||||
if (NtGetPeb()->OSMajorVersion >= 10 &&
|
||||
(intptr_t)v_ntsubsystem == kNtImageSubsystemWindowsCui) {
|
||||
|
@ -138,26 +139,23 @@ __msabi static textwindows wontreturn void WinMainNew(const char16_t *cmdline) {
|
|||
_mmi.n = ARRAYLEN(_mmi.s);
|
||||
stackaddr = GetStaticStackAddr(0);
|
||||
stacksize = GetStaticStackSize();
|
||||
allocaddr = stackaddr;
|
||||
allocsize = stacksize + sizeof(struct WinArgs);
|
||||
__imp_MapViewOfFileEx((_mmi.p[0].h = __imp_CreateFileMappingW(
|
||||
-1, &kNtIsInheritable, kNtPageExecuteReadwrite,
|
||||
allocsize >> 32, allocsize, NULL)),
|
||||
kNtFileMapWrite | kNtFileMapExecute, 0, 0, allocsize,
|
||||
(void *)allocaddr);
|
||||
stacksize >> 32, stacksize, NULL)),
|
||||
kNtFileMapWrite | kNtFileMapExecute, 0, 0, stacksize,
|
||||
(void *)stackaddr);
|
||||
int prot = (intptr_t)ape_stack_prot;
|
||||
if (~prot & PROT_EXEC) {
|
||||
uint32_t oldprot;
|
||||
__imp_VirtualProtect((void *)allocaddr, allocsize, kNtPageReadwrite,
|
||||
&oldprot);
|
||||
uint32_t old;
|
||||
__imp_VirtualProtect((void *)stackaddr, stacksize, kNtPageReadwrite, &old);
|
||||
}
|
||||
_mmi.p[0].x = allocaddr >> 16;
|
||||
_mmi.p[0].y = (allocaddr >> 16) + ((allocsize - 1) >> 16);
|
||||
_mmi.p[0].x = stackaddr >> 16;
|
||||
_mmi.p[0].y = (stackaddr >> 16) + ((stacksize - 1) >> 16);
|
||||
_mmi.p[0].prot = prot;
|
||||
_mmi.p[0].flags = 0x00000026; // stack+anonymous
|
||||
_mmi.p[0].size = allocsize;
|
||||
_mmi.p[0].size = stacksize;
|
||||
_mmi.i = 1;
|
||||
wa = (struct WinArgs *)(allocaddr + stacksize);
|
||||
wa = (struct WinArgs *)(stackaddr + (stacksize - sizeof(struct WinArgs)));
|
||||
int count = GetDosArgv(cmdline, wa->argblock, ARRAYLEN(wa->argblock),
|
||||
wa->argv, ARRAYLEN(wa->argv));
|
||||
for (int i = 0; wa->argv[0][i]; ++i) {
|
||||
|
@ -169,7 +167,7 @@ __msabi static textwindows wontreturn void WinMainNew(const char16_t *cmdline) {
|
|||
GetDosEnviron(env16, wa->envblock, ARRAYLEN(wa->envblock) - 8, wa->envp,
|
||||
ARRAYLEN(wa->envp) - 1);
|
||||
__imp_FreeEnvironmentStringsW(env16);
|
||||
_jmpstack((char *)(stackaddr + stacksize - (intptr_t)ape_stack_align), cosmo,
|
||||
_jmpstack((char *)(stackaddr + (stacksize - sizeof(struct WinArgs))), cosmo,
|
||||
count, wa->argv, wa->envp, wa->auxv);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue