summaryrefslogtreecommitdiff
path: root/lib/libc/arch/x86_64
diff options
context:
space:
mode:
authorKacper <kacper@mail.openlinux.dev>2025-12-15 18:24:54 +0100
committerKacper <kacper@mail.openlinux.dev>2025-12-15 18:24:54 +0100
commit69e6fe89fa9baafeca3e3515bb50897cd8ee7c35 (patch)
tree489046ce167b8b20d205f87f4ae1f4b680c19b43 /lib/libc/arch/x86_64
parent0d5bffe9d2caadc1215c875e560c52bca5161c54 (diff)
Add getauxval and cleanup libc startup
Diffstat (limited to 'lib/libc/arch/x86_64')
-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
5 files changed, 9 insertions, 145 deletions
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));
- }
- }
- }
-}