220 lines
6.9 KiB
Diff
220 lines
6.9 KiB
Diff
Index: qemu-0.9.0/linux-user/syscall.c
|
|
===================================================================
|
|
--- qemu-0.9.0.orig/linux-user/syscall.c
|
|
+++ qemu-0.9.0/linux-user/syscall.c
|
|
@@ -185,6 +185,9 @@ extern int getresgid(gid_t *, gid_t *, g
|
|
extern int setgroups(int, gid_t *);
|
|
extern int uselib(const char*);
|
|
|
|
+#include "exec-all.h"
|
|
+long mmap_lock;
|
|
+
|
|
static inline long get_errno(long ret)
|
|
{
|
|
if (ret == -1)
|
|
@@ -227,9 +235,11 @@ long do_brk(target_ulong new_brk)
|
|
|
|
/* We need to allocate more memory after the brk... */
|
|
new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
|
|
+ spin_lock(&mmap_lock);
|
|
mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
|
|
PROT_READ|PROT_WRITE,
|
|
MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
|
|
+ spin_unlock(&mmap_lock);
|
|
if (is_error(mapped_addr)) {
|
|
return mapped_addr;
|
|
} else {
|
|
@@ -2133,6 +2133,7 @@ static long do_futex(target_ulong uaddr,
|
|
struct timespec host_utime;
|
|
unsigned long val2 = utime;
|
|
|
|
+ spin_lock(&mmap_lock);
|
|
if (utime && (op == FUTEX_WAIT || op == FUTEX_LOCK_PI)) {
|
|
target_to_host_timespec(&host_utime, utime);
|
|
val2 = (unsigned long)&host_utime;
|
|
@@ -2230,6 +2265,7 @@ static long do_futex(target_ulong uaddr,
|
|
}
|
|
#endif
|
|
#endif
|
|
+ spin_unlock(&mmap_lock);
|
|
return syscall(__NR_futex, g2h(uaddr), op, val, val2, g2h(uaddr2), val3);
|
|
}
|
|
|
|
@@ -2985,15 +3021,19 @@ long do_syscall(void *cpu_env, int num,
|
|
v5 = tswapl(v[4]);
|
|
v6 = tswapl(v[5]);
|
|
unlock_user(v, arg1, 0);
|
|
+ spin_lock(&mmap_lock);
|
|
ret = get_errno(target_mmap(v1, v2, v3,
|
|
target_to_host_bitmask(v4, mmap_flags_tbl),
|
|
v5, v6));
|
|
+ spin_unlock(&mmap_lock);
|
|
}
|
|
#else
|
|
+ spin_lock(&mmap_lock);
|
|
ret = get_errno(target_mmap(arg1, arg2, arg3,
|
|
target_to_host_bitmask(arg4, mmap_flags_tbl),
|
|
arg5,
|
|
arg6));
|
|
+ spin_unlock(&mmap_lock);
|
|
#endif
|
|
break;
|
|
#ifdef TARGET_NR_mmap2
|
|
@@ -3003,36 +3043,54 @@ long do_syscall(void *cpu_env, int num,
|
|
#else
|
|
#define MMAP_SHIFT TARGET_PAGE_BITS
|
|
#endif
|
|
+ spin_lock(&mmap_lock);
|
|
ret = get_errno(target_mmap(arg1, arg2, arg3,
|
|
target_to_host_bitmask(arg4, mmap_flags_tbl),
|
|
arg5,
|
|
arg6 << MMAP_SHIFT));
|
|
+ spin_unlock(&mmap_lock);
|
|
break;
|
|
#endif
|
|
case TARGET_NR_munmap:
|
|
+ spin_lock(&mmap_lock);
|
|
ret = get_errno(target_munmap(arg1, arg2));
|
|
+ spin_unlock(&mmap_lock);
|
|
break;
|
|
case TARGET_NR_mprotect:
|
|
+ spin_lock(&mmap_lock);
|
|
ret = get_errno(target_mprotect(arg1, arg2, arg3));
|
|
+ spin_unlock(&mmap_lock);
|
|
break;
|
|
case TARGET_NR_mremap:
|
|
+ spin_lock(&mmap_lock);
|
|
ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
|
|
+ spin_unlock(&mmap_lock);
|
|
break;
|
|
/* ??? msync/mlock/munlock are broken for softmmu. */
|
|
case TARGET_NR_msync:
|
|
+ spin_lock(&mmap_lock);
|
|
ret = get_errno(msync(g2h(arg1), arg2, arg3));
|
|
+ spin_unlock(&mmap_lock);
|
|
break;
|
|
case TARGET_NR_mlock:
|
|
+ spin_lock(&mmap_lock);
|
|
ret = get_errno(mlock(g2h(arg1), arg2));
|
|
+ spin_unlock(&mmap_lock);
|
|
break;
|
|
case TARGET_NR_munlock:
|
|
+ spin_lock(&mmap_lock);
|
|
ret = get_errno(munlock(g2h(arg1), arg2));
|
|
+ spin_unlock(&mmap_lock);
|
|
break;
|
|
case TARGET_NR_mlockall:
|
|
+ spin_lock(&mmap_lock);
|
|
ret = get_errno(mlockall(arg1));
|
|
+ spin_unlock(&mmap_lock);
|
|
break;
|
|
case TARGET_NR_munlockall:
|
|
+ spin_lock(&mmap_lock);
|
|
ret = get_errno(munlockall());
|
|
+ spin_unlock(&mmap_lock);
|
|
break;
|
|
case TARGET_NR_truncate:
|
|
p = lock_user_string(arg1);
|
|
Index: qemu-0.9.0/exec.c
|
|
===================================================================
|
|
--- qemu-0.9.0.orig/exec.c
|
|
+++ qemu-0.9.0/exec.c
|
|
@@ -1676,6 +1684,50 @@ void page_dump(FILE *f)
|
|
}
|
|
}
|
|
|
|
+/* dump memory mappings */
|
|
+target_ulong page_find_end()
|
|
+{
|
|
+ unsigned long start, end;
|
|
+ int i, j, prot, prot1;
|
|
+ void *firsttb;
|
|
+ PageDesc *p;
|
|
+ target_ulong last = 0;
|
|
+
|
|
+ start = -1;
|
|
+ end = -1;
|
|
+ prot = 0;
|
|
+ for(i = 0; i <= L1_SIZE; i++) {
|
|
+ if (i < L1_SIZE)
|
|
+ p = l1_map[i];
|
|
+ else
|
|
+ p = NULL;
|
|
+ for(j = 0;j < L2_SIZE; j++) {
|
|
+ if (!p) {
|
|
+ firsttb = NULL;
|
|
+ prot1 = 0;
|
|
+ }
|
|
+ else {
|
|
+ prot1 = p[j].flags;
|
|
+ firsttb = p[j].first_tb;
|
|
+ }
|
|
+ if (prot1 != prot) {
|
|
+ end = (i << (32 - L1_BITS)) | (j << TARGET_PAGE_BITS);
|
|
+ if (start != -1) {
|
|
+ last = end;
|
|
+ }
|
|
+ if (prot1 != 0)
|
|
+ start = end;
|
|
+ else
|
|
+ start = -1;
|
|
+ prot = prot1;
|
|
+ }
|
|
+ if (!p)
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ return last;
|
|
+}
|
|
+
|
|
int page_get_flags(target_ulong address)
|
|
{
|
|
PageDesc *p;
|
|
Index: qemu-0.9.0/linux-user/mmap.c
|
|
===================================================================
|
|
--- qemu-0.9.0.orig/linux-user/mmap.c
|
|
+++ qemu-0.9.0/linux-user/mmap.c
|
|
@@ -48,8 +48,14 @@ int target_mprotect(target_ulong start,
|
|
end = start + len;
|
|
if (end < start)
|
|
return -EINVAL;
|
|
- if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
|
|
- return -EINVAL;
|
|
+ if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) {
|
|
+#ifdef DEBUG_MMAP
|
|
+ gemu_log("mprotect: ERROR (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)\n");
|
|
+#endif
|
|
+ // dirty hack to get mplayer running (sets PROT_GROWSDOWN) we just ignore advanced flags
|
|
+ prot &= (PROT_READ | PROT_WRITE | PROT_EXEC);
|
|
+// return -EINVAL;
|
|
+ }
|
|
if (len == 0)
|
|
return 0;
|
|
|
|
@@ -205,9 +233,23 @@ long target_mmap(target_ulong start, tar
|
|
defined(__ia64) || defined(__CYGWIN__)
|
|
/* tell the kenel to search at the same place as i386 */
|
|
if (real_start == 0) {
|
|
- real_start = last_start;
|
|
- last_start += HOST_PAGE_ALIGN(len);
|
|
+ target_ulong curend = page_find_end();
|
|
+
|
|
+ if(curend > last_start) {
|
|
+#ifdef DEBUG_MMAP
|
|
+ gemu_log("qemu: set last_start from %p to %p\n", last_start, curend + HOST_PAGE_ALIGN(len)); fflush(stdout); fflush(stderr);
|
|
+#endif
|
|
+ last_start = curend;
|
|
+#ifdef DEBUG_MMAP
|
|
+ } else {
|
|
+ gemu_log("qemu: curend(%p) <= last_start(%p)\n", curend, last_start); fflush(stdout); fflush(stderr);
|
|
+#endif
|
|
+ }
|
|
+
|
|
+ real_start = last_start;
|
|
+ last_start += HOST_PAGE_ALIGN(len);
|
|
}
|
|
+
|
|
#endif
|
|
if (0 && qemu_host_page_size != qemu_real_host_page_size) {
|
|
/* NOTE: this code is only for debugging with '-p' option */
|