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$ 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 #if defined(FREEBSD) || defined(SUNOS4) 74 int 75 sys_sbrk(tcp) 76 struct tcb *tcp; 77 { 78 if (entering(tcp)) { 79 tprintf("%lu", tcp->u_arg[0]); 80 } 81 return RVAL_HEX; 82 } 83 #endif /* FREEBSD || SUNOS4 */ 84 85 static const struct xlat mmap_prot[] = { 86 { PROT_NONE, "PROT_NONE", }, 87 { PROT_READ, "PROT_READ" }, 88 { PROT_WRITE, "PROT_WRITE" }, 89 { PROT_EXEC, "PROT_EXEC" }, 90 #ifdef PROT_SEM 91 { PROT_SEM, "PROT_SEM" }, 92 #endif 93 #ifdef PROT_GROWSDOWN 94 { PROT_GROWSDOWN,"PROT_GROWSDOWN"}, 95 #endif 96 #ifdef PROT_GROWSUP 97 { PROT_GROWSUP, "PROT_GROWSUP" }, 98 #endif 99 #ifdef PROT_SAO 100 { PROT_SAO, "PROT_SAO" }, 101 #endif 102 { 0, NULL }, 103 }; 104 105 static const struct xlat mmap_flags[] = { 106 { MAP_SHARED, "MAP_SHARED" }, 107 { MAP_PRIVATE, "MAP_PRIVATE" }, 108 { MAP_FIXED, "MAP_FIXED" }, 109 #ifdef MAP_ANONYMOUS 110 { MAP_ANONYMOUS,"MAP_ANONYMOUS" }, 111 #endif 112 #ifdef MAP_32BIT 113 { MAP_32BIT, "MAP_32BIT" }, 114 #endif 115 #ifdef MAP_RENAME 116 { MAP_RENAME, "MAP_RENAME" }, 117 #endif 118 #ifdef MAP_NORESERVE 119 { MAP_NORESERVE,"MAP_NORESERVE" }, 120 #endif 121 #ifdef MAP_POPULATE 122 { MAP_POPULATE, "MAP_POPULATE" }, 123 #endif 124 #ifdef MAP_NONBLOCK 125 { MAP_NONBLOCK, "MAP_NONBLOCK" }, 126 #endif 127 /* 128 * XXX - this was introduced in SunOS 4.x to distinguish between 129 * the old pre-4.x "mmap()", which: 130 * 131 * only let you map devices with an "mmap" routine (e.g., 132 * frame buffers) in; 133 * 134 * required you to specify the mapping address; 135 * 136 * returned 0 on success and -1 on failure; 137 * 138 * memory and which, and the 4.x "mmap()" which: 139 * 140 * can map plain files; 141 * 142 * can be asked to pick where to map the file; 143 * 144 * returns the address where it mapped the file on success 145 * and -1 on failure. 146 * 147 * It's not actually used in source code that calls "mmap()"; the 148 * "mmap()" routine adds it for you. 149 * 150 * It'd be nice to come up with some way of eliminating it from 151 * the flags, e.g. reporting calls *without* it as "old_mmap()" 152 * and calls with it as "mmap()". 153 */ 154 #ifdef _MAP_NEW 155 { _MAP_NEW, "_MAP_NEW" }, 156 #endif 157 #ifdef MAP_GROWSDOWN 158 { MAP_GROWSDOWN,"MAP_GROWSDOWN" }, 159 #endif 160 #ifdef MAP_DENYWRITE 161 { MAP_DENYWRITE,"MAP_DENYWRITE" }, 162 #endif 163 #ifdef MAP_EXECUTABLE 164 { MAP_EXECUTABLE,"MAP_EXECUTABLE"}, 165 #endif 166 #ifdef MAP_INHERIT 167 { MAP_INHERIT,"MAP_INHERIT" }, 168 #endif 169 #ifdef MAP_FILE 170 { MAP_FILE,"MAP_FILE"}, 171 #endif 172 #ifdef MAP_LOCKED 173 { MAP_LOCKED,"MAP_LOCKED"}, 174 #endif 175 /* FreeBSD ones */ 176 #ifdef MAP_ANON 177 { MAP_ANON, "MAP_ANON" }, 178 #endif 179 #ifdef MAP_HASSEMAPHORE 180 { MAP_HASSEMAPHORE, "MAP_HASSEMAPHORE" }, 181 #endif 182 #ifdef MAP_STACK 183 { MAP_STACK, "MAP_STACK" }, 184 #endif 185 #ifdef MAP_NOSYNC 186 { MAP_NOSYNC, "MAP_NOSYNC" }, 187 #endif 188 #ifdef MAP_NOCORE 189 { MAP_NOCORE, "MAP_NOCORE" }, 190 #endif 191 #ifdef TILE 192 { MAP_CACHE_NO_LOCAL, "MAP_CACHE_NO_LOCAL" }, 193 { MAP_CACHE_NO_L2, "MAP_CACHE_NO_L2" }, 194 { MAP_CACHE_NO_L1, "MAP_CACHE_NO_L1" }, 195 #endif 196 { 0, NULL }, 197 }; 198 199 #ifdef TILE 200 static 201 int 202 addtileflags(flags) 203 long flags; 204 { 205 long home = flags & _MAP_CACHE_MKHOME(_MAP_CACHE_HOME_MASK); 206 flags &= ~_MAP_CACHE_MKHOME(_MAP_CACHE_HOME_MASK); 207 208 if (flags & _MAP_CACHE_INCOHERENT) { 209 flags &= ~_MAP_CACHE_INCOHERENT; 210 if (home == MAP_CACHE_HOME_NONE) { 211 tprintf("|MAP_CACHE_INCOHERENT"); 212 return flags; 213 } 214 tprintf("|_MAP_CACHE_INCOHERENT"); 215 } 216 217 switch (home) { 218 case 0: break; 219 case MAP_CACHE_HOME_HERE: tprintf("|MAP_CACHE_HOME_HERE"); break; 220 case MAP_CACHE_HOME_NONE: tprintf("|MAP_CACHE_HOME_NONE"); break; 221 case MAP_CACHE_HOME_SINGLE: tprintf("|MAP_CACHE_HOME_SINGLE"); break; 222 case MAP_CACHE_HOME_TASK: tprintf("|MAP_CACHE_HOME_TASK"); break; 223 case MAP_CACHE_HOME_HASH: tprintf("|MAP_CACHE_HOME_HASH"); break; 224 default: 225 tprintf("|MAP_CACHE_HOME(%d)", 226 (home >> _MAP_CACHE_HOME_SHIFT) ); 227 break; 228 } 229 230 return flags; 231 } 232 #endif 233 234 #if !HAVE_LONG_LONG_OFF_T 235 static int 236 print_mmap(struct tcb *tcp, long *u_arg, long long offset) 237 { 238 if (entering(tcp)) { 239 /* addr */ 240 if (!u_arg[0]) 241 tprintf("NULL, "); 242 else 243 tprintf("%#lx, ", u_arg[0]); 244 /* len */ 245 tprintf("%lu, ", u_arg[1]); 246 /* prot */ 247 printflags(mmap_prot, u_arg[2], "PROT_???"); 248 tprintf(", "); 249 /* flags */ 250 #ifdef MAP_TYPE 251 printxval(mmap_flags, u_arg[3] & MAP_TYPE, "MAP_???"); 252 #ifdef TILE 253 addflags(mmap_flags, addtileflags(u_arg[3] & ~MAP_TYPE)); 254 #else 255 addflags(mmap_flags, u_arg[3] & ~MAP_TYPE); 256 #endif 257 #else 258 printflags(mmap_flags, u_arg[3], "MAP_???"); 259 #endif 260 /* fd */ 261 tprintf(", "); 262 printfd(tcp, u_arg[4]); 263 /* offset */ 264 tprintf(", %#llx", offset); 265 } 266 return RVAL_HEX; 267 } 268 269 #ifdef LINUX 270 int sys_old_mmap(tcp) 271 struct tcb *tcp; 272 { 273 long u_arg[6]; 274 275 #if defined(IA64) 276 int i, v; 277 /* 278 * IA64 processes never call this routine, they only use the 279 * new `sys_mmap' interface. This code converts the integer 280 * arguments that the IA32 process pushed onto the stack into 281 * longs. 282 * 283 * Note that addresses with bit 31 set will be sign extended. 284 * Fortunately, those addresses are not currently being generated 285 * for IA32 processes so it's not a problem. 286 */ 287 for (i = 0; i < 6; i++) 288 if (umove(tcp, tcp->u_arg[0] + (i * sizeof(int)), &v) == -1) 289 return 0; 290 else 291 u_arg[i] = v; 292 #elif defined(SH) || defined(SH64) 293 /* SH has always passed the args in registers */ 294 int i; 295 for (i=0; i<6; i++) 296 u_arg[i] = tcp->u_arg[i]; 297 #else 298 # if defined(X86_64) 299 if (current_personality == 1) { 300 int i; 301 for (i = 0; i < 6; ++i) { 302 unsigned int val; 303 if (umove(tcp, tcp->u_arg[0] + i * 4, &val) == -1) 304 return 0; 305 u_arg[i] = val; 306 } 307 } 308 else 309 # endif 310 if (umoven(tcp, tcp->u_arg[0], sizeof u_arg, (char *) u_arg) == -1) 311 return 0; 312 #endif // defined(IA64) 313 return print_mmap(tcp, u_arg, u_arg[5]); 314 } 315 #endif 316 317 int 318 sys_mmap(tcp) 319 struct tcb *tcp; 320 { 321 long long offset = tcp->u_arg[5]; 322 323 #if defined(LINUX) && defined(SH64) 324 /* 325 * Old mmap differs from new mmap in specifying the 326 * offset in units of bytes rather than pages. We 327 * pretend it's in byte units so the user only ever 328 * sees bytes in the printout. 329 */ 330 offset <<= PAGE_SHIFT; 331 #endif 332 #if defined(LINUX_MIPSN32) 333 offset = tcp->ext_arg[5]; 334 #endif 335 return print_mmap(tcp, tcp->u_arg, offset); 336 } 337 #endif /* !HAVE_LONG_LONG_OFF_T */ 338 339 #if _LFS64_LARGEFILE || HAVE_LONG_LONG_OFF_T 340 int 341 sys_mmap64(struct tcb *tcp) 342 { 343 #ifdef linux 344 #ifdef ALPHA 345 long *u_arg = tcp->u_arg; 346 #else /* !ALPHA */ 347 long u_arg[7]; 348 #endif /* !ALPHA */ 349 #else /* !linux */ 350 long *u_arg = tcp->u_arg; 351 #endif /* !linux */ 352 353 if (entering(tcp)) { 354 #ifdef linux 355 #ifndef ALPHA 356 if (umoven(tcp, tcp->u_arg[0], sizeof u_arg, 357 (char *) u_arg) == -1) 358 return 0; 359 #endif /* ALPHA */ 360 #endif /* linux */ 361 362 /* addr */ 363 tprintf("%#lx, ", u_arg[0]); 364 /* len */ 365 tprintf("%lu, ", u_arg[1]); 366 /* prot */ 367 printflags(mmap_prot, u_arg[2], "PROT_???"); 368 tprintf(", "); 369 /* flags */ 370 #ifdef MAP_TYPE 371 printxval(mmap_flags, u_arg[3] & MAP_TYPE, "MAP_???"); 372 addflags(mmap_flags, u_arg[3] & ~MAP_TYPE); 373 #else 374 printflags(mmap_flags, u_arg[3], "MAP_???"); 375 #endif 376 /* fd */ 377 tprintf(", "); 378 printfd(tcp, tcp->u_arg[4]); 379 /* offset */ 380 printllval(tcp, ", %#llx", 5); 381 } 382 return RVAL_HEX; 383 } 384 #endif 385 386 387 int 388 sys_munmap(tcp) 389 struct tcb *tcp; 390 { 391 if (entering(tcp)) { 392 tprintf("%#lx, %lu", 393 tcp->u_arg[0], tcp->u_arg[1]); 394 } 395 return 0; 396 } 397 398 int 399 sys_mprotect(tcp) 400 struct tcb *tcp; 401 { 402 if (entering(tcp)) { 403 tprintf("%#lx, %lu, ", 404 tcp->u_arg[0], tcp->u_arg[1]); 405 printflags(mmap_prot, tcp->u_arg[2], "PROT_???"); 406 } 407 return 0; 408 } 409 410 #ifdef LINUX 411 412 static const struct xlat mremap_flags[] = { 413 { MREMAP_MAYMOVE, "MREMAP_MAYMOVE" }, 414 #ifdef MREMAP_FIXED 415 { MREMAP_FIXED, "MREMAP_FIXED" }, 416 #endif 417 { 0, NULL } 418 }; 419 420 int 421 sys_mremap(struct tcb *tcp) 422 { 423 if (entering(tcp)) { 424 tprintf("%#lx, %lu, %lu, ", tcp->u_arg[0], tcp->u_arg[1], 425 tcp->u_arg[2]); 426 printflags(mremap_flags, tcp->u_arg[3], "MREMAP_???"); 427 #ifdef MREMAP_FIXED 428 if ((tcp->u_arg[3] & (MREMAP_MAYMOVE | MREMAP_FIXED)) == 429 (MREMAP_MAYMOVE | MREMAP_FIXED)) 430 tprintf(", %#lx", tcp->u_arg[4]); 431 #endif 432 } 433 return RVAL_HEX; 434 } 435 436 static const struct xlat madvise_cmds[] = { 437 #ifdef MADV_NORMAL 438 { MADV_NORMAL, "MADV_NORMAL" }, 439 #endif 440 #ifdef MADV_RANDOM 441 { MADV_RANDOM, "MADV_RANDOM" }, 442 #endif 443 #ifdef MADV_SEQUENTIAL 444 { MADV_SEQUENTIAL, "MADV_SEQUENTIAL" }, 445 #endif 446 #ifdef MADV_WILLNEED 447 { MADV_WILLNEED, "MADV_WILLNEED" }, 448 #endif 449 #ifdef MADV_DONTNEED 450 { MADV_DONTNEED, "MADV_DONTNEED" }, 451 #endif 452 { 0, NULL }, 453 }; 454 455 456 int 457 sys_madvise(tcp) 458 struct tcb *tcp; 459 { 460 if (entering(tcp)) { 461 tprintf("%#lx, %lu, ", tcp->u_arg[0], tcp->u_arg[1]); 462 printxval(madvise_cmds, tcp->u_arg[2], "MADV_???"); 463 } 464 return 0; 465 } 466 467 468 static const struct xlat mlockall_flags[] = { 469 #ifdef MCL_CURRENT 470 { MCL_CURRENT, "MCL_CURRENT" }, 471 #endif 472 #ifdef MCL_FUTURE 473 { MCL_FUTURE, "MCL_FUTURE" }, 474 #endif 475 { 0, NULL} 476 }; 477 478 int 479 sys_mlockall(tcp) 480 struct tcb *tcp; 481 { 482 if (entering(tcp)) { 483 printflags(mlockall_flags, tcp->u_arg[0], "MCL_???"); 484 } 485 return 0; 486 } 487 488 489 #endif /* LINUX */ 490 491 #ifdef MS_ASYNC 492 493 static const struct xlat mctl_sync[] = { 494 #ifdef MS_SYNC 495 { MS_SYNC, "MS_SYNC" }, 496 #endif 497 { MS_ASYNC, "MS_ASYNC" }, 498 { MS_INVALIDATE,"MS_INVALIDATE" }, 499 { 0, NULL }, 500 }; 501 502 int 503 sys_msync(tcp) 504 struct tcb *tcp; 505 { 506 if (entering(tcp)) { 507 /* addr */ 508 tprintf("%#lx", tcp->u_arg[0]); 509 /* len */ 510 tprintf(", %lu, ", tcp->u_arg[1]); 511 /* flags */ 512 printflags(mctl_sync, tcp->u_arg[2], "MS_???"); 513 } 514 return 0; 515 } 516 517 #endif /* MS_ASYNC */ 518 519 #ifdef MC_SYNC 520 521 static const struct xlat mctl_funcs[] = { 522 { MC_LOCK, "MC_LOCK" }, 523 { MC_LOCKAS, "MC_LOCKAS" }, 524 { MC_SYNC, "MC_SYNC" }, 525 { MC_UNLOCK, "MC_UNLOCK" }, 526 { MC_UNLOCKAS, "MC_UNLOCKAS" }, 527 { 0, NULL }, 528 }; 529 530 static const struct xlat mctl_lockas[] = { 531 { MCL_CURRENT, "MCL_CURRENT" }, 532 { MCL_FUTURE, "MCL_FUTURE" }, 533 { 0, NULL }, 534 }; 535 536 int 537 sys_mctl(tcp) 538 struct tcb *tcp; 539 { 540 int arg, function; 541 542 if (entering(tcp)) { 543 /* addr */ 544 tprintf("%#lx", tcp->u_arg[0]); 545 /* len */ 546 tprintf(", %lu, ", tcp->u_arg[1]); 547 /* function */ 548 function = tcp->u_arg[2]; 549 printflags(mctl_funcs, function, "MC_???"); 550 /* arg */ 551 arg = tcp->u_arg[3]; 552 tprintf(", "); 553 switch (function) { 554 case MC_SYNC: 555 printflags(mctl_sync, arg, "MS_???"); 556 break; 557 case MC_LOCKAS: 558 printflags(mctl_lockas, arg, "MCL_???"); 559 break; 560 default: 561 tprintf("%#x", arg); 562 break; 563 } 564 } 565 return 0; 566 } 567 568 #endif /* MC_SYNC */ 569 570 int 571 sys_mincore(tcp) 572 struct tcb *tcp; 573 { 574 unsigned long i, len; 575 char *vec = NULL; 576 577 if (entering(tcp)) { 578 tprintf("%#lx, %lu, ", tcp->u_arg[0], tcp->u_arg[1]); 579 } else { 580 len = tcp->u_arg[1]; 581 if (syserror(tcp) || tcp->u_arg[2] == 0 || 582 (vec = malloc(len)) == NULL || 583 umoven(tcp, tcp->u_arg[2], len, vec) < 0) 584 tprintf("%#lx", tcp->u_arg[2]); 585 else { 586 tprintf("["); 587 for (i = 0; i < len; i++) { 588 if (abbrev(tcp) && i >= max_strlen) { 589 tprintf("..."); 590 break; 591 } 592 tprintf((vec[i] & 1) ? "1" : "0"); 593 } 594 tprintf("]"); 595 } 596 if (vec) 597 free(vec); 598 } 599 return 0; 600 } 601 602 #if defined(ALPHA) || defined(FREEBSD) || defined(IA64) || defined(SUNOS4) || defined(SVR4) || defined(SPARC) || defined(SPARC64) 603 int 604 sys_getpagesize(tcp) 605 struct tcb *tcp; 606 { 607 if (exiting(tcp)) 608 return RVAL_HEX; 609 return 0; 610 } 611 #endif /* ALPHA || FREEBSD || IA64 || SUNOS4 || SVR4 */ 612 613 #if defined(LINUX) && defined(__i386__) 614 void 615 print_ldt_entry(struct modify_ldt_ldt_s *ldt_entry) 616 { 617 tprintf("base_addr:%#08lx, " 618 "limit:%d, " 619 "seg_32bit:%d, " 620 "contents:%d, " 621 "read_exec_only:%d, " 622 "limit_in_pages:%d, " 623 "seg_not_present:%d, " 624 "useable:%d}", 625 (long) ldt_entry->base_addr, 626 ldt_entry->limit, 627 ldt_entry->seg_32bit, 628 ldt_entry->contents, 629 ldt_entry->read_exec_only, 630 ldt_entry->limit_in_pages, 631 ldt_entry->seg_not_present, 632 ldt_entry->useable); 633 } 634 635 int 636 sys_modify_ldt(tcp) 637 struct tcb *tcp; 638 { 639 if (entering(tcp)) { 640 struct modify_ldt_ldt_s copy; 641 tprintf("%ld", tcp->u_arg[0]); 642 if (tcp->u_arg[1] == 0 643 || tcp->u_arg[2] != sizeof (struct modify_ldt_ldt_s) 644 || umove(tcp, tcp->u_arg[1], ©) == -1) 645 tprintf(", %lx", tcp->u_arg[1]); 646 else { 647 tprintf(", {entry_number:%d, ", copy.entry_number); 648 if (!verbose(tcp)) 649 tprintf("...}"); 650 else { 651 print_ldt_entry(©); 652 } 653 } 654 tprintf(", %lu", tcp->u_arg[2]); 655 } 656 return 0; 657 } 658 659 int 660 sys_set_thread_area(tcp) 661 struct tcb *tcp; 662 { 663 struct modify_ldt_ldt_s copy; 664 if (entering(tcp)) { 665 if (umove(tcp, tcp->u_arg[0], ©) != -1) { 666 if (copy.entry_number == -1) 667 tprintf("{entry_number:%d -> ", 668 copy.entry_number); 669 else 670 tprintf("{entry_number:"); 671 } 672 } else { 673 if (umove(tcp, tcp->u_arg[0], ©) != -1) { 674 tprintf("%d, ", copy.entry_number); 675 if (!verbose(tcp)) 676 tprintf("...}"); 677 else { 678 print_ldt_entry(©); 679 } 680 } else { 681 tprintf("%lx", tcp->u_arg[0]); 682 } 683 } 684 return 0; 685 686 } 687 688 int 689 sys_get_thread_area(tcp) 690 struct tcb *tcp; 691 { 692 struct modify_ldt_ldt_s copy; 693 if (exiting(tcp)) { 694 if (umove(tcp, tcp->u_arg[0], ©) != -1) { 695 tprintf("{entry_number:%d, ", copy.entry_number); 696 if (!verbose(tcp)) 697 tprintf("...}"); 698 else { 699 print_ldt_entry(©); 700 } 701 } else { 702 tprintf("%lx", tcp->u_arg[0]); 703 } 704 } 705 return 0; 706 707 } 708 #endif /* LINUX && __i386__ */ 709 710 #if defined(LINUX) && defined(M68K) 711 712 int 713 sys_set_thread_area(tcp) 714 struct tcb *tcp; 715 { 716 if (entering(tcp)) 717 tprintf("%#lx", tcp->u_arg[0]); 718 return 0; 719 720 } 721 722 int 723 sys_get_thread_area(tcp) 724 struct tcb *tcp; 725 { 726 return RVAL_HEX; 727 } 728 #endif 729 730 #if defined(LINUX) 731 int 732 sys_remap_file_pages(tcp) 733 struct tcb *tcp; 734 { 735 if (entering(tcp)) { 736 tprintf("%#lx, %lu, ", tcp->u_arg[0], tcp->u_arg[1]); 737 printflags(mmap_prot, tcp->u_arg[2], "PROT_???"); 738 tprintf(", %lu, ", tcp->u_arg[3]); 739 #ifdef MAP_TYPE 740 printxval(mmap_flags, tcp->u_arg[4] & MAP_TYPE, "MAP_???"); 741 addflags(mmap_flags, tcp->u_arg[4] & ~MAP_TYPE); 742 #else 743 printflags(mmap_flags, tcp->u_arg[4], "MAP_???"); 744 #endif 745 } 746 return 0; 747 } 748 749 750 #define MPOL_DEFAULT 0 751 #define MPOL_PREFERRED 1 752 #define MPOL_BIND 2 753 #define MPOL_INTERLEAVE 3 754 755 #define MPOL_F_NODE (1<<0) 756 #define MPOL_F_ADDR (1<<1) 757 758 #define MPOL_MF_STRICT (1<<0) 759 #define MPOL_MF_MOVE (1<<1) 760 #define MPOL_MF_MOVE_ALL (1<<2) 761 762 763 static const struct xlat policies[] = { 764 { MPOL_DEFAULT, "MPOL_DEFAULT" }, 765 { MPOL_PREFERRED, "MPOL_PREFERRED" }, 766 { MPOL_BIND, "MPOL_BIND" }, 767 { MPOL_INTERLEAVE, "MPOL_INTERLEAVE" }, 768 { 0, NULL } 769 }; 770 771 static const struct xlat mbindflags[] = { 772 { MPOL_MF_STRICT, "MPOL_MF_STRICT" }, 773 { MPOL_MF_MOVE, "MPOL_MF_MOVE" }, 774 { MPOL_MF_MOVE_ALL, "MPOL_MF_MOVE_ALL" }, 775 { 0, NULL } 776 }; 777 778 static const struct xlat mempolicyflags[] = { 779 { MPOL_F_NODE, "MPOL_F_NODE" }, 780 { MPOL_F_ADDR, "MPOL_F_ADDR" }, 781 { 0, NULL } 782 }; 783 784 static const struct xlat move_pages_flags[] = { 785 { MPOL_MF_MOVE, "MPOL_MF_MOVE" }, 786 { MPOL_MF_MOVE_ALL, "MPOL_MF_MOVE_ALL" }, 787 { 0, NULL } 788 }; 789 790 791 static void 792 get_nodes(tcp, ptr, maxnodes, err) 793 struct tcb *tcp; 794 unsigned long ptr; 795 unsigned long maxnodes; 796 int err; 797 { 798 unsigned long nlongs, size, end; 799 800 nlongs = (maxnodes + 8 * sizeof(long) - 1) / (8 * sizeof(long)); 801 size = nlongs * sizeof(long); 802 end = ptr + size; 803 if (nlongs == 0 || ((err || verbose(tcp)) && (size * 8 == maxnodes) 804 && (end > ptr))) { 805 unsigned long n, cur, abbrev_end; 806 int failed = 0; 807 808 if (abbrev(tcp)) { 809 abbrev_end = ptr + max_strlen * sizeof(long); 810 if (abbrev_end < ptr) 811 abbrev_end = end; 812 } else { 813 abbrev_end = end; 814 } 815 tprintf(", {"); 816 for (cur = ptr; cur < end; cur += sizeof(long)) { 817 if (cur > ptr) 818 tprintf(", "); 819 if (cur >= abbrev_end) { 820 tprintf("..."); 821 break; 822 } 823 if (umoven(tcp, cur, sizeof(n), (char *) &n) < 0) { 824 tprintf("?"); 825 failed = 1; 826 break; 827 } 828 tprintf("%#0*lx", (int) sizeof(long) * 2 + 2, n); 829 } 830 tprintf("}"); 831 if (failed) 832 tprintf(" %#lx", ptr); 833 } else 834 tprintf(", %#lx", ptr); 835 tprintf(", %lu", maxnodes); 836 } 837 838 int 839 sys_mbind(tcp) 840 struct tcb *tcp; 841 { 842 if (entering(tcp)) { 843 tprintf("%#lx, %lu, ", tcp->u_arg[0], tcp->u_arg[1]); 844 printxval(policies, tcp->u_arg[2], "MPOL_???"); 845 get_nodes(tcp, tcp->u_arg[3], tcp->u_arg[4], 0); 846 tprintf(", "); 847 printflags(mbindflags, tcp->u_arg[5], "MPOL_???"); 848 } 849 return 0; 850 } 851 852 int 853 sys_set_mempolicy(tcp) 854 struct tcb *tcp; 855 { 856 if (entering(tcp)) { 857 printxval(policies, tcp->u_arg[0], "MPOL_???"); 858 get_nodes(tcp, tcp->u_arg[1], tcp->u_arg[2], 0); 859 } 860 return 0; 861 } 862 863 int 864 sys_get_mempolicy(tcp) 865 struct tcb *tcp; 866 { 867 if (exiting(tcp)) { 868 int pol; 869 if (tcp->u_arg[0] == 0) 870 tprintf("NULL"); 871 else if (syserror(tcp) || umove(tcp, tcp->u_arg[0], &pol) < 0) 872 tprintf("%#lx", tcp->u_arg[0]); 873 else 874 printxval(policies, pol, "MPOL_???"); 875 get_nodes(tcp, tcp->u_arg[1], tcp->u_arg[2], syserror(tcp)); 876 tprintf(", %#lx, ", tcp->u_arg[3]); 877 printflags(mempolicyflags, tcp->u_arg[4], "MPOL_???"); 878 } 879 return 0; 880 } 881 882 int 883 sys_move_pages(tcp) 884 struct tcb *tcp; 885 { 886 if (entering(tcp)) { 887 unsigned long npages = tcp->u_arg[1]; 888 tprintf("%ld, %lu, ", tcp->u_arg[0], npages); 889 if (tcp->u_arg[2] == 0) 890 tprintf("NULL, "); 891 else { 892 int i; 893 long puser = tcp->u_arg[2]; 894 tprintf("{"); 895 for (i = 0; i < npages; ++i) { 896 void *p; 897 if (i > 0) 898 tprintf(", "); 899 if (umove(tcp, puser, &p) < 0) { 900 tprintf("???"); 901 break; 902 } 903 tprintf("%p", p); 904 puser += sizeof (void *); 905 } 906 tprintf("}, "); 907 } 908 if (tcp->u_arg[3] == 0) 909 tprintf("NULL, "); 910 else { 911 int i; 912 long nodeuser = tcp->u_arg[3]; 913 tprintf("{"); 914 for (i = 0; i < npages; ++i) { 915 int node; 916 if (i > 0) 917 tprintf(", "); 918 if (umove(tcp, nodeuser, &node) < 0) { 919 tprintf("???"); 920 break; 921 } 922 tprintf("%#x", node); 923 nodeuser += sizeof (int); 924 } 925 tprintf("}, "); 926 } 927 } 928 if (exiting(tcp)) { 929 unsigned long npages = tcp->u_arg[1]; 930 if (tcp->u_arg[4] == 0) 931 tprintf("NULL, "); 932 else { 933 int i; 934 long statususer = tcp->u_arg[4]; 935 tprintf("{"); 936 for (i = 0; i < npages; ++i) { 937 int status; 938 if (i > 0) 939 tprintf(", "); 940 if (umove(tcp, statususer, &status) < 0) { 941 tprintf("???"); 942 break; 943 } 944 tprintf("%#x", status); 945 statususer += sizeof (int); 946 } 947 tprintf("}, "); 948 } 949 printflags(move_pages_flags, tcp->u_arg[5], "MPOL_???"); 950 } 951 return 0; 952 } 953 #endif 954 955 #if defined(LINUX) && defined(POWERPC) 956 int 957 sys_subpage_prot(tcp) 958 struct tcb *tcp; 959 { 960 if (entering(tcp)) { 961 unsigned long cur, end, abbrev_end, entries; 962 unsigned int entry; 963 964 tprintf("%#lx, %#lx, ", tcp->u_arg[0], tcp->u_arg[1]); 965 entries = tcp->u_arg[1] >> 16; 966 if (!entries || !tcp->u_arg[2]) { 967 tprintf("{}"); 968 return 0; 969 } 970 cur = tcp->u_arg[2]; 971 end = cur + (sizeof(int) * entries); 972 if (!verbose(tcp) || end < tcp->u_arg[2]) { 973 tprintf("%#lx", tcp->u_arg[2]); 974 return 0; 975 } 976 if (abbrev(tcp)) { 977 abbrev_end = cur + (sizeof(int) * max_strlen); 978 if (abbrev_end > end) 979 abbrev_end = end; 980 } 981 else 982 abbrev_end = end; 983 tprintf("{"); 984 for (; cur < end; cur += sizeof(int)) { 985 if (cur > tcp->u_arg[2]) 986 tprintf(", "); 987 if (cur >= abbrev_end) { 988 tprintf("..."); 989 break; 990 } 991 if (umove(tcp, cur, &entry) < 0) { 992 tprintf("??? [%#lx]", cur); 993 break; 994 } 995 else 996 tprintf("%#08x", entry); 997 } 998 tprintf("}"); 999 } 1000 1001 return 0; 1002 } 1003 #endif 1004