Index: test/tools/llvm-objdump/macho-objc-meta-data.test =================================================================== --- test/tools/llvm-objdump/macho-objc-meta-data.test +++ test/tools/llvm-objdump/macho-objc-meta-data.test @@ -1,3 +1,444 @@ # RUN: llvm-objdump -macho -objc-meta-data %p/Inputs/empty.macho-armv7 | FileCheck %s # CHECK: empty.macho-armv7: + +# RUN: llvm-objdump -macho -objc-meta-data %p/Inputs/macho-objc-meta-data | FileCheck %s --check-prefix=OBJC + +# OBJC:macho-objc-meta-data: +# OBJC-NEXT:Contents of (__DATA,__objc_classlist) section +# OBJC-NEXT:00000001000010e8 0x100001600 _OBJC_CLASS_$_Foo +# OBJC-NEXT: isa 0x1000015d8 _OBJC_METACLASS_$_Foo +# OBJC-NEXT: superclass 0x0 _OBJC_CLASS_$_NSObject +# OBJC-NEXT: cache 0x0 +# OBJC-NEXT: vtable 0x0 +# OBJC-NEXT: data 0x100001390 (struct class_ro_t *) +# OBJC-NEXT: flags 0x0 +# OBJC-NEXT: instanceStart 8 +# OBJC-NEXT: instanceSize 12 +# OBJC-NEXT: reserved 0x0 +# OBJC-NEXT: ivarLayout 0x0 +# OBJC-NEXT: name 0x100000ed7 Foo +# OBJC-NEXT: baseMethods 0x100001110 (struct method_list_t *) +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 7 +# OBJC-NEXT: name 0x100000f60 categoryAddition +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x100000c90 -[Foo(Category) categoryAddition] +# OBJC-NEXT: name 0x100000f36 genericMethod +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x100000cc0 -[Foo(Category) genericMethod] +# OBJC-NEXT: name 0x100000f71 categoryProperty +# OBJC-NEXT: types 0x100000fa3 i16@0:8 +# OBJC-NEXT: imp 0x100000cf0 -[Foo(Category) categoryProperty] +# OBJC-NEXT: name 0x100000f36 genericMethod +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x100000b80 -[Foo genericMethod] +# OBJC-NEXT: name 0x100000f44 targetMethod: +# OBJC-NEXT: types 0x100000fab v24@0:8@16 +# OBJC-NEXT: imp 0x100000bb0 -[Foo targetMethod:] +# OBJC-NEXT: name 0x100000f06 verb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x100000c10 -[Foo verb] +# OBJC-NEXT: name 0x100000f0b intProperty +# OBJC-NEXT: types 0x100000fa3 i16@0:8 +# OBJC-NEXT: imp 0x100000c40 -[Foo intProperty] +# OBJC-NEXT: baseProtocols 0x100001230 +# OBJC-NEXT: count 2 +# OBJC-NEXT: list[0] 0x1000016d0 (struct protocol_t *) +# OBJC-NEXT: isa 0x0 +# OBJC-NEXT: name 0x100000edb Verbing +# OBJC-NEXT: protocols 0x0 +# OBJC-NEXT: instanceMethods 0x100001248  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 2 +# OBJC-NEXT: name 0x100000f06 verb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT: name 0x100000f0b intProperty +# OBJC-NEXT: types 0x100000fa3 i16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT: classMethods 0x100001280  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000efc classVerb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT:optionalInstanceMethods 0x1000012a0  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000f17 optionalVerb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT:optionalClassMethods 0x1000012c0  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000f24 classOptionalVerb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT:instanceProperties 0x1000012e0  +# OBJC-NEXT: entsize 16 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000e67 intProperty +# OBJC-NEXT: attributes 0x100000e73 Ti,R,N +# OBJC-NEXT: list[1] 0x1000016d0 (struct protocol_t *) +# OBJC-NEXT: isa 0x0 +# OBJC-NEXT: name 0x100000edb Verbing +# OBJC-NEXT: protocols 0x0 +# OBJC-NEXT: instanceMethods 0x100001248  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 2 +# OBJC-NEXT: name 0x100000f06 verb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT: name 0x100000f0b intProperty +# OBJC-NEXT: types 0x100000fa3 i16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT: classMethods 0x100001280  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000efc classVerb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT:optionalInstanceMethods 0x1000012a0  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000f17 optionalVerb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT:optionalClassMethods 0x1000012c0  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000f24 classOptionalVerb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT:instanceProperties 0x1000012e0  +# OBJC-NEXT: entsize 16 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000e67 intProperty +# OBJC-NEXT: attributes 0x100000e73 Ti,R,N +# OBJC-NEXT: ivars 0x100001368 +# OBJC-NEXT: entsize 32 +# OBJC-NEXT: count 1 +# OBJC-NEXT: offset 0x1000015c8 8 +# OBJC-NEXT: name 0x100000f52 m_intProperty +# OBJC-NEXT: type 0x100000fb6 i +# OBJC-NEXT: alignment 2 +# OBJC-NEXT: size 4 +# OBJC-NEXT: weakIvarLayout 0x0 +# OBJC-NEXT: baseProperties 0x1000011f8 +# OBJC-NEXT: entsize 16 +# OBJC-NEXT: count 3 +# OBJC-NEXT: name 0x100000ec6 categoryProperty +# OBJC-NEXT: attributes 0x100000e73 Ti,R,N +# OBJC-NEXT: name 0x100000e67 intProperty +# OBJC-NEXT: attributes 0x100000e73 Ti,R,N +# OBJC-NEXT: name 0x100000e67 intProperty +# OBJC-NEXT: attributes 0x100000e7a Ti,R,N,Vm_intProperty +# OBJC-NEXT:Meta Class +# OBJC-NEXT: isa 0x0 +# OBJC-NEXT: superclass 0x0 _OBJC_METACLASS_$_NSObject +# OBJC-NEXT: cache 0x0 +# OBJC-NEXT: vtable 0x0 +# OBJC-NEXT: data 0x100001320 (struct class_ro_t *) +# OBJC-NEXT: flags 0x1 RO_META +# OBJC-NEXT: instanceStart 40 +# OBJC-NEXT: instanceSize 40 +# OBJC-NEXT: reserved 0x0 +# OBJC-NEXT: ivarLayout 0x0 +# OBJC-NEXT: name 0x100000ed7 Foo +# OBJC-NEXT: baseMethods 0x1000011c0 (struct method_list_t *) +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 2 +# OBJC-NEXT: name 0x100000f82 categoryClass +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x100000c60 +[Foo(Category) categoryClass] +# OBJC-NEXT: name 0x100000efc classVerb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x100000be0 +[Foo classVerb] +# OBJC-NEXT: baseProtocols 0x100001230 +# OBJC-NEXT: count 2 +# OBJC-NEXT: list[0] 0x1000016d0 (struct protocol_t *) +# OBJC-NEXT: isa 0x0 +# OBJC-NEXT: name 0x100000edb Verbing +# OBJC-NEXT: protocols 0x0 +# OBJC-NEXT: instanceMethods 0x100001248  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 2 +# OBJC-NEXT: name 0x100000f06 verb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT: name 0x100000f0b intProperty +# OBJC-NEXT: types 0x100000fa3 i16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT: classMethods 0x100001280  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000efc classVerb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT:optionalInstanceMethods 0x1000012a0  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000f17 optionalVerb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT:optionalClassMethods 0x1000012c0  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000f24 classOptionalVerb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT:instanceProperties 0x1000012e0  +# OBJC-NEXT: entsize 16 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000e67 intProperty +# OBJC-NEXT: attributes 0x100000e73 Ti,R,N +# OBJC-NEXT: list[1] 0x1000016d0 (struct protocol_t *) +# OBJC-NEXT: isa 0x0 +# OBJC-NEXT: name 0x100000edb Verbing +# OBJC-NEXT: protocols 0x0 +# OBJC-NEXT: instanceMethods 0x100001248  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 2 +# OBJC-NEXT: name 0x100000f06 verb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT: name 0x100000f0b intProperty +# OBJC-NEXT: types 0x100000fa3 i16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT: classMethods 0x100001280  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000efc classVerb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT:optionalInstanceMethods 0x1000012a0  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000f17 optionalVerb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT:optionalClassMethods 0x1000012c0  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000f24 classOptionalVerb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT:instanceProperties 0x1000012e0  +# OBJC-NEXT: entsize 16 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000e67 intProperty +# OBJC-NEXT: attributes 0x100000e73 Ti,R,N +# OBJC-NEXT: ivars 0x0 +# OBJC-NEXT: weakIvarLayout 0x0 +# OBJC-NEXT: baseProperties 0x0 +# OBJC-NEXT:00000001000010f0 0x100001650 _OBJC_CLASS_$_FooSubclass +# OBJC-NEXT: isa 0x100001628 _OBJC_METACLASS_$_FooSubclass +# OBJC-NEXT: superclass 0x100001600 _OBJC_CLASS_$_Foo +# OBJC-NEXT: cache 0x0 +# OBJC-NEXT: vtable 0x0 +# OBJC-NEXT: data 0x100001420 (struct class_ro_t *) +# OBJC-NEXT: flags 0x0 +# OBJC-NEXT: instanceStart 12 +# OBJC-NEXT: instanceSize 12 +# OBJC-NEXT: reserved 0x0 +# OBJC-NEXT: ivarLayout 0x0 +# OBJC-NEXT: name 0x100000eec FooSubclass +# OBJC-NEXT: baseMethods 0x0 (struct method_list_t *) +# OBJC-NEXT: baseProtocols 0x0 +# OBJC-NEXT: ivars 0x0 +# OBJC-NEXT: weakIvarLayout 0x0 +# OBJC-NEXT: baseProperties 0x0 +# OBJC-NEXT:Meta Class +# OBJC-NEXT: isa 0x0 +# OBJC-NEXT: superclass 0x1000015d8 _OBJC_METACLASS_$_Foo +# OBJC-NEXT: cache 0x0 +# OBJC-NEXT: vtable 0x0 +# OBJC-NEXT: data 0x1000013d8 (struct class_ro_t *) +# OBJC-NEXT: flags 0x1 RO_META +# OBJC-NEXT: instanceStart 40 +# OBJC-NEXT: instanceSize 40 +# OBJC-NEXT: reserved 0x0 +# OBJC-NEXT: ivarLayout 0x0 +# OBJC-NEXT: name 0x100000eec FooSubclass +# OBJC-NEXT: baseMethods 0x0 (struct method_list_t *) +# OBJC-NEXT: baseProtocols 0x0 +# OBJC-NEXT: ivars 0x0 +# OBJC-NEXT: weakIvarLayout 0x0 +# OBJC-NEXT: baseProperties 0x0 +# OBJC-NEXT:00000001000010f8 0x1000016a0 _OBJC_CLASS_$_Bar +# OBJC-NEXT: isa 0x100001678 _OBJC_METACLASS_$_Bar +# OBJC-NEXT: superclass 0x0 _OBJC_CLASS_$_NSObject +# OBJC-NEXT: cache 0x0 +# OBJC-NEXT: vtable 0x0 +# OBJC-NEXT: data 0x100001560 (struct class_ro_t *) +# OBJC-NEXT: flags 0x0 +# OBJC-NEXT: instanceStart 8 +# OBJC-NEXT: instanceSize 12 +# OBJC-NEXT: reserved 0x0 +# OBJC-NEXT: ivarLayout 0x0 +# OBJC-NEXT: name 0x100000ef8 Bar +# OBJC-NEXT: baseMethods 0x1000014e8 (struct method_list_t *) +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 2 +# OBJC-NEXT: name 0x100000f06 verb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x100000d30 -[Bar verb] +# OBJC-NEXT: name 0x100000f0b intProperty +# OBJC-NEXT: types 0x100000fa3 i16@0:8 +# OBJC-NEXT: imp 0x100000d60 -[Bar intProperty] +# OBJC-NEXT: baseProtocols 0x100001488 +# OBJC-NEXT: count 1 +# OBJC-NEXT: list[0] 0x1000016d0 (struct protocol_t *) +# OBJC-NEXT: isa 0x0 +# OBJC-NEXT: name 0x100000edb Verbing +# OBJC-NEXT: protocols 0x0 +# OBJC-NEXT: instanceMethods 0x100001248  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 2 +# OBJC-NEXT: name 0x100000f06 verb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT: name 0x100000f0b intProperty +# OBJC-NEXT: types 0x100000fa3 i16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT: classMethods 0x100001280  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000efc classVerb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT:optionalInstanceMethods 0x1000012a0  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000f17 optionalVerb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT:optionalClassMethods 0x1000012c0  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000f24 classOptionalVerb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT:instanceProperties 0x1000012e0  +# OBJC-NEXT: entsize 16 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000e67 intProperty +# OBJC-NEXT: attributes 0x100000e73 Ti,R,N +# OBJC-NEXT: ivars 0x100001520 +# OBJC-NEXT: entsize 32 +# OBJC-NEXT: count 1 +# OBJC-NEXT: offset 0x1000015d0 8 +# OBJC-NEXT: name 0x100000f52 m_intProperty +# OBJC-NEXT: type 0x100000fb6 i +# OBJC-NEXT: alignment 2 +# OBJC-NEXT: size 4 +# OBJC-NEXT: weakIvarLayout 0x0 +# OBJC-NEXT: baseProperties 0x100001548 +# OBJC-NEXT: entsize 16 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000e67 intProperty +# OBJC-NEXT: attributes 0x100000e7a Ti,R,N,Vm_intProperty +# OBJC-NEXT:Meta Class +# OBJC-NEXT: isa 0x0 +# OBJC-NEXT: superclass 0x0 _OBJC_METACLASS_$_NSObject +# OBJC-NEXT: cache 0x0 +# OBJC-NEXT: vtable 0x0 +# OBJC-NEXT: data 0x1000014a0 (struct class_ro_t *) +# OBJC-NEXT: flags 0x1 RO_META +# OBJC-NEXT: instanceStart 40 +# OBJC-NEXT: instanceSize 40 +# OBJC-NEXT: reserved 0x0 +# OBJC-NEXT: ivarLayout 0x0 +# OBJC-NEXT: name 0x100000ef8 Bar +# OBJC-NEXT: baseMethods 0x100001468 (struct method_list_t *) +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000efc classVerb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x100000d00 +[Bar classVerb] +# OBJC-NEXT: baseProtocols 0x100001488 +# OBJC-NEXT: count 1 +# OBJC-NEXT: list[0] 0x1000016d0 (struct protocol_t *) +# OBJC-NEXT: isa 0x0 +# OBJC-NEXT: name 0x100000edb Verbing +# OBJC-NEXT: protocols 0x0 +# OBJC-NEXT: instanceMethods 0x100001248  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 2 +# OBJC-NEXT: name 0x100000f06 verb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT: name 0x100000f0b intProperty +# OBJC-NEXT: types 0x100000fa3 i16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT: classMethods 0x100001280  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000efc classVerb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT:optionalInstanceMethods 0x1000012a0  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000f17 optionalVerb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT:optionalClassMethods 0x1000012c0  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000f24 classOptionalVerb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT:instanceProperties 0x1000012e0  +# OBJC-NEXT: entsize 16 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000e67 intProperty +# OBJC-NEXT: attributes 0x100000e73 Ti,R,N +# OBJC-NEXT: ivars 0x0 +# OBJC-NEXT: weakIvarLayout 0x0 +# OBJC-NEXT: baseProperties 0x0 +# OBJC-NEXT:Contents of (__DATA,__objc_classrefs) section +# OBJC-NEXT:00000001000015b8 0x100001650 _OBJC_CLASS_$_FooSubclass +# OBJC-NEXT:00000001000015c0 0x1000016a0 _OBJC_CLASS_$_Bar +# OBJC-NEXT:Contents of (__DATA,__objc_catlist) section +# OBJC-NEXT:Contents of (__DATA,__objc_protolist) section +# OBJC-NEXT:0000000100001100 0x1000016d0 +# OBJC-NEXT: isa 0x0 +# OBJC-NEXT: name 0x100000edb Verbing +# OBJC-NEXT: protocols 0x0 +# OBJC-NEXT: instanceMethods 0x100001248  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 2 +# OBJC-NEXT: name 0x100000f06 verb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT: name 0x100000f0b intProperty +# OBJC-NEXT: types 0x100000fa3 i16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT: classMethods 0x100001280  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000efc classVerb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT:optionalInstanceMethods 0x1000012a0  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000f17 optionalVerb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT:optionalClassMethods 0x1000012c0  +# OBJC-NEXT: entsize 24 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000f24 classOptionalVerb +# OBJC-NEXT: types 0x100000f9b v16@0:8 +# OBJC-NEXT: imp 0x0 +# OBJC-NEXT:instanceProperties 0x1000012e0  +# OBJC-NEXT: entsize 16 +# OBJC-NEXT: count 1 +# OBJC-NEXT: name 0x100000e67 intProperty +# OBJC-NEXT: attributes 0x100000e73 Ti,R,N +# OBJC-NEXT:Contents of (__DATA,__objc_imageinfo) section +# OBJC-NEXT: version 0 +# OBJC-NEXT: flags 0x40 OBJC_IMAGE_HAS_CATEGORY_CLASS_PROPERTIES Index: tools/llvm-objdump/MachODump.cpp =================================================================== --- tools/llvm-objdump/MachODump.cpp +++ tools/llvm-objdump/MachODump.cpp @@ -4214,7 +4214,7 @@ outs() << indent << "\t\t imp "; name = get_symbol_64(offset + offsetof(struct method64_t, imp), S, info, n_value, m.imp); - if (info->verbose && name == nullptr) { + if (info->verbose) { if (n_value != 0) { outs() << format("0x%" PRIx64, n_value) << " "; if (m.imp != 0) @@ -4364,14 +4364,15 @@ return false; } +static void print_protocol64_t(uint64_t p, struct DisassembleInfo *info); + static void print_protocol_list64_t(uint64_t p, struct DisassembleInfo *info) { struct protocol_list64_t pl; uint64_t q, n_value; - struct protocol64_t pc; const char *r; - uint32_t offset, xoffset, left, i; + uint32_t offset, left, i; SectionRef S, xS; - const char *name, *sym_name; + const char *sym_name; r = get_pointer_64(p, offset, left, S, info); if (r == nullptr) @@ -4414,93 +4415,18 @@ outs() << format("0x%" PRIx64, q); outs() << " (struct protocol_t *)\n"; - r = get_pointer_64(q + n_value, offset, left, S, info); - if (r == nullptr) - return; - memset(&pc, '\0', sizeof(struct protocol64_t)); - if (left < sizeof(struct protocol64_t)) { - memcpy(&pc, r, left); - outs() << " (protocol_t entends past the end of the section)\n"; - } else - memcpy(&pc, r, sizeof(struct protocol64_t)); - if (info->O->isLittleEndian() != sys::IsLittleEndianHost) - swapStruct(pc); - - outs() << "\t\t\t isa " << format("0x%" PRIx64, pc.isa) << "\n"; - - outs() << "\t\t\t name "; - sym_name = get_symbol_64(offset + offsetof(struct protocol64_t, name), S, - info, n_value, pc.name); - if (n_value != 0) { - if (info->verbose && sym_name != nullptr) - outs() << sym_name; - else - outs() << format("0x%" PRIx64, n_value); - if (pc.name != 0) - outs() << " + " << format("0x%" PRIx64, pc.name); - } else - outs() << format("0x%" PRIx64, pc.name); - name = get_pointer_64(pc.name + n_value, xoffset, left, xS, info); - if (name != nullptr) - outs() << format(" %.*s", left, name); - outs() << "\n"; - - outs() << "\t\t\tprotocols " << format("0x%" PRIx64, pc.protocols) << "\n"; - - outs() << "\t\t instanceMethods "; - sym_name = - get_symbol_64(offset + offsetof(struct protocol64_t, instanceMethods), - S, info, n_value, pc.instanceMethods); - if (n_value != 0) { - if (info->verbose && sym_name != nullptr) - outs() << sym_name; - else - outs() << format("0x%" PRIx64, n_value); - if (pc.instanceMethods != 0) - outs() << " + " << format("0x%" PRIx64, pc.instanceMethods); - } else - outs() << format("0x%" PRIx64, pc.instanceMethods); - outs() << " (struct method_list_t *)\n"; - if (pc.instanceMethods + n_value != 0) - print_method_list64_t(pc.instanceMethods + n_value, info, "\t"); - - outs() << "\t\t classMethods "; - sym_name = - get_symbol_64(offset + offsetof(struct protocol64_t, classMethods), S, - info, n_value, pc.classMethods); - if (n_value != 0) { - if (info->verbose && sym_name != nullptr) - outs() << sym_name; - else - outs() << format("0x%" PRIx64, n_value); - if (pc.classMethods != 0) - outs() << " + " << format("0x%" PRIx64, pc.classMethods); - } else - outs() << format("0x%" PRIx64, pc.classMethods); - outs() << " (struct method_list_t *)\n"; - if (pc.classMethods + n_value != 0) - print_method_list64_t(pc.classMethods + n_value, info, "\t"); - - outs() << "\t optionalInstanceMethods " - << format("0x%" PRIx64, pc.optionalInstanceMethods) << "\n"; - outs() << "\t optionalClassMethods " - << format("0x%" PRIx64, pc.optionalClassMethods) << "\n"; - outs() << "\t instanceProperties " - << format("0x%" PRIx64, pc.instanceProperties) << "\n"; - - p += sizeof(uint64_t); - offset += sizeof(uint64_t); + print_protocol64_t(q + n_value, info); } } +static void print_protocol32_t(uint32_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; + uint32_t offset, left, i; SectionRef S, xS; - const char *name; r = get_pointer_32(p, offset, left, S, info); if (r == nullptr) @@ -4531,41 +4457,8 @@ 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); + + print_protocol32_t(q, info); } } @@ -5733,6 +5626,248 @@ print_objc_property_list32(c.instanceProperties, info); } +static void print_protocol64_t(uint64_t p, struct DisassembleInfo *info) { + struct protocol64_t pc; + const char *r; + uint32_t offset, xoffset, left; + SectionRef S, xS; + const char *name, *sym_name; + uint64_t n_value; + + r = get_pointer_64(p, offset, left, S, info); + if (r == nullptr) + return; + memset(&pc, '\0', sizeof(struct protocol64_t)); + if (left < sizeof(struct protocol64_t)) { + memcpy(&pc, r, left); + outs() << " (protocol_t entends past the end of the section)\n"; + } else + memcpy(&pc, r, sizeof(struct protocol64_t)); + if (info->O->isLittleEndian() != sys::IsLittleEndianHost) + swapStruct(pc); + + outs() << " isa "; + sym_name = get_symbol_64(offset + offsetof(struct protocol64_t, isa), S, + info, n_value, pc.isa); + if (n_value != 0) { + if (info->verbose && sym_name != nullptr) + outs() << sym_name; + else + outs() << format("0x%" PRIx64, n_value); + if (pc.isa != 0) + outs() << " + " << format("0x%" PRIx64, pc.isa); + } else + outs() << format("0x%" PRIx64, pc.isa); + name = get_pointer_64(pc.isa + n_value, xoffset, left, xS, info); + if (name != nullptr) + outs() << format(" %.*s", left, name); + outs() << "\n"; + + outs() << " name "; + sym_name = get_symbol_64(offset + offsetof(struct protocol64_t, name), S, + info, n_value, pc.name); + if (n_value != 0) { + if (info->verbose && sym_name != nullptr) + outs() << sym_name; + else + outs() << format("0x%" PRIx64, n_value); + if (pc.name != 0) + outs() << " + " << format("0x%" PRIx64, pc.name); + } else + outs() << format("0x%" PRIx64, pc.name); + name = get_pointer_64(pc.name + n_value, xoffset, left, xS, info); + if (name != nullptr) + outs() << format(" %.*s", left, name); + outs() << "\n"; + + outs() << " protocols "; + sym_name = get_symbol_64(offset + offsetof(struct protocol64_t, protocols), + S, info, n_value, pc.protocols); + if (n_value != 0) { + if (info->verbose && sym_name != nullptr) + outs() << sym_name; + else + outs() << format("0x%" PRIx64, n_value); + if (pc.protocols != 0) + outs() << " + " << format("0x%" PRIx64, pc.protocols); + } else + outs() << format("0x%" PRIx64, pc.protocols); + name = get_pointer_64(pc.protocols + n_value, xoffset, left, xS, info); + if (name != nullptr) + outs() << format(" %.*s", left, name); + outs() << "\n"; + if (pc.protocols + n_value != 0) + print_protocol_list64_t(pc.protocols + n_value, info); + + outs() << " instanceMethods "; + sym_name = get_symbol_64(offset + offsetof(struct protocol64_t, + instanceMethods), + S, info, n_value, pc.instanceMethods); + if (n_value != 0) { + if (info->verbose && sym_name != nullptr) + outs() << sym_name; + else + outs() << format("0x%" PRIx64, n_value); + if (pc.instanceMethods != 0) + outs() << " + " << format("0x%" PRIx64, pc.instanceMethods); + } else + outs() << format("0x%" PRIx64, pc.instanceMethods); + name = get_pointer_64(pc.instanceMethods + n_value, xoffset, left, + xS, info); + if (name != nullptr) + outs() << format(" %.*s", left, name); + outs() << "\n"; + if (pc.instanceMethods + n_value != 0) + print_method_list64_t(pc.instanceMethods + n_value, info, ""); + + outs() << " classMethods "; + sym_name = get_symbol_64(offset + offsetof(struct protocol64_t, + classMethods), + S, info, n_value, pc.classMethods); + if (n_value != 0) { + if (info->verbose && sym_name != nullptr) + outs() << sym_name; + else + outs() << format("0x%" PRIx64, n_value); + if (pc.classMethods != 0) + outs() << " + " << format("0x%" PRIx64, pc.classMethods); + } else + outs() << format("0x%" PRIx64, pc.classMethods); + name = get_pointer_64(pc.classMethods + n_value, xoffset, left, xS, info); + if (name != nullptr) + outs() << format(" %.*s", left, name); + outs() << "\n"; + if (pc.classMethods + n_value != 0) + print_method_list64_t(pc.classMethods + n_value, info, ""); + + outs() << "optionalInstanceMethods "; + sym_name = get_symbol_64(offset + offsetof(struct protocol64_t, + optionalInstanceMethods), + S, info, n_value, pc.optionalInstanceMethods); + if (n_value != 0) { + if (info->verbose && sym_name != nullptr) + outs() << sym_name; + else + outs() << format("0x%" PRIx64, n_value); + if (pc.optionalInstanceMethods != 0) + outs() << " + " << format("0x%" PRIx64, pc.optionalInstanceMethods); + } else + outs() << format("0x%" PRIx64, pc.optionalInstanceMethods); + name = get_pointer_64(pc.optionalInstanceMethods + n_value, xoffset, left, + xS, info); + if (name != nullptr) + outs() << format(" %.*s", left, name); + outs() << "\n"; + if (pc.optionalInstanceMethods + n_value != 0) + print_method_list64_t(pc.optionalInstanceMethods + n_value, info, ""); + + outs() << "optionalClassMethods "; + sym_name = get_symbol_64(offset + offsetof(struct protocol64_t, + optionalClassMethods), + S, info, n_value, pc.optionalClassMethods); + if (n_value != 0) { + if (info->verbose && sym_name != nullptr) + outs() << sym_name; + else + outs() << format("0x%" PRIx64, n_value); + if (pc.optionalClassMethods != 0) + outs() << " + " << format("0x%" PRIx64, pc.optionalClassMethods); + } else + outs() << format("0x%" PRIx64, pc.optionalClassMethods); + name = get_pointer_64(pc.optionalClassMethods + n_value, xoffset, left, + xS, info); + if (name != nullptr) + outs() << format(" %.*s", left, name); + outs() << "\n"; + if (pc.optionalClassMethods + n_value != 0) + print_method_list64_t(pc.optionalClassMethods + n_value, info, ""); + + outs() << "instanceProperties "; + sym_name = get_symbol_64(offset + offsetof(struct protocol64_t, + instanceProperties), + S, info, n_value, pc.instanceProperties); + if (n_value != 0) { + if (info->verbose && sym_name != nullptr) + outs() << sym_name; + else + outs() << format("0x%" PRIx64, n_value); + if (pc.instanceProperties != 0) + outs() << " + " << format("0x%" PRIx64, pc.instanceProperties); + } else + outs() << format("0x%" PRIx64, pc.instanceProperties); + name = get_pointer_64(pc.instanceProperties + n_value, xoffset, left, + xS, info); + if (name != nullptr) + outs() << format(" %.*s", left, name); + outs() << "\n"; + if (pc.instanceProperties + n_value != 0) + print_objc_property_list64(pc.instanceProperties + n_value, info); +} + +static void print_protocol32_t(uint32_t p, struct DisassembleInfo *info) { + struct protocol32_t pc; + 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(&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() << " isa " << format("0x%" PRIx32, pc.isa); + name = get_symbol_32(offset + offsetof(struct protocol32_t, isa), S, info, + pc.isa); + if (name) + outs() << " " << name; + outs() << "\n"; + + outs() << " name " << format("0x%" PRIx32, pc.name); + name = get_symbol_32(offset + offsetof(struct protocol32_t, name), S, info, + pc.name); + if (name) + outs() << " " << name; + outs() << "\n"; + + outs() << " protocols " << format("0x%" PRIx32, pc.protocols) << + "\n"; + if (pc.protocols != 0) + print_protocol_list32_t(pc.protocols, info); + + outs() << " instanceMethods " << format("0x%" PRIx32, pc.instanceMethods) + << "\n"; + if (pc.instanceMethods != 0) + print_method_list32_t(pc.instanceMethods, info, ""); + + outs() << " classMethods " << format("0x%" PRIx32, pc.classMethods) + << "\n"; + if (pc.classMethods != 0) + print_method_list32_t(pc.classMethods, info, ""); + + outs() << "optionalInstanceMethods " << + format("0x%" PRIx32, pc.optionalInstanceMethods) << "\n"; + if (pc.optionalInstanceMethods != 0) + print_method_list32_t(pc.optionalInstanceMethods, info, ""); + + outs() << "optionalClassMethods " << + format("0x%" PRIx32, pc.optionalClassMethods) << "\n"; + if (pc.optionalClassMethods != 0) + print_method_list32_t(pc.optionalClassMethods, info, ""); + + outs() << "instanceProperties " << + format("0x%" PRIx32, pc.instanceProperties) << "\n"; + if (pc.instanceProperties != 0) + print_objc_property_list32(pc.instanceProperties, info); +} + static void print_message_refs64(SectionRef S, struct DisassembleInfo *info) { uint32_t i, left, offset, xoffset; uint64_t p, n_value; @@ -6052,7 +6187,7 @@ if (PL == SectionRef()) PL = get_section(O, "__DATA_DIRTY", "__objc_protolist"); info.S = PL; - walk_pointer_list_64("protocol", PL, O, &info, nullptr); + walk_pointer_list_64("protocol", PL, O, &info, print_protocol64_t); SectionRef MR = get_section(O, "__OBJC2", "__message_refs"); if (MR == SectionRef()) @@ -6137,7 +6272,7 @@ if (PL == SectionRef()) PL = get_section(O, "__DATA_DIRTY", "__objc_protolist"); info.S = PL; - walk_pointer_list_32("protocol", PL, O, &info, nullptr); + walk_pointer_list_32("protocol", PL, O, &info, print_protocol32_t); SectionRef MR = get_section(O, "__OBJC2", "__message_refs"); if (MR == SectionRef())