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