Skip to content

Commit 15ea052

Browse files
committed
Reduce code size of mandatory runtime
This change reduces o/tiny/examples/life from 44kb to 24kb in size since it avoids linking mmap() when unnecessary. This is important, to helping cosmo not completely lose touch with its roots.
1 parent fdab49b commit 15ea052

File tree

17 files changed

+164
-163
lines changed

17 files changed

+164
-163
lines changed

libc/calls/sig.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,11 @@ textwindows void __sig_delete(int sig) {
8181
struct Dll *e;
8282
atomic_fetch_and_explicit(&__sig.pending, ~(1ull << (sig - 1)),
8383
memory_order_relaxed);
84-
BLOCK_SIGNALS;
8584
_pthread_lock();
86-
for (e = dll_last(_pthread_list); e; e = dll_prev(_pthread_list, e)) {
85+
for (e = dll_last(_pthread_list); e; e = dll_prev(_pthread_list, e))
8786
atomic_fetch_and_explicit(&POSIXTHREAD_CONTAINER(e)->tib->tib_sigpending,
8887
~(1ull << (sig - 1)), memory_order_relaxed);
89-
}
9088
_pthread_unlock();
91-
ALLOW_SIGNALS;
9289
}
9390

9491
static textwindows int __sig_getter(atomic_ulong *sigs, sigset_t masked) {
@@ -559,7 +556,7 @@ void __stack_call(struct NtExceptionPointers *, int, int, struct CosmoTib *,
559556
__msabi dontinstrument unsigned __sig_crash(struct NtExceptionPointers *ep) {
560557

561558
// translate win32 to unix si_signo and si_code
562-
int code, sig = __sig_crash_sig(ep, &code);
559+
int code, sig = __sig_crash_sig(ep->ExceptionRecord->ExceptionCode, &code);
563560

564561
// advance the instruction pointer to skip over debugger breakpoints
565562
// this behavior is consistent with how unix kernels are implemented

libc/calls/sig.internal.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#ifndef COSMOPOLITAN_LIBC_CALLS_SIGNALS_INTERNAL_H_
22
#define COSMOPOLITAN_LIBC_CALLS_SIGNALS_INTERNAL_H_
33
#include "libc/calls/struct/sigset.h"
4-
#include "libc/nt/struct/ntexceptionpointers.h"
54
#include "libc/thread/posixthread.internal.h"
65

76
#define SIG_HANDLED_NO_RESTART 1
@@ -18,7 +17,7 @@ extern struct Signals __sig;
1817

1918
bool __sig_ignored(int);
2019
int __sig_check(void);
21-
int __sig_crash_sig(struct NtExceptionPointers *, int *);
20+
int __sig_crash_sig(unsigned, int *);
2221
int __sig_get(sigset_t);
2322
int __sig_kill(struct PosixThread *, int, int);
2423
int __sig_mask(int, const sigset_t *, sigset_t *);

libc/calls/sigcrashsig.c

Lines changed: 84 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
╚─────────────────────────────────────────────────────────────────────────────*/
1919
#include "libc/calls/sig.internal.h"
2020
#include "libc/intrin/pushpop.internal.h"
21+
#include "libc/macros.internal.h"
2122
#include "libc/nt/enum/signal.h"
2223
#include "libc/nt/enum/status.h"
2324
#include "libc/nt/struct/ntexceptionpointers.h"
@@ -26,82 +27,90 @@
2627
// so, we trade away maintanibility for tininess
2728
// see libc/sysv/consts.sh for canonical magnums
2829

29-
#define SIGILL_ pushpop(4)
30-
#define SIGTRAP_ pushpop(5)
31-
#define SIGABRT_ pushpop(6)
32-
#define SIGFPE_ pushpop(8)
33-
#define SIGSEGV_ pushpop(11)
34-
#define SIGSYS_ pushpop(31)
30+
#define SIGILL_ 4
31+
#define SIGTRAP_ 5
32+
#define SIGABRT_ 6
33+
#define SIGFPE_ 8
34+
#define SIGSEGV_ 11
35+
#define SIGSYS_ 31
3536

36-
#define TRAP_BRKPT_ pushpop(1)
37-
#define ILL_ILLOPC_ pushpop(1)
38-
#define ILL_PRVOPC_ pushpop(5)
39-
#define SEGV_MAPERR_ pushpop(1)
40-
#define SEGV_ACCERR_ pushpop(2)
41-
#define SI_USER_ pushpop(0)
42-
#define FPE_FLTDIV_ pushpop(3)
43-
#define FPE_FLTOVF_ pushpop(4)
44-
#define FPE_INTOVF_ pushpop(2)
45-
#define FPE_FLTUND_ pushpop(5)
46-
#define FPE_FLTRES_ pushpop(6)
47-
#define FPE_FLTINV_ pushpop(7)
48-
#define SI_KERNEL_ 0x80
37+
#define TRAP_BRKPT_ 1
38+
#define ILL_ILLOPC_ 1
39+
#define ILL_PRVOPC_ 5
40+
#define SEGV_MAPERR_ 1
41+
#define SEGV_ACCERR_ 2
42+
#define SI_USER_ 0
43+
#define FPE_FLTDIV_ 3
44+
#define FPE_FLTOVF_ 4
45+
#define FPE_INTOVF_ 2
46+
#define FPE_FLTUND_ 5
47+
#define FPE_FLTRES_ 6
48+
#define FPE_FLTINV_ 7
49+
#define SI_KERNEL_ 128
4950

50-
textwindows int __sig_crash_sig(struct NtExceptionPointers *ep, int *code) {
51-
switch (ep->ExceptionRecord->ExceptionCode) {
52-
case kNtSignalBreakpoint:
53-
*code = TRAP_BRKPT_;
54-
return SIGTRAP_;
55-
case kNtSignalIllegalInstruction:
56-
*code = ILL_ILLOPC_;
57-
return SIGILL_;
58-
case kNtSignalPrivInstruction:
59-
*code = ILL_PRVOPC_;
60-
return SIGILL_;
61-
case kNtSignalInPageError:
62-
case kNtStatusStackOverflow:
63-
*code = SEGV_MAPERR_;
64-
return SIGSEGV_;
65-
case kNtSignalGuardPage:
66-
case kNtSignalAccessViolation:
67-
*code = SEGV_ACCERR_;
68-
return SIGSEGV_;
69-
case kNtSignalInvalidHandle:
70-
case kNtSignalInvalidParameter:
71-
case kNtSignalAssertionFailure:
72-
*code = SI_USER_;
73-
return SIGABRT_;
74-
case kNtStatusIntegerOverflow:
75-
*code = FPE_INTOVF_;
76-
return SIGFPE_;
77-
case kNtSignalFltDivideByZero:
78-
*code = FPE_FLTDIV_;
79-
return SIGFPE_;
80-
case kNtSignalFltOverflow:
81-
*code = FPE_FLTOVF_;
82-
return SIGFPE_;
83-
case kNtSignalFltUnderflow:
84-
*code = FPE_FLTUND_;
85-
return SIGFPE_;
86-
case kNtSignalFltInexactResult:
87-
*code = FPE_FLTRES_;
88-
return SIGFPE_;
89-
case kNtSignalFltDenormalOperand:
90-
case kNtSignalFltInvalidOperation:
91-
case kNtSignalFltStackCheck:
92-
case kNtSignalIntegerDivideByZero:
93-
case kNtSignalFloatMultipleFaults:
94-
case kNtSignalFloatMultipleTraps:
95-
*code = FPE_FLTINV_;
96-
return SIGFPE_;
97-
case kNtSignalDllNotFound:
98-
case kNtSignalOrdinalNotFound:
99-
case kNtSignalEntrypointNotFound:
100-
case kNtSignalDllInitFailed:
101-
*code = SI_KERNEL_;
102-
return SIGSYS_;
103-
default:
104-
*code = ep->ExceptionRecord->ExceptionCode;
105-
return SIGSEGV_;
51+
#define LO(x) (x & 255)
52+
#define HI(x) ((x >> 24) / !(x & 0x00ffff00u))
53+
#define ROW(x, sic, sig) \
54+
{ \
55+
{ \
56+
{ \
57+
LO(x), HI(x), sic / !(sic & 0xffffff00), sig / !(sig & 0xffffff00) \
58+
} \
59+
} \
10660
}
61+
62+
struct CrashSig {
63+
union {
64+
struct {
65+
unsigned char lo;
66+
unsigned char hi;
67+
unsigned char sic;
68+
unsigned char sig;
69+
};
70+
unsigned word;
71+
};
72+
};
73+
74+
static const struct CrashSig kNtCrashSigs[] = {
75+
ROW(kNtSignalBreakpoint, TRAP_BRKPT_, SIGTRAP_), //
76+
ROW(kNtSignalIllegalInstruction, ILL_ILLOPC_, SIGILL_), //
77+
ROW(kNtSignalPrivInstruction, ILL_PRVOPC_, SIGILL_), //
78+
ROW(kNtSignalInPageError, SEGV_MAPERR_, SIGSEGV_), //
79+
ROW(kNtStatusStackOverflow, SEGV_MAPERR_, SIGSEGV_), //
80+
ROW(kNtSignalGuardPage, SEGV_ACCERR_, SIGSEGV_), //
81+
ROW(kNtSignalAccessViolation, SEGV_ACCERR_, SIGSEGV_), //
82+
ROW(kNtSignalInvalidHandle, SI_USER_, SIGABRT_), //
83+
ROW(kNtSignalInvalidParameter, SI_USER_, SIGABRT_), //
84+
ROW(kNtStatusIntegerOverflow, FPE_INTOVF_, SIGFPE_), //
85+
ROW(kNtSignalFltDivideByZero, FPE_FLTDIV_, SIGFPE_), //
86+
ROW(kNtSignalFltOverflow, FPE_FLTOVF_, SIGFPE_), //
87+
ROW(kNtSignalFltUnderflow, FPE_FLTUND_, SIGFPE_), //
88+
ROW(kNtSignalFltInexactResult, FPE_FLTRES_, SIGFPE_), //
89+
ROW(kNtSignalFltDenormalOperand, FPE_FLTINV_, SIGFPE_), //
90+
ROW(kNtSignalFltInvalidOperation, FPE_FLTINV_, SIGFPE_), //
91+
ROW(kNtSignalFltStackCheck, FPE_FLTINV_, SIGFPE_), //
92+
ROW(kNtSignalIntegerDivideByZero, FPE_FLTINV_, SIGFPE_), //
93+
// ROW(kNtSignalAssertionFailure, SI_USER_, SIGABRT_),
94+
// ROW(kNtSignalFloatMultipleTraps, FPE_FLTINV_, SIGFPE_),
95+
// ROW(kNtSignalFloatMultipleFaults, FPE_FLTINV_, SIGFPE_),
96+
// ROW(kNtSignalDllNotFound, SI_KERNEL_, SIGSYS_),
97+
// ROW(kNtSignalOrdinalNotFound, SI_KERNEL_, SIGSYS_),
98+
// ROW(kNtSignalEntrypointNotFound, SI_KERNEL_, SIGSYS_),
99+
// ROW(kNtSignalDllInitFailed, SI_KERNEL_, SIGSYS_),
100+
};
101+
102+
textwindows dontinstrument int __sig_crash_sig(unsigned exception, int *code) {
103+
for (int i = 0; i < ARRAYLEN(kNtCrashSigs); ++i) {
104+
struct CrashSig cs;
105+
cs.word = kNtCrashSigs[i].word;
106+
unsigned lo = cs.lo;
107+
unsigned hi = cs.hi;
108+
unsigned ec = lo | hi << 24;
109+
if (ec == exception) {
110+
*code = cs.sic;
111+
return cs.sig;
112+
}
113+
}
114+
*code = exception;
115+
return SIGSEGV_;
107116
}

libc/intrin/__getauxval.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,8 @@
3030
*/
3131
struct AuxiliaryValue __getauxval(unsigned long at) {
3232
unsigned long *ap;
33-
for (ap = __auxv; ap[0]; ap += 2) {
34-
if (at == ap[0]) {
33+
for (ap = __auxv; ap && ap[0]; ap += 2)
34+
if (at == ap[0])
3535
return (struct AuxiliaryValue){ap[1], true};
36-
}
37-
}
3836
return (struct AuxiliaryValue){0, false};
3937
}

libc/intrin/g_fds.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,8 @@ textstartup void __init_fds(int argc, char **argv, char **envp) {
143143
break;
144144
if (!TokAtoi(&fdspec, &protocol))
145145
break;
146-
__ensurefds_unlocked(fd);
146+
if (_weaken(__ensurefds_unlocked))
147+
_weaken(__ensurefds_unlocked)(fd);
147148
struct Fd *f = fds->p + fd;
148149
if (f->handle && f->handle != -1 && f->handle != handle) {
149150
CloseHandle(f->handle);

libc/intrin/gettid.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,8 @@ int gettid(void) {
4040
int tid;
4141
if (VERY_LIKELY(__tls_enabled && !__vforked)) {
4242
tid = atomic_load_explicit(&__get_tls()->tib_tid, memory_order_acquire);
43-
if (VERY_LIKELY(tid > 0)) {
43+
if (VERY_LIKELY(tid > 0))
4444
return tid;
45-
}
4645
}
4746
if (IsXnuSilicon()) {
4847
return enosys(); // can only happen if we can't access thread local storage

libc/intrin/maps.c

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,35 +31,51 @@ __static_yoink("_init_maps");
3131

3232
struct Maps __maps;
3333

34+
void __maps_add(struct Map *map) {
35+
dll_init(&map->elem);
36+
dll_make_first(&__maps.used, &map->elem);
37+
map->next = __maps.maps;
38+
__maps.maps = map;
39+
++__maps.count;
40+
}
41+
42+
static void __maps_adder(struct Map *map, int pagesz) {
43+
__maps.pages += ((map->size + pagesz - 1) & -pagesz) / pagesz;
44+
__maps_add(map);
45+
}
46+
47+
void __maps_stack(void *stackaddr, int pagesz, size_t stacksize, int stackprot,
48+
intptr_t stackhand) {
49+
__maps.stack.addr = stackaddr;
50+
__maps.stack.size = stacksize;
51+
__maps.stack.prot = stackprot;
52+
__maps.stack.h = stackhand;
53+
__maps_adder(&__maps.stack, pagesz);
54+
}
55+
3456
void __maps_init(void) {
57+
int pagesz = getauxval(AT_PAGESZ);
3558

3659
// record _start() stack mapping
3760
if (!IsWindows()) {
3861
struct AddrSize stack;
3962
stack = __get_main_stack();
40-
dll_init(&__maps.stack.elem);
41-
__maps.stack.addr = stack.addr;
42-
__maps.stack.size = stack.size;
43-
__maps.stack.prot = (uintptr_t)ape_stack_prot;
44-
__maps_insert(&__maps.stack);
63+
__maps_stack(stack.addr, pagesz, stack.size, (uintptr_t)ape_stack_prot, 0);
4564
}
4665

4766
// record .text and .data mappings
4867
static struct Map text, data;
49-
dll_init(&text.elem);
5068
text.addr = (char *)__executable_start;
5169
text.size = _etext - __executable_start;
5270
text.prot = PROT_READ | PROT_EXEC;
53-
int pagesz = getauxval(AT_PAGESZ);
5471
uintptr_t ds = ((uintptr_t)_etext + pagesz - 1) & -pagesz;
5572
if (ds < (uintptr_t)_end) {
56-
dll_init(&data.elem);
5773
data.addr = (char *)ds;
5874
data.size = (uintptr_t)_end - ds;
5975
data.prot = PROT_READ | PROT_WRITE;
60-
__maps_insert(&data);
76+
__maps_adder(&data, pagesz);
6177
}
62-
__maps_insert(&text);
78+
__maps_adder(&text, pagesz);
6379
}
6480

6581
privileged void __maps_lock(void) {

libc/intrin/maps.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,13 @@ void __maps_init(void);
4343
void __maps_lock(void);
4444
void __maps_check(void);
4545
void __maps_unlock(void);
46+
void __maps_add(struct Map *);
4647
struct Map *__maps_alloc(void);
4748
void __maps_free(struct Map *);
4849
void __maps_insert(struct Map *);
4950
int __munmap(char *, size_t, bool);
5051
void *__mmap(char *, size_t, int, int, int, int64_t);
52+
void __maps_stack(void *, int, size_t, int, intptr_t);
5153
struct AddrSize __get_main_stack(void);
5254

5355
COSMOPOLITAN_C_END_

libc/intrin/mmap.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,7 @@ void __maps_insert(struct Map *map) {
144144
dll_make_first(&__maps.used, &last->elem);
145145
__maps_free(map);
146146
} else {
147-
dll_make_first(&__maps.used, &map->elem);
148-
map->next = __maps.maps;
149-
__maps.maps = map;
150-
++__maps.count;
147+
__maps_add(map);
151148
}
152149
__maps_check();
153150
}

libc/intrin/pthreadlock.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,12 @@
1818
╚─────────────────────────────────────────────────────────────────────────────*/
1919
#include "libc/thread/posixthread.internal.h"
2020

21-
pthread_spinlock_t _pthread_lock_obj;
22-
23-
void _pthread_init(void) {
24-
(void)pthread_spin_init(&_pthread_lock_obj, 0);
25-
}
21+
pthread_mutex_t _pthread_lock_obj = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
2622

2723
void _pthread_lock(void) {
28-
pthread_spin_lock(&_pthread_lock_obj);
24+
pthread_mutex_lock(&_pthread_lock_obj);
2925
}
3026

3127
void _pthread_unlock(void) {
32-
pthread_spin_unlock(&_pthread_lock_obj);
28+
pthread_mutex_unlock(&_pthread_lock_obj);
3329
}

0 commit comments

Comments
 (0)