1 /* 2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk (at) cs.few.eur.nl> 3 * Copyright (c) 1993 Branko Lankester <branko (at) hacktic.nl> 4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs (at) world.std.com> 5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert (at) cistron.nl> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "defs.h" 32 #include <fcntl.h> 33 #include <sys/uio.h> 34 35 SYS_FUNC(read) 36 { 37 if (entering(tcp)) { 38 printfd(tcp, tcp->u_arg[0]); 39 tprints(", "); 40 } else { 41 if (syserror(tcp)) 42 printaddr(tcp->u_arg[1]); 43 else 44 printstrn(tcp, tcp->u_arg[1], tcp->u_rval); 45 tprintf(", %" PRI_klu, tcp->u_arg[2]); 46 } 47 return 0; 48 } 49 50 SYS_FUNC(write) 51 { 52 printfd(tcp, tcp->u_arg[0]); 53 tprints(", "); 54 printstrn(tcp, tcp->u_arg[1], tcp->u_arg[2]); 55 tprintf(", %" PRI_klu, tcp->u_arg[2]); 56 57 return RVAL_DECODED; 58 } 59 60 struct print_iovec_config { 61 enum iov_decode decode_iov; 62 kernel_ulong_t data_size; 63 }; 64 65 static bool 66 print_iovec(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data) 67 { 68 const kernel_ulong_t *iov; 69 kernel_ulong_t iov_buf[2], len; 70 struct print_iovec_config *c = data; 71 72 if (elem_size < sizeof(iov_buf)) { 73 iov_buf[0] = ((unsigned int *) elem_buf)[0]; 74 iov_buf[1] = ((unsigned int *) elem_buf)[1]; 75 iov = iov_buf; 76 } else { 77 iov = elem_buf; 78 } 79 80 tprints("{iov_base="); 81 82 len = iov[1]; 83 84 switch (c->decode_iov) { 85 case IOV_DECODE_STR: 86 if (len > c->data_size) 87 len = c->data_size; 88 if (c->data_size != (kernel_ulong_t) -1) 89 c->data_size -= len; 90 printstrn(tcp, iov[0], len); 91 break; 92 case IOV_DECODE_NETLINK: 93 if (len > c->data_size) 94 len = c->data_size; 95 if (c->data_size != (kernel_ulong_t) -1) 96 c->data_size -= len; 97 decode_netlink(tcp, iov[0], iov[1]); 98 break; 99 default: 100 printaddr(iov[0]); 101 break; 102 } 103 104 tprintf(", iov_len=%" PRI_klu "}", iov[1]); 105 106 return true; 107 } 108 109 /* 110 * data_size limits the cumulative size of printed data. 111 * Example: recvmsg returing a short read. 112 */ 113 void 114 tprint_iov_upto(struct tcb *const tcp, const kernel_ulong_t len, 115 const kernel_ulong_t addr, const enum iov_decode decode_iov, 116 const kernel_ulong_t data_size) 117 { 118 kernel_ulong_t iov[2]; 119 struct print_iovec_config config = 120 { .decode_iov = decode_iov, .data_size = data_size }; 121 122 print_array(tcp, addr, len, iov, current_wordsize * 2, 123 umoven_or_printaddr_ignore_syserror, print_iovec, &config); 124 } 125 126 SYS_FUNC(readv) 127 { 128 if (entering(tcp)) { 129 printfd(tcp, tcp->u_arg[0]); 130 tprints(", "); 131 } else { 132 tprint_iov_upto(tcp, tcp->u_arg[2], tcp->u_arg[1], 133 syserror(tcp) ? IOV_DECODE_ADDR : 134 IOV_DECODE_STR, tcp->u_rval); 135 tprintf(", %" PRI_klu, tcp->u_arg[2]); 136 } 137 return 0; 138 } 139 140 SYS_FUNC(writev) 141 { 142 printfd(tcp, tcp->u_arg[0]); 143 tprints(", "); 144 tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1], IOV_DECODE_STR); 145 tprintf(", %" PRI_klu, tcp->u_arg[2]); 146 147 return RVAL_DECODED; 148 } 149 150 SYS_FUNC(pread) 151 { 152 if (entering(tcp)) { 153 printfd(tcp, tcp->u_arg[0]); 154 tprints(", "); 155 } else { 156 if (syserror(tcp)) 157 printaddr(tcp->u_arg[1]); 158 else 159 printstrn(tcp, tcp->u_arg[1], tcp->u_rval); 160 tprintf(", %" PRI_klu ", ", tcp->u_arg[2]); 161 printllval(tcp, "%lld", 3); 162 } 163 return 0; 164 } 165 166 SYS_FUNC(pwrite) 167 { 168 printfd(tcp, tcp->u_arg[0]); 169 tprints(", "); 170 printstrn(tcp, tcp->u_arg[1], tcp->u_arg[2]); 171 tprintf(", %" PRI_klu ", ", tcp->u_arg[2]); 172 printllval(tcp, "%lld", 3); 173 174 return RVAL_DECODED; 175 } 176 177 static void 178 print_lld_from_low_high_val(struct tcb *tcp, int arg) 179 { 180 #if SIZEOF_KERNEL_LONG_T > 4 181 # ifndef current_klongsize 182 if (current_klongsize < SIZEOF_KERNEL_LONG_T) { 183 tprintf("%" PRI_kld, (tcp->u_arg[arg + 1] << 32) 184 | tcp->u_arg[arg]); 185 } else 186 # endif /* !current_klongsize */ 187 { 188 tprintf("%" PRI_kld, tcp->u_arg[arg]); 189 } 190 #else /* SIZEOF_KERNEL_LONG_T == 4 */ 191 tprintf("%lld", 192 ((long long) tcp->u_arg[arg + 1] << 32) 193 | ((long long) tcp->u_arg[arg])); 194 #endif 195 } 196 197 #include "xlat/rwf_flags.h" 198 199 static int 200 do_preadv(struct tcb *tcp, const int flags_arg) 201 { 202 if (entering(tcp)) { 203 printfd(tcp, tcp->u_arg[0]); 204 tprints(", "); 205 } else { 206 kernel_ulong_t len = 207 truncate_kulong_to_current_wordsize(tcp->u_arg[2]); 208 209 tprint_iov_upto(tcp, len, tcp->u_arg[1], 210 syserror(tcp) ? IOV_DECODE_ADDR : 211 IOV_DECODE_STR, tcp->u_rval); 212 tprintf(", %" PRI_klu ", ", len); 213 print_lld_from_low_high_val(tcp, 3); 214 if (flags_arg >= 0) { 215 tprints(", "); 216 printflags(rwf_flags, tcp->u_arg[flags_arg], "RWF_???"); 217 } 218 } 219 return 0; 220 } 221 222 SYS_FUNC(preadv) 223 { 224 return do_preadv(tcp, -1); 225 } 226 227 SYS_FUNC(preadv2) 228 { 229 return do_preadv(tcp, 5); 230 } 231 232 static int 233 do_pwritev(struct tcb *tcp, const int flags_arg) 234 { 235 kernel_ulong_t len = 236 truncate_kulong_to_current_wordsize(tcp->u_arg[2]); 237 238 printfd(tcp, tcp->u_arg[0]); 239 tprints(", "); 240 tprint_iov(tcp, len, tcp->u_arg[1], IOV_DECODE_STR); 241 tprintf(", %" PRI_klu ", ", len); 242 print_lld_from_low_high_val(tcp, 3); 243 if (flags_arg >= 0) { 244 tprints(", "); 245 printflags(rwf_flags, tcp->u_arg[flags_arg], "RWF_???"); 246 } 247 248 return RVAL_DECODED; 249 } 250 251 SYS_FUNC(pwritev) 252 { 253 return do_pwritev(tcp, -1); 254 } 255 256 SYS_FUNC(pwritev2) 257 { 258 return do_pwritev(tcp, 5); 259 } 260 261 #include "xlat/splice_flags.h" 262 263 SYS_FUNC(tee) 264 { 265 /* int fd_in */ 266 printfd(tcp, tcp->u_arg[0]); 267 tprints(", "); 268 /* int fd_out */ 269 printfd(tcp, tcp->u_arg[1]); 270 tprints(", "); 271 /* size_t len */ 272 tprintf("%" PRI_klu ", ", tcp->u_arg[2]); 273 /* unsigned int flags */ 274 printflags(splice_flags, tcp->u_arg[3], "SPLICE_F_???"); 275 276 return RVAL_DECODED; 277 } 278 279 SYS_FUNC(splice) 280 { 281 /* int fd_in */ 282 printfd(tcp, tcp->u_arg[0]); 283 tprints(", "); 284 /* loff_t *off_in */ 285 printnum_int64(tcp, tcp->u_arg[1], "%" PRId64); 286 tprints(", "); 287 /* int fd_out */ 288 printfd(tcp, tcp->u_arg[2]); 289 tprints(", "); 290 /* loff_t *off_out */ 291 printnum_int64(tcp, tcp->u_arg[3], "%" PRId64); 292 tprints(", "); 293 /* size_t len */ 294 tprintf("%" PRI_klu ", ", tcp->u_arg[4]); 295 /* unsigned int flags */ 296 printflags(splice_flags, tcp->u_arg[5], "SPLICE_F_???"); 297 298 return RVAL_DECODED; 299 } 300 301 SYS_FUNC(vmsplice) 302 { 303 /* int fd */ 304 printfd(tcp, tcp->u_arg[0]); 305 tprints(", "); 306 /* const struct iovec *iov, unsigned long nr_segs */ 307 tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1], IOV_DECODE_STR); 308 tprintf(", %" PRI_klu ", ", tcp->u_arg[2]); 309 /* unsigned int flags */ 310 printflags(splice_flags, tcp->u_arg[3], "SPLICE_F_???"); 311 312 return RVAL_DECODED; 313 } 314