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