]> granicus.if.org Git - strace/blobdiff - numa.c
Update NEWS
[strace] / numa.c
diff --git a/numa.c b/numa.c
index 6ea9b5a1c64cc394ae298549fec27fda358ae2b8..b46fc7fc4a9d07c48de25db6350feeb6d404e938 100644 (file)
--- a/numa.c
+++ b/numa.c
 
 #include "defs.h"
 
-static void
-get_nodes(struct tcb *tcp, unsigned long ptr, unsigned long maxnodes, int err)
+static bool
+print_node(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
 {
-       unsigned long nlongs, size, end;
-
-       nlongs = (maxnodes + 8 * sizeof(long) - 1) / (8 * sizeof(long));
-       size = nlongs * sizeof(long);
-       end = ptr + size;
-       if (nlongs == 0 || ((err || verbose(tcp)) && (size * 8 == maxnodes)
-                           && (end > ptr))) {
-               unsigned long n, cur, abbrev_end;
-               int failed = 0;
-
-               if (abbrev(tcp)) {
-                       abbrev_end = ptr + max_strlen * sizeof(long);
-                       if (abbrev_end < ptr)
-                               abbrev_end = end;
-               } else {
-                       abbrev_end = end;
-               }
-               tprints(", {");
-               for (cur = ptr; cur < end; cur += sizeof(long)) {
-                       if (cur > ptr)
-                               tprints(", ");
-                       if (cur >= abbrev_end) {
-                               tprints("...");
-                               break;
-                       }
-                       if (umoven(tcp, cur, sizeof(n), &n) < 0) {
-                               tprints("?");
-                               failed = 1;
-                               break;
-                       }
-                       tprintf("%#0*lx", (int) sizeof(long) * 2 + 2, n);
-               }
-               tprints("}");
-               if (failed) {
-                       tprints(" ");
-                       printaddr(ptr);
-               }
+       if (elem_size < sizeof(long)) {
+               tprintf("%#0*x", (int) elem_size * 2 + 2,
+                       * (unsigned int *) elem_buf);
        } else {
-               tprints(" ");
-               printaddr(ptr);
+               tprintf("%#0*lx", (int) elem_size * 2 + 2,
+                       * (unsigned long *) elem_buf);
        }
-       tprintf(", %lu", maxnodes);
+
+       return true;
+}
+
+static void
+print_nodemask(struct tcb *tcp, unsigned long addr, unsigned long maxnodes)
+{
+       const unsigned long nmemb =
+               (maxnodes + 8 * current_wordsize - 2) / (8 * current_wordsize);
+
+       if (nmemb < maxnodes / (8 * current_wordsize) ||
+           (maxnodes && !nmemb)) {
+               printaddr(addr);
+               return;
+       }
+
+       unsigned long buf;
+       print_array(tcp, addr, nmemb, &buf, current_wordsize,
+                   umoven_or_printaddr, print_node, 0);
 }
 
 SYS_FUNC(migrate_pages)
 {
-       tprintf("%d, ", (int) tcp->u_arg[0]);
-       get_nodes(tcp, tcp->u_arg[2], tcp->u_arg[1], 0);
+       tprintf("%d, %lu, ", (int) tcp->u_arg[0], tcp->u_arg[1]);
+       print_nodemask(tcp, tcp->u_arg[2], tcp->u_arg[1]);
        tprints(", ");
-       get_nodes(tcp, tcp->u_arg[3], tcp->u_arg[1], 0);
+       print_nodemask(tcp, tcp->u_arg[3], tcp->u_arg[1]);
 
        return RVAL_DECODED;
 }
@@ -92,9 +76,10 @@ SYS_FUNC(mbind)
 {
        printaddr(tcp->u_arg[0]);
        tprintf(", %lu, ", tcp->u_arg[1]);
-       printxval(policies, tcp->u_arg[2], "MPOL_???");
-       get_nodes(tcp, tcp->u_arg[3], tcp->u_arg[4], 0);
+       printxval_long(policies, tcp->u_arg[2], "MPOL_???");
        tprints(", ");
+       print_nodemask(tcp, tcp->u_arg[3], tcp->u_arg[4]);
+       tprintf(", %lu, ", tcp->u_arg[4]);
        printflags(mbindflags, tcp->u_arg[5], "MPOL_???");
 
        return RVAL_DECODED;
@@ -103,7 +88,9 @@ SYS_FUNC(mbind)
 SYS_FUNC(set_mempolicy)
 {
        printxval(policies, tcp->u_arg[0], "MPOL_???");
-       get_nodes(tcp, tcp->u_arg[1], tcp->u_arg[2], 0);
+       tprints(", ");
+       print_nodemask(tcp, tcp->u_arg[1], tcp->u_arg[2]);
+       tprintf(", %lu", tcp->u_arg[2]);
 
        return RVAL_DECODED;
 }
@@ -119,81 +106,72 @@ SYS_FUNC(get_mempolicy)
                        printxval(policies, pol, "MPOL_???");
                        tprints("]");
                }
-               get_nodes(tcp, tcp->u_arg[1], tcp->u_arg[2], syserror(tcp));
                tprints(", ");
+               print_nodemask(tcp, tcp->u_arg[1], tcp->u_arg[2]);
+               tprintf(", %lu, ", tcp->u_arg[2]);
                printaddr(tcp->u_arg[3]);
                tprints(", ");
-               printflags(mempolicyflags, tcp->u_arg[4], "MPOL_???");
+               printflags_long(mempolicyflags, tcp->u_arg[4], "MPOL_???");
        }
        return 0;
 }
 
 #include "xlat/move_pages_flags.h"
 
