diff --git a/ape/ape.lds b/ape/ape.lds index 077ae3f91..7ca29a2c8 100644 --- a/ape/ape.lds +++ b/ape/ape.lds @@ -282,6 +282,9 @@ SECTIONS { KEEP(*(.textwindowsepilogue)) *(SORT_BY_ALIGNMENT(.text.modernity)) *(SORT_BY_ALIGNMENT(.text.modernity.*)) + HIDDEN(__text_syscall_start = .); + *(.text.syscall .text.syscall.*) + HIDDEN(__text_syscall_end = .); *(SORT_BY_ALIGNMENT(.text.hot)) *(SORT_BY_ALIGNMENT(.text.hot.*)) KEEP(*(.keep.text)) @@ -483,6 +486,10 @@ SHSTUB2(.Lape.macho.dd.skip, RVA(ape.macho) / 8); SHSTUB2(.Lape.macho.dd.count, (.Lape.macho.end - ape.macho) / 8); PFSTUB4(.Lape.pe.offset, ape.pe - ape.mz); +HIDDEN(__text_syscall_addr = ROUNDDOWN(__text_syscall_start, PAGESIZE)); +HIDDEN(__text_syscall_size = (ROUNDUP(__text_syscall_end, PAGESIZE) - + ROUNDDOWN(__text_syscall_start, PAGESIZE))); + HIDDEN(.Lape.pe.optsz = .Lape.pe.sections - (ape.pe + 24)); HIDDEN(.Lape.pe.shnum = (.Lape.pe.sections_end - .Lape.pe.sections) / 40); HIDDEN(.Lidata.idtsize = idata.idtend - idata.idt); diff --git a/build/config.mk b/build/config.mk index ea6e01e2f..90677eacb 100644 --- a/build/config.mk +++ b/build/config.mk @@ -94,8 +94,7 @@ CONFIG_CPPFLAGS += \ CONFIG_CCFLAGS += \ $(BACKTRACES) \ $(FTRACE) \ - -O1 \ - -fno-inline + -O2 CONFIG_COPTS += \ $(SECURITY_BLANKETS) \ diff --git a/examples/tiny-raw-linux-tutorial.S b/examples/tiny-raw-linux-tutorial.S index b851f9e60..2ae9f035e 100644 --- a/examples/tiny-raw-linux-tutorial.S +++ b/examples/tiny-raw-linux-tutorial.S @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.h" +.text.syscall / Tiny Raw Linux Binary Tutorial / diff --git a/libc/calls/chmod.c b/libc/calls/chmod.c index 334bbb665..7df6f93ad 100644 --- a/libc/calls/chmod.c +++ b/libc/calls/chmod.c @@ -42,7 +42,6 @@ * @errors ENOENT, ENOTDIR, ENOSYS * @asyncsignalsafe * @see fchmod() - * @syscall */ int chmod(const char *pathname, uint32_t mode) { if (!pathname) return efault(); diff --git a/libc/calls/clock_gettime.c b/libc/calls/clock_gettime.c index 25ac8e058..042c6ea39 100644 --- a/libc/calls/clock_gettime.c +++ b/libc/calls/clock_gettime.c @@ -50,7 +50,6 @@ * errno isn't restored to its original value, to detect prec. loss * @see strftime(), gettimeofday() * @asyncsignalsafe - * @syscall */ int clock_gettime(int clockid, struct timespec *out_ts) { /* TODO(jart): Just ignore O/S for MONOTONIC and measure RDTSC on start */ diff --git a/libc/calls/fadvise.c b/libc/calls/fadvise.c index 614348875..959884b6a 100644 --- a/libc/calls/fadvise.c +++ b/libc/calls/fadvise.c @@ -29,7 +29,6 @@ * @param len 0 means ‘til end of file * @param advice can be MADV_SEQUENTIAL, MADV_RANDOM, etc. * @return -1 on error - * @syscall */ int fadvise(int fd, uint64_t offset, uint64_t len, int advice) { if (!IsWindows()) { diff --git a/libc/calls/fallocate.c b/libc/calls/fallocate.c index 622641b16..e3c983c1b 100644 --- a/libc/calls/fallocate.c +++ b/libc/calls/fallocate.c @@ -38,7 +38,6 @@ * @return 0 on success, or -1 w/ errno * @note limited availability on rhel5 and openbsd * @see ftruncate() - * @syscall */ int fallocate(int fd, int32_t mode, int64_t offset, int64_t length) { int rc; diff --git a/libc/calls/fchmod.c b/libc/calls/fchmod.c index 86df1b92e..7c32f492f 100644 --- a/libc/calls/fchmod.c +++ b/libc/calls/fchmod.c @@ -40,7 +40,6 @@ * @errors ENOSYS * @asyncsignalsafe * @see chmod() - * @syscall */ int fchmod(int fd, uint32_t mode) { /* TODO(jart): Windows */ diff --git a/libc/calls/fchown.c b/libc/calls/fchown.c index f86e8ef12..92e821868 100644 --- a/libc/calls/fchown.c +++ b/libc/calls/fchown.c @@ -28,7 +28,6 @@ * @return 0 on success, or -1 w/ errno * @see /etc/passwd for user ids * @see /etc/group for group ids - * @syscall */ int fchown(int fd, uint32_t uid, uint32_t gid) { /* TODO(jart): Windows? */ diff --git a/libc/calls/fcntl.c b/libc/calls/fcntl.c index 157bca070..954daff77 100644 --- a/libc/calls/fcntl.c +++ b/libc/calls/fcntl.c @@ -29,7 +29,6 @@ * @param arg can be FD_CLOEXEC, etc. depending * @return 0 on success, or -1 w/ errno * @asyncsignalsafe - * @syscall */ int fcntl(int fd, int cmd, ...) { va_list va; diff --git a/libc/calls/fdatasync.c b/libc/calls/fdatasync.c index 59bed3393..9eacbbff3 100644 --- a/libc/calls/fdatasync.c +++ b/libc/calls/fdatasync.c @@ -26,7 +26,6 @@ * @return 0 on success, or -1 w/ errno * @see fsync(), sync_file_range() * @asyncsignalsafe - * @syscall */ int fdatasync(int fd) { if (!IsWindows()) { diff --git a/libc/calls/hefty/vfork.S b/libc/calls/hefty/vfork.S index 4821a69fb..021160cd2 100644 --- a/libc/calls/hefty/vfork.S +++ b/libc/calls/hefty/vfork.S @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/dce.h" #include "libc/macros.h" +.text.syscall / Forks process without copying page tables. / diff --git a/libc/calls/mprotect.greg.c b/libc/calls/mprotect.greg.c index 36a61d7a0..8c6558afc 100644 --- a/libc/calls/mprotect.greg.c +++ b/libc/calls/mprotect.greg.c @@ -34,7 +34,7 @@ extern __msabi typeof(VirtualProtect) *const __imp_VirtualProtect; * @return 0 on success, or -1 w/ errno * @see mmap() */ -int mprotect(void *addr, uint64_t len, int prot) { +textsyscall int mprotect(void *addr, uint64_t len, int prot) { bool cf; int64_t rc; uint32_t oldprot; diff --git a/libc/elf/elf.lds b/libc/elf/elf.lds index 845d938b2..87e553221 100644 --- a/libc/elf/elf.lds +++ b/libc/elf/elf.lds @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "ape/relocations.h" +#include "libc/macros.h" /** * @fileoverview Cosmopolitan ELF-Normative Linker Script. @@ -66,6 +67,9 @@ SECTIONS { .text : { *(SORT_BY_ALIGNMENT(.text.hot)) KEEP(*(.keep.text)) + HIDDEN(__text_syscall_start = .); + *(.text.syscall .text.syscall.*) + HIDDEN(__text_syscall_end = .); *(.text .text.*) KEEP(*(SORT_BY_NAME(.sort.text.*))) } @@ -207,3 +211,7 @@ SECTIONS { *(.*) } } + +HIDDEN(__text_syscall_addr = ROUNDDOWN(__text_syscall_start, PAGESIZE)); +HIDDEN(__text_syscall_size = (ROUNDUP(__text_syscall_end, PAGESIZE) - + ROUNDDOWN(__text_syscall_start, PAGESIZE))); diff --git a/libc/integral/c.inc b/libc/integral/c.inc index 56cc7d496..1a7e9dd85 100644 --- a/libc/integral/c.inc +++ b/libc/integral/c.inc @@ -618,6 +618,7 @@ typedef uint64_t uintmax_t; #define textexit _Section(".text.exit") noinstrument #define textreal _Section(".text.real") #define textwindows _Section(".text.windows") +#define textsyscall _Section(".text.syscall") #define antiquity _Section(".text.antiquity") #else #define testonly diff --git a/libc/intrin/asan.c b/libc/intrin/asan.c index 3d934be3b..3983a2a7a 100644 --- a/libc/intrin/asan.c +++ b/libc/intrin/asan.c @@ -374,7 +374,9 @@ static const char *__asan_dscribe_heap_poison(long c) { } } -static const char *__asan_describe_access_poison(int c) { +static const char *__asan_describe_access_poison(char *p) { + int c = p[0]; + if (1 <= c && c <= 7) c = p[1]; switch (c) { case kAsanHeapFree: return "heap use after free"; @@ -407,7 +409,7 @@ static const char *__asan_describe_access_poison(int c) { } } -static ssize_t __asan_write(const void *data, size_t size) { +static textsyscall ssize_t __asan_write(const void *data, size_t size) { ssize_t rc; if (weaken(write)) { if ((rc = weaken(write)(2, data, size)) != -1) { @@ -421,7 +423,7 @@ static ssize_t __asan_write_string(const char *s) { return __asan_write(s, __asan_strlen(s)); } -static wontreturn void __asan_exit(int rc) { +static textsyscall wontreturn void __asan_exit(int rc) { if (weaken(_Exit)) { weaken(_Exit)(rc); } else { @@ -431,6 +433,7 @@ static wontreturn void __asan_exit(int rc) { } static wontreturn void __asan_abort(void) { + if (weaken(__die)) weaken(__die)(); if (weaken(abort)) weaken(abort)(); __asan_exit(134); } @@ -468,7 +471,7 @@ static wontreturn void __asan_report_memory_fault(uint8_t *addr, int size, const char *kind) { char *p, ibuf[21], buf[256]; p = __asan_report_start(buf); - p = __asan_stpcpy(p, __asan_describe_access_poison(*SHADOW(addr))); + p = __asan_stpcpy(p, __asan_describe_access_poison(SHADOW(addr))); p = __asan_stpcpy(p, " "); p = __asan_mempcpy(p, ibuf, __asan_int2str(size, ibuf)); p = __asan_stpcpy(p, "-byte "); @@ -524,6 +527,7 @@ static void *__asan_allocate(size_t a, size_t n, int underrun, int overrun) { __asan_unpoison((uintptr_t)p, n); __asan_poison((uintptr_t)p - 16, 16, underrun); /* see dlmalloc design */ __asan_poison((uintptr_t)p + n, c - n, overrun); + __asan_memset(p, 0xF9, n); WRITE64BE(p + c - sizeof(n), n); } return p; @@ -664,6 +668,14 @@ void __asan_report_store_impl(uint8_t *addr, int size) { __asan_report_memory_fault(addr, size, "store"); } +void __asan_poison_stack_memory(uintptr_t addr, size_t size) { + __asan_poison(addr, size, kAsanStackFree); +} + +void __asan_unpoison_stack_memory(uintptr_t addr, size_t size) { + __asan_unpoison(addr, size); +} + void __asan_alloca_poison(uintptr_t addr, size_t size) { /* TODO(jart): Make sense of this function. */ /* __asan_poison(addr - 32, 32, kAsanAllocaUnderrun); */ diff --git a/libc/log/startfatal.c b/libc/log/startfatal.c index bc0cb46c4..abecaa951 100644 --- a/libc/log/startfatal.c +++ b/libc/log/startfatal.c @@ -17,9 +17,11 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" +#include "libc/fmt/itoa.h" #include "libc/log/color.internal.h" #include "libc/log/internal.h" #include "libc/runtime/runtime.h" +#include "libc/str/str.h" #include "libc/sysv/consts/fileno.h" /** @@ -29,6 +31,18 @@ * @see __start_fatal_ndebug() */ relegated void __start_fatal(const char *file, int line) { - dprintf(STDERR_FILENO, "%s%s%s%s:%s:%d:%s%s: ", CLS, RED, "error", BLUE1, - file, line, program_invocation_short_name, RESET); + char s[16 + 16 + 16 + 16 + PATH_MAX + 16 + NAME_MAX + 16], *p; + p = stpcpy(s, CLS); + p = stpcpy(p, RED); + p = stpcpy(p, "error"); + p = stpcpy(p, BLUE1); + p = stpcpy(p, ":"); + p = stpcpy(p, file); + p = stpcpy(p, ":"); + p += int64toarray_radix10(line, p); + p = stpcpy(p, ":"); + p = stpcpy(p, program_invocation_short_name); + p = stpcpy(p, RESET); + p = stpcpy(p, ": "); + write(2, s, p - s); } diff --git a/libc/macros.internal.inc b/libc/macros.internal.inc index 26a333f32..90c5aac7d 100644 --- a/libc/macros.internal.inc +++ b/libc/macros.internal.inc @@ -33,6 +33,9 @@ .macro .text.exit .section .text.exit,"ax",@progbits .endm +.macro .text.syscall + .section .text.syscall,"ax",@progbits +.endm .macro .firstclass .section .text.hot,"ax",@progbits .endm diff --git a/libc/nexgen32e/strcaseconv.S b/libc/nexgen32e/strcaseconv.S deleted file mode 100644 index ad0ff2d6f..000000000 --- a/libc/nexgen32e/strcaseconv.S +++ /dev/null @@ -1,100 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/nexgen32e/macros.h" -#include "libc/nexgen32e/x86feature.h" -#include "libc/macros.h" - -/ Mutates string to uppercase roman characters. -/ -/ @param RDI points to non-const NUL-terminated string -/ @return RAX will be original RDI -/ @note 10x faster than C -strtoupper: - mov $'A-'a,%edx # adding this uppers - mov $'a|'z<<8,%ecx # uint8_t range a..z - jmp strcaseconv - .endfn strtoupper,globl - -/ Mutates string to lowercase roman characters. -/ -/ @param RDI points to non-const NUL-terminated string -/ @return RAX will be original RDI -/ @note 10x faster than C -strtolower: - mov $'a-'A,%edx # adding this lowers - mov $'A|'Z<<8,%ecx # uint8_t range A..Z -/ 𝑠𝑙𝑖𝑑𝑒 - .endfn strtolower,globl - -/ Support code for strtolower() and strtoupper(). -/ -/ @param RDI points to non-const NUL-terminated string -/ @param CL defines start of character range to mutate -/ @param CH defines end of character range to mutate -/ @param DL is added to each DIL ∈ [CL,CH] -/ @return RAX will be original RDI -strcaseconv: - .leafprologue - .profilable - mov %rdi,%rsi -0: testb $15,%sil # is it aligned? -#if X86_NEED(SSE4_2) - jz .Lsse4 -#else - jnz 1f - testb X86_HAVE(SSE4_2)+kCpuids(%rip) - jnz .Lsse4 # is it nehalem? -#endif -1: lodsb # AL = *RSI++ - test %al,%al # is it NUL? - jz 3f - cmp %cl,%al # is it in range? - jb 0b - cmp %ch,%al - ja 0b - add %dl,-1(%rsi) - jmp 0b -.Lsse4: movd %ecx,%xmm1 # XMM1 = ['A,'Z,0,0,...] - movd %edx,%xmm2 # XMM2 = ['a-'A,'a-'A,...] - pbroadcastb %xmm2 - xor %ecx,%ecx -2: movdqa (%rsi,%rcx),%xmm3 -/ ┌─0:index of the LEAST significant, set, bit is used -/ │ regardless of corresponding input element validity -/ │ intres2 is returned in least significant bits of xmm0 -/ ├─1:index of the MOST significant, set, bit is used -/ │ regardless of corresponding input element validity -/ │ each bit of intres2 is expanded to byte/word -/ │┌─0:negation of intres1 is for all 16 (8) bits -/ │├─1:negation of intres1 is masked by reg/mem validity -/ ││┌─intres1 is negated (1’s complement) -/ │││┌─mode{equalany,ranges,equaleach,equalordered} -/ ││││ ┌─issigned -/ ││││ │┌─is16bit -/ u│││├┐││ - pcmpistrm $0b01000100,%xmm3,%xmm1 # →XMM0 8-bit byte mask - pand %xmm2,%xmm0 # won't mask after NUL - paddb %xmm0,%xmm3 - movdqa %xmm3,(%rsi,%rcx) - lea 16(%rcx),%rcx - jnz 2b # PCMPISTRM found NUL -3: mov %rdi,%rax - .leafepilogue - .endfn strcaseconv - .source __FILE__ diff --git a/libc/runtime/abort.S b/libc/runtime/abort.S index 36164db63..a2a24c9c5 100644 --- a/libc/runtime/abort.S +++ b/libc/runtime/abort.S @@ -21,7 +21,7 @@ #include "libc/sysv/consts/sig.h" #include "libc/sysv/consts/nr.h" #include "libc/macros.h" -.real +.text.syscall .source __FILE__ / Terminates program abnormally. diff --git a/libc/runtime/arch_prctl.c b/libc/runtime/arch_prctl.c index 4a148fa41..4f784b66a 100644 --- a/libc/runtime/arch_prctl.c +++ b/libc/runtime/arch_prctl.c @@ -95,7 +95,7 @@ static int arch_prctl$freebsd(int code, int64_t addr) { } } -static int arch_prctl$xnu(int code, int64_t addr) { +static textsyscall int arch_prctl$xnu(int code, int64_t addr) { int ax; switch (code) { case ARCH_SET_GS: @@ -113,7 +113,7 @@ static int arch_prctl$xnu(int code, int64_t addr) { } } -static int arch_prctl$openbsd(int code, int64_t addr) { +static textsyscall int arch_prctl$openbsd(int code, int64_t addr) { int64_t rax; switch (code) { case ARCH_GET_FS: diff --git a/libc/runtime/exit3.S b/libc/runtime/exit3.S index 5b12aa34e..421977f67 100644 --- a/libc/runtime/exit3.S +++ b/libc/runtime/exit3.S @@ -19,7 +19,7 @@ #include "libc/dce.h" #include "libc/runtime/internal.h" #include "libc/macros.h" -.privileged +.text.syscall .source __FILE__ / Terminates process, ignoring destructors and atexit() handlers. diff --git a/libc/runtime/print.greg.c b/libc/runtime/print.greg.c index 6d06456ba..8e18dda60 100644 --- a/libc/runtime/print.greg.c +++ b/libc/runtime/print.greg.c @@ -28,7 +28,7 @@ #define WasImported(SLOT) \ ((void *)*SLOT && *SLOT != (void *)&missingno /* see libc/crt/crt.S */) -static privileged void __print$nt(const void *data, size_t len) { +static void __print$nt(const void *data, size_t len) { int64_t hand; char xmm[256]; uint32_t wrote; @@ -49,7 +49,7 @@ static privileged void __print$nt(const void *data, size_t len) { * @param len can be computed w/ tinystrlen() * @clob nothing except flags */ -privileged void __print(const void *data, size_t len) { +textsyscall void __print(const void *data, size_t len) { int64_t ax, ordinal; if (WasImported(__imp_WriteFile)) { __print$nt(data, len); @@ -68,7 +68,7 @@ privileged void __print(const void *data, size_t len) { } } -privileged void __print_string(const char *s) { +void __print_string(const char *s) { size_t n = 0; while (s[n]) ++n; __print(s, n); diff --git a/libc/runtime/stackchkfail.c b/libc/runtime/stackchkfail.c index a9a604104..ff2c1da82 100644 --- a/libc/runtime/stackchkfail.c +++ b/libc/runtime/stackchkfail.c @@ -29,7 +29,7 @@ /** * Aborts program under enemy fire to avoid being taken alive. */ -void __stack_chk_fail(void) { +textsyscall void __stack_chk_fail(void) { size_t len; const char *msg; int64_t ax, cx, si; diff --git a/libc/str/memccpy.c b/libc/str/memccpy.c index c982372a4..adcd21eec 100644 --- a/libc/str/memccpy.c +++ b/libc/str/memccpy.c @@ -18,7 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/str/str.h" -static noasan uint64_t UncheckedAlignedRead64(unsigned char *p) { +static inline noasan uint64_t UncheckedAlignedRead64(unsigned char *p) { return (uint64_t)p[7] << 070 | (uint64_t)p[6] << 060 | (uint64_t)p[5] << 050 | (uint64_t)p[4] << 040 | (uint64_t)p[3] << 030 | (uint64_t)p[2] << 020 | (uint64_t)p[1] << 010 | (uint64_t)p[0] << 000; diff --git a/libc/str/pututf16.ncabi.c b/libc/str/pututf16.ncabi.c index 9f53e49a6..5023c7550 100644 --- a/libc/str/pututf16.ncabi.c +++ b/libc/str/pututf16.ncabi.c @@ -19,6 +19,8 @@ #include "libc/str/oldutf16.internal.h" #include "libc/str/str.h" +/* TODO(jart): DELETE */ + /** * Encodes character to string as UTF-16. * diff --git a/libc/str/rawmemchr.c b/libc/str/rawmemchr.c index dab660dc2..4ffd31621 100644 --- a/libc/str/rawmemchr.c +++ b/libc/str/rawmemchr.c @@ -19,7 +19,7 @@ #include "libc/assert.h" #include "libc/str/str.h" -static noasan uint64_t UncheckedAlignedRead64(unsigned char *p) { +static inline noasan uint64_t UncheckedAlignedRead64(unsigned char *p) { return (uint64_t)p[7] << 070 | (uint64_t)p[6] << 060 | (uint64_t)p[5] << 050 | (uint64_t)p[4] << 040 | (uint64_t)p[3] << 030 | (uint64_t)p[2] << 020 | (uint64_t)p[1] << 010 | (uint64_t)p[0] << 000; diff --git a/libc/str/str.h b/libc/str/str.h index 740227ec2..5def2bd4e 100644 --- a/libc/str/str.h +++ b/libc/str/str.h @@ -187,7 +187,6 @@ char16_t *tinystrstr16(const char16_t *, const char16_t *) strlenesque; void *tinymemmem(const void *, size_t, const void *, size_t) strlenesque; void *tinymemccpy(void *, const void *, int, size_t) memcpyesque; -void *memtolower(void *, size_t); char *strntolower(char *, size_t); char *strtolower(char *) paramsnonnull(); char *strntoupper(char *, size_t); diff --git a/libc/str/strntoupper.c b/libc/str/strntoupper.c index 48155a403..dea8994ae 100644 --- a/libc/str/strntoupper.c +++ b/libc/str/strntoupper.c @@ -18,16 +18,18 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/str/str.h" +/** + * Mutates string to ASCII uppercase w/ limit. + * + * @praam s is string + * @praam n is max bytes to consider + * @return string + */ char *strntoupper(char *s, size_t n) { - unsigned char *p = (unsigned char *)s; - for (;;) { - if (n-- && *p) { - if ('a' <= *p && *p <= 'z') { - *p -= 'a' - 'A'; - } - ++p; - } else { - break; + size_t i; + for (i = 0; s[i] && i < n; ++i) { + if ('a' <= s[i] && s[i] <= 'z') { + s[i] -= 'a' - 'A'; } } return s; diff --git a/libc/str/ctz.c b/libc/str/strtolower.c similarity index 87% rename from libc/str/ctz.c rename to libc/str/strtolower.c index 40f21d3fa..54a63a2ee 100644 --- a/libc/str/ctz.c +++ b/libc/str/strtolower.c @@ -16,9 +16,20 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/math.h" -#include "libc/nexgen32e/nexgen32e.h" +#include "libc/str/str.h" -bool ctz(double x, double y) { - return __builtin_islessgreater(x, y); +/** + * Mutates string to ASCII lowercase. + * + * @praam s is string + * @return string + */ +char *strtolower(char *s) { + size_t i; + for (i = 0; s[i]; ++i) { + if ('A' <= s[i] && s[i] <= 'Z') { + s[i] += 'a' - 'A'; + } + } + return s; } diff --git a/libc/str/strtoupper.c b/libc/str/strtoupper.c new file mode 100644 index 000000000..2ff4505d8 --- /dev/null +++ b/libc/str/strtoupper.c @@ -0,0 +1,35 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/str/str.h" + +/** + * Mutates string to ASCII uppercase. + * + * @praam s is string + * @return string + */ +char *strtoupper(char *s) { + size_t i; + for (i = 0; s[i]; ++i) { + if ('a' <= s[i] && s[i] <= 'z') { + s[i] -= 'a' - 'A'; + } + } + return s; +} diff --git a/libc/str/tinymemmem.c b/libc/str/tinymemmem.c index b6e67ca77..dcc9476b8 100644 --- a/libc/str/tinymemmem.c +++ b/libc/str/tinymemmem.c @@ -17,15 +17,21 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/str/str.h" -#include "libc/str/tinymemmem.internal.h" /** * Naïve substring search implementation. * @see libc/alg/memmem.c */ -void *tinymemmem(const void *haystk, size_t haystksize, const void *needle, +void *tinymemmem(const void *haystack, size_t haystacksize, const void *needle, size_t needlesize) { - return (/*unconst*/ void *)tinymemmemi( - (const unsigned char *)haystk, haystksize, (const unsigned char *)needle, - needlesize); + size_t i; + const char *p, *pe; + for (p = haystack, pe = p + haystacksize; p < pe;) { + for (++p, i = 0;;) { + if (++i > needlesize) return p - 1; + if (p == pe) break; + if (((const char *)needle)[i - 1] != (p - 1)[i - 1]) break; + } + } + return !haystacksize && !needlesize ? haystack : NULL; } diff --git a/libc/str/tinymemmem.internal.h b/libc/str/tinymemmem.internal.h deleted file mode 100644 index c96fccd32..000000000 --- a/libc/str/tinymemmem.internal.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef COSMOPOLITAN_LIBC_STR_TINYSTRSTR_H_ -#define COSMOPOLITAN_LIBC_STR_TINYSTRSTR_H_ -#ifndef __STRICT_ANSI__ -#include "libc/str/str.h" -#if !(__ASSEMBLER__ + __LINKER__ + 0) - -forceinline void *tinymemmemi(const void *haystk, size_t haystksize, - const void *needle, size_t needlesize) { - const char *p = (const char *)haystk; - const char *pe = (const char *)haystk + haystksize; - while (p < pe) { - size_t i = 0; - ++p; - for (;;) { - ++i; - if (i > needlesize) return (/*unconst*/ char *)(p - 1); - if (p == pe) break; - if (((const char *)needle)[i - 1] != (p - 1)[i - 1]) break; - } - } - return (/*unconst*/ char *)(!haystksize && !needlesize ? haystk : NULL); -} - -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#endif /* !ANSI */ -#endif /* COSMOPOLITAN_LIBC_STR_TINYMEMMEM_H_ */ diff --git a/libc/str/tinystrstr.c b/libc/str/tinystrstr.c index 4437049a5..86a53d3eb 100644 --- a/libc/str/tinystrstr.c +++ b/libc/str/tinystrstr.c @@ -17,13 +17,22 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/str/internal.h" -#include "libc/str/tinystrstr.internal.h" /** * Naïve substring search implementation. * @see libc/str/strstr.c * @asyncsignalsafe */ -char *(tinystrstr)(const char *haystack, const char *needle) { - return (/*unconst*/ char *)tinystrstr(haystack, needle); +char *tinystrstr(const char *haystack, const char *needle) { + size_t i; + for (;;) { + for (i = 0;;) { + if (!needle[i]) return (/*unconst*/ char *)haystack; + if (!haystack[i]) break; + if (needle[i] != haystack[i]) break; + ++i; + } + if (!*haystack++) break; + } + return NULL; } diff --git a/libc/str/tinystrstr.internal.h b/libc/str/tinystrstr.internal.h deleted file mode 100644 index 3c050339e..000000000 --- a/libc/str/tinystrstr.internal.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef COSMOPOLITAN_LIBC_STR_TINYSTRSTR_H_ -#define COSMOPOLITAN_LIBC_STR_TINYSTRSTR_H_ -#include "libc/str/str.h" -#if !(__ASSEMBLER__ + __LINKER__ + 0) - -#define tinystrstr(HAYSTACK, NEEDLE) \ - ({ \ - autotype(HAYSTACK) Haystack = (HAYSTACK); \ - typeof(Haystack) Needle = (NEEDLE); \ - for (;;) { \ - size_t i = 0; \ - for (;;) { \ - if (!Needle[i]) goto Found; \ - if (!Haystack[i]) break; \ - if (Needle[i] != Haystack[i]) break; \ - ++i; \ - } \ - if (!*Haystack++) break; \ - } \ - Haystack = NULL; \ - Found: \ - Haystack; \ - }) - -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#endif /* COSMOPOLITAN_LIBC_STR_TINYSTRSTR_H_ */ diff --git a/libc/str/tinystrstr16.c b/libc/str/tinystrstr16.c index 49614ef18..a17195684 100644 --- a/libc/str/tinystrstr16.c +++ b/libc/str/tinystrstr16.c @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/str/internal.h" -#include "libc/str/tinystrstr.internal.h" /** * Naïve substring search implementation. @@ -25,5 +24,15 @@ * @asyncsignalsafe */ char16_t *tinystrstr16(const char16_t *haystack, const char16_t *needle) { - return (/*unconst*/ char16_t *)tinystrstr(haystack, needle); + size_t i; + for (;;) { + for (i = 0;;) { + if (!needle[i]) return (/*unconst*/ char16_t *)haystack; + if (!haystack[i]) break; + if (needle[i] != haystack[i]) break; + ++i; + } + if (!*haystack++) break; + } + return NULL; } diff --git a/libc/str/tpdecode.ncabi.c b/libc/str/tpdecode.ncabi.c index 5b1511549..24d0c13e0 100644 --- a/libc/str/tpdecode.ncabi.c +++ b/libc/str/tpdecode.ncabi.c @@ -21,6 +21,8 @@ #include "libc/str/tpdecode.internal.h" #include "libc/str/tpdecodecb.internal.h" +/* TODO(jart): DELETE */ + forceinline int getbyte(void *arg, uint32_t i) { return ((const unsigned char *)arg)[i]; } diff --git a/libc/str/tpenc.h b/libc/str/tpenc.h index 0400a1bdc..f72d6d66c 100644 --- a/libc/str/tpenc.h +++ b/libc/str/tpenc.h @@ -6,19 +6,14 @@ COSMOPOLITAN_C_START_ uint64_t tpenc(int32_t) pureconst; #ifndef __STRICT_ANSI__ -#define tpenc(CODE) \ - ({ \ - long Buf; \ - int32_t Code = (CODE); \ - if (0 <= Code && Code <= 127) { \ - Buf = Code; \ - } else { \ - asm("call\ttpenc" \ - : "=a"(Buf), "+D"(Code) \ - : /* inputs */ \ - : "rcx", "rdx", "cc"); \ - } \ - Buf; \ +#define tpenc(CODE) \ + ({ \ + long Edi, Buf; \ + asm("call\ttpenc" \ + : "=a"(Buf), "=D"(Edi) \ + : "1"(CODE) \ + : "rcx", "rdx", "cc"); \ + Buf; \ }) #endif diff --git a/libc/stubs/asan.S b/libc/stubs/asan.S index e3a750ce5..3cd9388d4 100644 --- a/libc/stubs/asan.S +++ b/libc/stubs/asan.S @@ -22,253 +22,367 @@ / @fileoverview Address Sanitizer Linker Poison __asan_addr_is_in_fake_stack: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_addr_is_in_fake_stack,weak __asan_after_dynamic_init: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_after_dynamic_init,weak __asan_alloca_poison: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_alloca_poison,weak __asan_allocas_unpoison: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_allocas_unpoison,weak __asan_before_dynamic_init: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_before_dynamic_init,weak __asan_get_current_fake_stack: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_get_current_fake_stack,weak __asan_handle_no_return: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_handle_no_return,weak __asan_init: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_init,weak __asan_load1: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_load1,weak __asan_load2: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_load2,weak __asan_load4: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_load4,weak __asan_load8: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_load8,weak __asan_load16: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_load16,weak __asan_load32: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_load32,weak __asan_option_detect_stack_use_after_return: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_option_detect_stack_use_after_return,weak -__asan_poison_stack_memory: - ud2 - .endfn __asan_poison_stack_memory,weak - __asan_register_globals: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_register_globals,weak __asan_report_load1: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_report_load1,weak __asan_report_load2: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_report_load2,weak __asan_report_load4: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_report_load4,weak __asan_report_load8: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_report_load8,weak __asan_report_load16: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_report_load16,weak __asan_report_load_n: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_report_load_n,weak __asan_report_store1: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_report_store1,weak __asan_report_store2: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_report_store2,weak __asan_report_store4: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_report_store4,weak __asan_report_store8: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_report_store8,weak __asan_report_store16: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_report_store16,weak __asan_report_store32: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_report_store32,weak __asan_report_store_n: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_report_store_n,weak __asan_stack_free: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_free,weak __asan_stack_free_0: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_free_0,weak __asan_stack_free_1: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_free_1,weak __asan_stack_free_10: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_free_10,weak __asan_stack_free_2: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_free_2,weak __asan_stack_free_3: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_free_3,weak __asan_stack_free_4: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_free_4,weak __asan_stack_free_5: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_free_5,weak __asan_stack_free_6: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_free_6,weak __asan_stack_free_7: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_free_7,weak __asan_stack_free_8: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_free_8,weak __asan_stack_free_9: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_free_9,weak __asan_stack_malloc: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_malloc,weak __asan_stack_malloc_0: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_malloc_0,weak __asan_stack_malloc_1: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_malloc_1,weak __asan_stack_malloc_2: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_malloc_2,weak __asan_stack_malloc_3: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_malloc_3,weak __asan_stack_malloc_4: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_malloc_4,weak __asan_stack_malloc_5: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_malloc_5,weak __asan_stack_malloc_6: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_malloc_6,weak __asan_stack_malloc_7: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_malloc_7,weak __asan_stack_malloc_8: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_malloc_8,weak __asan_stack_malloc_9: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_malloc_9,weak __asan_stack_malloc_10: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_stack_malloc_10,weak __asan_store1: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_store1,weak __asan_store2: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_store2,weak __asan_store4: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_store4,weak __asan_store8: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_store8,weak __asan_store16: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_store16,weak __asan_store32: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_store32,weak -__asan_unpoison_stack_memory: - ud2 - .endfn __asan_unpoison_stack_memory,weak - __asan_unregister_globals: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_unregister_globals,weak __asan_version_mismatch_check_v8: + push %rbp + mov %rsp,%rbp ud2 .endfn __asan_version_mismatch_check_v8,weak diff --git a/libc/sysv/calls/msyscall.s b/libc/sysv/calls/msyscall.s new file mode 100644 index 000000000..1eb00f37d --- /dev/null +++ b/libc/sysv/calls/msyscall.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall msyscall 0x0025ffffffffffff globl diff --git a/libc/sysv/consts.sh b/libc/sysv/consts.sh index d7544d1fe..3c3d458c4 100755 --- a/libc/sysv/consts.sh +++ b/libc/sysv/consts.sh @@ -237,8 +237,9 @@ syscon mmap MAP_SHARED 1 1 1 1 1 # forced consensus & faked nt syscon mmap MAP_PRIVATE 2 2 2 2 2 # forced consensus & faked nt syscon mmap MAP_FIXED 0x10 0x10 0x10 0x10 0x10 # unix consensus; openbsd appears to forbid; faked nt syscon mmap MAP_ANONYMOUS 0x20 0x1000 0x1000 0x1000 0x20 # bsd consensus; faked nt +syscon mmap MAP_GROWSDOWN 0x0100 0 0x0400 0x4000 0x100000 # mandatory for OpenBSD stacks; MAP_STACK on Free/OpenBSD; MEM_TOP_DOWN on NT +syscon mmap MAP_CONCEAL 0 0 0x20000 0x8000 0 # omit from core dumps; MAP_NOCORE on FreeBSD syscon mmap MAP_NORESERVE 0x4000 0x40 0 0 0 # Linux calls it "reserve"; NT calls it "commit"? which is default? -syscon mmap MAP_GROWSDOWN 0x0100 0 0x0400 0x0400 0x100000 # MAP_STACK on BSD; MEM_TOP_DOWN on NT syscon mmap MAP_HUGETLB 0x040000 0 0 0 0x80000000 # kNtSecLargePages syscon mmap MAP_HUGE_MASK 63 0 0 0 0 syscon mmap MAP_HUGE_SHIFT 26 0 0 0 0 @@ -246,6 +247,8 @@ syscon mmap MAP_LOCKED 0x2000 0 0 0 0 syscon mmap MAP_NONBLOCK 0x10000 0 0 0 0 syscon mmap MAP_POPULATE 0x8000 0 0 0 0 # can avoid madvise(MADV_WILLNEED) on private file mapping syscon mmap MAP_TYPE 15 0 0 0 0 # what is it +syscon compat MAP_STACK 0x0100 0 0x0400 0x4000 0x100000 # use MAP_GROWSDOWN +syscon compat MAP_NOCORE 0 0 0x20000 0x8000 0 # use MAP_CONCEAL syscon compat MAP_ANON 0x20 0x1000 0x1000 0x1000 0x20 # bsd consensus; faked nt syscon compat MAP_STACK 0x020000 0 0x0400 0x4000 0x100000 syscon compat MAP_EXECUTABLE 0x1000 0 0 0 0 # ignored @@ -3112,6 +3115,7 @@ syscon nr __NR_io_uring_setup 0x01a9 -1 -1 -1 -1 syscon nr __NR_io_uring_enter 0x01aa -1 -1 -1 -1 syscon nr __NR_io_uring_register 0x01ab -1 -1 -1 -1 syscon nr __NR_pledge -1 -1 -1 0x006c -1 +syscon nr __NR_msyscall -1 -1 -1 0x0025 -1 syscon nr __NR_ktrace -1 -1 0x002d 0x002d -1 syscon nr __NR_kqueue -1 0x200016a 0x016a 0x010d -1 syscon nr __NR_kevent -1 0x2000171 0x0230 0x0048 -1 diff --git a/libc/sysv/consts/MAP_CONCEAL.s b/libc/sysv/consts/MAP_CONCEAL.s new file mode 100644 index 000000000..9b1d09cfd --- /dev/null +++ b/libc/sysv/consts/MAP_CONCEAL.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon mmap MAP_CONCEAL 0 0 0x20000 0x8000 0 diff --git a/libc/sysv/consts/MAP_GROWSDOWN.s b/libc/sysv/consts/MAP_GROWSDOWN.s index 984d336a9..af235cba3 100644 --- a/libc/sysv/consts/MAP_GROWSDOWN.s +++ b/libc/sysv/consts/MAP_GROWSDOWN.s @@ -1,2 +1,2 @@ .include "libc/sysv/consts/syscon.inc" -.syscon mmap MAP_GROWSDOWN 0x0100 0 0x0400 0x0400 0x100000 +.syscon mmap MAP_GROWSDOWN 0x0100 0 0x0400 0x4000 0x100000 diff --git a/libc/sysv/consts/MAP_NOCORE.s b/libc/sysv/consts/MAP_NOCORE.s new file mode 100644 index 000000000..57c215aa6 --- /dev/null +++ b/libc/sysv/consts/MAP_NOCORE.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon compat MAP_NOCORE 0 0 0x20000 0x8000 0 diff --git a/libc/sysv/consts/__NR_msyscall.s b/libc/sysv/consts/__NR_msyscall.s new file mode 100644 index 000000000..6fafd5ff5 --- /dev/null +++ b/libc/sysv/consts/__NR_msyscall.s @@ -0,0 +1,2 @@ +.include "libc/sysv/consts/syscon.inc" +.syscon nr __NR_msyscall -1 -1 -1 0x0025 -1 diff --git a/libc/sysv/consts/map.h b/libc/sysv/consts/map.h index 5c3681e9d..2778fd452 100644 --- a/libc/sysv/consts/map.h +++ b/libc/sysv/consts/map.h @@ -21,7 +21,6 @@ hidden extern const long MAP_NORESERVE; hidden extern const long MAP_POPULATE; hidden extern const long MAP_PRIVATE; hidden extern const long MAP_SHARED; -hidden extern const long MAP_STACK; hidden extern const long MAP_TYPE; COSMOPOLITAN_C_END_ @@ -34,6 +33,7 @@ COSMOPOLITAN_C_END_ #define MAP_32BIT SYMBOLIC(MAP_32BIT) #define MAP_ANONYMOUS SYMBOLIC(MAP_ANONYMOUS) +#define MAP_CONCEAL SYMBOLIC(MAP_CONCEAL) #define MAP_DENYWRITE SYMBOLIC(MAP_DENYWRITE) #define MAP_EXECUTABLE SYMBOLIC(MAP_EXECUTABLE) #define MAP_GROWSDOWN SYMBOLIC(MAP_GROWSDOWN) @@ -46,7 +46,8 @@ COSMOPOLITAN_C_END_ #define MAP_POPULATE SYMBOLIC(MAP_POPULATE) #define MAP_TYPE SYMBOLIC(MAP_TYPE) -#define MAP_ANON MAP_ANONYMOUS -#define MAP_STACK MAP_GROWSDOWN +#define MAP_ANON MAP_ANONYMOUS +#define MAP_NOCORE MAP_CONCEAL +#define MAP_STACK MAP_GROWSDOWN #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_MAP_H_ */ diff --git a/libc/sysv/consts/nr.h b/libc/sysv/consts/nr.h index c2c486e41..7a57e2035 100644 --- a/libc/sysv/consts/nr.h +++ b/libc/sysv/consts/nr.h @@ -332,6 +332,7 @@ #define __NR_io_uring_enter SYMBOLIC(__NR_io_uring_enter) #define __NR_io_uring_register SYMBOLIC(__NR_io_uring_register) #define __NR_pledge SYMBOLIC(__NR_pledge) +#define __NR_msyscall SYMBOLIC(__NR_msyscall) #define __NR_ktrace SYMBOLIC(__NR_ktrace) #define __NR_kqueue SYMBOLIC(__NR_kqueue) #define __NR_kevent SYMBOLIC(__NR_kevent) @@ -1105,6 +1106,7 @@ hidden extern const long __NR_io_uring_setup; hidden extern const long __NR_io_uring_enter; hidden extern const long __NR_io_uring_register; hidden extern const long __NR_pledge; +hidden extern const long __NR_msyscall; hidden extern const long __NR_ktrace; hidden extern const long __NR_kqueue; hidden extern const long __NR_kevent; diff --git a/libc/sysv/restorert.S b/libc/sysv/restorert.S index ffbc9af9d..299bbb6b2 100644 --- a/libc/sysv/restorert.S +++ b/libc/sysv/restorert.S @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.h" +.text.syscall .source __FILE__ / Linux Signal Trampoline (HOLY CODE) diff --git a/libc/sysv/syscalls.sh b/libc/sysv/syscalls.sh index 431267a93..15b540241 100755 --- a/libc/sysv/syscalls.sh +++ b/libc/sysv/syscalls.sh @@ -365,6 +365,7 @@ scall io_uring_enter 0xffffffffffff01aa globl scall io_uring_register 0xffffffffffff01ab globl #────────────────────────RHEL CLOUD────────────────────────── # ←┬─ red hat terminates community release of enterprise linux circa 2020 scall pledge 0x006cffffffffffff globl # └─ online linux services ban the president of united states of america +scall msyscall 0x0025ffffffffffff globl # The Fifth Bell System Interface, Community Edition # » besiyata dishmaya diff --git a/libc/sysv/systemfive.S b/libc/sysv/systemfive.S index 16ee0077f..4d7aa8dde 100644 --- a/libc/sysv/systemfive.S +++ b/libc/sysv/systemfive.S @@ -102,6 +102,8 @@ __systemfive: .quad 0 .endobj __systemfive,globl,hidden .previous + + .text.syscall .Lanchorpoint: systemfive.linux: movswl %ax,%eax # gnu/systemd ordinal is first word @@ -256,11 +258,9 @@ systemfive.init.magnums: pop %rbx / 𝑠𝑙𝑖𝑑𝑒 #ifndef TINY -systemfive.init.stack: +systemfive.init.stack: # determinism ftw! testb IsWindows() # already did this jnz systemfive.init.done - testb IsOpenbsd() # todo fix openbsd - jnz systemfive.init.done push %rdi push %rsi mov __NR_mmap,%eax @@ -269,13 +269,20 @@ systemfive.init.stack: mov $PROT_READ|PROT_WRITE,%edx mov $MAP_PRIVATE|MAP_FIXED,%r10d or MAP_ANONYMOUS,%r10d - or MAP_GROWSDOWN,%r10d - or $-1,%r8 + or $-1,%r8d xor %r9d,%r9d push %r9 # openbsd:pad -/ clc + push %r9 # openbsd:align + testb IsOpenbsd() + jz 0f + syscall # openbsd:dubstack + jc 1f + mov __NR_mmap,%eax +0: or MAP_GROWSDOWN,%r10d # openbsd:mapstack + clc syscall pop %r9 + pop %r9 jnc 2f 1: mov %eax,%edi mov __NR_exit_group,%eax @@ -295,12 +302,26 @@ systemfive.init.stack: pop %rdi leave pop %rcx - lea STACKSIZE(%rax),%rsp + lea STACKSIZE-16(%rax),%rsp # openbsd:stackbound push %rcx xor %ebp,%ebp push %rbp mov %rsp,%rbp / 𝑠𝑙𝑖𝑑𝑒 +systemfive.init.syscall: + mov __NR_msyscall,%eax # syscall origin protect + test %eax,%eax # openbsd is pretty cool + js systemfive.init.done + push %rdi + push %rsi + .weak __text_syscall_addr + .weak __text_syscall_size + mov $__text_syscall_addr,%edi + mov $__text_syscall_size,%esi + syscall + pop %rsi + pop %rdi +/ 𝑠𝑙𝑖𝑑𝑒 #endif /* TINY */ systemfive.init.done: nop diff --git a/test/libc/str/tpenc_test.c b/test/libc/str/tpenc_test.c index 47733e9fb..7d262e518 100644 --- a/test/libc/str/tpenc_test.c +++ b/test/libc/str/tpenc_test.c @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/limits.h" +#include "libc/rand/rand.h" #include "libc/stdio/stdio.h" #include "libc/str/str.h" #include "libc/str/tpenc.h" @@ -45,7 +46,7 @@ TEST(tpenc, testBeyondTheStandard) { } uint64_t Tpenc(int x) { - return (v = tpenc(VEIL("r", x))); + return (v = EXPROPRIATE(tpenc(VEIL("r", x)))); } BENCH(tpenc, bench) { diff --git a/third_party/chibicc/tokenize.c b/third_party/chibicc/tokenize.c index 73056fcb1..568fafbc8 100644 --- a/third_party/chibicc/tokenize.c +++ b/third_party/chibicc/tokenize.c @@ -275,7 +275,7 @@ static Token *read_string_literal(char *start, char *quote) { // is called a "surrogate pair". static Token *read_utf16_string_literal(char *start, char *quote) { char *end = string_literal_end(quote + 1); - uint16_t *buf = calloc(2, end - start - 1); + uint16_t *buf = calloc(2, end - start); int len = 0; for (char *p = quote + 1; p < end;) { if (*p == '\\') { diff --git a/third_party/third_party.mk b/third_party/third_party.mk index db1822be9..63217935b 100644 --- a/third_party/third_party.mk +++ b/third_party/third_party.mk @@ -1,15 +1,10 @@ #-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ #───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘ -# TODO(jart): make chibicc compiled chibicc work with asan runtime -ifneq ($(MODE),dbg) -THIRD_PARTY_CHIBICC_XXX = o/$(MODE)/third_party/chibicc -endif - .PHONY: o/$(MODE)/third_party o/$(MODE)/third_party: \ o/$(MODE)/third_party/blas \ - $(THIRD_PARTY_CHIBICC_XXX) \ + o/$(MODE)/third_party/chibicc \ o/$(MODE)/third_party/compiler_rt \ o/$(MODE)/third_party/dlmalloc \ o/$(MODE)/third_party/gdtoa \ diff --git a/tool/build/lib/syscall.c b/tool/build/lib/syscall.c index b2ac15305..a51ca8514 100644 --- a/tool/build/lib/syscall.c +++ b/tool/build/lib/syscall.c @@ -19,6 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/ioctl.h" +#include "libc/calls/struct/dirent.h" #include "libc/calls/struct/iovec.h" #include "libc/calls/struct/rusage.h" #include "libc/calls/struct/sigaction-linux.internal.h" @@ -770,6 +771,30 @@ static ssize_t OpRead(struct Machine *m, int fd, int64_t addr, size_t size) { return rc; } +static int OpGetdents(struct Machine *m, int dirfd, int64_t addr, + uint32_t size) { + int rc; + DIR *dir; + struct dirent *ent; + if (size < sizeof(struct dirent)) return einval(); + if (0 <= dirfd && dirfd < m->fds.i) { + if ((dir = fdopendir(m->fds.p[dirfd].fd))) { + rc = 0; + while (rc + sizeof(struct dirent) <= size) { + if (!(ent = readdir(dir))) break; + VirtualRecvWrite(m, addr + rc, ent, ent->d_reclen); + rc += ent->d_reclen; + } + free(dir); + } else { + rc = -1; + } + } else { + rc = ebadf(); + } + return rc; +} + static ssize_t OpPread(struct Machine *m, int fd, int64_t addr, size_t size, int64_t offset) { ssize_t rc; @@ -1395,6 +1420,7 @@ void OpSyscall(struct Machine *m, uint32_t rde) { SYSCALL(0x09E, OpArchPrctl(m, di, si)); SYSCALL(0x0BA, OpGetTid(m)); SYSCALL(0x0CB, sched_setaffinity(di, si, P(dx))); + SYSCALL(0x0D9, OpGetdents(m, di, si, dx)); SYSCALL(0x0DD, OpFadvise(m, di, si, dx, r0)); SYSCALL(0x0E4, OpClockGettime(m, di, si)); SYSCALL(0x101, OpOpenat(m, di, si, dx, r0)); diff --git a/tool/emacs/cosmo-c-keywords.el b/tool/emacs/cosmo-c-keywords.el index 1af8f1ca3..ad8a5243e 100644 --- a/tool/emacs/cosmo-c-keywords.el +++ b/tool/emacs/cosmo-c-keywords.el @@ -176,6 +176,7 @@ "interruptfn" "nocallback" "textstartup" + "textsyscall" "warnifused" "attributeallocsize" "attributeallocalign" diff --git a/tool/emacs/cosmo-stuff.el b/tool/emacs/cosmo-stuff.el index 2c8fbbf43..eeb77c7cc 100644 --- a/tool/emacs/cosmo-stuff.el +++ b/tool/emacs/cosmo-stuff.el @@ -441,7 +441,7 @@ (cond ((not (eq 0 (logand 8 arg))) (cosmo--assembly (setq arg (logand (lognot 8))) "SILENT=0 OVERRIDE_COPTS='-fverbose-asm -fsanitize=address'")) - (t (cosmo--assembly arg "SILENT=0 OVERRIDE_COPTS='-fverbose-asm -fsanitize=address' CPPFLAGS='-DSTACK_FRAME_UNLIMITED'")))) + (t (cosmo--assembly arg "SILENT=0 OVERRIDE_COPTS='' CPPFLAGS='-DSTACK_FRAME_UNLIMITED'")))) (defun cosmo-assembly-native (arg) (interactive "P")