Make fat ape binaries smaller again

This commit is contained in:
Justine Tunney 2023-08-17 11:12:10 -07:00
parent 1d8937d528
commit 3f9b39883f
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
7 changed files with 114 additions and 29 deletions

View file

@ -261,7 +261,7 @@ SECTIONS {
. = ALIGN(. != 0 ? CODE_GRANULE : 0); . = ALIGN(. != 0 ? CODE_GRANULE : 0);
KEEP(*(.ape.pad.head)) KEEP(*(.ape.pad.head))
. = ALIGN(. != 0 ? (SupportsWindows() || SupportsMetal() ? CONSTANT(MAXPAGESIZE) : 16) : 0); . = ALIGN(. != 0 ? (SupportsWindows() || SupportsMetal() ? CONSTANT(COMMONPAGESIZE) : 16) : 0);
_ehead = .; _ehead = .;
} :Head } :Head
@ -312,14 +312,14 @@ SECTIONS {
/* Privileged code invulnerable to magic */ /* Privileged code invulnerable to magic */
KEEP(*(.ape.pad.privileged)); KEEP(*(.ape.pad.privileged));
. = ALIGN(__privileged_end > __privileged_start ? CONSTANT(MAXPAGESIZE) : 0); . = ALIGN(__privileged_end > __privileged_start ? CONSTANT(COMMONPAGESIZE) : 0);
/*END: morphable code */ /*END: morphable code */
__privileged_start = .; __privileged_start = .;
*(.privileged) *(.privileged)
__privileged_end = .; __privileged_end = .;
KEEP(*(.ape.pad.text)) KEEP(*(.ape.pad.text))
. = ALIGN(. != 0 ? CONSTANT(MAXPAGESIZE) : 0); . = ALIGN(. != 0 ? CONSTANT(COMMONPAGESIZE) : 0);
/*END: Read Only Data (only needed for initialization) */ /*END: Read Only Data (only needed for initialization) */
} :Cod } :Cod
@ -354,7 +354,7 @@ SECTIONS {
KEEP(*(SORT_BY_NAME(.initro.*))) KEEP(*(SORT_BY_NAME(.initro.*)))
KEEP(*(.initroepilogue)) KEEP(*(.initroepilogue))
KEEP(*(SORT_BY_NAME(.sort.rodata.*))) KEEP(*(SORT_BY_NAME(.sort.rodata.*)))
. = ALIGN(. != 0 ? CONSTANT(MAXPAGESIZE) : 0); /* don't delete this line :o */ . = ALIGN(. != 0 ? CONSTANT(COMMONPAGESIZE) : 0); /* don't delete this line :o */
/*END: read-only data that's only needed for initialization */ /*END: read-only data that's only needed for initialization */
@ -368,13 +368,13 @@ SECTIONS {
*(SORT_BY_ALIGNMENT(.tdata.*)) *(SORT_BY_ALIGNMENT(.tdata.*))
_tdata_end = .; _tdata_end = .;
KEEP(*(.ape.pad.rodata)) KEEP(*(.ape.pad.rodata))
. = ALIGN(. != 0 ? CONSTANT(MAXPAGESIZE) : 0); . = ALIGN(. != 0 ? CONSTANT(COMMONPAGESIZE) : 0);
_etext = .; _etext = .;
PROVIDE(etext = .); PROVIDE(etext = .);
} :Tls :Rom } :Tls :Rom
/*END: Read Only Data */ /*END: Read Only Data */
. = ALIGN(CONSTANT(MAXPAGESIZE)); . = ALIGN(CONSTANT(COMMONPAGESIZE));
/* this only tells the linker about the layout of uninitialized */ /* this only tells the linker about the layout of uninitialized */
/* TLS data, and does not advance the linker's location counter */ /* TLS data, and does not advance the linker's location counter */
@ -432,14 +432,14 @@ SECTIONS {
KEEP(*(SORT_BY_NAME(.piro.data.sort.*))) KEEP(*(SORT_BY_NAME(.piro.data.sort.*)))
KEEP(*(.piro.pad.data)) KEEP(*(.piro.pad.data))
KEEP(*(.dataepilogue)) KEEP(*(.dataepilogue))
. = ALIGN(. != 0 ? CONSTANT(MAXPAGESIZE) : 0); . = ALIGN(. != 0 ? CONSTANT(COMMONPAGESIZE) : 0);
/*END: NT FORK COPYING */ /*END: NT FORK COPYING */
_edata = .; _edata = .;
PROVIDE(edata = .); PROVIDE(edata = .);
_ezip = .; /* <-- very deprecated */ _ezip = .; /* <-- very deprecated */
} :Ram } :Ram
. = ALIGN(CONSTANT(MAXPAGESIZE)); . = ALIGN(CONSTANT(COMMONPAGESIZE));
/*END: file content that's loaded by o/s */ /*END: file content that's loaded by o/s */
/*END: file content */ /*END: file content */
@ -464,12 +464,12 @@ SECTIONS {
KEEP(*(.bssepilogue)) KEEP(*(.bssepilogue))
. = ALIGN(. != 0 ? CONSTANT(MAXPAGESIZE) : 0); . = ALIGN(. != 0 ? CONSTANT(COMMONPAGESIZE) : 0);
/*END: NT FORK COPYING */ /*END: NT FORK COPYING */
} :Ram } :Ram
. = ALIGN(CONSTANT(MAXPAGESIZE)); . = ALIGN(CONSTANT(COMMONPAGESIZE));
_end = .; _end = .;
PROVIDE(end = .); PROVIDE(end = .);
@ -559,7 +559,7 @@ ape_cod_vaddr = ADDR(.head);
ape_cod_paddr = LOADADDR(.head); ape_cod_paddr = LOADADDR(.head);
ape_cod_filesz = ADDR(.rodata) - ADDR(.head); ape_cod_filesz = ADDR(.rodata) - ADDR(.head);
ape_cod_memsz = ape_cod_filesz; ape_cod_memsz = ape_cod_filesz;
ape_cod_align = CONSTANT(MAXPAGESIZE); ape_cod_align = CONSTANT(COMMONPAGESIZE);
ape_cod_rva = RVA(ape_cod_vaddr); ape_cod_rva = RVA(ape_cod_vaddr);
ape_rom_vaddr = ADDR(.rodata); ape_rom_vaddr = ADDR(.rodata);
@ -567,7 +567,7 @@ ape_rom_offset = ape_rom_vaddr - __executable_start;
ape_rom_paddr = LOADADDR(.rodata); ape_rom_paddr = LOADADDR(.rodata);
ape_rom_filesz = ADDR(.tbss) - ADDR(.rodata); ape_rom_filesz = ADDR(.tbss) - ADDR(.rodata);
ape_rom_memsz = ape_rom_filesz; ape_rom_memsz = ape_rom_filesz;
ape_rom_align = CONSTANT(MAXPAGESIZE); ape_rom_align = CONSTANT(COMMONPAGESIZE);
ape_rom_rva = RVA(ape_rom_vaddr); ape_rom_rva = RVA(ape_rom_vaddr);
ape_ram_vaddr = ADDR(.data); ape_ram_vaddr = ADDR(.data);
@ -575,7 +575,7 @@ ape_ram_offset = ape_ram_vaddr - __executable_start;
ape_ram_paddr = LOADADDR(.data); ape_ram_paddr = LOADADDR(.data);
ape_ram_filesz = ADDR(.bss) - ADDR(.data); ape_ram_filesz = ADDR(.bss) - ADDR(.data);
ape_ram_memsz = _end - ADDR(.data); ape_ram_memsz = _end - ADDR(.data);
ape_ram_align = CONSTANT(MAXPAGESIZE); ape_ram_align = CONSTANT(COMMONPAGESIZE);
ape_ram_rva = RVA(ape_ram_vaddr); ape_ram_rva = RVA(ape_ram_vaddr);
ape_stack_pf = DEFINED(ape_stack_pf) ? ape_stack_pf : PF_R | PF_W; ape_stack_pf = DEFINED(ape_stack_pf) ? ape_stack_pf : PF_R | PF_W;
@ -596,7 +596,7 @@ ape_text_offset = ape_text_vaddr - __executable_start;
ape_text_paddr = LOADADDR(.text); ape_text_paddr = LOADADDR(.text);
ape_text_filesz = ADDR(.rodata) - ADDR(.text); ape_text_filesz = ADDR(.rodata) - ADDR(.text);
ape_text_memsz = ape_text_filesz; ape_text_memsz = ape_text_filesz;
ape_text_align = CONSTANT(MAXPAGESIZE); ape_text_align = CONSTANT(COMMONPAGESIZE);
ape_text_rva = RVA(ape_text_vaddr); ape_text_rva = RVA(ape_text_vaddr);
/* we roundup here because xnu wants the file load segments page-aligned */ /* we roundup here because xnu wants the file load segments page-aligned */
@ -605,7 +605,7 @@ ape_text_rva = RVA(ape_text_vaddr);
SHSTUB2(ape_loader_dd_skip, DEFINED(ape_loader) ? RVA(ape_loader) / 64 : 0); SHSTUB2(ape_loader_dd_skip, DEFINED(ape_loader) ? RVA(ape_loader) / 64 : 0);
SHSTUB2(ape_loader_dd_count, SHSTUB2(ape_loader_dd_count,
DEFINED(ape_loader_end) DEFINED(ape_loader_end)
? ROUNDUP(ape_loader_end - ape_loader, CONSTANT(MAXPAGESIZE)) / 64 ? ROUNDUP(ape_loader_end - ape_loader, CONSTANT(COMMONPAGESIZE)) / 64
: 0); : 0);
#if defined(APE_IS_SHELL_SCRIPT) && !IsTiny() #if defined(APE_IS_SHELL_SCRIPT) && !IsTiny()

