[PATCH] D29632: Use ELF dynamic symbols for disassembly

Sam Parker via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 7 04:54:51 PST 2017


samparker created this revision.

Disassembly currently begins from addresses obtained from the objects symbol table. For ELF, also add the dynamic symbols to the list so that we can more successfully disassemble stripped binaries.


https://reviews.llvm.org/D29632

Files:
  test/tools/llvm-objdump/Inputs/stripped-elf.so
  test/tools/llvm-objdump/stripped-shared.test
  tools/llvm-objdump/llvm-objdump.cpp


Index: tools/llvm-objdump/llvm-objdump.cpp
===================================================================
--- tools/llvm-objdump/llvm-objdump.cpp
+++ tools/llvm-objdump/llvm-objdump.cpp
@@ -213,6 +213,8 @@
                 cl::value_desc("address"), cl::init(UINT64_MAX));
 static StringRef ToolName;
 
+typedef std::vector<std::tuple<uint64_t, StringRef, uint8_t>> SectionSymbolsTy;
+
 namespace {
 typedef std::function<bool(llvm::object::SectionRef const &)> FilterPredicate;
 
@@ -1108,6 +1110,51 @@
   llvm_unreachable("Unsupported binary format");
 }
 
+template <class ELFT> static void
+addDynamicElfSymbols(const ELFObjectFile<ELFT> *Obj,
+                     std::map<SectionRef, SectionSymbolsTy> &AllSymbols) {
+  for (auto Symbol : Obj->getDynamicSymbolIterators()) {
+    uint8_t SymbolType = Symbol.getELFType();
+    if (SymbolType == ELF::STT_FUNC && Symbol.getSize () != 0) {
+      Expected<uint64_t> AddressOrErr = Symbol.getAddress();
+      if (!AddressOrErr)
+        report_error(Obj->getFileName(), AddressOrErr.takeError());
+      uint64_t Address = *AddressOrErr;
+
+      Expected<StringRef> Name = Symbol.getName();
+      if (!Name)
+        report_error(Obj->getFileName(), Name.takeError());
+      if (Name->empty())
+        continue;
+
+      Expected<section_iterator> SectionOrErr = Symbol.getSection();
+      if (!SectionOrErr)
+        report_error(Obj->getFileName(), SectionOrErr.takeError());
+      section_iterator SecI = *SectionOrErr;
+      if (SecI == Obj->section_end())
+        continue;
+
+      AllSymbols[*SecI].emplace_back(Address, *Name, SymbolType);
+    }
+  }
+}
+
+static void
+addDynamicElfSymbols(const ObjectFile *Obj,
+                     std::map<SectionRef, SectionSymbolsTy> &AllSymbols) {
+  assert(Obj->isELF());
+  if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj))
+    addDynamicElfSymbols(Elf32LEObj, AllSymbols);
+  else if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj))
+    addDynamicElfSymbols(Elf64LEObj, AllSymbols);
+  else if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj))
+    addDynamicElfSymbols(Elf32BEObj, AllSymbols);
+  else if (auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj))
+    addDynamicElfSymbols(Elf64BEObj, AllSymbols);
+  else
+    llvm_unreachable("Unsupported binary format");
+}
+
 static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
   if (StartAddress > StopAddress)
     error("Start address should be less than stop address");
@@ -1182,7 +1229,6 @@
 
   // Create a mapping from virtual address to symbol name.  This is used to
   // pretty print the symbols while disassembling.
-  typedef std::vector<std::tuple<uint64_t, StringRef, uint8_t>> SectionSymbolsTy;
   std::map<SectionRef, SectionSymbolsTy> AllSymbols;
   for (const SymbolRef &Symbol : Obj->symbols()) {
     Expected<uint64_t> AddressOrErr = Symbol.getAddress();
@@ -1210,6 +1256,8 @@
     AllSymbols[*SecI].emplace_back(Address, *Name, SymbolType);
 
   }
+  if (Obj->isELF())
+    addDynamicElfSymbols(Obj, AllSymbols);
 
   // Create a mapping from virtual address to section.
   std::vector<std::pair<uint64_t, SectionRef>> SectionAddresses;
Index: test/tools/llvm-objdump/stripped-shared.test
===================================================================
--- /dev/null
+++ test/tools/llvm-objdump/stripped-shared.test
@@ -0,0 +1,10 @@
+// This test checks that dynamic symbols are used when disassembling elf files.
+// RUN: llvm-objdump -d %p/Inputs/stripped-elf.so | FileCheck %s
+
+# CHECK: .init
+# CHECK: .plt
+# CHECK: .text
+# CHECK: func0
+# CHECK: func1
+# CHECK: func2
+# CHECK: .fini


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D29632.87397.patch
Type: text/x-patch
Size: 3629 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170207/1439b1e8/attachment.bin>


More information about the llvm-commits mailing list