From 4906c5787661f305dd2d1a552b36fe0baa086bb9 Mon Sep 17 00:00:00 2001 From: Kevin Enderby Date: Thu, 16 Apr 2015 22:33:20 +0000 Subject: [PATCH] For llvm-objdump, dump the (__OBJC,__protocol) section for Objc1 32-bit Mach-O files with the -section option as objc_protocol_t structs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235141 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../X86/macho-objc-meta-data.test | 139 ++++++++++++++++++ tools/llvm-objdump/MachODump.cpp | 52 +++++++ 2 files changed, 191 insertions(+) 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 1ff42df7e1a..f4abf6cdb49 100644 --- a/test/tools/llvm-objdump/X86/macho-objc-meta-data.test +++ b/test/tools/llvm-objdump/X86/macho-objc-meta-data.test @@ -4,6 +4,7 @@ # RUN: llvm-objdump -m -objc-meta-data %p/Inputs/Objc2.32bit.obj.macho-i386 | FileCheck %s -check-prefix=OBJC2_32BIT_OBJ # RUN: llvm-objdump -m -objc-meta-data %p/Inputs/Objc1.32bit.exe.macho-i386 | FileCheck %s -check-prefix=OBJC1_32BIT_EXE # RUN: llvm-objdump -m -objc-meta-data %p/Inputs/Objc1.32bit.obj.macho-i386 | FileCheck %s -check-prefix=OBJC1_32BIT_OBJ +# RUN: llvm-objdump -m -section __OBJC,__protocol %p/Inputs/Objc1.32bit.exe.macho-i386 | FileCheck %s -check-prefix=PROTOCOL OBJC2_64BIT_EXE: Contents of (__DATA,__objc_classlist) section OBJC2_64BIT_EXE: 0000000100002028 0x1000029f0 @@ -898,3 +899,141 @@ OBJC1_32BIT_OBJ: protocols 0x00000000 (not in an __OBJC section) OBJC1_32BIT_OBJ: Contents of (__OBJC,__image_info) section OBJC1_32BIT_OBJ: version 0 OBJC1_32BIT_OBJ: flags 0x0 RR + +PROTOCOL: Contents of (__OBJC,__protocol) section +PROTOCOL: Protocol 0x437c +PROTOCOL: isa 0x00003120 +PROTOCOL: protocol_name 0x000025af NSObject +PROTOCOL: protocol_list 0x00000000 (not in an __OBJC section) +PROTOCOL: instance_methods 0x00004290 +PROTOCOL: count 19 +PROTOCOL: list[0] +PROTOCOL: name 0x00002de9 isEqual: +PROTOCOL: types 0x000026e7 c12@0:4@8 +PROTOCOL: list[1] +PROTOCOL: name 0x00002df2 class +PROTOCOL: types 0x00002df8 #8@0:4 +PROTOCOL: list[2] +PROTOCOL: name 0x00002dff self +PROTOCOL: types 0x00002e04 @8@0:4 +PROTOCOL: list[3] +PROTOCOL: name 0x00002e0b performSelector: +PROTOCOL: types 0x00002e1c @12@0:4:8 +PROTOCOL: list[4] +PROTOCOL: name 0x00002e26 performSelector:withObject: +PROTOCOL: types 0x00002e42 @16@0:4:8@12 +PROTOCOL: list[5] +PROTOCOL: name 0x00002e4f performSelector:withObject:withObject: +PROTOCOL: types 0x00002e76 @20@0:4:8@12@16 +PROTOCOL: list[6] +PROTOCOL: name 0x00002e86 isProxy +PROTOCOL: types 0x00002e8e c8@0:4 +PROTOCOL: list[7] +PROTOCOL: name 0x00002e95 isKindOfClass: +PROTOCOL: types 0x00002ea4 c12@0:4#8 +PROTOCOL: list[8] +PROTOCOL: name 0x00002eae isMemberOfClass: +PROTOCOL: types 0x00002ea4 c12@0:4#8 +PROTOCOL: list[9] +PROTOCOL: name 0x00002ebf conformsToProtocol: +PROTOCOL: types 0x000026e7 c12@0:4@8 +PROTOCOL: list[10] +PROTOCOL: name 0x00002ee7 respondsToSelector: +PROTOCOL: types 0x00002efb c12@0:4:8 +PROTOCOL: list[11] +PROTOCOL: name 0x00002f05 retain +PROTOCOL: types 0x00002e04 @8@0:4 +PROTOCOL: list[12] +PROTOCOL: name 0x00002f0c release +PROTOCOL: types 0x00002f14 Vv8@0:4 +PROTOCOL: list[13] +PROTOCOL: name 0x00002f1c autorelease +PROTOCOL: types 0x00002e04 @8@0:4 +PROTOCOL: list[14] +PROTOCOL: name 0x00002f28 retainCount +PROTOCOL: types 0x00002f34 I8@0:4 +PROTOCOL: list[15] +PROTOCOL: name 0x00002f3b zone +PROTOCOL: types 0x00002f40 ^{_NSZone=}8@0:4 +PROTOCOL: list[16] +PROTOCOL: name 0x00002f51 hash +PROTOCOL: types 0x00002f34 I8@0:4 +PROTOCOL: list[17] +PROTOCOL: name 0x00002f56 superclass +PROTOCOL: types 0x00002df8 #8@0:4 +PROTOCOL: list[18] +PROTOCOL: name 0x00002f61 description +PROTOCOL: types 0x00002e04 @8@0:4 +PROTOCOL: class_methods 0x00000000 (not in an __OBJC section) +PROTOCOL: Protocol 0x4390 +PROTOCOL: isa 0x000030b0 +PROTOCOL: protocol_name 0x00002dd3 NSApplicationDelegate +PROTOCOL: protocol_list 0x000043a4 +PROTOCOL: next 0x00000000 +PROTOCOL: count 1 +PROTOCOL: list[0] 0x0000437c +PROTOCOL: isa 0x00003120 +PROTOCOL: protocol_name 0x000025af NSObject +PROTOCOL: protocol_list 0x00000000 (not in an __OBJC section) +PROTOCOL: instance_methods 0x00004290 +PROTOCOL: count 19 +PROTOCOL: list[0] +PROTOCOL: name 0x00002de9 isEqual: +PROTOCOL: types 0x000026e7 c12@0:4@8 +PROTOCOL: list[1] +PROTOCOL: name 0x00002df2 class +PROTOCOL: types 0x00002df8 #8@0:4 +PROTOCOL: list[2] +PROTOCOL: name 0x00002dff self +PROTOCOL: types 0x00002e04 @8@0:4 +PROTOCOL: list[3] +PROTOCOL: name 0x00002e0b performSelector: +PROTOCOL: types 0x00002e1c @12@0:4:8 +PROTOCOL: list[4] +PROTOCOL: name 0x00002e26 performSelector:withObject: +PROTOCOL: types 0x00002e42 @16@0:4:8@12 +PROTOCOL: list[5] +PROTOCOL: name 0x00002e4f performSelector:withObject:withObject: +PROTOCOL: types 0x00002e76 @20@0:4:8@12@16 +PROTOCOL: list[6] +PROTOCOL: name 0x00002e86 isProxy +PROTOCOL: types 0x00002e8e c8@0:4 +PROTOCOL: list[7] +PROTOCOL: name 0x00002e95 isKindOfClass: +PROTOCOL: types 0x00002ea4 c12@0:4#8 +PROTOCOL: list[8] +PROTOCOL: name 0x00002eae isMemberOfClass: +PROTOCOL: types 0x00002ea4 c12@0:4#8 +PROTOCOL: list[9] +PROTOCOL: name 0x00002ebf conformsToProtocol: +PROTOCOL: types 0x000026e7 c12@0:4@8 +PROTOCOL: list[10] +PROTOCOL: name 0x00002ee7 respondsToSelector: +PROTOCOL: types 0x00002efb c12@0:4:8 +PROTOCOL: list[11] +PROTOCOL: name 0x00002f05 retain +PROTOCOL: types 0x00002e04 @8@0:4 +PROTOCOL: list[12] +PROTOCOL: name 0x00002f0c release +PROTOCOL: types 0x00002f14 Vv8@0:4 +PROTOCOL: list[13] +PROTOCOL: name 0x00002f1c autorelease +PROTOCOL: types 0x00002e04 @8@0:4 +PROTOCOL: list[14] +PROTOCOL: name 0x00002f28 retainCount +PROTOCOL: types 0x00002f34 I8@0:4 +PROTOCOL: list[15] +PROTOCOL: name 0x00002f3b zone +PROTOCOL: types 0x00002f40 ^{_NSZone=}8@0:4 +PROTOCOL: list[16] +PROTOCOL: name 0x00002f51 hash +PROTOCOL: types 0x00002f34 I8@0:4 +PROTOCOL: list[17] +PROTOCOL: name 0x00002f56 superclass +PROTOCOL: types 0x00002df8 #8@0:4 +PROTOCOL: list[18] +PROTOCOL: name 0x00002f61 description +PROTOCOL: types 0x00002e04 @8@0:4 +PROTOCOL: class_methods 0x00000000 (not in an __OBJC section) +PROTOCOL: instance_methods 0x00000000 (not in an __OBJC section) +PROTOCOL: class_methods 0x00000000 (not in an __OBJC section) diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 281ce9cc1f2..a491a376861 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -1025,6 +1025,8 @@ static void DumpRawSectionContents(MachOObjectFile *O, const char *sect, static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, StringRef DisSegName, StringRef DisSectName); +static void DumpProtocolSection(MachOObjectFile *O, const char *sect, + uint32_t size, uint32_t addr); static void DumpSectionContents(StringRef Filename, MachOObjectFile *O, bool verbose) { @@ -1087,6 +1089,10 @@ static void DumpSectionContents(StringRef Filename, MachOObjectFile *O, outs() << sect; continue; } + if (SegName == "__OBJC" && SectName == "__protocol") { + DumpProtocolSection(O, sect, sect_size, sect_addr); + continue; + } switch (section_type) { case MachO::S_REGULAR: DumpRawSectionContents(O, sect, sect_size, sect_addr); @@ -5545,6 +5551,52 @@ static bool printObjc1_32bit_MetaData(MachOObjectFile *O, bool verbose) { return true; } +static void DumpProtocolSection(MachOObjectFile *O, const char *sect, + uint32_t size, uint32_t addr) { + SymbolAddressMap AddrMap; + 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 = true; + 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 char *p; + struct objc_protocol_t protocol; + uint32_t left, paddr; + for (p = sect; p < sect + size; p += sizeof(struct objc_protocol_t)) { + memset(&protocol, '\0', sizeof(struct objc_protocol_t)); + left = size - (p - sect); + if (left < sizeof(struct objc_protocol_t)) { + outs() << "Protocol extends past end of __protocol section\n"; + memcpy(&protocol, p, left); + } else + memcpy(&protocol, p, sizeof(struct objc_protocol_t)); + if (O->isLittleEndian() != sys::IsLittleEndianHost) + swapStruct(protocol); + paddr = addr + (p - sect); + outs() << "Protocol " << format("0x%" PRIx32, paddr); + if (print_protocol(paddr, 0, &info)) + outs() << "(not in an __OBJC section)\n"; + } +} + static void printObjcMetaData(MachOObjectFile *O, bool verbose) { if (O->is64Bit()) printObjc2_64bit_MetaData(O, verbose); -- 2.34.1