llvm-symbolizer: Add a FRAME command.
This command prints a description of the referenced function's stack frame.
For each formal parameter and local variable, the tool prints:
- function name
- variable name
- file/line of declaration
- FP-relative variable location (if available)
- size in bytes
- HWASAN tag offset
This information will be used by the HWASAN runtime to identify local
variables in UAR reports.
Differential Revision: https://reviews.llvm.org/D63468
llvm-svn: 364225
diff --git a/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp b/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
index f6c7ef8..b2bfef2 100644
--- a/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
@@ -122,5 +122,28 @@
return *this;
}
+DIPrinter &DIPrinter::operator<<(const DILocal &Local) {
+ OS << Local.FunctionName << '\n';
+ OS << Local.Name << '\n';
+ if (Local.DeclFile.empty())
+ OS << "??";
+ else
+ OS << Local.DeclFile;
+ OS << ':' << Local.DeclLine << '\n';
+ if (Local.FrameOffset)
+ OS << *Local.FrameOffset << ' ';
+ else
+ OS << "?? ";
+ if (Local.Size)
+ OS << *Local.Size << ' ';
+ else
+ OS << "?? ";
+ if (Local.TagOffset)
+ OS << *Local.TagOffset << '\n';
+ else
+ OS << "??\n";
+ return *this;
+}
+
} // end namespace symbolize
} // end namespace llvm
diff --git a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
index 62f849f..6092584 100644
--- a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
@@ -298,6 +298,14 @@
return Res;
}
+std::vector<DILocal> SymbolizableObjectFile::symbolizeFrame(
+ object::SectionedAddress ModuleOffset) const {
+ if (ModuleOffset.SectionIndex == object::SectionedAddress::UndefSection)
+ ModuleOffset.SectionIndex =
+ getModuleSectionIndexForAddress(ModuleOffset.Address);
+ return DebugInfoContext->getLocalsForAddress(ModuleOffset);
+}
+
/// Search for the first occurence of specified Address in ObjectFile.
uint64_t SymbolizableObjectFile::getModuleSectionIndexForAddress(
uint64_t Address) const {
diff --git a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
index d5510cb..3a511dc 100644
--- a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
+++ b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
@@ -40,6 +40,8 @@
FunctionNameKind FNKind,
bool UseSymbolTable) const override;
DIGlobal symbolizeData(object::SectionedAddress ModuleOffset) const override;
+ std::vector<DILocal>
+ symbolizeFrame(object::SectionedAddress ModuleOffset) const override;
// Return true if this is a 32-bit x86 PE COFF module.
bool isWin32Module() const override;
diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
index 1bfd4e8..1cb8a7a 100644
--- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
@@ -133,6 +133,29 @@
return Global;
}
+Expected<std::vector<DILocal>>
+LLVMSymbolizer::symbolizeFrame(const std::string &ModuleName,
+ object::SectionedAddress ModuleOffset) {
+ SymbolizableModule *Info;
+ if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName))
+ Info = InfoOrErr.get();
+ else
+ return InfoOrErr.takeError();
+
+ // A null module means an error has already been reported. Return an empty
+ // result.
+ if (!Info)
+ return std::vector<DILocal>();
+
+ // If the user is giving us relative addresses, add the preferred base of
+ // the object to the offset before we do the query. It's what DIContext
+ // expects.
+ if (Opts.RelativeAddresses)
+ ModuleOffset.Address += Info->getModulePreferredBase();
+
+ return Info->symbolizeFrame(ModuleOffset);
+}
+
void LLVMSymbolizer::flush() {
ObjectForUBPathAndArch.clear();
BinaryForPath.clear();