Optimize memory layout

This commit is contained in:
Justine Tunney 2022-09-12 04:19:32 -07:00
parent 0305194d98
commit b69f3d2488
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
41 changed files with 383 additions and 347 deletions

View file

@ -714,8 +714,8 @@ ASSERT(!DEFINED(_start16) || REAL(_end) < 65536,
ASSERT(IS2POW(ape_stack_memsz), ASSERT(IS2POW(ape_stack_memsz),
"ape_stack_memsz must be a two power"); "ape_stack_memsz must be a two power");
ASSERT(!(ape_stack_vaddr & (ape_stack_memsz - 1)), ASSERT(ape_stack_vaddr % ape_stack_memsz == 0,
"ape_stack_vaddr must have ape_stack_memsz alignment; try using STATIC_STACK_ADDR(0x700000000000 - ape_stack_memsz);"); "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, ASSERT(ALIGNOF(.tdata) <= TLS_ALIGNMENT && ALIGNOF(.tbss) <= TLS_ALIGNMENT,
"_Thread_local _Alignof can't exceed TLS_ALIGNMENT"); "_Thread_local _Alignof can't exceed TLS_ALIGNMENT");

View file

@ -36,8 +36,8 @@
*/ */
#define REAL(x) ((x) - (IMAGE_BASE_VIRTUAL - IMAGE_BASE_REAL)) #define REAL(x) ((x) - (IMAGE_BASE_VIRTUAL - IMAGE_BASE_REAL))
#if IMAGE_BASE_VIRTUAL % 0x200000 != 0 #if IMAGE_BASE_VIRTUAL % 0x1000 != 0
#error "IMAGE_BASE_VIRTUAL must be 2mb aligned" #error "IMAGE_BASE_VIRTUAL must be 4kb aligned"
#endif #endif
#if IMAGE_BASE_PHYSICAL % 0x1000 != 0 #if IMAGE_BASE_PHYSICAL % 0x1000 != 0
#error "IMAGE_BASE_PHYSICAL must be 4kb aligned" #error "IMAGE_BASE_PHYSICAL must be 4kb aligned"

View file

@ -1,22 +1,8 @@
#ifndef COSMOPOLITAN_LIBC_ATOMIC_H_ #ifndef COSMOPOLITAN_LIBC_ATOMIC_H_
#define 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_bool _Atomic(_Bool)
#define atomic_bool32 atomic_int32 #define atomic_bool32 _Atomic(__INT32_TYPE__)
#define atomic_char _Atomic(char) #define atomic_char _Atomic(char)
#define atomic_schar _Atomic(signed char) #define atomic_schar _Atomic(signed char)
#define atomic_uchar _Atomic(unsigned char) #define atomic_uchar _Atomic(unsigned char)
@ -28,29 +14,29 @@ COSMOPOLITAN_C_START_
#define atomic_ulong _Atomic(unsigned long) #define atomic_ulong _Atomic(unsigned long)
#define atomic_llong _Atomic(long long) #define atomic_llong _Atomic(long long)
#define atomic_ullong _Atomic(unsigned long long) #define atomic_ullong _Atomic(unsigned long long)
#define atomic_char16_t _Atomic(char16_t) #define atomic_char16_t _Atomic(__CHAR16_TYPE__)
#define atomic_char32_t _Atomic(char32_t) #define atomic_char32_t _Atomic(__CHAR32_TYPE__)
#define atomic_wchar_t _Atomic(wchar_t) #define atomic_wchar_t _Atomic(__WCHAR_TYPE__)
#define atomic_intptr_t _Atomic(intptr_t) #define atomic_intptr_t _Atomic(__INTPTR_TYPE__)
#define atomic_uintptr_t _Atomic(uintptr_t) #define atomic_uintptr_t _Atomic(__UINTPTR_TYPE__)
#define atomic_size_t _Atomic(size_t) #define atomic_size_t _Atomic(__SIZE_TYPE__)
#define atomic_ptrdiff_t _Atomic(ptrdiff_t) #define atomic_ptrdiff_t _Atomic(__PTRDIFF_TYPE__)
#define atomic_int_fast8_t _Atomic(int_fast8_t) #define atomic_int_fast8_t _Atomic(__INT_FAST8_TYPE__)
#define atomic_uint_fast8_t _Atomic(uint_fast8_t) #define atomic_uint_fast8_t _Atomic(__UINT_FAST8_TYPE__)
#define atomic_int_fast16_t _Atomic(int_fast16_t) #define atomic_int_fast16_t _Atomic(__INT_FAST16_TYPE__)
#define atomic_uint_fast16_t _Atomic(uint_fast16_t) #define atomic_uint_fast16_t _Atomic(__UINT_FAST16_TYPE__)
#define atomic_int_fast32_t _Atomic(int_fast32_t) #define atomic_int_fast32_t _Atomic(__INT_FAST32_TYPE__)
#define atomic_uint_fast32_t _Atomic(uint_fast32_t) #define atomic_uint_fast32_t _Atomic(__UINT_FAST32_TYPE__)
#define atomic_int_fast64_t _Atomic(int_fast64_t) #define atomic_int_fast64_t _Atomic(__INT_FAST64_TYPE__)
#define atomic_uint_fast64_t _Atomic(uint_fast64_t) #define atomic_uint_fast64_t _Atomic(__UINT_FAST64_TYPE__)
#define atomic_int_least8_t _Atomic(int_least8_t) #define atomic_int_least8_t _Atomic(__INT_LEAST8_TYPE__)
#define atomic_uint_least8_t _Atomic(uint_least8_t) #define atomic_uint_least8_t _Atomic(__UINT_LEAST8_TYPE__)
#define atomic_int_least16_t _Atomic(int_least16_t) #define atomic_int_least16_t _Atomic(__INT_LEAST16_TYPE__)
#define atomic_uint_least16_t _Atomic(uint_least16_t) #define atomic_uint_least16_t _Atomic(__UINT_LEAST16_TYPE__)
#define atomic_int_least32_t _Atomic(int_least32_t) #define atomic_int_least32_t _Atomic(__INT_LEAST32_TYPE__)
#define atomic_uint_least32_t _Atomic(uint_least32_t) #define atomic_uint_least32_t _Atomic(__UINT_LEAST32_TYPE__)
#define atomic_int_least64_t _Atomic(int_least64_t) #define atomic_int_least64_t _Atomic(__INT_LEAST64_TYPE__)
#define atomic_uint_least64_t _Atomic(uint_least64_t) #define atomic_uint_least64_t _Atomic(__UINT_LEAST64_TYPE__)
#ifdef __CLANG_ATOMIC_BOOL_LOCK_FREE #ifdef __CLANG_ATOMIC_BOOL_LOCK_FREE
#define ATOMIC_BOOL_LOCK_FREE __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 #define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
#endif #endif
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_ATOMIC_H_ */ #endif /* COSMOPOLITAN_LIBC_ATOMIC_H_ */

View file

@ -38,7 +38,7 @@ int sys_munmap(void *p, size_t n) {
} else { } else {
rc = sys_munmap_metal(p, n); rc = sys_munmap_metal(p, n);
} }
KERNTRACE("sys_munmap(%p%s, %'zu) → %d", p, DescribeFrame((intptr_t)p >> 16), KERNTRACE("sys_munmap(%p /* %s */, %'zu) → %d", p,
n, rc); DescribeFrame((intptr_t)p >> 16), n, rc);
return rc; return rc;
} }

View file

@ -37,34 +37,8 @@
#define uid_t uint32_t #define uid_t uint32_t
#define rlim_t uint64_t /* int64_t on bsd */ #define rlim_t uint64_t /* int64_t on bsd */
typedef __INT_FAST8_TYPE__ int_fast8_t; #define TIME_T_MAX __INT64_MAX__
typedef __UINT_FAST8_TYPE__ uint_fast8_t; #define TIME_T_MIN (-TIME_T_MAX - 1)
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)
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_WEIRDTYPES_H_ */ #endif /* COSMOPOLITAN_LIBC_CALLS_WEIRDTYPES_H_ */

View file

@ -16,32 +16,62 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/dce.h"
#include "libc/intrin/describeflags.internal.h" #include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/runtime/memtrack.internal.h" #include "libc/runtime/memtrack.internal.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/runtime/winargs.internal.h"
#define ADDR(x) ((int64_t)((uint64_t)(x) << 32) >> 16) #define ADDR(x) ((int64_t)((uint64_t)(x) << 32) >> 16)
#define UNSHADOW(x) ((int64_t)(MAX(0, (x)-0x7fff8000)) << 3) #define UNSHADOW(x) ((int64_t)(MAX(0, (x)-0x7fff8000)) << 3)
#define FRAME(x) ((int)((x) >> 16)) #define FRAME(x) ((int)((x) >> 16))
const char *(DescribeFrame)(char buf[32], int x) { static const char *GetFrameName(int x) {
/* asan runtime depends on this function */ if (!x) {
char *p; return "null";
if (IsShadowFrame(x)) { } else if (IsShadowFrame(x)) {
ksnprintf(buf, 32, " shadow=%.8x", FRAME(UNSHADOW(ADDR(x)))); return "shadow";
return buf;
return " shadow ";
} else if (IsAutoFrame(x)) { } else if (IsAutoFrame(x)) {
return " automap"; return "automap";
} else if (IsFixedFrame(x)) { } else if (IsFixedFrame(x)) {
return " fixed "; return "fixed";
} else if (IsArenaFrame(x)) { } else if (IsArenaFrame(x)) {
return " arena "; return "arena";
} else if (IsStaticStackFrame(x)) { } 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 { } 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);
} }
} }

View file

