[llvm] r229548 - Add code to llvm-objdump so the -section option with -macho will dump literal pointer sections

Kevin Enderby enderby at apple.com
Tue Feb 17 13:35:48 PST 2015


Author: enderby
Date: Tue Feb 17 15:35:48 2015
New Revision: 229548

URL: http://llvm.org/viewvc/llvm-project?rev=229548&view=rev
Log:
Add code to llvm-objdump so the -section option with -macho will dump literal pointer sections
with the Mach-O S_LITERAL_POINTERS section type.

Also fix the printing of the leading addresses for literal sections to be consistent and
not print the 0x prefix.  Updated test cases to match.

Added:
    llvm/trunk/test/tools/llvm-objdump/X86/macho-literal-pointers-i386.test
    llvm/trunk/test/tools/llvm-objdump/X86/macho-literal-pointers-x86_64.test
Modified:
    llvm/trunk/test/tools/llvm-objdump/X86/macho-cstring-dump.test
    llvm/trunk/test/tools/llvm-objdump/X86/macho-literals.test
    llvm/trunk/tools/llvm-objdump/MachODump.cpp

Modified: llvm/trunk/test/tools/llvm-objdump/X86/macho-cstring-dump.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/X86/macho-cstring-dump.test?rev=229548&r1=229547&r2=229548&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/X86/macho-cstring-dump.test (original)
+++ llvm/trunk/test/tools/llvm-objdump/X86/macho-cstring-dump.test Tue Feb 17 15:35:48 2015
@@ -1,4 +1,4 @@
 RUN: llvm-objdump -m -section __TEXT,__cstring %p/Inputs/hello.obj.macho-x86_64 | FileCheck %s
 
 CHECK: Contents of (__TEXT,__cstring) section
-CHECK: 0x000000000000003b  Hello world\n
+CHECK: 000000000000003b  Hello world\n

Added: llvm/trunk/test/tools/llvm-objdump/X86/macho-literal-pointers-i386.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/X86/macho-literal-pointers-i386.test?rev=229548&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/X86/macho-literal-pointers-i386.test (added)
+++ llvm/trunk/test/tools/llvm-objdump/X86/macho-literal-pointers-i386.test Tue Feb 17 15:35:48 2015
@@ -0,0 +1,34 @@
+# RUN: llvm-mc < %s -triple i386-apple-darwin -filetype=obj | llvm-objdump -m -section __DATA,__litp - | FileCheck %s
+
+.cstring
+L1: .asciz "Hello world\n"
+
+.literal4
+.align 2
+L2: .float 4.0
+
+.literal8
+.align 3
+L3: .double 8.0
+
+.literal16
+.align 4
+L4: .long 0x10000016, 0x20000016, 0x30000016, 0x40000016
+
+.const
+L5: .asciz "const non-literal string"
+
+.section __DATA,__litp, literal_pointers
+.align 2
+.long L1
+.long L2
+.long L3
+.long L4
+.long L5
+
+# CHECK: Contents of (__DATA,__litp) section
+# CHECK: 0000004c  __TEXT:__cstring:Hello world\n
+# CHECK: 00000050  __TEXT:__literal4:0x40800000
+# CHECK: 00000054  __TEXT:__literal8:0x00000000 0x40200000
+# CHECK: 00000058  __TEXT:__literal16:0x10000016 0x20000016 0x30000016 0x40000016
+# CHECK: 0000005c  0x30 (not in a literal section)

