mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +01:00
[codeview] Dump CodeView inlinee lines subsection
llvm-svn: 257790
This commit is contained in:
parent
939b9c069c
commit
fc79a7dd17
@ -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
|
||||
|
BIN
test/tools/llvm-readobj/Inputs/codeview-inlining.obj.coff
Normal file
BIN
test/tools/llvm-readobj/Inputs/codeview-inlining.obj.coff
Normal file
Binary file not shown.
65
test/tools/llvm-readobj/codeview-inlining.test
Normal file
65
test/tools/llvm-readobj/codeview-inlining.test
Normal file
@ -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: }
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user