From 69e6fe89fa9baafeca3e3515bb50897cd8ee7c35 Mon Sep 17 00:00:00 2001 From: Kacper Date: Mon, 15 Dec 2025 18:24:54 +0100 Subject: Add getauxval and cleanup libc startup --- lib/libc/Kbuild | 2 + lib/libc/arch/x86_64/Kbuild | 4 +- lib/libc/arch/x86_64/_start.c | 8 ++ lib/libc/arch/x86_64/clock_gettime.c | 15 --- lib/libc/arch/x86_64/crt0.c | 63 ----------- lib/libc/arch/x86_64/vdso_setup.c | 64 ----------- lib/libc/ctype/isalnum.c | 7 +- lib/libc/devctl/posix_devctl.c | 18 ++-- lib/libc/errno/errno.c | 9 +- lib/libc/include/__thread.h | 2 +- lib/libc/include/features.h | 6 -- lib/libc/include/internal/io_uring.h | 6 ++ lib/libc/include/libc.h | 17 +-- lib/libc/internal/Kbuild | 2 + lib/libc/internal/init/Kbuild | 1 + lib/libc/internal/init/vdso.c | 56 ++++++++++ lib/libc/internal/libc_main.c | 40 +++++++ lib/libc/signal/pthread_sigmask.c | 17 ++- lib/libc/stdio/fdopen.c | 14 +-- lib/libc/stdio/fmemopen.c | 7 +- lib/libc/stdio/fopen.c | 16 +-- lib/libc/stdio/stdin.c | 8 +- lib/libc/stdio/stdout.c | 5 +- lib/libc/stdlib/abort.c | 5 +- lib/libc/stdlib/free.c | 34 +++--- lib/libc/stdlib/getenv.c | 6 +- lib/libc/stdlib/malloc.c | 75 +++++-------- lib/libc/stdlib/realloc.c | 9 +- lib/libc/stdlib/setenv.c | 18 ++-- lib/libc/string/memcpy.c | 11 +- lib/libc/string/strcoll.c | 3 +- lib/libc/string/strerror.c | 7 +- lib/libc/string/strxfrm.c | 7 +- lib/libc/strings/strcasecmp.c | 9 +- lib/libc/strings/strncasecmp.c | 9 +- lib/libc/sys/Kbuild | 3 +- lib/libc/sys/getauxval.c | 16 +++ lib/libc/time/clock_gettime.c | 13 +++ lib/libc/time/strftime.c | 199 ++++++++++++----------------------- lib/libc/time/time.c | 6 +- lib/libc/unistd/posix_close.c | 6 +- 41 files changed, 345 insertions(+), 478 deletions(-) create mode 100644 lib/libc/arch/x86_64/_start.c delete mode 100644 lib/libc/arch/x86_64/clock_gettime.c delete mode 100644 lib/libc/arch/x86_64/crt0.c delete mode 100644 lib/libc/arch/x86_64/vdso_setup.c delete mode 100644 lib/libc/include/features.h create mode 100644 lib/libc/include/internal/io_uring.h create mode 100644 lib/libc/internal/Kbuild create mode 100644 lib/libc/internal/init/Kbuild create mode 100644 lib/libc/internal/init/vdso.c create mode 100644 lib/libc/internal/libc_main.c create mode 100644 lib/libc/sys/getauxval.c create mode 100644 lib/libc/time/clock_gettime.c (limited to 'lib') diff --git a/lib/libc/Kbuild b/lib/libc/Kbuild index 28ef1c99..e1eafe87 100644 --- a/lib/libc/Kbuild +++ b/lib/libc/Kbuild @@ -15,6 +15,7 @@ obj-y += errno/ obj-y += fcntl/ obj-y += fenv/ obj-y += grp/ +obj-y += internal/ obj-y += inttypes/ obj-y += libgen/ obj-y += mman/ @@ -47,3 +48,4 @@ obj-y += utsname/ obj-y += wait/ obj-y += wchar/ obj-y += wctype/ + diff --git a/lib/libc/arch/x86_64/Kbuild b/lib/libc/arch/x86_64/Kbuild index fc8a2d3f..830a1c5b 100644 --- a/lib/libc/arch/x86_64/Kbuild +++ b/lib/libc/arch/x86_64/Kbuild @@ -1,7 +1,5 @@ -obj-y += clock_gettime.o -obj-y += crt0.o +obj-y += _start.o obj-y += fenv.o obj-y += longjmp.o obj-y += setjmp.o obj-y += sigsetjmp.o -obj-y += vdso_setup.o diff --git a/lib/libc/arch/x86_64/_start.c b/lib/libc/arch/x86_64/_start.c new file mode 100644 index 00000000..52b5c774 --- /dev/null +++ b/lib/libc/arch/x86_64/_start.c @@ -0,0 +1,8 @@ +#include +#include + +__dead __naked void _start(void) +{ + __asm__ __volatile__("mov %rsp, %rdi\n" + "call __libc_main\n"); +} diff --git a/lib/libc/arch/x86_64/clock_gettime.c b/lib/libc/arch/x86_64/clock_gettime.c deleted file mode 100644 index c05926fa..00000000 --- a/lib/libc/arch/x86_64/clock_gettime.c +++ /dev/null @@ -1,15 +0,0 @@ -#include "asm/unistd_64.h" // for __NR_clock_gettime - -#include // for __vdso_clock_gettime -#include // for __syscall_2, syscall -#include // for clock_gettime, clockid_t - -int clock_gettime(clockid_t clock_id, struct timespec *tp) -{ -#if defined(__x86_64__) - if (__vdso_clock_gettime) - return __vdso_clock_gettime(clock_id, tp); -#endif - - return syscall(clock_gettime, clock_id, tp); -} diff --git a/lib/libc/arch/x86_64/crt0.c b/lib/libc/arch/x86_64/crt0.c deleted file mode 100644 index c60239d3..00000000 --- a/lib/libc/arch/x86_64/crt0.c +++ /dev/null @@ -1,63 +0,0 @@ -#include "asm/auxvec.h" // for AT_SYSINFO_EHDR -#include -#include // for AT_NULL -#include // for Elf64_Ehdr -#include // for uintptr_t -#include // for exit - -#define weak_reference(old, new) \ - extern __typeof(old) new __attribute__((__weak__, __alias__(#old))) - -extern int main(int, char *[]); -char **environ; -char *__progname; - -struct __attribute__((packed)) auxv_t { - uintptr_t a_type; - uintptr_t a_val; -} *__auxv; - -static void __vdso_setup(Elf64_Ehdr *vdso_addr __attribute__((unused))) -{ -} - -weak_reference(__vdso_setup, vdso_setup); - -static void __io_uring_setup_(void) -{ -} -weak_reference(__io_uring_setup_, __io_uring_setup); - -__attribute__((used)) void __libc_start(uintptr_t *sp) -{ - char **argv; - int argc; - - argc = (int)(*sp); - argv = (char **)(++sp); - __progname = argv[0]; - sp += argc; - environ = (char **)(++sp); - - while (*sp) - sp++; - - __auxv = (struct auxv_t *)(++sp); - while (__auxv->a_type != AT_NULL) { - if (__auxv->a_type == AT_SYSINFO_EHDR) { - vdso_setup((Elf64_Ehdr *)__auxv->a_val); - } - - __auxv++; - } - - __io_uring_setup_(); - - exit(main(argc, argv)); -} - -__attribute__((noreturn, naked)) void _start(void) -{ - __asm__ __volatile__("mov %rsp, %rdi\n" - "call __libc_start\n"); -} diff --git a/lib/libc/arch/x86_64/vdso_setup.c b/lib/libc/arch/x86_64/vdso_setup.c deleted file mode 100644 index 059aa44a..00000000 --- a/lib/libc/arch/x86_64/vdso_setup.c +++ /dev/null @@ -1,64 +0,0 @@ -#include // for Elf64_Sym, (anonymous struct)::(anonymous) -#include "stddef.h" // for NULL - -#include // for strcmp - -struct timespec; - -int (*__vdso_clock_gettime)(int, struct timespec *) = NULL; -int (*__vdso_getcpu)(unsigned *, unsigned *, void *) = NULL; -int (*__vdso_time)(long *) = NULL; - -static __inline __attribute__((used)) void vdso_setup(Elf64_Ehdr *vdso_addr) -{ - Elf64_Phdr *phdr = - (Elf64_Phdr *)((char *)vdso_addr + vdso_addr->e_phoff); - - for (int i = 0; i < vdso_addr->e_phnum; i++) { - if (phdr[i].p_type == PT_DYNAMIC) { - Elf64_Dyn *dyn = (Elf64_Dyn *)((char *)vdso_addr + - phdr[i].p_offset); - const char *strtab = NULL; - Elf64_Sym *symtab = NULL; - for (; dyn->d_tag != DT_NULL; dyn++) { - if (dyn->d_tag == DT_STRTAB) { - strtab = (const char *)vdso_addr + - dyn->d_un.d_ptr; - } else if (dyn->d_tag == DT_SYMTAB) { - symtab = - (Elf64_Sym *)((char *)vdso_addr + - dyn->d_un.d_ptr); - } - } - - if (strtab == NULL || symtab == NULL) { - return; - } - - Elf64_Sym *sym = symtab; - while ((char *)sym < (char *)strtab) { - if (sym->st_name != 0 && sym->st_value != 0) { - const char *name = - strtab + sym->st_name; - if (strcmp(name, - "__vdso_clock_gettime") == 0) - __vdso_clock_gettime = - (void *)(vdso_addr + - sym->st_value); - else if (strcmp(name, - "__vdso_getcpu") == 0) - __vdso_getcpu = - (void *)(vdso_addr + - sym->st_value); - else if (strcmp(name, "__vdso_time") == - 0) - __vdso_time = - (void *)(vdso_addr + - sym->st_value); - } - sym = (Elf64_Sym *)((char *)sym + - sizeof(Elf64_Sym)); - } - } - } -} diff --git a/lib/libc/ctype/isalnum.c b/lib/libc/ctype/isalnum.c index 3263f693..9548071d 100644 --- a/lib/libc/ctype/isalnum.c +++ b/lib/libc/ctype/isalnum.c @@ -1,8 +1,5 @@ -#include "features.h" // for __weak - -#include // for isalnum, isalpha, isdigit, isalnum_l -#include // for __unused -#include // for locale_t +#include +#include int isalnum(int c) { diff --git a/lib/libc/devctl/posix_devctl.c b/lib/libc/devctl/posix_devctl.c index 7403ec53..59497833 100644 --- a/lib/libc/devctl/posix_devctl.c +++ b/lib/libc/devctl/posix_devctl.c @@ -1,17 +1,13 @@ +#include +#include +#include - -#include // for posix_devctl, size_t -#include // for errno -#include // for __unused -#include -#include // for __syscall_3, syscall - -int posix_devctl(int fildes, int dcmd, void *restrict dev_data_ptr, - size_t __unused nbyte, int *restrict dev_info_ptr) +int posix_devctl(int fildes, int dcmd, void *restrict dev_data_ptr, size_t __unused nbyte, int *restrict dev_info_ptr) { - long r; + int r; - if ((r = syscall(ioctl, fildes, dcmd, dev_data_ptr)) < 0) + r = syscall(ioctl, fildes, dcmd, dev_data_ptr); + if (r < 0) return errno; *dev_info_ptr = r; diff --git a/lib/libc/errno/errno.c b/lib/libc/errno/errno.c index 55423e22..09b22f4d 100644 --- a/lib/libc/errno/errno.c +++ b/lib/libc/errno/errno.c @@ -1,8 +1,7 @@ -// TODO: Should return the address of the calling thread's `errno` storage. -// Currently, this is a stub implementation that returns the address of a -// static variable. +#include <__thread.h> +#include + int *__errno(void) { - static int __thread_errno = 0; - return &__thread_errno; + return &thrd_current()->terrno; } diff --git a/lib/libc/include/__thread.h b/lib/libc/include/__thread.h index 662f1dc1..f978d018 100644 --- a/lib/libc/include/__thread.h +++ b/lib/libc/include/__thread.h @@ -3,7 +3,7 @@ struct __thread_self { int tid; - int _errno; + int terrno; }; #endif diff --git a/lib/libc/include/features.h b/lib/libc/include/features.h deleted file mode 100644 index 8f7fa940..00000000 --- a/lib/libc/include/features.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LIBC_FEATURES_H -#define __LIBC_FEATURES_H - -#define __weak extern __attribute__((weak)) - -#endif diff --git a/lib/libc/include/internal/io_uring.h b/lib/libc/include/internal/io_uring.h new file mode 100644 index 00000000..e7369146 --- /dev/null +++ b/lib/libc/include/internal/io_uring.h @@ -0,0 +1,6 @@ +#ifndef __INTERNAL_IO_URING_H +#define __INTERNAL_IO_URING_H + +void __io_uring_init(void); + +#endif diff --git a/lib/libc/include/libc.h b/lib/libc/include/libc.h index 6f233d35..87d4e88f 100644 --- a/lib/libc/include/libc.h +++ b/lib/libc/include/libc.h @@ -1,24 +1,25 @@ #ifndef __LIBC_LIBC_H #define __LIBC_LIBC_H +#include #include -#define likely(x) __builtin_expect(!!(x), 1) -#define unlikely(x) __builtin_expect(!!(x), 0) -#define __unused __attribute__((unused)) -#define aligned(type) __attribute__((aligned(__alignof__(type)))) -#define weak_reference(old, new) \ - extern __typeof(old)((new)) __attribute__((__weak__, __alias__(#old))) +#define weak_reference(old, new) extern __typeof(old)((new)) __attribute__((__weak__, __alias__(#old))) + +struct libc { + size_t auxv[32]; -static struct libc { enum { LIBC_ENVP_TOUCHED = 1 << 0, } flags; + struct { volatile atomic_flag abort; volatile atomic_flag malloc; volatile atomic_flag environ; } lock; -} libc = { .lock = { ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT, ATOMIC_FLAG_INIT } }; +}; + +extern struct libc __libc; #endif diff --git a/lib/libc/internal/Kbuild b/lib/libc/internal/Kbuild new file mode 100644 index 00000000..5015f987 --- /dev/null +++ b/lib/libc/internal/Kbuild @@ -0,0 +1,2 @@ +obj-y += init/ +obj-y += libc_main.o diff --git a/lib/libc/internal/init/Kbuild b/lib/libc/internal/init/Kbuild new file mode 100644 index 00000000..dd27261a --- /dev/null +++ b/lib/libc/internal/init/Kbuild @@ -0,0 +1 @@ +obj-y += vdso.o diff --git a/lib/libc/internal/init/vdso.c b/lib/libc/internal/init/vdso.c new file mode 100644 index 00000000..f94401f6 --- /dev/null +++ b/lib/libc/internal/init/vdso.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include + +void __init_vdso(void) +{ + Elf64_Ehdr *ehdr = (Elf64_Ehdr *)getauxval(AT_SYSINFO_EHDR); + Elf64_Phdr *phdr = (Elf64_Phdr *)(ehdr + ehdr->e_phoff); + + for (int i = 0; i < ehdr->e_phnum; i++) { + Elf64_Dyn *dyn; + Elf64_Sym *symtab; + const char *strtab; + + if (phdr[i].p_type == PT_DYNAMIC) { + Elf64_Sym *sym; + + dyn = (Elf64_Dyn *)((char *)ehdr + phdr[i].p_offset); + symtab = 0; + strtab = 0; + + while (dyn->d_tag != DT_NULL) { + if (dyn->d_tag == DT_STRTAB) { + strtab = (const char *)(ehdr + dyn->d_un.d_ptr); + } else if (dyn->d_tag == DT_SYMTAB) { + symtab = (Elf64_Sym *)(ehdr + dyn->d_un.d_ptr); + } + + if (strtab && symtab) { + break; + } + + dyn++; + } + + sym = symtab; + while ((char *)sym < strtab) { + if (sym->st_name != 0 && sym->st_value != 0) { + const char *name = strtab + sym->st_name; + + for (int i = 0; __vdso_symtab[i].name != 0; i++) { + if (strcmp(name, __vdso_symtab[i].name) == 0) { + __vdso_symtab[i].func = (void *)(ehdr + sym->st_value); + break; + } + } + } + + sym = (Elf64_Sym *)((char *)sym + sizeof(Elf64_Sym)); + } + + break; + } + } +} diff --git a/lib/libc/internal/libc_main.c b/lib/libc/internal/libc_main.c new file mode 100644 index 00000000..7ac15ab4 --- /dev/null +++ b/lib/libc/internal/libc_main.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include +#include + +extern void __init_vdso(void); + +struct libc __libc; +char **environ; +char *__progname; + +extern int main(int, char **, char **); + +__used void __libc_main(uintptr_t *rsp) +{ + char **argv; + size_t *auxv; + int argc; + + argc = (int)(*rsp); + argv = (char **)(++rsp); + + rsp += argc; + + environ = (char **)(++rsp); + __progname = argv[0]; + + while (*rsp) + rsp++; + + auxv = (size_t *)++rsp; + + for (size_t i = 0; auxv[i]; i += 2) + __libc.auxv[auxv[i]] = auxv[i + 1]; + + __init_vdso(); + + exit(main(argc, argv, environ)); +} diff --git a/lib/libc/signal/pthread_sigmask.c b/lib/libc/signal/pthread_sigmask.c index 5e657a6e..89c4f0d3 100644 --- a/lib/libc/signal/pthread_sigmask.c +++ b/lib/libc/signal/pthread_sigmask.c @@ -1,11 +1,11 @@ #define __ASSEMBLY__ -#include // for SIGRTMIN - +#include #undef __ASSEMBLY__ -#include // for errno -#include // for unlikely -#include // for NULL +#include +#include +#include +#include typedef __UINT64_TYPE__ sigset_t; @@ -13,13 +13,12 @@ int sigdelset(sigset_t *, int); int sigismember(const sigset_t *, int); int sigprocmask(int, const sigset_t *restrict, sigset_t *restrict); -int pthread_sigmask(int how, const sigset_t *restrict set, - sigset_t *restrict oset) +int pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict oset) { sigset_t lset; - if (set != NULL && (unlikely(sigismember(set, SIGRTMIN)) || - unlikely(sigismember(set, SIGRTMIN + 1)))) { + if (set != NULL && + (__predict_true(sigismember(set, SIGRTMIN)) || __predict_true(sigismember(set, SIGRTMIN + 1)))) { lset = *set; sigdelset(&lset, SIGRTMIN); sigdelset(&lset, SIGRTMIN + 1); diff --git a/lib/libc/stdio/fdopen.c b/lib/libc/stdio/fdopen.c index c5db3854..bded5f27 100644 --- a/lib/libc/stdio/fdopen.c +++ b/lib/libc/stdio/fdopen.c @@ -1,10 +1,7 @@ -#include "__stdio.h" // for __FILE, __libc_fadd -#include "features.h" // for __weak -#include "stdatomic.h" // for atomic_flag_clear -#include "stddef.h" // for NULL - -#include // for FILE, _IONBF, SEEK_END, _IOLBF, fdopen -#include // for calloc, free +#include "__stdio.h" // for __FILE, __libc_fadd +#include // for FILE, _IONBF, SEEK_END, _IOLBF, fdopen +#include // for calloc, free +#include #include // for lseek, off_t __weak void __stdio_cleanup(void) @@ -15,8 +12,7 @@ FILE *fdopen(int fildes, const char *mode) { FILE *stream; - if (mode == NULL || - (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a')) { + if (mode == NULL || (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a')) { return NULL; } diff --git a/lib/libc/stdio/fmemopen.c b/lib/libc/stdio/fmemopen.c index 920484b3..e1b2ccff 100644 --- a/lib/libc/stdio/fmemopen.c +++ b/lib/libc/stdio/fmemopen.c @@ -1,6 +1,5 @@ -#include "__stdio.h" // for __FILE, __libc_fadd -#include "features.h" // for __weak -#include "stddef.h" // for NULL +#include "__stdio.h" // for __FILE, __libc_fadd +#include "stddef.h" // for NULL #include // for EINVAL, errno #include // for O_WRONLY, O_CREAT, O_RDONLY, O_APPEND, O_RDWR @@ -8,6 +7,8 @@ #include // for calloc, free #include // for strchr +#include + __weak void __stdio_cleanup(void) { } diff --git a/lib/libc/stdio/fopen.c b/lib/libc/stdio/fopen.c index bef21f46..5415e711 100644 --- a/lib/libc/stdio/fopen.c +++ b/lib/libc/stdio/fopen.c @@ -1,13 +1,11 @@ -#include "__stdio.h" // for __FILE, __libc_fadd -#include "features.h" // for __weak -#include "stdatomic.h" // for atomic_flag_clear -#include "stddef.h" // for NULL +#include <__stdio.h> #include // for EINVAL, errno #include // for O_WRONLY, O_CREAT, O_RDONLY, open, O_APPEND #include // for FILE, BUFSIZ, fopen, _IOLBF #include // for calloc, free, malloc #include // for strchr +#include #include // for close __weak void __stdio_cleanup(void) @@ -36,10 +34,12 @@ FILE *fopen(const char *restrict pathname, const char *restrict mode) flags = (flags & ~(O_RDONLY | O_WRONLY)) | O_RDWR; } - if ((fd = open(pathname, flags, _mode)) < 0) + fd = open(pathname, flags, _mode); + if (fd < 0) return NULL; - if ((stream = calloc(1, sizeof(FILE))) == NULL) + stream = calloc(1, sizeof(struct __FILE)); + if (stream == NULL) return NULL; __FILE(stream)->fd = fd; @@ -48,7 +48,9 @@ FILE *fopen(const char *restrict pathname, const char *restrict mode) __FILE(stream)->type = _IOLBF; atomic_flag_clear(&__FILE(stream)->lock); - if ((__FILE(stream)->buf = malloc(BUFSIZ)) == NULL) { + __FILE(stream)->buf = malloc(BUFSIZ); + + if (__FILE(stream)->buf == NULL) { close(fd); free(stream); return NULL; diff --git a/lib/libc/stdio/stdin.c b/lib/libc/stdio/stdin.c index 45d42e27..0d127efa 100644 --- a/lib/libc/stdio/stdin.c +++ b/lib/libc/stdio/stdin.c @@ -1,8 +1,8 @@ -#include "__stdio.h" // for __FILE -#include "features.h" // for __weak +#include "__stdio.h" // for __FILE -#include // for O_RDONLY -#include // for FILE, stdin +#include // for O_RDONLY +#include // for FILE, stdin +#include #include // for STDOUT_FILENO #define BUFSIZ 4096 diff --git a/lib/libc/stdio/stdout.c b/lib/libc/stdio/stdout.c index 14637368..471a54b9 100644 --- a/lib/libc/stdio/stdout.c +++ b/lib/libc/stdio/stdout.c @@ -1,11 +1,10 @@ -#include "__stdio.h" // for __FILE, __libc_fadd -#include "features.h" // for __weak -#include "stdatomic.h" // for ATOMIC_FLAG_INIT, atomic_flag +#include "__stdio.h" // for __FILE, __libc_fadd #include // for LIBC_LOCK, LIBC_UNLOCK #include // for O_WRONLY #include // for NULL #include // for stdout +#include #include // for STDOUT_FILENO #define BUFSIZ 4096 diff --git a/lib/libc/stdlib/abort.c b/lib/libc/stdlib/abort.c index 466329d1..70738ab3 100644 --- a/lib/libc/stdlib/abort.c +++ b/lib/libc/stdlib/abort.c @@ -16,12 +16,11 @@ _Noreturn void abort(void) raise(SIGABRT); - LIBC_LOCK(libc.lock.abort); + LIBC_LOCK(__libc.lock.abort); sa.sa_handler = SIG_DFL; __syscall(rt_sigaction, SIGABRT, &sa, 0, 64 / 8); - __syscall(tkill, ((struct __thread_self *)thrd_current())->tid, - SIGABRT); + __syscall(tkill, ((struct __thread_self *)thrd_current())->tid, SIGABRT); // This point should never be reached raise(SIGKILL); diff --git a/lib/libc/stdlib/free.c b/lib/libc/stdlib/free.c index ab656633..4afc800e 100644 --- a/lib/libc/stdlib/free.c +++ b/lib/libc/stdlib/free.c @@ -12,15 +12,14 @@ void free(void *ptr) return; } - LIBC_LOCK(libc.lock.malloc); + LIBC_LOCK(__libc.lock.malloc); struct page *p = __malloc_pvec; int found_in_pages = 0; while (p) { if ((uintptr_t)ptr >= (uintptr_t)p->heap && - (uintptr_t)ptr < (uintptr_t)(p->heap + (p->block.size * - p->block.count))) { + (uintptr_t)ptr < (uintptr_t)(p->heap + (p->block.size * p->block.count))) { size_t offset = (uintptr_t)ptr - (uintptr_t)p->heap; size_t index = offset / p->block.size; size_t byte_index = index / 8; @@ -42,14 +41,12 @@ void free(void *ptr) if (p == __malloc_pvec) __malloc_pvec = p->next; - munmap(p, (p->flags == PAGE_SMALL) ? - SMALL_PAGE_SIZE : - (p->flags == PAGE_MEDIUM) ? - MEDIUM_PAGE_SIZE : - LARGE_PAGE_SIZE); + munmap(p, (p->flags == PAGE_SMALL) ? SMALL_PAGE_SIZE : + (p->flags == PAGE_MEDIUM) ? MEDIUM_PAGE_SIZE : + LARGE_PAGE_SIZE); } - LIBC_UNLOCK(libc.lock.malloc); + LIBC_UNLOCK(__libc.lock.malloc); return; } p = p->next; @@ -61,11 +58,8 @@ void free(void *ptr) p = __malloc_pvec; while (p) { if ((uintptr_t)potential_orig >= (uintptr_t)p->heap && - (uintptr_t)potential_orig < - (uintptr_t)(p->heap + - (p->block.size * p->block.count))) { - size_t offset = - (uintptr_t)potential_orig - (uintptr_t)p->heap; + (uintptr_t)potential_orig < (uintptr_t)(p->heap + (p->block.size * p->block.count))) { + size_t offset = (uintptr_t)potential_orig - (uintptr_t)p->heap; size_t index = offset / p->block.size; size_t byte_index = index / 8; size_t bit_index = index % 8; @@ -85,18 +79,16 @@ void free(void *ptr) if (p == __malloc_pvec) __malloc_pvec = p->next; - munmap(p, (p->flags == PAGE_SMALL) ? - SMALL_PAGE_SIZE : - (p->flags == PAGE_MEDIUM) ? - MEDIUM_PAGE_SIZE : - LARGE_PAGE_SIZE); + munmap(p, (p->flags == PAGE_SMALL) ? SMALL_PAGE_SIZE : + (p->flags == PAGE_MEDIUM) ? MEDIUM_PAGE_SIZE : + LARGE_PAGE_SIZE); } - LIBC_UNLOCK(libc.lock.malloc); + LIBC_UNLOCK(__libc.lock.malloc); return; } p = p->next; } - LIBC_UNLOCK(libc.lock.malloc); + LIBC_UNLOCK(__libc.lock.malloc); } diff --git a/lib/libc/stdlib/getenv.c b/lib/libc/stdlib/getenv.c index 41517e2f..91cdc87b 100644 --- a/lib/libc/stdlib/getenv.c +++ b/lib/libc/stdlib/getenv.c @@ -7,7 +7,7 @@ extern char **environ; char *getenv(const char *name) { - LIBC_LOCK(libc.lock.environ); + LIBC_LOCK(__libc.lock.environ); for (char **env = environ; *env; env++) { char *eq = NULL; @@ -21,12 +21,12 @@ char *getenv(const char *name) } } if (eq && name[eq - *env] == '\0') { - LIBC_UNLOCK(libc.lock.environ); + LIBC_UNLOCK(__libc.lock.environ); return eq + 1; } } - LIBC_UNLOCK(libc.lock.environ); + LIBC_UNLOCK(__libc.lock.environ); return NULL; } diff --git a/lib/libc/stdlib/malloc.c b/lib/libc/stdlib/malloc.c index 556fcbd1..c696e64c 100644 --- a/lib/libc/stdlib/malloc.c +++ b/lib/libc/stdlib/malloc.c @@ -1,14 +1,12 @@ -#include "stddef.h" // for NULL - #include // for LIBC_UNLOCK, LIBC_LOCK -#include // for __weak #include // for libc, libc::(anonymous) #include // for page, page::(anonymous), class, global_size_c... #include // for atomic_flag_clear #include // for uint32_t, uint8_t, uintptr_t #include // for malloc #include // for memset -#include // for size_t, mmap, munmap, MAP_ANONYMOUS, MAP_FAILED +#include +#include // for size_t, mmap, munmap, MAP_ANONYMOUS, MAP_FAILED struct page *__malloc_pvec = NULL; @@ -16,15 +14,13 @@ static __inline uint32_t get_size_class(size_t size) { uintptr_t minblock_count = (size + (16 - 1)) / 16; - if (size <= (16 * 64)) { + if (size <= (size_t)(16 * 64)) { return (uint32_t)(minblock_count ? minblock_count : 1); } - const uint32_t most_significant_bit = - (uint32_t)(63 - (int)__builtin_clzll(minblock_count)); + const uint32_t most_significant_bit = (uint32_t)(63 - (int)__builtin_clzll(minblock_count)); - const uint32_t subclass_bits = - (minblock_count >> (most_significant_bit - 2)) & 0x03; + const uint32_t subclass_bits = (minblock_count >> (most_significant_bit - 2)) & 0x03; return (uint32_t)((most_significant_bit << 2) + subclass_bits) + 41; } @@ -36,12 +32,11 @@ void *malloc(size_t size) if (size == 0) return NULL; - LIBC_LOCK(libc.lock.malloc); + LIBC_LOCK(__libc.lock.malloc); uint32_t class_index = get_size_class(size); - if (class_index >= - sizeof(global_size_class) / sizeof(global_size_class[0])) { - LIBC_UNLOCK(libc.lock.malloc); + if (class_index >= sizeof(global_size_class) / sizeof(global_size_class[0])) { + LIBC_UNLOCK(__libc.lock.malloc); return NULL; } const struct class *cls = &global_size_class[class_index]; @@ -50,70 +45,57 @@ void *malloc(size_t size) while (p) { if (p->flags == PAGE_SMALL && cls->size <= 16 * 64) { LIBC_LOCK(p->lock); - if (p->block.used < p->block.count && - p->block.size == cls->size) { + if (p->block.used < p->block.count && p->block.size == cls->size) { for (uint32_t i = 0; i < p->block.count; i++) { int byte_index = i / 8; int bit_index = i % 8; - if (!(p->bitmap[byte_index] & - (1 << bit_index))) { - p->bitmap[byte_index] |= - (1 << bit_index); + if (!(p->bitmap[byte_index] & (1 << bit_index))) { + p->bitmap[byte_index] |= (1 << bit_index); p->block.used++; LIBC_UNLOCK(p->lock); - LIBC_UNLOCK(libc.lock.malloc); + LIBC_UNLOCK(__libc.lock.malloc); if (p->heap == NULL) return NULL; - return p->heap + - (i * p->block.size); + return p->heap + (i * p->block.size); } } } LIBC_UNLOCK(p->lock); - } else if (p->flags == PAGE_MEDIUM && cls->size > 16 * 64 && - cls->size <= 16 * 8192) { + } else if (p->flags == PAGE_MEDIUM && cls->size > 16 * 64 && cls->size <= 16 * 8192) { LIBC_LOCK(p->lock); - if (p->block.used < p->block.count && - p->block.size == cls->size) { + if (p->block.used < p->block.count && p->block.size == cls->size) { for (uint32_t i = 0; i < p->block.count; i++) { int byte_index = i / 8; int bit_index = i % 8; - if (!(p->bitmap[byte_index] & - (1 << bit_index))) { + if (!(p->bitmap[byte_index] & (1 << bit_index))) { // Mark block as used - p->bitmap[byte_index] |= - (1 << bit_index); + p->bitmap[byte_index] |= (1 << bit_index); p->block.used++; LIBC_UNLOCK(p->lock); - LIBC_UNLOCK(libc.lock.malloc); + LIBC_UNLOCK(__libc.lock.malloc); if (p->heap == NULL) return NULL; - return p->heap + - (i * p->block.size); + return p->heap + (i * p->block.size); } } } LIBC_UNLOCK(p->lock); } else if (p->flags == PAGE_LARGE && cls->size > 16 * 8192) { LIBC_LOCK(p->lock); - if (p->block.used < p->block.count && - p->block.size == cls->size) { + if (p->block.used < p->block.count && p->block.size == cls->size) { // Find free block for (uint32_t i = 0; i < p->block.count; i++) { int byte_index = i / 8; int bit_index = i % 8; - if (!(p->bitmap[byte_index] & - (1 << bit_index))) { - p->bitmap[byte_index] |= - (1 << bit_index); + if (!(p->bitmap[byte_index] & (1 << bit_index))) { + p->bitmap[byte_index] |= (1 << bit_index); p->block.used++; LIBC_UNLOCK(p->lock); - LIBC_UNLOCK(libc.lock.malloc); + LIBC_UNLOCK(__libc.lock.malloc); if (p->heap == NULL) return NULL; - return p->heap + - (i * p->block.size); + return p->heap + (i * p->block.size); } } } @@ -137,11 +119,10 @@ void *malloc(size_t size) } size_t bitmap_size = (cls->count + 7) / 8; - void *mem = mmap(NULL, page_size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + void *mem = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (mem == MAP_FAILED) { - LIBC_UNLOCK(libc.lock.malloc); + LIBC_UNLOCK(__libc.lock.malloc); return NULL; } @@ -159,7 +140,7 @@ void *malloc(size_t size) if (new_page->heap == NULL || new_page->bitmap == NULL) { munmap(mem, page_size); - LIBC_UNLOCK(libc.lock.malloc); + LIBC_UNLOCK(__libc.lock.malloc); return NULL; } atomic_flag_clear(&new_page->lock); @@ -176,7 +157,7 @@ void *malloc(size_t size) new_page->bitmap[0] |= 1; new_page->block.used = 1; - LIBC_UNLOCK(libc.lock.malloc); + LIBC_UNLOCK(__libc.lock.malloc); return new_page->heap; } diff --git a/lib/libc/stdlib/realloc.c b/lib/libc/stdlib/realloc.c index dca8cac2..78081564 100644 --- a/lib/libc/stdlib/realloc.c +++ b/lib/libc/stdlib/realloc.c @@ -18,15 +18,14 @@ void *realloc(void *ptr, size_t size) return NULL; } - LIBC_LOCK(libc.lock.malloc); + LIBC_LOCK(__libc.lock.malloc); struct page *p = __malloc_pvec; while (p) { if ((uintptr_t)ptr >= (uintptr_t)p->heap && - (uintptr_t)ptr < (uintptr_t)(p->heap + (p->block.size * - p->block.count))) { + (uintptr_t)ptr < (uintptr_t)(p->heap + (p->block.size * p->block.count))) { size_t old_size = p->block.size; - LIBC_UNLOCK(libc.lock.malloc); + LIBC_UNLOCK(__libc.lock.malloc); if (size <= old_size) { return ptr; @@ -41,7 +40,7 @@ void *realloc(void *ptr, size_t size) p = p->next; } - LIBC_UNLOCK(libc.lock.malloc); + LIBC_UNLOCK(__libc.lock.malloc); errno = EINVAL; return NULL; diff --git a/lib/libc/stdlib/setenv.c b/lib/libc/stdlib/setenv.c index 3dfe3d22..22b7bef9 100644 --- a/lib/libc/stdlib/setenv.c +++ b/lib/libc/stdlib/setenv.c @@ -14,18 +14,15 @@ int setenv(const char *var, const char *value, int overwrite) for (; *env; env++) { char *eq = strchr(*env, '='); - if (eq && ((size_t)(eq - *env) == var_len) && - !strncmp(*env, var, var_len)) { + if (eq && ((size_t)(eq - *env) == var_len) && !strncmp(*env, var, var_len)) { if (overwrite) { size_t value_len = strlen(value); - char *new_env = - malloc(var_len + 1 + value_len + 1); + char *new_env = malloc(var_len + 1 + value_len + 1); if (!new_env) return -1; strcpy(new_env, var); new_env[var_len] = '='; - memcpy(new_env + var_len + 1, value, - value_len + 1); + memcpy(new_env + var_len + 1, value, value_len + 1); *env = new_env; } return 0; @@ -36,8 +33,7 @@ int setenv(const char *var, const char *value, int overwrite) while (environ[env_count]) env_count++; - char **new_envp = (char **)realloc((void *)environ, - (env_count + 2) * sizeof(char *)); + char **new_envp = (char **)realloc((void *)environ, (env_count + 2) * sizeof(char *)); if (!new_envp) return -1; @@ -52,10 +48,10 @@ int setenv(const char *var, const char *value, int overwrite) new_envp[env_count] = new_var; new_envp[env_count + 1] = NULL; - LIBC_LOCK(libc.lock.environ); + LIBC_LOCK(__libc.lock.environ); environ = new_envp; - LIBC_UNLOCK(libc.lock.environ); - libc.flags |= LIBC_ENVP_TOUCHED; + LIBC_UNLOCK(__libc.lock.environ); + __libc.flags |= LIBC_ENVP_TOUCHED; return 0; } diff --git a/lib/libc/string/memcpy.c b/lib/libc/string/memcpy.c index 46e24e42..f87d95cd 100644 --- a/lib/libc/string/memcpy.c +++ b/lib/libc/string/memcpy.c @@ -1,7 +1,7 @@ -#include // for EINVAL, ERANGE -#include // for __weak -#include // for NULL, errno_t -#include // for rsize_t, memcpy, size_t, memcpy_s +#include // for EINVAL, ERANGE +#include // for NULL, errno_t +#include // for rsize_t, memcpy, size_t, memcpy_s +#include __weak void *memcpy(void *restrict s1, const void *restrict s2, size_t n); @@ -17,8 +17,7 @@ void *memcpy(void *restrict s1, const void *restrict s2, size_t n) return s1; } -errno_t memcpy_s(void *restrict dest, rsize_t destsz, const void *restrict src, - rsize_t count) +errno_t memcpy_s(void *restrict dest, rsize_t destsz, const void *restrict src, rsize_t count) { if (dest == NULL || src == NULL) { if (dest != NULL && destsz > 0) { diff --git a/lib/libc/string/strcoll.c b/lib/libc/string/strcoll.c index e862bb11..2a4a3473 100644 --- a/lib/libc/string/strcoll.c +++ b/lib/libc/string/strcoll.c @@ -1,7 +1,6 @@ -#include "features.h" // for __weak - #include // for __unused #include // for strcmp, locale_t, strcoll, strcoll_l +#include int strcoll(const char *s1, const char *s2) { diff --git a/lib/libc/string/strerror.c b/lib/libc/string/strerror.c index 62bcea76..b96884ea 100644 --- a/lib/libc/string/strerror.c +++ b/lib/libc/string/strerror.c @@ -1,9 +1,7 @@ -#include "features.h" // for __weak - -#include "stddef.h" #include // for ERANGE, E2BIG, EACCES, EADDRINUSE, EADDRNOTAVAIL #include // for __unused #include // for memcpy, size_t, strerror, strlen, locale_t +#include char *strerror(int errnum) { @@ -105,8 +103,7 @@ char *strerror(int errnum) [EKEYREJECTED] = "Key was rejected by service", }; - if (errnum < 0 || (size_t)errnum >= sizeof(table) / sizeof(table[0]) || - !table[errnum]) { + if (errnum < 0 || (size_t)errnum >= sizeof(table) / sizeof(table[0]) || !table[errnum]) { errno = EINVAL; return NULL; } diff --git a/lib/libc/string/strxfrm.c b/lib/libc/string/strxfrm.c index ae51f984..ddfe8315 100644 --- a/lib/libc/string/strxfrm.c +++ b/lib/libc/string/strxfrm.c @@ -1,7 +1,5 @@ -#include "features.h" // for __weak - -#include // for __unused #include // for size_t, strlcpy, strlen, strxfrm, locale_t +#include size_t strxfrm(char *restrict s1, const char *restrict s2, size_t n) { @@ -13,8 +11,7 @@ size_t strxfrm(char *restrict s1, const char *restrict s2, size_t n) return len; } -__weak size_t strxfrm_l(char *restrict s1, const char *restrict s2, size_t n, - locale_t __unused locale) +__weak size_t strxfrm_l(char *restrict s1, const char *restrict s2, size_t n, locale_t __unused locale) { return strxfrm(s1, s2, n); } diff --git a/lib/libc/strings/strcasecmp.c b/lib/libc/strings/strcasecmp.c index fc38be4a..476a5d8d 100644 --- a/lib/libc/strings/strcasecmp.c +++ b/lib/libc/strings/strcasecmp.c @@ -1,8 +1,7 @@ -#include "features.h" // for __weak - #include // for tolower #include // for __unused #include // for locale_t +#include int strcasecmp(const char *s1, const char *s2) { @@ -17,12 +16,10 @@ int strcasecmp(const char *s1, const char *s2) s2++; } - return (unsigned char)tolower((unsigned char)*s1) - - (unsigned char)tolower((unsigned char)*s2); + return (unsigned char)tolower((unsigned char)*s1) - (unsigned char)tolower((unsigned char)*s2); } -__weak int strcasecmp_l(const char *s1, const char *s2, - locale_t __unused locale) +__weak int strcasecmp_l(const char *s1, const char *s2, locale_t __unused locale) { return strcasecmp(s1, s2); } diff --git a/lib/libc/strings/strncasecmp.c b/lib/libc/strings/strncasecmp.c index 0c46d27f..a36990cf 100644 --- a/lib/libc/strings/strncasecmp.c +++ b/lib/libc/strings/strncasecmp.c @@ -1,9 +1,8 @@ -#include "features.h" // for __weak - #include // for tolower #include // for __unused #include // for locale_t #include // for size_t +#include int strncasecmp(const char *s1, const char *s2, size_t n) { @@ -24,12 +23,10 @@ int strncasecmp(const char *s1, const char *s2, size_t n) if (n == (size_t)-1) return 0; - return (unsigned char)tolower((unsigned char)*s1) - - (unsigned char)tolower((unsigned char)*s2); + return (unsigned char)tolower((unsigned char)*s1) - (unsigned char)tolower((unsigned char)*s2); } -__weak int strncasecmp_l(const char *s1, const char *s2, size_t n, - locale_t __unused locale) +__weak int strncasecmp_l(const char *s1, const char *s2, size_t n, locale_t __unused locale) { return strncasecmp(s1, s2, n); } diff --git a/lib/libc/sys/Kbuild b/lib/libc/sys/Kbuild index fe9d0bfc..7e371981 100644 --- a/lib/libc/sys/Kbuild +++ b/lib/libc/sys/Kbuild @@ -1,6 +1,7 @@ +obj-y += eventfd.o obj-y += eventfd_read.o obj-y += eventfd_write.o -obj-y += eventfd.o +obj-y += getauxval.o obj-y += io_uring_enter.o obj-y += io_uring_register.o obj-y += io_uring_setup.o diff --git a/lib/libc/sys/getauxval.c b/lib/libc/sys/getauxval.c new file mode 100644 index 00000000..155d4258 --- /dev/null +++ b/lib/libc/sys/getauxval.c @@ -0,0 +1,16 @@ +#include +#include + +unsigned long getauxval(unsigned long type) +{ + size_t *auxv = __libc.auxv; + + while (*auxv) { + if (*auxv == type) + return auxv[1]; + auxv += 2; + } + + errno = ENOENT; + return 0; +} diff --git a/lib/libc/time/clock_gettime.c b/lib/libc/time/clock_gettime.c new file mode 100644 index 00000000..31e91d01 --- /dev/null +++ b/lib/libc/time/clock_gettime.c @@ -0,0 +1,13 @@ +#include +#include +#include + +int clock_gettime(clockid_t clock_id, struct timespec *tp) +{ +#if defined(__VDSO_CLOCK_GETTIME) + if (__vdso_clock_gettime) + return __vdso_clock_gettime(clock_id, tp); +#endif + + return syscall(clock_gettime, clock_id, tp); +} diff --git a/lib/libc/time/strftime.c b/lib/libc/time/strftime.c index e1078dd8..b1763380 100644 --- a/lib/libc/time/strftime.c +++ b/lib/libc/time/strftime.c @@ -1,11 +1,9 @@ -#include "features.h" // for __weak - #include // for __unused #include // for strlcpy, strlen -#include // for tm, size_t, locale_t, strftime, strftime_l +#include +#include // for tm, size_t, locale_t, strftime, strftime_l -static size_t append_string(char *restrict *s, size_t *remaining, - const char *str) +static size_t append_string(char *restrict *s, size_t *remaining, const char *str) { size_t len = strlen(str); if (len >= *remaining) { @@ -28,8 +26,7 @@ static size_t append_char(char *restrict *s, size_t *remaining, char c) return 1; } -static size_t format_int(char *restrict *s, size_t *remaining, int value, - int width, char pad, int show_sign) +static size_t format_int(char *restrict *s, size_t *remaining, int value, int width, char pad, int show_sign) { char buffer[32]; char *ptr = buffer + sizeof(buffer) - 1; @@ -65,27 +62,19 @@ static size_t format_int(char *restrict *s, size_t *remaining, int value, return append_string(s, remaining, ptr); } -static const char *weekday_abbr[] = { "Sun", "Mon", "Tue", "Wed", - "Thu", "Fri", "Sat" }; -static const char *weekday_full[] = { "Sunday", "Monday", "Tuesday", - "Wednesday", "Thursday", "Friday", - "Saturday" }; +static const char *weekday_abbr[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; +static const char *weekday_full[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; -static const char *month_abbr[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; -static const char *month_full[] = { "January", "February", "March", - "April", "May", "June", - "July", "August", "September", - "October", "November", "December" }; +static const char *month_abbr[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; +static const char *month_full[] = { "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" }; static int iso_week_number(const struct tm *tm, int *week_year) { int year = tm->tm_year + 1900; int yday = tm->tm_yday + 1; - int jan4_wday = (4 + year + (year - 1) / 4 - (year - 1) / 100 + - (year - 1) / 400) % - 7; + int jan4_wday = (4 + year + (year - 1) / 4 - (year - 1) / 100 + (year - 1) / 400) % 7; if (jan4_wday == 0) jan4_wday = 7; @@ -101,8 +90,7 @@ static int iso_week_number(const struct tm *tm, int *week_year) prev_jan4_wday = 7; int prev_week1_start = 4 - prev_jan4_wday + 1; int prev_year_days = 365; - if (((year - 1) % 4 == 0 && (year - 1) % 100 != 0) || - ((year - 1) % 400 == 0)) { + if (((year - 1) % 4 == 0 && (year - 1) % 100 != 0) || ((year - 1) % 400 == 0)) { prev_year_days = 366; } week = (prev_year_days - prev_week1_start + 8) / 7; @@ -124,8 +112,7 @@ static int iso_week_number(const struct tm *tm, int *week_year) return week; } -size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, - const struct tm *restrict timeptr) +size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, const struct tm *restrict timeptr) { if (maxsize == 0) return 0; @@ -172,91 +159,73 @@ size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, switch (*ptr) { case 'a': - if (!append_string(&s, &remaining, - weekday_abbr[timeptr->tm_wday])) { + if (!append_string(&s, &remaining, weekday_abbr[timeptr->tm_wday])) { *orig_s = '\0'; return 0; } break; case 'A': - if (!append_string(&s, &remaining, - weekday_full[timeptr->tm_wday])) { + if (!append_string(&s, &remaining, weekday_full[timeptr->tm_wday])) { *orig_s = '\0'; return 0; } break; case 'b': case 'h': - if (!append_string(&s, &remaining, - month_abbr[timeptr->tm_mon])) { + if (!append_string(&s, &remaining, month_abbr[timeptr->tm_mon])) { *orig_s = '\0'; return 0; } break; case 'B': - if (!append_string(&s, &remaining, - month_full[timeptr->tm_mon])) { + if (!append_string(&s, &remaining, month_full[timeptr->tm_mon])) { *orig_s = '\0'; return 0; } break; case 'c': - if (!append_string(&s, &remaining, - weekday_abbr[timeptr->tm_wday]) || + if (!append_string(&s, &remaining, weekday_abbr[timeptr->tm_wday]) || !append_char(&s, &remaining, ' ') || - !append_string(&s, &remaining, - month_abbr[timeptr->tm_mon]) || + !append_string(&s, &remaining, month_abbr[timeptr->tm_mon]) || !append_char(&s, &remaining, ' ') || - !format_int(&s, &remaining, timeptr->tm_mday, 2, - ' ', 0) || + !format_int(&s, &remaining, timeptr->tm_mday, 2, ' ', 0) || !append_char(&s, &remaining, ' ') || - !format_int(&s, &remaining, timeptr->tm_hour, 2, - '0', 0) || + !format_int(&s, &remaining, timeptr->tm_hour, 2, '0', 0) || !append_char(&s, &remaining, ':') || - !format_int(&s, &remaining, timeptr->tm_min, 2, '0', - 0) || + !format_int(&s, &remaining, timeptr->tm_min, 2, '0', 0) || !append_char(&s, &remaining, ':') || - !format_int(&s, &remaining, timeptr->tm_sec, 2, '0', - 0) || + !format_int(&s, &remaining, timeptr->tm_sec, 2, '0', 0) || !append_char(&s, &remaining, ' ') || - !format_int(&s, &remaining, timeptr->tm_year + 1900, - 4, '0', 0)) { + !format_int(&s, &remaining, timeptr->tm_year + 1900, 4, '0', 0)) { *orig_s = '\0'; return 0; } break; case 'C': - if (!format_int(&s, &remaining, - (timeptr->tm_year + 1900) / 100, - min_width ? min_width : 2, pad_char, - show_sign)) { + if (!format_int(&s, &remaining, (timeptr->tm_year + 1900) / 100, min_width ? min_width : 2, + pad_char, show_sign)) { *orig_s = '\0'; return 0; } break; case 'd': - if (!format_int(&s, &remaining, timeptr->tm_mday, 2, - '0', 0)) { + if (!format_int(&s, &remaining, timeptr->tm_mday, 2, '0', 0)) { *orig_s = '\0'; return 0; } break; case 'D': - if (!format_int(&s, &remaining, timeptr->tm_mon + 1, 2, - '0', 0) || + if (!format_int(&s, &remaining, timeptr->tm_mon + 1, 2, '0', 0) || !append_char(&s, &remaining, '/') || - !format_int(&s, &remaining, timeptr->tm_mday, 2, - '0', 0) || + !format_int(&s, &remaining, timeptr->tm_mday, 2, '0', 0) || !append_char(&s, &remaining, '/') || - !format_int(&s, &remaining, timeptr->tm_year % 100, - 2, '0', 0)) { + !format_int(&s, &remaining, timeptr->tm_year % 100, 2, '0', 0)) { *orig_s = '\0'; return 0; } break; case 'e': - if (!format_int(&s, &remaining, timeptr->tm_mday, 2, - ' ', 0)) { + if (!format_int(&s, &remaining, timeptr->tm_mday, 2, ' ', 0)) { *orig_s = '\0'; return 0; } @@ -265,14 +234,11 @@ size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, int width = min_width ? min_width - 6 : 4; if (width < 4) width = 4; - if (!format_int(&s, &remaining, timeptr->tm_year + 1900, - width, pad_char, show_sign) || + if (!format_int(&s, &remaining, timeptr->tm_year + 1900, width, pad_char, show_sign) || !append_char(&s, &remaining, '-') || - !format_int(&s, &remaining, timeptr->tm_mon + 1, 2, - '0', 0) || + !format_int(&s, &remaining, timeptr->tm_mon + 1, 2, '0', 0) || !append_char(&s, &remaining, '-') || - !format_int(&s, &remaining, timeptr->tm_mday, 2, - '0', 0)) { + !format_int(&s, &remaining, timeptr->tm_mday, 2, '0', 0)) { *orig_s = '\0'; return 0; } @@ -280,8 +246,7 @@ size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, case 'g': { int week_year; iso_week_number(timeptr, &week_year); - if (!format_int(&s, &remaining, week_year % 100, 2, '0', - 0)) { + if (!format_int(&s, &remaining, week_year % 100, 2, '0', 0)) { *orig_s = '\0'; return 0; } @@ -289,16 +254,13 @@ size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, case 'G': { int week_year; iso_week_number(timeptr, &week_year); - if (!format_int(&s, &remaining, week_year, - min_width ? min_width : 4, pad_char, - show_sign)) { + if (!format_int(&s, &remaining, week_year, min_width ? min_width : 4, pad_char, show_sign)) { *orig_s = '\0'; return 0; } } break; case 'H': - if (!format_int(&s, &remaining, timeptr->tm_hour, 2, - '0', 0)) { + if (!format_int(&s, &remaining, timeptr->tm_hour, 2, '0', 0)) { *orig_s = '\0'; return 0; } @@ -313,22 +275,19 @@ size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, } } break; case 'j': - if (!format_int(&s, &remaining, timeptr->tm_yday + 1, 3, - '0', 0)) { + if (!format_int(&s, &remaining, timeptr->tm_yday + 1, 3, '0', 0)) { *orig_s = '\0'; return 0; } break; case 'm': - if (!format_int(&s, &remaining, timeptr->tm_mon + 1, 2, - '0', 0)) { + if (!format_int(&s, &remaining, timeptr->tm_mon + 1, 2, '0', 0)) { *orig_s = '\0'; return 0; } break; case 'M': - if (!format_int(&s, &remaining, timeptr->tm_min, 2, '0', - 0)) { + if (!format_int(&s, &remaining, timeptr->tm_min, 2, '0', 0)) { *orig_s = '\0'; return 0; } @@ -340,9 +299,7 @@ size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, } break; case 'p': - if (!append_string(&s, &remaining, - timeptr->tm_hour < 12 ? "AM" : - "PM")) { + if (!append_string(&s, &remaining, timeptr->tm_hour < 12 ? "AM" : "PM")) { *orig_s = '\0'; return 0; } @@ -351,27 +308,20 @@ size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, int hour12 = timeptr->tm_hour % 12; if (hour12 == 0) hour12 = 12; - if (!format_int(&s, &remaining, hour12, 2, '0', 0) || - !append_char(&s, &remaining, ':') || - !format_int(&s, &remaining, timeptr->tm_min, 2, '0', - 0) || + if (!format_int(&s, &remaining, hour12, 2, '0', 0) || !append_char(&s, &remaining, ':') || + !format_int(&s, &remaining, timeptr->tm_min, 2, '0', 0) || !append_char(&s, &remaining, ':') || - !format_int(&s, &remaining, timeptr->tm_sec, 2, '0', - 0) || + !format_int(&s, &remaining, timeptr->tm_sec, 2, '0', 0) || !append_char(&s, &remaining, ' ') || - !append_string(&s, &remaining, - timeptr->tm_hour < 12 ? "AM" : - "PM")) { + !append_string(&s, &remaining, timeptr->tm_hour < 12 ? "AM" : "PM")) { *orig_s = '\0'; return 0; } } break; case 'R': - if (!format_int(&s, &remaining, timeptr->tm_hour, 2, - '0', 0) || + if (!format_int(&s, &remaining, timeptr->tm_hour, 2, '0', 0) || !append_char(&s, &remaining, ':') || - !format_int(&s, &remaining, timeptr->tm_min, 2, '0', - 0)) { + !format_int(&s, &remaining, timeptr->tm_min, 2, '0', 0)) { *orig_s = '\0'; return 0; } @@ -384,8 +334,7 @@ size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, } break; case 'S': - if (!format_int(&s, &remaining, timeptr->tm_sec, 2, '0', - 0)) { + if (!format_int(&s, &remaining, timeptr->tm_sec, 2, '0', 0)) { *orig_s = '\0'; return 0; } @@ -397,14 +346,11 @@ size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, } break; case 'T': - if (!format_int(&s, &remaining, timeptr->tm_hour, 2, - '0', 0) || + if (!format_int(&s, &remaining, timeptr->tm_hour, 2, '0', 0) || !append_char(&s, &remaining, ':') || - !format_int(&s, &remaining, timeptr->tm_min, 2, '0', - 0) || + !format_int(&s, &remaining, timeptr->tm_min, 2, '0', 0) || !append_char(&s, &remaining, ':') || - !format_int(&s, &remaining, timeptr->tm_sec, 2, '0', - 0)) { + !format_int(&s, &remaining, timeptr->tm_sec, 2, '0', 0)) { *orig_s = '\0'; return 0; } @@ -419,8 +365,7 @@ size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, } } break; case 'U': { - int week = - (timeptr->tm_yday + 7 - timeptr->tm_wday) / 7; + int week = (timeptr->tm_yday + 7 - timeptr->tm_wday) / 7; if (!format_int(&s, &remaining, week, 2, '0', 0)) { *orig_s = '\0'; return 0; @@ -435,8 +380,7 @@ size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, } } break; case 'w': - if (!format_int(&s, &remaining, timeptr->tm_wday, 1, - '0', 0)) { + if (!format_int(&s, &remaining, timeptr->tm_wday, 1, '0', 0)) { *orig_s = '\0'; return 0; } @@ -452,41 +396,33 @@ size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, } } break; case 'x': - if (!format_int(&s, &remaining, timeptr->tm_mon + 1, 2, - '0', 0) || + if (!format_int(&s, &remaining, timeptr->tm_mon + 1, 2, '0', 0) || !append_char(&s, &remaining, '/') || - !format_int(&s, &remaining, timeptr->tm_mday, 2, - '0', 0) || + !format_int(&s, &remaining, timeptr->tm_mday, 2, '0', 0) || !append_char(&s, &remaining, '/') || - !format_int(&s, &remaining, timeptr->tm_year % 100, - 2, '0', 0)) { + !format_int(&s, &remaining, timeptr->tm_year % 100, 2, '0', 0)) { *orig_s = '\0'; return 0; } break; case 'X': - if (!format_int(&s, &remaining, timeptr->tm_hour, 2, - '0', 0) || + if (!format_int(&s, &remaining, timeptr->tm_hour, 2, '0', 0) || !append_char(&s, &remaining, ':') || - !format_int(&s, &remaining, timeptr->tm_min, 2, '0', - 0) || + !format_int(&s, &remaining, timeptr->tm_min, 2, '0', 0) || !append_char(&s, &remaining, ':') || - !format_int(&s, &remaining, timeptr->tm_sec, 2, '0', - 0)) { + !format_int(&s, &remaining, timeptr->tm_sec, 2, '0', 0)) { *orig_s = '\0'; return 0; } break; case 'y': - if (!format_int(&s, &remaining, timeptr->tm_year % 100, - 2, '0', 0)) { + if (!format_int(&s, &remaining, timeptr->tm_year % 100, 2, '0', 0)) { *orig_s = '\0'; return 0; } break; case 'Y': - if (!format_int(&s, &remaining, timeptr->tm_year + 1900, - min_width ? min_width : 4, pad_char, + if (!format_int(&s, &remaining, timeptr->tm_year + 1900, min_width ? min_width : 4, pad_char, show_sign)) { *orig_s = '\0'; return 0; @@ -504,8 +440,7 @@ size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, } int hours = (int)(offset / 3600); int minutes = (int)((offset % 3600) / 60); - if (!append_char(&s, &remaining, sign) || - !format_int(&s, &remaining, hours, 2, '0', 0) || + if (!append_char(&s, &remaining, sign) || !format_int(&s, &remaining, hours, 2, '0', 0) || !format_int(&s, &remaining, minutes, 2, '0', 0)) { *orig_s = '\0'; return 0; @@ -513,8 +448,7 @@ size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, } break; case 'Z': if (timeptr->tm_zone) { - if (!append_string(&s, &remaining, - timeptr->tm_zone)) { + if (!append_string(&s, &remaining, timeptr->tm_zone)) { *orig_s = '\0'; return 0; } @@ -528,8 +462,7 @@ size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, break; default: - if (!append_char(&s, &remaining, '%') || - !append_char(&s, &remaining, *ptr)) { + if (!append_char(&s, &remaining, '%') || !append_char(&s, &remaining, *ptr)) { *orig_s = '\0'; return 0; } @@ -542,10 +475,8 @@ size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, return s - orig_s; } -__weak size_t strftime_l(char *restrict s, size_t maxsize, - const char *restrict format, - const struct tm *restrict timeptr, - locale_t __unused locale) +__weak size_t strftime_l(char *restrict s, size_t maxsize, const char *restrict format, + const struct tm *restrict timeptr, locale_t __unused locale) { return strftime(s, maxsize, format, timeptr); } diff --git a/lib/libc/time/time.c b/lib/libc/time/time.c index 3f8848a8..b5f0e449 100644 --- a/lib/libc/time/time.c +++ b/lib/libc/time/time.c @@ -1,11 +1,11 @@ -#include // for __vdso_time -#include // for timespec, clock_gettime, time_t, CLOCK_REALTIME +#include +#include time_t time(time_t *tloc) { struct timespec ts; -#if defined(__x86_64__) +#if defined(__VDSO_TIME) if (__vdso_time) return __vdso_time(tloc); #endif diff --git a/lib/libc/unistd/posix_close.c b/lib/libc/unistd/posix_close.c index 189f7db9..6c42f044 100644 --- a/lib/libc/unistd/posix_close.c +++ b/lib/libc/unistd/posix_close.c @@ -1,7 +1,5 @@ - - -#include // for __unused -#include // for __syscall_1, syscall +#include +#include int posix_close(int fildes, int __unused flag) { -- cgit v1.2.3