@@ -899,3 +899,23 @@ abi_long target_madvise(abi_ulong start, abi_ulong len_in, int advice)
return ret;
}
+
+abi_long old_mmap_get_args(abi_long *arg1, abi_long *arg2, abi_long *arg3,
+ abi_long *arg4, abi_long *arg5, abi_long *arg6)
+{
+ abi_long orig_arg1 = *arg1, *v;
+
+ v = lock_user(VERIFY_READ, orig_arg1, 6 * sizeof(abi_ulong), 1);
+ if (!v) {
+ return -TARGET_EFAULT;
+ }
+ *arg1 = tswapal(v[0]);
+ *arg2 = tswapal(v[1]);
+ *arg3 = tswapal(v[2]);
+ *arg4 = tswapal(v[3]);
+ *arg5 = tswapal(v[4]);
+ *arg6 = tswapal(v[5]);
+ unlock_user(v, orig_arg1, 0);
+
+ return 0;
+}
@@ -16,6 +16,7 @@
#include <sched.h>
#include "qemu.h"
#include "user-internals.h"
+#include "user-mmap.h"
#include "strace.h"
struct syscallname {
@@ -3532,9 +3533,9 @@ print_utimensat(CPUArchState *cpu_env, const struct syscallname *name,
#if defined(TARGET_NR_mmap) || defined(TARGET_NR_mmap2)
static void
-print_mmap(CPUArchState *cpu_env, const struct syscallname *name,
- abi_long arg0, abi_long arg1, abi_long arg2,
- abi_long arg3, abi_long arg4, abi_long arg5)
+print_mmap2(CPUArchState *cpu_env, const struct syscallname *name,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
{
print_syscall_prologue(name);
print_pointer(arg0, 0);
@@ -3545,7 +3546,22 @@ print_mmap(CPUArchState *cpu_env, const struct syscallname *name,
print_raw_param("%#x", arg5, 1);
print_syscall_epilogue(name);
}
-#define print_mmap2 print_mmap
+#endif
+
+#if defined(TARGET_NR_mmap)
+static void
+print_mmap(CPUArchState *cpu_env, const struct syscallname *name,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ if (mmap_get_args(&arg0, &arg1, &arg2, &arg3, &arg4, &arg5)) {
+ print_syscall_prologue(name);
+ print_pointer(arg0, 0);
+ print_syscall_epilogue(name);
+ return;
+ }
+ print_mmap2(cpu_env, name, arg0, arg1, arg2, arg3, arg4, arg5);
+}
#endif
#ifdef TARGET_NR_mprotect
@@ -9917,33 +9917,14 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
return ret;
#ifdef TARGET_NR_mmap
case TARGET_NR_mmap:
-#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || \
- (defined(TARGET_ARM) && defined(TARGET_ABI32)) || \
- defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
- || defined(TARGET_S390X)
- {
- abi_ulong *v;
- abi_ulong v1, v2, v3, v4, v5, v6;
- if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
- return -TARGET_EFAULT;
- v1 = tswapal(v[0]);
- v2 = tswapal(v[1]);
- v3 = tswapal(v[2]);
- v4 = tswapal(v[3]);
- v5 = tswapal(v[4]);
- v6 = tswapal(v[5]);
- unlock_user(v, arg1, 0);
- ret = get_errno(target_mmap(v1, v2, v3,
- target_to_host_bitmask(v4, mmap_flags_tbl),
- v5, v6));
+ ret = mmap_get_args(&arg1, &arg2, &arg3, &arg4, &arg5, &arg6);
+ if (ret) {
+ return ret;
}
-#else
- /* mmap pointers are always untagged */
ret = get_errno(target_mmap(arg1, arg2, arg3,
target_to_host_bitmask(arg4, mmap_flags_tbl),
arg5,
arg6));
-#endif
return ret;
#endif
#ifdef TARGET_NR_mmap2
@@ -31,5 +31,17 @@ extern abi_ulong mmap_next_start;
abi_ulong mmap_find_vma(abi_ulong, abi_ulong, abi_ulong);
void mmap_fork_start(void);
void mmap_fork_end(int child);
+abi_long old_mmap_get_args(abi_long *arg1, abi_long *arg2, abi_long *arg3,
+ abi_long *arg4, abi_long *arg5, abi_long *arg6);
+
+#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || \
+ (defined(TARGET_ARM) && defined(TARGET_ABI32)) || \
+ defined(TARGET_M68K) || defined(TARGET_CRIS) || \
+ defined(TARGET_MICROBLAZE) || defined(TARGET_S390X)
+/* __ARCH_WANT_SYS_OLD_MMAP */
+#define mmap_get_args old_mmap_get_args
+#else
+#define mmap_get_args(arg1, arg2, arg3, arg4, arg5, arg6) 0
+#endif
#endif /* LINUX_USER_USER_MMAP_H */
On some architectures mmap() arguments are passed via an in-memory array, and qemu's strace support does not recognize that. Fix by sharing the argument fetching logic between mmap() implementation and tracing. An alternative approach would be to fetch arguments only once at the beginning of do_syscall(), however, that would change what the qemu_plugin_register_vcpu_syscall_cb() users get. Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> --- linux-user/mmap.c | 20 ++++++++++++++++++++ linux-user/strace.c | 24 ++++++++++++++++++++---- linux-user/syscall.c | 25 +++---------------------- linux-user/user-mmap.h | 12 ++++++++++++ 4 files changed, 55 insertions(+), 26 deletions(-)