aboutsummaryrefslogtreecommitdiff
path: root/tools/llvm-symbolizer
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2013-02-14 13:06:18 +0000
committerDmitry Vyukov <dvyukov@google.com>2013-02-14 13:06:18 +0000
commitb181919d86bd46fdb6c21d782ccabf754167951a (patch)
tree2692e6260ff00aa89e7703af1bbaec6cfc8a1e32 /tools/llvm-symbolizer
parent79e8429e41c98d42e9e4d13de8276b8de24ddc83 (diff)
llvm-symbolizer: speedup symbol lookup
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175158 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-symbolizer')
-rw-r--r--tools/llvm-symbolizer/LLVMSymbolize.cpp98
-rw-r--r--tools/llvm-symbolizer/LLVMSymbolize.h18
2 files changed, 73 insertions, 43 deletions
diff --git a/tools/llvm-symbolizer/LLVMSymbolize.cpp b/tools/llvm-symbolizer/LLVMSymbolize.cpp
index 227580f465..fe32178f02 100644
--- a/tools/llvm-symbolizer/LLVMSymbolize.cpp
+++ b/tools/llvm-symbolizer/LLVMSymbolize.cpp
@@ -21,6 +21,12 @@
namespace llvm {
namespace symbolize {
+static bool error(error_code ec) {
+ if (!ec) return false;
+ errs() << "LLVMSymbolizer: error reading file: " << ec.message() << ".\n";
+ return true;
+}
+
static uint32_t getDILineInfoSpecifierFlags(
const LLVMSymbolizer::Options &Opts) {
uint32_t Flags = llvm::DILineInfoSpecifier::FileLineInfo |
@@ -37,6 +43,58 @@ static void patchFunctionNameInDILineInfo(const std::string &NewFunctionName,
LineInfo.getLine(), LineInfo.getColumn());
}
+ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx)
+ : Module(Obj)
+ , DebugInfoContext(DICtx) {
+ error_code ec;
+ for (symbol_iterator si = Module->begin_symbols(),
+ se = Module->end_symbols();
+ si != se; si.increment(ec)) {
+ if (error(ec))
+ return;
+ 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;
+ if (error(si->getSize(SymbolSize))
+ || SymbolSize == UnknownAddressOrSize)
+ continue;
+ StringRef SymbolName;
+ if (error(si->getName(SymbolName)))
+ continue;
+ // 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, SymbolAddress + SymbolSize};
+ M.insert(std::make_pair(SD, SymbolName));
+ }
+}
+
+bool ModuleInfo::getNameFromSymbolTable(SymbolRef::Type Type, uint64_t Address,
+ std::string &Name, uint64_t &Addr,
+ uint64_t &Size) const {
+ const SymbolMapTy& M = Type == SymbolRef::ST_Function ?
+ Functions : Objects;
+ SymbolDesc SD = {Address, Address + 1};
+ SymbolMapTy::const_iterator it = M.find(SD);
+ if (it == M.end())
+ return false;
+ if (Address < it->first.Addr || Address >= it->first.AddrEnd)
+ return false;
+ Name = it->second.str();
+ Addr = it->first.Addr;
+ Size = it->first.AddrEnd - it->first.Addr;
+ return true;
+}
+
DILineInfo ModuleInfo::symbolizeCode(uint64_t ModuleOffset,
const LLVMSymbolizer::Options& Opts) const {
DILineInfo LineInfo;
@@ -94,44 +152,6 @@ bool ModuleInfo::symbolizeData(uint64_t ModuleOffset, std::string &Name,
ModuleOffset, Name, Start, Size);
}
-static bool error(error_code ec) {
- if (!ec) return false;
- errs() << "LLVMSymbolizer: error reading file: " << ec.message() << ".\n";
- return true;
-}
-
-bool ModuleInfo::getNameFromSymbolTable(SymbolRef::Type Type, uint64_t Address,
- std::string &Name, uint64_t &Addr,
- uint64_t &Size) const {
- assert(Module);
- error_code ec;
- for (symbol_iterator si = Module->begin_symbols(),
- se = Module->end_symbols();
- si != se; si.increment(ec)) {
- if (error(ec)) return false;
- uint64_t SymbolAddress;
- uint64_t SymbolSize;
- SymbolRef::Type SymbolType;
- if (error(si->getAddress(SymbolAddress)) ||
- SymbolAddress == UnknownAddressOrSize) continue;
- if (error(si->getSize(SymbolSize)) ||
- SymbolSize == UnknownAddressOrSize) continue;
- if (error(si->getType(SymbolType))) continue;
- // FIXME: If a function has alias, there are two entries in symbol table
- // with same address size. Make sure we choose the correct one.
- if (SymbolAddress <= Address && Address < SymbolAddress + SymbolSize &&
- SymbolType == Type) {
- StringRef SymbolName;
- if (error(si->getName(SymbolName))) continue;
- Name = SymbolName.str();
- Addr = SymbolAddress;
- Size = SymbolSize;
- return true;
- }
- }
- return false;
-}
-
const char LLVMSymbolizer::kBadString[] = "??";
std::string LLVMSymbolizer::symbolizeCode(const std::string &ModuleName,
@@ -202,7 +222,6 @@ ModuleInfo *LLVMSymbolizer::getOrCreateModuleInfo(
return I->second;
ObjectFile *Obj = getObjectFile(ModuleName);
- ObjectFile *DbgObj = Obj;
if (Obj == 0) {
// Module name doesn't point to a valid object file.
Modules.insert(make_pair(ModuleName, (ModuleInfo*)0));
@@ -214,6 +233,7 @@ ModuleInfo *LLVMSymbolizer::getOrCreateModuleInfo(
if (getObjectEndianness(Obj, IsLittleEndian)) {
// On Darwin we may find DWARF in separate object file in
// resource directory.
+ ObjectFile *DbgObj = Obj;
if (isa<MachOObjectFile>(Obj)) {
const std::string &ResourceName = getDarwinDWARFResourceForModule(
ModuleName);
diff --git a/tools/llvm-symbolizer/LLVMSymbolize.h b/tools/llvm-symbolizer/LLVMSymbolize.h
index 89684ddef2..1755e1dc88 100644
--- a/tools/llvm-symbolizer/LLVMSymbolize.h
+++ b/tools/llvm-symbolizer/LLVMSymbolize.h
@@ -63,11 +63,8 @@ private:
};
class ModuleInfo {
- OwningPtr<ObjectFile> Module;
- OwningPtr<DIContext> DebugInfoContext;
public:
- ModuleInfo(ObjectFile *Obj, DIContext *DICtx)
- : Module(Obj), DebugInfoContext(DICtx) {}
+ ModuleInfo(ObjectFile *Obj, DIContext *DICtx);
DILineInfo symbolizeCode(
uint64_t ModuleOffset, const LLVMSymbolizer::Options& Opts) const;
@@ -80,6 +77,19 @@ class ModuleInfo {
bool getNameFromSymbolTable(SymbolRef::Type Type, uint64_t Address,
std::string &Name, uint64_t &Addr,
uint64_t &Size) const;
+ OwningPtr<ObjectFile> Module;
+ OwningPtr<DIContext> DebugInfoContext;
+
+ struct SymbolDesc {
+ uint64_t Addr;
+ uint64_t AddrEnd;
+ friend bool operator<(const SymbolDesc& s1, const SymbolDesc& s2) {
+ return s1.AddrEnd <= s2.Addr;
+ }
+ };
+ typedef std::map<SymbolDesc, StringRef> SymbolMapTy;
+ SymbolMapTy Functions;
+ SymbolMapTy Objects;
};
} // namespace symbolize