Tweak the implementation of llvm-objdump’s -objc-meta-data option so
authorKevin Enderby <enderby@apple.com>
Thu, 9 Feb 2017 17:56:26 +0000 (17:56 +0000)
committerKevin Enderby <enderby@apple.com>
Thu, 9 Feb 2017 17:56:26 +0000 (17:56 +0000)
that it works when the ObjC metadata sections end up in the
__DATA_CONST or __DATA_DIRTY segments.

rdar://26315238

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@294599 91177308-0d34-0410-b5e6-96231b3b80d8

test/tools/llvm-objdump/X86/Inputs/Objc2.64bit.obj.dylib-x86_64 [new file with mode: 0755]
test/tools/llvm-objdump/X86/macho-objc-meta-data.test
tools/llvm-objdump/MachODump.cpp

diff --git a/test/tools/llvm-objdump/X86/Inputs/Objc2.64bit.obj.dylib-x86_64 b/test/tools/llvm-objdump/X86/Inputs/Objc2.64bit.obj.dylib-x86_64
new file mode 100755 (executable)
index 0000000..07d465b
Binary files /dev/null and b/test/tools/llvm-objdump/X86/Inputs/Objc2.64bit.obj.dylib-x86_64 differ
index f4abf6cdb49e74b65b650d6f8697c95adc599464..0bdb39cdff843112e3b1897d7915c5e79f94b784 100644 (file)
@@ -5,6 +5,7 @@
 # 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
+# RUN: llvm-objdump -m -objc-meta-data %p/Inputs/Objc2.64bit.obj.dylib-x86_64 | FileCheck %s -check-prefix=OBJC2_64BIT_DYLIB
 
 OBJC2_64BIT_EXE: Contents of (__DATA,__objc_classlist) section
 OBJC2_64BIT_EXE: 0000000100002028 0x1000029f0
