From b69f3d2488dbaf9dcc541e699f5b7c09fbf046e0 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 12 Sep 2022 04:19:32 -0700 Subject: [PATCH] Optimize memory layout --- ape/ape.lds | 4 +- ape/relocations.h | 4 +- libc/atomic.h | 64 ++++++++------------ libc/calls/munmap-sysv.c | 4 +- libc/calls/weirdtypes.h | 30 +--------- libc/intrin/describeframe.c | 54 +++++++++++++---- libc/intrin/describemapping.c | 4 +- libc/intrin/directmap.c | 7 ++- libc/intrin/isatleastwindows10.greg.c | 1 - libc/intrin/memtrack.greg.c | 62 +++++++++---------- libc/intrin/printmemoryintervals.c | 20 +++---- libc/inttypes.h | 9 +++ libc/limits.h | 19 +++++- libc/log/backtrace.internal.h | 1 - libc/mem/arena.c | 8 +-- libc/mem/pvalloc.c | 7 ++- libc/mem/valloc.c | 6 +- libc/nt/version.h | 2 +- libc/runtime/brk.c | 4 +- libc/runtime/memtrack.internal.h | 82 +++++++++++++------------- libc/runtime/memtrack64.txt | 36 +++++------ libc/runtime/stack.h | 20 +++---- libc/runtime/winmain.greg.c | 15 +++-- test/libc/intrin/kprintf_test.c | 4 ++ test/libc/zipos/open_test.c | 2 +- test/tool/build/pledge_test.sh | 2 + third_party/nsync/atomic.h | 3 +- third_party/nsync/nsync.mk | 1 - third_party/zip/zipup.c | 8 ++- third_party/zlib/deflate.c | 39 +++++++----- third_party/zlib/deflate.internal.h | 6 +- third_party/zlib/infback.c | 48 +++++++-------- third_party/zlib/inffast.c | 9 ++- third_party/zlib/inffastchunk.c | 9 ++- third_party/zlib/inflate.c | 47 +++++++-------- third_party/zlib/inftrees.c | 2 +- third_party/zlib/trees.c | 49 ++++++++------- third_party/zlib/zconf.h | 4 ++ third_party/zlib/zutil.c | 10 +++- third_party/zlib/zutil.internal.h | 22 +++---- tool/emacs/cosmo-platform-constants.el | 2 + 41 files changed, 383 insertions(+), 347 deletions(-) diff --git a/ape/ape.lds b/ape/ape.lds index 6cb55b593..bd88af341 100644 --- a/ape/ape.lds +++ b/ape/ape.lds @@ -714,8 +714,8 @@ ASSERT(!DEFINED(_start16) || REAL(_end) < 65536, ASSERT(IS2POW(ape_stack_memsz), "ape_stack_memsz must be a two power"); -ASSERT(!(ape_stack_vaddr & (ape_stack_memsz - 1)), - "ape_stack_vaddr must have ape_stack_memsz alignment; try using STATIC_STACK_ADDR(0x700000000000 - ape_stack_memsz);"); +ASSERT(ape_stack_vaddr % ape_stack_memsz == 0, + "ape_stack_vaddr must have ape_stack_memsz alignment; try using STATIC_STACK_ADDR(0x700000040000 - ape_stack_memsz);"); ASSERT(ALIGNOF(.tdata) <= TLS_ALIGNMENT && ALIGNOF(.tbss) <= TLS_ALIGNMENT, "_Thread_local _Alignof can't exceed TLS_ALIGNMENT"); diff --git a/ape/relocations.h b/ape/relocations.h index 38895bbf4..9674f8882 100644 --- a/ape/relocations.h +++ b/ape/relocations.h @@ -36,8 +36,8 @@ */ #define REAL(x) ((x) - (IMAGE_BASE_VIRTUAL - IMAGE_BASE_REAL)) -#if IMAGE_BASE_VIRTUAL % 0x200000 != 0 -#error "IMAGE_BASE_VIRTUAL must be 2mb aligned" +#if IMAGE_BASE_VIRTUAL % 0x1000 != 0 +#error "IMAGE_BASE_VIRTUAL must be 4kb aligned" #endif #if IMAGE_BASE_PHYSICAL % 0x1000 != 0 #error "IMAGE_BASE_PHYSICAL must be 4kb aligned" diff --git a/libc/atomic.h b/libc/atomic.h index f132e5ed2..92a7cc077 100644 --- a/libc/atomic.h +++ b/libc/atomic.h @@ -1,22 +1,8 @@ #ifndef COSMOPOLITAN_LIBC_ATOMIC_H_ #define COSMOPOLITAN_LIBC_ATOMIC_H_ -#include "libc/inttypes.h" -#if !(__ASSEMBLER__ + __LINKER__ + 0) -COSMOPOLITAN_C_START_ - -/** - * @fileoverview C11 Atomic Types - * - * We supoprt C++ and old C compilers. It's recommended you use macros - * like `_Atomic(int)` rather than `_Atomic int` or `atomic_int` since - * we only define a portability macro for the syntax `_Atomic(T)`. - * - * @see libc/integral/c.inc - * @see libc/intrin/atomic.h - */ #define atomic_bool _Atomic(_Bool) -#define atomic_bool32 atomic_int32 +#define atomic_bool32 _Atomic(__INT32_TYPE__) #define atomic_char _Atomic(char) #define atomic_schar _Atomic(signed char) #define atomic_uchar _Atomic(unsigned char) @@ -28,29 +14,29 @@ COSMOPOLITAN_C_START_ #define atomic_ulong _Atomic(unsigned long) #define atomic_llong _Atomic(long long) #define atomic_ullong _Atomic(unsigned long long) -#define atomic_char16_t _Atomic(char16_t) -#define atomic_char32_t _Atomic(char32_t) -#define atomic_wchar_t _Atomic(wchar_t) -#define atomic_intptr_t _Atomic(intptr_t) -#define atomic_uintptr_t _Atomic(uintptr_t) -#define atomic_size_t _Atomic(size_t) -#define atomic_ptrdiff_t _Atomic(ptrdiff_t) -#define atomic_int_fast8_t _Atomic(int_fast8_t) -#define atomic_uint_fast8_t _Atomic(uint_fast8_t) -#define atomic_int_fast16_t _Atomic(int_fast16_t) -#define atomic_uint_fast16_t _Atomic(uint_fast16_t) -#define atomic_int_fast32_t _Atomic(int_fast32_t) -#define atomic_uint_fast32_t _Atomic(uint_fast32_t) -#define atomic_int_fast64_t _Atomic(int_fast64_t) -#define atomic_uint_fast64_t _Atomic(uint_fast64_t) -#define atomic_int_least8_t _Atomic(int_least8_t) -#define atomic_uint_least8_t _Atomic(uint_least8_t) -#define atomic_int_least16_t _Atomic(int_least16_t) -#define atomic_uint_least16_t _Atomic(uint_least16_t) -#define atomic_int_least32_t _Atomic(int_least32_t) -#define atomic_uint_least32_t _Atomic(uint_least32_t) -#define atomic_int_least64_t _Atomic(int_least64_t) -#define atomic_uint_least64_t _Atomic(uint_least64_t) +#define atomic_char16_t _Atomic(__CHAR16_TYPE__) +#define atomic_char32_t _Atomic(__CHAR32_TYPE__) +#define atomic_wchar_t _Atomic(__WCHAR_TYPE__) +#define atomic_intptr_t _Atomic(__INTPTR_TYPE__) +#define atomic_uintptr_t _Atomic(__UINTPTR_TYPE__) +#define atomic_size_t _Atomic(__SIZE_TYPE__) +#define atomic_ptrdiff_t _Atomic(__PTRDIFF_TYPE__) +#define atomic_int_fast8_t _Atomic(__INT_FAST8_TYPE__) +#define atomic_uint_fast8_t _Atomic(__UINT_FAST8_TYPE__) +#define atomic_int_fast16_t _Atomic(__INT_FAST16_TYPE__) +#define atomic_uint_fast16_t _Atomic(__UINT_FAST16_TYPE__) +#define atomic_int_fast32_t _Atomic(__INT_FAST32_TYPE__) +#define atomic_uint_fast32_t _Atomic(__UINT_FAST32_TYPE__) +#define atomic_int_fast64_t _Atomic(__INT_FAST64_TYPE__) +#define atomic_uint_fast64_t _Atomic(__UINT_FAST64_TYPE__) +#define atomic_int_least8_t _Atomic(__INT_LEAST8_TYPE__) +#define atomic_uint_least8_t _Atomic(__UINT_LEAST8_TYPE__) +#define atomic_int_least16_t _Atomic(__INT_LEAST16_TYPE__) +#define atomic_uint_least16_t _Atomic(__UINT_LEAST16_TYPE__) +#define atomic_int_least32_t _Atomic(__INT_LEAST32_TYPE__) +#define atomic_uint_least32_t _Atomic(__UINT_LEAST32_TYPE__) +#define atomic_int_least64_t _Atomic(__INT_LEAST64_TYPE__) +#define atomic_uint_least64_t _Atomic(__UINT_LEAST64_TYPE__) #ifdef __CLANG_ATOMIC_BOOL_LOCK_FREE #define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE @@ -76,6 +62,4 @@ COSMOPOLITAN_C_START_ #define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE #endif -COSMOPOLITAN_C_END_ -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_ATOMIC_H_ */ diff --git a/libc/calls/munmap-sysv.c b/libc/calls/munmap-sysv.c index 9f4c412ca..bf88b2f09 100644 --- a/libc/calls/munmap-sysv.c +++ b/libc/calls/munmap-sysv.c @@ -38,7 +38,7 @@ int sys_munmap(void *p, size_t n) { } else { rc = sys_munmap_metal(p, n); } - KERNTRACE("sys_munmap(%p%s, %'zu) → %d", p, DescribeFrame((intptr_t)p >> 16), - n, rc); + KERNTRACE("sys_munmap(%p /* %s */, %'zu) → %d", p, + DescribeFrame((intptr_t)p >> 16), n, rc); return rc; } diff --git a/libc/calls/weirdtypes.h b/libc/calls/weirdtypes.h index 77e25f8f7..2121cd7af 100644 --- a/libc/calls/weirdtypes.h +++ b/libc/calls/weirdtypes.h @@ -37,34 +37,8 @@ #define uid_t uint32_t #define rlim_t uint64_t /* int64_t on bsd */ -typedef __INT_FAST8_TYPE__ int_fast8_t; -typedef __UINT_FAST8_TYPE__ uint_fast8_t; -typedef __INT_FAST16_TYPE__ int_fast16_t; -typedef __UINT_FAST16_TYPE__ uint_fast16_t; -typedef __INT_FAST32_TYPE__ int_fast32_t; -typedef __UINT_FAST32_TYPE__ uint_fast32_t; -typedef __INT_FAST64_TYPE__ int_fast64_t; -typedef __UINT_FAST64_TYPE__ uint_fast64_t; - -#define TIME_T_MAX __INT64_MAX__ -#define UINT_FAST64_MAX __UINT_FAST64_MAX__ -#define UINT_FAST8_MAX __UINT_FAST8_MAX__ -#define INT_FAST32_MAX __INT_FAST32_MAX__ -#define INT_FAST16_MAX __INT_FAST16_MAX__ -#define UINT_FAST32_MAX __UINT_FAST32_MAX__ -#define INT_FAST8_MAX __INT_FAST8_MAX__ -#define INT_FAST64_MAX __INT_FAST64_MAX__ -#define UINT_FAST16_MAX __UINT_FAST16_MAX__ - -#define TIME_T_MIN (-TIME_T_MAX - 1) -#define UINT_FAST64_MIN (-UINT_FAST64_MAX - 1) -#define UINT_FAST8_MIN (-UINT_FAST8_MAX - 1) -#define INT_FAST32_MIN (-INT_FAST32_MAX - 1) -#define INT_FAST16_MIN (-INT_FAST16_MAX - 1) -#define UINT_FAST32_MIN (-UINT_FAST32_MAX - 1) -#define INT_FAST8_MIN (-INT_FAST8_MAX - 1) -#define INT_FAST64_MIN (-INT_FAST64_MAX - 1) -#define UINT_FAST16_MIN (-UINT_FAST16_MAX - 1) +#define TIME_T_MAX __INT64_MAX__ +#define TIME_T_MIN (-TIME_T_MAX - 1) #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_CALLS_WEIRDTYPES_H_ */ diff --git a/libc/intrin/describeframe.c b/libc/intrin/describeframe.c index 4bb56aad1..84d2a491a 100644 --- a/libc/intrin/describeframe.c +++ b/libc/intrin/describeframe.c @@ -16,32 +16,62 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" #include "libc/intrin/describeflags.internal.h" #include "libc/intrin/kprintf.h" #include "libc/macros.internal.h" #include "libc/runtime/memtrack.internal.h" #include "libc/runtime/runtime.h" +#include "libc/runtime/winargs.internal.h" #define ADDR(x) ((int64_t)((uint64_t)(x) << 32) >> 16) #define UNSHADOW(x) ((int64_t)(MAX(0, (x)-0x7fff8000)) << 3) #define FRAME(x) ((int)((x) >> 16)) -const char *(DescribeFrame)(char buf[32], int x) { - /* asan runtime depends on this function */ - char *p; - if (IsShadowFrame(x)) { - ksnprintf(buf, 32, " shadow=%.8x", FRAME(UNSHADOW(ADDR(x)))); - return buf; - return " shadow "; +static const char *GetFrameName(int x) { + if (!x) { + return "null"; + } else if (IsShadowFrame(x)) { + return "shadow"; } else if (IsAutoFrame(x)) { - return " automap"; + return "automap"; } else if (IsFixedFrame(x)) { - return " fixed "; + return "fixed"; } else if (IsArenaFrame(x)) { - return " arena "; + return "arena"; } else if (IsStaticStackFrame(x)) { - return " stack "; + return "stack"; + } else if (IsGfdsFrame(x)) { + return "g_fds"; + } else if (IsZiposFrame(x)) { + return "zipos"; + } else if (IsNsyncFrame(x)) { + return "nsync"; + } 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 "winargs"; + } else if ((int)((intptr_t)_base >> 16) <= x && + x <= (int)(((intptr_t)_end - 1) >> 16)) { + return "image"; } else { - return ""; + return "unknown"; + } +} + +const char *(DescribeFrame)(char buf[32], int x) { + char *p; + if (IsShadowFrame(x)) { + ksnprintf(buf, 64, "%s %s %.8x", GetFrameName(x), + GetFrameName(FRAME(UNSHADOW(ADDR(x)))), FRAME(UNSHADOW(ADDR(x)))); + return buf; + } else { + return GetFrameName(x); } } diff --git a/libc/intrin/describemapping.c b/libc/intrin/describemapping.c index f6e6964db..5fa2a206c 100644 --- a/libc/intrin/describemapping.c +++ b/libc/intrin/describemapping.c @@ -49,7 +49,7 @@ const char *(DescribeMapping)(char p[8], int prot, int flags) { DescribeProt(p, prot); p[3] = DescribeMapType(flags); p[4] = (flags & MAP_ANONYMOUS) ? 'a' : '-'; - p[6] = (flags & MAP_FIXED) ? 'F' : '-'; - p[7] = 0; + p[5] = (flags & MAP_FIXED) ? 'F' : '-'; + p[6] = 0; return p; } diff --git a/libc/intrin/directmap.c b/libc/intrin/directmap.c index d2e29ec5c..2feae3dd0 100644 --- a/libc/intrin/directmap.c +++ b/libc/intrin/directmap.c @@ -46,8 +46,9 @@ struct DirectMap sys_mmap(void *addr, size_t size, int prot, int flags, int fd, } else { d = sys_mmap_nt(addr, size, prot, flags, fd, off); } - KERNTRACE("sys_mmap(%.12p%s, %'zu, %s, %s, %d, %'ld) → {%.12p, %p}% m", addr, - DescribeFrame((intptr_t)addr >> 16), size, DescribeProtFlags(prot), - DescribeMapFlags(flags), fd, off, d.addr, d.maphandle); + KERNTRACE("sys_mmap(%.12p /* %s */, %'zu, %s, %s, %d, %'ld) → {%.12p, %p}% m", + addr, DescribeFrame((intptr_t)addr >> 16), size, + DescribeProtFlags(prot), DescribeMapFlags(flags), fd, off, d.addr, + d.maphandle); return d; } diff --git a/libc/intrin/isatleastwindows10.greg.c b/libc/intrin/isatleastwindows10.greg.c index 100098058..1135ec56d 100644 --- a/libc/intrin/isatleastwindows10.greg.c +++ b/libc/intrin/isatleastwindows10.greg.c @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" #include "libc/dce.h" -#include "libc/nt/enum/version.h" #include "libc/nt/version.h" /** diff --git a/libc/intrin/memtrack.greg.c b/libc/intrin/memtrack.greg.c index 4f5a2482a..c00b6351c 100644 --- a/libc/intrin/memtrack.greg.c +++ b/libc/intrin/memtrack.greg.c @@ -37,11 +37,20 @@ #include "libc/sysv/consts/prot.h" #include "libc/sysv/errfuns.h" +#if IsModeDbg() +#define ASSERT_MEMTRACK() \ + if (!AreMemoryIntervalsOk(mm)) { \ + PrintMemoryIntervals(2, mm); \ + notpossible; \ + } +#else +#define ASSERT_MEMTRACK() +#endif + static void *MoveMemoryIntervals(struct MemoryInterval *d, const struct MemoryInterval *s, int n) { - // asan runtime depends on this function int i; - assert(n >= 0); + if (n < 0) unreachable; if (d > s) { for (i = n; i--;) { d[i] = s[i]; @@ -55,9 +64,8 @@ static void *MoveMemoryIntervals(struct MemoryInterval *d, } static void RemoveMemoryIntervals(struct MemoryIntervals *mm, int i, int n) { - // asan runtime depends on this function - assert(i >= 0); - assert(i + n <= mm->i); + if (i < 0) unreachable; + if (i + n > mm->i) unreachable; MoveMemoryIntervals(mm->p + i, mm->p + i + n, mm->i - (i + n)); mm->i -= n; } @@ -96,19 +104,14 @@ static bool ExtendMemoryIntervals(struct MemoryIntervals *mm) { if (!dm.addr) return false; mm->n = (size + gran) / sizeof(*mm->p); } -#if IsModeDbg() - assert(AreMemoryIntervalsOk(mm)); -#endif + ASSERT_MEMTRACK(); return true; } int CreateMemoryInterval(struct MemoryIntervals *mm, int i) { - // asan runtime depends on this function - int rc; - rc = 0; - assert(i >= 0); - assert(i <= mm->i); - assert(mm->n >= 0); + if (i < 0) unreachable; + if (i > mm->i) unreachable; + if (mm->n < 0) unreachable; if (UNLIKELY(mm->i == mm->n) && !ExtendMemoryIntervals(mm)) return enomem(); MoveMemoryIntervals(mm->p + i + 1, mm->p + i, mm->i++ - i); return 0; @@ -126,12 +129,9 @@ static int PunchHole(struct MemoryIntervals *mm, int x, int y, int i) { int ReleaseMemoryIntervals(struct MemoryIntervals *mm, int x, int y, void wf(struct MemoryIntervals *, int, int)) { unsigned l, r; -#if IsModeDbg() - assert(y >= x); - assert(AreMemoryIntervalsOk(mm)); -#endif + ASSERT_MEMTRACK(); + if (y < x) unreachable; if (!mm->i) return 0; - // binary search for the lefthand side l = FindMemoryInterval(mm, x); if (l == mm->i) return 0; @@ -140,8 +140,8 @@ int ReleaseMemoryIntervals(struct MemoryIntervals *mm, int x, int y, // binary search for the righthand side r = FindMemoryInterval(mm, y); if (r == mm->i || (r > l && y < mm->p[r].x)) --r; - assert(r >= l); - assert(x <= mm->p[r].y); + if (r < l) unreachable; + if (x > mm->p[r].y) unreachable; // remove the middle of an existing map // @@ -162,11 +162,11 @@ int ReleaseMemoryIntervals(struct MemoryIntervals *mm, int x, int y, // ----|mmmm|----------------- after // if (x > mm->p[l].x && x <= mm->p[l].y) { - assert(y >= mm->p[l].y); + if (y < mm->p[l].y) unreachable; if (IsWindows()) return einval(); mm->p[l].size -= (size_t)(mm->p[l].y - (x - 1)) * FRAMESIZE; mm->p[l].y = x - 1; - assert(mm->p[l].x <= mm->p[l].y); + if (mm->p[l].x > mm->p[l].y) unreachable; ++l; } @@ -177,11 +177,11 @@ int ReleaseMemoryIntervals(struct MemoryIntervals *mm, int x, int y, // ---------------|mm|-------- after // if (y >= mm->p[r].x && y < mm->p[r].y) { - assert(x <= mm->p[r].x); + if (x > mm->p[r].x) unreachable; if (IsWindows()) return einval(); mm->p[r].size -= (size_t)((y + 1) - mm->p[r].x) * FRAMESIZE; mm->p[r].x = y + 1; - assert(mm->p[r].x <= mm->p[r].y); + if (mm->p[r].x > mm->p[r].y) unreachable; --r; } @@ -197,16 +197,9 @@ int ReleaseMemoryIntervals(struct MemoryIntervals *mm, int x, int y, int TrackMemoryInterval(struct MemoryIntervals *mm, int x, int y, long h, int prot, int flags, bool readonlyfile, bool iscow, long offset, long size) { - // asan runtime depends on this function unsigned i; -#if IsModeDbg() - assert(y >= x); - if (!AreMemoryIntervalsOk(mm)) { - PrintMemoryIntervals(2, mm); - } - assert(AreMemoryIntervalsOk(mm)); -#endif - + ASSERT_MEMTRACK(); + if (y < x) unreachable; i = FindMemoryInterval(mm, x); // try to extend the righthand side of the lefthand entry @@ -249,5 +242,6 @@ int TrackMemoryInterval(struct MemoryIntervals *mm, int x, int y, long h, mm->p[i].iscow = iscow; mm->p[i].readonlyfile = readonlyfile; } + return 0; } diff --git a/libc/intrin/printmemoryintervals.c b/libc/intrin/printmemoryintervals.c index 49f5912a0..6dc1caac7 100644 --- a/libc/intrin/printmemoryintervals.c +++ b/libc/intrin/printmemoryintervals.c @@ -16,6 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/fmt/conv.h" #include "libc/fmt/itoa.h" #include "libc/intrin/describeflags.internal.h" #include "libc/intrin/kprintf.h" @@ -34,28 +35,26 @@ static bool IsNoteworthyHole(unsigned i, const struct MemoryIntervals *mm) { } void PrintMemoryIntervals(int fd, const struct MemoryIntervals *mm) { - char *p, mappingbuf[8], framebuf[32]; - long i, w, frames, maptally = 0, gaptally = 0; + char *p, mappingbuf[8], framebuf[64], sb[16]; + long i, w, frames, maptally = 0; for (w = i = 0; i < mm->i; ++i) { w = MAX(w, LengthInt64Thousands(mm->p[i].y + 1 - mm->p[i].x)); } for (i = 0; i < mm->i; ++i) { frames = mm->p[i].y + 1 - mm->p[i].x; maptally += frames; - kprintf("%08x-%08x %s %'*ldx%s", mm->p[i].x, mm->p[i].y, + kprintf("%08x-%08x %s %'*ldx %s", mm->p[i].x, mm->p[i].y, (DescribeMapping)(mappingbuf, mm->p[i].prot, mm->p[i].flags), w, frames, (DescribeFrame)(framebuf, mm->p[i].x)); if (mm->p[i].iscow) kprintf(" cow"); if (mm->p[i].readonlyfile) kprintf(" readonlyfile"); - if (mm->p[i].size != - (size_t)(mm->p[i].y - mm->p[i].x) * FRAMESIZE + FRAMESIZE) { - kprintf(" size=%'zu", mm->p[i].size); - } + sizefmt(sb, mm->p[i].size, 1024); + kprintf(" %sB", sb); if (i + 1 < mm->i) { frames = mm->p[i + 1].x - mm->p[i].y - 1; if (frames && IsNoteworthyHole(i, mm)) { - gaptally += frames; - kprintf(" w/ %'ld frame hole", frames); + sizefmt(sb, frames * FRAMESIZE, 1024); + kprintf(" w/ %sB hole", sb); } } if (mm->p[i].h != -1) { @@ -63,5 +62,6 @@ void PrintMemoryIntervals(int fd, const struct MemoryIntervals *mm) { } kprintf("\n"); } - kprintf("# %ld frames mapped w/ %'ld frames gapped\n", maptally, gaptally); + sizefmt(sb, maptally * FRAMESIZE, 1024); + kprintf("# %sB total mapped memory\n", sb); } diff --git a/libc/inttypes.h b/libc/inttypes.h index e996192bc..7c8e341d8 100644 --- a/libc/inttypes.h +++ b/libc/inttypes.h @@ -10,6 +10,15 @@ typedef __UINT_LEAST32_TYPE__ uint_least32_t; typedef __INT_LEAST64_TYPE__ int_least64_t; typedef __UINT_LEAST64_TYPE__ uint_least64_t; +typedef __INT_FAST8_TYPE__ int_fast8_t; +typedef __UINT_FAST8_TYPE__ uint_fast8_t; +typedef __INT_FAST16_TYPE__ int_fast16_t; +typedef __UINT_FAST16_TYPE__ uint_fast16_t; +typedef __INT_FAST32_TYPE__ int_fast32_t; +typedef __UINT_FAST32_TYPE__ uint_fast32_t; +typedef __INT_FAST64_TYPE__ int_fast64_t; +typedef __UINT_FAST64_TYPE__ uint_fast64_t; + /*───────────────────────────────────────────────────────────────────────────│─╗ │ cosmopolitan § dismal format notation ─╬─│┼ ╚────────────────────────────────────────────────────────────────────────────│*/ diff --git a/libc/limits.h b/libc/limits.h index 732da64b2..ea4d9da32 100644 --- a/libc/limits.h +++ b/libc/limits.h @@ -36,7 +36,6 @@ #define INTMAX_MAX __INTMAX_MAX__ #define UINTMAX_MAX __UINTMAX_MAX__ -extern int __got_long_min; #define SCHAR_MIN (-SCHAR_MAX - 1) #define SHRT_MIN (-SHRT_MAX - 1) #define INT_MIN (-INT_MAX - 1) @@ -108,4 +107,22 @@ extern int __got_long_min; #define NL_SETMAX 255 #define NL_TEXTMAX 2048 +#define UINT_FAST64_MAX __UINT_FAST64_MAX__ +#define UINT_FAST8_MAX __UINT_FAST8_MAX__ +#define INT_FAST32_MAX __INT_FAST32_MAX__ +#define INT_FAST16_MAX __INT_FAST16_MAX__ +#define UINT_FAST32_MAX __UINT_FAST32_MAX__ +#define INT_FAST8_MAX __INT_FAST8_MAX__ +#define INT_FAST64_MAX __INT_FAST64_MAX__ +#define UINT_FAST16_MAX __UINT_FAST16_MAX__ + +#define UINT_FAST64_MIN (-UINT_FAST64_MAX - 1) +#define UINT_FAST8_MIN (-UINT_FAST8_MAX - 1) +#define INT_FAST32_MIN (-INT_FAST32_MAX - 1) +#define INT_FAST16_MIN (-INT_FAST16_MAX - 1) +#define UINT_FAST32_MIN (-UINT_FAST32_MAX - 1) +#define INT_FAST8_MIN (-INT_FAST8_MAX - 1) +#define INT_FAST64_MIN (-INT_FAST64_MAX - 1) +#define UINT_FAST16_MIN (-UINT_FAST16_MAX - 1) + #endif /* COSMOPOLITAN_LIBC_LIMITS_H_ */ diff --git a/libc/log/backtrace.internal.h b/libc/log/backtrace.internal.h index 04ea90d5b..872b423e4 100644 --- a/libc/log/backtrace.internal.h +++ b/libc/log/backtrace.internal.h @@ -10,7 +10,6 @@ forceinline pureconst bool IsValidStackFramePointer(struct StackFrame *x) { /* assumes __mmi_lock() is held */ return IsLegalPointer(x) && !((uintptr_t)x & 15) && (IsStaticStackFrame((uintptr_t)x >> 16) || - IsSigAltStackFrame((uintptr_t)x >> 16) || IsOldStackFrame((uintptr_t)x >> 16) || /* lua coroutines need this */ IsMemtracked((uintptr_t)x >> 16, (uintptr_t)x >> 16)); diff --git a/libc/mem/arena.c b/libc/mem/arena.c index 2b69ff080..198c09014 100644 --- a/libc/mem/arena.c +++ b/libc/mem/arena.c @@ -17,10 +17,10 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" -#include "libc/intrin/likely.h" -#include "libc/intrin/weaken.h" #include "libc/calls/calls.h" #include "libc/dce.h" +#include "libc/intrin/likely.h" +#include "libc/intrin/weaken.h" #include "libc/limits.h" #include "libc/log/log.h" #include "libc/macros.internal.h" @@ -35,8 +35,8 @@ #include "libc/sysv/consts/prot.h" #include "libc/sysv/errfuns.h" -#define BASE 0x50000000 -#define SIZE 0x2ffe0000 +#define BASE 0x50040000 +#define SIZE 0x2ff80000 #define P(i) ((void *)(intptr_t)(i)) #define EXCHANGE(HOOK, SLOT) \ __arena_hook((intptr_t *)weaken(HOOK), (intptr_t *)(&(SLOT))) diff --git a/libc/mem/pvalloc.c b/libc/mem/pvalloc.c index 2fb40aea2..bb82626d4 100644 --- a/libc/mem/pvalloc.c +++ b/libc/mem/pvalloc.c @@ -20,7 +20,10 @@ #include "libc/mem/mem.h" /** - * Equivalent to memalign(PAGESIZE, ROUNDUP(n, PAGESIZE)). + * Allocates granular aligned memory of granular size, i.e. + * + * memalign(sysconf(_SC_PAGESIZE), + * ROUNDUP(n, sysconf(_SC_PAGESIZE))); * * @param n number of bytes needed * @return memory address, or NULL w/ errno @@ -28,5 +31,5 @@ * @threadsafe */ void *pvalloc(size_t n) { - return memalign(PAGESIZE, ROUNDUP(n, PAGESIZE)); + return memalign(FRAMESIZE, ROUNDUP(n, FRAMESIZE)); } diff --git a/libc/mem/valloc.c b/libc/mem/valloc.c index 3f8e0fc77..401b6f489 100644 --- a/libc/mem/valloc.c +++ b/libc/mem/valloc.c @@ -19,7 +19,9 @@ #include "libc/mem/mem.h" /** - * Equivalent to memalign(PAGESIZE, n). + * Allocates granular aligned memory, i.e. + * + * memalign(sysconf(_SC_PAGESIZE), n); * * @param n number of bytes needed * @return memory address, or NULL w/ errno @@ -27,5 +29,5 @@ * @threadsafe */ void *valloc(size_t n) { - return memalign(PAGESIZE, n); + return memalign(FRAMESIZE, n); } diff --git a/libc/nt/version.h b/libc/nt/version.h index 106cc54eb..6c4612ef0 100644 --- a/libc/nt/version.h +++ b/libc/nt/version.h @@ -7,7 +7,7 @@ COSMOPOLITAN_C_START_ bool IsAtLeastWindows10(void) pureconst; bool32 GetVersionEx(struct NtOsVersionInfo *lpVersionInformation); -#if defined(__GCC_ASM_FLAG_OUTPUTS__) && !defined(__STRICT_ANSI__) +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) #define IsAtLeastWindows10() (GetNtMajorVersion() >= 10) #define GetNtMajorVersion() \ ({ \ diff --git a/libc/runtime/brk.c b/libc/runtime/brk.c index 481ae5b86..452a7a149 100644 --- a/libc/runtime/brk.c +++ b/libc/runtime/brk.c @@ -31,8 +31,8 @@ uintptr_t __break; * * This can be used to allocate and deallocate memory. It won't * conflict with malloc() and mmap(NULL, ...) allocations since - * APE binaries load the image at 0x400000 and does allocations - * starting at 0x100080000000. You should consult _end, or call + * APE binaries load the image at 0x440000 and does allocations + * starting at 0x100080040000. You should consult _end, or call * sbrk(NULL), to figure out where the existing break is first. * * @return 0 on success or -1 w/ errno diff --git a/libc/runtime/memtrack.internal.h b/libc/runtime/memtrack.internal.h index ff2488f0a..69a57f96a 100644 --- a/libc/runtime/memtrack.internal.h +++ b/libc/runtime/memtrack.internal.h @@ -1,42 +1,30 @@ #ifndef COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_ #define COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_ #include "libc/assert.h" -#include "libc/intrin/midpoint.h" #include "libc/dce.h" +#include "libc/intrin/midpoint.h" #include "libc/intrin/nopl.internal.h" #include "libc/macros.internal.h" -#include "libc/thread/tls.h" #include "libc/nt/version.h" #include "libc/runtime/stack.h" #include "libc/sysv/consts/ss.h" +#include "libc/thread/tls.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -#define kAutomapStart _kMem(0x100080000000, 0x000010000000) -#define kAutomapSize \ - _kMem(0x200000000000 - 0x100080000000 - _kMmi(0x800000000000), \ - 0x000040000000 - 0x000010000000 - _kMmi(0x000080000000)) -#define kMemtrackStart \ - (ROUNDDOWN(_kMem(0x200000000000 - _kMmi(0x800000000000), \ - 0x000040000000 - _kMmi(0x000080000000)), \ - FRAMESIZE * 8) - \ - 0x8000 * 8 /* so frame aligned after adding 0x7fff8000 */) -#define kMemtrackSize _kMem(_kMmi(0x800000000000), _kMmi(0x000080000000)) -#define kMemtrackGran (!IsAsan() ? FRAMESIZE : FRAMESIZE * 8) -#define kFixedmapStart _kMem(0x300000000000, 0x000040000000) -#define kFixedmapSize \ - _kMem(0x400000000000 - 0x300000000000, 0x000070000000 - 0x000040000000) -#define kMemtrackFdsStart \ - (ROUNDDOWN(_kMem(0x6fe000000000, 0x68000000), FRAMESIZE * 8) - 0x8000 * 8) -#define kMemtrackFdsSize _kMem(0x001000000000, 0x04000000) -#define kMemtrackZiposStart \ - (ROUNDDOWN(_kMem(0x6fd000000000, 0x6c000000), FRAMESIZE * 8) - 0x8000 * 8) -#define kMemtrackZiposSize _kMem(0x001000000000, 0x10000000) -#define _kMmi(VSPACE) \ - ROUNDUP(VSPACE / FRAMESIZE * (intptr_t)sizeof(struct MemoryInterval), \ - FRAMESIZE) -#define _kMem(NORMAL, WIN7) \ - (!IsWindows() || IsAtLeastWindows10() ? NORMAL : WIN7) +#define kAutomapStart 0x100080040000 +#define kAutomapSize (kMemtrackStart - kAutomapStart) +#define kMemtrackStart 0x1fe7fffc0000 +#define kMemtrackSize (0x1ffffffc0000 - kMemtrackStart) +#define kFixedmapStart 0x300000040000 +#define kFixedmapSize (0x400000040000 - kFixedmapStart) +#define kMemtrackFdsStart 0x6fe000040000 +#define kMemtrackFdsSize (0x6feffffc0000 - kMemtrackFdsStart) +#define kMemtrackZiposStart 0x6fd000040000 +#define kMemtrackZiposSize (0x6fdffffc0000 - kMemtrackZiposStart) +#define kMemtrackNsyncStart 0x6fc000040000 +#define kMemtrackNsyncSize (0x6fcffffc0000 - kMemtrackNsyncStart) +#define kMemtrackGran (!IsAsan() ? FRAMESIZE : FRAMESIZE * 8) struct MemoryInterval { int x; @@ -88,23 +76,38 @@ forceinline pureconst bool IsLegalSize(size_t n) { } forceinline pureconst bool IsAutoFrame(int x) { - return (kAutomapStart >> 16) <= x && - x <= ((kAutomapStart + (kAutomapSize - 1)) >> 16); + return (int)(kAutomapStart >> 16) <= x && + x <= (int)((kAutomapStart + kAutomapSize - 1) >> 16); } forceinline pureconst bool IsMemtrackFrame(int x) { - return (kAutomapStart >> 16) <= x && - x <= ((kAutomapStart + (kAutomapSize - 1)) >> 16); + return (int)(kAutomapStart >> 16) <= x && + x <= (int)((kAutomapStart + kAutomapSize - 1) >> 16); } -forceinline pureconst bool IsArenaFrame(int x) { - return 0x5000 <= x && x < 0x7ffe; +forceinline pureconst bool IsGfdsFrame(int x) { + return (int)(kMemtrackFdsStart >> 16) <= x && + x <= (int)((kMemtrackFdsStart + kMemtrackFdsSize - 1) >> 16); +} + +forceinline pureconst bool IsZiposFrame(int x) { + return (int)(kMemtrackZiposStart >> 16) <= x && + x <= (int)((kMemtrackZiposStart + kMemtrackZiposSize - 1) >> 16); +} + +forceinline pureconst bool IsNsyncFrame(int x) { + return (int)(kMemtrackNsyncStart >> 16) <= x && + x <= (int)((kMemtrackNsyncStart + kMemtrackNsyncSize - 1) >> 16); } forceinline pureconst bool IsShadowFrame(int x) { return 0x7fff <= x && x < 0x10008000; } +forceinline pureconst bool IsArenaFrame(int x) { + return 0x5004 <= x && x <= 0x7ffb; +} + forceinline pureconst bool IsKernelFrame(int x) { intptr_t stack = GetStaticStackAddr(0); return (int)(stack >> 16) <= x && @@ -123,15 +126,12 @@ forceinline pureconst bool IsStackFrame(int x) { x <= (int)((stack + (GetStackSize() - FRAMESIZE)) >> 16); } -forceinline pureconst bool IsSigAltStackFrame(int x) { - intptr_t stack = GetStackAddr(); - return (int)(stack >> 16) <= x && - x <= (int)((stack + (SIGSTKSZ - FRAMESIZE)) >> 16); -} - forceinline pureconst bool IsOldStackFrame(int x) { - intptr_t old = ROUNDDOWN(__oldstack, STACKSIZE); - return (old >> 16) <= x && x <= ((old + (STACKSIZE - FRAMESIZE)) >> 16); + /* openbsd uses 4mb stack by default */ + /* freebsd uses 512mb stack by default */ + /* most systems use 8mb stack by default */ + intptr_t old = ROUNDDOWN(__oldstack, GetStackSize()); + return (old >> 16) <= x && x <= ((old + (GetStackSize() - FRAMESIZE)) >> 16); } forceinline pureconst bool IsFixedFrame(int x) { diff --git a/libc/runtime/memtrack64.txt b/libc/runtime/memtrack64.txt index a16347005..9221a41f5 100644 --- a/libc/runtime/memtrack64.txt +++ b/libc/runtime/memtrack64.txt @@ -3,8 +3,8 @@ 00000000-0000001f 2048kb null 00000020-0000003f 2048kb loader -00000040-00004fff 1276mb image -00005000-00007ffd 768mb arena +00000040-00004ffb 1276mb image +00005004-00007ffb 768mb arena 00007ffe-00007ffe 64kb free # address sanitizer shadow memory @@ -264,10 +264,10 @@ 0fd00000-0fdfffff 64gb asan 0fe00000-0fefffff 64gb asan 0ff00000-0fffffff 64gb asan -10000000-10007fff 2048mb asan +10000000-10008003 2048mb asan # memory dedicated to mmap(NULL, ...) automation, e.g. malloc() -10008000-100fffff 62gb automap +10008004-100fffff 62gb automap 10100000-101fffff 64gb automap 10200000-102fffff 64gb automap 10300000-103fffff 64gb automap @@ -521,13 +521,13 @@ 1fb00000-1fbfffff 64gb automap 1fc00000-1fcfffff 64gb automap 1fd00000-1fdfffff 64gb automap -1fe00000-1fe7ffff 32gb automap +1fe00000-1fe7fffb 32gb automap 1fe7fffc-1fefffff 32gb _mmi 1ff00000-1ffffffb 64gb _mmi -1ffffffc-1fffffff 256kb free +1ffffffc-20000003 256kb free -20000000-200fffff 64gb free +20000004-200fffff 64gb free 20100000-201fffff 64gb free 20200000-202fffff 64gb free 20300000-203fffff 64gb free @@ -782,10 +782,10 @@ 2fc00000-2fcfffff 64gb free 2fd00000-2fdfffff 64gb free 2fe00000-2fefffff 64gb free -2ff00000-2fffffff 64gb free +2ff00000-30000003 64gb free # memory recommended for application MAP_FIXED usage -30000000-300fffff 64gb fixedmap +30000004-300fffff 64gb fixedmap 30100000-301fffff 64gb fixedmap 30200000-302fffff 64gb fixedmap 30300000-303fffff 64gb fixedmap @@ -1040,9 +1040,9 @@ 3fc00000-3fcfffff 64gb fixedmap 3fd00000-3fdfffff 64gb fixedmap 3fe00000-3fefffff 64gb fixedmap -3ff00000-3fffffff 64gb fixedmap +3ff00000-40000003 64gb fixedmap -40000000-400fffff 64gb free +40000004-400fffff 64gb free 40100000-401fffff 64gb free 40200000-402fffff 64gb free 40300000-403fffff 64gb free @@ -1808,14 +1808,14 @@ 6f900000-6f9fffff 64gb free 6fa00000-6fafffff 64gb free 6fb00000-6fbfffff 64gb free -6fc00004-6fcfffff 64gb nsync -6fd00000-6fdfffff 64gb zipos -6fe00004-6feffffc 64gb g_fds -6ff00000-6ffffffd 64gb free -6ffffffe-6fffffff 128kb winargs +6fc00004-6fcffffb 64gb nsync +6fd00004-6fdffffb 64gb zipos +6fe00004-6feffffb 64gb g_fds +6ff00004-70000003 64gb free -70000000-70000001 128kb stack -70000002-700fffff 64gb free +70000004-70000004 64kb stack +70000005-70000006 128kb winargs +70000005-700fffff 64gb free 70100000-701fffff 64gb free 70200000-702fffff 64gb free 70300000-703fffff 64gb free diff --git a/libc/runtime/stack.h b/libc/runtime/stack.h index 9e438984e..a748ceedb 100644 --- a/libc/runtime/stack.h +++ b/libc/runtime/stack.h @@ -107,18 +107,14 @@ extern char ape_stack_align[] __attribute__((__weak__)); * problematic, since MODE=tiny doesn't use any of the runtime codes * which want the stack to be cheaply knowable, e.g. ftrace, kprintf */ -#define GetStaticStackAddr(ADDEND) \ - ({ \ - intptr_t vAddr; \ - if (!IsWindows() || IsAtLeastWindows10()) { \ - __asm__(".weak\tape_stack_vaddr\n\t" \ - "movabs\t%1+ape_stack_vaddr,%0" \ - : "=r"(vAddr) \ - : "i"(ADDEND)); \ - } else { \ - vAddr = 0x100000000 - GetStackSize(); \ - } \ - vAddr; \ +#define GetStaticStackAddr(ADDEND) \ + ({ \ + intptr_t vAddr; \ + __asm__(".weak\tape_stack_vaddr\n\t" \ + "movabs\t%1+ape_stack_vaddr,%0" \ + : "=r"(vAddr) \ + : "i"(ADDEND)); \ + vAddr; \ }) /** diff --git a/libc/runtime/winmain.greg.c b/libc/runtime/winmain.greg.c index ae5f027a1..c28db3ec4 100644 --- a/libc/runtime/winmain.greg.c +++ b/libc/runtime/winmain.greg.c @@ -166,8 +166,8 @@ __msabi static textwindows wontreturn void WinMainNew(const char16_t *cmdline) { char outflagsbuf[128]; const char16_t *env16; int i, prot, count, version; + size_t allocsize, stacksize; intptr_t stackaddr, allocaddr; - size_t allocsize, argsize, stacksize; version = NtGetPeb()->OSMajorVersion; __oldstack = (intptr_t)__builtin_frame_address(0); if ((intptr_t)v_ntsubsystem == kNtImageSubsystemWindowsCui && version >= 10) { @@ -190,15 +190,14 @@ __msabi static textwindows wontreturn void WinMainNew(const char16_t *cmdline) { rc); } } + _Static_assert(sizeof(struct WinArgs) % FRAMESIZE == 0, ""); _mmi.p = _mmi.s; _mmi.n = ARRAYLEN(_mmi.s); - argsize = ROUNDUP(sizeof(struct WinArgs), FRAMESIZE); stackaddr = GetStaticStackAddr(0); stacksize = GetStackSize(); - allocsize = argsize + stacksize; - allocaddr = stackaddr - argsize; - NTTRACE("WinMainNew() mapping %'zu byte arg block + stack at %p", allocsize, - allocaddr); + allocaddr = stackaddr; + allocsize = stacksize + sizeof(struct WinArgs); + NTTRACE("WinMainNew() mapping %'zu byte stack at %p", allocsize, allocaddr); MapViewOfFileEx( (_mmi.p[0].h = CreateFileMapping(-1, &kNtIsInheritable, kNtPageExecuteReadwrite, @@ -209,12 +208,12 @@ __msabi static textwindows wontreturn void WinMainNew(const char16_t *cmdline) { VirtualProtect((void *)allocaddr, allocsize, kNtPageReadwrite, &oldprot); } _mmi.p[0].x = allocaddr >> 16; - _mmi.p[0].y = (allocaddr >> 16) + ((allocsize >> 16) - 1); + _mmi.p[0].y = (allocaddr >> 16) + ((allocsize - 1) >> 16); _mmi.p[0].prot = prot; _mmi.p[0].flags = 0x00000026; // stack+anonymous _mmi.p[0].size = allocsize; _mmi.i = 1; - wa = (struct WinArgs *)allocaddr; + wa = (struct WinArgs *)(allocaddr + stacksize); NTTRACE("WinMainNew() loading arg block"); count = GetDosArgv(cmdline, wa->argblock, ARRAYLEN(wa->argblock), wa->argv, ARRAYLEN(wa->argv)); diff --git a/test/libc/intrin/kprintf_test.c b/test/libc/intrin/kprintf_test.c index 1997bae6b..a0ae9e120 100644 --- a/test/libc/intrin/kprintf_test.c +++ b/test/libc/intrin/kprintf_test.c @@ -49,6 +49,10 @@ static uint64_t Rando(void) { return x; } +void SetUp(void) { + __print_maps(); +} + static const struct { const char *want; const char *fmt; diff --git a/test/libc/zipos/open_test.c b/test/libc/zipos/open_test.c index 28d97ab6e..9b1d5fad2 100644 --- a/test/libc/zipos/open_test.c +++ b/test/libc/zipos/open_test.c @@ -52,5 +52,5 @@ TEST(zipos, test) { 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(); */ + __print_maps(); } diff --git a/test/tool/build/pledge_test.sh b/test/tool/build/pledge_test.sh index 542cecc61..b895ee18f 100755 --- a/test/tool/build/pledge_test.sh +++ b/test/tool/build/pledge_test.sh @@ -10,6 +10,7 @@ if [ $# = 0 ]; then o//examples/life.com \ o//examples/hello.com \ o//examples/printargs.com \ + o//tool/build/assimilate.com \ o//tool/build/pledge.com || exit make -j16 MODE=$m \ o/$m/examples/ls.com \ @@ -17,6 +18,7 @@ if [ $# = 0 ]; then o/$m/examples/life.com \ o/$m/examples/hello.com \ o/$m/examples/printargs.com \ + o/$m/tool/build/assimilate.com \ o/$m/tool/build/pledge.com || exit test/tool/build/pledge_test.sh ape_binfmt_test_suite || exit test/tool/build/pledge_test.sh ape_loader_test_suite || exit diff --git a/third_party/nsync/atomic.h b/third_party/nsync/atomic.h index eeaae199a..d91f579c7 100644 --- a/third_party/nsync/atomic.h +++ b/third_party/nsync/atomic.h @@ -1,9 +1,10 @@ #ifndef NSYNC_ATOMIC_H_ #define NSYNC_ATOMIC_H_ +#include "libc/atomic.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -typedef uint32_t nsync_atomic_uint32_; +typedef atomic_uint_fast32_t nsync_atomic_uint32_; #define NSYNC_ATOMIC_UINT32_INIT_ 0 #define NSYNC_ATOMIC_UINT32_LOAD_(p) (*(p)) diff --git a/third_party/nsync/nsync.mk b/third_party/nsync/nsync.mk index 89e03a84a..4402fa12d 100644 --- a/third_party/nsync/nsync.mk +++ b/third_party/nsync/nsync.mk @@ -55,4 +55,3 @@ $(THIRD_PARTY_NSYNC_OBJS): third_party/nsync/nsync.mk .PHONY: o/$(MODE)/third_party/nsync o/$(MODE)/third_party/nsync: $(THIRD_PARTY_NSYNC_CHECKS) - diff --git a/third_party/zip/zipup.c b/third_party/zip/zipup.c index aa87e1381..f40fbd974 100644 --- a/third_party/zip/zipup.c +++ b/third_party/zip/zipup.c @@ -27,6 +27,8 @@ #include "libc/sysv/consts/prot.h" #include "libc/fmt/fmt.h" #include "libc/stdio/stdio.h" +#include "libc/runtime/sysconf.h" +#include "libc/runtime/sysconf.h" #include "libc/runtime/runtime.h" #ifndef UTIL /* This module contains no code for Zip Utilities */ @@ -537,17 +539,17 @@ struct zlist far *z; /* zip entry to compress */ if (window != NULL) free(window); /* window can't be a mapped file here */ window_size = (ulg)q + MIN_LOOKAHEAD; - remain = window_size & (FRAMESIZE-1); + remain = window_size & (sysconf(_SC_PAGESIZE)-1); /* If we can't touch the page beyond the end of file, we must * allocate an extra page. */ if (remain > MIN_LOOKAHEAD) { window = (uch*)mmap(0, window_size, PROT_READ, MAP_PRIVATE, ifile, 0); } else { - window = (uch*)valloc(window_size - remain + FRAMESIZE); + window = (uch*)pvalloc(window_size - remain + sysconf(_SC_PAGESIZE)); if (window != NULL) { window = (uch*)mmap((char*)window, window_size - remain, PROT_READ, - MAP_PRIVATE | MAP_FIXED, ifile, 0); + MAP_PRIVATE | MAP_FIXED, ifile, 0); } else { window = (uch*)(-1); } diff --git a/third_party/zlib/deflate.c b/third_party/zlib/deflate.c index 03861d2e5..b57b25115 100644 --- a/third_party/zlib/deflate.c +++ b/third_party/zlib/deflate.c @@ -5,8 +5,9 @@ │ Use of this source code is governed by the BSD-style licenses that can │ │ be found in the third_party/zlib/LICENSE file. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/intrin/bits.h" #include "libc/dce.h" +#include "libc/intrin/bits.h" +#include "libc/intrin/kprintf.h" #include "libc/macros.internal.h" #include "libc/mem/mem.h" #include "libc/nexgen32e/x86feature.h" @@ -119,7 +120,7 @@ Invented 1990 Phillip Walter Katz\""); (uint64_t)((long)s->strstart - s->block_start), (last)); \ s->block_start = s->strstart; \ flush_pending(s->strm); \ - Tracev((stderr, "[FLUSH]")); \ + Tracev(("[FLUSH]")); \ } /** @@ -1275,9 +1276,17 @@ static uInt longest_match(struct DeflateState *s, IPos cur_match) { * are always equal when the other bytes match, given that * the hash keys are equal and that HASH_BITS >= 8. */ - Assert(*scan == *match || scan[1] != match[1], "match[2]??"); scan += 2, match++; - Assert(*scan == *match, "match[2]?"); + if (1 /* !s->chromium_zlib_hash */) { + Assert(*scan == *match, "match[2]?"); + } else { + /* When using CRC hashing, scan[2] and match[2] may mismatch, but in + * that case at least one of the other hashed bytes will mismatch + * also. Bytes 0 and 1 were already checked above, and we know there + * are at least four bytes to check otherwise the mismatch would have + * been found by the scan_end comparison above, so: */ + Assert(*scan == *match || scan[1] != match[1], "match[2]??"); + } /* We check for insufficient lookahead only every 8th comparison; * the 256th check will be made at strstart+258. */ @@ -1362,17 +1371,17 @@ static uInt longest_match(struct DeflateState *s, IPos cur_match) { static void check_match(struct DeflateState *s, IPos start, IPos match, int length) { /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", start, match, length); + if (memcmp(s->window + match, s->window + start, length) != EQUAL) { + kprintf(" start %u, match %u, length %d\n", start, match, length); do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + kprintf("%c%c", s->window[match++], s->window[start++]); } while (--length != 0); - z_error("invalid match"); + z_error(__FILE__, __LINE__, "invalid match"); } if (z_verbose > 1) { - fprintf(stderr, "\\[%d,%d]", start - match, length); + kprintf("\\[%d,%d]", start - match, length); do { - putc(s->window[start++], stderr); + kprintf("%c", s->window[start++]); } while (--length != 0); } } @@ -1640,7 +1649,7 @@ static block_state deflate_fast(struct DeflateState *s, int flush) { } } else { /* No match, output a literal byte */ - Tracevv((stderr, "%c", s->window[s->strstart])); + Tracevv(("%c", s->window[s->strstart])); _tr_tally_lit(s, s->window[s->strstart], bflush); s->lookahead--; s->strstart++; @@ -1755,7 +1764,7 @@ static block_state deflate_slow(struct DeflateState *s, int flush) { * single literal. If there was a match but the current match * is longer, truncate the previous match to a single literal. */ - Tracevv((stderr, "%c", s->window[s->strstart - 1])); + Tracevv(("%c", s->window[s->strstart - 1])); _tr_tally_lit(s, s->window[s->strstart - 1], bflush); if (bflush) { FLUSH_BLOCK_ONLY(s, 0); @@ -1774,7 +1783,7 @@ static block_state deflate_slow(struct DeflateState *s, int flush) { } Assert(flush != Z_NO_FLUSH, "no flush?"); if (s->match_available) { - Tracevv((stderr, "%c", s->window[s->strstart - 1])); + Tracevv(("%c", s->window[s->strstart - 1])); _tr_tally_lit(s, s->window[s->strstart - 1], bflush); s->match_available = 0; } @@ -1839,7 +1848,7 @@ static block_state deflate_rle(struct DeflateState *s, int flush) { s->match_length = 0; } else { /* No match, output a literal byte */ - Tracevv((stderr, "%c", s->window[s->strstart])); + Tracevv(("%c", s->window[s->strstart])); _tr_tally_lit(s, s->window[s->strstart], bflush); s->lookahead--; s->strstart++; @@ -1873,7 +1882,7 @@ static block_state deflate_huff(struct DeflateState *s, int flush) { } /* Output a literal byte */ s->match_length = 0; - Tracevv((stderr, "%c", s->window[s->strstart])); + Tracevv(("%c", s->window[s->strstart])); _tr_tally_lit(s, s->window[s->strstart], bflush); s->lookahead--; s->strstart++; diff --git a/third_party/zlib/deflate.internal.h b/third_party/zlib/deflate.internal.h index 1b17ffd5d..df01e66b1 100644 --- a/third_party/zlib/deflate.internal.h +++ b/third_party/zlib/deflate.internal.h @@ -280,9 +280,6 @@ void _tr_stored_block(struct DeflateState *s, charf *buf, uint64_t stored_len, #define d_code(dist) \ ((dist) < 256 ? kZlibDistCode[dist] : kZlibDistCode[256 + ((dist) >> 7)]) -#ifndef ZLIB_DEBUG -/* Inline versions of _tr_tally for speed: */ - extern const ct_data kZlibStaticDtree[D_CODES] hidden; extern const ct_data kZlibStaticLtree[L_CODES + 2] hidden; extern const int kZlibBaseDist[D_CODES] hidden; @@ -290,6 +287,9 @@ extern const int kZlibBaseLength[LENGTH_CODES] hidden; extern const uint8_t kZlibDistCode[DIST_CODE_LEN] hidden; extern const uint8_t kZlibLengthCode[MAX_MATCH - MIN_MATCH + 1] hidden; +#ifndef ZLIB_DEBUG +/* Inline versions of _tr_tally for speed: */ + #define _tr_tally_lit(s, c, flush) \ { \ uint8_t cc = (c); \ diff --git a/third_party/zlib/infback.c b/third_party/zlib/infback.c index 34ffa8e58..0cbc5d37f 100644 --- a/third_party/zlib/infback.c +++ b/third_party/zlib/infback.c @@ -46,7 +46,7 @@ int inflateBackInit(z_streamp strm, int windowBits, unsigned char *window) { } state = (struct InflateState *)ZALLOC(strm, 1, sizeof(struct InflateState)); if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); + Tracev(("inflate: allocated\n")); strm->state = (struct DeflateState *)state; state->dmax = 32768U; state->wbits = (uInt)windowBits; @@ -54,6 +54,7 @@ int inflateBackInit(z_streamp strm, int windowBits, unsigned char *window) { state->window = window; state->wnext = 0; state->whave = 0; + state->sane = 0; return Z_OK; } @@ -97,7 +98,7 @@ static void fixedtables(struct InflateState *state) { } state->lencode = lenfix; state->distcode = distfix; -#else /* !BUILDFIXED */ +#else /* !BUILDFIXED */ state->lencode = kZlibLenfix; state->distcode = kZlibDistfix; #endif /* BUILDFIXED */ @@ -277,18 +278,18 @@ int inflateBack(z_streamp strm, in_func in, void *in_desc, out_func out, DROPBITS(1); switch (BITS(2)) { case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", + Tracev(("inflate: stored block%s\n", state->last ? " (last)" : "")); state->mode = STORED; break; case 1: /* fixed block */ fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", + Tracev(("inflate: fixed codes block%s\n", state->last ? " (last)" : "")); state->mode = LEN; /* decode codes */ break; case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", + Tracev(("inflate: dynamic codes block%s\n", state->last ? " (last)" : "")); state->mode = TABLE; break; @@ -309,7 +310,7 @@ int inflateBack(z_streamp strm, in_func in, void *in_desc, out_func out, break; } state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", state->length)); + Tracev(("inflate: stored length %u\n", state->length)); INITBITS(); /* copy stored block from input to output */ @@ -326,7 +327,7 @@ int inflateBack(z_streamp strm, in_func in, void *in_desc, out_func out, put += copy; state->length -= copy; } - Tracev((stderr, "inflate: stored end\n")); + Tracev(("inflate: stored end\n")); state->mode = TYPE; break; @@ -346,7 +347,7 @@ int inflateBack(z_streamp strm, in_func in, void *in_desc, out_func out, break; } #endif - Tracev((stderr, "inflate: table sizes ok\n")); + Tracev(("inflate: table sizes ok\n")); /* get code length code lengths (not a typo) */ state->have = 0; @@ -366,7 +367,7 @@ int inflateBack(z_streamp strm, in_func in, void *in_desc, out_func out, state->mode = BAD; break; } - Tracev((stderr, "inflate: code lengths ok\n")); + Tracev(("inflate: code lengths ok\n")); /* get length and distance code code lengths */ state->have = 0; @@ -445,7 +446,7 @@ int inflateBack(z_streamp strm, in_func in, void *in_desc, out_func out, state->mode = BAD; break; } - Tracev((stderr, "inflate: codes ok\n")); + Tracev(("inflate: codes ok\n")); state->mode = LEN; case LEN: @@ -479,8 +480,7 @@ int inflateBack(z_streamp strm, in_func in, void *in_desc, out_func out, /* process literal */ if (here.op == 0) { - Tracevv((stderr, - here.val >= 0x20 && here.val < 0x7f + Tracevv((here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", here.val)); @@ -493,7 +493,7 @@ int inflateBack(z_streamp strm, in_func in, void *in_desc, out_func out, /* process end of block */ if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); + Tracevv(("inflate: end of block\n")); state->mode = TYPE; break; } @@ -512,7 +512,7 @@ int inflateBack(z_streamp strm, in_func in, void *in_desc, out_func out, state->length += BITS(state->extra); DROPBITS(state->extra); } - Tracevv((stderr, "inflate: length %u\n", state->length)); + Tracevv(("inflate: length %u\n", state->length)); /* get distance code */ for (;;) { @@ -551,7 +551,7 @@ int inflateBack(z_streamp strm, in_func in, void *in_desc, out_func out, state->mode = BAD; break; } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); + Tracevv(("inflate: distance %u\n", state->offset)); /* copy match from window to output */ do { @@ -574,25 +574,27 @@ int inflateBack(z_streamp strm, in_func in, void *in_desc, out_func out, break; case DONE: - /* inflate stream terminated properly -- write leftover output */ + /* inflate stream terminated properly */ ret = Z_STREAM_END; - if (left < state->wsize) { - if (out(out_desc, state->window, state->wsize - left)) - ret = Z_BUF_ERROR; - } goto inf_leave; case BAD: ret = Z_DATA_ERROR; goto inf_leave; - default: /* can't happen, but makes compilers happy */ + default: + /* can't happen, but makes compilers happy */ ret = Z_STREAM_ERROR; goto inf_leave; } - /* Return unused input */ + /* Write leftover output and return unused input */ inf_leave: + if (left < state->wsize) { + if (out(out_desc, state->window, state->wsize - left) && + ret == Z_STREAM_END) + ret = Z_BUF_ERROR; + } strm->next_in = next; strm->avail_in = have; return ret; @@ -603,6 +605,6 @@ int inflateBackEnd(z_streamp strm) { return Z_STREAM_ERROR; ZFREE(strm, strm->state); strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); + Tracev(("inflate: end\n")); return Z_OK; } diff --git a/third_party/zlib/inffast.c b/third_party/zlib/inffast.c index 177a39a0b..896f64f19 100644 --- a/third_party/zlib/inffast.c +++ b/third_party/zlib/inffast.c @@ -122,8 +122,7 @@ void inflate_fast(z_streamp strm, unsigned start) { bits -= op; op = (unsigned)(here.op); if (op == 0) { /* literal */ - Tracevv((stderr, - here.val >= 0x20 && here.val < 0x7f + Tracevv((here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", here.val)); @@ -140,7 +139,7 @@ void inflate_fast(z_streamp strm, unsigned start) { hold >>= op; bits -= op; } - Tracevv((stderr, "inflate: length %u\n", len)); + Tracevv(("inflate: length %u\n", len)); if (bits < 15) { hold += (unsigned long)(*in++) << bits; bits += 8; @@ -174,7 +173,7 @@ void inflate_fast(z_streamp strm, unsigned start) { #endif hold >>= op; bits -= op; - Tracevv((stderr, "inflate: distance %u\n", dist)); + Tracevv(("inflate: distance %u\n", dist)); op = (unsigned)(out - beg); /* max distance in output */ if (dist > op) { /* see if copy from window */ op = dist - op; /* distance back in window */ @@ -277,7 +276,7 @@ void inflate_fast(z_streamp strm, unsigned start) { here = lcode[here.val + (hold & ((1U << op) - 1))]; goto dolen; } else if (op & 32) { /* end-of-block */ - Tracevv((stderr, "inflate: end of block\n")); + Tracevv(("inflate: end of block\n")); state->mode = TYPE; break; } else { diff --git a/third_party/zlib/inffastchunk.c b/third_party/zlib/inffastchunk.c index 89a79bd34..33f66bc52 100644 --- a/third_party/zlib/inffastchunk.c +++ b/third_party/zlib/inffastchunk.c @@ -147,8 +147,7 @@ void inflate_fast_chunk(z_streamp strm, unsigned start) { bits -= op; op = (unsigned)(here.op); if (op == 0) { /* literal */ - Tracevv((stderr, - here.val >= 0x20 && here.val < 0x7f + Tracevv((here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", here.val)); @@ -166,7 +165,7 @@ void inflate_fast_chunk(z_streamp strm, unsigned start) { hold >>= op; bits -= op; } - Tracevv((stderr, "inflate: length %u\n", len)); + Tracevv(("inflate: length %u\n", len)); if (bits < 15) { hold |= READ64LE(in) << bits; in += 6; @@ -196,7 +195,7 @@ void inflate_fast_chunk(z_streamp strm, unsigned start) { #endif hold >>= op; bits -= op; - Tracevv((stderr, "inflate: distance %u\n", dist)); + Tracevv(("inflate: distance %u\n", dist)); op = (unsigned)(out - beg); /* max distance in output */ if (dist > op) { /* see if copy from window */ op = dist - op; /* distance back in window */ @@ -283,7 +282,7 @@ void inflate_fast_chunk(z_streamp strm, unsigned start) { here = lcode[here.val + (hold & ((1U << op) - 1))]; goto dolen; } else if (op & 32) { /* end-of-block */ - Tracevv((stderr, "inflate: end of block\n")); + Tracevv(("inflate: end of block\n")); state->mode = TYPE; break; } else { diff --git a/third_party/zlib/inflate.c b/third_party/zlib/inflate.c index 884fa984b..4adac768f 100644 --- a/third_party/zlib/inflate.c +++ b/third_party/zlib/inflate.c @@ -147,7 +147,7 @@ int inflateResetKeep(z_streamp strm) { state->lencode = state->distcode = state->next = state->codes; state->sane = 1; state->back = -1; - Tracev((stderr, "inflate: reset\n")); + Tracev(("inflate: reset\n")); return Z_OK; } @@ -207,7 +207,7 @@ int inflateInit2(z_streamp strm, int windowBits) { } state = (struct InflateState *)ZALLOC(strm, 1, sizeof(struct InflateState)); if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); + Tracev(("inflate: allocated\n")); strm->state = (struct DeflateState *)state; state->strm = strm; state->window = Z_NULL; @@ -661,7 +661,7 @@ int inflate(z_streamp strm, int flush) { break; } state->dmax = 1U << len; - Tracev((stderr, "inflate: zlib header ok\n")); + Tracev(("inflate: zlib header ok\n")); strm->adler = state->check = adler32(0L, Z_NULL, 0); state->mode = hold & 0x200 ? DICTID : TYPE; INITBITS(); @@ -718,8 +718,9 @@ int inflate(z_streamp strm, int flush) { copy = state->length; if (copy > have) copy = have; if (copy) { - if (state->head != Z_NULL && state->head->extra != Z_NULL) { - len = state->head->extra_len - state->length; + if (state->head != Z_NULL && state->head->extra != Z_NULL && + (len = state->head->extra_len - state->length) < + state->head->extra_max) { memcpy(state->head->extra + len, next, len + copy > state->head->extra_max ? state->head->extra_max - len @@ -735,6 +736,7 @@ int inflate(z_streamp strm, int flush) { } state->length = 0; state->mode = NAME; + /* fallthrough */ case NAME: if (state->flags & 0x0800) { if (have == 0) goto inf_leave; @@ -815,13 +817,13 @@ int inflate(z_streamp strm, int flush) { DROPBITS(1); switch (BITS(2)) { case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", + Tracev(("inflate: stored block%s\n", state->last ? " (last)" : "")); state->mode = STORED; break; case 1: /* fixed block */ fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", + Tracev(("inflate: fixed codes block%s\n", state->last ? " (last)" : "")); state->mode = LEN_; /* decode codes */ if (flush == Z_TREES) { @@ -830,7 +832,7 @@ int inflate(z_streamp strm, int flush) { } break; case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", + Tracev(("inflate: dynamic codes block%s\n", state->last ? " (last)" : "")); state->mode = TABLE; break; @@ -849,7 +851,7 @@ int inflate(z_streamp strm, int flush) { break; } state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", state->length)); + Tracev(("inflate: stored length %u\n", state->length)); INITBITS(); state->mode = COPY_; if (flush == Z_TREES) goto inf_leave; @@ -869,7 +871,7 @@ int inflate(z_streamp strm, int flush) { state->length -= copy; break; } - Tracev((stderr, "inflate: stored end\n")); + Tracev(("inflate: stored end\n")); state->mode = TYPE; break; case TABLE: @@ -887,7 +889,7 @@ int inflate(z_streamp strm, int flush) { break; } #endif - Tracev((stderr, "inflate: table sizes ok\n")); + Tracev(("inflate: table sizes ok\n")); state->have = 0; state->mode = LENLENS; case LENLENS: @@ -910,7 +912,7 @@ int inflate(z_streamp strm, int flush) { state->mode = BAD; break; } - Tracev((stderr, "inflate: code lengths ok\n")); + Tracev(("inflate: code lengths ok\n")); state->have = 0; state->mode = CODELENS; case CODELENS: @@ -989,7 +991,7 @@ int inflate(z_streamp strm, int flush) { state->mode = BAD; break; } - Tracev((stderr, "inflate: codes ok\n")); + Tracev(("inflate: codes ok\n")); state->mode = LEN_; if (flush == Z_TREES) goto inf_leave; case LEN_: @@ -1023,8 +1025,7 @@ int inflate(z_streamp strm, int flush) { state->back += here.bits; state->length = (unsigned)here.val; if ((int)(here.op) == 0) { - Tracevv((stderr, - here.val >= 0x20 && here.val < 0x7f + Tracevv((here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", here.val)); @@ -1032,7 +1033,7 @@ int inflate(z_streamp strm, int flush) { break; } if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); + Tracevv(("inflate: end of block\n")); state->back = -1; state->mode = TYPE; break; @@ -1051,7 +1052,7 @@ int inflate(z_streamp strm, int flush) { DROPBITS(state->extra); state->back += state->extra; } - Tracevv((stderr, "inflate: length %u\n", state->length)); + Tracevv(("inflate: length %u\n", state->length)); state->was = state->length; state->mode = DIST; case DIST: @@ -1095,7 +1096,7 @@ int inflate(z_streamp strm, int flush) { break; } #endif - Tracevv((stderr, "inflate: distance %u\n", state->offset)); + Tracevv(("inflate: distance %u\n", state->offset)); state->mode = MATCH; case MATCH: if (left == 0) goto inf_leave; @@ -1109,7 +1110,7 @@ int inflate(z_streamp strm, int flush) { break; } #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - Trace((stderr, "inflate.c too far\n")); + Trace(("inflate.c too far\n")); copy -= state->whave; if (copy > state->length) copy = state->length; if (copy > left) copy = left; @@ -1166,7 +1167,7 @@ int inflate(z_streamp strm, int flush) { break; } INITBITS(); - Tracev((stderr, "inflate: check matches trailer\n")); + Tracev(("inflate: check matches trailer\n")); } #ifdef GUNZIP state->mode = LENGTH; @@ -1179,7 +1180,7 @@ int inflate(z_streamp strm, int flush) { break; } INITBITS(); - Tracev((stderr, "inflate: length matches trailer\n")); + Tracev(("inflate: length matches trailer\n")); } #endif state->mode = DONE; @@ -1245,7 +1246,7 @@ int inflateEnd(z_streamp strm) { if (state->window != Z_NULL) ZFREE(strm, state->window); ZFREE(strm, strm->state); strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); + Tracev(("inflate: end\n")); return Z_OK; } @@ -1293,7 +1294,7 @@ int inflateSetDictionary(z_streamp strm, const Bytef *dictionary, return Z_MEM_ERROR; } state->havedict = 1; - Tracev((stderr, "inflate: dictionary set\n")); + Tracev(("inflate: dictionary set\n")); return Z_OK; } diff --git a/third_party/zlib/inftrees.c b/third_party/zlib/inftrees.c index 25fb853ea..13774d811 100644 --- a/third_party/zlib/inftrees.c +++ b/third_party/zlib/inftrees.c @@ -27,7 +27,7 @@ static const uint16_t kZlibDeflateLbase[31] = { /* Length codes 257..285 extra */ static const uint16_t kZlibDeflateLext[31] = { 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 76, 202}; /* Distance codes 0..29 base */ static const uint16_t kZlibDeflateDbase[32] = { diff --git a/third_party/zlib/trees.c b/third_party/zlib/trees.c index d4a69e75f..f65695b87 100644 --- a/third_party/zlib/trees.c +++ b/third_party/zlib/trees.c @@ -5,6 +5,7 @@ │ Use of this source code is governed by the BSD-style licenses that can │ │ be found in the third_party/zlib/LICENSE file. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/intrin/kprintf.h" #include "libc/stdio/stdio.h" #include "libc/str/str.h" #include "third_party/zlib/deflate.internal.h" @@ -128,10 +129,10 @@ static void gen_trees_header(void); /* Send a code of the given tree. c and tree must not have side effects */ #else /* !ZLIB_DEBUG */ -#define send_code(s, c, tree) \ - { \ - if (z_verbose > 2) fprintf(stderr, "\ncd %3d ", (c)); \ - send_bits(s, tree[c].Code, tree[c].Len); \ +#define send_code(s, c, tree) \ + { \ + if (z_verbose > 2) kprintf("\ncd %3d ", (c)); \ + send_bits(s, tree[c].Code, tree[c].Len); \ } #endif @@ -151,7 +152,7 @@ static void gen_trees_header(void); */ #ifdef ZLIB_DEBUG static void send_bits(struct DeflateState *s, int value, int length) { - Tracevv((stderr, " l %2d v %4x ", length, value)); + Tracevv((" l %2d v %4x ", length, value)); Assert(length > 0 && length <= 15, "invalid length"); s->bits_sent += (uint64_t)length; /* If not enough room in bi_buf, use (valid) bits from bi_buf and @@ -466,7 +467,7 @@ static void gen_bitlen(struct DeflateState *s, tree_desc *desc) { } if (overflow == 0) return; - Tracev((stderr, "\nbit length overflow\n")); + Tracev(("\nbit length overflow\n")); /* This happens for example on obj2 and pic of the Calgary corpus */ /* Find the first bit length which could increase: */ @@ -493,7 +494,7 @@ static void gen_bitlen(struct DeflateState *s, tree_desc *desc) { m = s->heap[--h]; if (m > max_code) continue; if ((unsigned)tree[m].Len != (unsigned)bits) { - Tracev((stderr, "code %d bits %d->%d\n", m, tree[m].Len, bits)); + Tracev(("code %d bits %d->%d\n", m, tree[m].Len, bits)); s->opt_len += ((uint64_t)bits - tree[m].Len) * tree[m].Freq; tree[m].Len = (uint16_t)bits; } @@ -531,7 +532,7 @@ static void gen_codes(ct_data *tree, int max_code, uint16_t *bl_count) { */ Assert(code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1, "inconsistent bit counts"); - Tracev((stderr, "\ngen_codes: max_code %d ", max_code)); + Tracev(("\ngen_codes: max_code %d ", max_code)); for (n = 0; n <= max_code; n++) { int len = tree[n].Len; @@ -540,8 +541,8 @@ static void gen_codes(ct_data *tree, int max_code, uint16_t *bl_count) { tree[n].Code = (uint16_t)bi_reverse(next_code[len]++, len); Tracecv(tree != kZlibStaticLtree, - (stderr, "\nn %3d %c l %2d c %4x (%x) ", n, (isgraph(n) ? n : ' '), - len, tree[n].Code, next_code[len] - 1)); + ("\nn %3d %c l %2d c %4x (%x) ", n, (isgraph(n) ? n : ' '), len, + tree[n].Code, next_code[len] - 1)); } } @@ -614,8 +615,8 @@ static void build_tree(struct DeflateState *s, tree_desc *desc) { tree[n].Dad = tree[m].Dad = (uint16_t)node; #ifdef DUMP_BL_TREE if (tree == s->bl_tree) { - fprintf(stderr, "\nnode %d(%d), sons %d(%d) %d(%d)", node, - tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + kprintf("\nnode %d(%d), sons %d(%d) %d(%d)", node, tree[node].Freq, n, + tree[n].Freq, m, tree[m].Freq); } #endif /* and insert the new node in the heap */ @@ -765,7 +766,7 @@ static int build_bl_tree(struct DeflateState *s) { } /* Update opt_len to include the bit length tree and counts */ s->opt_len += 3 * ((uint64_t)max_blindex + 1) + 5 + 5 + 4; - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", s->opt_len, s->static_len)); + Tracev(("\ndyn trees: dyn %ld, stat %ld", s->opt_len, s->static_len)); return max_blindex; } @@ -782,21 +783,21 @@ static void send_all_trees(struct DeflateState *s, int lcodes, int dcodes, Assert(lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); Assert(lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, "too many codes"); - Tracev((stderr, "\nbl counts: ")); + Tracev(("\nbl counts: ")); send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ send_bits(s, dcodes - 1, 5); send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + Tracev(("\nbl code %2d ", bl_order[rank])); send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); } - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + Tracev(("\nbl tree: sent %ld", s->bits_sent)); send_tree(s, (ct_data *)s->dyn_ltree, lcodes - 1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + Tracev(("\nlit tree: sent %ld", s->bits_sent)); send_tree(s, (ct_data *)s->dyn_dtree, dcodes - 1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); + Tracev(("\ndist tree: sent %ld", s->bits_sent)); } /** @@ -860,12 +861,10 @@ void _tr_flush_block(struct DeflateState *s, charf *buf, uint64_t stored_len, /* Construct the literal and distance trees */ build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev( - (stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, s->static_len)); + Tracev(("\nlit data: dyn %ld, stat %ld", s->opt_len, s->static_len)); build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev( - (stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, s->static_len)); + Tracev(("\ndist data: dyn %ld, stat %ld", s->opt_len, s->static_len)); /* At this point, opt_len and static_len are the total bit lengths of * the compressed block data, excluding the tree representations. */ @@ -879,7 +878,7 @@ void _tr_flush_block(struct DeflateState *s, charf *buf, uint64_t stored_len, opt_lenb = (s->opt_len + 3 + 7) >> 3; static_lenb = (s->static_len + 3 + 7) >> 3; - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", opt_lenb, + Tracev(("\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, s->sym_next / 3)); @@ -937,7 +936,7 @@ void _tr_flush_block(struct DeflateState *s, charf *buf, uint64_t stored_len, s->compressed_len += 7; /* align on byte boundary */ #endif } - Tracev((stderr, "\ncomprlen %lu(%lu) ", s->compressed_len >> 3, + Tracev(("\ncomprlen %lu(%lu) ", s->compressed_len >> 3, s->compressed_len - 7 * last)); } @@ -987,7 +986,7 @@ static void compress_block(struct DeflateState *s, const ct_data *ltree, lc = s->sym_buf[sx++]; if (dist == 0) { send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr, " '%c' ", lc)); + Tracecv(isgraph(lc), (" '%c' ", lc)); } else { /* Here, lc is the match length - MIN_MATCH */ code = kZlibLengthCode[lc]; diff --git a/third_party/zlib/zconf.h b/third_party/zlib/zconf.h index 5a7d7272f..b7774c8d8 100644 --- a/third_party/zlib/zconf.h +++ b/third_party/zlib/zconf.h @@ -7,6 +7,10 @@ #define DEF_MEM_LEVEL 8 #define MAX_WBITS 15 /* 32K LZ77 window */ +#ifdef MODE_DBG +#define ZLIB_DEBUG +#endif + #if !(__ASSEMBLER__ + __LINKER__ + 0) typedef unsigned char Byte; diff --git a/third_party/zlib/zutil.c b/third_party/zlib/zutil.c index 43b8407e6..2079bcc1d 100644 --- a/third_party/zlib/zutil.c +++ b/third_party/zlib/zutil.c @@ -5,6 +5,9 @@ │ Use of this source code is governed by the BSD-style licenses that can │ │ be found in the third_party/zlib/LICENSE file. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/intrin/kprintf.h" +#include "libc/intrin/weaken.h" +#include "libc/log/log.h" #include "libc/mem/mem.h" #include "third_party/zlib/zutil.internal.h" @@ -117,9 +120,10 @@ uLong zlibCompileFlags() { #endif int z_verbose hidden = verbose; -void z_error(char *m) { - fprintf(stderr, "%s\n", m); - exit(1); +void z_error(const char *file, int line, char *m) { + kprintf("%s:%d: zlib panic: %s\n", file, line, m); + if (weaken(__die)) weaken(__die)(); + _Exit(1); } #endif diff --git a/third_party/zlib/zutil.internal.h b/third_party/zlib/zutil.internal.h index 388fbf3d4..067b8c52b 100644 --- a/third_party/zlib/zutil.internal.h +++ b/third_party/zlib/zutil.internal.h @@ -1,5 +1,6 @@ #ifndef ZUTIL_H #define ZUTIL_H +#include "libc/intrin/kprintf.h" #include "third_party/zlib/zlib.h" /* default windowBits for decompression. MAX_WBITS is for compression only */ @@ -46,32 +47,33 @@ extern const char *const z_errmsg[10] hidden; /* indexed by 2-zlib_error */ /* Diagnostic functions */ #ifdef ZLIB_DEBUG -#include "libc/stdio/stdio.h" extern int z_verbose hidden; -extern void z_error(char *m) hidden; -#define Assert(cond, msg) \ - { \ - if (!(cond)) z_error(msg); \ +extern void z_error(const char *, int, char *) hidden; +#define Assert(cond, msg) \ + { \ + if (!(cond)) { \ + z_error(__FILE__, __LINE__, msg); \ + } \ } #define Trace(x) \ { \ - if (z_verbose >= 0) fprintf x; \ + if (z_verbose >= 0) kprintf x; \ } #define Tracev(x) \ { \ - if (z_verbose > 0) fprintf x; \ + if (z_verbose > 0) kprintf x; \ } #define Tracevv(x) \ { \ - if (z_verbose > 1) fprintf x; \ + if (z_verbose > 1) kprintf x; \ } #define Tracec(c, x) \ { \ - if (z_verbose > 0 && (c)) fprintf x; \ + if (z_verbose > 0 && (c)) kprintf x; \ } #define Tracecv(c, x) \ { \ - if (z_verbose > 1 && (c)) fprintf x; \ + if (z_verbose > 1 && (c)) kprintf x; \ } #else #define Assert(cond, msg) diff --git a/tool/emacs/cosmo-platform-constants.el b/tool/emacs/cosmo-platform-constants.el index 8c078a353..7c7121880 100644 --- a/tool/emacs/cosmo-platform-constants.el +++ b/tool/emacs/cosmo-platform-constants.el @@ -17,6 +17,8 @@ "__SIZE_TYPE__" "__PTRDIFF_TYPE__" "__WCHAR_TYPE__" + "__CHAR16_TYPE__" + "__CHAR32_TYPE__" "__WINT_TYPE__" "__INTMAX_TYPE__" "__DEPRECATED"