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 printstr(tcp, tcp->u_arg[1], tcp->u_rval); 45 tprintf(", %lu", 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 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); 55 tprintf(", %lu", tcp->u_arg[2]); 56 57 return RVAL_DECODED; 58 } 59 60 /* 61 * data_size limits the cumulative size of printed data. 62 * Example: recvmsg returing a short read. 63 */ 64 void 65 tprint_iov_upto(struct tcb *tcp, unsigned long len, unsigned long addr, int decode_iov, unsigned long data_size) 66 { 67 unsigned long iov[2]; 68 unsigned long size, cur, end, abbrev_end; 69 const unsigned long sizeof_iov = current_wordsize * 2; 70 71 if (!len) { 72 tprints("[]"); 73 return; 74 } 75 size = len * sizeof_iov; 76 end = addr + size; 77 if (!verbose(tcp) || (exiting(tcp) && syserror(tcp)) || 78 !addr || size / sizeof_iov != len || end < addr) { 79 printaddr(addr); 80 return; 81 } 82 if (abbrev(tcp)) { 83 abbrev_end = addr + max_strlen * sizeof_iov; 84 if (abbrev_end < addr) 85 abbrev_end = end; 86 } else { 87 abbrev_end = end; 88 } 89 tprints("["); 90 for (cur = addr; cur < end; cur += sizeof_iov) { 91 if (cur > addr) 92 tprints(", "); 93 if (cur >= abbrev_end) { 94 tprints("..."); 95 break; 96 } 97 if (umove_ulong_array_or_printaddr(tcp, cur, iov, 98 ARRAY_SIZE(iov))) 99 break; 100 tprints("{"); 101 if (decode_iov) { 102 unsigned long len = iov[1]; 103 if (len > data_size) 104 len = data_size; 105 data_size -= len; 106 printstr(tcp, iov[0], len); 107 } else 108 printaddr(iov[0]); 109 tprintf(", %lu}", iov[1]); 110 } 111 tprints("]"); 112 } 113 114 void 115 tprint_iov(struct tcb *tcp, unsigned long len, unsigned long addr, int decode_iov) 116 { 117 tprint_iov_upto(tcp, len, addr, decode_iov, (unsigned long) -1L); 118 } 119 120 SYS_FUNC(readv) 121 { 122 if (entering(tcp)) { 123 printfd(tcp, tcp->u_arg[0]); 124 tprints(", "); 125 } else { 126 tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1], 1); 127 tprintf(", %lu", tcp->u_arg[2]); 128 } 129 return 0; 130 } 131 132 SYS_FUNC(writev) 133 { 134 printfd(tcp, tcp->u_arg[0]); 135 tprints(", "); 136 tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1], 1); 137 tprintf(", %lu", tcp->u_arg[2]); 138 139 return RVAL_DECODED; 140 } 141 142 /* The SH4 ABI does allow long longs in odd-numbered registers, but 143 does not allow them to be split between registers and memory - and 144 there are only four argument registers for normal functions. As a 145 result pread takes an extra padding argument before the offset. This 146 was changed late in the 2.4 series (around 2.4.20). */ 147 #if defined(SH) 148 #define PREAD_OFFSET_ARG 4 149 #else 150 #define PREAD_OFFSET_ARG 3 151 #endif 152 153 SYS_FUNC(pread) 154 { 155 if (entering(tcp)) { 156 printfd(tcp, tcp->u_arg[0]); 157 tprints(", "); 158 } else { 159 if (syserror(tcp)) 160 printaddr(tcp->u_arg[1]); 161 else 162 printstr(tcp, tcp->u_arg[1], tcp->u_rval); 163 tprintf(", %lu, ", tcp->u_arg[2]); 164 printllval(tcp, "%llu", PREAD_OFFSET_ARG); 165 } 166 return 0; 167 } 168 169 SYS_FUNC(pwrite) 170 { 171 printfd(tcp, tcp->u_arg[0]); 172 tprints(", "); 173 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); 174 tprintf(", %lu, ", tcp->u_arg[2]); 175 printllval(tcp, "%llu", PREAD_OFFSET_ARG); 176 177 return RVAL_DECODED; 178 } 179 180 static void 181 print_llu_from_low_high_val(struct tcb *tcp, int arg) 182 { 183 #if SIZEOF_LONG == SIZEOF_LONG_LONG 184 # if SUPPORTED_PERSONALITIES > 1 185 # ifdef X86_64 186 if (current_personality != 1) 187 # else 188 if (current_wordsize == sizeof(long)) 189 # endif 190 # endif 191 tprintf("%lu", (unsigned long) tcp->u_arg[arg]); 192 # if SUPPORTED_PERSONALITIES > 1 193 else 194 tprintf("%lu", 195 ((unsigned long) tcp->u_arg[arg + 1] << current_wordsize * 8) 196 | (unsigned long) tcp->u_arg[arg]); 197 # endif 198 #else 199 # ifdef X32 200 if (current_personality == 0) 201 tprintf("%llu", (unsigned long long) tcp->ext_arg[arg]); 202 else 203 # endif 204 tprintf("%llu", 205 ((unsigned long long) (unsigned long) tcp->u_arg[arg + 1] << sizeof(long) * 8) 206 | (unsigned long long) (unsigned long) tcp->u_arg[arg]); 207 #endif 208 } 209 210 SYS_FUNC(preadv) 211 { 212 if (entering(tcp)) { 213 printfd(tcp, tcp->u_arg[0]); 214 tprints(", "); 215 } else { 216 tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1], 1); 217 tprintf(", %lu, ", tcp->u_arg[2]); 218 print_llu_from_low_high_val(tcp, 3); 219 } 220 return 0; 221 } 222 223 SYS_FUNC(pwritev) 224 { 225 printfd(tcp, tcp->u_arg[0]); 226 tprints(", "); 227 tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1], 1); 228 tprintf(", %lu, ", tcp->u_arg[2]); 229 print_llu_from_low_high_val(tcp, 3); 230 231 return RVAL_DECODED; 232 } 233 234 #include "xlat/splice_flags.h" 235 236 SYS_FUNC(tee) 237 { 238 /* int fd_in */ 239 printfd(tcp, tcp->u_arg[0]); 240 tprints(", "); 241 /* int fd_out */ 242 printfd(tcp, tcp->u_arg[1]); 243 tprints(", "); 244 /* size_t len */ 245 tprintf("%lu, ", tcp->u_arg[2]); 246 /* unsigned int flags */ 247 printflags(splice_flags, tcp->u_arg[3], "SPLICE_F_???"); 248 249 return RVAL_DECODED; 250 } 251 252 SYS_FUNC(splice) 253 { 254 /* int fd_in */ 255 printfd(tcp, tcp->u_arg[0]); 256 tprints(", "); 257 /* loff_t *off_in */ 258 printnum_int64(tcp, tcp->u_arg[1], "%" PRIu64); 259 tprints(", "); 260 /* int fd_out */ 261 printfd(tcp, tcp->u_arg[2]); 262 tprints(", "); 263 /* loff_t *off_out */ 264 printnum_int64(tcp, tcp->u_arg[3], "%" PRIu64); 265 tprints(", "); 266 /* size_t len */ 267 tprintf("%lu, ", tcp->u_arg[4]); 268 /* unsigned int flags */ 269 printflags(splice_flags, tcp->u_arg[5], "SPLICE_F_???"); 270 271 return RVAL_DECODED; 272 } 273 274 SYS_FUNC(vmsplice) 275 { 276 /* int fd */ 277 printfd(tcp, tcp->u_arg[0]); 278 tprints(", "); 279 /* const struct iovec *iov, unsigned long nr_segs */ 280 tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1], 1); 281 tprintf(", %lu, ", tcp->u_arg[2]); 282 /* unsigned int flags */ 283 printflags(splice_flags, tcp->u_arg[3], "SPLICE_F_???"); 284 285 return RVAL_DECODED; 286 } 287