summaryrefslogtreecommitdiff
path: root/include/llvm/DebugInfo/CodeView
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/DebugInfo/CodeView')
-rw-r--r--include/llvm/DebugInfo/CodeView/CodeView.h5
-rw-r--r--include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h1
-rw-r--r--include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h2
-rw-r--r--include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h7
-rw-r--r--include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h80
-rw-r--r--include/llvm/DebugInfo/CodeView/Formatters.h17
-rw-r--r--include/llvm/DebugInfo/CodeView/StringsAndChecksums.h106
-rw-r--r--include/llvm/DebugInfo/CodeView/SymbolRecord.h10
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeIndex.h2
9 files changed, 158 insertions, 72 deletions
diff --git a/include/llvm/DebugInfo/CodeView/CodeView.h b/include/llvm/DebugInfo/CodeView/CodeView.h
index 251c9d1ae62c9..6820e26b754c0 100644
--- a/include/llvm/DebugInfo/CodeView/CodeView.h
+++ b/include/llvm/DebugInfo/CodeView/CodeView.h
@@ -418,6 +418,8 @@ CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ProcSymFlags)
/// Corresponds to COMPILESYM2::Flags bitfield.
enum class CompileSym2Flags : uint32_t {
+ None = 0,
+ SourceLanguageMask = 0xFF,
EC = 1 << 8,
NoDbgInfo = 1 << 9,
LTCG = 1 << 10,
@@ -432,6 +434,8 @@ CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(CompileSym2Flags)
/// Corresponds to COMPILESYM3::Flags bitfield.
enum class CompileSym3Flags : uint32_t {
+ None = 0,
+ SourceLanguageMask = 0xFF,
EC = 1 << 8,
NoDbgInfo = 1 << 9,
LTCG = 1 << 10,
@@ -448,6 +452,7 @@ enum class CompileSym3Flags : uint32_t {
CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(CompileSym3Flags)
enum class ExportFlags : uint16_t {
+ None = 0,
IsConstant = 1 << 0,
IsData = 1 << 1,
IsPrivate = 1 << 2,
diff --git a/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h b/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h
index 686b5c4f242e3..1e329c7c3f141 100644
--- a/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h
+++ b/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h
@@ -49,6 +49,7 @@ public:
Error commit(BinaryStreamWriter &Writer) const override;
void addFrameData(const FrameData &Frame);
+ void setFrames(ArrayRef<FrameData> Frames);
private:
std::vector<FrameData> Frames;
diff --git a/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h b/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h
index c9b062717baaa..7484af6631051 100644
--- a/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h
+++ b/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h
@@ -19,7 +19,7 @@
namespace llvm {
namespace codeview {
-class DebugInlineeLinesSubsectionsRef;
+class DebugInlineeLinesSubsectionRef;
class DebugChecksumsSubsection;
enum class InlineeLinesSignature : uint32_t {
diff --git a/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h b/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h
index 49a269d92e35d..6947317420643 100644
--- a/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h
+++ b/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h
@@ -49,13 +49,13 @@ private:
class DebugSubsectionRecordBuilder {
public:
- DebugSubsectionRecordBuilder(std::unique_ptr<DebugSubsection> Subsection,
+ DebugSubsectionRecordBuilder(std::shared_ptr<DebugSubsection> Subsection,
CodeViewContainer Container);
uint32_t calculateSerializedLength();
Error commit(BinaryStreamWriter &Writer) const;
private:
- std::unique_ptr<DebugSubsection> Subsection;
+ std::shared_ptr<DebugSubsection> Subsection;
CodeViewContainer Container;
};
@@ -64,6 +64,9 @@ private:
template <> struct VarStreamArrayExtractor<codeview::DebugSubsectionRecord> {
Error operator()(BinaryStreamRef Stream, uint32_t &Length,
codeview::DebugSubsectionRecord &Info) {
+ // FIXME: We need to pass the container type through to this function. In
+ // practice this isn't super important since the subsection header describes
+ // its length and we can just skip it. It's more important when writing.
if (auto EC = codeview::DebugSubsectionRecord::initialize(
Stream, Info, codeview::CodeViewContainer::Pdb))
return EC;
diff --git a/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h b/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h
index d4a3d9195a366..75f749dfa9334 100644
--- a/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h
+++ b/include/llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h
@@ -12,6 +12,7 @@
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
+#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
#include "llvm/Support/Error.h"
#include <cstdint>
@@ -30,56 +31,7 @@ class DebugStringTableSubsectionRef;
class DebugSymbolRVASubsectionRef;
class DebugSymbolsSubsectionRef;
class DebugUnknownSubsectionRef;
-
-struct DebugSubsectionState {
-public:
- // If no subsections are known about initially, we find as much as we can.
- DebugSubsectionState();
-
- // If only a string table subsection is given, we find a checksums subsection.
- explicit DebugSubsectionState(const DebugStringTableSubsectionRef &Strings);
-
- // If both subsections are given, we don't need to find anything.
- DebugSubsectionState(const DebugStringTableSubsectionRef &Strings,
- const DebugChecksumsSubsectionRef &Checksums);
-
- template <typename T> void initialize(T &&FragmentRange) {
- for (const DebugSubsectionRecord &R : FragmentRange) {
- if (Strings && Checksums)
- return;
- if (R.kind() == DebugSubsectionKind::FileChecksums) {
- initializeChecksums(R);
- continue;
- }
- if (R.kind() == DebugSubsectionKind::StringTable && !Strings) {
- // While in practice we should never encounter a string table even
- // though the string table is already initialized, in theory it's
- // possible. PDBs are supposed to have one global string table and
- // then this subsection should not appear. Whereas object files are
- // supposed to have this subsection appear exactly once. However,
- // for testing purposes it's nice to be able to test this subsection
- // independently of one format or the other, so for some tests we
- // manually construct a PDB that contains this subsection in addition
- // to a global string table.
- initializeStrings(R);
- continue;
- }
- }
- }
-
- const DebugStringTableSubsectionRef &strings() const { return *Strings; }
- const DebugChecksumsSubsectionRef &checksums() const { return *Checksums; }
-
-private:
- void initializeStrings(const DebugSubsectionRecord &SR);
- void initializeChecksums(const DebugSubsectionRecord &FCR);
-
- std::unique_ptr<DebugStringTableSubsectionRef> OwnedStrings;
- std::unique_ptr<DebugChecksumsSubsectionRef> OwnedChecksums;
-
- const DebugStringTableSubsectionRef *Strings = nullptr;
- const DebugChecksumsSubsectionRef *Checksums = nullptr;
-};
+class StringsAndChecksumsRef;
class DebugSubsectionVisitor {
public:
@@ -89,38 +41,38 @@ public:
return Error::success();
}
virtual Error visitLines(DebugLinesSubsectionRef &Lines,
- const DebugSubsectionState &State) = 0;
+ const StringsAndChecksumsRef &State) = 0;
virtual Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums,
- const DebugSubsectionState &State) = 0;
+ const StringsAndChecksumsRef &State) = 0;
virtual Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees,
- const DebugSubsectionState &State) = 0;
+ const StringsAndChecksumsRef &State) = 0;
virtual Error
visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef &CSE,
- const DebugSubsectionState &State) = 0;
+ const StringsAndChecksumsRef &State) = 0;
virtual Error
visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &CSE,
- const DebugSubsectionState &State) = 0;
+ const StringsAndChecksumsRef &State) = 0;
virtual Error visitStringTable(DebugStringTableSubsectionRef &ST,
- const DebugSubsectionState &State) = 0;
+ const StringsAndChecksumsRef &State) = 0;
virtual Error visitSymbols(DebugSymbolsSubsectionRef &CSE,
- const DebugSubsectionState &State) = 0;
+ const StringsAndChecksumsRef &State) = 0;
virtual Error visitFrameData(DebugFrameDataSubsectionRef &FD,
- const DebugSubsectionState &State) = 0;
+ const StringsAndChecksumsRef &State) = 0;
virtual Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &RVAs,
- const DebugSubsectionState &State) = 0;
+ const StringsAndChecksumsRef &State) = 0;
};
Error visitDebugSubsection(const DebugSubsectionRecord &R,
DebugSubsectionVisitor &V,
- const DebugSubsectionState &State);
+ const StringsAndChecksumsRef &State);
namespace detail {
template <typename T>
Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V,
- DebugSubsectionState &State) {
+ StringsAndChecksumsRef &State) {
State.initialize(std::forward<T>(FragmentRange));
for (const DebugSubsectionRecord &L : FragmentRange) {
@@ -133,7 +85,7 @@ Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V,
template <typename T>
Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V) {
- DebugSubsectionState State;
+ StringsAndChecksumsRef State;
return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V,
State);
}
@@ -141,7 +93,7 @@ Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V) {
template <typename T>
Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V,
const DebugStringTableSubsectionRef &Strings) {
- DebugSubsectionState State(Strings);
+ StringsAndChecksumsRef State(Strings);
return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V,
State);
}
@@ -150,7 +102,7 @@ template <typename T>
Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V,
const DebugStringTableSubsectionRef &Strings,
const DebugChecksumsSubsectionRef &Checksums) {
- DebugSubsectionState State(Strings, Checksums);
+ StringsAndChecksumsRef State(Strings, Checksums);
return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V,
State);
}
diff --git a/include/llvm/DebugInfo/CodeView/Formatters.h b/include/llvm/DebugInfo/CodeView/Formatters.h
index 37a91098a8b65..1fbb0dd6f9b00 100644
--- a/include/llvm/DebugInfo/CodeView/Formatters.h
+++ b/include/llvm/DebugInfo/CodeView/Formatters.h
@@ -12,7 +12,10 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/Support/FormatAdapters.h"
+#include "llvm/Support/FormatProviders.h"
+#include "llvm/Support/FormatVariadic.h"
namespace llvm {
namespace codeview {
@@ -35,6 +38,20 @@ inline detail::GuidAdapter fmt_guid(ArrayRef<uint8_t> Item) {
return detail::GuidAdapter(Item);
}
}
+
+template <> struct format_provider<codeview::TypeIndex> {
+public:
+ static void format(const codeview::TypeIndex &V, llvm::raw_ostream &Stream,
+ StringRef Style) {
+ if (V.isNoneType())
+ Stream << "<no type>";
+ else {
+ Stream << formatv("{0:X+4}", V.getIndex());
+ if (V.isSimple())
+ Stream << " (" << codeview::TypeIndex::simpleTypeName(V) << ")";
+ }
+ }
+};
}
#endif
diff --git a/include/llvm/DebugInfo/CodeView/StringsAndChecksums.h b/include/llvm/DebugInfo/CodeView/StringsAndChecksums.h
new file mode 100644
index 0000000000000..708b317164fc7
--- /dev/null
+++ b/include/llvm/DebugInfo/CodeView/StringsAndChecksums.h
@@ -0,0 +1,106 @@
+//===- StringsAndChecksums.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_STRINGS_AND_CHECKSUMS_H
+#define LLVM_DEBUGINFO_CODEVIEW_STRINGS_AND_CHECKSUMS_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
+
+#include <memory>
+
+namespace llvm {
+namespace codeview {
+
+class DebugSubsectionRecord;
+class DebugChecksumsSubsectionRef;
+class DebugStringTableSubsectionRef;
+class DebugChecksumsSubsection;
+class DebugStringTableSubsection;
+
+class StringsAndChecksumsRef {
+public:
+ // If no subsections are known about initially, we find as much as we can.
+ StringsAndChecksumsRef();
+
+ // If only a string table subsection is given, we find a checksums subsection.
+ explicit StringsAndChecksumsRef(const DebugStringTableSubsectionRef &Strings);
+
+ // If both subsections are given, we don't need to find anything.
+ StringsAndChecksumsRef(const DebugStringTableSubsectionRef &Strings,
+ const DebugChecksumsSubsectionRef &Checksums);
+
+ void setChecksums(const DebugChecksumsSubsectionRef &CS);
+
+ template <typename T> void initialize(T &&FragmentRange) {
+ for (const DebugSubsectionRecord &R : FragmentRange) {
+ if (Strings && Checksums)
+ return;
+ if (R.kind() == DebugSubsectionKind::FileChecksums) {
+ initializeChecksums(R);
+ continue;
+ }
+ if (R.kind() == DebugSubsectionKind::StringTable && !Strings) {
+ // While in practice we should never encounter a string table even
+ // though the string table is already initialized, in theory it's
+ // possible. PDBs are supposed to have one global string table and
+ // then this subsection should not appear. Whereas object files are
+ // supposed to have this subsection appear exactly once. However,
+ // for testing purposes it's nice to be able to test this subsection
+ // independently of one format or the other, so for some tests we
+ // manually construct a PDB that contains this subsection in addition
+ // to a global string table.
+ initializeStrings(R);
+ continue;
+ }
+ }
+ }
+
+ const DebugStringTableSubsectionRef &strings() const { return *Strings; }
+ const DebugChecksumsSubsectionRef &checksums() const { return *Checksums; }
+
+ bool hasStrings() const { return Strings != nullptr; }
+ bool hasChecksums() const { return Checksums != nullptr; }
+
+private:
+ void initializeStrings(const DebugSubsectionRecord &SR);
+ void initializeChecksums(const DebugSubsectionRecord &FCR);
+
+ std::unique_ptr<DebugStringTableSubsectionRef> OwnedStrings;
+ std::unique_ptr<DebugChecksumsSubsectionRef> OwnedChecksums;
+
+ const DebugStringTableSubsectionRef *Strings = nullptr;
+ const DebugChecksumsSubsectionRef *Checksums = nullptr;
+};
+
+class StringsAndChecksums {
+public:
+ using StringsPtr = std::shared_ptr<DebugStringTableSubsection>;
+ using ChecksumsPtr = std::shared_ptr<DebugChecksumsSubsection>;
+ // If no subsections are known about initially, we find as much as we can.
+ StringsAndChecksums() {}
+
+ void setStrings(const StringsPtr &SP) { Strings = SP; }
+ void setChecksums(const ChecksumsPtr &CP) { Checksums = CP; }
+
+ const StringsPtr &strings() const { return Strings; }
+ const ChecksumsPtr &checksums() const { return Checksums; }
+
+ bool hasStrings() const { return Strings != nullptr; }
+ bool hasChecksums() const { return Checksums != nullptr; }
+
+private:
+ StringsPtr Strings;
+ ChecksumsPtr Checksums;
+};
+
+} // namespace codeview
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/include/llvm/DebugInfo/CodeView/SymbolRecord.h
index a3e4dff647bd7..5f85ed28cb3a1 100644
--- a/include/llvm/DebugInfo/CodeView/SymbolRecord.h
+++ b/include/llvm/DebugInfo/CodeView/SymbolRecord.h
@@ -363,7 +363,7 @@ public:
: SymbolRecord(SymbolRecordKind::PublicSym32),
RecordOffset(RecordOffset) {}
- uint32_t Index;
+ TypeIndex Index;
uint32_t Offset;
uint16_t Segment;
StringRef Name;
@@ -379,7 +379,7 @@ public:
: SymbolRecord(SymbolRecordKind::RegisterSym),
RecordOffset(RecordOffset) {}
- uint32_t Index;
+ TypeIndex Index;
RegisterId Register;
StringRef Name;
@@ -679,7 +679,7 @@ public:
: SymbolRecord(SymbolRecordKind::FileStaticSym),
RecordOffset(RecordOffset) {}
- uint32_t Index;
+ TypeIndex Index;
uint32_t ModFilenameOffset;
LocalSymFlags Flags;
StringRef Name;
@@ -814,7 +814,7 @@ public:
uint32_t CodeOffset;
uint16_t Register;
- uint8_t CookieKind;
+ FrameCookieKind CookieKind;
uint8_t Flags;
uint32_t RecordOffset;
@@ -871,7 +871,7 @@ public:
uint32_t Offset;
TypeIndex Type;
- uint16_t Register;
+ RegisterId Register;
StringRef Name;
uint32_t RecordOffset;
diff --git a/include/llvm/DebugInfo/CodeView/TypeIndex.h b/include/llvm/DebugInfo/CodeView/TypeIndex.h
index 31eed7d3e877a..10d51c2d6244f 100644
--- a/include/llvm/DebugInfo/CodeView/TypeIndex.h
+++ b/include/llvm/DebugInfo/CodeView/TypeIndex.h
@@ -248,6 +248,8 @@ public:
return A.toArrayIndex() - B.toArrayIndex();
}
+ static StringRef simpleTypeName(TypeIndex TI);
+
private:
support::ulittle32_t Index;
};