Added: llvm/trunk/test/tools/llvm-objdump/X86/macho-literal-pointers-x86_64.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/X86/macho-literal-pointers-x86_64.test?rev=229548&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/X86/macho-literal-pointers-x86_64.test (added)
+++ llvm/trunk/test/tools/llvm-objdump/X86/macho-literal-pointers-x86_64.test Tue Feb 17 15:35:48 2015
@@ -0,0 +1,34 @@
+# RUN: llvm-mc < %s -triple x86_64-apple-darwin -filetype=obj | llvm-objdump -m -section __DATA,__litp - | FileCheck %s
+
+.cstring
+L1: .asciz "Hello world\n"
+
+.literal4
+.align 2
+L2: .float 4.0
+
+.literal8
+.align 3
+L3: .double 8.0
+
+.literal16
+.align 4
+L4: .long 0x10000016, 0x20000016, 0x30000016, 0x40000016
+
+.const
+L5: .asciz "const non-literal string"
+
+.section __DATA,__litp, literal_pointers
+.align 3
+.quad L1
+.quad L2
+.quad L3
+.quad L4
+.quad L5
+
+# CHECK: Contents of (__DATA,__litp) section
+# CHECK: 0000000000000050  __TEXT:__cstring:Hello world\n
+# CHECK: 0000000000000058  __TEXT:__literal4:0x40800000
+# CHECK: 0000000000000060  __TEXT:__literal8:0x00000000 0x40200000
+# CHECK: 0000000000000068  __TEXT:__literal16:0x10000016 0x20000016 0x30000016 0x40000016
+# CHECK: 0000000000000070  0x30 (not in a literal section)

Modified: llvm/trunk/test/tools/llvm-objdump/X86/macho-literals.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/X86/macho-literals.test?rev=229548&r1=229547&r2=229548&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/X86/macho-literals.test (original)
+++ llvm/trunk/test/tools/llvm-objdump/X86/macho-literals.test Tue Feb 17 15:35:48 2015
@@ -11,12 +11,12 @@
 .long 0x7f800001
 
 # CHECK-LIT4: Contents of (__TEXT,__literal4) section
-# CHECK-LIT4: 0x0000000000000000  0x40200000
-# CHECK-LIT4: 0x0000000000000004  0x41040000
-# CHECK-LIT4: 0x0000000000000008  0x7f800000
-# CHECK-LIT4: 0x000000000000000c  0xff800000
-# CHECK-LIT4: 0x0000000000000010  0x7fc00000
-# CHECK-LIT4: 0x0000000000000014  0x7f800001
+# CHECK-LIT4: 0000000000000000  0x40200000
+# CHECK-LIT4: 0000000000000004  0x41040000
+# CHECK-LIT4: 0000000000000008  0x7f800000
+# CHECK-LIT4: 000000000000000c  0xff800000
+# CHECK-LIT4: 0000000000000010  0x7fc00000
+# CHECK-LIT4: 0000000000000014  0x7f800001
 
 .literal8
 .double 2.5
@@ -31,12 +31,12 @@
 .long 0x7ff00000
 
 # CHECK-LIT8: Contents of (__TEXT,__literal8) section
-# CHECK-LIT8: 0x0000000000000018  0x00000000 0x40040000
-# CHECK-LIT8: 0x0000000000000020  0x00000000 0x40208000
-# CHECK-LIT8: 0x0000000000000028  0x00000000 0x7ff00000
-# CHECK-LIT8: 0x0000000000000030  0x00000000 0xfff00000
-# CHECK-LIT8: 0x0000000000000038  0x00000000 0x7ff80000
-# CHECK-LIT8: 0x0000000000000040  0x00000001 0x7ff00000
+# CHECK-LIT8: 0000000000000018  0x00000000 0x40040000
+# CHECK-LIT8: 0000000000000020  0x00000000 0x40208000
+# CHECK-LIT8: 0000000000000028  0x00000000 0x7ff00000
+# CHECK-LIT8: 0000000000000030  0x00000000 0xfff00000
+# CHECK-LIT8: 0000000000000038  0x00000000 0x7ff80000
+# CHECK-LIT8: 0000000000000040  0x00000001 0x7ff00000
 
 .literal16
 .long 1
@@ -45,4 +45,4 @@
 .long 4
 
 # CHECK-LIT16: Contents of (__TEXT,__literal16) section
-# CHECK-LIT16: 0x0000000000000050  0x00000001 0x00000002 0x00000003 0x00000004
+# CHECK-LIT16: 0000000000000050  0x00000001 0x00000002 0x00000003 0x00000004

Modified: llvm/trunk/tools/llvm-objdump/MachODump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MachODump.cpp?rev=229548&r1=229547&r2=229548&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/MachODump.cpp (original)
+++ llvm/trunk/tools/llvm-objdump/MachODump.cpp Tue Feb 17 15:35:48 2015
@@ -537,22 +537,25 @@ static const char *GuessSymbolName(uint6
   return SymbolName;
 }
 
