diff --git a/Makefile b/Makefile index de71e9b39..73fed5bd3 100644 --- a/Makefile +++ b/Makefile @@ -211,6 +211,7 @@ include test/libc/fmt/test.mk include test/libc/dns/test.mk include test/libc/time/test.mk include test/libc/stdio/test.mk +include test/libc/zipos/test.mk include test/libc/release/test.mk include test/libc/test.mk include test/net/http/test.mk diff --git a/examples/walk.c b/examples/walk.c index b9eca8eba..6b6253a70 100644 --- a/examples/walk.c +++ b/examples/walk.c @@ -7,16 +7,12 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif -#include "libc/calls/calls.h" -#include "libc/calls/struct/stat.h" #include "libc/errno.h" -#include "libc/runtime/gc.h" #include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" #include "libc/str/str.h" #include "libc/sysv/consts/exit.h" #include "libc/sysv/consts/s.h" -#include "libc/x/x.h" #include "third_party/musl/ftw.h" /** diff --git a/libc/calls/calls.mk b/libc/calls/calls.mk index bab0d35be..10177d083 100644 --- a/libc/calls/calls.mk +++ b/libc/calls/calls.mk @@ -79,14 +79,6 @@ o/$(MODE)/libc/calls/vdsofunc.greg.o: private \ -ffreestanding \ -fno-sanitize=address -# we can't use asan because: -# asan guard pages haven't been allocated yet -o/$(MODE)/libc/calls/directmap.o \ -o/$(MODE)/libc/calls/directmap-nt.o: private \ - OVERRIDE_COPTS += \ - -ffreestanding \ - -fno-sanitize=address - # we can't use asan because: # ntspawn allocates 128kb of heap memory via win32 o/$(MODE)/libc/calls/ntspawn.o \ @@ -144,12 +136,6 @@ o/$(MODE)/libc/calls/ioctl-siocgifconf-nt.o: private \ -ffunction-sections \ -fdata-sections -# we want small code size because: -# to keep .text.head under 4096 bytes -o/$(MODE)/libc/calls/mman.greg.o: private \ - OVERRIDE_COPTS += \ - -Os - # we always want -Os because: # va_arg codegen is very bloated in default mode o//libc/calls/open.o \ diff --git a/libc/calls/extend.internal.h b/libc/calls/extend.internal.h new file mode 100644 index 000000000..6de407ddc --- /dev/null +++ b/libc/calls/extend.internal.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_EXTEND_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_CALLS_EXTEND_INTERNAL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +void *_extend(void *, size_t, void *, intptr_t); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_EXTEND_INTERNAL_H_ */ diff --git a/libc/calls/reservefd.c b/libc/calls/reservefd.c index ee27f7b6f..d0a4f3e34 100644 --- a/libc/calls/reservefd.c +++ b/libc/calls/reservefd.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" #include "libc/calls/calls.h" +#include "libc/calls/extend.internal.h" #include "libc/calls/internal.h" #include "libc/calls/state.internal.h" #include "libc/calls/strace.internal.h" @@ -46,33 +47,11 @@ static volatile size_t mapsize; * @asyncsignalsafe */ int __ensurefds_unlocked(int fd) { - uint64_t addr; - int prot, flags; - size_t size, chunk; - struct DirectMap dm; + bool relocate; if (fd < g_fds.n) return fd; - STRACE("__ensurefds(%d) extending", fd); - size = mapsize; - chunk = FRAMESIZE; - if (IsAsan()) chunk *= 8; - addr = kMemtrackFdsStart + size; - prot = PROT_READ | PROT_WRITE; - flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED; - dm = sys_mmap((char *)addr, chunk, prot, flags, -1, 0); - TrackMemoryInterval(&_mmi, addr >> 16, (addr + chunk - 1) >> 16, dm.maphandle, - prot, flags, false, false, 0, chunk); - if (IsAsan()) { - addr = (addr >> 3) + 0x7fff8000; - dm = sys_mmap((char *)addr, FRAMESIZE, prot, flags, -1, 0); - TrackMemoryInterval(&_mmi, addr >> 16, addr >> 16, dm.maphandle, prot, - flags, false, false, 0, FRAMESIZE); - } - if (!size) { - g_fds.p = memcpy((char *)kMemtrackFdsStart, g_fds.__init_p, - sizeof(g_fds.__init_p)); - } - g_fds.n = (size + chunk) / sizeof(*g_fds.p); - mapsize = size + chunk; + g_fds.n = fd + 1; + g_fds.e = + _extend(g_fds.p, g_fds.n * sizeof(*g_fds.p), g_fds.e, 0x6ff000000000); return fd; } diff --git a/libc/calls/sig2.c b/libc/calls/sig2.c index 606514086..9d4c0bd19 100644 --- a/libc/calls/sig2.c +++ b/libc/calls/sig2.c @@ -16,6 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" #include "libc/calls/sig.internal.h" #include "libc/calls/state.internal.h" #include "libc/calls/strace.internal.h" diff --git a/libc/calls/struct/fd.internal.h b/libc/calls/struct/fd.internal.h index 17d586236..fe117b253 100644 --- a/libc/calls/struct/fd.internal.h +++ b/libc/calls/struct/fd.internal.h @@ -25,10 +25,9 @@ struct Fd { }; struct Fds { - int f; /* lowest free slot */ - size_t n; /* monotonic capacity */ - struct Fd *p; - struct Fd __init_p[OPEN_MAX]; + int f; /* lowest free slot */ + size_t n; + struct Fd *p, *e; }; COSMOPOLITAN_C_END_ diff --git a/libc/integral/normalize.inc b/libc/integral/normalize.inc index 513778444..30be7c9b9 100644 --- a/libc/integral/normalize.inc +++ b/libc/integral/normalize.inc @@ -67,8 +67,8 @@ #endif /* TODO(jart): Remove this in favor of GetStackSize() */ -#if defined(COSMO) && defined(MODE_DBG) -#define STACKSIZE 131072 /* 128kb stack */ +#if defined(COSMO) && (defined(MODE_DBG) || defined(__SANITIZE_ADDRESS__)) +#define STACKSIZE 262144 /* 256kb stack */ #elif defined(COSMO) #define STACKSIZE 65536 /* 64kb stack */ #else diff --git a/libc/calls/arememoryintervalsok.c b/libc/intrin/arememoryintervalsok.c similarity index 100% rename from libc/calls/arememoryintervalsok.c rename to libc/intrin/arememoryintervalsok.c diff --git a/libc/calls/directmap-metal.c b/libc/intrin/directmap-metal.c similarity index 100% rename from libc/calls/directmap-metal.c rename to libc/intrin/directmap-metal.c diff --git a/libc/calls/directmap-nt.c b/libc/intrin/directmap-nt.c similarity index 100% rename from libc/calls/directmap-nt.c rename to libc/intrin/directmap-nt.c diff --git a/libc/calls/directmap.c b/libc/intrin/directmap.c similarity index 100% rename from libc/calls/directmap.c rename to libc/intrin/directmap.c diff --git a/libc/intrin/extend.c b/libc/intrin/extend.c new file mode 100644 index 000000000..11da2f91f --- /dev/null +++ b/libc/intrin/extend.c @@ -0,0 +1,84 @@ +/*-*- 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/assert.h" +#include "libc/calls/calls.h" +#include "libc/dce.h" +#include "libc/intrin/asan.internal.h" +#include "libc/intrin/asancodes.h" +#include "libc/macros.internal.h" +#include "libc/runtime/directmap.internal.h" +#include "libc/runtime/memtrack.internal.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/prot.h" + +#define G FRAMESIZE + +static void _mapframe(void *p) { + int prot, flags; + struct DirectMap dm; + prot = PROT_READ | PROT_WRITE; + flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED; + if ((dm = sys_mmap(p, G, prot, flags, -1, 0)).addr != p) { + notpossible; + } + if (TrackMemoryInterval(&_mmi, (uintptr_t)p >> 16, + ((uintptr_t)p + G - 1) >> 16, dm.maphandle, prot, + flags, false, false, 0, G)) { + notpossible; + } +} + +/** + * Extends static allocation. + * + * This simple fixed allocator has unusual invariants + * + * !(p & 0xffff) && !(((p >> 3) + 0x7fff8000) & 0xffff) + * + * which must be the case when selecting a starting address. + * + * @param p points to start of memory region + * @param n specifies how many bytes are needed + * @param e points to end of memory that's allocated + * @param h is highest address to which `e` may grow + * @return new value for `e` + */ +noasan void *_extend(void *p, size_t n, void *e, intptr_t h) { + char *q; +#ifndef NDEBUG + if ((uintptr_t)SHADOW(p) & (G - 1)) notpossible; + if ((uintptr_t)p + (G << kAsanScale) > h) notpossible; +#endif + for (q = e; q < ((char *)p + n); q += 8) { + if (!((uintptr_t)q & (G - 1))) { + if (q + G > (char *)h) notpossible; + _mapframe(q); + if (IsAsan()) { + if (!((uintptr_t)SHADOW(q) & (G - 1))) { + _mapframe(SHADOW(q)); + __asan_poison(q, G << kAsanScale, kAsanProtected); + } + } + } + if (IsAsan()) { + *SHADOW(q) = 0; + } + } + return q; +} diff --git a/libc/intrin/g_fds.c b/libc/intrin/g_fds.c index 192476725..171fb3801 100644 --- a/libc/intrin/g_fds.c +++ b/libc/intrin/g_fds.c @@ -16,6 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/extend.internal.h" #include "libc/calls/internal.h" #include "libc/calls/state.internal.h" #include "libc/intrin/pthread.h" @@ -33,8 +34,8 @@ static textwindows dontinline void SetupWinStd(struct Fds *fds, int i, int x) { int64_t h; h = GetStdHandle(x); if (!h || h == -1) return; - fds->__init_p[i].kind = pushpop(kFdFile); - fds->__init_p[i].handle = h; + fds->p[i].kind = pushpop(kFdFile); + fds->p[i].handle = h; fds->f = i + 1; } @@ -42,29 +43,30 @@ textstartup void InitializeFileDescriptors(void) { struct Fds *fds; __fds_lock_obj.type = PTHREAD_MUTEX_RECURSIVE; fds = VEIL("r", &g_fds); - pushmov(&fds->n, ARRAYLEN(fds->__init_p)); + fds->p = fds->e = (void *)0x6fe000040000; + fds->n = 4; fds->f = 3; - fds->p = fds->__init_p; + fds->e = _extend(fds->p, fds->n * sizeof(*fds->p), fds->e, 0x6ff000000000); if (IsMetal()) { extern const char vga_console[]; pushmov(&fds->f, 3ull); if (weaken(vga_console)) { - fds->__init_p[0].kind = pushpop(kFdConsole); - fds->__init_p[1].kind = pushpop(kFdConsole); - fds->__init_p[2].kind = pushpop(kFdConsole); + fds->p[0].kind = pushpop(kFdConsole); + fds->p[1].kind = pushpop(kFdConsole); + fds->p[2].kind = pushpop(kFdConsole); } else { - fds->__init_p[0].kind = pushpop(kFdSerial); - fds->__init_p[1].kind = pushpop(kFdSerial); - fds->__init_p[2].kind = pushpop(kFdSerial); + fds->p[0].kind = pushpop(kFdSerial); + fds->p[1].kind = pushpop(kFdSerial); + fds->p[2].kind = pushpop(kFdSerial); } - fds->__init_p[0].handle = VEIL("r", 0x3F8ull); - fds->__init_p[1].handle = VEIL("r", 0x3F8ull); - fds->__init_p[2].handle = VEIL("r", 0x3F8ull); + fds->p[0].handle = VEIL("r", 0x3F8ull); + fds->p[1].handle = VEIL("r", 0x3F8ull); + fds->p[2].handle = VEIL("r", 0x3F8ull); } else if (IsWindows()) { SetupWinStd(fds, 0, kNtStdInputHandle); SetupWinStd(fds, 1, kNtStdOutputHandle); SetupWinStd(fds, 2, kNtStdErrorHandle); } - fds->__init_p[1].flags = O_WRONLY | O_APPEND; - fds->__init_p[2].flags = O_WRONLY | O_APPEND; + fds->p[1].flags = O_WRONLY | O_APPEND; + fds->p[2].flags = O_WRONLY | O_APPEND; } diff --git a/libc/intrin/intrin.mk b/libc/intrin/intrin.mk index 891ae56c0..7d32d0143 100644 --- a/libc/intrin/intrin.mk +++ b/libc/intrin/intrin.mk @@ -43,6 +43,20 @@ $(LIBC_INTRIN_A).pkg: \ $(LIBC_INTRIN_A_OBJS) \ $(foreach x,$(LIBC_INTRIN_A_DIRECTDEPS),$($(x)_A).pkg) +# we can't use asan because: +# asan guard pages haven't been allocated yet +o/$(MODE)/libc/intrin/directmap.o \ +o/$(MODE)/libc/intrin/directmap-nt.o: private \ + OVERRIDE_COPTS += \ + -ffreestanding \ + -fno-sanitize=address + +# we want small code size because: +# to keep .text.head under 4096 bytes +o/$(MODE)/libc/intrin/mman.greg.o: private \ + OVERRIDE_COPTS += \ + -Os + # we can't use asan and ubsan because: # this is asan and ubsan o/$(MODE)/libc/intrin/asan.o \ diff --git a/libc/calls/memtrack.greg.c b/libc/intrin/memtrack.greg.c similarity index 100% rename from libc/calls/memtrack.greg.c rename to libc/intrin/memtrack.greg.c diff --git a/libc/calls/mman.greg.c b/libc/intrin/mman.greg.c similarity index 100% rename from libc/calls/mman.greg.c rename to libc/intrin/mman.greg.c diff --git a/libc/log/libfatal.internal.h b/libc/log/libfatal.internal.h index ddf054af6..77a55f4b1 100644 --- a/libc/log/libfatal.internal.h +++ b/libc/log/libfatal.internal.h @@ -1,9 +1,7 @@ #ifndef COSMOPOLITAN_LIBC_LOG_LIBFATAL_INTERNAL_H_ #define COSMOPOLITAN_LIBC_LOG_LIBFATAL_INTERNAL_H_ -#include "libc/calls/calls.h" #include "libc/dce.h" #include "libc/macros.internal.h" -#include "libc/nexgen32e/bsr.h" #include "libc/nt/runtime.h" #include "libc/sysv/consts/nr.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) @@ -206,7 +204,7 @@ forceinline char *__fixcpy(char p[hasatleast 17], uint64_t x, uint8_t k) { } forceinline char *__hexcpy(char p[hasatleast 17], uint64_t x) { - return __fixcpy(p, x, ROUNDUP(x ? bsrl(x) + 1 : 1, 4)); + return __fixcpy(p, x, ROUNDUP(x ? (__builtin_clzll(x) ^ 63) + 1 : 1, 4)); } forceinline const void *__memchr(const void *s, unsigned char c, size_t n) { diff --git a/libc/log/showcrashreports.c b/libc/log/showcrashreports.c index fafdddf1c..c460ea04b 100644 --- a/libc/log/showcrashreports.c +++ b/libc/log/showcrashreports.c @@ -121,8 +121,7 @@ void ShowCrashReports(void) { ss.ss_size = GetStackSize(); // FreeBSD sigaltstack() will EFAULT if we use MAP_STACK here // OpenBSD sigaltstack() auto-applies MAP_STACK to the memory - if ((sp = mmap(0, GetStackSize(), PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) != MAP_FAILED) { + if ((sp = _mapanon(GetStackSize()))) { ss.ss_sp = sp; if (!sigaltstack(&ss, &g_oldsigaltstack)) { __cxa_atexit(FreeSigAltStack, ss.ss_sp, 0); diff --git a/libc/runtime/enable_tls.c b/libc/runtime/enable_tls.c index b6916d131..a6c4f9bb3 100644 --- a/libc/runtime/enable_tls.c +++ b/libc/runtime/enable_tls.c @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" #include "libc/calls/calls.h" -#include "libc/calls/strace.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" diff --git a/libc/runtime/fork-nt.c b/libc/runtime/fork-nt.c index a80a6a75b..93401e7a1 100644 --- a/libc/runtime/fork-nt.c +++ b/libc/runtime/fork-nt.c @@ -226,9 +226,9 @@ textwindows void WinMainForked(void) { // rewrap the stdin named pipe hack // since the handles closed on fork struct Fds *fds = VEIL("r", &g_fds); - fds->p[0].handle = fds->__init_p[0].handle = GetStdHandle(kNtStdInputHandle); - fds->p[1].handle = fds->__init_p[1].handle = GetStdHandle(kNtStdOutputHandle); - fds->p[2].handle = fds->__init_p[2].handle = GetStdHandle(kNtStdErrorHandle); + fds->p[0].handle = GetStdHandle(kNtStdInputHandle); + fds->p[1].handle = GetStdHandle(kNtStdOutputHandle); + fds->p[2].handle = GetStdHandle(kNtStdErrorHandle); // untrack children of parent since we specify with both // CreateProcess() and CreateThread() as non-inheritable diff --git a/libc/runtime/hook.greg.c b/libc/runtime/hook.greg.c index c68cbb904..24d7de0a3 100644 --- a/libc/runtime/hook.greg.c +++ b/libc/runtime/hook.greg.c @@ -16,16 +16,9 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/calls.h" #include "libc/calls/struct/sigset.h" -#include "libc/dce.h" -#include "libc/errno.h" -#include "libc/intrin/bits.h" -#include "libc/log/libfatal.internal.h" #include "libc/runtime/runtime.h" #include "libc/runtime/symbols.internal.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/prot.h" /** * Rewrites code in memory to hook function calls. diff --git a/libc/runtime/memtrack64.txt b/libc/runtime/memtrack64.txt index 2f5356616..9b090ce99 100644 --- a/libc/runtime/memtrack64.txt +++ b/libc/runtime/memtrack64.txt @@ -1810,7 +1810,7 @@ 6fb00000-6fbfffff 64gb free 6fc00000-6fcfffff 64gb free 6fd00000-6fdfffff 64gb zipos -6fe00000-6fefffff 64gb g_fds +6fe00004-6feffffc 64gb g_fds 6ff00000-6ffffffd 64gb free 6ffffffe-6fffffff 128kb winargs diff --git a/libc/stdio/ecvt.c b/libc/stdio/ecvt.c index 61f4455d9..2eba91728 100644 --- a/libc/stdio/ecvt.c +++ b/libc/stdio/ecvt.c @@ -24,6 +24,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/fmt/fmt.h" #include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" #include "libc/str/str.h" #include "third_party/gdtoa/gdtoa.h" @@ -33,10 +34,24 @@ Copyright (c) 2002, 2006, 2010 Todd C. Miller \""); asm(".include \"libc/disclaimer.inc\""); // clang-format off +static char *s; + +static void +__cvt_atexit(void) +{ + free(s); + s = 0; +} + +static void __attribute__((__constructor__)) +__cvt_init(void) +{ + atexit(__cvt_atexit); +} + static char * __cvt(double value, int ndigit, int *decpt, int *sign, int fmode, int pad) { - static char *s; char *p, *rve, c; size_t siz; diff --git a/libc/zipos/free.c b/libc/zipos/free.c index 5962dcc3a..512a71eba 100644 --- a/libc/zipos/free.c +++ b/libc/zipos/free.c @@ -23,11 +23,6 @@ #include "libc/str/str.h" #include "libc/zipos/zipos.internal.h" -/** - * Frees ZipOS handle. - * @asyncsignalsafe - * @threadsafe - */ void __zipos_free(struct Zipos *z, struct ZiposHandle *h) { if (IsAsan()) { __asan_poison((char *)h + sizeof(struct ZiposHandle), diff --git a/libc/zipos/open.c b/libc/zipos/open.c index ad6ad9918..44979f08e 100644 --- a/libc/zipos/open.c +++ b/libc/zipos/open.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" #include "libc/calls/calls.h" +#include "libc/calls/extend.internal.h" #include "libc/calls/internal.h" #include "libc/calls/state.internal.h" #include "libc/calls/struct/sigset.h" @@ -42,47 +43,19 @@ #include "libc/zip.h" #include "libc/zipos/zipos.internal.h" -static volatile size_t maptotal; - -static pureconst size_t __zipos_granularity(void) { - return FRAMESIZE * (IsAsan() ? 8 : 1); -} +static char *mapend; +static size_t maptotal; static void *__zipos_mmap(size_t mapsize) { + char *start; size_t offset; - struct DirectMap dm; - int rc, prot, flags; - uint64_t addr, addr2, addr3; assert(mapsize); - do offset = maptotal; - while (!_cmpxchg(&maptotal, offset, maptotal + mapsize)); - if (offset + mapsize <= kMemtrackZiposSize) { - prot = PROT_READ | PROT_WRITE; - flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED; - addr = kMemtrackZiposStart + offset; - if ((dm = sys_mmap((void *)addr, mapsize, prot, flags, -1, 0)).addr != - MAP_FAILED) { - rc = TrackMemoryInterval(&_mmi, addr >> 16, (addr + mapsize - 1) >> 16, - dm.maphandle, prot, flags, false, false, 0, - mapsize); - assert(!rc); - if (IsAsan()) { - addr2 = (addr >> 3) + 0x7fff8000; - addr3 = ((addr + mapsize) >> 3) + 0x7fff8000; - assert(!(addr2 & (FRAMESIZE - 1))); - assert(!(addr3 & (FRAMESIZE - 1))); - dm = sys_mmap((void *)addr2, mapsize >> 3, prot, flags, -1, 0); - assert(dm.addr != MAP_FAILED); - rc = TrackMemoryInterval(&_mmi, addr2 >> 16, (addr3 >> 16) - 1, - dm.maphandle, prot, flags, false, false, 0, - mapsize >> 3); - assert(!rc); - } - return (void *)addr; - } - } - enomem(); - return 0; + offset = maptotal; + maptotal += mapsize; + start = (char *)0x6fd000040000; + if (!mapend) mapend = start; + mapend = _extend(start, maptotal, mapend, 0x6fdfffff0000); + return start + offset; } static struct ZiposHandle *__zipos_alloc(struct Zipos *zipos, size_t size) { @@ -90,7 +63,7 @@ static struct ZiposHandle *__zipos_alloc(struct Zipos *zipos, size_t size) { struct ZiposHandle *h, **ph; __zipos_lock(); mapsize = sizeof(struct ZiposHandle) + size; - mapsize = ROUNDUP(mapsize, __zipos_granularity()); + mapsize = ROUNDUP(mapsize, 4096); StartOver: ph = &zipos->freelist; while ((h = *ph)) { diff --git a/libc/zipos/zipos.h b/libc/zipos/zipos.h new file mode 100755 index 000000000..e69de29bb diff --git a/libc/zipos/zipos.internal.h b/libc/zipos/zipos.internal.h index 6fb612e6a..dcccad9cb 100644 --- a/libc/zipos/zipos.internal.h +++ b/libc/zipos/zipos.internal.h @@ -1,6 +1,5 @@ #ifndef COSMOPOLITAN_LIBC_ZIPOS_ZIPOS_H_ #define COSMOPOLITAN_LIBC_ZIPOS_ZIPOS_H_ -#include "libc/calls/calls.h" #include "libc/intrin/nopl.h" #include "libc/nexgen32e/threaded.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) diff --git a/test/libc/calls/reservefd_test.c b/test/libc/calls/reservefd_test.c index a513cb243..b06e47680 100644 --- a/test/libc/calls/reservefd_test.c +++ b/test/libc/calls/reservefd_test.c @@ -61,7 +61,6 @@ void PullSomeZipFilesIntoLinkage(void) { TEST(reservefd, testGrowthOfFdsDataStructure) { int i, n; struct rlimit rlim; - ASSERT_EQ(g_fds.n, OPEN_MAX); n = 1700; // pe '2**16/40' → 1638 (likely value of g_fds.n) if (!getrlimit(RLIMIT_NOFILE, &rlim)) n = MIN(n, rlim.rlim_cur - 3); for (i = 0; i < n; ++i) { diff --git a/test/libc/fmt/fcvt_test.c b/test/libc/stdio/ecvt_test.c similarity index 100% rename from test/libc/fmt/fcvt_test.c rename to test/libc/stdio/ecvt_test.c diff --git a/test/libc/test.mk b/test/libc/test.mk index ef908621a..4abd1a1e0 100644 --- a/test/libc/test.mk +++ b/test/libc/test.mk @@ -19,4 +19,5 @@ o/$(MODE)/test/libc: \ o/$(MODE)/test/libc/time \ o/$(MODE)/test/libc/tinymath \ o/$(MODE)/test/libc/x \ + o/$(MODE)/test/libc/zipos \ o/$(MODE)/test/libc/xed diff --git a/test/libc/thread/pthread_create_test.c b/test/libc/thread/pthread_create_test.c index 421761208..b59d3c51b 100644 --- a/test/libc/thread/pthread_create_test.c +++ b/test/libc/thread/pthread_create_test.c @@ -26,6 +26,7 @@ #include "libc/intrin/pthread2.h" #include "libc/macros.internal.h" #include "libc/mem/mem.h" +#include "libc/nexgen32e/nexgen32e.h" #include "libc/runtime/runtime.h" #include "libc/runtime/stack.h" #include "libc/sysv/consts/prot.h" @@ -37,18 +38,19 @@ #include "libc/testlib/testlib.h" #include "libc/thread/thread.h" -void OnTrap(int sig, struct siginfo *si, void *vctx) { +void OnUsr1(int sig, struct siginfo *si, void *vctx) { struct ucontext *ctx = vctx; } void SetUp(void) { - struct sigaction sig = {.sa_sigaction = OnTrap, .sa_flags = SA_SIGINFO}; - sigaction(SIGTRAP, &sig, 0); + struct sigaction sig = {.sa_sigaction = OnUsr1, .sa_flags = SA_SIGINFO}; + sigaction(SIGUSR1, &sig, 0); } void TriggerSignal(void) { sched_yield(); - DebugBreak(); + /* kprintf("raising at %p\n", __builtin_frame_address(0)); */ + raise(SIGUSR1); sched_yield(); } @@ -67,6 +69,7 @@ TEST(pthread_create, testCreateReturnJoin) { } static void *IncExit(void *arg) { + CheckStackIsAligned(); TriggerSignal(); pthread_exit((void *)((uintptr_t)arg + 1)); } diff --git a/test/libc/zipos/open_test.c b/test/libc/zipos/open_test.c new file mode 100644 index 000000000..a94e8bba3 --- /dev/null +++ b/test/libc/zipos/open_test.c @@ -0,0 +1,56 @@ +/*-*- 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/mem/mem.h" +#include "libc/runtime/gc.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/o.h" +#include "libc/testlib/hyperion.h" +#include "libc/testlib/testlib.h" +#include "libc/thread/spawn.h" +#include "libc/zipos/zipos.h" + +STATIC_YOINK("zip_uri_support"); +STATIC_YOINK("libc/testlib/hyperion.txt"); +/* STATIC_YOINK("inflate"); */ +/* STATIC_YOINK("inflateInit2"); */ +/* STATIC_YOINK("inflateEnd"); */ + +int Worker(void *arg, int tid) { + int i, fd; + char *data; + for (i = 0; i < 20; ++i) { + ASSERT_NE(-1, (fd = open("/zip/libc/testlib/hyperion.txt", O_RDONLY))); + data = malloc(kHyperionSize); + ASSERT_EQ(kHyperionSize, read(fd, data, kHyperionSize)); + ASSERT_EQ(0, memcmp(data, kHyperion, kHyperionSize)); + ASSERT_SYS(0, 0, close(fd)); + free(data); + } + return 0; +} + +TEST(zipos, test) { + int i, n = 16; + struct spawn *t = _gc(malloc(sizeof(struct spawn) * n)); + for (i = 0; i < n; ++i) ASSERT_SYS(0, 0, _spawn(Worker, 0, t + i)); + for (i = 0; i < n; ++i) EXPECT_SYS(0, 0, _join(t + i)); + /* __print_maps(); */ +} diff --git a/test/libc/zipos/test.mk b/test/libc/zipos/test.mk new file mode 100644 index 000000000..086867e33 --- /dev/null +++ b/test/libc/zipos/test.mk @@ -0,0 +1,63 @@ +#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ +#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ + +PKGS += TEST_LIBC_ZIPOS + +TEST_LIBC_ZIPOS_SRCS := $(wildcard test/libc/zipos/*.c) +TEST_LIBC_ZIPOS_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_ZIPOS_SRCS)) + +TEST_LIBC_ZIPOS_OBJS = \ + $(TEST_LIBC_ZIPOS_SRCS:%.c=o/$(MODE)/%.o) + +TEST_LIBC_ZIPOS_COMS = \ + $(TEST_LIBC_ZIPOS_SRCS:%.c=o/$(MODE)/%.com) + +TEST_LIBC_ZIPOS_BINS = \ + $(TEST_LIBC_ZIPOS_COMS) \ + $(TEST_LIBC_ZIPOS_COMS:%=%.dbg) + +TEST_LIBC_ZIPOS_TESTS = \ + $(TEST_LIBC_ZIPOS_SRCS_TEST:%.c=o/$(MODE)/%.com.ok) + +TEST_LIBC_ZIPOS_CHECKS = \ + $(TEST_LIBC_ZIPOS_SRCS_TEST:%.c=o/$(MODE)/%.com.runs) + +TEST_LIBC_ZIPOS_DIRECTDEPS = \ + LIBC_CALLS \ + LIBC_FMT \ + LIBC_INTRIN \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_RUNTIME \ + LIBC_STR \ + LIBC_STUBS \ + LIBC_THREAD \ + LIBC_SYSV \ + LIBC_ZIPOS \ + LIBC_TIME \ + LIBC_TESTLIB \ + THIRD_PARTY_ZLIB + +TEST_LIBC_ZIPOS_DEPS := \ + $(call uniq,$(foreach x,$(TEST_LIBC_ZIPOS_DIRECTDEPS),$($(x)))) + +o/$(MODE)/test/libc/zipos/zipos.pkg: \ + $(TEST_LIBC_ZIPOS_OBJS) \ + $(foreach x,$(TEST_LIBC_ZIPOS_DIRECTDEPS),$($(x)_A).pkg) + +#o/$(MODE)/libc/testlib/hyperion.txt.zip.o: private ZIPOBJ_FLAGS += -0 + +o/$(MODE)/test/libc/zipos/%.com.dbg: \ + $(TEST_LIBC_ZIPOS_DEPS) \ + o/$(MODE)/test/libc/zipos/%.o \ + o/$(MODE)/test/libc/zipos/zipos.pkg \ + o/$(MODE)/libc/testlib/hyperion.txt.zip.o \ + $(LIBC_TESTMAIN) \ + $(CRT) \ + $(APE_NO_MODIFY_SELF) + @$(APELINK) + +.PHONY: o/$(MODE)/test/libc/zipos +o/$(MODE)/test/libc/zipos: \ + $(TEST_LIBC_ZIPOS_BINS) \ + $(TEST_LIBC_ZIPOS_CHECKS) diff --git a/tool/scripts/check-includes.py b/tool/scripts/check-includes.py deleted file mode 100755 index eed104417..000000000 --- a/tool/scripts/check-includes.py +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env python.com - -import os -import sys - -def CheckFile(path): - if path.endswith(('.png', '.ico')): - return - sys.stderr.write('%s\n' % (path)) - with open(path) as f: - data = f.read() - assert '#include' not in data[65530:], "late include in %s" % (path) - -for arg in sys.argv[1:]: - if os.path.isdir(arg): - for dirpath, dirs, files in os.walk(arg): - for filepath in files: - CheckFile(os.path.join(dirpath, filepath)) - else: - CheckFile(arg)