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

View file

@ -173,7 +173,7 @@ else
fatal_error "$ARCH: unsupported architecture"
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
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"
CPPFLAGS_X86_64="$CPPFLAGS -mno-red-zone"
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"
if [ $MCOSMO -eq 1 ]; then
CPPFLAGS_X86_64="${CPPFLAGS_X86_64} -D_COSMO_SOURCE"

View file

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

View file

@ -33,6 +33,7 @@
#include "libc/stdio/stdio.h"
#include "libc/stdio/temp.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/lock.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/ok.h"
#include "libc/sysv/consts/s.h"
@ -236,6 +237,73 @@ static int Echo(void) {
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) {
ssize_t rc;
char buf[512];
@ -300,6 +368,7 @@ static int Mktemp(void) {
perror("mkstemp");
return 1;
}
strlcat(template, "\n", sizeof(template));
Write(1, template);
close(fd);
return 0;
@ -328,11 +397,6 @@ static int Read(void) {
return rc;
}
static int NeedArgument(const char *prog) {
tinyprint(2, prog, ": missing argument\n", NULL);
return 1;
}
static int Cd(void) {
const char *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], "cat")) return Cat();
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], "echo")) return Echo();
if (!strcmp(args[0], "read")) return Read();
if (!strcmp(args[0], "true")) return True();
if (!strcmp(args[0], "test")) return Test();
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], "rmdir")) return Rmdir();
if (!strcmp(args[0], "mkdir")) return Mkdir();
@ -913,6 +980,13 @@ int _cocmd(int argc, char **argv, char **envp) {
unsupported['?'] = true;
}
if (argc >= 3 && !strcmp(argv[1], "--")) {
for (i = 2; i < argc; ++i) {
args[n++] = argv[i];
}
_Exit(ShellExec());
}
if (argc != 3) {
tinyprint(2, prog, ": error: wrong number of args\n", NULL);
_Exit(10);

View file

@ -1882,11 +1882,6 @@ int main(int argc, char *argv[]) {
struct Input *in = inputs.p + i;
if (GetElfSymbol(in, "__zipos_get")) {
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/sig.h"
#include "libc/sysv/consts/termios.h"
#include "libc/thread/thread.h"
#include "libc/time/time.h"
#include "libc/x/x.h"
#include "third_party/getopt/getopt.internal.h"
@ -114,6 +115,7 @@ FLAGS\n\
-C SECS set cpu limit [default 16]\n\
-L SECS set lat limit [default 90]\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\
-F BYTES set fsz limit [default 256m]\n\
-O BYTES set out limit [default 1m]\n\
@ -173,6 +175,7 @@ int pipefds[2];
long cpuquota;
long fszquota;
long memquota;
long stkquota;
long proquota;
long outquota;
@ -547,6 +550,14 @@ void SetMemLimit(long n) {
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) {
struct rlimit rlim = {n, n};
if (n <= 0) return;
@ -650,6 +661,7 @@ int Launch(void) {
SetCpuLimit(cpuquota);
SetFszLimit(fszquota);
SetMemLimit(memquota);
SetStkLimit(stkquota);
SetProLimit(proquota);
if (stdoutmustclose) dup2(pipefds[1], 1);
dup2(pipefds[1], 2);
@ -860,10 +872,11 @@ int main(int argc, char *argv[]) {
timeout = 90; /* secs */
cpuquota = 32; /* secs */
proquota = 2048; /* procs */
stkquota = 2 * 1024 * 1024; /* bytes */
fszquota = 256 * 1000 * 1000; /* bytes */
memquota = 512 * 1024 * 1024; /* bytes */
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) {
case 'n':
exit(0);
@ -903,6 +916,9 @@ int main(int argc, char *argv[]) {
case 'M':
memquota = sizetol(optarg, 1024);
break;
case 'S':
stkquota = sizetol(optarg, 1024);
break;
case 'O':
outquota = sizetol(optarg, 1024);
break;