From 0e832a9329cc4d4647e1ce529846073f21e66991 Mon Sep 17 00:00:00 2001 From: Kacper Date: Tue, 16 Dec 2025 12:55:34 +0100 Subject: Fix several segv issues and improve x86_64 startup code --- lib/libc/internal/Kbuild | 1 - lib/libc/internal/init/Kbuild | 1 + lib/libc/internal/init/init.c | 40 ++++++++++++++++++++++++++++++++++++++++ lib/libc/internal/init/vdso.c | 5 +++++ lib/libc/internal/libc_main.c | 40 ---------------------------------------- 5 files changed, 46 insertions(+), 41 deletions(-) create mode 100644 lib/libc/internal/init/init.c delete mode 100644 lib/libc/internal/libc_main.c (limited to 'lib/libc/internal') diff --git a/lib/libc/internal/Kbuild b/lib/libc/internal/Kbuild index 5015f987..01daa04b 100644 --- a/lib/libc/internal/Kbuild +++ b/lib/libc/internal/Kbuild @@ -1,2 +1 @@ obj-y += init/ -obj-y += libc_main.o diff --git a/lib/libc/internal/init/Kbuild b/lib/libc/internal/init/Kbuild index dd27261a..7941a53c 100644 --- a/lib/libc/internal/init/Kbuild +++ b/lib/libc/internal/init/Kbuild @@ -1 +1,2 @@ +obj-y += init.o obj-y += vdso.o diff --git a/lib/libc/internal/init/init.c b/lib/libc/internal/init/init.c new file mode 100644 index 00000000..36e66ee4 --- /dev/null +++ b/lib/libc/internal/init/init.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include +#include + +extern void __init_vdso(void); + +struct libc __libc = { 0 }; +char **environ; +char *__progname; + +extern int main(int, char **, char **); + +__used void __init(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/internal/init/vdso.c b/lib/libc/internal/init/vdso.c index f94401f6..de8d0e2f 100644 --- a/lib/libc/internal/init/vdso.c +++ b/lib/libc/internal/init/vdso.c @@ -6,6 +6,11 @@ void __init_vdso(void) { Elf64_Ehdr *ehdr = (Elf64_Ehdr *)getauxval(AT_SYSINFO_EHDR); + + if (ehdr == NULL) { + return; + } + Elf64_Phdr *phdr = (Elf64_Phdr *)(ehdr + ehdr->e_phoff); for (int i = 0; i < ehdr->e_phnum; i++) { diff --git a/lib/libc/internal/libc_main.c b/lib/libc/internal/libc_main.c deleted file mode 100644 index 7ac15ab4..00000000 --- a/lib/libc/internal/libc_main.c +++ /dev/null @@ -1,40 +0,0 @@ -#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)); -} -- cgit v1.2.3