1/* 2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl> 3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl> 4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com> 5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@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 * $Id$ 31 */ 32 33#include "defs.h" 34 35#include <fcntl.h> 36#if HAVE_SYS_UIO_H 37#include <sys/uio.h> 38#endif 39 40#ifdef HAVE_LONG_LONG_OFF_T 41/* 42 * Hacks for systems that have a long long off_t 43 */ 44 45#define sys_pread64 sys_pread 46#define sys_pwrite64 sys_pwrite 47#endif 48 49int 50sys_read(struct tcb *tcp) 51{ 52 if (entering(tcp)) { 53 printfd(tcp, tcp->u_arg[0]); 54 tprintf(", "); 55 } else { 56 if (syserror(tcp)) 57 tprintf("%#lx", tcp->u_arg[1]); 58 else 59 printstr(tcp, tcp->u_arg[1], tcp->u_rval); 60 tprintf(", %lu", tcp->u_arg[2]); 61 } 62 return 0; 63} 64 65int 66sys_write(struct tcb *tcp) 67{ 68 if (entering(tcp)) { 69 printfd(tcp, tcp->u_arg[0]); 70 tprintf(", "); 71 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); 72 tprintf(", %lu", tcp->u_arg[2]); 73 } 74 return 0; 75} 76 77#if HAVE_SYS_UIO_H 78void 79tprint_iov(tcp, len, addr) 80struct tcb * tcp; 81unsigned long len; 82unsigned long addr; 83{ 84#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1 85 union { 86 struct { u_int32_t base; u_int32_t len; } iov32; 87 struct { u_int64_t base; u_int64_t len; } iov64; 88 } iov; 89#define sizeof_iov \ 90 (personality_wordsize[current_personality] == 4 \ 91 ? sizeof(iov.iov32) : sizeof(iov.iov64)) 92#define iov_iov_base \ 93 (personality_wordsize[current_personality] == 4 \ 94 ? (u_int64_t) iov.iov32.base : iov.iov64.base) 95#define iov_iov_len \ 96 (personality_wordsize[current_personality] == 4 \ 97 ? (u_int64_t) iov.iov32.len : iov.iov64.len) 98#else 99 struct iovec iov; 100#define sizeof_iov sizeof(iov) 101#define iov_iov_base iov.iov_base 102#define iov_iov_len iov.iov_len 103#endif 104 unsigned long size, cur, end, abbrev_end; 105 int failed = 0; 106 107 if (!len) { 108 tprintf("[]"); 109 return; 110 } 111 size = len * sizeof_iov; 112 end = addr + size; 113 if (!verbose(tcp) || size / sizeof_iov != len || end < addr) { 114 tprintf("%#lx", addr); 115 return; 116 } 117 if (abbrev(tcp)) { 118 abbrev_end = addr + max_strlen * sizeof_iov; 119 if (abbrev_end < addr) 120 abbrev_end = end; 121 } else { 122 abbrev_end = end; 123 } 124 tprintf("["); 125 for (cur = addr; cur < end; cur += sizeof_iov) { 126 if (cur > addr) 127 tprintf(", "); 128 if (cur >= abbrev_end) { 129 tprintf("..."); 130 break; 131 } 132 if (umoven(tcp, cur, sizeof_iov, (char *) &iov) < 0) { 133 tprintf("?"); 134 failed = 1; 135 break; 136 } 137 tprintf("{"); 138 printstr(tcp, (long) iov_iov_base, iov_iov_len); 139 tprintf(", %lu}", (unsigned long)iov_iov_len); 140 } 141 tprintf("]"); 142 if (failed) 143 tprintf(" %#lx", addr); 144#undef sizeof_iov 145#undef iov_iov_base 146#undef iov_iov_len 147} 148 149int 150sys_readv(struct tcb *tcp) 151{ 152 if (entering(tcp)) { 153 printfd(tcp, tcp->u_arg[0]); 154 tprintf(", "); 155 } else { 156 if (syserror(tcp)) { 157 tprintf("%#lx, %lu", 158 tcp->u_arg[1], tcp->u_arg[2]); 159 return 0; 160 } 161 tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1]); 162 tprintf(", %lu", tcp->u_arg[2]); 163 } 164 return 0; 165} 166 167int 168sys_writev(struct tcb *tcp) 169{ 170 if (entering(tcp)) { 171 printfd(tcp, tcp->u_arg[0]); 172 tprintf(", "); 173 tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1]); 174 tprintf(", %lu", tcp->u_arg[2]); 175 } 176 return 0; 177} 178#endif 179 180#if defined(SVR4) 181 182int 183sys_pread(struct tcb *tcp) 184{ 185 if (entering(tcp)) { 186 printfd(tcp, tcp->u_arg[0]); 187 tprintf(", "); 188 } else { 189 if (syserror(tcp)) 190 tprintf("%#lx", tcp->u_arg[1]); 191 else 192 printstr(tcp, tcp->u_arg[1], tcp->u_rval); 193#if UNIXWARE 194 /* off_t is signed int */ 195 tprintf(", %lu, %ld", tcp->u_arg[2], tcp->u_arg[3]); 196#else 197 tprintf(", %lu, %llu", tcp->u_arg[2], 198 LONG_LONG(tcp->u_arg[3], tcp->u_arg[4])); 199#endif 200 } 201 return 0; 202} 203 204int 205sys_pwrite(struct tcb *tcp) 206{ 207 if (entering(tcp)) { 208 printfd(tcp, tcp->u_arg[0]); 209 tprintf(", "); 210 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); 211#if UNIXWARE 212 /* off_t is signed int */ 213 tprintf(", %lu, %ld", tcp->u_arg[2], tcp->u_arg[3]); 214#else 215 tprintf(", %lu, %llu", tcp->u_arg[2], 216 LONG_LONG(tcp->u_arg[3], tcp->u_arg[4])); 217#endif 218 } 219 return 0; 220} 221#endif /* SVR4 */ 222 223#ifdef FREEBSD 224#include <sys/types.h> 225#include <sys/socket.h> 226 227int 228sys_sendfile(struct tcb *tcp) 229{ 230 if (entering(tcp)) { 231 printfd(tcp, tcp->u_arg[0]); 232 tprintf(", "); 233 printfd(tcp, tcp->u_arg[1]); 234 tprintf(", %llu, %lu", 235 LONG_LONG(tcp->u_arg[2], tcp->u_arg[3]), 236 tcp->u_arg[4]); 237 } else { 238 off_t offset; 239 240 if (!tcp->u_arg[5]) 241 tprintf(", NULL"); 242 else { 243 struct sf_hdtr hdtr; 244 245 if (umove(tcp, tcp->u_arg[5], &hdtr) < 0) 246 tprintf(", %#lx", tcp->u_arg[5]); 247 else { 248 tprintf(", { "); 249 tprint_iov(tcp, hdtr.hdr_cnt, hdtr.headers); 250 tprintf(", %u, ", hdtr.hdr_cnt); 251 tprint_iov(tcp, hdtr.trl_cnt, hdtr.trailers); 252 tprintf(", %u }", hdtr.hdr_cnt); 253 } 254 } 255 if (!tcp->u_arg[6]) 256 tprintf(", NULL"); 257 else if (umove(tcp, tcp->u_arg[6], &offset) < 0) 258 tprintf(", %#lx", tcp->u_arg[6]); 259 else 260 tprintf(", [%llu]", offset); 261 tprintf(", %lu", tcp->u_arg[7]); 262 } 263 return 0; 264} 265#endif /* FREEBSD */ 266 267#ifdef LINUX 268 269/* The SH4 ABI does allow long longs in odd-numbered registers, but 270 does not allow them to be split between registers and memory - and 271 there are only four argument registers for normal functions. As a 272 result pread takes an extra padding argument before the offset. This 273 was changed late in the 2.4 series (around 2.4.20). */ 274#if defined(SH) 275#define PREAD_OFFSET_ARG 4 276#else 277#define PREAD_OFFSET_ARG 3 278#endif 279 280int 281sys_pread(struct tcb *tcp) 282{ 283 if (entering(tcp)) { 284 printfd(tcp, tcp->u_arg[0]); 285 tprintf(", "); 286 } else { 287 if (syserror(tcp)) 288 tprintf("%#lx", tcp->u_arg[1]); 289 else 290 printstr(tcp, tcp->u_arg[1], tcp->u_rval); 291 tprintf(", %lu, ", tcp->u_arg[2]); 292 printllval(tcp, "%llu", PREAD_OFFSET_ARG); 293 } 294 return 0; 295} 296 297int 298sys_pwrite(struct tcb *tcp) 299{ 300 if (entering(tcp)) { 301 printfd(tcp, tcp->u_arg[0]); 302 tprintf(", "); 303 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); 304 tprintf(", %lu, ", tcp->u_arg[2]); 305 printllval(tcp, "%llu", PREAD_OFFSET_ARG); 306 } 307 return 0; 308} 309 310int 311sys_sendfile(struct tcb *tcp) 312{ 313 if (entering(tcp)) { 314 off_t offset; 315 316 printfd(tcp, tcp->u_arg[0]); 317 tprintf(", "); 318 printfd(tcp, tcp->u_arg[1]); 319 tprintf(", "); 320 if (!tcp->u_arg[2]) 321 tprintf("NULL"); 322 else if (umove(tcp, tcp->u_arg[2], &offset) < 0) 323 tprintf("%#lx", tcp->u_arg[2]); 324 else 325 tprintf("[%lu]", offset); 326 tprintf(", %lu", tcp->u_arg[3]); 327 } 328 return 0; 329} 330 331int 332sys_sendfile64(struct tcb *tcp) 333{ 334 if (entering(tcp)) { 335 loff_t offset; 336 337 printfd(tcp, tcp->u_arg[0]); 338 tprintf(", "); 339 printfd(tcp, tcp->u_arg[1]); 340 tprintf(", "); 341 if (!tcp->u_arg[2]) 342 tprintf("NULL"); 343 else if (umove(tcp, tcp->u_arg[2], &offset) < 0) 344 tprintf("%#lx", tcp->u_arg[2]); 345 else 346 tprintf("[%llu]", (unsigned long long int) offset); 347 tprintf(", %lu", tcp->u_arg[3]); 348 } 349 return 0; 350} 351 352#endif /* LINUX */ 353 354#if _LFS64_LARGEFILE || HAVE_LONG_LONG_OFF_T 355int 356sys_pread64(struct tcb *tcp) 357{ 358 if (entering(tcp)) { 359 printfd(tcp, tcp->u_arg[0]); 360 tprintf(", "); 361 } else { 362 if (syserror(tcp)) 363 tprintf("%#lx", tcp->u_arg[1]); 364 else 365 printstr(tcp, tcp->u_arg[1], tcp->u_rval); 366 tprintf(", %lu, ", tcp->u_arg[2]); 367 printllval(tcp, "%#llx", 3); 368 } 369 return 0; 370} 371 372int 373sys_pwrite64(struct tcb *tcp) 374{ 375 if (entering(tcp)) { 376 printfd(tcp, tcp->u_arg[0]); 377 tprintf(", "); 378 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); 379 tprintf(", %lu, ", tcp->u_arg[2]); 380 printllval(tcp, "%#llx", 3); 381 } 382 return 0; 383} 384#endif 385 386int 387sys_ioctl(struct tcb *tcp) 388{ 389 const struct ioctlent *iop; 390 391 if (entering(tcp)) { 392 printfd(tcp, tcp->u_arg[0]); 393 tprintf(", "); 394 iop = ioctl_lookup(tcp->u_arg[1]); 395 if (iop) { 396 tprintf("%s", iop->symbol); 397 while ((iop = ioctl_next_match(iop))) 398 tprintf(" or %s", iop->symbol); 399 } else 400 tprintf("%#lx", tcp->u_arg[1]); 401 ioctl_decode(tcp, tcp->u_arg[1], tcp->u_arg[2]); 402 } 403 else { 404 int ret; 405 if (!(ret = ioctl_decode(tcp, tcp->u_arg[1], tcp->u_arg[2]))) 406 tprintf(", %#lx", tcp->u_arg[2]); 407 else 408 return ret - 1; 409 } 410 return 0; 411} 412