From c8df2f9d420eecaa376649e8b62096585ab3edfe Mon Sep 17 00:00:00 2001 From: flysand7 Date: Sun, 23 Jul 2023 03:28:16 +1100 Subject: [PATCH] Retrieve envp, call main --- include/cia_definitions.h | 3 ++- src/linux/crt_entry.asm | 19 ++++++++++++++----- src/linux/entry.c | 13 +++++++++---- test.sh | 2 +- tests/empty.c | 20 +++++++++++++++++++- 5 files changed, 45 insertions(+), 12 deletions(-) diff --git a/include/cia_definitions.h b/include/cia_definitions.h index 48fc08c..64fe76a 100644 --- a/include/cia_definitions.h +++ b/include/cia_definitions.h @@ -1,8 +1,9 @@ #pragma once -// Pre-C23 keyword macros +// Pre-C23 keyword macros and stddef #define static_assert _Static_assert +#define NULL ((void *)0) // Platform macros #define CIA_LINUX 1 diff --git a/src/linux/crt_entry.asm b/src/linux/crt_entry.asm index 9e37153..cf24e6b 100644 --- a/src/linux/crt_entry.asm +++ b/src/linux/crt_entry.asm @@ -22,17 +22,26 @@ _start: mov r9, rdx ;; Get argc and argv from the stack pop rsi - mov rdx, qword [rsp] + mov rdx, rsp ;; Align stack to 16, push junk and stack ptr and rsp, ~0xf push rax push rsp - ;; Push fini and init sections - mov rcx, __libc_global_init wrt ..got - mov r8, __libc_global_fini wrt ..got + ;; Load fini and init initializers as function parameters + %ifdef CIA_SHARED + mov rcx, __libc_global_init wrt ..got + mov r8, __libc_global_fini wrt ..got + %else + mov rcx, __libc_global_init + mov r8, __libc_global_fini + %endif mov rdi, main ;; Call start main - call __libc_start_main wrt ..plt + %ifdef CIA_SHARED + call __libc_start_main wrt ..plt + %else + call __libc_start_main + %endif ;; No idea why halt it, I guess that's a funny ;; way to crash your application if the function we called ;; returns instead of calling the exit syscall diff --git a/src/linux/entry.c b/src/linux/entry.c index d900c06..27040d4 100644 --- a/src/linux/entry.c +++ b/src/linux/entry.c @@ -1,6 +1,6 @@ -int __stack_chk_fial() { +int __stack_chk_fail() { // TODO: implement proper stack protector support return 0; } @@ -10,10 +10,15 @@ void __libc_start_main( int argc, char **argv, int (*init)(int, char**, char**), void (*fini)(void), - void (*rtld_fini)(void), + void (*runtime_ld_fini)(void), void *stack_end ) { - static char string[] = "Hello, world!\n"; - syscall_write(STDOUT_FILENO, string, sizeof string); + char **envp = argv + (argc + 1); + init(argc, argv, envp); + main(argc, argv, envp); + fini(); + if(runtime_ld_fini != NULL) { + runtime_ld_fini(); + } syscall_exit(0); } diff --git a/test.sh b/test.sh index 78865b9..44faf72 100755 --- a/test.sh +++ b/test.sh @@ -3,6 +3,6 @@ if [ "$1" != "-shared" ]; then clang -static -nostdlib tests/empty.c lib/ciabatta.a -Iinclude else - clang -fPIE tests/empty.c -c -o tests/empty.o + clang -g -fno-stack-protector -fPIE tests/empty.c -c -o tests/empty.o ld -no-pie -nostdlib lib/entry.o tests/empty.o lib/ciabatta.so lib/ctors.o -Iinclude fi \ No newline at end of file diff --git a/tests/empty.c b/tests/empty.c index 2b8c6ac..9fe76e4 100644 --- a/tests/empty.c +++ b/tests/empty.c @@ -1,4 +1,22 @@ -int main() { +#include + +#define STDOUT_FILENO 1 +#define SYS_write 1 + +static __inline i64 __syscall3(i64 n, i64 a1, i64 a2, i64 a3) { + i64 ret; + __asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2), + "d"(a3) : "rcx", "r11", "memory"); + return ret; +} + +static inline i64 syscall_write(u32 fd, char const *buf, u64 count) { + return __syscall3(SYS_write, (i64)fd, (i64)buf, (u64)count); +} + +char string[] = "Hello, world!\n"; +int main(int argc, char **argv, char **envp) { + syscall_write(STDOUT_FILENO, string, sizeof string); return 0; }