View file

@ -173,7 +173,7 @@ else
fatal_error "$ARCH: unsupported architecture" fatal_error "$ARCH: unsupported architecture"
fi fi
LDFLAGS="$LDFLAGS -Wl,-z,common-page-size=$PAGESZ -Wl,-z,max-page-size=$PAGESZ" LDFLAGS="$LDFLAGS -Wl,-z,common-page-size=$PAGESZ -Wl,-z,max-page-size=16384"
if [ ! -d "$COSMO" ]; then if [ ! -d "$COSMO" ]; then
fatal_error "you need to clone cosmopolitan to your $COSMO directory" fatal_error "you need to clone cosmopolitan to your $COSMO directory"

View file

@ -386,7 +386,7 @@ fi
CRT_X86_64="$COSMO/o/$MODE/ape/ape.o $COSMO/o/$MODE/libc/crt/crt.o" CRT_X86_64="$COSMO/o/$MODE/ape/ape.o $COSMO/o/$MODE/libc/crt/crt.o"
CPPFLAGS_X86_64="$CPPFLAGS -mno-red-zone" CPPFLAGS_X86_64="$CPPFLAGS -mno-red-zone"
CFLAGS_X86_64="$CFLAGS -mno-tls-direct-seg-refs" CFLAGS_X86_64="$CFLAGS -mno-tls-direct-seg-refs"
LDFLAGS_X86_64="$LDFLAGS -L$COSMOS/lib -Wl,-T,$COSMO/o/$MODE/ape/ape.lds -Wl,-z,common-page-size=4096 -Wl,-z,max-page-size=4096" LDFLAGS_X86_64="$LDFLAGS -L$COSMOS/lib -Wl,-T,$COSMO/o/$MODE/ape/ape.lds -Wl,-z,common-page-size=4096 -Wl,-z,max-page-size=16384"
LDLIBS_X86_64="$COSMO/o/$MODE/cosmopolitan.a" LDLIBS_X86_64="$COSMO/o/$MODE/cosmopolitan.a"
if [ $MCOSMO -eq 1 ]; then if [ $MCOSMO -eq 1 ]; then
CPPFLAGS_X86_64="${CPPFLAGS_X86_64} -D_COSMO_SOURCE" CPPFLAGS_X86_64="${CPPFLAGS_X86_64} -D_COSMO_SOURCE"

