Branch data Line data Source code
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 : :
31 : : #include "defs.h"
32 : : #include <fcntl.h>
33 : : #include <sys/uio.h>
34 : :
35 : 492 : SYS_FUNC(read)
36 : : {
37 [ + + ]: 492 : if (entering(tcp)) {
38 : 246 : printfd(tcp, tcp->u_arg[0]);
39 : 246 : tprints(", ");
40 : : } else {
41 [ + + ]: 246 : if (syserror(tcp))
42 : 6 : printaddr(tcp->u_arg[1]);
43 : : else
44 : 240 : printstrn(tcp, tcp->u_arg[1], tcp->u_rval);
45 : 246 : tprintf(", %" PRI_klu, tcp->u_arg[2]);
46 : : }
47 : 492 : return 0;
48 : : }
49 : :
50 : 222 : SYS_FUNC(write)
51 : : {
52 : 222 : printfd(tcp, tcp->u_arg[0]);
53 : 222 : tprints(", ");
54 : 222 : printstrn(tcp, tcp->u_arg[1], tcp->u_arg[2]);
55 : 222 : tprintf(", %" PRI_klu, tcp->u_arg[2]);
56 : :
57 : 222 : 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 : 43830 : 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 : 43830 : struct print_iovec_config *c = data;
71 : :
72 [ + + ]: 43830 : if (elem_size < sizeof(iov_buf)) {
73 : 5177 : iov_buf[0] = ((unsigned int *) elem_buf)[0];
74 : 5177 : iov_buf[1] = ((unsigned int *) elem_buf)[1];
75 : 5177 : iov = iov_buf;
76 : : } else {
77 : 38653 : iov = elem_buf;
78 : : }
79 : :
80 : 43830 : tprints("{iov_base=");
81 : :
82 : 43830 : len = iov[1];
83 : :
84 [ + - + ]: 43830 : switch (c->decode_iov) {
85 : : case IOV_DECODE_STR:
86 [ + + ]: 43536 : if (len > c->data_size)
87 : 162 : len = c->data_size;
88 [ + + ]: 43536 : if (c->data_size != (kernel_ulong_t) -1)
89 : 2202 : c->data_size -= len;
90 : 43536 : printstrn(tcp, iov[0], len);
91 : 43536 : break;
92 : : case IOV_DECODE_NETLINK:
93 [ # # ]: 0 : if (len > c->data_size)
94 : 0 : len = c->data_size;
95 [ # # ]: 0 : if (c->data_size != (kernel_ulong_t) -1)
96 : 0 : c->data_size -= len;
97 : 0 : decode_netlink(tcp, iov[0], iov[1]);
98 : 0 : break;
99 : : default:
100 : 294 : printaddr(iov[0]);
101 : 294 : break;
102 : : }
103 : :
104 : 43830 : tprintf(", iov_len=%" PRI_klu "}", iov[1]);
105 : :
106 : 43830 : 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 : 255258 : 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 : 255258 : struct print_iovec_config config =
120 : : { .decode_iov = decode_iov, .data_size = data_size };
121 : :
122 : 255258 : print_array(tcp, addr, len, iov, current_wordsize * 2,
123 : : umoven_or_printaddr_ignore_syserror, print_iovec, &config);
124 : 255258 : }
125 : :
126 : 252 : SYS_FUNC(readv)
127 : : {
128 [ + + ]: 252 : if (entering(tcp)) {
129 : 126 : printfd(tcp, tcp->u_arg[0]);
130 : 126 : tprints(", ");
131 : : } else {
132 : 126 : tprint_iov_upto(tcp, tcp->u_arg[2], tcp->u_arg[1],
133 : 126 : syserror(tcp) ? IOV_DECODE_ADDR :
134 : 126 : IOV_DECODE_STR, tcp->u_rval);
135 : 126 : tprintf(", %" PRI_klu, tcp->u_arg[2]);
136 : : }
137 : 252 : return 0;
138 : : }
139 : :
140 : 27924 : SYS_FUNC(writev)
141 : : {
142 : 27924 : printfd(tcp, tcp->u_arg[0]);
143 : 27924 : tprints(", ");
144 : 27924 : tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1], IOV_DECODE_STR);
145 : 27924 : tprintf(", %" PRI_klu, tcp->u_arg[2]);
146 : :
147 : 27924 : return RVAL_DECODED;
148 : : }
149 : :
150 : 468 : SYS_FUNC(pread)
151 : : {
152 [ + + ]: 468 : if (entering(tcp)) {
153 : 234 : printfd(tcp, tcp->u_arg[0]);
154 : 234 : tprints(", ");
155 : : } else {
156 [ + + ]: 234 : if (syserror(tcp))
157 : 12 : printaddr(tcp->u_arg[1]);
158 : : else
159 : 222 : printstrn(tcp, tcp->u_arg[1], tcp->u_rval);
160 : 234 : tprintf(", %" PRI_klu ", ", tcp->u_arg[2]);
161 : 234 : printllval(tcp, "%lld", 3);
162 : : }
163 : 468 : return 0;
164 : : }
165 : :
166 : 228 : SYS_FUNC(pwrite)
167 : : {
168 : 228 : printfd(tcp, tcp->u_arg[0]);
169 : 228 : tprints(", ");
170 : 228 : printstrn(tcp, tcp->u_arg[1], tcp->u_arg[2]);
171 : 228 : tprintf(", %" PRI_klu ", ", tcp->u_arg[2]);
172 : 228 : printllval(tcp, "%lld", 3);
173 : :
174 : 228 : return RVAL_DECODED;
175 : : }
176 : :
177 : : static void
178 : 258 : print_lld_from_low_high_val(struct tcb *tcp, int arg)
179 : : {
180 : : #if SIZEOF_KERNEL_LONG_T > 4
181 : : # ifndef current_klongsize
182 [ + + ]: 258 : if (current_klongsize < SIZEOF_KERNEL_LONG_T) {
183 : 43 : tprintf("%" PRI_kld, (tcp->u_arg[arg + 1] << 32)
184 : 43 : | tcp->u_arg[arg]);
185 : : } else
186 : : # endif /* !current_klongsize */
187 : : {
188 : 215 : 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 : 258 : }
196 : :
197 : : #include "xlat/rwf_flags.h"
198 : :
199 : : static int
200 : 156 : do_preadv(struct tcb *tcp, const int flags_arg)
201 : : {
202 [ + + ]: 156 : if (entering(tcp)) {
203 : 78 : printfd(tcp, tcp->u_arg[0]);
204 : 78 : tprints(", ");
205 : : } else {
206 : 78 : kernel_ulong_t len =
207 : 78 : truncate_kulong_to_current_wordsize(tcp->u_arg[2]);
208 : :
209 : 78 : tprint_iov_upto(tcp, len, tcp->u_arg[1],
210 : 78 : syserror(tcp) ? IOV_DECODE_ADDR :
211 : 78 : IOV_DECODE_STR, tcp->u_rval);
212 : 78 : tprintf(", %" PRI_klu ", ", len);
213 : 78 : print_lld_from_low_high_val(tcp, 3);
214 [ + + ]: 78 : if (flags_arg >= 0) {
215 : 18 : tprints(", ");
216 : 18 : printflags(rwf_flags, tcp->u_arg[flags_arg], "RWF_???");
217 : : }
218 : : }
219 : 156 : return 0;
220 : : }
221 : :
222 : 120 : SYS_FUNC(preadv)
223 : : {
224 : 120 : return do_preadv(tcp, -1);
225 : : }
226 : :
227 : : static int
228 : 180 : do_pwritev(struct tcb *tcp, const int flags_arg)
229 : : {
230 : 180 : kernel_ulong_t len =
231 : 180 : truncate_kulong_to_current_wordsize(tcp->u_arg[2]);
232 : :
233 : 180 : printfd(tcp, tcp->u_arg[0]);
234 : 180 : tprints(", ");
235 : 180 : tprint_iov(tcp, len, tcp->u_arg[1], IOV_DECODE_STR);
236 : 180 : tprintf(", %" PRI_klu ", ", len);
237 : 180 : print_lld_from_low_high_val(tcp, 3);
238 [ + + ]: 180 : if (flags_arg >= 0) {
239 : 24 : tprints(", ");
240 : 24 : printflags(rwf_flags, tcp->u_arg[flags_arg], "RWF_???");
241 : : }
242 : :
243 : 180 : return RVAL_DECODED;
244 : : }
245 : :
246 : 156 : SYS_FUNC(pwritev)
247 : : {
248 : 156 : return do_pwritev(tcp, -1);
249 : : }
250 : :
251 : : /*
252 : : * x32 is the only architecture where preadv2 takes 5 arguments
253 : : * instead of 6, see preadv64v2 in kernel sources.
254 : : * Likewise, x32 is the only architecture where pwritev2 takes 5 arguments
255 : : * instead of 6, see pwritev64v2 in kernel sources.
256 : : */
257 : :
258 : : #if defined X86_64
259 : : # define PREADV2_PWRITEV2_FLAGS_ARG_NO (current_personality == 2 ? 4 : 5)
260 : : #elif defined X32
261 : : # define PREADV2_PWRITEV2_FLAGS_ARG_NO (current_personality == 0 ? 4 : 5)
262 : : #else
263 : : # define PREADV2_PWRITEV2_FLAGS_ARG_NO 5
264 : : #endif
265 : :
266 : 36 : SYS_FUNC(preadv2)
267 : : {
268 [ - + ]: 36 : return do_preadv(tcp, PREADV2_PWRITEV2_FLAGS_ARG_NO);
269 : : }
270 : :
271 : 24 : SYS_FUNC(pwritev2)
272 : : {
273 [ - + ]: 24 : return do_pwritev(tcp, PREADV2_PWRITEV2_FLAGS_ARG_NO);
274 : : }
275 : :
276 : : #include "xlat/splice_flags.h"
277 : :
278 : 6 : SYS_FUNC(tee)
279 : : {
280 : : /* int fd_in */
281 : 6 : printfd(tcp, tcp->u_arg[0]);
282 : 6 : tprints(", ");
283 : : /* int fd_out */
284 : 6 : printfd(tcp, tcp->u_arg[1]);
285 : 6 : tprints(", ");
286 : : /* size_t len */
287 : 6 : tprintf("%" PRI_klu ", ", tcp->u_arg[2]);
288 : : /* unsigned int flags */
289 : 6 : printflags(splice_flags, tcp->u_arg[3], "SPLICE_F_???");
290 : :
291 : 6 : return RVAL_DECODED;
292 : : }
293 : :
294 : 6 : SYS_FUNC(splice)
295 : : {
296 : : /* int fd_in */
297 : 6 : printfd(tcp, tcp->u_arg[0]);
298 : 6 : tprints(", ");
299 : : /* loff_t *off_in */
300 : 6 : printnum_int64(tcp, tcp->u_arg[1], "%" PRId64);
301 : 6 : tprints(", ");
302 : : /* int fd_out */
303 : 6 : printfd(tcp, tcp->u_arg[2]);
304 : 6 : tprints(", ");
305 : : /* loff_t *off_out */
306 : 6 : printnum_int64(tcp, tcp->u_arg[3], "%" PRId64);
307 : 6 : tprints(", ");
308 : : /* size_t len */
309 : 6 : tprintf("%" PRI_klu ", ", tcp->u_arg[4]);
310 : : /* unsigned int flags */
311 : 6 : printflags(splice_flags, tcp->u_arg[5], "SPLICE_F_???");
312 : :
313 : 6 : return RVAL_DECODED;
314 : : }
315 : :
316 : 6 : SYS_FUNC(vmsplice)
317 : : {
318 : : /* int fd */
319 : 6 : printfd(tcp, tcp->u_arg[0]);
320 : 6 : tprints(", ");
321 : : /* const struct iovec *iov, unsigned long nr_segs */
322 : 6 : tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1], IOV_DECODE_STR);
323 : 6 : tprintf(", %" PRI_klu ", ", tcp->u_arg[2]);
324 : : /* unsigned int flags */
325 : 6 : printflags(splice_flags, tcp->u_arg[3], "SPLICE_F_???");
326 : :
327 : 6 : return RVAL_DECODED;
328 : : }
|