mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-07 03:38:31 +00:00
Make numerous improvements
- Python static hello world now 1.8mb - Python static fully loaded now 10mb - Python HTTPS client now uses MbedTLS - Python REPL now completes import stmts - Increase stack size for Python for now - Begin synthesizing posixpath and ntpath - Restore Python \N{UNICODE NAME} support - Restore Python NFKD symbol normalization - Add optimized code path for Intel SHA-NI - Get more Python unit tests passing faster - Get Python help() pagination working on NT - Python hashlib now supports MbedTLS PBKDF2 - Make memcpy/memmove/memcmp/bcmp/etc. faster - Add Mersenne Twister and Vigna to LIBC_RAND - Provide privileged __printf() for error code - Fix zipos opendir() so that it reports ENOTDIR - Add basic chmod() implementation for Windows NT - Add Cosmo's best functions to Python cosmo module - Pin function trace indent depth to that of caller - Show memory diagram on invalid access in MODE=dbg - Differentiate stack overflow on crash in MODE=dbg - Add stb_truetype and tools for analyzing font files - Upgrade to UNICODE 13 and reduce its binary footprint - COMPILE.COM now logs resource usage of build commands - Start implementing basic poll() support on bare metal - Set getauxval(AT_EXECFN) to GetModuleFileName() on NT - Add descriptions to strerror() in non-TINY build modes - Add COUNTBRANCH() macro to help with micro-optimizations - Make error / backtrace / asan / memory code more unbreakable - Add fast perfect C implementation of μ-Law and a-Law audio codecs - Make strtol() functions consistent with other libc implementations - Improve Linenoise implementation (see also github.com/jart/bestline) - COMPILE.COM now suppresses stdout/stderr of successful build commands
This commit is contained in:
parent
fa7b4f5bd1
commit
39bf41f4eb
806 changed files with 77494 additions and 63859 deletions
|
@ -19,183 +19,123 @@
|
|||
#include "libc/assert.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/sysdebug.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/directmap.internal.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
typedef long long xmm_t __attribute__((__vector_size__(16), __aligned__(1)));
|
||||
|
||||
static noasan void *MoveMemoryNoAsan(void *dst, const void *src, size_t n) {
|
||||
size_t i;
|
||||
xmm_t v, w;
|
||||
char *d, *r;
|
||||
const char *s;
|
||||
uint64_t a, b;
|
||||
d = dst;
|
||||
s = src;
|
||||
switch (n) {
|
||||
case 9 ... 15:
|
||||
__builtin_memcpy(&a, s, 8);
|
||||
__builtin_memcpy(&b, s + n - 8, 8);
|
||||
__builtin_memcpy(d, &a, 8);
|
||||
__builtin_memcpy(d + n - 8, &b, 8);
|
||||
return d;
|
||||
case 5 ... 7:
|
||||
__builtin_memcpy(&a, s, 4);
|
||||
__builtin_memcpy(&b, s + n - 4, 4);
|
||||
__builtin_memcpy(d, &a, 4);
|
||||
__builtin_memcpy(d + n - 4, &b, 4);
|
||||
return d;
|
||||
case 17 ... 32:
|
||||
__builtin_memcpy(&v, s, 16);
|
||||
__builtin_memcpy(&w, s + n - 16, 16);
|
||||
__builtin_memcpy(d, &v, 16);
|
||||
__builtin_memcpy(d + n - 16, &w, 16);
|
||||
return d;
|
||||
case 16:
|
||||
__builtin_memcpy(&v, s, 16);
|
||||
__builtin_memcpy(d, &v, 16);
|
||||
return d;
|
||||
case 0:
|
||||
return d;
|
||||
case 1:
|
||||
*d = *s;
|
||||
return d;
|
||||
case 8:
|
||||
__builtin_memcpy(&a, s, 8);
|
||||
__builtin_memcpy(d, &a, 8);
|
||||
return d;
|
||||
case 4:
|
||||
__builtin_memcpy(&a, s, 4);
|
||||
__builtin_memcpy(d, &a, 4);
|
||||
return d;
|
||||
case 2:
|
||||
__builtin_memcpy(&a, s, 2);
|
||||
__builtin_memcpy(d, &a, 2);
|
||||
return d;
|
||||
case 3:
|
||||
__builtin_memcpy(&a, s, 2);
|
||||
__builtin_memcpy(&b, s + 1, 2);
|
||||
__builtin_memcpy(d, &a, 2);
|
||||
__builtin_memcpy(d + 1, &b, 2);
|
||||
return d;
|
||||
default:
|
||||
r = d;
|
||||
if (d > s) {
|
||||
do {
|
||||
n -= 32;
|
||||
__builtin_memcpy(&v, s + n, 16);
|
||||
__builtin_memcpy(&w, s + n + 16, 16);
|
||||
__builtin_memcpy(d + n, &v, 16);
|
||||
__builtin_memcpy(d + n + 16, &w, 16);
|
||||
} while (n >= 32);
|
||||
} else {
|
||||
i = 0;
|
||||
do {
|
||||
__builtin_memcpy(&v, s + i, 16);
|
||||
__builtin_memcpy(&w, s + i + 16, 16);
|
||||
__builtin_memcpy(d + i, &v, 16);
|
||||
__builtin_memcpy(d + i + 16, &w, 16);
|
||||
} while ((i += 32) + 32 <= n);
|
||||
d += i;
|
||||
s += i;
|
||||
n -= i;
|
||||
}
|
||||
switch (n) {
|
||||
case 0:
|
||||
return r;
|
||||
case 17 ... 31:
|
||||
__builtin_memcpy(&v, s, 16);
|
||||
__builtin_memcpy(&w, s + n - 16, 16);
|
||||
__builtin_memcpy(d, &v, 16);
|
||||
__builtin_memcpy(d + n - 16, &w, 16);
|
||||
return r;
|
||||
case 9 ... 15:
|
||||
__builtin_memcpy(&a, s, 8);
|
||||
__builtin_memcpy(&b, s + n - 8, 8);
|
||||
__builtin_memcpy(d, &a, 8);
|
||||
__builtin_memcpy(d + n - 8, &b, 8);
|
||||
return r;
|
||||
case 5 ... 7:
|
||||
__builtin_memcpy(&a, s, 4);
|
||||
__builtin_memcpy(&b, s + n - 4, 4);
|
||||
__builtin_memcpy(d, &a, 4);
|
||||
__builtin_memcpy(d + n - 4, &b, 4);
|
||||
return r;
|
||||
case 16:
|
||||
__builtin_memcpy(&v, s, 16);
|
||||
__builtin_memcpy(d, &v, 16);
|
||||
return r;
|
||||
case 8:
|
||||
__builtin_memcpy(&a, s, 8);
|
||||
__builtin_memcpy(d, &a, 8);
|
||||
return r;
|
||||
case 4:
|
||||
__builtin_memcpy(&a, s, 4);
|
||||
__builtin_memcpy(d, &a, 4);
|
||||
return r;
|
||||
case 1:
|
||||
*d = *s;
|
||||
return r;
|
||||
case 2:
|
||||
__builtin_memcpy(&a, s, 2);
|
||||
__builtin_memcpy(d, &a, 2);
|
||||
return r;
|
||||
case 3:
|
||||
__builtin_memcpy(&a, s, 2);
|
||||
__builtin_memcpy(&b, s + 1, 2);
|
||||
__builtin_memcpy(d, &a, 2);
|
||||
__builtin_memcpy(d + 1, &b, 2);
|
||||
return r;
|
||||
default:
|
||||
unreachable;
|
||||
}
|
||||
static noasan void *MoveMemoryIntervals(struct MemoryInterval *d,
|
||||
const struct MemoryInterval *s, int n) {
|
||||
int i;
|
||||
assert(n >= 0);
|
||||
if (d > s) {
|
||||
for (i = n; i--;) {
|
||||
d[i] = s[i];
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < n; ++i) {
|
||||
d[i] = s[i];
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
#ifndef __FSANITIZE_ADDRESS__
|
||||
#define MoveMemoryNoAsan memmove
|
||||
#endif
|
||||
|
||||
static noasan void RemoveMemoryIntervals(struct MemoryIntervals *mm, int i,
|
||||
int n) {
|
||||
assert(i >= 0);
|
||||
assert(i + n <= mm->i);
|
||||
MoveMemoryNoAsan(mm->p + i, mm->p + i + n,
|
||||
(intptr_t)(mm->p + mm->i) - (intptr_t)(mm->p + i + n));
|
||||
MoveMemoryIntervals(mm->p + i, mm->p + i + n, mm->i - (i + n));
|
||||
mm->i -= n;
|
||||
}
|
||||
|
||||
static noasan int CreateMemoryInterval(struct MemoryIntervals *mm, int i) {
|
||||
static noasan void MapNewMappingArray(struct MemoryIntervals *mm) {
|
||||
void *a;
|
||||
int i, x, y, g;
|
||||
size_t n, m, f;
|
||||
int prot, flags;
|
||||
struct DirectMap dm;
|
||||
struct MemoryInterval *p, *q;
|
||||
assert(mm->i);
|
||||
assert(AreMemoryIntervalsOk(mm));
|
||||
n = mm->n;
|
||||
n = n * sizeof(*mm->p);
|
||||
n = ROUNDUP(n, FRAMESIZE);
|
||||
if (mm->p == mm->s) {
|
||||
m = n;
|
||||
q = 0;
|
||||
} else {
|
||||
q = mm->p;
|
||||
m = n + (n >> 1);
|
||||
m = ROUNDUP(m, FRAMESIZE);
|
||||
}
|
||||
/*
|
||||
* find a hole in the automap range
|
||||
* we pad the sides for easier insertion logic
|
||||
* only time this fails is MODE=tiny which makes no stack
|
||||
*/
|
||||
i = 0;
|
||||
f = m >> 16;
|
||||
for (;;) {
|
||||
if (++i == mm->i || mm->p[i].x - mm->p[i - 1].y >= 1 + f + 1) {
|
||||
x = mm->p[i - 1].y + 1;
|
||||
y = x + f - 1;
|
||||
a = (void *)((intptr_t)((uint64_t)x << 32) >> 16);
|
||||
if (i == mm->i || (kAutomapStart <= (intptr_t)a &&
|
||||
(intptr_t)a + m < kAutomapStart + kAutomapSize)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED;
|
||||
prot = PROT_READ | PROT_WRITE;
|
||||
SYSDEBUG("MapNewMappingArray(0x%x, 0x%x) %d/%d/%d", a, m, i, mm->i, mm->n);
|
||||
dm = sys_mmap(a, m, prot, flags, -1, 0);
|
||||
if ((p = dm.addr) != MAP_FAILED) {
|
||||
MoveMemoryIntervals(p, mm->p, i);
|
||||
MoveMemoryIntervals(p + i + 1, mm->p + i, mm->i - i);
|
||||
mm->i += 1;
|
||||
mm->n = m / sizeof(*mm->p);
|
||||
mm->p = p;
|
||||
mm->p[i].x = x;
|
||||
mm->p[i].y = y;
|
||||
mm->p[i].h = dm.maphandle;
|
||||
mm->p[i].prot = prot;
|
||||
mm->p[i].flags = flags;
|
||||
if (q) {
|
||||
munmap(q, n);
|
||||
}
|
||||
if (IsAsan()) {
|
||||
__asan_map_shadow((uintptr_t)a, m);
|
||||
}
|
||||
SYSDEBUG("MapNewMappingArray() succeeded");
|
||||
} else {
|
||||
SYSDEBUG("MapNewMappingArray() failed: %s", strerror(errno));
|
||||
}
|
||||
assert(AreMemoryIntervalsOk(mm));
|
||||
}
|
||||
|
||||
noasan int CreateMemoryInterval(struct MemoryIntervals *mm, int i) {
|
||||
int rc;
|
||||
void *p;
|
||||
size_t n;
|
||||
static bool noreentry;
|
||||
rc = 0;
|
||||
assert(i >= 0);
|
||||
assert(i <= mm->i);
|
||||
assert(mm->i < mm->n);
|
||||
MoveMemoryNoAsan(mm->p + i + 1, mm->p + i,
|
||||
(intptr_t)(mm->p + mm->i) - (intptr_t)(mm->p + i));
|
||||
if (++mm->i > (mm->n >> 1) && cmpxchg(&noreentry, false, true)) {
|
||||
n = mm->n << 1;
|
||||
p = weaken(malloc) ? weaken(malloc)(n * sizeof(*mm->p)) : 0;
|
||||
if (p) {
|
||||
memcpy(p, mm->p, mm->i * sizeof(*mm->p));
|
||||
if (mm->p != mm->s && weaken(free)) {
|
||||
weaken(free)(mm->p);
|
||||
}
|
||||
mm->p = p;
|
||||
mm->n = n;
|
||||
} else {
|
||||
rc = enomem();
|
||||
}
|
||||
noreentry = false;
|
||||
assert(mm->n >= 0);
|
||||
if (mm->i == mm->n) {
|
||||
SYSDEBUG("CreateMemoryInterval() failed");
|
||||
return enomem();
|
||||
}
|
||||
MoveMemoryIntervals(mm->p + i + 1, mm->p + i, mm->i++ - i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -272,6 +212,9 @@ noasan int TrackMemoryInterval(struct MemoryIntervals *mm, int x, int y, long h,
|
|||
mm->p[i].h = h;
|
||||
mm->p[i].prot = prot;
|
||||
mm->p[i].flags = flags;
|
||||
if (mm->i >= mm->n / 2) {
|
||||
MapNewMappingArray(mm);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue