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