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 * $Id: mem.c,v 1.36 2005/06/01 19:22:07 roland Exp $
33 */
34
35 #include "defs.h"
36
37 #ifdef LINUX
38 #include <asm/mman.h>
39 #endif
40 #include <sys/mman.h>
41
42 #if defined(LINUX) && defined(I386)
43 #include <asm/ldt.h>
44 # ifdef HAVE_STRUCT_USER_DESC
45 # define modify_ldt_ldt_s user_desc
46 # endif
47 #endif
48 #if defined(LINUX) && defined(SH64)
49 #include <asm/page.h> /* for PAGE_SHIFT */
50 #endif
51
52 #ifdef HAVE_LONG_LONG_OFF_T
53 /*
54 * Ugly hacks for systems that have a long long off_t
55 */
56 #define sys_mmap64 sys_mmap
57 #endif
58
59 int
sys_brk(tcp)60 sys_brk(tcp)
61 struct tcb *tcp;
62 {
63 if (entering(tcp)) {
64 tprintf("%#lx", tcp->u_arg[0]);
65 }
66 #ifdef LINUX
67 return RVAL_HEX;
68 #else
69 return 0;
70 #endif
71 }
72
73 int
sys_sbrk(tcp)74 sys_sbrk(tcp)
75 struct tcb *tcp;
76 {
77 if (entering(tcp)) {
78 tprintf("%lu", tcp->u_arg[0]);
79 }
80 return RVAL_HEX;
81 }
82
83 static const struct xlat mmap_prot[] = {
84 { PROT_NONE, "PROT_NONE", },
85 { PROT_READ, "PROT_READ" },
86 { PROT_WRITE, "PROT_WRITE" },
87 { PROT_EXEC, "PROT_EXEC" },
88 #ifdef PROT_SEM
89 { PROT_SEM, "PROT_SEM" },
90 #endif
91 #ifdef PROT_GROWSDOWN
92 { PROT_GROWSDOWN,"PROT_GROWSDOWN"},
93 #endif
94 #ifdef PROT_GROWSUP
95 { PROT_GROWSUP, "PROT_GROWSUP" },
96 #endif
97 { 0, NULL },
98 };
99
100 static const struct xlat mmap_flags[] = {
101 { MAP_SHARED, "MAP_SHARED" },
102 { MAP_PRIVATE, "MAP_PRIVATE" },
103 { MAP_FIXED, "MAP_FIXED" },
104 #ifdef MAP_ANONYMOUS
105 { MAP_ANONYMOUS,"MAP_ANONYMOUS" },
106 #endif
107 #ifdef MAP_RENAME
108 { MAP_RENAME, "MAP_RENAME" },
109 #endif
110 #ifdef MAP_NORESERVE
111 { MAP_NORESERVE,"MAP_NORESERVE" },
112 #endif
113 #ifdef MAP_POPULATE
114 { MAP_POPULATE, "MAP_POPULATE" },
115 #endif
116 #ifdef MAP_NONBLOCK
117 { MAP_NONBLOCK, "MAP_NONBLOCK" },
118 #endif
119 /*
120 * XXX - this was introduced in SunOS 4.x to distinguish between
121 * the old pre-4.x "mmap()", which:
122 *
123 * only let you map devices with an "mmap" routine (e.g.,
124 * frame buffers) in;
125 *
126 * required you to specify the mapping address;
127 *
128 * returned 0 on success and -1 on failure;
129 *
130 * memory and which, and the 4.x "mmap()" which:
131 *
132 * can map plain files;
133 *
134 * can be asked to pick where to map the file;
135 *
136 * returns the address where it mapped the file on success
137 * and -1 on failure.
138 *
139 * It's not actually used in source code that calls "mmap()"; the
140 * "mmap()" routine adds it for you.
141 *
142 * It'd be nice to come up with some way of eliminating it from
143 * the flags, e.g. reporting calls *without* it as "old_mmap()"
144 * and calls with it as "mmap()".
145 */
146 #ifdef _MAP_NEW
147 { _MAP_NEW, "_MAP_NEW" },
148 #endif
149 #ifdef MAP_GROWSDOWN
150 { MAP_GROWSDOWN,"MAP_GROWSDOWN" },
151 #endif
152 #ifdef MAP_DENYWRITE
153 { MAP_DENYWRITE,"MAP_DENYWRITE" },
154 #endif
155 #ifdef MAP_EXECUTABLE
156 { MAP_EXECUTABLE,"MAP_EXECUTABLE"},
157 #endif
158 #ifdef MAP_INHERIT
159 { MAP_INHERIT,"MAP_INHERIT" },
160 #endif
161 #ifdef MAP_FILE
162 { MAP_FILE,"MAP_FILE"},
163 #endif
164 #ifdef MAP_LOCKED
165 { MAP_LOCKED,"MAP_LOCKED"},
166 #endif
167 /* FreeBSD ones */
168 #ifdef MAP_ANON
169 { MAP_ANON, "MAP_ANON" },
170 #endif
171 #ifdef MAP_HASSEMAPHORE
172 { MAP_HASSEMAPHORE, "MAP_HASSEMAPHORE" },
173 #endif
174 #ifdef MAP_STACK
175 { MAP_STACK, "MAP_STACK" },
176 #endif
177 #ifdef MAP_NOSYNC
178 { MAP_NOSYNC, "MAP_NOSYNC" },
179 #endif
180 #ifdef MAP_NOCORE
181 { MAP_NOCORE, "MAP_NOCORE" },
182 #endif
183 { 0, NULL },
184 };
185
186 #if !HAVE_LONG_LONG_OFF_T
187 static
188 int
print_mmap(tcp,u_arg)189 print_mmap(tcp,u_arg)
190 struct tcb *tcp;
191 long *u_arg;
192 {
193 if (entering(tcp)) {
194 /* addr */
195 if (!u_arg[0])
196 tprintf("NULL, ");
197 else
198 tprintf("%#lx, ", u_arg[0]);
199 /* len */
200 tprintf("%lu, ", u_arg[1]);
201 /* prot */
202 printflags(mmap_prot, u_arg[2], "PROT_???");
203 tprintf(", ");
204 /* flags */
205 #ifdef MAP_TYPE
206 printxval(mmap_flags, u_arg[3] & MAP_TYPE, "MAP_???");
207 addflags(mmap_flags, u_arg[3] & ~MAP_TYPE);
208 #else
209 printflags(mmap_flags, u_arg[3], "MAP_???");
210 #endif
211 /* fd (is always int, not long) */
212 tprintf(", %d, ", (int)u_arg[4]);
213 /* offset */
214 tprintf("%#lx", u_arg[5]);
215 }
216 return RVAL_HEX;
217 }
218
219 #ifdef LINUX
sys_old_mmap(tcp)220 int sys_old_mmap(tcp)
221 struct tcb *tcp;
222 {
223 long u_arg[6];
224
225 #if defined(IA64)
226 int i, v;
227 /*
228 * IA64 processes never call this routine, they only use the
229 * new `sys_mmap' interface. This code converts the integer
230 * arguments that the IA32 process pushed onto the stack into
231 * longs.
232 *
233 * Note that addresses with bit 31 set will be sign extended.
234 * Fortunately, those addresses are not currently being generated
235 * for IA32 processes so it's not a problem.
236 */
237 for (i = 0; i < 6; i++)
238 if (umove(tcp, tcp->u_arg[0] + (i * sizeof(int)), &v) == -1)
239 return 0;
240 else
241 u_arg[i] = v;
242 #elif defined(SH) || defined(SH64)
243 /* SH has always passed the args in registers */
244 int i;
245 for (i=0; i<6; i++)
246 u_arg[i] = tcp->u_arg[i];
247 #else
248 if (umoven(tcp, tcp->u_arg[0], sizeof u_arg, (char *) u_arg) == -1)
249 return 0;
250 #endif // defined(IA64)
251 return print_mmap(tcp, u_arg);
252
253 }
254 #endif
255
256 int
sys_mmap(tcp)257 sys_mmap(tcp)
258 struct tcb *tcp;
259 {
260 #if defined(LINUX) && defined(SH64)
261 /*
262 * Old mmap differs from new mmap in specifying the
263 * offset in units of bytes rather than pages. We
264 * pretend it's in byte units so the user only ever
265 * sees bytes in the printout.
266 */
267 tcp->u_arg[5] <<= PAGE_SHIFT;
268 #endif
269 return print_mmap(tcp, tcp->u_arg);
270 }
271 #endif /* !HAVE_LONG_LONG_OFF_T */
272
273 #if _LFS64_LARGEFILE || HAVE_LONG_LONG_OFF_T
274 int
sys_mmap64(tcp)275 sys_mmap64(tcp)
276 struct tcb *tcp;
277 {
278 #ifdef linux
279 #ifdef ALPHA
280 long *u_arg = tcp->u_arg;
281 #else /* !ALPHA */
282 long u_arg[7];
283 #endif /* !ALPHA */
284 #else /* !linux */
285 long *u_arg = tcp->u_arg;
286 #endif /* !linux */
287
288 if (entering(tcp)) {
289 #ifdef linux
290 #ifndef ALPHA
291 if (umoven(tcp, tcp->u_arg[0], sizeof u_arg,
292 (char *) u_arg) == -1)
293 return 0;
294 #endif /* ALPHA */
295 #endif /* linux */
296 ALIGN64 (tcp, 5); /* FreeBSD wierdies */
297
298 /* addr */
299 tprintf("%#lx, ", u_arg[0]);
300 /* len */
301 tprintf("%lu, ", u_arg[1]);
302 /* prot */
303 printflags(mmap_prot, u_arg[2], "PROT_???");
304 tprintf(", ");
305 /* flags */
306 #ifdef MAP_TYPE
307 printxval(mmap_flags, u_arg[3] & MAP_TYPE, "MAP_???");
308 addflags(mmap_flags, u_arg[3] & ~MAP_TYPE);
309 #else
310 printflags(mmap_flags, u_arg[3], "MAP_???");
311 #endif
312 /* fd */
313 tprintf(", %ld, ", u_arg[4]);
314 /* offset */
315 tprintf("%#llx", LONG_LONG(u_arg[5], u_arg[6]));
316 }
317 return RVAL_HEX;
318 }
319 #endif
320
321
322 int
sys_munmap(tcp)323 sys_munmap(tcp)
324 struct tcb *tcp;
325 {
326 if (entering(tcp)) {
327 tprintf("%#lx, %lu",
328 tcp->u_arg[0], tcp->u_arg[1]);
329 }
330 return 0;
331 }
332
333 int
sys_mprotect(tcp)334 sys_mprotect(tcp)
335 struct tcb *tcp;
336 {
337 if (entering(tcp)) {
338 tprintf("%#lx, %lu, ",
339 tcp->u_arg[0], tcp->u_arg[1]);
340 printflags(mmap_prot, tcp->u_arg[2], "PROT_???");
341 }
342 return 0;
343 }
344
345 #ifdef LINUX
346
347 static const struct xlat mremap_flags[] = {
348 { MREMAP_MAYMOVE, "MREMAP_MAYMOVE" },
349 { 0, NULL }
350 };
351
352 int
sys_mremap(tcp)353 sys_mremap(tcp)
354 struct tcb *tcp;
355 {
356 if (entering(tcp)) {
357 tprintf("%#lx, %lu, %lu, ", tcp->u_arg[0], tcp->u_arg[1],
358 tcp->u_arg[2]);
359 printflags(mremap_flags, tcp->u_arg[3], "MREMAP_???");
360 }
361 return RVAL_HEX;
362 }
363
364 static const struct xlat madvise_flags[] = {
365 #ifdef MADV_NORMAL
366 { MADV_NORMAL, "MADV_NORMAL" },
367 #endif
368 #ifdef MADZV_RANDOM
369 { MADV_RANDOM, "MADV_RANDOM" },
370 #endif
371 #ifdef MADV_SEQUENTIAL
372 { MADV_SEQUENTIAL, "MADV_SEQUENTIAL" },
373 #endif
374 #ifdef MADV_WILLNEED
375 { MADV_WILLNEED, "MADV_WILLNEED" },
376 #endif
377 #ifdef MADV_DONTNED
378 { MADV_DONTNEED, "MADV_DONTNEED" },
379 #endif
380 { 0, NULL },
381 };
382
383
384 int
sys_madvise(tcp)385 sys_madvise(tcp)
386 struct tcb *tcp;
387 {
388 if (entering(tcp)) {
389 tprintf("%#lx, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
390 printflags(madvise_flags, tcp->u_arg[2], "MADV_???");
391 }
392 return 0;
393 }
394
395
396 static const struct xlat mlockall_flags[] = {
397 #ifdef MCL_CURRENT
398 { MCL_CURRENT, "MCL_CURRENT" },
399 #endif
400 #ifdef MCL_FUTURE
401 { MCL_FUTURE, "MCL_FUTURE" },
402 #endif
403 { 0, NULL}
404 };
405
406 int
sys_mlockall(tcp)407 sys_mlockall(tcp)
408 struct tcb *tcp;
409 {
410 if (entering(tcp)) {
411 printflags(mlockall_flags, tcp->u_arg[0], "MCL_???");
412 }
413 return 0;
414 }
415
416
417 #endif /* LINUX */
418
419 #ifdef MS_ASYNC
420
421 static const struct xlat mctl_sync[] = {
422 #ifdef MS_SYNC
423 { MS_SYNC, "MS_SYNC" },
424 #endif
425 { MS_ASYNC, "MS_ASYNC" },
426 { MS_INVALIDATE,"MS_INVALIDATE" },
427 { 0, NULL },
428 };
429
430 int
sys_msync(tcp)431 sys_msync(tcp)
432 struct tcb *tcp;
433 {
434 if (entering(tcp)) {
435 /* addr */
436 tprintf("%#lx", tcp->u_arg[0]);
437 /* len */
438 tprintf(", %lu, ", tcp->u_arg[1]);
439 /* flags */
440 printflags(mctl_sync, tcp->u_arg[2], "MS_???");
441 }
442 return 0;
443 }
444
445 #endif /* MS_ASYNC */
446
447 #ifdef MC_SYNC
448
449 static const struct xlat mctl_funcs[] = {
450 { MC_LOCK, "MC_LOCK" },
451 { MC_LOCKAS, "MC_LOCKAS" },
452 { MC_SYNC, "MC_SYNC" },
453 { MC_UNLOCK, "MC_UNLOCK" },
454 { MC_UNLOCKAS, "MC_UNLOCKAS" },
455 { 0, NULL },
456 };
457
458 static const struct xlat mctl_lockas[] = {
459 { MCL_CURRENT, "MCL_CURRENT" },
460 { MCL_FUTURE, "MCL_FUTURE" },
461 { 0, NULL },
462 };
463
464 int
sys_mctl(tcp)465 sys_mctl(tcp)
466 struct tcb *tcp;
467 {
468 int arg, function;
469
470 if (entering(tcp)) {
471 /* addr */
472 tprintf("%#lx", tcp->u_arg[0]);
473 /* len */
474 tprintf(", %lu, ", tcp->u_arg[1]);
475 /* function */
476 function = tcp->u_arg[2];
477 printflags(mctl_funcs, function, "MC_???");
478 /* arg */
479 arg = tcp->u_arg[3];
480 tprintf(", ");
481 switch (function) {
482 case MC_SYNC:
483 printflags(mctl_sync, arg, "MS_???");
484 break;
485 case MC_LOCKAS:
486 printflags(mctl_lockas, arg, "MCL_???");
487 break;
488 default:
489 tprintf("%#x", arg);
490 break;
491 }
492 }
493 return 0;
494 }
495
496 #endif /* MC_SYNC */
497
498 int
sys_mincore(tcp)499 sys_mincore(tcp)
500 struct tcb *tcp;
501 {
502 unsigned long i, len;
503 char *vec = NULL;
504
505 if (entering(tcp)) {
506 tprintf("%#lx, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
507 } else {
508 len = tcp->u_arg[1];
509 if (syserror(tcp) || tcp->u_arg[2] == 0 ||
510 (vec = malloc(len)) == NULL ||
511 umoven(tcp, tcp->u_arg[2], len, vec) < 0)
512 tprintf("%#lx", tcp->u_arg[2]);
513 else {
514 tprintf("[");
515 for (i = 0; i < len; i++) {
516 if (abbrev(tcp) && i >= max_strlen) {
517 tprintf("...");
518 break;
519 }
520 tprintf((vec[i] & 1) ? "1" : "0");
521 }
522 tprintf("]");
523 }
524 if (vec)
525 free(vec);
526 }
527 return 0;
528 }
529
530 int
sys_getpagesize(tcp)531 sys_getpagesize(tcp)
532 struct tcb *tcp;
533 {
534 if (exiting(tcp))
535 return RVAL_HEX;
536 return 0;
537 }
538
539 #if defined(LINUX) && defined(__i386__)
540 void
print_ldt_entry(ldt_entry)541 print_ldt_entry (ldt_entry)
542 struct modify_ldt_ldt_s *ldt_entry;
543 {
544 tprintf("base_addr:%#08lx, "
545 "limit:%d, "
546 "seg_32bit:%d, "
547 "contents:%d, "
548 "read_exec_only:%d, "
549 "limit_in_pages:%d, "
550 "seg_not_present:%d, "
551 "useable:%d}",
552 ldt_entry->base_addr,
553 ldt_entry->limit,
554 ldt_entry->seg_32bit,
555 ldt_entry->contents,
556 ldt_entry->read_exec_only,
557 ldt_entry->limit_in_pages,
558 ldt_entry->seg_not_present,
559 ldt_entry->useable);
560 }
561
562 int
sys_modify_ldt(tcp)563 sys_modify_ldt(tcp)
564 struct tcb *tcp;
565 {
566 if (entering(tcp)) {
567 struct modify_ldt_ldt_s copy;
568 tprintf("%ld", tcp->u_arg[0]);
569 if (tcp->u_arg[1] == 0
570 || tcp->u_arg[2] != sizeof (struct modify_ldt_ldt_s)
571 || umove(tcp, tcp->u_arg[1], ©) == -1)
572 tprintf(", %lx", tcp->u_arg[1]);
573 else {
574 tprintf(", {entry_number:%d, ", copy.entry_number);
575 if (!verbose(tcp))
576 tprintf("...}");
577 else {
578 print_ldt_entry(©);
579 }
580 }
581 tprintf(", %lu", tcp->u_arg[2]);
582 }
583 return 0;
584 }
585
586 int
sys_set_thread_area(tcp)587 sys_set_thread_area(tcp)
588 struct tcb *tcp;
589 {
590 struct modify_ldt_ldt_s copy;
591 if (entering(tcp)) {
592 if (umove(tcp, tcp->u_arg[0], ©) != -1) {
593 if (copy.entry_number == -1)
594 tprintf("{entry_number:%d -> ",
595 copy.entry_number);
596 else
597 tprintf("{entry_number:");
598 }
599 } else {
600 if (umove(tcp, tcp->u_arg[0], ©) != -1) {
601 tprintf("%d, ", copy.entry_number);
602 if (!verbose(tcp))
603 tprintf("...}");
604 else {
605 print_ldt_entry(©);
606 }
607 } else {
608 tprintf("%lx", tcp->u_arg[0]);
609 }
610 }
611 return 0;
612
613 }
614
615 int
sys_get_thread_area(tcp)616 sys_get_thread_area(tcp)
617 struct tcb *tcp;
618 {
619 struct modify_ldt_ldt_s copy;
620 if (exiting(tcp)) {
621 if (umove(tcp, tcp->u_arg[0], ©) != -1) {
622 tprintf("{entry_number:%d, ", copy.entry_number);
623 if (!verbose(tcp))
624 tprintf("...}");
625 else {
626 print_ldt_entry(©);
627 }
628 } else {
629 tprintf("%lx", tcp->u_arg[0]);
630 }
631 }
632 return 0;
633
634 }
635 #endif /* LINUX && __i386__ */
636
637 #if defined(LINUX)
638 int
sys_remap_file_pages(tcp)639 sys_remap_file_pages(tcp)
640 struct tcb *tcp;
641 {
642 if (entering(tcp)) {
643 tprintf("%#lx, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
644 printflags(mmap_prot, tcp->u_arg[2], "PROT_???");
645 tprintf(", %lu, ", tcp->u_arg[3]);
646 #ifdef MAP_TYPE
647 printxval(mmap_flags, tcp->u_arg[4] & MAP_TYPE, "MAP_???");
648 addflags(mmap_flags, tcp->u_arg[4] & ~MAP_TYPE);
649 #else
650 printflags(mmap_flags, tcp->u_arg[4], "MAP_???");
651 #endif
652 }
653 return 0;
654 }
655
656
657 #define MPOL_DEFAULT 0
658 #define MPOL_PREFERRED 1
659 #define MPOL_BIND 2
660 #define MPOL_INTERLEAVE 3
661
662 #define MPOL_F_NODE (1<<0)
663 #define MPOL_F_ADDR (1<<1)
664
665 #define MPOL_MF_STRICT (1<<0)
666
667
668 static const struct xlat policies[] = {
669 { MPOL_DEFAULT, "MPOL_DEFAULT" },
670 { MPOL_PREFERRED, "MPOL_PREFERRED" },
671 { MPOL_BIND, "MPOL_BIND" },
672 { MPOL_INTERLEAVE, "MPOL_INTERLEAVE" },
673 { 0, NULL }
674 };
675
676 static const struct xlat mbindflags[] = {
677 { MPOL_MF_STRICT, "MPOL_MF_STRICT" },
678 { 0, NULL }
679 };
680
681 static const struct xlat mempolicyflags[] = {
682 { MPOL_F_NODE, "MPOL_F_NODE" },
683 { MPOL_F_ADDR, "MPOL_F_ADDR" },
684 { 0, NULL }
685 };
686
687
688 static void
get_nodes(tcp,ptr,maxnodes,err)689 get_nodes(tcp, ptr, maxnodes, err)
690 struct tcb *tcp;
691 unsigned long ptr;
692 unsigned long maxnodes;
693 int err;
694 {
695 unsigned long nlongs, size, end;
696
697 nlongs = (maxnodes + 8 * sizeof(long) - 1) / (8 * sizeof(long));
698 size = nlongs * sizeof(long);
699 end = ptr + size;
700 if (nlongs == 0 || ((err || verbose(tcp)) && (size * 8 == maxnodes)
701 && (end > ptr))) {
702 unsigned long n, cur, abbrev_end;
703 int failed = 0;
704
705 if (abbrev(tcp)) {
706 abbrev_end = ptr + max_strlen * sizeof(long);
707 if (abbrev_end < ptr)
708 abbrev_end = end;
709 } else {
710 abbrev_end = end;
711 }
712 tprintf(", {");
713 for (cur = ptr; cur < end; cur += sizeof(long)) {
714 if (cur > ptr)
715 tprintf(", ");
716 if (cur >= abbrev_end) {
717 tprintf("...");
718 break;
719 }
720 if (umoven(tcp, cur, sizeof(n), (char *) &n) < 0) {
721 tprintf("?");
722 failed = 1;
723 break;
724 }
725 tprintf("%#0*lx", (int) sizeof(long) * 2 + 2, n);
726 }
727 tprintf("}");
728 if (failed)
729 tprintf(" %#lx", ptr);
730 } else
731 tprintf(", %#lx", ptr);
732 tprintf(", %lu", maxnodes);
733 }
734
735 int
sys_mbind(tcp)736 sys_mbind(tcp)
737 struct tcb *tcp;
738 {
739 if (entering(tcp)) {
740 tprintf("%lu, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
741 printxval(policies, tcp->u_arg[2], "MPOL_???");
742 get_nodes(tcp, tcp->u_arg[3], tcp->u_arg[4], 0);
743 tprintf(", ");
744 printflags(mbindflags, tcp->u_arg[5], "MPOL_???");
745 }
746 return 0;
747 }
748
749 int
sys_set_mempolicy(tcp)750 sys_set_mempolicy(tcp)
751 struct tcb *tcp;
752 {
753 if (entering(tcp)) {
754 printxval(policies, tcp->u_arg[0], "MPOL_???");
755 get_nodes(tcp, tcp->u_arg[1], tcp->u_arg[2], 0);
756 }
757 return 0;
758 }
759
760 int
sys_get_mempolicy(tcp)761 sys_get_mempolicy(tcp)
762 struct tcb *tcp;
763 {
764 if (exiting(tcp)) {
765 int pol;
766 if (tcp->u_arg[0] == 0)
767 tprintf("NULL");
768 else if (syserror(tcp) || umove(tcp, tcp->u_arg[0], &pol) < 0)
769 tprintf("%#lx", tcp->u_arg[0]);
770 else
771 printxval(policies, pol, "MPOL_???");
772 get_nodes(tcp, tcp->u_arg[1], tcp->u_arg[2], syserror(tcp));
773 tprintf(", %#lx, ", tcp->u_arg[3]);
774 printflags(mempolicyflags, tcp->u_arg[4], "MPOL_???");
775 }
776 return 0;
777 }
778 #endif
779