@@ -1037,3 +1038,64 @@ 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)
+
+OBJC2_64BIT_DYLIB: Contents of (__DATA_CONST,__objc_classlist) section
+OBJC2_64BIT_DYLIB: 000000000000c038 0x8030 _OBJC_CLASS_$_Test
+OBJC2_64BIT_DYLIB:            isa 0x8008 _OBJC_METACLASS_$_Test
+OBJC2_64BIT_DYLIB:     superclass 0x0
+OBJC2_64BIT_DYLIB:          cache 0x0
+OBJC2_64BIT_DYLIB:         vtable 0x0
+OBJC2_64BIT_DYLIB:           data 0xc120 (struct class_ro_t *)
+OBJC2_64BIT_DYLIB:                     flags 0x0
+OBJC2_64BIT_DYLIB:             instanceStart 8
+OBJC2_64BIT_DYLIB:              instanceSize 16
+OBJC2_64BIT_DYLIB:                  reserved 0x0
+OBJC2_64BIT_DYLIB:                ivarLayout 0x0
+OBJC2_64BIT_DYLIB:                      name 0x4f59 Test
+OBJC2_64BIT_DYLIB:               baseMethods 0xc090 (struct method_list_t *)
+OBJC2_64BIT_DYLIB:                entsize 24
+OBJC2_64BIT_DYLIB:                  count 3
+OBJC2_64BIT_DYLIB:                   name 0x4f5e testMethod
+OBJC2_64BIT_DYLIB:                  types 0x4f89 v16@0:8
+OBJC2_64BIT_DYLIB:                    imp -[Test testMethod]
+OBJC2_64BIT_DYLIB:                   name 0x4f69 testProp
+OBJC2_64BIT_DYLIB:                  types 0x4f91 Q16@0:8
+OBJC2_64BIT_DYLIB:                    imp -[Test testProp]
+OBJC2_64BIT_DYLIB:                   name 0x4f72 setTestProp:
+OBJC2_64BIT_DYLIB:                  types 0x4f99 v24@0:8Q16
+OBJC2_64BIT_DYLIB:                    imp -[Test setTestProp:]
+OBJC2_64BIT_DYLIB:             baseProtocols 0x0
+OBJC2_64BIT_DYLIB:                     ivars 0xc0e0
+OBJC2_64BIT_DYLIB:                     entsize 32
+OBJC2_64BIT_DYLIB:                       count 1
+OBJC2_64BIT_DYLIB:                        offset 0x8000 8
+OBJC2_64BIT_DYLIB:                          name 0x4f7f _testProp
+OBJC2_64BIT_DYLIB:                          type 0x4fa4 Q
+OBJC2_64BIT_DYLIB:                     alignment 3
+OBJC2_64BIT_DYLIB:                          size 8
+OBJC2_64BIT_DYLIB:            weakIvarLayout 0x0
+OBJC2_64BIT_DYLIB:            baseProperties 0xc108
+OBJC2_64BIT_DYLIB:                     entsize 16
+OBJC2_64BIT_DYLIB:                       count 1
+OBJC2_64BIT_DYLIB:                          name 0x4f42 testProp
+OBJC2_64BIT_DYLIB:                     attributes 0x4f4b TQ,V_testProp
+OBJC2_64BIT_DYLIB: Meta Class
+OBJC2_64BIT_DYLIB:            isa 0x0
+OBJC2_64BIT_DYLIB:     superclass 0x0
+OBJC2_64BIT_DYLIB:          cache 0x0
+OBJC2_64BIT_DYLIB:         vtable 0x0
+OBJC2_64BIT_DYLIB:           data 0xc048 (struct class_ro_t *)
+OBJC2_64BIT_DYLIB:                     flags 0x1 RO_META
+OBJC2_64BIT_DYLIB:             instanceStart 40
+OBJC2_64BIT_DYLIB:              instanceSize 40
+OBJC2_64BIT_DYLIB:                  reserved 0x0
+OBJC2_64BIT_DYLIB:                ivarLayout 0x0
+OBJC2_64BIT_DYLIB:                      name 0x4f59 Test
+OBJC2_64BIT_DYLIB:               baseMethods 0x0 (struct method_list_t *)
+OBJC2_64BIT_DYLIB:             baseProtocols 0x0
+OBJC2_64BIT_DYLIB:                     ivars 0x0
+OBJC2_64BIT_DYLIB:            weakIvarLayout 0x0
+OBJC2_64BIT_DYLIB:            baseProperties 0x0
+OBJC2_64BIT_DYLIB: Contents of (__DATA_CONST,__objc_imageinfo) section
+OBJC2_64BIT_DYLIB:   version 0
+OBJC2_64BIT_DYLIB:     flags 0x40
index 928e4ed8511796133d2cd87c3cd1b7659aa64c5e..4742582342451d66345bd9da2d903c81b8091a0e 100644 (file)
@@ -5271,42 +5271,70 @@ static void printObjc2_64bit_MetaData(MachOObjectFile *O, bool verbose) {
   SectionRef CL = get_section(O, "__OBJC2", "__class_list");
   if (CL == SectionRef())
     CL = get_section(O, "__DATA", "__objc_classlist");
+  if (CL == SectionRef())
+    CL = get_section(O, "__DATA_CONST", "__objc_classlist");
+  if (CL == SectionRef())
+    CL = get_section(O, "__DATA_DIRTY", "__objc_classlist");
   info.S = CL;
   walk_pointer_list_64("class", CL, O, &info, print_class64_t);
 
   SectionRef CR = get_section(O, "__OBJC2", "__class_refs");
   if (CR == SectionRef())
     CR = get_section(O, "__DATA", "__objc_classrefs");
+  if (CR == SectionRef())
+    CR = get_section(O, "__DATA_CONST", "__objc_classrefs");
+  if (CR == SectionRef())
+    CR = get_section(O, "__DATA_DIRTY", "__objc_classrefs");
   info.S = CR;
   walk_pointer_list_64("class refs", CR, O, &info, nullptr);
 
   SectionRef SR = get_section(O, "__OBJC2", "__super_refs");
   if (SR == SectionRef())
     SR = get_section(O, "__DATA", "__objc_superrefs");
+  if (SR == SectionRef())
+    SR = get_section(O, "__DATA_CONST", "__objc_superrefs");
+  if (SR == SectionRef())
+    SR = get_section(O, "__DATA_DIRTY", "__objc_superrefs");
   info.S = SR;
   walk_pointer_list_64("super refs", SR, O, &info, nullptr);
 
   SectionRef CA = get_section(O, "__OBJC2", "__category_list");
   if (CA == SectionRef())
     CA = get_section(O, "__DATA", "__objc_catlist");
+  if (CA == SectionRef())
+    CA = get_section(O, "__DATA_CONST", "__objc_catlist");
+  if (CA == SectionRef())
+    CA = get_section(O, "__DATA_DIRTY", "__objc_catlist");
   info.S = CA;
   walk_pointer_list_64("category", CA, O, &info, print_category64_t);
 
   SectionRef PL = get_section(O, "__OBJC2", "__protocol_list");
   if (PL == SectionRef())
     PL = get_section(O, "__DATA", "__objc_protolist");
+  if (PL == SectionRef())
+    PL = get_section(O, "__DATA_CONST", "__objc_protolist");
+  if (PL == SectionRef())
+    PL = get_section(O, "__DATA_DIRTY", "__objc_protolist");
   info.S = PL;
   walk_pointer_list_64("protocol", PL, O, &info, nullptr);
 
   SectionRef MR = get_section(O, "__OBJC2", "__message_refs");
   if (MR == SectionRef())
     MR = get_section(O, "__DATA", "__objc_msgrefs");
+  if (MR == SectionRef())
+    MR = get_section(O, "__DATA_CONST", "__objc_msgrefs");
+  if (MR == SectionRef())
+    MR = get_section(O, "__DATA_DIRTY", "__objc_msgrefs");
   info.S = MR;
   print_message_refs64(MR, &info);
 
   SectionRef II = get_section(O, "__OBJC2", "__image_info");
   if (II == SectionRef())
     II = get_section(O, "__DATA", "__objc_imageinfo");
+  if (II == SectionRef())
+    II = get_section(O, "__DATA_CONST", "__objc_imageinfo");
+  if (II == SectionRef())
+    II = get_section(O, "__DATA_DIRTY", "__objc_imageinfo");
   info.S = II;
   print_image_info64(II, &info);
 }
