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-2018 The strace developers.
11 * SPDX-License-Identifier: LGPL-2.1-or-later
15 #include <linux/mman.h>
21 static unsigned long pagesize;
24 long ret = sysconf(_SC_PAGESIZE);
27 perror_func_msg_and_die("sysconf(_SC_PAGESIZE)");
29 error_func_msg_and_die("sysconf(_SC_PAGESIZE) "
32 pagesize = (unsigned long) ret;
40 printaddr(tcp->u_arg[0]);
42 return RVAL_DECODED | RVAL_HEX;
45 #include "xlat/mmap_prot.h"
46 #include "xlat/mmap_flags.h"
48 #ifndef MAP_HUGE_SHIFT
49 # define MAP_HUGE_SHIFT 26
53 # define MAP_HUGE_MASK 0x3f
57 print_mmap_flags(kernel_ulong_t flags)
59 if (xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
60 tprintf("%#" PRI_klx, flags);
62 if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
65 if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
68 printxvals_ex(flags & MAP_TYPE, "MAP_???", XLAT_STYLE_ABBREV,
72 const unsigned int mask = MAP_HUGE_MASK << MAP_HUGE_SHIFT;
73 const unsigned int hugetlb_value = flags & mask;
78 printflags_ex(flags, NULL, XLAT_STYLE_ABBREV,
83 tprintf("|%u<<MAP_HUGE_SHIFT",
84 hugetlb_value >> MAP_HUGE_SHIFT);
86 if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
91 print_mmap(struct tcb *tcp, kernel_ulong_t *u_arg, unsigned long long offset)
93 const kernel_ulong_t addr = u_arg[0];
94 const kernel_ulong_t len = u_arg[1];
95 const kernel_ulong_t prot = u_arg[2];
96 const kernel_ulong_t flags = u_arg[3];
97 const int fd = u_arg[4];
100 tprintf(", %" PRI_klu ", ", len);
101 printflags64(mmap_prot, prot, "PROT_???");
103 print_mmap_flags(flags);
106 tprintf(", %#llx", offset);
109 /* Syscall name<->function correspondence is messed up on many arches.
111 * i386 has __NR_mmap == 90, and it is "old mmap", and
112 * also it has __NR_mmap2 == 192, which is a "new mmap with page offsets".
113 * But x86_64 has just one __NR_mmap == 9, a "new mmap with byte offsets".
117 #if HAVE_ARCH_OLD_MMAP
118 /* Params are pointed to by u_arg[0], offset is in bytes */
121 kernel_ulong_t *args =
122 fetch_indirect_syscall_args(tcp, tcp->u_arg[0], 6);
125 print_mmap(tcp, args, args[5]);
127 printaddr(tcp->u_arg[0]);
129 return RVAL_DECODED | RVAL_HEX;
132 # if HAVE_ARCH_OLD_MMAP_PGOFF
133 /* Params are pointed to by u_arg[0], offset is in pages */
134 SYS_FUNC(old_mmap_pgoff)
136 kernel_ulong_t *args =
137 fetch_indirect_syscall_args(tcp, tcp->u_arg[0], 6);
140 unsigned long long offset;
143 offset *= get_pagesize();
145 print_mmap(tcp, args, offset);
147 printaddr(tcp->u_arg[0]);
150 return RVAL_DECODED | RVAL_HEX;
152 # endif /* HAVE_ARCH_OLD_MMAP_PGOFF */
153 #endif /* HAVE_ARCH_OLD_MMAP */
155 /* Params are passed directly, offset is in bytes */
158 /* Example of kernel-side handling of this variety of mmap:
159 * arch/x86/kernel/sys_x86_64.c::SYSCALL_DEFINE6(mmap, ...) calls
160 * sys_mmap_pgoff(..., off >> PAGE_SHIFT); i.e. off is in bytes,
161 * since the above code converts off to pages.
163 print_mmap(tcp, tcp->u_arg, tcp->u_arg[5]);
165 return RVAL_DECODED | RVAL_HEX;
168 /* Params are passed directly, offset is in pages */
171 /* Try test/mmap_offset_decode.c */
172 unsigned long long offset;
173 offset = tcp->u_arg[5];
174 offset *= get_pagesize();
175 print_mmap(tcp, tcp->u_arg, offset);
177 return RVAL_DECODED | RVAL_HEX;
180 /* Params are passed directly, offset is in 4k units */
183 unsigned long long offset;
184 offset = tcp->u_arg[5];
186 print_mmap(tcp, tcp->u_arg, offset);
188 return RVAL_DECODED | RVAL_HEX;
193 printaddr(tcp->u_arg[0]);
194 tprintf(", %" PRI_klu, tcp->u_arg[1]);
200 do_mprotect(struct tcb *tcp, bool has_pkey)
202 printaddr(tcp->u_arg[0]);
203 tprintf(", %" PRI_klu ", ", tcp->u_arg[1]);
204 printflags64(mmap_prot, tcp->u_arg[2], "PROT_???");
207 tprintf(", %d", (int) tcp->u_arg[3]);
214 return do_mprotect(tcp, false);
217 SYS_FUNC(pkey_mprotect)
219 return do_mprotect(tcp, true);
222 #include "xlat/mremap_flags.h"
226 printaddr(tcp->u_arg[0]);
227 tprintf(", %" PRI_klu ", %" PRI_klu ", ", tcp->u_arg[1], tcp->u_arg[2]);
228 printflags64(mremap_flags, tcp->u_arg[3], "MREMAP_???");
230 if ((tcp->u_arg[3] & (MREMAP_MAYMOVE | MREMAP_FIXED)) ==
231 (MREMAP_MAYMOVE | MREMAP_FIXED)) {
233 printaddr(tcp->u_arg[4]);
236 return RVAL_DECODED | RVAL_HEX;
239 #include "xlat/madvise_cmds.h"
243 printaddr(tcp->u_arg[0]);
244 tprintf(", %" PRI_klu ", ", tcp->u_arg[1]);
245 printxval(madvise_cmds, tcp->u_arg[2], "MADV_???");
250 #include "xlat/mlockall_flags.h"
254 printflags(mlockall_flags, tcp->u_arg[0], "MCL_???");
259 #include "xlat/mctl_sync.h"
264 printaddr(tcp->u_arg[0]);
266 tprintf(", %" PRI_klu ", ", tcp->u_arg[1]);
268 printflags(mctl_sync, tcp->u_arg[2], "MS_???");
273 #include "xlat/mlock_flags.h"
277 printaddr(tcp->u_arg[0]);
278 tprintf(", %" PRI_klu ", ", tcp->u_arg[1]);
279 printflags(mlock_flags, tcp->u_arg[2], "MLOCK_???");
287 printaddr(tcp->u_arg[0]);
288 tprintf(", %" PRI_klu ", ", tcp->u_arg[1]);
290 const unsigned long page_size = get_pagesize();
291 const unsigned long page_mask = page_size - 1;
292 unsigned long len = tcp->u_arg[1];
293 unsigned char *vec = NULL;
295 len = len / page_size + (len & page_mask ? 1 : 0);
296 if (syserror(tcp) || !verbose(tcp) ||
297 !tcp->u_arg[2] || !(vec = malloc(len)) ||
298 umoven(tcp, tcp->u_arg[2], len, vec) < 0)
299 printaddr(tcp->u_arg[2]);
303 for (i = 0; i < len; i++) {
306 if (abbrev(tcp) && i >= max_strlen) {
310 tprints((vec[i] & 1) ? "1" : "0");
319 SYS_FUNC(remap_file_pages)
321 const kernel_ulong_t addr = tcp->u_arg[0];
322 const kernel_ulong_t size = tcp->u_arg[1];
323 const kernel_ulong_t prot = tcp->u_arg[2];
324 const kernel_ulong_t pgoff = tcp->u_arg[3];
325 const kernel_ulong_t flags = tcp->u_arg[4];
328 tprintf(", %" PRI_klu ", ", size);
329 printflags64(mmap_prot, prot, "PROT_???");
330 tprintf(", %" PRI_klu ", ", pgoff);
331 print_mmap_flags(flags);
338 print_protmap_entry(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
340 tprintf("%#08x", *(unsigned int *) elem_buf);
345 SYS_FUNC(subpage_prot)
347 kernel_ulong_t addr = tcp->u_arg[0];
348 kernel_ulong_t len = tcp->u_arg[1];
349 kernel_ulong_t nmemb = len >> 16;
350 kernel_ulong_t map = tcp->u_arg[2];
353 tprintf(", %" PRI_klu ", ", len);
356 print_array(tcp, map, nmemb, &entry, sizeof(entry),
357 tfetch_mem, print_protmap_entry, 0);