diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2020-10-07 22:40:10 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2020-10-07 22:40:10 +0200 |
commit | ea6526c444028ad8293593476f31f88c7e693745 (patch) | |
tree | d90c54572410b9902207de9e61101611d86ba689 /kern | |
parent | e8f87dc5ac86ed6c42119cf40f8fc30171bb7248 (diff) | |
download | gnumach-ea6526c444028ad8293593476f31f88c7e693745.tar.gz gnumach-ea6526c444028ad8293593476f31f88c7e693745.tar.bz2 gnumach-ea6526c444028ad8293593476f31f88c7e693745.zip |
elf-load: Avoid loading PIE binaries at address 0
It seems that ld.so sometimes gets into troubles and hangs at bootstrap.
* kern/elf-load.c (exec_load): When x.e_type == ET_DYN || x.e_type ==
ET_REL, add 128MiB as loadbase.
Diffstat (limited to 'kern')
-rw-r--r-- | kern/elf-load.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/kern/elf-load.c b/kern/elf-load.c index 441276ef..3e80edfe 100644 --- a/kern/elf-load.c +++ b/kern/elf-load.c @@ -36,6 +36,7 @@ int exec_load(exec_read_func_t *read, exec_read_exec_func_t *read_exec, vm_size_t phsize; int i; int result; + vm_offset_t loadbase = 0; /* Read the ELF header. */ if ((result = (*read)(handle, 0, &x, sizeof(x), &actual)) != 0) @@ -55,8 +56,13 @@ int exec_load(exec_read_func_t *read, exec_read_exec_func_t *read_exec, (x.e_machine != MY_E_MACHINE)) return EX_WRONG_ARCH; + /* Leave room for mmaps etc. before PIE binaries. + * Could add address randomization here. */ + if (x.e_type == ET_DYN || x.e_type == ET_REL) + loadbase = 128 << 20; + /* XXX others */ - out_info->entry = (vm_offset_t) x.e_entry; + out_info->entry = (vm_offset_t) x.e_entry + loadbase; phsize = x.e_phnum * x.e_phentsize; phdr = (Elf32_Phdr *)alloca(phsize); @@ -77,9 +83,10 @@ int exec_load(exec_read_func_t *read, exec_read_exec_func_t *read_exec, if (ph->p_flags & PF_R) type |= EXEC_SECTYPE_READ; if (ph->p_flags & PF_W) type |= EXEC_SECTYPE_WRITE; if (ph->p_flags & PF_X) type |= EXEC_SECTYPE_EXECUTE; + result = (*read_exec)(handle, ph->p_offset, ph->p_filesz, - ph->p_vaddr, ph->p_memsz, type); + ph->p_vaddr + loadbase, ph->p_memsz, type); if (result) return result; } |