Home | History | Annotate | Download | only in strace
      1 /*
      2  * Copyright (c) 2003-2007 Ulrich Drepper <drepper (at) redhat.com>
      3  * Copyright (c) 2005-2016 Dmitry V. Levin <ldv (at) altlinux.org>
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  * 3. The name of the author may not be used to endorse or promote products
     15  *    derived from this software without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #include "defs.h"
     30 
     31 static bool
     32 print_node(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
     33 {
     34 	if (elem_size < sizeof(kernel_ulong_t)) {
     35 		tprintf("%#0*x", (int) elem_size * 2 + 2,
     36 			* (unsigned int *) elem_buf);
     37 	} else {
     38 		tprintf("%#0*" PRI_klx, (int) elem_size * 2 + 2,
     39 			* (kernel_ulong_t *) elem_buf);
     40 	}
     41 
     42 	return true;
     43 }
     44 
     45 static void
     46 print_nodemask(struct tcb *const tcp, const kernel_ulong_t addr,
     47 	       const kernel_ulong_t maxnodes)
     48 {
     49 	const unsigned int bits_per_long = 8 * current_wordsize;
     50 	const kernel_ulong_t nmemb =
     51 		(maxnodes + bits_per_long - 2) / bits_per_long;
     52 
     53 	if (nmemb < maxnodes / bits_per_long ||
     54 	    (maxnodes && !nmemb)) {
     55 		printaddr(addr);
     56 		return;
     57 	}
     58 
     59 	kernel_ulong_t buf;
     60 	print_array(tcp, addr, nmemb, &buf, current_wordsize,
     61 		    umoven_or_printaddr, print_node, 0);
     62 }
     63 
     64 SYS_FUNC(migrate_pages)
     65 {
     66 	tprintf("%d, %" PRI_klu ", ", (int) tcp->u_arg[0], tcp->u_arg[1]);
     67 	print_nodemask(tcp, tcp->u_arg[2], tcp->u_arg[1]);
     68 	tprints(", ");
     69 	print_nodemask(tcp, tcp->u_arg[3], tcp->u_arg[1]);
     70 
     71 	return RVAL_DECODED;
     72 }
     73 
     74 #include "xlat/policies.h"
     75 #include "xlat/mbindflags.h"
     76 
     77 SYS_FUNC(mbind)
     78 {
     79 	printaddr(tcp->u_arg[0]);
     80 	tprintf(", %" PRI_klu ", ", tcp->u_arg[1]);
     81 	printxval64(policies, tcp->u_arg[2], "MPOL_???");
     82 	tprints(", ");
     83 	print_nodemask(tcp, tcp->u_arg[3], tcp->u_arg[4]);
     84 	tprintf(", %" PRI_klu ", ", tcp->u_arg[4]);
     85 	printflags(mbindflags, tcp->u_arg[5], "MPOL_???");
     86 
     87 	return RVAL_DECODED;
     88 }
     89 
     90 SYS_FUNC(set_mempolicy)
     91 {
     92 	printxval(policies, tcp->u_arg[0], "MPOL_???");
     93 	tprints(", ");
     94 	print_nodemask(tcp, tcp->u_arg[1], tcp->u_arg[2]);
     95 	tprintf(", %" PRI_klu, tcp->u_arg[2]);
     96 
     97 	return RVAL_DECODED;
     98 }
     99 
    100 #include "xlat/mempolicyflags.h"
    101 
    102 SYS_FUNC(get_mempolicy)
    103 {
    104 	if (exiting(tcp)) {
    105 		int pol;
    106 		if (!umove_or_printaddr(tcp, tcp->u_arg[0], &pol)) {
    107 			tprints("[");
    108 			printxval(policies, pol, "MPOL_???");
    109 			tprints("]");
    110 		}
    111 		tprints(", ");
    112 		print_nodemask(tcp, tcp->u_arg[1], tcp->u_arg[2]);
    113 		tprintf(", %" PRI_klu ", ", tcp->u_arg[2]);
    114 		printaddr(tcp->u_arg[3]);
    115 		tprints(", ");
    116 		printflags64(mempolicyflags, tcp->u_arg[4], "MPOL_???");
    117 	}
    118 	return 0;
    119 }
    120 
    121 #include "xlat/move_pages_flags.h"
    122 
    123 static bool
    124 print_addr(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
    125 {
    126 	kernel_ulong_t addr;
    127 
    128 	if (elem_size < sizeof(addr)) {
    129 		addr = * (unsigned int *) elem_buf;
    130 	} else {
    131 		addr = * (kernel_ulong_t *) elem_buf;
    132 	}
    133 
    134 	printaddr(addr);
    135 
    136 	return true;
    137 }
    138 
    139 static bool
    140 print_status(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
    141 {
    142 	const int status = * (int *) elem_buf;
    143 
    144 	if (status < 0 && (unsigned) -status < nerrnos)
    145 		tprintf("%s", errnoent[-status]);
    146 	else
    147 		tprintf("%d", status);
    148 
    149 	return true;
    150 }
    151 
    152 static bool
    153 print_int(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
    154 {
    155 	tprintf("%d", * (int *) elem_buf);
    156 
    157 	return true;
    158 }
    159 
    160 SYS_FUNC(move_pages)
    161 {
    162 	const kernel_ulong_t npages = tcp->u_arg[1];
    163 	kernel_ulong_t buf;
    164 
    165 	if (entering(tcp)) {
    166 		tprintf("%d, %" PRI_klu ", ", (int) tcp->u_arg[0], npages);
    167 		print_array(tcp, tcp->u_arg[2], npages, &buf, current_wordsize,
    168 			    umoven_or_printaddr, print_addr, 0);
    169 		tprints(", ");
    170 		print_array(tcp, tcp->u_arg[3], npages, &buf, sizeof(int),
    171 			    umoven_or_printaddr, print_int, 0);
    172 		tprints(", ");
    173 	} else {
    174 		print_array(tcp, tcp->u_arg[4], npages, &buf, sizeof(int),
    175 			    umoven_or_printaddr, print_status, 0);
    176 		tprints(", ");
    177 		printflags(move_pages_flags, tcp->u_arg[5], "MPOL_???");
    178 	}
    179 	return 0;
    180 }
    181