On 9/19/26 19:20, Warner Losh wrote:
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 295dad4643..eaa8676f5a 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -561,12 +561,14 @@ load_elf_sections(const struct elfhdr *hdr, struct
elf_phdr *phdr, int fd,
elf_prot |= PROT_EXEC;
}
+ int flags = MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE;
+ if (rbase == 0) {
+ flags |= MAP_EXCL;
+ }
error = target_mmap(TARGET_ELF_PAGESTART(rbase + elf_ppnt->p_vaddr),
(elf_ppnt->p_filesz +
TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
- elf_prot,
- (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
- fd,
+ elf_prot, flags, fd,
This is wrong, or at least very not ideal.
What's missing no the freebsd side is a probe for the entire address
space for the guest program.
/*
* Reserve address space for all of this.
*
* In the case of ET_EXEC, we supply MAP_FIXED_NOREPLACE so that we get
* exactly the address range that is required. Without reserved_va,
* the guest address space is not isolated. We have attempted to avoid
* conflict with the host program itself via probe_guest_base, but using
* MAP_FIXED_NOREPLACE instead of MAP_FIXED provides an extra check.
*
* Otherwise this is ET_DYN, and we are searching for a location
* that can hold the memory space required. If the image is
* pre-linked, LOAD_ADDR will be non-zero, and the kernel should
* honor that address if it happens to be free.
*
* In both cases, we will overwrite pages in this range with mappings
* from the executable.
*/
reserve_size = range.hi - range.lo + 1;
align_size = reserve_size;
if (ehdr->e_type != ET_EXEC && align > qemu_real_host_page_size()) {
align_size += align - 1;
}
load_addr = target_mmap(load_addr, align_size, PROT_NONE,
MAP_PRIVATE | MAP_ANON | MAP_NORESERVE |
(ehdr->e_type == ET_EXEC ? MAP_FIXED_NOREPLACE : 0),
-1, 0);
which handles ET_DYN properly, which is missing from the freebsd side
entirely. Afterward, elf sections are mapped onto this reserved range.
I'll note that FreeBSD should be able to do better than Linux wrt the
alignment handling here, since you have MAP_ALIGNED(). So long as
guest_base is suitably aligned, anyway.
r~
r~