@@ -5337,75 +5365,75 @@ static void printObjc2_32bit_MetaData(MachOObjectFile *O, bool verbose) {
   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);
-  }
+  SectionRef CL = get_section(O, "__OBJC2", "__class_list");
+  if (CL == SectionRef())
+    CL = get_section(O, "__DATA", "__objc_classlist");
+  if (CL == SectionRef())
+    CL = get_section(O, "__DATA_CONST", "__objc_classlist");
+  if (CL == SectionRef())
+    CL = get_section(O, "__DATA_DIRTY", "__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);
-  }
+  SectionRef CR = get_section(O, "__OBJC2", "__class_refs");
+  if (CR == SectionRef())
+    CR = get_section(O, "__DATA", "__objc_classrefs");
+  if (CR == SectionRef())
+    CR = get_section(O, "__DATA_CONST", "__objc_classrefs");
+  if (CR == SectionRef())
+    CR = get_section(O, "__DATA_DIRTY", "__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);
-  }
+  SectionRef SR = get_section(O, "__OBJC2", "__super_refs");
+  if (SR == SectionRef())
+    SR = get_section(O, "__DATA", "__objc_superrefs");
+  if (SR == SectionRef())
+    SR = get_section(O, "__DATA_CONST", "__objc_superrefs");
+  if (SR == SectionRef())
+    SR = get_section(O, "__DATA_DIRTY", "__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);
-  }
+  SectionRef CA = get_section(O, "__OBJC2", "__category_list");
+  if (CA == SectionRef())
+    CA = get_section(O, "__DATA", "__objc_catlist");
+  if (CA == SectionRef())
+    CA = get_section(O, "__DATA_CONST", "__objc_catlist");
+  if (CA == SectionRef())
+    CA = get_section(O, "__DATA_DIRTY", "__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);
-  }
+  SectionRef PL = get_section(O, "__OBJC2", "__protocol_list");
+  if (PL == SectionRef())
+    PL = get_section(O, "__DATA", "__objc_protolist");
+  if (PL == SectionRef())
+    PL = get_section(O, "__DATA_CONST", "__objc_protolist");
+  if (PL == SectionRef())
+    PL = get_section(O, "__DATA_DIRTY", "__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);
-  }
+  SectionRef MR = get_section(O, "__OBJC2", "__message_refs");
+  if (MR == SectionRef())
+    MR = get_section(O, "__DATA", "__objc_msgrefs");
+  if (MR == SectionRef())
+    MR = get_section(O, "__DATA_CONST", "__objc_msgrefs");
+  if (MR == SectionRef())
+    MR = get_section(O, "__DATA_DIRTY", "__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);
-  }
+  SectionRef II = get_section(O, "__OBJC2", "__image_info");
+  if (II == SectionRef())
+    II = get_section(O, "__DATA", "__objc_imageinfo");
+  if (II == SectionRef())
+    II = get_section(O, "__DATA_CONST", "__objc_imageinfo");
+  if (II == SectionRef())
+    II = get_section(O, "__DATA_DIRTY", "__objc_imageinfo");
+  info.S = II;
+  print_image_info32(II, &info);
 }
 
 static bool printObjc1_32bit_MetaData(MachOObjectFile *O, bool verbose) {