]> granicus.if.org Git - strace/commitdiff
mem.c: introduce fetch_old_mmap_args
authorEugene Syromyatnikov <evgsyr@gmail.com>
Wed, 17 Jan 2018 01:18:45 +0000 (02:18 +0100)
committerDmitry V. Levin <ldv@altlinux.org>
Wed, 17 Jan 2018 04:34:49 +0000 (04:34 +0000)
Move common old_mmap/old_mmap_pgoff argument fetching code into a
separate function.

As it is, it also fixes the case of non-verbose printing of old_mmap
arguments (see the new test in the next commit).  Also, it is a
preparation for the fix of path tracing for these syscalls.

* defs.h [HAVE_ARCH_OLD_MMAP] (fetch_old_mmap_args): New prototype.
* mem.c [HAVE_ARCH_OLD_MMAP] (fetch_old_mmap_args): New function.
[HAVE_ARCH_OLD_MMAP] (old_mmap, old_mmap_pgoff): Use it.

Fixes: 3db07f11 "Fix old_mmap output when mmap arguments are unfetchable"
Suggested-by: Dmitry V. Levin <ldv@altlinux.org>
defs.h
mem.c

diff --git a/defs.h b/defs.h
index 04e9c22d572b9d220fc60b8d513f2e0a9a5f739b..3e42908871ab23c9a762f4ff238e3eb1a770d896 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -575,6 +575,10 @@ extern void print_numeric_long_umask(unsigned long);
 extern void print_dev_t(unsigned long long dev);
 extern void print_abnormal_hi(kernel_ulong_t);
 
+#ifdef HAVE_ARCH_OLD_MMAP
+extern kernel_ulong_t *fetch_old_mmap_args(struct tcb *tcp);
+#endif
+
 extern void
 dumpiov_in_msghdr(struct tcb *, kernel_ulong_t addr, kernel_ulong_t data_size);
 
diff --git a/mem.c b/mem.c
index 5d223a8b3580c8670ebf17be508eafd91ebfe10d..3a34fbb872072f0c413300779a1bc80fd96b7bef 100644 (file)
--- a/mem.c
+++ b/mem.c
@@ -108,47 +108,64 @@ print_mmap(struct tcb *tcp, kernel_ulong_t *u_arg, unsigned long long offset)
  */
 
 #ifdef HAVE_ARCH_OLD_MMAP
-/* Params are pointed to by u_arg[0], offset is in bytes */
-SYS_FUNC(old_mmap)
+/**
+ * Fetch old_mmap/old_mmap_pgoff arguments that are provided as a 6-element
+ * array.  Return pointer to a static array or NULL in case of fetch failure.
+ */
+kernel_ulong_t *
+fetch_old_mmap_args(struct tcb *tcp)
 {
-       kernel_ulong_t u_arg[6];
+       static kernel_ulong_t u_arg[6];
+
 # if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG
        /* We are here only in a 32-bit personality. */
        unsigned int narrow_arg[6];
-       if (umove_or_printaddr(tcp, tcp->u_arg[0], &narrow_arg))
-               return RVAL_DECODED | RVAL_HEX;
-       unsigned int i;
-       for (i = 0; i < 6; i++)
+       if (umove(tcp, tcp->u_arg[0], &narrow_arg))
+               return NULL;
+       for (unsigned int i = 0; i < 6; i++)
                u_arg[i] = narrow_arg[i];
 # else
-       if (umove_or_printaddr(tcp, tcp->u_arg[0], &u_arg))
-               return RVAL_DECODED | RVAL_HEX;
+       if (umove(tcp, tcp->u_arg[0], &u_arg))
+               return NULL;
 # endif
-       print_mmap(tcp, u_arg, u_arg[5]);
+
+       return u_arg;
+}
+
+/* Params are pointed to by u_arg[0], offset is in bytes */
+SYS_FUNC(old_mmap)
+{
+       kernel_ulong_t *args = fetch_old_mmap_args(tcp);
+
+       if (args)
+               print_mmap(tcp, args, args[5]);
+       else
+               printaddr(tcp->u_arg[0]);
 
        return RVAL_DECODED | RVAL_HEX;
 }
-#endif /* HAVE_ARCH_OLD_MMAP */
 
-#ifdef S390
+# ifdef S390
 /* Params are pointed to by u_arg[0], offset is in pages */
 SYS_FUNC(old_mmap_pgoff)
 {
-       kernel_ulong_t u_arg[5];
-       int i;
-       unsigned int narrow_arg[6];
-       unsigned long long offset;
-       if (umove_or_printaddr(tcp, tcp->u_arg[0], &narrow_arg))
-               return RVAL_DECODED | RVAL_HEX;
-       for (i = 0; i < 5; i++)
-               u_arg[i] = narrow_arg[i];
-       offset = narrow_arg[5];
-       offset *= get_pagesize();
-       print_mmap(tcp, u_arg, offset);
+       kernel_ulong_t *args = fetch_old_mmap_args(tcp);
+
+       if (args) {
+               unsigned long long offset;
+
+               offset = args[5];
+               offset *= get_pagesize();
+
+               print_mmap(tcp, args, offset);
+       } else {
+               printaddr(tcp->u_arg[0]);
+       }
 
        return RVAL_DECODED | RVAL_HEX;
 }
-#endif /* S390 */
+# endif /* S390 */
+#endif /* HAVE_ARCH_OLD_MMAP */
 
 /* Params are passed directly, offset is in bytes */
 SYS_FUNC(mmap)