[llvm] r362037 - [llvm-pdbutil] Dump inline call site line table annotations
Reid Kleckner via llvm-commits
llvm-commits at lists.llvm.org
Wed May 29 14:26:26 PDT 2019
Author: rnk
Date: Wed May 29 14:26:25 2019
New Revision: 362037
URL: http://llvm.org/viewvc/llvm-project?rev=362037&view=rev
Log:
[llvm-pdbutil] Dump inline call site line table annotations
This ports and improves on some existing llvm-readobj -codeview dumping
functionality that llvm-pdbutil lacked.
Helpful for comparing inline line tables between MSVC and clang.
Modified:
llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h
llvm/trunk/test/MC/COFF/cv-inline-linetable.s
llvm/trunk/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h?rev=362037&r1=362036&r2=362037&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h Wed May 29 14:26:25 2019
@@ -13,6 +13,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
@@ -155,15 +156,19 @@ public:
uint32_t RecordOffset;
};
-struct BinaryAnnotationIterator {
- struct AnnotationData {
- BinaryAnnotationsOpCode OpCode;
- StringRef Name;
- uint32_t U1;
- uint32_t U2;
- int32_t S1;
- };
+struct DecodedAnnotation {
+ StringRef Name;
+ ArrayRef<uint8_t> Bytes;
+ BinaryAnnotationsOpCode OpCode;
+ uint32_t U1 = 0;
+ uint32_t U2 = 0;
+ int32_t S1 = 0;
+};
+struct BinaryAnnotationIterator
+ : public iterator_facade_base<BinaryAnnotationIterator,
+ std::forward_iterator_tag,
+ DecodedAnnotation> {
BinaryAnnotationIterator() = default;
BinaryAnnotationIterator(ArrayRef<uint8_t> Annotations) : Data(Annotations) {}
BinaryAnnotationIterator(const BinaryAnnotationIterator &Other)
@@ -173,10 +178,6 @@ struct BinaryAnnotationIterator {
return Data == Other.Data;
}
- bool operator!=(const BinaryAnnotationIterator &Other) const {
- return !(*this == Other);
- }
-
BinaryAnnotationIterator &operator=(const BinaryAnnotationIterator Other) {
Data = Other.Data;
return *this;
@@ -193,13 +194,7 @@ struct BinaryAnnotationIterator {
return *this;
}
- BinaryAnnotationIterator operator++(int) {
- BinaryAnnotationIterator Orig(*this);
- ++(*this);
- return Orig;
- }
-
- const AnnotationData &operator*() {
+ const DecodedAnnotation &operator*() {
ParseCurrentAnnotation();
return Current.getValue();
}
@@ -241,17 +236,17 @@ private:
(ThirdByte << 8) | FourthByte;
return -1;
- };
+ }
static int32_t DecodeSignedOperand(uint32_t Operand) {
if (Operand & 1)
return -(Operand >> 1);
return Operand >> 1;
- };
+ }
static int32_t DecodeSignedOperand(ArrayRef<uint8_t> &Annotations) {
return DecodeSignedOperand(GetCompressedAnnotation(Annotations));
- };
+ }
bool ParseCurrentAnnotation() {
if (Current.hasValue())
@@ -259,7 +254,7 @@ private:
Next = Data;
uint32_t Op = GetCompressedAnnotation(Next);
- AnnotationData Result;
+ DecodedAnnotation Result;
Result.OpCode = static_cast<BinaryAnnotationsOpCode>(Op);
switch (Result.OpCode) {
case BinaryAnnotationsOpCode::Invalid:
@@ -324,11 +319,12 @@ private:
break;
}
}
+ Result.Bytes = Data.take_front(Data.size() - Next.size());
Current = Result;
return true;
}
- Optional<AnnotationData> Current;
+ Optional<DecodedAnnotation> Current;
ArrayRef<uint8_t> Data;
ArrayRef<uint8_t> Next;
};
Modified: llvm/trunk/test/MC/COFF/cv-inline-linetable.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/cv-inline-linetable.s?rev=362037&r1=362036&r2=362037&view=diff
==============================================================================
--- llvm/trunk/test/MC/COFF/cv-inline-linetable.s (original)
+++ llvm/trunk/test/MC/COFF/cv-inline-linetable.s Wed May 29 14:26:25 2019
@@ -1,4 +1,7 @@
-# RUN: llvm-mc -triple=i686-pc-win32 -filetype=obj < %s | llvm-readobj --codeview | FileCheck %s
+# RUN: llvm-mc -triple=i686-pc-win32 -filetype=obj %s -o %t.o
+# RUN: llvm-readobj --codeview %t.o | FileCheck %s
+# RUN: llvm-objdump -d %t.o | FileCheck %s --check-prefix=ASM
+# RUN: llvm-pdbutil dump -symbols %t.o | FileCheck %s --check-prefix=PDB
.text
.def @feat.00;
.scl 3;
@@ -43,6 +46,40 @@ Lfunc_begin0:
retl
Lfunc_end0:
+# Check the disassembly so we have accurate instruction offsets in hex.
+# ASM-LABEL: ?baz@@YAXXZ:
+# ASM-NEXT: 0: {{.*}} pushl %eax
+# ASM-NEXT: 1: {{.*}} addl $6, 0
+# ASM-NEXT: 8: {{.*}} addl $4, 0
+# ASM-NEXT: f: {{.*}} movl $1, (%esp)
+# ASM-NEXT: 16: {{.*}} leal (%esp), %eax
+# ASM-NEXT: 19: {{.*}} addl %eax, 0
+# ASM-NEXT: 1f: {{.*}} addl $2, 0
+# ASM-NEXT: 26: {{.*}} addl $3, 0
+# ASM-NEXT: 2d: {{.*}} addl $5, 0
+# ASM-NEXT: 34: {{.*}} addl $7, 0
+# ASM-NEXT: 3b: {{.*}} popl %eax
+# ASM-NEXT: 3c: {{.*}} retl
+
+# PDB: S_GPROC32_ID {{.*}} `baz`
+# PDB: S_INLINESITE
+# PDB-NEXT: inlinee = 0x1003 (bar), parent = 0, end = 0
+# PDB-NEXT: 0B08 code 0x8 (+0x8) line 0 (-0)
+# PDB-NEXT: 0B27 code 0xF (+0x7) line 1 (+1)
+# PDB-NEXT: 0602 line 2 (+1)
+# PDB-NEXT: 031E code 0x2D (+0x1E)
+# PDB-NEXT: 0407 code end 0x34 (+0x7)
+# PDB: S_INLINESITE
+# PDB-NEXT: inlinee = 0x1004 (foo), parent = 0, end = 0
+# PDB-NEXT: 0B0F code 0xF (+0xF) line 0 (-0)
+# PDB-NEXT: 0B2A code 0x19 (+0xA) line 1 (+1)
+# PDB-NEXT: 0B26 code 0x1F (+0x6) line 2 (+1)
+# PDB-NEXT: 0B27 code 0x26 (+0x7) line 3 (+1)
+# PDB-NEXT: 0407 code end 0x2D (+0x7)
+# PEB: S_INLINESITE_END
+# PEB: S_INLINESITE_END
+# PEB: S_PROC_ID_END
+
.section .debug$T,"dr"
.long 4
.short 6
Modified: llvm/trunk/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/MinimalSymbolDumper.cpp?rev=362037&r1=362036&r2=362037&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/MinimalSymbolDumper.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/MinimalSymbolDumper.cpp Wed May 29 14:26:25 2019
@@ -650,13 +650,85 @@ Error MinimalSymbolDumper::visitKnownRec
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, InlineSiteSym &IS) {
AutoIndent Indent(P, 7);
- auto Bytes = makeArrayRef(IS.AnnotationData);
- StringRef Annotations(reinterpret_cast<const char *>(Bytes.begin()),
- Bytes.size());
-
P.formatLine("inlinee = {0}, parent = {1}, end = {2}", idIndex(IS.Inlinee),
IS.Parent, IS.End);
- P.formatLine("annotations = {0}", toHex(Annotations));
+
+ // Break down the annotation byte code and calculate code and line offsets.
+ // FIXME: It would be helpful if we could look up the initial file and inlinee
+ // lines offset using the inlinee index above.
+ uint32_t CodeOffset = 0;
+ int32_t LineOffset = 0;
+ for (auto &Annot : IS.annotations()) {
+ P.formatLine(" {0}", fmt_align(toHex(Annot.Bytes), AlignStyle::Left, 9));
+
+ auto formatCodeOffset = [&](uint32_t Delta) {
+ CodeOffset += Delta;
+ P.format(" code 0x{0} (+0x{1})", utohexstr(CodeOffset), utohexstr(Delta));
+ };
+ auto formatCodeLength = [&](uint32_t Length) {
+ // Notably, changing the code length does not affect the code offset.
+ P.format(" code end 0x{0} (+0x{1})", utohexstr(CodeOffset + Length),
+ utohexstr(Length));
+ };
+ auto formatLineOffset = [&](int32_t Delta) {
+ LineOffset += Delta;
+ char Sign = Delta > 0 ? '+' : '-';
+ P.format(" line {0} ({1}{2})", LineOffset, Sign, std::abs(Delta));
+ };
+
+ // Use the opcode to interpret the integer values.
+ switch (Annot.OpCode) {
+ case BinaryAnnotationsOpCode::Invalid:
+ break;
+ case BinaryAnnotationsOpCode::CodeOffset:
+ case BinaryAnnotationsOpCode::ChangeCodeOffset:
+ formatCodeOffset(Annot.U1);
+ break;
+ case BinaryAnnotationsOpCode::ChangeLineOffset:
+ formatLineOffset(Annot.S1);
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeLength:
+ formatCodeLength(Annot.U1);
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
+ formatCodeOffset(Annot.U1);
+ formatLineOffset(Annot.S1);
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
+ formatCodeOffset(Annot.U2);
+ formatCodeLength(Annot.U1);
+ break;
+
+ case BinaryAnnotationsOpCode::ChangeFile: {
+ uint32_t FileOffset = Annot.U1;
+ StringRef Filename = "<unknown>";
+ if (SymGroup) {
+ if (Expected<StringRef> MaybeFile =
+ SymGroup->getNameFromStringTable(FileOffset))
+ Filename = *MaybeFile;
+ else
+ return MaybeFile.takeError();
+ }
+ P.format(" setfile {0} 0x{1}", utohexstr(FileOffset));
+ break;
+ }
+
+ // The rest of these are hard to convince MSVC to emit, so they are not as
+ // well understood.
+ case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
+ formatCodeOffset(Annot.U1);
+ break;
+ case BinaryAnnotationsOpCode::ChangeLineEndDelta:
+ case BinaryAnnotationsOpCode::ChangeRangeKind:
+ case BinaryAnnotationsOpCode::ChangeColumnStart:
+ case BinaryAnnotationsOpCode::ChangeColumnEnd:
+ P.format(" {0} {1}", Annot.Name, Annot.U1);
+ break;
+ case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
+ P.format(" {0} {1}", Annot.Name, Annot.S1);
+ break;
+ }
+ }
return Error::success();
}
More information about the llvm-commits
mailing list