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