[PATCH] D29632: Use ELF dynamic symbols for disassembly

Sam Parker via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 7 06:45:59 PST 2017


samparker updated this revision to Diff 87421.
samparker added a comment.

Now we only try to add dynamic symbols if there are no static symbols.


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 (AllSymbols.empty() && 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.87421.patch
Type: text/x-patch
Size: 3651 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170207/a09ddc41/attachment.bin>


More information about the llvm-commits mailing list