mirror of
https://github.com/jart/cosmopolitan.git
synced 2026-11-09 02:39:44 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce9aeb2aed | ||
|
|
ed93fc3dd7 | ||
|
|
5f61d273e4 | ||
|
|
bf3531de81 | ||
|
|
3b0ea2db4d | ||
|
|
f029375d39 | ||
|
|
9b87dd2b87 | ||
|
|
787b04f752 | ||
|
|
0768807935 | ||
|
|
0b59f01b43 | ||
|
|
cf70a44756 | ||
|
|
a52792c59f | ||
|
|
65c9b28e99 | ||
|
|
4292348707 | ||
|
|
2ec20b6c4c | ||
|
|
47183551d6 | ||
|
|
42891e82bb | ||
|
|
624119ea38 | ||
|
|
2f3c6e7cc3 | ||
|
|
13b9ecd537 | ||
|
|
6659981457 | ||
|
|
ae2a7ac844 | ||
|
|
793393a341 | ||
|
|
952b9009e8 | ||
|
|
8f18b3ad65 | ||
|
|
56e0fd9d1d | ||
|
|
df68a6362b | ||
|
|
19c81863a3 | ||
|
|
7d31fc311a | ||
|
|
57c0b065c8 | ||
|
|
a6ecbb747d | ||
|
|
3bf95ae7ec | ||
|
|
5fd7b07fac | ||
|
|
317c8bc312 | ||
|
|
2a1f352622 | ||
|
|
06d916b449 | ||
|
|
9ea64725b6 | ||
|
|
f9fc7eb49f | ||
|
|
b0df6c1fce | ||
|
|
d5ebb1fa5b |
No files matched your search
@@ -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
@@ -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
@@ -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
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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.
@@ -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
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ DSP_MPEG_A_DIRECTDEPS = \
|
||||
LIBC_STDIO \
|
||||
LIBC_STR \
|
||||
LIBC_SYSV \
|
||||
LIBC_TIME \
|
||||
LIBC_TINYMATH \
|
||||
THIRD_PARTY_COMPILER_RT
|
||||
|
||||
|
||||
+1
-1
@@ -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");
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ DSP_SCALE_A_DIRECTDEPS = \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_STR \
|
||||
LIBC_TIME \
|
||||
LIBC_TINYMATH \
|
||||
LIBC_X
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@ DSP_TTY_A_DIRECTDEPS = \
|
||||
LIBC_SOCK \
|
||||
LIBC_SYSV \
|
||||
LIBC_TINYMATH \
|
||||
LIBC_TIME \
|
||||
LIBC_X
|
||||
|
||||
DSP_TTY_A_DEPS := \
|
||||
|
||||
+3
-2
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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"
|
||||
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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.
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
@@ -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,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 {
|
||||
|
||||
@@ -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
@@ -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"
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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_ */
|
||||
@@ -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
@@ -45,7 +45,7 @@ char *sleb64(char *p, int64_t x) {
|
||||
*p++ = c;
|
||||
return p;
|
||||
} else {
|
||||
*p++ = c | 64;
|
||||
*p++ = c | 128;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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))
|
||||
|
||||
@@ -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"}, //
|
||||
|
||||
@@ -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.
@@ -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;
|
||||
@@ -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`.
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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_ */
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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_ */
|
||||
@@ -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
|
||||
@@ -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
@@ -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 */
|
||||
@@ -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,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 */
|
||||
@@ -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
@@ -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))))
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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));
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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 */
|
||||
@@ -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, //
|
||||
|
||||
@@ -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
|
||||
@@ -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, ' ', '!', '\"', '#', '$', '%', '&', '\'', '(', ')',
|
||||
|
||||
@@ -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, ' ', '!', '\"', '#', '$', '%', '&', '\'', '(', ')',
|
||||
|
||||
@@ -16,4 +16,6 @@
|
||||
#define kNtMemLargePages 0x20000000
|
||||
#define kNtMem4mbPages 0x80000000
|
||||
|
||||
#define kNtMemReplacePlaceholder 0x00004000
|
||||
|
||||
#endif /* COSMOPOLITAN_LIBC_NT_ENUM_MEMFLAGS_H_ */
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
Reference in new issue
Block a user