summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2016-01-14 19:20:17 +0000
committerReid Kleckner <rnk@google.com>2016-01-14 19:20:17 +0000
commite9ab3498f3dada67659871617d4e47e8c2a41bc9 (patch)
treed3c9d09682e5373382a58d5d53a4583555d908ef
parent1f242d6a776aa6759af39ce4581dc7a015da9f72 (diff)
downloadbcm5719-llvm-e9ab3498f3dada67659871617d4e47e8c2a41bc9.tar.gz
bcm5719-llvm-e9ab3498f3dada67659871617d4e47e8c2a41bc9.zip
[codeview] Dump CodeView inlinee lines subsection
llvm-svn: 257790
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/Line.h22
-rw-r--r--llvm/test/tools/llvm-readobj/Inputs/codeview-inlining.obj.coffbin0 -> 8396 bytes
-rw-r--r--llvm/test/tools/llvm-readobj/codeview-inlining.test65
-rw-r--r--llvm/tools/llvm-readobj/COFFDumper.cpp36
4 files changed, 121 insertions, 2 deletions
diff --git a/llvm/include/llvm/DebugInfo/CodeView/Line.h b/llvm/include/llvm/DebugInfo/CodeView/Line.h
index a7cdbdaac32..b466ca6e223 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/Line.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/Line.h
@@ -10,11 +10,14 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_LINE_H
#define LLVM_DEBUGINFO_CODEVIEW_LINE_H
+#include "llvm/Support/Endian.h"
#include <cinttypes>
namespace llvm {
namespace codeview {
+using llvm::support::ulittle32_t;
+
class LineInfo {
public:
static const uint32_t AlwaysStepIntoLineNumber = 0xfeefee;
@@ -118,7 +121,22 @@ public:
bool isNeverStepInto() const { return LineInf.isNeverStepInto(); }
};
-}
-}
+
+enum class InlineeLinesSignature : uint32_t {
+ Normal, // CV_INLINEE_SOURCE_LINE_SIGNATURE
+ ExtraFiles // CV_INLINEE_SOURCE_LINE_SIGNATURE_EX
+};
+
+struct InlineeSourceLine {
+ TypeIndex Inlinee; // ID of the function that was inlined.
+ ulittle32_t FileID; // Offset into FileChecksums subsection.
+ ulittle32_t SourceLineNum; // First line of inlined code.
+ // If extra files present:
+ // ulittle32_t ExtraFileCount;
+ // ulittle32_t Files[];
+};
+
+} // namespace codeview
+} // namespace llvm
#endif
diff --git a/llvm/test/tools/llvm-readobj/Inputs/codeview-inlining.obj.coff b/llvm/test/tools/llvm-readobj/Inputs/codeview-inlining.obj.coff
new file mode 100644
index 00000000000..782e991c3bc
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/Inputs/codeview-inlining.obj.coff
Binary files differ
diff --git a/llvm/test/tools/llvm-readobj/codeview-inlining.test b/llvm/test/tools/llvm-readobj/codeview-inlining.test
new file mode 100644
index 00000000000..13be86b6337
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/codeview-inlining.test
@@ -0,0 +1,65 @@
+; The following two object files were generated using the following command:
+; $ cl /d2Zi+ /Zc:inline /O2 /Z7 /c t.cpp
+; The contents of t.cpp follow:
+; static void bar() {
+; __asm nop
+; }
+; static void baz() {
+; __asm nop
+; }
+; static __forceinline void foo() {
+; __asm nop
+; #include "a.h"
+; #include "b.h"
+; __asm nop
+; goto forwards;
+;
+; backwards:
+; __asm nop
+; return;
+;
+; forwards:
+; __asm rep nop
+; goto backwards;
+; }
+; int main() {
+; bar();
+; baz();
+; foo();
+; }
+;
+; Both a.h and b.h contain "__asm nop".
+
+RUN: llvm-readobj -s -codeview -section-symbols %p/Inputs/codeview-inlining.obj.coff | FileCheck %s
+
+; FIXME: If we were more clever, we could turn FileIDs into paths.
+
+; CHECK: SubSectionType: InlineeLines (0xF6)
+; CHECK-NEXT: SubSectionSize: 0x3C
+; CHECK-NEXT: InlineeSourceLine {
+; CHECK-NEXT: Inlinee: bar (0x1002)
+; CHECK-NEXT: FileID: 0x30
+; CHECK-NEXT: SourceLineNum: 2
+; CHECK-NEXT: ExtraFileCount: 0
+; CHECK-NEXT: ExtraFiles [
+; CHECK-NEXT: ]
+; CHECK-NEXT: }
+; CHECK-NEXT: InlineeSourceLine {
+; CHECK-NEXT: Inlinee: baz (0x1003)
+; CHECK-NEXT: FileID: 0x30
+; CHECK-NEXT: SourceLineNum: 5
+; CHECK-NEXT: ExtraFileCount: 0
+; CHECK-NEXT: ExtraFiles [
+; CHECK-NEXT: ]
+; CHECK-NEXT: }
+; The 'foo' inline site has extra files due to includes.
+; CHECK-NEXT: InlineeSourceLine {
+; CHECK-NEXT: Inlinee: foo (0x1004)
+; CHECK-NEXT: FileID: 0x0
+; CHECK-NEXT: SourceLineNum: 1
+; CHECK-NEXT: ExtraFileCount: 2
+; CHECK-NEXT: ExtraFiles [
+; CHECK-NEXT: FileID: 0x18
+; CHECK-NEXT: FileID: 0x30
+; CHECK-NEXT: ]
+; CHECK-NEXT: }
diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp
index e521c3a8fa5..b600fa63261 100644
--- a/llvm/tools/llvm-readobj/COFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/COFFDumper.cpp
@@ -25,6 +25,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/Line.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
@@ -91,6 +92,8 @@ private:
const SectionRef &Section,
StringRef SectionContents);
+ void printCodeViewInlineeLines(StringRef Subsection);
+
void printMemberAttributes(MemberAttributes Attrs);
void printRelocatedField(StringRef Label, const coff_section *Sec,
@@ -991,6 +994,11 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName,
case ModuleSubstreamKind::Symbols:
printCodeViewSymbolsSubsection(Contents, Section, SectionContents);
break;
+
+ case ModuleSubstreamKind::InlineeLines:
+ printCodeViewInlineeLines(Contents);
+ break;
+
case ModuleSubstreamKind::Lines: {
// Holds a PC to file:line table. Some data to parse this subsection is
// stored in the other subsections, so just check sanity and store the
@@ -1685,6 +1693,34 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
}
}
+void COFFDumper::printCodeViewInlineeLines(StringRef Subsection) {
+ StringRef Data = Subsection;
+ uint32_t Signature;
+ error(consumeUInt32(Data, Signature));
+ bool HasExtraFiles = Signature == unsigned(InlineeLinesSignature::ExtraFiles);
+
+ while (!Data.empty()) {
+ const InlineeSourceLine *ISL;
+ error(consumeObject(Data, ISL));
+ DictScope S(W, "InlineeSourceLine");
+ printTypeIndex("Inlinee", ISL->Inlinee);
+ W.printHex("FileID", ISL->FileID);
+ W.printNumber("SourceLineNum", ISL->SourceLineNum);
+
+ if (HasExtraFiles) {
+ uint32_t ExtraFileCount;
+ error(consumeUInt32(Data, ExtraFileCount));
+ W.printNumber("ExtraFileCount", ExtraFileCount);
+ ListScope ExtraFiles(W, "ExtraFiles");
+ for (unsigned I = 0; I < ExtraFileCount; ++I) {
+ uint32_t FileID;
+ error(consumeUInt32(Data, FileID));
+ W.printHex("FileID", FileID);
+ }
+ }
+ }
+}
+
StringRef getRemainingTypeBytes(const TypeRecordPrefix *Rec, const char *Start) {
ptrdiff_t StartOffset = Start - reinterpret_cast<const char *>(Rec);
size_t RecSize = Rec->Len + 2;
OpenPOWER on IntegriCloud