View file

@ -258,7 +258,7 @@ DEFAULT_LDFLAGS += \
-znorelro -znorelro
else else
DEFAULT_LDFLAGS += \ DEFAULT_LDFLAGS += \
-zmax-page-size=0x1000 \ -zmax-page-size=0x4000 \
-zcommon-page-size=0x1000 -zcommon-page-size=0x1000
endif endif

View file

@ -33,6 +33,7 @@
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"
#include "libc/stdio/temp.h" #include "libc/stdio/temp.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/sysv/consts/lock.h"
#include "libc/sysv/consts/o.h" #include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/ok.h" #include "libc/sysv/consts/ok.h"
#include "libc/sysv/consts/s.h" #include "libc/sysv/consts/s.h"
@ -236,6 +237,73 @@ static int Echo(void) {
return 0; return 0;
} }
static int NeedArgument(const char *prog) {
tinyprint(2, prog, ": missing argument\n", NULL);
return 1;
}
static int Flock(void) {
int fd;
int i = 1;
char *endptr;
int mode = LOCK_EX;
if (i < n && args[i][0] == '-' && args[i][1] == 'x' && !args[i][2]) {
++i, mode = LOCK_EX;
}
if (i < n && args[i][0] == '-' && args[i][1] == 's' && !args[i][2]) {
++i, mode = LOCK_SH;
}
if (i == n) {
return NeedArgument("flock");
}
if (i + 1 != n) {
tinyprint(2, "flock: too many arguments\n", NULL);
return 1;
}
fd = strtol(args[i], &endptr, 10);
if (*endptr) {
tinyprint(2, "flock: need a number\n", NULL);
return 1;
}
if (flock(fd, mode)) {
perror("flock");
return 1;
}
return 0;
}
static int Chmod(void) {
int i, mode;
char *endptr;
if (n < 3) {
return NeedArgument("chmod");
}
mode = strtol(args[1], &endptr, 8);
if (*endptr) {
tinyprint(2, "chmod: bad octal mode\n", NULL);
return 1;
}
for (i = 2; i < n; ++i) {
if (chmod(args[i], mode)) {
perror(args[i]);
return 1;
}
}
return 0;
}
static int Pwd(void) {
char path[PATH_MAX + 2];
if (getcwd(path, PATH_MAX)) {
strlcat(path, "\n", sizeof(path));
Write(1, path);
return 0;
} else {
perror("pwd");
return 1;
}
}
static int CatDump(const char *path, int fd, bool dontclose) { static int CatDump(const char *path, int fd, bool dontclose) {
ssize_t rc; ssize_t rc;
char buf[512]; char buf[512];
@ -300,6 +368,7 @@ static int Mktemp(void) {
perror("mkstemp"); perror("mkstemp");
return 1; return 1;
} }
strlcat(template, "\n", sizeof(template));
Write(1, template); Write(1, template);
close(fd); close(fd);
return 0; return 0;
@ -328,11 +397,6 @@ static int Read(void) {
return rc; return rc;
} }
static int NeedArgument(const char *prog) {
tinyprint(2, prog, ": missing argument\n", NULL);
return 1;
}
static int Cd(void) { static int Cd(void) {
const char *s; const char *s;
if ((s = n > 1 ? args[1] : _getenv(envs, "HOME").s)) { if ((s = n > 1 ? args[1] : _getenv(envs, "HOME").s)) {
@ -601,12 +665,15 @@ static int TryBuiltin(void) {
if (!strcmp(args[0], "[")) return Test(); if (!strcmp(args[0], "[")) return Test();
if (!strcmp(args[0], "cat")) return Cat(); if (!strcmp(args[0], "cat")) return Cat();
if (!strcmp(args[0], "env")) return Env(); if (!strcmp(args[0], "env")) return Env();
if (!strcmp(args[0], "pwd")) return Pwd();
if (!strcmp(args[0], "wait")) return Wait(); if (!strcmp(args[0], "wait")) return Wait();
if (!strcmp(args[0], "echo")) return Echo(); if (!strcmp(args[0], "echo")) return Echo();
if (!strcmp(args[0], "read")) return Read(); if (!strcmp(args[0], "read")) return Read();
if (!strcmp(args[0], "true")) return True(); if (!strcmp(args[0], "true")) return True();
if (!strcmp(args[0], "test")) return Test(); if (!strcmp(args[0], "test")) return Test();
if (!strcmp(args[0], "kill")) return Kill(); if (!strcmp(args[0], "kill")) return Kill();
if (!strcmp(args[0], "flock")) return Flock();
if (!strcmp(args[0], "chmod")) return Chmod();
if (!strcmp(args[0], "touch")) return Touch(); if (!strcmp(args[0], "touch")) return Touch();
if (!strcmp(args[0], "rmdir")) return Rmdir(); if (!strcmp(args[0], "rmdir")) return Rmdir();
if (!strcmp(args[0], "mkdir")) return Mkdir(); if (!strcmp(args[0], "mkdir")) return Mkdir();
@ -913,6 +980,13 @@ int _cocmd(int argc, char **argv, char **envp) {
unsupported['?'] = true; unsupported['?'] = true;
} }
if (argc >= 3 && !strcmp(argv[1], "--")) {
for (i = 2; i < argc; ++i) {
args[n++] = argv[i];
}
_Exit(ShellExec());
}
if (argc != 3) { if (argc != 3) {
tinyprint(2, prog, ": error: wrong number of args\n", NULL); tinyprint(2, prog, ": error: wrong number of args\n", NULL);
_Exit(10); _Exit(10);

View file

@ -1882,11 +1882,6 @@ int main(int argc, char *argv[]) {
struct Input *in = inputs.p + i; struct Input *in = inputs.p + i;
if (GetElfSymbol(in, "__zipos_get")) { if (GetElfSymbol(in, "__zipos_get")) {
LoadSymbols(in->elf, in->size, in->path); LoadSymbols(in->elf, in->size, in->path);
} else if (!want_stripped) {
tinyprint(2, in->path,
": warning: won't generate symbol table unless "
"__static_yoink(\"zipos\") is linked\n",
NULL);
} }
} }
} }

View file

@ -62,6 +62,7 @@
#include "libc/sysv/consts/sa.h" #include "libc/sysv/consts/sa.h"
#include "libc/sysv/consts/sig.h" #include "libc/sysv/consts/sig.h"
#include "libc/sysv/consts/termios.h" #include "libc/sysv/consts/termios.h"
#include "libc/thread/thread.h"
#include "libc/time/time.h" #include "libc/time/time.h"
#include "libc/x/x.h" #include "libc/x/x.h"
#include "third_party/getopt/getopt.internal.h" #include "third_party/getopt/getopt.internal.h"
@ -114,6 +115,7 @@ FLAGS\n\
-C SECS set cpu limit [default 16]\n\ -C SECS set cpu limit [default 16]\n\
-L SECS set lat limit [default 90]\n\ -L SECS set lat limit [default 90]\n\
-P PROCS set pro limit [default 2048]\n\ -P PROCS set pro limit [default 2048]\n\
-S BYTES set stk limit [default 2m]\n\
-M BYTES set mem limit [default 512m]\n\ -M BYTES set mem limit [default 512m]\n\
-F BYTES set fsz limit [default 256m]\n\ -F BYTES set fsz limit [default 256m]\n\
-O BYTES set out limit [default 1m]\n\ -O BYTES set out limit [default 1m]\n\
@ -173,6 +175,7 @@ int pipefds[2];
long cpuquota; long cpuquota;
long fszquota; long fszquota;
long memquota; long memquota;
long stkquota;
long proquota; long proquota;
long outquota; long outquota;
@ -547,6 +550,14 @@ void SetMemLimit(long n) {
setrlimit(RLIMIT_AS, &rlim); setrlimit(RLIMIT_AS, &rlim);
} }
void SetStkLimit(long n) {
if (IsWindows()) return;
if (n <= 0) return;
n = MAX(n, PTHREAD_STACK_MIN * 2);
struct rlimit rlim = {n, n};
setrlimit(RLIMIT_STACK, &rlim);
}
void SetProLimit(long n) { void SetProLimit(long n) {
struct rlimit rlim = {n, n}; struct rlimit rlim = {n, n};
if (n <= 0) return; if (n <= 0) return;
@ -650,6 +661,7 @@ int Launch(void) {
SetCpuLimit(cpuquota); SetCpuLimit(cpuquota);
SetFszLimit(fszquota); SetFszLimit(fszquota);
SetMemLimit(memquota); SetMemLimit(memquota);
SetStkLimit(stkquota);
SetProLimit(proquota); SetProLimit(proquota);
if (stdoutmustclose) dup2(pipefds[1], 1); if (stdoutmustclose) dup2(pipefds[1], 1);
dup2(pipefds[1], 2); dup2(pipefds[1], 2);
@ -860,10 +872,11 @@ int main(int argc, char *argv[]) {
timeout = 90; /* secs */ timeout = 90; /* secs */
cpuquota = 32; /* secs */ cpuquota = 32; /* secs */
proquota = 2048; /* procs */ proquota = 2048; /* procs */
stkquota = 2 * 1024 * 1024; /* bytes */
fszquota = 256 * 1000 * 1000; /* bytes */ fszquota = 256 * 1000 * 1000; /* bytes */
memquota = 512 * 1024 * 1024; /* bytes */ memquota = 512 * 1024 * 1024; /* bytes */
if ((s = getenv("V"))) verbose = atoi(s); if ((s = getenv("V"))) verbose = atoi(s);
while ((opt = getopt(argc, argv, "hnstvwA:C:F:L:M:O:P:T:V:")) != -1) { while ((opt = getopt(argc, argv, "hnstvwA:C:F:L:M:O:P:T:V:S:")) != -1) {
switch (opt) { switch (opt) {
case 'n': case 'n':
exit(0); exit(0);
@ -903,6 +916,9 @@ int main(int argc, char *argv[]) {
case 'M': case 'M':
memquota = sizetol(optarg, 1024); memquota = sizetol(optarg, 1024);
break; break;
case 'S':
stkquota = sizetol(optarg, 1024);
break;
case 'O': case 'O':
outquota = sizetol(optarg, 1024); outquota = sizetol(optarg, 1024);
break; break;