summaryrefslogtreecommitdiff
path: root/lib/libc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/Kbuild2
-rw-r--r--lib/libc/arch/x86_64/Kbuild4
-rw-r--r--lib/libc/arch/x86_64/_start.c8
-rw-r--r--lib/libc/arch/x86_64/clock_gettime.c15
-rw-r--r--lib/libc/arch/x86_64/crt0.c63
-rw-r--r--lib/libc/arch/x86_64/vdso_setup.c64
-rw-r--r--lib/libc/ctype/isalnum.c7
-rw-r--r--lib/libc/devctl/posix_devctl.c18
-rw-r--r--lib/libc/errno/errno.c9
-rw-r--r--lib/libc/include/__thread.h2
-rw-r--r--lib/libc/include/features.h6
-rw-r--r--lib/libc/include/internal/io_uring.h6
-rw-r--r--lib/libc/include/libc.h17
-rw-r--r--lib/libc/internal/Kbuild2
-rw-r--r--lib/libc/internal/init/Kbuild1
-rw-r--r--lib/libc/internal/init/vdso.c56
-rw-r--r--lib/libc/internal/libc_main.c40
-rw-r--r--lib/libc/signal/pthread_sigmask.c17
-rw-r--r--lib/libc/stdio/fdopen.c14
-rw-r--r--lib/libc/stdio/fmemopen.c7
-rw-r--r--lib/libc/stdio/fopen.c16
-rw-r--r--lib/libc/stdio/stdin.c8
-rw-r--r--lib/libc/stdio/stdout.c5
-rw-r--r--lib/libc/stdlib/abort.c5
-rw-r--r--lib/libc/stdlib/free.c34
-rw-r--r--lib/libc/stdlib/getenv.c6
-rw-r--r--lib/libc/stdlib/malloc.c75
-rw-r--r--lib/libc/stdlib/realloc.c9
-rw-r--r--lib/libc/stdlib/setenv.c18
-rw-r--r--lib/libc/string/memcpy.c11
-rw-r--r--lib/libc/string/strcoll.c3
-rw-r--r--lib/libc/string/strerror.c7
-rw-r--r--lib/libc/string/strxfrm.c7
-rw-r--r--lib/libc/strings/strcasecmp.c9
-rw-r--r--lib/libc/strings/strncasecmp.c9
-rw-r--r--lib/libc/sys/Kbuild3
-rw-r--r--lib/libc/sys/getauxval.c16
-rw-r--r--lib/libc/time/clock_gettime.c13
-rw-r--r--lib/libc/time/strftime.c199
-rw-r--r--lib/libc/time/time.c6
-rw-r--r--lib/libc/unistd/posix_close.c6
41 files changed, 345 insertions, 478 deletions
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 <libc.h>
+#include <sys/cdefs.h>
+
+__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 <asm/vdso.h> // for __vdso_clock_gettime
-#include <syscall.h> // for __syscall_2, syscall
-#include <time.h> // 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 <io_uring.h>
-#include <linux/auxvec.h> // for AT_NULL
-#include <linux/elf.h> // for Elf64_Ehdr
-#include <stdint.h> // for uintptr_t
-#include <stdlib.h> // 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 <linux/elf.h> // for Elf64_Sym, (anonymous struct)::(anonymous)
-#include "stddef.h" // for NULL
-
-#include <string.h> // 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 <ctype.h> // for isalnum, isalpha, isdigit, isalnum_l
-#include <libc.h> // for __unused
-#include <locale.h> // for locale_t
+#include <ctype.h>
+#include <sys/cdefs.h>
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 <devctl.h>
+#include <sys/cdefs.h>
+#include <syscall.h>
-
-#include <devctl.h> // for posix_devctl, size_t
-#include <errno.h> // for errno
-#include <libc.h> // for __unused
-#include <stddef.h>
-#include <syscall.h> // 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 <threads.h>
+
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 <stddef.h>
#include <stdatomic.h>
-#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 <asm/vdso.h>
+#include <elf.h>
+#include <string.h>
+#include <sys/auxv.h>
+
+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 <libc.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/cdefs.h>
+
+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 <asm-generic/signal.h> // for SIGRTMIN
-
+#include <asm-generic/signal.h>
#undef __ASSEMBLY__
-#include <errno.h> // for errno
-#include <libc.h> // for unlikely
-#include <stddef.h> // for NULL
+#include <errno.h>
+#include <libc.h>
+#include <stddef.h>
+#include <sys/cdefs.h>
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 <stdio.h> // for FILE, _IONBF, SEEK_END, _IOLBF, fdopen
-#include <stdlib.h> // for calloc, free
+#include "__stdio.h" // for __FILE, __libc_fadd
+#include <stdio.h> // for FILE, _IONBF, SEEK_END, _IOLBF, fdopen
+#include <stdlib.h> // for calloc, free
+#include <sys/cdefs.h>
#include <unistd.h> // 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 <errno.h> // for EINVAL, errno
#include <fcntl.h> // for O_WRONLY, O_CREAT, O_RDONLY, O_APPEND, O_RDWR
@@ -8,6 +7,8 @@
#include <stdlib.h> // for calloc, free
#include <string.h> // for strchr
+#include <sys/cdefs.h>
+
__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 <errno.h> // for EINVAL, errno
#include <fcntl.h> // for O_WRONLY, O_CREAT, O_RDONLY, open, O_APPEND
#include <stdio.h> // for FILE, BUFSIZ, fopen, _IOLBF
#include <stdlib.h> // for calloc, free, malloc
#include <string.h> // for strchr
+#include <sys/cdefs.h>
#include <unistd.h> // 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 <fcntl.h> // for O_RDONLY
-#include <stdio.h> // for FILE, stdin
+#include <fcntl.h> // for O_RDONLY
+#include <stdio.h> // for FILE, stdin
+#include <sys/cdefs.h>
#include <unistd.h> // 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 <atomic.h> // for LIBC_LOCK, LIBC_UNLOCK
#include <fcntl.h> // for O_WRONLY
#include <stddef.h> // for NULL
#include <stdio.h> // for stdout
+#include <sys/cdefs.h>
#include <unistd.h> // 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 <atomic.h> // for LIBC_UNLOCK, LIBC_LOCK
-#include <features.h> // for __weak
#include <libc.h> // for libc, libc::(anonymous)
#include <malloc.h> // for page, page::(anonymous), class, global_size_c...
#include <stdatomic.h> // for atomic_flag_clear
#include <stdint.h> // for uint32_t, uint8_t, uintptr_t
#include <stdlib.h> // for malloc
#include <string.h> // for memset
-#include <sys/mman.h> // for size_t, mmap, munmap, MAP_ANONYMOUS, MAP_FAILED
+#include <sys/cdefs.h>
+#include <sys/mman.h> // 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 <errno.h> // for EINVAL, ERANGE
-#include <features.h> // for __weak
-#include <stddef.h> // for NULL, errno_t
-#include <string.h> // for rsize_t, memcpy, size_t, memcpy_s
+#include <errno.h> // for EINVAL, ERANGE
+#include <stddef.h> // for NULL, errno_t
+#include <string.h> // for rsize_t, memcpy, size_t, memcpy_s
+#include <sys/cdefs.h>
__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 <libc.h> // for __unused
#include <string.h> // for strcmp, locale_t, strcoll, strcoll_l
+#include <sys/cdefs.h>
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 <errno.h> // for ERANGE, E2BIG, EACCES, EADDRINUSE, EADDRNOTAVAIL
#include <libc.h> // for __unused
#include <string.h> // for memcpy, size_t, strerror, strlen, locale_t
+#include <sys/cdefs.h>
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 <libc.h> // for __unused
#include <string.h> // for size_t, strlcpy, strlen, strxfrm, locale_t
+#include <sys/cdefs.h>
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 <ctype.h> // for tolower
#include <libc.h> // for __unused
#include <locale.h> // for locale_t
+#include <sys/cdefs.h>
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 <ctype.h> // for tolower
#include <libc.h> // for __unused
#include <locale.h> // for locale_t
#include <stddef.h> // for size_t
+#include <sys/cdefs.h>
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 <errno.h>
+#include <libc.h>
+
+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 <asm/vdso.h>
+#include <syscall.h>
+#include <time.h>
+
+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 <libc.h> // for __unused
#include <string.h> // for strlcpy, strlen
-#include <time.h> // for tm, size_t, locale_t, strftime, strftime_l
+#include <sys/cdefs.h>
+#include <time.h> // 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 <asm/vdso.h> // for __vdso_time
-#include <time.h> // for timespec, clock_gettime, time_t, CLOCK_REALTIME
+#include <asm/vdso.h>
+#include <time.h>
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 <libc.h> // for __unused
-#include <syscall.h> // for __syscall_1, syscall
+#include <sys/cdefs.h>
+#include <syscall.h>
int posix_close(int fildes, int __unused flag)
{