diff --git a/src/libraries/j6/include/j6/init.h b/src/libraries/j6/include/j6/init.h index 12803dd..0839372 100644 --- a/src/libraries/j6/include/j6/init.h +++ b/src/libraries/j6/include/j6/init.h @@ -43,7 +43,6 @@ struct j6_arg_loader uintptr_t *got; uintptr_t entrypoint; uintptr_t start_addr; - uintptr_t other; }; struct j6_arg_driver diff --git a/src/user/ld.so/start.s b/src/user/ld.so/start.s index 73fdbd5..f0a248c 100644 --- a/src/user/ld.so/start.s +++ b/src/user/ld.so/start.s @@ -17,10 +17,12 @@ _ldso_start: ; Call ldso_init with the loader-provided stack data and ; also the address of the GOT, since clang refuses to take ; the address of it, only dereference it. - mov rdi, rbp + mov rdi, [rbp] lea rsi, [rel _GLOBAL_OFFSET_TABLE_] call ldso_init - ; The real program's entrypoint is now in rax + + ; The real program's entrypoint is now in rax, save it to r11 + mov r11, rax ; Put the function call params back pop r9 @@ -30,7 +32,19 @@ _ldso_start: pop rsi pop rdi - jmp rax + ; Pop all the loader args + pop rsp ; Point the stack at the first arg + mov rax, 0 + mov rbx, 0 +.poploop: + mov eax, [dword rsp] ; size + mov ebx, [dword rsp+4] ; type + add rsp, rax + cmp ebx, 0 + jne .poploop + + mov rbp, rsp + jmp r11 .end: diff --git a/src/user/srv.init/loader.cpp b/src/user/srv.init/loader.cpp index 5d353dc..be56e8f 100644 --- a/src/user/srv.init/loader.cpp +++ b/src/user/srv.init/loader.cpp @@ -49,7 +49,7 @@ stack_push_sentinel(uint8_t *&stack) memset(stack, 0, size); j6_arg_header *header = reinterpret_cast(stack); header->type = j6_arg_type_none; - header->size = 0; + header->size = size; } template T * @@ -222,6 +222,7 @@ load_program( uintptr_t entrypoint = program_elf.entrypoint() + program_image_base; if (dyn) { + stack_push_sentinel(stack); j6_arg_loader *loader_arg = stack_push(stack, 0); const elf::file_header *h = program_elf.header(); loader_arg->image_base = program_image_base; @@ -240,6 +241,15 @@ load_program( handles_arg->handles[1].handle = vfs; handles_arg->handles[1].proto = j6::proto::vfs::id; + // Align the stack to be one word short of 16-byte aligned, so + // that the arg address will be aligned when pushed + while ((reinterpret_cast(stack) & 0xf) != 0x8) --stack; + + // Push the args list address itself + stack -= sizeof(uintptr_t); + uintptr_t *args_addr = reinterpret_cast(stack); + *args_addr = stack_top - (stack_orig - reinterpret_cast(handles_arg)); + uintptr_t ldso_image_base = (eop & ~(MiB-1)) + MiB; for (auto seg : program_elf.segments()) {