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 33 /* --- Copied from libaio-0.3.109/src/libaio.h --- 34 * Why keep a copy instead of using external libaio.h? 35 * Because we want to properly decode 32-bit aio calls 36 * by 64-bit strace. For that, we need more definitions than 37 * libaio.h provides. (TODO). 38 * Keeping our local 32-bit compat defs in sync with libaio.h 39 * _without seeing libaio structs_ is hard/more bug-prone. 40 * A smaller benefit is that we don't need libaio installed. 41 */ 42 #define HAVE_LIBAIO_H 1 43 typedef enum io_iocb_cmd { 44 IO_CMD_PREAD = 0, 45 IO_CMD_PWRITE = 1, 46 47 IO_CMD_FSYNC = 2, 48 IO_CMD_FDSYNC = 3, 49 50 IO_CMD_POLL = 5, /* Never implemented in mainline, see io_prep_poll */ 51 IO_CMD_NOOP = 6, 52 IO_CMD_PREADV = 7, 53 IO_CMD_PWRITEV = 8, 54 } io_iocb_cmd_t; 55 56 #if defined(__i386__) /* little endian, 32 bits */ 57 #define PADDED(x, y) x; unsigned y 58 #define PADDEDptr(x, y) x; unsigned y 59 #define PADDEDul(x, y) unsigned long x; unsigned y 60 #elif defined(__ia64__) || defined(__x86_64__) || defined(__alpha__) 61 #define PADDED(x, y) x, y 62 #define PADDEDptr(x, y) x 63 #define PADDEDul(x, y) unsigned long x 64 #elif defined(__powerpc64__) /* big endian, 64 bits */ 65 #define PADDED(x, y) unsigned y; x 66 #define PADDEDptr(x,y) x 67 #define PADDEDul(x, y) unsigned long x 68 #elif defined(__PPC__) /* big endian, 32 bits */ 69 #define PADDED(x, y) unsigned y; x 70 #define PADDEDptr(x, y) unsigned y; x 71 #define PADDEDul(x, y) unsigned y; unsigned long x 72 #elif defined(__s390x__) /* big endian, 64 bits */ 73 #define PADDED(x, y) unsigned y; x 74 #define PADDEDptr(x,y) x 75 #define PADDEDul(x, y) unsigned long x 76 #elif defined(__s390__) /* big endian, 32 bits */ 77 #define PADDED(x, y) unsigned y; x 78 #define PADDEDptr(x, y) unsigned y; x 79 #define PADDEDul(x, y) unsigned y; unsigned long x 80 #elif defined(__arm__) 81 # if defined (__ARMEB__) /* big endian, 32 bits */ 82 #define PADDED(x, y) unsigned y; x 83 #define PADDEDptr(x, y) unsigned y; x 84 #define PADDEDul(x, y) unsigned y; unsigned long x 85 # else /* little endian, 32 bits */ 86 #define PADDED(x, y) x; unsigned y 87 #define PADDEDptr(x, y) x; unsigned y 88 #define PADDEDul(x, y) unsigned long x; unsigned y 89 # endif 90 #else 91 # warning No AIO definitions for this architecture => no io_submit decoding 92 # undef HAVE_LIBAIO_H 93 #endif 94 95 #ifdef HAVE_LIBAIO_H 96 struct io_iocb_poll { 97 PADDED(int events, __pad1); 98 }; /* result code is the set of result flags or -'ve errno */ 99 100 struct io_iocb_sockaddr { 101 struct sockaddr *addr; 102 int len; 103 }; /* result code is the length of the sockaddr, or -'ve errno */ 104 105 struct io_iocb_common { 106 PADDEDptr(void *buf, __pad1); 107 PADDEDul(nbytes, __pad2); 108 long long offset; 109 long long __pad3; 110 unsigned flags; 111 unsigned resfd; 112 }; /* result code is the amount read or -'ve errno */ 113 114 struct io_iocb_vector { 115 const struct iovec *vec; 116 int nr; 117 long long offset; 118 }; /* result code is the amount read or -'ve errno */ 119 120 struct iocb { 121 PADDEDptr(void *data, __pad1); /* Return in the io completion event */ 122 PADDED(unsigned key, __pad2); /* For use in identifying io requests */ 123 124 short aio_lio_opcode; 125 short aio_reqprio; 126 int aio_fildes; 127 128 union { 129 struct io_iocb_common c; 130 struct io_iocb_vector v; 131 struct io_iocb_poll poll; 132 struct io_iocb_sockaddr saddr; 133 } u; 134 }; 135 136 struct io_event { 137 PADDEDptr(void *data, __pad1); 138 PADDEDptr(struct iocb *obj, __pad2); 139 PADDEDul(res, __pad3); 140 PADDEDul(res2, __pad4); 141 }; 142 143 #undef PADDED 144 #undef PADDEDptr 145 #undef PADDEDul 146 147 #endif /* HAVE_LIBAIO_H */ 148 149 /* --- End of a chunk of libaio.h --- */ 150 /* Not defined in libaio.h */ 151 #ifndef IOCB_RESFD 152 # define IOCB_RESFD (1 << 0) 153 #endif 154 155 int 156 sys_io_setup(struct tcb *tcp) 157 { 158 if (entering(tcp)) 159 tprintf("%ld, ", tcp->u_arg[0]); 160 else { 161 if (syserror(tcp)) 162 tprintf("0x%0lx", tcp->u_arg[1]); 163 else { 164 unsigned long user_id; 165 if (umove(tcp, tcp->u_arg[1], &user_id) == 0) 166 tprintf("{%lu}", user_id); 167 else 168 tprints("{...}"); 169 } 170 } 171 return 0; 172 } 173 174 int 175 sys_io_destroy(struct tcb *tcp) 176 { 177 if (entering(tcp)) 178 tprintf("%lu", tcp->u_arg[0]); 179 return 0; 180 } 181 182 #ifdef HAVE_LIBAIO_H 183 184 enum iocb_sub { 185 SUB_NONE, SUB_COMMON, SUB_POLL, SUB_VECTOR 186 }; 187 188 static enum iocb_sub 189 tprint_lio_opcode(unsigned cmd) 190 { 191 static const struct { 192 const char *name; 193 enum iocb_sub sub; 194 } cmds[] = { 195 { "pread", SUB_COMMON }, 196 { "pwrite", SUB_COMMON }, 197 { "fsync", SUB_NONE }, 198 { "fdsync", SUB_NONE }, 199 { "op4", SUB_NONE }, 200 { "poll", SUB_POLL }, 201 { "noop", SUB_NONE }, 202 { "preadv", SUB_VECTOR }, 203 { "pwritev", SUB_VECTOR }, 204 }; 205 206 if (cmd < ARRAY_SIZE(cmds)) { 207 tprints(cmds[cmd].name); 208 return cmds[cmd].sub; 209 } 210 tprintf("%u /* SUB_??? */", cmd); 211 return SUB_NONE; 212 } 213 214 static void 215 print_common_flags(struct iocb *iocb) 216 { 217 if (iocb->u.c.flags & IOCB_RESFD) 218 tprintf(", resfd=%d", iocb->u.c.resfd); 219 if (iocb->u.c.flags & ~IOCB_RESFD) 220 tprintf(", flags=%x", iocb->u.c.flags); 221 } 222 223 #endif /* HAVE_LIBAIO_H */ 224 225 int 226 sys_io_submit(struct tcb *tcp) 227 { 228 if (entering(tcp)) { 229 #ifdef HAVE_LIBAIO_H 230 long nr = tcp->u_arg[1]; 231 /* if nr <= 0, we end up printing just "{}" */ 232 tprintf("%lu, %ld, {", tcp->u_arg[0], tcp->u_arg[1]); 233 { 234 long i; 235 struct iocb **iocbs = (void *)tcp->u_arg[2]; 236 //FIXME: decoding of 32-bit call by 64-bit strace 237 238 for (i = 0; i < nr; i++, iocbs++) { 239 enum iocb_sub sub; 240 struct iocb *iocbp; 241 struct iocb iocb; 242 if (i) 243 tprints(", "); 244 245 if (umove(tcp, (unsigned long)iocbs, &iocbp)) { 246 tprintf("%#lx", (unsigned long)iocbs); 247 /* No point in trying to read iocbs+1 etc */ 248 /* (nr can be ridiculously large): */ 249 break; 250 } 251 if (umove(tcp, (unsigned long)iocbp, &iocb)) { 252 tprintf("{%#lx}", (unsigned long)iocbp); 253 continue; 254 } 255 tprints("{"); 256 if (iocb.data) 257 tprintf("data:%p, ", iocb.data); 258 if (iocb.key) 259 tprintf("key:%u, ", iocb.key); 260 sub = tprint_lio_opcode(iocb.aio_lio_opcode); 261 if (iocb.aio_reqprio) 262 tprintf(", reqprio:%d", iocb.aio_reqprio); 263 tprintf(", filedes:%d", iocb.aio_fildes); 264 switch (sub) { 265 case SUB_COMMON: 266 if (iocb.aio_lio_opcode == IO_CMD_PWRITE) { 267 tprints(", str:"); 268 printstr(tcp, (unsigned long)iocb.u.c.buf, 269 iocb.u.c.nbytes); 270 } else 271 tprintf(", buf:%p", iocb.u.c.buf); 272 tprintf(", nbytes:%lu, offset:%lld", 273 iocb.u.c.nbytes, 274 iocb.u.c.offset); 275 print_common_flags(&iocb); 276 break; 277 case SUB_VECTOR: 278 tprintf(", %lld", iocb.u.v.offset); 279 print_common_flags(&iocb); 280 tprints(", "); 281 tprint_iov(tcp, iocb.u.v.nr, 282 (unsigned long)iocb.u.v.vec, 283 iocb.aio_lio_opcode == IO_CMD_PWRITEV 284 ); 285 break; 286 case SUB_POLL: 287 tprintf(", %x", iocb.u.poll.events); 288 break; 289 case SUB_NONE: 290 break; 291 } 292 tprints("}"); 293 } 294 } 295 tprints("}"); 296 #else 297 tprintf("%lu, %ld, %#lx", tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]); 298 #endif 299 } 300 return 0; 301 } 302 303 int 304 sys_io_cancel(struct tcb *tcp) 305 { 306 if (entering(tcp)) { 307 #ifdef HAVE_LIBAIO_H 308 struct iocb iocb; 309 #endif 310 tprintf("%lu, ", tcp->u_arg[0]); 311 #ifdef HAVE_LIBAIO_H 312 if (umove(tcp, tcp->u_arg[1], &iocb) == 0) { 313 tprintf("{%p, %u, %u, %u, %d}, ", 314 iocb.data, iocb.key, 315 (unsigned)iocb.aio_lio_opcode, 316 (unsigned)iocb.aio_reqprio, iocb.aio_fildes); 317 } else 318 #endif 319 tprints("{...}, "); 320 } else { 321 if (tcp->u_rval < 0) 322 tprints("{...}"); 323 else { 324 #ifdef HAVE_LIBAIO_H 325 struct io_event event; 326 if (umove(tcp, tcp->u_arg[2], &event) == 0) 327 tprintf("{%p, %p, %ld, %ld}", 328 event.data, event.obj, 329 event.res, event.res2); 330 else 331 #endif 332 tprints("{...}"); 333 } 334 } 335 return 0; 336 } 337 338 int 339 sys_io_getevents(struct tcb *tcp) 340 { 341 if (entering(tcp)) { 342 tprintf("%ld, %ld, %ld, ", tcp->u_arg[0], tcp->u_arg[1], 343 tcp->u_arg[2]); 344 } else { 345 if (tcp->u_rval == 0) { 346 tprints("{}"); 347 } else { 348 #ifdef HAVE_LIBAIO_H 349 struct io_event *events = (void *)tcp->u_arg[3]; 350 long i, nr = tcp->u_rval; 351 352 for (i = 0; i < nr; i++, events++) { 353 struct io_event event; 354 355 if (i == 0) 356 tprints("{"); 357 else 358 tprints(", "); 359 360 if (umove(tcp, (unsigned long)events, &event) != 0) { 361 tprints("{...}"); 362 continue; 363 } 364 tprintf("{%p, %p, %ld, %ld}", event.data, 365 event.obj, event.res, event.res2); 366 } 367 tprints("}, "); 368 #else 369 tprints("{...}"); 370 #endif 371 } 372 373 print_timespec(tcp, tcp->u_arg[4]); 374 } 375 return 0; 376 } 377