Compare commits

...
40 Commits
Author SHA1 Message Date
Justine Tunney ce9aeb2aed Release Cosmopolitan v3.3.7 2024-05-24 19:37:21 -07:00
Justine Tunney ed93fc3dd7 Fix fread() with 2gb+ sizes 2024-05-24 19:28:23 -07:00
Justine Tunney 5f61d273e4 Add hwap constants to sys/auxv.h 2024-05-24 11:44:44 -07:00
Justine Tunney bf3531de81 Make crash reports reliable in multithreaded case 2024-05-24 11:44:44 -07:00
Justine Tunney 3b0ea2db4d Remove -fno-schedule-insns2
This was originally added when we were using the mcount hooking
technique, to prevent the nop from floating above the frame pointer
creation. Now we use a better codegen technique for hooking so it's no
longer needed to sacrifice performance by using this flag.
2024-05-24 11:44:44 -07:00
Justine Tunney f029375d39 Introduce MAP_HUGETLB 2024-05-24 11:44:44 -07:00
Justine Tunney 9b87dd2b87 Refactor some code 2024-05-24 11:44:44 -07:00
Jōshin 787b04f752 Run all BLAKE2B256 test vectors (#1185) 2024-05-24 10:59:23 -07:00
Jōshin 0768807935 Rename python -> python3 (closes #1144) (#1187)
When we removed the com suffix from ape binaries, we broke the build for
ape's python for any case-insensitive file system, i.e. Windows and XNU,
because there is a third_party/python/Python that gets mirrored in the o
directory with the python object files and clashes with the binary name.
This patch hacks around this by renaming the binary to "python3" so that
it no longer clashes with that directory.
2024-05-24 10:56:33 -07:00
Justine Tunney 0b59f01b43 Put confstr() in unistd.h
Fixes #1184
2024-05-21 15:35:06 -07:00
Justine Tunney cf70a44756 Support shebang on Windows
Fixes #1010
2024-05-20 22:11:42 -07:00
Justine Tunney a52792c59f Add some missing build dependencies 2024-05-20 17:23:25 -07:00
Jōshin 65c9b28e99 Fix buffer overflow in os.tmpname (#1180)
At least on macOS, `strlen(getenv("TMPDIR"))` is 50. We now allow a /tmp
that takes up to 120 or so bytes to spell. Instead of overflowing, we do
a bounds check and the function fails successfully on even longer /tmps.

Fixes #1108 (os.tmpname crashes redbean)
2024-05-20 03:46:27 -04:00
Jōshin 4292348707 Import libbsd readpassphrase (#1182)
Included from:

https://gitlab.freedesktop.org/libbsd/libbsd

At commit 04a24db27ad1572f766bad772cdd9c146e6d9cf0.
2024-05-20 03:37:30 -04:00
Jōshin 2ec20b6c4c Fix #922 (Duplicated line) (#1178) 2024-05-20 00:33:50 -07:00
Jōshin 47183551d6 Fix sleb64 (#1179)
Fixes #920
2024-05-20 00:33:17 -07:00
Jōshin 42891e82bb Fix #959 (typo in cosmocc --version) 2024-05-18 15:20:27 -07:00
Gavin Hayes 624119ea38 Fix NT accept/connect not initializing with SO_UPDATE_*_CONTEXT (#1164) 2024-05-17 02:45:30 -07:00
Justine Tunney 2f3c6e7cc3 Revert "Remove zlib namespacing (#1142)"
This reverts commit 5488f0b2ca which was a
good experiment to try, that didn't work out due to #1176

Fixes #1176
2024-05-14 20:45:23 -07:00
Justine Tunney 13b9ecd537 Remove outdated restriction on -Werror on cosmocc
This was a good idea back when we were only using it to build various
open source projects. However it no longer makes sense that many more
people are depending on cosmocc, to develop new software. Our tooling
shouldn't be making these kinds of decisions for the user.
2024-05-09 14:03:51 -07:00
Justine Tunney 6659981457 Release Cosmopolitan v3.3.6 2024-05-08 04:20:22 -07:00
Justine Tunney ae2a7ac844 Fix thread-local storage bugs on aarch64
This change fixes an issue where .tbss memory might not be initialized.
2024-05-08 04:20:22 -07:00
Justine Tunney 793393a341 Polyfill SA_RESETHAND on MacOS ARM64
This change solves the XNU crash loop mystery. Apple's documentation
claims to support this feature, but they only define the constant in
their header files. The kernel acknowledges thi SA_RESETHAND bit, by
clearing it from the sa_flags state, returns zero, and does nothing.
2024-05-08 04:20:22 -07:00
Justine Tunney 952b9009e8 Avoid crash looping on AARCH64 2024-05-08 04:20:22 -07:00
Jōshin 8f18b3ad65 Reapply apeinstall.sh binfmt flags (#1171)
7d31fc3 made it safe to register ape with the binfmt P flag. Older files
will still get their paths passed via argv[0] and everything should just
work. This also restores the F flag that was rolled back alongside the P
flag; this seems like a good idea to me now. It makes it so /usr/bin/ape
is kind of part of the kernel; simply replacing the file will not change
the loader used. The binfmt will have to be reregistered as well.

ape/apeinstall.sh will already nag you if there's an existing binfmt for
ape. It might be nice to make it actually replace the registration.

This reverts commit df648fb174.
2024-05-08 01:48:48 -04:00
Jōshin 56e0fd9d1d Use latest cosmocc (#1175) 2024-05-08 00:08:26 -04:00
Justine Tunney df68a6362b Release Cosmopolitan v3.3.5 2024-05-07 18:18:10 -07:00
Justine Tunney 19c81863a3 Improve crash backtrace reliability
We're now able to pretty print a C++ backtrace upon crashing in pretty
much any runtime execution scenario. The default pledge sandbox policy
on Linux is now to return EPERM. If you call pledge and have debugging
functions linked (e.g. GetSymbolTable) then the symbol table shall get
loaded before any security policy is put in place. This change updates
build/bootstrap/fixupobj too and fixes some other sneaky build errors.
2024-05-07 18:10:28 -07:00
Jōshin 7d31fc311a Loaders rewrite argv[0] for old binaries (#1170)
For this to work, a loader has to be able to tell the difference between
an ‘old’ and a ‘new’ binary. This is achieved via a repurposing of ELF’s
e_flags field. We previously tried to use the padding in e_ident for it,
but binutils was resetting it to zero in e.g. strip.

This introduces one new ELF flag for cosmopolitan binaries. It is called
`EF_APE_MODERN`. We choose 0x101ca75, "lol cat 5".

It should now be safe to install the ape loader binfmt registration with
the `P` flag.
2024-05-07 20:42:18 -04:00
Justine Tunney 57c0b065c8 Make old C++ demangler asynchronous signal safe
It's now possible to safely print C++ backtraces from signal handlers.
This symbol demangler doesn't need malloc, tls, or even static memory.
Additionally, this change makes it 2x faster and adds test cases. It's
almost as performant and accurate as the libcxxabi implementation now.
2024-05-07 03:41:33 -07:00
Justine Tunney a6ecbb747d Introduce libc/mem/tinymalloc.inc
This allocator shaves ~20kb off single-threaded tool programs and is
slightly faster than proper malloc for simple non-demanding programs
2024-05-07 03:19:49 -07:00
Justine Tunney 3bf95ae7ec Invent tool for renaming ELF object symbols 2024-05-07 03:19:49 -07:00
Justine Tunney 5fd7b07fac Improve AVX512 feature detection 2024-05-07 03:19:49 -07:00
Jōshin 317c8bc312 Update MODE=tiny time zone list (#1167)
I took one canonical IANA zone ID from each of the different colored
regions in this article, except those that do not observe DST and do
not have a Google office. See the "Time in Europe" Wikipedia article.

As to which canonical ID to use, this was somewhat arbitrary. Brussels
was obvious, as the de facto capital of the EU. For the rest, I mostly
just went with lexicographic ordering of the most recognizable options.

I've sorted the American zones. This Keeps the U.S. ones together but
does everything alphabetically otherwise. I've added the remaining
Canadian zones These have DST (and Newfoundland is off by a half-
hour from a UTC interval) so they cannot use Etc/. The Pacific/ zones
are sort of sorted. The Chathan Islands have been added. This is the
last of the zones I believe with a non-integer hour offset from UTC.
2024-05-06 16:48:49 -07:00
Jōshin 2a1f352622 Tell vim not to mess with ape.S 2024-05-06 15:36:35 -07:00
Justine Tunney 06d916b449 Add VirtualAlloc2 WIN32 API 2024-05-04 23:26:40 -07:00
Justine Tunney 9ea64725b6 Fix build error 2024-05-04 23:23:56 -07:00
Justine Tunney f9fc7eb49f Fix MODE=dbg build errors 2024-05-04 23:20:12 -07:00
Justine Tunney b0df6c1fce Implement proper time zone support
Cosmopolitan now supports 104 time zones. They're embedded inside any
binary that links the localtime() function. Doing so adds about 100kb
to the binary size. This change also gets time zones working properly
on Windows for the first time. It's not needed to have /etc/localtime
exist on Windows, since we can get this information from WIN32. We're
also now updated to the latest version of Paul Eggert's TZ library.
2024-05-04 23:06:37 -07:00
Justine Tunney d5ebb1fa5b Add MapViewOfFile3 WIN32 API 2024-05-04 12:25:41 -07:00
746 changed files with 47778 additions and 4691 deletions

No files matched your search

+4 -5
View File
@@ -149,9 +149,9 @@ export MODE
export SOURCE_DATE_EPOCH
export TMPDIR
COSMOCC = .cosmocc/3.3.3
COSMOCC = .cosmocc/3.3.5
TOOLCHAIN = $(COSMOCC)/bin/$(ARCH)-linux-cosmo-
DOWNLOAD := $(shell build/download-cosmocc.sh $(COSMOCC) 3.3.3 e4d0fa63cd79cc3bfff6c2d015f1776db081409907625aea8ad40cefc1996d08)
DOWNLOAD := $(shell build/download-cosmocc.sh $(COSMOCC) 3.3.5 db78fd8d3f8706e9dff4be72bf71d37a3f12062f212f407e1c33bc4af3780dd0)
AS = $(TOOLCHAIN)as
CC = $(TOOLCHAIN)gcc
@@ -258,7 +258,7 @@ include libc/thread/BUILD.mk # │ You can finally call malloc()
include third_party/zlib/BUILD.mk # │
include libc/stdio/BUILD.mk # │
include tool/hello/BUILD.mk # │
include libc/time/BUILD.mk # │
include third_party/tz/BUILD.mk # │
include net/BUILD.mk # │
include third_party/vqsort/BUILD.mk # │
include libc/log/BUILD.mk # │
@@ -440,7 +440,7 @@ COSMOPOLITAN_OBJECTS = \
LIBC_X \
THIRD_PARTY_GETOPT \
LIBC_LOG \
LIBC_TIME \
THIRD_PARTY_TZ \
THIRD_PARTY_OPENMP \
THIRD_PARTY_MUSL \
THIRD_PARTY_ZLIB_GZ \
@@ -505,7 +505,6 @@ COSMOPOLITAN_H_PKGS = \
LIBC_STR \
LIBC_SYSV \
LIBC_THREAD \
LIBC_TIME \
LIBC_TINYMATH \
LIBC_X \
LIBC_VGA \
+18 -1
View File
@@ -254,7 +254,24 @@ o/$(MODE)/ape: $(APE_CHECKS) \
endif
# these assembly files are safe to build on aarch64
o/$(MODE)/ape/ape.o: ape/ape.S
o/$(MODE)/ape/ape.o: \
ape/ape.S \
ape/ape.h \
libc/dce.h \
libc/elf/def.h \
ape/relocations.h \
libc/thread/tls.h \
ape/ape.internal.h \
ape/macros.internal.h \
libc/macho.internal.h \
libc/macros.internal.h \
libc/sysv/consts/prot.h \
libc/nt/pedef.internal.h \
libc/runtime/pc.internal.h \
libc/runtime/e820.internal.h \
libc/runtime/mman.internal.h \
libc/nexgen32e/uart.internal.h \
libc/calls/metalfile.internal.h
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/ape/ape.lds: \
+3 -4
View File
@@ -293,7 +293,6 @@ _tdata_size = _tdata_end - _tdata_start;
_tbss_size = _tbss_end - _tbss_start;
_tbss_offset = _tbss_start - _tdata_start;
_tls_content = (_tdata_end - _tdata_start) + (_tbss_end - _tbss_start);
_tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss));
ASSERT(ALIGNOF(.tdata) <= TLS_ALIGNMENT && ALIGNOF(.tbss) <= TLS_ALIGNMENT,
"_Thread_local _Alignof can't exceed TLS_ALIGNMENT");
_tdata_align = ALIGNOF(.tdata);
_tbss_align = ALIGNOF(.tbss);
_tls_align = MAX(TLS_ALIGNMENT, MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)));
+8 -1
View File
@@ -146,6 +146,9 @@ struct Syslib {
#define AT_RANDOM 25
#define AT_EXECFN 31
#define EF_APE_MODERN 0x101ca75
#define EF_APE_MODERN_MASK 0x1ffffff
#define AUXV_WORDS 31
/* from the xnu codebase */
@@ -799,7 +802,7 @@ __attribute__((__noreturn__)) static void Spawn(const char *exe, int fd,
}
static const char *TryElf(struct ApeLoader *M, union ElfEhdrBuf *ebuf,
const char *exe, int fd, long *sp, long *auxv,
char *exe, int fd, long *sp, long *auxv,
char *execfn) {
long i, rc;
unsigned size;
@@ -820,6 +823,10 @@ static const char *TryElf(struct ApeLoader *M, union ElfEhdrBuf *ebuf,
if (e->e_machine != EM_AARCH64) {
return "couldn't find ELF header with ARM64 machine type";
}
if ((e->e_flags & EF_APE_MODERN_MASK) != EF_APE_MODERN && sp[0] > 0) {
/* change argv[0] to resolved path for older binaries */
((char **)(sp + 1))[0] = exe;
}
if (e->e_phentsize != sizeof(struct ElfPhdr)) {
Pexit(exe, 0, "e_phentsize is wrong");
}
+3 -3
View File
@@ -1,5 +1,5 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
│ vi: set noet ft=asm ts=8 sw=8 fenc=utf-8 :vi │
│ vi: set noet ft=asm ts=8 sw=8 fenc=utf-8 nofixeol :vi │
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
@@ -196,7 +196,7 @@ ape_mz:
.quad ape_elf_entry // 18: e_entry
.quad ape_elf_phoff // 20: e_phoff
.quad ape_elf_shoff // 28: e_shoff
.long 0 // 30: e_flags
.long 0x101ca75 // 30: ape e_flags
.short 64 // 34: e_ehsize
.short 56 // 36: e_phentsize
.short ape_elf_phnum // 38: e_phnum
@@ -669,7 +669,7 @@ apesh: .ascii "\n@\n#'\"\n" // sixth edition shebang
.shstub ape_elf_entry,8 // 18: e_entry
.shstub ape_elf_phoff,8 // 20: e_phoff
.shstub ape_elf_shoff,8 // 28: e_shoff
.ascii "\\0\\0\\0\\0" // 30: e_flags
.ascii "\\165\\312\\1\\1" // 30: ape e_flags
.ascii "\\100\\0" // 34: e_ehsize
.ascii "\\070\\0" // 36: e_phentsize
.shstub ape_elf_phnum,2 // 38: e_phnum
+3 -1
View File
@@ -553,7 +553,9 @@ _tdata_size = _tdata_end - _tdata_start;
_tbss_size = _tbss_end - _tbss_start;
_tbss_offset = _tbss_start - _tdata_start;
_tls_content = (_tdata_end - _tdata_start) + (_tbss_end - _tbss_start);
_tls_align = 1;
_tdata_align = ALIGNOF(.tdata);
_tbss_align = ALIGNOF(.tbss);
_tls_align = MAX(TLS_ALIGNMENT, MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)));
ape_cod_offset = 0;
ape_cod_vaddr = ADDR(.head);
+11 -4
View File
@@ -137,13 +137,20 @@ if [ x"$(uname -s)" = xLinux ]; then
echo done >&2
fi
uname_r="$(uname -r)"
if printf '%s\n%s\n' 5.12 "$uname_r" | sort -CV; then
FLAGS=FP
else
FLAGS=F
fi
echo >&2
echo registering APE with binfmt_misc >&2
echo you may need to edit configs to persist across reboot >&2
echo '$SUDO sh -c "echo '"'"':APE:M::MZqFpD::/usr/bin/ape:'"'"' >/proc/sys/fs/binfmt_misc/register"' >&2
$SUDO sh -c "echo ':APE:M::MZqFpD::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register" || exit
echo '$SUDO sh -c "echo '"'"':APE-jart:M::jartsr::/usr/bin/ape:'"'"' >/proc/sys/fs/binfmt_misc/register"' >&2
$SUDO sh -c "echo ':APE-jart:M::jartsr::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register" || exit
echo '$SUDO sh -c "echo '"'"':APE:M::MZqFpD::/usr/bin/ape:'"$FLAGS'"' >/proc/sys/fs/binfmt_misc/register"' >&2
$SUDO sh -c "echo ':APE:M::MZqFpD::/usr/bin/ape:$FLAGS' >/proc/sys/fs/binfmt_misc/register" || exit
echo '$SUDO sh -c "echo '"'"':APE-jart:M::jartsr::/usr/bin/ape:'"$FLAGS'"' >/proc/sys/fs/binfmt_misc/register"' >&2
$SUDO sh -c "echo ':APE-jart:M::jartsr::/usr/bin/ape:$FLAGS' >/proc/sys/fs/binfmt_misc/register" || exit
echo done >&2
if [ x"$(cat /proc/sys/fs/binfmt_misc/status)" = xdisabled ]; then
+7
View File
@@ -152,6 +152,9 @@
#define PR_SET_MM 35
#define PR_SET_MM_EXE_FILE 13
#define EF_APE_MODERN 0x101ca75
#define EF_APE_MODERN_MASK 0x1ffffff
#define READ32(S) \
((unsigned)(255 & (S)[3]) << 030 | (unsigned)(255 & (S)[2]) << 020 | \
(unsigned)(255 & (S)[1]) << 010 | (unsigned)(255 & (S)[0]) << 000)
@@ -834,6 +837,10 @@ static const char *TryElf(struct ApeLoader *M, union ElfEhdrBuf *ebuf,
return "couldn't find ELF header with x86-64 machine type";
}
#endif
if ((e->e_flags & EF_APE_MODERN_MASK) != EF_APE_MODERN && sp[0] > 0) {
/* change argv[0] to resolved path for older binaries */
((char **)(sp + 1))[0] = exe;
}
if (e->e_phentsize != sizeof(struct ElfPhdr)) {
Pexit(os, exe, 0, "e_phentsize is wrong");
}
+2
View File
@@ -16,6 +16,8 @@ extern unsigned char _tdata_end[] __attribute__((__weak__));
extern unsigned char _tbss_start[] __attribute__((__weak__));
extern unsigned char _tbss_end[] __attribute__((__weak__));
extern unsigned char _tls_align[] __attribute__((__weak__));
extern unsigned char _tdata_align[] __attribute__((__weak__));
extern unsigned char _tbss_align[] __attribute__((__weak__));
extern unsigned char __test_start[] __attribute__((__weak__));
extern unsigned char __ro[] __attribute__((__weak__));
extern unsigned char __data_start[] __attribute__((__weak__));
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-4
View File
@@ -63,10 +63,6 @@ BACKTRACES = \
-fno-optimize-sibling-calls \
-mno-omit-leaf-frame-pointer
ifneq ($(ARCH), aarch64)
BACKTRACES += -fno-schedule-insns2
endif
SANITIZER = \
-fsanitize=address
-1
View File
@@ -35,7 +35,6 @@ DSP_MPEG_A_DIRECTDEPS = \
LIBC_STDIO \
LIBC_STR \
LIBC_SYSV \
LIBC_TIME \
LIBC_TINYMATH \
THIRD_PARTY_COMPILER_RT
+1 -1
View File
@@ -39,7 +39,7 @@
#include "libc/math.h"
#include "libc/mem/mem.h"
#include "libc/str/str.h"
#include "libc/time/time.h"
#include "libc/time.h"
#include "libc/x/x.h"
__static_yoink("pl_mpeg_notice");
-1
View File
@@ -31,7 +31,6 @@ DSP_SCALE_A_DIRECTDEPS = \
LIBC_NEXGEN32E \
LIBC_RUNTIME \
LIBC_STR \
LIBC_TIME \
LIBC_TINYMATH \
LIBC_X
-1
View File
@@ -38,7 +38,6 @@ DSP_TTY_A_DIRECTDEPS = \
LIBC_SOCK \
LIBC_SYSV \
LIBC_TINYMATH \
LIBC_TIME \
LIBC_X
DSP_TTY_A_DEPS := \
+3 -2
View File
@@ -65,7 +65,6 @@ EXAMPLES_DIRECTDEPS = \
LIBC_SYSV_CALLS \
LIBC_TESTLIB \
LIBC_THREAD \
LIBC_TIME \
LIBC_TINYMATH \
LIBC_VGA \
LIBC_X \
@@ -89,6 +88,7 @@ EXAMPLES_DIRECTDEPS = \
THIRD_PARTY_SED \
THIRD_PARTY_STB \
THIRD_PARTY_TR \
THIRD_PARTY_TZ \
THIRD_PARTY_VQSORT \
THIRD_PARTY_XED \
THIRD_PARTY_ZLIB \
@@ -154,7 +154,8 @@ o/$(MODE)/examples/picol.dbg: \
@$(APELINK)
o/$(MODE)/usr/share/dict/words.zip.o: private ZIPOBJ_FLAGS += -C2
o/$(MODE)/examples/wut.o: private COPTS += -fopenmp
o/$(MODE)/examples/blas.o: private COPTS += -O3 -fopenmp
$(EXAMPLES_OBJS): examples/BUILD.mk
+16
View File
@@ -0,0 +1,16 @@
#include <stdlib.h>
__static_yoink("__die");
__static_yoink("GetSymbolByAddr");
__static_yoink("malloc_inspect_all");
char *lol(int n) {
return malloc(n);
}
char *(*pLol)(int) = lol;
int main(int argc, char *argv[]) {
char *s = pLol(4);
s[4] = 1;
}
+221
View File
@@ -0,0 +1,221 @@
// Copyright 2024 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 <unistd.h>
#include <cinttypes>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include "libc/assert.h"
// high performance high accuracy matrix multiplication in ansi c
#define MATH __target_clones("avx512f,fma")
namespace {
namespace ansiBLAS {
static constexpr int KN = 8;
struct Vector {
double v[KN];
};
Vector load(const float *p) {
Vector x;
for (int i = 0; i < KN; ++i)
x.v[i] = p[i];
return x;
}
Vector madd(Vector x, Vector y, Vector s) {
for (int i = 0; i < KN; ++i)
s.v[i] = fma(x.v[i], y.v[i], s.v[i]);
return s;
}
float hsum(Vector x) {
double s = 0;
for (int i = 0; i < KN; ++i)
s += x.v[i];
return s;
}
struct ansiBLAS {
public:
ansiBLAS(int k, const float *A, int lda, const float *B, int ldb, float *C,
int ldc, int ith, int nth)
: k(k),
A(A),
lda(lda),
B(B),
ldb(ldb),
C(C),
ldc(ldc),
ith(ith),
nth(nth) {
}
void matmul(int m, int n) {
mnpack(0, m, 0, n);
}
private:
void mnpack(int m0, int m, int n0, int n) {
int mc, nc, mp, np;
if (m - m0 <= 0 || n - n0 <= 0)
return;
if (m - m0 >= 4 && n - n0 >= 3) {
mc = 4;
nc = 3;
gemm<4, 3>(m0, m, n0, n);
} else {
mc = 1;
nc = 1;
gemm<1, 1>(m0, m, n0, n);
}
mp = m0 + (m - m0) / mc * mc;
np = n0 + (n - n0) / nc * nc;
mnpack(mp, m, n0, np);
mnpack(m0, m, np, n);
}
template <int RM, int RN>
MATH void gemm(int m0, int m, int n0, int n) {
int ytiles = (m - m0) / RM;
int xtiles = (n - n0) / RN;
int tiles = xtiles * ytiles;
int duty = (tiles + nth - 1) / nth;
int start = duty * ith;
int end = start + duty;
if (end > tiles)
end = tiles;
for (int job = start; job < end; ++job) {
int ii = m0 + job / xtiles * RM;
int jj = n0 + job % xtiles * RN;
Vector Cv[RN][RM] = {};
for (int l = 0; l < k; l += KN)
for (int j = 0; j < RN; ++j)
for (int i = 0; i < RM; ++i)
Cv[j][i] = madd(load(A + lda * (ii + i) + l), //
load(B + ldb * (jj + j) + l), //
Cv[j][i]);
for (int j = 0; j < RN; ++j)
for (int i = 0; i < RM; ++i)
C[ldc * (jj + j) + (ii + i)] = hsum(Cv[j][i]);
}
}
const int k;
const float *const A;
const int lda;
const float *const B;
const int ldb;
float *const C;
const int ldc;
const int ith;
const int nth;
};
void sgemm(int m, int n, int k, //
const float *A, int lda, //
const float *B, int ldb, //
float *C, int ldc) {
int nth = sysconf(_SC_NPROCESSORS_ONLN);
#pragma omp parallel for
for (int ith = 0; ith < nth; ++ith) {
ansiBLAS tb{k, A, lda, B, ldb, C, ldc, ith, nth};
tb.matmul(m, n);
}
}
} // namespace ansiBLAS
long micros(void) {
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
return ts.tv_sec * 1000000 + (ts.tv_nsec + 999) / 1000;
}
unsigned rand32(void) {
/* Knuth, D.E., "The Art of Computer Programming," Vol 2,
Seminumerical Algorithms, Third Edition, Addison-Wesley, 1998,
p. 106 (line 26) & p. 108 */
static unsigned long long lcg = 1;
lcg *= 6364136223846793005;
lcg += 1442695040888963407;
return lcg >> 32;
}
float float01(unsigned x) { // (0,1)
return 1.f / 8388608 * ((x >> 9) + .5f);
}
float numba(void) { // (-1,1)
return float01(rand32()) * 2 - 1;
}
void fill(int m, int n, float *A, int lda) {
for (int j = 0; j < n; ++j)
for (int i = 0; i < m; ++i)
A[lda * j + i] = numba();
}
float *new_matrix(int m, int n, int *lda) {
void *ptr = 0;
int b = 64 / sizeof(float);
*lda = (n + b - 1) & -b;
posix_memalign(&ptr, 4096, sizeof(float) * m * *lda);
return (float *)ptr;
}
} // namespace
void barrier(void) {
}
void (*pBarrier)(void) = barrier;
#define BENCH(x) \
do { \
x; \
int N = 10; \
long t1 = micros(); \
for (long i = 0; i < N; ++i) { \
pBarrier(); \
x; \
} \
long t2 = micros(); \
printf("%8" PRId64 " µs %s %g gigaflops\n", (t2 - t1 + N - 1) / N, #x, \
1e6 / ((t2 - t1 + N - 1) / N) * m * n * k * 2 * 1e-9); \
} while (0)
int main() {
int m = 1024;
int n = 1024;
int k = 1024;
int lda, ldb, ldc;
float *A = new_matrix(m, k, &lda);
float *B = new_matrix(n, k, &ldb);
float *C = new_matrix(n, m, &ldc);
fill(k, n, A, lda);
fill(k, m, B, ldb);
BENCH(ansiBLAS::sgemm(m, n, k, A, lda, B, ldb, C, ldc));
assert(C[0] == -0x1.20902ap+4);
assert(C[1] == -0x1.bf7726p+4);
free(C);
free(B);
free(A);
}
+12
View File
@@ -7,6 +7,7 @@
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/calls/calls.h"
#include "libc/math.h"
#include "libc/runtime/runtime.h"
@@ -18,6 +19,17 @@ void crash(long x0, long x1, long x2, //
void (*pCrash)(long, long, long, double, double, double) = crash;
int main(int argc, char *argv[]) {
// // by default we launch an addr2line subprocess to print backtraces
// // with line numbers. you can force it to use the embedded solution
// setenv("ADDR2LINE", "", true);
// // using a seccomp sandbox is another way to force embedded backtraces
// pledge("stdio", NULL);
// enable the crash reporting feature
ShowCrashReports();
// time to die
pCrash(1, 2, 3, NAN, NAN, NAN);
}
+25 -4
View File
@@ -9,19 +9,30 @@
#endif
#include "libc/calls/calls.h"
#include "libc/calls/struct/timespec.h"
#include "libc/intrin/kprintf.h"
#include "libc/macros.internal.h"
#include "libc/nt/enum/timezoneid.h"
#include "libc/nt/struct/timezoneinformation.h"
#include "libc/nt/time.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/time/struct/tm.h"
#include "libc/thread/threads.h"
#include "libc/time.h"
/**
* @fileoverview High performance ISO-8601 timestamp formatter.
*
* The strftime() function is very slow. This goes much faster.
* Consider using something like this instead for your loggers.
*/
char *GetTimestamp(void) {
int x;
struct timespec ts;
_Thread_local static long last;
_Thread_local static char s[27];
_Thread_local static struct tm tm;
thread_local static long last;
thread_local static char s[32];
thread_local static struct tm tm;
clock_gettime(0, &ts);
if (ts.tv_sec != last) {
localtime_r(&ts.tv_sec, &tm);
@@ -61,11 +72,21 @@ char *GetTimestamp(void) {
s[23] = '0' + x / 100000 % 10;
s[24] = '0' + x / 10000 % 10;
s[25] = '0' + x / 1000 % 10;
s[26] = tm.tm_gmtoff < 0 ? '-' : '+';
x = ABS(tm.tm_gmtoff) / 60 / 60;
s[27] = '0' + x / 10 % 10;
s[28] = '0' + x % 10;
x = ABS(tm.tm_gmtoff) / 60 % 60;
s[29] = '0' + x / 10 % 10;
s[30] = '0' + x % 10;
return s;
}
int main(int argc, char *argv[]) {
char buf[128], *p = buf;
// setenv("TZ", "UTC", true);
// setenv("TZ", "US/Eastern", true);
// setenv("TZ", "Asia/Kolkata", true);
p = stpcpy(p, GetTimestamp());
p = stpcpy(p, "\n");
write(1, buf, p - buf);
+1 -1
View File
@@ -42,7 +42,7 @@
#include "libc/stdio/rand.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/time/time.h"
#include "libc/time.h"
#include "third_party/zlib/zlib.h"
// clang-format off
+1 -1
View File
@@ -71,7 +71,7 @@ Contact: [email protected]");
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/termios.h"
#include "libc/time/time.h"
#include "libc/time.h"
/* Syntax highlight types */
#define HL_NORMAL 0
+15
View File
@@ -0,0 +1,15 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
│ To the extent possible under law, Justine Tunney has waived │
│ all copyright and related or neighboring rights to this file, │
│ as it is written in the following disclaimers: │
│ • http://unlicense.org/ │
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/time.h"
int main(int argc, char *argv[]) {
int64_t t = 0;
localtime(&t);
}
+1 -1
View File
@@ -44,7 +44,7 @@
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/consts/w.h"
#include "libc/thread/thread.h"
#include "libc/time/time.h"
#include "libc/time.h"
#include "libc/x/xasprintf.h"
#include "libc/x/xsigaction.h"
#include "libc/zip.internal.h"
+1 -1
View File
@@ -50,7 +50,7 @@
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/consts/s.h"
#include "libc/sysv/consts/termios.h"
#include "libc/time/time.h"
#include "libc/time.h"
#include "third_party/getopt/getopt.internal.h"
// clang-format off
+1 -1
View File
@@ -17,7 +17,7 @@
#include "libc/sysv/consts/itimer.h"
#include "libc/sysv/consts/sa.h"
#include "libc/sysv/consts/sig.h"
#include "libc/time/time.h"
#include "libc/time.h"
volatile bool gotalrm;
+30 -11
View File
@@ -8,16 +8,18 @@
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/calls/struct/stat.h"
#include "libc/assert.h"
#include "libc/calls/calls.h"
#include "libc/errno.h"
#include "libc/fmt/conv.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
#include "libc/mem/gc.h"
#include "libc/mem/mem.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/s.h"
#include "libc/x/xiso8601.h"
#include "libc/time.h"
/**
* @fileoverview File metadata viewer.
@@ -27,6 +29,23 @@
bool numeric;
char *xiso8601(struct timespec ts) {
struct tm tm;
if (!localtime_r(&ts.tv_sec, &tm))
return 0;
int len = 128;
char *res = malloc(len);
char *ptr = res;
char *end = res + len;
if (!res)
return 0;
ptr += strftime(ptr, end - ptr, "%Y-%m-%d %H:%M:%S", &tm);
ptr += snprintf(ptr, end - ptr, ".%09ld", ts.tv_nsec);
ptr += strftime(ptr, end - ptr, "%z %Z", &tm);
unassert(ptr + 1 <= end);
return res;
}
const char *DescribeFileType(unsigned mode) {
switch (mode & S_IFMT) {
case S_IFIFO:
@@ -74,16 +93,16 @@ void PrintFileMetadata(const char *pathname, struct stat *st) {
"%-32s%s\n"
"%-32s%s\n"
"%-32s%s\n",
"bytes in file", st->st_size, "physical bytes", st->st_blocks * 512,
"device id w/ file", st->st_dev, "inode", st->st_ino,
"hard link count", st->st_nlink, "mode / permissions", st->st_mode,
DescribeFileType(st->st_mode), "owner id", st->st_uid, "group id",
st->st_gid, "flags", st->st_flags, "gen", st->st_gen,
"device id (if special)", st->st_rdev, "block size", st->st_blksize,
"access time", gc(xiso8601(&st->st_atim)), "modified time",
gc(xiso8601(&st->st_mtim)), "c[omplicated]time",
gc(xiso8601(&st->st_ctim)), "birthtime",
gc(xiso8601(&st->st_birthtim)));
"bytes in file:", st->st_size, "physical bytes:", st->st_blocks * 512,
"device id w/ file:", st->st_dev, "inode:", st->st_ino,
"hard link count:", st->st_nlink, "mode / permissions:", st->st_mode,
DescribeFileType(st->st_mode), "owner id:", st->st_uid,
"group id:", st->st_gid, "flags:", st->st_flags, "gen:", st->st_gen,
"device id (if special):", st->st_rdev, "block size:", st->st_blksize,
"access time:", gc(xiso8601(st->st_atim)),
"modified time:", gc(xiso8601(st->st_mtim)),
"c[omplicated]time:", gc(xiso8601(st->st_ctim)),
"[birthtime]:", gc(xiso8601(st->st_birthtim)));
}
int main(int argc, char *argv[]) {
+1 -1
View File
@@ -16,7 +16,7 @@
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/o.h"
#include "libc/time/struct/tm.h"
#include "libc/time.h"
#include "third_party/getopt/getopt.internal.h"
#include "third_party/musl/passwd.h"
-1
View File
@@ -300,7 +300,6 @@ o/$(MODE)/libc: o/$(MODE)/libc/calls \
o/$(MODE)/libc/sysv \
o/$(MODE)/libc/testlib \
o/$(MODE)/libc/thread \
o/$(MODE)/libc/time \
o/$(MODE)/libc/tinymath \
o/$(MODE)/libc/vga \
o/$(MODE)/libc/x \
+1 -1
View File
@@ -23,7 +23,7 @@
#include "libc/intrin/strace.internal.h"
#include "libc/sysv/consts/clock.h"
#include "libc/sysv/errfuns.h"
#include "libc/time/time.h"
#include "libc/time.h"
static int sys_clock_getres_poly(int clock, struct timespec *ts, int64_t real,
int64_t real_coarse, int64_t boot) {
File renamed without changes.
+1 -1
View File
@@ -19,7 +19,7 @@
#include "libc/calls/struct/timespec.h"
#include "libc/calls/struct/timeval.h"
#include "libc/sysv/consts/clock.h"
#include "libc/time/struct/timezone.h"
#include "libc/time.h"
/**
* Returns system wall time in microseconds, e.g.
+18 -21
View File
@@ -23,6 +23,7 @@
#include "libc/mem/mem.h"
#include "libc/nt/files.h"
#include "libc/proc/ntspawn.h"
#include "libc/stdio/sysparam.h"
#include "libc/str/str.h"
#include "libc/str/thompike.h"
#include "libc/str/utf16.h"
@@ -31,16 +32,14 @@
#define APPEND(c) \
do { \
if (k == 32766) { \
return e2big(); \
} \
cmdline[k++] = c; \
if (k < size) \
cmdline[k] = c; \
++k; \
} while (0)
static bool NeedsQuotes(const char *s) {
if (!*s) {
static textwindows bool NeedsQuotes(const char *s) {
if (!*s)
return true;
}
do {
switch (*s) {
case '"':
@@ -60,7 +59,7 @@ static inline int IsAlpha(int c) {
return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z');
}
static bool LooksLikeCosmoDrivePath(const char *s) {
static textwindows bool LooksLikeCosmoDrivePath(const char *s) {
return s[0] == '/' && //
IsAlpha(s[1]) && //
s[2] == '/';
@@ -74,12 +73,13 @@ static bool LooksLikeCosmoDrivePath(const char *s) {
//
// @param cmdline is output buffer
// @param argv is an a NULL-terminated array of UTF-8 strings
// @return 0 on success, or -1 w/ errno
// @raise E2BIG if everything is too huge
// @param size is number of characters in cmdline buffer
// @return length on success, which is >=size on truncation
// @see "Everyone quotes command line arguments the wrong way" MSDN
// @see libc/runtime/getdosargv.c
// @asyncsignalsafe
textwindows int mkntcmdline(char16_t cmdline[32767], char *const argv[]) {
textwindows size_t mkntcmdline(char16_t *cmdline, char *const argv[],
size_t size) {
char *arg;
int slashes, n;
bool needsquote;
@@ -95,9 +95,8 @@ textwindows int mkntcmdline(char16_t cmdline[32767], char *const argv[]) {
} else {
arg = argv[i];
}
if ((needsquote = NeedsQuotes(arg))) {
if ((needsquote = NeedsQuotes(arg)))
APPEND(u'"');
}
for (slashes = j = 0;;) {
wint_t x = arg[j++] & 255;
if (x >= 0300) {
@@ -122,9 +121,8 @@ textwindows int mkntcmdline(char16_t cmdline[32767], char *const argv[]) {
APPEND(u'"');
APPEND(u'"');
} else {
for (s = 0; s < slashes; ++s) {
for (s = 0; s < slashes; ++s)
APPEND(u'\\');
}
slashes = 0;
uint32_t w = EncodeUtf16(x);
do
@@ -132,13 +130,12 @@ textwindows int mkntcmdline(char16_t cmdline[32767], char *const argv[]) {
while ((w >>= 16));
}
}
for (s = 0; s < (slashes << needsquote); ++s) {
for (s = 0; s < (slashes << needsquote); ++s)
APPEND(u'\\');
}
if (needsquote) {
if (needsquote)
APPEND(u'"');
}
}
cmdline[k] = 0;
return 0;
if (size)
cmdline[MIN(k, size - 1)] = 0;
return k;
}
+168 -86
View File
@@ -20,9 +20,15 @@
#include "libc/calls/struct/sigset.internal.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/nt/createfile.h"
#include "libc/nt/enum/accessmask.h"
#include "libc/nt/enum/creationdisposition.h"
#include "libc/nt/enum/fileflagandattributes.h"
#include "libc/nt/enum/filesharemode.h"
#include "libc/nt/enum/processaccess.h"
#include "libc/nt/enum/processcreationflags.h"
#include "libc/nt/errors.h"
#include "libc/nt/events.h"
#include "libc/nt/files.h"
#include "libc/nt/memory.h"
#include "libc/nt/process.h"
@@ -33,6 +39,7 @@
#include "libc/nt/struct/startupinfo.h"
#include "libc/nt/struct/startupinfoex.h"
#include "libc/proc/ntspawn.h"
#include "libc/stdalign.internal.h"
#include "libc/str/str.h"
#include "libc/sysv/errfuns.h"
#ifdef __x86_64__
@@ -44,14 +51,167 @@ struct SpawnBlock {
char envbuf[32767];
};
static void *ntspawn_malloc(size_t size) {
static textwindows void *ntspawn_malloc(size_t size) {
return HeapAlloc(GetProcessHeap(), 0, size);
}
static void ntspawn_free(void *ptr) {
static textwindows void ntspawn_free(void *ptr) {
HeapFree(GetProcessHeap(), 0, ptr);
}
static textwindows ssize_t ntspawn_read(intptr_t fh, char *buf, size_t len) {
bool ok;
uint32_t got;
struct NtOverlapped overlap = {.hEvent = CreateEvent(0, 0, 0, 0)};
ok = (ReadFile(fh, buf, len, 0, &overlap) ||
GetLastError() == kNtErrorIoPending) &&
GetOverlappedResult(fh, &overlap, &got, true);
CloseHandle(overlap.hEvent);
return ok ? got : -1;
}
static textwindows int ntspawn2(struct NtSpawnArgs *a, struct SpawnBlock *sb) {
// make executable path
if (__mkntpathath(a->dirhand, a->prog, 0, sb->path) == -1)
return -1;
// open executable
char *p = sb->envbuf;
char *pe = p + sizeof(sb->envbuf);
intptr_t fh = CreateFile(
sb->path, kNtFileGenericRead,
kNtFileShareRead | kNtFileShareWrite | kNtFileShareDelete, 0,
kNtOpenExisting, kNtFileAttributeNormal | kNtFileFlagBackupSemantics, 0);
if (fh == -1)
return -1;
ssize_t got = ntspawn_read(fh, p, pe - p);
CloseHandle(fh);
if (got < 3)
return enoexec();
pe = p + got;
// handle shebang
size_t i = 0; // represents space of sb->cmdline consumed
if (p[0] == 'M' && p[1] == 'Z') {
// it's a windows executable
} else if (p[0] == '#' && p[1] == '!') {
p += 2;
// make sure we got a complete first line
pe = memchr(p, '\n', pe - p);
if (!pe)
return enoexec();
*pe = 0;
int argc = 0;
char *argv[4];
// it's legal to say "#! /bin/sh"
while (p < pe && (*p == ' ' || *p == '\t'))
++p;
if (p == pe)
return enoexec();
argv[argc++] = p;
// find the optional argument
while (p < pe && !(*p == ' ' || *p == '\t'))
++p;
if (p < pe) {
*p++ = 0;
while (p < pe && (*p == ' ' || *p == '\t'))
++p;
if (p < pe) {
argv[argc++] = p;
}
}
// now add the prog
argv[argc++] = (char *)a->prog;
argv[argc] = 0;
// ignore argv[0]
if (*a->argv)
++a->argv;
// prepend arguments
if ((i += mkntcmdline(sb->cmdline + i, argv, 32767 - i)) >= 32767 - 1)
return e2big();
sb->cmdline[i++] = ' ';
sb->cmdline[i] = 0;
// setup the true executable path
if (__mkntpathath(a->dirhand, argv[0], 0, sb->path) == -1)
return -1;
} else {
// it's something else
return enoexec();
}
// setup arguments and environment
if ((i += mkntcmdline(sb->cmdline + i, a->argv, 32767 - i)) >= 32767)
return e2big();
if (mkntenvblock(sb->envblock, a->envp, a->extravars, sb->envbuf) == -1)
return -1;
// create attribute list
// this code won't call malloc in practice
bool32 ok;
void *freeme = 0;
alignas(16) char memory[128];
size_t size = sizeof(memory);
struct NtProcThreadAttributeList *alist = (void *)memory;
uint32_t items = !!a->opt_hParentProcess + !!a->opt_lpExplicitHandleList;
ok = InitializeProcThreadAttributeList(alist, items, 0, &size);
if (!ok && GetLastError() == kNtErrorInsufficientBuffer) {
ok = !!(alist = freeme = ntspawn_malloc(size));
if (ok) {
ok = InitializeProcThreadAttributeList(alist, items, 0, &size);
}
}
if (ok && a->opt_hParentProcess) {
ok = UpdateProcThreadAttribute(
alist, 0, kNtProcThreadAttributeParentProcess, &a->opt_hParentProcess,
sizeof(a->opt_hParentProcess), 0, 0);
}
if (ok && a->opt_lpExplicitHandleList) {
ok = UpdateProcThreadAttribute(
alist, 0, kNtProcThreadAttributeHandleList, a->opt_lpExplicitHandleList,
a->dwExplicitHandleCount * sizeof(*a->opt_lpExplicitHandleList), 0, 0);
}
// create the process
int rc;
if (ok) {
struct NtStartupInfoEx info = {
.StartupInfo = *a->lpStartupInfo,
.StartupInfo.cb = sizeof(info),
.lpAttributeList = alist,
};
if (ok) {
if (CreateProcess(sb->path, sb->cmdline, 0, 0, true,
a->dwCreationFlags | kNtCreateUnicodeEnvironment |
kNtExtendedStartupinfoPresent |
kNtInheritParentAffinity |
GetPriorityClass(GetCurrentProcess()),
sb->envblock, a->opt_lpCurrentDirectory,
&info.StartupInfo, a->opt_out_lpProcessInformation)) {
rc = 0;
} else {
rc = -1;
STRACE("CreateProcess() failed w/ %d", GetLastError());
if (GetLastError() == kNtErrorSharingViolation) {
etxtbsy();
} else if (GetLastError() == kNtErrorInvalidName) {
enoent();
}
}
rc = __fix_enotdir(rc, sb->path);
}
} else {
rc = __winerr();
}
// clean up resources
if (alist)
DeleteProcThreadAttributeList(alist);
if (freeme)
ntspawn_free(freeme);
return rc;
}
/**
* Spawns process on Windows NT.
*
@@ -72,93 +232,15 @@ static void ntspawn_free(void *ptr) {
* @see spawnve() which abstracts this function
* @asyncsignalsafe
*/
textwindows int ntspawn(
int64_t dirhand, const char *prog, char *const argv[], char *const envp[],
char *const extravars[], uint32_t dwCreationFlags,
const char16_t *opt_lpCurrentDirectory, int64_t opt_hParentProcess,
int64_t *opt_lpExplicitHandleList, uint32_t dwExplicitHandleCount,
const struct NtStartupInfo *lpStartupInfo,
struct NtProcessInformation *opt_out_lpProcessInformation) {
int rc = -1;
textwindows int ntspawn(struct NtSpawnArgs *args) {
int rc;
struct SpawnBlock *sb;
BLOCK_SIGNALS;
if ((sb = ntspawn_malloc(sizeof(*sb))) &&
__mkntpathath(dirhand, prog, 0, sb->path) != -1) {
if (!mkntcmdline(sb->cmdline, argv) &&
!mkntenvblock(sb->envblock, envp, extravars, sb->envbuf)) {
bool32 ok;
int64_t dp = GetCurrentProcess();
// create attribute list
// this code won't call malloc in practice
void *freeme = 0;
_Alignas(16) char memory[128];
size_t size = sizeof(memory);
struct NtProcThreadAttributeList *alist = (void *)memory;
uint32_t items = !!opt_hParentProcess + !!opt_lpExplicitHandleList;
ok = InitializeProcThreadAttributeList(alist, items, 0, &size);
if (!ok && GetLastError() == kNtErrorInsufficientBuffer) {
ok = !!(alist = freeme = ntspawn_malloc(size));
if (ok) {
ok = InitializeProcThreadAttributeList(alist, items, 0, &size);
}
}
if (ok && opt_hParentProcess) {
ok = UpdateProcThreadAttribute(
alist, 0, kNtProcThreadAttributeParentProcess, &opt_hParentProcess,
sizeof(opt_hParentProcess), 0, 0);
}
if (ok && opt_lpExplicitHandleList) {
ok = UpdateProcThreadAttribute(
alist, 0, kNtProcThreadAttributeHandleList,
opt_lpExplicitHandleList,
dwExplicitHandleCount * sizeof(*opt_lpExplicitHandleList), 0, 0);
}
// create the process
if (ok) {
struct NtStartupInfoEx info;
bzero(&info, sizeof(info));
info.StartupInfo = *lpStartupInfo;
info.StartupInfo.cb = sizeof(info);
info.lpAttributeList = alist;
if (ok) {
if (CreateProcess(sb->path, sb->cmdline, 0, 0, true,
dwCreationFlags | kNtCreateUnicodeEnvironment |
kNtExtendedStartupinfoPresent |
kNtInheritParentAffinity |
GetPriorityClass(GetCurrentProcess()),
sb->envblock, opt_lpCurrentDirectory,
&info.StartupInfo, opt_out_lpProcessInformation)) {
rc = 0;
} else {
STRACE("CreateProcess() failed w/ %d", GetLastError());
if (GetLastError() == kNtErrorSharingViolation) {
etxtbsy();
} else if (GetLastError() == kNtErrorInvalidName) {
enoent();
}
}
rc = __fix_enotdir(rc, sb->path);
}
} else {
rc = __winerr();
}
// clean up resources
if (alist) {
DeleteProcThreadAttributeList(alist);
}
if (freeme) {
ntspawn_free(freeme);
}
if (dp && dp != GetCurrentProcess()) {
CloseHandle(dp);
}
}
if ((sb = ntspawn_malloc(sizeof(*sb)))) {
rc = ntspawn2(args, sb);
} else {
rc = -1;
}
if (sb)
ntspawn_free(sb);
ALLOW_SIGNALS;
return rc;
}
+1 -2
View File
@@ -1641,7 +1641,6 @@ static privileged void AllowMmapExec(struct Filter *f) {
//
// - MAP_LOCKED (0x02000)
// - MAP_NONBLOCK (0x10000)
// - MAP_HUGETLB (0x40000)
//
static privileged void AllowMmapNoexec(struct Filter *f) {
static const struct sock_filter fragment[] = {
@@ -1650,7 +1649,7 @@ static privileged void AllowMmapNoexec(struct Filter *f) {
/*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, ~(PROT_READ | PROT_WRITE)),
/*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 8 - 4),
/*L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[3])), // flags
/*L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x52000),
/*L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x12000),
/*L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
/*L7*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
/*L8*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
+16 -12
View File
@@ -24,11 +24,13 @@
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/promises.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h"
#include "libc/nexgen32e/vendor.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/symbols.internal.h"
#include "libc/runtime/zipos.internal.h"
#include "libc/sysv/consts/pr.h"
#include "libc/sysv/errfuns.h"
@@ -199,22 +201,22 @@
* `__pledge_mode` is available to improve the experience of pledge() on
* Linux. It should specify one of the following penalties:
*
* - `PLEDGE_PENALTY_RETURN_EPERM` causes system calls to just return an
* `EPERM` error instead of killing. This is the default on Linux.
* This is a gentler solution that allows code to display a friendly
* warning. Please note this may lead to weird behaviors if the
* software being sandboxed is lazy about checking error results.
*
* - `PLEDGE_PENALTY_KILL_THREAD` causes the violating thread to be
* killed. This is the default on Linux. It's effectively the same as
* killing the process, since redbean has no threads. The termination
* signal can't be caught and will be either `SIGSYS` or `SIGABRT`.
* Consider enabling stderr logging below so you'll know why your
* program failed. Otherwise check the system log.
* killed. It's effectively the same as killing the process, since
* redbean has no threads. The termination signal can't be caught and
* will be either `SIGSYS` or `SIGABRT`. Consider enabling stderr
* logging below so you'll know why your program failed. Otherwise
* check the system log.
*
* - `PLEDGE_PENALTY_KILL_PROCESS` causes the process and all its
* threads to be killed. This is always the case on OpenBSD.
*
* - `PLEDGE_PENALTY_RETURN_EPERM` causes system calls to just return an
* `EPERM` error instead of killing. This is a gentler solution that
* allows code to display a friendly warning. Please note this may
* lead to weird behaviors if the software being sandboxed is lazy
* about checking error results.
*
* `mode` may optionally bitwise or the following flags:
*
* - `PLEDGE_STDERR_LOGGING` enables friendly error message logging
@@ -240,6 +242,8 @@
int pledge(const char *promises, const char *execpromises) {
int e, rc;
unsigned long ipromises, iexecpromises;
if (_weaken(GetSymbolTable))
_weaken(GetSymbolTable)();
if (!promises) {
// OpenBSD says NULL argument means it doesn't change, i.e.
// pledge(0,0) on OpenBSD does nothing. The Cosmopolitan Libc
+1 -1
View File
@@ -22,7 +22,7 @@
#include "libc/dce.h"
#include "libc/intrin/strace.internal.h"
#include "libc/sysv/errfuns.h"
#include "libc/time/struct/timezone.h"
#include "libc/time.h"
/**
* Changes time.
+6
View File
@@ -252,6 +252,12 @@ static int __sigaction(int sig, const struct sigaction *act,
rc = sys_sigaction(sig, ap, oldact, arg4, arg5);
} else {
rc = _sysret(__syslib->__sigaction(sig, ap, oldact));
// xnu silicon claims to support sa_resethand but it does nothing
// this can be tested, since it clears the bit from flags as well
if (!rc && oldact &&
(((struct sigaction_silicon *)oldact)->sa_flags & SA_RESETHAND)) {
((struct sigaction_silicon *)oldact)->sa_flags |= SA_RESETHAND;
}
}
if (rc != -1) {
sigaction_native2cosmo((union metasigaction *)oldact);
+17
View File
@@ -30,6 +30,7 @@
#include "libc/log/libfatal.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/stack.h"
#include "libc/runtime/syslib.internal.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/sa.h"
@@ -494,6 +495,8 @@ privileged void __sigenter_xnu(void *fn, int infostyle, int sig,
privileged void __sigenter_xnu(int sig, struct siginfo_xnu *xnuinfo,
struct __darwin_ucontext *xnuctx) {
#endif
// allocate signal frame on stack
#pragma GCC push_options
#pragma GCC diagnostic ignored "-Wframe-larger-than="
struct Goodies {
@@ -502,10 +505,24 @@ privileged void __sigenter_xnu(int sig, struct siginfo_xnu *xnuinfo,
} g;
CheckLargeStackAllocation(&g, sizeof(g));
#pragma GCC pop_options
// handle signal
int rva, flags;
rva = __sighandrvas[sig];
if (rva >= kSigactionMinRva) {
flags = __sighandflags[sig];
#ifdef __aarch64__
// xnu silicon claims to support sa_resethand but it does nothing
// this can be tested, since it clears the bit from flags as well
if (flags & SA_RESETHAND) {
struct sigaction sa = {0};
__syslib->__sigaction(sig, &sa, 0);
__sighandflags[sig] = 0;
__sighandrvas[sig] = 0;
}
#endif
if (~flags & SA_SIGINFO) {
((sigaction_f)(__executable_start + rva))(sig, 0, 0);
} else {
+1 -1
View File
@@ -24,7 +24,7 @@
#include "libc/sysv/consts/clock.h"
#include "libc/thread/posixthread.internal.h"
#include "libc/thread/thread.h"
#include "libc/time/time.h"
#include "libc/time.h"
/**
* Sleeps for particular number of seconds.
+1 -1
View File
@@ -17,7 +17,7 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/struct/timeval.h"
#include "libc/time/time.h"
#include "libc/time.h"
/**
* Changes time, the old fashioned way.
-1
View File
@@ -5,7 +5,6 @@
#include "libc/mem/alloca.h"
COSMOPOLITAN_C_START_
ssize_t __robust_writev(int, struct iovec *, int);
int64_t sys_preadv(int, struct iovec *, int, int64_t, int64_t);
int64_t sys_pwritev(int, const struct iovec *, int, int64_t, int64_t);
int64_t sys_readv(int32_t, const struct iovec *, int32_t);
+1 -1
View File
@@ -1,7 +1,7 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMEVAL_H_
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMEVAL_H_
#include "libc/calls/struct/timespec.h"
#include "libc/time/struct/timezone.h"
#include "libc/time.h"
COSMOPOLITAN_C_START_
struct timeval {
+1 -1
View File
@@ -2,7 +2,7 @@
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_TIMEVAL_INTERNAL_H_
#include "libc/calls/struct/timeval.h"
#include "libc/mem/alloca.h"
#include "libc/time/struct/timezone.h"
#include "libc/time.h"
COSMOPOLITAN_C_START_
int sys_settimeofday(const struct timeval *, const struct timezone *);
+1 -1
View File
@@ -16,7 +16,7 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/time/time.h"
#include "libc/time.h"
#include "libc/calls/struct/timeval.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
+1 -1
View File
@@ -18,7 +18,7 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/struct/timespec.h"
#include "libc/sysv/consts/clock.h"
#include "libc/time/time.h"
#include "libc/time.h"
/**
* Returns high-precision timestamp, the C11 way.
+1 -1
View File
@@ -18,7 +18,7 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/struct/timespec.h"
#include "libc/sysv/consts/clock.h"
#include "libc/time/time.h"
#include "libc/time.h"
/**
* Returns high-precision timestamp granularity, the C23 way.
+1 -1
View File
@@ -21,7 +21,7 @@
#include "libc/sysv/consts/clock.h"
#include "libc/sysv/consts/utime.h"
#include "libc/sysv/errfuns.h"
#include "libc/time/time.h"
#include "libc/time.h"
/**
* Sleeps for particular number of microseconds.
+1 -1
View File
@@ -16,8 +16,8 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/utime.h"
#include "libc/calls/struct/timeval.h"
#include "libc/time/struct/utimbuf.h"
/**
* Changes last accessed/modified times on file.
+1 -1
View File
@@ -33,7 +33,7 @@
#include "libc/sysv/consts/at.h"
#include "libc/sysv/consts/utime.h"
#include "libc/sysv/errfuns.h"
#include "libc/time/time.h"
#include "libc/time.h"
static textwindows int sys_utimensat_nt_impl(int dirfd, const char *path,
const struct timespec ts[2],
+1 -1
View File
@@ -24,7 +24,7 @@
#include "libc/fmt/conv.h"
#include "libc/runtime/zipos.internal.h"
#include "libc/sysv/consts/at.h"
#include "libc/time/time.h"
#include "libc/time.h"
int sys_utimensat(int dirfd, const char *path, const struct timespec ts[2],
int flags) {
+2
View File
@@ -6,6 +6,8 @@ errno_t cosmo_once(_Atomic(uint32_t) *, void (*)(void));
int systemvpe(const char *, char *const[], char *const[]) libcesque;
char *GetProgramExecutableName(void);
void unleaf(void);
int __demangle(char *, const char *, size_t);
int __is_mangled(const char *);
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_COSMO_H_ */
+4
View File
@@ -85,6 +85,10 @@
#define EM_RISCV 243
#define EM_BPF 247
/* the ape flag, "lol cat 5" */
#define EF_APE_MODERN 0x101ca75
#define EF_APE_MODERN_MASK 0x1ffffff
#define GRP_COMDAT 1
#define STN_UNDEF 0
+1 -1
View File
@@ -45,7 +45,7 @@ char *sleb64(char *p, int64_t x) {
*p++ = c;
return p;
} else {
*p++ = c | 64;
*p++ = c | 128;
}
}
}
+1 -1
View File
@@ -4,7 +4,7 @@
#define __COSMOPOLITAN_MAJOR__ 3
#define __COSMOPOLITAN_MINOR__ 3
#define __COSMOPOLITAN_PATCH__ 4
#define __COSMOPOLITAN_PATCH__ 7
#define __COSMOPOLITAN__ \
(100000000 * __COSMOPOLITAN_MAJOR__ + 1000000 * __COSMOPOLITAN_MINOR__ + \
__COSMOPOLITAN_PATCH__)
+18 -1
View File
@@ -82,7 +82,16 @@ o//libc/intrin/memcmp.o \
o//libc/intrin/memset.o \
o//libc/intrin/memmove.o: private \
CFLAGS += \
-O2 -finline -foptimize-sibling-calls
-O2 \
-finline \
-foptimize-sibling-calls
# make asan stack traces shorter
o/$(MODE)/libc/intrin/asanthunk.o: private \
CFLAGS += \
-Os \
$(NO_MAGIC) \
-foptimize-sibling-calls
o/$(MODE)/libc/intrin/bzero.o \
o/$(MODE)/libc/intrin/memcmp.o \
@@ -132,6 +141,14 @@ o/$(MODE)/libc/intrin/ktcpoptnames.o: libc/intrin/ktcpoptnames.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/intrin/stackcall.o: libc/intrin/stackcall.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/intrin/kmonthname.o: libc/intrin/kmonthname.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/intrin/kmonthnameshort.o: libc/intrin/kmonthnameshort.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/intrin/kweekdayname.o: libc/intrin/kweekdayname.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/intrin/kweekdaynameshort.o: libc/intrin/kweekdaynameshort.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
LIBC_INTRIN_LIBS = $(foreach x,$(LIBC_INTRIN_ARTIFACTS),$($(x)))
LIBC_INTRIN_HDRS = $(foreach x,$(LIBC_INTRIN_ARTIFACTS),$($(x)_HDRS))
+1
View File
@@ -30,6 +30,7 @@ const char *(DescribeMapFlags)(char buf[64], int x) {
{MAP_SHARED, "SHARED"}, //
{MAP_FIXED, "FIXED"}, //
{MAP_FIXED_NOREPLACE, "FIXED_NOREPLACE"}, //
{MAP_HUGETLB, "HUGETLB"}, //
{MAP_CONCEAL, "CONCEAL"}, //
{MAP_LOCKED, "LOCKED"}, //
{MAP_NORESERVE, "NORESERVE"}, //
+6 -9
View File
@@ -78,17 +78,14 @@ int feenableexcept(int excepts) {
#elif defined(__aarch64__)
unsigned fpcr;
unsigned fpcr2;
unsigned updated_fpcr;
fpcr = __builtin_aarch64_get_fpcr();
fpcr2 = fpcr | (excepts << 8);
unsigned fpcr = __builtin_aarch64_get_fpcr();
unsigned want = excepts << 8;
unsigned fpcr2 = fpcr | want;
if (fpcr != fpcr2) {
__builtin_aarch64_set_fpcr(fpcr2);
// floating point exception trapping is optional in aarch64
updated_fpcr = __builtin_aarch64_get_fpsr();
if (fpcr2 & ~updated_fpcr)
return -1;
fpcr2 = __builtin_aarch64_get_fpsr();
if ((fpcr2 & want) != want)
return -1; // not supported by cpu
}
return (fpcr >> 8) & FE_ALL_EXCEPT;
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+1 -1
View File
@@ -21,6 +21,6 @@
// XXX: should be inherited thread local
// see also sys_pledge_linux() which is 100% pure
int __pledge_mode;
int __pledge_mode = PLEDGE_PENALTY_RETURN_EPERM;
unsigned long __promises;
unsigned long __execpromises;
+2 -1
View File
@@ -18,9 +18,10 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/dce.h"
#include "libc/fmt/magnumstrs.internal.h"
#include "libc/stdalign.internal.h"
#include "libc/str/str.h"
_Alignas(1) static char strerror_buf[128];
alignas(1) static char strerror_buf[128];
/**
* Returns string describing `err`.
+3
View File
@@ -16,6 +16,7 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/intrin/ubsan.h"
#include "libc/calls/calls.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/pushpop.internal.h"
@@ -241,6 +242,8 @@ static void __ubsan_warning(const struct UbsanSourceLocation *loc,
const char *description) {
kprintf("%s:%d: %subsan warning: %s is undefined behavior%s\n", loc->file,
loc->line, SUBTLE, description, RESET);
if (__ubsan_strict)
__ubsan_die()();
}
__wur __ubsan_die_f *__ubsan_abort(const struct UbsanSourceLocation *loc,
+8
View File
@@ -0,0 +1,8 @@
#ifndef COSMOPOLITAN_LIBC_INTRIN_UBSAN_H_
#define COSMOPOLITAN_LIBC_INTRIN_UBSAN_H_
COSMOPOLITAN_C_START_
extern bool32 __ubsan_strict;
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_INTRIN_UBSAN_H_ */
@@ -1,7 +1,7 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi │
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2022 Justine Alexandra Roberts Tunney │
│ Copyright 2024 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 │
@@ -16,8 +16,8 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/time/time.h"
char *tzname[2];
long timezone;
int daylight;
/**
* If set to true, UBSAN warnings will become fatal.
*/
bool32 __ubsan_strict = false;
+2 -135
View File
@@ -12,135 +12,9 @@
//
//===----------------------------------------------------------------------===//
#if defined(__x86_64__) && (defined(__GNUC__) || defined(__clang__))
#include "libc/intrin/x86.h"
enum VendorSignatures {
SIG_INTEL = 0x756e6547, // Genu
SIG_AMD = 0x68747541, // Auth
};
enum ProcessorVendors {
VENDOR_INTEL = 1,
VENDOR_AMD,
VENDOR_OTHER,
VENDOR_MAX
};
enum ProcessorTypes {
INTEL_BONNELL = 1,
INTEL_CORE2,
INTEL_COREI7,
AMDFAM10H,
AMDFAM15H,
INTEL_SILVERMONT,
INTEL_KNL,
AMD_BTVER1,
AMD_BTVER2,
AMDFAM17H,
INTEL_KNM,
INTEL_GOLDMONT,
INTEL_GOLDMONT_PLUS,
INTEL_TREMONT,
AMDFAM19H,
ZHAOXIN_FAM7H,
INTEL_SIERRAFOREST,
INTEL_GRANDRIDGE,
INTEL_CLEARWATERFOREST,
CPU_TYPE_MAX
};
enum ProcessorSubtypes {
INTEL_COREI7_NEHALEM = 1,
INTEL_COREI7_WESTMERE,
INTEL_COREI7_SANDYBRIDGE,
AMDFAM10H_BARCELONA,
AMDFAM10H_SHANGHAI,
AMDFAM10H_ISTANBUL,
AMDFAM15H_BDVER1,
AMDFAM15H_BDVER2,
AMDFAM15H_BDVER3,
AMDFAM15H_BDVER4,
AMDFAM17H_ZNVER1,
INTEL_COREI7_IVYBRIDGE,
INTEL_COREI7_HASWELL,
INTEL_COREI7_BROADWELL,
INTEL_COREI7_SKYLAKE,
INTEL_COREI7_SKYLAKE_AVX512,
INTEL_COREI7_CANNONLAKE,
INTEL_COREI7_ICELAKE_CLIENT,
INTEL_COREI7_ICELAKE_SERVER,
AMDFAM17H_ZNVER2,
INTEL_COREI7_CASCADELAKE,
INTEL_COREI7_TIGERLAKE,
INTEL_COREI7_COOPERLAKE,
INTEL_COREI7_SAPPHIRERAPIDS,
INTEL_COREI7_ALDERLAKE,
AMDFAM19H_ZNVER3,
INTEL_COREI7_ROCKETLAKE,
ZHAOXIN_FAM7H_LUJIAZUI,
AMDFAM19H_ZNVER4,
INTEL_COREI7_GRANITERAPIDS,
INTEL_COREI7_GRANITERAPIDS_D,
INTEL_COREI7_ARROWLAKE,
INTEL_COREI7_ARROWLAKE_S,
INTEL_COREI7_PANTHERLAKE,
CPU_SUBTYPE_MAX
};
enum ProcessorFeatures {
FEATURE_CMOV = 0,
FEATURE_MMX,
FEATURE_POPCNT,
FEATURE_SSE,
FEATURE_SSE2,
FEATURE_SSE3,
FEATURE_SSSE3,
FEATURE_SSE4_1,
FEATURE_SSE4_2,
FEATURE_AVX,
FEATURE_AVX2,
FEATURE_SSE4_A,
FEATURE_FMA4,
FEATURE_XOP,
FEATURE_FMA,
FEATURE_AVX512F,
FEATURE_BMI,
FEATURE_BMI2,
FEATURE_AES,
FEATURE_PCLMUL,
FEATURE_AVX512VL,
FEATURE_AVX512BW,
FEATURE_AVX512DQ,
FEATURE_AVX512CD,
FEATURE_AVX512ER,
FEATURE_AVX512PF,
FEATURE_AVX512VBMI,
FEATURE_AVX512IFMA,
FEATURE_AVX5124VNNIW,
FEATURE_AVX5124FMAPS,
FEATURE_AVX512VPOPCNTDQ,
FEATURE_AVX512VBMI2,
FEATURE_GFNI,
FEATURE_VPCLMULQDQ,
FEATURE_AVX512VNNI,
FEATURE_AVX512BITALG,
FEATURE_AVX512BF16,
FEATURE_AVX512VP2INTERSECT,
FEATURE_CMPXCHG16B = 46,
FEATURE_F16C = 49,
FEATURE_LAHF_LM = 54,
FEATURE_LM,
FEATURE_WP,
FEATURE_LZCNT,
FEATURE_MOVBE,
FEATURE_AVX512FP16 = 94,
FEATURE_X86_64_BASELINE,
FEATURE_X86_64_V2,
FEATURE_X86_64_V3,
FEATURE_X86_64_V4,
CPU_FEATURE_MAX
};
struct __processor_model __cpu_model;
// The check below for i386 was copied from clang's cpuid.h (__get_cpuid_max).
// Check motivated by bug reports for OpenSSL crashing on CPUs without CPUID
@@ -782,13 +656,6 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf,
#undef setFeature
}
struct __processor_model {
unsigned int __cpu_vendor;
unsigned int __cpu_type;
unsigned int __cpu_subtype;
unsigned int __cpu_features[1];
} __cpu_model = {0, 0, 0, {0}};
unsigned __cpu_features2[(CPU_FEATURE_MAX - 1) / 32];
// A constructor function that is sets __cpu_model and __cpu_features2 with
+147
View File
@@ -0,0 +1,147 @@
#ifndef COSMOPOLITAN_LIBC_INTRIN_X86_H_
#define COSMOPOLITAN_LIBC_INTRIN_X86_H_
COSMOPOLITAN_C_START_
enum VendorSignatures {
SIG_INTEL = 0x756e6547, /* Genu */
SIG_AMD = 0x68747541, /* Auth */
};
enum ProcessorVendors {
VENDOR_INTEL = 1,
VENDOR_AMD,
VENDOR_OTHER,
VENDOR_MAX
};
enum ProcessorTypes {
INTEL_BONNELL = 1,
INTEL_CORE2,
INTEL_COREI7,
AMDFAM10H,
AMDFAM15H,
INTEL_SILVERMONT,
INTEL_KNL,
AMD_BTVER1,
AMD_BTVER2,
AMDFAM17H,
INTEL_KNM,
INTEL_GOLDMONT,
INTEL_GOLDMONT_PLUS,
INTEL_TREMONT,
AMDFAM19H,
ZHAOXIN_FAM7H,
INTEL_SIERRAFOREST,
INTEL_GRANDRIDGE,
INTEL_CLEARWATERFOREST,
CPU_TYPE_MAX
};
enum ProcessorSubtypes {
INTEL_COREI7_NEHALEM = 1,
INTEL_COREI7_WESTMERE,
INTEL_COREI7_SANDYBRIDGE,
AMDFAM10H_BARCELONA,
AMDFAM10H_SHANGHAI,
AMDFAM10H_ISTANBUL,
AMDFAM15H_BDVER1,
AMDFAM15H_BDVER2,
AMDFAM15H_BDVER3,
AMDFAM15H_BDVER4,
AMDFAM17H_ZNVER1,
INTEL_COREI7_IVYBRIDGE,
INTEL_COREI7_HASWELL,
INTEL_COREI7_BROADWELL,
INTEL_COREI7_SKYLAKE,
INTEL_COREI7_SKYLAKE_AVX512,
INTEL_COREI7_CANNONLAKE,
INTEL_COREI7_ICELAKE_CLIENT,
INTEL_COREI7_ICELAKE_SERVER,
AMDFAM17H_ZNVER2,
INTEL_COREI7_CASCADELAKE,
INTEL_COREI7_TIGERLAKE,
INTEL_COREI7_COOPERLAKE,
INTEL_COREI7_SAPPHIRERAPIDS,
INTEL_COREI7_ALDERLAKE,
AMDFAM19H_ZNVER3,
INTEL_COREI7_ROCKETLAKE,
ZHAOXIN_FAM7H_LUJIAZUI,
AMDFAM19H_ZNVER4,
INTEL_COREI7_GRANITERAPIDS,
INTEL_COREI7_GRANITERAPIDS_D,
INTEL_COREI7_ARROWLAKE,
INTEL_COREI7_ARROWLAKE_S,
INTEL_COREI7_PANTHERLAKE,
CPU_SUBTYPE_MAX
};
enum ProcessorFeatures {
FEATURE_CMOV = 0,
FEATURE_MMX,
FEATURE_POPCNT,
FEATURE_SSE,
FEATURE_SSE2,
FEATURE_SSE3,
FEATURE_SSSE3,
FEATURE_SSE4_1,
FEATURE_SSE4_2,
FEATURE_AVX,
FEATURE_AVX2,
FEATURE_SSE4_A,
FEATURE_FMA4,
FEATURE_XOP,
FEATURE_FMA,
FEATURE_AVX512F,
FEATURE_BMI,
FEATURE_BMI2,
FEATURE_AES,
FEATURE_PCLMUL,
FEATURE_AVX512VL,
FEATURE_AVX512BW,
FEATURE_AVX512DQ,
FEATURE_AVX512CD,
FEATURE_AVX512ER,
FEATURE_AVX512PF,
FEATURE_AVX512VBMI,
FEATURE_AVX512IFMA,
FEATURE_AVX5124VNNIW,
FEATURE_AVX5124FMAPS,
FEATURE_AVX512VPOPCNTDQ,
FEATURE_AVX512VBMI2,
FEATURE_GFNI,
FEATURE_VPCLMULQDQ,
FEATURE_AVX512VNNI,
FEATURE_AVX512BITALG,
FEATURE_AVX512BF16,
FEATURE_AVX512VP2INTERSECT,
FEATURE_CMPXCHG16B = 46,
FEATURE_F16C = 49,
FEATURE_LAHF_LM = 54,
FEATURE_LM,
FEATURE_WP,
FEATURE_LZCNT,
FEATURE_MOVBE,
FEATURE_AVX512FP16 = 94,
FEATURE_X86_64_BASELINE,
FEATURE_X86_64_V2,
FEATURE_X86_64_V3,
FEATURE_X86_64_V4,
CPU_FEATURE_MAX
};
struct __processor_model {
unsigned __cpu_vendor;
unsigned __cpu_type;
unsigned __cpu_subtype;
unsigned __cpu_features[1];
const char *__cpu_march;
};
extern struct __processor_model __cpu_model;
const char *__cpu_march(unsigned);
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_INTRIN_X86_H_ */
+94
View File
@@ -0,0 +1,94 @@
// Copyright 2024 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/intrin/x86.h"
/**
* Returns microarchitecture name, e.g.
*
* puts(__cpu_march(__cpu_model.__cpu_subtype));
*
*/
const char *__cpu_march(unsigned subtype) {
switch (subtype) {
case INTEL_COREI7_NEHALEM:
return "nehalem";
case INTEL_COREI7_WESTMERE:
return "westmere";
case INTEL_COREI7_SANDYBRIDGE:
return "sandybridge";
case AMDFAM10H_BARCELONA:
return "amdfam10";
case AMDFAM10H_SHANGHAI:
return "amdfam10";
case AMDFAM10H_ISTANBUL:
return "amdfam10";
case AMDFAM15H_BDVER1:
return "bdver2";
case AMDFAM15H_BDVER2:
return "bdver2";
case AMDFAM15H_BDVER3:
return "bdver3";
case AMDFAM15H_BDVER4:
return "bdver4";
case AMDFAM17H_ZNVER1:
return "znver2";
case INTEL_COREI7_IVYBRIDGE:
return "ivybridge";
case INTEL_COREI7_HASWELL:
return "haswell";
case INTEL_COREI7_BROADWELL:
return "broadwell";
case INTEL_COREI7_SKYLAKE:
return "skylake";
case INTEL_COREI7_SKYLAKE_AVX512:
return "skylake-avx512";
case INTEL_COREI7_CANNONLAKE:
return "cannonlake";
case INTEL_COREI7_ICELAKE_CLIENT:
return "icelake-client";
case INTEL_COREI7_ICELAKE_SERVER:
return "icelake-server";
case AMDFAM17H_ZNVER2:
return "znver2";
case INTEL_COREI7_CASCADELAKE:
return "cascadelake";
case INTEL_COREI7_TIGERLAKE:
return "tigerlake";
case INTEL_COREI7_COOPERLAKE:
return "cooperlake";
case INTEL_COREI7_SAPPHIRERAPIDS:
return "sapphirerapids";
case INTEL_COREI7_ALDERLAKE:
return "alderlake";
case AMDFAM19H_ZNVER3:
return "znver3";
case INTEL_COREI7_ROCKETLAKE:
return "rocketlake";
case AMDFAM19H_ZNVER4:
return "znver4";
case INTEL_COREI7_GRANITERAPIDS:
return "graniterapids";
case INTEL_COREI7_GRANITERAPIDS_D:
return "graniterapids-d";
case INTEL_COREI7_ARROWLAKE:
return "arrowlake";
case INTEL_COREI7_ARROWLAKE_S:
return "arrowlake-s";
case INTEL_COREI7_PANTHERLAKE:
return "pantherlake";
default:
return 0;
}
}
+1
View File
@@ -2,4 +2,5 @@
#define COSMOPOLITAN_LIBC_ISYSTEM_SYS_AUXV_H_
#include "libc/runtime/runtime.h"
#include "libc/sysv/consts/auxv.h"
#include "libc/sysv/consts/hwcap.h"
#endif /* COSMOPOLITAN_LIBC_ISYSTEM_SYS_AUXV_H_ */
+1 -1
View File
@@ -7,5 +7,5 @@
#include "libc/calls/weirdtypes.h"
#include "libc/sysv/consts/s.h"
#include "libc/sysv/consts/utime.h"
#include "libc/time/time.h"
#include "libc/time.h"
#endif
+1 -2
View File
@@ -6,6 +6,5 @@
#include "libc/sock/select.h"
#include "libc/sysv/consts/clock.h"
#include "libc/sysv/consts/itimer.h"
#include "libc/time/struct/timezone.h"
#include "libc/time/time.h"
#include "libc/time.h"
#endif
+1 -2
View File
@@ -7,6 +7,5 @@
#include "libc/sysv/consts/clock.h"
#include "libc/sysv/consts/sched.h"
#include "libc/sysv/consts/timer.h"
#include "libc/time/struct/tm.h"
#include "libc/time/time.h"
#include "libc/time.h"
#endif /* _TIME_H */
+1 -1
View File
@@ -9,7 +9,7 @@
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/ok.h"
#include "libc/time/time.h"
#include "libc/time.h"
#include "libc/unistd.h"
#include "third_party/getopt/long1.h"
#include "third_party/musl/crypt.h"
+1 -2
View File
@@ -1,5 +1,4 @@
#ifndef _UTIME_H
#define _UTIME_H
#include "libc/time/struct/utimbuf.h"
#include "libc/time/time.h"
#include "libc/utime.h"
#endif /* _UTIME_H */
+1 -1
View File
@@ -5,5 +5,5 @@
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/str/unicode.h"
#include "libc/time/time.h"
#include "libc/time.h"
#endif /* _WCHAR_H */
+2 -2
View File
@@ -39,11 +39,11 @@ LIBC_LOG_A_DIRECTDEPS = \
LIBC_SYSV \
LIBC_SYSV_CALLS \
LIBC_THREAD \
LIBC_TIME \
LIBC_TINYMATH \
THIRD_PARTY_COMPILER_RT \
THIRD_PARTY_DLMALLOC \
THIRD_PARTY_GDTOA
THIRD_PARTY_GDTOA \
THIRD_PARTY_TZ
LIBC_LOG_A_DEPS := \
$(call uniq,$(foreach x,$(LIBC_LOG_A_DIRECTDEPS),$($(x))))
+10 -6
View File
@@ -37,9 +37,14 @@ static struct {
} g_addr2line;
void GetAddr2linePathInit(void) {
char *res;
int e = errno;
const char *path;
if (!(path = getenv("ADDR2LINE"))) {
const char *env, *cmd, *path;
if ((env = getenv("ADDR2LINE"))) {
cmd = env;
path = env;
} else {
cmd = "addr2line";
path = ADDR2LINE;
}
char *buf = g_addr2line.buf;
@@ -48,12 +53,11 @@ void GetAddr2linePathInit(void) {
strlcat(buf, "/", PATH_MAX);
}
strlcat(buf, path, PATH_MAX);
}
if (*buf) {
g_addr2line.res = buf;
res = buf;
} else {
g_addr2line.res = commandv("addr2line", buf, PATH_MAX);
res = commandv(cmd, buf, PATH_MAX);
}
g_addr2line.res = res;
errno = e;
}
+1 -1
View File
@@ -66,7 +66,7 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) {
}
if (!PLEDGED(STDIO) || !PLEDGED(EXEC) || !PLEDGED(EXEC)) {
ShowHint("won't print addr2line backtrace because pledge");
ShowHint("pledge() sandboxing makes backtraces not as good");
return -1;
}
+14 -2
View File
@@ -18,6 +18,7 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/assert.h"
#include "libc/calls/calls.h"
#include "libc/cosmo.h"
#include "libc/fmt/itoa.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/weaken.h"
@@ -29,6 +30,7 @@
#include "libc/runtime/runtime.h"
#include "libc/runtime/symbols.internal.h"
#include "libc/str/str.h"
#include "libc/thread/thread.h"
#include "libc/thread/tls.h"
#define LIMIT 100
@@ -47,8 +49,11 @@ dontinstrument dontasan int PrintBacktraceUsingSymbols(
int fd, const struct StackFrame *bp, struct SymbolTable *st) {
size_t gi;
intptr_t addr;
const char *name;
int i, symbol, addend;
static char cxxbuf[8192];
struct Garbages *garbage;
static pthread_spinlock_t lock;
const struct StackFrame *frame;
(void)gi;
if (!bp)
@@ -83,8 +88,15 @@ dontinstrument dontasan int PrintBacktraceUsingSymbols(
symbol = 0;
addend = 0;
}
kprintf("%012lx %lx %s%+d\n", frame, addr, __get_symbol_name(st, symbol),
addend);
if ((name = __get_symbol_name(st, symbol)) && __is_mangled(name)) {
pthread_spin_lock(&lock);
__demangle(cxxbuf, name, sizeof(cxxbuf));
kprintf("%012lx %lx %s%+d\n", frame, addr, cxxbuf, addend);
pthread_spin_unlock(&lock);
name = cxxbuf;
} else {
kprintf("%012lx %lx %s%+d\n", frame, addr, name, addend);
}
}
return 0;
}
+2
View File
@@ -192,6 +192,8 @@ void ShowCrashReportHook(int, int, int, struct siginfo *, ucontext_t *);
static relegated void ShowCrashReport(int err, int sig, struct siginfo *si,
ucontext_t *ctx) {
if (sig != SIGTRAP && sig != SIGQUIT)
sigaddset(&ctx->uc_sigmask, sig);
#pragma GCC push_options
#pragma GCC diagnostic ignored "-Walloca-larger-than="
long size = __get_safe_size(8192, 4096);
+15 -16
View File
@@ -31,6 +31,7 @@
#include "libc/calls/struct/utsname.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/calls/ucontext.h"
#include "libc/cosmo.h"
#include "libc/cxxabi.h"
#include "libc/errno.h"
#include "libc/intrin/atomic.h"
@@ -40,7 +41,6 @@
#include "libc/log/internal.h"
#include "libc/log/log.h"
#include "libc/macros.internal.h"
#include "libc/mem/mem.h"
#include "libc/nexgen32e/stackframe.h"
#include "libc/runtime/memtrack.internal.h"
#include "libc/runtime/runtime.h"
@@ -178,19 +178,21 @@ static relegated bool AppendFileLine(struct Buffer *b, const char *addr2line,
}
}
static relegated char *GetSymbolName(struct SymbolTable *st, int symbol,
char **mem, size_t *memsz) {
char *s, *t;
if ((s = __get_symbol_name(st, symbol)) && //
s[0] == '_' && s[1] == 'Z' && //
(t = __cxa_demangle(s, *mem, memsz, 0))) {
*mem = s = t;
}
return s;
static relegated char *GetSymbolName(struct SymbolTable *st, int symbol) {
char *str;
static char buf[8192];
if (!(str = __get_symbol_name(st, symbol)))
return str;
if (!__is_mangled(str))
return str;
__demangle(buf, str, sizeof(buf));
return buf;
}
static relegated void __oncrash_impl(int sig, struct siginfo *si,
ucontext_t *ctx) {
if (sig != SIGTRAP && sig != SIGQUIT)
sigaddset(&ctx->uc_sigmask, sig);
#pragma GCC push_options
#pragma GCC diagnostic ignored "-Walloca-larger-than="
long size = __get_safe_size(10000, 4096);
@@ -241,8 +243,6 @@ static relegated void __oncrash_impl(int sig, struct siginfo *si,
: (struct StackFrame *)__builtin_frame_address(0)));
if (ctx) {
long pc;
char *mem = 0;
size_t memsz = 0;
int addend, symbol;
const char *debugbin;
const char *addr2line;
@@ -305,7 +305,7 @@ static relegated void __oncrash_impl(int sig, struct siginfo *si,
addend -= st->symbols[symbol].x;
Append(b, " ");
if (!AppendFileLine(b, addr2line, debugbin, pc)) {
Append(b, "%s", GetSymbolName(st, symbol, &mem, &memsz));
Append(b, "%s", GetSymbolName(st, symbol));
if (addend)
Append(b, "%+d", addend);
}
@@ -327,7 +327,7 @@ static relegated void __oncrash_impl(int sig, struct siginfo *si,
addend -= st->symbols[symbol].x;
Append(b, " ");
if (!AppendFileLine(b, addr2line, debugbin, pc)) {
Append(b, "%s", GetSymbolName(st, symbol, &mem, &memsz));
Append(b, "%s", GetSymbolName(st, symbol));
if (addend)
Append(b, "%+d", addend);
}
@@ -367,13 +367,12 @@ static relegated void __oncrash_impl(int sig, struct siginfo *si,
}
Append(b, " %016lx fp %lx lr ", fp, pc);
if (!AppendFileLine(b, addr2line, debugbin, pc) && st) {
Append(b, "%s", GetSymbolName(st, symbol, &mem, &memsz));
Append(b, "%s", GetSymbolName(st, symbol));
if (addend)
Append(b, "%+d", addend);
}
Append(b, "\n");
}
free(mem);
}
b->p[b->n - 1] = '\n';
klog(b->p, MIN(b->i, b->n));
+6 -6
View File
@@ -85,13 +85,13 @@ void ShowCrashReports(void) {
#ifdef __x86_64__
InstallCrashHandler(SIGTRAP, 0);
#else
InstallCrashHandler(SIGTRAP, SA_RESETHAND);
InstallCrashHandler(SIGTRAP, 0);
#endif
InstallCrashHandler(SIGFPE, SA_RESETHAND);
InstallCrashHandler(SIGILL, SA_RESETHAND);
InstallCrashHandler(SIGBUS, SA_RESETHAND);
InstallCrashHandler(SIGABRT, SA_RESETHAND);
InstallCrashHandler(SIGSEGV, SA_RESETHAND | SA_ONSTACK);
InstallCrashHandler(SIGFPE, 0);
InstallCrashHandler(SIGILL, 0);
InstallCrashHandler(SIGBUS, 0);
InstallCrashHandler(SIGABRT, 0);
InstallCrashHandler(SIGSEGV, SA_ONSTACK);
}
IGNORE_LEAKS(ShowCrashReports)
+1 -2
View File
@@ -37,8 +37,7 @@
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/fileno.h"
#include "libc/time/struct/tm.h"
#include "libc/time/time.h"
#include "libc/time.h"
#define kNontrivialSize (8 * 1000 * 1000)
+2
View File
@@ -8,6 +8,7 @@ LIBC_MEM = $(LIBC_MEM_A_DEPS) $(LIBC_MEM_A)
LIBC_MEM_A = o/$(MODE)/libc/mem/mem.a
LIBC_MEM_A_FILES := $(wildcard libc/mem/*)
LIBC_MEM_A_HDRS = $(filter %.h,$(LIBC_MEM_A_FILES))
LIBC_MEM_A_INCS = $(filter %.inc,$(LIBC_MEM_A_FILES))
LIBC_MEM_A_SRCS = $(filter %.c,$(LIBC_MEM_A_FILES))
LIBC_MEM_A_OBJS = $(LIBC_MEM_A_SRCS:%.c=o/$(MODE)/%.o)
@@ -46,6 +47,7 @@ $(LIBC_MEM_A_OBJS): private \
LIBC_MEM_LIBS = $(foreach x,$(LIBC_MEM_ARTIFACTS),$($(x)))
LIBC_MEM_SRCS = $(foreach x,$(LIBC_MEM_ARTIFACTS),$($(x)_SRCS))
LIBC_MEM_HDRS = $(foreach x,$(LIBC_MEM_ARTIFACTS),$($(x)_HDRS))
LIBC_MEM_INCS = $(foreach x,$(LIBC_MEM_ARTIFACTS),$($(x)_INCS))
LIBC_MEM_BINS = $(foreach x,$(LIBC_MEM_ARTIFACTS),$($(x)_BINS))
LIBC_MEM_CHECKS = $(foreach x,$(LIBC_MEM_ARTIFACTS),$($(x)_CHECKS))
LIBC_MEM_OBJS = $(foreach x,$(LIBC_MEM_ARTIFACTS),$($(x)_OBJS))
+169
View File
@@ -0,0 +1,169 @@
// Copyright 2024 Justine Alexandra Roberts Tunney
//
// Permission to use, copy, modify, and/or distribute this software for
// any purpose with or without fee is hereby granted, provided that the
// above copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include "libc/assert.h"
#include "libc/errno.h"
#include "libc/mem/mem.h"
#include "libc/stdalign.internal.h"
#include "libc/stdckdint.h"
#include "libc/str/str.h"
#ifndef TINYMALLOC_MAX_BYTES
#define TINYMALLOC_MAX_BYTES 1073741824
#endif
#ifndef TINYMALLOC_MAX_ALIGN
#define TINYMALLOC_MAX_ALIGN 4096
#endif
#ifndef MODE_DBG /* don't interfere with asan dlmalloc hooking */
alignas(TINYMALLOC_MAX_ALIGN) static struct {
char memory[TINYMALLOC_MAX_BYTES];
unsigned used, last, free;
} heap;
static inline bool isheap(char *mem) {
return heap.memory <= mem && mem < heap.memory + heap.used;
}
void free(void *ptr) {
char *mem;
unsigned base;
if (ptr) {
mem = (char *)ptr;
unassert(isheap(mem));
base = mem - heap.memory;
*(unsigned *)mem = heap.free;
heap.free = base;
}
}
size_t malloc_usable_size(void *ptr) {
char *mem = (char *)ptr;
unassert(isheap(mem));
return ((unsigned *)mem)[-1];
}
void *memalign(size_t align, size_t need) {
char *res;
unsigned next, next2, base, toto, *link, *link2;
// normalize arguments
while (align & (align - 1))
++align;
if (need < sizeof(unsigned))
need = sizeof(unsigned);
if (align < sizeof(unsigned))
align = sizeof(unsigned);
if (align > TINYMALLOC_MAX_ALIGN)
goto InvalidArgument;
if (ckd_add(&need, need, sizeof(unsigned) - 1))
goto OutOfMemory;
need &= -sizeof(unsigned);
// allocate from free list
next = heap.free;
link = &heap.free;
while (next) {
next2 = *(unsigned *)(heap.memory + next);
link2 = (unsigned *)(heap.memory + next);
if (need <= ((unsigned *)(heap.memory + next))[-1]) {
*link = next2;
return (void *)(heap.memory + next);
}
next = next2;
link = link2;
}
// allocate new static memory
base = heap.used;
base += sizeof(unsigned);
base += align - 1;
base &= -align;
if (ckd_add(&toto, base, need))
goto OutOfMemory;
if (toto > TINYMALLOC_MAX_BYTES)
goto OutOfMemory;
res = heap.memory + base;
((unsigned *)res)[-1] = need;
heap.used = toto;
heap.last = base;
return res;
// we require more vespene gas
OutOfMemory:
errno = ENOMEM;
return 0;
InvalidArgument:
errno = EINVAL;
return 0;
}
void *malloc(size_t need) {
return memalign(sizeof(max_align_t), need);
}
void *calloc(size_t count, size_t size) {
char *res;
unsigned need, used;
if (ckd_mul(&need, count, size))
need = -1;
used = heap.used;
if ((res = (char *)malloc(need)))
if (res - heap.memory < used)
bzero(res, need);
return res;
}
void *realloc(void *ptr, size_t need) {
char *res, *mem;
unsigned base, have, toto;
if (!ptr) {
res = (char *)malloc(need);
} else {
mem = (char *)ptr;
unassert(isheap(mem));
have = ((unsigned *)mem)[-1];
base = mem - heap.memory;
if (need < have) {
res = mem;
} else if (base == heap.last) {
if (need < sizeof(unsigned))
need = sizeof(unsigned);
if (ckd_add(&need, need, sizeof(unsigned) - 1))
goto OutOfMemory;
need &= -sizeof(unsigned);
if (ckd_add(&toto, base, need))
goto OutOfMemory;
if (toto > TINYMALLOC_MAX_BYTES)
goto OutOfMemory;
((unsigned *)mem)[-1] = need;
heap.used = toto;
res = mem;
} else if ((res = (char *)malloc(need))) {
if (have > need)
have = need;
memcpy(res, mem, have);
free(mem);
}
}
return res;
OutOfMemory:
errno = ENOMEM;
return 0;
}
#endif /* MODE_DBG */
+2 -1
View File
@@ -16,9 +16,10 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/stdalign.internal.h"
#include "libc/str/tab.internal.h"
_Alignas(uint8_t) const uint8_t kBase36[256] = {
alignas(uint8_t) const uint8_t kBase36[256] = {
['0'] = 1, //
['1'] = 2, //
['2'] = 3, //
+26 -7
View File
@@ -93,18 +93,37 @@ kCpuids:.long 0,0,0,0 // EAX=0 (Basic Processor Info)
add $4*4,%rdi
jmp 2b
3: nop
#if !X86_NEED(AVX2)
// test if cpu supports avx
testb X86_HAVE(AVX)(%r8)
jz 5f
jz 7f
testb X86_HAVE(OSXSAVE)(%r8)
jz 4f
jz 5f
xor %ecx,%ecx
xgetbv
mov %eax,%ecx
// test if operating system saves avx registers
and $XCR0_SSE|XCR0_AVX,%eax
cmp $XCR0_SSE|XCR0_AVX,%eax
je 5f
4: btr $X86_BIT(AVX),X86_WORD(AVX)(%r8)
jne 5f
// test if operating system saves avx512 registers
and $XCR0_OPMASK|XCR0_ZMM_HI256|XCR0_HI16_ZMM,%ecx
cmp $XCR0_OPMASK|XCR0_ZMM_HI256|XCR0_HI16_ZMM,%ecx
jne 6f
je 7f
// operating system doesn't support avx
5: btr $X86_BIT(AVX),X86_WORD(AVX)(%r8)
btr $X86_BIT(AVX2),X86_WORD(AVX2)(%r8)
#endif
5: pop %rbx
// operating system supports avx but not avx512
6: andl $~(1<<30|1<<28|1<<17|1<<27|1<<16|1<<21|1<<26|1<<31),KCPUIDS(7H, EBX)(%r8)
andl $~(1<<1|1<<12|1<<6|1<<11|1<<14),KCPUIDS(7H, ECX)(%r8)
andl $~(1<<2|1<<3|1<<8),KCPUIDS(7H, EDX)(%r8)
andl $~(1<<5),KCPUIDS(7H_1H, EAX)(%r8)
// we're done
7: pop %rbx
.init.end 201,_init_kCpuids
+2 -1
View File
@@ -16,9 +16,10 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/stdalign.internal.h"
#include "libc/str/tab.internal.h"
_Alignas(uint8_t) const uint8_t kToLower[256] = {
alignas(uint8_t) const uint8_t kToLower[256] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31, ' ', '!', '\"', '#', '$', '%', '&', '\'', '(', ')',
+2 -1
View File
@@ -16,9 +16,10 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/stdalign.internal.h"
#include "libc/str/tab.internal.h"
_Alignas(uint8_t) const uint8_t kToUpper[256] = {
alignas(uint8_t) const uint8_t kToUpper[256] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31, ' ', '!', '\"', '#', '$', '%', '&', '\'', '(', ')',
+2
View File
@@ -16,4 +16,6 @@
#define kNtMemLargePages 0x20000000
#define kNtMem4mbPages 0x80000000
#define kNtMemReplacePlaceholder 0x00004000
#endif /* COSMOPOLITAN_LIBC_NT_ENUM_MEMFLAGS_H_ */
+8
View File
@@ -0,0 +1,8 @@
#ifndef COSMOPOLITAN_LIBC_NT_ENUM_TIMEZONEID_H_
#define COSMOPOLITAN_LIBC_NT_ENUM_TIMEZONEID_H_
#define kNtTimeZoneIdUnknown 0
#define kNtTimeZoneIdStandard 1
#define kNtTimeZoneIdDaylight 2
#endif /* COSMOPOLITAN_LIBC_NT_ENUM_TIMEZONEID_H_ */
@@ -0,0 +1,20 @@
#include "libc/nt/codegen.h"
.imp kernel32,__imp_GetDynamicTimeZoneInformation,GetDynamicTimeZoneInformation
.text.windows
.ftrace1
GetDynamicTimeZoneInformation:
.ftrace2
#ifdef __x86_64__
push %rbp
mov %rsp,%rbp
mov %rdi,%rcx
sub $32,%rsp
call *__imp_GetDynamicTimeZoneInformation(%rip)
leave
#elif defined(__aarch64__)
mov x0,#0
#endif
ret
.endfn GetDynamicTimeZoneInformation,globl
.previous
+20
View File
@@ -0,0 +1,20 @@
#include "libc/nt/codegen.h"
.imp kernel32,__imp_GetTimeZoneInformation,GetTimeZoneInformation
.text.windows
.ftrace1
GetTimeZoneInformation:
.ftrace2
#ifdef __x86_64__
push %rbp
mov %rsp,%rbp
mov %rdi,%rcx
sub $32,%rsp
call *__imp_GetTimeZoneInformation(%rip)
leave
#elif defined(__aarch64__)
mov x0,#0
#endif
ret
.endfn GetTimeZoneInformation,globl
.previous
+18
View File
@@ -0,0 +1,18 @@
#include "libc/nt/codegen.h"
.imp kernel32,__imp_MapViewOfFile3,MapViewOfFile3
.text.windows
.ftrace1
MapViewOfFile3:
.ftrace2
#ifdef __x86_64__
push %rbp
mov %rsp,%rbp
mov __imp_MapViewOfFile3(%rip),%rax
jmp __sysv2nt10
#elif defined(__aarch64__)
mov x0,#0
ret
#endif
.endfn MapViewOfFile3,globl
.previous
+18
View File
@@ -0,0 +1,18 @@
#include "libc/nt/codegen.h"
.imp kernel32,__imp_VirtualAlloc2,VirtualAlloc2
.text.windows
.ftrace1
VirtualAlloc2:
.ftrace2
#ifdef __x86_64__
push %rbp
mov %rsp,%rbp
mov __imp_VirtualAlloc2(%rip),%rax
jmp __sysv2nt8
#elif defined(__aarch64__)
mov x0,#0
ret
#endif
.endfn VirtualAlloc2,globl
.previous
Loaded 100 of 746 files, more files were not shown because too many files have changed in this diff. Show more