diff options
-rw-r--r-- | test/DebugInfo/Inputs/shared-object-stripped.elf-i386 | bin | 0 -> 1280 bytes | |||
-rw-r--r-- | test/DebugInfo/llvm-symbolizer.test | 6 | ||||
-rw-r--r-- | tools/llvm-symbolizer/LLVMSymbolize.cpp | 72 | ||||
-rw-r--r-- | tools/llvm-symbolizer/LLVMSymbolize.h | 1 |
4 files changed, 50 insertions, 29 deletions
diff --git a/test/DebugInfo/Inputs/shared-object-stripped.elf-i386 b/test/DebugInfo/Inputs/shared-object-stripped.elf-i386 Binary files differnew file mode 100644 index 0000000000..727c6a67b0 --- /dev/null +++ b/test/DebugInfo/Inputs/shared-object-stripped.elf-i386 diff --git a/test/DebugInfo/llvm-symbolizer.test b/test/DebugInfo/llvm-symbolizer.test index d6e6e75442..4b532f3e4a 100644 --- a/test/DebugInfo/llvm-symbolizer.test +++ b/test/DebugInfo/llvm-symbolizer.test @@ -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 diff --git a/tools/llvm-symbolizer/LLVMSymbolize.cpp b/tools/llvm-symbolizer/LLVMSymbolize.cpp index 9f329a6de6..3adf297259 100644 --- a/tools/llvm-symbolizer/LLVMSymbolize.cpp +++ b/tools/llvm-symbolizer/LLVMSymbolize.cpp @@ -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, diff --git a/tools/llvm-symbolizer/LLVMSymbolize.h b/tools/llvm-symbolizer/LLVMSymbolize.h index 03c765cc9c..4ad3e97306 100644 --- a/tools/llvm-symbolizer/LLVMSymbolize.h +++ b/tools/llvm-symbolizer/LLVMSymbolize.h @@ -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; |