1 /* 2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk (at) cs.few.eur.nl> 3 * Copyright (c) 1993 Branko Lankester <branko (at) hacktic.nl> 4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs (at) world.std.com> 5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert (at) cistron.nl> 6 * Copyright (c) 2000 PocketPenguins Inc. Linux for Hitachi SuperH 7 * port by Greg Banks <gbanks (at) 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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