@ -49,7 +49,7 @@ const char *(DescribeMapping)(char p[8], int prot, int flags) {
DescribeProt(p, prot); DescribeProt(p, prot);
p[3] = DescribeMapType(flags); p[3] = DescribeMapType(flags);
p[4] = (flags & MAP_ANONYMOUS) ? 'a' : '-'; p[4] = (flags & MAP_ANONYMOUS) ? 'a' : '-';
p[6] = (flags & MAP_FIXED) ? 'F' : '-'; p[5] = (flags & MAP_FIXED) ? 'F' : '-';
p[7] = 0; p[6] = 0;
return p; return p;
} }

View file

@ -46,8 +46,9 @@ struct DirectMap sys_mmap(void *addr, size_t size, int prot, int flags, int fd,
} else { } else {
d = sys_mmap_nt(addr, size, prot, flags, fd, off); d = sys_mmap_nt(addr, size, prot, flags, fd, off);
} }
KERNTRACE("sys_mmap(%.12p%s, %'zu, %s, %s, %d, %'ld) → {%.12p, %p}% m", addr, KERNTRACE("sys_mmap(%.12p /* %s */, %'zu, %s, %s, %d, %'ld) → {%.12p, %p}% m",
DescribeFrame((intptr_t)addr >> 16), size, DescribeProtFlags(prot), addr, DescribeFrame((intptr_t)addr >> 16), size,
DescribeMapFlags(flags), fd, off, d.addr, d.maphandle); DescribeProtFlags(prot), DescribeMapFlags(flags), fd, off, d.addr,
d.maphandle);
return d; return d;
} }

View file

@ -18,7 +18,6 @@
*/ */
#include "libc/assert.h" #include "libc/assert.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/nt/enum/version.h"
#include "libc/nt/version.h" #include "libc/nt/version.h"
/** /**

View file

@ -37,11 +37,20 @@
#include "libc/sysv/consts/prot.h" #include "libc/sysv/consts/prot.h"
#include "libc/sysv/errfuns.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, static void *MoveMemoryIntervals(struct MemoryInterval *d,
const struct MemoryInterval *s, int n) { const struct MemoryInterval *s, int n) {
// asan runtime depends on this function
int i; int i;
assert(n >= 0); if (n < 0) unreachable;
if (d > s) { if (d > s) {
for (i = n; i--;) { for (i = n; i--;) {
d[i] = s[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) { static void RemoveMemoryIntervals(struct MemoryIntervals *mm, int i, int n) {
// asan runtime depends on this function if (i < 0) unreachable;
assert(i >= 0); if (i + n > mm->i) unreachable;
assert(i + n <= mm->i);
MoveMemoryIntervals(mm->p + i, mm->p + i + n, mm->i - (i + n)); MoveMemoryIntervals(mm->p + i, mm->p + i + n, mm->i - (i + n));
mm->i -= n; mm->i -= n;
} }
@ -96,19 +104,14 @@ static bool ExtendMemoryIntervals(struct MemoryIntervals *mm) {
if (!dm.addr) return false; if (!dm.addr) return false;
mm->n = (size + gran) / sizeof(*mm->p); mm->n = (size + gran) / sizeof(*mm->p);
} }
#if IsModeDbg() ASSERT_MEMTRACK();
assert(AreMemoryIntervalsOk(mm));
#endif
return true; return true;
} }
int CreateMemoryInterval(struct MemoryIntervals *mm, int i) { int CreateMemoryInterval(struct MemoryIntervals *mm, int i) {
// asan runtime depends on this function if (i < 0) unreachable;
int rc; if (i > mm->i) unreachable;
rc = 0; if (mm->n < 0) unreachable;
assert(i >= 0);
assert(i <= mm->i);
assert(mm->n >= 0);
if (UNLIKELY(mm->i == mm->n) && !ExtendMemoryIntervals(mm)) return enomem(); if (UNLIKELY(mm->i == mm->n) && !ExtendMemoryIntervals(mm)) return enomem();
MoveMemoryIntervals(mm->p + i + 1, mm->p + i, mm->i++ - i); MoveMemoryIntervals(mm->p + i + 1, mm->p + i, mm->i++ - i);
return 0; 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, int ReleaseMemoryIntervals(struct MemoryIntervals *mm, int x, int y,
void wf(struct MemoryIntervals *, int, int)) { void wf(struct MemoryIntervals *, int, int)) {
unsigned l, r; unsigned l, r;
#if IsModeDbg() ASSERT_MEMTRACK();
assert(y >= x); if (y < x) unreachable;
assert(AreMemoryIntervalsOk(mm));
#endif
if (!mm->i) return 0; if (!mm->i) return 0;
// binary search for the lefthand side // binary search for the lefthand side
l = FindMemoryInterval(mm, x); l = FindMemoryInterval(mm, x);
if (l == mm->i) return 0; 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 // binary search for the righthand side
r = FindMemoryInterval(mm, y); r = FindMemoryInterval(mm, y);
if (r == mm->i || (r > l && y < mm->p[r].x)) --r; if (r == mm->i || (r > l && y < mm->p[r].x)) --r;
assert(r >= l); if (r < l) unreachable;
assert(x <= mm->p[r].y); if (x > mm->p[r].y) unreachable;
// remove the middle of an existing map // remove the middle of an existing map
// //
@ -162,11 +162,11 @@ int ReleaseMemoryIntervals(struct MemoryIntervals *mm, int x, int y,
// ----|mmmm|----------------- after // ----|mmmm|----------------- after
// //
if (x > mm->p[l].x && x <= mm->p[l].y) { 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(); if (IsWindows()) return einval();
mm->p[l].size -= (size_t)(mm->p[l].y - (x - 1)) * FRAMESIZE; mm->p[l].size -= (size_t)(mm->p[l].y - (x - 1)) * FRAMESIZE;
mm->p[l].y = x - 1; 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; ++l;
} }
@ -177,11 +177,11 @@ int ReleaseMemoryIntervals(struct MemoryIntervals *mm, int x, int y,
// ---------------|mm|-------- after // ---------------|mm|-------- after
// //
if (y >= mm->p[r].x && y < mm->p[r].y) { 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(); if (IsWindows()) return einval();
mm->p[r].size -= (size_t)((y + 1) - mm->p[r].x) * FRAMESIZE; mm->p[r].size -= (size_t)((y + 1) - mm->p[r].x) * FRAMESIZE;
mm->p[r].x = y + 1; 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; --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 TrackMemoryInterval(struct MemoryIntervals *mm, int x, int y, long h,
int prot, int flags, bool readonlyfile, bool iscow, int prot, int flags, bool readonlyfile, bool iscow,
long offset, long size) { long offset, long size) {
// asan runtime depends on this function
unsigned i; unsigned i;
#if IsModeDbg() ASSERT_MEMTRACK();
assert(y >= x); if (y < x) unreachable;
if (!AreMemoryIntervalsOk(mm)) {
PrintMemoryIntervals(2, mm);
}
assert(AreMemoryIntervalsOk(mm));
#endif
i = FindMemoryInterval(mm, x); i = FindMemoryInterval(mm, x);
// try to extend the righthand side of the lefthand entry // 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].iscow = iscow;
mm->p[i].readonlyfile = readonlyfile; mm->p[i].readonlyfile = readonlyfile;
} }
return 0; return 0;
} }

View file

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/fmt/conv.h"
#include "libc/fmt/itoa.h" #include "libc/fmt/itoa.h"
#include "libc/intrin/describeflags.internal.h" #include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.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) { void PrintMemoryIntervals(int fd, const struct MemoryIntervals *mm) {
char *p, mappingbuf[8], framebuf[32]; char *p, mappingbuf[8], framebuf[64], sb[16];
long i, w, frames, maptally = 0, gaptally = 0; long i, w, frames, maptally = 0;
for (w = i = 0; i < mm->i; ++i) { for (w = i = 0; i < mm->i; ++i) {
w = MAX(w, LengthInt64Thousands(mm->p[i].y + 1 - mm->p[i].x)); w = MAX(w, LengthInt64Thousands(mm->p[i].y + 1 - mm->p[i].x));
} }
for (i = 0; i < mm->i; ++i) { for (i = 0; i < mm->i; ++i) {
frames = mm->p[i].y + 1 - mm->p[i].x; frames = mm->p[i].y + 1 - mm->p[i].x;
maptally += frames; 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, (DescribeMapping)(mappingbuf, mm->p[i].prot, mm->p[i].flags), w,
frames, (DescribeFrame)(framebuf, mm->p[i].x)); frames, (DescribeFrame)(framebuf, mm->p[i].x));
if (mm->p[i].iscow) kprintf(" cow"); if (mm->p[i].iscow) kprintf(" cow");
if (mm->p[i].readonlyfile) kprintf(" readonlyfile"); if (mm->p[i].readonlyfile) kprintf(" readonlyfile");
if (mm->p[i].size != sizefmt(sb, mm->p[i].size, 1024);
(size_t)(mm->p[i].y - mm->p[i].x) * FRAMESIZE + FRAMESIZE) { kprintf(" %sB", sb);
kprintf(" size=%'zu", mm->p[i].size);
}
if (i + 1 < mm->i) { if (i + 1 < mm->i) {
frames = mm->p[i + 1].x - mm->p[i].y - 1; frames = mm->p[i + 1].x - mm->p[i].y - 1;
if (frames && IsNoteworthyHole(i, mm)) { if (frames && IsNoteworthyHole(i, mm)) {
gaptally += frames; sizefmt(sb, frames * FRAMESIZE, 1024);
kprintf(" w/ %'ld frame hole", frames); kprintf(" w/ %sB hole", sb);
} }
} }
if (mm->p[i].h != -1) { if (mm->p[i].h != -1) {
@ -63,5 +62,6 @@ void PrintMemoryIntervals(int fd, const struct MemoryIntervals *mm) {
} }
kprintf("\n"); 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);
} }

View file

@ -10,6 +10,15 @@ typedef __UINT_LEAST32_TYPE__ uint_least32_t;
typedef __INT_LEAST64_TYPE__ int_least64_t; typedef __INT_LEAST64_TYPE__ int_least64_t;
typedef __UINT_LEAST64_TYPE__ uint_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 cosmopolitan § dismal format notation
*/ */

