[llvm] r294430 - Use dynamic symbols for ELF disassembly

Sam Parker via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 8 01:44:19 PST 2017


Author: sam_parker
Date: Wed Feb  8 03:44:18 2017
New Revision: 294430

URL: http://llvm.org/viewvc/llvm-project?rev=294430&view=rev
Log:
Use dynamic symbols for ELF disassembly

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

Differential Revision: https://reviews.llvm.org/D29632


Added:
    llvm/trunk/test/tools/llvm-objdump/Inputs/stripped-elf.so
    llvm/trunk/test/tools/llvm-objdump/stripped-shared.test
Modified:
    llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp

Added: llvm/trunk/test/tools/llvm-objdump/Inputs/stripped-elf.so
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/Inputs/stripped-elf.so?rev=294430&view=auto
==============================================================================
Binary files llvm/trunk/test/tools/llvm-objdump/Inputs/stripped-elf.so (added) and llvm/trunk/test/tools/llvm-objdump/Inputs/stripped-elf.so Wed Feb  8 03:44:18 2017 differ

Added: llvm/trunk/test/tools/llvm-objdump/stripped-shared.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objdump/stripped-shared.test?rev=294430&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objdump/stripped-shared.test (added)
+++ llvm/trunk/test/tools/llvm-objdump/stripped-shared.test Wed Feb  8 03:44:18 2017
@@ -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

Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp?rev=294430&r1=294429&r2=294430&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp (original)
+++ llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp Wed Feb  8 03:44:18 2017
@@ -213,6 +213,8 @@ cl::opt<unsigned long long>
                 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,52 @@ static uint8_t getElfSymbolType(const Ob
   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)
+      continue;
+
+    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 +1230,6 @@ static void DisassembleObject(const Obje
 
   // 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 +1257,8 @@ static void DisassembleObject(const Obje
     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;




More information about the llvm-commits mailing list