1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

Add support for DWARF embedded source to llvm-symbolizer.

This patch adds DWARF embedded source printout to llvm-symbolizer.

Reviewed By: jhenderson, dblaikie

Differential Revision: https://reviews.llvm.org/D102355
This commit is contained in:
Alex Orlov 2021-05-20 21:40:28 +04:00
parent 7cef6d55d4
commit 5487f701b4
2 changed files with 95 additions and 25 deletions

View File

@ -82,6 +82,29 @@ public:
FirstLine(std::max(static_cast<int64_t>(1), Line - Lines / 2)),
LastLine(FirstLine + Lines - 1),
PrunedSource(pruneSource(load(FileName, EmbeddedSource))) {}
void format(raw_ostream &OS) {
if (!PrunedSource)
return;
size_t MaxLineNumberWidth = std::ceil(std::log10(LastLine));
int64_t L = FirstLine;
for (size_t Pos = 0; Pos < PrunedSource->size(); ++L) {
size_t PosEnd = PrunedSource->find('\n', Pos);
StringRef String = PrunedSource->substr(
Pos, (PosEnd == StringRef::npos) ? StringRef::npos : (PosEnd - Pos));
if (String.endswith("\r"))
String = String.drop_back(1);
OS << format_decimal(L, MaxLineNumberWidth);
if (L == Line)
OS << " >: ";
else
OS << " : ";
OS << String << '\n';
if (PosEnd == StringRef::npos)
break;
Pos = PosEnd + 1;
}
}
};
void PlainPrinterBase::printHeader(uint64_t Address) {
@ -95,27 +118,7 @@ void PlainPrinterBase::printHeader(uint64_t Address) {
// Prints source code around in the FileName the Line.
void PlainPrinterBase::printContext(SourceCode SourceCode) {
if (!SourceCode.PrunedSource)
return;
StringRef Source = *SourceCode.PrunedSource;
std::string SourceCopy;
if (*Source.end() != '\0') {
SourceCopy = Source.str();
Source = SourceCopy;
}
size_t MaxLineNumberWidth = std::ceil(std::log10(SourceCode.LastLine));
for (line_iterator I = line_iterator(MemoryBufferRef(Source, ""), false);
!I.is_at_eof(); ++I) {
int64_t L = SourceCode.FirstLine + I.line_number() - 1;
OS << format_decimal(L, MaxLineNumberWidth);
if (L == SourceCode.Line)
OS << " >: ";
else
OS << " : ";
OS << *I << '\n';
}
SourceCode.format(OS);
}
void PlainPrinterBase::printFunctionName(StringRef FunctionName, bool Inlined) {
@ -131,7 +134,8 @@ void PlainPrinterBase::printFunctionName(StringRef FunctionName, bool Inlined) {
void LLVMPrinter::printSimpleLocation(StringRef Filename,
const DILineInfo &Info) {
OS << Filename << ':' << Info.Line << ':' << Info.Column << '\n';
printContext(SourceCode(Filename, Info.Line, Config.SourceContextLines));
printContext(
SourceCode(Filename, Info.Line, Config.SourceContextLines, Info.Source));
}
void GNUPrinter::printSimpleLocation(StringRef Filename,
@ -140,7 +144,8 @@ void GNUPrinter::printSimpleLocation(StringRef Filename,
if (Info.Discriminator)
OS << " (discriminator " << Info.Discriminator << ')';
OS << '\n';
printContext(SourceCode(Filename, Info.Line, Config.SourceContextLines));
printContext(
SourceCode(Filename, Info.Line, Config.SourceContextLines, Info.Source));
}
void PlainPrinterBase::printVerbose(StringRef Filename,
@ -291,7 +296,7 @@ void JSONPrinter::print(const Request &Request, const DIInliningInfo &Info) {
json::Array Array;
for (uint32_t I = 0, N = Info.getNumberOfFrames(); I < N; ++I) {
const DILineInfo &LineInfo = Info.getFrame(I);
Array.push_back(json::Object(
json::Object Object(
{{"FunctionName", LineInfo.FunctionName != DILineInfo::BadString
? LineInfo.FunctionName
: ""},
@ -305,7 +310,15 @@ void JSONPrinter::print(const Request &Request, const DIInliningInfo &Info) {
LineInfo.FileName != DILineInfo::BadString ? LineInfo.FileName : ""},
{"Line", LineInfo.Line},
{"Column", LineInfo.Column},
{"Discriminator", LineInfo.Discriminator}}));
{"Discriminator", LineInfo.Discriminator}});
SourceCode SourceCode(LineInfo.FileName, LineInfo.Line,
Config.SourceContextLines, LineInfo.Source);
std::string FormattedSource;
raw_string_ostream Stream(FormattedSource);
SourceCode.format(Stream);
if (!FormattedSource.empty())
Object["Source"] = std::move(FormattedSource);
Array.push_back(std::move(Object));
}
json::Object Json = toJSON(Request);
Json["Symbol"] = std::move(Array);

View File

@ -0,0 +1,57 @@
;; This test checks output of the DWARF embedded source.
; REQUIRES: x86-registered-target
; RUN: llc -filetype=obj -o %t.o %s
;; Check LLVM style output.
; RUN: llvm-symbolizer --print-source-context-lines=3 --obj=%t.o 0 | \
; RUN: FileCheck %s --check-prefixes=COMMON,LLVM --strict-whitespace --match-full-lines --implicit-check-not={{.}}
;; Check GNU output style.
; RUN: llvm-symbolizer --print-source-context-lines=3 --obj=%t.o 0 --output-style=GNU | \
; RUN: FileCheck %s --check-prefixes=COMMON,GNU --strict-whitespace --match-full-lines --implicit-check-not={{.}}
; COMMON:foo
; LLVM-NEXT:/source.c:3:13
; GNU-NEXT:/source.c:3
; COMMON-NEXT:2 : // Line 2
; COMMON-NEXT:3 >: void foo() {}
; COMMON-NEXT:4 : // Line 4
;; Check JSON style output.
; RUN: llvm-symbolizer --print-source-context-lines=3 --obj=%t.o 0 --output-style=JSON | \
; RUN: FileCheck %s --check-prefix=JSON --strict-whitespace --match-full-lines --implicit-check-not={{.}}
; JSON:[{"Address":"0x0","ModuleName":"{{.*}}.o","Symbol":[{"Column":13,"Discriminator":0,"FileName":"/source.c","FunctionName":"foo","Line":3,"Source":"2 : // Line 2\n3 >: void foo() {}\n4 : // Line 4\n","StartAddress":"0x0","StartFileName":"/source.c","StartLine":3}]}]
;; Generated from the following source:
;; // Line 1
;; // Line 2
;; void foo() {}
;; // Line 4
;; // Line 5
;; clang --target=x86_64-pc-linux -gdwarf-5 -gembed-source -g -emit-llvm -S source.c -o source.ll
source_filename = "source.c"
target triple = "x86_64-pc-linux"
define dso_local void @foo() #0 !dbg !7 {
entry:
ret void, !dbg !10
}
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4, !5}
!llvm.ident = !{!6}
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 12.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
!1 = !DIFile(filename: "source.c", directory: "/", source: "// Line 1\0A// Line 2\0Avoid foo() {}\0A// Line 4\0A// Line 5\0A")
!2 = !{}
!3 = !{i32 7, !"Dwarf Version", i32 5}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{i32 1, !"wchar_size", i32 4}
!6 = !{!"clang version 12.0.0"}
!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
!8 = !DISubroutineType(types: !9)
!9 = !{null}
!10 = !DILocation(line: 3, column: 13, scope: !7)