View file

@ -36,7 +36,6 @@
#define INTMAX_MAX __INTMAX_MAX__ #define INTMAX_MAX __INTMAX_MAX__
#define UINTMAX_MAX __UINTMAX_MAX__ #define UINTMAX_MAX __UINTMAX_MAX__
extern int __got_long_min;
#define SCHAR_MIN (-SCHAR_MAX - 1) #define SCHAR_MIN (-SCHAR_MAX - 1)
#define SHRT_MIN (-SHRT_MAX - 1) #define SHRT_MIN (-SHRT_MAX - 1)
#define INT_MIN (-INT_MAX - 1) #define INT_MIN (-INT_MAX - 1)
@ -108,4 +107,22 @@ extern int __got_long_min;
#define NL_SETMAX 255 #define NL_SETMAX 255
#define NL_TEXTMAX 2048 #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_ */ #endif /* COSMOPOLITAN_LIBC_LIMITS_H_ */

View file

@ -10,7 +10,6 @@ forceinline pureconst bool IsValidStackFramePointer(struct StackFrame *x) {
/* assumes __mmi_lock() is held */ /* assumes __mmi_lock() is held */
return IsLegalPointer(x) && !((uintptr_t)x & 15) && return IsLegalPointer(x) && !((uintptr_t)x & 15) &&
(IsStaticStackFrame((uintptr_t)x >> 16) || (IsStaticStackFrame((uintptr_t)x >> 16) ||
IsSigAltStackFrame((uintptr_t)x >> 16) ||
IsOldStackFrame((uintptr_t)x >> 16) || IsOldStackFrame((uintptr_t)x >> 16) ||
/* lua coroutines need this */ /* lua coroutines need this */
IsMemtracked((uintptr_t)x >> 16, (uintptr_t)x >> 16)); IsMemtracked((uintptr_t)x >> 16, (uintptr_t)x >> 16));

View file

@ -17,10 +17,10 @@
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/assert.h" #include "libc/assert.h"
#include "libc/intrin/likely.h"
#include "libc/intrin/weaken.h"
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/intrin/likely.h"
#include "libc/intrin/weaken.h"
#include "libc/limits.h" #include "libc/limits.h"
#include "libc/log/log.h" #include "libc/log/log.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
@ -35,8 +35,8 @@
#include "libc/sysv/consts/prot.h" #include "libc/sysv/consts/prot.h"
#include "libc/sysv/errfuns.h" #include "libc/sysv/errfuns.h"
#define BASE 0x50000000 #define BASE 0x50040000
#define SIZE 0x2ffe0000 #define SIZE 0x2ff80000
#define P(i) ((void *)(intptr_t)(i)) #define P(i) ((void *)(intptr_t)(i))
#define EXCHANGE(HOOK, SLOT) \ #define EXCHANGE(HOOK, SLOT) \
__arena_hook((intptr_t *)weaken(HOOK), (intptr_t *)(&(SLOT))) __arena_hook((intptr_t *)weaken(HOOK), (intptr_t *)(&(SLOT)))

View file

@ -20,7 +20,10 @@
#include "libc/mem/mem.h" #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 * @param n number of bytes needed
* @return memory address, or NULL w/ errno * @return memory address, or NULL w/ errno
@ -28,5 +31,5 @@
* @threadsafe * @threadsafe
*/ */
void *pvalloc(size_t n) { void *pvalloc(size_t n) {
return memalign(PAGESIZE, ROUNDUP(n, PAGESIZE)); return memalign(FRAMESIZE, ROUNDUP(n, FRAMESIZE));
} }

View file

@ -19,7 +19,9 @@
#include "libc/mem/mem.h" #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 * @param n number of bytes needed
* @return memory address, or NULL w/ errno * @return memory address, or NULL w/ errno
@ -27,5 +29,5 @@
* @threadsafe * @threadsafe
*/ */
void *valloc(size_t n) { void *valloc(size_t n) {
return memalign(PAGESIZE, n); return memalign(FRAMESIZE, n);
} }

View file

@ -7,7 +7,7 @@ COSMOPOLITAN_C_START_
bool IsAtLeastWindows10(void) pureconst; bool IsAtLeastWindows10(void) pureconst;
bool32 GetVersionEx(struct NtOsVersionInfo *lpVersionInformation); 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 IsAtLeastWindows10() (GetNtMajorVersion() >= 10)
#define GetNtMajorVersion() \ #define GetNtMajorVersion() \
({ \ ({ \

View file

@ -31,8 +31,8 @@ uintptr_t __break;
* *
* This can be used to allocate and deallocate memory. It won't * This can be used to allocate and deallocate memory. It won't
* conflict with malloc() and mmap(NULL, ...) allocations since * conflict with malloc() and mmap(NULL, ...) allocations since
* APE binaries load the image at 0x400000 and does allocations * APE binaries load the image at 0x440000 and does allocations
* starting at 0x100080000000. You should consult _end, or call * starting at 0x100080040000. You should consult _end, or call
* sbrk(NULL), to figure out where the existing break is first. * sbrk(NULL), to figure out where the existing break is first.
* *
* @return 0 on success or -1 w/ errno * @return 0 on success or -1 w/ errno

View file

@ -1,42 +1,30 @@
#ifndef COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_ #ifndef COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_
#define COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_ #define COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_
#include "libc/assert.h" #include "libc/assert.h"
#include "libc/intrin/midpoint.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/intrin/midpoint.h"
#include "libc/intrin/nopl.internal.h" #include "libc/intrin/nopl.internal.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/thread/tls.h"
#include "libc/nt/version.h" #include "libc/nt/version.h"
#include "libc/runtime/stack.h" #include "libc/runtime/stack.h"
#include "libc/sysv/consts/ss.h" #include "libc/sysv/consts/ss.h"
#include "libc/thread/tls.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0) #if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_ COSMOPOLITAN_C_START_
#define kAutomapStart _kMem(0x100080000000, 0x000010000000) #define kAutomapStart 0x100080040000
#define kAutomapSize \ #define kAutomapSize (kMemtrackStart - kAutomapStart)
_kMem(0x200000000000 - 0x100080000000 - _kMmi(0x800000000000), \ #define kMemtrackStart 0x1fe7fffc0000
0x000040000000 - 0x000010000000 - _kMmi(0x000080000000)) #define kMemtrackSize (0x1ffffffc0000 - kMemtrackStart)
#define kMemtrackStart \ #define kFixedmapStart 0x300000040000
(ROUNDDOWN(_kMem(0x200000000000 - _kMmi(0x800000000000), \ #define kFixedmapSize (0x400000040000 - kFixedmapStart)
0x000040000000 - _kMmi(0x000080000000)), \ #define kMemtrackFdsStart 0x6fe000040000
FRAMESIZE * 8) - \ #define kMemtrackFdsSize (0x6feffffc0000 - kMemtrackFdsStart)
0x8000 * 8 /* so frame aligned after adding 0x7fff8000 */) #define kMemtrackZiposStart 0x6fd000040000
#define kMemtrackSize _kMem(_kMmi(0x800000000000), _kMmi(0x000080000000)) #define kMemtrackZiposSize (0x6fdffffc0000 - kMemtrackZiposStart)
#define kMemtrackGran (!IsAsan() ? FRAMESIZE : FRAMESIZE * 8) #define kMemtrackNsyncStart 0x6fc000040000
#define kFixedmapStart _kMem(0x300000000000, 0x000040000000) #define kMemtrackNsyncSize (0x6fcffffc0000 - kMemtrackNsyncStart)
#define kFixedmapSize \ #define kMemtrackGran (!IsAsan() ? FRAMESIZE : FRAMESIZE * 8)
_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)
struct MemoryInterval { struct MemoryInterval {
int x; int x;
@ -88,23 +76,38 @@ forceinline pureconst bool IsLegalSize(size_t n) {
} }
forceinline pureconst bool IsAutoFrame(int x) { forceinline pureconst bool IsAutoFrame(int x) {
return (kAutomapStart >> 16) <= x && return (int)(kAutomapStart >> 16) <= x &&
x <= ((kAutomapStart + (kAutomapSize - 1)) >> 16); x <= (int)((kAutomapStart + kAutomapSize - 1) >> 16);
} }
forceinline pureconst bool IsMemtrackFrame(int x) { forceinline pureconst bool IsMemtrackFrame(int x) {
return (kAutomapStart >> 16) <= x && return (int)(kAutomapStart >> 16) <= x &&
x <= ((kAutomapStart + (kAutomapSize - 1)) >> 16); x <= (int)((kAutomapStart + kAutomapSize - 1) >> 16);
} }
forceinline pureconst bool IsArenaFrame(int x) { forceinline pureconst bool IsGfdsFrame(int x) {
return 0x5000 <= x && x < 0x7ffe; 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) { forceinline pureconst bool IsShadowFrame(int x) {
return 0x7fff <= x && x < 0x10008000; return 0x7fff <= x && x < 0x10008000;
} }
forceinline pureconst bool IsArenaFrame(int x) {
return 0x5004 <= x && x <= 0x7ffb;
}
forceinline pureconst bool IsKernelFrame(int x) { forceinline pureconst bool IsKernelFrame(int x) {
intptr_t stack = GetStaticStackAddr(0); intptr_t stack = GetStaticStackAddr(0);
return (int)(stack >> 16) <= x && return (int)(stack >> 16) <= x &&
@ -123,15 +126,12 @@ forceinline pureconst bool IsStackFrame(int x) {
x <= (int)((stack + (GetStackSize() - FRAMESIZE)) >> 16); 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) { forceinline pureconst bool IsOldStackFrame(int x) {
intptr_t old = ROUNDDOWN(__oldstack, STACKSIZE); /* openbsd uses 4mb stack by default */
return (old >> 16) <= x && x <= ((old + (STACKSIZE - FRAMESIZE)) >> 16); /* 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) { forceinline pureconst bool IsFixedFrame(int x) {

View file

@ -3,8 +3,8 @@
00000000-0000001f 2048kb null 00000000-0000001f 2048kb null
00000020-0000003f 2048kb loader 00000020-0000003f 2048kb loader
00000040-00004fff 1276mb image 00000040-00004ffb 1276mb image
00005000-00007ffd 768mb arena 00005004-00007ffb 768mb arena
00007ffe-00007ffe 64kb free 00007ffe-00007ffe 64kb free
# address sanitizer shadow memory # address sanitizer shadow memory
@ -264,10 +264,10 @@
0fd00000-0fdfffff 64gb asan 0fd00000-0fdfffff 64gb asan
0fe00000-0fefffff 64gb asan 0fe00000-0fefffff 64gb asan
0ff00000-0fffffff 64gb asan 0ff00000-0fffffff 64gb asan
10000000-10007fff 2048mb asan 10000000-10008003 2048mb asan
# memory dedicated to mmap(NULL, ...) automation, e.g. malloc() # memory dedicated to mmap(NULL, ...) automation, e.g. malloc()
10008000-100fffff 62gb automap 10008004-100fffff 62gb automap
10100000-101fffff 64gb automap 10100000-101fffff 64gb automap
10200000-102fffff 64gb automap 10200000-102fffff 64gb automap
10300000-103fffff 64gb automap 10300000-103fffff 64gb automap
@ -521,13 +521,13 @@
1fb00000-1fbfffff 64gb automap 1fb00000-1fbfffff 64gb automap
1fc00000-1fcfffff 64gb automap 1fc00000-1fcfffff 64gb automap
1fd00000-1fdfffff 64gb automap 1fd00000-1fdfffff 64gb automap
1fe00000-1fe7ffff 32gb automap 1fe00000-1fe7fffb 32gb automap
1fe7fffc-1fefffff 32gb _mmi 1fe7fffc-1fefffff 32gb _mmi
1ff00000-1ffffffb 64gb _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 20100000-201fffff 64gb free
20200000-202fffff 64gb free 20200000-202fffff 64gb free
20300000-203fffff 64gb free 20300000-203fffff 64gb free
@ -782,10 +782,10 @@
2fc00000-2fcfffff 64gb free 2fc00000-2fcfffff 64gb free
2fd00000-2fdfffff 64gb free 2fd00000-2fdfffff 64gb free
2fe00000-2fefffff 64gb free 2fe00000-2fefffff 64gb free
2ff00000-2fffffff 64gb free 2ff00000-30000003 64gb free
# memory recommended for application MAP_FIXED usage # memory recommended for application MAP_FIXED usage
30000000-300fffff 64gb fixedmap 30000004-300fffff 64gb fixedmap
30100000-301fffff 64gb fixedmap 30100000-301fffff 64gb fixedmap
30200000-302fffff 64gb fixedmap 30200000-302fffff 64gb fixedmap
30300000-303fffff 64gb fixedmap 30300000-303fffff 64gb fixedmap
@ -1040,9 +1040,9 @@
3fc00000-3fcfffff 64gb fixedmap 3fc00000-3fcfffff 64gb fixedmap
3fd00000-3fdfffff 64gb fixedmap 3fd00000-3fdfffff 64gb fixedmap
3fe00000-3fefffff 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 40100000-401fffff 64gb free
40200000-402fffff 64gb free 40200000-402fffff 64gb free
40300000-403fffff 64gb free 40300000-403fffff 64gb free
@ -1808,14 +1808,14 @@
6f900000-6f9fffff 64gb free 6f900000-6f9fffff 64gb free
6fa00000-6fafffff 64gb free 6fa00000-6fafffff 64gb free
6fb00000-6fbfffff 64gb free 6fb00000-6fbfffff 64gb free
6fc00004-6fcfffff 64gb nsync 6fc00004-6fcffffb 64gb nsync
6fd00000-6fdfffff 64gb zipos 6fd00004-6fdffffb 64gb zipos
6fe00004-6feffffc 64gb g_fds 6fe00004-6feffffb 64gb g_fds
6ff00000-6ffffffd 64gb free 6ff00004-70000003 64gb free
6ffffffe-6fffffff 128kb winargs
70000000-70000001 128kb stack 70000004-70000004 64kb stack
70000002-700fffff 64gb free 70000005-70000006 128kb winargs
70000005-700fffff 64gb free
70100000-701fffff 64gb free 70100000-701fffff 64gb free
70200000-702fffff 64gb free 70200000-702fffff 64gb free
70300000-703fffff 64gb free 70300000-703fffff 64gb free

View file

@ -107,18 +107,14 @@ extern char ape_stack_align[] __attribute__((__weak__));
* problematic, since MODE=tiny doesn't use any of the runtime codes * problematic, since MODE=tiny doesn't use any of the runtime codes
* which want the stack to be cheaply knowable, e.g. ftrace, kprintf * which want the stack to be cheaply knowable, e.g. ftrace, kprintf
*/ */
#define GetStaticStackAddr(ADDEND) \ #define GetStaticStackAddr(ADDEND) \
({ \ ({ \
intptr_t vAddr; \ intptr_t vAddr; \
if (!IsWindows() || IsAtLeastWindows10()) { \ __asm__(".weak\tape_stack_vaddr\n\t" \
__asm__(".weak\tape_stack_vaddr\n\t" \ "movabs\t%1+ape_stack_vaddr,%0" \
"movabs\t%1+ape_stack_vaddr,%0" \ : "=r"(vAddr) \
: "=r"(vAddr) \ : "i"(ADDEND)); \
: "i"(ADDEND)); \ vAddr; \
} else { \
vAddr = 0x100000000 - GetStackSize(); \
} \
vAddr; \
}) })
/** /**

View file

@ -166,8 +166,8 @@ __msabi static textwindows wontreturn void WinMainNew(const char16_t *cmdline) {
char outflagsbuf[128]; char outflagsbuf[128];
const char16_t *env16; const char16_t *env16;
int i, prot, count, version; int i, prot, count, version;
size_t allocsize, stacksize;
intptr_t stackaddr, allocaddr; intptr_t stackaddr, allocaddr;
size_t allocsize, argsize, stacksize;
version = NtGetPeb()->OSMajorVersion; version = NtGetPeb()->OSMajorVersion;
__oldstack = (intptr_t)__builtin_frame_address(0); __oldstack = (intptr_t)__builtin_frame_address(0);
if ((intptr_t)v_ntsubsystem == kNtImageSubsystemWindowsCui && version >= 10) { if ((intptr_t)v_ntsubsystem == kNtImageSubsystemWindowsCui && version >= 10) {
@ -190,15 +190,14 @@ __msabi static textwindows wontreturn void WinMainNew(const char16_t *cmdline) {
rc); rc);
} }
} }
_Static_assert(sizeof(struct WinArgs) % FRAMESIZE == 0, "");
_mmi.p = _mmi.s; _mmi.p = _mmi.s;
_mmi.n = ARRAYLEN(_mmi.s); _mmi.n = ARRAYLEN(_mmi.s);
argsize = ROUNDUP(sizeof(struct WinArgs), FRAMESIZE);
stackaddr = GetStaticStackAddr(0); stackaddr = GetStaticStackAddr(0);
stacksize = GetStackSize(); stacksize = GetStackSize();
allocsize = argsize + stacksize; allocaddr = stackaddr;
allocaddr = stackaddr - argsize; allocsize = stacksize + sizeof(struct WinArgs);
NTTRACE("WinMainNew() mapping %'zu byte arg block + stack at %p", allocsize, NTTRACE("WinMainNew() mapping %'zu byte stack at %p", allocsize, allocaddr);
allocaddr);
MapViewOfFileEx( MapViewOfFileEx(
(_mmi.p[0].h = (_mmi.p[0].h =
CreateFileMapping(-1, &kNtIsInheritable, kNtPageExecuteReadwrite, CreateFileMapping(-1, &kNtIsInheritable, kNtPageExecuteReadwrite,
@ -209,12 +208,12 @@ __msabi static textwindows wontreturn void WinMainNew(const char16_t *cmdline) {
VirtualProtect((void *)allocaddr, allocsize, kNtPageReadwrite, &oldprot); VirtualProtect((void *)allocaddr, allocsize, kNtPageReadwrite, &oldprot);
} }
_mmi.p[0].x = allocaddr >> 16; _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].prot = prot;
_mmi.p[0].flags = 0x00000026; // stack+anonymous _mmi.p[0].flags = 0x00000026; // stack+anonymous
_mmi.p[0].size = allocsize; _mmi.p[0].size = allocsize;
_mmi.i = 1; _mmi.i = 1;
wa = (struct WinArgs *)allocaddr; wa = (struct WinArgs *)(allocaddr + stacksize);
NTTRACE("WinMainNew() loading arg block"); NTTRACE("WinMainNew() loading arg block");
count = GetDosArgv(cmdline, wa->argblock, ARRAYLEN(wa->argblock), wa->argv, count = GetDosArgv(cmdline, wa->argblock, ARRAYLEN(wa->argblock), wa->argv,
ARRAYLEN(wa->argv)); ARRAYLEN(wa->argv));

View file

@ -49,6 +49,10 @@ static uint64_t Rando(void) {
return x; return x;
} }
void SetUp(void) {
__print_maps();
}
static const struct { static const struct {
const char *want; const char *want;
const char *fmt; const char *fmt;

View file

@ -52,5 +52,5 @@ TEST(zipos, test) {
struct spawn *t = _gc(malloc(sizeof(struct spawn) * n)); 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) ASSERT_SYS(0, 0, _spawn(Worker, 0, t + i));
for (i = 0; i < n; ++i) EXPECT_SYS(0, 0, _join(t + i)); for (i = 0; i < n; ++i) EXPECT_SYS(0, 0, _join(t + i));
/* __print_maps(); */ __print_maps();
} }

View file

@ -10,6 +10,7 @@ if [ $# = 0 ]; then
o//examples/life.com \ o//examples/life.com \
o//examples/hello.com \ o//examples/hello.com \
o//examples/printargs.com \ o//examples/printargs.com \
o//tool/build/assimilate.com \
o//tool/build/pledge.com || exit o//tool/build/pledge.com || exit
make -j16 MODE=$m \ make -j16 MODE=$m \
o/$m/examples/ls.com \ o/$m/examples/ls.com \
@ -17,6 +18,7 @@ if [ $# = 0 ]; then
o/$m/examples/life.com \ o/$m/examples/life.com \
o/$m/examples/hello.com \ o/$m/examples/hello.com \
o/$m/examples/printargs.com \ o/$m/examples/printargs.com \
o/$m/tool/build/assimilate.com \
o/$m/tool/build/pledge.com || exit 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_binfmt_test_suite || exit
test/tool/build/pledge_test.sh ape_loader_test_suite || exit test/tool/build/pledge_test.sh ape_loader_test_suite || exit

View file

@ -1,9 +1,10 @@
#ifndef NSYNC_ATOMIC_H_ #ifndef NSYNC_ATOMIC_H_
#define NSYNC_ATOMIC_H_ #define NSYNC_ATOMIC_H_
#include "libc/atomic.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0) #if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_ 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_INIT_ 0
#define NSYNC_ATOMIC_UINT32_LOAD_(p) (*(p)) #define NSYNC_ATOMIC_UINT32_LOAD_(p) (*(p))

View file

@ -55,4 +55,3 @@ $(THIRD_PARTY_NSYNC_OBJS): third_party/nsync/nsync.mk
.PHONY: o/$(MODE)/third_party/nsync .PHONY: o/$(MODE)/third_party/nsync
o/$(MODE)/third_party/nsync: $(THIRD_PARTY_NSYNC_CHECKS) o/$(MODE)/third_party/nsync: $(THIRD_PARTY_NSYNC_CHECKS)

View file

@ -27,6 +27,8 @@
#include "libc/sysv/consts/prot.h" #include "libc/sysv/consts/prot.h"
#include "libc/fmt/fmt.h" #include "libc/fmt/fmt.h"
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"
#include "libc/runtime/sysconf.h"
#include "libc/runtime/sysconf.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#ifndef UTIL /* This module contains no code for Zip Utilities */ #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) if (window != NULL)
free(window); /* window can't be a mapped file here */ free(window); /* window can't be a mapped file here */
window_size = (ulg)q + MIN_LOOKAHEAD; 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 /* If we can't touch the page beyond the end of file, we must
* allocate an extra page. * allocate an extra page.
*/ */
if (remain > MIN_LOOKAHEAD) { if (remain > MIN_LOOKAHEAD) {
window = (uch*)mmap(0, window_size, PROT_READ, MAP_PRIVATE, ifile, 0); window = (uch*)mmap(0, window_size, PROT_READ, MAP_PRIVATE, ifile, 0);
} else { } else {
window = (uch*)valloc(window_size - remain + FRAMESIZE); window = (uch*)pvalloc(window_size - remain + sysconf(_SC_PAGESIZE));
if (window != NULL) { if (window != NULL) {
window = (uch*)mmap((char*)window, window_size - remain, PROT_READ, window = (uch*)mmap((char*)window, window_size - remain, PROT_READ,
MAP_PRIVATE | MAP_FIXED, ifile, 0); MAP_PRIVATE | MAP_FIXED, ifile, 0);
} else { } else {
window = (uch*)(-1); window = (uch*)(-1);
} }

View file

@ -5,8 +5,9 @@
Use of this source code is governed by the BSD-style licenses that can Use of this source code is governed by the BSD-style licenses that can
be found in the third_party/zlib/LICENSE file. be found in the third_party/zlib/LICENSE file.
*/ */
#include "libc/intrin/bits.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/intrin/bits.h"
#include "libc/intrin/kprintf.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/nexgen32e/x86feature.h" #include "libc/nexgen32e/x86feature.h"
@ -119,7 +120,7 @@ Invented 1990 Phillip Walter Katz\"");
(uint64_t)((long)s->strstart - s->block_start), (last)); \ (uint64_t)((long)s->strstart - s->block_start), (last)); \
s->block_start = s->strstart; \ s->block_start = s->strstart; \
flush_pending(s->strm); \ 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 * are always equal when the other bytes match, given that
* the hash keys are equal and that HASH_BITS >= 8. * the hash keys are equal and that HASH_BITS >= 8.
*/ */
Assert(*scan == *match || scan[1] != match[1], "match[2]??");
scan += 2, match++; 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; /* We check for insufficient lookahead only every 8th comparison;
* the 256th check will be made at strstart+258. * 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, static void check_match(struct DeflateState *s, IPos start, IPos match,
int length) { int length) {
/* check that the match is indeed a match */ /* check that the match is indeed a match */
if (zmemcmp(s->window + match, s->window + start, length) != EQUAL) { if (memcmp(s->window + match, s->window + start, length) != EQUAL) {
fprintf(stderr, " start %u, match %u, length %d\n", start, match, length); kprintf(" start %u, match %u, length %d\n", start, match, length);
do { do {
fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); kprintf("%c%c", s->window[match++], s->window[start++]);
} while (--length != 0); } while (--length != 0);
z_error("invalid match"); z_error(__FILE__, __LINE__, "invalid match");
} }
if (z_verbose > 1) { if (z_verbose > 1) {
fprintf(stderr, "\\[%d,%d]", start - match, length); kprintf("\\[%d,%d]", start - match, length);
do { do {
putc(s->window[start++], stderr); kprintf("%c", s->window[start++]);
} while (--length != 0); } while (--length != 0);
} }
} }
@ -1640,7 +1649,7 @@ static block_state deflate_fast(struct DeflateState *s, int flush) {
} }
} else { } else {
/* No match, output a literal byte */ /* 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); _tr_tally_lit(s, s->window[s->strstart], bflush);
s->lookahead--; s->lookahead--;
s->strstart++; 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 * single literal. If there was a match but the current match
* is longer, truncate the previous match to a single literal. * 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); _tr_tally_lit(s, s->window[s->strstart - 1], bflush);
if (bflush) { if (bflush) {
FLUSH_BLOCK_ONLY(s, 0); 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?"); Assert(flush != Z_NO_FLUSH, "no flush?");
if (s->match_available) { 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); _tr_tally_lit(s, s->window[s->strstart - 1], bflush);
s->match_available = 0; s->match_available = 0;
} }
@ -1839,7 +1848,7 @@ static block_state deflate_rle(struct DeflateState *s, int flush) {
s->match_length = 0; s->match_length = 0;
} else { } else {
/* No match, output a literal byte */ /* 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); _tr_tally_lit(s, s->window[s->strstart], bflush);
s->lookahead--; s->lookahead--;
s->strstart++; s->strstart++;
@ -1873,7 +1882,7 @@ static block_state deflate_huff(struct DeflateState *s, int flush) {
} }
/* Output a literal byte */ /* Output a literal byte */
s->match_length = 0; 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); _tr_tally_lit(s, s->window[s->strstart], bflush);
s->lookahead--; s->lookahead--;
s->strstart++; s->strstart++;

View file

@ -280,9 +280,6 @@ void _tr_stored_block(struct DeflateState *s, charf *buf, uint64_t stored_len,
#define d_code(dist) \ #define d_code(dist) \
((dist) < 256 ? kZlibDistCode[dist] : kZlibDistCode[256 + ((dist) >> 7)]) ((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 kZlibStaticDtree[D_CODES] hidden;
extern const ct_data kZlibStaticLtree[L_CODES + 2] hidden; extern const ct_data kZlibStaticLtree[L_CODES + 2] hidden;
extern const int kZlibBaseDist[D_CODES] 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 kZlibDistCode[DIST_CODE_LEN] hidden;
extern const uint8_t kZlibLengthCode[MAX_MATCH - MIN_MATCH + 1] 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) \ #define _tr_tally_lit(s, c, flush) \
{ \ { \
uint8_t cc = (c); \ uint8_t cc = (c); \

View file

@ -46,7 +46,7 @@ int inflateBackInit(z_streamp strm, int windowBits, unsigned char *window) {
} }
state = (struct InflateState *)ZALLOC(strm, 1, sizeof(struct InflateState)); state = (struct InflateState *)ZALLOC(strm, 1, sizeof(struct InflateState));
if (state == Z_NULL) return Z_MEM_ERROR; if (state == Z_NULL) return Z_MEM_ERROR;
Tracev((stderr, "inflate: allocated\n")); Tracev(("inflate: allocated\n"));
strm->state = (struct DeflateState *)state; strm->state = (struct DeflateState *)state;
state->dmax = 32768U; state->dmax = 32768U;
state->wbits = (uInt)windowBits; state->wbits = (uInt)windowBits;
@ -54,6 +54,7 @@ int inflateBackInit(z_streamp strm, int windowBits, unsigned char *window) {
state->window = window; state->window = window;
state->wnext = 0; state->wnext = 0;
state->whave = 0; state->whave = 0;
state->sane = 0;
return Z_OK; return Z_OK;
} }
@ -97,7 +98,7 @@ static void fixedtables(struct InflateState *state) {
} }
state->lencode = lenfix; state->lencode = lenfix;
state->distcode = distfix; state->distcode = distfix;
#else /* !BUILDFIXED */ #else /* !BUILDFIXED */
state->lencode = kZlibLenfix; state->lencode = kZlibLenfix;
state->distcode = kZlibDistfix; state->distcode = kZlibDistfix;
#endif /* BUILDFIXED */ #endif /* BUILDFIXED */
@ -277,18 +278,18 @@ int inflateBack(z_streamp strm, in_func in, void *in_desc, out_func out,
DROPBITS(1); DROPBITS(1);
switch (BITS(2)) { switch (BITS(2)) {
case 0: /* stored block */ case 0: /* stored block */
Tracev((stderr, "inflate: stored block%s\n", Tracev(("inflate: stored block%s\n",
state->last ? " (last)" : "")); state->last ? " (last)" : ""));
state->mode = STORED; state->mode = STORED;
break; break;
case 1: /* fixed block */ case 1: /* fixed block */
fixedtables(state); fixedtables(state);
Tracev((stderr, "inflate: fixed codes block%s\n", Tracev(("inflate: fixed codes block%s\n",
state->last ? " (last)" : "")); state->last ? " (last)" : ""));
state->mode = LEN; /* decode codes */ state->mode = LEN; /* decode codes */
break; break;
case 2: /* dynamic block */ case 2: /* dynamic block */
Tracev((stderr, "inflate: dynamic codes block%s\n", Tracev(("inflate: dynamic codes block%s\n",
state->last ? " (last)" : "")); state->last ? " (last)" : ""));
state->mode = TABLE; state->mode = TABLE;
break; break;
@ -309,7 +310,7 @@ int inflateBack(z_streamp strm, in_func in, void *in_desc, out_func out,
break; break;
} }
state->length = (unsigned)hold & 0xffff; state->length = (unsigned)hold & 0xffff;
Tracev((stderr, "inflate: stored length %u\n", state->length)); Tracev(("inflate: stored length %u\n", state->length));
INITBITS(); INITBITS();
/* copy stored block from input to output */ /* 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; put += copy;
state->length -= copy; state->length -= copy;
} }
Tracev((stderr, "inflate: stored end\n")); Tracev(("inflate: stored end\n"));
state->mode = TYPE; state->mode = TYPE;
break; break;
@ -346,7 +347,7 @@ int inflateBack(z_streamp strm, in_func in, void *in_desc, out_func out,
break; break;
} }
#endif #endif
Tracev((stderr, "inflate: table sizes ok\n")); Tracev(("inflate: table sizes ok\n"));
/* get code length code lengths (not a typo) */ /* get code length code lengths (not a typo) */
state->have = 0; state->have = 0;
@ -366,7 +367,7 @@ int inflateBack(z_streamp strm, in_func in, void *in_desc, out_func out,
state->mode = BAD; state->mode = BAD;
break; break;
} }
Tracev((stderr, "inflate: code lengths ok\n")); Tracev(("inflate: code lengths ok\n"));
/* get length and distance code code lengths */ /* get length and distance code code lengths */
state->have = 0; state->have = 0;
@ -445,7 +446,7 @@ int inflateBack(z_streamp strm, in_func in, void *in_desc, out_func out,
state->mode = BAD; state->mode = BAD;
break; break;
} }
Tracev((stderr, "inflate: codes ok\n")); Tracev(("inflate: codes ok\n"));
state->mode = LEN; state->mode = LEN;
case LEN: case LEN:
@ -479,8 +480,7 @@ int inflateBack(z_streamp strm, in_func in, void *in_desc, out_func out,
/* process literal */ /* process literal */
if (here.op == 0) { if (here.op == 0) {
Tracevv((stderr, Tracevv((here.val >= 0x20 && here.val < 0x7f
here.val >= 0x20 && here.val < 0x7f
? "inflate: literal '%c'\n" ? "inflate: literal '%c'\n"
: "inflate: literal 0x%02x\n", : "inflate: literal 0x%02x\n",
here.val)); here.val));
@ -493,7 +493,7 @@ int inflateBack(z_streamp strm, in_func in, void *in_desc, out_func out,
/* process end of block */ /* process end of block */
if (here.op & 32) { if (here.op & 32) {
Tracevv((stderr, "inflate: end of block\n")); Tracevv(("inflate: end of block\n"));
state->mode = TYPE; state->mode = TYPE;
break; break;
} }
@ -512,7 +512,7 @@ int inflateBack(z_streamp strm, in_func in, void *in_desc, out_func out,
state->length += BITS(state->extra); state->length += BITS(state->extra);
DROPBITS(state->extra); DROPBITS(state->extra);
} }
Tracevv((stderr, "inflate: length %u\n", state->length)); Tracevv(("inflate: length %u\n", state->length));
/* get distance code */ /* get distance code */
for (;;) { for (;;) {
@ -551,7 +551,7 @@ int inflateBack(z_streamp strm, in_func in, void *in_desc, out_func out,
state->mode = BAD; state->mode = BAD;
break; break;
} }
Tracevv((stderr, "inflate: distance %u\n", state->offset)); Tracevv(("inflate: distance %u\n", state->offset));
/* copy match from window to output */ /* copy match from window to output */
do { do {
@ -574,25 +574,27 @@ int inflateBack(z_streamp strm, in_func in, void *in_desc, out_func out,
break; break;
case DONE: case DONE:
/* inflate stream terminated properly -- write leftover output */ /* inflate stream terminated properly */
ret = Z_STREAM_END; ret = Z_STREAM_END;
if (left < state->wsize) {
if (out(out_desc, state->window, state->wsize - left))
ret = Z_BUF_ERROR;
}
goto inf_leave; goto inf_leave;
case BAD: case BAD:
ret = Z_DATA_ERROR; ret = Z_DATA_ERROR;
goto inf_leave; goto inf_leave;
default: /* can't happen, but makes compilers happy */ default:
/* can't happen, but makes compilers happy */
ret = Z_STREAM_ERROR; ret = Z_STREAM_ERROR;
goto inf_leave; goto inf_leave;
} }
/* Return unused input */ /* Write leftover output and return unused input */
inf_leave: 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->next_in = next;
strm->avail_in = have; strm->avail_in = have;
return ret; return ret;
@ -603,6 +605,6 @@ int inflateBackEnd(z_streamp strm) {
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
ZFREE(strm, strm->state); ZFREE(strm, strm->state);
strm->state = Z_NULL; strm->state = Z_NULL;
Tracev((stderr, "inflate: end\n")); Tracev(("inflate: end\n"));
return Z_OK; return Z_OK;
} }

View file

@ -122,8 +122,7 @@ void inflate_fast(z_streamp strm, unsigned start) {
bits -= op; bits -= op;
op = (unsigned)(here.op); op = (unsigned)(here.op);
if (op == 0) { /* literal */ if (op == 0) { /* literal */
Tracevv((stderr, Tracevv((here.val >= 0x20 && here.val < 0x7f
here.val >= 0x20 && here.val < 0x7f
? "inflate: literal '%c'\n" ? "inflate: literal '%c'\n"
: "inflate: literal 0x%02x\n", : "inflate: literal 0x%02x\n",
here.val)); here.val));
@ -140,7 +139,7 @@ void inflate_fast(z_streamp strm, unsigned start) {
hold >>= op; hold >>= op;
bits -= op; bits -= op;
} }
Tracevv((stderr, "inflate: length %u\n", len)); Tracevv(("inflate: length %u\n", len));
if (bits < 15) { if (bits < 15) {
hold += (unsigned long)(*in++) << bits; hold += (unsigned long)(*in++) << bits;
bits += 8; bits += 8;
@ -174,7 +173,7 @@ void inflate_fast(z_streamp strm, unsigned start) {
#endif #endif
hold >>= op; hold >>= op;
bits -= op; bits -= op;
Tracevv((stderr, "inflate: distance %u\n", dist)); Tracevv(("inflate: distance %u\n", dist));
op = (unsigned)(out - beg); /* max distance in output */ op = (unsigned)(out - beg); /* max distance in output */
if (dist > op) { /* see if copy from window */ if (dist > op) { /* see if copy from window */
op = dist - op; /* distance back in 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))]; here = lcode[here.val + (hold & ((1U << op) - 1))];
goto dolen; goto dolen;
} else if (op & 32) { /* end-of-block */ } else if (op & 32) { /* end-of-block */
Tracevv((stderr, "inflate: end of block\n")); Tracevv(("inflate: end of block\n"));
state->mode = TYPE; state->mode = TYPE;
break; break;
} else { } else {

View file

@ -147,8 +147,7 @@ void inflate_fast_chunk(z_streamp strm, unsigned start) {
bits -= op; bits -= op;
op = (unsigned)(here.op); op = (unsigned)(here.op);
if (op == 0) { /* literal */ if (op == 0) { /* literal */
Tracevv((stderr, Tracevv((here.val >= 0x20 && here.val < 0x7f
here.val >= 0x20 && here.val < 0x7f
? "inflate: literal '%c'\n" ? "inflate: literal '%c'\n"
: "inflate: literal 0x%02x\n", : "inflate: literal 0x%02x\n",
here.val)); here.val));
@ -166,7 +165,7 @@ void inflate_fast_chunk(z_streamp strm, unsigned start) {
hold >>= op; hold >>= op;
bits -= op; bits -= op;
} }
Tracevv((stderr, "inflate: length %u\n", len)); Tracevv(("inflate: length %u\n", len));
if (bits < 15) { if (bits < 15) {
hold |= READ64LE(in) << bits; hold |= READ64LE(in) << bits;
in += 6; in += 6;
@ -196,7 +195,7 @@ void inflate_fast_chunk(z_streamp strm, unsigned start) {
#endif #endif
hold >>= op; hold >>= op;
bits -= op; bits -= op;
Tracevv((stderr, "inflate: distance %u\n", dist)); Tracevv(("inflate: distance %u\n", dist));
op = (unsigned)(out - beg); /* max distance in output */ op = (unsigned)(out - beg); /* max distance in output */
if (dist > op) { /* see if copy from window */ if (dist > op) { /* see if copy from window */
op = dist - op; /* distance back in 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))]; here = lcode[here.val + (hold & ((1U << op) - 1))];
goto dolen; goto dolen;
} else if (op & 32) { /* end-of-block */ } else if (op & 32) { /* end-of-block */
Tracevv((stderr, "inflate: end of block\n")); Tracevv(("inflate: end of block\n"));
state->mode = TYPE; state->mode = TYPE;
break; break;
} else { } else {

View file

@ -147,7 +147,7 @@ int inflateResetKeep(z_streamp strm) {
state->lencode = state->distcode = state->next = state->codes; state->lencode = state->distcode = state->next = state->codes;
state->sane = 1; state->sane = 1;
state->back = -1; state->back = -1;
Tracev((stderr, "inflate: reset\n")); Tracev(("inflate: reset\n"));
return Z_OK; return Z_OK;
} }
@ -207,7 +207,7 @@ int inflateInit2(z_streamp strm, int windowBits) {
} }
state = (struct InflateState *)ZALLOC(strm, 1, sizeof(struct InflateState)); state = (struct InflateState *)ZALLOC(strm, 1, sizeof(struct InflateState));
if (state == Z_NULL) return Z_MEM_ERROR; if (state == Z_NULL) return Z_MEM_ERROR;
Tracev((stderr, "inflate: allocated\n")); Tracev(("inflate: allocated\n"));
strm->state = (struct DeflateState *)state; strm->state = (struct DeflateState *)state;
state->strm = strm; state->strm = strm;
state->window = Z_NULL; state->window = Z_NULL;
@ -661,7 +661,7 @@ int inflate(z_streamp strm, int flush) {
break; break;
} }
state->dmax = 1U << len; 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); strm->adler = state->check = adler32(0L, Z_NULL, 0);
state->mode = hold & 0x200 ? DICTID : TYPE; state->mode = hold & 0x200 ? DICTID : TYPE;
INITBITS(); INITBITS();
@ -718,8 +718,9 @@ int inflate(z_streamp strm, int flush) {
copy = state->length; copy = state->length;
if (copy > have) copy = have; if (copy > have) copy = have;
if (copy) { if (copy) {
if (state->head != Z_NULL && state->head->extra != Z_NULL) { if (state->head != Z_NULL && state->head->extra != Z_NULL &&
len = state->head->extra_len - state->length; (len = state->head->extra_len - state->length) <
state->head->extra_max) {
memcpy(state->head->extra + len, next, memcpy(state->head->extra + len, next,
len + copy > state->head->extra_max len + copy > state->head->extra_max
? state->head->extra_max - len ? state->head->extra_max - len
@ -735,6 +736,7 @@ int inflate(z_streamp strm, int flush) {
} }
state->length = 0; state->length = 0;
state->mode = NAME; state->mode = NAME;
/* fallthrough */
case NAME: case NAME:
if (state->flags & 0x0800) { if (state->flags & 0x0800) {
if (have == 0) goto inf_leave; if (have == 0) goto inf_leave;
@ -815,13 +817,13 @@ int inflate(z_streamp strm, int flush) {
DROPBITS(1); DROPBITS(1);
switch (BITS(2)) { switch (BITS(2)) {
case 0: /* stored block */ case 0: /* stored block */
Tracev((stderr, "inflate: stored block%s\n", Tracev(("inflate: stored block%s\n",
state->last ? " (last)" : "")); state->last ? " (last)" : ""));
state->mode = STORED; state->mode = STORED;
break; break;
case 1: /* fixed block */ case 1: /* fixed block */
fixedtables(state); fixedtables(state);
Tracev((stderr, "inflate: fixed codes block%s\n", Tracev(("inflate: fixed codes block%s\n",
state->last ? " (last)" : "")); state->last ? " (last)" : ""));
state->mode = LEN_; /* decode codes */ state->mode = LEN_; /* decode codes */
if (flush == Z_TREES) { if (flush == Z_TREES) {
@ -830,7 +832,7 @@ int inflate(z_streamp strm, int flush) {
} }
break; break;
case 2: /* dynamic block */ case 2: /* dynamic block */
Tracev((stderr, "inflate: dynamic codes block%s\n", Tracev(("inflate: dynamic codes block%s\n",
state->last ? " (last)" : "")); state->last ? " (last)" : ""));
state->mode = TABLE; state->mode = TABLE;
break; break;
@ -849,7 +851,7 @@ int inflate(z_streamp strm, int flush) {
break; break;
} }
state->length = (unsigned)hold & 0xffff; state->length = (unsigned)hold & 0xffff;
Tracev((stderr, "inflate: stored length %u\n", state->length)); Tracev(("inflate: stored length %u\n", state->length));
INITBITS(); INITBITS();
state->mode = COPY_; state->mode = COPY_;
if (flush == Z_TREES) goto inf_leave; if (flush == Z_TREES) goto inf_leave;
@ -869,7 +871,7 @@ int inflate(z_streamp strm, int flush) {
state->length -= copy; state->length -= copy;
break; break;
} }
Tracev((stderr, "inflate: stored end\n")); Tracev(("inflate: stored end\n"));
state->mode = TYPE; state->mode = TYPE;
break; break;
case TABLE: case TABLE:
@ -887,7 +889,7 @@ int inflate(z_streamp strm, int flush) {
break; break;
} }
#endif #endif
Tracev((stderr, "inflate: table sizes ok\n")); Tracev(("inflate: table sizes ok\n"));
state->have = 0; state->have = 0;
state->mode = LENLENS; state->mode = LENLENS;
case LENLENS: case LENLENS:
@ -910,7 +912,7 @@ int inflate(z_streamp strm, int flush) {
state->mode = BAD; state->mode = BAD;
break; break;
} }
Tracev((stderr, "inflate: code lengths ok\n")); Tracev(("inflate: code lengths ok\n"));
state->have = 0; state->have = 0;
state->mode = CODELENS; state->mode = CODELENS;
case CODELENS: case CODELENS:
@ -989,7 +991,7 @@ int inflate(z_streamp strm, int flush) {
state->mode = BAD; state->mode = BAD;
break; break;
} }
Tracev((stderr, "inflate: codes ok\n")); Tracev(("inflate: codes ok\n"));
state->mode = LEN_; state->mode = LEN_;
if (flush == Z_TREES) goto inf_leave; if (flush == Z_TREES) goto inf_leave;
case LEN_: case LEN_:
@ -1023,8 +1025,7 @@ int inflate(z_streamp strm, int flush) {
state->back += here.bits; state->back += here.bits;
state->length = (unsigned)here.val; state->length = (unsigned)here.val;
if ((int)(here.op) == 0) { if ((int)(here.op) == 0) {
Tracevv((stderr, Tracevv((here.val >= 0x20 && here.val < 0x7f
here.val >= 0x20 && here.val < 0x7f
? "inflate: literal '%c'\n" ? "inflate: literal '%c'\n"
: "inflate: literal 0x%02x\n", : "inflate: literal 0x%02x\n",
here.val)); here.val));
@ -1032,7 +1033,7 @@ int inflate(z_streamp strm, int flush) {
break; break;
} }
if (here.op & 32) { if (here.op & 32) {
Tracevv((stderr, "inflate: end of block\n")); Tracevv(("inflate: end of block\n"));
state->back = -1; state->back = -1;
state->mode = TYPE; state->mode = TYPE;
break; break;
@ -1051,7 +1052,7 @@ int inflate(z_streamp strm, int flush) {
DROPBITS(state->extra); DROPBITS(state->extra);
state->back += 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->was = state->length;
state->mode = DIST; state->mode = DIST;
case DIST: case DIST:
@ -1095,7 +1096,7 @@ int inflate(z_streamp strm, int flush) {
break; break;
} }
#endif #endif
Tracevv((stderr, "inflate: distance %u\n", state->offset)); Tracevv(("inflate: distance %u\n", state->offset));
state->mode = MATCH; state->mode = MATCH;
case MATCH: case MATCH:
if (left == 0) goto inf_leave; if (left == 0) goto inf_leave;
@ -1109,7 +1110,7 @@ int inflate(z_streamp strm, int flush) {
break; break;
} }
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
Trace((stderr, "inflate.c too far\n")); Trace(("inflate.c too far\n"));
copy -= state->whave; copy -= state->whave;
if (copy > state->length) copy = state->length; if (copy > state->length) copy = state->length;
if (copy > left) copy = left; if (copy > left) copy = left;
@ -1166,7 +1167,7 @@ int inflate(z_streamp strm, int flush) {
break; break;
} }
INITBITS(); INITBITS();
Tracev((stderr, "inflate: check matches trailer\n")); Tracev(("inflate: check matches trailer\n"));
} }
#ifdef GUNZIP #ifdef GUNZIP
state->mode = LENGTH; state->mode = LENGTH;
@ -1179,7 +1180,7 @@ int inflate(z_streamp strm, int flush) {
break; break;
} }
INITBITS(); INITBITS();
Tracev((stderr, "inflate: length matches trailer\n")); Tracev(("inflate: length matches trailer\n"));
} }
#endif #endif
state->mode = DONE; state->mode = DONE;
@ -1245,7 +1246,7 @@ int inflateEnd(z_streamp strm) {
if (state->window != Z_NULL) ZFREE(strm, state->window); if (state->window != Z_NULL) ZFREE(strm, state->window);
ZFREE(strm, strm->state); ZFREE(strm, strm->state);
strm->state = Z_NULL; strm->state = Z_NULL;
Tracev((stderr, "inflate: end\n")); Tracev(("inflate: end\n"));
return Z_OK; return Z_OK;
} }
@ -1293,7 +1294,7 @@ int inflateSetDictionary(z_streamp strm, const Bytef *dictionary,
return Z_MEM_ERROR; return Z_MEM_ERROR;
} }
state->havedict = 1; state->havedict = 1;
Tracev((stderr, "inflate: dictionary set\n")); Tracev(("inflate: dictionary set\n"));
return Z_OK; return Z_OK;
} }

View file

@ -27,7 +27,7 @@ static const uint16_t kZlibDeflateLbase[31] = {
/* Length codes 257..285 extra */ /* Length codes 257..285 extra */
static const uint16_t kZlibDeflateLext[31] = { static const uint16_t kZlibDeflateLext[31] = {
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 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 */ /* Distance codes 0..29 base */
static const uint16_t kZlibDeflateDbase[32] = { static const uint16_t kZlibDeflateDbase[32] = {

View file

@ -5,6 +5,7 @@
Use of this source code is governed by the BSD-style licenses that can Use of this source code is governed by the BSD-style licenses that can
be found in the third_party/zlib/LICENSE file. be found in the third_party/zlib/LICENSE file.
*/ */
#include "libc/intrin/kprintf.h"
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "third_party/zlib/deflate.internal.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 */ /* Send a code of the given tree. c and tree must not have side effects */
#else /* !ZLIB_DEBUG */ #else /* !ZLIB_DEBUG */
#define send_code(s, c, tree) \ #define send_code(s, c, tree) \
{ \ { \
if (z_verbose > 2) fprintf(stderr, "\ncd %3d ", (c)); \ if (z_verbose > 2) kprintf("\ncd %3d ", (c)); \
send_bits(s, tree[c].Code, tree[c].Len); \ send_bits(s, tree[c].Code, tree[c].Len); \
} }
#endif #endif
@ -151,7 +152,7 @@ static void gen_trees_header(void);
*/ */
#ifdef ZLIB_DEBUG #ifdef ZLIB_DEBUG
static void send_bits(struct DeflateState *s, int value, int length) { 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"); Assert(length > 0 && length <= 15, "invalid length");
s->bits_sent += (uint64_t)length; s->bits_sent += (uint64_t)length;
/* If not enough room in bi_buf, use (valid) bits from bi_buf and /* 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; 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 */ /* This happens for example on obj2 and pic of the Calgary corpus */
/* Find the first bit length which could increase: */ /* 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]; m = s->heap[--h];
if (m > max_code) continue; if (m > max_code) continue;
if ((unsigned)tree[m].Len != (unsigned)bits) { 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; s->opt_len += ((uint64_t)bits - tree[m].Len) * tree[m].Freq;
tree[m].Len = (uint16_t)bits; 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, Assert(code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1,
"inconsistent bit counts"); "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++) { for (n = 0; n <= max_code; n++) {
int len = tree[n].Len; 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); tree[n].Code = (uint16_t)bi_reverse(next_code[len]++, len);
Tracecv(tree != kZlibStaticLtree, Tracecv(tree != kZlibStaticLtree,
(stderr, "\nn %3d %c l %2d c %4x (%x) ", n, (isgraph(n) ? n : ' '), ("\nn %3d %c l %2d c %4x (%x) ", n, (isgraph(n) ? n : ' '), len,
len, tree[n].Code, next_code[len] - 1)); 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; tree[n].Dad = tree[m].Dad = (uint16_t)node;
#ifdef DUMP_BL_TREE #ifdef DUMP_BL_TREE
if (tree == s->bl_tree) { if (tree == s->bl_tree) {
fprintf(stderr, "\nnode %d(%d), sons %d(%d) %d(%d)", node, kprintf("\nnode %d(%d), sons %d(%d) %d(%d)", node, tree[node].Freq, n,
tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); tree[n].Freq, m, tree[m].Freq);
} }
#endif #endif
/* and insert the new node in the heap */ /* 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 */ /* Update opt_len to include the bit length tree and counts */
s->opt_len += 3 * ((uint64_t)max_blindex + 1) + 5 + 5 + 4; 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; 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 >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
Assert(lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, Assert(lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
"too many 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, lcodes - 257, 5); /* not +255 as stated in appnote.txt */
send_bits(s, dcodes - 1, 5); send_bits(s, dcodes - 1, 5);
send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */
for (rank = 0; rank < blcodes; rank++) { 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); 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 */ 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 */ 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 */ /* Construct the literal and distance trees */
build_tree(s, (tree_desc *)(&(s->l_desc))); build_tree(s, (tree_desc *)(&(s->l_desc)));
Tracev( Tracev(("\nlit data: dyn %ld, stat %ld", s->opt_len, s->static_len));
(stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, s->static_len));
build_tree(s, (tree_desc *)(&(s->d_desc))); build_tree(s, (tree_desc *)(&(s->d_desc)));
Tracev( Tracev(("\ndist data: dyn %ld, stat %ld", s->opt_len, s->static_len));
(stderr, "\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 /* At this point, opt_len and static_len are the total bit lengths of
* the compressed block data, excluding the tree representations. * 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; opt_lenb = (s->opt_len + 3 + 7) >> 3;
static_lenb = (s->static_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->opt_len, static_lenb, s->static_len, stored_len,
s->sym_next / 3)); 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 */ s->compressed_len += 7; /* align on byte boundary */
#endif #endif
} }
Tracev((stderr, "\ncomprlen %lu(%lu) ", s->compressed_len >> 3, Tracev(("\ncomprlen %lu(%lu) ", s->compressed_len >> 3,
s->compressed_len - 7 * last)); 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++]; lc = s->sym_buf[sx++];
if (dist == 0) { if (dist == 0) {
send_code(s, lc, ltree); /* send a literal byte */ send_code(s, lc, ltree); /* send a literal byte */
Tracecv(isgraph(lc), (stderr, " '%c' ", lc)); Tracecv(isgraph(lc), (" '%c' ", lc));
} else { } else {
/* Here, lc is the match length - MIN_MATCH */ /* Here, lc is the match length - MIN_MATCH */
code = kZlibLengthCode[lc]; code = kZlibLengthCode[lc];

View file

@ -7,6 +7,10 @@
#define DEF_MEM_LEVEL 8 #define DEF_MEM_LEVEL 8
#define MAX_WBITS 15 /* 32K LZ77 window */ #define MAX_WBITS 15 /* 32K LZ77 window */
#ifdef MODE_DBG
#define ZLIB_DEBUG
#endif
#if !(__ASSEMBLER__ + __LINKER__ + 0) #if !(__ASSEMBLER__ + __LINKER__ + 0)
typedef unsigned char Byte; typedef unsigned char Byte;

View file

@ -5,6 +5,9 @@
Use of this source code is governed by the BSD-style licenses that can Use of this source code is governed by the BSD-style licenses that can
be found in the third_party/zlib/LICENSE file. 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 "libc/mem/mem.h"
#include "third_party/zlib/zutil.internal.h" #include "third_party/zlib/zutil.internal.h"
@ -117,9 +120,10 @@ uLong zlibCompileFlags() {
#endif #endif
int z_verbose hidden = verbose; int z_verbose hidden = verbose;
void z_error(char *m) { void z_error(const char *file, int line, char *m) {
fprintf(stderr, "%s\n", m); kprintf("%s:%d: zlib panic: %s\n", file, line, m);
exit(1); if (weaken(__die)) weaken(__die)();
_Exit(1);
} }
#endif #endif

View file

@ -1,5 +1,6 @@
#ifndef ZUTIL_H #ifndef ZUTIL_H
#define ZUTIL_H #define ZUTIL_H
#include "libc/intrin/kprintf.h"
#include "third_party/zlib/zlib.h" #include "third_party/zlib/zlib.h"
/* default windowBits for decompression. MAX_WBITS is for compression only */ /* 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 */ /* Diagnostic functions */
#ifdef ZLIB_DEBUG #ifdef ZLIB_DEBUG
#include "libc/stdio/stdio.h"
extern int z_verbose hidden; extern int z_verbose hidden;
extern void z_error(char *m) hidden; extern void z_error(const char *, int, char *) hidden;
#define Assert(cond, msg) \ #define Assert(cond, msg) \
{ \ { \
if (!(cond)) z_error(msg); \ if (!(cond)) { \
z_error(__FILE__, __LINE__, msg); \
} \
} }
#define Trace(x) \ #define Trace(x) \
{ \ { \
if (z_verbose >= 0) fprintf x; \ if (z_verbose >= 0) kprintf x; \
} }
#define Tracev(x) \ #define Tracev(x) \
{ \ { \
if (z_verbose > 0) fprintf x; \ if (z_verbose > 0) kprintf x; \
} }
#define Tracevv(x) \ #define Tracevv(x) \
{ \ { \
if (z_verbose > 1) fprintf x; \ if (z_verbose > 1) kprintf x; \
} }
#define Tracec(c, x) \ #define Tracec(c, x) \
{ \ { \
if (z_verbose > 0 && (c)) fprintf x; \ if (z_verbose > 0 && (c)) kprintf x; \
} }
#define Tracecv(c, x) \ #define Tracecv(c, x) \
{ \ { \
if (z_verbose > 1 && (c)) fprintf x; \ if (z_verbose > 1 && (c)) kprintf x; \
} }
#else #else
#define Assert(cond, msg) #define Assert(cond, msg)

View file

@ -17,6 +17,8 @@
"__SIZE_TYPE__" "__SIZE_TYPE__"
"__PTRDIFF_TYPE__" "__PTRDIFF_TYPE__"
"__WCHAR_TYPE__" "__WCHAR_TYPE__"
"__CHAR16_TYPE__"
"__CHAR32_TYPE__"
"__WINT_TYPE__" "__WINT_TYPE__"
"__INTMAX_TYPE__" "__INTMAX_TYPE__"
"__DEPRECATED" "__DEPRECATED"