diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c index 548b4824df..5068e5c3b7 100644 --- a/bsd-user/mmap.c +++ b/bsd-user/mmap.c @@ -215,11 +215,15 @@ static int mmap_frag(abi_ulong real_start, prot_new = prot | prot1; if (fd != -1) { - /* msync() won't work here, so we return an error if write is - possible while it is a shared mapping */ - if ((flags & TARGET_BSD_MAP_FLAGMASK) == MAP_SHARED && - (prot & PROT_WRITE)) + /* + * msync() won't work here, so we return an error if write is + * possible while it is a shared mapping + */ + if (!(flags & MAP_ANON) + && (flags & MAP_TYPE) == MAP_SHARED + && (prot & PROT_WRITE)) { return -1; + } /* adjust protection to be able to read */ if (!(prot1 & PROT_WRITE)) @@ -586,8 +590,9 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, * msync() won't work here, so we return an error if write is * possible while it is a shared mapping */ - if ((flags & TARGET_BSD_MAP_FLAGMASK) == MAP_SHARED && - (prot & PROT_WRITE)) { + if (!(flags & MAP_ANON) + && (flags & MAP_TYPE) == MAP_SHARED + && (prot & PROT_WRITE)) { errno = EINVAL; goto fail; } diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h index 9fa16e0863..c4fd5f5589 100644 --- a/bsd-user/syscall_defs.h +++ b/bsd-user/syscall_defs.h @@ -121,7 +121,14 @@ struct target_msgbuf { /* * sys/mman.h */ -#define TARGET_BSD_MAP_FLAGMASK 0x3ff7 +/* + * FreeBSD doesn't define this, but Linux does. In Linux, it's only MAP_PRIVATE + * and MAP_SHARED and a few Linux-specific types (0xf). FreeBSD allows other + * types of mapping with MAP_ANON, MAP_GUARD, and MAP_STACK. The mask on Linux + * excludes these: They don't have MAP_GUARD, and MAP_STACK and MAP_ANON have + * similar flags with different names that aren't in it's 0xf MAP_TYPE. + */ +#define MAP_TYPE (MAP_PRIVATE | MAP_SHARED) /* * sys/time.h