+static void DumpCstringChar(const char c) {
+  char p[2];
+  p[0] = c;
+  p[1] = '\0';
+  outs().write_escaped(p);
+}
+
 static void DumpCstringSection(MachOObjectFile *O, const char *sect,
                                uint32_t sect_size, uint64_t sect_addr,
                                bool print_addresses) {
   for (uint32_t i = 0; i < sect_size; i++) {
     if (print_addresses) {
       if (O->is64Bit())
-        outs() << format("0x%016" PRIx64, sect_addr + i) << "  ";
+        outs() << format("%016" PRIx64, sect_addr + i) << "  ";
       else
-        outs() << format("0x%08" PRIx64, sect_addr + i) << "  ";
-    }
-    for (; i < sect_size && sect[i] != '\0'; i++) {
-      char p[2];
-      p[0] = sect[i];
-      p[1] = '\0';
-      outs().write_escaped(p);
+        outs() << format("%08" PRIx64, sect_addr + i) << "  ";
     }
+    for (; i < sect_size && sect[i] != '\0'; i++)
+      DumpCstringChar(sect[i]);
     if (i < sect_size && sect[i] == '\0')
       outs() << "\n";
   }
@@ -580,9 +583,9 @@ static void DumpLiteral4Section(MachOObj
   for (uint32_t i = 0; i < sect_size; i += sizeof(float)) {
     if (print_addresses) {
       if (O->is64Bit())
-        outs() << format("0x%016" PRIx64, sect_addr + i) << "  ";
+        outs() << format("%016" PRIx64, sect_addr + i) << "  ";
       else
-        outs() << format("0x%08" PRIx64, sect_addr + i) << "  ";
+        outs() << format("%08" PRIx64, sect_addr + i) << "  ";
     }
     float f;
     memcpy(&f, sect + i, sizeof(float));
@@ -628,9 +631,9 @@ static void DumpLiteral8Section(MachOObj
   for (uint32_t i = 0; i < sect_size; i += sizeof(double)) {
     if (print_addresses) {
       if (O->is64Bit())
-        outs() << format("0x%016" PRIx64, sect_addr + i) << "  ";
+        outs() << format("%016" PRIx64, sect_addr + i) << "  ";
       else
-        outs() << format("0x%08" PRIx64, sect_addr + i) << "  ";
+        outs() << format("%08" PRIx64, sect_addr + i) << "  ";
     }
     double d;
     memcpy(&d, sect + i, sizeof(double));
@@ -647,15 +650,22 @@ static void DumpLiteral8Section(MachOObj
   }
 }
 
+static void DumpLiteral16(uint32_t l0, uint32_t l1, uint32_t l2, uint32_t l3) {
+  outs() << format("0x%08" PRIx32, l0) << " ";
+  outs() << format("0x%08" PRIx32, l1) << " ";
+  outs() << format("0x%08" PRIx32, l2) << " ";
+  outs() << format("0x%08" PRIx32, l3) << "\n";
+}
+
 static void DumpLiteral16Section(MachOObjectFile *O, const char *sect,
                                  uint32_t sect_size, uint64_t sect_addr,
                                  bool print_addresses) {
   for (uint32_t i = 0; i < sect_size; i += 16) {
     if (print_addresses) {
       if (O->is64Bit())
-        outs() << format("0x%016" PRIx64, sect_addr + i) << "  ";
+        outs() << format("%016" PRIx64, sect_addr + i) << "  ";
       else
-        outs() << format("0x%08" PRIx64, sect_addr + i) << "  ";
+        outs() << format("%08" PRIx64, sect_addr + i) << "  ";
     }
     uint32_t l0, l1, l2, l3;
     memcpy(&l0, sect + i, sizeof(uint32_t));
@@ -668,10 +678,174 @@ static void DumpLiteral16Section(MachOOb
       sys::swapByteOrder(l2);
       sys::swapByteOrder(l3);
     }
-    outs() << format("0x%08" PRIx32, l0) << " ";
-    outs() << format("0x%08" PRIx32, l1) << " ";
-    outs() << format("0x%08" PRIx32, l2) << " ";
-    outs() << format("0x%08" PRIx32, l3) << "\n";
+    DumpLiteral16(l0, l1, l2, l3);
+  }
+}
+
+static void DumpLiteralPointerSection(MachOObjectFile *O,
+                                      const SectionRef &Section,
+                                      const char *sect, uint32_t sect_size,
+                                      uint64_t sect_addr,
+                                      bool print_addresses) {
+  // Collect the literal sections in this Mach-O file.
+  std::vector<SectionRef> LiteralSections;
+  for (const SectionRef &Section : O->sections()) {
+    DataRefImpl Ref = Section.getRawDataRefImpl();
+    uint32_t section_type;
+    if (O->is64Bit()) {
+      const MachO::section_64 Sec = O->getSection64(Ref);
+      section_type = Sec.flags & MachO::SECTION_TYPE;
+    } else {
+      const MachO::section Sec = O->getSection(Ref);
+      section_type = Sec.flags & MachO::SECTION_TYPE;
+    }
+    if (section_type == MachO::S_CSTRING_LITERALS ||
+        section_type == MachO::S_4BYTE_LITERALS ||
+        section_type == MachO::S_8BYTE_LITERALS ||
+        section_type == MachO::S_16BYTE_LITERALS)
+      LiteralSections.push_back(Section);
+  }
+
+  // Set the size of the literal pointer.
+  uint32_t lp_size = O->is64Bit() ? 8 : 4;
+
+  // Collect the external relocation symbols for the the literal pointers.
+  std::vector<std::pair<uint64_t, SymbolRef>> Relocs;
+  for (const RelocationRef &Reloc : Section.relocations()) {
+    DataRefImpl Rel;
+    MachO::any_relocation_info RE;
+    bool isExtern = false;
+    Rel = Reloc.getRawDataRefImpl();
+    RE = O->getRelocation(Rel);
+    isExtern = O->getPlainRelocationExternal(RE);
+    if (isExtern) {
+      uint64_t RelocOffset;
+      Reloc.getOffset(RelocOffset);
+      symbol_iterator RelocSym = Reloc.getSymbol();
+      Relocs.push_back(std::make_pair(RelocOffset, *RelocSym));
+    }
+  }
+  array_pod_sort(Relocs.begin(), Relocs.end());
+
+  // Dump each literal pointer.
+  for (uint32_t i = 0; i < sect_size; i += lp_size) {
+    if (print_addresses) {
+      if (O->is64Bit())
+        outs() << format("%016" PRIx64, sect_addr + i) << "  ";
+      else
+        outs() << format("%08" PRIx64, sect_addr + i) << "  ";
+    }
+    uint64_t lp;
+    if (O->is64Bit()) {
+      memcpy(&lp, sect + i, sizeof(uint64_t));
+      if (O->isLittleEndian() != sys::IsLittleEndianHost)
+        sys::swapByteOrder(lp);
+    } else {
+      uint32_t li;
+      memcpy(&li, sect + i, sizeof(uint32_t));
+      if (O->isLittleEndian() != sys::IsLittleEndianHost)
+        sys::swapByteOrder(li);
+      lp = li;
+    }
+
+    // First look for an external relocation entry for this literal pointer.
+    bool reloc_found = false;
+    for (unsigned j = 0, e = Relocs.size(); j != e; ++j) {
+      if (Relocs[i].first == i) {
+        symbol_iterator RelocSym = Relocs[j].second;
+        StringRef SymName;
+        RelocSym->getName(SymName);
+        outs() << "external relocation entry for symbol:" << SymName << "\n";
+        reloc_found = true;
+      }
+    }
+    if (reloc_found == true)
+      continue;
+
+    // For local references see what the section the literal pointer points to.
+    bool found = false;
+    for (unsigned SectIdx = 0; SectIdx != LiteralSections.size(); SectIdx++) {
+      uint64_t SectAddress = LiteralSections[SectIdx].getAddress();
+      uint64_t SectSize = LiteralSections[SectIdx].getSize();
+      if (lp >= SectAddress && lp < SectAddress + SectSize) {
+        found = true;
+
+        StringRef SectName;
+        LiteralSections[SectIdx].getName(SectName);
+        DataRefImpl Ref = LiteralSections[SectIdx].getRawDataRefImpl();
+        StringRef SegmentName = O->getSectionFinalSegmentName(Ref);
+        outs() << SegmentName << ":" << SectName << ":";
+
+        uint32_t section_type;
+        if (O->is64Bit()) {
+          const MachO::section_64 Sec = O->getSection64(Ref);
+          section_type = Sec.flags & MachO::SECTION_TYPE;
+        } else {
+          const MachO::section Sec = O->getSection(Ref);
+          section_type = Sec.flags & MachO::SECTION_TYPE;
+        }
+
+        StringRef BytesStr;
+        LiteralSections[SectIdx].getContents(BytesStr);
+        const char *Contents = reinterpret_cast<const char *>(BytesStr.data());
+
+        switch (section_type) {
+        case MachO::S_CSTRING_LITERALS:
+          for (uint64_t i = lp - SectAddress;
+               i < SectSize && Contents[i] != '\0'; i++) {
+            DumpCstringChar(Contents[i]);
+          }
+          outs() << "\n";
+          break;
+        case MachO::S_4BYTE_LITERALS:
+          float f;
+          memcpy(&f, Contents + (lp - SectAddress), sizeof(float));
+          uint32_t l;
+          memcpy(&l, Contents + (lp - SectAddress), sizeof(uint32_t));
+          if (O->isLittleEndian() != sys::IsLittleEndianHost) {
+            sys::swapByteOrder(f);
+            sys::swapByteOrder(l);
+          }
+          DumpLiteral4(l, f);
+          break;
+        case MachO::S_8BYTE_LITERALS: {
+          double d;
+          memcpy(&d, Contents + (lp - SectAddress), sizeof(double));
+          uint32_t l0, l1;
+          memcpy(&l0, Contents + (lp - SectAddress), sizeof(uint32_t));
+          memcpy(&l1, Contents + (lp - SectAddress) + sizeof(uint32_t),
+                 sizeof(uint32_t));
+          if (O->isLittleEndian() != sys::IsLittleEndianHost) {
+            sys::swapByteOrder(f);
+            sys::swapByteOrder(l0);
+            sys::swapByteOrder(l1);
+          }
+          DumpLiteral8(O, l0, l1, d);
+          break;
+        }
+        case MachO::S_16BYTE_LITERALS: {
+          uint32_t l0, l1, l2, l3;
+          memcpy(&l0, Contents + (lp - SectAddress), sizeof(uint32_t));
+          memcpy(&l1, Contents + (lp - SectAddress) + sizeof(uint32_t),
+                 sizeof(uint32_t));
+          memcpy(&l2, Contents + (lp - SectAddress) + 2 * sizeof(uint32_t),
+                 sizeof(uint32_t));
+          memcpy(&l3, Contents + (lp - SectAddress) + 3 * sizeof(uint32_t),
+                 sizeof(uint32_t));
+          if (O->isLittleEndian() != sys::IsLittleEndianHost) {
+            sys::swapByteOrder(l0);
+            sys::swapByteOrder(l1);
+            sys::swapByteOrder(l2);
+            sys::swapByteOrder(l3);
+          }
+          DumpLiteral16(l0, l1, l2, l3);
+          break;
+        }
+        }
+      }
+    }
+    if (found == false)
+      outs() << format("0x%" PRIx64, lp) << " (not in a literal section)\n";
   }
 }
 
@@ -826,6 +1000,10 @@ static void DumpSectionContents(StringRe
           case MachO::S_16BYTE_LITERALS:
             DumpLiteral16Section(O, sect, sect_size, sect_addr, verbose);
             break;
+          case MachO::S_LITERAL_POINTERS:
+            DumpLiteralPointerSection(O, Section, sect, sect_size, sect_addr,
+                                      verbose);
+            break;
           case MachO::S_MOD_INIT_FUNC_POINTERS:
           case MachO::S_MOD_TERM_FUNC_POINTERS:
             DumpInitTermPointerSection(O, sect, sect_size, sect_addr, &AddrMap,





More information about the llvm-commits mailing list