On Sun, Sep 20, 2026 at 4:33 PM Richard Henderson <
[email protected]> wrote:

> 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.
>

I believe I have those missing pieces in the next round. I'll pull them
forward into this round when I rework.

Warner


> >     /*
> >      * 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~
>

Reply via email to