From 12c9f92bb18a7ac8b8915645e915e8e48415e757 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Wed, 26 Feb 2014 13:10:01 +0000 Subject: [PATCH] llvm-symbolizer: use dynamic symbol table if the regular one is stripped. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202265 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Inputs/shared-object-stripped.elf-i386 | Bin 0 -> 1280 bytes test/DebugInfo/llvm-symbolizer.test | 6 ++ tools/llvm-symbolizer/LLVMSymbolize.cpp | 72 +++++++++++------- tools/llvm-symbolizer/LLVMSymbolize.h | 1 + 4 files changed, 50 insertions(+), 29 deletions(-) create mode 100644 test/DebugInfo/Inputs/shared-object-stripped.elf-i386 diff --git a/test/DebugInfo/Inputs/shared-object-stripped.elf-i386 b/test/DebugInfo/Inputs/shared-object-stripped.elf-i386 new file mode 100644 index 0000000000000000000000000000000000000000..727c6a67b0ce7a84f59b0cd56a5de0ca0c51e73a GIT binary patch literal 1280 zcmb7@O=}ZT6oyYss<92)RuM(P3W6?Vun>yN3VsxE;Rk}dVUn3NflMZ3uFw`i7hUux zbt%|I7G3%m-0Lrh?{hP^1f-w`-Z@|IoO|y(bH6-){i0T@S+Kg*jqH~mZTXG*ywkP~ zTe64NvK8MCeEhQub1adpn(zDCy6VEA%16S*sxP|j=&_?77%K<#8^R@F@qKEGc>B|( zD*a{QeYV^bn8Tj@y7IwTALE?Nt&T|P%;-(EH~MR~Z1<}U`3+5M$)B9{FWXDy@Ud0< zJ$o;Ix{%*gj;5@&uBqGdi+t-Ad0vd-azD2;>kUR(>f_yE(Mg7J@6)JjZdm%-aM0;S zWf5(eqI@33S(>=S;rv&m|Z&A8GLQL=7#3GmNIg7G>+?ynMrrZlgJIM!Ki*^eajfbMl z>(VjI{}<0WI3rqcUeK;`Ij;j+tO;=8p#%7;7=1Yh9Q3#)P=kkV0KJ02#qJ5j=*s^E zt|<-{w0)ogJmxj@0NaX#u`aeLz^kjk-Q^yJ9{mtMQOug`k#E6$9#^@X=Wz$03Vxpa rv3SSgad(0-54;irk9&1;&bn{JV=n7*f2QZ~!Yt9e!TS&rdHUENQ#*OS literal 0 HcmV?d00001 diff --git a/test/DebugInfo/llvm-symbolizer.test b/test/DebugInfo/llvm-symbolizer.test index d6e6e754424..4b532f3e4aa 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 9f329a6de61..3adf2972593 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(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 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(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 03c765cc9c3..4ad3e97306d 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 DebugInfoContext; -- 2.34.1