diff --git a/test/tools/llvm-objdump/X86/Inputs/Objc2.32bit.exe.macho-i386 b/test/tools/llvm-objdump/X86/Inputs/Objc2.32bit.exe.macho-i386 new file mode 100755 index 00000000000..b44c7dc5873 Binary files /dev/null and b/test/tools/llvm-objdump/X86/Inputs/Objc2.32bit.exe.macho-i386 differ diff --git a/test/tools/llvm-objdump/X86/Inputs/Objc2.32bit.obj.macho-i386 b/test/tools/llvm-objdump/X86/Inputs/Objc2.32bit.obj.macho-i386 new file mode 100644 index 00000000000..51449643fcd Binary files /dev/null and b/test/tools/llvm-objdump/X86/Inputs/Objc2.32bit.obj.macho-i386 differ diff --git a/test/tools/llvm-objdump/X86/macho-objc-meta-data.test b/test/tools/llvm-objdump/X86/macho-objc-meta-data.test index 4f2362cf6f9..af0a01f3973 100644 --- a/test/tools/llvm-objdump/X86/macho-objc-meta-data.test +++ b/test/tools/llvm-objdump/X86/macho-objc-meta-data.test @@ -1,5 +1,7 @@ # RUN: llvm-objdump -m -objc-meta-data %p/Inputs/Objc2.64bit.exe.macho-x86_64 | FileCheck %s -check-prefix=OBJC2_64BIT_EXE # RUN: llvm-objdump -m -objc-meta-data %p/Inputs/Objc2.64bit.obj.macho-x86_64 | FileCheck %s -check-prefix=OBJC2_64BIT_OBJ +# RUN: llvm-objdump -m -objc-meta-data %p/Inputs/Objc2.32bit.exe.macho-i386 | FileCheck %s -check-prefix=OBJC2_32BIT_EXE +# RUN: llvm-objdump -m -objc-meta-data %p/Inputs/Objc2.32bit.obj.macho-i386 | FileCheck %s -check-prefix=OBJC2_32BIT_OBJ OBJC2_64BIT_EXE: Contents of (__DATA,__objc_classlist) section OBJC2_64BIT_EXE: 0000000100002028 0x1000029f0 @@ -204,3 +206,411 @@ OBJC2_64BIT_OBJ: 0000000000001aa8 0x1a50 l_OBJC_PROTOCOL_$_NSApplicationDelegate OBJC2_64BIT_OBJ: Contents of (__DATA,__objc_imageinfo) section OBJC2_64BIT_OBJ: version 0 OBJC2_64BIT_OBJ: flags 0x0 + +OBJC2_32BIT_EXE: Objective-C segment +OBJC2_32BIT_EXE: Contents of (__DATA,__objc_classlist) section +OBJC2_32BIT_EXE: 00006068 0x6a84 +OBJC2_32BIT_EXE: isa 0x6a70 +OBJC2_32BIT_EXE: superclass 0x0 +OBJC2_32BIT_EXE: cache 0x0 +OBJC2_32BIT_EXE: vtable 0x0 +OBJC2_32BIT_EXE: data 0x66e0 (struct class_ro_t *) +OBJC2_32BIT_EXE: flags 0x184 RO_HAS_CXX_STRUCTORS +OBJC2_32BIT_EXE: instanceStart 4 +OBJC2_32BIT_EXE: instanceSize 8 +OBJC2_32BIT_EXE: ivarLayout 0x52c2 +OBJC2_32BIT_EXE: layout map: 0x01 +OBJC2_32BIT_EXE: name 0x5279 AppDelegate +OBJC2_32BIT_EXE: baseMethods 0x6614 (struct method_list_t *) +OBJC2_32BIT_EXE: entsize 12 +OBJC2_32BIT_EXE: count 10 +OBJC2_32BIT_EXE: name 0x454c application:didFinishLaunchingWithOptions: +OBJC2_32BIT_EXE: types 0x562b c16@0:4@8@12 +OBJC2_32BIT_EXE: imp 0x23c0 +OBJC2_32BIT_EXE: name 0x4593 applicationWillResignActive: +OBJC2_32BIT_EXE: types 0x5608 v12@0:4@8 +OBJC2_32BIT_EXE: imp 0x25f0 +OBJC2_32BIT_EXE: name 0x4a6a applicationDidEnterBackground: +OBJC2_32BIT_EXE: types 0x5608 v12@0:4@8 +OBJC2_32BIT_EXE: imp 0x2640 +OBJC2_32BIT_EXE: name 0x4a89 applicationWillEnterForeground: +OBJC2_32BIT_EXE: types 0x5608 v12@0:4@8 +OBJC2_32BIT_EXE: imp 0x2690 +OBJC2_32BIT_EXE: name 0x4577 applicationDidBecomeActive: +OBJC2_32BIT_EXE: types 0x5608 v12@0:4@8 +OBJC2_32BIT_EXE: imp 0x26e0 +OBJC2_32BIT_EXE: name 0x463e applicationWillTerminate: +OBJC2_32BIT_EXE: types 0x5608 v12@0:4@8 +OBJC2_32BIT_EXE: imp 0x2730 +OBJC2_32BIT_EXE: name 0x42da splitViewController:collapseSecondaryViewController:ontoPrimaryViewController: +OBJC2_32BIT_EXE: types 0x5351 c20@0:4@8@12@16 +OBJC2_32BIT_EXE: imp 0x2780 +OBJC2_32BIT_EXE: name 0x4e21 .cxx_destruct +OBJC2_32BIT_EXE: types 0x5d44 v8@0:4 +OBJC2_32BIT_EXE: imp 0x2a70 +OBJC2_32BIT_EXE: name 0x40fc window +OBJC2_32BIT_EXE: types 0x5c80 @8@0:4 +OBJC2_32BIT_EXE: imp 0x2a00 +OBJC2_32BIT_EXE: name 0x4d1a setWindow: +OBJC2_32BIT_EXE: types 0x5608 v12@0:4@8 +OBJC2_32BIT_EXE: imp 0x2a30 +OBJC2_32BIT_EXE: baseProtocols 0x65dc +OBJC2_32BIT_EXE: count 2 +OBJC2_32BIT_EXE: list[0] 0x6ae8 (struct protocol_t *) +OBJC2_32BIT_EXE: isa 0x0 +OBJC2_32BIT_EXE: name 0x5285 UISplitViewControllerDelegate +OBJC2_32BIT_EXE: protocols 0x0 +OBJC2_32BIT_EXE: instanceMethods 0x0 (struct method_list_t *) +OBJC2_32BIT_EXE: classMethods 0x0 (struct method_list_t *) +OBJC2_32BIT_EXE: optionalInstanceMethods 0x6088 +OBJC2_32BIT_EXE: optionalClassMethods 0x0 +OBJC2_32BIT_EXE: instanceProperties 0x0 +OBJC2_32BIT_EXE: list[1] 0x6b40 (struct protocol_t *) +OBJC2_32BIT_EXE: isa 0x0 +OBJC2_32BIT_EXE: name 0x52a3 UIApplicationDelegate +OBJC2_32BIT_EXE: protocols 0x62e8 +OBJC2_32BIT_EXE: instanceMethods 0x0 (struct method_list_t *) +OBJC2_32BIT_EXE: classMethods 0x0 (struct method_list_t *) +OBJC2_32BIT_EXE: optionalInstanceMethods 0x62f4 +OBJC2_32BIT_EXE: optionalClassMethods 0x0 +OBJC2_32BIT_EXE: instanceProperties 0x6518 +OBJC2_32BIT_EXE: ivars 0x6694 +OBJC2_32BIT_EXE: entsize 20 +OBJC2_32BIT_EXE: count 1 +OBJC2_32BIT_EXE: offset 0x6a5c 4 +OBJC2_32BIT_EXE: name 0x4e2f _window +OBJC2_32BIT_EXE: type 0x5d4b @"UIWindow" +OBJC2_32BIT_EXE: alignment 2 +OBJC2_32BIT_EXE: size 4 +OBJC2_32BIT_EXE: weakIvarLayout 0x0 +OBJC2_32BIT_EXE: baseProperties 0x66b0 +OBJC2_32BIT_EXE: entsize 8 +OBJC2_32BIT_EXE: count 5 +OBJC2_32BIT_EXE: name 0x5df3 window +OBJC2_32BIT_EXE: attributes 0x5e0b T@"UIWindow",&,N,V_window +OBJC2_32BIT_EXE: name 0x5dab hash +OBJC2_32BIT_EXE: attributes 0x5db0 TI,R +OBJC2_32BIT_EXE: name 0x5db5 superclass +OBJC2_32BIT_EXE: attributes 0x5dc0 T#,R +OBJC2_32BIT_EXE: name 0x5dc5 description +OBJC2_32BIT_EXE: attributes 0x5dd1 T@"NSString",R,C +OBJC2_32BIT_EXE: name 0x5de2 debugDescription +OBJC2_32BIT_EXE: attributes 0x5dd1 T@"NSString",R,C +OBJC2_32BIT_EXE: Meta Class +OBJC2_32BIT_EXE: isa 0x0 +OBJC2_32BIT_EXE: superclass 0x0 +OBJC2_32BIT_EXE: cache 0x0 +OBJC2_32BIT_EXE: vtable 0x0 +OBJC2_32BIT_EXE: data 0x65ec (struct class_ro_t *) +OBJC2_32BIT_EXE: flags 0x185 RO_META RO_HAS_CXX_STRUCTORS +OBJC2_32BIT_EXE: instanceStart 20 +OBJC2_32BIT_EXE: instanceSize 20 +OBJC2_32BIT_EXE: ivarLayout 0x0 +OBJC2_32BIT_EXE: name 0x5279 AppDelegate +OBJC2_32BIT_EXE: baseMethods 0x0 (struct method_list_t *) +OBJC2_32BIT_EXE: baseProtocols 0x65dc +OBJC2_32BIT_EXE: count 2 +OBJC2_32BIT_EXE: list[0] 0x6ae8 (struct protocol_t *) +OBJC2_32BIT_EXE: isa 0x0 +OBJC2_32BIT_EXE: name 0x5285 UISplitViewControllerDelegate +OBJC2_32BIT_EXE: protocols 0x0 +OBJC2_32BIT_EXE: instanceMethods 0x0 (struct method_list_t *) +OBJC2_32BIT_EXE: classMethods 0x0 (struct method_list_t *) +OBJC2_32BIT_EXE: optionalInstanceMethods 0x6088 +OBJC2_32BIT_EXE: optionalClassMethods 0x0 +OBJC2_32BIT_EXE: instanceProperties 0x0 +OBJC2_32BIT_EXE: list[1] 0x6b40 (struct protocol_t *) +OBJC2_32BIT_EXE: isa 0x0 +OBJC2_32BIT_EXE: name 0x52a3 UIApplicationDelegate +OBJC2_32BIT_EXE: protocols 0x62e8 +OBJC2_32BIT_EXE: instanceMethods 0x0 (struct method_list_t *) +OBJC2_32BIT_EXE: classMethods 0x0 (struct method_list_t *) +OBJC2_32BIT_EXE: optionalInstanceMethods 0x62f4 +OBJC2_32BIT_EXE: optionalClassMethods 0x0 +OBJC2_32BIT_EXE: instanceProperties 0x6518 +OBJC2_32BIT_EXE: ivars 0x0 +OBJC2_32BIT_EXE: weakIvarLayout 0x0 +OBJC2_32BIT_EXE: baseProperties 0x0 +OBJC2_32BIT_EXE: 0000606c 0x6a98 +OBJC2_32BIT_EXE: isa 0x6aac +OBJC2_32BIT_EXE: superclass 0x0 +OBJC2_32BIT_EXE: cache 0x0 +OBJC2_32BIT_EXE: vtable 0x0 +OBJC2_32BIT_EXE: data 0x6838 (struct class_ro_t *) +OBJC2_32BIT_EXE: flags 0x184 RO_HAS_CXX_STRUCTORS +OBJC2_32BIT_EXE: instanceStart 4 +OBJC2_32BIT_EXE: instanceSize 12 +OBJC2_32BIT_EXE: ivarLayout 0x52d9 +OBJC2_32BIT_EXE: layout map: 0x02 +OBJC2_32BIT_EXE: name 0x52c4 MasterViewController +OBJC2_32BIT_EXE: baseMethods 0x6730 (struct method_list_t *) +OBJC2_32BIT_EXE: entsize 12 +OBJC2_32BIT_EXE: count 15 +OBJC2_32BIT_EXE: name 0x4e37 awakeFromNib +OBJC2_32BIT_EXE: types 0x5d44 v8@0:4 +OBJC2_32BIT_EXE: imp 0x2ab0 +OBJC2_32BIT_EXE: name 0x4ea2 viewDidLoad +OBJC2_32BIT_EXE: types 0x5d44 v8@0:4 +OBJC2_32BIT_EXE: imp 0x2c20 +OBJC2_32BIT_EXE: name 0x4f43 didReceiveMemoryWarning +OBJC2_32BIT_EXE: types 0x5d44 v8@0:4 +OBJC2_32BIT_EXE: imp 0x2e80 +OBJC2_32BIT_EXE: name 0x4ec3 insertNewObject: +OBJC2_32BIT_EXE: types 0x5608 v12@0:4@8 +OBJC2_32BIT_EXE: imp 0x2ed0 +OBJC2_32BIT_EXE: name 0x5119 prepareForSegue:sender: +OBJC2_32BIT_EXE: types 0x57b1 v16@0:4@8@12 +OBJC2_32BIT_EXE: imp 0x3160 +OBJC2_32BIT_EXE: name 0x5131 numberOfSectionsInTableView: +OBJC2_32BIT_EXE: types 0x5326 i12@0:4@8 +OBJC2_32BIT_EXE: imp 0x34c0 +OBJC2_32BIT_EXE: name 0x514e tableView:numberOfRowsInSection: +OBJC2_32BIT_EXE: types 0x5d57 i16@0:4@8i12 +OBJC2_32BIT_EXE: imp 0x3520 +OBJC2_32BIT_EXE: name 0x516f tableView:cellForRowAtIndexPath: +OBJC2_32BIT_EXE: types 0x5422 @16@0:4@8@12 +OBJC2_32BIT_EXE: imp 0x35e0 +OBJC2_32BIT_EXE: name 0x5190 tableView:canEditRowAtIndexPath: +OBJC2_32BIT_EXE: types 0x562b c16@0:4@8@12 +OBJC2_32BIT_EXE: imp 0x37e0 +OBJC2_32BIT_EXE: name 0x51b1 tableView:commitEditingStyle:forRowAtIndexPath: +OBJC2_32BIT_EXE: types 0x5d64 v20@0:4@8i12@16 +OBJC2_32BIT_EXE: imp 0x3880 +OBJC2_32BIT_EXE: name 0x4e21 .cxx_destruct +OBJC2_32BIT_EXE: types 0x5d44 v8@0:4 +OBJC2_32BIT_EXE: imp 0x3b40 +OBJC2_32BIT_EXE: name 0x51e1 detailViewController +OBJC2_32BIT_EXE: types 0x5c80 @8@0:4 +OBJC2_32BIT_EXE: imp 0x3a30 +OBJC2_32BIT_EXE: name 0x4f2a setDetailViewController: +OBJC2_32BIT_EXE: types 0x5608 v12@0:4@8 +OBJC2_32BIT_EXE: imp 0x3a60 +OBJC2_32BIT_EXE: name 0x4f5b objects +OBJC2_32BIT_EXE: types 0x5c80 @8@0:4 +OBJC2_32BIT_EXE: imp 0x3aa0 +OBJC2_32BIT_EXE: name 0x4f68 setObjects: +OBJC2_32BIT_EXE: types 0x5608 v12@0:4@8 +OBJC2_32BIT_EXE: imp 0x3af0 +OBJC2_32BIT_EXE: baseProtocols 0x0 +OBJC2_32BIT_EXE: ivars 0x67ec +OBJC2_32BIT_EXE: entsize 20 +OBJC2_32BIT_EXE: count 2 +OBJC2_32BIT_EXE: offset 0x6a60 4 +OBJC2_32BIT_EXE: name 0x51f6 _detailViewController +OBJC2_32BIT_EXE: type 0x5d74 @"DetailViewController" +OBJC2_32BIT_EXE: alignment 2 +OBJC2_32BIT_EXE: size 4 +OBJC2_32BIT_EXE: offset 0x6a64 8 +OBJC2_32BIT_EXE: name 0x520c _objects +OBJC2_32BIT_EXE: type 0x5d8c @"NSMutableArray" +OBJC2_32BIT_EXE: alignment 2 +OBJC2_32BIT_EXE: size 4 +OBJC2_32BIT_EXE: weakIvarLayout 0x0 +OBJC2_32BIT_EXE: baseProperties 0x6820 +OBJC2_32BIT_EXE: entsize 8 +OBJC2_32BIT_EXE: count 2 +OBJC2_32BIT_EXE: name 0x5e35 detailViewController +OBJC2_32BIT_EXE: attributes 0x5e4a T@"DetailViewController",&,N,V_detailViewController +OBJC2_32BIT_EXE: name 0x5e7e objects +OBJC2_32BIT_EXE: attributes 0x5e86 T@"NSMutableArray",&,V_objects +OBJC2_32BIT_EXE: Meta Class +OBJC2_32BIT_EXE: isa 0x0 +OBJC2_32BIT_EXE: superclass 0x0 +OBJC2_32BIT_EXE: cache 0x0 +OBJC2_32BIT_EXE: vtable 0x0 +OBJC2_32BIT_EXE: data 0x6708 (struct class_ro_t *) +OBJC2_32BIT_EXE: flags 0x185 RO_META RO_HAS_CXX_STRUCTORS +OBJC2_32BIT_EXE: instanceStart 20 +OBJC2_32BIT_EXE: instanceSize 20 +OBJC2_32BIT_EXE: ivarLayout 0x0 +OBJC2_32BIT_EXE: name 0x52c4 MasterViewController +OBJC2_32BIT_EXE: baseMethods 0x0 (struct method_list_t *) +OBJC2_32BIT_EXE: baseProtocols 0x0 +OBJC2_32BIT_EXE: ivars 0x0 +OBJC2_32BIT_EXE: weakIvarLayout 0x0 +OBJC2_32BIT_EXE: baseProperties 0x0 +OBJC2_32BIT_EXE: 00006070 0x6ac0 +OBJC2_32BIT_EXE: isa 0x6ad4 +OBJC2_32BIT_EXE: superclass 0x0 +OBJC2_32BIT_EXE: cache 0x0 +OBJC2_32BIT_EXE: vtable 0x0 +OBJC2_32BIT_EXE: data 0x6938 (struct class_ro_t *) +OBJC2_32BIT_EXE: flags 0x184 RO_HAS_CXX_STRUCTORS +OBJC2_32BIT_EXE: instanceStart 4 +OBJC2_32BIT_EXE: instanceSize 12 +OBJC2_32BIT_EXE: ivarLayout 0x52f0 +OBJC2_32BIT_EXE: layout map: 0x01 0x10 +OBJC2_32BIT_EXE: name 0x52db DetailViewController +OBJC2_32BIT_EXE: baseMethods 0x6888 (struct method_list_t *) +OBJC2_32BIT_EXE: entsize 12 +OBJC2_32BIT_EXE: count 8 +OBJC2_32BIT_EXE: name 0x5061 setDetailItem: +OBJC2_32BIT_EXE: types 0x5608 v12@0:4@8 +OBJC2_32BIT_EXE: imp 0x3c70 +OBJC2_32BIT_EXE: name 0x5215 configureView +OBJC2_32BIT_EXE: types 0x5d44 v8@0:4 +OBJC2_32BIT_EXE: imp 0x3d20 +OBJC2_32BIT_EXE: name 0x4ea2 viewDidLoad +OBJC2_32BIT_EXE: types 0x5d44 v8@0:4 +OBJC2_32BIT_EXE: imp 0x3e20 +OBJC2_32BIT_EXE: name 0x4f43 didReceiveMemoryWarning +OBJC2_32BIT_EXE: types 0x5d44 v8@0:4 +OBJC2_32BIT_EXE: imp 0x3e80 +OBJC2_32BIT_EXE: name 0x4e21 .cxx_destruct +OBJC2_32BIT_EXE: types 0x5d44 v8@0:4 +OBJC2_32BIT_EXE: imp 0x3f90 +OBJC2_32BIT_EXE: name 0x41a0 detailItem +OBJC2_32BIT_EXE: types 0x5c80 @8@0:4 +OBJC2_32BIT_EXE: imp 0x3ed0 +OBJC2_32BIT_EXE: name 0x5223 detailDescriptionLabel +OBJC2_32BIT_EXE: types 0x5c80 @8@0:4 +OBJC2_32BIT_EXE: imp 0x3f00 +OBJC2_32BIT_EXE: name 0x523a setDetailDescriptionLabel: +OBJC2_32BIT_EXE: types 0x5608 v12@0:4@8 +OBJC2_32BIT_EXE: imp 0x3f40 +OBJC2_32BIT_EXE: baseProtocols 0x0 +OBJC2_32BIT_EXE: ivars 0x68f0 +OBJC2_32BIT_EXE: entsize 20 +OBJC2_32BIT_EXE: count 2 +OBJC2_32BIT_EXE: offset 0x6a68 4 +OBJC2_32BIT_EXE: name 0x5255 _detailItem +OBJC2_32BIT_EXE: type 0x5d9e @ +OBJC2_32BIT_EXE: alignment 2 +OBJC2_32BIT_EXE: size 4 +OBJC2_32BIT_EXE: offset 0x6a6c 8 +OBJC2_32BIT_EXE: name 0x5261 _detailDescriptionLabel +OBJC2_32BIT_EXE: type 0x5da0 @"UILabel" +OBJC2_32BIT_EXE: alignment 2 +OBJC2_32BIT_EXE: size 4 +OBJC2_32BIT_EXE: weakIvarLayout 0x52f3 +OBJC2_32BIT_EXE: layout map: 0x11 +OBJC2_32BIT_EXE: baseProperties 0x6920 +OBJC2_32BIT_EXE: entsize 8 +OBJC2_32BIT_EXE: count 2 +OBJC2_32BIT_EXE: name 0x5ea5 detailItem +OBJC2_32BIT_EXE: attributes 0x5eb0 T@,&,N,V_detailItem +OBJC2_32BIT_EXE: name 0x5ec4 detailDescriptionLabel +OBJC2_32BIT_EXE: attributes 0x5edb T@"UILabel",W,N,V_detailDescriptionLabel +OBJC2_32BIT_EXE: Meta Class +OBJC2_32BIT_EXE: isa 0x0 +OBJC2_32BIT_EXE: superclass 0x0 +OBJC2_32BIT_EXE: cache 0x0 +OBJC2_32BIT_EXE: vtable 0x0 +OBJC2_32BIT_EXE: data 0x6860 (struct class_ro_t *) +OBJC2_32BIT_EXE: flags 0x185 RO_META RO_HAS_CXX_STRUCTORS +OBJC2_32BIT_EXE: instanceStart 20 +OBJC2_32BIT_EXE: instanceSize 20 +OBJC2_32BIT_EXE: ivarLayout 0x0 +OBJC2_32BIT_EXE: name 0x52db DetailViewController +OBJC2_32BIT_EXE: baseMethods 0x0 (struct method_list_t *) +OBJC2_32BIT_EXE: baseProtocols 0x0 +OBJC2_32BIT_EXE: ivars 0x0 +OBJC2_32BIT_EXE: weakIvarLayout 0x0 +OBJC2_32BIT_EXE: baseProperties 0x0 +OBJC2_32BIT_EXE: Contents of (__DATA,__objc_classrefs) section +OBJC2_32BIT_EXE: 00006a30 0x0 +OBJC2_32BIT_EXE: 00006a34 0x6ac0 +OBJC2_32BIT_EXE: 00006a38 0x0 +OBJC2_32BIT_EXE: 00006a3c 0x0 +OBJC2_32BIT_EXE: 00006a40 0x0 +OBJC2_32BIT_EXE: 00006a44 0x0 +OBJC2_32BIT_EXE: 00006a48 0x0 +OBJC2_32BIT_EXE: 00006a4c 0x0 +OBJC2_32BIT_EXE: 00006a50 0x6a84 +OBJC2_32BIT_EXE: Contents of (__DATA,__objc_superrefs) section +OBJC2_32BIT_EXE: 00006a54 0x6a98 +OBJC2_32BIT_EXE: 00006a58 0x6ac0 +OBJC2_32BIT_EXE: Contents of (__DATA,__objc_protolist) section +OBJC2_32BIT_EXE: 00006074 0x6ae8 +OBJC2_32BIT_EXE: 00006078 0x6b14 +OBJC2_32BIT_EXE: 0000607c 0x6b40 +OBJC2_32BIT_EXE: Contents of (__DATA,__objc_imageinfo) section +OBJC2_32BIT_EXE: version 0 +OBJC2_32BIT_EXE: flags 0x20 + +OBJC2_32BIT_OBJ: /Volumes/SandBox/llvm/test/tools/llvm-objdump/X86/Inputs/Objc2.32bit.obj.macho-i386: +OBJC2_32BIT_OBJ: Objective-C segment +OBJC2_32BIT_OBJ: Contents of (__DATA,__objc_classlist) section +OBJC2_32BIT_OBJ: 00003ae4 0x3914 _OBJC_CLASS_$_DetailViewController +OBJC2_32BIT_OBJ: isa 0x3928 _OBJC_METACLASS_$_DetailViewController +OBJC2_32BIT_OBJ: superclass 0x0 _OBJC_CLASS_$_UIViewController +OBJC2_32BIT_OBJ: cache 0x0 __objc_empty_cache +OBJC2_32BIT_OBJ: vtable 0x0 -[DetailViewController setDetailItem:] +OBJC2_32BIT_OBJ: data 0x3a38 (struct class_ro_t *) +OBJC2_32BIT_OBJ: flags 0x184 RO_HAS_CXX_STRUCTORS +OBJC2_32BIT_OBJ: instanceStart 4 +OBJC2_32BIT_OBJ: instanceSize 12 +OBJC2_32BIT_OBJ: ivarLayout 0x3955 +OBJC2_32BIT_OBJ: layout map: 0x01 0x10 +OBJC2_32BIT_OBJ: name 0x3940 DetailViewController +OBJC2_32BIT_OBJ: baseMethods 0x3988 (struct method_list_t *) +OBJC2_32BIT_OBJ: entsize 12 +OBJC2_32BIT_OBJ: count 8 +OBJC2_32BIT_OBJ: name 0x3899 setDetailItem: +OBJC2_32BIT_OBJ: types 0x3a60 v12@0:4@8 +OBJC2_32BIT_OBJ: imp 0x0 -[DetailViewController setDetailItem:] +OBJC2_32BIT_OBJ: name 0x3830 configureView +OBJC2_32BIT_OBJ: types 0x3a6a v8@0:4 +OBJC2_32BIT_OBJ: imp 0xb0 -[DetailViewController configureView] +OBJC2_32BIT_OBJ: name 0x3875 viewDidLoad +OBJC2_32BIT_OBJ: types 0x3a6a v8@0:4 +OBJC2_32BIT_OBJ: imp 0x1b0 -[DetailViewController viewDidLoad] +OBJC2_32BIT_OBJ: name 0x3881 didReceiveMemoryWarning +OBJC2_32BIT_OBJ: types 0x3a6a v8@0:4 +OBJC2_32BIT_OBJ: imp 0x210 -[DetailViewController didReceiveMemoryWarning] +OBJC2_32BIT_OBJ: name 0x38a8 .cxx_destruct +OBJC2_32BIT_OBJ: types 0x3a6a v8@0:4 +OBJC2_32BIT_OBJ: imp 0x320 -[DetailViewController .cxx_destruct] +OBJC2_32BIT_OBJ: name 0x383e detailItem +OBJC2_32BIT_OBJ: types 0x3a71 @8@0:4 +OBJC2_32BIT_OBJ: imp 0x260 -[DetailViewController detailItem] +OBJC2_32BIT_OBJ: name 0x3849 detailDescriptionLabel +OBJC2_32BIT_OBJ: types 0x3a71 @8@0:4 +OBJC2_32BIT_OBJ: imp 0x290 -[DetailViewController detailDescriptionLabel] +OBJC2_32BIT_OBJ: name 0x38b6 setDetailDescriptionLabel: +OBJC2_32BIT_OBJ: types 0x3a60 v12@0:4@8 +OBJC2_32BIT_OBJ: imp 0x2d0 -[DetailViewController setDetailDescriptionLabel:] +OBJC2_32BIT_OBJ: baseProtocols 0x0 +OBJC2_32BIT_OBJ: ivars 0x39f0 +OBJC2_32BIT_OBJ: entsize 20 +OBJC2_32BIT_OBJ: count 2 +OBJC2_32BIT_OBJ: offset 0x3828 4 +OBJC2_32BIT_OBJ: name 0x38d1 _detailItem +OBJC2_32BIT_OBJ: type 0x3a78 @ +OBJC2_32BIT_OBJ: alignment 2 +OBJC2_32BIT_OBJ: size 4 +OBJC2_32BIT_OBJ: offset 0x382c 8 +OBJC2_32BIT_OBJ: name 0x38dd _detailDescriptionLabel +OBJC2_32BIT_OBJ: type 0x3a7a @"UILabel" +OBJC2_32BIT_OBJ: alignment 2 +OBJC2_32BIT_OBJ: size 4 +OBJC2_32BIT_OBJ: weakIvarLayout 0x3958 +OBJC2_32BIT_OBJ: layout map: 0x11 +OBJC2_32BIT_OBJ: baseProperties 0x3a20 +OBJC2_32BIT_OBJ: entsize 8 +OBJC2_32BIT_OBJ: count 2 +OBJC2_32BIT_OBJ: name 0x3a85 detailItem +OBJC2_32BIT_OBJ: attributes 0x3a90 T@,&,N,V_detailItem +OBJC2_32BIT_OBJ: name 0x3aa4 detailDescriptionLabel +OBJC2_32BIT_OBJ: attributes 0x3abb T@"UILabel",W,N,V_detailDescriptionLabel +OBJC2_32BIT_OBJ: Meta Class +OBJC2_32BIT_OBJ: isa 0x0 _OBJC_METACLASS_$_NSObject +OBJC2_32BIT_OBJ: superclass 0x0 _OBJC_METACLASS_$_UIViewController +OBJC2_32BIT_OBJ: cache 0x0 __objc_empty_cache +OBJC2_32BIT_OBJ: vtable 0x0 -[DetailViewController setDetailItem:] +OBJC2_32BIT_OBJ: data 0x3960 (struct class_ro_t *) +OBJC2_32BIT_OBJ: flags 0x185 RO_META RO_HAS_CXX_STRUCTORS +OBJC2_32BIT_OBJ: instanceStart 20 +OBJC2_32BIT_OBJ: instanceSize 20 +OBJC2_32BIT_OBJ: ivarLayout 0x0 +OBJC2_32BIT_OBJ: name 0x3940 DetailViewController +OBJC2_32BIT_OBJ: baseMethods 0x0 (struct method_list_t *) +OBJC2_32BIT_OBJ: baseProtocols 0x0 +OBJC2_32BIT_OBJ: ivars 0x0 +OBJC2_32BIT_OBJ: weakIvarLayout 0x0 +OBJC2_32BIT_OBJ: baseProperties 0x0 +OBJC2_32BIT_OBJ: Contents of (__DATA,__objc_superrefs) section +OBJC2_32BIT_OBJ: 0000393c 0x3914 _OBJC_CLASS_$_DetailViewController +OBJC2_32BIT_OBJ: Contents of (__DATA,__objc_imageinfo) section +OBJC2_32BIT_OBJ: version 0 +OBJC2_32BIT_OBJ: flags 0x20 diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 7c8dcb2af4d..4eb93b5c474 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -135,7 +135,6 @@ static cl::opt NoSymbolicOperands( "no-symbolic-operands", cl::desc("do not symbolic operands when disassembling (requires -macho)")); - static cl::list ArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"), cl::ZeroOrMore); @@ -2424,14 +2423,21 @@ static const char *get_pointer_64(uint64_t Address, uint32_t &offset, return nullptr; } +static const char *get_pointer_32(uint32_t Address, uint32_t &offset, + uint32_t &left, SectionRef &S, + DisassembleInfo *info) { + return get_pointer_64(Address, offset, left, S, info); +} + // get_symbol_64() returns the name of a symbol (or nullptr) and the address of // the symbol indirectly through n_value. Based on the relocation information // for the specified section offset in the specified section reference. // If no relocation information is found and a non-zero ReferenceValue for the // symbol is passed, look up that address in the info's AddrMap. -static const char *get_symbol_64(uint32_t sect_offset, SectionRef S, - DisassembleInfo *info, uint64_t &n_value, - uint64_t ReferenceValue = 0) { +static const char * +get_symbol_64(uint32_t sect_offset, SectionRef S, DisassembleInfo *info, + uint64_t &n_value, + uint64_t ReferenceValue = UnknownAddressOrSize) { n_value = 0; if (!info->verbose) return nullptr; @@ -2486,12 +2492,19 @@ static const char *get_symbol_64(uint32_t sect_offset, SectionRef S, // We did not find an external relocation entry so look up the ReferenceValue // as an address of a symbol and if found return that symbol's name. - if (ReferenceValue != 0) + if (ReferenceValue != UnknownAddressOrSize) SymbolName = GuessSymbolName(ReferenceValue, info->AddrMap); return SymbolName; } +static const char *get_symbol_32(uint32_t sect_offset, SectionRef S, + DisassembleInfo *info, + uint32_t ReferenceValue) { + uint64_t n_value64; + return get_symbol_64(sect_offset, S, info, n_value64, ReferenceValue); +} + // These are structs in the Objective-C meta data and read to produce the // comments for disassembly. While these are part of the ABI they are no // public defintions. So the are here not in include/llvm/Support/MachO.h . @@ -2513,6 +2526,14 @@ struct class64_t { uint64_t data; // class_ro64_t * (64-bit pointer) }; +struct class32_t { + uint32_t isa; /* class32_t * (32-bit pointer) */ + uint32_t superclass; /* class32_t * (32-bit pointer) */ + uint32_t cache; /* Cache (32-bit pointer) */ + uint32_t vtable; /* IMP * (32-bit pointer) */ + uint32_t data; /* class_ro32_t * (32-bit pointer) */ +}; + struct class_ro64_t { uint32_t flags; uint32_t instanceStart; @@ -2527,7 +2548,21 @@ struct class_ro64_t { uint64_t baseProperties; // const struct objc_property_list (64-bit pointer) }; -/* Values for class_ro64_t->flags */ +struct class_ro32_t { + uint32_t flags; + uint32_t instanceStart; + uint32_t instanceSize; + uint32_t ivarLayout; /* const uint8_t * (32-bit pointer) */ + uint32_t name; /* const char * (32-bit pointer) */ + uint32_t baseMethods; /* const method_list_t * (32-bit pointer) */ + uint32_t baseProtocols; /* const protocol_list_t * (32-bit pointer) */ + uint32_t ivars; /* const ivar_list_t * (32-bit pointer) */ + uint32_t weakIvarLayout; /* const uint8_t * (32-bit pointer) */ + uint32_t baseProperties; /* const struct objc_property_list * + (32-bit pointer) */ +}; + +/* Values for class_ro{64,32}_t->flags */ #define RO_META (1 << 0) #define RO_ROOT (1 << 1) #define RO_HAS_CXX_STRUCTORS (1 << 2) @@ -2538,17 +2573,34 @@ struct method_list64_t { /* struct method64_t first; These structures follow inline */ }; +struct method_list32_t { + uint32_t entsize; + uint32_t count; + /* struct method32_t first; These structures follow inline */ +}; + struct method64_t { uint64_t name; /* SEL (64-bit pointer) */ uint64_t types; /* const char * (64-bit pointer) */ uint64_t imp; /* IMP (64-bit pointer) */ }; +struct method32_t { + uint32_t name; /* SEL (32-bit pointer) */ + uint32_t types; /* const char * (32-bit pointer) */ + uint32_t imp; /* IMP (32-bit pointer) */ +}; + struct protocol_list64_t { uint64_t count; /* uintptr_t (a 64-bit value) */ /* struct protocol64_t * list[0]; These pointers follow inline */ }; +struct protocol_list32_t { + uint32_t count; /* uintptr_t (a 32-bit value) */ + /* struct protocol32_t * list[0]; These pointers follow inline */ +}; + struct protocol64_t { uint64_t isa; /* id * (64-bit pointer) */ uint64_t name; /* const char * (64-bit pointer) */ @@ -2562,10 +2614,29 @@ struct protocol64_t { (64-bit pointer) */ }; +struct protocol32_t { + uint32_t isa; /* id * (32-bit pointer) */ + uint32_t name; /* const char * (32-bit pointer) */ + uint32_t protocols; /* struct protocol_list_t * + (32-bit pointer) */ + uint32_t instanceMethods; /* method_list_t * (32-bit pointer) */ + uint32_t classMethods; /* method_list_t * (32-bit pointer) */ + uint32_t optionalInstanceMethods; /* method_list_t * (32-bit pointer) */ + uint32_t optionalClassMethods; /* method_list_t * (32-bit pointer) */ + uint32_t instanceProperties; /* struct objc_property_list * + (32-bit pointer) */ +}; + struct ivar_list64_t { uint32_t entsize; uint32_t count; - /* struct ivar_t first; These structures follow inline */ + /* struct ivar64_t first; These structures follow inline */ +}; + +struct ivar_list32_t { + uint32_t entsize; + uint32_t count; + /* struct ivar32_t first; These structures follow inline */ }; struct ivar64_t { @@ -2576,10 +2647,24 @@ struct ivar64_t { uint32_t size; }; +struct ivar32_t { + uint32_t offset; /* uintptr_t * (32-bit pointer) */ + uint32_t name; /* const char * (32-bit pointer) */ + uint32_t type; /* const char * (32-bit pointer) */ + uint32_t alignment; + uint32_t size; +}; + struct objc_property_list64 { uint32_t entsize; uint32_t count; - /* struct objc_property first; These structures follow inline */ + /* struct objc_property64 first; These structures follow inline */ +}; + +struct objc_property_list32 { + uint32_t entsize; + uint32_t count; + /* struct objc_property32 first; These structures follow inline */ }; struct objc_property64 { @@ -2587,6 +2672,11 @@ struct objc_property64 { uint64_t attributes; /* const char * (64-bit pointer) */ }; +struct objc_property32 { + uint32_t name; /* const char * (32-bit pointer) */ + uint32_t attributes; /* const char * (32-bit pointer) */ +}; + struct category64_t { uint64_t name; /* const char * (64-bit pointer) */ uint64_t cls; /* struct class_t * (64-bit pointer) */ @@ -2597,10 +2687,24 @@ struct category64_t { (64-bit pointer) */ }; +struct category32_t { + uint32_t name; /* const char * (32-bit pointer) */ + uint32_t cls; /* struct class_t * (32-bit pointer) */ + uint32_t instanceMethods; /* struct method_list_t * (32-bit pointer) */ + uint32_t classMethods; /* struct method_list_t * (32-bit pointer) */ + uint32_t protocols; /* struct protocol_list_t * (32-bit pointer) */ + uint32_t instanceProperties; /* struct objc_property_list * + (32-bit pointer) */ +}; + struct objc_image_info64 { uint32_t version; uint32_t flags; }; +struct objc_image_info32 { + uint32_t version; + uint32_t flags; +}; /* masks for objc_image_info.flags */ #define OBJC_IMAGE_IS_REPLACEMENT (1 << 0) #define OBJC_IMAGE_SUPPORTS_GC (1 << 1) @@ -2610,6 +2714,11 @@ struct message_ref64 { uint64_t sel; /* SEL (64-bit pointer) */ }; +struct message_ref32 { + uint32_t imp; /* IMP (32-bit pointer) */ + uint32_t sel; /* SEL (32-bit pointer) */ +}; + inline void swapStruct(struct cfstring64_t &cfs) { sys::swapByteOrder(cfs.isa); sys::swapByteOrder(cfs.flags); @@ -2625,6 +2734,14 @@ inline void swapStruct(struct class64_t &c) { sys::swapByteOrder(c.data); } +inline void swapStruct(struct class32_t &c) { + sys::swapByteOrder(c.isa); + sys::swapByteOrder(c.superclass); + sys::swapByteOrder(c.cache); + sys::swapByteOrder(c.vtable); + sys::swapByteOrder(c.data); +} + inline void swapStruct(struct class_ro64_t &cro) { sys::swapByteOrder(cro.flags); sys::swapByteOrder(cro.instanceStart); @@ -2639,21 +2756,49 @@ inline void swapStruct(struct class_ro64_t &cro) { sys::swapByteOrder(cro.baseProperties); } +inline void swapStruct(struct class_ro32_t &cro) { + sys::swapByteOrder(cro.flags); + sys::swapByteOrder(cro.instanceStart); + sys::swapByteOrder(cro.instanceSize); + sys::swapByteOrder(cro.ivarLayout); + sys::swapByteOrder(cro.name); + sys::swapByteOrder(cro.baseMethods); + sys::swapByteOrder(cro.baseProtocols); + sys::swapByteOrder(cro.ivars); + sys::swapByteOrder(cro.weakIvarLayout); + sys::swapByteOrder(cro.baseProperties); +} + inline void swapStruct(struct method_list64_t &ml) { sys::swapByteOrder(ml.entsize); sys::swapByteOrder(ml.count); } +inline void swapStruct(struct method_list32_t &ml) { + sys::swapByteOrder(ml.entsize); + sys::swapByteOrder(ml.count); +} + inline void swapStruct(struct method64_t &m) { sys::swapByteOrder(m.name); sys::swapByteOrder(m.types); sys::swapByteOrder(m.imp); } +inline void swapStruct(struct method32_t &m) { + sys::swapByteOrder(m.name); + sys::swapByteOrder(m.types); + sys::swapByteOrder(m.imp); +} + inline void swapStruct(struct protocol_list64_t &pl) { sys::swapByteOrder(pl.count); } +inline void swapStruct(struct protocol_list32_t &pl) { + sys::swapByteOrder(pl.count); +} + inline void swapStruct(struct protocol64_t &p) { sys::swapByteOrder(p.isa); sys::swapByteOrder(p.name); @@ -2665,11 +2810,27 @@ inline void swapStruct(struct protocol64_t &p) { sys::swapByteOrder(p.instanceProperties); } +inline void swapStruct(struct protocol32_t &p) { + sys::swapByteOrder(p.isa); + sys::swapByteOrder(p.name); + sys::swapByteOrder(p.protocols); + sys::swapByteOrder(p.instanceMethods); + sys::swapByteOrder(p.classMethods); + sys::swapByteOrder(p.optionalInstanceMethods); + sys::swapByteOrder(p.optionalClassMethods); + sys::swapByteOrder(p.instanceProperties); +} + inline void swapStruct(struct ivar_list64_t &il) { sys::swapByteOrder(il.entsize); sys::swapByteOrder(il.count); } +inline void swapStruct(struct ivar_list32_t &il) { + sys::swapByteOrder(il.entsize); + sys::swapByteOrder(il.count); +} + inline void swapStruct(struct ivar64_t &i) { sys::swapByteOrder(i.offset); sys::swapByteOrder(i.name); @@ -2678,16 +2839,34 @@ inline void swapStruct(struct ivar64_t &i) { sys::swapByteOrder(i.size); } +inline void swapStruct(struct ivar32_t &i) { + sys::swapByteOrder(i.offset); + sys::swapByteOrder(i.name); + sys::swapByteOrder(i.type); + sys::swapByteOrder(i.alignment); + sys::swapByteOrder(i.size); +} + inline void swapStruct(struct objc_property_list64 &pl) { sys::swapByteOrder(pl.entsize); sys::swapByteOrder(pl.count); } +inline void swapStruct(struct objc_property_list32 &pl) { + sys::swapByteOrder(pl.entsize); + sys::swapByteOrder(pl.count); +} + inline void swapStruct(struct objc_property64 &op) { sys::swapByteOrder(op.name); sys::swapByteOrder(op.attributes); } +inline void swapStruct(struct objc_property32 &op) { + sys::swapByteOrder(op.name); + sys::swapByteOrder(op.attributes); +} + inline void swapStruct(struct category64_t &c) { sys::swapByteOrder(c.name); sys::swapByteOrder(c.cls); @@ -2697,16 +2876,35 @@ inline void swapStruct(struct category64_t &c) { sys::swapByteOrder(c.instanceProperties); } +inline void swapStruct(struct category32_t &c) { + sys::swapByteOrder(c.name); + sys::swapByteOrder(c.cls); + sys::swapByteOrder(c.instanceMethods); + sys::swapByteOrder(c.classMethods); + sys::swapByteOrder(c.protocols); + sys::swapByteOrder(c.instanceProperties); +} + inline void swapStruct(struct objc_image_info64 &o) { sys::swapByteOrder(o.version); sys::swapByteOrder(o.flags); } +inline void swapStruct(struct objc_image_info32 &o) { + sys::swapByteOrder(o.version); + sys::swapByteOrder(o.flags); +} + inline void swapStruct(struct message_ref64 &mr) { sys::swapByteOrder(mr.imp); sys::swapByteOrder(mr.sel); } +inline void swapStruct(struct message_ref32 &mr) { + sys::swapByteOrder(mr.imp); + sys::swapByteOrder(mr.sel); +} + static const char *get_dyld_bind_info_symbolname(uint64_t ReferenceValue, struct DisassembleInfo *info); @@ -2879,6 +3077,57 @@ walk_pointer_list_64(const char *listname, const SectionRef S, } } +static void +walk_pointer_list_32(const char *listname, const SectionRef S, + MachOObjectFile *O, struct DisassembleInfo *info, + void (*func)(uint32_t, struct DisassembleInfo *info)) { + if (S == SectionRef()) + return; + + StringRef SectName; + S.getName(SectName); + DataRefImpl Ref = S.getRawDataRefImpl(); + StringRef SegName = O->getSectionFinalSegmentName(Ref); + outs() << "Contents of (" << SegName << "," << SectName << ") section\n"; + + StringRef BytesStr; + S.getContents(BytesStr); + const char *Contents = reinterpret_cast(BytesStr.data()); + + for (uint32_t i = 0; i < S.getSize(); i += sizeof(uint32_t)) { + uint32_t left = S.getSize() - i; + uint32_t size = left < sizeof(uint32_t) ? left : sizeof(uint32_t); + uint32_t p = 0; + memcpy(&p, Contents + i, size); + if (i + sizeof(uint32_t) > S.getSize()) + outs() << listname << " list pointer extends past end of (" << SegName + << "," << SectName << ") section\n"; + outs() << format("%08" PRIx32, S.getAddress() + i) << " "; + + if (O->isLittleEndian() != sys::IsLittleEndianHost) + sys::swapByteOrder(p); + outs() << format("0x%" PRIx32, p); + + const char *name = get_symbol_32(i, S, info, p); + if (name != nullptr) + outs() << " " << name; + outs() << "\n"; + + if (func) + func(p, info); + } +} + +static void print_layout_map(const char *layout_map, uint32_t left) { + outs() << " layout map: "; + do { + outs() << format("0x%02" PRIx32, (*layout_map) & 0xff) << " "; + left--; + layout_map++; + } while (*layout_map != '\0' && left != 0); + outs() << "\n"; +} + static void print_layout_map64(uint64_t p, struct DisassembleInfo *info) { uint32_t offset, left; SectionRef S; @@ -2887,15 +3136,18 @@ static void print_layout_map64(uint64_t p, struct DisassembleInfo *info) { if (p == 0) return; layout_map = get_pointer_64(p, offset, left, S, info); - if (layout_map != nullptr) { - outs() << " layout map: "; - do { - outs() << format("0x%02" PRIx32, (*layout_map) & 0xff) << " "; - left--; - layout_map++; - } while (*layout_map != '\0' && left != 0); - outs() << "\n"; - } + print_layout_map(layout_map, left); +} + +static void print_layout_map32(uint32_t p, struct DisassembleInfo *info) { + uint32_t offset, left; + SectionRef S; + const char *layout_map; + + if (p == 0) + return; + layout_map = get_pointer_32(p, offset, left, S, info); + print_layout_map(layout_map, left); } static void print_method_list64_t(uint64_t p, struct DisassembleInfo *info, @@ -2991,6 +3243,68 @@ static void print_method_list64_t(uint64_t p, struct DisassembleInfo *info, } } +static void print_method_list32_t(uint64_t p, struct DisassembleInfo *info, + const char *indent) { + struct method_list32_t ml; + struct method32_t m; + const char *r; + uint32_t offset, xoffset, left, i; + SectionRef S, xS; + const char *name; + + r = get_pointer_32(p, offset, left, S, info); + if (r == nullptr) + return; + memset(&ml, '\0', sizeof(struct method_list32_t)); + if (left < sizeof(struct method_list32_t)) { + memcpy(&ml, r, left); + outs() << " (method_list_t entends past the end of the section)\n"; + } else + memcpy(&ml, r, sizeof(struct method_list32_t)); + if (info->O->isLittleEndian() != sys::IsLittleEndianHost) + swapStruct(ml); + outs() << indent << "\t\t entsize " << ml.entsize << "\n"; + outs() << indent << "\t\t count " << ml.count << "\n"; + + p += sizeof(struct method_list32_t); + offset += sizeof(struct method_list32_t); + for (i = 0; i < ml.count; i++) { + r = get_pointer_32(p, offset, left, S, info); + if (r == nullptr) + return; + memset(&m, '\0', sizeof(struct method32_t)); + if (left < sizeof(struct method32_t)) { + memcpy(&ml, r, left); + outs() << indent << " (method_t entends past the end of the section)\n"; + } else + memcpy(&m, r, sizeof(struct method32_t)); + if (info->O->isLittleEndian() != sys::IsLittleEndianHost) + swapStruct(m); + + outs() << indent << "\t\t name " << format("0x%" PRIx32, m.name); + name = get_pointer_32(m.name, xoffset, left, xS, info); + if (name != nullptr) + outs() << format(" %.*s", left, name); + outs() << "\n"; + + outs() << indent << "\t\t types " << format("0x%" PRIx32, m.types); + name = get_pointer_32(m.types, xoffset, left, xS, info); + if (name != nullptr) + outs() << format(" %.*s", left, name); + outs() << "\n"; + + outs() << indent << "\t\t imp " << format("0x%" PRIx32, m.imp); + name = get_symbol_32(offset + offsetof(struct method32_t, imp), S, info, + m.imp); + if (name != nullptr) + outs() << " " << name; + outs() << "\n"; + + p += sizeof(struct method32_t); + offset += sizeof(struct method32_t); + } +} + static void print_protocol_list64_t(uint64_t p, struct DisassembleInfo *info) { struct protocol_list64_t pl; uint64_t q, n_value; @@ -3120,6 +3434,82 @@ static void print_protocol_list64_t(uint64_t p, struct DisassembleInfo *info) { } } +static void print_protocol_list32_t(uint32_t p, struct DisassembleInfo *info) { + struct protocol_list32_t pl; + uint32_t q; + struct protocol32_t pc; + const char *r; + uint32_t offset, xoffset, left, i; + SectionRef S, xS; + const char *name; + + r = get_pointer_32(p, offset, left, S, info); + if (r == nullptr) + return; + memset(&pl, '\0', sizeof(struct protocol_list32_t)); + if (left < sizeof(struct protocol_list32_t)) { + memcpy(&pl, r, left); + outs() << " (protocol_list_t entends past the end of the section)\n"; + } else + memcpy(&pl, r, sizeof(struct protocol_list32_t)); + if (info->O->isLittleEndian() != sys::IsLittleEndianHost) + swapStruct(pl); + outs() << " count " << pl.count << "\n"; + + p += sizeof(struct protocol_list32_t); + offset += sizeof(struct protocol_list32_t); + for (i = 0; i < pl.count; i++) { + r = get_pointer_32(p, offset, left, S, info); + if (r == nullptr) + return; + q = 0; + if (left < sizeof(uint32_t)) { + memcpy(&q, r, left); + outs() << " (protocol_t * entends past the end of the section)\n"; + } else + memcpy(&q, r, sizeof(uint32_t)); + if (info->O->isLittleEndian() != sys::IsLittleEndianHost) + sys::swapByteOrder(q); + outs() << "\t\t list[" << i << "] " << format("0x%" PRIx32, q) + << " (struct protocol_t *)\n"; + r = get_pointer_32(q, offset, left, S, info); + if (r == nullptr) + return; + memset(&pc, '\0', sizeof(struct protocol32_t)); + if (left < sizeof(struct protocol32_t)) { + memcpy(&pc, r, left); + outs() << " (protocol_t entends past the end of the section)\n"; + } else + memcpy(&pc, r, sizeof(struct protocol32_t)); + if (info->O->isLittleEndian() != sys::IsLittleEndianHost) + swapStruct(pc); + outs() << "\t\t\t isa " << format("0x%" PRIx32, pc.isa) << "\n"; + outs() << "\t\t\t name " << format("0x%" PRIx32, pc.name); + name = get_pointer_32(pc.name, xoffset, left, xS, info); + if (name != nullptr) + outs() << format(" %.*s", left, name); + outs() << "\n"; + outs() << "\t\t\tprotocols " << format("0x%" PRIx32, pc.protocols) << "\n"; + outs() << "\t\t instanceMethods " + << format("0x%" PRIx32, pc.instanceMethods) + << " (struct method_list_t *)\n"; + if (pc.instanceMethods != 0) + print_method_list32_t(pc.instanceMethods, info, "\t"); + outs() << "\t\t classMethods " << format("0x%" PRIx32, pc.classMethods) + << " (struct method_list_t *)\n"; + if (pc.classMethods != 0) + print_method_list32_t(pc.classMethods, info, "\t"); + outs() << "\t optionalInstanceMethods " + << format("0x%" PRIx32, pc.optionalInstanceMethods) << "\n"; + outs() << "\t optionalClassMethods " + << format("0x%" PRIx32, pc.optionalClassMethods) << "\n"; + outs() << "\t instanceProperties " + << format("0x%" PRIx32, pc.instanceProperties) << "\n"; + p += sizeof(uint32_t); + offset += sizeof(uint32_t); + } +} + static void print_ivar_list64_t(uint64_t p, struct DisassembleInfo *info) { struct ivar_list64_t il; struct ivar64_t i; @@ -3221,6 +3611,74 @@ static void print_ivar_list64_t(uint64_t p, struct DisassembleInfo *info) { } } +static void print_ivar_list32_t(uint32_t p, struct DisassembleInfo *info) { + struct ivar_list32_t il; + struct ivar32_t i; + const char *r; + uint32_t offset, xoffset, left, j; + SectionRef S, xS; + const char *name, *ivar_offset_p; + uint32_t ivar_offset; + + r = get_pointer_32(p, offset, left, S, info); + if (r == nullptr) + return; + memset(&il, '\0', sizeof(struct ivar_list32_t)); + if (left < sizeof(struct ivar_list32_t)) { + memcpy(&il, r, left); + outs() << " (ivar_list_t entends past the end of the section)\n"; + } else + memcpy(&il, r, sizeof(struct ivar_list32_t)); + if (info->O->isLittleEndian() != sys::IsLittleEndianHost) + swapStruct(il); + outs() << " entsize " << il.entsize << "\n"; + outs() << " count " << il.count << "\n"; + + p += sizeof(struct ivar_list32_t); + offset += sizeof(struct ivar_list32_t); + for (j = 0; j < il.count; j++) { + r = get_pointer_32(p, offset, left, S, info); + if (r == nullptr) + return; + memset(&i, '\0', sizeof(struct ivar32_t)); + if (left < sizeof(struct ivar32_t)) { + memcpy(&i, r, left); + outs() << " (ivar_t entends past the end of the section)\n"; + } else + memcpy(&i, r, sizeof(struct ivar32_t)); + if (info->O->isLittleEndian() != sys::IsLittleEndianHost) + swapStruct(i); + + outs() << "\t\t\t offset " << format("0x%" PRIx32, i.offset); + ivar_offset_p = get_pointer_32(i.offset, xoffset, left, xS, info); + if (ivar_offset_p != nullptr && left >= sizeof(*ivar_offset_p)) { + memcpy(&ivar_offset, ivar_offset_p, sizeof(ivar_offset)); + if (info->O->isLittleEndian() != sys::IsLittleEndianHost) + sys::swapByteOrder(ivar_offset); + outs() << " " << ivar_offset << "\n"; + } else + outs() << "\n"; + + outs() << "\t\t\t name " << format("0x%" PRIx32, i.name); + name = get_pointer_32(i.name, xoffset, left, xS, info); + if (name != nullptr) + outs() << format(" %.*s", left, name); + outs() << "\n"; + + outs() << "\t\t\t type " << format("0x%" PRIx32, i.type); + name = get_pointer_32(i.type, xoffset, left, xS, info); + if (name != nullptr) + outs() << format(" %.*s", left, name); + outs() << "\n"; + + outs() << "\t\t\talignment " << i.alignment << "\n"; + outs() << "\t\t\t size " << i.size << "\n"; + + p += sizeof(struct ivar32_t); + offset += sizeof(struct ivar32_t); + } +} + static void print_objc_property_list64(uint64_t p, struct DisassembleInfo *info) { struct objc_property_list64 opl; @@ -3300,6 +3758,61 @@ static void print_objc_property_list64(uint64_t p, } } +static void print_objc_property_list32(uint32_t p, + struct DisassembleInfo *info) { + struct objc_property_list32 opl; + struct objc_property32 op; + const char *r; + uint32_t offset, xoffset, left, j; + SectionRef S, xS; + const char *name; + + r = get_pointer_32(p, offset, left, S, info); + if (r == nullptr) + return; + memset(&opl, '\0', sizeof(struct objc_property_list32)); + if (left < sizeof(struct objc_property_list32)) { + memcpy(&opl, r, left); + outs() << " (objc_property_list entends past the end of the section)\n"; + } else + memcpy(&opl, r, sizeof(struct objc_property_list32)); + if (info->O->isLittleEndian() != sys::IsLittleEndianHost) + swapStruct(opl); + outs() << " entsize " << opl.entsize << "\n"; + outs() << " count " << opl.count << "\n"; + + p += sizeof(struct objc_property_list32); + offset += sizeof(struct objc_property_list32); + for (j = 0; j < opl.count; j++) { + r = get_pointer_32(p, offset, left, S, info); + if (r == nullptr) + return; + memset(&op, '\0', sizeof(struct objc_property32)); + if (left < sizeof(struct objc_property32)) { + memcpy(&op, r, left); + outs() << " (objc_property entends past the end of the section)\n"; + } else + memcpy(&op, r, sizeof(struct objc_property32)); + if (info->O->isLittleEndian() != sys::IsLittleEndianHost) + swapStruct(op); + + outs() << "\t\t\t name " << format("0x%" PRIx32, op.name); + name = get_pointer_32(op.name, xoffset, left, xS, info); + if (name != nullptr) + outs() << format(" %.*s", left, name); + outs() << "\n"; + + outs() << "\t\t\tattributes " << format("0x%" PRIx32, op.attributes); + name = get_pointer_32(op.attributes, xoffset, left, xS, info); + if (name != nullptr) + outs() << format(" %.*s", left, name); + outs() << "\n"; + + p += sizeof(struct objc_property32); + offset += sizeof(struct objc_property32); + } +} + static void print_class_ro64_t(uint64_t p, struct DisassembleInfo *info, bool &is_meta_class) { struct class_ro64_t cro; @@ -3388,7 +3901,7 @@ static void print_class_ro64_t(uint64_t p, struct DisassembleInfo *info, outs() << " ivars "; sym_name = get_symbol_64(offset + offsetof(struct class_ro64_t, ivars), S, - info, n_value, cro.baseProtocols); + info, n_value, cro.ivars); if (n_value != 0) { if (info->verbose && sym_name != nullptr) outs() << sym_name; @@ -3438,6 +3951,69 @@ static void print_class_ro64_t(uint64_t p, struct DisassembleInfo *info, is_meta_class = (cro.flags & RO_META) ? true : false; } +static void print_class_ro32_t(uint32_t p, struct DisassembleInfo *info, + bool &is_meta_class) { + struct class_ro32_t cro; + const char *r; + uint32_t offset, xoffset, left; + SectionRef S, xS; + const char *name; + + r = get_pointer_32(p, offset, left, S, info); + if (r == nullptr) + return; + memset(&cro, '\0', sizeof(struct class_ro32_t)); + if (left < sizeof(struct class_ro32_t)) { + memcpy(&cro, r, left); + outs() << " (class_ro_t entends past the end of the section)\n"; + } else + memcpy(&cro, r, sizeof(struct class_ro32_t)); + if (info->O->isLittleEndian() != sys::IsLittleEndianHost) + swapStruct(cro); + outs() << " flags " << format("0x%" PRIx32, cro.flags); + if (cro.flags & RO_META) + outs() << " RO_META"; + if (cro.flags & RO_ROOT) + outs() << " RO_ROOT"; + if (cro.flags & RO_HAS_CXX_STRUCTORS) + outs() << " RO_HAS_CXX_STRUCTORS"; + outs() << "\n"; + outs() << " instanceStart " << cro.instanceStart << "\n"; + outs() << " instanceSize " << cro.instanceSize << "\n"; + outs() << " ivarLayout " << format("0x%" PRIx32, cro.ivarLayout) + << "\n"; + print_layout_map32(cro.ivarLayout, info); + + outs() << " name " << format("0x%" PRIx32, cro.name); + name = get_pointer_32(cro.name, xoffset, left, xS, info); + if (name != nullptr) + outs() << format(" %.*s", left, name); + outs() << "\n"; + + outs() << " baseMethods " + << format("0x%" PRIx32, cro.baseMethods) + << " (struct method_list_t *)\n"; + if (cro.baseMethods != 0) + print_method_list32_t(cro.baseMethods, info, ""); + + outs() << " baseProtocols " + << format("0x%" PRIx32, cro.baseProtocols) << "\n"; + if (cro.baseProtocols != 0) + print_protocol_list32_t(cro.baseProtocols, info); + outs() << " ivars " << format("0x%" PRIx32, cro.ivars) + << "\n"; + if (cro.ivars != 0) + print_ivar_list32_t(cro.ivars, info); + outs() << " weakIvarLayout " + << format("0x%" PRIx32, cro.weakIvarLayout) << "\n"; + print_layout_map32(cro.weakIvarLayout, info); + outs() << " baseProperties " + << format("0x%" PRIx32, cro.baseProperties) << "\n"; + if (cro.baseProperties != 0) + print_objc_property_list32(cro.baseProperties, info); + is_meta_class = (cro.flags & RO_META) ? true : false; +} + static void print_class64_t(uint64_t p, struct DisassembleInfo *info) { struct class64_t c; const char *r; @@ -3504,7 +4080,7 @@ static void print_class64_t(uint64_t p, struct DisassembleInfo *info) { if ((c.data + n_value) & 0x7) outs() << " Swift class"; outs() << "\n"; - bool is_meta_class = true; + bool is_meta_class; print_class_ro64_t((c.data + n_value) & ~0x7, info, is_meta_class); if (is_meta_class == false) { @@ -3513,6 +4089,71 @@ static void print_class64_t(uint64_t p, struct DisassembleInfo *info) { } } +static void print_class32_t(uint32_t p, struct DisassembleInfo *info) { + struct class32_t c; + const char *r; + uint32_t offset, left; + SectionRef S; + const char *name; + + r = get_pointer_32(p, offset, left, S, info); + if (r == nullptr) + return; + memset(&c, '\0', sizeof(struct class32_t)); + if (left < sizeof(struct class32_t)) { + memcpy(&c, r, left); + outs() << " (class_t entends past the end of the section)\n"; + } else + memcpy(&c, r, sizeof(struct class32_t)); + if (info->O->isLittleEndian() != sys::IsLittleEndianHost) + swapStruct(c); + + outs() << " isa " << format("0x%" PRIx32, c.isa); + name = + get_symbol_32(offset + offsetof(struct class32_t, isa), S, info, c.isa); + if (name != nullptr) + outs() << " " << name; + outs() << "\n"; + + outs() << " superclass " << format("0x%" PRIx32, c.superclass); + name = get_symbol_32(offset + offsetof(struct class32_t, superclass), S, info, + c.superclass); + if (name != nullptr) + outs() << " " << name; + outs() << "\n"; + + outs() << " cache " << format("0x%" PRIx32, c.cache); + name = get_symbol_32(offset + offsetof(struct class32_t, cache), S, info, + c.cache); + if (name != nullptr) + outs() << " " << name; + outs() << "\n"; + + outs() << " vtable " << format("0x%" PRIx32, c.vtable); + name = get_symbol_32(offset + offsetof(struct class32_t, vtable), S, info, + c.vtable); + if (name != nullptr) + outs() << " " << name; + outs() << "\n"; + + name = + get_symbol_32(offset + offsetof(struct class32_t, data), S, info, c.data); + outs() << " data " << format("0x%" PRIx32, c.data) + << " (struct class_ro_t *)"; + + // This is a Swift class if some of the low bits of the pointer are set. + if (c.data & 0x3) + outs() << " Swift class"; + outs() << "\n"; + bool is_meta_class; + print_class_ro32_t(c.data & ~0x3, info, is_meta_class); + + if (is_meta_class == false) { + outs() << "Meta Class\n"; + print_class32_t(c.isa, info); + } +} + static void print_category64_t(uint64_t p, struct DisassembleInfo *info) { struct category64_t c; const char *r; @@ -3633,6 +4274,52 @@ static void print_category64_t(uint64_t p, struct DisassembleInfo *info) { print_objc_property_list64(c.instanceProperties + n_value, info); } +static void print_category32_t(uint32_t p, struct DisassembleInfo *info) { + struct category32_t c; + const char *r; + uint32_t offset, left; + SectionRef S, xS; + const char *name; + + r = get_pointer_32(p, offset, left, S, info); + if (r == nullptr) + return; + memset(&c, '\0', sizeof(struct category32_t)); + if (left < sizeof(struct category32_t)) { + memcpy(&c, r, left); + outs() << " (category_t entends past the end of the section)\n"; + } else + memcpy(&c, r, sizeof(struct category32_t)); + if (info->O->isLittleEndian() != sys::IsLittleEndianHost) + swapStruct(c); + + outs() << " name " << format("0x%" PRIx32, c.name); + name = get_symbol_32(offset + offsetof(struct category32_t, name), S, info, + c.name); + if (name != NULL) + outs() << " " << name; + outs() << "\n"; + + outs() << " cls " << format("0x%" PRIx32, c.cls) << "\n"; + if (c.cls != 0) + print_class32_t(c.cls, info); + outs() << " instanceMethods " << format("0x%" PRIx32, c.instanceMethods) + << "\n"; + if (c.instanceMethods != 0) + print_method_list32_t(c.instanceMethods, info, ""); + outs() << " classMethods " << format("0x%" PRIx32, c.classMethods) + << "\n"; + if (c.classMethods != 0) + print_method_list32_t(c.classMethods, info, ""); + outs() << " protocols " << format("0x%" PRIx32, c.protocols) << "\n"; + if (c.protocols != 0) + print_protocol_list32_t(c.protocols, info); + outs() << "instanceProperties " << format("0x%" PRIx32, c.instanceProperties) + << "\n"; + if (c.instanceProperties != 0) + print_objc_property_list32(c.instanceProperties, info); +} + static void print_message_refs64(SectionRef S, struct DisassembleInfo *info) { uint32_t i, left, offset, xoffset; uint64_t p, n_value; @@ -3698,6 +4385,52 @@ static void print_message_refs64(SectionRef S, struct DisassembleInfo *info) { } } +static void print_message_refs32(SectionRef S, struct DisassembleInfo *info) { + uint32_t i, left, offset, xoffset, p; + struct message_ref32 mr; + const char *name, *r; + SectionRef xS; + + if (S == SectionRef()) + return; + + StringRef SectName; + S.getName(SectName); + DataRefImpl Ref = S.getRawDataRefImpl(); + StringRef SegName = info->O->getSectionFinalSegmentName(Ref); + outs() << "Contents of (" << SegName << "," << SectName << ") section\n"; + offset = 0; + for (i = 0; i < S.getSize(); i += sizeof(struct message_ref64)) { + p = S.getAddress() + i; + r = get_pointer_32(p, offset, left, S, info); + if (r == nullptr) + return; + memset(&mr, '\0', sizeof(struct message_ref32)); + if (left < sizeof(struct message_ref32)) { + memcpy(&mr, r, left); + outs() << " (message_ref entends past the end of the section)\n"; + } else + memcpy(&mr, r, sizeof(struct message_ref32)); + if (info->O->isLittleEndian() != sys::IsLittleEndianHost) + swapStruct(mr); + + outs() << " imp " << format("0x%" PRIx32, mr.imp); + name = get_symbol_32(offset + offsetof(struct message_ref32, imp), S, info, + mr.imp); + if (name != nullptr) + outs() << " " << name; + outs() << "\n"; + + outs() << " sel " << format("0x%" PRIx32, mr.sel); + name = get_pointer_32(mr.sel, xoffset, left, xS, info); + if (name != nullptr) + outs() << " " << name; + outs() << "\n"; + + offset += sizeof(struct message_ref32); + } +} + static void print_image_info64(SectionRef S, struct DisassembleInfo *info) { uint32_t left, offset, swift_version; uint64_t p; @@ -3739,6 +4472,46 @@ static void print_image_info64(SectionRef S, struct DisassembleInfo *info) { outs() << "\n"; } +static void print_image_info32(SectionRef S, struct DisassembleInfo *info) { + uint32_t left, offset, swift_version, p; + struct objc_image_info32 o; + const char *r; + + StringRef SectName; + S.getName(SectName); + DataRefImpl Ref = S.getRawDataRefImpl(); + StringRef SegName = info->O->getSectionFinalSegmentName(Ref); + outs() << "Contents of (" << SegName << "," << SectName << ") section\n"; + p = S.getAddress(); + r = get_pointer_32(p, offset, left, S, info); + if (r == nullptr) + return; + memset(&o, '\0', sizeof(struct objc_image_info32)); + if (left < sizeof(struct objc_image_info32)) { + memcpy(&o, r, left); + outs() << " (objc_image_info entends past the end of the section)\n"; + } else + memcpy(&o, r, sizeof(struct objc_image_info32)); + if (info->O->isLittleEndian() != sys::IsLittleEndianHost) + swapStruct(o); + outs() << " version " << o.version << "\n"; + outs() << " flags " << format("0x%" PRIx32, o.flags); + if (o.flags & OBJC_IMAGE_IS_REPLACEMENT) + outs() << " OBJC_IMAGE_IS_REPLACEMENT"; + if (o.flags & OBJC_IMAGE_SUPPORTS_GC) + outs() << " OBJC_IMAGE_SUPPORTS_GC"; + swift_version = (o.flags >> 8) & 0xff; + if (swift_version != 0) { + if (swift_version == 1) + outs() << " Swift 1.0"; + else if (swift_version == 2) + outs() << " Swift 1.1"; + else + outs() << " unknown future Swift version (" << swift_version << ")"; + } + outs() << "\n"; +} + static void printObjc2_64bit_MetaData(MachOObjectFile *O, bool verbose) { SymbolAddressMap AddrMap; if (verbose) @@ -3840,10 +4613,104 @@ static void printObjc2_64bit_MetaData(MachOObjectFile *O, bool verbose) { } static void printObjc2_32bit_MetaData(MachOObjectFile *O, bool verbose) { - outs() << "Printing Objc2 32-bit MetaData not yet supported\n"; + SymbolAddressMap AddrMap; + if (verbose) + CreateSymbolAddressMap(O, &AddrMap); + + std::vector Sections; + for (const SectionRef &Section : O->sections()) { + StringRef SectName; + Section.getName(SectName); + Sections.push_back(Section); + } + + struct DisassembleInfo info; + // Set up the block of info used by the Symbolizer call backs. + info.verbose = verbose; + info.O = O; + info.AddrMap = &AddrMap; + info.Sections = &Sections; + info.class_name = nullptr; + info.selector_name = nullptr; + info.method = nullptr; + info.demangled_name = nullptr; + info.bindtable = nullptr; + info.adrp_addr = 0; + info.adrp_inst = 0; + + const SectionRef CL = get_section(O, "__OBJC2", "__class_list"); + if (CL != SectionRef()) { + info.S = CL; + walk_pointer_list_32("class", CL, O, &info, print_class32_t); + } else { + const SectionRef CL = get_section(O, "__DATA", "__objc_classlist"); + info.S = CL; + walk_pointer_list_32("class", CL, O, &info, print_class32_t); + } + + const SectionRef CR = get_section(O, "__OBJC2", "__class_refs"); + if (CR != SectionRef()) { + info.S = CR; + walk_pointer_list_32("class refs", CR, O, &info, nullptr); + } else { + const SectionRef CR = get_section(O, "__DATA", "__objc_classrefs"); + info.S = CR; + walk_pointer_list_32("class refs", CR, O, &info, nullptr); + } + + const SectionRef SR = get_section(O, "__OBJC2", "__super_refs"); + if (SR != SectionRef()) { + info.S = SR; + walk_pointer_list_32("super refs", SR, O, &info, nullptr); + } else { + const SectionRef SR = get_section(O, "__DATA", "__objc_superrefs"); + info.S = SR; + walk_pointer_list_32("super refs", SR, O, &info, nullptr); + } + + const SectionRef CA = get_section(O, "__OBJC2", "__category_list"); + if (CA != SectionRef()) { + info.S = CA; + walk_pointer_list_32("category", CA, O, &info, print_category32_t); + } else { + const SectionRef CA = get_section(O, "__DATA", "__objc_catlist"); + info.S = CA; + walk_pointer_list_32("category", CA, O, &info, print_category32_t); + } + + const SectionRef PL = get_section(O, "__OBJC2", "__protocol_list"); + if (PL != SectionRef()) { + info.S = PL; + walk_pointer_list_32("protocol", PL, O, &info, nullptr); + } else { + const SectionRef PL = get_section(O, "__DATA", "__objc_protolist"); + info.S = PL; + walk_pointer_list_32("protocol", PL, O, &info, nullptr); + } + + const SectionRef MR = get_section(O, "__OBJC2", "__message_refs"); + if (MR != SectionRef()) { + info.S = MR; + print_message_refs32(MR, &info); + } else { + const SectionRef MR = get_section(O, "__DATA", "__objc_msgrefs"); + info.S = MR; + print_message_refs32(MR, &info); + } + + const SectionRef II = get_section(O, "__OBJC2", "__image_info"); + if (II != SectionRef()) { + info.S = II; + print_image_info32(II, &info); + } else { + const SectionRef II = get_section(O, "__DATA", "__objc_imageinfo"); + info.S = II; + print_image_info32(II, &info); + } } static bool printObjc1_32bit_MetaData(MachOObjectFile *O, bool verbose) { + outs() << "Objective-C segment\n"; const SectionRef S = get_section(O, "__OBJC", "__module_info"); if (S != SectionRef()) { outs() << "Printing Objc1 32-bit MetaData not yet supported\n";