blob: 53793e6d1e3684fa3ecbebd740e8210652a0db03 [file] [log] [blame]
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001/*
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>
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00005 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
Roland McGrathe1e584b2003-06-02 19:18:58 +00006 * Copyright (c) 2000 PocketPenguins Inc. Linux for Hitachi SuperH
7 * port by Greg Banks <gbanks@pocketpenguins.com>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00008 * 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.
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000031 */
32
33#include "defs.h"
Roland McGrath05cdd3c2004-03-02 06:16:59 +000034#include <asm/mman.h>
Wichert Akkerman2e2553a1999-05-09 00:29:58 +000035#include <sys/mman.h>
Denys Vlasenko1ba85432013-02-19 11:28:20 +010036
Dmitry V. Levinea1fea62015-03-31 19:45:08 +000037unsigned long
38get_pagesize(void)
Dmitry V. Levinc76a3632013-03-05 14:58:24 +000039{
40 static unsigned long pagesize;
41
42 if (!pagesize)
43 pagesize = sysconf(_SC_PAGESIZE);
44 return pagesize;
45}
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000046
Dmitry V. Levina0bd3742015-04-07 01:36:50 +000047SYS_FUNC(brk)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000048{
Dmitry V. Levin85813ce2015-07-19 23:37:40 +000049 printaddr(tcp->u_arg[0]);
50
51 return RVAL_DECODED | RVAL_HEX;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000052}
53
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +000054#include "xlat/mmap_prot.h"
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +000055#include "xlat/mmap_flags.h"
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000056
Dmitry V. Levin85813ce2015-07-19 23:37:40 +000057static void
Denys Vlasenko923255c2013-02-18 02:36:36 +010058print_mmap(struct tcb *tcp, long *u_arg, unsigned long long offset)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000059{
Dmitry V. Levin3ae86902016-04-01 15:31:23 +000060 const unsigned long addr = u_arg[0];
61 const unsigned long len = u_arg[1];
62 const unsigned long prot = u_arg[2];
63 const unsigned long flags = u_arg[3];
64 const int fd = u_arg[4];
65
66 printaddr(addr);
67 tprintf(", %lu, ", len);
68 printflags(mmap_prot, prot, "PROT_???");
Dmitry V. Levin85813ce2015-07-19 23:37:40 +000069 tprints(", ");
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +000070#ifdef MAP_TYPE
Dmitry V. Levin3ae86902016-04-01 15:31:23 +000071 printxval(mmap_flags, flags & MAP_TYPE, "MAP_???");
72 addflags(mmap_flags, flags & ~MAP_TYPE);
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +000073#else
Dmitry V. Levin3ae86902016-04-01 15:31:23 +000074 printflags(mmap_flags, flags, "MAP_???");
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +000075#endif
Dmitry V. Levin85813ce2015-07-19 23:37:40 +000076 tprints(", ");
Dmitry V. Levin3ae86902016-04-01 15:31:23 +000077 printfd(tcp, fd);
Dmitry V. Levin85813ce2015-07-19 23:37:40 +000078 tprintf(", %#llx", offset);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000079}
80
Denys Vlasenko1ba85432013-02-19 11:28:20 +010081/* 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/* Params are pointed to by u_arg[0], offset is in bytes */
Dmitry V. Levina0bd3742015-04-07 01:36:50 +000090SYS_FUNC(old_mmap)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +000091{
Denys Vlasenko1ba85432013-02-19 11:28:20 +010092 long u_arg[6];
Denys Vlasenko72a58482011-08-19 16:01:51 +020093#if defined(IA64)
Denys Vlasenkoadedb512008-12-30 18:47:55 +000094 /*
Denys Vlasenko9aa97962011-08-19 17:07:38 +020095 * IA64 processes never call this routine, they only use the
Denys Vlasenko1ba85432013-02-19 11:28:20 +010096 * new 'sys_mmap' interface. Only IA32 processes come here.
Denys Vlasenkoadedb512008-12-30 18:47:55 +000097 */
Denys Vlasenko9aa97962011-08-19 17:07:38 +020098 int i;
Denys Vlasenko923255c2013-02-18 02:36:36 +010099 unsigned narrow_arg[6];
Denys Vlasenko7e69ed92015-03-21 19:50:53 +0100100 if (umoven(tcp, tcp->u_arg[0], sizeof(narrow_arg), narrow_arg) == -1)
Denys Vlasenko9aa97962011-08-19 17:07:38 +0200101 return 0;
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000102 for (i = 0; i < 6; i++)
Denys Vlasenko1ba85432013-02-19 11:28:20 +0100103 u_arg[i] = (unsigned long) narrow_arg[i];
Denys Vlasenko923255c2013-02-18 02:36:36 +0100104#elif defined(X86_64)
Denys Vlasenko1ba85432013-02-19 11:28:20 +0100105 /* We are here only in personality 1 (i386) */
106 int i;
107 unsigned narrow_arg[6];
Denys Vlasenko7e69ed92015-03-21 19:50:53 +0100108 if (umoven(tcp, tcp->u_arg[0], sizeof(narrow_arg), narrow_arg) == -1)
Denys Vlasenko1ba85432013-02-19 11:28:20 +0100109 return 0;
110 for (i = 0; i < 6; ++i)
111 u_arg[i] = (unsigned long) narrow_arg[i];
Denys Vlasenko923255c2013-02-18 02:36:36 +0100112#else
Denys Vlasenko7e69ed92015-03-21 19:50:53 +0100113 if (umoven(tcp, tcp->u_arg[0], sizeof(u_arg), u_arg) == -1)
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000114 return 0;
Denys Vlasenko923255c2013-02-18 02:36:36 +0100115#endif
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000116 print_mmap(tcp, u_arg, (unsigned long) u_arg[5]);
117
118 return RVAL_DECODED | RVAL_HEX;
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +0000119}
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +0000120
Denys Vlasenko1ba85432013-02-19 11:28:20 +0100121#if defined(S390)
122/* Params are pointed to by u_arg[0], offset is in pages */
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000123SYS_FUNC(old_mmap_pgoff)
Denys Vlasenko1ba85432013-02-19 11:28:20 +0100124{
125 long u_arg[5];
126 int i;
127 unsigned narrow_arg[6];
128 unsigned long long offset;
Denys Vlasenko7e69ed92015-03-21 19:50:53 +0100129 if (umoven(tcp, tcp->u_arg[0], sizeof(narrow_arg), narrow_arg) == -1)
Denys Vlasenko1ba85432013-02-19 11:28:20 +0100130 return 0;
131 for (i = 0; i < 5; i++)
132 u_arg[i] = (unsigned long) narrow_arg[i];
133 offset = narrow_arg[5];
Dmitry V. Levinc76a3632013-03-05 14:58:24 +0000134 offset *= get_pagesize();
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000135 print_mmap(tcp, u_arg, offset);
136
137 return RVAL_DECODED | RVAL_HEX;
Denys Vlasenko1ba85432013-02-19 11:28:20 +0100138}
139#endif
140
141/* Params are passed directly, offset is in bytes */
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000142SYS_FUNC(mmap)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +0000143{
Denys Vlasenko8dedb0d2013-02-18 03:13:07 +0100144 unsigned long long offset = (unsigned long) tcp->u_arg[5];
Denys Vlasenko1ba85432013-02-19 11:28:20 +0100145#if defined(LINUX_MIPSN32) || defined(X32)
Denys Vlasenko8dedb0d2013-02-18 03:13:07 +0100146 /* Try test/x32_mmap.c */
Denys Vlasenkoadedb512008-12-30 18:47:55 +0000147 offset = tcp->ext_arg[5];
Roland McGrath542c2c62008-05-20 01:11:56 +0000148#endif
Denys Vlasenko1ba85432013-02-19 11:28:20 +0100149 /* Example of kernel-side handling of this variety of mmap:
150 * arch/x86/kernel/sys_x86_64.c::SYSCALL_DEFINE6(mmap, ...) calls
151 * sys_mmap_pgoff(..., off >> PAGE_SHIFT); i.e. off is in bytes,
152 * since the above code converts off to pages.
153 */
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000154 print_mmap(tcp, tcp->u_arg, offset);
155
156 return RVAL_DECODED | RVAL_HEX;
Denys Vlasenko1ba85432013-02-19 11:28:20 +0100157}
158
159/* Params are passed directly, offset is in pages */
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000160SYS_FUNC(mmap_pgoff)
Denys Vlasenko1ba85432013-02-19 11:28:20 +0100161{
162 /* Try test/mmap_offset_decode.c */
163 unsigned long long offset;
164 offset = (unsigned long) tcp->u_arg[5];
Dmitry V. Levinc76a3632013-03-05 14:58:24 +0000165 offset *= get_pagesize();
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000166 print_mmap(tcp, tcp->u_arg, offset);
167
168 return RVAL_DECODED | RVAL_HEX;
Denys Vlasenko1ba85432013-02-19 11:28:20 +0100169}
170
171/* Params are passed directly, offset is in 4k units */
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000172SYS_FUNC(mmap_4koff)
Denys Vlasenko1ba85432013-02-19 11:28:20 +0100173{
174 unsigned long long offset;
175 offset = (unsigned long) tcp->u_arg[5];
176 offset <<= 12;
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000177 print_mmap(tcp, tcp->u_arg, offset);
178
179 return RVAL_DECODED | RVAL_HEX;
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +0000180}
181
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000182SYS_FUNC(munmap)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000183{
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000184 printaddr(tcp->u_arg[0]);
185 tprintf(", %lu", tcp->u_arg[1]);
186
187 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000188}
189
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000190SYS_FUNC(mprotect)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000191{
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000192 printaddr(tcp->u_arg[0]);
193 tprintf(", %lu, ", tcp->u_arg[1]);
194 printflags(mmap_prot, tcp->u_arg[2], "PROT_???");
195
196 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000197}
198
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000199#include "xlat/mremap_flags.h"
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000200
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000201SYS_FUNC(mremap)
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000202{
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000203 printaddr(tcp->u_arg[0]);
204 tprintf(", %lu, %lu, ", tcp->u_arg[1], tcp->u_arg[2]);
205 printflags(mremap_flags, tcp->u_arg[3], "MREMAP_???");
Dmitry V. Levinfdc45592009-12-24 23:34:58 +0000206#ifdef MREMAP_FIXED
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000207 if ((tcp->u_arg[3] & (MREMAP_MAYMOVE | MREMAP_FIXED)) ==
208 (MREMAP_MAYMOVE | MREMAP_FIXED)) {
209 tprints(", ");
210 printaddr(tcp->u_arg[4]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000211 }
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000212#endif
213 return RVAL_DECODED | RVAL_HEX;
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000214}
215
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000216#include "xlat/madvise_cmds.h"
Wichert Akkermanc7926982000-04-10 22:22:31 +0000217
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000218SYS_FUNC(madvise)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000219{
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000220 printaddr(tcp->u_arg[0]);
221 tprintf(", %lu, ", tcp->u_arg[1]);
222 printxval(madvise_cmds, tcp->u_arg[2], "MADV_???");
223
224 return RVAL_DECODED;
Wichert Akkermanc7926982000-04-10 22:22:31 +0000225}
226
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000227#include "xlat/mlockall_flags.h"
Wichert Akkermanc7926982000-04-10 22:22:31 +0000228
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000229SYS_FUNC(mlockall)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000230{
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000231 printflags(mlockall_flags, tcp->u_arg[0], "MCL_???");
232
233 return RVAL_DECODED;
Wichert Akkermanc7926982000-04-10 22:22:31 +0000234}
235
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000236#include "xlat/mctl_sync.h"
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000237
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000238SYS_FUNC(msync)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000239{
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000240 /* addr */
241 printaddr(tcp->u_arg[0]);
242 /* len */
243 tprintf(", %lu, ", tcp->u_arg[1]);
244 /* flags */
245 printflags(mctl_sync, tcp->u_arg[2], "MS_???");
246
247 return RVAL_DECODED;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000248}
249
Dmitry V. Levin0d0a50a2015-11-15 02:35:57 +0000250#include "xlat/mlock_flags.h"
251
252SYS_FUNC(mlock2)
253{
254 printaddr(tcp->u_arg[0]);
255 tprintf(", %lu, ", tcp->u_arg[1]);
256 printflags(mlock_flags, tcp->u_arg[2], "MLOCK_???");
257
258 return RVAL_DECODED;
259}
260
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000261SYS_FUNC(mincore)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000262{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000263 if (entering(tcp)) {
Dmitry V. Levin2c389f62015-07-19 23:25:56 +0000264 printaddr(tcp->u_arg[0]);
265 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000266 } else {
Dmitry V. Levindfea1da2016-01-29 01:51:54 +0000267 const unsigned long page_size = get_pagesize();
268 const unsigned long page_mask = page_size - 1;
269 unsigned long len = tcp->u_arg[1];
270 unsigned char *vec = NULL;
Denys Vlasenko1d46ba52011-08-31 14:00:02 +0200271
Dmitry V. Levindfea1da2016-01-29 01:51:54 +0000272 len = len / page_size + (len & page_mask ? 1 : 0);
Dmitry V. Levin2c389f62015-07-19 23:25:56 +0000273 if (syserror(tcp) || !verbose(tcp) ||
274 !tcp->u_arg[2] || !(vec = malloc(len)) ||
275 umoven(tcp, tcp->u_arg[2], len, vec) < 0)
276 printaddr(tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000277 else {
Dmitry V. Levindfea1da2016-01-29 01:51:54 +0000278 unsigned long i;
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200279 tprints("[");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000280 for (i = 0; i < len; i++) {
281 if (abbrev(tcp) && i >= max_strlen) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200282 tprints("...");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000283 break;
284 }
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200285 tprints((vec[i] & 1) ? "1" : "0");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000286 }
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200287 tprints("]");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000288 }
Denys Vlasenko1d46ba52011-08-31 14:00:02 +0200289 free(vec);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000290 }
291 return 0;
292}
293
Dmitry V. Levinece9ce62015-07-21 15:55:09 +0000294#if defined ALPHA || defined IA64 || defined M68K \
295 || defined SPARC || defined SPARC64
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000296SYS_FUNC(getpagesize)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000297{
Dmitry V. Levinb61b2d82016-01-08 19:20:05 +0000298 return RVAL_DECODED | RVAL_HEX;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000299}
Denys Vlasenko84703742012-02-25 02:38:52 +0100300#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000301
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000302SYS_FUNC(remap_file_pages)
Roland McGrath72c5b7b2003-03-05 04:08:00 +0000303{
Dmitry V. Levin3ae86902016-04-01 15:31:23 +0000304 const unsigned long addr = tcp->u_arg[0];
305 const unsigned long size = tcp->u_arg[1];
306 const unsigned long prot = tcp->u_arg[2];
307 const unsigned long pgoff = tcp->u_arg[3];
308 const unsigned long flags = tcp->u_arg[4];
309
310 printaddr(addr);
311 tprintf(", %lu, ", size);
312 printflags(mmap_prot, prot, "PROT_???");
313 tprintf(", %lu, ", pgoff);
Roland McGrath72c5b7b2003-03-05 04:08:00 +0000314#ifdef MAP_TYPE
Dmitry V. Levin3ae86902016-04-01 15:31:23 +0000315 printxval(mmap_flags, flags & MAP_TYPE, "MAP_???");
316 addflags(mmap_flags, flags & ~MAP_TYPE);
Roland McGrath72c5b7b2003-03-05 04:08:00 +0000317#else
Dmitry V. Levin3ae86902016-04-01 15:31:23 +0000318 printflags(mmap_flags, flags, "MAP_???");
Roland McGrath72c5b7b2003-03-05 04:08:00 +0000319#endif
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000320
321 return RVAL_DECODED;
Roland McGrath72c5b7b2003-03-05 04:08:00 +0000322}
Roland McGrathb10a3352004-10-07 18:53:12 +0000323
Roland McGrathb10a3352004-10-07 18:53:12 +0000324#define MPOL_DEFAULT 0
325#define MPOL_PREFERRED 1
326#define MPOL_BIND 2
327#define MPOL_INTERLEAVE 3
328
329#define MPOL_F_NODE (1<<0)
330#define MPOL_F_ADDR (1<<1)
331
332#define MPOL_MF_STRICT (1<<0)
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000333#define MPOL_MF_MOVE (1<<1)
334#define MPOL_MF_MOVE_ALL (1<<2)
Roland McGrathb10a3352004-10-07 18:53:12 +0000335
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000336#include "xlat/policies.h"
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000337#include "xlat/mbindflags.h"
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000338#include "xlat/mempolicyflags.h"
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +0000339#include "xlat/move_pages_flags.h"
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000340
Roland McGrathb10a3352004-10-07 18:53:12 +0000341static void
Denys Vlasenko12014262011-05-30 14:00:14 +0200342get_nodes(struct tcb *tcp, unsigned long ptr, unsigned long maxnodes, int err)
Roland McGrathb10a3352004-10-07 18:53:12 +0000343{
Roland McGrathaa524c82005-06-01 19:22:06 +0000344 unsigned long nlongs, size, end;
345
346 nlongs = (maxnodes + 8 * sizeof(long) - 1) / (8 * sizeof(long));
347 size = nlongs * sizeof(long);
348 end = ptr + size;
349 if (nlongs == 0 || ((err || verbose(tcp)) && (size * 8 == maxnodes)
350 && (end > ptr))) {
351 unsigned long n, cur, abbrev_end;
352 int failed = 0;
353
354 if (abbrev(tcp)) {
355 abbrev_end = ptr + max_strlen * sizeof(long);
356 if (abbrev_end < ptr)
357 abbrev_end = end;
358 } else {
359 abbrev_end = end;
Roland McGrathb10a3352004-10-07 18:53:12 +0000360 }
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200361 tprints(", {");
Roland McGrathaa524c82005-06-01 19:22:06 +0000362 for (cur = ptr; cur < end; cur += sizeof(long)) {
363 if (cur > ptr)
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200364 tprints(", ");
Roland McGrathaa524c82005-06-01 19:22:06 +0000365 if (cur >= abbrev_end) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200366 tprints("...");
Roland McGrathaa524c82005-06-01 19:22:06 +0000367 break;
368 }
Denys Vlasenko7e69ed92015-03-21 19:50:53 +0100369 if (umoven(tcp, cur, sizeof(n), &n) < 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200370 tprints("?");
Roland McGrathaa524c82005-06-01 19:22:06 +0000371 failed = 1;
372 break;
373 }
374 tprintf("%#0*lx", (int) sizeof(long) * 2 + 2, n);
375 }
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200376 tprints("}");
Dmitry V. Levin2c389f62015-07-19 23:25:56 +0000377 if (failed) {
378 tprints(" ");
379 printaddr(ptr);
380 }
381 } else {
382 tprints(" ");
383 printaddr(ptr);
384 }
Roland McGrathb10a3352004-10-07 18:53:12 +0000385 tprintf(", %lu", maxnodes);
386}
387
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000388SYS_FUNC(mbind)
Roland McGrathb10a3352004-10-07 18:53:12 +0000389{
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000390 printaddr(tcp->u_arg[0]);
391 tprintf(", %lu, ", tcp->u_arg[1]);
392 printxval(policies, tcp->u_arg[2], "MPOL_???");
393 get_nodes(tcp, tcp->u_arg[3], tcp->u_arg[4], 0);
394 tprints(", ");
395 printflags(mbindflags, tcp->u_arg[5], "MPOL_???");
396
397 return RVAL_DECODED;
Roland McGrathb10a3352004-10-07 18:53:12 +0000398}
399
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000400SYS_FUNC(set_mempolicy)
Roland McGrathb10a3352004-10-07 18:53:12 +0000401{
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000402 printxval(policies, tcp->u_arg[0], "MPOL_???");
403 get_nodes(tcp, tcp->u_arg[1], tcp->u_arg[2], 0);
404
405 return RVAL_DECODED;
Roland McGrathb10a3352004-10-07 18:53:12 +0000406}
407
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000408SYS_FUNC(get_mempolicy)
Roland McGrathb10a3352004-10-07 18:53:12 +0000409{
410 if (exiting(tcp)) {
411 int pol;
Dmitry V. Levin2c389f62015-07-19 23:25:56 +0000412 if (!umove_or_printaddr(tcp, tcp->u_arg[0], &pol))
Roland McGrathb10a3352004-10-07 18:53:12 +0000413 printxval(policies, pol, "MPOL_???");
414 get_nodes(tcp, tcp->u_arg[1], tcp->u_arg[2], syserror(tcp));
Dmitry V. Levin2c389f62015-07-19 23:25:56 +0000415 tprints(", ");
416 printaddr(tcp->u_arg[3]);
417 tprints(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +0000418 printflags(mempolicyflags, tcp->u_arg[4], "MPOL_???");
Roland McGrathb10a3352004-10-07 18:53:12 +0000419 }
420 return 0;
421}
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000422
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000423SYS_FUNC(migrate_pages)
Dmitry V. Levin64d0e712012-03-11 22:44:14 +0000424{
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000425 tprintf("%ld, ", (long) (pid_t) tcp->u_arg[0]);
426 get_nodes(tcp, tcp->u_arg[2], tcp->u_arg[1], 0);
427 tprints(", ");
428 get_nodes(tcp, tcp->u_arg[3], tcp->u_arg[1], 0);
429
430 return RVAL_DECODED;
Dmitry V. Levin64d0e712012-03-11 22:44:14 +0000431}
432
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000433SYS_FUNC(move_pages)
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000434{
435 if (entering(tcp)) {
436 unsigned long npages = tcp->u_arg[1];
437 tprintf("%ld, %lu, ", tcp->u_arg[0], npages);
438 if (tcp->u_arg[2] == 0)
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200439 tprints("NULL, ");
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000440 else {
Dmitry V. Levin3ed5d022014-09-10 13:46:04 +0000441 unsigned int i;
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000442 long puser = tcp->u_arg[2];
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200443 tprints("{");
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000444 for (i = 0; i < npages; ++i) {
445 void *p;
446 if (i > 0)
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200447 tprints(", ");
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000448 if (umove(tcp, puser, &p) < 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200449 tprints("???");
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000450 break;
451 }
452 tprintf("%p", p);
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200453 puser += sizeof(void *);
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000454 }
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200455 tprints("}, ");
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000456 }
457 if (tcp->u_arg[3] == 0)
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200458 tprints("NULL, ");
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000459 else {
Dmitry V. Levin3ed5d022014-09-10 13:46:04 +0000460 unsigned int i;
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000461 long nodeuser = tcp->u_arg[3];
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200462 tprints("{");
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000463 for (i = 0; i < npages; ++i) {
464 int node;
465 if (i > 0)
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200466 tprints(", ");
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000467 if (umove(tcp, nodeuser, &node) < 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200468 tprints("???");
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000469 break;
470 }
471 tprintf("%#x", node);
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200472 nodeuser += sizeof(int);
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000473 }
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200474 tprints("}, ");
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000475 }
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000476 } else {
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000477 unsigned long npages = tcp->u_arg[1];
478 if (tcp->u_arg[4] == 0)
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200479 tprints("NULL, ");
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000480 else {
Dmitry V. Levin3ed5d022014-09-10 13:46:04 +0000481 unsigned int i;
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000482 long statususer = tcp->u_arg[4];
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200483 tprints("{");
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000484 for (i = 0; i < npages; ++i) {
485 int status;
486 if (i > 0)
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200487 tprints(", ");
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000488 if (umove(tcp, statususer, &status) < 0) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200489 tprints("???");
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000490 break;
491 }
492 tprintf("%#x", status);
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200493 statususer += sizeof(int);
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000494 }
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200495 tprints("}, ");
Roland McGrath2c00a4a2007-07-24 01:52:58 +0000496 }
497 printflags(move_pages_flags, tcp->u_arg[5], "MPOL_???");
498 }
499 return 0;
500}
Roland McGrath4a6f6522008-08-25 03:09:16 +0000501
Denys Vlasenko84703742012-02-25 02:38:52 +0100502#if defined(POWERPC)
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000503SYS_FUNC(subpage_prot)
Roland McGrath4a6f6522008-08-25 03:09:16 +0000504{
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000505 unsigned long cur, end, abbrev_end, entries;
506 unsigned int entry;
Roland McGrath4a6f6522008-08-25 03:09:16 +0000507
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000508 printaddr(tcp->u_arg[0]);
509 tprints(", ");
510 printaddr(tcp->u_arg[1]);
511 tprints(", ");
512 entries = tcp->u_arg[1] >> 16;
513 if (!entries || !tcp->u_arg[2]) {
514 tprints("{}");
515 return 0;
516 }
517 cur = tcp->u_arg[2];
518 end = cur + (sizeof(int) * entries);
519 if (!verbose(tcp) || end < (unsigned long) tcp->u_arg[2]) {
520 printaddr(tcp->u_arg[2]);
521 return 0;
522 }
523 if (abbrev(tcp)) {
524 abbrev_end = cur + (sizeof(int) * max_strlen);
525 if (abbrev_end > end)
526 abbrev_end = end;
527 }
528 else
529 abbrev_end = end;
530 tprints("{");
531 for (; cur < end; cur += sizeof(int)) {
532 if (cur > (unsigned long) tcp->u_arg[2])
533 tprints(", ");
534 if (cur >= abbrev_end) {
535 tprints("...");
536 break;
Roland McGrath4a6f6522008-08-25 03:09:16 +0000537 }
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000538 if (umove(tcp, cur, &entry) < 0) {
539 tprintf("??? [%#lx]", cur);
540 break;
Roland McGrath4a6f6522008-08-25 03:09:16 +0000541 }
542 else
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000543 tprintf("%#08x", entry);
Roland McGrath4a6f6522008-08-25 03:09:16 +0000544 }
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000545 tprints("}");
Roland McGrath4a6f6522008-08-25 03:09:16 +0000546
Dmitry V. Levin85813ce2015-07-19 23:37:40 +0000547 return RVAL_DECODED;
Roland McGrath4a6f6522008-08-25 03:09:16 +0000548}
549#endif