2 * Copyright © 2009 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its
15 * contributors may be used to endorse or promote products derived from this
16 * software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * @APPLE_LICENSE_HEADER_END@
33 #include "mach-o/loader.h"
34 #include "objc/objc-runtime.h"
35 #include "stuff/allocate.h"
36 #include "stuff/bytesex.h"
37 #include "stuff/symbol.h"
38 #include "ofile_print.h"
41 * Here we need structures that have the same memory layout and size as the
42 * 32-bit Objective-C 1 meta data structures.
44 * The real structure definitions come from the header file objc/objc-runtime.h
45 * and those it includes like objc/objc-class.h, etc. But since this program
46 * must also run on 64-bit hosts that can't be used.
49 struct objc_module_t
{
52 uint32_t name
; /* char * (32-bit pointer) */
53 uint32_t symtab
; /* struct objc_symtab * (32-bit pointer) */
56 struct objc_symtab_t
{
58 uint32_t refs
; /* SEL * (32-bit pointer) */
61 uint32_t defs
[1]; /* void * (32-bit pointer) variable size */
65 uint32_t isa
; /* struct objc_class * (32-bit pointer) */
66 uint32_t super_class
; /* struct objc_class * (32-bit pointer) */
67 uint32_t name
; /* const char * (32-bit pointer) */
70 int32_t instance_size
;
71 uint32_t ivars
; /* struct objc_ivar_list * (32-bit pointer) */
72 uint32_t methodLists
; /* struct objc_method_list ** (32-bit pointer) */
73 uint32_t cache
; /* struct objc_cache * (32-bit pointer) */
74 uint32_t protocols
; /* struct objc_protocol_list * (32-bit pointer) */
77 struct objc_category_t
{
78 uint32_t category_name
; /* char * (32-bit pointer) */
79 uint32_t class_name
; /* char * (32-bit pointer) */
80 uint32_t instance_methods
; /* struct objc_method_list * (32-bit pointer) */
81 uint32_t class_methods
; /* struct objc_method_list * (32-bit pointer) */
82 uint32_t protocols
; /* struct objc_protocol_list * (32-bit ptr) */
86 uint32_t ivar_name
; /* char * (32-bit pointer) */
87 uint32_t ivar_type
; /* char * (32-bit pointer) */
91 struct objc_ivar_list_t
{
93 struct objc_ivar_t ivar_list
[1]; /* variable length structure */
96 struct objc_method_t
{
97 uint32_t method_name
; /* SEL, aka struct objc_selector * (32-bit pointer) */
98 uint32_t method_types
; /* char * (32-bit pointer) */
99 uint32_t method_imp
; /* IMP, aka function pointer, (*IMP)(id, SEL, ...)
103 struct objc_method_list_t
{
104 uint32_t obsolete
; /* struct objc_method_list * (32-bit pointer) */
105 int32_t method_count
;
106 struct objc_method_t method_list
[1]; /* variable length structure */
109 struct objc_protocol_t
{
110 uint32_t isa
; /* struct objc_class * (32-bit pointer) */
111 uint32_t protocol_name
; /* char * (32-bit pointer) */
112 uint32_t protocol_list
; /* struct objc_protocol_list *
114 uint32_t instance_methods
; /* struct objc_method_description_list *
116 uint32_t class_methods
; /* struct objc_method_description_list *
120 struct objc_protocol_list_t
{
121 uint32_t next
; /* struct objc_protocol_list * (32-bit pointer) */
123 uint32_t list
[1]; /* Protocol *, aka struct objc_protocol_t * (
127 struct objc_method_description_t
{
128 uint32_t name
; /* SEL, aka struct objc_selector * (32-bit pointer) */
129 uint32_t types
; /* char * (32-bit pointer) */
132 struct objc_method_description_list_t
{
134 struct objc_method_description_t list
[1];
139 * The header file "objc/NXString.h" has gone away and there is no real public
140 * header file to get this definition from anymore.
142 struct objc_string_object_t
{
143 uint32_t isa
; /* struct objc_class * (32-bit pointer) */
144 uint32_t characters
; /* char * (32-bit pointer) */
147 typedef struct objc_string_object_t NXConstantString
;
149 #define SIZEHASHTABLE 821
150 struct _hashEntry_t
{
151 uint32_t next
; /* struct _hashEntry * (32-bit pointer) */
152 uint32_t sel
; /* char * (32-bit pointer) */
163 struct imageInfo_t
*o
,
164 enum byte_sex target_byte_sex
)
166 o
->version
= SWAP_INT(o
->version
);
167 o
->flags
= SWAP_INT(o
->flags
);
172 struct objc_module_t
*module
,
173 enum byte_sex target_byte_sex
)
175 module
->version
= SWAP_INT(module
->version
);
176 module
->size
= SWAP_INT(module
->size
);
177 module
->name
= SWAP_INT(module
->name
);
178 module
->symtab
= SWAP_INT(module
->symtab
);
183 struct objc_symtab_t
*symtab
,
184 enum byte_sex target_byte_sex
)
186 symtab
->sel_ref_cnt
= SWAP_INT(symtab
->sel_ref_cnt
);
187 symtab
->refs
= SWAP_INT(symtab
->refs
);
188 symtab
->cls_def_cnt
= SWAP_SHORT(symtab
->cls_def_cnt
);
189 symtab
->cat_def_cnt
= SWAP_SHORT(symtab
->cat_def_cnt
);
194 struct objc_class_t
*objc_class
,
195 enum byte_sex target_byte_sex
)
197 objc_class
->isa
= SWAP_INT(objc_class
->isa
);
198 objc_class
->super_class
= SWAP_INT(objc_class
->super_class
);
199 objc_class
->name
= SWAP_INT(objc_class
->name
);
200 objc_class
->version
= SWAP_INT(objc_class
->version
);
201 objc_class
->info
= SWAP_INT(objc_class
->info
);
202 objc_class
->instance_size
= SWAP_INT(objc_class
->instance_size
);
203 objc_class
->ivars
= SWAP_INT(objc_class
->ivars
);
204 objc_class
->methodLists
= SWAP_INT(objc_class
->methodLists
);
205 objc_class
->cache
= SWAP_INT(objc_class
->cache
);
206 objc_class
->protocols
= SWAP_INT(objc_class
->protocols
);
210 swap_objc_category_t(
211 struct objc_category_t
*objc_category
,
212 enum byte_sex target_byte_sex
)
214 objc_category
->category_name
= SWAP_INT(objc_category
->category_name
);
215 objc_category
->class_name
= SWAP_INT(objc_category
->class_name
);
216 objc_category
->instance_methods
=
217 SWAP_INT(objc_category
->instance_methods
);
218 objc_category
->class_methods
=
219 SWAP_INT(objc_category
->class_methods
);
220 objc_category
->protocols
=
221 SWAP_INT(objc_category
->protocols
);
225 swap_objc_ivar_list_t(
226 struct objc_ivar_list_t
*objc_ivar_list
,
227 enum byte_sex target_byte_sex
)
229 objc_ivar_list
->ivar_count
= SWAP_INT(objc_ivar_list
->ivar_count
);
234 struct objc_ivar_t
*objc_ivar
,
235 enum byte_sex target_byte_sex
)
237 objc_ivar
->ivar_name
= SWAP_INT(objc_ivar
->ivar_name
);
238 objc_ivar
->ivar_type
= SWAP_INT(objc_ivar
->ivar_type
);
239 objc_ivar
->ivar_offset
= SWAP_INT(objc_ivar
->ivar_offset
);
243 swap_objc_method_list_t(
244 struct objc_method_list_t
*method_list
,
245 enum byte_sex target_byte_sex
)
247 method_list
->obsolete
= SWAP_INT(method_list
->obsolete
);
248 method_list
->method_count
= SWAP_INT(method_list
->method_count
);
253 struct objc_method_t
*method
,
254 enum byte_sex target_byte_sex
)
256 method
->method_name
= SWAP_INT(method
->method_name
);
257 method
->method_types
= SWAP_INT(method
->method_types
);
258 method
->method_imp
= SWAP_INT(method
->method_imp
);
262 swap_objc_protocol_list_t(
263 struct objc_protocol_list_t
*protocol_list
,
264 enum byte_sex target_byte_sex
)
266 protocol_list
->next
= SWAP_INT(protocol_list
->next
);
267 protocol_list
->count
= SWAP_INT(protocol_list
->count
);
271 swap_objc_protocol_t(
272 struct objc_protocol_t
*protocol
,
273 enum byte_sex target_byte_sex
)
275 protocol
->isa
= SWAP_INT(protocol
->isa
);
276 protocol
->protocol_name
= SWAP_INT(protocol
->protocol_name
);
277 protocol
->protocol_list
= SWAP_INT(protocol
->protocol_list
);
278 protocol
->instance_methods
= SWAP_INT(protocol
->instance_methods
);
279 protocol
->class_methods
= SWAP_INT(protocol
->class_methods
);
283 swap_objc_method_description_list_t(
284 struct objc_method_description_list_t
*mdl
,
285 enum byte_sex target_byte_sex
)
287 mdl
->count
= SWAP_INT(mdl
->count
);
291 swap_objc_method_description_t(
292 struct objc_method_description_t
*md
,
293 enum byte_sex target_byte_sex
)
295 md
->name
= SWAP_INT(md
->name
);
296 md
->types
= SWAP_INT(md
->types
);
300 swap_string_object_t(
301 struct objc_string_object_t
*string_object
,
302 enum byte_sex target_byte_sex
)
304 string_object
->isa
= SWAP_INT(string_object
->isa
);
305 string_object
->characters
= SWAP_INT(string_object
->characters
);
306 string_object
->_length
= SWAP_INT(string_object
->_length
);
311 struct _hashEntry_t
*_hashEntry
,
312 enum byte_sex target_byte_sex
)
314 _hashEntry
->next
= SWAP_INT(_hashEntry
->next
);
315 _hashEntry
->sel
= SWAP_INT(_hashEntry
->sel
);
318 struct section_info
{
327 static void get_objc_sections(
328 struct load_command
*load_commands
,
331 enum byte_sex object_byte_sex
,
333 uint32_t object_size
,
334 struct section_info
**objc_sections
,
335 uint32_t *nobjc_sections
,
339 uint32_t *sect_size
);
341 static void get_cstring_section(
342 struct load_command
*load_commands
,
345 enum byte_sex object_byte_sex
,
347 uint32_t object_size
,
348 struct section_info
*cstring_section_ptr
);
350 static enum bool print_method_list(
352 struct section_info
*objc_sections
,
353 uint32_t nobjc_sections
,
354 struct section_info
*cstring_section_ptr
,
355 enum byte_sex host_byte_sex
,
357 struct symbol
*sorted_symbols
,
358 uint32_t nsorted_symbols
,
361 static enum bool print_protocol_list(
364 struct section_info
*objc_sections
,
365 uint32_t nobjc_sections
,
366 struct section_info
*cstring_section_ptr
,
367 enum byte_sex host_byte_sex
,
371 static void print_protocol(
373 struct objc_protocol_t
*protocol
,
374 struct section_info
*objc_sections
,
375 uint32_t nobjc_sections
,
376 struct section_info
*cstring_section_ptr
,
377 enum byte_sex host_byte_sex
,
381 static enum bool print_method_description_list(
384 struct section_info
*objc_sections
,
385 uint32_t nobjc_sections
,
386 struct section_info
*cstring_section_ptr
,
387 enum byte_sex host_byte_sex
,
391 static enum bool print_PHASH(
394 struct section_info
*objc_sections
,
395 uint32_t nobjc_sections
,
396 struct section_info
*cstring_section_ptr
,
397 enum byte_sex host_byte_sex
,
401 static void print_indent(
404 static void *get_pointer(
407 struct section_info
*objc_sections
,
408 uint32_t nobjc_sections
,
409 struct section_info
*cstring_section_ptr
);
411 static enum bool get_symtab(
413 struct objc_symtab_t
*symtab
,
417 struct section_info
*objc_sections
,
418 uint32_t nobjc_sections
,
419 enum byte_sex host_byte_sex
,
422 static enum bool get_objc_class(
424 struct objc_class_t
*objc_class
,
426 struct section_info
*objc_sections
,
427 uint32_t nobjc_sections
,
428 enum byte_sex host_byte_sex
,
431 static enum bool get_objc_category(
433 struct objc_category_t
*objc_category
,
435 struct section_info
*objc_sections
,
436 uint32_t nobjc_sections
,
437 enum byte_sex host_byte_sex
,
440 static enum bool get_ivar_list(
442 struct objc_ivar_list_t
*objc_ivar_list
,
443 struct objc_ivar_t
**ivar_list
,
446 struct section_info
*objc_sections
,
447 uint32_t nobjc_sections
,
448 enum byte_sex host_byte_sex
,
451 static enum bool get_method_list(
453 struct objc_method_list_t
*method_list
,
454 struct objc_method_t
**methods
,
457 struct section_info
*objc_sections
,
458 uint32_t nobjc_sections
,
459 enum byte_sex host_byte_sex
,
462 static enum bool get_protocol_list(
464 struct objc_protocol_list_t
*protocol_list
,
468 struct section_info
*objc_sections
,
469 uint32_t nobjc_sections
,
470 enum byte_sex host_byte_sex
,
473 static enum bool get_protocol(
475 struct objc_protocol_t
*protocol
,
477 struct section_info
*objc_sections
,
478 uint32_t nobjc_sections
,
479 enum byte_sex host_byte_sex
,
482 static enum bool get_method_description_list(
484 struct objc_method_description_list_t
*mdl
,
485 struct objc_method_description_t
**list
,
488 struct section_info
*objc_sections
,
489 uint32_t nobjc_sections
,
490 enum byte_sex host_byte_sex
,
493 static enum bool get_hashEntry(
495 struct _hashEntry_t
*_hashEntry
,
497 struct section_info
*objc_sections
,
498 uint32_t nobjc_sections
,
499 enum byte_sex host_byte_sex
,
503 * Print the objc segment.
507 cpu_type_t mh_cputype
,
508 struct load_command
*load_commands
,
511 enum byte_sex object_byte_sex
,
513 uint32_t object_size
,
514 struct symbol
*sorted_symbols
,
515 uint32_t nsorted_symbols
,
518 enum byte_sex host_byte_sex
;
519 enum bool swapped
, trunc
;
520 uint32_t i
, j
, left
, size
, defs_left
, def
, ivar_list_left
;
522 struct section_info
*objc_sections
;
523 uint32_t nobjc_sections
;
524 struct section_info cstring_section
;
526 struct objc_module_t
*modules
, *m
, module
;
527 uint32_t modules_addr
, modules_size
;
528 struct objc_symtab_t symtab
;
530 struct objc_class_t objc_class
;
531 struct objc_ivar_list_t objc_ivar_list
;
532 struct objc_ivar_t
*ivar_list
, ivar
;
533 struct objc_category_t objc_category
;
535 struct imageInfo_t
*imageInfo
, info
;
536 uint32_t imageInfo_addr
, imageInfo_size
;
538 printf("Objective-C segment\n");
539 get_objc_sections(load_commands
, ncmds
, sizeofcmds
, object_byte_sex
,
540 object_addr
, object_size
, &objc_sections
,
541 &nobjc_sections
, SECT_OBJC_MODULES
, (char **)&modules
,
542 &modules_addr
, &modules_size
);
545 if(mh_cputype
== CPU_TYPE_I386
)
547 printf("can't print objective-C information no (" SEG_OBJC
","
548 SECT_OBJC_MODULES
") section\n");
553 get_cstring_section(load_commands
, ncmds
, sizeofcmds
, object_byte_sex
,
554 object_addr
, object_size
, &cstring_section
);
556 host_byte_sex
= get_host_byte_sex();
557 swapped
= host_byte_sex
!= object_byte_sex
;
559 memset(&module
, '\0', sizeof(struct objc_module_t
));
562 (char *)m
< (char *)modules
+ modules_size
;
563 m
= (struct objc_module_t
*)((char *)m
+ module
.size
) ){
565 memset(&module
, '\0', sizeof(struct objc_module_t
));
566 left
= modules_size
- (m
- modules
);
567 size
= left
< sizeof(struct objc_module_t
) ?
568 left
: sizeof(struct objc_module_t
);
569 memcpy(&module
, m
, size
);
571 swap_objc_module_t(&module
, host_byte_sex
);
573 if((char *)m
+ module
.size
> (char *)m
+ modules_size
)
574 printf("module extends past end of " SECT_OBJC_MODULES
576 printf("Module 0x%x\n", (unsigned int)
577 (modules_addr
+ (char *)m
- (char *)modules
));
579 printf(" version %u\n", module
.version
);
580 printf(" size %u\n", module
.size
);
582 p
= get_pointer(module
.name
, &left
,
583 objc_sections
, nobjc_sections
, &cstring_section
);
585 printf(" name %.*s\n", (int)left
, p
);
587 printf(" name 0x%08x (not in an " SEG_OBJC
588 " section)\n", (unsigned int)module
.name
);
591 printf(" name 0x%08x\n", (unsigned int)(module
.name
));
593 if(get_symtab(module
.symtab
, &symtab
, &defs
, &defs_left
, &trunc
,
594 objc_sections
, nobjc_sections
,
595 host_byte_sex
, swapped
) == FALSE
){
596 printf(" symtab 0x%08x (not in an " SEG_OBJC
597 " section)\n", (unsigned int)module
.symtab
);
600 printf(" symtab 0x%08x\n", (unsigned int)module
.symtab
);
602 printf("\tsymtab extends past end of an " SEG_OBJC
604 printf("\tsel_ref_cnt %u\n", symtab
.sel_ref_cnt
);
605 p
= get_pointer(symtab
.refs
, &left
,
606 objc_sections
, nobjc_sections
, &cstring_section
);
608 printf("\trefs 0x%08x", symtab
.refs
);
610 printf("\trefs 0x%08x (not in an " SEG_OBJC
" section)\n",
613 printf("\tcls_def_cnt %d\n", symtab
.cls_def_cnt
);
614 printf("\tcat_def_cnt %d\n", symtab
.cat_def_cnt
);
615 if(symtab
.cls_def_cnt
> 0)
616 printf("\tClass Definitions\n");
617 for(i
= 0; i
< symtab
.cls_def_cnt
; i
++){
618 if((i
+ 1) * sizeof(uint32_t) > defs_left
){
619 printf("\t(remaining class defs entries entends past "
620 "the end of the section)\n");
624 memcpy(&def
, defs
+ i
, sizeof(uint32_t));
628 if(get_objc_class(def
, &objc_class
, &trunc
, objc_sections
,
629 nobjc_sections
, host_byte_sex
, swapped
) == TRUE
){
630 printf("\tdefs[%u] 0x%08x", i
, def
);
633 printf(" (entends past the end of the section)\n");
636 printf("\t\t isa 0x%08x", objc_class
.isa
);
638 if(verbose
&& CLS_GETINFO(&objc_class
, CLS_META
)){
639 p
= get_pointer(objc_class
.isa
, &left
, objc_sections
,
640 nobjc_sections
, &cstring_section
);
642 printf(" %.*s\n", (int)left
, p
);
644 printf(" (not in an " SEG_OBJC
" section)\n");
649 printf("\t super_class 0x%08x",objc_class
.super_class
);
651 p
= get_pointer(objc_class
.super_class
, &left
,
652 objc_sections
, nobjc_sections
, &cstring_section
);
654 printf(" %.*s\n", (int)left
, p
);
656 printf(" (not in an " SEG_OBJC
" section)\n");
661 printf("\t\t name 0x%08x", objc_class
.name
);
663 p
= get_pointer(objc_class
.name
, &left
,
664 objc_sections
, nobjc_sections
, &cstring_section
);
666 printf(" %.*s\n", (int)left
, p
);
668 printf(" (not in an " SEG_OBJC
" section)\n");
672 printf("\t\t version 0x%08x\n",
673 (unsigned int)objc_class
.version
);
674 printf("\t\t info 0x%08x",
675 (unsigned int)objc_class
.info
);
677 if(CLS_GETINFO(&objc_class
, CLS_CLASS
))
678 printf(" CLS_CLASS\n");
679 else if(CLS_GETINFO(&objc_class
, CLS_META
))
680 printf(" CLS_META\n");
686 printf("\t instance_size 0x%08x\n",
687 (unsigned int)objc_class
.instance_size
);
689 if(get_ivar_list(objc_class
.ivars
, &objc_ivar_list
,
690 &ivar_list
, &ivar_list_left
, &trunc
,
691 objc_sections
, nobjc_sections
, host_byte_sex
,
693 printf("\t\t ivars 0x%08x\n",
694 (unsigned int)objc_class
.ivars
);
696 printf("\t\t objc_ivar_list extends past end "
697 "of " SECT_OBJC_SYMBOLS
" section\n");
698 printf("\t\t ivar_count %d\n",
699 objc_ivar_list
.ivar_count
);
701 j
< (uint32_t)objc_ivar_list
.ivar_count
;
703 if((j
+ 1) * sizeof(struct objc_ivar_t
) >
705 printf("\t\t remaining ivar's extend past "
706 "the of the section\n");
709 memcpy(&ivar
, ivar_list
+ j
,
710 sizeof(struct objc_ivar_t
));
712 swap_objc_ivar_t(&ivar
, host_byte_sex
);
714 printf("\t\t\tivar_name 0x%08x",
715 (unsigned int)ivar
.ivar_name
);
717 p
= get_pointer(ivar
.ivar_name
, &left
,
718 objc_sections
, nobjc_sections
, &cstring_section
);
720 printf(" %.*s\n", (int)left
, p
);
722 printf(" (not in an " SEG_OBJC
727 printf("\t\t\tivar_type 0x%08x",
728 (unsigned int)ivar
.ivar_type
);
730 p
= get_pointer(ivar
.ivar_type
, &left
,
731 objc_sections
, nobjc_sections
, &cstring_section
);
733 printf(" %.*s\n", (int)left
, p
);
735 printf(" (not in an " SEG_OBJC
740 printf("\t\t ivar_offset 0x%08x\n",
741 (unsigned int)ivar
.ivar_offset
);
745 printf("\t\t ivars 0x%08x (not in an " SEG_OBJC
747 (unsigned int)objc_class
.ivars
);
750 printf("\t\t methods 0x%08x",
751 (unsigned int)objc_class
.methodLists
);
752 if(print_method_list(objc_class
.methodLists
,
753 objc_sections
, nobjc_sections
,
755 host_byte_sex
, swapped
, sorted_symbols
,
756 nsorted_symbols
, verbose
) == FALSE
)
757 printf(" (not in an " SEG_OBJC
" section)\n");
759 printf("\t\t cache 0x%08x\n",
760 (unsigned int)objc_class
.cache
);
762 printf("\t\tprotocols 0x%08x",
763 (unsigned int)objc_class
.protocols
);
764 if(print_protocol_list(16, objc_class
.protocols
,
765 objc_sections
, nobjc_sections
, &cstring_section
,
766 host_byte_sex
, swapped
, verbose
) == FALSE
)
767 printf(" (not in an " SEG_OBJC
" section)\n");
769 if(CLS_GETINFO((&objc_class
), CLS_CLASS
)){
770 printf("\tMeta Class");
771 if(get_objc_class((uint32_t)objc_class
.isa
,
772 &objc_class
, &trunc
, objc_sections
, nobjc_sections
,
773 host_byte_sex
, swapped
) == TRUE
){
774 goto print_objc_class
;
777 printf(" (not in " SECT_OBJC_SYMBOLS
782 printf("\tdefs[%u] 0x%08x (not in an " SEG_OBJC
783 " section)\n", i
, (unsigned int)def
);
785 if(symtab
.cat_def_cnt
> 0)
786 printf("\tCategory Definitions\n");
787 for(i
= 0; i
< symtab
.cat_def_cnt
; i
++){
788 if((i
+ symtab
.cls_def_cnt
+ 1) * sizeof(uint32_t) >
790 printf("\t(remaining category defs entries entends "
791 "past the end of the section)\n");
795 memcpy(&def
, defs
+ i
+ symtab
.cls_def_cnt
, sizeof(uint32_t));
799 if(get_objc_category(def
, &objc_category
, &trunc
,
800 objc_sections
, nobjc_sections
,
801 host_byte_sex
, swapped
) == TRUE
){
802 printf("\tdefs[%u] 0x%08x", i
+ symtab
.cls_def_cnt
,
805 printf(" (entends past the end of the section)\n");
808 printf("\t category name 0x%08x",
809 objc_category
.category_name
);
811 p
= get_pointer(objc_category
.category_name
, &left
,
812 objc_sections
, nobjc_sections
,
815 printf(" %.*s\n", (int)left
, p
);
817 printf(" (not in an " SEG_OBJC
" section)\n");
822 printf("\t\t class name 0x%08x", objc_category
.class_name
);
824 p
= get_pointer(objc_category
.class_name
, &left
,
825 objc_sections
, nobjc_sections
,
828 printf(" %.*s\n", (int)left
, p
);
830 printf(" (not in an " SEG_OBJC
" section)\n");
835 printf("\t instance methods 0x%08x",
836 objc_category
.instance_methods
);
837 if(print_method_list(objc_category
.instance_methods
,
838 objc_sections
, nobjc_sections
,
840 host_byte_sex
, swapped
,
841 sorted_symbols
, nsorted_symbols
,
843 printf(" (not in an " SEG_OBJC
" section)\n");
845 printf("\t class methods 0x%08x",
846 objc_category
.class_methods
);
847 if(print_method_list(objc_category
.class_methods
,
848 objc_sections
, nobjc_sections
, &cstring_section
,
849 host_byte_sex
, swapped
, sorted_symbols
, nsorted_symbols
,
851 printf(" (not in an " SEG_OBJC
" section)\n");
854 printf("\tdefs[%u] 0x%08x (not in an " SEG_OBJC
855 " section)\n", i
+ symtab
.cls_def_cnt
,
860 printf("Contents of (%s,%s) section\n", SEG_OBJC
, "__image_info");
861 get_objc_sections(load_commands
, ncmds
, sizeofcmds
, object_byte_sex
,
862 object_addr
, object_size
, &objc_sections
,
863 &nobjc_sections
, "__image_info", (char **)&imageInfo
,
864 &imageInfo_addr
, &imageInfo_size
);
865 memset(&info
, '\0', sizeof(struct imageInfo_t
));
866 if(imageInfo_size
< sizeof(struct imageInfo_t
)){
867 memcpy(&info
, imageInfo
, imageInfo_size
);
868 printf(" (imageInfo entends past the end of the section)\n");
871 memcpy(&info
, imageInfo
, sizeof(struct imageInfo_t
));
873 swap_imageInfo_t(&info
, host_byte_sex
);
874 printf(" version %u\n", info
.version
);
875 printf(" flags 0x%x", info
.flags
);
889 print_objc_protocol_section(
890 struct load_command
*load_commands
,
893 enum byte_sex object_byte_sex
,
895 uint32_t object_size
,
898 enum byte_sex host_byte_sex
;
900 struct section_info
*objc_sections
, cstring_section
;
901 uint32_t nobjc_sections
;
902 struct objc_protocol_t
*protocols
, *p
, protocol
;
903 uint32_t protocols_addr
, protocols_size
;
906 printf("Contents of (" SEG_OBJC
",__protocol) section\n");
907 get_objc_sections(load_commands
, ncmds
, sizeofcmds
, object_byte_sex
,
908 object_addr
, object_size
, &objc_sections
,
909 &nobjc_sections
, "__protocol", (char **)&protocols
,
910 &protocols_addr
, &protocols_size
);
913 get_cstring_section(load_commands
, ncmds
, sizeofcmds
, object_byte_sex
,
914 object_addr
, object_size
, &cstring_section
);
916 host_byte_sex
= get_host_byte_sex();
917 swapped
= host_byte_sex
!= object_byte_sex
;
919 for(p
= protocols
; (char *)p
< (char *)protocols
+ protocols_size
; p
++){
921 memset(&protocol
, '\0', sizeof(struct objc_protocol_t
));
922 left
= protocols_size
- (p
- protocols
);
923 size
= left
< sizeof(struct objc_protocol_t
) ?
924 left
: sizeof(struct objc_protocol_t
);
925 memcpy(&protocol
, p
, size
);
927 if((char *)p
+ sizeof(struct objc_protocol_t
) >
928 (char *)p
+ protocols_size
)
929 printf("Protocol extends past end of __protocol section\n");
930 printf("Protocol 0x%x\n", (unsigned int)
931 (protocols_addr
+ (char *)p
- (char *)protocols
));
933 print_protocol(0, &protocol
,
934 objc_sections
, nobjc_sections
, &cstring_section
,
935 host_byte_sex
, swapped
, verbose
);
940 print_objc_string_object_section(
942 struct load_command
*load_commands
,
945 enum byte_sex object_byte_sex
,
947 uint32_t object_size
,
950 enum byte_sex host_byte_sex
;
952 struct section_info
*objc_sections
;
953 uint32_t nobjc_sections
;
954 struct section_info cstring_section
;
955 struct objc_string_object_t
*string_objects
, *s
, string_object
;
956 uint32_t string_objects_addr
, string_objects_size
;
960 printf("Contents of (" SEG_OBJC
",%s) section\n", sectname
);
961 get_objc_sections(load_commands
, ncmds
, sizeofcmds
, object_byte_sex
,
962 object_addr
, object_size
, &objc_sections
,
963 &nobjc_sections
, sectname
, (char **)&string_objects
,
964 &string_objects_addr
, &string_objects_size
);
966 get_cstring_section(load_commands
, ncmds
, sizeofcmds
, object_byte_sex
,
967 object_addr
, object_size
, &cstring_section
);
969 host_byte_sex
= get_host_byte_sex();
970 swapped
= host_byte_sex
!= object_byte_sex
;
972 for(s
= string_objects
;
973 (char *)s
< (char *)string_objects
+ string_objects_size
;
976 memset(&string_object
, '\0', sizeof(struct objc_string_object_t
));
977 left
= string_objects_size
- (s
- string_objects
);
978 size
= left
< sizeof(struct objc_string_object_t
) ?
979 left
: sizeof(struct objc_string_object_t
);
980 memcpy(&string_object
, s
, size
);
982 if((char *)s
+ sizeof(struct objc_string_object_t
) >
983 (char *)s
+ string_objects_size
)
984 printf("String Object extends past end of %s section\n",
986 printf("String Object 0x%x\n", (unsigned int)
987 (string_objects_addr
+ (char *)s
- (char *)string_objects
));
990 swap_string_object_t(&string_object
, host_byte_sex
);
991 printf(" isa 0x%x\n", string_object
.isa
);
992 printf(" characters 0x%x",
993 (unsigned int)string_object
.characters
);
995 p
= get_pointer(string_object
.characters
, &left
,
996 &cstring_section
, 1, &cstring_section
);
998 printf(" %.*s\n", (int)left
, p
);
1000 printf(" (not in the (" SEG_TEXT
",__cstring) section)\n");
1004 printf(" _length %u\n", string_object
._length
);
1009 * PHASH[SIZEHASHTABLE];
1010 * HASH[?]; variable sized (computed from size of section).
1013 print_objc_runtime_setup_section(
1014 struct load_command
*load_commands
,
1016 uint32_t sizeofcmds
,
1017 enum byte_sex object_byte_sex
,
1019 uint32_t object_size
,
1023 enum byte_sex host_byte_sex
;
1025 struct section_info
*objc_sections
, cstring_section
;
1026 uint32_t i
, nobjc_sections
, left
;
1027 struct _hashEntry_t
**PHASH
, *HASH
, _hashEntry
;
1029 uint32_t sect_addr
, sect_size
, phash
;
1031 printf("Contents of (" SEG_OBJC
",__runtime_setup) section\n");
1032 get_objc_sections(load_commands
, ncmds
, sizeofcmds
, object_byte_sex
,
1033 object_addr
, object_size
, &objc_sections
,
1034 &nobjc_sections
, "__runtime_setup", §
, §_addr
,
1038 get_cstring_section(load_commands
, ncmds
, sizeofcmds
, object_byte_sex
,
1039 object_addr
, object_size
, &cstring_section
);
1041 host_byte_sex
= get_host_byte_sex();
1042 swapped
= host_byte_sex
!= object_byte_sex
;
1044 PHASH
= (struct _hashEntry_t
**)sect
;
1046 i
< SIZEHASHTABLE
&& (i
+ 1) * sizeof(uint32_t) < sect_size
;
1049 memcpy(&phash
, PHASH
+ i
, sizeof(uint32_t));
1051 phash
= SWAP_INT(phash
);
1056 printf("PHASH[%3u] 0x%x", i
, (unsigned int)phash
);
1057 if(print_PHASH(4, phash
,
1058 objc_sections
, nobjc_sections
, &cstring_section
,
1059 host_byte_sex
, swapped
, verbose
) == FALSE
)
1060 printf(" (not in an " SEG_OBJC
" section)\n");
1063 HASH
= (struct _hashEntry_t
*)(PHASH
+ SIZEHASHTABLE
);
1064 for(i
= 0; (char *)(HASH
+ i
) < sect
+ sect_size
; i
++){
1065 memcpy((char *)&_hashEntry
, HASH
+ i
, sizeof(struct _hashEntry_t
));
1067 swap_hashEntry_t(&_hashEntry
, host_byte_sex
);
1069 printf("HASH at 0x%08x\n",
1070 (unsigned int)(sect_addr
+ (char *)(HASH
+ i
) - sect
));
1071 printf(" sel 0x%08x", (unsigned int)_hashEntry
.sel
);
1073 p
= get_pointer(_hashEntry
.sel
, &left
, objc_sections
,
1074 nobjc_sections
, &cstring_section
);
1076 printf(" %.*s\n", (int)left
, p
);
1078 printf(" (not in an " SEG_OBJC
" section)\n");
1083 printf(" next 0x%08x", (unsigned int)_hashEntry
.next
);
1084 if(_hashEntry
.next
== 0){
1088 if((uint32_t)_hashEntry
.next
< sect_addr
||
1089 (uint32_t)_hashEntry
.next
>= sect_addr
+ sect_size
)
1090 printf(" (not in the ("SEG_OBJC
",__runtime_setup "
1101 struct load_command
*load_commands
,
1103 uint32_t sizeofcmds
,
1104 enum byte_sex object_byte_sex
,
1106 uint32_t object_size
,
1107 struct section_info
**objc_sections
,
1108 uint32_t *nobjc_sections
,
1111 uint32_t *sect_addr
,
1112 uint32_t *sect_size
)
1114 enum byte_sex host_byte_sex
;
1115 enum bool swapped
, encrypt_found
, encrypt64_found
;
1117 uint32_t i
, j
, left
, size
;
1118 struct load_command lcmd
, *lc
;
1120 struct segment_command sg
;
1122 struct encryption_info_command encrypt
;
1123 struct encryption_info_command_64 encrypt64
;
1125 host_byte_sex
= get_host_byte_sex();
1126 swapped
= host_byte_sex
!= object_byte_sex
;
1128 *objc_sections
= NULL
;
1129 *nobjc_sections
= 0;
1133 encrypt_found
= FALSE
;
1134 encrypt64_found
= FALSE
;
1137 for(i
= 0 ; i
< ncmds
; i
++){
1138 memcpy((char *)&lcmd
, (char *)lc
, sizeof(struct load_command
));
1140 swap_load_command(&lcmd
, host_byte_sex
);
1141 if(lcmd
.cmdsize
% sizeof(int32_t) != 0)
1142 printf("load command %u size not a multiple of "
1143 "sizeof(int32_t)\n", i
);
1144 if((char *)lc
+ lcmd
.cmdsize
>
1145 (char *)load_commands
+ sizeofcmds
)
1146 printf("load command %u extends past end of load "
1148 left
= sizeofcmds
- ((char *)lc
- (char *)load_commands
);
1152 memset((char *)&sg
, '\0', sizeof(struct segment_command
));
1153 size
= left
< sizeof(struct segment_command
) ?
1154 left
: sizeof(struct segment_command
);
1155 memcpy((char *)&sg
, (char *)lc
, size
);
1157 swap_segment_command(&sg
, host_byte_sex
);
1159 p
= (char *)lc
+ sizeof(struct segment_command
);
1160 for(j
= 0 ; j
< sg
.nsects
; j
++){
1161 if(p
+ sizeof(struct section
) >
1162 (char *)load_commands
+ sizeofcmds
){
1163 printf("section structure command extends past "
1164 "end of load commands\n");
1166 left
= sizeofcmds
- (p
- (char *)load_commands
);
1167 memset((char *)&s
, '\0', sizeof(struct section
));
1168 size
= left
< sizeof(struct section
) ?
1169 left
: sizeof(struct section
);
1170 memcpy((char *)&s
, p
, size
);
1172 swap_section(&s
, 1, host_byte_sex
);
1174 if(strcmp(s
.segname
, SEG_OBJC
) == 0){
1175 *objc_sections
= reallocate(*objc_sections
,
1176 sizeof(struct section_info
) * (*nobjc_sections
+ 1));
1177 (*objc_sections
)[*nobjc_sections
].addr
= s
.addr
;
1178 (*objc_sections
)[*nobjc_sections
].contents
=
1179 object_addr
+ s
.offset
;
1180 (*objc_sections
)[*nobjc_sections
].offset
= s
.offset
;
1181 (*objc_sections
)[*nobjc_sections
].zerofill
=
1182 (s
.flags
& SECTION_TYPE
) == S_ZEROFILL
? TRUE
: FALSE
;
1183 if(s
.offset
> object_size
){
1184 printf("section contents of: (%.16s,%.16s) is past "
1185 "end of file\n", s
.segname
, s
.sectname
);
1186 (*objc_sections
)[*nobjc_sections
].size
= 0;
1188 else if(s
.offset
+ s
.size
> object_size
){
1189 printf("part of section contents of: (%.16s,%.16s) "
1190 "is past end of file\n",
1191 s
.segname
, s
.sectname
);
1192 (*objc_sections
)[*nobjc_sections
].size
=
1193 object_size
- s
.offset
;
1196 (*objc_sections
)[*nobjc_sections
].size
= s
.size
;
1198 if(strncmp(s
.sectname
, sectname
, 16) == 0){
1200 printf("more than one (" SEG_OBJC
",%s) "
1201 "section\n", sectname
);
1203 *sect
= (object_addr
+ s
.offset
);
1204 *sect_size
= s
.size
;
1205 *sect_addr
= s
.addr
;
1208 if(sg
.flags
& SG_PROTECTED_VERSION_1
)
1209 (*objc_sections
)[*nobjc_sections
].protected = TRUE
;
1211 (*objc_sections
)[*nobjc_sections
].protected = FALSE
;
1212 (*nobjc_sections
)++;
1215 if(p
+ sizeof(struct section
) >
1216 (char *)load_commands
+ sizeofcmds
)
1221 case LC_ENCRYPTION_INFO
:
1222 memset((char *)&encrypt
, '\0',
1223 sizeof(struct encryption_info_command
));
1224 size
= left
< sizeof(struct encryption_info_command
) ?
1225 left
: sizeof(struct encryption_info_command
);
1226 memcpy((char *)&encrypt
, (char *)lc
, size
);
1228 swap_encryption_command(&encrypt
, host_byte_sex
);
1229 encrypt_found
= TRUE
;
1231 case LC_ENCRYPTION_INFO_64
:
1232 memset((char *)&encrypt64
, '\0',
1233 sizeof(struct encryption_info_command_64
));
1234 size
= left
< sizeof(struct encryption_info_command_64
) ?
1235 left
: sizeof(struct encryption_info_command_64
);
1236 memcpy((char *)&encrypt64
, (char *)lc
, size
);
1238 swap_encryption_command_64(&encrypt64
, host_byte_sex
);
1239 encrypt64_found
= TRUE
;
1242 if(lcmd
.cmdsize
== 0){
1243 printf("load command %u size zero (can't advance to other "
1244 "load commands)\n", i
);
1247 lc
= (struct load_command
*)((char *)lc
+ lcmd
.cmdsize
);
1248 if((char *)lc
> (char *)load_commands
+ sizeofcmds
)
1252 if(encrypt_found
== TRUE
&& encrypt
.cryptid
!= 0){
1253 for(i
= 0; i
< *nobjc_sections
; i
++){
1254 if((*objc_sections
)[i
].size
> 0 &&
1255 (*objc_sections
)[i
].zerofill
== FALSE
){
1256 if((*objc_sections
)[i
].offset
>
1257 encrypt
.cryptoff
+ encrypt
.cryptsize
){
1258 /* section starts past encryption area */ ;
1260 else if((*objc_sections
)[i
].offset
+
1261 (*objc_sections
)[i
].size
< encrypt
.cryptoff
){
1262 /* section ends before encryption area */ ;
1265 /* section has part in the encrypted area */
1266 (*objc_sections
)[i
].protected = TRUE
;
1271 if(encrypt64_found
== TRUE
&& encrypt64
.cryptid
!= 0){
1272 for(i
= 0; i
< *nobjc_sections
; i
++){
1273 if((*objc_sections
)[i
].size
> 0 &&
1274 (*objc_sections
)[i
].zerofill
== FALSE
){
1275 if((*objc_sections
)[i
].offset
>
1276 encrypt64
.cryptoff
+ encrypt64
.cryptsize
){
1277 /* section starts past encryption area */ ;
1279 else if((*objc_sections
)[i
].offset
+
1280 (*objc_sections
)[i
].size
< encrypt64
.cryptoff
){
1281 /* section ends before encryption area */ ;
1284 /* section has part in the encrypted area */
1285 (*objc_sections
)[i
].protected = TRUE
;
1294 get_cstring_section(
1295 struct load_command
*load_commands
,
1297 uint32_t sizeofcmds
,
1298 enum byte_sex object_byte_sex
,
1300 uint32_t object_size
,
1301 struct section_info
*cstring_section
)
1303 enum byte_sex host_byte_sex
;
1306 uint32_t i
, j
, left
, size
;
1307 struct load_command lcmd
, *lc
;
1309 struct segment_command sg
;
1312 host_byte_sex
= get_host_byte_sex();
1313 swapped
= host_byte_sex
!= object_byte_sex
;
1315 memset(cstring_section
, '\0', sizeof(struct section_info
));
1318 for(i
= 0 ; i
< ncmds
; i
++){
1319 memcpy((char *)&lcmd
, (char *)lc
, sizeof(struct load_command
));
1321 swap_load_command(&lcmd
, host_byte_sex
);
1322 if(lcmd
.cmdsize
% sizeof(int32_t) != 0)
1323 printf("load command %u size not a multiple of "
1324 "sizeof(int32_t)\n", i
);
1325 if((char *)lc
+ lcmd
.cmdsize
>
1326 (char *)load_commands
+ sizeofcmds
)
1327 printf("load command %u extends past end of load "
1329 left
= sizeofcmds
- ((char *)lc
- (char *)load_commands
);
1333 memset((char *)&sg
, '\0', sizeof(struct segment_command
));
1334 size
= left
< sizeof(struct segment_command
) ?
1335 left
: sizeof(struct segment_command
);
1336 memcpy((char *)&sg
, (char *)lc
, size
);
1338 swap_segment_command(&sg
, host_byte_sex
);
1340 p
= (char *)lc
+ sizeof(struct segment_command
);
1341 for(j
= 0 ; j
< sg
.nsects
; j
++){
1342 if(p
+ sizeof(struct section
) >
1343 (char *)load_commands
+ sizeofcmds
){
1344 printf("section structure command extends past "
1345 "end of load commands\n");
1347 left
= sizeofcmds
- (p
- (char *)load_commands
);
1348 memset((char *)&s
, '\0', sizeof(struct section
));
1349 size
= left
< sizeof(struct section
) ?
1350 left
: sizeof(struct section
);
1351 memcpy((char *)&s
, p
, size
);
1353 swap_section(&s
, 1, host_byte_sex
);
1355 if(strcmp(s
.segname
, SEG_TEXT
) == 0 &&
1356 strcmp(s
.sectname
, "__cstring") == 0){
1357 cstring_section
->addr
= s
.addr
;
1358 cstring_section
->contents
= object_addr
+ s
.offset
;
1359 if(s
.offset
> object_size
){
1360 printf("section contents of: (%.16s,%.16s) is past "
1361 "end of file\n", s
.segname
, s
.sectname
);
1362 cstring_section
->size
= 0;
1364 else if(s
.offset
+ s
.size
> object_size
){
1365 printf("part of section contents of: (%.16s,%.16s) "
1366 "is past end of file\n",
1367 s
.segname
, s
.sectname
);
1368 cstring_section
->size
= object_size
- s
.offset
;
1371 cstring_section
->size
= s
.size
;
1372 if(sg
.flags
& SG_PROTECTED_VERSION_1
)
1373 cstring_section
->protected = TRUE
;
1375 cstring_section
->protected = FALSE
;
1379 if(p
+ sizeof(struct section
) >
1380 (char *)load_commands
+ sizeofcmds
)
1386 if(lcmd
.cmdsize
== 0){
1387 printf("load command %u size zero (can't advance to other "
1388 "load commands)\n", i
);
1391 lc
= (struct load_command
*)((char *)lc
+ lcmd
.cmdsize
);
1392 if((char *)lc
> (char *)load_commands
+ sizeofcmds
)
1401 struct section_info
*objc_sections
,
1402 uint32_t nobjc_sections
,
1403 struct section_info
*cstring_section_ptr
,
1404 enum byte_sex host_byte_sex
,
1406 struct symbol
*sorted_symbols
,
1407 uint32_t nsorted_symbols
,
1410 struct objc_method_t
*methods
, method
;
1411 struct objc_method_list_t method_list
;
1413 uint32_t i
, methods_left
, left
;
1416 if(get_method_list(addr
, &method_list
, &methods
, &methods_left
, &trunc
,
1417 objc_sections
, nobjc_sections
,
1418 host_byte_sex
, swapped
) == FALSE
)
1423 printf("\t\t objc_method_list extends past end of the section\n");
1425 printf("\t\t obsolete 0x%08x\n",
1426 (unsigned int)method_list
.obsolete
);
1427 printf("\t\t method_count %d\n",
1428 method_list
.method_count
);
1430 for(i
= 0; i
< (uint32_t)method_list
.method_count
; i
++){
1431 if((i
+ 1) * sizeof(struct objc_method_t
) > methods_left
){
1432 printf("\t\t remaining method's extend past the of the "
1436 memcpy(&method
, methods
+ i
, sizeof(struct objc_method_t
));
1438 swap_objc_method_t(&method
, host_byte_sex
);
1440 printf("\t\t method_name 0x%08x", method
.method_name
);
1442 p
= get_pointer(method
.method_name
, &left
, objc_sections
,
1443 nobjc_sections
, cstring_section_ptr
);
1445 printf(" %.*s\n", (int)left
, p
);
1447 printf(" (not in an " SEG_OBJC
" section)\n");
1452 printf("\t\t method_types 0x%08x", method
.method_types
);
1454 p
= get_pointer(method
.method_types
, &left
, objc_sections
,
1455 nobjc_sections
, cstring_section_ptr
);
1457 printf(" %.*s\n", (int)left
, p
);
1459 printf(" (not in an " SEG_OBJC
" section)\n");
1463 printf("\t\t method_imp 0x%08x ", method
.method_imp
);
1465 print_label(method
.method_imp
, FALSE
, sorted_symbols
,
1474 print_protocol_list(
1477 struct section_info
*objc_sections
,
1478 uint32_t nobjc_sections
,
1479 struct section_info
*cstring_section_ptr
,
1480 enum byte_sex host_byte_sex
,
1485 struct objc_protocol_t protocol
;
1486 struct objc_protocol_list_t protocol_list
;
1488 uint32_t l
, i
, list_left
;
1490 if(get_protocol_list(addr
, &protocol_list
, &list
, &list_left
, &trunc
,
1491 objc_sections
, nobjc_sections
,
1492 host_byte_sex
, swapped
) == FALSE
)
1497 print_indent(indent
);
1498 printf(" objc_protocol_list extends past end of the section\n");
1501 print_indent(indent
);
1502 printf(" next 0x%08x\n",
1503 (unsigned int)protocol_list
.next
);
1504 print_indent(indent
);
1505 printf(" count %u\n", protocol_list
.count
);
1507 for(i
= 0; i
< protocol_list
.count
; i
++){
1508 if((i
+ 1) * sizeof(uint32_t) > list_left
){
1509 print_indent(indent
);
1510 printf(" remaining list entries extend past the of the "
1514 memcpy(&l
, list
+ i
, sizeof(uint32_t));
1518 print_indent(indent
);
1519 printf(" list[%u] 0x%08x", i
, l
);
1520 if(get_protocol(l
, &protocol
, &trunc
, objc_sections
, nobjc_sections
,
1521 host_byte_sex
, swapped
) == FALSE
){
1522 printf(" (not in an " SEG_OBJC
" section)\n");
1527 print_indent(indent
);
1528 printf(" Protocol extends past end of the "
1531 print_protocol(indent
, &protocol
,
1532 objc_sections
, nobjc_sections
, cstring_section_ptr
,
1533 host_byte_sex
, swapped
, verbose
);
1542 struct objc_protocol_t
*protocol
,
1543 struct section_info
*objc_sections
,
1544 uint32_t nobjc_sections
,
1545 struct section_info
*cstring_section_ptr
,
1546 enum byte_sex host_byte_sex
,
1553 print_indent(indent
);
1554 printf(" isa 0x%08x\n",
1555 (unsigned int)protocol
->isa
);
1556 print_indent(indent
);
1557 printf(" protocol_name 0x%08x",
1558 (unsigned int)protocol
->protocol_name
);
1560 p
= get_pointer(protocol
->protocol_name
, &left
,
1561 objc_sections
, nobjc_sections
, cstring_section_ptr
);
1563 printf(" %.*s\n", (int)left
, p
);
1565 printf(" (not in an " SEG_OBJC
" section)\n");
1569 print_indent(indent
);
1570 printf(" protocol_list 0x%08x",
1571 (unsigned int)protocol
->protocol_list
);
1572 if(print_protocol_list(indent
+ 4, protocol
->protocol_list
,
1573 objc_sections
, nobjc_sections
, cstring_section_ptr
,
1574 host_byte_sex
, swapped
, verbose
) == FALSE
)
1575 printf(" (not in an " SEG_OBJC
" section)\n");
1577 print_indent(indent
);
1578 printf(" instance_methods 0x%08x",
1579 (unsigned int)protocol
->instance_methods
);
1580 if(print_method_description_list(indent
, protocol
->instance_methods
,
1581 objc_sections
, nobjc_sections
, cstring_section_ptr
,
1582 host_byte_sex
, swapped
, verbose
) == FALSE
)
1583 printf(" (not in an " SEG_OBJC
" section)\n");
1585 print_indent(indent
);
1586 printf(" class_methods 0x%08x",
1587 (unsigned int)protocol
->class_methods
);
1588 if(print_method_description_list(indent
, protocol
->class_methods
,
1589 objc_sections
, nobjc_sections
, cstring_section_ptr
,
1590 host_byte_sex
, swapped
, verbose
) == FALSE
)
1591 printf(" (not in an " SEG_OBJC
" section)\n");
1596 print_method_description_list(
1599 struct section_info
*objc_sections
,
1600 uint32_t nobjc_sections
,
1601 struct section_info
*cstring_section_ptr
,
1602 enum byte_sex host_byte_sex
,
1606 struct objc_method_description_list_t mdl
;
1607 struct objc_method_description_t
*list
, md
;
1609 uint32_t i
, list_left
, left
;
1612 if(get_method_description_list(addr
, &mdl
, &list
, &list_left
,
1613 &trunc
, objc_sections
, nobjc_sections
,
1614 host_byte_sex
, swapped
) == FALSE
)
1619 print_indent(indent
);
1620 printf(" objc_method_description_list extends past end of the "
1624 print_indent(indent
);
1625 printf(" count %d\n", mdl
.count
);
1627 for(i
= 0; i
< (uint32_t)mdl
.count
; i
++){
1628 if((i
+ 1) * sizeof(struct objc_method_description_t
) > list_left
){
1629 print_indent(indent
);
1630 printf(" remaining list entries extend past the of the "
1634 print_indent(indent
);
1635 printf(" list[%u]\n", i
);
1636 memcpy(&md
, list
+ i
, sizeof(struct objc_method_description_t
));
1638 swap_objc_method_description_t(&md
, host_byte_sex
);
1640 print_indent(indent
);
1641 printf(" name 0x%08x", (unsigned int)md
.name
);
1643 p
= get_pointer(md
.name
, &left
,
1644 objc_sections
, nobjc_sections
, cstring_section_ptr
);
1646 printf(" %.*s\n", (int)left
, p
);
1648 printf(" (not in an " SEG_OBJC
" section)\n");
1653 print_indent(indent
);
1654 printf(" types 0x%08x", (unsigned int)md
.types
);
1656 p
= get_pointer(md
.types
, &left
,
1657 objc_sections
, nobjc_sections
, cstring_section_ptr
);
1659 printf(" %.*s\n", (int)left
, p
);
1661 printf(" (not in an " SEG_OBJC
" section)\n");
1673 struct section_info
*objc_sections
,
1674 uint32_t nobjc_sections
,
1675 struct section_info
*cstring_section_ptr
,
1676 enum byte_sex host_byte_sex
,
1680 struct _hashEntry_t _hashEntry
;
1685 if(get_hashEntry(addr
, &_hashEntry
, &trunc
, objc_sections
,
1686 nobjc_sections
, host_byte_sex
, swapped
) == FALSE
)
1691 print_indent(indent
);
1692 printf("_hashEntry extends past end of the section\n");
1695 print_indent(indent
);
1696 printf(" sel 0x%08x", (unsigned int)_hashEntry
.sel
);
1698 p
= get_pointer(_hashEntry
.sel
, &left
,
1699 objc_sections
, nobjc_sections
, cstring_section_ptr
);
1701 printf(" %.*s\n", (int)left
, p
);
1703 printf(" (not in an " SEG_OBJC
" section)\n");
1708 print_indent(indent
);
1709 printf("next 0x%08x", (unsigned int)_hashEntry
.next
);
1710 if(_hashEntry
.next
== 0){
1714 if(print_PHASH(indent
+4, _hashEntry
.next
,
1715 objc_sections
, nobjc_sections
, cstring_section_ptr
,
1716 host_byte_sex
, swapped
, verbose
) == FALSE
)
1717 printf(" (not in an " SEG_OBJC
" section)\n");
1728 for(i
= 0; i
< indent
; ){
1729 if(indent
- i
>= 8){
1734 printf("%.*s", (int)(indent
- i
), " ");
1745 struct section_info
*objc_sections
,
1746 uint32_t nobjc_sections
,
1747 struct section_info
*cstring_section_ptr
)
1749 void* returnValue
= NULL
;
1752 if(addr
>= cstring_section_ptr
->addr
&&
1753 addr
< cstring_section_ptr
->addr
+ cstring_section_ptr
->size
){
1754 *left
= cstring_section_ptr
->size
-
1755 (addr
- cstring_section_ptr
->addr
);
1756 if(cstring_section_ptr
->protected == TRUE
)
1757 returnValue
= "some string from a protected section";
1759 returnValue
= (cstring_section_ptr
->contents
+
1760 (addr
- cstring_section_ptr
->addr
));
1762 for(i
= 0; returnValue
!= NULL
&& i
< nobjc_sections
; i
++){
1763 if(addr
>= objc_sections
[i
].addr
&&
1764 addr
< objc_sections
[i
].addr
+ objc_sections
[i
].size
){
1765 *left
= objc_sections
[i
].size
-
1766 (addr
- objc_sections
[i
].addr
);
1767 returnValue
= (objc_sections
[i
].contents
+
1768 (addr
- objc_sections
[i
].addr
));
1771 return(returnValue
);
1778 struct objc_symtab_t
*symtab
,
1782 struct section_info
*objc_sections
,
1783 uint32_t nobjc_sections
,
1784 enum byte_sex host_byte_sex
,
1789 memset(symtab
, '\0', sizeof(struct objc_symtab_t
));
1792 for(i
= 0; i
< nobjc_sections
; i
++){
1793 if(addr
>= objc_sections
[i
].addr
&&
1794 addr
< objc_sections
[i
].addr
+ objc_sections
[i
].size
){
1796 *left
= objc_sections
[i
].size
-
1797 (addr
- objc_sections
[i
].addr
);
1798 if(*left
>= sizeof(struct objc_symtab_t
) - sizeof(uint32_t)){
1800 objc_sections
[i
].contents
+
1801 (addr
- objc_sections
[i
].addr
),
1802 sizeof(struct objc_symtab_t
) - sizeof(uint32_t));
1803 *left
-= sizeof(struct objc_symtab_t
) - sizeof(uint32_t);
1804 *defs
= (uint32_t *)(objc_sections
[i
].contents
+
1805 (addr
- objc_sections
[i
].addr
) +
1806 sizeof(struct objc_symtab_t
) -
1812 objc_sections
[i
].contents
+
1813 (addr
- objc_sections
[i
].addr
),
1820 swap_objc_symtab_t(symtab
, host_byte_sex
);
1831 struct objc_class_t
*objc_class
,
1833 struct section_info
*objc_sections
,
1834 uint32_t nobjc_sections
,
1835 enum byte_sex host_byte_sex
,
1840 memset(objc_class
, '\0', sizeof(struct objc_class_t
));
1843 for(i
= 0; i
< nobjc_sections
; i
++){
1844 if(addr
>= objc_sections
[i
].addr
&&
1845 addr
< objc_sections
[i
].addr
+ objc_sections
[i
].size
){
1847 left
= objc_sections
[i
].size
-
1848 (addr
- objc_sections
[i
].addr
);
1849 if(left
>= sizeof(struct objc_class_t
)){
1851 objc_sections
[i
].contents
+
1852 (addr
- objc_sections
[i
].addr
),
1853 sizeof(struct objc_class_t
));
1858 objc_sections
[i
].contents
+
1859 (addr
- objc_sections
[i
].addr
),
1864 swap_objc_class_t(objc_class
, host_byte_sex
);
1875 struct objc_category_t
*objc_category
,
1877 struct section_info
*objc_sections
,
1878 uint32_t nobjc_sections
,
1879 enum byte_sex host_byte_sex
,
1884 memset(objc_category
, '\0', sizeof(struct objc_category_t
));
1887 for(i
= 0; i
< nobjc_sections
; i
++){
1888 if(addr
>= objc_sections
[i
].addr
&&
1889 addr
< objc_sections
[i
].addr
+ objc_sections
[i
].size
){
1891 left
= objc_sections
[i
].size
-
1892 (addr
- objc_sections
[i
].addr
);
1893 if(left
>= sizeof(struct objc_category_t
)){
1894 memcpy(objc_category
,
1895 objc_sections
[i
].contents
+
1896 (addr
- objc_sections
[i
].addr
),
1897 sizeof(struct objc_category_t
));
1901 memcpy(objc_category
,
1902 objc_sections
[i
].contents
+
1903 (addr
- objc_sections
[i
].addr
),
1908 swap_objc_category_t(objc_category
, host_byte_sex
);
1919 struct objc_ivar_list_t
*objc_ivar_list
,
1920 struct objc_ivar_t
**ivar_list
,
1923 struct section_info
*objc_sections
,
1924 uint32_t nobjc_sections
,
1925 enum byte_sex host_byte_sex
,
1930 memset(objc_ivar_list
, '\0', sizeof(struct objc_ivar_list_t
));
1933 for(i
= 0; i
< nobjc_sections
; i
++){
1934 if(addr
>= objc_sections
[i
].addr
&&
1935 addr
< objc_sections
[i
].addr
+ objc_sections
[i
].size
){
1937 *left
= objc_sections
[i
].size
-
1938 (addr
- objc_sections
[i
].addr
);
1939 if(*left
>= sizeof(struct objc_ivar_list_t
) -
1940 sizeof(struct objc_ivar_t
)){
1941 memcpy(objc_ivar_list
,
1942 objc_sections
[i
].contents
+
1943 (addr
- objc_sections
[i
].addr
),
1944 sizeof(struct objc_ivar_list_t
) -
1945 sizeof(struct objc_ivar_t
));
1946 *left
-= sizeof(struct objc_ivar_list_t
) -
1947 sizeof(struct objc_ivar_t
);
1948 *ivar_list
= (struct objc_ivar_t
*)
1949 (objc_sections
[i
].contents
+
1950 (addr
- objc_sections
[i
].addr
) +
1951 sizeof(struct objc_ivar_list_t
) -
1952 sizeof(struct objc_ivar_t
));
1956 memcpy(objc_ivar_list
,
1957 objc_sections
[i
].contents
+
1958 (addr
- objc_sections
[i
].addr
),
1965 swap_objc_ivar_list_t(objc_ivar_list
, host_byte_sex
);
1976 struct objc_method_list_t
*method_list
,
1977 struct objc_method_t
**methods
,
1980 struct section_info
*objc_sections
,
1981 uint32_t nobjc_sections
,
1982 enum byte_sex host_byte_sex
,
1987 memset(method_list
, '\0', sizeof(struct objc_method_list_t
));
1990 for(i
= 0; i
< nobjc_sections
; i
++){
1991 if(addr
>= objc_sections
[i
].addr
&&
1992 addr
< objc_sections
[i
].addr
+ objc_sections
[i
].size
){
1994 *left
= objc_sections
[i
].size
-
1995 (addr
- objc_sections
[i
].addr
);
1996 if(*left
>= sizeof(struct objc_method_list_t
) -
1997 sizeof(struct objc_method_t
)){
1999 objc_sections
[i
].contents
+
2000 (addr
- objc_sections
[i
].addr
),
2001 sizeof(struct objc_method_list_t
) -
2002 sizeof(struct objc_method_t
));
2003 *left
-= sizeof(struct objc_method_list_t
) -
2004 sizeof(struct objc_method_t
);
2005 *methods
= (struct objc_method_t
*)
2006 (objc_sections
[i
].contents
+
2007 (addr
- objc_sections
[i
].addr
) +
2008 sizeof(struct objc_method_list_t
) -
2009 sizeof(struct objc_method_t
));
2014 objc_sections
[i
].contents
+
2015 (addr
- objc_sections
[i
].addr
),
2022 swap_objc_method_list_t(method_list
, host_byte_sex
);
2033 struct objc_protocol_list_t
*protocol_list
,
2037 struct section_info
*objc_sections
,
2038 uint32_t nobjc_sections
,
2039 enum byte_sex host_byte_sex
,
2044 memset(protocol_list
, '\0', sizeof(struct objc_protocol_list_t
));
2047 for(i
= 0; i
< nobjc_sections
; i
++){
2048 if(addr
>= objc_sections
[i
].addr
&&
2049 addr
< objc_sections
[i
].addr
+ objc_sections
[i
].size
){
2051 *left
= objc_sections
[i
].size
-
2052 (addr
- objc_sections
[i
].addr
);
2053 if(*left
>= sizeof(struct objc_protocol_list_t
) -
2055 memcpy(protocol_list
,
2056 objc_sections
[i
].contents
+
2057 (addr
- objc_sections
[i
].addr
),
2058 sizeof(struct objc_protocol_list_t
) -
2060 *left
-= sizeof(struct objc_protocol_list_t
) -
2062 *list
= (uint32_t *)
2063 (objc_sections
[i
].contents
+
2064 (addr
- objc_sections
[i
].addr
) +
2065 sizeof(struct objc_protocol_list_t
) -
2070 memcpy(protocol_list
,
2071 objc_sections
[i
].contents
+
2072 (addr
- objc_sections
[i
].addr
),
2079 swap_objc_protocol_list_t(protocol_list
, host_byte_sex
);
2090 struct objc_protocol_t
*protocol
,
2092 struct section_info
*objc_sections
,
2093 uint32_t nobjc_sections
,
2094 enum byte_sex host_byte_sex
,
2099 memset(protocol
, '\0', sizeof(struct objc_protocol_t
));
2102 for(i
= 0; i
< nobjc_sections
; i
++){
2103 if(addr
>= objc_sections
[i
].addr
&&
2104 addr
< objc_sections
[i
].addr
+ objc_sections
[i
].size
){
2106 left
= objc_sections
[i
].size
-
2107 (addr
- objc_sections
[i
].addr
);
2108 if(left
>= sizeof(struct objc_protocol_t
)){
2110 objc_sections
[i
].contents
+
2111 (addr
- objc_sections
[i
].addr
),
2112 sizeof(struct objc_protocol_t
));
2117 objc_sections
[i
].contents
+
2118 (addr
- objc_sections
[i
].addr
),
2123 swap_objc_protocol_t(protocol
, host_byte_sex
);
2132 get_method_description_list(
2134 struct objc_method_description_list_t
*mdl
,
2135 struct objc_method_description_t
**list
,
2138 struct section_info
*objc_sections
,
2139 uint32_t nobjc_sections
,
2140 enum byte_sex host_byte_sex
,
2145 memset(mdl
, '\0', sizeof(struct objc_method_description_list_t
));
2148 for(i
= 0; i
< nobjc_sections
; i
++){
2149 if(addr
>= objc_sections
[i
].addr
&&
2150 addr
< objc_sections
[i
].addr
+ objc_sections
[i
].size
){
2152 *left
= objc_sections
[i
].size
-
2153 (addr
- objc_sections
[i
].addr
);
2154 if(*left
>= sizeof(struct objc_method_description_list_t
) -
2155 sizeof(struct objc_method_description_t
)){
2157 objc_sections
[i
].contents
+
2158 (addr
- objc_sections
[i
].addr
),
2159 sizeof(struct objc_method_description_list_t
) -
2160 sizeof(struct objc_method_description_t
));
2161 *left
-= sizeof(struct objc_method_description_list_t
) -
2162 sizeof(struct objc_method_description_t
);
2163 *list
= (struct objc_method_description_t
*)
2164 (objc_sections
[i
].contents
+
2165 (addr
- objc_sections
[i
].addr
) +
2166 sizeof(struct objc_method_description_list_t
) -
2167 sizeof(struct objc_method_description_t
));
2172 objc_sections
[i
].contents
+
2173 (addr
- objc_sections
[i
].addr
),
2180 swap_objc_method_description_list_t(mdl
, host_byte_sex
);
2191 struct _hashEntry_t
*_hashEntry
,
2193 struct section_info
*objc_sections
,
2194 uint32_t nobjc_sections
,
2195 enum byte_sex host_byte_sex
,
2200 memset(_hashEntry
, '\0', sizeof(struct _hashEntry_t
));
2203 for(i
= 0; i
< nobjc_sections
; i
++){
2204 if(addr
>= objc_sections
[i
].addr
&&
2205 addr
< objc_sections
[i
].addr
+ objc_sections
[i
].size
){
2207 left
= objc_sections
[i
].size
-
2208 (addr
- objc_sections
[i
].addr
);
2209 if(left
>= sizeof(struct _hashEntry_t
)){
2211 objc_sections
[i
].contents
+
2212 (addr
- objc_sections
[i
].addr
),
2213 sizeof(struct _hashEntry_t
));
2218 objc_sections
[i
].contents
+
2219 (addr
- objc_sections
[i
].addr
),
2224 swap_hashEntry_t(_hashEntry
, host_byte_sex
);