diff --git a/sys/cpu/x86_64/include/elf.h b/sys/cpu/x86_64/include/elf.h index 6ee31d2..2d42dfa 100644 --- a/sys/cpu/x86_64/include/elf.h +++ b/sys/cpu/x86_64/include/elf.h @@ -155,11 +155,6 @@ __ElfType(Auxinfo); #define ELF_TARG_MACH EM_X86_64 #define ELF_TARG_VER 1 - /* - * x86_64 load base for PIE binaries - */ -#define ET_DYN_LOAD_ADDR 0x01021000 - #ifdef _KERNEL /* * On the i386 we load the dynamic linker where a userland call diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index b0e0460..6bb0003 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -610,7 +610,7 @@ __CONCAT(exec_,__elfN(imgact))(struct image_params *imgp) u_long text_size = 0, data_size = 0, total_size = 0; u_long text_addr = 0, data_addr = 0; u_long seg_size, seg_addr; - u_long addr, baddr, et_dyn_addr, entry = 0, proghdr = 0; + u_long addr, baddr, et_dyn_addr = 0, entry = 0, proghdr = 0; int32_t osrel = 0; int error = 0, i, n; boolean_t failure; @@ -689,16 +689,16 @@ __CONCAT(exec_,__elfN(imgact))(struct image_params *imgp) kfree(interp, M_TEMP); return (ENOEXEC); } - /* - * Honour the base load address from the dso if it is - * non-zero for some reason. - */ - if (baddr == 0) - et_dyn_addr = ET_DYN_LOAD_ADDR; - else - et_dyn_addr = 0; - } else - et_dyn_addr = 0; + if (baddr == 0) { + /* + * If p_vaddr field of PT_LOAD program header is zero and type of an executale + * is ET_DYN, then it must be a position independent executable (PIE). + * In this case the system needs to pick a base address for us. + * Set et_dyn_addr to non-zero and choose the actual address when we are ready. + */ + et_dyn_addr = 1; + } + } if (interp != NULL && brand_info->interp_newpath != NULL) newinterp = brand_info->interp_newpath; @@ -715,6 +715,10 @@ __CONCAT(exec_,__elfN(imgact))(struct image_params *imgp) vmspace = imgp->proc->p_vmspace; + /* Choose the base address for dynamic executables if we need to. */ + if (et_dyn_addr) + et_dyn_addr = vm_map_hint(imgp->proc, 0, VM_PROT_READ | VM_PROT_EXECUTE); + for (i = 0; i < hdr->e_phnum; i++) { switch (phdr[i].p_type) { case PT_LOAD: /* Loadable segment */