llvm-objdump: handle stubbed and malformed dylibs better
authorTim Northover <tnorthover@apple.com>
Thu, 14 Jul 2016 22:13:32 +0000 (22:13 +0000)
committerTim Northover <tnorthover@apple.com>
Thu, 14 Jul 2016 22:13:32 +0000 (22:13 +0000)
We were quite happy to read past the end of the valid section data when
disassembling. Instead we entirely skip stub dylibs, and tell the user what's
happened if their section only has partial data.

llvm-svn: 275487

llvm/test/tools/llvm-objdump/X86/Inputs/stubbed.dylib.macho-x86_64 [new file with mode: 0755]
llvm/test/tools/llvm-objdump/X86/Inputs/truncated-section.dylib.macho-x86_64 [new file with mode: 0755]
llvm/test/tools/llvm-objdump/X86/stubbed-dylib.test [new file with mode: 0644]
llvm/test/tools/llvm-objdump/X86/truncated-section.test [new file with mode: 0644]
llvm/tools/llvm-objdump/MachODump.cpp

diff --git a/llvm/test/tools/llvm-objdump/X86/Inputs/stubbed.dylib.macho-x86_64 b/llvm/test/tools/llvm-objdump/X86/Inputs/stubbed.dylib.macho-x86_64
new file mode 100755 (executable)
index 0000000..144738b
Binary files /dev/null and b/llvm/test/tools/llvm-objdump/X86/Inputs/stubbed.dylib.macho-x86_64 differ
diff --git a/llvm/test/tools/llvm-objdump/X86/Inputs/truncated-section.dylib.macho-x86_64 b/llvm/test/tools/llvm-objdump/X86/Inputs/truncated-section.dylib.macho-x86_64
new file mode 100755 (executable)
index 0000000..a099ee2
Binary files /dev/null and b/llvm/test/tools/llvm-objdump/X86/Inputs/truncated-section.dylib.macho-x86_64 differ
diff --git a/llvm/test/tools/llvm-objdump/X86/stubbed-dylib.test b/llvm/test/tools/llvm-objdump/X86/stubbed-dylib.test
new file mode 100644 (file)
index 0000000..6f7f722
--- /dev/null
@@ -0,0 +1,5 @@
+RUN: llvm-objdump -macho -d %p/Inputs/stubbed.dylib.macho-x86_64 | FileCheck %s
+
+CHECK: (__TEXT,__text) section
+CHECK-NOT: func
+CHECK-NOT: func2
diff --git a/llvm/test/tools/llvm-objdump/X86/truncated-section.test b/llvm/test/tools/llvm-objdump/X86/truncated-section.test
new file mode 100644 (file)
index 0000000..e9fe75d
--- /dev/null
@@ -0,0 +1,7 @@
+RUN: llvm-objdump -macho -d %p/Inputs/truncated-section.dylib.macho-x86_64 | FileCheck %s
+
+CHECK: _func:
+CHECK:     retq
+CHECK:     retq
+
+CHECK: section data ends, _func2 lies outside valid range
index 08bc1f4..991ccee 100644 (file)
@@ -6662,6 +6662,10 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF,
 
     unsigned int Arch = MachOOF->getArch();
 
+    // Skip all symbols if this is a stubs file.
+    if (Bytes.size() == 0)
+      return;
+
     // Disassemble symbol by symbol.
     for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) {
       Expected<StringRef> SymNameOrErr = Symbols[SymIdx].getName();
@@ -6716,10 +6720,17 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF,
         continue;
 
       // Start at the address of the symbol relative to the section's address.
+      uint64_t SectSize = Sections[SectIdx].getSize();
       uint64_t Start = Symbols[SymIdx].getValue();
       uint64_t SectionAddress = Sections[SectIdx].getAddress();
       Start -= SectionAddress;
 
+      if (Start > SectSize) {
+        outs() << "section data ends, " << SymName
+               << " lies outside valid range\n";
+        return;
+      }
+
       // Stop disassembling either at the beginning of the next symbol or at
       // the end of the section.
       bool containsNextSym = false;
@@ -6745,8 +6756,7 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF,
         ++NextSymIdx;
       }
 
-      uint64_t SectSize = Sections[SectIdx].getSize();
-      uint64_t End = containsNextSym ? NextSym : SectSize;
+      uint64_t End = containsNextSym ? std::min(NextSym, SectSize) : SectSize;
       uint64_t Size;
 
       symbolTableWorked = true;