llvm-symbolizer: use dynamic symbol table if the regular one is stripped.
authorAlexey Samsonov <samsonov@google.com>
Wed, 26 Feb 2014 13:10:01 +0000 (13:10 +0000)
committerAlexey Samsonov <samsonov@google.com>
Wed, 26 Feb 2014 13:10:01 +0000 (13:10 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202265 91177308-0d34-0410-b5e6-96231b3b80d8

test/DebugInfo/Inputs/shared-object-stripped.elf-i386 [new file with mode: 0644]
test/DebugInfo/llvm-symbolizer.test
tools/llvm-symbolizer/LLVMSymbolize.cpp
tools/llvm-symbolizer/LLVMSymbolize.h

diff --git a/test/DebugInfo/Inputs/shared-object-stripped.elf-i386 b/test/DebugInfo/Inputs/shared-object-stripped.elf-i386
new file mode 100644 (file)
index 0000000..727c6a6
Binary files /dev/null and b/test/DebugInfo/Inputs/shared-object-stripped.elf-i386 differ
index d6e6e7544242df20999e1d79d9fcd55c0ebfbcd9..4b532f3e4aac2341d1bb303158974af78bae31d2 100644 (file)
@@ -77,3 +77,9 @@ BINARY_C:       main
 BINARY_C-NEXT: /tmp/dbginfo{{[/\\]}}llvm-symbolizer-test.c:10
 BINARY_C:      _start
 BINARY_C:      {{g$}}
+
+RUN: echo "0x1f1" > %t.input6
+RUN: llvm-symbolizer --obj %p/Inputs/shared-object-stripped.elf-i386 < %t.input6 \
+RUN:   | FileCheck %s --check-prefix=STRIPPED
+
+STRIPPED:  global_func
index 9f329a6de61a77bac28f233d5005fa7404cdc78e..3adf29725932f4ae726c91215b1397052fa45e71 100644 (file)
@@ -14,6 +14,7 @@
 #include "LLVMSymbolize.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Config/config.h"
+#include "llvm/Object/ELFObjectFile.h"
 #include "llvm/Object/MachO.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Compression.h"
@@ -54,36 +55,49 @@ ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx)
     : Module(Obj), DebugInfoContext(DICtx) {
   for (symbol_iterator si = Module->symbol_begin(), se = Module->symbol_end();
        si != se; ++si) {
-    SymbolRef::Type SymbolType;
-    if (error(si->getType(SymbolType)))
-      continue;
-    if (SymbolType != SymbolRef::ST_Function &&
-        SymbolType != SymbolRef::ST_Data)
-      continue;
-    uint64_t SymbolAddress;
-    if (error(si->getAddress(SymbolAddress)) ||
-        SymbolAddress == UnknownAddressOrSize)
-      continue;
-    uint64_t SymbolSize;
-    // Getting symbol size is linear for Mach-O files, so assume that symbol
-    // occupies the memory range up to the following symbol.
-    if (isa<MachOObjectFile>(Obj))
-      SymbolSize = 0;
-    else if (error(si->getSize(SymbolSize)) ||
-             SymbolSize == UnknownAddressOrSize)
-      continue;
-    StringRef SymbolName;
-    if (error(si->getName(SymbolName)))
-      continue;
-    // Mach-O symbol table names have leading underscore, skip it.
-    if (Module->isMachO() && SymbolName.size() > 0 && SymbolName[0] == '_')
-      SymbolName = SymbolName.drop_front();
-    // FIXME: If a function has alias, there are two entries in symbol table
-    // with same address size. Make sure we choose the correct one.
-    SymbolMapTy &M = SymbolType == SymbolRef::ST_Function ? Functions : Objects;
-    SymbolDesc SD = { SymbolAddress, SymbolSize };
-    M.insert(std::make_pair(SD, SymbolName));
+    addSymbol(si);
   }
+  bool NoSymbolTable = (Module->symbol_begin() == Module->symbol_end());
+  if (NoSymbolTable && Module->isELF()) {
+    // Fallback to dynamic symbol table, if regular symbol table is stripped.
+    std::pair<symbol_iterator, symbol_iterator> IDyn =
+        getELFDynamicSymbolIterators(Module);
+    for (symbol_iterator si = IDyn.first, se = IDyn.second; si != se; ++si) {
+      addSymbol(si);
+    }
+  }
+}
+
+void ModuleInfo::addSymbol(const symbol_iterator &Sym) {
+  SymbolRef::Type SymbolType;
+  if (error(Sym->getType(SymbolType)))
+    return;
+  if (SymbolType != SymbolRef::ST_Function &&
+      SymbolType != SymbolRef::ST_Data)
+    return;
+  uint64_t SymbolAddress;
+  if (error(Sym->getAddress(SymbolAddress)) ||
+      SymbolAddress == UnknownAddressOrSize)
+    return;
+  uint64_t SymbolSize;
+  // Getting symbol size is linear for Mach-O files, so assume that symbol
+  // occupies the memory range up to the following symbol.
+  if (isa<MachOObjectFile>(Module))
+    SymbolSize = 0;
+  else if (error(Sym->getSize(SymbolSize)) ||
+           SymbolSize == UnknownAddressOrSize)
+    return;
+  StringRef SymbolName;
+  if (error(Sym->getName(SymbolName)))
+    return;
+  // Mach-O symbol table names have leading underscore, skip it.
+  if (Module->isMachO() && SymbolName.size() > 0 && SymbolName[0] == '_')
+    SymbolName = SymbolName.drop_front();
+  // FIXME: If a function has alias, there are two entries in symbol table
+  // with same address size. Make sure we choose the correct one.
+  SymbolMapTy &M = SymbolType == SymbolRef::ST_Function ? Functions : Objects;
+  SymbolDesc SD = { SymbolAddress, SymbolSize };
+  M.insert(std::make_pair(SD, SymbolName));
 }
 
 bool ModuleInfo::getNameFromSymbolTable(SymbolRef::Type Type, uint64_t Address,
index 03c765cc9c309a8d6aa282b0f03b4c070bddd1dc..4ad3e97306d51ff89aaf11eced7ba6728d07d95d 100644 (file)
@@ -102,6 +102,7 @@ private:
   bool getNameFromSymbolTable(SymbolRef::Type Type, uint64_t Address,
                               std::string &Name, uint64_t &Addr,
                               uint64_t &Size) const;
+  void addSymbol(const symbol_iterator &Sym);
   ObjectFile *Module;
   OwningPtr<DIContext> DebugInfoContext;