summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-symbolizer/LLVMSymbolize.cpp
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2015-10-16 23:43:22 +0000
committerReid Kleckner <rnk@google.com>2015-10-16 23:43:22 +0000
commit02b74368ce181614741c7f5aa3a39a86df78f9af (patch)
tree27e34f0a50bc64fc5fb4439eefd1b54c3b03c05f /llvm/tools/llvm-symbolizer/LLVMSymbolize.cpp
parent15560778df3e80d73d085d21196f531415c5b5fa (diff)
downloadbcm5719-llvm-02b74368ce181614741c7f5aa3a39a86df78f9af.tar.gz
bcm5719-llvm-02b74368ce181614741c7f5aa3a39a86df78f9af.zip
[llvm-symbolizer] Use the export table if no symbols are present
This lets us make guesses about symbols in third party DLLs without debug info, like MSVCR120.dll or kernel32.dll. dbghelp does the same thing. llvm-svn: 250582
Diffstat (limited to 'llvm/tools/llvm-symbolizer/LLVMSymbolize.cpp')
-rw-r--r--llvm/tools/llvm-symbolizer/LLVMSymbolize.cpp44
1 files changed, 44 insertions, 0 deletions
diff --git a/llvm/tools/llvm-symbolizer/LLVMSymbolize.cpp b/llvm/tools/llvm-symbolizer/LLVMSymbolize.cpp
index 996520b8430..ae164b07b96 100644
--- a/llvm/tools/llvm-symbolizer/LLVMSymbolize.cpp
+++ b/llvm/tools/llvm-symbolizer/LLVMSymbolize.cpp
@@ -83,6 +83,50 @@ ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx)
computeSymbolSizes(*Module);
for (auto &P : Symbols)
addSymbol(P.first, P.second, OpdExtractor.get(), OpdAddress);
+
+ // If this is a COFF object and we didn't find any symbols, try the export
+ // table.
+ if (Symbols.empty()) {
+ if (auto *CoffObj = dyn_cast<COFFObjectFile>(Obj))
+ addCoffExportSymbols(CoffObj);
+ }
+}
+
+void ModuleInfo::addCoffExportSymbols(const COFFObjectFile *CoffObj) {
+ // Get all export names and offsets.
+ struct OffsetNamePair {
+ uint32_t Offset;
+ StringRef Name;
+ };
+ std::vector<OffsetNamePair> ExportSyms;
+ for (const ExportDirectoryEntryRef &Ref : CoffObj->export_directories()) {
+ StringRef Name;
+ uint32_t Offset;
+ if (error(Ref.getSymbolName(Name)) || error(Ref.getExportRVA(Offset)))
+ return;
+ ExportSyms.push_back(OffsetNamePair{Offset, Name});
+ }
+ if (ExportSyms.empty())
+ return;
+
+ // Sort by ascending offset.
+ array_pod_sort(ExportSyms.begin(), ExportSyms.end(),
+ [](const OffsetNamePair *L, const OffsetNamePair *R) -> int {
+ return L->Offset - R->Offset;
+ });
+
+ // Approximate the symbol sizes by assuming they run to the next symbol.
+ // FIXME: This assumes all exports are functions.
+ uint64_t ImageBase = CoffObj->getImageBase();
+ for (auto I = ExportSyms.begin(), E = ExportSyms.end(); I != E; ++I) {
+ OffsetNamePair &Export = *I;
+ // FIXME: The last export has a one byte size now.
+ uint32_t NextOffset = I != E ? I->Offset : Export.Offset + 1;
+ uint64_t SymbolStart = ImageBase + Export.Offset;
+ uint64_t SymbolSize = NextOffset - Export.Offset;
+ SymbolDesc SD = {SymbolStart, SymbolSize};
+ Functions.insert(std::make_pair(SD, Export.Name));
+ }
}
void ModuleInfo::addSymbol(const SymbolRef &Symbol, uint64_t SymbolSize,
OpenPOWER on IntegriCloud