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 : : * Copyright (c) 2000 PocketPenguins Inc. Linux for Hitachi SuperH
7 : : * port by Greg Banks <gbanks@pocketpenguins.com>
8 : : * Copyright (c) 1999-2017 The strace developers.
9 : : * All rights reserved.
10 : : *
11 : : * Redistribution and use in source and binary forms, with or without
12 : : * modification, are permitted provided that the following conditions
13 : : * are met:
14 : : * 1. Redistributions of source code must retain the above copyright
15 : : * notice, this list of conditions and the following disclaimer.
16 : : * 2. Redistributions in binary form must reproduce the above copyright
17 : : * notice, this list of conditions and the following disclaimer in the
18 : : * documentation and/or other materials provided with the distribution.
19 : : * 3. The name of the author may not be used to endorse or promote products
20 : : * derived from this software without specific prior written permission.
21 : : *
22 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 : : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 : : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 : : * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 : : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 : : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 : : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 : : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 : : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 : : */
33 : :
34 : : #include "defs.h"
35 : : #include <asm/mman.h>
36 : : #include <sys/mman.h>
37 : :
38 : : unsigned long
39 : 20272 : get_pagesize(void)
40 : : {
41 : : static unsigned long pagesize;
42 : :
43 [ + + ]: 20272 : if (!pagesize)
44 : 481 : pagesize = sysconf(_SC_PAGESIZE);
45 : 20272 : return pagesize;
46 : : }
47 : :
48 : 14 : SYS_FUNC(brk)
49 : : {
50 : 14 : printaddr(tcp->u_arg[0]);
51 : :
52 : 14 : return RVAL_DECODED | RVAL_HEX;
53 : : }
54 : :
55 : : #include "xlat/mmap_prot.h"
56 : : #include "xlat/mmap_flags.h"
57 : :
58 : : static void
59 : 186 : print_mmap(struct tcb *tcp, kernel_ulong_t *u_arg, unsigned long long offset)
60 : : {
61 : 186 : const kernel_ulong_t addr = u_arg[0];
62 : 186 : const kernel_ulong_t len = u_arg[1];
63 : 186 : const kernel_ulong_t prot = u_arg[2];
64 : 186 : const kernel_ulong_t flags = u_arg[3];
65 : 186 : const int fd = u_arg[4];
66 : :
67 : 186 : printaddr(addr);
68 : 186 : tprintf(", %" PRI_klu ", ", len);
69 : : printflags64(mmap_prot, prot, "PROT_???");
70 : 186 : tprints(", ");
71 : : #ifdef MAP_TYPE
72 : 186 : printxval64(mmap_flags, flags & MAP_TYPE, "MAP_???");
73 : 186 : addflags(mmap_flags, flags & ~MAP_TYPE);
74 : : #else
75 : : printflags64(mmap_flags, flags, "MAP_???");
76 : : #endif
77 : 186 : tprints(", ");
78 : 186 : printfd(tcp, fd);
79 : 186 : tprintf(", %#llx", offset);
80 : 186 : }
81 : :
82 : : /* Syscall name<->function correspondence is messed up on many arches.
83 : : * For example:
84 : : * i386 has __NR_mmap == 90, and it is "old mmap", and
85 : : * also it has __NR_mmap2 == 192, which is a "new mmap with page offsets".
86 : : * But x86_64 has just one __NR_mmap == 9, a "new mmap with byte offsets".
87 : : * Confused? Me too!
88 : : */
89 : :
90 : : #if defined AARCH64 || defined ARM \
91 : : || defined I386 || defined X86_64 || defined X32 \
92 : : || defined M68K \
93 : : || defined S390 || defined S390X
94 : : /* Params are pointed to by u_arg[0], offset is in bytes */
95 : 3 : SYS_FUNC(old_mmap)
96 : : {
97 : : kernel_ulong_t u_arg[6];
98 : : # if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG
99 : : /* We are here only in a 32-bit personality. */
100 : : unsigned int narrow_arg[6];
101 [ + + ]: 3 : if (umove_or_printaddr(tcp, tcp->u_arg[0], &narrow_arg))
102 : : return RVAL_DECODED | RVAL_HEX;
103 : : unsigned int i;
104 [ + + ]: 14 : for (i = 0; i < 6; i++)
105 : 12 : u_arg[i] = narrow_arg[i];
106 : : # else
107 : : if (umove_or_printaddr(tcp, tcp->u_arg[0], &u_arg))
108 : : return RVAL_DECODED | RVAL_HEX;
109 : : # endif
110 : 2 : print_mmap(tcp, u_arg, u_arg[5]);
111 : :
112 : 2 : return RVAL_DECODED | RVAL_HEX;
113 : : }
114 : : #endif /* old_mmap architectures */
115 : :
116 : : #ifdef S390
117 : : /* Params are pointed to by u_arg[0], offset is in pages */
118 : : SYS_FUNC(old_mmap_pgoff)
119 : : {
120 : : kernel_ulong_t u_arg[5];
121 : : int i;
122 : : unsigned int narrow_arg[6];
123 : : unsigned long long offset;
124 : : if (umove_or_printaddr(tcp, tcp->u_arg[0], &narrow_arg))
125 : : return RVAL_DECODED | RVAL_HEX;
126 : : for (i = 0; i < 5; i++)
127 : : u_arg[i] = narrow_arg[i];
128 : : offset = narrow_arg[5];
129 : : offset *= get_pagesize();
130 : : print_mmap(tcp, u_arg, offset);
131 : :
132 : : return RVAL_DECODED | RVAL_HEX;
133 : : }
134 : : #endif /* S390 */
135 : :
136 : : /* Params are passed directly, offset is in bytes */
137 : 97 : SYS_FUNC(mmap)
138 : : {
139 : : /* Example of kernel-side handling of this variety of mmap:
140 : : * arch/x86/kernel/sys_x86_64.c::SYSCALL_DEFINE6(mmap, ...) calls
141 : : * sys_mmap_pgoff(..., off >> PAGE_SHIFT); i.e. off is in bytes,
142 : : * since the above code converts off to pages.
143 : : */
144 : 97 : print_mmap(tcp, tcp->u_arg, tcp->u_arg[5]);
145 : :
146 : 97 : return RVAL_DECODED | RVAL_HEX;
147 : : }
148 : :
149 : : /* Params are passed directly, offset is in pages */
150 : 87 : SYS_FUNC(mmap_pgoff)
151 : : {
152 : : /* Try test/mmap_offset_decode.c */
153 : : unsigned long long offset;
154 : 87 : offset = tcp->u_arg[5];
155 : 87 : offset *= get_pagesize();
156 : 87 : print_mmap(tcp, tcp->u_arg, offset);
157 : :
158 : 87 : return RVAL_DECODED | RVAL_HEX;
159 : : }
160 : :
161 : : /* Params are passed directly, offset is in 4k units */
162 : 0 : SYS_FUNC(mmap_4koff)
163 : : {
164 : : unsigned long long offset;
165 : 0 : offset = tcp->u_arg[5];
166 : 0 : offset <<= 12;
167 : 0 : print_mmap(tcp, tcp->u_arg, offset);
168 : :
169 : 0 : return RVAL_DECODED | RVAL_HEX;
170 : : }
171 : :
172 : 52 : SYS_FUNC(munmap)
173 : : {
174 : 52 : printaddr(tcp->u_arg[0]);
175 : 52 : tprintf(", %" PRI_klu, tcp->u_arg[1]);
176 : :
177 : 52 : return RVAL_DECODED;
178 : : }
179 : :
180 : : static int
181 : 762 : do_mprotect(struct tcb *tcp, bool has_pkey)
182 : : {
183 : 762 : printaddr(tcp->u_arg[0]);
184 : 762 : tprintf(", %" PRI_klu ", ", tcp->u_arg[1]);
185 : 762 : printflags64(mmap_prot, tcp->u_arg[2], "PROT_???");
186 : :
187 [ + + ]: 762 : if (has_pkey)
188 : 720 : tprintf(", %d", (int) tcp->u_arg[3]);
189 : :
190 : 762 : return RVAL_DECODED;
191 : : }
192 : :
193 : 42 : SYS_FUNC(mprotect)
194 : : {
195 : 42 : return do_mprotect(tcp, false);
196 : : }
197 : :
198 : 720 : SYS_FUNC(pkey_mprotect)
199 : : {
200 : 720 : return do_mprotect(tcp, true);
201 : : }
202 : :
203 : : #include "xlat/mremap_flags.h"
204 : :
205 : 8 : SYS_FUNC(mremap)
206 : : {
207 : 8 : printaddr(tcp->u_arg[0]);
208 : 8 : tprintf(", %" PRI_klu ", %" PRI_klu ", ", tcp->u_arg[1], tcp->u_arg[2]);
209 : 8 : printflags64(mremap_flags, tcp->u_arg[3], "MREMAP_???");
210 : : #ifdef MREMAP_FIXED
211 [ + + ]: 8 : if ((tcp->u_arg[3] & (MREMAP_MAYMOVE | MREMAP_FIXED)) ==
212 : : (MREMAP_MAYMOVE | MREMAP_FIXED)) {
213 : 4 : tprints(", ");
214 : 4 : printaddr(tcp->u_arg[4]);
215 : : }
216 : : #endif
217 : 8 : return RVAL_DECODED | RVAL_HEX;
218 : : }
219 : :
220 : : #include "xlat/madvise_cmds.h"
221 : :
222 : 6 : SYS_FUNC(madvise)
223 : : {
224 : 6 : printaddr(tcp->u_arg[0]);
225 : 6 : tprintf(", %" PRI_klu ", ", tcp->u_arg[1]);
226 : 6 : printxval(madvise_cmds, tcp->u_arg[2], "MADV_???");
227 : :
228 : 6 : return RVAL_DECODED;
229 : : }
230 : :
231 : : #include "xlat/mlockall_flags.h"
232 : :
233 : 8 : SYS_FUNC(mlockall)
234 : : {
235 : 8 : printflags(mlockall_flags, tcp->u_arg[0], "MCL_???");
236 : :
237 : 8 : return RVAL_DECODED;
238 : : }
239 : :
240 : : #include "xlat/mctl_sync.h"
241 : :
242 : 4 : SYS_FUNC(msync)
243 : : {
244 : : /* addr */
245 : 4 : printaddr(tcp->u_arg[0]);
246 : : /* len */
247 : 4 : tprintf(", %" PRI_klu ", ", tcp->u_arg[1]);
248 : : /* flags */
249 : 4 : printflags(mctl_sync, tcp->u_arg[2], "MS_???");
250 : :
251 : 4 : return RVAL_DECODED;
252 : : }
253 : :
254 : : #include "xlat/mlock_flags.h"
255 : :
256 : 2 : SYS_FUNC(mlock2)
257 : : {
258 : 2 : printaddr(tcp->u_arg[0]);
259 : 2 : tprintf(", %" PRI_klu ", ", tcp->u_arg[1]);
260 : 2 : printflags(mlock_flags, tcp->u_arg[2], "MLOCK_???");
261 : :
262 : 2 : return RVAL_DECODED;
263 : : }
264 : :
265 : 48 : SYS_FUNC(mincore)
266 : : {
267 [ + + ]: 48 : if (entering(tcp)) {
268 : 24 : printaddr(tcp->u_arg[0]);
269 : 24 : tprintf(", %" PRI_klu ", ", tcp->u_arg[1]);
270 : : } else {
271 : 24 : const unsigned long page_size = get_pagesize();
272 : 24 : const unsigned long page_mask = page_size - 1;
273 : 24 : unsigned long len = tcp->u_arg[1];
274 : 24 : unsigned char *vec = NULL;
275 : :
276 [ + + ]: 24 : len = len / page_size + (len & page_mask ? 1 : 0);
277 [ + + ][ + - ]: 24 : if (syserror(tcp) || !verbose(tcp) ||
[ + - ]
278 [ + - - + ]: 32 : !tcp->u_arg[2] || !(vec = malloc(len)) ||
279 : 16 : umoven(tcp, tcp->u_arg[2], len, vec) < 0)
280 : 8 : printaddr(tcp->u_arg[2]);
281 : : else {
282 : : unsigned long i;
283 : 16 : tprints("[");
284 [ + + ]: 284 : for (i = 0; i < len; i++) {
285 [ + + ]: 272 : if (i)
286 : 256 : tprints(", ");
287 [ + - ][ + + ]: 272 : if (abbrev(tcp) && i >= max_strlen) {
288 : 4 : tprints("...");
289 : 4 : break;
290 : : }
291 [ - + ]: 268 : tprints((vec[i] & 1) ? "1" : "0");
292 : : }
293 : 16 : tprints("]");
294 : : }
295 : 24 : free(vec);
296 : : }
297 : 48 : return 0;
298 : : }
299 : :
300 : : #if defined ALPHA || defined IA64 || defined M68K \
301 : : || defined SPARC || defined SPARC64
302 : : SYS_FUNC(getpagesize)
303 : : {
304 : : return RVAL_DECODED | RVAL_HEX;
305 : : }
306 : : #endif
307 : :
308 : 2 : SYS_FUNC(remap_file_pages)
309 : : {
310 : 2 : const kernel_ulong_t addr = tcp->u_arg[0];
311 : 2 : const kernel_ulong_t size = tcp->u_arg[1];
312 : 2 : const kernel_ulong_t prot = tcp->u_arg[2];
313 : 2 : const kernel_ulong_t pgoff = tcp->u_arg[3];
314 : 2 : const kernel_ulong_t flags = tcp->u_arg[4];
315 : :
316 : 2 : printaddr(addr);
317 : 2 : tprintf(", %" PRI_klu ", ", size);
318 : : printflags64(mmap_prot, prot, "PROT_???");
319 : 2 : tprintf(", %" PRI_klu ", ", pgoff);
320 : : #ifdef MAP_TYPE
321 : 2 : printxval64(mmap_flags, flags & MAP_TYPE, "MAP_???");
322 : 2 : addflags(mmap_flags, flags & ~MAP_TYPE);
323 : : #else
324 : : printflags64(mmap_flags, flags, "MAP_???");
325 : : #endif
326 : :
327 : 2 : return RVAL_DECODED;
328 : : }
329 : :
330 : : #if defined(POWERPC)
331 : : static bool
332 : : print_protmap_entry(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
333 : : {
334 : : tprintf("%#08x", *(unsigned int *) elem_buf);
335 : :
336 : : return true;
337 : : }
338 : :
339 : : SYS_FUNC(subpage_prot)
340 : : {
341 : : kernel_ulong_t addr = tcp->u_arg[0];
342 : : kernel_ulong_t len = tcp->u_arg[1];
343 : : kernel_ulong_t nmemb = len >> 16;
344 : : kernel_ulong_t map = tcp->u_arg[2];
345 : :
346 : : printaddr(addr);
347 : : tprintf(", %" PRI_klu ", ", len);
348 : :
349 : : unsigned int entry;
350 : : print_array(tcp, map, nmemb, &entry, sizeof(entry),
351 : : umoven_or_printaddr, print_protmap_entry, 0);
352 : :
353 : : return RVAL_DECODED;
354 : : }
355 : : #endif
|