mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-03 16:30:29 +00:00
Merge branch 'master' into ctl-shared
This commit is contained in:
commit
f7178894ee
29 changed files with 945 additions and 608 deletions
|
@ -4,5 +4,5 @@ UNAMES=$(uname -s)
|
||||||
if [ x"$UNAMES" = x"Darwin" ] && [ x"$UNAMEM" = x"arm64" ]; then
|
if [ x"$UNAMES" = x"Darwin" ] && [ x"$UNAMEM" = x"arm64" ]; then
|
||||||
exec ape "$@"
|
exec ape "$@"
|
||||||
else
|
else
|
||||||
exec "$@"
|
exec rusage "$@"
|
||||||
fi
|
fi
|
||||||
|
|
125
examples/aba.c
Normal file
125
examples/aba.c
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
#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 <assert.h>
|
||||||
|
#include <cosmo.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdatomic.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// lockless push / pop tutorial
|
||||||
|
//
|
||||||
|
// this file demonstrates how to create a singly linked list that can be
|
||||||
|
// pushed and popped across multiple threads, using only atomics. atomic
|
||||||
|
// operations (rather than using a mutex) make push/pop go faster and it
|
||||||
|
// ensures asynchronous signal safety too. therefore it will be safe for
|
||||||
|
// use in a variety of contexts, such as signal handlers.
|
||||||
|
|
||||||
|
#define THREADS 128
|
||||||
|
#define ITERATIONS 10000
|
||||||
|
|
||||||
|
// adjust mask based on alignment of list struct
|
||||||
|
//
|
||||||
|
// - 0x00fffffffffffff0 may be used if List* is always 16-byte aligned.
|
||||||
|
// We know that's the case here, because we call malloc() to create
|
||||||
|
// every List* object, and malloc() results are always max aligned.
|
||||||
|
//
|
||||||
|
// - 0x00fffffffffffff8 may be used if List* is always 8-byte aligned.
|
||||||
|
// This might be the case if you're pushing and popping stuff that was
|
||||||
|
// allocated from an array, to avoid malloc() calls. This has one
|
||||||
|
// fewer byte of safeguards against the ABA problem though.
|
||||||
|
//
|
||||||
|
// - 0x00fffffffffff000 may be used if List* is always page aligned.
|
||||||
|
// This is a good choice if you use mmap() to allocate each List*
|
||||||
|
// element, since it offers maximum protection against ABA.
|
||||||
|
//
|
||||||
|
// - only the highest byte of a 64-bit pointer is safe to use on our
|
||||||
|
// supported platforms. on most x86 and arm systems, it's possible to
|
||||||
|
// use the top sixteen bits. however that's not the case on more
|
||||||
|
// recent high end x86-64 systems that have pml5t.
|
||||||
|
//
|
||||||
|
#define MASQUE 0x00fffffffffffff0
|
||||||
|
|
||||||
|
#define PTR(x) ((uintptr_t)(x) & MASQUE)
|
||||||
|
#define TAG(x) ROL((uintptr_t)(x) & ~MASQUE, 8)
|
||||||
|
#define ABA(p, t) ((uintptr_t)(p) | (ROR((uintptr_t)(t), 8) & ~MASQUE))
|
||||||
|
#define ROL(x, n) (((x) << (n)) | ((x) >> (64 - (n))))
|
||||||
|
#define ROR(x, n) (((x) >> (n)) | ((x) << (64 - (n))))
|
||||||
|
|
||||||
|
struct List {
|
||||||
|
struct List* next;
|
||||||
|
int count;
|
||||||
|
};
|
||||||
|
|
||||||
|
atomic_uintptr_t list;
|
||||||
|
|
||||||
|
void push(struct List* elem) {
|
||||||
|
uintptr_t tip;
|
||||||
|
assert(!TAG(elem));
|
||||||
|
for (tip = atomic_load_explicit(&list, memory_order_relaxed);;) {
|
||||||
|
elem->next = (struct List*)PTR(tip);
|
||||||
|
if (atomic_compare_exchange_weak_explicit(
|
||||||
|
&list, &tip, ABA(elem, TAG(tip) + 1), memory_order_release,
|
||||||
|
memory_order_relaxed))
|
||||||
|
break;
|
||||||
|
pthread_pause_np();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct List* pop(void) {
|
||||||
|
uintptr_t tip;
|
||||||
|
struct List* elem;
|
||||||
|
tip = atomic_load_explicit(&list, memory_order_relaxed);
|
||||||
|
while ((elem = (struct List*)PTR(tip))) {
|
||||||
|
if (atomic_compare_exchange_weak_explicit(
|
||||||
|
&list, &tip, ABA(elem->next, TAG(tip) + 1), memory_order_acquire,
|
||||||
|
memory_order_relaxed))
|
||||||
|
break;
|
||||||
|
pthread_pause_np();
|
||||||
|
}
|
||||||
|
return elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* tester(void* arg) {
|
||||||
|
struct List* elem;
|
||||||
|
for (int i = 0; i < ITERATIONS; ++i) {
|
||||||
|
while (!(elem = pop())) {
|
||||||
|
elem = malloc(sizeof(*elem));
|
||||||
|
elem->count = 0;
|
||||||
|
push(elem);
|
||||||
|
}
|
||||||
|
elem->count++;
|
||||||
|
push(elem);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
printf("testing aba problem...");
|
||||||
|
fflush(stdout);
|
||||||
|
pthread_t th[THREADS];
|
||||||
|
for (int i = 0; i < THREADS; ++i)
|
||||||
|
pthread_create(&th[i], 0, tester, 0);
|
||||||
|
for (int i = 0; i < THREADS; ++i)
|
||||||
|
pthread_join(th[i], 0);
|
||||||
|
int sum = 0;
|
||||||
|
struct List* elem;
|
||||||
|
while ((elem = pop())) {
|
||||||
|
printf(" %d", elem->count);
|
||||||
|
sum += elem->count;
|
||||||
|
free(elem);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
assert(sum == ITERATIONS * THREADS);
|
||||||
|
printf("you are the dancing queen\n");
|
||||||
|
CheckForMemoryLeaks();
|
||||||
|
}
|
|
@ -17,6 +17,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <wctype.h>
|
#include <wctype.h>
|
||||||
|
#include "libc/ctype.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @fileoverview Roman Transliteration, e.g.
|
* @fileoverview Roman Transliteration, e.g.
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "libc/elf/tinyelf.internal.h"
|
#include "libc/elf/tinyelf.internal.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/intrin/directmap.h"
|
#include "libc/intrin/directmap.h"
|
||||||
|
#include "libc/intrin/promises.h"
|
||||||
#include "libc/nt/memory.h"
|
#include "libc/nt/memory.h"
|
||||||
#include "libc/nt/runtime.h"
|
#include "libc/nt/runtime.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
@ -37,7 +38,6 @@
|
||||||
#include "libc/sysv/consts/prot.h"
|
#include "libc/sysv/consts/prot.h"
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
atomic_uint once;
|
|
||||||
const char *res;
|
const char *res;
|
||||||
char buf[PATH_MAX];
|
char buf[PATH_MAX];
|
||||||
} g_comdbg;
|
} g_comdbg;
|
||||||
|
@ -69,35 +69,26 @@ static int GetElfMachine(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsMyDebugBinary(const char *path) {
|
static bool IsMyDebugBinary(const char *path) {
|
||||||
|
void *addr;
|
||||||
int64_t size;
|
int64_t size;
|
||||||
uintptr_t value;
|
uintptr_t value;
|
||||||
bool res = false;
|
bool res = false;
|
||||||
int fd, e = errno;
|
int fd, e = errno;
|
||||||
struct DirectMap dm;
|
|
||||||
BLOCK_CANCELATION;
|
|
||||||
if ((fd = open(path, O_RDONLY | O_CLOEXEC, 0)) != -1) {
|
if ((fd = open(path, O_RDONLY | O_CLOEXEC, 0)) != -1) {
|
||||||
// sanity test that this .com.dbg file (1) is an elf image, and (2)
|
// sanity test that this .com.dbg file (1) is an elf image, and (2)
|
||||||
// contains the same number of bytes of code as our .com executable
|
// contains the same number of bytes of code as our .com executable
|
||||||
// which is currently running in memory.
|
// which is currently running in memory.
|
||||||
if ((size = lseek(fd, 0, SEEK_END)) != -1 &&
|
if ((size = lseek(fd, 0, SEEK_END)) != -1 &&
|
||||||
(dm = sys_mmap((void *)0x12345000000, size, PROT_READ, MAP_SHARED, fd,
|
(addr = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0)) != MAP_FAILED) {
|
||||||
0))
|
if (READ32LE((char *)addr) == READ32LE("\177ELF") &&
|
||||||
.addr != MAP_FAILED) {
|
((Elf64_Ehdr *)addr)->e_machine == GetElfMachine() &&
|
||||||
if (READ32LE((char *)dm.addr) == READ32LE("\177ELF") &&
|
GetElfSymbolValue(addr, "_etext", &value)) {
|
||||||
((Elf64_Ehdr *)dm.addr)->e_machine == GetElfMachine() &&
|
|
||||||
GetElfSymbolValue(dm.addr, "_etext", &value)) {
|
|
||||||
res = !_etext || value == (uintptr_t)_etext;
|
res = !_etext || value == (uintptr_t)_etext;
|
||||||
}
|
}
|
||||||
if (!IsWindows()) {
|
munmap(addr, size);
|
||||||
sys_munmap(dm.addr, size);
|
|
||||||
} else {
|
|
||||||
CloseHandle(dm.maphandle);
|
|
||||||
UnmapViewOfFile(dm.addr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
ALLOW_CANCELATION;
|
|
||||||
errno = e;
|
errno = e;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +97,7 @@ static void FindDebugBinaryInit(void) {
|
||||||
const char *comdbg;
|
const char *comdbg;
|
||||||
if (issetugid())
|
if (issetugid())
|
||||||
return;
|
return;
|
||||||
if ((comdbg = getenv("COMDBG")) && IsMyDebugBinary(comdbg)) {
|
if ((comdbg = getenv("COMDBG"))) {
|
||||||
g_comdbg.res = comdbg;
|
g_comdbg.res = comdbg;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -125,9 +116,18 @@ static void FindDebugBinaryInit(void) {
|
||||||
/**
|
/**
|
||||||
* Returns path of binary with the debug information, or null.
|
* Returns path of binary with the debug information, or null.
|
||||||
*
|
*
|
||||||
* @return path to debug binary, or NULL
|
* You can specify the COMDBG environment variable, with the path of the
|
||||||
|
* debug binary, in case the automatic heuristics fail. What we look for
|
||||||
|
* is GetProgramExecutableName() with ".dbg", ".com.dbg", etc. appended.
|
||||||
|
*
|
||||||
|
* @return path to debug binary, or NULL if we couldn't find it
|
||||||
|
* @asyncsignalsafe
|
||||||
*/
|
*/
|
||||||
const char *FindDebugBinary(void) {
|
const char *FindDebugBinary(void) {
|
||||||
cosmo_once(&g_comdbg.once, FindDebugBinaryInit);
|
|
||||||
return g_comdbg.res;
|
return g_comdbg.res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pay startup cost to make this signal safe from the user's perspective
|
||||||
|
__attribute__((__constructor__(10))) static void FindDebugBinaryCtor(void) {
|
||||||
|
FindDebugBinaryInit();
|
||||||
|
}
|
||||||
|
|
|
@ -232,6 +232,21 @@
|
||||||
* option might not be a good idea if you're pledging `exec` because
|
* option might not be a good idea if you're pledging `exec` because
|
||||||
* subprocesses can't inherit the `SIGSYS` handler this installs.
|
* subprocesses can't inherit the `SIGSYS` handler this installs.
|
||||||
*
|
*
|
||||||
|
* If you experience crashes during startup when execve'ing a cosmo
|
||||||
|
* binary that's had permissions like rpath pledged away, then try doing
|
||||||
|
* this before calling execve. This prevents special startup checks.
|
||||||
|
*
|
||||||
|
* putenv("COMDBG=program.dbg");
|
||||||
|
*
|
||||||
|
* If having pledge() security is mission critical, then add this code
|
||||||
|
* to the start of your main() function to ensure your program fails
|
||||||
|
* with an error if it isn't available.
|
||||||
|
*
|
||||||
|
* if (pledge(0, 0)) {
|
||||||
|
* fprintf(stderr, "error: OS doesn't support pledge() security\n");
|
||||||
|
* exit(1);
|
||||||
|
* }
|
||||||
|
*
|
||||||
* @return 0 on success, or -1 w/ errno
|
* @return 0 on success, or -1 w/ errno
|
||||||
* @raise ENOSYS if `pledge(0, 0)` was used and security is not possible
|
* @raise ENOSYS if `pledge(0, 0)` was used and security is not possible
|
||||||
* @raise EINVAL if `execpromises` on Linux isn't a subset of `promises`
|
* @raise EINVAL if `execpromises` on Linux isn't a subset of `promises`
|
||||||
|
|
|
@ -405,6 +405,15 @@ int sys_unveil_linux(const char *path, const char *permissions) {
|
||||||
* - `c` allows `path` to be created and removed, corresponding to
|
* - `c` allows `path` to be created and removed, corresponding to
|
||||||
* the pledge promise "cpath".
|
* the pledge promise "cpath".
|
||||||
*
|
*
|
||||||
|
* If having unveil() security is mission critical, then add this code
|
||||||
|
* to the start of your main() function to ensure your program fails
|
||||||
|
* with an error if it isn't available.
|
||||||
|
*
|
||||||
|
* if (unveil("", 0) >= 0) {
|
||||||
|
* fprintf(stderr, "error: OS doesn't support unveil() security\n");
|
||||||
|
* exit(1);
|
||||||
|
* }
|
||||||
|
*
|
||||||
* @return 0 on success, or -1 w/ errno; note: if `unveil("",0)` is used
|
* @return 0 on success, or -1 w/ errno; note: if `unveil("",0)` is used
|
||||||
* to perform a feature check, then on Linux a value greater than 0
|
* to perform a feature check, then on Linux a value greater than 0
|
||||||
* shall be returned which is the supported Landlock ABI version
|
* shall be returned which is the supported Landlock ABI version
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
*
|
*
|
||||||
* @return null always
|
* @return null always
|
||||||
*/
|
*/
|
||||||
void *dlopen(const char *, int) {
|
void *dlopen(const char *, int) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -531,10 +531,6 @@ typedef struct {
|
||||||
#pragma GCC diagnostic ignored "-Wold-style-definition" /* orwellian bullsh */
|
#pragma GCC diagnostic ignored "-Wold-style-definition" /* orwellian bullsh */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(__cplusplus) && defined(__GNUC__) && __GNUC__ >= 14
|
|
||||||
#pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
#define DebugBreak() __asm__("int3")
|
#define DebugBreak() __asm__("int3")
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
/*-*- 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 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/atomic.h"
|
|
||||||
|
|
||||||
bool dog(_Atomic(long) *p, long *e, long w) {
|
|
||||||
return atomic_compare_exchange_weak_explicit(p, e, w, memory_order_acq_rel,
|
|
||||||
memory_order_relaxed);
|
|
||||||
}
|
|
|
@ -29,7 +29,7 @@ struct Map {
|
||||||
struct Maps {
|
struct Maps {
|
||||||
struct Tree *maps;
|
struct Tree *maps;
|
||||||
_Atomic(uint64_t) lock;
|
_Atomic(uint64_t) lock;
|
||||||
_Atomic(struct Map *) freed;
|
_Atomic(uintptr_t) freed;
|
||||||
size_t count;
|
size_t count;
|
||||||
size_t pages;
|
size_t pages;
|
||||||
_Atomic(char *) pick;
|
_Atomic(char *) pick;
|
||||||
|
|
|
@ -50,6 +50,13 @@
|
||||||
|
|
||||||
#define PGUP(x) (((x) + pagesz - 1) & -pagesz)
|
#define PGUP(x) (((x) + pagesz - 1) & -pagesz)
|
||||||
|
|
||||||
|
#define MASQUE 0x00fffffffffffff8
|
||||||
|
#define PTR(x) ((uintptr_t)(x) & MASQUE)
|
||||||
|
#define TAG(x) ROL((uintptr_t)(x) & ~MASQUE, 8)
|
||||||
|
#define ABA(p, t) ((uintptr_t)(p) | (ROR((uintptr_t)(t), 8) & ~MASQUE))
|
||||||
|
#define ROL(x, n) (((x) << (n)) | ((x) >> (64 - (n))))
|
||||||
|
#define ROR(x, n) (((x) >> (n)) | ((x) << (64 - (n))))
|
||||||
|
|
||||||
#if !MMDEBUG
|
#if !MMDEBUG
|
||||||
#define ASSERT(x) (void)0
|
#define ASSERT(x) (void)0
|
||||||
#else
|
#else
|
||||||
|
@ -227,14 +234,17 @@ StartOver:
|
||||||
}
|
}
|
||||||
|
|
||||||
void __maps_free(struct Map *map) {
|
void __maps_free(struct Map *map) {
|
||||||
|
uintptr_t tip;
|
||||||
|
ASSERT(!TAG(map));
|
||||||
map->size = 0;
|
map->size = 0;
|
||||||
map->addr = MAP_FAILED;
|
map->addr = MAP_FAILED;
|
||||||
map->freed = atomic_load_explicit(&__maps.freed, memory_order_relaxed);
|
for (tip = atomic_load_explicit(&__maps.freed, memory_order_relaxed);;) {
|
||||||
for (;;) {
|
map->freed = (struct Map *)PTR(tip);
|
||||||
if (atomic_compare_exchange_weak_explicit(&__maps.freed, &map->freed, map,
|
if (atomic_compare_exchange_weak_explicit(
|
||||||
memory_order_release,
|
&__maps.freed, &tip, ABA(map, TAG(tip) + 1), memory_order_release,
|
||||||
memory_order_relaxed))
|
memory_order_relaxed))
|
||||||
break;
|
break;
|
||||||
|
pthread_pause_np();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,12 +307,13 @@ void __maps_insert(struct Map *map) {
|
||||||
|
|
||||||
struct Map *__maps_alloc(void) {
|
struct Map *__maps_alloc(void) {
|
||||||
struct Map *map;
|
struct Map *map;
|
||||||
map = atomic_load_explicit(&__maps.freed, memory_order_relaxed);
|
uintptr_t tip = atomic_load_explicit(&__maps.freed, memory_order_relaxed);
|
||||||
while (map) {
|
while ((map = (struct Map *)PTR(tip))) {
|
||||||
if (atomic_compare_exchange_weak_explicit(&__maps.freed, &map, map->freed,
|
if (atomic_compare_exchange_weak_explicit(
|
||||||
memory_order_acquire,
|
&__maps.freed, &tip, ABA(map->freed, TAG(tip) + 1),
|
||||||
memory_order_relaxed))
|
memory_order_acquire, memory_order_relaxed))
|
||||||
return map;
|
return map;
|
||||||
|
pthread_pause_np();
|
||||||
}
|
}
|
||||||
int gransz = __gransize;
|
int gransz = __gransize;
|
||||||
struct DirectMap sys = sys_mmap(0, gransz, PROT_READ | PROT_WRITE,
|
struct DirectMap sys = sys_mmap(0, gransz, PROT_READ | PROT_WRITE,
|
||||||
|
|
|
@ -59,8 +59,8 @@ textwindows int WSARecv(
|
||||||
}
|
}
|
||||||
if (UNLIKELY(__strace > 0) && strace_enabled(0) > 0) {
|
if (UNLIKELY(__strace > 0) && strace_enabled(0) > 0) {
|
||||||
kprintf(STRACE_PROLOGUE "WSARecv(%lu, [", s);
|
kprintf(STRACE_PROLOGUE "WSARecv(%lu, [", s);
|
||||||
DescribeIovNt(inout_lpBuffers, dwBufferCount,
|
_DescribeIovNt(inout_lpBuffers, dwBufferCount,
|
||||||
rc != -1 ? NumberOfBytesRecvd : 0);
|
rc != -1 ? NumberOfBytesRecvd : 0);
|
||||||
kprintf("], %u, [%'u], %p, %s, %p) → %d% lm\n", dwBufferCount,
|
kprintf("], %u, [%'u], %p, %s, %p) → %d% lm\n", dwBufferCount,
|
||||||
NumberOfBytesRecvd, inout_lpFlags,
|
NumberOfBytesRecvd, inout_lpFlags,
|
||||||
DescribeNtOverlapped(opt_inout_lpOverlapped),
|
DescribeNtOverlapped(opt_inout_lpOverlapped),
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/mem/alg.h"
|
#include "libc/mem/alg.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
|
#include "libc/str/str.h"
|
||||||
|
|
||||||
#define MIN3(a, b, c) \
|
#define MIN3(a, b, c) \
|
||||||
((a) < (b) ? ((a) < (c) ? (a) : (c)) : ((b) < (c) ? (b) : (c)))
|
((a) < (b) ? ((a) < (c) ? (a) : (c)) : ((b) < (c) ? (b) : (c)))
|
||||||
|
|
|
@ -7,7 +7,7 @@ struct NtIovec {
|
||||||
char *buf;
|
char *buf;
|
||||||
};
|
};
|
||||||
|
|
||||||
void DescribeIovNt(const struct NtIovec *, uint32_t, ssize_t);
|
void _DescribeIovNt(const struct NtIovec *, uint32_t, ssize_t);
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
COSMOPOLITAN_C_END_
|
||||||
#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IOVEC_H_ */
|
#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_IOVEC_H_ */
|
||||||
|
|
|
@ -9,9 +9,9 @@ struct NtSecurityAttributes {
|
||||||
bool32 bInheritHandle;
|
bool32 bInheritHandle;
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *DescribeNtSecurityAttributes(char[32],
|
const char *_DescribeNtSecurityAttributes(char[32],
|
||||||
const struct NtSecurityAttributes *);
|
const struct NtSecurityAttributes *);
|
||||||
#define DescribeNtSecurityAttributes(x) \
|
#define DescribeNtSecurityAttributes(x) \
|
||||||
DescribeNtSecurityAttributes(alloca(32), x)
|
_DescribeNtSecurityAttributes(alloca(32), x)
|
||||||
|
|
||||||
#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_SECURITYATTRIBUTES_H_ */
|
#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_SECURITYATTRIBUTES_H_ */
|
||||||
|
|
|
@ -119,7 +119,7 @@ void __morph_begin(void) libcesque;
|
||||||
void __morph_end(void) libcesque;
|
void __morph_end(void) libcesque;
|
||||||
void __jit_begin(void) libcesque;
|
void __jit_begin(void) libcesque;
|
||||||
void __jit_end(void) libcesque;
|
void __jit_end(void) libcesque;
|
||||||
void __clear_cache(void *, void *) libcesque;
|
void __clear_cache(void *, void *);
|
||||||
/* portability */
|
/* portability */
|
||||||
bool32 IsGenuineBlink(void) libcesque;
|
bool32 IsGenuineBlink(void) libcesque;
|
||||||
bool32 IsCygwin(void) libcesque;
|
bool32 IsCygwin(void) libcesque;
|
||||||
|
|
|
@ -44,9 +44,6 @@ $(LIBC_STR_A).pkg: \
|
||||||
$(LIBC_STR_A_OBJS) \
|
$(LIBC_STR_A_OBJS) \
|
||||||
$(foreach x,$(LIBC_STR_A_DIRECTDEPS),$($(x)_A).pkg)
|
$(foreach x,$(LIBC_STR_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||||
|
|
||||||
o/$(MODE)/libc/str/wow.o: private \
|
|
||||||
CC = gcc
|
|
||||||
|
|
||||||
o/$(MODE)/libc/str/wmemset.o \
|
o/$(MODE)/libc/str/wmemset.o \
|
||||||
o/$(MODE)/libc/str/memset16.o \
|
o/$(MODE)/libc/str/memset16.o \
|
||||||
o/$(MODE)/libc/str/dosdatetimetounix.o: private \
|
o/$(MODE)/libc/str/dosdatetimetounix.o: private \
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -109,12 +109,15 @@ TEST(pledge, execpromises_notok) {
|
||||||
int ws, pid;
|
int ws, pid;
|
||||||
ASSERT_NE(-1, (pid = fork()));
|
ASSERT_NE(-1, (pid = fork()));
|
||||||
if (!pid) {
|
if (!pid) {
|
||||||
|
putenv("COMDBG=REDACTED");
|
||||||
__pledge_mode = PLEDGE_PENALTY_RETURN_EPERM;
|
__pledge_mode = PLEDGE_PENALTY_RETURN_EPERM;
|
||||||
ASSERT_SYS(0, 0, pledge("stdio rpath exec", "stdio"));
|
ASSERT_SYS(0, 0, pledge("stdio rpath exec", "stdio"));
|
||||||
execl("sock.elf", "sock.elf", 0);
|
execl("sock.elf", "sock.elf", 0);
|
||||||
_Exit(127);
|
_Exit(127);
|
||||||
}
|
}
|
||||||
EXPECT_NE(-1, wait(&ws));
|
EXPECT_NE(-1, wait(&ws));
|
||||||
|
EXPECT_FALSE(WIFSIGNALED(ws));
|
||||||
|
EXPECT_EQ(0, WTERMSIG(ws));
|
||||||
EXPECT_TRUE(WIFEXITED(ws));
|
EXPECT_TRUE(WIFEXITED(ws));
|
||||||
EXPECT_EQ(129, WEXITSTATUS(ws));
|
EXPECT_EQ(129, WEXITSTATUS(ws));
|
||||||
}
|
}
|
||||||
|
@ -532,6 +535,7 @@ TEST(pledge, execpromises_ok) {
|
||||||
int ws, pid;
|
int ws, pid;
|
||||||
ASSERT_NE(-1, (pid = fork()));
|
ASSERT_NE(-1, (pid = fork()));
|
||||||
if (!pid) {
|
if (!pid) {
|
||||||
|
putenv("COMDBG=REDACTED");
|
||||||
ASSERT_SYS(0, 0, pledge("stdio exec", "stdio"));
|
ASSERT_SYS(0, 0, pledge("stdio exec", "stdio"));
|
||||||
execl("life.elf", "life.elf", 0);
|
execl("life.elf", "life.elf", 0);
|
||||||
_Exit(127);
|
_Exit(127);
|
||||||
|
@ -547,6 +551,7 @@ TEST(pledge, execpromises_notok1) {
|
||||||
int ws, pid;
|
int ws, pid;
|
||||||
ASSERT_NE(-1, (pid = fork()));
|
ASSERT_NE(-1, (pid = fork()));
|
||||||
if (!pid) {
|
if (!pid) {
|
||||||
|
putenv("COMDBG=REDACTED");
|
||||||
ASSERT_SYS(0, 0, pledge("stdio exec", "stdio"));
|
ASSERT_SYS(0, 0, pledge("stdio exec", "stdio"));
|
||||||
execl("sock.elf", "sock.elf", 0);
|
execl("sock.elf", "sock.elf", 0);
|
||||||
_Exit(127);
|
_Exit(127);
|
||||||
|
@ -562,6 +567,7 @@ TEST(pledge, execpromises_reducesAtExecOnLinux) {
|
||||||
int ws, pid;
|
int ws, pid;
|
||||||
ASSERT_NE(-1, (pid = fork()));
|
ASSERT_NE(-1, (pid = fork()));
|
||||||
if (!pid) {
|
if (!pid) {
|
||||||
|
putenv("COMDBG=REDACTED");
|
||||||
ASSERT_SYS(0, 0, pledge("stdio inet tty exec", "stdio tty"));
|
ASSERT_SYS(0, 0, pledge("stdio inet tty exec", "stdio tty"));
|
||||||
execl("sock.elf", "sock.elf", 0);
|
execl("sock.elf", "sock.elf", 0);
|
||||||
_Exit(127);
|
_Exit(127);
|
||||||
|
@ -619,6 +625,7 @@ TEST(pledge_openbsd, execpromises_notok) {
|
||||||
int ws, pid;
|
int ws, pid;
|
||||||
ASSERT_NE(-1, (pid = fork()));
|
ASSERT_NE(-1, (pid = fork()));
|
||||||
if (!pid) {
|
if (!pid) {
|
||||||
|
putenv("COMDBG=REDACTED");
|
||||||
ASSERT_SYS(0, 0, pledge("stdio exec", "stdio"));
|
ASSERT_SYS(0, 0, pledge("stdio exec", "stdio"));
|
||||||
execl("sock.elf", "sock.elf", 0);
|
execl("sock.elf", "sock.elf", 0);
|
||||||
_Exit(127);
|
_Exit(127);
|
||||||
|
|
1
third_party/dlmalloc/threaded.inc
vendored
1
third_party/dlmalloc/threaded.inc
vendored
|
@ -25,6 +25,7 @@
|
||||||
#include "libc/thread/thread.h"
|
#include "libc/thread/thread.h"
|
||||||
#include "libc/thread/threads.h"
|
#include "libc/thread/threads.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
|
#include "libc/calls/struct/cpuset.h"
|
||||||
#include "third_party/dlmalloc/dlmalloc.h"
|
#include "third_party/dlmalloc/dlmalloc.h"
|
||||||
|
|
||||||
#if !FOOTERS || !MSPACES
|
#if !FOOTERS || !MSPACES
|
||||||
|
|
1
third_party/lua/lua.main.c
vendored
1
third_party/lua/lua.main.c
vendored
|
@ -50,6 +50,7 @@
|
||||||
#include "third_party/lua/lrepl.h"
|
#include "third_party/lua/lrepl.h"
|
||||||
#include "third_party/lua/lualib.h"
|
#include "third_party/lua/lualib.h"
|
||||||
#include "third_party/lua/lunix.h"
|
#include "third_party/lua/lunix.h"
|
||||||
|
#include "libc/cosmo.h"
|
||||||
#include "libc/mem/leaks.h"
|
#include "libc/mem/leaks.h"
|
||||||
__static_yoink("lua_notice");
|
__static_yoink("lua_notice");
|
||||||
|
|
||||||
|
|
65
third_party/nsync/common.c
vendored
65
third_party/nsync/common.c
vendored
|
@ -15,6 +15,7 @@
|
||||||
│ See the License for the specific language governing permissions and │
|
│ See the License for the specific language governing permissions and │
|
||||||
│ limitations under the License. │
|
│ limitations under the License. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/atomic.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/syscall-sysv.internal.h"
|
#include "libc/calls/syscall-sysv.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
@ -136,14 +137,45 @@ waiter *nsync_dll_waiter_samecond_ (struct Dll *e) {
|
||||||
|
|
||||||
/* -------------------------------- */
|
/* -------------------------------- */
|
||||||
|
|
||||||
static _Atomic(waiter *) free_waiters;
|
#define MASQUE 0x00fffffffffffff8
|
||||||
|
#define PTR(x) ((uintptr_t)(x) & MASQUE)
|
||||||
|
#define TAG(x) ROL((uintptr_t)(x) & ~MASQUE, 8)
|
||||||
|
#define ABA(p, t) ((uintptr_t)(p) | (ROR((uintptr_t)(t), 8) & ~MASQUE))
|
||||||
|
#define ROL(x, n) (((x) << (n)) | ((x) >> (64 - (n))))
|
||||||
|
#define ROR(x, n) (((x) >> (n)) | ((x) << (64 - (n))))
|
||||||
|
|
||||||
|
static atomic_uintptr_t free_waiters;
|
||||||
|
|
||||||
static void free_waiters_push (waiter *w) {
|
static void free_waiters_push (waiter *w) {
|
||||||
int backoff = 0;
|
uintptr_t tip;
|
||||||
w->next_free = atomic_load_explicit (&free_waiters, memory_order_relaxed);
|
ASSERT (!TAG(w));
|
||||||
while (!atomic_compare_exchange_weak_explicit (&free_waiters, &w->next_free, w,
|
tip = atomic_load_explicit (&free_waiters, memory_order_relaxed);
|
||||||
memory_order_acq_rel, memory_order_relaxed))
|
for (;;) {
|
||||||
backoff = pthread_delay_np (free_waiters, backoff);
|
w->next_free = (waiter *) PTR (tip);
|
||||||
|
if (atomic_compare_exchange_weak_explicit (&free_waiters,
|
||||||
|
&tip,
|
||||||
|
ABA (w, TAG (tip) + 1),
|
||||||
|
memory_order_release,
|
||||||
|
memory_order_relaxed))
|
||||||
|
break;
|
||||||
|
pthread_pause_np ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static waiter *free_waiters_pop (void) {
|
||||||
|
waiter *w;
|
||||||
|
uintptr_t tip;
|
||||||
|
tip = atomic_load_explicit (&free_waiters, memory_order_relaxed);
|
||||||
|
while ((w = (waiter *) PTR (tip))) {
|
||||||
|
if (atomic_compare_exchange_weak_explicit (&free_waiters,
|
||||||
|
&tip,
|
||||||
|
ABA (w->next_free, TAG (tip) + 1),
|
||||||
|
memory_order_acquire,
|
||||||
|
memory_order_relaxed))
|
||||||
|
break;
|
||||||
|
pthread_pause_np ();
|
||||||
|
}
|
||||||
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_waiters_populate (void) {
|
static void free_waiters_populate (void) {
|
||||||
|
@ -172,30 +204,12 @@ static void free_waiters_populate (void) {
|
||||||
}
|
}
|
||||||
w->nw.sem = &w->sem;
|
w->nw.sem = &w->sem;
|
||||||
dll_init (&w->nw.q);
|
dll_init (&w->nw.q);
|
||||||
NSYNC_ATOMIC_UINT32_STORE_ (&w->nw.waiting, 0);
|
|
||||||
w->nw.flags = NSYNC_WAITER_FLAG_MUCV;
|
w->nw.flags = NSYNC_WAITER_FLAG_MUCV;
|
||||||
ATM_STORE (&w->remove_count, 0);
|
|
||||||
dll_init (&w->same_condition);
|
dll_init (&w->same_condition);
|
||||||
w->flags = 0;
|
|
||||||
free_waiters_push (w);
|
free_waiters_push (w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static waiter *free_waiters_pop (void) {
|
|
||||||
waiter *w;
|
|
||||||
int backoff = 0;
|
|
||||||
for (;;) {
|
|
||||||
if ((w = atomic_load_explicit (&free_waiters, memory_order_relaxed))) {
|
|
||||||
if (atomic_compare_exchange_weak_explicit (&free_waiters, &w, w->next_free,
|
|
||||||
memory_order_acq_rel, memory_order_relaxed))
|
|
||||||
return w;
|
|
||||||
backoff = pthread_delay_np (free_waiters, backoff);
|
|
||||||
} else {
|
|
||||||
free_waiters_populate ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------- */
|
/* -------------------------------- */
|
||||||
|
|
||||||
#define waiter_for_thread __get_tls()->tib_nsync
|
#define waiter_for_thread __get_tls()->tib_nsync
|
||||||
|
@ -221,7 +235,8 @@ waiter *nsync_waiter_new_ (void) {
|
||||||
tw = waiter_for_thread;
|
tw = waiter_for_thread;
|
||||||
w = tw;
|
w = tw;
|
||||||
if (w == NULL || (w->flags & (WAITER_RESERVED|WAITER_IN_USE)) != WAITER_RESERVED) {
|
if (w == NULL || (w->flags & (WAITER_RESERVED|WAITER_IN_USE)) != WAITER_RESERVED) {
|
||||||
w = free_waiters_pop ();
|
while (!(w = free_waiters_pop ()))
|
||||||
|
free_waiters_populate ();
|
||||||
if (tw == NULL) {
|
if (tw == NULL) {
|
||||||
w->flags |= WAITER_RESERVED;
|
w->flags |= WAITER_RESERVED;
|
||||||
waiter_for_thread = w;
|
waiter_for_thread = w;
|
||||||
|
|
3
third_party/nsync/mem/nsync_cv.c
vendored
3
third_party/nsync/mem/nsync_cv.c
vendored
|
@ -233,7 +233,9 @@ static int nsync_cv_wait_with_deadline_impl_ (struct nsync_cv_wait_with_deadline
|
||||||
/* Requeue on *pmu using existing waiter struct; current thread
|
/* Requeue on *pmu using existing waiter struct; current thread
|
||||||
is the designated waker. */
|
is the designated waker. */
|
||||||
nsync_mu_lock_slow_ (c->cv_mu, c->w, MU_DESIG_WAKER, c->w->l_type);
|
nsync_mu_lock_slow_ (c->cv_mu, c->w, MU_DESIG_WAKER, c->w->l_type);
|
||||||
|
nsync_waiter_free_ (c->w);
|
||||||
} else {
|
} else {
|
||||||
|
nsync_waiter_free_ (c->w);
|
||||||
/* Traditional case: We've woken from the cv, and need to reacquire *pmu. */
|
/* Traditional case: We've woken from the cv, and need to reacquire *pmu. */
|
||||||
if (c->is_reader_mu) {
|
if (c->is_reader_mu) {
|
||||||
nsync_mu_rlock (c->cv_mu);
|
nsync_mu_rlock (c->cv_mu);
|
||||||
|
@ -241,7 +243,6 @@ static int nsync_cv_wait_with_deadline_impl_ (struct nsync_cv_wait_with_deadline
|
||||||
(*c->lock) (c->pmu);
|
(*c->lock) (c->pmu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nsync_waiter_free_ (c->w);
|
|
||||||
IGNORE_RACES_END ();
|
IGNORE_RACES_END ();
|
||||||
return (outcome);
|
return (outcome);
|
||||||
}
|
}
|
||||||
|
|
6
third_party/nsync/mu_semaphore_sem.c
vendored
6
third_party/nsync/mu_semaphore_sem.c
vendored
|
@ -52,11 +52,11 @@ static nsync_semaphore *sem_big_enough_for_sem = (nsync_semaphore *) (uintptr_t)
|
||||||
(sizeof (struct sem) <= sizeof (*sem_big_enough_for_sem)));
|
(sizeof (struct sem) <= sizeof (*sem_big_enough_for_sem)));
|
||||||
|
|
||||||
static void sems_push (struct sem *f) {
|
static void sems_push (struct sem *f) {
|
||||||
int backoff = 0;
|
|
||||||
f->next = atomic_load_explicit (&g_sems, memory_order_relaxed);
|
f->next = atomic_load_explicit (&g_sems, memory_order_relaxed);
|
||||||
while (!atomic_compare_exchange_weak_explicit (&g_sems, &f->next, f,
|
while (!atomic_compare_exchange_weak_explicit (&g_sems, &f->next, f,
|
||||||
memory_order_acq_rel, memory_order_relaxed))
|
memory_order_acq_rel,
|
||||||
backoff = pthread_delay_np (&g_sems, backoff);
|
memory_order_relaxed))
|
||||||
|
pthread_pause_np ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool nsync_mu_semaphore_sem_create (struct sem *f) {
|
static bool nsync_mu_semaphore_sem_create (struct sem *f) {
|
||||||
|
|
|
@ -417,7 +417,7 @@ statements instead, so that Cosmopolitan Libc's system constants will
|
||||||
work as expected. Our modifications to GNU GCC are published under the
|
work as expected. Our modifications to GNU GCC are published under the
|
||||||
ISC license at <https://github.com/ahgamut/gcc/tree/portcosmo-14.1>. The
|
ISC license at <https://github.com/ahgamut/gcc/tree/portcosmo-14.1>. The
|
||||||
binaries you see here were first published at
|
binaries you see here were first published at
|
||||||
<https://github.com/ahgamut/superconfigure/releases/tag/z0.0.52> which
|
<https://github.com/ahgamut/superconfigure/releases/tag/z0.0.53> which
|
||||||
is regularly updated.
|
is regularly updated.
|
||||||
|
|
||||||
## Legal
|
## Legal
|
||||||
|
|
|
@ -75,6 +75,15 @@ elif [ ! -d "$TMPDIR" ]; then
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
CLANG=0
|
||||||
|
CC_X86_64="$BIN/x86_64-linux-cosmo-gcc"
|
||||||
|
CC_AARCH64="$BIN/aarch64-linux-cosmo-gcc"
|
||||||
|
CXX_X86_64="$BIN/x86_64-linux-cosmo-g++"
|
||||||
|
CXX_AARCH64="$BIN/aarch64-linux-cosmo-g++"
|
||||||
|
FPORTCOSMO="-fportcosmo"
|
||||||
|
TARGET_X86_64=
|
||||||
|
TARGET_AARCH64=
|
||||||
|
|
||||||
X=
|
X=
|
||||||
OPT=
|
OPT=
|
||||||
ARGS=
|
ARGS=
|
||||||
|
@ -93,6 +102,7 @@ FLAGS_AARCH64=
|
||||||
INPUT_FILE_COUNT=0
|
INPUT_FILE_COUNT=0
|
||||||
DEPENDENCY_OUTPUT=
|
DEPENDENCY_OUTPUT=
|
||||||
NEED_DEPENDENCY_OUTPUT=
|
NEED_DEPENDENCY_OUTPUT=
|
||||||
|
|
||||||
for x; do
|
for x; do
|
||||||
if [ x"$x" != x"${x#* }" ]; then
|
if [ x"$x" != x"${x#* }" ]; then
|
||||||
fatal_error "arguments containing spaces unsupported: $x"
|
fatal_error "arguments containing spaces unsupported: $x"
|
||||||
|
@ -185,6 +195,16 @@ EOF
|
||||||
elif [ x"$x" = x"-moptlinux" ]; then
|
elif [ x"$x" = x"-moptlinux" ]; then
|
||||||
MODE=optlinux
|
MODE=optlinux
|
||||||
continue
|
continue
|
||||||
|
elif [ x"$x" = x"-mclang" ]; then
|
||||||
|
CLANG=1
|
||||||
|
CC_X86_64="$BIN/cosmo-clang"
|
||||||
|
CC_AARCH64="$BIN/cosmo-clang"
|
||||||
|
CXX_X86_64="$BIN/cosmo-clang++"
|
||||||
|
CXX_AARCH64="$BIN/cosmo-clang++"
|
||||||
|
TARGET_X86_64="--target=x86_64"
|
||||||
|
TARGET_AARCH64="--target=aarch64"
|
||||||
|
FPORTCOSMO=
|
||||||
|
continue
|
||||||
elif [ x"$x" = x"-m64" ]; then
|
elif [ x"$x" = x"-m64" ]; then
|
||||||
continue
|
continue
|
||||||
elif [ x"$x" = x"-fomit-frame-pointer" ]; then
|
elif [ x"$x" = x"-fomit-frame-pointer" ]; then
|
||||||
|
@ -298,7 +318,7 @@ fi
|
||||||
PLATFORM="-D__COSMOPOLITAN__ -D__COSMOCC__ -D__FATCOSMOCC__"
|
PLATFORM="-D__COSMOPOLITAN__ -D__COSMOCC__ -D__FATCOSMOCC__"
|
||||||
PREDEF="-include libc/integral/normalize.inc"
|
PREDEF="-include libc/integral/normalize.inc"
|
||||||
CPPFLAGS="-fno-pie -nostdinc -isystem $BIN/../include"
|
CPPFLAGS="-fno-pie -nostdinc -isystem $BIN/../include"
|
||||||
CFLAGS="-fportcosmo -fno-dwarf2-cfi-asm -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-semantic-interposition"
|
CFLAGS="$FPORTCOSMO -fno-dwarf2-cfi-asm -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-semantic-interposition"
|
||||||
LDFLAGS="-static -nostdlib -no-pie -fuse-ld=bfd -Wl,-z,noexecstack -Wl,-z,norelro -Wl,--gc-sections"
|
LDFLAGS="-static -nostdlib -no-pie -fuse-ld=bfd -Wl,-z,noexecstack -Wl,-z,norelro -Wl,--gc-sections"
|
||||||
PRECIOUS="-fno-omit-frame-pointer"
|
PRECIOUS="-fno-omit-frame-pointer"
|
||||||
|
|
||||||
|
@ -307,7 +327,9 @@ if [ x"$OPT" != x"-Os" ] && [ x"$MODE" != x"tiny" ] && [ x"$MODE" != x"optlinux"
|
||||||
CFLAGS="$CFLAGS -fno-optimize-sibling-calls -mno-omit-leaf-frame-pointer"
|
CFLAGS="$CFLAGS -fno-optimize-sibling-calls -mno-omit-leaf-frame-pointer"
|
||||||
fi
|
fi
|
||||||
if [ x"$OPT" != x"-O3" ] && [ x"$MODE" != x"optlinux" ]; then
|
if [ x"$OPT" != x"-O3" ] && [ x"$MODE" != x"optlinux" ]; then
|
||||||
CFLAGS="$CFLAGS -fno-schedule-insns2"
|
if [ $CLANG -eq 0 ]; then
|
||||||
|
CFLAGS="$CFLAGS -fno-schedule-insns2"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ x"$X" = x"c" ] || [ x"$X" = x"c-header" ]; then
|
if [ x"$X" = x"c" ] || [ x"$X" = x"c-header" ]; then
|
||||||
|
@ -320,11 +342,9 @@ else
|
||||||
CPLUSPLUS=0
|
CPLUSPLUS=0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
CC_X86_64="$BIN/x86_64-linux-cosmo-gcc"
|
|
||||||
CC_AARCH64="$BIN/aarch64-linux-cosmo-gcc"
|
|
||||||
if [ $CPLUSPLUS -eq 1 ]; then
|
if [ $CPLUSPLUS -eq 1 ]; then
|
||||||
CC_X86_64="$BIN/x86_64-linux-cosmo-g++"
|
CC_X86_64=$CXX_X86_64
|
||||||
CC_AARCH64="$BIN/aarch64-linux-cosmo-g++"
|
CC_AARCH64=$CXX_AARCH64
|
||||||
if [ $INTENT != cpp ]; then
|
if [ $INTENT != cpp ]; then
|
||||||
CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -fuse-cxa-atexit"
|
CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -fuse-cxa-atexit"
|
||||||
fi
|
fi
|
||||||
|
@ -461,6 +481,7 @@ build_object() {
|
||||||
(
|
(
|
||||||
set -- \
|
set -- \
|
||||||
"$CC_X86_64" \
|
"$CC_X86_64" \
|
||||||
|
$TARGET_X86_64 \
|
||||||
-o"$OUTPUT_X86_64" \
|
-o"$OUTPUT_X86_64" \
|
||||||
$PLATFORM \
|
$PLATFORM \
|
||||||
$PREDEF \
|
$PREDEF \
|
||||||
|
@ -482,6 +503,7 @@ build_object() {
|
||||||
(
|
(
|
||||||
set -- \
|
set -- \
|
||||||
"$CC_AARCH64" \
|
"$CC_AARCH64" \
|
||||||
|
$TARGET_AARCH64 \
|
||||||
-o"$OUTPUT_AARCH64" \
|
-o"$OUTPUT_AARCH64" \
|
||||||
$PLATFORM \
|
$PLATFORM \
|
||||||
$PREDEF \
|
$PREDEF \
|
||||||
|
@ -588,6 +610,7 @@ TEMP_FILES="${TEMP_FILES} $out2"
|
||||||
(
|
(
|
||||||
set -- \
|
set -- \
|
||||||
"$CC_X86_64" \
|
"$CC_X86_64" \
|
||||||
|
$TARGET_X86_64 \
|
||||||
-o"$OUTPUT_X86_64"\
|
-o"$OUTPUT_X86_64"\
|
||||||
$CRT_X86_64 \
|
$CRT_X86_64 \
|
||||||
$LDFLAGS_X86_64 \
|
$LDFLAGS_X86_64 \
|
||||||
|
@ -605,6 +628,7 @@ pid1=$!
|
||||||
(
|
(
|
||||||
set -- \
|
set -- \
|
||||||
"$CC_AARCH64" \
|
"$CC_AARCH64" \
|
||||||
|
$TARGET_AARCH64 \
|
||||||
-o"$OUTPUT_AARCH64"\
|
-o"$OUTPUT_AARCH64"\
|
||||||
$CRT_AARCH64 \
|
$CRT_AARCH64 \
|
||||||
$LDFLAGS_AARCH64 \
|
$LDFLAGS_AARCH64 \
|
||||||
|
|
|
@ -182,12 +182,17 @@ fetch() {
|
||||||
OLD=$PWD
|
OLD=$PWD
|
||||||
cd "$OUTDIR/"
|
cd "$OUTDIR/"
|
||||||
if [ ! -x bin/x86_64-linux-cosmo-gcc ]; then
|
if [ ! -x bin/x86_64-linux-cosmo-gcc ]; then
|
||||||
fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.52/aarch64-gcc.zip
|
fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.53/aarch64-gcc.zip &
|
||||||
unzip aarch64-gcc.zip
|
fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.53/x86_64-gcc.zip &
|
||||||
|
fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.53/llvm.zip &
|
||||||
|
wait
|
||||||
|
unzip aarch64-gcc.zip &
|
||||||
|
unzip x86_64-gcc.zip &
|
||||||
|
unzip llvm.zip bin/clang-18 &
|
||||||
|
wait
|
||||||
rm -f aarch64-gcc.zip
|
rm -f aarch64-gcc.zip
|
||||||
fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.52/x86_64-gcc.zip
|
|
||||||
unzip x86_64-gcc.zip
|
|
||||||
rm -f x86_64-gcc.zip
|
rm -f x86_64-gcc.zip
|
||||||
|
mv bin/clang-18 bin/cosmo-clang
|
||||||
fi
|
fi
|
||||||
rm -f bin/*-cpp
|
rm -f bin/*-cpp
|
||||||
rm -f bin/*-gcc-*
|
rm -f bin/*-gcc-*
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "libc/calls/struct/termios.h"
|
#include "libc/calls/struct/termios.h"
|
||||||
#include "libc/calls/struct/timespec.h"
|
#include "libc/calls/struct/timespec.h"
|
||||||
#include "libc/calls/termios.h"
|
#include "libc/calls/termios.h"
|
||||||
|
#include "libc/cosmo.h"
|
||||||
#include "libc/ctype.h"
|
#include "libc/ctype.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/dos.h"
|
#include "libc/dos.h"
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/calls/struct/timespec.h"
|
#include "libc/calls/struct/timespec.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
#include "libc/stdio/stdio.h"
|
||||||
#include "libc/thread/thread.h"
|
#include "libc/thread/thread.h"
|
||||||
|
|
||||||
#define ALLOCATIONS 1000
|
#define ALLOCATIONS 1000
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue