Skip to content

Commit 59bd2d8

Browse files
committed
correct mmap /dev/zero macOS-vs-Linux differences
1 parent 052eb07 commit 59bd2d8

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

darwin-user/mmap.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
*/
1919
#include "qemu/osdep.h"
2020

21+
#include <sys/syslimits.h>
22+
#include <fcntl.h>
23+
2124
#include "qemu.h"
2225
#include "qemu-common.h"
2326
#include "translate-all.h"
@@ -367,11 +370,12 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
367370
int flags, int fd, abi_ulong offset)
368371
{
369372
abi_ulong ret, end, real_start, real_end, retaddr, host_offset, host_len;
373+
char filePath[PATH_MAX];
370374

371375
mmap_lock();
372376
#ifdef DEBUG_MMAP
373377
{
374-
printf("mmap: start=0x" TARGET_ABI_FMT_lx
378+
printf("\nmmap: start=0x" TARGET_ABI_FMT_lx
375379
" len=0x" TARGET_ABI_FMT_lx " prot=%c%c%c flags=",
376380
start, len,
377381
prot & PROT_READ ? 'r' : '-',
@@ -393,9 +397,29 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
393397
break;
394398
}
395399
printf("fd=%d offset=" TARGET_ABI_FMT_lx "\n", fd, offset);
400+
if (fcntl(fd, F_GETPATH, filePath) != -1) {
401+
printf("fd name=%s\n", filePath);
402+
}
396403
}
397404
#endif
398405

406+
/* macOS cannot mmap /dev/zero. It needs `MAP_ANON` with an fd of -1
407+
* Catch this scenario and fix
408+
* https://stackoverflow.com/questions/28679577/mmapping-dev-zero-on-mac-osx-gives-invalid-argument
409+
* https://stackoverflow.com/questions/1188757/retrieve-filename-from-file-descriptor-in-c
410+
*/
411+
if (fd != -1
412+
&& !(flags & MAP_ANON)
413+
&& fcntl(fd, F_GETPATH, filePath) != -1
414+
&& strcmp(filePath, "/dev/zero") == 0
415+
) {
416+
fd = -1;
417+
flags |= MAP_ANON;
418+
#ifdef DEBUG_MMAP
419+
printf("Changed fd and flags to support mmap /dev/zero\n");
420+
#endif
421+
}
422+
399423
if (offset & ~TARGET_PAGE_MASK) {
400424
errno = EINVAL;
401425
goto fail;

darwin-user/syscall.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10830,7 +10830,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
1083010830
if (!target_dirp) {
1083110831
goto efault;
1083210832
}
10833-
10833+
1083410834
struct dirent *de;
1083510835
struct target_dirent *tde = target_dirp;
1083610836
uint bytes_used = 0;

0 commit comments

Comments
 (0)