1/* 2 * Copyright © 2009 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 15 * contributors may be used to endorse or promote products derived from this 16 * software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * @APPLE_LICENSE_HEADER_END@ 30 */ 31/* 32 * This file intention is to beable to print the structures in an object file 33 * and handle problems with reguard to alignment and bytesex. The goal is to 34 * print as much as possible even when things are truncated or trashed. Both 35 * a verbose (symbolic) and non-verbose modes are supported to aid in seeing 36 * the values even if they are not correct. As much as possible strict checks 37 * on values of fields for correctness should be done (such as proper alignment) 38 * and notations on errors should be printed. 39 */ 40 41#define __cr cr 42#define __ctr ctr 43#define __dar dar 44#define __dsisr dsisr 45#define __exception exception 46#define __fpregs fpregs 47#define __fpscr fpscr 48#define __fpscr_pad fpscr_pad 49#define __lr lr 50#define __mq mq 51#define __pad0 pad0 52#define __pad1 pad1 53#define __r0 r0 54#define __r1 r1 55#define __r10 r10 56#define __r11 r11 57#define __r12 r12 58#define __r13 r13 59#define __r14 r14 60#define __r15 r15 61#define __r16 r16 62#define __r17 r17 63#define __r18 r18 64#define __r19 r19 65#define __r2 r2 66#define __r20 r20 67#define __r21 r21 68#define __r22 r22 69#define __r23 r23 70#define __r24 r24 71#define __r25 r25 72#define __r26 r26 73#define __r27 r27 74#define __r28 r28 75#define __r29 r29 76#define __r3 r3 77#define __r30 r30 78#define __r31 r31 79#define __r4 r4 80#define __r5 r5 81#define __r6 r6 82#define __r7 r7 83#define __r8 r8 84#define __r9 r9 85#define __srr0 srr0 86#define __srr1 srr1 87#define __vrsave vrsave 88#define __xer xer 89 90#define __darwin_i386_exception_state i386_exception_state 91#define __darwin_i386_float_state i386_float_state 92#define __darwin_i386_thread_state i386_thread_state 93#define __busy busy 94#define __c0 c0 95#define __c1 c1 96#define __c2 c2 97#define __c3 c3 98#define __cs cs 99#define __darwin_fp_control fp_control 100#define __darwin_fp_status fp_status 101#define __darwin_mmst_reg mmst_reg 102#define __darwin_xmm_reg xmm_reg 103#define __denorm denorm 104#define __ds ds 105#define __eax eax 106#define __ebp ebp 107#define __ebx ebx 108#define __ecx ecx 109#define __edi edi 110#define __edx edx 111#define __eflags eflags 112#define __eip eip 113#define __err err 114#define __errsumm errsumm 115#define __es es 116#define __esi esi 117#define __esp esp 118#define __faultvaddr faultvaddr 119#define __fpu_cs fpu_cs 120#define __fpu_dp fpu_dp 121#define __fpu_ds fpu_ds 122#define __fpu_fcw fpu_fcw 123#define __fpu_fop fpu_fop 124#define __fpu_fsw fpu_fsw 125#define __fpu_ftw fpu_ftw 126#define __fpu_ip fpu_ip 127#define __fpu_mxcsr fpu_mxcsr 128#define __fpu_mxcsrmask fpu_mxcsrmask 129#define __fpu_reserved fpu_reserved 130#define __fpu_reserved1 fpu_reserved1 131#define __fpu_rsrv1 fpu_rsrv1 132#define __fpu_rsrv2 fpu_rsrv2 133#define __fpu_rsrv3 fpu_rsrv3 134#define __fpu_rsrv4 fpu_rsrv4 135#define __fpu_stmm0 fpu_stmm0 136#define __fpu_stmm1 fpu_stmm1 137#define __fpu_stmm2 fpu_stmm2 138#define __fpu_stmm3 fpu_stmm3 139#define __fpu_stmm4 fpu_stmm4 140#define __fpu_stmm5 fpu_stmm5 141#define __fpu_stmm6 fpu_stmm6 142#define __fpu_stmm7 fpu_stmm7 143#define __fpu_xmm0 fpu_xmm0 144#define __fpu_xmm1 fpu_xmm1 145#define __fpu_xmm2 fpu_xmm2 146#define __fpu_xmm3 fpu_xmm3 147#define __fpu_xmm4 fpu_xmm4 148#define __fpu_xmm5 fpu_xmm5 149#define __fpu_xmm6 fpu_xmm6 150#define __fpu_xmm7 fpu_xmm7 151#define __fpu_xmm8 fpu_xmm8 152#define __fpu_xmm9 fpu_xmm9 153#define __fpu_xmm10 fpu_xmm10 154#define __fpu_xmm11 fpu_xmm11 155#define __fpu_xmm12 fpu_xmm12 156#define __fpu_xmm13 fpu_xmm13 157#define __fpu_xmm14 fpu_xmm14 158#define __fpu_xmm15 fpu_xmm15 159#define __fs fs 160#define __gs gs 161#define __invalid invalid 162#define __mmst_reg mmst_reg 163#define __mmst_rsrv mmst_rsrv 164#define __ovrfl ovrfl 165#define __pc pc 166#define __precis precis 167#define __rc rc 168#define __ss ss 169#define __stkflt stkflt 170#define __tos tos 171#define __trapno trapno 172#define __undfl undfl 173#define __xmm_reg xmm_reg 174#define __zdiv zdiv 175 176#define __rax rax 177#define __rbx rbx 178#define __rcx rcx 179#define __rdx rdx 180#define __rdi rdi 181#define __rsi rsi 182#define __rbp rbp 183#define __rsp rsp 184#define __r8 r8 185#define __r9 r9 186#define __r10 r10 187#define __r11 r11 188#define __r12 r12 189#define __r13 r13 190#define __r14 r14 191#define __r15 r15 192#define __rip rip 193#define __rflags rflags 194 195#define __dr0 dr0 196#define __dr1 dr1 197#define __dr2 dr2 198#define __dr3 dr3 199#define __dr4 dr4 200#define __dr5 dr5 201#define __dr6 dr6 202#define __dr7 dr7 203 204#include <stdlib.h> 205#include <stddef.h> 206#include <string.h> 207#include <ctype.h> 208#include <math.h> 209#include <limits.h> 210#include <ar.h> 211#include <libc.h> 212#include <mach-o/fat.h> 213#include <mach-o/loader.h> 214#include <mach-o/reloc.h> 215#include <mach-o/i860/reloc.h> 216#include <mach-o/m88k/reloc.h> 217#include <mach-o/ppc/reloc.h> 218#include <mach-o/hppa/reloc.h> 219#include <mach-o/sparc/reloc.h> 220#include <mach-o/arm/reloc.h> 221#include "stuff/symbol.h" 222#include "stuff/ofile.h" 223#include "stuff/allocate.h" 224#include "stuff/errors.h" 225#include "stuff/guess_short_name.h" 226#include "ofile_print.h" 227 228/* <mach/loader.h> */ 229/* The maximum section alignment allowed to be specified, as a power of two */ 230#define MAXSECTALIGN 15 /* 2**15 or 0x8000 */ 231 232static void print_arch( 233 struct fat_arch *fat_arch); 234static void print_cputype( 235 cpu_type_t cputype, 236 cpu_subtype_t cpusubtype); 237 238#if i386_THREAD_STATE == 1 239#ifdef i386_EXCEPTION_STATE_COUNT 240static void print_mmst_reg( 241 struct mmst_reg *r); 242static void print_xmm_reg( 243 struct xmm_reg *r); 244#endif /* defined(i386_EXCEPTION_STATE_COUNT) */ 245#endif /* i386_THREAD_STATE == 1 */ 246 247static void print_unknown_state( 248 char *begin, 249 char *end, 250 unsigned int count, 251 enum bool swapped); 252 253struct reloc_section_info { 254 char segname[16]; 255 char sectname[16]; 256 uint32_t nreloc; 257 uint32_t reloff; 258}; 259 260static void print_relocs( 261 unsigned reloff, 262 unsigned nreloc, 263 struct reloc_section_info *sect_rel, 264 uint32_t nsects, 265 enum bool swapped, 266 cpu_type_t cputype, 267 char *object_addr, 268 uint32_t object_size, 269 struct nlist *symbols, 270 struct nlist_64 *symbols64, 271 uint32_t nsymbols, 272 char *strings, 273 uint32_t strings_size, 274 enum bool verbose); 275static void print_r_type( 276 cpu_type_t cputype, 277 uint32_t r_type, 278 enum bool predicted); 279static void print_cstring_char( 280 char c); 281static void print_literal4( 282 uint32_t l, 283 float f); 284static void print_literal8( 285 uint32_t l0, 286 uint32_t l1, 287 double d); 288static void print_literal16( 289 uint32_t l0, 290 uint32_t l1, 291 uint32_t l2, 292 uint32_t l3); 293static int rel_bsearch( 294 uint32_t *address, 295 struct relocation_info *rel); 296 297/* 298 * Print the fat header and the fat_archs. The caller is responsible for making 299 * sure the structures are properly aligned and that the fat_archs is of the 300 * size fat_header->nfat_arch * sizeof(struct fat_arch). 301 */ 302void 303print_fat_headers( 304struct fat_header *fat_header, 305struct fat_arch *fat_archs, 306uint64_t size, 307enum bool verbose) 308{ 309 uint32_t i, j; 310 uint64_t big_size; 311 312 if(verbose){ 313 if(fat_header->magic == FAT_MAGIC) 314 printf("fat_magic FAT_MAGIC\n"); 315 else 316 printf("fat_magic 0x%x\n", (unsigned int)(fat_header->magic)); 317 } 318 else 319 printf("fat_magic 0x%x\n", (unsigned int)(fat_header->magic)); 320 printf("nfat_arch %u", fat_header->nfat_arch); 321 big_size = fat_header->nfat_arch; 322 big_size *= sizeof(struct fat_arch); 323 big_size += sizeof(struct fat_header); 324 if(fat_header->nfat_arch == 0) 325 printf(" (malformed, contains zero architecture types)\n"); 326 else if(big_size > size) 327 printf(" (malformed, architectures past end of file)\n"); 328 else 329 printf("\n"); 330 331 for(i = 0; i < fat_header->nfat_arch; i++){ 332 big_size = i; 333 big_size *= sizeof(struct fat_arch); 334 big_size += sizeof(struct fat_header); 335 if(big_size > size) 336 break; 337 printf("architecture "); 338 for(j = 0; i != 0 && j <= i - 1; j++){ 339 if(fat_archs[i].cputype != 0 && fat_archs[i].cpusubtype != 0 && 340 fat_archs[i].cputype == fat_archs[j].cputype && 341 (fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 342 (fat_archs[j].cpusubtype & ~CPU_SUBTYPE_MASK)){ 343 printf("(illegal duplicate architecture) "); 344 break; 345 } 346 } 347 if(verbose){ 348 print_arch(fat_archs + i); 349 print_cputype(fat_archs[i].cputype, 350 fat_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK); 351 } 352 else{ 353 printf("%u\n", i); 354 printf(" cputype %d\n", fat_archs[i].cputype); 355 printf(" cpusubtype %d\n", fat_archs[i].cpusubtype & 356 ~CPU_SUBTYPE_MASK); 357 } 358 if(verbose && (fat_archs[i].cpusubtype & CPU_SUBTYPE_MASK) == 359 CPU_SUBTYPE_LIB64) 360 printf(" capabilities CPU_SUBTYPE_LIB64\n"); 361 else 362 printf(" capabilities 0x%x\n", (unsigned int) 363 ((fat_archs[i].cpusubtype & CPU_SUBTYPE_MASK) >>24)); 364 printf(" offset %u", fat_archs[i].offset); 365 if(fat_archs[i].offset > size) 366 printf(" (past end of file)"); 367 if(fat_archs[i].offset % (1 << fat_archs[i].align) != 0) 368 printf(" (not aligned on it's alignment (2^%u))\n", 369 fat_archs[i].align); 370 else 371 printf("\n"); 372 373 printf(" size %u", fat_archs[i].size); 374 big_size = fat_archs[i].offset; 375 big_size += fat_archs[i].size; 376 if(big_size > size) 377 printf(" (past end of file)\n"); 378 else 379 printf("\n"); 380 381 printf(" align 2^%u (%d)", fat_archs[i].align, 382 1 << fat_archs[i].align); 383 if(fat_archs[i].align > MAXSECTALIGN) 384 printf("( too large, maximum 2^%d)\n", MAXSECTALIGN); 385 else 386 printf("\n"); 387 } 388} 389 390/* 391 * print_arch() helps print_fat_headers by printing the 392 * architecture name for the cputype and cpusubtype. 393 */ 394static 395void 396print_arch( 397struct fat_arch *fat_arch) 398{ 399 switch(fat_arch->cputype){ 400 case CPU_TYPE_MC680x0: 401 switch(fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK){ 402 case CPU_SUBTYPE_MC680x0_ALL: 403 printf("m68k\n"); 404 break; 405 case CPU_SUBTYPE_MC68030_ONLY: 406 printf("m68030\n"); 407 break; 408 case CPU_SUBTYPE_MC68040: 409 printf("m68040\n"); 410 break; 411 default: 412 goto print_arch_unknown; 413 } 414 break; 415 case CPU_TYPE_MC88000: 416 switch(fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK){ 417 case CPU_SUBTYPE_MC88000_ALL: 418 case CPU_SUBTYPE_MC88110: 419 printf("m88k\n"); 420 break; 421 default: 422 goto print_arch_unknown; 423 } 424 break; 425 case CPU_TYPE_I386: 426 switch(fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK){ 427 case CPU_SUBTYPE_I386_ALL: 428 /* case CPU_SUBTYPE_386: same as above */ 429 printf("i386\n"); 430 break; 431 case CPU_SUBTYPE_486: 432 printf("i486\n"); 433 break; 434 case CPU_SUBTYPE_486SX: 435 printf("i486SX\n"); 436 break; 437 case CPU_SUBTYPE_PENT: /* same as 586 */ 438 printf("pentium\n"); 439 break; 440 case CPU_SUBTYPE_PENTPRO: 441 printf("pentpro\n"); 442 break; 443 case CPU_SUBTYPE_PENTII_M3: 444 printf("pentIIm3\n"); 445 break; 446 case CPU_SUBTYPE_PENTII_M5: 447 printf("pentIIm5\n"); 448 break; 449 default: 450 printf("intel x86 family %d model %d\n", 451 CPU_SUBTYPE_INTEL_FAMILY(fat_arch->cpusubtype & 452 ~CPU_SUBTYPE_MASK), 453 CPU_SUBTYPE_INTEL_MODEL(fat_arch->cpusubtype & 454 ~CPU_SUBTYPE_MASK)); 455 break; 456 } 457 break; 458 case CPU_TYPE_X86_64: 459 switch(fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK){ 460 case CPU_SUBTYPE_X86_64_ALL: 461 printf("x86_64\n"); 462 break; 463 default: 464 goto print_arch_unknown; 465 } 466 break; 467 case CPU_TYPE_I860: 468 switch(fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK){ 469 case CPU_SUBTYPE_I860_ALL: 470 case CPU_SUBTYPE_I860_860: 471 printf("i860\n"); 472 break; 473 default: 474 goto print_arch_unknown; 475 } 476 break; 477 case CPU_TYPE_POWERPC: 478 switch(fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK){ 479 case CPU_SUBTYPE_POWERPC_ALL: 480 printf("ppc\n"); 481 break; 482 case CPU_SUBTYPE_POWERPC_601: 483 printf("ppc601\n"); 484 break; 485 case CPU_SUBTYPE_POWERPC_602: 486 printf("ppc602\n"); 487 break; 488 case CPU_SUBTYPE_POWERPC_603: 489 printf("ppc603\n"); 490 break; 491 case CPU_SUBTYPE_POWERPC_603e: 492 printf("ppc603e\n"); 493 break; 494 case CPU_SUBTYPE_POWERPC_603ev: 495 printf("ppc603ev\n"); 496 break; 497 case CPU_SUBTYPE_POWERPC_604: 498 printf("ppc604\n"); 499 break; 500 case CPU_SUBTYPE_POWERPC_604e: 501 printf("ppc604e\n"); 502 break; 503 case CPU_SUBTYPE_POWERPC_620: 504 printf("ppc620\n"); 505 break; 506 case CPU_SUBTYPE_POWERPC_750: 507 printf("ppc750\n"); 508 break; 509 case CPU_SUBTYPE_POWERPC_7400: 510 printf("ppc7400\n"); 511 break; 512 case CPU_SUBTYPE_POWERPC_7450: 513 printf("ppc7450\n"); 514 break; 515 case CPU_SUBTYPE_POWERPC_970: 516 printf("ppc970\n"); 517 break; 518 default: 519 goto print_arch_unknown; 520 } 521 break; 522 case CPU_TYPE_POWERPC64: 523 switch(fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK){ 524 case CPU_SUBTYPE_POWERPC_ALL: 525 printf("ppc64\n"); 526 break; 527 case CPU_SUBTYPE_POWERPC_970: 528 printf("ppc970-64\n"); 529 break; 530 default: 531 goto print_arch_unknown; 532 } 533 break; 534 case CPU_TYPE_VEO: 535 switch(fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK){ 536 case CPU_SUBTYPE_VEO_1: 537 printf("veo1\n"); 538 break; 539 case CPU_SUBTYPE_VEO_2: 540 printf("veo2\n"); 541 break; 542 case CPU_SUBTYPE_VEO_3: 543 printf("veo3\n"); 544 break; 545 case CPU_SUBTYPE_VEO_4: 546 printf("veo4\n"); 547 break; 548 default: 549 goto print_arch_unknown; 550 } 551 break; 552 case CPU_TYPE_HPPA: 553 switch(fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK){ 554 case CPU_SUBTYPE_HPPA_ALL: 555 case CPU_SUBTYPE_HPPA_7100LC: 556 printf("hppa\n"); 557 break; 558 default: 559 goto print_arch_unknown; 560 } 561 break; 562 case CPU_TYPE_SPARC: 563 switch(fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK){ 564 case CPU_SUBTYPE_SPARC_ALL: 565 printf("sparc\n"); 566 break; 567 default: 568 goto print_arch_unknown; 569 } 570 break; 571 case CPU_TYPE_ARM: 572 switch(fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK){ 573 case CPU_SUBTYPE_ARM_ALL: 574 printf("arm\n"); 575 break; 576 case CPU_SUBTYPE_ARM_V4T: 577 printf("armv4t\n"); 578 break; 579 case CPU_SUBTYPE_ARM_V5TEJ: 580 printf("armv5\n"); 581 break; 582 case CPU_SUBTYPE_ARM_XSCALE: 583 printf("xscale\n"); 584 break; 585 case CPU_SUBTYPE_ARM_V6: 586 printf("armv6\n"); 587 break; 588 case CPU_SUBTYPE_ARM_V6M: 589 printf("armv6m\n"); 590 break; 591 case CPU_SUBTYPE_ARM_V7: 592 printf("armv7\n"); 593 break; 594 case CPU_SUBTYPE_ARM_V7F: 595 printf("armv7f\n"); 596 break; 597 case CPU_SUBTYPE_ARM_V7S: 598 printf("armv7s\n"); 599 break; 600 case CPU_SUBTYPE_ARM_V7K: 601 printf("armv7k\n"); 602 break; 603 case CPU_SUBTYPE_ARM_V7M: 604 printf("armv7m\n"); 605 break; 606 case CPU_SUBTYPE_ARM_V7EM: 607 printf("armv7em\n"); 608 break; 609 default: 610 goto print_arch_unknown; 611 break; 612 } 613 break; 614 case CPU_TYPE_ANY: 615 switch((int)(fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK)){ 616 case CPU_SUBTYPE_MULTIPLE: 617 printf("any\n"); 618 break; 619 case CPU_SUBTYPE_LITTLE_ENDIAN: 620 printf("little\n"); 621 break; 622 case CPU_SUBTYPE_BIG_ENDIAN: 623 printf("big\n"); 624 break; 625 default: 626 goto print_arch_unknown; 627 } 628 break; 629print_arch_unknown: 630 default: 631 printf("cputype (%d) cpusubtype (%d)\n", fat_arch->cputype, 632 fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK); 633 break; 634 } 635} 636 637/* 638 * print_cputype() helps print_fat_headers by printing the cputype and 639 * cpusubtype (symbolically for the one's it knows about). 640 */ 641static 642void 643print_cputype( 644cpu_type_t cputype, 645cpu_subtype_t cpusubtype) 646{ 647 switch(cputype){ 648 case CPU_TYPE_MC680x0: 649 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 650 case CPU_SUBTYPE_MC680x0_ALL: 651 printf(" cputype CPU_TYPE_MC680x0\n" 652 " cpusubtype CPU_SUBTYPE_MC680x0_ALL\n"); 653 break; 654 case CPU_SUBTYPE_MC68030_ONLY: 655 printf(" cputype CPU_TYPE_MC680x0\n" 656 " cpusubtype CPU_SUBTYPE_MC68030_ONLY\n"); 657 break; 658 case CPU_SUBTYPE_MC68040: 659 printf(" cputype CPU_TYPE_MC680x0\n" 660 " cpusubtype CPU_SUBTYPE_MC68040\n"); 661 break; 662 default: 663 goto print_arch_unknown; 664 } 665 break; 666 case CPU_TYPE_MC88000: 667 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 668 case CPU_SUBTYPE_MC88000_ALL: 669 printf(" cputype CPU_TYPE_MC88000\n" 670 " cpusubtype CPU_SUBTYPE_MC88000_ALL\n"); 671 break; 672 case CPU_SUBTYPE_MC88110: 673 printf(" cputype CPU_TYPE_MC88000\n" 674 " cpusubtype CPU_SUBTYPE_MC88110\n"); 675 break; 676 default: 677 goto print_arch_unknown; 678 } 679 break; 680 case CPU_TYPE_I386: 681 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 682 case CPU_SUBTYPE_I386_ALL: 683 /* case CPU_SUBTYPE_386: same as above */ 684 printf(" cputype CPU_TYPE_I386\n" 685 " cpusubtype CPU_SUBTYPE_I386_ALL\n"); 686 break; 687 case CPU_SUBTYPE_486: 688 printf(" cputype CPU_TYPE_I386\n" 689 " cpusubtype CPU_SUBTYPE_486\n"); 690 break; 691 case CPU_SUBTYPE_486SX: 692 printf(" cputype CPU_TYPE_I386\n" 693 " cpusubtype CPU_SUBTYPE_486SX\n"); 694 break; 695 case CPU_SUBTYPE_PENT: /* same as 586 */ 696 printf(" cputype CPU_TYPE_I386\n" 697 " cpusubtype CPU_SUBTYPE_PENT\n"); 698 break; 699 case CPU_SUBTYPE_PENTPRO: 700 printf(" cputype CPU_TYPE_I386\n" 701 " cpusubtype CPU_SUBTYPE_PENTPRO\n"); 702 break; 703 case CPU_SUBTYPE_PENTII_M3: 704 printf(" cputype CPU_TYPE_I386\n" 705 " cpusubtype CPU_SUBTYPE_PENTII_M3\n"); 706 break; 707 case CPU_SUBTYPE_PENTII_M5: 708 printf(" cputype CPU_TYPE_I386\n" 709 " cpusubtype CPU_SUBTYPE_PENTII_M5\n"); 710 break; 711 default: 712 goto print_arch_unknown; 713 } 714 break; 715 case CPU_TYPE_X86_64: 716 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 717 case CPU_SUBTYPE_X86_64_ALL: 718 printf(" cputype CPU_TYPE_X86_64\n" 719 " cpusubtype CPU_SUBTYPE_X86_64_ALL\n"); 720 break; 721 default: 722 goto print_arch_unknown; 723 } 724 break; 725 case CPU_TYPE_I860: 726 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 727 case CPU_SUBTYPE_I860_ALL: 728 printf(" cputype CPU_TYPE_I860\n" 729 " cpusubtype CPU_SUBTYPE_I860_ALL\n"); 730 break; 731 case CPU_SUBTYPE_I860_860: 732 printf(" cputype CPU_TYPE_I860\n" 733 " cpusubtype CPU_SUBTYPE_I860_860\n"); 734 break; 735 default: 736 goto print_arch_unknown; 737 } 738 break; 739 case CPU_TYPE_POWERPC: 740 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 741 case CPU_SUBTYPE_POWERPC_ALL: 742 printf(" cputype CPU_TYPE_POWERPC\n" 743 " cpusubtype CPU_SUBTYPE_POWERPC_ALL\n"); 744 break; 745 case CPU_SUBTYPE_POWERPC_601: 746 printf(" cputype CPU_TYPE_POWERPC\n" 747 " cpusubtype CPU_SUBTYPE_POWERPC_601\n"); 748 break; 749 case CPU_SUBTYPE_POWERPC_602: 750 printf(" cputype CPU_TYPE_POWERPC\n" 751 " cpusubtype CPU_SUBTYPE_POWERPC_602\n"); 752 break; 753 case CPU_SUBTYPE_POWERPC_603: 754 printf(" cputype CPU_TYPE_POWERPC\n" 755 " cpusubtype CPU_SUBTYPE_POWERPC_603\n"); 756 break; 757 case CPU_SUBTYPE_POWERPC_603e: 758 printf(" cputype CPU_TYPE_POWERPC\n" 759 " cpusubtype CPU_SUBTYPE_POWERPC_603e\n"); 760 break; 761 case CPU_SUBTYPE_POWERPC_603ev: 762 printf(" cputype CPU_TYPE_POWERPC\n" 763 " cpusubtype CPU_SUBTYPE_POWERPC_603ev\n"); 764 break; 765 case CPU_SUBTYPE_POWERPC_604: 766 printf(" cputype CPU_TYPE_POWERPC\n" 767 " cpusubtype CPU_SUBTYPE_POWERPC_604\n"); 768 break; 769 case CPU_SUBTYPE_POWERPC_604e: 770 printf(" cputype CPU_TYPE_POWERPC\n" 771 " cpusubtype CPU_SUBTYPE_POWERPC_604e\n"); 772 break; 773 case CPU_SUBTYPE_POWERPC_620: 774 printf(" cputype CPU_TYPE_POWERPC\n" 775 " cpusubtype CPU_SUBTYPE_POWERPC_620\n"); 776 break; 777 case CPU_SUBTYPE_POWERPC_750: 778 printf(" cputype CPU_TYPE_POWERPC\n" 779 " cpusubtype CPU_SUBTYPE_POWERPC_750\n"); 780 break; 781 case CPU_SUBTYPE_POWERPC_7400: 782 printf(" cputype CPU_TYPE_POWERPC\n" 783 " cpusubtype CPU_SUBTYPE_POWERPC_7400\n"); 784 break; 785 case CPU_SUBTYPE_POWERPC_7450: 786 printf(" cputype CPU_TYPE_POWERPC\n" 787 " cpusubtype CPU_SUBTYPE_POWERPC_7450\n"); 788 break; 789 case CPU_SUBTYPE_POWERPC_970: 790 printf(" cputype CPU_TYPE_POWERPC\n" 791 " cpusubtype CPU_SUBTYPE_POWERPC_970\n"); 792 break; 793 default: 794 goto print_arch_unknown; 795 } 796 break; 797 case CPU_TYPE_POWERPC64: 798 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 799 case CPU_SUBTYPE_POWERPC_ALL: 800 printf(" cputype CPU_TYPE_POWERPC64\n" 801 " cpusubtype CPU_SUBTYPE_POWERPC64_ALL\n"); 802 break; 803 case CPU_SUBTYPE_POWERPC_970: 804 printf(" cputype CPU_TYPE_POWERPC64\n" 805 " cpusubtype CPU_SUBTYPE_POWERPC_970\n"); 806 break; 807 default: 808 goto print_arch_unknown; 809 } 810 break; 811 case CPU_TYPE_VEO: 812 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 813 case CPU_SUBTYPE_VEO_1: 814 printf(" cputype CPU_TYPE_VEO\n" 815 " cpusubtype CPU_SUBTYPE_VEO_1\n"); 816 break; 817 case CPU_SUBTYPE_VEO_2: 818 printf(" cputype CPU_TYPE_VEO\n" 819 " cpusubtype CPU_SUBTYPE_VEO_2\n"); 820 break; 821 case CPU_SUBTYPE_VEO_3: 822 printf(" cputype CPU_TYPE_VEO\n" 823 " cpusubtype CPU_SUBTYPE_VEO_3\n"); 824 break; 825 case CPU_SUBTYPE_VEO_4: 826 printf(" cputype CPU_TYPE_VEO\n" 827 " cpusubtype CPU_SUBTYPE_VEO_4\n"); 828 break; 829 default: 830 goto print_arch_unknown; 831 } 832 break; 833 case CPU_TYPE_HPPA: 834 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 835 case CPU_SUBTYPE_HPPA_ALL: 836 printf(" cputype CPU_TYPE_HPPA\n" 837 " cpusubtype CPU_SUBTYPE_HPPA_ALL\n"); 838 break; 839 case CPU_SUBTYPE_HPPA_7100LC: 840 printf(" cputype CPU_TYPE_HPPA\n" 841 " cpusubtype CPU_SUBTYPE_HPPA_7100LC\n"); 842 break; 843 default: 844 goto print_arch_unknown; 845 } 846 break; 847 case CPU_TYPE_SPARC: 848 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 849 case CPU_SUBTYPE_SPARC_ALL: 850 printf(" cputype CPU_TYPE_SPARC\n" 851 " cpusubtype CPU_SUBTYPE_SPARC_ALL\n"); 852 break; 853 default: 854 goto print_arch_unknown; 855 } 856 break; 857 case CPU_TYPE_ARM: 858 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 859 case CPU_SUBTYPE_ARM_ALL: 860 printf(" cputype CPU_TYPE_ARM\n" 861 " cpusubtype CPU_SUBTYPE_ARM_ALL\n"); 862 break; 863 case CPU_SUBTYPE_ARM_V4T: 864 printf(" cputype CPU_TYPE_ARM\n" 865 " cpusubtype CPU_SUBTYPE_ARM_V4T\n"); 866 break; 867 case CPU_SUBTYPE_ARM_V5TEJ: 868 printf(" cputype CPU_TYPE_ARM\n" 869 " cpusubtype CPU_SUBTYPE_ARM_V5TEJ\n"); 870 break; 871 case CPU_SUBTYPE_ARM_XSCALE: 872 printf(" cputype CPU_TYPE_ARM\n" 873 " cpusubtype CPU_SUBTYPE_ARM_XSCALE\n"); 874 break; 875 case CPU_SUBTYPE_ARM_V6: 876 printf(" cputype CPU_TYPE_ARM\n" 877 " cpusubtype CPU_SUBTYPE_ARM_V6\n"); 878 break; 879 case CPU_SUBTYPE_ARM_V6M: 880 printf(" cputype CPU_TYPE_ARM\n" 881 " cpusubtype CPU_SUBTYPE_ARM_V6M\n"); 882 break; 883 case CPU_SUBTYPE_ARM_V7: 884 printf(" cputype CPU_TYPE_ARM\n" 885 " cpusubtype CPU_SUBTYPE_ARM_V7\n"); 886 break; 887 case CPU_SUBTYPE_ARM_V7F: 888 printf(" cputype CPU_TYPE_ARM\n" 889 " cpusubtype CPU_SUBTYPE_ARM_V7F\n"); 890 break; 891 case CPU_SUBTYPE_ARM_V7S: 892 printf(" cputype CPU_TYPE_ARM\n" 893 " cpusubtype CPU_SUBTYPE_ARM_V7S\n"); 894 break; 895 case CPU_SUBTYPE_ARM_V7K: 896 printf(" cputype CPU_TYPE_ARM\n" 897 " cpusubtype CPU_SUBTYPE_ARM_V7K\n"); 898 break; 899 case CPU_SUBTYPE_ARM_V7M: 900 printf(" cputype CPU_TYPE_ARM\n" 901 " cpusubtype CPU_SUBTYPE_ARM_V7M\n"); 902 break; 903 case CPU_SUBTYPE_ARM_V7EM: 904 printf(" cputype CPU_TYPE_ARM\n" 905 " cpusubtype CPU_SUBTYPE_ARM_V7EM\n"); 906 break; 907 default: 908 goto print_arch_unknown; 909 } 910 break; 911 case CPU_TYPE_ANY: 912 switch((int)(cpusubtype & ~CPU_SUBTYPE_MASK)){ 913 case CPU_SUBTYPE_MULTIPLE: 914 printf(" cputype CPU_TYPE_ANY\n" 915 " cpusubtype CPU_SUBTYPE_MULTIPLE\n"); 916 break; 917 case CPU_SUBTYPE_LITTLE_ENDIAN: 918 printf(" cputype CPU_TYPE_ANY\n" 919 " cpusubtype CPU_SUBTYPE_LITTLE_ENDIAN\n"); 920 break; 921 case CPU_SUBTYPE_BIG_ENDIAN: 922 printf(" cputype CPU_TYPE_ANY\n" 923 " cpusubtype CPU_SUBTYPE_BIG_ENDIAN\n"); 924 break; 925 default: 926 goto print_arch_unknown; 927 } 928 break; 929print_arch_unknown: 930 default: 931 printf(" cputype (%d)\n" 932 " cpusubtype (%d)\n", cputype, 933 cpusubtype & ~CPU_SUBTYPE_MASK); 934 break; 935 } 936} 937 938/* 939 * Print the archive header. The format is constant width character fields 940 * blank padded. So the trailing blanks are stripped and full field widths 941 * are handled correctly. 942 */ 943void 944print_ar_hdr( 945struct ar_hdr *ar_hdr, 946char *member_name, 947uint32_t member_name_size, 948uint32_t member_offset, 949enum bool verbose, 950enum bool print_offset) 951{ 952 int32_t i; 953 uint32_t j, mode; 954 time_t date; 955 char *p, *endp; 956 957 char date_buf[sizeof(ar_hdr->ar_date) + 1]; 958 char uid_buf[sizeof(ar_hdr->ar_uid) + 1]; 959 char gid_buf[sizeof(ar_hdr->ar_gid) + 1]; 960 char mode_buf[sizeof(ar_hdr->ar_mode) + 1]; 961 char size_buf[sizeof(ar_hdr->ar_size) + 1]; 962 963 memcpy(date_buf, ar_hdr->ar_date, sizeof(ar_hdr->ar_date)); 964 for(i = sizeof(ar_hdr->ar_date) - 1; i >= 0 && date_buf[i] == ' '; i--) 965 date_buf[i] = '\0'; 966 date_buf[sizeof(ar_hdr->ar_date)] = '\0'; 967 968 memcpy(uid_buf, ar_hdr->ar_uid, sizeof(ar_hdr->ar_uid)); 969 for(i = sizeof(ar_hdr->ar_uid) - 1; i >= 0 && uid_buf[i] == ' '; i--) 970 uid_buf[i] = '\0'; 971 uid_buf[sizeof(ar_hdr->ar_uid)] = '\0'; 972 973 memcpy(gid_buf, ar_hdr->ar_gid, sizeof(ar_hdr->ar_gid)); 974 for(i = sizeof(ar_hdr->ar_gid) - 1; i >= 0 && gid_buf[i] == ' '; i--) 975 gid_buf[i] = '\0'; 976 gid_buf[sizeof(ar_hdr->ar_gid)] = '\0'; 977 978 memcpy(mode_buf, ar_hdr->ar_mode, sizeof(ar_hdr->ar_mode)); 979 for(i = sizeof(ar_hdr->ar_mode) - 1; i >= 0 && mode_buf[i] == ' '; i--) 980 mode_buf[i] = '\0'; 981 mode_buf[sizeof(ar_hdr->ar_mode)] = '\0'; 982 983 memcpy(size_buf, ar_hdr->ar_size, sizeof(ar_hdr->ar_size)); 984 for(i = sizeof(ar_hdr->ar_size) - 1; i >= 0 && size_buf[i] == ' '; i--) 985 size_buf[i] = '\0'; 986 size_buf[sizeof(ar_hdr->ar_size)] = '\0'; 987 988 if(print_offset == TRUE) 989 printf("%u\t", member_offset); 990 991 if(verbose == TRUE){ 992 mode = strtoul(mode_buf, &endp, 8); 993 if(*endp != '\0') 994 printf("(mode: \"%s\" contains non-octal chars) ", mode_buf); 995 switch(mode & S_IFMT){ 996 case S_IFDIR: 997 printf("d"); 998 break; 999 case S_IFCHR: 1000 printf("c"); 1001 break; 1002 case S_IFBLK: 1003 printf("b"); 1004 break; 1005 case S_IFREG: 1006 printf("-"); 1007 break; 1008 case S_IFLNK: 1009 printf("l"); 1010 break; 1011 case S_IFSOCK: 1012 printf("s"); 1013 break; 1014 default: 1015 printf("?"); 1016 break; 1017 } 1018 1019 /* owner permissions */ 1020 if(mode & S_IREAD) 1021 printf("r"); 1022 else 1023 printf("-"); 1024 if(mode & S_IWRITE) 1025 printf("w"); 1026 else 1027 printf("-"); 1028 if(mode & S_ISUID) 1029 printf("s"); 1030 else if(mode & S_IEXEC) 1031 printf("x"); 1032 else 1033 printf("-"); 1034 1035 /* group permissions */ 1036 if(mode & (S_IREAD >> 3)) 1037 printf("r"); 1038 else 1039 printf("-"); 1040 if(mode & (S_IWRITE >> 3)) 1041 printf("w"); 1042 else 1043 printf("-"); 1044 if(mode & S_ISGID) 1045 printf("s"); 1046 else if(mode & (S_IEXEC >> 3)) 1047 printf("x"); 1048 else 1049 printf("-"); 1050 1051 /* other permissions */ 1052 if(mode & (S_IREAD >> 6)) 1053 printf("r"); 1054 else 1055 printf("-"); 1056 if(mode & (S_IWRITE >> 6)) 1057 printf("w"); 1058 else 1059 printf("-"); 1060 if(mode & S_ISVTX) 1061 printf("t"); 1062 else if(mode & (S_IEXEC >> 6)) 1063 printf("x"); 1064 else 1065 printf("-"); 1066 } 1067 else 1068 /* printf("0%03o ", mode & 0777); */ 1069 printf("0%s ", mode_buf); 1070 1071 printf("%3s/%-3s %5s ", uid_buf, gid_buf, size_buf); 1072 1073 /* 1074 * Since cime(3) returns a 26 character string of the form: 1075 * "Sun Sep 16 01:03:52 1973\n\0" 1076 * and the new line is not wanted a '\0' is placed there. 1077 */ 1078 if(verbose){ 1079 date = strtoul(date_buf, &endp, 10); 1080 if(*endp != '\0') 1081 printf("(date: \"%s\" contains non-decimal chars) ", date_buf); 1082 p = ctime(&date); 1083 p[24] = '\0'; 1084 printf("%s ", p); 1085 } 1086 else 1087 printf("%s ", date_buf); 1088 1089 if(verbose){ 1090 printf("%.*s", (int)member_name_size, member_name); 1091 } 1092 else{ 1093 j = size_ar_name(ar_hdr); 1094 printf("%.*s", (int)j, ar_hdr->ar_name); 1095 } 1096 1097 if(memcmp(ar_hdr->ar_fmag, ARFMAG, sizeof(ARFMAG) - 1) == 0) 1098 printf("\n"); 1099 else 1100 printf(" (ar_fmag not ARFMAG)\n"); 1101} 1102 1103/* 1104 * print_library_toc prints the table of contents of the a library. It is 1105 * converted to the host byte sex if toc_byte_sex is not the host byte sex. 1106 * The problem with determing the byte sex of the table of contents is left 1107 * to the caller. The determination is based on the byte sex of the object 1108 * files contained in the library (this can still present a problem since the 1109 * object files could be of differing byte sex in an erroneous library). There 1110 * is no problem of a library containing no objects with respect to the byte 1111 * sex of the table of contents since the table of contents would be made up 1112 * of two binary uint32_t zeros which are the same in either byte sex. 1113 */ 1114void 1115print_library_toc( 1116struct ar_hdr *toc_ar_hdr, 1117char *toc_name, 1118uint32_t toc_name_size, 1119char *toc_addr, 1120uint32_t toc_size, 1121enum byte_sex toc_byte_sex, 1122char *library_name, 1123char *library_addr, 1124uint64_t library_size, 1125char *arch_name, 1126enum bool verbose) 1127{ 1128 enum byte_sex host_byte_sex; 1129 uint32_t ran_size, nranlibs, str_size, i, member_name_size; 1130 uint64_t toc_offset; 1131 struct ranlib *ranlibs; 1132 char *strings, *member_name; 1133 struct ar_hdr *ar_hdr; 1134 int n; 1135 char buf[20]; 1136 uint64_t big_size; 1137 1138 host_byte_sex = get_host_byte_sex(); 1139 toc_offset = 0; 1140 strings = NULL; 1141 1142 if(toc_offset + sizeof(uint32_t) > toc_size){ 1143 error_with_arch(arch_name, "truncated table of contents in: " 1144 "%s(%.*s) (size of ranlib structs extends past the end of the " 1145 "table of contents member)", library_name, (int)toc_name_size, 1146 toc_name); 1147 return; 1148 } 1149 memcpy((char *)&ran_size, toc_addr + toc_offset, sizeof(uint32_t)); 1150 /* 1151 * With the advent of things like LTO object files we may end up getting 1152 * handed UNKNOWN_BYTE_SEX for the table of contents byte sex. So at 1153 * this point we are guessing. A better guess is to go with the host 1154 * bytesex as that is more likely. Otherwise we will always think it is 1155 * swapped. 1156 */ 1157 if(toc_byte_sex == UNKNOWN_BYTE_SEX) 1158 toc_byte_sex = host_byte_sex; 1159 if(toc_byte_sex != host_byte_sex) 1160 ran_size = SWAP_INT(ran_size); 1161 toc_offset += sizeof(uint32_t); 1162 1163 big_size = toc_offset; 1164 big_size += ran_size; 1165 if(big_size > toc_size){ 1166 error_with_arch(arch_name, "truncated table of contents in: " 1167 "%s(%.*s) (ranlib structures extends past the end of the " 1168 "table of contents member)", library_name, (int)toc_name_size, 1169 toc_name); 1170 return; 1171 } 1172 ranlibs = allocate(ran_size); 1173 memcpy((char *)ranlibs, toc_addr + toc_offset, ran_size); 1174 nranlibs = ran_size / sizeof(struct ranlib); 1175 if(toc_byte_sex != host_byte_sex) 1176 swap_ranlib(ranlibs, nranlibs, host_byte_sex); 1177 toc_offset += ran_size; 1178 1179 if(verbose){ 1180 if(toc_offset + sizeof(uint32_t) > toc_size){ 1181 error_with_arch(arch_name, "truncated table of contents in: " 1182 "%s(%.*s) (size of ranlib strings extends past the end of " 1183 "the table of contents member)", library_name, 1184 (int)toc_name_size, toc_name); 1185 free(ranlibs); 1186 return; 1187 } 1188 memcpy((char *)&str_size, toc_addr + toc_offset, 1189 sizeof(uint32_t)); 1190 if(toc_byte_sex != host_byte_sex) 1191 str_size = SWAP_INT(str_size); 1192 toc_offset += sizeof(uint32_t); 1193 1194 big_size = toc_offset; 1195 big_size += str_size; 1196 if(big_size > toc_size){ 1197 error_with_arch(arch_name, "truncated table of contents in: " 1198 "%s(%.*s) (ranlib strings extends past the end of the " 1199 "table of contents member)", library_name, 1200 (int)toc_name_size, toc_name); 1201 free(ranlibs); 1202 return; 1203 } 1204 strings = toc_addr + toc_offset; 1205 } 1206 1207 printf("Table of contents from: %s(%.*s)", library_name, 1208 (int)toc_name_size, toc_name); 1209 if(arch_name != NULL) 1210 printf(" (for architecture %s)\n", arch_name); 1211 else 1212 printf("\n"); 1213 printf("size of ranlib structures: %u (number %u)\n", ran_size, 1214 nranlibs); 1215 if(verbose){ 1216 printf("size of strings: %u", str_size); 1217 if(str_size % sizeof(int32_t) != 0) 1218 printf(" (not multiple of sizeof(int32_t))\n"); 1219 else 1220 printf("\n"); 1221 } 1222 if(verbose) 1223 printf("object symbol name\n"); 1224 else 1225 printf("object offset string index\n"); 1226 1227 for(i = 0; i < nranlibs; i++){ 1228 if(verbose){ 1229 if(ranlibs[i].ran_off + sizeof(struct ar_hdr) <= library_size){ 1230 ar_hdr = (struct ar_hdr *) 1231 (library_addr + ranlibs[i].ran_off); 1232 if(strncmp(ar_hdr->ar_name, AR_EFMT1, 1233 sizeof(AR_EFMT1) - 1) == 0){ 1234 member_name = ar_hdr->ar_name + sizeof(struct ar_hdr); 1235 member_name_size = strtoul(ar_hdr->ar_name + 1236 sizeof(AR_EFMT1) - 1, NULL, 10); 1237 while(member_name_size > 0 && 1238 member_name[member_name_size - 1] == '\0') 1239 member_name_size--; 1240 printf("%-.*s ", (int)member_name_size, member_name); 1241 if(member_name_size < 16) 1242 printf("%-.*s", (int)(16 - member_name_size), 1243 " "); 1244 } 1245 else{ 1246 printf("%-.16s ", ar_hdr->ar_name); 1247 } 1248 } 1249 else{ 1250 n = sprintf(buf, "?(%u) ", (uint32_t)ranlibs[i].ran_off); 1251 printf("%s%.*s", buf, 17 - n, " "); 1252 } 1253 if(ranlibs[i].ran_un.ran_strx < str_size) 1254 printf("%s\n", strings + ranlibs[i].ran_un.ran_strx); 1255 else 1256 printf("?(%u)\n", (uint32_t)ranlibs[i].ran_un.ran_strx); 1257 } 1258 else{ 1259 printf("%-14u %u\n", (uint32_t)ranlibs[i].ran_off, 1260 (uint32_t)ranlibs[i].ran_un.ran_strx); 1261 } 1262 } 1263 1264 free(ranlibs); 1265} 1266 1267/* 1268 * Print the mach header. It is assumed that the parameters are in the host 1269 * byte sex. In this way it is up to the caller to determine he has a 1270 * mach_header and what byte sex it is and get it aligned in the host byte sex 1271 * for the parameters to this routine. 1272 */ 1273void 1274print_mach_header( 1275uint32_t magic, 1276cpu_type_t cputype, 1277cpu_subtype_t cpusubtype, 1278uint32_t filetype, 1279uint32_t ncmds, 1280uint32_t sizeofcmds, 1281uint32_t flags, 1282enum bool verbose) 1283{ 1284 uint32_t f; 1285 1286 printf("Mach header\n"); 1287 printf(" magic cputype cpusubtype caps filetype ncmds " 1288 "sizeofcmds flags\n"); 1289 if(verbose){ 1290 if(magic == MH_MAGIC) 1291 printf("%11s", "MH_MAGIC"); 1292 else if(magic == MH_MAGIC_64) 1293 printf("%11s", "MH_MAGIC_64"); 1294 else 1295 printf(" 0x%08x", (unsigned int)magic); 1296 switch(cputype){ 1297 case CPU_TYPE_POWERPC64: 1298 printf(" PPC64"); 1299 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 1300 case CPU_SUBTYPE_POWERPC_ALL: 1301 printf(" ALL"); 1302 break; 1303 case CPU_SUBTYPE_POWERPC_970: 1304 printf(" ppc970"); 1305 break; 1306 default: 1307 printf(" %10d", cpusubtype & ~CPU_SUBTYPE_MASK); 1308 break; 1309 } 1310 break; 1311 case CPU_TYPE_X86_64: 1312 printf(" X86_64"); 1313 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 1314 case CPU_SUBTYPE_X86_64_ALL: 1315 printf(" ALL"); 1316 break; 1317 default: 1318 printf(" %10d", cpusubtype & ~CPU_SUBTYPE_MASK); 1319 break; 1320 } 1321 break; 1322 case CPU_TYPE_VAX: 1323 printf(" VAX"); 1324 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 1325 case CPU_SUBTYPE_VAX780: 1326 printf(" VAX780"); 1327 break; 1328 case CPU_SUBTYPE_VAX785: 1329 printf(" VAX785"); 1330 break; 1331 case CPU_SUBTYPE_VAX750: 1332 printf(" VAX750"); 1333 break; 1334 case CPU_SUBTYPE_VAX730: 1335 printf(" VAX730"); 1336 break; 1337 case CPU_SUBTYPE_UVAXI: 1338 printf(" UVAXI"); 1339 break; 1340 case CPU_SUBTYPE_UVAXII: 1341 printf(" UVAXII"); 1342 break; 1343 case CPU_SUBTYPE_VAX8200: 1344 printf(" VAX8200"); 1345 break; 1346 case CPU_SUBTYPE_VAX8500: 1347 printf(" VAX8500"); 1348 break; 1349 case CPU_SUBTYPE_VAX8600: 1350 printf(" VAX8600"); 1351 break; 1352 case CPU_SUBTYPE_VAX8650: 1353 printf(" VAX8650"); 1354 break; 1355 case CPU_SUBTYPE_VAX8800: 1356 printf(" VAX8800"); 1357 break; 1358 case CPU_SUBTYPE_UVAXIII: 1359 printf(" UVAXIII"); 1360 break; 1361 default: 1362 printf(" %10d", cpusubtype & ~CPU_SUBTYPE_MASK); 1363 break; 1364 } 1365 break; 1366 case CPU_TYPE_ROMP: 1367 printf(" ROMP"); 1368 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 1369 case CPU_SUBTYPE_RT_PC: 1370 printf(" RT_PC"); 1371 break; 1372 case CPU_SUBTYPE_RT_APC: 1373 printf(" RT_APC"); 1374 break; 1375 case CPU_SUBTYPE_RT_135: 1376 printf(" RT_135"); 1377 break; 1378 1379 default: 1380 printf(" %10d", cpusubtype & ~CPU_SUBTYPE_MASK); 1381 break; 1382 } 1383 break; 1384 case CPU_TYPE_NS32032: 1385 printf(" NS32032"); 1386 goto NS32; 1387 case CPU_TYPE_NS32332: 1388 printf(" NS32332"); 1389NS32: 1390 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 1391 case CPU_SUBTYPE_MMAX_DPC: 1392 printf(" MMAX_DPC"); 1393 break; 1394 case CPU_SUBTYPE_SQT: 1395 printf(" SQT"); 1396 break; 1397 case CPU_SUBTYPE_MMAX_APC_FPU: 1398 printf(" MMAX_APC_FPC"); 1399 break; 1400 case CPU_SUBTYPE_MMAX_APC_FPA: 1401 printf(" MMAX_APC_FPA"); 1402 break; 1403 case CPU_SUBTYPE_MMAX_XPC: 1404 printf(" MMAX_XPC"); 1405 break; 1406 default: 1407 printf(" %10d", cpusubtype & ~CPU_SUBTYPE_MASK); 1408 break; 1409 } 1410 break; 1411 case CPU_TYPE_MC680x0: 1412 printf(" MC680x0"); 1413 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 1414 case CPU_SUBTYPE_MC680x0_ALL: 1415 printf(" ALL"); 1416 break; 1417 case CPU_SUBTYPE_MC68030_ONLY: 1418 printf(" MC68030"); 1419 break; 1420 case CPU_SUBTYPE_MC68040: 1421 printf(" MC68040"); 1422 break; 1423 default: 1424 printf(" %10d", cpusubtype & ~CPU_SUBTYPE_MASK); 1425 break; 1426 } 1427 break; 1428 case CPU_TYPE_MC88000: 1429 printf(" MC88000"); 1430 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 1431 case CPU_SUBTYPE_MC88000_ALL: 1432 printf(" ALL"); 1433 break; 1434 case CPU_SUBTYPE_MC88100: 1435 printf(" MC88100"); 1436 break; 1437 case CPU_SUBTYPE_MC88110: 1438 printf(" MC88110"); 1439 break; 1440 default: 1441 printf(" %10d", cpusubtype & ~CPU_SUBTYPE_MASK); 1442 break; 1443 } 1444 break; 1445 case CPU_TYPE_I860: 1446 printf(" I860"); 1447 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 1448 case CPU_SUBTYPE_I860_ALL: 1449 printf(" ALL"); 1450 break; 1451 case CPU_SUBTYPE_I860_860: 1452 printf(" 860"); 1453 break; 1454 default: 1455 printf(" %10d", cpusubtype & ~CPU_SUBTYPE_MASK); 1456 break; 1457 } 1458 break; 1459 case CPU_TYPE_I386: 1460 printf(" I386"); 1461 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 1462 case CPU_SUBTYPE_I386_ALL: 1463 /* case CPU_SUBTYPE_386: same as above */ 1464 printf(" ALL"); 1465 break; 1466 case CPU_SUBTYPE_486: 1467 printf(" 486"); 1468 break; 1469 case CPU_SUBTYPE_486SX: 1470 printf(" 486SX"); 1471 break; 1472 case CPU_SUBTYPE_PENT: /* same as 586 */ 1473 printf(" PENT"); 1474 break; 1475 case CPU_SUBTYPE_PENTPRO: 1476 printf(" PENTPRO"); 1477 break; 1478 case CPU_SUBTYPE_PENTII_M3: 1479 printf(" PENTII_M3"); 1480 break; 1481 case CPU_SUBTYPE_PENTII_M5: 1482 printf(" PENTII_M5"); 1483 break; 1484 default: 1485 printf(" %10d", cpusubtype & ~CPU_SUBTYPE_MASK); 1486 break; 1487 } 1488 break; 1489 case CPU_TYPE_POWERPC: 1490 printf(" PPC"); 1491 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 1492 case CPU_SUBTYPE_POWERPC_ALL: 1493 printf(" ALL"); 1494 break; 1495 case CPU_SUBTYPE_POWERPC_601: 1496 printf(" ppc601"); 1497 break; 1498 case CPU_SUBTYPE_POWERPC_602: 1499 printf(" ppc602"); 1500 break; 1501 case CPU_SUBTYPE_POWERPC_603: 1502 printf(" ppc603"); 1503 break; 1504 case CPU_SUBTYPE_POWERPC_603e: 1505 printf(" ppc603e"); 1506 break; 1507 case CPU_SUBTYPE_POWERPC_603ev: 1508 printf(" ppc603ev"); 1509 break; 1510 case CPU_SUBTYPE_POWERPC_604: 1511 printf(" ppc604"); 1512 break; 1513 case CPU_SUBTYPE_POWERPC_604e: 1514 printf(" ppc604e"); 1515 break; 1516 case CPU_SUBTYPE_POWERPC_620: 1517 printf(" ppc620"); 1518 break; 1519 case CPU_SUBTYPE_POWERPC_750: 1520 printf(" ppc750"); 1521 break; 1522 case CPU_SUBTYPE_POWERPC_7400: 1523 printf(" ppc7400"); 1524 break; 1525 case CPU_SUBTYPE_POWERPC_7450: 1526 printf(" ppc7450"); 1527 break; 1528 case CPU_SUBTYPE_POWERPC_970: 1529 printf(" ppc970"); 1530 break; 1531 default: 1532 printf(" %10d", cpusubtype & ~CPU_SUBTYPE_MASK); 1533 break; 1534 } 1535 break; 1536 case CPU_TYPE_VEO: 1537 printf(" VEO"); 1538 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 1539 case CPU_SUBTYPE_VEO_1: 1540 printf(" veo1"); 1541 break; 1542 case CPU_SUBTYPE_VEO_2: 1543 printf(" veo2"); 1544 break; 1545 case CPU_SUBTYPE_VEO_3: 1546 printf(" veo3"); 1547 break; 1548 case CPU_SUBTYPE_VEO_4: 1549 printf(" veo4"); 1550 break; 1551 default: 1552 printf(" %10d", cpusubtype & ~CPU_SUBTYPE_MASK); 1553 break; 1554 } 1555 break; 1556 case CPU_TYPE_HPPA: 1557 printf(" HPPA"); 1558 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 1559 case CPU_SUBTYPE_HPPA_ALL: 1560 printf(" ALL"); 1561 break; 1562 case CPU_SUBTYPE_HPPA_7100LC: 1563 printf(" HPPA_7100LC"); 1564 break; 1565 default: 1566 printf(" %10d", cpusubtype & ~CPU_SUBTYPE_MASK); 1567 break; 1568 } 1569 break; 1570 case CPU_TYPE_SPARC: 1571 printf(" SPARC"); 1572 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 1573 case CPU_SUBTYPE_SPARC_ALL: 1574 printf(" ALL"); 1575 break; 1576 default: 1577 printf(" %10d", cpusubtype & ~CPU_SUBTYPE_MASK); 1578 break; 1579 } 1580 break; 1581 case CPU_TYPE_ARM: 1582 printf(" ARM"); 1583 switch(cpusubtype){ 1584 case CPU_SUBTYPE_ARM_ALL: 1585 printf(" ALL"); 1586 break; 1587 case CPU_SUBTYPE_ARM_V4T: 1588 printf(" V4T"); 1589 break; 1590 case CPU_SUBTYPE_ARM_V5TEJ: 1591 printf(" V5TEJ"); 1592 break; 1593 case CPU_SUBTYPE_ARM_XSCALE: 1594 printf(" XSCALE"); 1595 break; 1596 case CPU_SUBTYPE_ARM_V6: 1597 printf(" V6"); 1598 break; 1599 case CPU_SUBTYPE_ARM_V6M: 1600 printf(" V6M"); 1601 break; 1602 case CPU_SUBTYPE_ARM_V7: 1603 printf(" V7"); 1604 break; 1605 case CPU_SUBTYPE_ARM_V7F: 1606 printf(" V7F"); 1607 break; 1608 case CPU_SUBTYPE_ARM_V7S: 1609 printf(" V7S"); 1610 break; 1611 case CPU_SUBTYPE_ARM_V7K: 1612 printf(" V7K"); 1613 break; 1614 case CPU_SUBTYPE_ARM_V7M: 1615 printf(" V7M"); 1616 break; 1617 case CPU_SUBTYPE_ARM_V7EM: 1618 printf(" V7EM"); 1619 break; 1620 default: 1621 printf(" %10d", cpusubtype & ~CPU_SUBTYPE_MASK); 1622 break; 1623 } 1624 break; 1625 default: 1626 printf(" %7d %10d", cputype, cpusubtype & ~CPU_SUBTYPE_MASK); 1627 break; 1628 } 1629 if((cpusubtype & CPU_SUBTYPE_MASK) == CPU_SUBTYPE_LIB64){ 1630 printf(" LIB64 "); 1631 } 1632 else{ 1633 printf(" 0x%02x ", (unsigned int) 1634 ((cpusubtype & ~CPU_SUBTYPE_MASK) >> 24)); 1635 } 1636 switch(filetype){ 1637 case MH_OBJECT: 1638 printf(" OBJECT"); 1639 break; 1640 case MH_EXECUTE: 1641 printf(" EXECUTE"); 1642 break; 1643 case MH_FVMLIB: 1644 printf(" FVMLIB"); 1645 break; 1646 case MH_CORE: 1647 printf(" CORE"); 1648 break; 1649 case MH_PRELOAD: 1650 printf(" PRELOAD"); 1651 break; 1652 case MH_DYLIB: 1653 printf(" DYLIB"); 1654 break; 1655 case MH_DYLIB_STUB: 1656 printf(" DYLIB_STUB"); 1657 break; 1658 case MH_DYLINKER: 1659 printf(" DYLINKER"); 1660 break; 1661 case MH_BUNDLE: 1662 printf(" BUNDLE"); 1663 break; 1664 case MH_DSYM: 1665 printf(" DSYM"); 1666 break; 1667 case MH_KEXT_BUNDLE: 1668 printf(" KEXTBUNDLE"); 1669 break; 1670 default: 1671 printf(" %10u", filetype); 1672 break; 1673 } 1674 printf(" %5u %10u", ncmds, sizeofcmds); 1675 f = flags; 1676 if(f & MH_NOUNDEFS){ 1677 printf(" NOUNDEFS"); 1678 f &= ~MH_NOUNDEFS; 1679 } 1680 if(f & MH_INCRLINK){ 1681 printf(" INCRLINK"); 1682 f &= ~MH_INCRLINK; 1683 } 1684 if(f & MH_DYLDLINK){ 1685 printf(" DYLDLINK"); 1686 f &= ~MH_DYLDLINK; 1687 } 1688 if(f & MH_BINDATLOAD){ 1689 printf(" BINDATLOAD"); 1690 f &= ~MH_BINDATLOAD; 1691 } 1692 if(f & MH_PREBOUND){ 1693 printf(" PREBOUND"); 1694 f &= ~MH_PREBOUND; 1695 } 1696 if(f & MH_SPLIT_SEGS){ 1697 printf(" SPLIT_SEGS"); 1698 f &= ~MH_SPLIT_SEGS; 1699 } 1700 if(f & MH_LAZY_INIT){ 1701 printf(" LAZY_INIT"); 1702 f &= ~MH_LAZY_INIT; 1703 } 1704 if(f & MH_TWOLEVEL){ 1705 printf(" TWOLEVEL"); 1706 f &= ~MH_TWOLEVEL; 1707 } 1708 if(f & MH_FORCE_FLAT){ 1709 printf(" FORCE_FLAT"); 1710 f &= ~MH_FORCE_FLAT; 1711 } 1712 if(f & MH_NOMULTIDEFS){ 1713 printf(" NOMULTIDEFS"); 1714 f &= ~MH_NOMULTIDEFS; 1715 } 1716 if(f & MH_NOFIXPREBINDING){ 1717 printf(" NOFIXPREBINDING"); 1718 f &= ~MH_NOFIXPREBINDING; 1719 } 1720 if(f & MH_PREBINDABLE){ 1721 printf(" PREBINDABLE"); 1722 f &= ~MH_PREBINDABLE; 1723 } 1724 if(f & MH_ALLMODSBOUND){ 1725 printf(" ALLMODSBOUND"); 1726 f &= ~MH_ALLMODSBOUND; 1727 } 1728 if(f & MH_SUBSECTIONS_VIA_SYMBOLS){ 1729 printf(" SUBSECTIONS_VIA_SYMBOLS"); 1730 f &= ~MH_SUBSECTIONS_VIA_SYMBOLS; 1731 } 1732 if(f & MH_CANONICAL){ 1733 printf(" CANONICAL"); 1734 f &= ~MH_CANONICAL; 1735 } 1736 if(f & MH_WEAK_DEFINES){ 1737 printf(" WEAK_DEFINES"); 1738 f &= ~MH_WEAK_DEFINES; 1739 } 1740 if(f & MH_BINDS_TO_WEAK){ 1741 printf(" BINDS_TO_WEAK"); 1742 f &= ~MH_BINDS_TO_WEAK; 1743 } 1744 if(f & MH_ALLOW_STACK_EXECUTION){ 1745 printf(" ALLOW_STACK_EXECUTION"); 1746 f &= ~MH_ALLOW_STACK_EXECUTION; 1747 } 1748 if(f & MH_DEAD_STRIPPABLE_DYLIB){ 1749 printf(" DEAD_STRIPPABLE_DYLIB"); 1750 f &= ~MH_DEAD_STRIPPABLE_DYLIB; 1751 } 1752 if(f & MH_PIE){ 1753 printf(" PIE"); 1754 f &= ~MH_PIE; 1755 } 1756 if(f & MH_NO_REEXPORTED_DYLIBS){ 1757 printf(" NO_REEXPORTED_DYLIBS"); 1758 f &= ~MH_NO_REEXPORTED_DYLIBS; 1759 } 1760 if(f & MH_NO_HEAP_EXECUTION){ 1761 printf(" MH_NO_HEAP_EXECUTION"); 1762 f &= ~MH_NO_HEAP_EXECUTION; 1763 } 1764 if(f != 0 || flags == 0) 1765 printf(" 0x%08x", (unsigned int)f); 1766 printf("\n"); 1767 } 1768 else{ 1769 printf(" 0x%08x %7d %10d 0x%02x %10u %5u %10u 0x%08x\n", 1770 (unsigned int)magic, cputype, cpusubtype & ~CPU_SUBTYPE_MASK, 1771 (unsigned int)((cpusubtype & CPU_SUBTYPE_MASK) >> 24), 1772 filetype, ncmds, sizeofcmds, 1773 (unsigned int)flags); 1774 } 1775} 1776 1777/* 1778 * Print the load commands. The load commands pointed to by load_commands can 1779 * have any alignment, are in the specified byte_sex, and must be at least 1780 * sizeofcmds in length. 1781 */ 1782void 1783print_loadcmds( 1784struct load_command *load_commands, 1785uint32_t ncmds, 1786uint32_t sizeofcmds, 1787cpu_type_t cputype, 1788uint32_t filetype, 1789enum byte_sex load_commands_byte_sex, 1790uint32_t object_size, 1791enum bool verbose, 1792enum bool very_verbose) 1793{ 1794 enum byte_sex host_byte_sex; 1795 enum bool swapped; 1796 uint32_t i, j, k, left, size, *unknown, nsyms; 1797 char *p, *begin, *end; 1798 struct load_command *lc, l; 1799 struct segment_command sg; 1800 struct section s; 1801 struct segment_command_64 sg64; 1802 struct section_64 s64; 1803 struct symtab_command st; 1804 struct dysymtab_command dyst; 1805 struct symseg_command ss; 1806 struct fvmlib_command fl; 1807 struct dylib_command dl; 1808 struct prebound_dylib_command pbdylib; 1809 struct sub_framework_command sub; 1810 struct sub_umbrella_command usub; 1811 struct sub_library_command lsub; 1812 struct sub_client_command csub; 1813 struct fvmfile_command ff; 1814 struct dylinker_command dyld; 1815 struct routines_command rc; 1816 struct routines_command_64 rc64; 1817 struct twolevel_hints_command hints; 1818 struct prebind_cksum_command cs; 1819 struct uuid_command uuid; 1820 struct linkedit_data_command ld; 1821 struct rpath_command rpath; 1822 struct encryption_info_command encrypt; 1823 struct encryption_info_command_64 encrypt64; 1824 struct linker_option_command lo; 1825 struct dyld_info_command dyld_info; 1826 struct version_min_command vd; 1827 struct entry_point_command ep; 1828 struct source_version_command sv; 1829 uint64_t big_load_end; 1830 1831 host_byte_sex = get_host_byte_sex(); 1832 swapped = host_byte_sex != load_commands_byte_sex; 1833 1834 nsyms = UINT_MAX; 1835 lc = load_commands; 1836 big_load_end = 0; 1837 for(i = 0 ; i < ncmds; i++){ 1838 printf("Load command %u\n", i); 1839 1840 memcpy((char *)&l, (char *)lc, sizeof(struct load_command)); 1841 if(swapped) 1842 swap_load_command(&l, host_byte_sex); 1843 if(l.cmdsize % sizeof(int32_t) != 0) 1844 printf("load command %u size not a multiple of " 1845 "sizeof(int32_t)\n", i); 1846 big_load_end += l.cmdsize; 1847 if(big_load_end > sizeofcmds) 1848 printf("load command %u extends past end of load commands\n", 1849 i); 1850 left = sizeofcmds - ((char *)lc - (char *)load_commands); 1851 1852 switch(l.cmd){ 1853 case LC_SEGMENT: 1854 memset((char *)&sg, '\0', sizeof(struct segment_command)); 1855 size = left < sizeof(struct segment_command) ? 1856 left : sizeof(struct segment_command); 1857 memcpy((char *)&sg, (char *)lc, size); 1858 if(swapped) 1859 swap_segment_command(&sg, host_byte_sex); 1860 print_segment_command(sg.cmd, sg.cmdsize, sg.segname, 1861 sg.vmaddr, sg.vmsize, sg.fileoff, sg.filesize, 1862 sg.maxprot, sg.initprot, sg.nsects, sg.flags, 1863 object_size, verbose); 1864 p = (char *)lc + sizeof(struct segment_command); 1865 for(j = 0 ; j < sg.nsects ; j++){ 1866 if(p + sizeof(struct section) > 1867 (char *)load_commands + sizeofcmds){ 1868 printf("section structure command extends past end of " 1869 "load commands\n"); 1870 } 1871 left = sizeofcmds - (p - (char *)load_commands); 1872 memset((char *)&s, '\0', sizeof(struct section)); 1873 size = left < sizeof(struct section) ? 1874 left : sizeof(struct section); 1875 memcpy((char *)&s, p, size); 1876 if(swapped) 1877 swap_section(&s, 1, host_byte_sex); 1878 print_section(s.sectname, s.segname, s.addr, s.size, 1879 s.offset, s.align, s.reloff, s.nreloc, s.flags, 1880 s.reserved1, s.reserved2, sg.cmd, sg.segname, 1881 filetype, object_size, verbose); 1882 if(p + sizeof(struct section) > 1883 (char *)load_commands + sizeofcmds) 1884 return; 1885 p += size; 1886 } 1887 break; 1888 1889 case LC_SEGMENT_64: 1890 memset((char *)&sg64, '\0', sizeof(struct segment_command_64)); 1891 size = left < sizeof(struct segment_command_64) ? 1892 left : sizeof(struct segment_command_64); 1893 memcpy((char *)&sg64, (char *)lc, size); 1894 if(swapped) 1895 swap_segment_command_64(&sg64, host_byte_sex); 1896 print_segment_command(sg64.cmd, sg64.cmdsize, sg64.segname, 1897 sg64.vmaddr, sg64.vmsize, sg64.fileoff, sg64.filesize, 1898 sg64.maxprot, sg64.initprot, sg64.nsects, sg64.flags, 1899 object_size, verbose); 1900 p = (char *)lc + sizeof(struct segment_command_64); 1901 for(j = 0 ; j < sg64.nsects ; j++){ 1902 if(p + sizeof(struct section_64) > 1903 (char *)load_commands + sizeofcmds){ 1904 printf("section structure command extends past end of " 1905 "load commands\n"); 1906 } 1907 left = sizeofcmds - (p - (char *)load_commands); 1908 memset((char *)&s64, '\0', sizeof(struct section_64)); 1909 size = left < sizeof(struct section_64) ? 1910 left : sizeof(struct section_64); 1911 memcpy((char *)&s64, p, size); 1912 if(swapped) 1913 swap_section_64(&s64, 1, host_byte_sex); 1914 print_section(s64.sectname, s64.segname, s64.addr, 1915 s64.size, s64.offset, s64.align, s64.reloff, 1916 s64.nreloc, s64.flags, s64.reserved1, s64.reserved2, 1917 sg64.cmd, sg64.segname, filetype, object_size, 1918 verbose); 1919 if(p + sizeof(struct section_64) > 1920 (char *)load_commands + sizeofcmds) 1921 return; 1922 p += size; 1923 } 1924 break; 1925 1926 case LC_SYMTAB: 1927 memset((char *)&st, '\0', sizeof(struct symtab_command)); 1928 size = left < sizeof(struct symtab_command) ? 1929 left : sizeof(struct symtab_command); 1930 memcpy((char *)&st, (char *)lc, size); 1931 if(swapped) 1932 swap_symtab_command(&st, host_byte_sex); 1933 nsyms = st.nsyms; 1934 print_symtab_command(&st, cputype, object_size); 1935 break; 1936 1937 case LC_DYSYMTAB: 1938 memset((char *)&dyst, '\0', sizeof(struct dysymtab_command)); 1939 size = left < sizeof(struct dysymtab_command) ? 1940 left : sizeof(struct dysymtab_command); 1941 memcpy((char *)&dyst, (char *)lc, size); 1942 if(swapped) 1943 swap_dysymtab_command(&dyst, host_byte_sex); 1944 print_dysymtab_command(&dyst, nsyms, object_size, cputype); 1945 break; 1946 1947 case LC_SYMSEG: 1948 memset((char *)&ss, '\0', sizeof(struct symseg_command)); 1949 size = left < sizeof(struct symseg_command) ? 1950 left : sizeof(struct symseg_command); 1951 memcpy((char *)&ss, (char *)lc, size); 1952 if(swapped) 1953 swap_symseg_command(&ss, host_byte_sex); 1954 print_symseg_command(&ss, object_size); 1955 break; 1956 1957 case LC_IDFVMLIB: 1958 case LC_LOADFVMLIB: 1959 memset((char *)&fl, '\0', sizeof(struct fvmlib_command)); 1960 size = left < sizeof(struct fvmlib_command) ? 1961 left : sizeof(struct fvmlib_command); 1962 memcpy((char *)&fl, (char *)lc, size); 1963 if(swapped) 1964 swap_fvmlib_command(&fl, host_byte_sex); 1965 print_fvmlib_command(&fl, lc); 1966 break; 1967 1968 case LC_ID_DYLIB: 1969 case LC_LOAD_DYLIB: 1970 case LC_LOAD_WEAK_DYLIB: 1971 case LC_REEXPORT_DYLIB: 1972 case LC_LOAD_UPWARD_DYLIB: 1973 case LC_LAZY_LOAD_DYLIB: 1974 memset((char *)&dl, '\0', sizeof(struct dylib_command)); 1975 size = left < sizeof(struct dylib_command) ? 1976 left : sizeof(struct dylib_command); 1977 memcpy((char *)&dl, (char *)lc, size); 1978 if(swapped) 1979 swap_dylib_command(&dl, host_byte_sex); 1980 print_dylib_command(&dl, lc); 1981 break; 1982 1983 case LC_SUB_FRAMEWORK: 1984 memset((char *)&sub, '\0',sizeof(struct sub_framework_command)); 1985 size = left < sizeof(struct sub_framework_command) ? 1986 left : sizeof(struct sub_framework_command); 1987 memcpy((char *)&sub, (char *)lc, size); 1988 if(swapped) 1989 swap_sub_framework_command(&sub, host_byte_sex); 1990 print_sub_framework_command(&sub, lc); 1991 break; 1992 1993 case LC_SUB_UMBRELLA: 1994 memset((char *)&usub, '\0',sizeof(struct sub_umbrella_command)); 1995 size = left < sizeof(struct sub_umbrella_command) ? 1996 left : sizeof(struct sub_umbrella_command); 1997 memcpy((char *)&usub, (char *)lc, size); 1998 if(swapped) 1999 swap_sub_umbrella_command(&usub, host_byte_sex); 2000 print_sub_umbrella_command(&usub, lc); 2001 break; 2002 2003 case LC_SUB_LIBRARY: 2004 memset((char *)&lsub, '\0',sizeof(struct sub_library_command)); 2005 size = left < sizeof(struct sub_library_command) ? 2006 left : sizeof(struct sub_library_command); 2007 memcpy((char *)&lsub, (char *)lc, size); 2008 if(swapped) 2009 swap_sub_library_command(&lsub, host_byte_sex); 2010 print_sub_library_command(&lsub, lc); 2011 break; 2012 2013 case LC_SUB_CLIENT: 2014 memset((char *)&csub, '\0',sizeof(struct sub_client_command)); 2015 size = left < sizeof(struct sub_client_command) ? 2016 left : sizeof(struct sub_client_command); 2017 memcpy((char *)&csub, (char *)lc, size); 2018 if(swapped) 2019 swap_sub_client_command(&csub, host_byte_sex); 2020 print_sub_client_command(&csub, lc); 2021 break; 2022 2023 case LC_PREBOUND_DYLIB: 2024 memset((char *)&pbdylib, '\0', 2025 sizeof(struct prebound_dylib_command)); 2026 size = left < sizeof(struct prebound_dylib_command) ? 2027 left : sizeof(struct prebound_dylib_command); 2028 memcpy((char *)&pbdylib, (char *)lc, size); 2029 if(swapped) 2030 swap_prebound_dylib_command(&pbdylib, host_byte_sex); 2031 print_prebound_dylib_command(&pbdylib, lc, very_verbose); 2032 break; 2033 2034 case LC_ID_DYLINKER: 2035 case LC_LOAD_DYLINKER: 2036 case LC_DYLD_ENVIRONMENT: 2037 memset((char *)&dyld, '\0', sizeof(struct dylinker_command)); 2038 size = left < sizeof(struct dylinker_command) ? 2039 left : sizeof(struct dylinker_command); 2040 memcpy((char *)&dyld, (char *)lc, size); 2041 if(swapped) 2042 swap_dylinker_command(&dyld, host_byte_sex); 2043 print_dylinker_command(&dyld, lc); 2044 break; 2045 2046 case LC_FVMFILE: 2047 memset((char *)&ff, '\0', sizeof(struct fvmfile_command)); 2048 size = left < sizeof(struct fvmfile_command) ? 2049 left : sizeof(struct fvmfile_command); 2050 memcpy((char *)&ff, (char *)lc, size); 2051 if(swapped) 2052 swap_fvmfile_command(&ff, host_byte_sex); 2053 print_fvmfile_command(&ff, lc); 2054 break; 2055 2056 case LC_UNIXTHREAD: 2057 case LC_THREAD: 2058 if(l.cmd == LC_UNIXTHREAD) 2059 printf(" cmd LC_UNIXTHREAD\n"); 2060 else 2061 printf(" cmd LC_THREAD\n"); 2062 printf(" cmdsize %u\n", l.cmdsize); 2063 2064 if(left <= sizeof(struct thread_command)) 2065 break; 2066 begin = (char *)lc + sizeof(struct thread_command); 2067 if(left >= l.cmdsize) 2068 end = (char *)lc + l.cmdsize; 2069 else 2070 end = (char *)lc + left; 2071 print_thread_states(begin, end, cputype, 2072 load_commands_byte_sex); 2073 break; 2074 2075 case LC_IDENT: 2076 printf(" cmd LC_IDENT\n"); 2077 printf(" cmdsize %u", l.cmdsize); 2078 if(l.cmdsize < sizeof(struct ident_command)) 2079 printf(" Incorrect size\n"); 2080 else 2081 printf("\n"); 2082 begin = (char *)lc + sizeof(struct ident_command); 2083 left -= sizeof(struct ident_command); 2084 if(left >= l.cmdsize) 2085 end = (char *)lc + l.cmdsize; 2086 else 2087 end = (char *)lc + left; 2088 2089 p = ((char *)lc) + sizeof(struct ident_command); 2090 while(begin < end){ 2091 if(*begin == '\0'){ 2092 begin++; 2093 continue; 2094 } 2095 for(j = 0; begin + j < end && begin[j] != '\0'; j++) 2096 ; 2097 printf(" ident string %.*s\n", (int)j, begin); 2098 begin += j; 2099 } 2100 break; 2101 2102 case LC_ROUTINES: 2103 memset((char *)&rc, '\0', sizeof(struct routines_command)); 2104 size = left < sizeof(struct routines_command) ? 2105 left : sizeof(struct routines_command); 2106 memcpy((char *)&rc, (char *)lc, size); 2107 if(swapped) 2108 swap_routines_command(&rc, host_byte_sex); 2109 print_routines_command(&rc); 2110 break; 2111 2112 case LC_ROUTINES_64: 2113 memset((char *)&rc64, '\0', sizeof(struct routines_command_64)); 2114 size = left < sizeof(struct routines_command_64) ? 2115 left : sizeof(struct routines_command_64); 2116 memcpy((char *)&rc64, (char *)lc, size); 2117 if(swapped) 2118 swap_routines_command_64(&rc64, host_byte_sex); 2119 print_routines_command_64(&rc64); 2120 break; 2121 2122 case LC_TWOLEVEL_HINTS: 2123 memset((char *)&hints, '\0', 2124 sizeof(struct twolevel_hints_command)); 2125 size = left < sizeof(struct twolevel_hints_command) ? 2126 left : sizeof(struct twolevel_hints_command); 2127 memcpy((char *)&hints, (char *)lc, size); 2128 if(swapped) 2129 swap_twolevel_hints_command(&hints, host_byte_sex); 2130 print_twolevel_hints_command(&hints, object_size); 2131 break; 2132 2133 case LC_PREBIND_CKSUM: 2134 memset((char *)&cs, '\0', sizeof(struct prebind_cksum_command)); 2135 size = left < sizeof(struct prebind_cksum_command) ? 2136 left : sizeof(struct prebind_cksum_command); 2137 memcpy((char *)&cs, (char *)lc, size); 2138 if(swapped) 2139 swap_prebind_cksum_command(&cs, host_byte_sex); 2140 print_prebind_cksum_command(&cs); 2141 break; 2142 2143 case LC_UUID: 2144 memset((char *)&uuid, '\0', sizeof(struct uuid_command)); 2145 size = left < sizeof(struct uuid_command) ? 2146 left : sizeof(struct uuid_command); 2147 memcpy((char *)&uuid, (char *)lc, size); 2148 if(swapped) 2149 swap_uuid_command(&uuid, host_byte_sex); 2150 print_uuid_command(&uuid); 2151 break; 2152 2153 case LC_CODE_SIGNATURE: 2154 case LC_SEGMENT_SPLIT_INFO: 2155 case LC_FUNCTION_STARTS: 2156 case LC_DATA_IN_CODE: 2157 case LC_DYLIB_CODE_SIGN_DRS: 2158 memset((char *)&ld, '\0', sizeof(struct linkedit_data_command)); 2159 size = left < sizeof(struct linkedit_data_command) ? 2160 left : sizeof(struct linkedit_data_command); 2161 memcpy((char *)&ld, (char *)lc, size); 2162 if(swapped) 2163 swap_linkedit_data_command(&ld, host_byte_sex); 2164 print_linkedit_data_command(&ld, object_size); 2165 break; 2166 2167 case LC_RPATH: 2168 memset((char *)&rpath, '\0', sizeof(struct rpath_command)); 2169 size = left < sizeof(struct rpath_command) ? 2170 left : sizeof(struct rpath_command); 2171 memcpy((char *)&rpath, (char *)lc, size); 2172 if(swapped) 2173 swap_rpath_command(&rpath, host_byte_sex); 2174 print_rpath_command(&rpath, lc); 2175 break; 2176 2177 case LC_ENCRYPTION_INFO: 2178 memset((char *)&encrypt, '\0', 2179 sizeof(struct encryption_info_command)); 2180 size = left < sizeof(struct encryption_info_command) ? 2181 left : sizeof(struct encryption_info_command); 2182 memcpy((char *)&encrypt, (char *)lc, size); 2183 if(swapped) 2184 swap_encryption_command(&encrypt, host_byte_sex); 2185 print_encryption_info_command(&encrypt, object_size); 2186 break; 2187 2188 case LC_ENCRYPTION_INFO_64: 2189 memset((char *)&encrypt64, '\0', 2190 sizeof(struct encryption_info_command_64)); 2191 size = left < sizeof(struct encryption_info_command_64) ? 2192 left : sizeof(struct encryption_info_command_64); 2193 memcpy((char *)&encrypt64, (char *)lc, size); 2194 if(swapped) 2195 swap_encryption_command_64(&encrypt64, host_byte_sex); 2196 print_encryption_info_command_64(&encrypt64, object_size); 2197 break; 2198 2199 case LC_LINKER_OPTION: 2200 memset((char *)&lo, '\0', 2201 sizeof(struct linker_option_command)); 2202 size = left < sizeof(struct linker_option_command) ? 2203 left : sizeof(struct linker_option_command); 2204 memcpy((char *)&lo, (char *)lc, size); 2205 if(swapped) 2206 swap_linker_option_command(&lo, host_byte_sex); 2207 print_linker_option_command(&lo, lc); 2208 break; 2209 2210 case LC_DYLD_INFO: 2211 case LC_DYLD_INFO_ONLY: 2212 memset((char *)&dyld_info, '\0', 2213 sizeof(struct dyld_info_command)); 2214 size = left < sizeof(struct dyld_info_command) ? 2215 left : sizeof(struct dyld_info_command); 2216 memcpy((char *)&dyld_info, (char *)lc, size); 2217 if(swapped) 2218 swap_dyld_info_command(&dyld_info, host_byte_sex); 2219 print_dyld_info_info_command(&dyld_info, object_size); 2220 break; 2221 2222 case LC_VERSION_MIN_MACOSX: 2223 case LC_VERSION_MIN_IPHONEOS: 2224 memset((char *)&vd, '\0', sizeof(struct version_min_command)); 2225 size = left < sizeof(struct version_min_command) ? 2226 left : sizeof(struct version_min_command); 2227 memcpy((char *)&vd, (char *)lc, size); 2228 if(swapped) 2229 swap_version_min_command(&vd, host_byte_sex); 2230 print_version_min_command(&vd); 2231 break; 2232 2233 case LC_SOURCE_VERSION: 2234 memset((char *)&sv, '\0',sizeof(struct source_version_command)); 2235 size = left < sizeof(struct source_version_command) ? 2236 left : sizeof(struct source_version_command); 2237 memcpy((char *)&sv, (char *)lc, size); 2238 if(swapped) 2239 swap_source_version_command(&sv, host_byte_sex); 2240 print_source_version_command(&sv); 2241 break; 2242 2243 case LC_MAIN: 2244 memset((char *)&ep, '\0', sizeof(struct entry_point_command)); 2245 size = left < sizeof(struct entry_point_command) ? 2246 left : sizeof(struct entry_point_command); 2247 memcpy((char *)&ep, (char *)lc, size); 2248 if(swapped) 2249 swap_entry_point_command(&ep, host_byte_sex); 2250 print_entry_point_command(&ep); 2251 break; 2252 2253 default: 2254 printf(" cmd ?(0x%08x) Unknown load command\n", 2255 (unsigned int)l.cmd); 2256 printf(" cmdsize %u\n", l.cmdsize); 2257 if(left < sizeof(struct load_command)) 2258 return; 2259 left -= sizeof(struct load_command); 2260 size = left < l.cmdsize - sizeof(struct load_command) ? 2261 left : l.cmdsize - sizeof(struct load_command); 2262 unknown = allocate(size); 2263 memcpy((char *)unknown, 2264 ((char *)lc) + sizeof(struct load_command), size); 2265 if(swapped) 2266 for(j = 0; j < size / sizeof(uint32_t); j++) 2267 unknown[j] = SWAP_INT(unknown[j]); 2268 for(j = 0; j < size / sizeof(uint32_t); j += k){ 2269 for(k = 0; 2270 k < 8 && j + k < size / sizeof(uint32_t); 2271 k++) 2272 printf("%08x ", (unsigned int)unknown[j + k]); 2273 printf("\n"); 2274 } 2275 break; 2276 } 2277 if(l.cmdsize == 0){ 2278 printf("load command %u size zero (can't advance to other " 2279 "load commands)\n", i); 2280 return; 2281 } 2282 lc = (struct load_command *)((char *)lc + l.cmdsize); 2283 if((char *)lc > (char *)load_commands + sizeofcmds) 2284 return; 2285 } 2286 if((char *)load_commands + sizeofcmds != (char *)lc) 2287 printf("Inconsistent sizeofcmds\n"); 2288} 2289 2290void 2291print_libraries( 2292struct load_command *load_commands, 2293uint32_t ncmds, 2294uint32_t sizeofcmds, 2295enum byte_sex load_commands_byte_sex, 2296enum bool just_id, 2297enum bool verbose) 2298{ 2299 enum byte_sex host_byte_sex; 2300 enum bool swapped; 2301 uint32_t i, left, size; 2302 struct load_command *lc, l; 2303 struct fvmlib_command fl; 2304 struct dylib_command dl; 2305 char *p; 2306 time_t timestamp; 2307 2308 host_byte_sex = get_host_byte_sex(); 2309 swapped = host_byte_sex != load_commands_byte_sex; 2310 2311 lc = load_commands; 2312 for(i = 0 ; i < ncmds; i++){ 2313 memcpy((char *)&l, (char *)lc, sizeof(struct load_command)); 2314 if(swapped) 2315 swap_load_command(&l, host_byte_sex); 2316 if(l.cmdsize % sizeof(int32_t) != 0) 2317 printf("load command %u size not a multiple of " 2318 "sizeof(int32_t)\n", i); 2319 if((char *)lc + l.cmdsize > (char *)load_commands + sizeofcmds) 2320 printf("load command %u extends past end of load commands\n", 2321 i); 2322 left = sizeofcmds - ((char *)lc - (char *)load_commands); 2323 2324 switch(l.cmd){ 2325 case LC_IDFVMLIB: 2326 case LC_LOADFVMLIB: 2327 if(just_id == TRUE) 2328 break; 2329 memset((char *)&fl, '\0', sizeof(struct fvmlib_command)); 2330 size = left < sizeof(struct fvmlib_command) ? 2331 left : sizeof(struct fvmlib_command); 2332 memcpy((char *)&fl, (char *)lc, size); 2333 if(swapped) 2334 swap_fvmlib_command(&fl, host_byte_sex); 2335 if(fl.fvmlib.name.offset < fl.cmdsize){ 2336 p = (char *)lc + fl.fvmlib.name.offset; 2337 printf("\t%s (minor version %u)\n", p, 2338 fl.fvmlib.minor_version); 2339 } 2340 else{ 2341 printf("\tBad offset (%u) for name of %s command %u\n", 2342 fl.fvmlib.name.offset, l.cmd == LC_IDFVMLIB ? 2343 "LC_IDFVMLIB" : "LC_LOADFVMLIB" , i); 2344 } 2345 break; 2346 2347 case LC_LOAD_DYLIB: 2348 case LC_LOAD_WEAK_DYLIB: 2349 case LC_REEXPORT_DYLIB: 2350 case LC_LOAD_UPWARD_DYLIB: 2351 case LC_LAZY_LOAD_DYLIB: 2352 if(just_id == TRUE) 2353 break; 2354 case LC_ID_DYLIB: 2355 memset((char *)&dl, '\0', sizeof(struct dylib_command)); 2356 size = left < sizeof(struct dylib_command) ? 2357 left : sizeof(struct dylib_command); 2358 memcpy((char *)&dl, (char *)lc, size); 2359 if(swapped) 2360 swap_dylib_command(&dl, host_byte_sex); 2361 if(dl.dylib.name.offset < dl.cmdsize){ 2362 p = (char *)lc + dl.dylib.name.offset; 2363 if(just_id == TRUE) 2364 printf("%s\n", p); 2365 else 2366 printf("\t%s (compatibility version %u.%u.%u, " 2367 "current version %u.%u.%u)\n", p, 2368 dl.dylib.compatibility_version >> 16, 2369 (dl.dylib.compatibility_version >> 8) & 0xff, 2370 dl.dylib.compatibility_version & 0xff, 2371 dl.dylib.current_version >> 16, 2372 (dl.dylib.current_version >> 8) & 0xff, 2373 dl.dylib.current_version & 0xff); 2374 if(verbose){ 2375 printf("\ttime stamp %u ", dl.dylib.timestamp); 2376 timestamp = (time_t)dl.dylib.timestamp; 2377 printf("%s", ctime(×tamp)); 2378 } 2379 } 2380 else{ 2381 printf("\tBad offset (%u) for name of ", 2382 dl.dylib.name.offset); 2383 if(l.cmd == LC_ID_DYLIB) 2384 printf("LC_ID_DYLIB "); 2385 else if(l.cmd == LC_LOAD_DYLIB) 2386 printf("LC_LOAD_DYLIB "); 2387 else if(l.cmd == LC_LOAD_WEAK_DYLIB) 2388 printf("LC_LOAD_WEAK_DYLIB "); 2389 else if(l.cmd == LC_LAZY_LOAD_DYLIB) 2390 printf("LC_LAZY_LOAD_DYLIB "); 2391 else if(l.cmd == LC_REEXPORT_DYLIB) 2392 printf("LC_REEXPORT_DYLIB "); 2393 else if(l.cmd == LC_LOAD_UPWARD_DYLIB) 2394 printf("LC_LOAD_UPWARD_DYLIB "); 2395 else 2396 printf("LC_??? "); 2397 printf("command %u\n", i); 2398 } 2399 break; 2400 } 2401 if(l.cmdsize == 0){ 2402 printf("load command %u size zero (can't advance to other " 2403 "load commands)\n", i); 2404 return; 2405 } 2406 lc = (struct load_command *)((char *)lc + l.cmdsize); 2407 if((char *)lc > (char *)load_commands + sizeofcmds) 2408 return; 2409 } 2410 if((char *)load_commands + sizeofcmds != (char *)lc) 2411 printf("Inconsistent sizeofcmds\n"); 2412} 2413 2414/* 2415 * print an LC_SEGMENT command. The fields of the segment_command must 2416 * be in the host byte sex. 2417 */ 2418void 2419print_segment_command( 2420uint32_t cmd, 2421uint32_t cmdsize, 2422char *segname, 2423uint64_t vmaddr, 2424uint64_t vmsize, 2425uint64_t fileoff, 2426uint64_t filesize, 2427vm_prot_t maxprot, 2428vm_prot_t initprot, 2429uint32_t nsects, 2430uint32_t flags, 2431uint32_t object_size, 2432enum bool verbose) 2433{ 2434 uint64_t expected_cmdsize; 2435 2436 if(cmd == LC_SEGMENT){ 2437 printf(" cmd LC_SEGMENT\n"); 2438 expected_cmdsize = nsects; 2439 expected_cmdsize *= sizeof(struct section); 2440 expected_cmdsize += sizeof(struct segment_command); 2441 } 2442 else{ 2443 printf(" cmd LC_SEGMENT_64\n"); 2444 expected_cmdsize = nsects; 2445 expected_cmdsize *= sizeof(struct section_64); 2446 expected_cmdsize += sizeof(struct segment_command_64); 2447 } 2448 printf(" cmdsize %u", cmdsize); 2449 if(cmdsize != expected_cmdsize) 2450 printf(" Inconsistent size\n"); 2451 else 2452 printf("\n"); 2453 printf(" segname %.16s\n", segname); 2454 if(cmd == LC_SEGMENT_64){ 2455 printf(" vmaddr 0x%016llx\n", vmaddr); 2456 printf(" vmsize 0x%016llx\n", vmsize); 2457 } 2458 else{ 2459 printf(" vmaddr 0x%08x\n", (uint32_t)vmaddr); 2460 printf(" vmsize 0x%08x\n", (uint32_t)vmsize); 2461 } 2462 printf(" fileoff %llu", fileoff); 2463 if(fileoff > object_size) 2464 printf(" (past end of file)\n"); 2465 else 2466 printf("\n"); 2467 printf(" filesize %llu", filesize); 2468 if(fileoff + filesize > object_size) 2469 printf(" (past end of file)\n"); 2470 else 2471 printf("\n"); 2472 if(verbose){ 2473 if((maxprot & 2474 ~(VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)) != 0) 2475 printf(" maxprot ?(0x%08x)\n", (unsigned int)maxprot); 2476 else{ 2477 if(maxprot & VM_PROT_READ) 2478 printf(" maxprot r"); 2479 else 2480 printf(" maxprot -"); 2481 if(maxprot & VM_PROT_WRITE) 2482 printf("w"); 2483 else 2484 printf("-"); 2485 if(maxprot & VM_PROT_EXECUTE) 2486 printf("x\n"); 2487 else 2488 printf("-\n"); 2489 } 2490 if((initprot & 2491 ~(VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)) != 0) 2492 printf(" initprot ?(0x%08x)\n", (unsigned int)initprot); 2493 else{ 2494 if(initprot & VM_PROT_READ) 2495 printf(" initprot r"); 2496 else 2497 printf(" initprot -"); 2498 if(initprot & VM_PROT_WRITE) 2499 printf("w"); 2500 else 2501 printf("-"); 2502 if(initprot & VM_PROT_EXECUTE) 2503 printf("x\n"); 2504 else 2505 printf("-\n"); 2506 } 2507 } 2508 else{ 2509 printf(" maxprot 0x%08x\n", (unsigned int)maxprot); 2510 printf(" initprot 0x%08x\n", (unsigned int)initprot); 2511 } 2512 printf(" nsects %u\n", nsects); 2513 if(verbose){ 2514 printf(" flags"); 2515 if(flags == 0) 2516 printf(" (none)\n"); 2517 else{ 2518 if(flags & SG_HIGHVM){ 2519 printf(" HIGHVM"); 2520 flags &= ~SG_HIGHVM; 2521 } 2522 if(flags & SG_FVMLIB){ 2523 printf(" FVMLIB"); 2524 flags &= ~SG_FVMLIB; 2525 } 2526 if(flags & SG_NORELOC){ 2527 printf(" NORELOC"); 2528 flags &= ~SG_NORELOC; 2529 } 2530 if(flags & SG_PROTECTED_VERSION_1){ 2531 printf(" PROTECTED_VERSION_1"); 2532 flags &= ~SG_PROTECTED_VERSION_1; 2533 } 2534 if(flags) 2535 printf(" 0x%x (unknown flags)\n", (unsigned int)flags); 2536 else 2537 printf("\n"); 2538 } 2539 } 2540 else{ 2541 printf(" flags 0x%x\n", (unsigned int)flags); 2542 } 2543} 2544 2545/* 2546 * print a section structure. All parameters must be in the host byte sex. 2547 */ 2548void 2549print_section( 2550char *sectname, 2551char *segname, 2552uint64_t addr, 2553uint64_t size, 2554uint32_t offset, 2555uint32_t align, 2556uint32_t reloff, 2557uint32_t nreloc, 2558uint32_t flags, 2559uint32_t reserved1, 2560uint32_t reserved2, 2561uint32_t cmd, 2562char *sg_segname, 2563uint32_t filetype, 2564uint32_t object_size, 2565enum bool verbose) 2566{ 2567 uint32_t section_type, section_attributes; 2568 2569 printf("Section\n"); 2570 printf(" sectname %.16s\n", sectname); 2571 printf(" segname %.16s", segname); 2572 if(filetype != MH_OBJECT && 2573 strcmp(sg_segname, segname) != 0) 2574 printf(" (does not match segment)\n"); 2575 else 2576 printf("\n"); 2577 if(cmd == LC_SEGMENT_64){ 2578 printf(" addr 0x%016llx\n", addr); 2579 printf(" size 0x%016llx", size); 2580 } 2581 else{ 2582 printf(" addr 0x%08x\n", (uint32_t)addr); 2583 printf(" size 0x%08x", (uint32_t)size); 2584 } 2585 if((flags & S_ZEROFILL) != 0 && offset + size > object_size) 2586 printf(" (past end of file)\n"); 2587 else 2588 printf("\n"); 2589 printf(" offset %u", offset); 2590 if(offset > object_size) 2591 printf(" (past end of file)\n"); 2592 else 2593 printf("\n"); 2594 printf(" align 2^%u (%d)\n", align, 1 << align); 2595 printf(" reloff %u", reloff); 2596 if(reloff > object_size) 2597 printf(" (past end of file)\n"); 2598 else 2599 printf("\n"); 2600 printf(" nreloc %u", nreloc); 2601 if(reloff + nreloc * sizeof(struct relocation_info) > object_size) 2602 printf(" (past end of file)\n"); 2603 else 2604 printf("\n"); 2605 section_type = flags & SECTION_TYPE; 2606 if(verbose){ 2607 printf(" type"); 2608 if(section_type == S_REGULAR) 2609 printf(" S_REGULAR\n"); 2610 else if(section_type == S_ZEROFILL) 2611 printf(" S_ZEROFILL\n"); 2612 else if(section_type == S_CSTRING_LITERALS) 2613 printf(" S_CSTRING_LITERALS\n"); 2614 else if(section_type == S_4BYTE_LITERALS) 2615 printf(" S_4BYTE_LITERALS\n"); 2616 else if(section_type == S_8BYTE_LITERALS) 2617 printf(" S_8BYTE_LITERALS\n"); 2618 else if(section_type == S_16BYTE_LITERALS) 2619 printf(" S_16BYTE_LITERALS\n"); 2620 else if(section_type == S_LITERAL_POINTERS) 2621 printf(" S_LITERAL_POINTERS\n"); 2622 else if(section_type == S_NON_LAZY_SYMBOL_POINTERS) 2623 printf(" S_NON_LAZY_SYMBOL_POINTERS\n"); 2624 else if(section_type == S_LAZY_SYMBOL_POINTERS) 2625 printf(" S_LAZY_SYMBOL_POINTERS\n"); 2626 else if(section_type == S_SYMBOL_STUBS) 2627 printf(" S_SYMBOL_STUBS\n"); 2628 else if(section_type == S_MOD_INIT_FUNC_POINTERS) 2629 printf(" S_MOD_INIT_FUNC_POINTERS\n"); 2630 else if(section_type == S_MOD_TERM_FUNC_POINTERS) 2631 printf(" S_MOD_TERM_FUNC_POINTERS\n"); 2632 else if(section_type == S_COALESCED) 2633 printf(" S_COALESCED\n"); 2634 else if(section_type == S_INTERPOSING) 2635 printf(" S_INTERPOSING\n"); 2636 else if(section_type == S_DTRACE_DOF) 2637 printf(" S_DTRACE_DOF\n"); 2638 else if(section_type == S_LAZY_DYLIB_SYMBOL_POINTERS) 2639 printf(" S_LAZY_DYLIB_SYMBOL_POINTERS\n"); 2640 else if(section_type == S_THREAD_LOCAL_REGULAR) 2641 printf(" S_THREAD_LOCAL_REGULAR\n"); 2642 else if(section_type == S_THREAD_LOCAL_ZEROFILL) 2643 printf(" S_THREAD_LOCAL_ZEROFILL\n"); 2644 else if(section_type == S_THREAD_LOCAL_VARIABLES) 2645 printf(" S_THREAD_LOCAL_VARIABLES\n"); 2646 else if(section_type == S_THREAD_LOCAL_VARIABLE_POINTERS) 2647 printf(" S_THREAD_LOCAL_VARIABLE_POINTERS\n"); 2648 else if(section_type == S_THREAD_LOCAL_INIT_FUNCTION_POINTERS) 2649 printf(" S_THREAD_LOCAL_INIT_FUNCTION_POINTERS\n"); 2650 else 2651 printf(" 0x%08x\n", (unsigned int)section_type); 2652 2653 printf("attributes"); 2654 section_attributes = flags & SECTION_ATTRIBUTES; 2655 if(section_attributes & S_ATTR_PURE_INSTRUCTIONS) 2656 printf(" PURE_INSTRUCTIONS"); 2657 if(section_attributes & S_ATTR_NO_TOC) 2658 printf(" NO_TOC"); 2659 if(section_attributes & S_ATTR_STRIP_STATIC_SYMS) 2660 printf(" STRIP_STATIC_SYMS"); 2661 if(section_attributes & S_ATTR_NO_DEAD_STRIP) 2662 printf(" NO_DEAD_STRIP"); 2663 if(section_attributes & S_ATTR_LIVE_SUPPORT) 2664 printf(" LIVE_SUPPORT"); 2665 if(section_attributes & S_ATTR_SELF_MODIFYING_CODE) 2666 printf(" SELF_MODIFYING_CODE"); 2667 if(section_attributes & S_ATTR_DEBUG) 2668 printf(" DEBUG"); 2669 if(section_attributes & S_ATTR_SOME_INSTRUCTIONS) 2670 printf(" SOME_INSTRUCTIONS"); 2671 if(section_attributes & S_ATTR_EXT_RELOC) 2672 printf(" EXT_RELOC"); 2673 if(section_attributes & S_ATTR_LOC_RELOC) 2674 printf(" LOC_RELOC"); 2675 if(section_attributes == 0) 2676 printf(" (none)"); 2677 printf("\n"); 2678 } 2679 else 2680 printf(" flags 0x%08x\n", (unsigned int)flags); 2681 printf(" reserved1 %u", reserved1); 2682 if(section_type == S_SYMBOL_STUBS || 2683 section_type == S_LAZY_SYMBOL_POINTERS || 2684 section_type == S_LAZY_DYLIB_SYMBOL_POINTERS || 2685 section_type == S_NON_LAZY_SYMBOL_POINTERS || 2686 section_type == S_THREAD_LOCAL_VARIABLE_POINTERS) 2687 printf(" (index into indirect symbol table)\n"); 2688 else 2689 printf("\n"); 2690 printf(" reserved2 %u", reserved2); 2691 if(section_type == S_SYMBOL_STUBS) 2692 printf(" (size of stubs)\n"); 2693 else 2694 printf("\n"); 2695} 2696 2697/* 2698 * print an LC_SYMTAB command. The symtab_command structure specified must 2699 * be aligned correctly and in the host byte sex. 2700 */ 2701void 2702print_symtab_command( 2703struct symtab_command *st, 2704cpu_type_t cputype, 2705uint32_t object_size) 2706{ 2707 uint64_t big_size; 2708 2709 printf(" cmd LC_SYMTAB\n"); 2710 printf(" cmdsize %u", st->cmdsize); 2711 if(st->cmdsize != sizeof(struct symtab_command)) 2712 printf(" Incorrect size\n"); 2713 else 2714 printf("\n"); 2715 printf(" symoff %u", st->symoff); 2716 if(st->symoff > object_size) 2717 printf(" (past end of file)\n"); 2718 else 2719 printf("\n"); 2720 printf(" nsyms %u", st->nsyms); 2721 if(cputype & CPU_ARCH_ABI64){ 2722 big_size = st->nsyms; 2723 big_size *= sizeof(struct nlist_64); 2724 big_size += st->symoff; 2725 if(big_size > object_size) 2726 printf(" (past end of file)\n"); 2727 else 2728 printf("\n"); 2729 } 2730 else{ 2731 big_size = st->nsyms; 2732 big_size *= sizeof(struct nlist); 2733 big_size += st->symoff; 2734 if(big_size > object_size) 2735 printf(" (past end of file)\n"); 2736 else 2737 printf("\n"); 2738 } 2739 printf(" stroff %u", st->stroff); 2740 if(st->stroff > object_size) 2741 printf(" (past end of file)\n"); 2742 else 2743 printf("\n"); 2744 printf(" strsize %u", st->strsize); 2745 if(st->stroff + st->strsize > object_size) 2746 printf(" (past end of file)\n"); 2747 else 2748 printf("\n"); 2749} 2750 2751/* 2752 * print an LC_DYSYMTAB command. The dysymtab_command structure specified must 2753 * be aligned correctly and in the host byte sex. 2754 */ 2755void 2756print_dysymtab_command( 2757struct dysymtab_command *dyst, 2758uint32_t nsyms, 2759uint32_t object_size, 2760cpu_type_t cputype) 2761{ 2762 uint64_t modtabend, big_size; 2763 2764 printf(" cmd LC_DYSYMTAB\n"); 2765 printf(" cmdsize %u", dyst->cmdsize); 2766 if(dyst->cmdsize != sizeof(struct dysymtab_command)) 2767 printf(" Incorrect size\n"); 2768 else 2769 printf("\n"); 2770 2771 printf(" ilocalsym %u", dyst->ilocalsym); 2772 if(dyst->ilocalsym > nsyms) 2773 printf(" (greater than the number of symbols)\n"); 2774 else 2775 printf("\n"); 2776 printf(" nlocalsym %u", dyst->nlocalsym); 2777 big_size = dyst->ilocalsym; 2778 big_size += dyst->nlocalsym; 2779 if(big_size > nsyms) 2780 printf(" (past the end of the symbol table)\n"); 2781 else 2782 printf("\n"); 2783 printf(" iextdefsym %u", dyst->iextdefsym); 2784 if(dyst->iextdefsym > nsyms) 2785 printf(" (greater than the number of symbols)\n"); 2786 else 2787 printf("\n"); 2788 printf(" nextdefsym %u", dyst->nextdefsym); 2789 if(dyst->iextdefsym + dyst->nextdefsym > nsyms) 2790 printf(" (past the end of the symbol table)\n"); 2791 else 2792 printf("\n"); 2793 printf(" iundefsym %u", dyst->iundefsym); 2794 if(dyst->iundefsym > nsyms) 2795 printf(" (greater than the number of symbols)\n"); 2796 else 2797 printf("\n"); 2798 printf(" nundefsym %u", dyst->nundefsym); 2799 big_size = dyst->iundefsym; 2800 big_size += dyst->nundefsym; 2801 if(big_size > nsyms) 2802 printf(" (past the end of the symbol table)\n"); 2803 else 2804 printf("\n"); 2805 printf(" tocoff %u", dyst->tocoff); 2806 if(dyst->tocoff > object_size) 2807 printf(" (past end of file)\n"); 2808 else 2809 printf("\n"); 2810 printf(" ntoc %u", dyst->ntoc); 2811 big_size = dyst->ntoc; 2812 big_size *= sizeof(struct dylib_table_of_contents); 2813 big_size += dyst->tocoff; 2814 if(big_size > object_size) 2815 printf(" (past end of file)\n"); 2816 else 2817 printf("\n"); 2818 printf(" modtaboff %u", dyst->modtaboff); 2819 if(dyst->modtaboff > object_size) 2820 printf(" (past end of file)\n"); 2821 else 2822 printf("\n"); 2823 printf(" nmodtab %u", dyst->nmodtab); 2824 if(cputype & CPU_ARCH_ABI64){ 2825 modtabend = dyst->nmodtab; 2826 modtabend *= sizeof(struct dylib_module_64); 2827 modtabend += dyst->modtaboff; 2828 } 2829 else{ 2830 modtabend = dyst->nmodtab; 2831 modtabend *= sizeof(struct dylib_module); 2832 modtabend += dyst->modtaboff; 2833 } 2834 if(modtabend > object_size) 2835 printf(" (past end of file)\n"); 2836 else 2837 printf("\n"); 2838 printf(" extrefsymoff %u", dyst->extrefsymoff); 2839 if(dyst->extrefsymoff > object_size) 2840 printf(" (past end of file)\n"); 2841 else 2842 printf("\n"); 2843 printf(" nextrefsyms %u", dyst->nextrefsyms); 2844 big_size = dyst->nextrefsyms; 2845 big_size *= sizeof(struct dylib_reference); 2846 big_size += dyst->extrefsymoff; 2847 if(big_size > object_size) 2848 printf(" (past end of file)\n"); 2849 else 2850 printf("\n"); 2851 printf(" indirectsymoff %u", dyst->indirectsymoff); 2852 if(dyst->indirectsymoff > object_size) 2853 printf(" (past end of file)\n"); 2854 else 2855 printf("\n"); 2856 printf(" nindirectsyms %u", dyst->nindirectsyms); 2857 big_size = dyst->nindirectsyms; 2858 big_size *= sizeof(uint32_t); 2859 big_size += dyst->indirectsymoff; 2860 if(big_size > object_size) 2861 printf(" (past end of file)\n"); 2862 else 2863 printf("\n"); 2864 printf(" extreloff %u", dyst->extreloff); 2865 if(dyst->extreloff > object_size) 2866 printf(" (past end of file)\n"); 2867 else 2868 printf("\n"); 2869 printf(" nextrel %u", dyst->nextrel); 2870 if(dyst->extreloff + dyst->nextrel * sizeof(struct relocation_info) > 2871 object_size) 2872 printf(" (past end of file)\n"); 2873 else 2874 printf("\n"); 2875 printf(" locreloff %u", dyst->locreloff); 2876 if(dyst->locreloff > object_size) 2877 printf(" (past end of file)\n"); 2878 else 2879 printf("\n"); 2880 printf(" nlocrel %u", dyst->nlocrel); 2881 big_size = dyst->nlocrel; 2882 big_size *= sizeof(struct relocation_info); 2883 big_size += dyst->locreloff; 2884 if(big_size > object_size) 2885 printf(" (past end of file)\n"); 2886 else 2887 printf("\n"); 2888} 2889 2890/* 2891 * print an LC_SYMSEG command. The symseg_command structure specified must 2892 * be aligned correctly and in the host byte sex. 2893 */ 2894void 2895print_symseg_command( 2896struct symseg_command *ss, 2897uint32_t object_size) 2898{ 2899 uint64_t big_size; 2900 2901 printf(" cmd LC_SYMSEG (obsolete)\n"); 2902 printf(" cmdsize %u", ss->cmdsize); 2903 if(ss->cmdsize != sizeof(struct symseg_command)) 2904 printf(" Incorrect size\n"); 2905 else 2906 printf("\n"); 2907 printf(" offset %u", ss->offset); 2908 if(ss->offset > object_size) 2909 printf(" (past end of file)\n"); 2910 else 2911 printf("\n"); 2912 printf(" size %u", ss->size); 2913 big_size = ss->offset; 2914 big_size += ss->size; 2915 if(big_size > object_size) 2916 printf(" (past end of file)\n"); 2917 else 2918 printf("\n"); 2919} 2920 2921/* 2922 * print an LC_IDFVMLIB or LC_LOADFVMLIB command. The fvmlib_command structure 2923 * specified must be aligned correctly and in the host byte sex. 2924 */ 2925void 2926print_fvmlib_command( 2927struct fvmlib_command *fl, 2928struct load_command *lc) 2929{ 2930 char *p; 2931 2932 if(fl->cmd == LC_IDFVMLIB) 2933 printf(" cmd LC_IDFVMLIB\n"); 2934 else 2935 printf(" cmd LC_LOADFVMLIB\n"); 2936 printf(" cmdsize %u", fl->cmdsize); 2937 if(fl->cmdsize < sizeof(struct fvmlib_command)) 2938 printf(" Incorrect size\n"); 2939 else 2940 printf("\n"); 2941 if(fl->fvmlib.name.offset < fl->cmdsize){ 2942 p = (char *)lc + fl->fvmlib.name.offset; 2943 printf(" name %s (offset %u)\n", 2944 p, fl->fvmlib.name.offset); 2945 } 2946 else{ 2947 printf(" name ?(bad offset %u)\n", 2948 fl->fvmlib.name.offset); 2949 } 2950 printf(" minor version %u\n", fl->fvmlib.minor_version); 2951 printf(" header addr 0x%08x\n", (unsigned int)fl->fvmlib.header_addr); 2952} 2953 2954/* 2955 * print an LC_ID_DYLIB, LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB, LC_REEXPORT_DYLIB, 2956 * LC_LAZY_LOAD_DYLIB, or LC_LOAD_UPWARD_DYLIB command. The dylib_command 2957 * structure specified must be aligned correctly and in the host byte sex. 2958 */ 2959void 2960print_dylib_command( 2961struct dylib_command *dl, 2962struct load_command *lc) 2963{ 2964 char *p; 2965 time_t t; 2966 2967 if(dl->cmd == LC_ID_DYLIB) 2968 printf(" cmd LC_ID_DYLIB\n"); 2969 else if(dl->cmd == LC_LOAD_DYLIB) 2970 printf(" cmd LC_LOAD_DYLIB\n"); 2971 else if(dl->cmd == LC_LOAD_WEAK_DYLIB) 2972 printf(" cmd LC_LOAD_WEAK_DYLIB\n"); 2973 else if(dl->cmd == LC_REEXPORT_DYLIB) 2974 printf(" cmd LC_REEXPORT_DYLIB\n"); 2975 else if(dl->cmd == LC_LAZY_LOAD_DYLIB) 2976 printf(" cmd LC_LAZY_LOAD_DYLIB\n"); 2977 else if(dl->cmd == LC_LOAD_UPWARD_DYLIB) 2978 printf(" cmd LC_LOAD_UPWARD_DYLIB\n"); 2979 else 2980 printf(" cmd %u (unknown)\n", dl->cmd); 2981 printf(" cmdsize %u", dl->cmdsize); 2982 if(dl->cmdsize < sizeof(struct dylib_command)) 2983 printf(" Incorrect size\n"); 2984 else 2985 printf("\n"); 2986 if(dl->dylib.name.offset < dl->cmdsize){ 2987 p = (char *)lc + dl->dylib.name.offset; 2988 printf(" name %s (offset %u)\n", 2989 p, dl->dylib.name.offset); 2990 } 2991 else{ 2992 printf(" name ?(bad offset %u)\n", 2993 dl->dylib.name.offset); 2994 } 2995 printf(" time stamp %u ", dl->dylib.timestamp); 2996 t = dl->dylib.timestamp; 2997 printf("%s", ctime(&t)); 2998 printf(" current version "); 2999 if(dl->dylib.current_version == 0xffffffff) 3000 printf("n/a\n"); 3001 else 3002 printf("%u.%u.%u\n", 3003 dl->dylib.current_version >> 16, 3004 (dl->dylib.current_version >> 8) & 0xff, 3005 dl->dylib.current_version & 0xff); 3006 printf("compatibility version "); 3007 if(dl->dylib.compatibility_version == 0xffffffff) 3008 printf("n/a\n"); 3009 else 3010 printf("%u.%u.%u\n", 3011 dl->dylib.compatibility_version >> 16, 3012 (dl->dylib.compatibility_version >> 8) & 0xff, 3013 dl->dylib.compatibility_version & 0xff); 3014} 3015 3016/* 3017 * print an LC_SUB_FRAMEWORK command. The sub_framework_command 3018 * structure specified must be aligned correctly and in the host byte sex. 3019 */ 3020void 3021print_sub_framework_command( 3022struct sub_framework_command *sub, 3023struct load_command *lc) 3024{ 3025 char *p; 3026 3027 printf(" cmd LC_SUB_FRAMEWORK\n"); 3028 printf(" cmdsize %u", sub->cmdsize); 3029 if(sub->cmdsize < sizeof(struct sub_framework_command)) 3030 printf(" Incorrect size\n"); 3031 else 3032 printf("\n"); 3033 if(sub->umbrella.offset < sub->cmdsize){ 3034 p = (char *)lc + sub->umbrella.offset; 3035 printf(" umbrella %s (offset %u)\n", 3036 p, sub->umbrella.offset); 3037 } 3038 else{ 3039 printf(" umbrella ?(bad offset %u)\n", 3040 sub->umbrella.offset); 3041 } 3042} 3043 3044/* 3045 * print an LC_SUB_UMBRELLA command. The sub_umbrella_command 3046 * structure specified must be aligned correctly and in the host byte sex. 3047 */ 3048void 3049print_sub_umbrella_command( 3050struct sub_umbrella_command *usub, 3051struct load_command *lc) 3052{ 3053 char *p; 3054 3055 printf(" cmd LC_SUB_UMBRELLA\n"); 3056 printf(" cmdsize %u", usub->cmdsize); 3057 if(usub->cmdsize < sizeof(struct sub_umbrella_command)) 3058 printf(" Incorrect size\n"); 3059 else 3060 printf("\n"); 3061 if(usub->sub_umbrella.offset < usub->cmdsize){ 3062 p = (char *)lc + usub->sub_umbrella.offset; 3063 printf(" sub_umbrella %s (offset %u)\n", 3064 p, usub->sub_umbrella.offset); 3065 } 3066 else{ 3067 printf(" sub_umbrella ?(bad offset %u)\n", 3068 usub->sub_umbrella.offset); 3069 } 3070} 3071 3072/* 3073 * print an LC_SUB_LIBRARY command. The sub_library_command 3074 * structure specified must be aligned correctly and in the host byte sex. 3075 */ 3076void 3077print_sub_library_command( 3078struct sub_library_command *lsub, 3079struct load_command *lc) 3080{ 3081 char *p; 3082 3083 printf(" cmd LC_SUB_LIBRARY\n"); 3084 printf(" cmdsize %u", lsub->cmdsize); 3085 if(lsub->cmdsize < sizeof(struct sub_library_command)) 3086 printf(" Incorrect size\n"); 3087 else 3088 printf("\n"); 3089 if(lsub->sub_library.offset < lsub->cmdsize){ 3090 p = (char *)lc + lsub->sub_library.offset; 3091 printf(" sub_library %s (offset %u)\n", 3092 p, lsub->sub_library.offset); 3093 } 3094 else{ 3095 printf(" sub_library ?(bad offset %u)\n", 3096 lsub->sub_library.offset); 3097 } 3098} 3099 3100/* 3101 * print an LC_SUB_CLIENT command. The sub_client_command 3102 * structure specified must be aligned correctly and in the host byte sex. 3103 */ 3104void 3105print_sub_client_command( 3106struct sub_client_command *csub, 3107struct load_command *lc) 3108{ 3109 char *p; 3110 3111 printf(" cmd LC_SUB_CLIENT\n"); 3112 printf(" cmdsize %u", csub->cmdsize); 3113 if(csub->cmdsize < sizeof(struct sub_client_command)) 3114 printf(" Incorrect size\n"); 3115 else 3116 printf("\n"); 3117 if(csub->client.offset < csub->cmdsize){ 3118 p = (char *)lc + csub->client.offset; 3119 printf(" client %s (offset %u)\n", 3120 p, csub->client.offset); 3121 } 3122 else{ 3123 printf(" client ?(bad offset %u)\n", 3124 csub->client.offset); 3125 } 3126} 3127 3128/* 3129 * print an LC_PREBOUND_DYLIB command. The prebound_dylib_command structure 3130 * specified must be aligned correctly and in the host byte sex. 3131 */ 3132void 3133print_prebound_dylib_command( 3134struct prebound_dylib_command *pbdylib, 3135struct load_command *lc, 3136enum bool verbose) 3137{ 3138 char *p; 3139 uint32_t i; 3140 3141 printf(" cmd LC_PREBOUND_DYLIB\n"); 3142 printf(" cmdsize %u", pbdylib->cmdsize); 3143 if(pbdylib->cmdsize < sizeof(struct prebound_dylib_command)) 3144 printf(" Incorrect size\n"); 3145 else 3146 printf("\n"); 3147 if(pbdylib->name.offset < pbdylib->cmdsize){ 3148 p = (char *)lc + pbdylib->name.offset; 3149 printf(" name %s (offset %u)\n", 3150 p, pbdylib->name.offset); 3151 } 3152 else{ 3153 printf(" name ?(bad offset %u)\n", 3154 pbdylib->name.offset); 3155 } 3156 printf(" nmodules %u\n", pbdylib->nmodules); 3157 3158 if(pbdylib->linked_modules.offset < pbdylib->cmdsize){ 3159 p = (char *)lc + pbdylib->linked_modules.offset; 3160 if(verbose == TRUE){ 3161 printf(" linked_modules (offset %u)\n", 3162 pbdylib->linked_modules.offset); 3163 for(i = 0; i < pbdylib->nmodules; i++){ 3164 if(((p[i/8] >> (i%8)) & 1) == 1) 3165 printf("%u\n", i); 3166 } 3167 } 3168 else{ 3169 printf(" linked_modules "); 3170 for(i = 0; i < pbdylib->nmodules && i < 8; i++){ 3171 if(((*p >> i) & 1) == 0) 3172 printf("0"); 3173 else 3174 printf("1"); 3175 } 3176 if(i <= pbdylib->nmodules) 3177 printf("..."); 3178 printf(" (offset %u)\n", pbdylib->linked_modules.offset); 3179 } 3180 } 3181 else{ 3182 printf(" linked_modules ?(bad offset %u)\n", 3183 pbdylib->linked_modules.offset); 3184 } 3185} 3186 3187/* 3188 * print an LC_ID_DYLINKER, LC_LOAD_DYLINKER or LC_DYLD_ENVIRONMENT command. 3189 * The dylinker_command structure specified must be aligned correctly and in the 3190 * host byte sex. 3191 */ 3192void 3193print_dylinker_command( 3194struct dylinker_command *dyld, 3195struct load_command *lc) 3196{ 3197 char *p; 3198 3199 if(dyld->cmd == LC_ID_DYLINKER) 3200 printf(" cmd LC_ID_DYLINKER\n"); 3201 else if(dyld->cmd == LC_LOAD_DYLINKER) 3202 printf(" cmd LC_LOAD_DYLINKER\n"); 3203 else if(dyld->cmd == LC_DYLD_ENVIRONMENT) 3204 printf(" cmd LC_DYLD_ENVIRONMENT\n"); 3205 else 3206 printf(" cmd ?(%u)\n", dyld->cmd); 3207 printf(" cmdsize %u", dyld->cmdsize); 3208 if(dyld->cmdsize < sizeof(struct dylinker_command)) 3209 printf(" Incorrect size\n"); 3210 else 3211 printf("\n"); 3212 if(dyld->name.offset < dyld->cmdsize){ 3213 p = (char *)lc + dyld->name.offset; 3214 printf(" name %s (offset %u)\n", p, dyld->name.offset); 3215 } 3216 else{ 3217 printf(" name ?(bad offset %u)\n", dyld->name.offset); 3218 } 3219} 3220 3221/* 3222 * print an LC_FVMFILE command. The fvmfile_command structure specified must 3223 * be aligned correctly and in the host byte sex. 3224 */ 3225void 3226print_fvmfile_command( 3227struct fvmfile_command *ff, 3228struct load_command *lc) 3229{ 3230 char *p; 3231 3232 printf(" cmd LC_FVMFILE\n"); 3233 printf(" cmdsize %u", ff->cmdsize); 3234 if(ff->cmdsize < sizeof(struct fvmfile_command)) 3235 printf(" Incorrect size\n"); 3236 else 3237 printf("\n"); 3238 if(ff->name.offset < ff->cmdsize){ 3239 p = (char *)lc + ff->name.offset; 3240 printf(" name %s (offset %u)\n", p, ff->name.offset); 3241 } 3242 else{ 3243 printf(" name ?(bad offset %u)\n", ff->name.offset); 3244 } 3245 printf(" header addr 0x%08x\n", (unsigned int)ff->header_addr); 3246} 3247 3248/* 3249 * print an LC_ROUTINES command. The routines_command structure specified must 3250 * be aligned correctly and in the host byte sex. 3251 */ 3252void 3253print_routines_command( 3254struct routines_command *rc) 3255{ 3256 printf(" cmd LC_ROUTINES\n"); 3257 printf(" cmdsize %u", rc->cmdsize); 3258 if(rc->cmdsize != sizeof(struct routines_command)) 3259 printf(" Incorrect size\n"); 3260 else 3261 printf("\n"); 3262 printf(" init_address 0x%08x\n", rc->init_address); 3263 printf(" init_module %u\n", rc->init_module); 3264 printf(" reserved1 %u\n", rc->reserved1); 3265 printf(" reserved2 %u\n", rc->reserved2); 3266 printf(" reserved3 %u\n", rc->reserved3); 3267 printf(" reserved4 %u\n", rc->reserved4); 3268 printf(" reserved5 %u\n", rc->reserved5); 3269 printf(" reserved6 %u\n", rc->reserved6); 3270} 3271 3272/* 3273 * print an LC_ROUTINES_64 command. The routines_command_64 structure specified 3274 * must be aligned correctly and in the host byte sex. 3275 */ 3276void 3277print_routines_command_64( 3278struct routines_command_64 *rc64) 3279{ 3280 printf(" cmd LC_ROUTINES_64\n"); 3281 printf(" cmdsize %u", rc64->cmdsize); 3282 if(rc64->cmdsize != sizeof(struct routines_command_64)) 3283 printf(" Incorrect size\n"); 3284 else 3285 printf("\n"); 3286 printf(" init_address 0x%016llx\n", rc64->init_address); 3287 printf(" init_module %llu\n", rc64->init_module); 3288 printf(" reserved1 %llu\n", rc64->reserved1); 3289 printf(" reserved2 %llu\n", rc64->reserved2); 3290 printf(" reserved3 %llu\n", rc64->reserved3); 3291 printf(" reserved4 %llu\n", rc64->reserved4); 3292 printf(" reserved5 %llu\n", rc64->reserved5); 3293 printf(" reserved6 %llu\n", rc64->reserved6); 3294} 3295 3296/* 3297 * print an LC_TWOLEVEL_HINTS command. The twolevel_hints_command structure 3298 * specified must be aligned correctly and in the host byte sex. 3299 */ 3300void 3301print_twolevel_hints_command( 3302struct twolevel_hints_command *hints, 3303uint32_t object_size) 3304{ 3305 uint64_t big_size; 3306 3307 printf(" cmd LC_TWOLEVEL_HINTS\n"); 3308 printf(" cmdsize %u", hints->cmdsize); 3309 if(hints->cmdsize != sizeof(struct twolevel_hints_command)) 3310 printf(" Incorrect size\n"); 3311 else 3312 printf("\n"); 3313 printf(" offset %u", hints->offset); 3314 if(hints->offset > object_size) 3315 printf(" (past end of file)\n"); 3316 else 3317 printf("\n"); 3318 printf(" nhints %u", hints->nhints); 3319 big_size = hints->nhints; 3320 big_size *= sizeof(struct twolevel_hint); 3321 big_size += hints->offset; 3322 if(big_size > object_size) 3323 printf(" (past end of file)\n"); 3324 else 3325 printf("\n"); 3326} 3327 3328/* 3329 * print an LC_PREBIND_CKSUM command. The prebind_cksum_command structure 3330 * specified must be aligned correctly and in the host byte sex. 3331 */ 3332void 3333print_prebind_cksum_command( 3334struct prebind_cksum_command *cksum) 3335{ 3336 printf(" cmd LC_PREBIND_CKSUM\n"); 3337 printf(" cmdsize %u", cksum->cmdsize); 3338 if(cksum->cmdsize != sizeof(struct prebind_cksum_command)) 3339 printf(" Incorrect size\n"); 3340 else 3341 printf("\n"); 3342 printf(" cksum 0x%08x\n", (unsigned int)cksum->cksum); 3343} 3344 3345/* 3346 * print an LC_UUID command. The uuid_command structure 3347 * specified must be aligned correctly and in the host byte sex. 3348 */ 3349void 3350print_uuid_command( 3351struct uuid_command *uuid) 3352{ 3353 printf(" cmd LC_UUID\n"); 3354 printf(" cmdsize %u", uuid->cmdsize); 3355 if(uuid->cmdsize != sizeof(struct uuid_command)) 3356 printf(" Incorrect size\n"); 3357 else 3358 printf("\n"); 3359 printf(" uuid %02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-" 3360 "%02X%02X%02X%02X%02X%02X\n", 3361 (unsigned int)uuid->uuid[0], (unsigned int)uuid->uuid[1], 3362 (unsigned int)uuid->uuid[2], (unsigned int)uuid->uuid[3], 3363 (unsigned int)uuid->uuid[4], (unsigned int)uuid->uuid[5], 3364 (unsigned int)uuid->uuid[6], (unsigned int)uuid->uuid[7], 3365 (unsigned int)uuid->uuid[8], (unsigned int)uuid->uuid[9], 3366 (unsigned int)uuid->uuid[10], (unsigned int)uuid->uuid[11], 3367 (unsigned int)uuid->uuid[12], (unsigned int)uuid->uuid[13], 3368 (unsigned int)uuid->uuid[14], (unsigned int)uuid->uuid[15]); 3369} 3370 3371/* 3372 * print a linkedit_data_command. The linkedit_data_command structure 3373 * specified must be aligned correctly and in the host byte sex. 3374 */ 3375void 3376print_linkedit_data_command( 3377struct linkedit_data_command *ld, 3378uint32_t object_size) 3379{ 3380 uint64_t big_size; 3381 3382 if(ld->cmd == LC_CODE_SIGNATURE) 3383 printf(" cmd LC_CODE_SIGNATURE\n"); 3384 else if(ld->cmd == LC_SEGMENT_SPLIT_INFO) 3385 printf(" cmd LC_SEGMENT_SPLIT_INFO\n"); 3386 else if(ld->cmd == LC_FUNCTION_STARTS) 3387 printf(" cmd LC_FUNCTION_STARTS\n"); 3388 else if(ld->cmd == LC_DATA_IN_CODE) 3389 printf(" cmd LC_DATA_IN_CODE\n"); 3390 else if(ld->cmd == LC_DYLIB_CODE_SIGN_DRS) 3391 printf(" cmd LC_DYLIB_CODE_SIGN_DRS\n"); 3392 else 3393 printf(" cmd %u (?)\n", ld->cmd); 3394 printf(" cmdsize %u", ld->cmdsize); 3395 if(ld->cmdsize != sizeof(struct linkedit_data_command)) 3396 printf(" Incorrect size\n"); 3397 else 3398 printf("\n"); 3399 printf(" dataoff %u", ld->dataoff); 3400 if(ld->dataoff > object_size) 3401 printf(" (past end of file)\n"); 3402 else 3403 printf("\n"); 3404 printf(" datasize %u", ld->datasize); 3405 big_size = ld->dataoff; 3406 big_size += ld->datasize; 3407 if(big_size > object_size) 3408 printf(" (past end of file)\n"); 3409 else 3410 printf("\n"); 3411} 3412 3413/* 3414 * print a version_min_command. The version_min_command structure 3415 * specified must be aligned correctly and in the host byte sex. 3416 */ 3417void 3418print_version_min_command( 3419struct version_min_command *vd) 3420{ 3421 if(vd->cmd == LC_VERSION_MIN_MACOSX) 3422 printf(" cmd LC_VERSION_MIN_MACOSX\n"); 3423 else if(vd->cmd == LC_VERSION_MIN_IPHONEOS) 3424 printf(" cmd LC_VERSION_MIN_IPHONEOS\n"); 3425 else 3426 printf(" cmd %u (?)\n", vd->cmd); 3427 printf(" cmdsize %u", vd->cmdsize); 3428 if(vd->cmdsize != sizeof(struct version_min_command)) 3429 printf(" Incorrect size\n"); 3430 else 3431 printf("\n"); 3432 if((vd->version & 0xff) == 0) 3433 printf(" version %u.%u\n", 3434 vd->version >> 16, 3435 (vd->version >> 8) & 0xff); 3436 else 3437 printf(" version %u.%u.%u\n", 3438 vd->version >> 16, 3439 (vd->version >> 8) & 0xff, 3440 vd->version & 0xff); 3441 if(vd->sdk == 0) 3442 printf(" sdk n/a\n"); 3443 else{ 3444 if((vd->sdk & 0xff) == 0) 3445 printf(" sdk %u.%u\n", 3446 vd->sdk >> 16, 3447 (vd->sdk >> 8) & 0xff); 3448 else 3449 printf(" sdk %u.%u.%u\n", 3450 vd->sdk >> 16, 3451 (vd->sdk >> 8) & 0xff, 3452 vd->sdk & 0xff); 3453 } 3454} 3455 3456/* 3457 * print a source_version_command. The source_version_command structure 3458 * specified must be aligned correctly and in the host byte sex. 3459 */ 3460void 3461print_source_version_command( 3462struct source_version_command *sv) 3463{ 3464 uint64_t a, b, c, d, e; 3465 3466 printf(" cmd LC_SOURCE_VERSION\n"); 3467 printf(" cmdsize %u", sv->cmdsize); 3468 if(sv->cmdsize != sizeof(struct source_version_command)) 3469 printf(" Incorrect size\n"); 3470 else 3471 printf("\n"); 3472 a = (sv->version >> 40) & 0xffffff; 3473 b = (sv->version >> 30) & 0x3ff; 3474 c = (sv->version >> 20) & 0x3ff; 3475 d = (sv->version >> 10) & 0x3ff; 3476 e = sv->version & 0x3ff; 3477 if(e != 0) 3478 printf(" version %llu.%llu.%llu.%llu.%llu\n", a, b, c, d, e); 3479 else if(d != 0) 3480 printf(" version %llu.%llu.%llu.%llu\n", a, b, c, d); 3481 else if(c != 0) 3482 printf(" version %llu.%llu.%llu\n", a, b, c); 3483 else 3484 printf(" version %llu.%llu\n", a, b); 3485} 3486 3487/* 3488 * print a entry_point_command. The entry_point_command structure 3489 * specified must be aligned correctly and in the host byte sex. 3490 */ 3491void 3492print_entry_point_command( 3493struct entry_point_command *ep) 3494{ 3495 printf(" cmd LC_MAIN\n"); 3496 printf(" cmdsize %u", ep->cmdsize); 3497 if(ep->cmdsize < sizeof(struct entry_point_command)) 3498 printf(" Incorrect size\n"); 3499 else 3500 printf("\n"); 3501 printf(" entryoff %llu\n", ep->entryoff); 3502 printf(" stacksize %llu\n", ep->stacksize); 3503} 3504 3505/* 3506 * print an LC_RPATH command. The rpath_command structure specified must be 3507 * aligned correctly and in the host byte sex. 3508 */ 3509void 3510print_rpath_command( 3511struct rpath_command *rpath, 3512struct load_command *lc) 3513{ 3514 char *p; 3515 3516 printf(" cmd LC_RPATH\n"); 3517 printf(" cmdsize %u", rpath->cmdsize); 3518 if(rpath->cmdsize < sizeof(struct rpath_command)) 3519 printf(" Incorrect size\n"); 3520 else 3521 printf("\n"); 3522 if(rpath->path.offset < rpath->cmdsize){ 3523 p = (char *)lc + rpath->path.offset; 3524 printf(" path %s (offset %u)\n", p, rpath->path.offset); 3525 } 3526 else{ 3527 printf(" path ?(bad offset %u)\n", rpath->path.offset); 3528 } 3529} 3530 3531/* 3532 * print an LC_ENCRYPTION_INFO command. The encryption_info_command structure 3533 * specified must be aligned correctly and in the host byte sex. 3534 */ 3535void 3536print_encryption_info_command( 3537struct encryption_info_command *ec, 3538uint32_t object_size) 3539{ 3540 uint64_t big_size; 3541 3542 printf(" cmd LC_ENCRYPTION_INFO\n"); 3543 printf(" cmdsize %u", ec->cmdsize); 3544 if(ec->cmdsize < sizeof(struct encryption_info_command)) 3545 printf(" Incorrect size\n"); 3546 else 3547 printf("\n"); 3548 printf(" cryptoff %u", ec->cryptoff); 3549 if(ec->cryptoff > object_size) 3550 printf(" (past end of file)\n"); 3551 else 3552 printf("\n"); 3553 printf(" cryptsize %u", ec->cryptsize); 3554 big_size = ec->cryptsize; 3555 big_size += ec->cryptoff; 3556 if(big_size > object_size) 3557 printf(" (past end of file)\n"); 3558 else 3559 printf("\n"); 3560 printf(" cryptid %u\n", ec->cryptid); 3561} 3562 3563/* 3564 * print an LC_ENCRYPTION_INFO_64 command. The encryption_info_command_64 3565 * structure specified must be aligned correctly and in the host byte sex. 3566 */ 3567void 3568print_encryption_info_command_64( 3569struct encryption_info_command_64 *ec, 3570uint32_t object_size) 3571{ 3572 uint64_t big_size; 3573 3574 printf(" cmd LC_ENCRYPTION_INFO_64\n"); 3575 printf(" cmdsize %u", ec->cmdsize); 3576 if(ec->cmdsize < sizeof(struct encryption_info_command_64)) 3577 printf(" Incorrect size\n"); 3578 else 3579 printf("\n"); 3580 printf(" cryptoff %u", ec->cryptoff); 3581 if(ec->cryptoff > object_size) 3582 printf(" (past end of file)\n"); 3583 else 3584 printf("\n"); 3585 printf(" cryptsize %u", ec->cryptsize); 3586 big_size = ec->cryptsize; 3587 big_size += ec->cryptoff; 3588 if(big_size > object_size) 3589 printf(" (past end of file)\n"); 3590 else 3591 printf("\n"); 3592 printf(" cryptid %u\n", ec->cryptid); 3593 printf(" pad %u\n", ec->pad); 3594} 3595 3596/* 3597 * print an LC_LINKER_OPTION command. The linker_option_command structure 3598 * specified must be aligned correctly and in the host byte sex. The lc is 3599 * the actual load command with the strings that follow it and must have been 3600 * previously checked so that the cmdsize does not extend past the size of the 3601 * load commands. 3602 */ 3603void 3604print_linker_option_command( 3605struct linker_option_command *lo, 3606struct load_command *lc) 3607{ 3608 int left, len, i; 3609 char *string; 3610 3611 printf(" cmd LC_LINKER_OPTION\n"); 3612 printf(" cmdsize %u", lo->cmdsize); 3613 if(lo->cmdsize < sizeof(struct linker_option_command)) 3614 printf(" Incorrect size\n"); 3615 else 3616 printf("\n"); 3617 printf(" count %u\n", lo->count); 3618 string = (char *)lc + sizeof(struct linker_option_command); 3619 left = lo->cmdsize - sizeof(struct linker_option_command); 3620 i = 0; 3621 while(left > 0){ 3622 while(*string == '\0' && left > 0){ 3623 string++; 3624 left--; 3625 } 3626 if(left > 0){ 3627 i++; 3628 printf(" string #%d %.*s\n", i, left, string); 3629 len = strnlen(string, left) + 1; 3630 string += len; 3631 left -= len; 3632 } 3633 } 3634 if(lo->count != i) 3635 printf(" count %u does not match number of strings %u\n", 3636 lo->count, i); 3637} 3638 3639/* 3640 * print an LC_DYLD_INFO command. The dyld_info_command structure 3641 * specified must be aligned correctly and in the host byte sex. 3642 */ 3643void 3644print_dyld_info_info_command( 3645struct dyld_info_command *dc, 3646uint32_t object_size) 3647{ 3648 uint64_t big_size; 3649 3650 if(dc->cmd == LC_DYLD_INFO) 3651 printf(" cmd LC_DYLD_INFO\n"); 3652 else 3653 printf(" cmd LC_DYLD_INFO_ONLY\n"); 3654 printf(" cmdsize %u", dc->cmdsize); 3655 if(dc->cmdsize < sizeof(struct dyld_info_command)) 3656 printf(" Incorrect size\n"); 3657 else 3658 printf("\n"); 3659 3660 printf(" rebase_off %u", dc->rebase_off); 3661 if(dc->rebase_off > object_size) 3662 printf(" (past end of file)\n"); 3663 else 3664 printf("\n"); 3665 printf(" rebase_size %u", dc->rebase_size); 3666 big_size = dc->rebase_off; 3667 big_size += dc->rebase_size; 3668 if(big_size > object_size) 3669 printf(" (past end of file)\n"); 3670 else 3671 printf("\n"); 3672 3673 printf(" bind_off %u", dc->bind_off); 3674 if(dc->bind_off > object_size) 3675 printf(" (past end of file)\n"); 3676 else 3677 printf("\n"); 3678 printf(" bind_size %u", dc->bind_size); 3679 big_size = dc->bind_off; 3680 big_size += dc->bind_size; 3681 if(big_size > object_size) 3682 printf(" (past end of file)\n"); 3683 else 3684 printf("\n"); 3685 3686 printf(" weak_bind_off %u", dc->weak_bind_off); 3687 if(dc->weak_bind_off > object_size) 3688 printf(" (past end of file)\n"); 3689 else 3690 printf("\n"); 3691 printf(" weak_bind_size %u", dc->weak_bind_size); 3692 big_size = dc->weak_bind_off; 3693 big_size += dc->weak_bind_size; 3694 if(big_size > object_size) 3695 printf(" (past end of file)\n"); 3696 else 3697 printf("\n"); 3698 3699 printf(" lazy_bind_off %u", dc->lazy_bind_off); 3700 if(dc->lazy_bind_off > object_size) 3701 printf(" (past end of file)\n"); 3702 else 3703 printf("\n"); 3704 printf(" lazy_bind_size %u", dc->lazy_bind_size); 3705 big_size = dc->lazy_bind_off; 3706 big_size += dc->lazy_bind_size; 3707 if(big_size > object_size) 3708 printf(" (past end of file)\n"); 3709 else 3710 printf("\n"); 3711 3712 printf(" export_off %u", dc->export_off); 3713 if(dc->export_off > object_size) 3714 printf(" (past end of file)\n"); 3715 else 3716 printf("\n"); 3717 printf(" export_size %u", dc->export_size); 3718 big_size = dc->export_off; 3719 big_size += dc->export_size; 3720 if(big_size > object_size) 3721 printf(" (past end of file)\n"); 3722 else 3723 printf("\n"); 3724} 3725 3726/* 3727 * print the thread states from an LC_THREAD or LC_UNIXTHREAD command. The 3728 * thread state triples (flavor, count, state) are in memory between begin and 3729 * and end values specified, and in the specified byte sex. The mach_header 3730 * structure specified must be aligned correctly and in the host byte sex. 3731 */ 3732void 3733print_thread_states( 3734char *begin, 3735char *end, 3736cpu_type_t cputype, 3737enum byte_sex thread_states_byte_sex) 3738{ 3739 uint32_t i, j, k, flavor, count, left; 3740 enum byte_sex host_byte_sex; 3741 enum bool swapped; 3742 3743 i = 0; 3744 host_byte_sex = get_host_byte_sex(); 3745 swapped = host_byte_sex != thread_states_byte_sex; 3746 3747 if(cputype == CPU_TYPE_MC680x0){ 3748 struct m68k_thread_state_regs cpu; 3749 struct m68k_thread_state_68882 fpu; 3750 struct m68k_thread_state_user_reg user_reg; 3751 3752 while(begin < end){ 3753 if(end - begin > (ptrdiff_t)sizeof(uint32_t)){ 3754 memcpy((char *)&flavor, begin, sizeof(uint32_t)); 3755 begin += sizeof(uint32_t); 3756 } 3757 else{ 3758 flavor = 0; 3759 begin = end; 3760 } 3761 if(swapped) 3762 flavor = SWAP_INT(flavor); 3763 if(end - begin > (ptrdiff_t)sizeof(uint32_t)){ 3764 memcpy((char *)&count, begin, sizeof(uint32_t)); 3765 begin += sizeof(uint32_t); 3766 } 3767 else{ 3768 count = 0; 3769 begin = end; 3770 } 3771 if(swapped) 3772 count = SWAP_INT(count); 3773 3774 switch(flavor){ 3775 case M68K_THREAD_STATE_REGS: 3776 printf(" flavor M68K_THREAD_STATE_REGS\n"); 3777 if(count == M68K_THREAD_STATE_REGS_COUNT) 3778 printf(" count M68K_THREAD_STATE_" 3779 "REGS_COUNT\n"); 3780 else 3781 printf(" count %u (not M68K_THREAD_STATE_" 3782 "REGS_COUNT)\n", count); 3783 left = end - begin; 3784 if(left >= sizeof(struct m68k_thread_state_regs)){ 3785 memcpy((char *)&cpu, begin, 3786 sizeof(struct m68k_thread_state_regs)); 3787 begin += sizeof(struct m68k_thread_state_regs); 3788 } 3789 else{ 3790 memset((char *)&cpu, '\0', 3791 sizeof(struct m68k_thread_state_regs)); 3792 memcpy((char *)&cpu, begin, left); 3793 begin += left; 3794 } 3795 if(swapped) 3796 swap_m68k_thread_state_regs(&cpu, host_byte_sex); 3797 printf(" dregs "); 3798 for(j = 0 ; j < 8 ; j++) 3799 printf(" %08x", (unsigned int)cpu.dreg[j]); 3800 printf("\n"); 3801 printf(" aregs "); 3802 for(j = 0 ; j < 8 ; j++) 3803 printf(" %08x", (unsigned int)cpu.areg[j]); 3804 printf("\n"); 3805 printf(" pad 0x%04x sr 0x%04x pc 0x%08x\n", 3806 (unsigned int)(cpu.pad0 & 0x0000ffff), 3807 (unsigned int)(cpu.sr & 0x0000ffff), 3808 (unsigned int)cpu.pc); 3809 break; 3810 3811 case M68K_THREAD_STATE_68882: 3812 printf(" flavor M68K_THREAD_STATE_68882\n"); 3813 if(count == M68K_THREAD_STATE_68882_COUNT) 3814 printf(" count M68K_THREAD_STATE_" 3815 "68882_COUNT\n"); 3816 else 3817 printf(" count %u (not M68K_THREAD_STATE_" 3818 "68882_COUNT\n", count); 3819 left = end - begin; 3820 if(left >= sizeof(struct m68k_thread_state_68882)){ 3821 memcpy((char *)&fpu, begin, 3822 sizeof(struct m68k_thread_state_68882)); 3823 begin += sizeof(struct m68k_thread_state_68882); 3824 } 3825 else{ 3826 memset((char *)&fpu, '\0', 3827 sizeof(struct m68k_thread_state_68882)); 3828 memcpy((char *)&fpu, begin, left); 3829 begin += left; 3830 } 3831 if(swapped) 3832 swap_m68k_thread_state_68882(&fpu, host_byte_sex); 3833 for(j = 0 ; j < 8 ; j++) 3834 printf(" fp reg %u %08x %08x %08x\n", j, 3835 (unsigned int)fpu.regs[j].fp[0], 3836 (unsigned int)fpu.regs[j].fp[1], 3837 (unsigned int)fpu.regs[j].fp[2]); 3838 printf(" cr 0x%08x sr 0x%08x state 0x%08x\n", 3839 (unsigned int)fpu.cr, (unsigned int)fpu.sr, 3840 (unsigned int)fpu.state); 3841 break; 3842 3843 case M68K_THREAD_STATE_USER_REG: 3844 printf(" flavor M68K_THREAD_STATE_USER_REG\n"); 3845 if(count == M68K_THREAD_STATE_USER_REG_COUNT) 3846 printf(" count M68K_THREAD_STATE_" 3847 "USER_REG_COUNT\n"); 3848 else 3849 printf(" count %u (not M68K_THREAD_STATE_" 3850 "USER_REG_COUNT", count); 3851 left = end - begin; 3852 if(left >= sizeof(struct m68k_thread_state_user_reg)){ 3853 memcpy((char *)&user_reg, begin, 3854 sizeof(struct m68k_thread_state_user_reg)); 3855 begin += sizeof(struct m68k_thread_state_user_reg); 3856 } 3857 else{ 3858 memset((char *)&user_reg, '\0', 3859 sizeof(struct m68k_thread_state_user_reg)); 3860 memcpy((char *)&user_reg, begin, left); 3861 begin += left; 3862 } 3863 if(swapped) 3864 swap_m68k_thread_state_user_reg(&user_reg, 3865 host_byte_sex); 3866 printf(" user_reg 0x%08x\n", 3867 (unsigned int)user_reg.user_reg); 3868 break; 3869 3870 default: 3871 printf(" flavor %u (unknown)\n", flavor); 3872 printf(" count %u\n", count); 3873 printf(" state:\n"); 3874 print_unknown_state(begin, end, count, swapped); 3875 begin += count * sizeof(uint32_t); 3876 break; 3877 } 3878 } 3879 } 3880 else if(cputype == CPU_TYPE_HPPA){ 3881 while(begin < end){ 3882 if(end - begin > (ptrdiff_t)sizeof(uint32_t)){ 3883 memcpy((char *)&flavor, begin, sizeof(uint32_t)); 3884 begin += sizeof(uint32_t); 3885 } 3886 else{ 3887 flavor = 0; 3888 begin = end; 3889 } 3890 if(swapped) 3891 flavor = SWAP_INT(flavor); 3892 if(end - begin > (ptrdiff_t)sizeof(uint32_t)){ 3893 memcpy((char *)&count, begin, sizeof(uint32_t)); 3894 begin += sizeof(uint32_t); 3895 } 3896 else{ 3897 count = 0; 3898 begin = end; 3899 } 3900 if(swapped) 3901 count = SWAP_INT(count); 3902 3903 switch(flavor){ 3904 case HPPA_INTEGER_THREAD_STATE: 3905 { struct hp_pa_integer_thread_state frame; 3906 3907 printf(" flavor HPPA_INTEGER_THREAD_STATE\n"); 3908 if(count == HPPA_INTEGER_THREAD_STATE_COUNT) 3909 printf(" count HPPA_INTEGER_THREAD_STATE_COUNT\n"); 3910 else 3911 printf(" count %u (not HPPA_INTEGER_THREAD_STATE_" 3912 "COUNT)\n", count); 3913 left = end - begin; 3914 if(left >= sizeof(struct hp_pa_integer_thread_state)){ 3915 memcpy((char *)&frame, begin, 3916 sizeof(struct hp_pa_integer_thread_state)); 3917 begin += sizeof(struct hp_pa_integer_thread_state); 3918 } 3919 else{ 3920 memset((char *)&frame, '\0', 3921 sizeof(struct hp_pa_integer_thread_state)); 3922 memcpy((char *)&frame, begin, left); 3923 begin += left; 3924 } 3925 if(swapped) 3926 swap_hppa_integer_thread_state(&frame, host_byte_sex); 3927 printf( 3928 "r1 0x%08x r2 0x%08x r3 0x%08x r4 0x%08x\n" 3929 "r5 0x%08x r6 0x%08x r7 0x%08x r8 0x%08x\n" 3930 "r9 0x%08x r10 0x%08x r11 0x%08x r12 0x%08x\n" 3931 "r13 0x%08x r14 0x%08x r15 0x%08x r16 0x%08x\n" 3932 "r17 0x%08x r18 0x%08x r19 0x%08x r20 0x%08x\n" 3933 "r21 0x%08x r22 0x%08x r23 0x%08x r24 0x%08x\n" 3934 "r25 0x%08x r26 0x%08x r27 0x%08x r28 0x%08x\n" 3935 "r29 0x%08x r30 0x%08x r31 0x%08x\n" 3936 "sr0 0x%08x sr1 0x%08x sr2 0x%08x sar 0x%08x\n", 3937 frame.ts_gr1, frame.ts_gr2, frame.ts_gr3, frame.ts_gr4, 3938 frame.ts_gr5, frame.ts_gr6, frame.ts_gr7, frame.ts_gr8, 3939 frame.ts_gr9, frame.ts_gr10, frame.ts_gr11, frame.ts_gr12, 3940 frame.ts_gr13, frame.ts_gr14, frame.ts_gr15, frame.ts_gr16, 3941 frame.ts_gr17, frame.ts_gr18, frame.ts_gr19, frame.ts_gr20, 3942 frame.ts_gr21, frame.ts_gr22, frame.ts_gr23, frame.ts_gr24, 3943 frame.ts_gr25, frame.ts_gr26, frame.ts_gr27, frame.ts_gr28, 3944 frame.ts_gr29, frame.ts_gr30, frame.ts_gr31, 3945 frame.ts_sr0, frame.ts_sr1, frame.ts_sr2, frame.ts_sar); 3946 } 3947 break; 3948 case HPPA_FRAME_THREAD_STATE: { 3949 struct hp_pa_frame_thread_state frame; 3950 printf(" flavor HPPA_FRAME_THREAD_STATE\n"); 3951 if(count == HPPA_FRAME_THREAD_STATE_COUNT) 3952 printf(" count HPPA_FRAME_THREAD_STATE_COUNT\n"); 3953 else 3954 printf(" count %u (not HPPA_FRAME_THREAD_STATE_" 3955 "COUNT)\n", count); 3956 left = end - begin; 3957 if(left >= sizeof(struct hp_pa_frame_thread_state)){ 3958 memcpy((char *)&frame, begin, 3959 sizeof(struct hp_pa_frame_thread_state)); 3960 begin += sizeof(struct hp_pa_frame_thread_state); 3961 } 3962 else{ 3963 memset((char *)&frame, '\0', 3964 sizeof(struct hp_pa_frame_thread_state)); 3965 memcpy((char *)&frame, begin, left); 3966 begin += left; 3967 } 3968 if(swapped) 3969 swap_hppa_frame_thread_state(&frame, host_byte_sex); 3970 printf("pcsq_front 0x%08x pcsq_back 0x%08x\n" 3971 "pcoq_front 0x%08x pcoq_back 0x%08x\n" 3972 " psw 0x%08x\n", 3973 frame.ts_pcsq_front, frame.ts_pcsq_back, 3974 frame.ts_pcoq_front, frame.ts_pcoq_back, 3975 frame.ts_psw); 3976 break; 3977 } 3978 case HPPA_FP_THREAD_STATE: { 3979 struct hp_pa_fp_thread_state frame; 3980 printf(" flavor HPPA_FP_THREAD_STATE\n"); 3981 if(count == HPPA_FP_THREAD_STATE_COUNT) 3982 printf(" count HPPA_FP_THREAD_STATE_COUNT\n"); 3983 else 3984 printf(" count %u (not HPPA_FP_THREAD_STATE_" 3985 "COUNT)\n", count); 3986 left = end - begin; 3987 if(left >= sizeof(struct hp_pa_fp_thread_state)){ 3988 memcpy((char *)&frame, begin, 3989 sizeof(struct hp_pa_fp_thread_state)); 3990 begin += sizeof(struct hp_pa_fp_thread_state); 3991 } 3992 else{ 3993 memset((char *)&frame, '\0', 3994 sizeof(struct hp_pa_fp_thread_state)); 3995 memcpy((char *)&frame, begin, left); 3996 begin += left; 3997 } 3998 if(swapped) 3999 swap_hppa_fp_thread_state(&frame, host_byte_sex); 4000 printf("fp0 %f fp1 %f\nfp2 %f fp3 %f\n" 4001 "fp4 %f fp5 %f\nfp6 %f fp7 %f\n" 4002 "fp8 %f fp9 %f\nfp10 %f fp11 %f\n" 4003 "fp12 %f fp13 %f\nfp14 %f fp15 %f\n" 4004 "fp16 %f fp17 %f\nfp18 %f fp19 %f\n" 4005 "fp20 %f fp21 %f\nfp22 %f fp23 %f\n" 4006 "fp24 %f fp25 %f\nfp26 %f fp27 %f\n" 4007 "fp28 %f fp29 %f\nfp30 %f fp31 %f\n", 4008 frame.ts_fp0, frame.ts_fp1, frame.ts_fp2, frame.ts_fp3, 4009 frame.ts_fp4, frame.ts_fp5, frame.ts_fp6, frame.ts_fp7, 4010 frame.ts_fp8, frame.ts_fp9, frame.ts_fp10, frame.ts_fp11, 4011 frame.ts_fp12, frame.ts_fp13, frame.ts_fp14, frame.ts_fp15, 4012 frame.ts_fp16, frame.ts_fp17, frame.ts_fp18, frame.ts_fp19, 4013 frame.ts_fp20, frame.ts_fp21, frame.ts_fp22, frame.ts_fp23, 4014 frame.ts_fp24, frame.ts_fp25, frame.ts_fp26, frame.ts_fp27, 4015 frame.ts_fp28, frame.ts_fp29, frame.ts_fp30, frame.ts_fp31); 4016 break; 4017 } 4018 default: 4019 printf(" flavor %u (unknown)\n", flavor); 4020 printf(" count %u\n", count); 4021 printf(" state:\n"); 4022 print_unknown_state(begin, end, count, swapped); 4023 begin += count * sizeof(uint32_t); 4024 break; 4025 } 4026 } 4027 } 4028 else if(cputype == CPU_TYPE_SPARC){ 4029 while(begin < end){ 4030 if(end - begin > (ptrdiff_t)sizeof(uint32_t)){ 4031 memcpy((char *)&flavor, begin, sizeof(uint32_t)); 4032 begin += sizeof(uint32_t); 4033 } 4034 else{ 4035 flavor = 0; 4036 begin = end; 4037 } 4038 if(swapped) 4039 flavor = SWAP_INT(flavor); 4040 if(end - begin > (ptrdiff_t)sizeof(uint32_t)){ 4041 memcpy((char *)&count, begin, sizeof(uint32_t)); 4042 begin += sizeof(uint32_t); 4043 } 4044 else{ 4045 count = 0; 4046 begin = end; 4047 } 4048 if(swapped) 4049 count = SWAP_INT(count); 4050 4051 switch(flavor){ 4052 case SPARC_THREAD_STATE_REGS: 4053 { struct sparc_thread_state_regs cpu; 4054 printf(" flavor SPARC_THREAD_STATE_REGS\n"); 4055 if (count == SPARC_THREAD_STATE_REGS_COUNT) 4056 printf(" count SPARC_THREAD_STATE_REGS_COUNT\n"); 4057 else 4058 printf(" count %u (not SPARC_THREAD_STATE_REGS_COUNT)\n", 4059 count); 4060 left = begin - end; 4061 if (left >= sizeof(struct sparc_thread_state_regs)) { 4062 memcpy((char *) &cpu, begin, 4063 sizeof(struct sparc_thread_state_regs)); 4064 begin += sizeof(struct sparc_thread_state_regs); 4065 } else { 4066 memset((char *) &cpu, '\0', 4067 sizeof(struct sparc_thread_state_regs)); 4068 begin += left; 4069 } 4070 if (swapped) 4071 swap_sparc_thread_state_regs(&cpu, host_byte_sex); 4072 printf( 4073 "psr 0x%08x pc 0x%08x npc 0x%08x y 0x%08x\n" 4074 "g0 0x%08x g1 0x%08x g2 0x%08x g3 0x%08x\n" 4075 "g4 0x%08x g5 0x%08x g6 0x%08x g7 0x%08x\n" 4076 "o0 0x%08x o1 0x%08x o2 0x%08x o3 0x%08x\n" 4077 "o4 0x%08x o5 0x%08x o6 0x%08x o7 0x%08x\n", 4078 cpu.regs.r_psr, cpu.regs.r_pc, cpu.regs.r_npc, 4079 cpu.regs.r_y, 0, cpu.regs.r_g1, 4080 cpu.regs.r_g2, cpu.regs.r_g3, 4081 cpu.regs.r_g4, cpu.regs.r_g5, 4082 cpu.regs.r_g6, cpu.regs.r_g7, 4083 cpu.regs.r_o0, cpu.regs.r_o1, 4084 cpu.regs.r_o2, cpu.regs.r_o3, 4085 cpu.regs.r_o4, cpu.regs.r_o5, 4086 cpu.regs.r_o6, cpu.regs.r_o7); 4087 break; 4088 } 4089 case SPARC_THREAD_STATE_FPU: 4090 { struct sparc_thread_state_fpu fpu; 4091 4092 printf(" flavor SPARC_THREAD_STATE_FPU\n"); 4093 if (count == SPARC_THREAD_STATE_FPU_COUNT) 4094 printf(" count SPARC_THREAD_STATE_FPU_COUNT\n"); 4095 else 4096 printf(" count %u (not SPARC_THREAD_STATE_FPU_COUNT)\n", 4097 count); 4098 left = begin - end; 4099 if (left >= sizeof(struct sparc_thread_state_fpu)) { 4100 memcpy((char *) &fpu, begin, 4101 sizeof(struct sparc_thread_state_fpu)); 4102 begin += sizeof(struct sparc_thread_state_fpu); 4103 } else { 4104 memset((char *) &fpu, '\0', 4105 sizeof(struct sparc_thread_state_fpu)); 4106 begin += left; 4107 } 4108 if (swapped) 4109 swap_sparc_thread_state_fpu(&fpu, host_byte_sex); 4110 printf( 4111 "f0 0x%08x f1 0x%08x f2 0x%08x f3 0x%08x\n" 4112 "f4 0x%08x f5 0x%08x f6 0x%08x f7 0x%08x\n" 4113 "f8 0x%08x f9 0x%08x f10 0x%08x f11 0x%08x\n" 4114 "f12 0x%08x f13 0x%08x f14 0x%08x f15 0x%08x\n" 4115 "f16 0x%08x f17 0x%08x f18 0x%08x f19 0x%08x\n" 4116 "f20 0x%08x f21 0x%08x f22 0x%08x f23 0x%08x\n" 4117 "f24 0x%08x f25 0x%08x f26 0x%08x f27 0x%08x\n" 4118 "f28 0x%08x f29 0x%08x f30 0x%08x f31 0x%08x\n" 4119 "fsr 0x%08x\n", 4120 fpu.fpu.fpu_fr.Fpu_regs[0], fpu.fpu.fpu_fr.Fpu_regs[1], 4121 fpu.fpu.fpu_fr.Fpu_regs[2], fpu.fpu.fpu_fr.Fpu_regs[3], 4122 fpu.fpu.fpu_fr.Fpu_regs[4], fpu.fpu.fpu_fr.Fpu_regs[5], 4123 fpu.fpu.fpu_fr.Fpu_regs[6], fpu.fpu.fpu_fr.Fpu_regs[7], 4124 fpu.fpu.fpu_fr.Fpu_regs[8], fpu.fpu.fpu_fr.Fpu_regs[9], 4125 fpu.fpu.fpu_fr.Fpu_regs[10], fpu.fpu.fpu_fr.Fpu_regs[11], 4126 fpu.fpu.fpu_fr.Fpu_regs[12], fpu.fpu.fpu_fr.Fpu_regs[13], 4127 fpu.fpu.fpu_fr.Fpu_regs[14], fpu.fpu.fpu_fr.Fpu_regs[15], 4128 fpu.fpu.fpu_fr.Fpu_regs[16], fpu.fpu.fpu_fr.Fpu_regs[17], 4129 fpu.fpu.fpu_fr.Fpu_regs[18], fpu.fpu.fpu_fr.Fpu_regs[19], 4130 fpu.fpu.fpu_fr.Fpu_regs[20], fpu.fpu.fpu_fr.Fpu_regs[21], 4131 fpu.fpu.fpu_fr.Fpu_regs[22], fpu.fpu.fpu_fr.Fpu_regs[23], 4132 fpu.fpu.fpu_fr.Fpu_regs[24], fpu.fpu.fpu_fr.Fpu_regs[25], 4133 fpu.fpu.fpu_fr.Fpu_regs[26], fpu.fpu.fpu_fr.Fpu_regs[27], 4134 fpu.fpu.fpu_fr.Fpu_regs[28], fpu.fpu.fpu_fr.Fpu_regs[29], 4135 fpu.fpu.fpu_fr.Fpu_regs[30], fpu.fpu.fpu_fr.Fpu_regs[31], 4136 fpu.fpu.Fpu_fsr); 4137 break; 4138 } 4139 default: 4140 printf(" flavor %u (unknown)\n", flavor); 4141 printf(" count %u\n", count); 4142 printf(" state:\n"); 4143 print_unknown_state(begin, end, count, swapped); 4144 begin += count * sizeof(uint32_t); 4145 break; 4146 } 4147 } 4148 } 4149 else if(cputype == CPU_TYPE_POWERPC || 4150 cputype == CPU_TYPE_POWERPC64 || 4151 cputype == CPU_TYPE_VEO){ 4152 ppc_thread_state_t cpu; 4153 ppc_thread_state64_t cpu64; 4154 ppc_float_state_t fpu; 4155 ppc_exception_state_t except; 4156 4157 while(begin < end){ 4158 if(end - begin > (ptrdiff_t)sizeof(uint32_t)){ 4159 memcpy((char *)&flavor, begin, sizeof(uint32_t)); 4160 begin += sizeof(uint32_t); 4161 } 4162 else{ 4163 flavor = 0; 4164 begin = end; 4165 } 4166 if(swapped) 4167 flavor = SWAP_INT(flavor); 4168 if(end - begin > (ptrdiff_t)sizeof(uint32_t)){ 4169 memcpy((char *)&count, begin, sizeof(uint32_t)); 4170 begin += sizeof(uint32_t); 4171 } 4172 else{ 4173 count = 0; 4174 begin = end; 4175 } 4176 if(swapped) 4177 count = SWAP_INT(count); 4178 4179 switch(flavor){ 4180 case PPC_THREAD_STATE: 4181 printf(" flavor PPC_THREAD_STATE\n"); 4182 if(count == PPC_THREAD_STATE_COUNT) 4183 printf(" count PPC_THREAD_STATE_COUNT\n"); 4184 else 4185 printf(" count %u (not PPC_THREAD_STATE_" 4186 "COUNT)\n", count); 4187 left = end - begin; 4188 if(left >= sizeof(ppc_thread_state_t)){ 4189 memcpy((char *)&cpu, begin, 4190 sizeof(ppc_thread_state_t)); 4191 begin += sizeof(ppc_thread_state_t); 4192 } 4193 else{ 4194 memset((char *)&cpu, '\0', 4195 sizeof(ppc_thread_state_t)); 4196 memcpy((char *)&cpu, begin, left); 4197 begin += left; 4198 } 4199 if(swapped) 4200 swap_ppc_thread_state_t(&cpu, host_byte_sex); 4201 printf(" r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x " 4202 "r4 0x%08x\n" 4203 " r5 0x%08x r6 0x%08x r7 0x%08x r8 0x%08x " 4204 "r9 0x%08x\n" 4205 " r10 0x%08x r11 0x%08x r12 0x%08x r13 0x%08x " 4206 "r14 0x%08x\n" 4207 " r15 0x%08x r16 0x%08x r17 0x%08x r18 0x%08x " 4208 "r19 0x%08x\n" 4209 " r20 0x%08x r21 0x%08x r22 0x%08x r23 0x%08x " 4210 "r24 0x%08x\n" 4211 " r25 0x%08x r26 0x%08x r27 0x%08x r28 0x%08x " 4212 "r29 0x%08x\n" 4213 " r30 0x%08x r31 0x%08x cr 0x%08x xer 0x%08x " 4214 "lr 0x%08x\n" 4215 " ctr 0x%08x mq 0x%08x vrsave 0x%08x srr0 0x%08x" 4216 " srr1 0x%08x\n", 4217 cpu.r0, cpu.r1, cpu.r2, cpu.r3, cpu.r4, cpu.r5, 4218 cpu.r6, cpu.r7, cpu.r8, cpu.r9, cpu.r10, cpu.r11, 4219 cpu.r12, cpu.r13, cpu.r14, cpu.r15, cpu.r16, cpu.r17, 4220 cpu.r18, cpu.r19, cpu.r20, cpu.r21, cpu.r22, cpu.r23, 4221 cpu.r24, cpu.r25, cpu.r26, cpu.r27, cpu.r28, cpu.r29, 4222 cpu.r30, cpu.r31, cpu.cr, cpu.xer, cpu.lr, cpu.ctr, 4223 cpu.mq, cpu.vrsave, cpu.srr0, cpu.srr1); 4224 break; 4225 case PPC_FLOAT_STATE: 4226 printf(" flavor PPC_FLOAT_STATE\n"); 4227 if(count == PPC_FLOAT_STATE_COUNT) 4228 printf(" count PPC_FLOAT_STATE_COUNT\n"); 4229 else 4230 printf(" count %u (not PPC_FLOAT_STATE_" 4231 "COUNT)\n", count); 4232 left = end - begin; 4233 if(left >= sizeof(ppc_float_state_t)){ 4234 memcpy((char *)&fpu, begin, 4235 sizeof(ppc_float_state_t)); 4236 begin += sizeof(ppc_float_state_t); 4237 } 4238 else{ 4239 memset((char *)&fpu, '\0', 4240 sizeof(ppc_float_state_t)); 4241 memcpy((char *)&fpu, begin, left); 4242 begin += left; 4243 } 4244 if(swapped) 4245 swap_ppc_float_state_t(&fpu, host_byte_sex); 4246 printf(" f0 %f f1 %f\n f2 %f f3 %f\n" 4247 " f4 %f f5 %f\n f6 %f f7 %f\n" 4248 " f8 %f f9 %f\n f10 %f f11 %f\n" 4249 " f12 %f f13 %f\n f14 %f f15 %f\n" 4250 " f16 %f f17 %f\n f18 %f f19 %f\n" 4251 " f20 %f f21 %f\n f22 %f f23 %f\n" 4252 " f24 %f f25 %f\n f26 %f f27 %f\n" 4253 " f28 %f f29 %f\n f30 %f f31 %f\n", 4254 fpu.fpregs[0], fpu.fpregs[1], fpu.fpregs[2], 4255 fpu.fpregs[3], fpu.fpregs[4], fpu.fpregs[5], 4256 fpu.fpregs[6], fpu.fpregs[7], fpu.fpregs[8], 4257 fpu.fpregs[9], fpu.fpregs[10], fpu.fpregs[11], 4258 fpu.fpregs[12], fpu.fpregs[13], fpu.fpregs[14], 4259 fpu.fpregs[15], fpu.fpregs[16], fpu.fpregs[17], 4260 fpu.fpregs[18], fpu.fpregs[19], fpu.fpregs[20], 4261 fpu.fpregs[21], fpu.fpregs[22], fpu.fpregs[23], 4262 fpu.fpregs[24], fpu.fpregs[25], fpu.fpregs[26], 4263 fpu.fpregs[27], fpu.fpregs[28], fpu.fpregs[29], 4264 fpu.fpregs[30], fpu.fpregs[31]); 4265 printf(" fpscr_pad 0x%x fpscr 0x%x\n", fpu.fpscr_pad, 4266 fpu.fpscr); 4267 break; 4268 case PPC_EXCEPTION_STATE: 4269 printf(" flavor PPC_EXCEPTION_STATE\n"); 4270 if(count == PPC_EXCEPTION_STATE_COUNT) 4271 printf(" count PPC_EXCEPTION_STATE_COUNT\n"); 4272 else 4273 printf(" count %u (not PPC_EXCEPTION_STATE_COUNT" 4274 ")\n", count); 4275 left = end - begin; 4276 if(left >= sizeof(ppc_exception_state_t)){ 4277 memcpy((char *)&except, begin, 4278 sizeof(ppc_exception_state_t)); 4279 begin += sizeof(ppc_exception_state_t); 4280 } 4281 else{ 4282 memset((char *)&except, '\0', 4283 sizeof(ppc_exception_state_t)); 4284 memcpy((char *)&except, begin, left); 4285 begin += left; 4286 } 4287 if(swapped) 4288 swap_ppc_exception_state_t(&except, host_byte_sex); 4289 printf(" dar 0x%x dsisr 0x%x exception 0x%x pad0 " 4290 "0x%x\n", (unsigned int)except.dar, 4291 (unsigned int)except.dsisr, 4292 (unsigned int)except.exception, 4293 (unsigned int)except.pad0); 4294 printf(" pad1[0] 0x%x pad1[1] 0x%x pad1[2] " 4295 "0x%x pad1[3] 0x%x\n", (unsigned int)except.pad1[0], 4296 (unsigned int)except.pad1[0], 4297 (unsigned int)except.pad1[0], 4298 (unsigned int)except.pad1[0]); 4299 break; 4300 case PPC_THREAD_STATE64: 4301 printf(" flavor PPC_THREAD_STATE64\n"); 4302 if(count == PPC_THREAD_STATE64_COUNT) 4303 printf(" count PPC_THREAD_STATE64_COUNT\n"); 4304 else 4305 printf(" count %u (not PPC_THREAD_STATE64_" 4306 "COUNT)\n", count); 4307 left = end - begin; 4308 if(left >= sizeof(ppc_thread_state64_t)){ 4309 memcpy((char *)&cpu64, begin, 4310 sizeof(ppc_thread_state64_t)); 4311 begin += sizeof(ppc_thread_state64_t); 4312 } 4313 else{ 4314 memset((char *)&cpu64, '\0', 4315 sizeof(ppc_thread_state64_t)); 4316 memcpy((char *)&cpu64, begin, left); 4317 begin += left; 4318 } 4319 if(swapped) 4320 swap_ppc_thread_state64_t(&cpu64, host_byte_sex); 4321 printf(" r0 0x%016llx r1 0x%016llx r2 0x%016llx\n" 4322 " r3 0x%016llx r4 0x%016llx r5 0x%016llx\n" 4323 " r6 0x%016llx r7 0x%016llx r8 0x%016llx\n" 4324 " r9 0x%016llx r10 0x%016llx r11 0x%016llx\n" 4325 " r12 0x%016llx r13 0x%016llx r14 0x%016llx\n" 4326 " r15 0x%016llx r16 0x%016llx r17 0x%016llx\n" 4327 " r18 0x%016llx r19 0x%016llx r20 0x%016llx\n" 4328 " r21 0x%016llx r22 0x%016llx r23 0x%016llx\n" 4329 " r24 0x%016llx r25 0x%016llx r26 0x%016llx\n" 4330 " r27 0x%016llx r28 0x%016llx r29 0x%016llx\n" 4331 " r30 0x%016llx r31 0x%016llx cr 0x%08x\n" 4332 " xer 0x%016llx lr 0x%016llx ctr 0x%016llx\n" 4333 "vrsave 0x%08x srr0 0x%016llx srr1 " 4334 "0x%016llx\n", 4335 cpu64.r0, cpu64.r1, cpu64.r2, cpu64.r3, cpu64.r4, 4336 cpu64.r5, cpu64.r6, cpu64.r7, cpu64.r8, cpu64.r9, 4337 cpu64.r10, cpu64.r11, cpu64.r12, cpu64.r13,cpu64.r14, 4338 cpu64.r15, cpu64.r16, cpu64.r17, cpu64.r18,cpu64.r19, 4339 cpu64.r20, cpu64.r21, cpu64.r22, cpu64.r23,cpu64.r24, 4340 cpu64.r25, cpu64.r26, cpu64.r27, cpu64.r28,cpu64.r29, 4341 cpu64.r30, cpu64.r31, cpu64.cr, cpu64.xer, cpu64.lr, 4342 cpu64.ctr, cpu64.vrsave, cpu64.srr0, cpu64.srr1); 4343 break; 4344 default: 4345 printf(" flavor %u (unknown)\n", flavor); 4346 printf(" count %u\n", count); 4347 printf(" state:\n"); 4348 print_unknown_state(begin, end, count, swapped); 4349 begin += count * sizeof(uint32_t); 4350 break; 4351 } 4352 } 4353 } 4354 else if(cputype == CPU_TYPE_MC88000){ 4355 m88k_thread_state_grf_t cpu; 4356 m88k_thread_state_xrf_t fpu; 4357 m88k_thread_state_user_t user; 4358 m88110_thread_state_impl_t spu; 4359 4360 while(begin < end){ 4361 if(end - begin > (ptrdiff_t)sizeof(uint32_t)){ 4362 memcpy((char *)&flavor, begin, sizeof(uint32_t)); 4363 begin += sizeof(uint32_t); 4364 } 4365 else{ 4366 flavor = 0; 4367 begin = end; 4368 } 4369 if(swapped) 4370 flavor = SWAP_INT(flavor); 4371 if(end - begin > (ptrdiff_t)sizeof(uint32_t)){ 4372 memcpy((char *)&count, begin, sizeof(uint32_t)); 4373 begin += sizeof(uint32_t); 4374 } 4375 else{ 4376 count = 0; 4377 begin = end; 4378 } 4379 if(swapped) 4380 count = SWAP_INT(count); 4381 4382 switch(flavor){ 4383 case M88K_THREAD_STATE_GRF: 4384 printf(" flavor M88K_THREAD_STATE_GRF\n"); 4385 if(count == M88K_THREAD_STATE_GRF_COUNT) 4386 printf(" count M88K_THREAD_STATE_GRF_COUNT\n"); 4387 else 4388 printf(" count %u (not M88K_THREAD_STATE_GRF_" 4389 "COUNT)\n", count); 4390 left = end - begin; 4391 if(left >= sizeof(m88k_thread_state_grf_t)){ 4392 memcpy((char *)&cpu, begin, 4393 sizeof(m88k_thread_state_grf_t)); 4394 begin += sizeof(m88k_thread_state_grf_t); 4395 } 4396 else{ 4397 memset((char *)&cpu, '\0', 4398 sizeof(m88k_thread_state_grf_t)); 4399 memcpy((char *)&cpu, begin, left); 4400 begin += left; 4401 } 4402 if(swapped) 4403 swap_m88k_thread_state_grf_t(&cpu, host_byte_sex); 4404 printf(" r1 0x%08x r2 0x%08x r3 0x%08x r4 0x%08x " 4405 "r5 0x%08x\n" 4406 " r6 0x%08x r7 0x%08x r8 0x%08x r9 0x%08x " 4407 "r10 0x%08x\n" 4408 " r11 0x%08x r12 0x%08x r13 0x%08x r14 0x%08x " 4409 "r15 0x%08x\n" 4410 " r16 0x%08x r17 0x%08x r18 0x%08x r19 0x%08x " 4411 "r20 0x%08x\n" 4412 " r21 0x%08x r22 0x%08x r23 0x%08x r24 0x%08x " 4413 "r25 0x%08x\n" 4414 " r26 0x%08x r27 0x%08x r28 0x%08x r29 0x%08x " 4415 "r30 0x%08x\n" 4416 " r31 0x%08x xip 0x%08x xip_in_bd 0x%08x nip " 4417 "0x%08x\n", 4418 cpu.r1, cpu.r2, cpu.r3, cpu.r4, cpu.r5, 4419 cpu.r6, cpu.r7, cpu.r8, cpu.r9, cpu.r10, 4420 cpu.r11, cpu.r12, cpu.r13, cpu.r14, cpu.r15, 4421 cpu.r16, cpu.r17, cpu.r18, cpu.r19, cpu.r20, 4422 cpu.r21, cpu.r22, cpu.r23, cpu.r24, cpu.r25, 4423 cpu.r26, cpu.r27, cpu.r28, cpu.r29, cpu.r30, 4424 cpu.r31, cpu.xip, cpu.xip_in_bd, cpu.nip); 4425 break; 4426 case M88K_THREAD_STATE_XRF: 4427 printf(" flavor M88K_THREAD_STATE_XRF\n"); 4428 if(count == M88K_THREAD_STATE_XRF_COUNT) 4429 printf(" count M88K_THREAD_STATE_XRF_COUNT\n"); 4430 else 4431 printf(" count %u (not M88K_THREAD_STATE_XRF_" 4432 "COUNT)\n", count); 4433 left = end - begin; 4434 if(left >= sizeof(m88k_thread_state_xrf_t)){ 4435 memcpy((char *)&fpu, begin, 4436 sizeof(m88k_thread_state_xrf_t)); 4437 begin += sizeof(m88k_thread_state_xrf_t); 4438 } 4439 else{ 4440 memset((char *)&fpu, '\0', 4441 sizeof(m88k_thread_state_xrf_t)); 4442 memcpy((char *)&fpu, begin, left); 4443 begin += left; 4444 } 4445 if(swapped) 4446 swap_m88k_thread_state_xrf_t(&fpu, host_byte_sex); 4447 printf(" x1 0x%08x 0x%08x 0x%08x 0x%08x\n" 4448 " x2 0x%08x 0x%08x 0x%08x 0x%08x\n" 4449 " x3 0x%08x 0x%08x 0x%08x 0x%08x\n" 4450 " x4 0x%08x 0x%08x 0x%08x 0x%08x\n" 4451 " x5 0x%08x 0x%08x 0x%08x 0x%08x\n" 4452 " x6 0x%08x 0x%08x 0x%08x 0x%08x\n" 4453 " x7 0x%08x 0x%08x 0x%08x 0x%08x\n" 4454 " x8 0x%08x 0x%08x 0x%08x 0x%08x\n" 4455 " x9 0x%08x 0x%08x 0x%08x 0x%08x\n" 4456 " x10 0x%08x 0x%08x 0x%08x 0x%08x\n" 4457 " x11 0x%08x 0x%08x 0x%08x 0x%08x\n" 4458 " x12 0x%08x 0x%08x 0x%08x 0x%08x\n" 4459 " x13 0x%08x 0x%08x 0x%08x 0x%08x\n" 4460 " x14 0x%08x 0x%08x 0x%08x 0x%08x\n" 4461 " x15 0x%08x 0x%08x 0x%08x 0x%08x\n" 4462 " x16 0x%08x 0x%08x 0x%08x 0x%08x\n" 4463 " x17 0x%08x 0x%08x 0x%08x 0x%08x\n" 4464 " x18 0x%08x 0x%08x 0x%08x 0x%08x\n" 4465 " x19 0x%08x 0x%08x 0x%08x 0x%08x\n" 4466 " x20 0x%08x 0x%08x 0x%08x 0x%08x\n" 4467 " x21 0x%08x 0x%08x 0x%08x 0x%08x\n" 4468 " x22 0x%08x 0x%08x 0x%08x 0x%08x\n" 4469 " x23 0x%08x 0x%08x 0x%08x 0x%08x\n" 4470 " x24 0x%08x 0x%08x 0x%08x 0x%08x\n" 4471 " x25 0x%08x 0x%08x 0x%08x 0x%08x\n" 4472 " x26 0x%08x 0x%08x 0x%08x 0x%08x\n" 4473 " x27 0x%08x 0x%08x 0x%08x 0x%08x\n" 4474 " x28 0x%08x 0x%08x 0x%08x 0x%08x\n" 4475 " x29 0x%08x 0x%08x 0x%08x 0x%08x\n" 4476 " x30 0x%08x 0x%08x 0x%08x 0x%08x\n" 4477 " x31 0x%08x 0x%08x 0x%08x 0x%08x\n", 4478 fpu.x1.x[0],fpu.x1.x[1],fpu.x1.x[2],fpu.x1.x[3], 4479 fpu.x2.x[0],fpu.x2.x[1],fpu.x2.x[2],fpu.x2.x[3], 4480 fpu.x3.x[0],fpu.x3.x[1],fpu.x3.x[2],fpu.x3.x[3], 4481 fpu.x4.x[0],fpu.x4.x[1],fpu.x4.x[2],fpu.x4.x[3], 4482 fpu.x5.x[0],fpu.x5.x[1],fpu.x5.x[2],fpu.x5.x[3], 4483 fpu.x6.x[0],fpu.x6.x[1],fpu.x6.x[2],fpu.x6.x[3], 4484 fpu.x7.x[0],fpu.x7.x[1],fpu.x7.x[2],fpu.x7.x[3], 4485 fpu.x8.x[0],fpu.x8.x[1],fpu.x8.x[2],fpu.x8.x[3], 4486 fpu.x9.x[0],fpu.x9.x[1],fpu.x9.x[2],fpu.x9.x[3], 4487 fpu.x10.x[0],fpu.x10.x[1],fpu.x10.x[2],fpu.x10.x[3], 4488 fpu.x11.x[0],fpu.x11.x[1],fpu.x11.x[2],fpu.x11.x[3], 4489 fpu.x12.x[0],fpu.x12.x[1],fpu.x12.x[2],fpu.x12.x[3], 4490 fpu.x13.x[0],fpu.x13.x[1],fpu.x13.x[2],fpu.x13.x[3], 4491 fpu.x14.x[0],fpu.x14.x[1],fpu.x14.x[2],fpu.x14.x[3], 4492 fpu.x15.x[0],fpu.x15.x[1],fpu.x15.x[2],fpu.x15.x[3], 4493 fpu.x16.x[0],fpu.x16.x[1],fpu.x16.x[2],fpu.x16.x[3], 4494 fpu.x17.x[0],fpu.x17.x[1],fpu.x17.x[2],fpu.x17.x[3], 4495 fpu.x18.x[0],fpu.x18.x[1],fpu.x18.x[2],fpu.x18.x[3], 4496 fpu.x19.x[0],fpu.x19.x[1],fpu.x19.x[2],fpu.x19.x[3], 4497 fpu.x20.x[0],fpu.x20.x[1],fpu.x20.x[2],fpu.x20.x[3], 4498 fpu.x21.x[0],fpu.x21.x[1],fpu.x21.x[2],fpu.x21.x[3], 4499 fpu.x22.x[0],fpu.x22.x[1],fpu.x22.x[2],fpu.x22.x[3], 4500 fpu.x23.x[0],fpu.x23.x[1],fpu.x23.x[2],fpu.x23.x[3], 4501 fpu.x24.x[0],fpu.x24.x[1],fpu.x24.x[2],fpu.x24.x[3], 4502 fpu.x25.x[0],fpu.x25.x[1],fpu.x25.x[2],fpu.x25.x[3], 4503 fpu.x26.x[0],fpu.x26.x[1],fpu.x26.x[2],fpu.x26.x[3], 4504 fpu.x27.x[0],fpu.x27.x[1],fpu.x27.x[2],fpu.x27.x[3], 4505 fpu.x28.x[0],fpu.x28.x[1],fpu.x28.x[2],fpu.x28.x[3], 4506 fpu.x29.x[0],fpu.x29.x[1],fpu.x29.x[2],fpu.x29.x[3], 4507 fpu.x30.x[0],fpu.x30.x[1],fpu.x30.x[2],fpu.x30.x[3], 4508 fpu.x31.x[0],fpu.x31.x[1],fpu.x31.x[2],fpu.x31.x[3]); 4509 printf(" fpsr xmod %d afinv %d afdvz %d afunf %d " 4510 "afovf %d afinx %d\n", fpu.fpsr.xmod, fpu.fpsr.afinv, 4511 fpu.fpsr.afdvz, fpu.fpsr.afunf, 4512 fpu.fpsr.afovf, fpu.fpsr.afinx); 4513 printf(" fpcr rm "); 4514 switch(fpu.fpcr.rm){ 4515 case M88K_RM_NEAREST: 4516 printf("RM_NEAREST "); 4517 break; 4518 case M88K_RM_ZERO: 4519 printf("RM_ZERO "); 4520 break; 4521 case M88K_RM_NEGINF: 4522 printf("RM_NEGINF "); 4523 break; 4524 case M88K_RM_POSINF: 4525 printf("RM_POSINF "); 4526 break; 4527 } 4528 printf("efinv %d efdvz %d efunf %d efovf %d efinx %d\n", 4529 fpu.fpcr.efinv, fpu.fpcr.efdvz, fpu.fpcr.efunf, 4530 fpu.fpcr.efovf, fpu.fpcr.efinx); 4531 break; 4532 case M88K_THREAD_STATE_USER: 4533 printf(" flavor M88K_THREAD_STATE_USER\n"); 4534 if(count == M88K_THREAD_STATE_USER_COUNT) 4535 printf(" count M88K_THREAD_STATE_USER_COUNT\n"); 4536 else 4537 printf(" count %u (not M88K_THREAD_STATE_USER_" 4538 "COUNT)\n", count); 4539 left = end - begin; 4540 if(left >= sizeof(m88k_thread_state_user_t)){ 4541 memcpy((char *)&user, begin, 4542 sizeof(m88k_thread_state_user_t)); 4543 begin += sizeof(m88k_thread_state_user_t); 4544 } 4545 else{ 4546 memset((char *)&user, '\0', 4547 sizeof(m88k_thread_state_user_t)); 4548 memcpy((char *)&user, begin, left); 4549 begin += left; 4550 } 4551 if(swapped) 4552 swap_m88k_thread_state_user_t(&user, host_byte_sex); 4553 printf(" user 0x%08x\n", (unsigned int)user.user); 4554 break; 4555 4556 case M88110_THREAD_STATE_IMPL: 4557 printf(" flavor M88110_THREAD_STATE_IMPL\n"); 4558 if(count == M88110_THREAD_STATE_IMPL_COUNT) 4559 printf(" count M88110_THREAD_STATE_IMPL_COUNT\n"); 4560 else 4561 printf(" count %u (not M88110_THREAD_STATE_IMPL_" 4562 "COUNT)\n", count); 4563 left = end - begin; 4564 if(left >= sizeof(m88110_thread_state_impl_t)){ 4565 memcpy((char *)&spu, begin, 4566 sizeof(m88110_thread_state_impl_t)); 4567 begin += sizeof(m88110_thread_state_impl_t); 4568 } 4569 else{ 4570 memset((char *)&spu, '\0', 4571 sizeof(m88110_thread_state_impl_t)); 4572 memcpy((char *)&spu, begin, left); 4573 begin += left; 4574 } 4575 if(swapped) 4576 swap_m88110_thread_state_impl_t(&spu, host_byte_sex); 4577 for(j = 0; j < M88110_N_DATA_BP; j++){ 4578 printf(" data_bp[%u] addr 0x%08x\n", 4579 j, (unsigned int)spu.data_bp[i].addr); 4580 printf(" cntl rw %d rwm %d " 4581 "addr_match ", spu.data_bp[j].ctrl.rw, 4582 spu.data_bp[j].ctrl.rwm); 4583 switch(spu.data_bp[j].ctrl.addr_match){ 4584 case M88110_MATCH_BYTE: 4585 printf("MATCH_BYTE "); 4586 break; 4587 case M88110_MATCH_SHORT: 4588 printf("MATCH_SHORT "); 4589 break; 4590 case M88110_MATCH_WORD: 4591 printf("MATCH_WORD "); 4592 break; 4593 case M88110_MATCH_DOUBLE: 4594 printf("MATCH_DOUBLE "); 4595 break; 4596 case M88110_MATCH_QUAD: 4597 printf("MATCH_QUAD "); 4598 break; 4599 case M88110_MATCH_32: 4600 printf("MATCH_32 "); 4601 break; 4602 case M88110_MATCH_64: 4603 printf("MATCH_64 "); 4604 break; 4605 case M88110_MATCH_128: 4606 printf("MATCH_128 "); 4607 break; 4608 case M88110_MATCH_256: 4609 printf("MATCH_256 "); 4610 break; 4611 case M88110_MATCH_512: 4612 printf("MATCH_512 "); 4613 break; 4614 case M88110_MATCH_1024: 4615 printf("MATCH_1024 "); 4616 break; 4617 case M88110_MATCH_2048: 4618 printf("MATCH_2048 "); 4619 break; 4620 case M88110_MATCH_4096: 4621 printf("MATCH_4096 "); 4622 break; 4623 default: 4624 printf("%d (?)", spu.data_bp[j].ctrl.addr_match); 4625 break; 4626 } 4627 printf("v %d\n", spu.data_bp[j].ctrl.v); 4628 } 4629 printf(" psr le %d se %d c %d sgn_imd %d sm %d " 4630 "sfu1dis %d mxm_dis %d\n" , spu.psr.le, spu.psr.se, 4631 spu.psr.c, spu.psr.sgn_imd, spu.psr.sm, 4632 spu.psr.sfu1dis, spu.psr.mxm_dis); 4633 break; 4634 4635 default: 4636 printf(" flavor %u (unknown)\n", flavor); 4637 printf(" count %u\n", count); 4638 printf(" state:\n"); 4639 print_unknown_state(begin, end, count, swapped); 4640 begin += count * sizeof(uint32_t); 4641 break; 4642 } 4643 } 4644 } 4645 else if(cputype == CPU_TYPE_I860){ 4646 struct i860_thread_state_regs cpu; 4647 4648 while(begin < end){ 4649 if(end - begin > (ptrdiff_t)sizeof(uint32_t)){ 4650 memcpy((char *)&flavor, begin, sizeof(uint32_t)); 4651 begin += sizeof(uint32_t); 4652 } 4653 else{ 4654 flavor = 0; 4655 begin = end; 4656 } 4657 if(swapped) 4658 flavor = SWAP_INT(flavor); 4659 if(end - begin > (ptrdiff_t)sizeof(uint32_t)){ 4660 memcpy((char *)&count, begin, sizeof(uint32_t)); 4661 begin += sizeof(uint32_t); 4662 } 4663 else{ 4664 count = 0; 4665 begin = end; 4666 } 4667 if(swapped) 4668 count = SWAP_INT(count); 4669 4670 switch(flavor){ 4671 case I860_THREAD_STATE_REGS: 4672 printf(" flavor I860_THREAD_STATE_REGS\n"); 4673 if(count == I860_THREAD_STATE_REGS_COUNT) 4674 printf(" count I860_THREAD_STATE_REGS_COUNT\n"); 4675 else 4676 printf(" count %u (not I860_THREAD_STATE_REGS_" 4677 "COUNT)\n", count); 4678 left = end - begin; 4679 if(left >= sizeof(struct i860_thread_state_regs)){ 4680 memcpy((char *)&cpu, begin, 4681 sizeof(struct i860_thread_state_regs)); 4682 begin += sizeof(struct i860_thread_state_regs); 4683 } 4684 else{ 4685 memset((char *)&cpu, '\0', 4686 sizeof(struct i860_thread_state_regs)); 4687 memcpy((char *)&cpu, begin, left); 4688 begin += left; 4689 } 4690 if(swapped) 4691 swap_i860_thread_state_regs(&cpu, host_byte_sex); 4692 printf(" iregs\n"); 4693 for(j = 0 ; j < 31 ; j += k){ 4694 for(k = 0 ; k < 5 && j + k < 31 ; k++) 4695 printf(" i%-2u 0x%08x", j + k, 4696 (unsigned int)cpu.ireg[j + k]); 4697 printf("\n"); 4698 } 4699 printf(" fregs\n"); 4700 for(j = 0 ; j < 30 ; j += k){ 4701 for(k = 0 ; k < 5 && j + k < 30 ; k++) 4702 printf(" f%-2u 0x%08x", j + k, 4703 (unsigned int)cpu.freg[j + k]); 4704 printf("\n"); 4705 } 4706 printf(" psr 0x%08x epsr 0x%08x db 0x%08x pc 0x%08x\n", 4707 (unsigned int)cpu.psr, (unsigned int)cpu.epsr, 4708 (unsigned int)cpu.db, (unsigned int)cpu.pc); 4709 printf(" Mres3 %e Ares3 %e\n", cpu.Mres3, cpu.Ares3); 4710 printf(" Mres2 %e Ares2 %e\n", cpu.Mres2, cpu.Ares2); 4711 printf(" Mres1 %e Ares1 %e\n", cpu.Mres1, cpu.Ares1); 4712 printf(" Ires1 %e\n", cpu.Ires1); 4713 printf(" Lres3m %e Lres2m %e Lres1m %e\n", cpu.Lres3m, 4714 cpu.Lres2m, cpu.Lres1m); 4715 printf(" KR %e KI %e T %e\n", cpu.KR, cpu.KI, cpu.T); 4716 printf(" Fsr3 0x%08x Fsr2 0x%08x Fsr1 0x%08x\n", 4717 (unsigned int)cpu.Fsr3, (unsigned int)cpu.Fsr2, 4718 (unsigned int)cpu.Fsr1); 4719 printf(" Mergelo32 0x%08x Mergehi32 0x%08x\n", 4720 (unsigned int)cpu.Mergelo32, 4721 (unsigned int)cpu.Mergehi32); 4722 break; 4723 4724 default: 4725 printf(" flavor %u (unknown)\n", flavor); 4726 printf(" count %u\n", count); 4727 printf(" state:\n"); 4728 print_unknown_state(begin, end, count, swapped); 4729 begin += count * sizeof(uint32_t); 4730 break; 4731 } 4732 } 4733 } 4734 else if(cputype == CPU_TYPE_I386 || 4735 cputype == CPU_TYPE_X86_64){ 4736 i386_thread_state_t cpu; 4737/* current i386 thread states */ 4738#if i386_THREAD_STATE == 1 4739#ifndef i386_EXCEPTION_STATE_COUNT 4740 char *fpu; 4741 uint32_t fpu_size; 4742#else /* defined(i386_EXCEPTION_STATE_COUNT) */ 4743 i386_float_state_t fpu; 4744#endif /* defined(i386_EXCEPTION_STATE_COUNT) */ 4745 i386_exception_state_t exc; 4746 uint32_t f, g; 4747 4748#ifdef x86_THREAD_STATE64 4749 x86_thread_state64_t cpu64; 4750 x86_float_state64_t fpu64; 4751 x86_exception_state64_t exc64; 4752 x86_debug_state64_t debug64; 4753 x86_debug_state32_t debug; 4754 struct x86_thread_state ts; 4755 struct x86_float_state fs; 4756 struct x86_exception_state es; 4757 struct x86_debug_state ds; 4758#endif /* x86_THREAD_STATE64 */ 4759 4760#endif /* i386_THREAD_STATE == 1 */ 4761 4762/* i386 thread states on older releases */ 4763#if i386_THREAD_STATE == -1 4764 i386_thread_fpstate_t fpu; 4765 i386_thread_exceptstate_t exc; 4766 i386_thread_cthreadstate_t user; 4767 const char *tags[] = { "VALID", "ZERO", "SPEC", "EMPTY" }; 4768#endif /* i386_THREAD_STATE == -1 */ 4769 4770 while(begin < end){ 4771 if(end - begin > (ptrdiff_t)sizeof(uint32_t)){ 4772 memcpy((char *)&flavor, begin, sizeof(uint32_t)); 4773 begin += sizeof(uint32_t); 4774 } 4775 else{ 4776 flavor = 0; 4777 begin = end; 4778 } 4779 if(swapped) 4780 flavor = SWAP_INT(flavor); 4781 if(end - begin > (ptrdiff_t)sizeof(uint32_t)){ 4782 memcpy((char *)&count, begin, sizeof(uint32_t)); 4783 begin += sizeof(uint32_t); 4784 } 4785 else{ 4786 count = 0; 4787 begin = end; 4788 } 4789 if(swapped) 4790 count = SWAP_INT(count); 4791 4792 switch(flavor){ 4793 case i386_THREAD_STATE: 4794 printf(" flavor i386_THREAD_STATE\n"); 4795 if(count == i386_THREAD_STATE_COUNT) 4796 printf(" count i386_THREAD_STATE_COUNT\n"); 4797 else 4798 printf(" count %u (not i386_THREAD_STATE_" 4799 "COUNT)\n", count); 4800 left = end - begin; 4801 if(left >= sizeof(i386_thread_state_t)){ 4802 memcpy((char *)&cpu, begin, 4803 sizeof(i386_thread_state_t)); 4804 begin += sizeof(i386_thread_state_t); 4805 } 4806 else{ 4807 memset((char *)&cpu, '\0', 4808 sizeof(i386_thread_state_t)); 4809 memcpy((char *)&cpu, begin, left); 4810 begin += left; 4811 } 4812#if defined(x86_THREAD_STATE64) && i386_THREAD_STATE != -1 4813print_x86_thread_state32: 4814#endif 4815 if(swapped) 4816 swap_i386_thread_state(&cpu, host_byte_sex); 4817 printf( 4818 "\t eax 0x%08x ebx 0x%08x ecx 0x%08x edx 0x%08x\n" 4819 "\t edi 0x%08x esi 0x%08x ebp 0x%08x esp 0x%08x\n" 4820 "\t ss 0x%08x eflags 0x%08x eip 0x%08x cs 0x%08x\n" 4821 "\t ds 0x%08x es 0x%08x fs 0x%08x gs 0x%08x\n", 4822 cpu.eax, cpu.ebx, cpu.ecx, cpu.edx, cpu.edi, cpu.esi, 4823 cpu.ebp, cpu.esp, cpu.ss, cpu.eflags, cpu.eip, cpu.cs, 4824 cpu.ds, cpu.es, cpu.fs, cpu.gs); 4825 break; 4826 4827/* current i386 thread states */ 4828#if i386_THREAD_STATE == 1 4829 case i386_FLOAT_STATE: 4830 printf(" flavor i386_FLOAT_STATE\n"); 4831 if(count == i386_FLOAT_STATE_COUNT) 4832 printf(" count i386_FLOAT_STATE_COUNT\n"); 4833 else 4834 printf(" count %u (not i386_FLOAT_STATE_COUNT)\n", 4835 count); 4836 left = end - begin; 4837#ifndef i386_EXCEPTION_STATE_COUNT 4838 fpu = begin; 4839 if(left >= sizeof(struct i386_float_state)){ 4840 fpu_size = sizeof(struct i386_float_state); 4841 begin += sizeof(struct i386_float_state); 4842 } 4843 else{ 4844 fpu_size = left; 4845 begin += left; 4846 } 4847 printf("\t i386_float_state:\n"); 4848 for(f = 0; f < fpu_size; /* no increment expr */){ 4849 printf("\t "); 4850 for(g = 0; g < 16 && f < fpu_size; g++){ 4851 printf("%02x ", (unsigned int)(fpu[f] & 0xff)); 4852 f++; 4853 } 4854 printf("\n"); 4855 } 4856#else /* defined(i386_EXCEPTION_STATE_COUNT) */ 4857 if(left >= sizeof(i386_float_state_t)){ 4858 memcpy((char *)&fpu, begin, 4859 sizeof(i386_float_state_t)); 4860 begin += sizeof(i386_float_state_t); 4861 } 4862 else{ 4863 memset((char *)&fpu, '\0', 4864 sizeof(i386_float_state_t)); 4865 memcpy((char *)&fpu, begin, left); 4866 begin += left; 4867 } 4868#ifdef x86_THREAD_STATE64 4869print_x86_float_state32: 4870#endif /* x86_THREAD_STATE64 */ 4871 if(swapped) 4872 swap_i386_float_state(&fpu, host_byte_sex); 4873 printf("\t fpu_reserved[0] %d fpu_reserved[1] %d\n", 4874 fpu.fpu_reserved[0], fpu.fpu_reserved[1]); 4875 printf("\t control: invalid %d denorm %d zdiv %d ovrfl " 4876 "%d undfl %d precis %d\n", 4877 fpu.fpu_fcw.invalid, 4878 fpu.fpu_fcw.denorm, 4879 fpu.fpu_fcw.zdiv, 4880 fpu.fpu_fcw.ovrfl, 4881 fpu.fpu_fcw.undfl, 4882 fpu.fpu_fcw.precis); 4883 printf("\t\t pc "); 4884 switch(fpu.fpu_fcw.pc){ 4885 case FP_PREC_24B: 4886 printf("FP_PREC_24B "); 4887 break; 4888 case FP_PREC_53B: 4889 printf("FP_PREC_53B "); 4890 break; 4891 case FP_PREC_64B: 4892 printf("FP_PREC_64B "); 4893 break; 4894 default: 4895 printf("%d ", fpu.fpu_fcw.pc); 4896 break; 4897 } 4898 printf("rc "); 4899 switch(fpu.fpu_fcw.rc){ 4900 case FP_RND_NEAR: 4901 printf("FP_RND_NEAR "); 4902 break; 4903 case FP_RND_DOWN: 4904 printf("FP_RND_DOWN "); 4905 break; 4906 case FP_RND_UP: 4907 printf("FP_RND_UP "); 4908 break; 4909 case FP_CHOP: 4910 printf("FP_CHOP "); 4911 break; 4912 } 4913 printf("\n"); 4914 printf("\t status: invalid %d denorm %d zdiv %d ovrfl " 4915 "%d undfl %d precis %d stkflt %d\n", 4916 fpu.fpu_fsw.invalid, 4917 fpu.fpu_fsw.denorm, 4918 fpu.fpu_fsw.zdiv, 4919 fpu.fpu_fsw.ovrfl, 4920 fpu.fpu_fsw.undfl, 4921 fpu.fpu_fsw.precis, 4922 fpu.fpu_fsw.stkflt); 4923 printf("\t errsumm %d c0 %d c1 %d c2 %d tos %d " 4924 "c3 %d busy %d\n", 4925 fpu.fpu_fsw.errsumm, 4926 fpu.fpu_fsw.c0, 4927 fpu.fpu_fsw.c1, 4928 fpu.fpu_fsw.c2, 4929 fpu.fpu_fsw.tos, 4930 fpu.fpu_fsw.c3, 4931 fpu.fpu_fsw.busy); 4932 printf("\t fpu_ftw 0x%02x fpu_rsrv1 0x%02x fpu_fop " 4933 "0x%04x fpu_ip 0x%08x\n", 4934 (unsigned int)fpu.fpu_ftw, 4935 (unsigned int)fpu.fpu_rsrv1, 4936 (unsigned int)fpu.fpu_fop, 4937 (unsigned int)fpu.fpu_ip); 4938 printf("\t fpu_cs 0x%04x fpu_rsrv2 0x%04x fpu_dp 0x%08x " 4939 "fpu_ds 0x%04x\n", 4940 (unsigned int)fpu.fpu_cs, 4941 (unsigned int)fpu.fpu_rsrv2, 4942 (unsigned int)fpu.fpu_dp, 4943 (unsigned int)fpu.fpu_ds); 4944 printf("\t fpu_rsrv3 0x%04x fpu_mxcsr 0x%08x " 4945 "fpu_mxcsrmask 0x%08x\n", 4946 (unsigned int)fpu.fpu_rsrv3, 4947 (unsigned int)fpu.fpu_mxcsr, 4948 (unsigned int)fpu.fpu_mxcsrmask); 4949 printf("\t fpu_stmm0:\n"); 4950 print_mmst_reg(&fpu.fpu_stmm0); 4951 printf("\t fpu_stmm1:\n"); 4952 print_mmst_reg(&fpu.fpu_stmm1); 4953 printf("\t fpu_stmm2:\n"); 4954 print_mmst_reg(&fpu.fpu_stmm2); 4955 printf("\t fpu_stmm3:\n"); 4956 print_mmst_reg(&fpu.fpu_stmm3); 4957 printf("\t fpu_stmm4:\n"); 4958 print_mmst_reg(&fpu.fpu_stmm4); 4959 printf("\t fpu_stmm5:\n"); 4960 print_mmst_reg(&fpu.fpu_stmm5); 4961 printf("\t fpu_stmm6:\n"); 4962 print_mmst_reg(&fpu.fpu_stmm6); 4963 printf("\t fpu_stmm7:\n"); 4964 print_mmst_reg(&fpu.fpu_stmm7); 4965 printf("\t fpu_xmm0:\n"); 4966 print_xmm_reg(&fpu.fpu_xmm0); 4967 printf("\t fpu_xmm1:\n"); 4968 print_xmm_reg(&fpu.fpu_xmm1); 4969 printf("\t fpu_xmm2:\n"); 4970 print_xmm_reg(&fpu.fpu_xmm2); 4971 printf("\t fpu_xmm3:\n"); 4972 print_xmm_reg(&fpu.fpu_xmm3); 4973 printf("\t fpu_xmm4:\n"); 4974 print_xmm_reg(&fpu.fpu_xmm4); 4975 printf("\t fpu_xmm5:\n"); 4976 print_xmm_reg(&fpu.fpu_xmm5); 4977 printf("\t fpu_xmm6:\n"); 4978 print_xmm_reg(&fpu.fpu_xmm6); 4979 printf("\t fpu_xmm7:\n"); 4980 print_xmm_reg(&fpu.fpu_xmm7); 4981 printf("\t fpu_rsrv4:\n"); 4982 for(f = 0; f < 14; f++){ 4983 printf("\t "); 4984 for(g = 0; g < 16; g++){ 4985 printf("%02x ", 4986 (unsigned int)(fpu.fpu_rsrv4[f*g] & 0xff)); 4987 } 4988 printf("\n"); 4989 } 4990 printf("\t fpu_reserved1 0x%08x\n", 4991 (unsigned int)fpu.fpu_reserved1); 4992#endif /* defined(i386_EXCEPTION_STATE_COUNT) */ 4993 break; 4994 4995 case i386_EXCEPTION_STATE: 4996 printf(" flavor i386_EXCEPTION_STATE\n"); 4997 if(count == I386_EXCEPTION_STATE_COUNT) 4998 printf(" count I386_EXCEPTION_STATE_COUNT\n"); 4999 else 5000 printf(" count %u (not I386_EXCEPTION_STATE_COUNT" 5001 ")\n", count); 5002 left = end - begin; 5003 if(left >= sizeof(i386_exception_state_t)){ 5004 memcpy((char *)&exc, begin, 5005 sizeof(i386_exception_state_t)); 5006 begin += sizeof(i386_exception_state_t); 5007 } 5008 else{ 5009 memset((char *)&exc, '\0', 5010 sizeof(i386_exception_state_t)); 5011 memcpy((char *)&exc, begin, left); 5012 begin += left; 5013 } 5014#ifdef x86_THREAD_STATE64 5015print_x86_exception_state32: 5016#endif /* x86_THREAD_STATE64 */ 5017 if(swapped) 5018 swap_i386_exception_state(&exc, host_byte_sex); 5019 printf("\t trapno 0x%08x err 0x%08x faultvaddr 0x%08x\n", 5020 exc.trapno, exc.err, exc.faultvaddr); 5021 break; 5022 5023#ifdef x86_THREAD_STATE64 5024 case x86_DEBUG_STATE32: 5025 printf(" flavor x86_DEBUG_STATE32\n"); 5026 if(count == x86_DEBUG_STATE32_COUNT) 5027 printf(" count x86_DEBUG_STATE32_COUNT\n"); 5028 else 5029 printf(" count %u (not x86_DEBUG_STATE32_COUNT" 5030 ")\n", count); 5031 left = end - begin; 5032 if(left >= sizeof(x86_debug_state32_t)){ 5033 memcpy((char *)&debug, begin, 5034 sizeof(x86_debug_state32_t)); 5035 begin += sizeof(x86_debug_state32_t); 5036 } 5037 else{ 5038 memset((char *)&debug, '\0', 5039 sizeof(x86_debug_state32_t)); 5040 memcpy((char *)&debug, begin, left); 5041 begin += left; 5042 } 5043print_x86_debug_state32: 5044 if(swapped) 5045 swap_x86_debug_state32(&debug, host_byte_sex); 5046 printf("\t dr0 0x%08x dr1 0x%08x dr2 0x%08x dr3 " 5047 "0x%08x\n", debug.dr0, debug.dr1, debug.dr2, 5048 debug.dr3); 5049 printf("\t dr4 0x%08x dr5 0x%08x dr6 0x%08x dr7 " 5050 "0x%08x\n", debug.dr4, debug.dr5, debug.dr6, 5051 debug.dr7); 5052 break; 5053 5054 case x86_THREAD_STATE64: 5055 printf(" flavor x86_THREAD_STATE64\n"); 5056 if(count == x86_THREAD_STATE64_COUNT) 5057 printf(" count x86_THREAD_STATE64_COUNT\n"); 5058 else 5059 printf(" count %u (not x86_THREAD_STATE64_" 5060 "COUNT)\n", count); 5061 left = end - begin; 5062 if(left >= sizeof(x86_thread_state64_t)){ 5063 memcpy((char *)&cpu64, begin, 5064 sizeof(x86_thread_state64_t)); 5065 begin += sizeof(x86_thread_state64_t); 5066 } 5067 else{ 5068 memset((char *)&cpu64, '\0', 5069 sizeof(x86_thread_state64_t)); 5070 memcpy((char *)&cpu64, begin, left); 5071 begin += left; 5072 } 5073print_x86_thread_state64: 5074 if(swapped) 5075 swap_x86_thread_state64(&cpu64, host_byte_sex); 5076 5077 printf(" rax 0x%016llx rbx 0x%016llx rcx 0x%016llx\n" 5078 " rdx 0x%016llx rdi 0x%016llx rsi 0x%016llx\n" 5079 " rbp 0x%016llx rsp 0x%016llx r8 0x%016llx\n" 5080 " r9 0x%016llx r10 0x%016llx r11 0x%016llx\n" 5081 " r12 0x%016llx r13 0x%016llx r14 0x%016llx\n" 5082 " r15 0x%016llx rip 0x%016llx\n" 5083 "rflags 0x%016llx cs 0x%016llx fs 0x%016llx\n" 5084 " gs 0x%016llx\n", 5085 cpu64.rax, cpu64.rbx, cpu64.rcx, cpu64.rdx, cpu64.rdi, 5086 cpu64.rsi, cpu64.rbp, cpu64.rsp, cpu64.r8, cpu64.r9, 5087 cpu64.r10, cpu64.r11, cpu64.r12, cpu64.r13, cpu64.r14, 5088 cpu64.r15, cpu64.rip, cpu64.rflags, cpu64.cs, cpu64.fs, 5089 cpu64.gs); 5090 break; 5091 5092 case x86_FLOAT_STATE64: 5093 printf(" flavor x86_FLOAT_STATE64\n"); 5094 if(count == x86_FLOAT_STATE64_COUNT) 5095 printf(" count x86_FLOAT_STATE64_COUNT\n"); 5096 else 5097 printf(" count %u (not x86_FLOAT_STATE64_" 5098 "COUNT)\n", count); 5099 left = end - begin; 5100 if(left >= sizeof(x86_float_state64_t)){ 5101 memcpy((char *)&fpu64, begin, 5102 sizeof(x86_float_state64_t)); 5103 begin += sizeof(x86_float_state64_t); 5104 } 5105 else{ 5106 memset((char *)&fpu64, '\0', 5107 sizeof(x86_float_state64_t)); 5108 memcpy((char *)&fpu64, begin, left); 5109 begin += left; 5110 } 5111print_x86_float_state64: 5112 if(swapped) 5113 swap_x86_float_state64(&fpu64, host_byte_sex); 5114 printf("\t fpu_reserved[0] %d fpu_reserved[1] %d\n", 5115 fpu64.fpu_reserved[0], fpu64.fpu_reserved[1]); 5116 printf("\t control: invalid %d denorm %d zdiv %d ovrfl " 5117 "%d undfl %d precis %d\n", 5118 fpu64.fpu_fcw.invalid, 5119 fpu64.fpu_fcw.denorm, 5120 fpu64.fpu_fcw.zdiv, 5121 fpu64.fpu_fcw.ovrfl, 5122 fpu64.fpu_fcw.undfl, 5123 fpu64.fpu_fcw.precis); 5124 printf("\t\t pc "); 5125 switch(fpu64.fpu_fcw.pc){ 5126 case FP_PREC_24B: 5127 printf("FP_PREC_24B "); 5128 break; 5129 case FP_PREC_53B: 5130 printf("FP_PREC_53B "); 5131 break; 5132 case FP_PREC_64B: 5133 printf("FP_PREC_64B "); 5134 break; 5135 default: 5136 printf("%d ", fpu64.fpu_fcw.pc); 5137 break; 5138 } 5139 printf("rc "); 5140 switch(fpu64.fpu_fcw.rc){ 5141 case FP_RND_NEAR: 5142 printf("FP_RND_NEAR "); 5143 break; 5144 case FP_RND_DOWN: 5145 printf("FP_RND_DOWN "); 5146 break; 5147 case FP_RND_UP: 5148 printf("FP_RND_UP "); 5149 break; 5150 case FP_CHOP: 5151 printf("FP_CHOP "); 5152 break; 5153 } 5154 printf("\n"); 5155 printf("\t status: invalid %d denorm %d zdiv %d ovrfl " 5156 "%d undfl %d precis %d stkflt %d\n", 5157 fpu64.fpu_fsw.invalid, 5158 fpu64.fpu_fsw.denorm, 5159 fpu64.fpu_fsw.zdiv, 5160 fpu64.fpu_fsw.ovrfl, 5161 fpu64.fpu_fsw.undfl, 5162 fpu64.fpu_fsw.precis, 5163 fpu64.fpu_fsw.stkflt); 5164 printf("\t errsumm %d c0 %d c1 %d c2 %d tos %d " 5165 "c3 %d busy %d\n", 5166 fpu64.fpu_fsw.errsumm, 5167 fpu64.fpu_fsw.c0, 5168 fpu64.fpu_fsw.c1, 5169 fpu64.fpu_fsw.c2, 5170 fpu64.fpu_fsw.tos, 5171 fpu64.fpu_fsw.c3, 5172 fpu64.fpu_fsw.busy); 5173 printf("\t fpu_ftw 0x%02x fpu_rsrv1 0x%02x fpu_fop " 5174 "0x%04x fpu_ip 0x%08x\n", 5175 (unsigned int)fpu64.fpu_ftw, 5176 (unsigned int)fpu64.fpu_rsrv1, 5177 (unsigned int)fpu64.fpu_fop, 5178 (unsigned int)fpu64.fpu_ip); 5179 printf("\t fpu_cs 0x%04x fpu_rsrv2 0x%04x fpu_dp 0x%08x " 5180 "fpu_ds 0x%04x\n", 5181 (unsigned int)fpu64.fpu_cs, 5182 (unsigned int)fpu64.fpu_rsrv2, 5183 (unsigned int)fpu64.fpu_dp, 5184 (unsigned int)fpu64.fpu_ds); 5185 printf("\t fpu_rsrv3 0x%04x fpu_mxcsr 0x%08x " 5186 "fpu_mxcsrmask 0x%08x\n", 5187 (unsigned int)fpu64.fpu_rsrv3, 5188 (unsigned int)fpu64.fpu_mxcsr, 5189 (unsigned int)fpu64.fpu_mxcsrmask); 5190 printf("\t fpu_stmm0:\n"); 5191 print_mmst_reg(&fpu64.fpu_stmm0); 5192 printf("\t fpu_stmm1:\n"); 5193 print_mmst_reg(&fpu64.fpu_stmm1); 5194 printf("\t fpu_stmm2:\n"); 5195 print_mmst_reg(&fpu64.fpu_stmm2); 5196 printf("\t fpu_stmm3:\n"); 5197 print_mmst_reg(&fpu64.fpu_stmm3); 5198 printf("\t fpu_stmm4:\n"); 5199 print_mmst_reg(&fpu64.fpu_stmm4); 5200 printf("\t fpu_stmm5:\n"); 5201 print_mmst_reg(&fpu64.fpu_stmm5); 5202 printf("\t fpu_stmm6:\n"); 5203 print_mmst_reg(&fpu64.fpu_stmm6); 5204 printf("\t fpu_stmm7:\n"); 5205 print_mmst_reg(&fpu64.fpu_stmm7); 5206 printf("\t fpu_xmm0:\n"); 5207 print_xmm_reg(&fpu64.fpu_xmm0); 5208 printf("\t fpu_xmm1:\n"); 5209 print_xmm_reg(&fpu64.fpu_xmm1); 5210 printf("\t fpu_xmm2:\n"); 5211 print_xmm_reg(&fpu64.fpu_xmm2); 5212 printf("\t fpu_xmm3:\n"); 5213 print_xmm_reg(&fpu64.fpu_xmm3); 5214 printf("\t fpu_xmm4:\n"); 5215 print_xmm_reg(&fpu64.fpu_xmm4); 5216 printf("\t fpu_xmm5:\n"); 5217 print_xmm_reg(&fpu64.fpu_xmm5); 5218 printf("\t fpu_xmm6:\n"); 5219 print_xmm_reg(&fpu64.fpu_xmm6); 5220 printf("\t fpu_xmm7:\n"); 5221 print_xmm_reg(&fpu64.fpu_xmm7); 5222 printf("\t fpu_xmm8:\n"); 5223 print_xmm_reg(&fpu64.fpu_xmm8); 5224 printf("\t fpu_xmm9:\n"); 5225 print_xmm_reg(&fpu64.fpu_xmm9); 5226 printf("\t fpu_xmm10:\n"); 5227 print_xmm_reg(&fpu64.fpu_xmm10); 5228 printf("\t fpu_xmm11:\n"); 5229 print_xmm_reg(&fpu64.fpu_xmm11); 5230 printf("\t fpu_xmm12:\n"); 5231 print_xmm_reg(&fpu64.fpu_xmm12); 5232 printf("\t fpu_xmm13:\n"); 5233 print_xmm_reg(&fpu64.fpu_xmm13); 5234 printf("\t fpu_xmm14:\n"); 5235 print_xmm_reg(&fpu64.fpu_xmm14); 5236 printf("\t fpu_xmm15:\n"); 5237 print_xmm_reg(&fpu64.fpu_xmm15); 5238 printf("\t fpu_rsrv4:\n"); 5239 for(f = 0; f < 6; f++){ 5240 printf("\t "); 5241 for(g = 0; g < 16; g++){ 5242 printf("%02x ", 5243 (unsigned int)(fpu64.fpu_rsrv4[f*g] & 0xff)); 5244 } 5245 printf("\n"); 5246 } 5247 printf("\t fpu_reserved1 0x%08x\n", 5248 (unsigned int)fpu64.fpu_reserved1); 5249 break; 5250 5251 case x86_EXCEPTION_STATE64: 5252 printf(" flavor x86_EXCEPTION_STATE64\n"); 5253 if(count == x86_EXCEPTION_STATE64_COUNT) 5254 printf(" count x86_EXCEPTION_STATE64_COUNT\n"); 5255 else 5256 printf(" count %u (not x86_EXCEPTION_STATE64_" 5257 "COUNT)\n", count); 5258 left = end - begin; 5259 if(left >= sizeof(x86_exception_state64_t)){ 5260 memcpy((char *)&exc64, begin, 5261 sizeof(x86_exception_state64_t)); 5262 begin += sizeof(x86_exception_state64_t); 5263 } 5264 else{ 5265 memset((char *)&exc64, '\0', 5266 sizeof(x86_exception_state64_t)); 5267 memcpy((char *)&exc64, begin, left); 5268 begin += left; 5269 } 5270print_x86_exception_state64: 5271 if(swapped) 5272 swap_x86_exception_state64(&exc64, host_byte_sex); 5273 printf("\t trapno 0x%08x err 0x%08x faultvaddr " 5274 "0x%016llx\n", exc64.trapno, exc64.err, 5275 exc64.faultvaddr); 5276 break; 5277 5278 case x86_DEBUG_STATE64: 5279 printf(" flavor x86_DEBUG_STATE64\n"); 5280 if(count == x86_DEBUG_STATE64_COUNT) 5281 printf(" count x86_DEBUG_STATE64_COUNT\n"); 5282 else 5283 printf(" count %u (not x86_DEBUG_STATE64_COUNT" 5284 ")\n", count); 5285 left = end - begin; 5286 if(left >= sizeof(x86_debug_state64_t)){ 5287 memcpy((char *)&debug64, begin, 5288 sizeof(x86_debug_state32_t)); 5289 begin += sizeof(x86_debug_state32_t); 5290 } 5291 else{ 5292 memset((char *)&debug64, '\0', 5293 sizeof(x86_debug_state64_t)); 5294 memcpy((char *)&debug64, begin, left); 5295 begin += left; 5296 } 5297print_x86_debug_state64: 5298 if(swapped) 5299 swap_x86_debug_state64(&debug64, host_byte_sex); 5300 printf("\t dr0 0x%016llx dr1 0x%016llx dr2 0x%016llx " 5301 "dr3 0x%016llx\n", debug64.dr0, debug64.dr1, 5302 debug64.dr2, debug64.dr3); 5303 printf("\t dr4 0x%016llx dr5 0x%016llx dr6 0x%016llx " 5304 "dr7 0x%016llx\n", debug64.dr4, debug64.dr5, 5305 debug64.dr6, debug64.dr7); 5306 break; 5307 5308 case x86_THREAD_STATE: 5309 printf(" flavor x86_THREAD_STATE\n"); 5310 if(count == x86_THREAD_STATE_COUNT) 5311 printf(" count x86_THREAD_STATE_COUNT\n"); 5312 else 5313 printf(" count %u (not x86_THREAD_STATE_COUNT)\n", 5314 count); 5315 left = end - begin; 5316 if(left >= sizeof(x86_thread_state_t)){ 5317 memcpy((char *)&ts, begin, 5318 sizeof(x86_thread_state_t)); 5319 begin += sizeof(x86_thread_state_t); 5320 } 5321 else{ 5322 memset((char *)&ts, '\0', 5323 sizeof(x86_thread_state_t)); 5324 memcpy((char *)&ts, begin, left); 5325 begin += left; 5326 } 5327 if(swapped) 5328 swap_x86_state_hdr(&ts.tsh, host_byte_sex); 5329 if(ts.tsh.flavor == x86_THREAD_STATE32){ 5330 printf("\t tsh.flavor x86_THREAD_STATE32 "); 5331 if(ts.tsh.count == x86_THREAD_STATE32_COUNT) 5332 printf("tsh.count x86_THREAD_STATE32_COUNT\n"); 5333 else 5334 printf("tsh.count %d (not x86_THREAD_STATE32_" 5335 "COUNT\n", ts.tsh.count); 5336 cpu = ts.uts.ts32; 5337 goto print_x86_thread_state32; 5338 } 5339 else if(ts.tsh.flavor == x86_THREAD_STATE64){ 5340 printf("\t tsh.flavor x86_THREAD_STATE64 "); 5341 if(ts.tsh.count == x86_THREAD_STATE64_COUNT) 5342 printf("tsh.count x86_THREAD_STATE64_COUNT\n"); 5343 else 5344 printf("tsh.count %d (not x86_THREAD_STATE64_" 5345 "COUNT\n", ts.tsh.count); 5346 cpu64 = ts.uts.ts64; 5347 goto print_x86_thread_state64; 5348 } 5349 else{ 5350 printf("\t tsh.flavor %d tsh.count %d\n", 5351 ts.tsh.flavor, ts.tsh.count); 5352 } 5353 break; 5354 5355 case x86_FLOAT_STATE: 5356 printf(" flavor x86_FLOAT_STATE\n"); 5357 if(count == x86_FLOAT_STATE_COUNT) 5358 printf(" count x86_FLOAT_STATE_COUNT\n"); 5359 else 5360 printf(" count %u (not x86_FLOAT_STATE_COUNT)\n", 5361 count); 5362 left = end - begin; 5363 if(left >= sizeof(x86_float_state_t)){ 5364 memcpy((char *)&fs, begin, 5365 sizeof(x86_float_state_t)); 5366 begin += sizeof(x86_float_state_t); 5367 } 5368 else{ 5369 memset((char *)&fs, '\0', 5370 sizeof(x86_float_state_t)); 5371 memcpy((char *)&fs, begin, left); 5372 begin += left; 5373 } 5374 if(swapped) 5375 swap_x86_state_hdr(&fs.fsh, host_byte_sex); 5376 if(fs.fsh.flavor == x86_FLOAT_STATE32){ 5377 printf("\t fsh.flavor x86_FLOAT_STATE32 "); 5378 if(fs.fsh.count == x86_FLOAT_STATE32_COUNT) 5379 printf("tsh.count x86_FLOAT_STATE32_COUNT\n"); 5380 else 5381 printf("tsh.count %d (not x86_FLOAT_STATE32_COUNT" 5382 "\n", fs.fsh.count); 5383 fpu = fs.ufs.fs32; 5384 goto print_x86_float_state32; 5385 } 5386 else if(fs.fsh.flavor == x86_FLOAT_STATE64){ 5387 printf("\t fsh.flavor x86_FLOAT_STATE64 "); 5388 if(fs.fsh.count == x86_FLOAT_STATE64_COUNT) 5389 printf("tsh.count x86_FLOAT_STATE64_COUNT\n"); 5390 else 5391 printf("tsh.count %d (not x86_FLOAT_STATE64_COUNT" 5392 "\n", fs.fsh.count); 5393 fpu64 = fs.ufs.fs64; 5394 goto print_x86_float_state64; 5395 } 5396 else{ 5397 printf("\t fsh.flavor %d fsh.count %d\n", 5398 fs.fsh.flavor, fs.fsh.count); 5399 } 5400 break; 5401 5402 case x86_EXCEPTION_STATE: 5403 printf(" flavor x86_EXCEPTION_STATE\n"); 5404 if(count == x86_EXCEPTION_STATE_COUNT) 5405 printf(" count x86_EXCEPTION_STATE_COUNT\n"); 5406 else 5407 printf(" count %u (not x86_EXCEPTION_STATE_" 5408 "COUNT)\n", count); 5409 left = end - begin; 5410 if(left >= sizeof(x86_exception_state_t)){ 5411 memcpy((char *)&es, begin, 5412 sizeof(x86_exception_state_t)); 5413 begin += sizeof(x86_exception_state_t); 5414 } 5415 else{ 5416 memset((char *)&es, '\0', 5417 sizeof(x86_exception_state_t)); 5418 memcpy((char *)&es, begin, left); 5419 begin += left; 5420 } 5421 if(swapped) 5422 swap_x86_state_hdr(&es.esh, host_byte_sex); 5423 if(es.esh.flavor == x86_EXCEPTION_STATE32){ 5424 printf("\t esh.flavor x86_EXCEPTION_STATE32\n"); 5425 if(es.esh.count == x86_EXCEPTION_STATE32_COUNT) 5426 printf("\t esh.count x86_EXCEPTION_STATE32_" 5427 "COUNT\n"); 5428 else 5429 printf("\t esh.count %d (not x86_EXCEPTION_" 5430 "STATE32_COUNT\n", es.esh.count); 5431 exc = es.ues.es32; 5432 goto print_x86_exception_state32; 5433 } 5434 else if(es.esh.flavor == x86_EXCEPTION_STATE64){ 5435 printf("\t esh.flavor x86_EXCEPTION_STATE64\n"); 5436 if(es.esh.count == x86_EXCEPTION_STATE64_COUNT) 5437 printf("\t esh.count x86_EXCEPTION_STATE64_" 5438 "COUNT\n"); 5439 else 5440 printf("\t esh.count %d (not x86_EXCEPTION_" 5441 "STATE64_COUNT\n", es.esh.count); 5442 exc64 = es.ues.es64; 5443 goto print_x86_exception_state64; 5444 } 5445 else{ 5446 printf("\t esh.flavor %d esh.count %d\n", 5447 es.esh.flavor, es.esh.count); 5448 } 5449 break; 5450 5451 case x86_DEBUG_STATE: 5452 printf(" flavor x86_DEBUG_STATE\n"); 5453 if(count == x86_DEBUG_STATE_COUNT) 5454 printf(" count x86_DEBUG_STATE_COUNT\n"); 5455 else 5456 printf(" count %u (not x86_DEBUG_STATE_COUNT" 5457 "\n", count); 5458 left = end - begin; 5459 if(left >= sizeof(x86_debug_state_t)){ 5460 memcpy((char *)&ds, begin, 5461 sizeof(x86_debug_state_t)); 5462 begin += sizeof(x86_debug_state_t); 5463 } 5464 else{ 5465 memset((char *)&ds, '\0', 5466 sizeof(x86_debug_state_t)); 5467 memcpy((char *)&ds, begin, left); 5468 begin += left; 5469 } 5470 if(swapped) 5471 swap_x86_state_hdr(&ds.dsh, host_byte_sex); 5472 if(ds.dsh.flavor == x86_DEBUG_STATE32){ 5473 printf("\t dsh.flavor x86_DEBUG_STATE32\n"); 5474 if(ds.dsh.count == x86_DEBUG_STATE32_COUNT) 5475 printf("\t dsh.count x86_DEBUG_STATE32_COUNT\n"); 5476 else 5477 printf("\t esh.count %d (not x86_DEBUG_STATE32_" 5478 "_COUNT\n", ds.dsh.count); 5479 debug = ds.uds.ds32; 5480 goto print_x86_debug_state32; 5481 } 5482 if(ds.dsh.flavor == x86_DEBUG_STATE64){ 5483 printf("\t dsh.flavor x86_DEBUG_STATE64\n"); 5484 if(ds.dsh.count == x86_DEBUG_STATE64_COUNT) 5485 printf("\t dsh.count x86_DEBUG_STATE64_COUNT\n"); 5486 else 5487 printf("\t esh.count %d (not x86_DEBUG_STATE64_" 5488 "_COUNT\n", ds.dsh.count); 5489 debug64 = ds.uds.ds64; 5490 goto print_x86_debug_state64; 5491 } 5492 else{ 5493 printf("\t dsh.flavor %d dsh.count %d\n", 5494 ds.dsh.flavor, ds.dsh.count); 5495 } 5496 break; 5497#endif /* x86_THREAD_STATE64 */ 5498#endif /* i386_THREAD_STATE == 1 */ 5499 5500/* i386 thread states on older releases */ 5501#if i386_THREAD_STATE == -1 5502 case i386_THREAD_FPSTATE: 5503 printf(" flavor i386_THREAD_FPSTATE\n"); 5504 if(count == i386_THREAD_FPSTATE_COUNT) 5505 printf(" count i386_THREAD_FPSTATE_COUNT\n"); 5506 else 5507 printf(" count %u (not i386_THREAD_FPSTATE_" 5508 "COUNT)\n", count); 5509 left = end - begin; 5510 if(left >= sizeof(i386_thread_fpstate_t)){ 5511 memcpy((char *)&fpu, begin, 5512 sizeof(i386_thread_fpstate_t)); 5513 begin += sizeof(i386_thread_fpstate_t); 5514 } 5515 else{ 5516 memset((char *)&fpu, '\0', 5517 sizeof(i386_thread_fpstate_t)); 5518 memcpy((char *)&fpu, begin, left); 5519 begin += left; 5520 } 5521 if(swapped) 5522 swap_i386_thread_fpstate(&fpu, host_byte_sex); 5523 printf("\t control: invalid %d denorm %d zdiv %d ovrfl " 5524 "%d undfl %d precis %d\n", 5525 fpu.environ.control.invalid, 5526 fpu.environ.control.denorm, 5527 fpu.environ.control.zdiv, 5528 fpu.environ.control.ovrfl, 5529 fpu.environ.control.undfl, 5530 fpu.environ.control.precis); 5531 printf("\t\t pc "); 5532 switch(fpu.environ.control.pc){ 5533 case FP_PREC_24B: 5534 printf("FP_PREC_24B "); 5535 break; 5536 case FP_PREC_53B: 5537 printf("FP_PREC_53B "); 5538 break; 5539 case FP_PREC_64B: 5540 printf("FP_PREC_64B "); 5541 break; 5542 default: 5543 printf("%d ", fpu.environ.control.pc); 5544 break; 5545 } 5546 printf("rc "); 5547 switch(fpu.environ.control.rc){ 5548 case FP_RND_NEAR: 5549 printf("FP_RND_NEAR "); 5550 break; 5551 case FP_RND_DOWN: 5552 printf("FP_RND_DOWN "); 5553 break; 5554 case FP_RND_UP: 5555 printf("FP_RND_UP "); 5556 break; 5557 case FP_CHOP: 5558 printf("FP_CHOP "); 5559 break; 5560 } 5561 printf("\n"); 5562 5563 printf("\t status: invalid %d denorm %d zdiv %d ovrfl " 5564 "%d undfl %d precis %d stkflt %d\n", 5565 fpu.environ.status.invalid, 5566 fpu.environ.status.denorm, 5567 fpu.environ.status.zdiv, 5568 fpu.environ.status.ovrfl, 5569 fpu.environ.status.undfl, 5570 fpu.environ.status.precis, 5571 fpu.environ.status.stkflt); 5572 printf("\t\t errsumm %d c0 %d c1 %d c2 %d tos %d c3 %d " 5573 "busy %d\n", fpu.environ.status.errsumm, 5574 fpu.environ.status.c0, fpu.environ.status.c1, 5575 fpu.environ.status.c2, fpu.environ.status.tos, 5576 fpu.environ.status.c3, fpu.environ.status.busy); 5577 printf("\t tags: tag0 %s tag1 %s tag2 %s tag3 %s\n" 5578 "\t tag4 %s tag5 %s tag6 %s tag7 %s\n", 5579 tags[fpu.environ.tag.tag0], 5580 tags[fpu.environ.tag.tag1], 5581 tags[fpu.environ.tag.tag2], 5582 tags[fpu.environ.tag.tag3], 5583 tags[fpu.environ.tag.tag4], 5584 tags[fpu.environ.tag.tag5], 5585 tags[fpu.environ.tag.tag6], 5586 tags[fpu.environ.tag.tag7]); 5587 printf("\t ip 0x%08x\n", fpu.environ.ip); 5588 printf("\t cs: rpl "); 5589 switch(fpu.environ.cs.rpl){ 5590 case KERN_PRIV: 5591 printf("KERN_PRIV "); 5592 break; 5593 case USER_PRIV: 5594 printf("USER_PRIV "); 5595 break; 5596 default: 5597 printf("%d ", fpu.environ.cs.rpl); 5598 break; 5599 } 5600 printf("ti "); 5601 switch(fpu.environ.cs.ti){ 5602 case SEL_GDT: 5603 printf("SEL_GDT "); 5604 break; 5605 case SEL_LDT: 5606 printf("SEL_LDT "); 5607 break; 5608 } 5609 printf("index %d\n", fpu.environ.cs.index); 5610 printf("\t opcode 0x%04x\n", 5611 (unsigned int)fpu.environ.opcode); 5612 printf("\t dp 0x%08x\n", fpu.environ.dp); 5613 printf("\t ds: rpl "); 5614 switch(fpu.environ.ds.rpl){ 5615 case KERN_PRIV: 5616 printf("KERN_PRIV "); 5617 break; 5618 case USER_PRIV: 5619 printf("USER_PRIV "); 5620 break; 5621 default: 5622 printf("%d ", fpu.environ.ds.rpl); 5623 break; 5624 } 5625 printf("ti "); 5626 switch(fpu.environ.ds.ti){ 5627 case SEL_GDT: 5628 printf("SEL_GDT "); 5629 break; 5630 case SEL_LDT: 5631 printf("SEL_LDT "); 5632 break; 5633 } 5634 printf("index %d\n", fpu.environ.ds.index); 5635 printf("\t stack:\n"); 5636 for(i = 0; i < 8; i++){ 5637 printf("\t\tST[%u] mant 0x%04x 0x%04x 0x%04x 0x%04x " 5638 "exp 0x%04x sign %d\n", i, 5639 (unsigned int)fpu.stack.ST[i].mant, 5640 (unsigned int)fpu.stack.ST[i].mant1, 5641 (unsigned int)fpu.stack.ST[i].mant2, 5642 (unsigned int)fpu.stack.ST[i].mant3, 5643 (unsigned int)fpu.stack.ST[i].exp, 5644 fpu.stack.ST[i].sign); 5645 } 5646 break; 5647 case i386_THREAD_EXCEPTSTATE: 5648 printf(" flavor i386_THREAD_EXCEPTSTATE\n"); 5649 if(count == i386_THREAD_EXCEPTSTATE_COUNT) 5650 printf(" count i386_THREAD_EXCEPTSTATE_COUNT\n"); 5651 else 5652 printf(" count %u (not i386_THREAD_EXCEPTSTATE_" 5653 "COUNT)\n", count); 5654 left = end - begin; 5655 if(left >= sizeof(i386_thread_exceptstate_t)){ 5656 memcpy((char *)&exc, begin, 5657 sizeof(i386_thread_exceptstate_t)); 5658 begin += sizeof(i386_thread_exceptstate_t); 5659 } 5660 else{ 5661 memset((char *)&exc, '\0', 5662 sizeof(i386_thread_exceptstate_t)); 5663 memcpy((char *)&exc, begin, left); 5664 begin += left; 5665 } 5666 if(swapped) 5667 swap_i386_thread_exceptstate(&exc, host_byte_sex); 5668 printf("\t trapno 0x%08x\n", exc.trapno); 5669 if(exc.trapno == 14){ 5670 printf("\t err.pgfault: prot %d wrtflt %d user %d\n", 5671 exc.err.pgfault.prot, exc.err.pgfault.wrtflt, 5672 exc.err.pgfault.user); 5673 } 5674 else{ 5675 printf("\t err.normal: ext %d ", exc.err.normal.ext); 5676 printf("tbl "); 5677 switch(exc.err.normal.tbl){ 5678 case ERR_GDT: 5679 printf("ERR_GDT "); 5680 break; 5681 case ERR_IDT: 5682 printf("ERR_IDT "); 5683 break; 5684 case ERR_LDT: 5685 printf("ERR_LDT "); 5686 break; 5687 default: 5688 printf("%d ", exc.err.normal.tbl); 5689 break; 5690 } 5691 printf("index %d\n", exc.err.normal.index); 5692 } 5693 break; 5694 5695 case i386_THREAD_CTHREADSTATE: 5696 printf(" flavor i386_THREAD_CTHREADSTATE\n"); 5697 if(count == i386_THREAD_CTHREADSTATE_COUNT) 5698 printf(" count i386_THREAD_CTHREADSTATE_COUNT\n"); 5699 else 5700 printf(" count %u (not i386_THREAD_CTHREADSTATE_" 5701 "COUNT)\n", count); 5702 left = end - begin; 5703 if(left >= sizeof(i386_thread_cthreadstate_t)){ 5704 memcpy((char *)&user, begin, 5705 sizeof(i386_thread_cthreadstate_t)); 5706 begin += sizeof(i386_thread_cthreadstate_t); 5707 } 5708 else{ 5709 memset((char *)&user, '\0', 5710 sizeof(i386_thread_cthreadstate_t)); 5711 memcpy((char *)&user, begin, left); 5712 begin += left; 5713 } 5714 if(swapped) 5715 swap_i386_thread_cthreadstate(&user, host_byte_sex); 5716 printf("\t self 0x%08x\n", user.self); 5717 break; 5718#endif /* i386_THREAD_STATE == -1 */ 5719 default: 5720 printf(" flavor %u (unknown)\n", flavor); 5721 printf(" count %u\n", count); 5722 printf(" state:\n"); 5723 print_unknown_state(begin, end, count, swapped); 5724 begin += count * sizeof(uint32_t); 5725 break; 5726 } 5727 } 5728 } 5729 else if(cputype == CPU_TYPE_ARM){ 5730 arm_thread_state_t cpu; 5731 while(begin < end){ 5732 if(end - begin > (ptrdiff_t)sizeof(uint32_t)){ 5733 memcpy((char *)&flavor, begin, sizeof(uint32_t)); 5734 begin += sizeof(uint32_t); 5735 } 5736 else{ 5737 flavor = 0; 5738 begin = end; 5739 } 5740 if(swapped) 5741 flavor = SWAP_INT(flavor); 5742 if(end - begin > (ptrdiff_t)sizeof(uint32_t)){ 5743 memcpy((char *)&count, begin, sizeof(uint32_t)); 5744 begin += sizeof(uint32_t); 5745 } 5746 else{ 5747 count = 0; 5748 begin = end; 5749 } 5750 if(swapped) 5751 count = SWAP_INT(count); 5752 5753 switch(flavor){ 5754 case ARM_THREAD_STATE: 5755 printf(" flavor ARM_THREAD_STATE\n"); 5756 if(count == ARM_THREAD_STATE_COUNT) 5757 printf(" count ARM_THREAD_STATE_COUNT\n"); 5758 else 5759 printf(" count %u (not ARM_THREAD_STATE_" 5760 "COUNT)\n", count); 5761 left = end - begin; 5762 if(left >= sizeof(arm_thread_state_t)){ 5763 memcpy((char *)&cpu, begin, 5764 sizeof(arm_thread_state_t)); 5765 begin += sizeof(arm_thread_state_t); 5766 } 5767 else{ 5768 memset((char *)&cpu, '\0', 5769 sizeof(arm_thread_state_t)); 5770 memcpy((char *)&cpu, begin, left); 5771 begin += left; 5772 } 5773 if(swapped) 5774 swap_arm_thread_state_t(&cpu, host_byte_sex); 5775 printf( 5776 "\t r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n" 5777 "\t r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n" 5778 "\t r8 0x%08x r9 0x%08x r10 0x%08x r11 0x%08x\n" 5779 "\t r12 0x%08x sp 0x%08x lr 0x%08x pc 0x%08x\n" 5780 "\t cpsr 0x%08x\n", 5781 cpu.__r[0], cpu.__r[1], cpu.__r[2], cpu.__r[3], 5782 cpu.__r[4], cpu.__r[5], cpu.__r[6], cpu.__r[7], 5783 cpu.__r[8], cpu.__r[9], cpu.__r[10], cpu.__r[11], 5784 cpu.__r[12], cpu.__sp, cpu.__lr, cpu.__pc, cpu.__cpsr); 5785 break; 5786 default: 5787 printf(" flavor %u (unknown)\n", flavor); 5788 printf(" count %u\n", count); 5789 printf(" state:\n"); 5790 print_unknown_state(begin, end, count, swapped); 5791 begin += count * sizeof(uint32_t); 5792 break; 5793 } 5794 } 5795 } 5796 else{ 5797 while(begin < end){ 5798 if(end - begin > (ptrdiff_t)sizeof(uint32_t)){ 5799 memcpy((char *)&flavor, begin, sizeof(uint32_t)); 5800 begin += sizeof(uint32_t); 5801 } 5802 else{ 5803 flavor = 0; 5804 begin = end; 5805 } 5806 if(swapped) 5807 flavor = SWAP_INT(flavor); 5808 if(end - begin > (ptrdiff_t)sizeof(uint32_t)){ 5809 memcpy((char *)&count, begin, sizeof(uint32_t)); 5810 begin += sizeof(uint32_t); 5811 } 5812 else{ 5813 count = 0; 5814 begin = end; 5815 } 5816 if(swapped) 5817 count = SWAP_INT(count); 5818 printf(" flavor %u\n", flavor); 5819 printf(" count %u\n", count); 5820 printf(" state (Unknown cputype/cpusubtype):\n"); 5821 print_unknown_state(begin, end, count, swapped); 5822 begin += count * sizeof(uint32_t); 5823 } 5824 } 5825} 5826 5827/* current i386 thread states */ 5828#if i386_THREAD_STATE == 1 5829#ifdef i386_EXCEPTION_STATE_COUNT 5830 5831static 5832void 5833print_mmst_reg( 5834struct mmst_reg *r) 5835{ 5836 uint32_t f; 5837 5838 printf("\t mmst_reg "); 5839 for(f = 0; f < 10; f++){ 5840 printf("%02x ", 5841 (unsigned int)(r->mmst_reg[f] & 0xff)); 5842 } 5843 printf("\n"); 5844 printf("\t mmst_rsrv "); 5845 for(f = 0; f < 6; f++){ 5846 printf("%02x ", 5847 (unsigned int)(r->mmst_rsrv[f] & 0xff)); 5848 } 5849 printf("\n"); 5850} 5851 5852static 5853void 5854print_xmm_reg( 5855struct xmm_reg *r) 5856{ 5857 uint32_t f; 5858 5859 printf("\t xmm_reg "); 5860 for(f = 0; f < 16; f++){ 5861 printf("%02x ", 5862 (unsigned int)(r->xmm_reg[f] & 0xff)); 5863 } 5864 printf("\n"); 5865} 5866#endif /* defined(i386_EXCEPTION_STATE_COUNT) */ 5867#endif /* i386_THREAD_STATE == 1 */ 5868 5869static 5870void 5871print_unknown_state( 5872char *begin, 5873char *end, 5874unsigned int count, 5875enum bool swapped) 5876{ 5877 uint32_t left, *state, i, j; 5878 5879 left = end - begin; 5880 if(left * sizeof(uint32_t) >= count){ 5881 state = allocate(count * sizeof(uint32_t)); 5882 memcpy((char *)state, begin, count * sizeof(uint32_t)); 5883 begin += count * sizeof(uint32_t); 5884 } 5885 else{ 5886 state = allocate(left); 5887 memset((char *)state, '\0', left); 5888 memcpy((char *)state, begin, left); 5889 count = left / sizeof(uint32_t); 5890 begin += left; 5891 } 5892 if(swapped) 5893 for(i = 0 ; i < count; i++) 5894 state[i] = SWAP_INT(state[i]); 5895 for(i = 0 ; i < count; i += j){ 5896 for(j = 0 ; j < 8 && i + j < count; j++) 5897 printf("%08x ", (unsigned int)state[i + j]); 5898 printf("\n"); 5899 } 5900 free(state); 5901} 5902 5903/* 5904 * Print the relocation information. 5905 */ 5906void 5907print_reloc( 5908struct load_command *load_commands, 5909uint32_t ncmds, 5910uint32_t sizeofcmds, 5911cpu_type_t cputype, 5912enum byte_sex load_commands_byte_sex, 5913char *object_addr, 5914uint32_t object_size, 5915struct nlist *symbols, 5916struct nlist_64 *symbols64, 5917uint32_t nsymbols, 5918char *strings, 5919uint32_t strings_size, 5920enum bool verbose) 5921{ 5922 enum byte_sex host_byte_sex; 5923 enum bool swapped; 5924 uint32_t i, j, k, left, size, nsects; 5925 char *p; 5926 struct load_command *lc, l; 5927 struct segment_command sg; 5928 struct section s; 5929 struct segment_command_64 sg64; 5930 struct section_64 s64; 5931 struct reloc_section_info *sect_rel; 5932 struct dysymtab_command dyst; 5933 uint64_t big_size; 5934 5935 host_byte_sex = get_host_byte_sex(); 5936 swapped = host_byte_sex != load_commands_byte_sex; 5937 5938 /* 5939 * Create an array of section structures in the host byte sex so it 5940 * can be processed and indexed into directly. 5941 */ 5942 k = 0; 5943 nsects = 0; 5944 sect_rel = NULL; 5945 lc = load_commands; 5946 dyst.cmd = 0; 5947 for(i = 0 ; i < ncmds; i++){ 5948 memcpy((char *)&l, (char *)lc, sizeof(struct load_command)); 5949 if(swapped) 5950 swap_load_command(&l, host_byte_sex); 5951 if(l.cmdsize % sizeof(int32_t) != 0) 5952 printf("load command %u size not a multiple of " 5953 "sizeof(int32_t)\n", i); 5954 if((char *)lc + l.cmdsize > 5955 (char *)load_commands + sizeofcmds) 5956 printf("load command %u extends past end of load " 5957 "commands\n", i); 5958 left = sizeofcmds - ((char *)lc - (char *)load_commands); 5959 5960 switch(l.cmd){ 5961 case LC_SEGMENT: 5962 memset((char *)&sg, '\0', sizeof(struct segment_command)); 5963 size = left < sizeof(struct segment_command) ? 5964 left : sizeof(struct segment_command); 5965 memcpy((char *)&sg, (char *)lc, size); 5966 if(swapped) 5967 swap_segment_command(&sg, host_byte_sex); 5968 5969 big_size = sg.nsects; 5970 big_size *= sizeof(struct segment_command); 5971 if(big_size > sg.cmdsize){ 5972 printf("number of sections in load command %u extends past " 5973 "end of load command\n", i); 5974 sg.nsects = (sg.cmdsize - sizeof(struct segment_command)) / 5975 sizeof(struct section); 5976 } 5977 nsects += sg.nsects; 5978 sect_rel = reallocate(sect_rel, 5979 nsects * sizeof(struct reloc_section_info)); 5980 memset((char *)(sect_rel + (nsects - sg.nsects)), '\0', 5981 sizeof(struct reloc_section_info) * sg.nsects); 5982 p = (char *)lc + sizeof(struct segment_command); 5983 for(j = 0 ; j < sg.nsects ; j++){ 5984 left = sizeofcmds - (p - (char *)load_commands); 5985 size = left < sizeof(struct section) ? 5986 left : sizeof(struct section); 5987 memcpy((char *)&s, p, size); 5988 if(swapped) 5989 swap_section(&s, 1, host_byte_sex); 5990 5991 if(p + sizeof(struct section) > 5992 (char *)load_commands + sizeofcmds) 5993 break; 5994 p += size; 5995 memcpy(sect_rel[k].segname, s.segname, 16); 5996 memcpy(sect_rel[k].sectname, s.sectname, 16); 5997 sect_rel[k].nreloc = s.nreloc; 5998 sect_rel[k].reloff = s.reloff; 5999 k++; 6000 } 6001 break; 6002 case LC_SEGMENT_64: 6003 memset((char *)&sg64, '\0', sizeof(struct segment_command_64)); 6004 size = left < sizeof(struct segment_command_64) ? 6005 left : sizeof(struct segment_command_64); 6006 memcpy((char *)&sg64, (char *)lc, size); 6007 if(swapped) 6008 swap_segment_command_64(&sg64, host_byte_sex); 6009 6010 big_size = sg64.nsects; 6011 big_size *= sizeof(struct segment_command_64); 6012 if(big_size > sg64.cmdsize){ 6013 printf("number of sections in load command %u extends past " 6014 "end of load command\n", i); 6015 sg64.nsects = (sg64.cmdsize - 6016 sizeof(struct segment_command_64)) / 6017 sizeof(struct section_64); 6018 } 6019 nsects += sg64.nsects; 6020 sect_rel = reallocate(sect_rel, 6021 nsects * sizeof(struct reloc_section_info)); 6022 memset((char *)(sect_rel + (nsects - sg64.nsects)), '\0', 6023 sizeof(struct reloc_section_info) * sg64.nsects); 6024 p = (char *)lc + sizeof(struct segment_command_64); 6025 for(j = 0 ; j < sg64.nsects ; j++){ 6026 left = sizeofcmds - (p - (char *)load_commands); 6027 size = left < sizeof(struct section_64) ? 6028 left : sizeof(struct section_64); 6029 memcpy((char *)&s64, p, size); 6030 if(swapped) 6031 swap_section_64(&s64, 1, host_byte_sex); 6032 6033 if(p + sizeof(struct section_64) > 6034 (char *)load_commands + sizeofcmds) 6035 break; 6036 p += size; 6037 memcpy(sect_rel[k].segname, s64.segname, 16); 6038 memcpy(sect_rel[k].sectname, s64.sectname, 16); 6039 sect_rel[k].nreloc = s64.nreloc; 6040 sect_rel[k].reloff = s64.reloff; 6041 k++; 6042 } 6043 break; 6044 case LC_DYSYMTAB: 6045 memset((char *)&dyst, '\0', sizeof(struct dysymtab_command)); 6046 size = left < sizeof(struct dysymtab_command) ? 6047 left : sizeof(struct dysymtab_command); 6048 memcpy((char *)&dyst, (char *)lc, size); 6049 if(swapped) 6050 swap_dysymtab_command(&dyst, host_byte_sex); 6051 break; 6052 } 6053 if(l.cmdsize == 0){ 6054 printf("load command %u size zero (can't advance to other " 6055 "load commands)\n", i); 6056 break; 6057 } 6058 lc = (struct load_command *)((char *)lc + l.cmdsize); 6059 if((char *)lc > (char *)load_commands + sizeofcmds) 6060 break; 6061 } 6062 if((char *)load_commands + sizeofcmds != (char *)lc) 6063 printf("Inconsistent sizeofcmds\n"); 6064 6065 if(dyst.cmd != 0){ 6066 if(dyst.nextrel != 0){ 6067 printf("External relocation information %u entries", 6068 dyst.nextrel); 6069 if(dyst.extreloff > object_size){ 6070 printf(" (offset to relocation entries extends past the " 6071 "end of the file)\n"); 6072 } 6073 else{ 6074 printf("\naddress pcrel length extern type scattered " 6075 "symbolnum/value\n"); 6076 6077 print_relocs(dyst.extreloff, dyst.nextrel, sect_rel, nsects, 6078 swapped, cputype, object_addr, object_size, 6079 symbols, symbols64, nsymbols, strings, 6080 strings_size, verbose); 6081 } 6082 } 6083 if(dyst.nlocrel != 0){ 6084 printf("Local relocation information %u entries", dyst.nlocrel); 6085 if(dyst.locreloff > object_size){ 6086 printf(" (offset to relocation entries extends past the " 6087 "end of the file)\n"); 6088 } 6089 else{ 6090 printf("\naddress pcrel length extern type scattered " 6091 "symbolnum/value\n"); 6092 6093 print_relocs(dyst.locreloff, dyst.nlocrel, sect_rel, nsects, 6094 swapped, cputype, object_addr, object_size, 6095 symbols, symbols64, nsymbols, strings, 6096 strings_size, verbose); 6097 } 6098 } 6099 } 6100 6101 for(i = 0 ; i < nsects ; i++){ 6102 if(sect_rel[i].nreloc == 0) 6103 continue; 6104 printf("Relocation information (%.16s,%.16s) %u entries", 6105 sect_rel[i].segname, sect_rel[i].sectname, 6106 sect_rel[i].nreloc); 6107 if(sect_rel[i].reloff > object_size){ 6108 printf(" (offset to relocation entries extends past the end of " 6109 " the file)\n"); 6110 continue; 6111 } 6112 printf("\naddress pcrel length extern type scattered " 6113 "symbolnum/value\n"); 6114 6115 print_relocs(sect_rel[i].reloff, sect_rel[i].nreloc, sect_rel, 6116 nsects, swapped, cputype, object_addr, object_size, 6117 symbols, symbols64, nsymbols, strings, strings_size, 6118 verbose); 6119 } 6120} 6121 6122static 6123void 6124print_relocs( 6125unsigned reloff, 6126unsigned nreloc, 6127struct reloc_section_info *sect_rel, 6128uint32_t nsects, 6129enum bool swapped, 6130cpu_type_t cputype, 6131char *object_addr, 6132uint32_t object_size, 6133struct nlist *symbols, 6134struct nlist_64 *symbols64, 6135uint32_t nsymbols, 6136char *strings, 6137uint32_t strings_size, 6138enum bool verbose) 6139{ 6140 enum byte_sex host_byte_sex; 6141 uint32_t j; 6142 struct relocation_info *r, reloc; 6143 struct scattered_relocation_info *sr; 6144 enum bool previous_sectdiff, previous_ppc_jbsr, previous_arm_half,predicted; 6145 uint32_t sectdiff_r_type; 6146 uint32_t n_strx; 6147 6148 host_byte_sex = get_host_byte_sex(); 6149 6150 previous_sectdiff = FALSE; 6151 previous_ppc_jbsr = FALSE; 6152 previous_arm_half = FALSE; 6153 sectdiff_r_type = 0; 6154 for(j = 0 ; 6155 j < nreloc && 6156 reloff + (j + 1) * sizeof(struct relocation_info) <= object_size; 6157 j++){ 6158 predicted = FALSE; 6159 r = (struct relocation_info *) 6160 (object_addr + reloff + 6161 j * sizeof(struct relocation_info)); 6162 memcpy((char *)&reloc, (char *)r, 6163 sizeof(struct relocation_info)); 6164 if(swapped) 6165 swap_relocation_info(&reloc, 1, host_byte_sex); 6166 6167 if((reloc.r_address & R_SCATTERED) != 0 && 6168 cputype != CPU_TYPE_X86_64){ 6169 sr = (struct scattered_relocation_info *)&reloc; 6170 if(verbose){ 6171 if((cputype == CPU_TYPE_MC680x0 && 6172 sr->r_type == GENERIC_RELOC_PAIR) || 6173 (cputype == CPU_TYPE_I386 && 6174 sr->r_type == GENERIC_RELOC_PAIR) || 6175 (cputype == CPU_TYPE_MC88000 && 6176 sr->r_type == M88K_RELOC_PAIR) || 6177 ((cputype == CPU_TYPE_POWERPC || 6178 cputype == CPU_TYPE_POWERPC64 || 6179 cputype == CPU_TYPE_VEO) && 6180 sr->r_type == PPC_RELOC_PAIR) || 6181 (cputype == CPU_TYPE_HPPA && 6182 sr->r_type == HPPA_RELOC_PAIR) || 6183 (cputype == CPU_TYPE_SPARC && 6184 sr->r_type == SPARC_RELOC_PAIR) || 6185 (cputype == CPU_TYPE_ARM && 6186 sr->r_type == ARM_RELOC_PAIR) || 6187 (cputype == CPU_TYPE_I860 && 6188 sr->r_type == I860_RELOC_PAIR)) 6189 printf(" "); 6190 else 6191 printf("%08x ", (unsigned int)sr->r_address); 6192 if(sr->r_pcrel) 6193 printf("True "); 6194 else 6195 printf("False "); 6196 if(cputype == CPU_TYPE_ARM && 6197 (sr->r_type == ARM_RELOC_HALF || 6198 sr->r_type == ARM_RELOC_HALF_SECTDIFF || 6199 previous_arm_half == TRUE)){ 6200 if((sr->r_length & 0x1) == 0) 6201 printf("lo/"); 6202 else 6203 printf("hi/"); 6204 if((sr->r_length & 0x2) == 0) 6205 printf("arm "); 6206 else 6207 printf("thm "); 6208 } 6209 else{ 6210 switch(sr->r_length){ 6211 case 0: 6212 printf("byte "); 6213 break; 6214 case 1: 6215 printf("word "); 6216 break; 6217 case 2: 6218 printf("long "); 6219 break; 6220 case 3: 6221 /* 6222 * The value of 3 for r_length for PowerPC is to 6223 * encode that a conditional branch using the Y-bit 6224 * for static branch prediction was predicted in 6225 * the assembly source. 6226 */ 6227 if((cputype == CPU_TYPE_POWERPC64 && 6228 reloc.r_type == PPC_RELOC_VANILLA) || 6229 cputype == CPU_TYPE_X86_64) { 6230 printf("quad "); 6231 } 6232 else if(cputype == CPU_TYPE_POWERPC || 6233 cputype == CPU_TYPE_POWERPC64 || 6234 cputype == CPU_TYPE_VEO){ 6235 printf("long "); 6236 predicted = TRUE; 6237 } 6238 else 6239 printf("?(%2d) ", sr->r_length); 6240 break; 6241 default: 6242 printf("?(%2d) ", sr->r_length); 6243 break; 6244 } 6245 } 6246 printf("n/a "); 6247 print_r_type(cputype, sr->r_type, predicted); 6248 printf("True 0x%08x", (unsigned int)sr->r_value); 6249 if(previous_sectdiff == FALSE){ 6250 if((cputype == CPU_TYPE_MC88000 && 6251 sr->r_type == M88K_RELOC_PAIR) || 6252 (cputype == CPU_TYPE_SPARC && 6253 sr->r_type == SPARC_RELOC_PAIR) || 6254 (cputype == CPU_TYPE_ARM && 6255 sr->r_type == ARM_RELOC_PAIR) || 6256 (cputype == CPU_TYPE_I860 && 6257 sr->r_type == I860_RELOC_PAIR)) 6258 printf(" half = 0x%04x ", 6259 (unsigned int)sr->r_address); 6260 else if(cputype == CPU_TYPE_HPPA && 6261 sr->r_type == HPPA_RELOC_PAIR) 6262 printf(" other_part = 0x%06x ", 6263 (unsigned int)sr->r_address); 6264 else if(((cputype == CPU_TYPE_POWERPC || 6265 cputype == CPU_TYPE_POWERPC64 || 6266 cputype == CPU_TYPE_VEO) && 6267 sr->r_type == PPC_RELOC_PAIR)){ 6268 if(previous_ppc_jbsr == FALSE) 6269 printf(" half = 0x%04x ", 6270 (unsigned int)reloc.r_address); 6271 else{ 6272 printf(" <- other_part "); 6273 } 6274 } 6275 } 6276 else if(cputype == CPU_TYPE_HPPA && 6277 (sectdiff_r_type == HPPA_RELOC_HI21_SECTDIFF || 6278 sectdiff_r_type == HPPA_RELOC_LO14_SECTDIFF)){ 6279 printf(" other_part = 0x%06x ", 6280 (unsigned int)sr->r_address); 6281 } 6282 else if(cputype == CPU_TYPE_SPARC && 6283 (sectdiff_r_type == SPARC_RELOC_HI22_SECTDIFF || 6284 sectdiff_r_type == SPARC_RELOC_LO10_SECTDIFF)){ 6285 printf(" other_part = 0x%06x ", 6286 (unsigned int)sr->r_address); 6287 } 6288 else if((cputype == CPU_TYPE_POWERPC || 6289 cputype == CPU_TYPE_POWERPC64 || 6290 cputype == CPU_TYPE_VEO) && 6291 (sectdiff_r_type == PPC_RELOC_HI16_SECTDIFF || 6292 sectdiff_r_type == PPC_RELOC_LO16_SECTDIFF || 6293 sectdiff_r_type == PPC_RELOC_LO14_SECTDIFF || 6294 sectdiff_r_type == PPC_RELOC_HA16_SECTDIFF)){ 6295 printf(" other_half = 0x%04x ", 6296 (unsigned int)sr->r_address); 6297 } 6298 else if(cputype == CPU_TYPE_ARM && 6299 sectdiff_r_type == ARM_RELOC_HALF_SECTDIFF){ 6300 printf(" other_half = 0x%04x ", 6301 (unsigned int)sr->r_address); 6302 } 6303 if((cputype == CPU_TYPE_MC680x0 && 6304 (sr->r_type == GENERIC_RELOC_SECTDIFF || 6305 sr->r_type == GENERIC_RELOC_LOCAL_SECTDIFF)) || 6306 (cputype == CPU_TYPE_I386 && 6307 (sr->r_type == GENERIC_RELOC_SECTDIFF || 6308 sr->r_type == GENERIC_RELOC_LOCAL_SECTDIFF)) || 6309 (cputype == CPU_TYPE_MC88000 && 6310 sr->r_type == M88K_RELOC_SECTDIFF) || 6311 ((cputype == CPU_TYPE_POWERPC || 6312 cputype == CPU_TYPE_POWERPC64 || 6313 cputype == CPU_TYPE_VEO) && 6314 (sr->r_type == PPC_RELOC_SECTDIFF || 6315 sr->r_type == PPC_RELOC_LOCAL_SECTDIFF || 6316 sr->r_type == PPC_RELOC_HI16_SECTDIFF || 6317 sr->r_type == PPC_RELOC_LO16_SECTDIFF || 6318 sr->r_type == PPC_RELOC_LO14_SECTDIFF || 6319 sr->r_type == PPC_RELOC_HA16_SECTDIFF)) || 6320 (cputype == CPU_TYPE_I860 && 6321 sr->r_type == I860_RELOC_SECTDIFF) || 6322 (cputype == CPU_TYPE_HPPA && 6323 (sr->r_type == HPPA_RELOC_SECTDIFF || 6324 sr->r_type == HPPA_RELOC_HI21_SECTDIFF || 6325 sr->r_type == HPPA_RELOC_LO14_SECTDIFF)) || 6326 (cputype == CPU_TYPE_ARM && 6327 (sr->r_type == ARM_RELOC_SECTDIFF || 6328 sr->r_type == ARM_RELOC_LOCAL_SECTDIFF || 6329 sr->r_type == ARM_RELOC_HALF_SECTDIFF)) || 6330 (cputype == CPU_TYPE_SPARC && 6331 (sr->r_type == SPARC_RELOC_SECTDIFF || 6332 sr->r_type == SPARC_RELOC_HI22_SECTDIFF || 6333 sr->r_type == SPARC_RELOC_LO10_SECTDIFF))){ 6334 previous_sectdiff = TRUE; 6335 sectdiff_r_type = sr->r_type; 6336 } 6337 else 6338 previous_sectdiff = FALSE; 6339 if(((cputype == CPU_TYPE_POWERPC || 6340 cputype == CPU_TYPE_POWERPC64 || 6341 cputype == CPU_TYPE_VEO) && 6342 sr->r_type == PPC_RELOC_JBSR)) 6343 previous_ppc_jbsr = TRUE; 6344 else 6345 previous_ppc_jbsr = FALSE; 6346 if(cputype == CPU_TYPE_ARM && 6347 (sr->r_type == ARM_RELOC_HALF || 6348 sr->r_type == ARM_RELOC_HALF_SECTDIFF)) 6349 previous_arm_half = TRUE; 6350 else 6351 previous_arm_half = FALSE; 6352 printf("\n"); 6353 } 6354 else{ 6355 printf("%08x %1d %-2d n/a %-7d 1 " 6356 "0x%08x\n", (unsigned int)sr->r_address, 6357 sr->r_pcrel, sr->r_length, sr->r_type, 6358 (unsigned int)sr->r_value); 6359 } 6360 } 6361 else{ 6362 if(verbose){ 6363 if((cputype == CPU_TYPE_MC88000 && 6364 reloc.r_type == M88K_RELOC_PAIR) || 6365 ((cputype == CPU_TYPE_POWERPC || 6366 cputype == CPU_TYPE_POWERPC64 || 6367 cputype == CPU_TYPE_VEO) && 6368 reloc.r_type == PPC_RELOC_PAIR) || 6369 (cputype == CPU_TYPE_HPPA && 6370 reloc.r_type == HPPA_RELOC_PAIR) || 6371 (cputype == CPU_TYPE_SPARC && 6372 reloc.r_type == SPARC_RELOC_PAIR) || 6373 (cputype == CPU_TYPE_ARM && 6374 reloc.r_type == ARM_RELOC_PAIR) || 6375 (cputype == CPU_TYPE_I860 && 6376 reloc.r_type == I860_RELOC_PAIR)) 6377 printf(" "); 6378 else 6379 printf("%08x ", (unsigned int)reloc.r_address); 6380 if(reloc.r_pcrel) 6381 printf("True "); 6382 else 6383 printf("False "); 6384 if(cputype == CPU_TYPE_ARM && 6385 (reloc.r_type == ARM_RELOC_HALF || 6386 reloc.r_type == ARM_RELOC_HALF_SECTDIFF || 6387 previous_arm_half == TRUE)){ 6388 if((reloc.r_length & 0x1) == 0) 6389 printf("lo/"); 6390 else 6391 printf("hi/"); 6392 if((reloc.r_length & 0x2) == 0) 6393 printf("arm "); 6394 else 6395 printf("thm "); 6396 } 6397 else{ 6398 switch(reloc.r_length){ 6399 case 0: 6400 printf("byte "); 6401 break; 6402 case 1: 6403 printf("word "); 6404 break; 6405 case 2: 6406 printf("long "); 6407 break; 6408 case 3: 6409 /* 6410 * The value of 3 for r_length for PowerPC is to 6411 * encode that a conditional branch using the Y-bit 6412 * for static branch prediction was predicted in 6413 * the assembly source. 6414 */ 6415 if((cputype == CPU_TYPE_POWERPC64 && 6416 reloc.r_type == PPC_RELOC_VANILLA) || 6417 cputype == CPU_TYPE_X86_64) { 6418 printf("quad "); 6419 } 6420 else if(cputype == CPU_TYPE_POWERPC || 6421 cputype == CPU_TYPE_POWERPC64 || 6422 cputype == CPU_TYPE_VEO){ 6423 printf("long "); 6424 predicted = TRUE; 6425 } 6426 else 6427 printf("?(%2d) ", reloc.r_length); 6428 break; 6429 default: 6430 printf("?(%2d) ", reloc.r_length); 6431 break; 6432 } 6433 } 6434 if(reloc.r_extern){ 6435 printf("True "); 6436 print_r_type(cputype, reloc.r_type, predicted); 6437 printf("False "); 6438 if((symbols == NULL && symbols64 == NULL) || 6439 strings == NULL || 6440 reloc.r_symbolnum > nsymbols) 6441 printf("?(%d)\n", reloc.r_symbolnum); 6442 else{ 6443 if(symbols != NULL) 6444 n_strx = symbols[reloc.r_symbolnum].n_un.n_strx; 6445 else 6446 n_strx = symbols64[reloc.r_symbolnum]. 6447 n_un.n_strx; 6448 if(n_strx > strings_size) 6449 printf("?(%d)\n", reloc.r_symbolnum); 6450 else 6451 printf("%s\n", strings + n_strx); 6452 } 6453 } 6454 else{ 6455 printf("False "); 6456 print_r_type(cputype, reloc.r_type, predicted); 6457 printf("False "); 6458 if((cputype == CPU_TYPE_I860 && 6459 reloc.r_type == I860_RELOC_PAIR) || 6460 (cputype == CPU_TYPE_MC88000 && 6461 reloc.r_type == M88K_RELOC_PAIR) ){ 6462 printf("half = 0x%04x\n", 6463 (unsigned int)reloc.r_address); 6464 } 6465 else if((cputype == CPU_TYPE_HPPA && 6466 reloc.r_type == HPPA_RELOC_PAIR) || 6467 (cputype == CPU_TYPE_SPARC && 6468 reloc.r_type == SPARC_RELOC_PAIR)){ 6469 printf(" other_part = 0x%06x\n", 6470 (unsigned int)reloc.r_address); 6471 } 6472 else if(((cputype == CPU_TYPE_POWERPC || 6473 cputype == CPU_TYPE_POWERPC64 || 6474 cputype == CPU_TYPE_VEO) && 6475 reloc.r_type == PPC_RELOC_PAIR)){ 6476 if(previous_ppc_jbsr == FALSE) 6477 printf("half = 0x%04x\n", 6478 (unsigned int)reloc.r_address); 6479 else 6480 printf("other_part = 0x%08x\n", 6481 (unsigned int)reloc.r_address); 6482 } 6483 else if(cputype == CPU_TYPE_ARM && 6484 reloc.r_type == ARM_RELOC_PAIR) 6485 printf("other_half = 0x%04x\n", 6486 (unsigned int)reloc.r_address); 6487 else{ 6488 printf("%d ", reloc.r_symbolnum); 6489 if(reloc.r_symbolnum > nsects + 1) 6490 printf("(?,?)\n"); 6491 else{ 6492 if(reloc.r_symbolnum == R_ABS) 6493 printf("R_ABS\n"); 6494 else 6495 printf("(%.16s,%.16s)\n", 6496 sect_rel[reloc.r_symbolnum-1].segname, 6497 sect_rel[reloc.r_symbolnum-1].sectname); 6498 } 6499 } 6500 } 6501 if(((cputype == CPU_TYPE_POWERPC || 6502 cputype == CPU_TYPE_POWERPC64 || 6503 cputype == CPU_TYPE_VEO) && 6504 reloc.r_type == PPC_RELOC_JBSR)) 6505 previous_ppc_jbsr = TRUE; 6506 else 6507 previous_ppc_jbsr = FALSE; 6508 if(cputype == CPU_TYPE_ARM && 6509 (reloc.r_type == ARM_RELOC_HALF || 6510 reloc.r_type == ARM_RELOC_HALF_SECTDIFF)) 6511 previous_arm_half = TRUE; 6512 else 6513 previous_arm_half = FALSE; 6514 } 6515 else{ 6516 printf("%08x %1d %-2d %1d %-7d 0" 6517 " %d\n", (unsigned int)reloc.r_address, 6518 reloc.r_pcrel, reloc.r_length, reloc.r_extern, 6519 reloc.r_type, reloc.r_symbolnum); 6520 } 6521 } 6522 } 6523} 6524 6525 6526static char *generic_r_types[] = { 6527 "VANILLA ", "PAIR ", "SECTDIF ", "PBLAPTR ", "LOCSDIF ", "TLV ", 6528 " 6 (?) ", " 7 (?) ", " 8 (?) ", " 9 (?) ", " 10 (?) ", " 11 (?) ", 6529 " 12 (?) ", " 13 (?) ", " 14 (?) ", " 15 (?) " 6530}; 6531static char *m88k_r_types[] = { 6532 "VANILLA ", "PAIR ", "PC16 ", "PC26 ", "HI16 ", "LO16 ", 6533 "SECTDIF ", "PBLAPTR ", " 8 (?) ", " 9 (?) ", " 10 (?) ", " 11 (?) ", 6534 " 12 (?) ", " 13 (?) ", " 14 (?) ", " 15 (?) " 6535}; 6536static char *i860_r_types[] = { 6537 "VANILLA ", "PAIR ", "HIGH ", "LOW0 ", "LOW1 ", "LOW2 ", 6538 "LOW3 ", "LOW4 ", "SPLIT0 ", "SPLIT1 ", "SPLIT2 ", "HIGHADJ ", 6539 "BRADDR ", "SECTDIF ", " 14 (?) ", " 15 (?) " 6540}; 6541static char *ppc_r_types[] = { 6542 "VANILLA ", "PAIR ", "BR14", "BR24 ", "HI16 ", "LO16 ", 6543 "HA16 ", "LO14 ", "SECTDIF ", "PBLAPTR ", "HI16DIF ", "LO16DIF ", 6544 "HA16DIF ", "JBSR ", "LO14DIF ", "LOCSDIF " 6545}; 6546static char *x86_64_r_types[] = { 6547 "UNSIGND ", "SIGNED ", "BRANCH ", "GOT_LD ", "GOT ", "SUB ", 6548 "SIGNED1 ", "SIGNED2 ", "SIGNED4 ", "TLV ", " 10 (?) ", " 11 (?) ", 6549 " 12 (?) ", " 13 (?) ", " 14 (?) ", " 15 (?) " 6550}; 6551static char *hppa_r_types[] = { 6552 "VANILLA ", "PAIR ", "HI21 ", "LO14 ", "BR17 ", 6553 "BL17 ", "JBSR ", "SECTDIF ", "HI21DIF ", "LO14DIF ", 6554 "PBLAPTR ", " 11 (?) ", " 12 (?) ", " 13 (?) ", " 14 (?) ", " 15 (?) " 6555}; 6556 6557static char *sparc_r_types[] = { 6558 "VANILLA ", "PAIR ", "HI22 ", "LO10 ", "DISP22 ", 6559 "DISP30 ", "SECTDIFF", "HI22DIFF", "LO10DIFF", "PBLAPTR ", 6560 " 10 (?) ", " 11 (?) ", " 12 (?) ", " 13 (?) ", " 14 (?) ", " 15 (?) " 6561}; 6562 6563static char *arm_r_types[] = { 6564 "VANILLA ", "PAIR ", "SECTDIFF", "LOCSDIF ", "PBLAPTR ", 6565 "BR24 ", "T_BR22 ", "T_BR32 ", "HALF ", "HALFDIF ", 6566 " 10 (?) ", " 11 (?) ", " 12 (?) ", " 13 (?) ", " 14 (?) ", " 15 (?) " 6567}; 6568 6569static 6570void 6571print_r_type( 6572cpu_type_t cputype, 6573uint32_t r_type, 6574enum bool predicted) 6575{ 6576 if(r_type > 0xf){ 6577 printf("%-7u ", r_type); 6578 return; 6579 } 6580 switch(cputype){ 6581 case CPU_TYPE_MC680x0: 6582 case CPU_TYPE_I386: 6583 printf("%s", generic_r_types[r_type]); 6584 break; 6585 case CPU_TYPE_X86_64: 6586 printf("%s", x86_64_r_types[r_type]); 6587 break; 6588 case CPU_TYPE_MC88000: 6589 printf("%s", m88k_r_types[r_type]); 6590 break; 6591 case CPU_TYPE_I860: 6592 printf("%s", i860_r_types[r_type]); 6593 break; 6594 case CPU_TYPE_POWERPC: 6595 case CPU_TYPE_POWERPC64: 6596 case CPU_TYPE_VEO: 6597 printf("%s", ppc_r_types[r_type]); 6598 if(r_type == PPC_RELOC_BR14){ 6599 if(predicted == TRUE) 6600 printf("+/- "); 6601 else 6602 printf(" "); 6603 } 6604 break; 6605 case CPU_TYPE_HPPA: 6606 printf("%s", hppa_r_types[r_type]); 6607 break; 6608 case CPU_TYPE_SPARC: 6609 printf("%s", sparc_r_types[r_type]); 6610 break; 6611 case CPU_TYPE_ARM: 6612 printf("%s", arm_r_types[r_type]); 6613 break; 6614 default: 6615 printf("%-7u ", r_type); 6616 } 6617} 6618 6619/* 6620 * Print the table of contents. 6621 */ 6622void 6623print_toc( 6624struct load_command *load_commands, 6625uint32_t ncmds, 6626uint32_t sizeofcmds, 6627enum byte_sex load_commands_byte_sex, 6628char *object_addr, 6629uint32_t object_size, 6630struct dylib_table_of_contents *tocs, 6631uint32_t ntocs, 6632struct dylib_module *mods, 6633struct dylib_module_64 *mods64, 6634uint32_t nmods, 6635struct nlist *symbols, 6636struct nlist_64 *symbols64, 6637uint32_t nsymbols, 6638char *strings, 6639uint32_t strings_size, 6640enum bool verbose) 6641{ 6642 uint32_t i; 6643 uint32_t n_strx; 6644 uint8_t n_type; 6645 6646 printf("Table of contents (%u entries)\n", ntocs); 6647 if(verbose) 6648 printf("module name symbol name\n"); 6649 else 6650 printf("module index symbol index\n"); 6651 for(i = 0; i < ntocs; i++){ 6652 if(verbose){ 6653 if(tocs[i].module_index > nmods) 6654 printf("%-16u (past the end of the module table) ", 6655 tocs[i].module_index); 6656 else if(mods != NULL){ 6657 if(mods[tocs[i].module_index].module_name > strings_size) 6658 printf("%-16u (string index past the end of string " 6659 "table) ", tocs[i].module_index); 6660 else 6661 printf("%-16s ", strings + 6662 mods[tocs[i].module_index].module_name); 6663 } 6664 else{ 6665 if(mods64[tocs[i].module_index].module_name > strings_size) 6666 printf("%-16u (string index past the end of string " 6667 "table) ", tocs[i].module_index); 6668 else 6669 printf("%-16s ", strings + 6670 mods64[tocs[i].module_index].module_name); 6671 } 6672 6673 if(tocs[i].symbol_index > nsymbols) 6674 printf("%u (past the end of the symbol table)\n", 6675 tocs[i].symbol_index); 6676 else{ 6677 if(symbols != NULL){ 6678 n_strx = symbols[tocs[i].symbol_index].n_un.n_strx; 6679 n_type = symbols[tocs[i].symbol_index].n_type; 6680 } 6681 else{ 6682 n_strx = symbols64[tocs[i].symbol_index].n_un.n_strx; 6683 n_type = symbols64[tocs[i].symbol_index].n_type; 6684 } 6685 if(n_strx > strings_size){ 6686 printf("%u (string index past the end of the string " 6687 "table)\n", tocs[i].symbol_index); 6688 } 6689 else{ 6690 printf("%s", strings + n_strx); 6691 if(n_type & N_EXT) 6692 printf("\n"); 6693 else 6694 printf(" [private]\n"); 6695 } 6696 } 6697 } 6698 else{ 6699 printf("%-12u %u\n", tocs[i].module_index, 6700 tocs[i].symbol_index); 6701 } 6702 } 6703} 6704 6705/* 6706 * Print the module table (32-bit). 6707 */ 6708void 6709print_module_table( 6710struct dylib_module *mods, 6711uint32_t nmods, 6712char *strings, 6713uint32_t strings_size, 6714enum bool verbose) 6715{ 6716 uint32_t i; 6717 6718 printf("Module table (%u entries)\n", nmods); 6719 for(i = 0; i < nmods; i++){ 6720 printf("module %u\n", i); 6721 if(verbose){ 6722 if(mods[i].module_name > strings_size) 6723 printf(" module_name = %u (past end of string table)\n", 6724 mods[i].module_name); 6725 else 6726 printf(" module_name = %s\n", 6727 strings + mods[i].module_name); 6728 } 6729 else{ 6730 if(mods[i].module_name > strings_size) 6731 printf(" module_name = %u (past end of string table)\n", 6732 mods[i].module_name); 6733 else 6734 printf(" module_name = %u\n", mods[i].module_name); 6735 } 6736 printf(" iextdefsym = %u\n", mods[i].iextdefsym); 6737 printf(" nextdefsym = %u\n", mods[i].nextdefsym); 6738 printf(" irefsym = %u\n", mods[i].irefsym); 6739 printf(" nrefsym = %u\n", mods[i].nrefsym); 6740 printf(" ilocalsym = %u\n", mods[i].ilocalsym); 6741 printf(" nlocalsym = %u\n", mods[i].nlocalsym); 6742 printf(" iextrel = %u\n", mods[i].iextrel); 6743 printf(" nextrel = %u\n", mods[i].nextrel); 6744 printf(" iinit_iterm = %u %u\n", 6745 mods[i].iinit_iterm & 0xffff, 6746 (mods[i].iinit_iterm >> 16) & 0xffff); 6747 printf(" ninit_nterm = %u %u\n", 6748 mods[i].ninit_nterm & 0xffff, 6749 (mods[i].ninit_nterm >> 16) & 0xffff); 6750 printf(" objc_addr = 0x%x\n", 6751 (unsigned int)mods[i].objc_module_info_addr); 6752 printf(" objc_size = %u\n", mods[i].objc_module_info_size); 6753 } 6754} 6755 6756/* 6757 * Print the module table (64-bit). 6758 */ 6759void 6760print_module_table_64( 6761struct dylib_module_64 *mods64, 6762uint32_t nmods, 6763char *strings, 6764uint32_t strings_size, 6765enum bool verbose) 6766{ 6767 uint32_t i; 6768 6769 printf("Module table (%u entries)\n", nmods); 6770 for(i = 0; i < nmods; i++){ 6771 printf("module %u\n", i); 6772 if(verbose){ 6773 if(mods64[i].module_name > strings_size) 6774 printf(" module_name = %u (past end of string table)\n", 6775 mods64[i].module_name); 6776 else 6777 printf(" module_name = %s\n", 6778 strings + mods64[i].module_name); 6779 } 6780 else{ 6781 if(mods64[i].module_name > strings_size) 6782 printf(" module_name = %u (past end of string table)\n", 6783 mods64[i].module_name); 6784 else 6785 printf(" module_name = %u\n", mods64[i].module_name); 6786 } 6787 printf(" iextdefsym = %u\n", mods64[i].iextdefsym); 6788 printf(" nextdefsym = %u\n", mods64[i].nextdefsym); 6789 printf(" irefsym = %u\n", mods64[i].irefsym); 6790 printf(" nrefsym = %u\n", mods64[i].nrefsym); 6791 printf(" ilocalsym = %u\n", mods64[i].ilocalsym); 6792 printf(" nlocalsym = %u\n", mods64[i].nlocalsym); 6793 printf(" iextrel = %u\n", mods64[i].iextrel); 6794 printf(" nextrel = %u\n", mods64[i].nextrel); 6795 printf(" iinit_iterm = %u %u\n", 6796 mods64[i].iinit_iterm & 0xffff, 6797 (mods64[i].iinit_iterm >> 16) & 0xffff); 6798 printf(" ninit_nterm = %u %u\n", 6799 mods64[i].ninit_nterm & 0xffff, 6800 (mods64[i].ninit_nterm >> 16) & 0xffff); 6801 printf(" objc_addr = 0x%016llx\n", 6802 mods64[i].objc_module_info_addr); 6803 printf(" objc_size = %u\n", mods64[i].objc_module_info_size); 6804 } 6805} 6806 6807/* 6808 * Print the reference table. 6809 */ 6810void 6811print_refs( 6812struct dylib_reference *refs, 6813uint32_t nrefs, 6814struct dylib_module *mods, 6815struct dylib_module_64 *mods64, 6816uint32_t nmods, 6817struct nlist *symbols, 6818struct nlist_64 *symbols64, 6819uint32_t nsymbols, 6820char *strings, 6821uint32_t strings_size, 6822enum bool verbose) 6823{ 6824 uint32_t i, j; 6825 uint32_t module_name, irefsym, nrefsym, n_strx; 6826 uint64_t big_size; 6827 6828 printf("Reference table (%u entries)\n", nrefs); 6829 for(i = 0; i < nmods; i++){ 6830 if(mods != NULL){ 6831 module_name = mods[i].module_name; 6832 irefsym = mods[i].irefsym; 6833 nrefsym = mods[i].nrefsym; 6834 } 6835 else{ 6836 module_name = mods64[i].module_name; 6837 irefsym = mods64[i].irefsym; 6838 nrefsym = mods64[i].nrefsym; 6839 } 6840 if(verbose){ 6841 if(module_name > strings_size) 6842 printf(" module %u (past end of string table)", 6843 module_name); 6844 else 6845 printf(" module %s", strings + module_name); 6846 } 6847 else{ 6848 printf(" module %u", module_name); 6849 } 6850 if(irefsym > nrefs){ 6851 printf(" %u entries, at index %u (past end of reference " 6852 "table)\n", nrefsym, irefsym); 6853 continue; 6854 } 6855 big_size = irefsym; 6856 big_size += nrefsym; 6857 if(big_size > nrefs) 6858 printf(" %u entries (extends past the end of the reference " 6859 "table), at index %u\n", nrefsym, irefsym); 6860 else 6861 printf(" %u entries, at index %u\n", nrefsym, irefsym); 6862 for(j = irefsym; 6863 j - irefsym < nrefsym && j < nrefs; 6864 j++){ 6865 if(refs[j].isym > nsymbols) 6866 printf("\t%u (past the end of the symbol table) ", 6867 refs[j].isym); 6868 else{ 6869 if(verbose){ 6870 if(refs[j].isym > nsymbols) 6871 printf("\t%u (past the end of the symbol table) ", 6872 refs[j].isym); 6873 else{ 6874 if(symbols != NULL) 6875 n_strx = symbols[refs[j].isym].n_un.n_strx; 6876 else 6877 n_strx = symbols64[refs[j].isym].n_un.n_strx; 6878 if(n_strx > strings_size) 6879 printf("\t%u (string index past the end of the " 6880 "string table) ", refs[j].isym); 6881 else 6882 printf("\t%s ", strings + n_strx); 6883 } 6884 } 6885 else 6886 printf("\tisym %u ", refs[j].isym); 6887 } 6888 if(verbose){ 6889 switch(refs[j].flags){ 6890 case REFERENCE_FLAG_UNDEFINED_NON_LAZY: 6891 printf("undefined [non-lazy]\n"); 6892 break; 6893 case REFERENCE_FLAG_UNDEFINED_LAZY: 6894 printf("undefined [lazy]\n"); 6895 break; 6896 case REFERENCE_FLAG_DEFINED: 6897 printf("defined\n"); 6898 break; 6899 case REFERENCE_FLAG_PRIVATE_DEFINED: 6900 printf("private defined\n"); 6901 break; 6902 case REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY: 6903 printf("private undefined [non-lazy]\n"); 6904 break; 6905 case REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY: 6906 printf("private undefined [lazy]\n"); 6907 break; 6908 default: 6909 printf("%u\n", (unsigned int)refs[j].flags); 6910 break; 6911 } 6912 } 6913 else 6914 printf("flags %u\n", (unsigned int)refs[j].flags); 6915 } 6916 } 6917} 6918 6919/* 6920 * Print the indirect symbol table. 6921 */ 6922void 6923print_indirect_symbols( 6924struct load_command *load_commands, 6925uint32_t ncmds, 6926uint32_t sizeofcmds, 6927cpu_type_t cputype, 6928enum byte_sex load_commands_byte_sex, 6929uint32_t *indirect_symbols, 6930uint32_t nindirect_symbols, 6931struct nlist *symbols, 6932struct nlist_64 *symbols64, 6933uint32_t nsymbols, 6934char *strings, 6935uint32_t strings_size, 6936enum bool verbose) 6937{ 6938 enum byte_sex host_byte_sex; 6939 enum bool swapped; 6940 uint32_t i, j, k, left, size, nsects, n, count, stride, section_type; 6941 uint64_t bigsize, big_load_end; 6942 char *p; 6943 struct load_command *lc, l; 6944 struct segment_command sg; 6945 struct section s; 6946 struct segment_command_64 sg64; 6947 struct section_64 s64; 6948 struct section_indirect_info { 6949 char segname[16]; 6950 char sectname[16]; 6951 uint64_t size; 6952 uint64_t addr; 6953 uint32_t reserved1; 6954 uint32_t reserved2; 6955 uint32_t flags; 6956 } *sect_ind; 6957 uint32_t n_strx; 6958 6959 sect_ind = NULL; 6960 host_byte_sex = get_host_byte_sex(); 6961 swapped = host_byte_sex != load_commands_byte_sex; 6962 6963 /* 6964 * Create an array of section structures in the host byte sex so it 6965 * can be processed and indexed into directly. 6966 */ 6967 k = 0; 6968 nsects = 0; 6969 lc = load_commands; 6970 big_load_end = 0; 6971 for(i = 0 ; i < ncmds; i++){ 6972 memcpy((char *)&l, (char *)lc, sizeof(struct load_command)); 6973 if(swapped) 6974 swap_load_command(&l, host_byte_sex); 6975 if(l.cmdsize % sizeof(int32_t) != 0) 6976 printf("load command %u size not a multiple of " 6977 "sizeof(int32_t)\n", i); 6978 big_load_end += l.cmdsize; 6979 if(big_load_end > sizeofcmds) 6980 printf("load command %u extends past end of load " 6981 "commands\n", i); 6982 left = sizeofcmds - ((char *)lc - (char *)load_commands); 6983 6984 switch(l.cmd){ 6985 case LC_SEGMENT: 6986 memset((char *)&sg, '\0', sizeof(struct segment_command)); 6987 size = left < sizeof(struct segment_command) ? 6988 left : sizeof(struct segment_command); 6989 left -= size; 6990 memcpy((char *)&sg, (char *)lc, size); 6991 if(swapped) 6992 swap_segment_command(&sg, host_byte_sex); 6993 bigsize = sg.nsects; 6994 bigsize *= sizeof(struct section); 6995 bigsize += size; 6996 if(bigsize > sg.cmdsize){ 6997 printf("number of sections in load command %u extends " 6998 "past end of load commands\n", i); 6999 sg.nsects = (sg.cmdsize-size) / sizeof(struct section); 7000 } 7001 nsects += sg.nsects; 7002 sect_ind = reallocate(sect_ind, 7003 nsects * sizeof(struct section_indirect_info)); 7004 memset((char *)(sect_ind + (nsects - sg.nsects)), '\0', 7005 sizeof(struct section_indirect_info) * sg.nsects); 7006 p = (char *)lc + sizeof(struct segment_command); 7007 for(j = 0 ; j < sg.nsects ; j++){ 7008 left = sizeofcmds - (p - (char *)load_commands); 7009 size = left < sizeof(struct section) ? 7010 left : sizeof(struct section); 7011 memcpy((char *)&s, p, size); 7012 if(swapped) 7013 swap_section(&s, 1, host_byte_sex); 7014 7015 if(p + sizeof(struct section) > 7016 (char *)load_commands + sizeofcmds) 7017 break; 7018 p += size; 7019 memcpy(sect_ind[k].segname, s.segname, 16); 7020 memcpy(sect_ind[k].sectname, s.sectname, 16); 7021 sect_ind[k].size = s.size; 7022 sect_ind[k].addr = s.addr; 7023 sect_ind[k].reserved1 = s.reserved1; 7024 sect_ind[k].reserved2 = s.reserved2; 7025 sect_ind[k].flags = s.flags; 7026 k++; 7027 } 7028 break; 7029 case LC_SEGMENT_64: 7030 memset((char *)&sg64, '\0', sizeof(struct segment_command_64)); 7031 size = left < sizeof(struct segment_command_64) ? 7032 left : sizeof(struct segment_command_64); 7033 memcpy((char *)&sg64, (char *)lc, size); 7034 if(swapped) 7035 swap_segment_command_64(&sg64, host_byte_sex); 7036 bigsize = sg64.nsects; 7037 bigsize *= sizeof(struct section_64); 7038 bigsize += size; 7039 if(bigsize > sg64.cmdsize){ 7040 printf("number of sections in load command %u extends " 7041 "past end of load commands\n", i); 7042 sg64.nsects = (sg64.cmdsize-size) / 7043 sizeof(struct section_64); 7044 } 7045 nsects += sg64.nsects; 7046 sect_ind = reallocate(sect_ind, 7047 nsects * sizeof(struct section_indirect_info)); 7048 memset((char *)(sect_ind + (nsects - sg64.nsects)), '\0', 7049 sizeof(struct section_indirect_info) * sg64.nsects); 7050 p = (char *)lc + sizeof(struct segment_command_64); 7051 for(j = 0 ; j < sg64.nsects ; j++){ 7052 left = sizeofcmds - (p - (char *)load_commands); 7053 size = left < sizeof(struct section_64) ? 7054 left : sizeof(struct section_64); 7055 memcpy((char *)&s64, p, size); 7056 if(swapped) 7057 swap_section_64(&s64, 1, host_byte_sex); 7058 7059 if(p + sizeof(struct section) > 7060 (char *)load_commands + sizeofcmds) 7061 break; 7062 p += size; 7063 memcpy(sect_ind[k].segname, s64.segname, 16); 7064 memcpy(sect_ind[k].sectname, s64.sectname, 16); 7065 sect_ind[k].size = s64.size; 7066 sect_ind[k].addr = s64.addr; 7067 sect_ind[k].reserved1 = s64.reserved1; 7068 sect_ind[k].reserved2 = s64.reserved2; 7069 sect_ind[k].flags = s64.flags; 7070 k++; 7071 } 7072 break; 7073 } 7074 if(l.cmdsize == 0){ 7075 printf("load command %u size zero (can't advance to other " 7076 "load commands)\n", i); 7077 break; 7078 } 7079 lc = (struct load_command *)((char *)lc + l.cmdsize); 7080 if((char *)lc > (char *)load_commands + sizeofcmds) 7081 break; 7082 } 7083 if((char *)load_commands + sizeofcmds != (char *)lc) 7084 printf("Inconsistent sizeofcmds\n"); 7085 7086 for(i = 0 ; i < nsects ; i++){ 7087 section_type = sect_ind[i].flags & SECTION_TYPE; 7088 if(section_type == S_SYMBOL_STUBS){ 7089 stride = sect_ind[i].reserved2; 7090 if(stride == 0){ 7091 printf("Can't print indirect symbols for (%.16s,%.16s) " 7092 "(size of stubs in reserved2 field is zero)\n", 7093 sect_ind[i].segname, sect_ind[i].sectname); 7094 continue; 7095 } 7096 } 7097 else if(section_type == S_LAZY_SYMBOL_POINTERS || 7098 section_type == S_NON_LAZY_SYMBOL_POINTERS || 7099 section_type == S_LAZY_DYLIB_SYMBOL_POINTERS || 7100 section_type == S_THREAD_LOCAL_VARIABLE_POINTERS){ 7101 if(cputype & CPU_ARCH_ABI64) 7102 stride = 8; 7103 else 7104 stride = 4; 7105 } 7106 else 7107 continue; 7108 7109 count = sect_ind[i].size / stride; 7110 printf("Indirect symbols for (%.16s,%.16s) %u entries", 7111 sect_ind[i].segname, sect_ind[i].sectname, 7112 count); 7113 7114 n = sect_ind[i].reserved1; 7115 if(n > nindirect_symbols) 7116 printf(" (entries start past the end of the indirect symbol " 7117 "table) (reserved1 field greater than the table size)"); 7118 else if(n + count > nindirect_symbols) 7119 printf(" (entries extends past the end of the indirect symbol " 7120 "table)"); 7121 if(cputype & CPU_ARCH_ABI64) 7122 printf("\naddress index"); 7123 else 7124 printf("\naddress index"); 7125 if(verbose) 7126 printf(" name\n"); 7127 else 7128 printf("\n"); 7129 7130 for(j = 0 ; j < count && n + j < nindirect_symbols; j++){ 7131 if(cputype & CPU_ARCH_ABI64) 7132 printf("0x%016llx ", sect_ind[i].addr + j * stride); 7133 else 7134 printf("0x%08x ",(uint32_t) 7135 (sect_ind[i].addr + j * stride)); 7136 if(indirect_symbols[j + n] == INDIRECT_SYMBOL_LOCAL){ 7137 printf("LOCAL\n"); 7138 continue; 7139 } 7140 if(indirect_symbols[j + n] == 7141 (INDIRECT_SYMBOL_LOCAL | INDIRECT_SYMBOL_ABS)){ 7142 printf("LOCAL ABSOLUTE\n"); 7143 continue; 7144 } 7145 if(indirect_symbols[j + n] == INDIRECT_SYMBOL_ABS){ 7146 /* 7147 * Used for unused slots in the i386 __jump_table 7148 * and for image-loader-cache slot for new lazy 7149 * symbol binding in Mac OS X 10.6 and later 7150 */ 7151 printf("ABSOLUTE\n"); 7152 continue; 7153 } 7154 printf("%5u ", indirect_symbols[j + n]); 7155 if(verbose){ 7156 if(indirect_symbols[j + n] >= nsymbols || 7157 (symbols == NULL && symbols64 == NULL) || 7158 strings == NULL) 7159 printf("?\n"); 7160 else{ 7161 if(symbols != NULL) 7162 n_strx = symbols[indirect_symbols[j+n]].n_un.n_strx; 7163 else 7164 n_strx = symbols64[indirect_symbols[j+n]]. 7165 n_un.n_strx; 7166 if(n_strx >= strings_size) 7167 printf("?\n"); 7168 else 7169 printf("%s\n", strings + n_strx); 7170 } 7171 } 7172 else 7173 printf("\n"); 7174 } 7175 n += count; 7176 } 7177} 7178 7179void 7180print_hints( 7181struct load_command *load_commands, 7182uint32_t ncmds, 7183uint32_t sizeofcmds, 7184enum byte_sex load_commands_byte_sex, 7185struct twolevel_hint *hints, 7186uint32_t nhints, 7187struct nlist *symbols, 7188struct nlist_64 *symbols64, 7189uint32_t nsymbols, 7190char *strings, 7191uint32_t strings_size, 7192enum bool verbose) 7193{ 7194 enum byte_sex host_byte_sex; 7195 enum bool swapped, is_framework; 7196 uint32_t i, left, size, nlibs, dyst_cmd, lib_ord; 7197 char *p, **libs, *short_name, *has_suffix; 7198 struct load_command *lc, l; 7199 struct dysymtab_command dyst; 7200 struct dylib_command dl; 7201 uint32_t n_strx; 7202 uint16_t n_desc; 7203 uint64_t big_load_end; 7204 7205 host_byte_sex = get_host_byte_sex(); 7206 swapped = host_byte_sex != load_commands_byte_sex; 7207 7208 /* 7209 * If verbose is TRUE create an array of load dylibs names so it 7210 * indexed into directly. 7211 */ 7212 nlibs = 0; 7213 libs = NULL; 7214 dyst_cmd = UINT_MAX; 7215 lc = load_commands; 7216 big_load_end = 0; 7217 memset((char *)&dyst, '\0', sizeof(struct dysymtab_command)); 7218 for(i = 0 ; verbose == TRUE && i < ncmds; i++){ 7219 memcpy((char *)&l, (char *)lc, sizeof(struct load_command)); 7220 if(swapped) 7221 swap_load_command(&l, host_byte_sex); 7222 if(l.cmdsize % sizeof(int32_t) != 0) 7223 printf("load command %u size not a multiple of " 7224 "sizeof(int32_t)\n", i); 7225 big_load_end += l.cmdsize; 7226 if(big_load_end > sizeofcmds) 7227 printf("load command %u extends past end of load " 7228 "commands\n", i); 7229 left = sizeofcmds - ((char *)lc - (char *)load_commands); 7230 7231 switch(l.cmd){ 7232 case LC_DYSYMTAB: 7233 if(dyst_cmd != UINT_MAX){ 7234 printf("more than one LC_DYSYMTAB command (using command " 7235 "%u)\n", dyst_cmd); 7236 break; 7237 } 7238 size = left < sizeof(struct dysymtab_command) ? 7239 left : sizeof(struct dysymtab_command); 7240 memcpy((char *)&dyst, (char *)lc, size); 7241 if(swapped) 7242 swap_dysymtab_command(&dyst, host_byte_sex); 7243 dyst_cmd = i; 7244 break; 7245 7246 case LC_LOAD_DYLIB: 7247 case LC_LOAD_WEAK_DYLIB: 7248 case LC_REEXPORT_DYLIB: 7249 case LC_LOAD_UPWARD_DYLIB: 7250 case LC_LAZY_LOAD_DYLIB: 7251 memset((char *)&dl, '\0', sizeof(struct dylib_command)); 7252 size = left < sizeof(struct dylib_command) ? 7253 left : sizeof(struct dylib_command); 7254 memcpy((char *)&dl, (char *)lc, size); 7255 if(swapped) 7256 swap_dylib_command(&dl, host_byte_sex); 7257 if(dl.dylib.name.offset < dl.cmdsize){ 7258 p = (char *)lc + dl.dylib.name.offset; 7259 short_name = guess_short_name(p, &is_framework, 7260 &has_suffix); 7261 if(short_name != NULL) 7262 p = short_name; 7263 } 7264 else{ 7265 p = "bad dylib.name.offset"; 7266 } 7267 libs = reallocate(libs, (nlibs+1) * sizeof(char *)); 7268 libs[nlibs] = p; 7269 nlibs++; 7270 break; 7271 } 7272 if(l.cmdsize == 0){ 7273 printf("load command %u size zero (can't advance to other " 7274 "load commands)\n", i); 7275 break; 7276 } 7277 lc = (struct load_command *)((char *)lc + l.cmdsize); 7278 if((char *)lc > (char *)load_commands + sizeofcmds) 7279 break; 7280 } 7281 if(verbose == TRUE && 7282 (char *)load_commands + sizeofcmds != (char *)lc) 7283 printf("Inconsistent sizeofcmds\n"); 7284 7285 printf("Two-level namespace hints table (%u hints)\n", nhints); 7286 printf("index isub itoc\n"); 7287 for(i = 0; i < nhints; i++){ 7288 printf("%5u %5d %5u", i, (int)hints[i].isub_image, hints[i].itoc); 7289 if(verbose){ 7290 if(dyst_cmd != UINT_MAX && 7291 dyst.iundefsym + i < nsymbols){ 7292 if(symbols != NULL){ 7293 n_strx = symbols[dyst.iundefsym + i].n_un.n_strx; 7294 n_desc = symbols[dyst.iundefsym + i].n_desc; 7295 } 7296 else{ 7297 n_strx = symbols64[dyst.iundefsym + i].n_un.n_strx; 7298 n_desc = symbols64[dyst.iundefsym + i].n_desc; 7299 } 7300 if(n_strx > strings_size) 7301 printf(" (bad string index in symbol %u)\n", 7302 dyst.iundefsym + i); 7303 else{ 7304 printf(" %s", strings + n_strx); 7305 lib_ord = GET_LIBRARY_ORDINAL(n_desc); 7306 if(lib_ord != SELF_LIBRARY_ORDINAL && 7307 lib_ord - 1 < nlibs) 7308 printf(" (from %s)\n", libs[lib_ord - 1]); 7309 else 7310 printf("\n"); 7311 } 7312 } 7313 else 7314 printf("\n"); 7315 } 7316 else 7317 printf("\n"); 7318 } 7319} 7320 7321void 7322print_dices( 7323struct data_in_code_entry *dices, 7324uint32_t ndices, 7325enum bool verbose) 7326{ 7327 uint32_t i; 7328 7329 printf("Data in code table (%u entries)\n", ndices); 7330 printf("offset length kind\n"); 7331 for(i = 0; i < ndices; i++){ 7332 printf("0x%08x %6u ", (unsigned)dices[i].offset, dices[i].length); 7333 if(verbose){ 7334 switch(dices[i].kind){ 7335 case DICE_KIND_DATA: 7336 printf("DATA"); 7337 break; 7338 case DICE_KIND_JUMP_TABLE8: 7339 printf("JUMP_TABLE8"); 7340 break; 7341 case DICE_KIND_JUMP_TABLE16: 7342 printf("JUMP_TABLE16"); 7343 break; 7344 case DICE_KIND_JUMP_TABLE32: 7345 printf("JUMP_TABLE32"); 7346 break; 7347 case DICE_KIND_ABS_JUMP_TABLE32: 7348 printf("ABS_JUMP_TABLE32"); 7349 break; 7350 default: 7351 printf("0x%04x", (unsigned)dices[i].kind); 7352 break; 7353 } 7354 } 7355 else 7356 printf("0x%04x", (unsigned)dices[i].kind); 7357 printf("\n"); 7358 } 7359} 7360 7361void 7362print_cstring_section( 7363cpu_type_t cputype, 7364char *sect, 7365uint32_t sect_size, 7366uint64_t sect_addr, 7367enum bool print_addresses) 7368{ 7369 uint32_t i; 7370 7371 for(i = 0; i < sect_size ; i++){ 7372 if(print_addresses == TRUE){ 7373 if(cputype & CPU_ARCH_ABI64) 7374 printf("0x%016llx ", sect_addr + i); 7375 else 7376 printf("%08x ", (unsigned int)(sect_addr + i)); 7377 } 7378 7379 for( ; i < sect_size && sect[i] != '\0'; i++) 7380 print_cstring_char(sect[i]); 7381 if(i < sect_size && sect[i] == '\0') 7382 printf("\n"); 7383 } 7384} 7385 7386static 7387void 7388print_cstring_char( 7389char c) 7390{ 7391 if(isprint(c)){ 7392 if(c == '\\') /* backslash */ 7393 printf("\\\\"); 7394 else /* all other printable characters */ 7395 printf("%c", c); 7396 } 7397 else{ 7398 switch(c){ 7399 case '\n': /* newline */ 7400 printf("\\n"); 7401 break; 7402 case '\t': /* tab */ 7403 printf("\\t"); 7404 break; 7405 case '\v': /* vertical tab */ 7406 printf("\\v"); 7407 break; 7408 case '\b': /* backspace */ 7409 printf("\\b"); 7410 break; 7411 case '\r': /* carriage return */ 7412 printf("\\r"); 7413 break; 7414 case '\f': /* formfeed */ 7415 printf("\\f"); 7416 break; 7417 case '\a': /* audiable alert */ 7418 printf("\\a"); 7419 break; 7420 default: 7421 printf("\\%03o", (unsigned int)c); 7422 } 7423 } 7424} 7425 7426void 7427print_literal4_section( 7428char *sect, 7429uint32_t sect_size, 7430uint32_t sect_addr, 7431enum byte_sex literal_byte_sex, 7432enum bool print_addresses) 7433{ 7434 enum byte_sex host_byte_sex; 7435 enum bool swapped; 7436 uint32_t i, l; 7437 float f; 7438 7439 host_byte_sex = get_host_byte_sex(); 7440 swapped = host_byte_sex != literal_byte_sex; 7441 7442 for(i = 0; i < sect_size ; i += sizeof(float)){ 7443 if(print_addresses == TRUE) 7444 printf("%08x ", (unsigned int)(sect_addr + i)); 7445 memcpy((char *)&f, sect + i, sizeof(float)); 7446 memcpy((char *)&l, sect + i, sizeof(uint32_t)); 7447 if(swapped){ 7448 f = SWAP_FLOAT(f); 7449 l = SWAP_INT(l); 7450 } 7451 print_literal4(l, f); 7452 } 7453} 7454 7455static 7456void 7457print_literal4( 7458uint32_t l, 7459float f) 7460{ 7461 printf("0x%08x", (unsigned int)l); 7462 if((l & 0x7f800000) != 0x7f800000){ 7463 printf(" (%.16e)\n", f); 7464 } 7465 else{ 7466 if(l == 0x7f800000) 7467 printf(" (+Infinity)\n"); 7468 else if(l == 0xff800000) 7469 printf(" (-Infinity)\n"); 7470 else if((l & 0x00400000) == 0x00400000) 7471 printf(" (non-signaling Not-a-Number)\n"); 7472 else 7473 printf(" (signaling Not-a-Number)\n"); 7474 } 7475} 7476 7477void 7478print_literal8_section( 7479char *sect, 7480uint32_t sect_size, 7481uint32_t sect_addr, 7482enum byte_sex literal_byte_sex, 7483enum bool print_addresses) 7484{ 7485 enum byte_sex host_byte_sex; 7486 enum bool swapped; 7487 uint32_t i, l0, l1; 7488 double d; 7489 7490 host_byte_sex = get_host_byte_sex(); 7491 swapped = host_byte_sex != literal_byte_sex; 7492 7493 for(i = 0; i < sect_size ; i += sizeof(double)){ 7494 if(print_addresses == TRUE) 7495 printf("%08x ", (unsigned int)(sect_addr + i)); 7496 memcpy((char *)&d, sect + i, sizeof(double)); 7497 memcpy((char *)&l0, sect + i, sizeof(uint32_t)); 7498 memcpy((char *)&l1, sect + i + sizeof(uint32_t), 7499 sizeof(uint32_t)); 7500 if(swapped){ 7501 d = SWAP_DOUBLE(d); 7502 l0 = SWAP_INT(l0); 7503 l1 = SWAP_INT(l1); 7504 } 7505 print_literal8(l0, l1, d); 7506 } 7507} 7508 7509static 7510void 7511print_literal8( 7512uint32_t l0, 7513uint32_t l1, 7514double d) 7515{ 7516 printf("0x%08x 0x%08x", (unsigned int)l0, (unsigned int)l1); 7517 /* l0 is the high word, so this is equivalent to if(isfinite(d)) */ 7518 if((l0 & 0x7ff00000) != 0x7ff00000) 7519 printf(" (%.16e)\n", d); 7520 else{ 7521 if(l0 == 0x7ff00000 && l1 == 0) 7522 printf(" (+Infinity)\n"); 7523 else if(l0 == 0xfff00000 && l1 == 0) 7524 printf(" (-Infinity)\n"); 7525 else if((l0 & 0x00080000) == 0x00080000) 7526 printf(" (non-signaling Not-a-Number)\n"); 7527 else 7528 printf(" (signaling Not-a-Number)\n"); 7529 } 7530} 7531 7532void 7533print_literal16_section( 7534char *sect, 7535uint32_t sect_size, 7536uint32_t sect_addr, 7537enum byte_sex literal_byte_sex, 7538enum bool print_addresses) 7539{ 7540 enum byte_sex host_byte_sex; 7541 enum bool swapped; 7542 uint32_t i, l0, l1, l2, l3; 7543 7544 host_byte_sex = get_host_byte_sex(); 7545 swapped = host_byte_sex != literal_byte_sex; 7546 7547 for(i = 0; i < sect_size ; i += 4 * sizeof(uint32_t)){ 7548 if(print_addresses == TRUE) 7549 printf("%08x ", (unsigned int)(sect_addr + i)); 7550 memcpy((char *)&l0, sect + i, sizeof(uint32_t)); 7551 memcpy((char *)&l1, sect + i + sizeof(uint32_t), 7552 sizeof(uint32_t)); 7553 memcpy((char *)&l2, sect + i + 2 * sizeof(uint32_t), 7554 sizeof(uint32_t)); 7555 memcpy((char *)&l3, sect + i + 3 * sizeof(uint32_t), 7556 sizeof(uint32_t)); 7557 if(swapped){ 7558 l0 = SWAP_INT(l0); 7559 l1 = SWAP_INT(l1); 7560 l2 = SWAP_INT(l2); 7561 l3 = SWAP_INT(l3); 7562 } 7563 print_literal16(l0, l1, l2, l3); 7564 } 7565} 7566 7567static 7568void 7569print_literal16( 7570uint32_t l0, 7571uint32_t l1, 7572uint32_t l2, 7573uint32_t l3) 7574{ 7575 printf("0x%08x 0x%08x 0x%08x 0x%08x\n", (unsigned int)l0,\ 7576 (unsigned int)l1, (unsigned int)l2, (unsigned int)l3); 7577} 7578 7579void 7580print_literal_pointer_section( 7581cpu_type_t cputype, 7582struct load_command *load_commands, 7583uint32_t ncmds, 7584uint32_t sizeofcmds, 7585enum byte_sex object_byte_sex, 7586char *object_addr, 7587uint32_t object_size, 7588char *sect, 7589uint32_t sect_size, 7590uint64_t sect_addr, 7591struct nlist *symbols, 7592struct nlist_64 *symbols64, 7593uint32_t nsymbols, 7594char *strings, 7595uint32_t strings_size, 7596struct relocation_info *relocs, 7597uint32_t nrelocs, 7598enum bool print_addresses) 7599{ 7600 enum byte_sex host_byte_sex; 7601 enum bool swapped, found; 7602 uint32_t i, j, k, li, l0, l1, l2, l3, left, size, lp_size; 7603 uint64_t lp; 7604 struct load_command lcmd, *lc; 7605 struct segment_command sg; 7606 struct section s; 7607 struct segment_command_64 sg64; 7608 struct section_64 s64; 7609 struct literal_section { 7610 char segname[16]; 7611 char sectname[16]; 7612 uint64_t addr; 7613 uint32_t flags; 7614 char *contents; 7615 uint32_t size; 7616 } *literal_sections; 7617 char *p; 7618 uint32_t nliteral_sections; 7619 float f; 7620 double d; 7621 struct relocation_info *reloc; 7622 uint32_t n_strx; 7623 uint64_t big_load_end, big_size; 7624 7625 host_byte_sex = get_host_byte_sex(); 7626 swapped = host_byte_sex != object_byte_sex; 7627 7628 literal_sections = NULL; 7629 nliteral_sections = 0; 7630 7631 lc = load_commands; 7632 big_load_end = 0; 7633 for(i = 0 ; i < ncmds; i++){ 7634 memcpy((char *)&lcmd, (char *)lc, sizeof(struct load_command)); 7635 if(swapped) 7636 swap_load_command(&lcmd, host_byte_sex); 7637 if(lcmd.cmdsize % sizeof(int32_t) != 0) 7638 printf("load command %u size not a multiple of " 7639 "sizeof(int32_t)\n", i); 7640 big_load_end += lcmd.cmdsize; 7641 if(big_load_end > sizeofcmds) 7642 printf("load command %u extends past end of load " 7643 "commands\n", i); 7644 left = sizeofcmds - ((char *)lc - (char *)load_commands); 7645 7646 switch(lcmd.cmd){ 7647 case LC_SEGMENT: 7648 memset((char *)&sg, '\0', sizeof(struct segment_command)); 7649 size = left < sizeof(struct segment_command) ? 7650 left : sizeof(struct segment_command); 7651 memcpy((char *)&sg, (char *)lc, size); 7652 if(swapped) 7653 swap_segment_command(&sg, host_byte_sex); 7654 7655 p = (char *)lc + sizeof(struct segment_command); 7656 for(j = 0 ; j < sg.nsects ; j++){ 7657 if(p + sizeof(struct section) > 7658 (char *)load_commands + sizeofcmds){ 7659 printf("section structure command extends past " 7660 "end of load commands\n"); 7661 } 7662 left = sizeofcmds - (p - (char *)load_commands); 7663 memset((char *)&s, '\0', sizeof(struct section)); 7664 size = left < sizeof(struct section) ? 7665 left : sizeof(struct section); 7666 memcpy((char *)&s, p, size); 7667 if(swapped) 7668 swap_section(&s, 1, host_byte_sex); 7669 7670 if(s.flags == S_CSTRING_LITERALS || 7671 s.flags == S_4BYTE_LITERALS || 7672 s.flags == S_8BYTE_LITERALS || 7673 s.flags == S_16BYTE_LITERALS){ 7674 literal_sections = reallocate(literal_sections, 7675 sizeof(struct literal_section) * 7676 (nliteral_sections + 1)); 7677 memcpy(literal_sections[nliteral_sections].segname, 7678 s.segname, 16); 7679 memcpy(literal_sections[nliteral_sections].sectname, 7680 s.sectname, 16); 7681 literal_sections[nliteral_sections].addr = s.addr; 7682 literal_sections[nliteral_sections].flags = s.flags; 7683 literal_sections[nliteral_sections].contents = 7684 object_addr + s.offset; 7685 big_size = s.offset; 7686 big_size += s.size; 7687 if(s.offset > object_size){ 7688 printf("section contents of: (%.16s,%.16s) is past " 7689 "end of file\n", s.segname, s.sectname); 7690 literal_sections[nliteral_sections].size = 0; 7691 } 7692 else if(big_size > object_size){ 7693 printf("part of section contents of: (%.16s,%.16s) " 7694 "is past end of file\n", 7695 s.segname, s.sectname); 7696 literal_sections[nliteral_sections].size = 7697 object_size - s.offset; 7698 } 7699 else 7700 literal_sections[nliteral_sections].size = s.size; 7701 nliteral_sections++; 7702 } 7703 7704 if(p + sizeof(struct section) > 7705 (char *)load_commands + sizeofcmds) 7706 break; 7707 p += size; 7708 } 7709 break; 7710 case LC_SEGMENT_64: 7711 memset((char *)&sg64, '\0', sizeof(struct segment_command_64)); 7712 size = left < sizeof(struct segment_command_64) ? 7713 left : sizeof(struct segment_command_64); 7714 memcpy((char *)&sg64, (char *)lc, size); 7715 if(swapped) 7716 swap_segment_command_64(&sg64, host_byte_sex); 7717 7718 p = (char *)lc + sizeof(struct segment_command_64); 7719 for(j = 0 ; j < sg64.nsects ; j++){ 7720 if(p + sizeof(struct section_64) > 7721 (char *)load_commands + sizeofcmds){ 7722 printf("section structure command extends past " 7723 "end of load commands\n"); 7724 } 7725 left = sizeofcmds - (p - (char *)load_commands); 7726 memset((char *)&s64, '\0', sizeof(struct section_64)); 7727 size = left < sizeof(struct section_64) ? 7728 left : sizeof(struct section_64); 7729 memcpy((char *)&s64, p, size); 7730 if(swapped) 7731 swap_section_64(&s64, 1, host_byte_sex); 7732 7733 if(s64.flags == S_CSTRING_LITERALS || 7734 s64.flags == S_4BYTE_LITERALS || 7735 s64.flags == S_8BYTE_LITERALS || 7736 s64.flags == S_16BYTE_LITERALS){ 7737 literal_sections = reallocate(literal_sections, 7738 sizeof(struct literal_section) * 7739 (nliteral_sections + 1)); 7740 memcpy(literal_sections[nliteral_sections].segname, 7741 s64.segname, 16); 7742 memcpy(literal_sections[nliteral_sections].sectname, 7743 s64.sectname, 16); 7744 literal_sections[nliteral_sections].addr = s64.addr; 7745 literal_sections[nliteral_sections].flags = s64.flags; 7746 literal_sections[nliteral_sections].contents = 7747 object_addr + s64.offset; 7748 big_size = s64.offset; 7749 big_size += s64.size; 7750 if(s64.offset > object_size){ 7751 printf("section contents of: (%.16s,%.16s) is past " 7752 "end of file\n", s64.segname, s64.sectname); 7753 literal_sections[nliteral_sections].size = 0; 7754 } 7755 else if(big_size > object_size){ 7756 printf("part of section contents of: (%.16s,%.16s) " 7757 "is past end of file\n", 7758 s64.segname, s64.sectname); 7759 literal_sections[nliteral_sections].size = 7760 object_size - s64.offset; 7761 } 7762 else 7763 literal_sections[nliteral_sections].size = s64.size; 7764 nliteral_sections++; 7765 } 7766 7767 if(p + sizeof(struct section) > 7768 (char *)load_commands + sizeofcmds) 7769 break; 7770 p += size; 7771 } 7772 break; 7773 } 7774 if(lcmd.cmdsize == 0){ 7775 printf("load command %u size zero (can't advance to other " 7776 "load commands)\n", i); 7777 break; 7778 } 7779 lc = (struct load_command *)((char *)lc + lcmd.cmdsize); 7780 if((char *)lc > (char *)load_commands + sizeofcmds) 7781 break; 7782 } 7783 7784 /* loop through the literal pointer section and print the pointers */ 7785 if(cputype & CPU_ARCH_ABI64) 7786 lp_size = 8; 7787 else 7788 lp_size = 4; 7789 for(i = 0; i < sect_size ; i += lp_size){ 7790 if(print_addresses == TRUE){ 7791 if(cputype & CPU_ARCH_ABI64) 7792 printf("0x%016llx ", sect_addr + i); 7793 else 7794 printf("%08x ", (unsigned int)(sect_addr + i)); 7795 } 7796 if(cputype & CPU_ARCH_ABI64){ 7797 lp = (uint64_t)*((uint64_t *)(sect + i)); 7798 memcpy((char *)&lp, sect + i, sizeof(uint64_t)); 7799 if(swapped) 7800 lp = SWAP_LONG_LONG(lp); 7801 } 7802 else{ 7803 li = (int32_t)*((int32_t *)(sect + i)); 7804 memcpy((char *)&li, sect + i, sizeof(uint32_t)); 7805 if(swapped) 7806 li = SWAP_INT(li); 7807 lp = li; 7808 } 7809 /* 7810 * If there is an external relocation entry for this pointer then 7811 * print the symbol and any offset. 7812 */ 7813 reloc = bsearch(&i, relocs, nrelocs, sizeof(struct relocation_info), 7814 (int (*)(const void *, const void *))rel_bsearch); 7815 if(reloc != NULL && (reloc->r_address & R_SCATTERED) == 0 && 7816 reloc->r_extern == 1){ 7817 printf("external relocation entry for symbol:"); 7818 if(reloc->r_symbolnum < nsymbols){ 7819 if(symbols != NULL) 7820 n_strx = symbols[reloc->r_symbolnum].n_un.n_strx; 7821 else 7822 n_strx = symbols64[reloc->r_symbolnum].n_un.n_strx; 7823 if(n_strx < strings_size){ 7824 if(lp != 0) 7825 printf("%s+0x%llx\n", strings + n_strx, lp); 7826 else 7827 printf("%s\n", strings + n_strx); 7828 } 7829 else{ 7830 printf("bad string index for symbol: %u\n", 7831 reloc->r_symbolnum); 7832 } 7833 } 7834 else{ 7835 printf("bad relocation entry\n"); 7836 } 7837 continue; 7838 } 7839 found = FALSE; 7840 for(j = 0; j < nliteral_sections; j++){ 7841 if(lp >= literal_sections[j].addr && 7842 lp < literal_sections[j].addr + 7843 literal_sections[j].size){ 7844 printf("%.16s:%.16s:", literal_sections[j].segname, 7845 literal_sections[j].sectname); 7846 switch(literal_sections[j].flags){ 7847 case S_CSTRING_LITERALS: 7848 for(k = lp - literal_sections[j].addr; 7849 k < literal_sections[j].size && 7850 literal_sections[j].contents[k] != '\0'; 7851 k++) 7852 print_cstring_char(literal_sections[j].contents[k]); 7853 printf("\n"); 7854 break; 7855 case S_4BYTE_LITERALS: 7856 memcpy((char *)&f, 7857 (char *)(literal_sections[j].contents + 7858 lp - literal_sections[j].addr), 7859 sizeof(float)); 7860 memcpy((char *)&l0, 7861 (char *)(literal_sections[j].contents + 7862 lp - literal_sections[j].addr), 7863 sizeof(uint32_t)); 7864 if(swapped){ 7865 d = SWAP_DOUBLE(d); 7866 l0 = SWAP_INT(l0); 7867 } 7868 print_literal4(l0, f); 7869 break; 7870 case S_8BYTE_LITERALS: 7871 memcpy((char *)&d, 7872 (char *)(literal_sections[j].contents + 7873 lp - literal_sections[j].addr), 7874 sizeof(double)); 7875 memcpy((char *)&l0, 7876 (char *)(literal_sections[j].contents + 7877 lp - literal_sections[j].addr), 7878 sizeof(uint32_t)); 7879 memcpy((char *)&l1, 7880 (char *)(literal_sections[j].contents + 7881 lp - literal_sections[j].addr + 7882 sizeof(uint32_t)), 7883 sizeof(uint32_t)); 7884 if(swapped){ 7885 d = SWAP_DOUBLE(d); 7886 l0 = SWAP_INT(l0); 7887 l1 = SWAP_INT(l1); 7888 } 7889 print_literal8(l0, l1, d); 7890 break; 7891 case S_16BYTE_LITERALS: 7892 memcpy((char *)&l0, 7893 (char *)(literal_sections[j].contents + 7894 lp - literal_sections[j].addr), 7895 sizeof(uint32_t)); 7896 memcpy((char *)&l1, 7897 (char *)(literal_sections[j].contents + 7898 lp - literal_sections[j].addr + 7899 sizeof(uint32_t)), 7900 sizeof(uint32_t)); 7901 memcpy((char *)&l2, 7902 (char *)(literal_sections[j].contents + 7903 lp - literal_sections[j].addr + 7904 2 * sizeof(uint32_t)), 7905 sizeof(uint32_t)); 7906 memcpy((char *)&l3, 7907 (char *)(literal_sections[j].contents + 7908 lp - literal_sections[j].addr + 7909 3 * sizeof(uint32_t)), 7910 sizeof(uint32_t)); 7911 if(swapped){ 7912 l0 = SWAP_INT(l0); 7913 l1 = SWAP_INT(l1); 7914 l2 = SWAP_INT(l2); 7915 l3 = SWAP_INT(l3); 7916 } 7917 print_literal16(l0, l1, l2, l3); 7918 break; 7919 } 7920 found = TRUE; 7921 break; 7922 } 7923 } 7924 if(found == FALSE) 7925 printf("0x%llx (not in a literal section)\n", lp); 7926 } 7927 7928 if(literal_sections != NULL) 7929 free(literal_sections); 7930} 7931 7932void 7933print_init_term_pointer_section( 7934cpu_type_t cputype, 7935char *sect, 7936uint32_t sect_size, 7937uint64_t sect_addr, 7938enum byte_sex object_byte_sex, 7939struct symbol *sorted_symbols, 7940uint32_t nsorted_symbols, 7941enum bool verbose) 7942{ 7943 uint32_t i, stride, p; 7944 uint64_t q; 7945 enum byte_sex host_byte_sex; 7946 enum bool swapped; 7947 const char *name; 7948 7949 host_byte_sex = get_host_byte_sex(); 7950 swapped = host_byte_sex != object_byte_sex; 7951 p = 0; 7952 q = 0; 7953 7954 if(cputype & CPU_ARCH_ABI64) 7955 stride = sizeof(uint64_t); 7956 else 7957 stride = sizeof(uint32_t); 7958 7959 for(i = 0 ; i < sect_size; i += stride){ 7960 if(cputype & CPU_ARCH_ABI64) 7961 printf("0x%016llx ", sect_addr + i * stride); 7962 else 7963 printf("0x%08x ",(uint32_t)(sect_addr + i * stride)); 7964 7965 if(cputype & CPU_ARCH_ABI64) 7966 memcpy(&q, sect + i, stride); 7967 else 7968 memcpy(&p, sect + i, stride); 7969 7970 if(swapped == TRUE){ 7971 if(cputype & CPU_ARCH_ABI64) 7972 q = SWAP_LONG_LONG(q); 7973 else 7974 p = SWAP_INT(p); 7975 } 7976 if(cputype & CPU_ARCH_ABI64) 7977 printf("0x%016llx", q); 7978 else 7979 printf("0x%08x", p); 7980 7981 if(verbose == TRUE){ 7982 if(cputype & CPU_ARCH_ABI64) 7983 name = guess_symbol(q, sorted_symbols, nsorted_symbols, 7984 verbose); 7985 else 7986 name = guess_symbol(p, sorted_symbols, nsorted_symbols, 7987 verbose); 7988 if(name != NULL) 7989 printf(" %s\n", name); 7990 else 7991 printf("\n"); 7992 } 7993 else{ 7994 printf("\n"); 7995 } 7996 } 7997} 7998 7999/* 8000 * Function for bsearch for searching relocation entries. 8001 */ 8002static 8003int 8004rel_bsearch( 8005uint32_t *address, 8006struct relocation_info *rel) 8007{ 8008 struct scattered_relocation_info *srel; 8009 uint32_t r_address; 8010 8011 if((rel->r_address & R_SCATTERED) != 0){ 8012 srel = (struct scattered_relocation_info *)rel; 8013 r_address = srel->r_address; 8014 } 8015 else 8016 r_address = rel->r_address; 8017 8018 if(*address == r_address) 8019 return(0); 8020 if(*address < r_address) 8021 return(-1); 8022 else 8023 return(1); 8024} 8025 8026/* 8027 * Print the shared library initialization table. 8028 */ 8029void 8030print_shlib_init( 8031enum byte_sex object_byte_sex, 8032char *sect, 8033uint32_t sect_size, 8034uint32_t sect_addr, 8035struct symbol *sorted_symbols, 8036uint32_t nsorted_symbols, 8037struct nlist *symbols, 8038struct nlist_64 *symbols64, 8039uint32_t nsymbols, 8040char *strings, 8041uint32_t strings_size, 8042struct relocation_info *relocs, 8043uint32_t nrelocs, 8044enum bool verbose) 8045{ 8046 enum byte_sex host_byte_sex; 8047 enum bool swapped; 8048 uint32_t i; 8049 struct shlib_init { 8050 int32_t value; /* the value to be stored at the address */ 8051 int32_t address; /* the address to store the value */ 8052 } shlib_init; 8053 8054 host_byte_sex = get_host_byte_sex(); 8055 swapped = host_byte_sex != object_byte_sex; 8056 8057 for(i = 0; i < sect_size; i += sizeof(struct shlib_init)){ 8058 memcpy((char *)&shlib_init, sect + i, sizeof(struct shlib_init)); 8059 if(swapped){ 8060 shlib_init.value = SWAP_INT(shlib_init.value); 8061 shlib_init.address = SWAP_INT(shlib_init.address); 8062 } 8063 printf("\tvalue 0x%08x ", (unsigned int)shlib_init.value); 8064 (void)print_symbol(shlib_init.value, sect_addr + i, 0, relocs, 8065 nrelocs, symbols, symbols64, nsymbols, 8066 sorted_symbols, nsorted_symbols, strings, 8067 strings_size, verbose); 8068 printf("\n"); 8069 printf("\taddress 0x%08x ", (unsigned int)shlib_init.address); 8070 (void)print_symbol(shlib_init.address, sect_addr+i+sizeof(int32_t), 0, 8071 relocs, nrelocs, symbols, symbols64, nsymbols, 8072 sorted_symbols, nsorted_symbols, strings, 8073 strings_size, verbose); 8074 printf("\n"); 8075 } 8076} 8077 8078/* 8079 * Print_symbol prints a symbol name for the addr if a symbol exist with the 8080 * same address. Nothing else is printed, no whitespace, no newline. If it 8081 * prints something then it returns TRUE, else it returns FALSE. 8082 */ 8083enum bool 8084print_symbol( 8085uint64_t value, 8086uint32_t r_address, 8087uint32_t dot_value, 8088struct relocation_info *relocs, 8089uint32_t nrelocs, 8090struct nlist *symbols, 8091struct nlist_64 *symbols64, 8092uint32_t nsymbols, 8093struct symbol *sorted_symbols, 8094uint32_t nsorted_symbols, 8095char *strings, 8096uint32_t strings_size, 8097enum bool verbose) 8098{ 8099 uint32_t i, offset; 8100 struct scattered_relocation_info *sreloc, *pair; 8101 unsigned int r_symbolnum; 8102 uint32_t n_strx; 8103 const char *name, *add, *sub; 8104 8105 if(verbose == FALSE) 8106 return(FALSE); 8107 8108 for(i = 0; i < nrelocs; i++){ 8109 if(((relocs[i].r_address) & R_SCATTERED) != 0){ 8110 sreloc = (struct scattered_relocation_info *)(relocs + i); 8111 if(sreloc->r_type == GENERIC_RELOC_PAIR){ 8112 fprintf(stderr, "Stray GENERIC_RELOC_PAIR relocation entry " 8113 "%u\n", i); 8114 continue; 8115 } 8116 if(sreloc->r_type == GENERIC_RELOC_VANILLA){ 8117 if(sreloc->r_address == r_address){ 8118 name = guess_symbol(sreloc->r_value, sorted_symbols, 8119 nsorted_symbols, verbose); 8120 offset = value - sreloc->r_value; 8121 if(name != NULL){ 8122 printf("%s+0x%x", name, (unsigned int)offset); 8123 return(TRUE); 8124 } 8125 } 8126 continue; 8127 } 8128 if(sreloc->r_type != GENERIC_RELOC_SECTDIFF && 8129 sreloc->r_type != GENERIC_RELOC_LOCAL_SECTDIFF){ 8130 fprintf(stderr, "Unknown relocation r_type for entry " 8131 "%u\n", i); 8132 continue; 8133 } 8134 if(i + 1 < nrelocs){ 8135 pair = (struct scattered_relocation_info *)(relocs + i + 1); 8136 if(pair->r_scattered == 0 || 8137 pair->r_type != GENERIC_RELOC_PAIR){ 8138 fprintf(stderr, "No GENERIC_RELOC_PAIR relocation " 8139 "entry after entry %u\n", i); 8140 continue; 8141 } 8142 } 8143 else{ 8144 fprintf(stderr, "No GENERIC_RELOC_PAIR relocation entry " 8145 "after entry %u\n", i); 8146 continue; 8147 } 8148 i++; /* skip the pair reloc */ 8149 8150 if(sreloc->r_address == r_address){ 8151 add = guess_symbol(sreloc->r_value, sorted_symbols, 8152 nsorted_symbols, verbose); 8153 sub = guess_symbol(pair->r_value, sorted_symbols, 8154 nsorted_symbols, verbose); 8155 offset = value - (sreloc->r_value - pair->r_value); 8156 if(add != NULL) 8157 printf("%s", add); 8158 else 8159 printf("0x%x", (unsigned int)sreloc->r_value); 8160 if(sub != NULL) 8161 printf("-%s", sub); 8162 else{ 8163 if((uint32_t)pair->r_value == dot_value) 8164 printf("-."); 8165 else 8166 printf("-0x%x", (unsigned int)pair->r_value); 8167 } 8168 if(offset != 0) 8169 printf("+0x%x", (unsigned int)offset); 8170 return(TRUE); 8171 } 8172 } 8173 else{ 8174 if((uint32_t)relocs[i].r_address == r_address){ 8175 r_symbolnum = relocs[i].r_symbolnum; 8176 if(relocs[i].r_extern){ 8177 if(r_symbolnum >= nsymbols) 8178 return(FALSE); 8179 if(symbols != NULL) 8180 n_strx = symbols[r_symbolnum].n_un.n_strx; 8181 else 8182 n_strx = symbols64[r_symbolnum].n_un.n_strx; 8183 if(n_strx <= 0 || n_strx >= strings_size) 8184 return(FALSE); 8185 if(value != 0) 8186 printf("%s+0x%x", strings + n_strx, 8187 (unsigned int)value); 8188 else 8189 printf("%s", strings + n_strx); 8190 return(TRUE); 8191 } 8192 break; 8193 } 8194 } 8195 } 8196 8197 name = guess_symbol(value, sorted_symbols, nsorted_symbols, verbose); 8198 if(name != NULL){ 8199 printf("%s", name); 8200 return(TRUE); 8201 } 8202 return(FALSE); 8203} 8204 8205/* 8206 * guess_symbol() guesses the name for a symbol based on the specified value. 8207 * It returns the name of symbol or NULL. It only returns a symbol name if 8208 * a symbol with that exact value exists. 8209 */ 8210const char * 8211guess_symbol( 8212const uint64_t value, /* the value of this symbol (in) */ 8213const struct symbol *sorted_symbols, 8214const uint32_t nsorted_symbols, 8215const enum bool verbose) 8216{ 8217 int32_t high, low, mid; 8218 8219 if(verbose == FALSE) 8220 return(NULL); 8221 8222 low = 0; 8223 high = nsorted_symbols - 1; 8224 mid = (high - low) / 2; 8225 while(high >= low){ 8226 if(sorted_symbols[mid].n_value == value){ 8227 return(sorted_symbols[mid].name); 8228 } 8229 if(sorted_symbols[mid].n_value > value){ 8230 high = mid - 1; 8231 mid = (high + low) / 2; 8232 } 8233 else{ 8234 low = mid + 1; 8235 mid = (high + low) / 2; 8236 } 8237 } 8238 return(NULL); 8239} 8240 8241/* 8242 * guess_indirect_symbol() returns the name of the indirect symbol for the 8243 * value passed in or NULL. 8244 */ 8245const char * 8246guess_indirect_symbol( 8247const uint64_t value, /* the value of this symbol (in) */ 8248const uint32_t ncmds, 8249const uint32_t sizeofcmds, 8250const struct load_command *load_commands, 8251const enum byte_sex load_commands_byte_sex, 8252const uint32_t *indirect_symbols, 8253const uint32_t nindirect_symbols, 8254const struct nlist *symbols, 8255const struct nlist_64 *symbols64, 8256const uint32_t nsymbols, 8257const char *strings, 8258const uint32_t strings_size) 8259{ 8260 enum byte_sex host_byte_sex; 8261 enum bool swapped; 8262 uint32_t i, j, section_type, index, stride; 8263 const struct load_command *lc; 8264 struct load_command l; 8265 struct segment_command sg; 8266 struct section s; 8267 struct segment_command_64 sg64; 8268 struct section_64 s64; 8269 char *p; 8270 uint64_t big_load_end; 8271 8272 host_byte_sex = get_host_byte_sex(); 8273 swapped = host_byte_sex != load_commands_byte_sex; 8274 8275 lc = load_commands; 8276 big_load_end = 0; 8277 for(i = 0 ; i < ncmds; i++){ 8278 memcpy((char *)&l, (char *)lc, sizeof(struct load_command)); 8279 if(swapped) 8280 swap_load_command(&l, host_byte_sex); 8281 if(l.cmdsize % sizeof(int32_t) != 0) 8282 return(NULL); 8283 big_load_end += l.cmdsize; 8284 if(big_load_end > sizeofcmds) 8285 return(NULL); 8286 switch(l.cmd){ 8287 case LC_SEGMENT: 8288 memcpy((char *)&sg, (char *)lc, sizeof(struct segment_command)); 8289 if(swapped) 8290 swap_segment_command(&sg, host_byte_sex); 8291 p = (char *)lc + sizeof(struct segment_command); 8292 for(j = 0 ; j < sg.nsects ; j++){ 8293 memcpy((char *)&s, p, sizeof(struct section)); 8294 p += sizeof(struct section); 8295 if(swapped) 8296 swap_section(&s, 1, host_byte_sex); 8297 section_type = s.flags & SECTION_TYPE; 8298 if((section_type == S_NON_LAZY_SYMBOL_POINTERS || 8299 section_type == S_LAZY_SYMBOL_POINTERS || 8300 section_type == S_LAZY_DYLIB_SYMBOL_POINTERS || 8301 section_type == S_THREAD_LOCAL_VARIABLE_POINTERS || 8302 section_type == S_SYMBOL_STUBS) && 8303 value >= s.addr && value < s.addr + s.size){ 8304 if(section_type == S_SYMBOL_STUBS) 8305 stride = s.reserved2; 8306 else 8307 stride = 4; 8308 if(stride == 0) 8309 return(NULL); 8310 index = s.reserved1 + (value - s.addr) / stride; 8311 if(index < nindirect_symbols && 8312 symbols != NULL && strings != NULL && 8313 indirect_symbols[index] < nsymbols && 8314 (uint32_t)symbols[indirect_symbols[index]]. 8315 n_un.n_strx < strings_size) 8316 return(strings + 8317 symbols[indirect_symbols[index]].n_un.n_strx); 8318 else 8319 return(NULL); 8320 } 8321 } 8322 break; 8323 case LC_SEGMENT_64: 8324 memcpy((char *)&sg64, (char *)lc, 8325 sizeof(struct segment_command_64)); 8326 if(swapped) 8327 swap_segment_command_64(&sg64, host_byte_sex); 8328 p = (char *)lc + sizeof(struct segment_command_64); 8329 for(j = 0 ; j < sg64.nsects ; j++){ 8330 memcpy((char *)&s64, p, sizeof(struct section_64)); 8331 p += sizeof(struct section_64); 8332 if(swapped) 8333 swap_section_64(&s64, 1, host_byte_sex); 8334 section_type = s64.flags & SECTION_TYPE; 8335 if((section_type == S_NON_LAZY_SYMBOL_POINTERS || 8336 section_type == S_LAZY_SYMBOL_POINTERS || 8337 section_type == S_LAZY_DYLIB_SYMBOL_POINTERS || 8338 section_type == S_THREAD_LOCAL_VARIABLE_POINTERS || 8339 section_type == S_SYMBOL_STUBS) && 8340 value >= s64.addr && value < s64.addr + s64.size){ 8341 if(section_type == S_SYMBOL_STUBS) 8342 stride = s64.reserved2; 8343 else 8344 stride = 8; 8345 if(stride == 0) 8346 return(NULL); 8347 index = s64.reserved1 + (value - s64.addr) / stride; 8348 if(index < nindirect_symbols && 8349 symbols64 != NULL && strings != NULL && 8350 indirect_symbols[index] < nsymbols && 8351 (uint32_t)symbols64[indirect_symbols[index]]. 8352 n_un.n_strx < strings_size) 8353 return(strings + 8354 symbols64[indirect_symbols[index]].n_un.n_strx); 8355 else 8356 return(NULL); 8357 } 8358 } 8359 break; 8360 } 8361 if(l.cmdsize == 0){ 8362 return(NULL); 8363 } 8364 lc = (struct load_command *)((char *)lc + l.cmdsize); 8365 if((char *)lc > (char *)load_commands + sizeofcmds) 8366 return(NULL); 8367 } 8368 return(NULL); 8369} 8370 8371void 8372print_sect( 8373cpu_type_t cputype, 8374enum byte_sex object_byte_sex, 8375char *sect, 8376uint64_t size, 8377uint64_t addr) 8378{ 8379 enum byte_sex host_byte_sex; 8380 enum bool swapped; 8381 uint64_t i, j; 8382 uint32_t long_word; 8383 unsigned short short_word; 8384 unsigned char byte_word; 8385 8386 host_byte_sex = get_host_byte_sex(); 8387 swapped = host_byte_sex != object_byte_sex; 8388 8389 if(cputype == CPU_TYPE_I386 || 8390 cputype == CPU_TYPE_X86_64){ 8391 for(i = 0 ; i < size ; i += j , addr += j){ 8392 if(cputype & CPU_ARCH_ABI64) 8393 printf("%016llx\t", addr); 8394 else 8395 printf("%08x\t", (uint32_t)addr); 8396 for(j = 0; 8397 j < 16 * sizeof(char) && i + j < size; 8398 j += sizeof(char)){ 8399 byte_word = *(sect + i + j); 8400 printf("%02x ", (unsigned int)byte_word); 8401 } 8402 printf("\n"); 8403 } 8404 } 8405 else if(cputype == CPU_TYPE_MC680x0){ 8406 for(i = 0 ; i < size ; i += j , addr += j){ 8407 printf("%08x ", (unsigned int)addr); 8408 for(j = 0; 8409 j < 8 * sizeof(short) && i + j < size; 8410 j += sizeof(short)){ 8411 memcpy(&short_word, sect + i + j, sizeof(short)); 8412 if(swapped) 8413 short_word = SWAP_SHORT(short_word); 8414 printf("%04x ", (unsigned int)short_word); 8415 } 8416 printf("\n"); 8417 } 8418 } 8419 else{ 8420 for(i = 0 ; i < size ; i += j , addr += j){ 8421 if(cputype & CPU_ARCH_ABI64) 8422 printf("%016llx\t", addr); 8423 else 8424 printf("%08x\t", (uint32_t)addr); 8425 for(j = 0; 8426 j < 4 * sizeof(int32_t) && i + j < size; 8427 j += sizeof(int32_t)){ 8428 memcpy(&long_word, sect + i + j, sizeof(int32_t)); 8429 if(swapped) 8430 long_word = SWAP_INT(long_word); 8431 printf("%08x ", (unsigned int)long_word); 8432 } 8433 printf("\n"); 8434 } 8435 } 8436} 8437 8438/* 8439 * get_label returns a symbol name for the addr if a symbol exist with the 8440 * same address else it returns NULL. 8441 */ 8442char * 8443get_label( 8444uint64_t addr, 8445struct symbol *sorted_symbols, 8446uint32_t nsorted_symbols) 8447{ 8448 int32_t high, low, mid; 8449 8450 low = 0; 8451 high = nsorted_symbols - 1; 8452 mid = (high - low) / 2; 8453 while(high >= low){ 8454 if(sorted_symbols[mid].n_value == addr) 8455 return(sorted_symbols[mid].name); 8456 if(sorted_symbols[mid].n_value > addr){ 8457 high = mid - 1; 8458 mid = (high + low) / 2; 8459 } 8460 else{ 8461 low = mid + 1; 8462 mid = (high + low) / 2; 8463 } 8464 } 8465 return(NULL); 8466} 8467 8468/* 8469 * print_label prints a symbol name for the addr if a symbol exist with the 8470 * same address in label form, namely:. 8471 * 8472 * <symbol name>:\n 8473 * 8474 * The colon and the newline are printed if colon_and_newline is TRUE. 8475 */ 8476void 8477print_label( 8478uint64_t addr, 8479enum bool colon_and_newline, 8480struct symbol *sorted_symbols, 8481uint32_t nsorted_symbols) 8482{ 8483 char *name; 8484 8485 name = get_label(addr, sorted_symbols, nsorted_symbols); 8486 if(name != NULL){ 8487 printf("%s", name); 8488 if(colon_and_newline == TRUE) 8489 printf(":\n"); 8490 } 8491} 8492