diff options
Diffstat (limited to 'contrib/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp')
-rw-r--r-- | contrib/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp | 88 |
1 files changed, 65 insertions, 23 deletions
diff --git a/contrib/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp b/contrib/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp index 9c9f3ad..9503493 100644 --- a/contrib/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ b/contrib/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -15,8 +15,9 @@ // //===----------------------------------------------------------------------===// -#include "LLVMSymbolize.h" #include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/Symbolize/DIPrinter.h" +#include "llvm/DebugInfo/Symbolize/Symbolize.h" #include "llvm/Support/COM.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -73,19 +74,33 @@ static cl::list<std::string> ClDsymHint("dsym-hint", cl::ZeroOrMore, cl::desc("Path to .dSYM bundles to search for debug info for the " "object files")); +static cl::opt<bool> + ClPrintAddress("print-address", cl::init(false), + cl::desc("Show address before line information")); + +static cl::opt<bool> + ClPrettyPrint("pretty-print", cl::init(false), + cl::desc("Make the output more human friendly")); + +static cl::opt<int> ClPrintSourceContextLines( + "print-source-context-lines", cl::init(0), + cl::desc("Print N number of source file context")); + +static bool error(std::error_code ec) { + if (!ec) + return false; + errs() << "LLVMSymbolizer: error reading file: " << ec.message() << ".\n"; + return true; +} -static bool parseCommand(bool &IsData, std::string &ModuleName, - uint64_t &ModuleOffset) { +static bool parseCommand(StringRef InputString, bool &IsData, + std::string &ModuleName, uint64_t &ModuleOffset) { const char *kDataCmd = "DATA "; const char *kCodeCmd = "CODE "; - const int kMaxInputStringLength = 1024; - const char kDelimiters[] = " \n"; - char InputString[kMaxInputStringLength]; - if (!fgets(InputString, sizeof(InputString), stdin)) - return false; + const char kDelimiters[] = " \n\r"; IsData = false; ModuleName = ""; - char *pos = InputString; + const char *pos = InputString.data(); if (strncmp(pos, kDataCmd, strlen(kDataCmd)) == 0) { IsData = true; pos += strlen(kDataCmd); @@ -102,7 +117,7 @@ static bool parseCommand(bool &IsData, std::string &ModuleName, if (*pos == '"' || *pos == '\'') { char quote = *pos; pos++; - char *end = strchr(pos, quote); + const char *end = strchr(pos, quote); if (!end) return false; ModuleName = std::string(pos, end - pos); @@ -118,9 +133,7 @@ static bool parseCommand(bool &IsData, std::string &ModuleName, // Skip delimiters and parse module offset. pos += strspn(pos, kDelimiters); int offset_length = strcspn(pos, kDelimiters); - if (StringRef(pos, offset_length).getAsInteger(0, ModuleOffset)) - return false; - return true; + return !StringRef(pos, offset_length).getAsInteger(0, ModuleOffset); } int main(int argc, char **argv) { @@ -132,9 +145,9 @@ int main(int argc, char **argv) { llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::MultiThreaded); cl::ParseCommandLineOptions(argc, argv, "llvm-symbolizer\n"); - LLVMSymbolizer::Options Opts(ClPrintFunctions, ClUseSymbolTable, - ClPrintInlining, ClDemangle, + LLVMSymbolizer::Options Opts(ClPrintFunctions, ClUseSymbolTable, ClDemangle, ClUseRelativeAddress, ClDefaultArch); + for (const auto &hint : ClDsymHint) { if (sys::path::extension(hint) == ".dSYM") { Opts.DsymHints.push_back(hint); @@ -145,14 +158,43 @@ int main(int argc, char **argv) { } LLVMSymbolizer Symbolizer(Opts); - bool IsData = false; - std::string ModuleName; - uint64_t ModuleOffset; - while (parseCommand(IsData, ModuleName, ModuleOffset)) { - std::string Result = - IsData ? Symbolizer.symbolizeData(ModuleName, ModuleOffset) - : Symbolizer.symbolizeCode(ModuleName, ModuleOffset); - outs() << Result << "\n"; + DIPrinter Printer(outs(), ClPrintFunctions != FunctionNameKind::None, + ClPrettyPrint, ClPrintSourceContextLines); + + const int kMaxInputStringLength = 1024; + char InputString[kMaxInputStringLength]; + + while (true) { + if (!fgets(InputString, sizeof(InputString), stdin)) + break; + + bool IsData = false; + std::string ModuleName; + uint64_t ModuleOffset = 0; + if (!parseCommand(StringRef(InputString), IsData, ModuleName, + ModuleOffset)) { + outs() << InputString; + continue; + } + + if (ClPrintAddress) { + outs() << "0x"; + outs().write_hex(ModuleOffset); + StringRef Delimiter = (ClPrettyPrint == true) ? ": " : "\n"; + outs() << Delimiter; + } + if (IsData) { + auto ResOrErr = Symbolizer.symbolizeData(ModuleName, ModuleOffset); + Printer << (error(ResOrErr.getError()) ? DIGlobal() : ResOrErr.get()); + } else if (ClPrintInlining) { + auto ResOrErr = Symbolizer.symbolizeInlinedCode(ModuleName, ModuleOffset); + Printer << (error(ResOrErr.getError()) ? DIInliningInfo() + : ResOrErr.get()); + } else { + auto ResOrErr = Symbolizer.symbolizeCode(ModuleName, ModuleOffset); + Printer << (error(ResOrErr.getError()) ? DILineInfo() : ResOrErr.get()); + } + outs() << "\n"; outs().flush(); } |