For llvm-objdump, dump the (__OBJC,__protocol) section for Objc1 32-bit Mach-O files
authorKevin Enderby <enderby@apple.com>
Thu, 16 Apr 2015 22:33:20 +0000 (22:33 +0000)
committerKevin Enderby <enderby@apple.com>
Thu, 16 Apr 2015 22:33:20 +0000 (22:33 +0000)
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

test/tools/llvm-objdump/X86/macho-objc-meta-data.test
tools/llvm-objdump/MachODump.cpp

index 1ff42df7e1a33de98551ed991ed740895dd5091e..f4abf6cdb49e74b65b650d6f8697c95adc599464 100644 (file)
@@ -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)
index 281ce9cc1f2b8f21563b0ca1edff81c73cac7cd5..a491a3768617066ff22d63fd4f37c295a7b490e4 100644 (file)
@@ -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<SectionRef> 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);