diff options
| author | Kacper <kacper@mail.openlinux.dev> | 2025-12-16 17:02:05 +0100 |
|---|---|---|
| committer | Kacper <kacper@mail.openlinux.dev> | 2025-12-16 17:02:05 +0100 |
| commit | 90dad97fc07f049383903a166631e2c257f9b8c1 (patch) | |
| tree | 096cd247ecfda9e46598215a4f32aecedeedda90 /lib | |
| parent | 0e832a9329cc4d4647e1ce529846073f21e66991 (diff) | |
Add support for TLS in the libc
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/libc/Kbuild | 4 | ||||
| -rw-r--r-- | lib/libc/devctl/posix_devctl.c | 6 | ||||
| -rw-r--r-- | lib/libc/errno/errno.c | 8 | ||||
| -rw-r--r-- | lib/libc/include/libc.h | 25 | ||||
| -rw-r--r-- | lib/libc/include/syscall.h | 59 | ||||
| -rw-r--r-- | lib/libc/internal/Kbuild | 4 | ||||
| -rw-r--r-- | lib/libc/internal/arch/Kbuild (renamed from lib/libc/arch/Kbuild) | 0 | ||||
| -rw-r--r-- | lib/libc/internal/arch/x86_64/Kbuild (renamed from lib/libc/arch/x86_64/Kbuild) | 0 | ||||
| -rw-r--r-- | lib/libc/internal/arch/x86_64/_start.c (renamed from lib/libc/arch/x86_64/_start.c) | 0 | ||||
| -rw-r--r-- | lib/libc/internal/arch/x86_64/fenv.s (renamed from lib/libc/arch/x86_64/fenv.s) | 0 | ||||
| -rw-r--r-- | lib/libc/internal/arch/x86_64/longjmp.c (renamed from lib/libc/arch/x86_64/longjmp.c) | 0 | ||||
| -rw-r--r-- | lib/libc/internal/arch/x86_64/setjmp.c (renamed from lib/libc/arch/x86_64/setjmp.c) | 0 | ||||
| -rw-r--r-- | lib/libc/internal/arch/x86_64/sigsetjmp.c (renamed from lib/libc/arch/x86_64/sigsetjmp.c) | 0 | ||||
| -rw-r--r-- | lib/libc/internal/deinit/tls.c | 13 | ||||
| -rw-r--r-- | lib/libc/internal/include/__aio.h (renamed from lib/libc/include/__aio.h) | 0 | ||||
| -rw-r--r-- | lib/libc/internal/include/__dirent.h (renamed from lib/libc/include/__dirent.h) | 0 | ||||
| -rw-r--r-- | lib/libc/internal/include/__select.h (renamed from lib/libc/include/__select.h) | 0 | ||||
| -rw-r--r-- | lib/libc/internal/include/__signal.h (renamed from lib/libc/include/__signal.h) | 0 | ||||
| -rw-r--r-- | lib/libc/internal/include/__statvfs.h (renamed from lib/libc/include/__statvfs.h) | 0 | ||||
| -rw-r--r-- | lib/libc/internal/include/__stdio.h (renamed from lib/libc/include/__stdio.h) | 0 | ||||
| -rw-r--r-- | lib/libc/internal/include/__thread.h (renamed from lib/libc/include/__thread.h) | 1 | ||||
| -rw-r--r-- | lib/libc/internal/include/atomic.h (renamed from lib/libc/include/atomic.h) | 0 | ||||
| -rw-r--r-- | lib/libc/internal/include/byteswap.h (renamed from lib/libc/include/byteswap.h) | 0 | ||||
| -rw-r--r-- | lib/libc/internal/include/internal/io_uring.h (renamed from lib/libc/include/internal/io_uring.h) | 0 | ||||
| -rw-r--r-- | lib/libc/internal/include/io_uring.h (renamed from lib/libc/include/io_uring.h) | 0 | ||||
| -rw-r--r-- | lib/libc/internal/include/libc.h | 48 | ||||
| -rw-r--r-- | lib/libc/internal/include/libc/dirent.h (renamed from lib/libc/include/libc/dirent.h) | 0 | ||||
| -rw-r--r-- | lib/libc/internal/include/malloc.h (renamed from lib/libc/include/malloc.h) | 0 | ||||
| -rw-r--r-- | lib/libc/internal/include/syscall.h | 44 | ||||
| -rw-r--r-- | lib/libc/internal/init/Kbuild | 1 | ||||
| -rw-r--r-- | lib/libc/internal/init/init.c | 6 | ||||
| -rw-r--r-- | lib/libc/internal/init/tls.c | 76 | ||||
| -rw-r--r-- | lib/libc/internal/panic.c | 29 | ||||
| -rw-r--r-- | lib/libc/internal/syscall.c | 12 | ||||
| -rw-r--r-- | lib/libc/mman/mmap.c | 2 | ||||
| -rw-r--r-- | lib/libc/mqueue/mq_notify.c | 4 | ||||
| -rw-r--r-- | lib/libc/mqueue/mq_unlink.c | 2 | ||||
| -rw-r--r-- | lib/libc/sys/getauxval.c | 2 | ||||
| -rw-r--r-- | lib/libc/thread/thrd_current.c | 9 |
39 files changed, 246 insertions, 109 deletions
diff --git a/lib/libc/Kbuild b/lib/libc/Kbuild index 76e05807..8a52fdb3 100644 --- a/lib/libc/Kbuild +++ b/lib/libc/Kbuild @@ -1,10 +1,9 @@ lib-y := libc.a install-y := lib/libc.a -cflags-y += -I $(src)/include +cflags-y += -I $(src)/internal/include obj-y += aio/ -obj-y += arch/ obj-y += arpa/ obj-y += assert/ obj-y += ctype/ @@ -49,4 +48,3 @@ obj-y += utsname/ obj-y += wait/ obj-y += wchar/ obj-y += wctype/ - diff --git a/lib/libc/devctl/posix_devctl.c b/lib/libc/devctl/posix_devctl.c index 59497833..01af3111 100644 --- a/lib/libc/devctl/posix_devctl.c +++ b/lib/libc/devctl/posix_devctl.c @@ -1,13 +1,13 @@ #include <devctl.h> +#include <errno.h> #include <sys/cdefs.h> #include <syscall.h> int posix_devctl(int fildes, int dcmd, void *restrict dev_data_ptr, size_t __unused nbyte, int *restrict dev_info_ptr) { - int r; + int r = syscall(ioctl, fildes, dcmd, dev_data_ptr); - r = syscall(ioctl, fildes, dcmd, dev_data_ptr); - if (r < 0) + if (__predict_false(r < 0)) return errno; *dev_info_ptr = r; diff --git a/lib/libc/errno/errno.c b/lib/libc/errno/errno.c index 09b22f4d..fc7c99bb 100644 --- a/lib/libc/errno/errno.c +++ b/lib/libc/errno/errno.c @@ -1,7 +1 @@ -#include <__thread.h> -#include <threads.h> - -int *__errno(void) -{ - return &thrd_current()->terrno; -} +_Thread_local int errno; diff --git a/lib/libc/include/libc.h b/lib/libc/include/libc.h deleted file mode 100644 index 87d4e88f..00000000 --- a/lib/libc/include/libc.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __LIBC_LIBC_H -#define __LIBC_LIBC_H - -#include <stddef.h> -#include <stdatomic.h> - -#define weak_reference(old, new) extern __typeof(old)((new)) __attribute__((__weak__, __alias__(#old))) - -struct libc { - size_t auxv[32]; - - enum { - LIBC_ENVP_TOUCHED = 1 << 0, - } flags; - - struct { - volatile atomic_flag abort; - volatile atomic_flag malloc; - volatile atomic_flag environ; - } lock; -}; - -extern struct libc __libc; - -#endif diff --git a/lib/libc/include/syscall.h b/lib/libc/include/syscall.h deleted file mode 100644 index 645c4bcd..00000000 --- a/lib/libc/include/syscall.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef __LIBC_SYSCALL_H -#define __LIBC_SYSCALL_H - -#include <asm/syscall.h> -#include <asm/unistd_64.h> -#include <errno.h> - -typedef long syscall_arg_t; - -#define __SYSCALL_NARGS_(a, b, c, d, e, f, g, h, n, ...) n -#define __SYSCALL_NARGS(...) \ - __SYSCALL_NARGS_(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0, ) - -#define __SYSCALL_CONCAT_(a, b) a##b -#define __SYSCALL_CONCAT(a, b) __SYSCALL_CONCAT_(a, b) - -#define __SYSCALL_(b, ...) \ - __SYSCALL_CONCAT(b, __SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__) - -#define __syscall(...) __SYSCALL_(__syscall_, __VA_ARGS__) -#define syscall(...) __syscall_ret(__syscall(__VA_ARGS__)) - -#define __sa(x) ((syscall_arg_t)(x)) - -#define __syscall_0(n) __syscall0(__NR_##n) -#define __syscall_1(n, a) __syscall1(__NR_##n, __sa(a)) -#define __syscall_2(n, a, b) __syscall2(__NR_##n, __sa(a), __sa(b)) -#define __syscall_3(n, a, b, c) __syscall3(__NR_##n, __sa(a), __sa(b), __sa(c)) -#define __syscall_4(n, a, b, c, d) \ - __syscall4(__NR_##n, __sa(a), __sa(b), __sa(c), __sa(d)) -#define __syscall_5(n, a, b, c, d, e) \ - __syscall5(__NR_##n, __sa(a), __sa(b), __sa(c), __sa(d), __sa(e)) -#define __syscall_6(n, a, b, c, d, e, f) \ - __syscall6(__NR_##n, __sa(a), __sa(b), __sa(c), __sa(d), __sa(e), \ - __sa(f)) -#define __syscall_7(n, a, b, c, d, e, f, g) \ - __syscall7(__NR_##n, __sa(a), __sa(b), __sa(c), __sa(d), __sa(e), \ - __sa(f), __sa(g)) - -static __inline long __syscall_ret(long ret) -{ - if (ret > -4096 && ret < 0) { - errno = -ret; - ret = -1; - } - return ret; -} - -#ifdef __NR_pread64 -#undef __NR_pread -#define __NR_pread __NR_pread64 -#endif - -#ifdef __NR_pwrite64 -#undef __NR_pwrite -#define __NR_pwrite __NR_pwrite64 -#endif - -#endif diff --git a/lib/libc/internal/Kbuild b/lib/libc/internal/Kbuild index 01daa04b..d391eaa8 100644 --- a/lib/libc/internal/Kbuild +++ b/lib/libc/internal/Kbuild @@ -1 +1,5 @@ obj-y += init/ +obj-y += arch/ + +obj-y += panic.o +obj-y += syscall.o diff --git a/lib/libc/arch/Kbuild b/lib/libc/internal/arch/Kbuild index ad3a7486..ad3a7486 100644 --- a/lib/libc/arch/Kbuild +++ b/lib/libc/internal/arch/Kbuild diff --git a/lib/libc/arch/x86_64/Kbuild b/lib/libc/internal/arch/x86_64/Kbuild index 830a1c5b..830a1c5b 100644 --- a/lib/libc/arch/x86_64/Kbuild +++ b/lib/libc/internal/arch/x86_64/Kbuild diff --git a/lib/libc/arch/x86_64/_start.c b/lib/libc/internal/arch/x86_64/_start.c index f3f4fef2..f3f4fef2 100644 --- a/lib/libc/arch/x86_64/_start.c +++ b/lib/libc/internal/arch/x86_64/_start.c diff --git a/lib/libc/arch/x86_64/fenv.s b/lib/libc/internal/arch/x86_64/fenv.s index b9a46581..b9a46581 100644 --- a/lib/libc/arch/x86_64/fenv.s +++ b/lib/libc/internal/arch/x86_64/fenv.s diff --git a/lib/libc/arch/x86_64/longjmp.c b/lib/libc/internal/arch/x86_64/longjmp.c index dbd18632..dbd18632 100644 --- a/lib/libc/arch/x86_64/longjmp.c +++ b/lib/libc/internal/arch/x86_64/longjmp.c diff --git a/lib/libc/arch/x86_64/setjmp.c b/lib/libc/internal/arch/x86_64/setjmp.c index ea205e16..ea205e16 100644 --- a/lib/libc/arch/x86_64/setjmp.c +++ b/lib/libc/internal/arch/x86_64/setjmp.c diff --git a/lib/libc/arch/x86_64/sigsetjmp.c b/lib/libc/internal/arch/x86_64/sigsetjmp.c index 2d900ce7..2d900ce7 100644 --- a/lib/libc/arch/x86_64/sigsetjmp.c +++ b/lib/libc/internal/arch/x86_64/sigsetjmp.c diff --git a/lib/libc/internal/deinit/tls.c b/lib/libc/internal/deinit/tls.c new file mode 100644 index 00000000..438f0122 --- /dev/null +++ b/lib/libc/internal/deinit/tls.c @@ -0,0 +1,13 @@ +#include <libc.h> +#include <sys/mman.h> + +void __deinit_tls(void) +{ + int r; + + if (__libc.tls.base == NULL) + return; + + r = munmap(__libc.tls.base, __libc.tls.size); + panic_if(__predict_false(r < 0), "munmap(tls) failed"); +} diff --git a/lib/libc/include/__aio.h b/lib/libc/internal/include/__aio.h index 93cb1f79..93cb1f79 100644 --- a/lib/libc/include/__aio.h +++ b/lib/libc/internal/include/__aio.h diff --git a/lib/libc/include/__dirent.h b/lib/libc/internal/include/__dirent.h index 4f9ead80..4f9ead80 100644 --- a/lib/libc/include/__dirent.h +++ b/lib/libc/internal/include/__dirent.h diff --git a/lib/libc/include/__select.h b/lib/libc/internal/include/__select.h index a38bbdce..a38bbdce 100644 --- a/lib/libc/include/__select.h +++ b/lib/libc/internal/include/__select.h diff --git a/lib/libc/include/__signal.h b/lib/libc/internal/include/__signal.h index 6b762dee..6b762dee 100644 --- a/lib/libc/include/__signal.h +++ b/lib/libc/internal/include/__signal.h diff --git a/lib/libc/include/__statvfs.h b/lib/libc/internal/include/__statvfs.h index c8a746d4..c8a746d4 100644 --- a/lib/libc/include/__statvfs.h +++ b/lib/libc/internal/include/__statvfs.h diff --git a/lib/libc/include/__stdio.h b/lib/libc/internal/include/__stdio.h index 487a0382..487a0382 100644 --- a/lib/libc/include/__stdio.h +++ b/lib/libc/internal/include/__stdio.h diff --git a/lib/libc/include/__thread.h b/lib/libc/internal/include/__thread.h index f978d018..7639707a 100644 --- a/lib/libc/include/__thread.h +++ b/lib/libc/internal/include/__thread.h @@ -3,7 +3,6 @@ struct __thread_self { int tid; - int terrno; }; #endif diff --git a/lib/libc/include/atomic.h b/lib/libc/internal/include/atomic.h index e0593021..e0593021 100644 --- a/lib/libc/include/atomic.h +++ b/lib/libc/internal/include/atomic.h diff --git a/lib/libc/include/byteswap.h b/lib/libc/internal/include/byteswap.h index 9dfe6520..9dfe6520 100644 --- a/lib/libc/include/byteswap.h +++ b/lib/libc/internal/include/byteswap.h diff --git a/lib/libc/include/internal/io_uring.h b/lib/libc/internal/include/internal/io_uring.h index e7369146..e7369146 100644 --- a/lib/libc/include/internal/io_uring.h +++ b/lib/libc/internal/include/internal/io_uring.h diff --git a/lib/libc/include/io_uring.h b/lib/libc/internal/include/io_uring.h index 4dac4583..4dac4583 100644 --- a/lib/libc/include/io_uring.h +++ b/lib/libc/internal/include/io_uring.h diff --git a/lib/libc/internal/include/libc.h b/lib/libc/internal/include/libc.h new file mode 100644 index 00000000..f06fa6d8 --- /dev/null +++ b/lib/libc/internal/include/libc.h @@ -0,0 +1,48 @@ +#ifndef __LIBC_LIBC_H +#define __LIBC_LIBC_H + +#include <stdatomic.h> +#include <stddef.h> +#include <sys/cdefs.h> + +#define weak_reference(old, new) extern __typeof(old)((new)) __attribute__((__weak__, __alias__(#old))) + +struct tls { + struct tls *next; + void *data; + size_t size; + size_t align; + size_t length; + size_t offset; +}; + +struct libc { + size_t auxv[32]; + struct { + void *base; + size_t size; + } tls; + + enum { + LIBC_ENVP_TOUCHED = 1 << 0, + } flags; + + struct { + volatile atomic_flag abort; + volatile atomic_flag malloc; + volatile atomic_flag environ; + } lock; +}; + +extern struct libc __libc; + +#define panic(__errmsg) __libc_panic(__FILE__ ":" __STRING(__LINE__) ": ", __PRETTY_FUNCTION__, ": " __STRING(__errmsg)) + +#define panic_if(__cond, __errmsg) \ + do { \ + if (__predict_false(__cond)) \ + panic(__errmsg); \ + } while (0) + +__dead void __libc_panic(const char *, const char *, const char *); +#endif diff --git a/lib/libc/include/libc/dirent.h b/lib/libc/internal/include/libc/dirent.h index 296cc91e..296cc91e 100644 --- a/lib/libc/include/libc/dirent.h +++ b/lib/libc/internal/include/libc/dirent.h diff --git a/lib/libc/include/malloc.h b/lib/libc/internal/include/malloc.h index b7cb0093..b7cb0093 100644 --- a/lib/libc/include/malloc.h +++ b/lib/libc/internal/include/malloc.h diff --git a/lib/libc/internal/include/syscall.h b/lib/libc/internal/include/syscall.h new file mode 100644 index 00000000..ea72ece4 --- /dev/null +++ b/lib/libc/internal/include/syscall.h @@ -0,0 +1,44 @@ +#ifndef __LIBC_SYSCALL_H +#define __LIBC_SYSCALL_H + +#include <asm/syscall.h> +#include <asm/unistd_64.h> + +typedef long syscall_arg_t; + +#define __SYSCALL_NARGS_(a, b, c, d, e, f, g, h, n, ...) n +#define __SYSCALL_NARGS(...) __SYSCALL_NARGS_(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0, ) + +#define __SYSCALL_CONCAT_(a, b) a##b +#define __SYSCALL_CONCAT(a, b) __SYSCALL_CONCAT_(a, b) + +#define __SYSCALL_(b, ...) __SYSCALL_CONCAT(b, __SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__) + +#define __syscall(...) __SYSCALL_(__syscall_, __VA_ARGS__) +#define syscall(...) __syscall_ret(__syscall(__VA_ARGS__)) + +#define __sa(x) ((syscall_arg_t)(x)) + +#define __syscall_0(n) __syscall0(__NR_##n) +#define __syscall_1(n, a) __syscall1(__NR_##n, __sa(a)) +#define __syscall_2(n, a, b) __syscall2(__NR_##n, __sa(a), __sa(b)) +#define __syscall_3(n, a, b, c) __syscall3(__NR_##n, __sa(a), __sa(b), __sa(c)) +#define __syscall_4(n, a, b, c, d) __syscall4(__NR_##n, __sa(a), __sa(b), __sa(c), __sa(d)) +#define __syscall_5(n, a, b, c, d, e) __syscall5(__NR_##n, __sa(a), __sa(b), __sa(c), __sa(d), __sa(e)) +#define __syscall_6(n, a, b, c, d, e, f) __syscall6(__NR_##n, __sa(a), __sa(b), __sa(c), __sa(d), __sa(e), __sa(f)) +#define __syscall_7(n, a, b, c, d, e, f, g) \ + __syscall7(__NR_##n, __sa(a), __sa(b), __sa(c), __sa(d), __sa(e), __sa(f), __sa(g)) + +#ifdef __NR_pread64 +#undef __NR_pread +#define __NR_pread __NR_pread64 +#endif + +#ifdef __NR_pwrite64 +#undef __NR_pwrite +#define __NR_pwrite __NR_pwrite64 +#endif + +extern long __syscall_ret(long ret); + +#endif diff --git a/lib/libc/internal/init/Kbuild b/lib/libc/internal/init/Kbuild index 7941a53c..361f220a 100644 --- a/lib/libc/internal/init/Kbuild +++ b/lib/libc/internal/init/Kbuild @@ -1,2 +1,3 @@ obj-y += init.o +obj-y += tls.o obj-y += vdso.o diff --git a/lib/libc/internal/init/init.c b/lib/libc/internal/init/init.c index 36e66ee4..b2dd8487 100644 --- a/lib/libc/internal/init/init.c +++ b/lib/libc/internal/init/init.c @@ -5,13 +5,14 @@ #include <sys/cdefs.h> extern void __init_vdso(void); +extern void __init_tls(void); + +extern int main(int, char **, char **); struct libc __libc = { 0 }; char **environ; char *__progname; -extern int main(int, char **, char **); - __used void __init(uintptr_t *rsp) { char **argv; @@ -34,6 +35,7 @@ __used void __init(uintptr_t *rsp) for (size_t i = 0; auxv[i]; i += 2) __libc.auxv[auxv[i]] = auxv[i + 1]; + __init_tls(); __init_vdso(); exit(main(argc, argv, environ)); diff --git a/lib/libc/internal/init/tls.c b/lib/libc/internal/init/tls.c new file mode 100644 index 00000000..f6ccde35 --- /dev/null +++ b/lib/libc/internal/init/tls.c @@ -0,0 +1,76 @@ +#include <__thread.h> +#include <asm/prctl.h> +#include <elf.h> +#include <libc.h> +#include <string.h> +#include <sys/mman.h> +#include <syscall.h> + +#define ALIGN_DOWN(x, a) ((x) & ~((a) - 1)) +#define ALIGN_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) + +static struct tls __libc_tls = { 0 }; +static struct __thread_self __libc_thread; +volatile int __libc_tid; + +void __init_tls(void) +{ + int r; + void *mem; + size_t base; + unsigned char *p; + Elf64_Phdr *tls_phdr; + struct __thread_self *thrd; + + base = 0; + tls_phdr = 0; + p = (void *)__libc.auxv[AT_PHDR]; + for (size_t n = __libc.auxv[AT_PHNUM]; n > 0; n--, p += __libc.auxv[AT_PHENT]) { + Elf64_Phdr *phdr = (Elf64_Phdr *)p; + + if (phdr->p_type == PT_PHDR) { + base = __libc.auxv[AT_PHDR] - phdr->p_vaddr; + } else if (phdr->p_type == PT_TLS) { + tls_phdr = phdr; + } + } + + if (tls_phdr) { + __libc_tls.data = (void *)(base + tls_phdr->p_vaddr); + __libc_tls.length = tls_phdr->p_filesz; + __libc_tls.size = tls_phdr->p_memsz; + __libc_tls.align = tls_phdr->p_align; + } + + if (__libc_tls.size != 0) { + void *tls_mem; + size_t tls_size = __libc_tls.size + sizeof(struct __thread_self); + tls_size = (tls_size + __libc_tls.align - 1) & ~(__libc_tls.align - 1); + + mem = mmap(0, tls_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + panic_if(mem == MAP_FAILED, "mmap failed"); + + __libc.tls.base = mem; + __libc.tls.size = tls_size; + + thrd = (struct __thread_self *)mem; + tls_mem = (unsigned char *)mem + sizeof(struct __thread_self); + + if (tls_phdr->p_filesz > 0) { + memcpy(tls_mem, (void *)tls_phdr->p_vaddr, tls_phdr->p_filesz); + memset(tls_mem + tls_phdr->p_filesz, 0, tls_phdr->p_memsz - tls_phdr->p_filesz); + } else { + memset(tls_mem, 0, tls_phdr->p_memsz); + } + + r = syscall(arch_prctl, ARCH_SET_FS, mem + sizeof(struct __thread_self)); + panic_if(r < 0, "arch_prctl(SET_FS) failed"); + } else { + __libc.tls.base = NULL; + thrd = &__libc_thread; + } + + r = syscall(set_tid_address, &__libc_tid); + panic_if(r < 0, "set_tid_address failed"); + thrd->tid = r; +} diff --git a/lib/libc/internal/panic.c b/lib/libc/internal/panic.c new file mode 100644 index 00000000..1af6d6cf --- /dev/null +++ b/lib/libc/internal/panic.c @@ -0,0 +1,29 @@ +#include <string.h> +#include <sys/cdefs.h> +#include <sys/uio.h> +#include <unistd.h> + +__dead void __libc_panic(const char *prefix, const char *f, const char *errmsg) +{ + struct iovec iovec[5]; + const char *e = "libc panic: "; + + iovec[0].iov_base = (char *)e; + iovec[0].iov_len = sizeof("libc panic: ") - 1; + + iovec[1].iov_base = (char *)prefix; + iovec[1].iov_len = strlen(prefix); + + iovec[2].iov_base = (char *)f; + iovec[2].iov_len = strlen(f); + + iovec[3].iov_base = (char *)errmsg; + iovec[3].iov_len = strlen(errmsg); + + iovec[4].iov_base = "\n"; + iovec[4].iov_len = 1; + + writev(STDERR_FILENO, iovec, 5); + + __builtin_trap(); +} diff --git a/lib/libc/internal/syscall.c b/lib/libc/internal/syscall.c new file mode 100644 index 00000000..f7fd3c4b --- /dev/null +++ b/lib/libc/internal/syscall.c @@ -0,0 +1,12 @@ +#include <errno.h> +#include <sys/cdefs.h> + +long __syscall_ret(long ret) +{ + if (__predict_false(ret > -4096 && ret < 0)) { + errno = (int)-ret; + ret = -1; + } + + return ret; +} diff --git a/lib/libc/mman/mmap.c b/lib/libc/mman/mmap.c index d43ed686..b3ebdbbd 100644 --- a/lib/libc/mman/mmap.c +++ b/lib/libc/mman/mmap.c @@ -1,5 +1,3 @@ - - #include <stddef.h> // for size_t #include <syscall.h> // for __syscall_6, syscall diff --git a/lib/libc/mqueue/mq_notify.c b/lib/libc/mqueue/mq_notify.c index a7617375..6011f567 100644 --- a/lib/libc/mqueue/mq_notify.c +++ b/lib/libc/mqueue/mq_notify.c @@ -1,11 +1,11 @@ +#include <errno.h> #include <mqueue.h> #include <signal.h> #include <syscall.h> int mq_notify(mqd_t mqdes, const struct sigevent *notification) { - if (notification == NULL || - notification->sigev_notify != SIGEV_THREAD) { + if (notification == NULL || notification->sigev_notify != SIGEV_THREAD) { return syscall(mq_notify, mqdes, notification); } diff --git a/lib/libc/mqueue/mq_unlink.c b/lib/libc/mqueue/mq_unlink.c index d136f109..da16f030 100644 --- a/lib/libc/mqueue/mq_unlink.c +++ b/lib/libc/mqueue/mq_unlink.c @@ -1,3 +1,4 @@ +#include <errno.h> #include <mqueue.h> #include <syscall.h> @@ -11,7 +12,6 @@ int mq_unlink(const char *name) r = __syscall(mq_unlink, name); if (r < 0) { - // Correct errno for POSIX compliance if (r == -EPERM) r = -EACCES; errno = -r; diff --git a/lib/libc/sys/getauxval.c b/lib/libc/sys/getauxval.c index 155d4258..c9a2bf66 100644 --- a/lib/libc/sys/getauxval.c +++ b/lib/libc/sys/getauxval.c @@ -1,6 +1,8 @@ #include <errno.h> #include <libc.h> +#include <stdio.h> + unsigned long getauxval(unsigned long type) { size_t *auxv = __libc.auxv; diff --git a/lib/libc/thread/thrd_current.c b/lib/libc/thread/thrd_current.c index 69a99723..b588cc27 100644 --- a/lib/libc/thread/thrd_current.c +++ b/lib/libc/thread/thrd_current.c @@ -1,8 +1,9 @@ -#include <__thread.h> // for __thread_self -#include <threads.h> // for thrd_current, thrd_t +#include <__thread.h> +#include <threads.h> + +thread_local struct __thread_self __thread_self; thrd_t thrd_current(void) { - static struct __thread_self self = { 0 }; - return &self; + return &__thread_self; } |
