Home | History | Annotate | Download | only in strace
      1 /*
      2  * Copyright (c) 2015-2017 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=%lld, tv_usec=%llu}";
     37 
     38 static void
     39 print_timeval_t(const timeval_t *t)
     40 {
     41 	tprintf(timeval_fmt, (long long) t->tv_sec,
     42 		zero_extend_signed_to_ull(t->tv_usec));
     43 }
     44 
     45 static void
     46 print_timeval_t_utime(const timeval_t *t)
     47 {
     48 	print_timeval_t(t);
     49 	tprints_comment(sprinttime_usec(t->tv_sec,
     50 		zero_extend_signed_to_ull(t->tv_usec)));
     51 }
     52 
     53 MPERS_PRINTER_DECL(void, print_struct_timeval, const void *arg)
     54 {
     55 	print_timeval_t(arg);
     56 }
     57 
     58 MPERS_PRINTER_DECL(bool, print_struct_timeval_data_size,
     59 		   const void *arg, const size_t size)
     60 {
     61 	if (size < sizeof(timeval_t)) {
     62 		tprints("?");
     63 		return false;
     64 	}
     65 
     66 	print_timeval_t(arg);
     67 	return true;
     68 }
     69 
     70 MPERS_PRINTER_DECL(void, print_timeval,
     71 		   struct tcb *const tcp, const kernel_ulong_t addr)
     72 {
     73 	timeval_t t;
     74 
     75 	if (umove_or_printaddr(tcp, addr, &t))
     76 		return;
     77 
     78 	print_timeval_t(&t);
     79 }
     80 
     81 MPERS_PRINTER_DECL(void, print_timeval_utimes,
     82 		   struct tcb *const tcp, const kernel_ulong_t addr)
     83 {
     84 	timeval_t t[2];
     85 
     86 	if (umove_or_printaddr(tcp, addr, &t))
     87 		return;
     88 
     89 	tprints("[");
     90 	print_timeval_t_utime(&t[0]);
     91 	tprints(", ");
     92 	print_timeval_t_utime(&t[1]);
     93 	tprints("]");
     94 }
     95 
     96 MPERS_PRINTER_DECL(const char *, sprint_timeval,
     97 		   struct tcb *const tcp, const kernel_ulong_t addr)
     98 {
     99 	timeval_t t;
    100 	static char buf[sizeof(timeval_fmt) + 3 * sizeof(t)];
    101 
    102 	if (!addr) {
    103 		strcpy(buf, "NULL");
    104 	} else if (!verbose(tcp) || (exiting(tcp) && syserror(tcp)) ||
    105 		   umove(tcp, addr, &t)) {
    106 		snprintf(buf, sizeof(buf), "%#" PRI_klx, addr);
    107 	} else {
    108 		snprintf(buf, sizeof(buf), timeval_fmt,
    109 			 (long long) t.tv_sec,
    110 			 zero_extend_signed_to_ull(t.tv_usec));
    111 	}
    112 
    113 	return buf;
    114 }
    115 
    116 MPERS_PRINTER_DECL(void, print_itimerval,
    117 		   struct tcb *const tcp, const kernel_ulong_t addr)
    118 {
    119 	timeval_t t[2];
    120 
    121 	if (umove_or_printaddr(tcp, addr, &t))
    122 		return;
    123 
    124 	tprints("{it_interval=");
    125 	print_timeval_t(&t[0]);
    126 	tprints(", it_value=");
    127 	print_timeval_t(&t[1]);
    128 	tprints("}");
    129 }
    130 
    131 #ifdef ALPHA
    132 
    133 void
    134 print_timeval32_t(const timeval32_t *t)
    135 {
    136 	tprintf(timeval_fmt, (long long) t->tv_sec,
    137 		zero_extend_signed_to_ull(t->tv_usec));
    138 }
    139 
    140 static void
    141 print_timeval32_t_utime(const timeval32_t *t)
    142 {
    143 	print_timeval32_t(t);
    144 	tprints_comment(sprinttime_usec(t->tv_sec,
    145 		zero_extend_signed_to_ull(t->tv_usec)));
    146 }
    147 
    148 void
    149 print_timeval32(struct tcb *const tcp, const kernel_ulong_t addr)
    150 {
    151 	timeval32_t t;
    152 
    153 	if (umove_or_printaddr(tcp, addr, &t))
    154 		return;
    155 
    156 	print_timeval32_t(&t);
    157 }
    158 
    159 void
    160 print_timeval32_utimes(struct tcb *const tcp, const kernel_ulong_t addr)
    161 {
    162 	timeval32_t t[2];
    163 
    164 	if (umove_or_printaddr(tcp, addr, &t))
    165 		return;
    166 
    167 	tprints("[");
    168 	print_timeval32_t_utime(&t[0]);
    169 	tprints(", ");
    170 	print_timeval32_t_utime(&t[1]);
    171 	tprints("]");
    172 }
    173 
    174 void
    175 print_itimerval32(struct tcb *const tcp, const kernel_ulong_t addr)
    176 {
    177 	timeval32_t t[2];
    178 
    179 	if (umove_or_printaddr(tcp, addr, &t))
    180 		return;
    181 
    182 	tprints("{it_interval=");
    183 	print_timeval32_t(&t[0]);
    184 	tprints(", it_value=");
    185 	print_timeval32_t(&t[1]);
    186 	tprints("}");
    187 }
    188 
    189 const char *
    190 sprint_timeval32(struct tcb *const tcp, const kernel_ulong_t addr)
    191 {
    192 	timeval32_t t;
    193 	static char buf[sizeof(timeval_fmt) + 3 * sizeof(t)];
    194 
    195 	if (!addr) {
    196 		strcpy(buf, "NULL");
    197 	} else if (!verbose(tcp) || (exiting(tcp) && syserror(tcp)) ||
    198 		   umove(tcp, addr, &t)) {
    199 		snprintf(buf, sizeof(buf), "%#" PRI_klx, addr);
    200 	} else {
    201 		snprintf(buf, sizeof(buf), timeval_fmt,
    202 			 (long long) t.tv_sec,
    203 			 zero_extend_signed_to_ull(t.tv_usec));
    204 	}
    205 
    206 	return buf;
    207 }
    208 
    209 #endif /* ALPHA */
    210