+static bool
+print_addr(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
+{
+       unsigned long addr;
+
+       if (elem_size < sizeof(long)) {
+               addr = * (unsigned int *) elem_buf;
+       } else {
+               addr = * (unsigned long *) elem_buf;
+       }
+
+       printaddr(addr);
+
+       return true;
+}
+
+static bool
+print_status(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
+{
+       const int status = * (int *) elem_buf;
+
+       if (status < 0 && (unsigned) -status < nerrnos)
+               tprintf("%s", errnoent[-status]);
+       else
+               tprintf("%d", status);
+
+       return true;
+}
+
+static bool
+print_int(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
+{
+       tprintf("%d", * (int *) elem_buf);
+
+       return true;
+}
+
 SYS_FUNC(move_pages)
 {
+       const unsigned long npages = tcp->u_arg[1];
+       long buf;
+
        if (entering(tcp)) {
-               unsigned long npages = tcp->u_arg[1];
-               tprintf("%ld, %lu, ", tcp->u_arg[0], npages);
-               if (tcp->u_arg[2] == 0)
-                       tprints("NULL, ");
-               else {
-                       unsigned int i;
-                       long puser = tcp->u_arg[2];
-                       tprints("{");
-                       for (i = 0; i < npages; ++i) {
-                               void *p;
-                               if (i > 0)
-                                       tprints(", ");
-                               if (umove(tcp, puser, &p) < 0) {
-                                       tprints("???");
-                                       break;
-                               }
-                               tprintf("%p", p);
-                               puser += sizeof(void *);
-                       }
-                       tprints("}, ");
-               }
-               if (tcp->u_arg[3] == 0)
-                       tprints("NULL, ");
-               else {
-                       unsigned int i;
-                       long nodeuser = tcp->u_arg[3];
-                       tprints("{");
-                       for (i = 0; i < npages; ++i) {
-                               int node;
-                               if (i > 0)
-                                       tprints(", ");
-                               if (umove(tcp, nodeuser, &node) < 0) {
-                                       tprints("???");
-                                       break;
-                               }
-                               tprintf("%#x", node);
-                               nodeuser += sizeof(int);
-                       }
-                       tprints("}, ");
-               }
+               tprintf("%d, %lu, ", (int) tcp->u_arg[0], npages);
+               print_array(tcp, tcp->u_arg[2], npages, &buf, current_wordsize,
+                           umoven_or_printaddr, print_addr, 0);
+               tprints(", ");
+               print_array(tcp, tcp->u_arg[3], npages, &buf, sizeof(int),
+                           umoven_or_printaddr, print_int, 0);
+               tprints(", ");
        } else {
-               unsigned long npages = tcp->u_arg[1];
-               if (tcp->u_arg[4] == 0)
-                       tprints("NULL, ");
-               else {
-                       unsigned int i;
-                       long statususer = tcp->u_arg[4];
-                       tprints("{");
-                       for (i = 0; i < npages; ++i) {
-                               int status;
-                               if (i > 0)
-                                       tprints(", ");
-                               if (umove(tcp, statususer, &status) < 0) {
-                                       tprints("???");
-                                       break;
-                               }
-                               tprintf("%#x", status);
-                               statususer += sizeof(int);
-                       }
-                       tprints("}, ");
-               }
+               print_array(tcp, tcp->u_arg[4], npages, &buf, sizeof(int),
+                           umoven_or_printaddr, print_status, 0);
+               tprints(", ");
                printflags(move_pages_flags, tcp->u_arg[5], "MPOL_???");
        }
        return 0;