[ld.so] Properly handle stack alignment in ld.so args
Now when loading a process, init will push all the loader args, align the stack so that the next pointer will have correct alignment, then push a pointer to the loader args. Also: * _ldso_start will pop all loader args off of the stack before jumping to the loaded program's entrypoint, as if it had never run. * The sentinel arg structures have a size instead of being all zeros, so that they can be popped off properly when done.
This commit is contained in:
@@ -49,7 +49,7 @@ stack_push_sentinel(uint8_t *&stack)
|
||||
memset(stack, 0, size);
|
||||
j6_arg_header *header = reinterpret_cast<j6_arg_header*>(stack);
|
||||
header->type = j6_arg_type_none;
|
||||
header->size = 0;
|
||||
header->size = size;
|
||||
}
|
||||
|
||||
template <typename T> 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<j6_arg_loader>(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<uintptr_t>(stack) & 0xf) != 0x8) --stack;
|
||||
|
||||
// Push the args list address itself
|
||||
stack -= sizeof(uintptr_t);
|
||||
uintptr_t *args_addr = reinterpret_cast<uintptr_t*>(stack);
|
||||
*args_addr = stack_top - (stack_orig - reinterpret_cast<uint8_t*>(handles_arg));
|
||||
|
||||
uintptr_t ldso_image_base = (eop & ~(MiB-1)) + MiB;
|
||||
|
||||
for (auto seg : program_elf.segments()) {
|
||||
|
||||
Reference in New Issue
Block a user