mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-04 01:26:41 +00:00
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@250582 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
95dcdb985b
commit
dd65b7a9f5
@ -1,5 +1,5 @@
|
||||
// To generate the corresponding EXE, run:
|
||||
// clang-cl -O2 -gdwarf -c coff-dwarf.cpp && lld-link -debug coff-dwarf.obj
|
||||
// clang-cl -MD -O2 -gdwarf -c coff-dwarf.cpp && lld-link -debug coff-dwarf.obj
|
||||
|
||||
extern "C" int puts(const char *str);
|
||||
|
||||
|
20
test/tools/llvm-symbolizer/Inputs/coff-exports.cpp
Normal file
20
test/tools/llvm-symbolizer/Inputs/coff-exports.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
// To generate the corresponding EXE, run:
|
||||
// clang-cl -MD -c coff-exports.cpp && lld-link /MANIFEST:NO coff-exports.obj
|
||||
|
||||
#define EXPORT __declspec(dllexport)
|
||||
|
||||
extern "C" int puts(const char *str);
|
||||
|
||||
EXPORT void __declspec(noinline) foo() {
|
||||
puts("foo1");
|
||||
puts("foo2");
|
||||
}
|
||||
|
||||
void bar() {
|
||||
foo();
|
||||
}
|
||||
|
||||
EXPORT int main() {
|
||||
bar();
|
||||
return 0;
|
||||
}
|
BIN
test/tools/llvm-symbolizer/Inputs/coff-exports.exe
Normal file
BIN
test/tools/llvm-symbolizer/Inputs/coff-exports.exe
Normal file
Binary file not shown.
17
test/tools/llvm-symbolizer/coff-exports.test
Normal file
17
test/tools/llvm-symbolizer/coff-exports.test
Normal file
@ -0,0 +1,17 @@
|
||||
RUN: grep '^ADDR:' %s | sed -s 's/ADDR: //' \
|
||||
RUN: | llvm-symbolizer --inlining --relative-address -obj="%p/Inputs/coff-exports.exe" \
|
||||
RUN: | FileCheck %s
|
||||
|
||||
ADDR: 0x500A
|
||||
ADDR: 0x5038
|
||||
ADDR: 0x504B
|
||||
|
||||
We get the expected stack trace, except 'foo' appears for the 'bar' frame
|
||||
because 'bar' isn't in the export table.
|
||||
|
||||
CHECK: foo(void)
|
||||
CHECK: ??:0:0
|
||||
CHECK: foo(void)
|
||||
CHECK: ??:0:0
|
||||
CHECK: main
|
||||
CHECK: ??:0:0
|
@ -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,
|
||||
|
@ -130,6 +130,7 @@ private:
|
||||
void addSymbol(const SymbolRef &Symbol, uint64_t SymbolSize,
|
||||
DataExtractor *OpdExtractor = nullptr,
|
||||
uint64_t OpdAddress = 0);
|
||||
void addCoffExportSymbols(const COFFObjectFile *CoffObj);
|
||||
ObjectFile *Module;
|
||||
std::unique_ptr<DIContext> DebugInfoContext;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user