diff --git a/include/llvm/DebugInfo/CodeView/CodeView.h b/include/llvm/DebugInfo/CodeView/CodeView.h index f12b47e30be..3316e71916e 100644 --- a/include/llvm/DebugInfo/CodeView/CodeView.h +++ b/include/llvm/DebugInfo/CodeView/CodeView.h @@ -13,6 +13,8 @@ #include #include +#include "llvm/Support/Endian.h" + namespace llvm { namespace codeview { @@ -550,6 +552,24 @@ enum LineFlags : uint16_t { LF_None = 0, LF_HaveColumns = 1, // CV_LINES_HAVE_COLUMNS }; + +/// Data in the the SUBSEC_FRAMEDATA subection. +struct FrameData { + support::ulittle32_t RvaStart; + support::ulittle32_t CodeSize; + support::ulittle32_t LocalSize; + support::ulittle32_t ParamsSize; + support::ulittle32_t MaxStackSize; + support::ulittle32_t FrameFunc; + support::ulittle16_t PrologSize; + support::ulittle16_t SavedRegsSize; + support::ulittle32_t Flags; + enum : uint32_t { + HasSEH = 1 << 0, + HasEH = 1 << 1, + IsFunctionStart = 1 << 2, + }; +}; } } diff --git a/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h b/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h index 47cfa808063..e7036033d2d 100644 --- a/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h +++ b/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h @@ -21,7 +21,7 @@ namespace llvm { namespace codeview { -class StringTable; +class DebugStringTableSubsection; struct FileChecksumEntry { uint32_t FileNameOffset; // Byte offset of filename in global stringtable. @@ -55,7 +55,10 @@ public: return S->kind() == DebugSubsectionKind::FileChecksums; } + bool valid() const { return Checksums.valid(); } + Error initialize(BinaryStreamReader Reader); + Error initialize(BinaryStreamRef Stream); Iterator begin() { return Checksums.begin(); } Iterator end() { return Checksums.end(); } @@ -68,7 +71,7 @@ private: class DebugChecksumsSubsection final : public DebugSubsection { public: - explicit DebugChecksumsSubsection(StringTable &Strings); + explicit DebugChecksumsSubsection(DebugStringTableSubsection &Strings); static bool classof(const DebugSubsection *S) { return S->kind() == DebugSubsectionKind::FileChecksums; @@ -77,12 +80,12 @@ public: void addChecksum(StringRef FileName, FileChecksumKind Kind, ArrayRef Bytes); - uint32_t calculateSerializedLength() override; - Error commit(BinaryStreamWriter &Writer) override; + uint32_t calculateSerializedSize() const override; + Error commit(BinaryStreamWriter &Writer) const override; uint32_t mapChecksumOffset(StringRef FileName) const; private: - StringTable &Strings; + DebugStringTableSubsection &Strings; DenseMap OffsetMap; uint32_t SerializedSize = 0; diff --git a/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h b/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h new file mode 100644 index 00000000000..686b5c4f242 --- /dev/null +++ b/include/llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h @@ -0,0 +1,59 @@ +//===- DebugFrameDataSubsection.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_DEBUGFRAMEDATASUBSECTION_H +#define LLVM_DEBUGINFO_CODEVIEW_DEBUGFRAMEDATASUBSECTION_H + +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/DebugSubsection.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/Error.h" + +namespace llvm { +namespace codeview { +class DebugFrameDataSubsectionRef final : public DebugSubsectionRef { +public: + DebugFrameDataSubsectionRef() + : DebugSubsectionRef(DebugSubsectionKind::FrameData) {} + static bool classof(const DebugSubsection *S) { + return S->kind() == DebugSubsectionKind::FrameData; + } + + Error initialize(BinaryStreamReader Reader); + + FixedStreamArray::Iterator begin() const { return Frames.begin(); } + FixedStreamArray::Iterator end() const { return Frames.end(); } + + const void *getRelocPtr() const { return RelocPtr; } + +private: + const uint32_t *RelocPtr = nullptr; + FixedStreamArray Frames; +}; + +class DebugFrameDataSubsection final : public DebugSubsection { +public: + DebugFrameDataSubsection() + : DebugSubsection(DebugSubsectionKind::FrameData) {} + static bool classof(const DebugSubsection *S) { + return S->kind() == DebugSubsectionKind::FrameData; + } + + uint32_t calculateSerializedSize() const override; + Error commit(BinaryStreamWriter &Writer) const override; + + void addFrameData(const FrameData &Frame); + +private: + std::vector Frames; +}; +} +} + +#endif diff --git a/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h b/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h index 0fd2fae010f..e2cfc3c9923 100644 --- a/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h +++ b/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h @@ -21,7 +21,6 @@ namespace codeview { class DebugInlineeLinesSubsectionsRef; class DebugChecksumsSubsection; -class StringTable; enum class InlineeLinesSignature : uint32_t { Normal, // CV_INLINEE_SOURCE_LINE_SIGNATURE @@ -82,8 +81,8 @@ public: return S->kind() == DebugSubsectionKind::InlineeLines; } - Error commit(BinaryStreamWriter &Writer) override; - uint32_t calculateSerializedLength() override; + Error commit(BinaryStreamWriter &Writer) const override; + uint32_t calculateSerializedSize() const override; void addInlineSite(TypeIndex FuncId, StringRef FileName, uint32_t SourceLine); void addExtraFile(StringRef FileName); diff --git a/include/llvm/DebugInfo/CodeView/DebugLinesSubsection.h b/include/llvm/DebugInfo/CodeView/DebugLinesSubsection.h index c35ae860b26..1b63af59c2e 100644 --- a/include/llvm/DebugInfo/CodeView/DebugLinesSubsection.h +++ b/include/llvm/DebugInfo/CodeView/DebugLinesSubsection.h @@ -20,7 +20,7 @@ namespace llvm { namespace codeview { class DebugChecksumsSubsection; -class StringTable; +class DebugStringTableSubsection; // Corresponds to the `CV_DebugSLinesHeader_t` structure. struct LineFragmentHeader { @@ -108,7 +108,7 @@ class DebugLinesSubsection final : public DebugSubsection { public: DebugLinesSubsection(DebugChecksumsSubsection &Checksums, - StringTable &Strings); + DebugStringTableSubsection &Strings); static bool classof(const DebugSubsection *S) { return S->kind() == DebugSubsectionKind::Lines; @@ -119,8 +119,8 @@ public: void addLineAndColumnInfo(uint32_t Offset, const LineInfo &Line, uint32_t ColStart, uint32_t ColEnd); - uint32_t calculateSerializedLength() override; - Error commit(BinaryStreamWriter &Writer) override; + uint32_t calculateSerializedSize() const override; + Error commit(BinaryStreamWriter &Writer) const override; void setRelocationAddress(uint16_t Segment, uint16_t Offset); void setCodeSize(uint32_t Size); diff --git a/include/llvm/DebugInfo/CodeView/StringTable.h b/include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h similarity index 55% rename from include/llvm/DebugInfo/CodeView/StringTable.h rename to include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h index 05dc02ee849..fbe39cb16f0 100644 --- a/include/llvm/DebugInfo/CodeView/StringTable.h +++ b/include/llvm/DebugInfo/CodeView/DebugStringTableSubsection.h @@ -1,4 +1,4 @@ -//===- StringTable.h - CodeView String Table Reader/Writer ------*- C++ -*-===// +//===- DebugStringTableSubsection.h - CodeView String Table -----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,12 +7,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DEBUGINFO_CODEVIEW_STRINGTABLE_H -#define LLVM_DEBUGINFO_CODEVIEW_STRINGTABLE_H +#ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGSTRINGTABLESUBSECTION_H +#define LLVM_DEBUGINFO_CODEVIEW_DEBUGSTRINGTABLESUBSECTION_H #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" - +#include "llvm/DebugInfo/CodeView/DebugSubsection.h" #include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/Error.h" @@ -28,11 +28,15 @@ namespace codeview { /// Represents a read-only view of a CodeView string table. This is a very /// simple flat buffer consisting of null-terminated strings, where strings -/// are retrieved by their offset in the buffer. StringTableRef does not own -/// the underlying storage for the buffer. -class StringTableRef { +/// are retrieved by their offset in the buffer. DebugStringTableSubsectionRef +/// does not own the underlying storage for the buffer. +class DebugStringTableSubsectionRef : public DebugSubsectionRef { public: - StringTableRef(); + DebugStringTableSubsectionRef(); + + static bool classof(const DebugSubsectionRef *S) { + return S->kind() == DebugSubsectionKind::StringTable; + } Error initialize(BinaryStreamRef Contents); @@ -44,11 +48,18 @@ private: BinaryStreamRef Stream; }; -/// Represents a read-write view of a CodeView string table. StringTable owns -/// the underlying storage for the table, and is capable of serializing the -/// string table into a format understood by StringTableRef. -class StringTable { +/// Represents a read-write view of a CodeView string table. +/// DebugStringTableSubsection owns the underlying storage for the table, and is +/// capable of serializing the string table into a format understood by +/// DebugStringTableSubsectionRef. +class DebugStringTableSubsection : public DebugSubsection { public: + DebugStringTableSubsection(); + + static bool classof(const DebugSubsection *S) { + return S->kind() == DebugSubsectionKind::StringTable; + } + // If string S does not exist in the string table, insert it. // Returns the ID for S. uint32_t insert(StringRef S); @@ -56,8 +67,8 @@ public: // Return the ID for string S. Assumes S exists in the table. uint32_t getStringId(StringRef S) const; - uint32_t calculateSerializedSize() const; - Error commit(BinaryStreamWriter &Writer) const; + uint32_t calculateSerializedSize() const override; + Error commit(BinaryStreamWriter &Writer) const override; uint32_t size() const; diff --git a/include/llvm/DebugInfo/CodeView/DebugSubsection.h b/include/llvm/DebugInfo/CodeView/DebugSubsection.h index e022d2b6a3a..e427e0006a5 100644 --- a/include/llvm/DebugInfo/CodeView/DebugSubsection.h +++ b/include/llvm/DebugInfo/CodeView/DebugSubsection.h @@ -22,6 +22,8 @@ public: explicit DebugSubsectionRef(DebugSubsectionKind Kind) : Kind(Kind) {} virtual ~DebugSubsectionRef(); + static bool classof(const DebugSubsectionRef *S) { return true; } + DebugSubsectionKind kind() const { return Kind; } protected: @@ -33,10 +35,12 @@ public: explicit DebugSubsection(DebugSubsectionKind Kind) : Kind(Kind) {} virtual ~DebugSubsection(); + static bool classof(const DebugSubsection *S) { return true; } + DebugSubsectionKind kind() const { return Kind; } - virtual Error commit(BinaryStreamWriter &Writer) = 0; - virtual uint32_t calculateSerializedLength() = 0; + virtual Error commit(BinaryStreamWriter &Writer) const = 0; + virtual uint32_t calculateSerializedSize() const = 0; protected: DebugSubsectionKind Kind; diff --git a/include/llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h b/include/llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h new file mode 100644 index 00000000000..3d1eb27ba27 --- /dev/null +++ b/include/llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h @@ -0,0 +1,53 @@ +//===- DebugSymbolsSubsection.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_DEBUGSYMBOLSSUBSECTION_H +#define LLVM_DEBUGINFO_CODEVIEW_DEBUGSYMBOLSSUBSECTION_H + +#include "llvm/DebugInfo/CodeView/DebugSubsection.h" +#include "llvm/DebugInfo/CodeView/SymbolRecord.h" +#include "llvm/Support/Error.h" + +namespace llvm { +namespace codeview { +class DebugSymbolsSubsectionRef final : public DebugSubsectionRef { +public: + DebugSymbolsSubsectionRef() + : DebugSubsectionRef(DebugSubsectionKind::Symbols) {} + + static bool classof(const DebugSubsectionRef *S) { + return S->kind() == DebugSubsectionKind::Symbols; + } + + Error initialize(BinaryStreamReader Reader); + +private: + CVSymbolArray Records; +}; + +class DebugSymbolsSubsection final : public DebugSubsection { +public: + DebugSymbolsSubsection() : DebugSubsection(DebugSubsectionKind::Symbols) {} + static bool classof(const DebugSubsection *S) { + return S->kind() == DebugSubsectionKind::Symbols; + } + + uint32_t calculateSerializedSize() const override; + Error commit(BinaryStreamWriter &Writer) const override; + + void addSymbol(CVSymbol Symbol); + +private: + uint32_t Length = 0; + std::vector Records; +}; +} +} + +#endif diff --git a/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h b/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h index 96c8a47a366..a2a3c6f18fb 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h +++ b/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h @@ -19,7 +19,7 @@ class BinaryStreamReader; namespace codeview { -class StringTableRef; +class DebugStringTableSubsectionRef; class SymbolVisitorDelegate { public: @@ -27,7 +27,7 @@ public: virtual uint32_t getRecordOffset(BinaryStreamReader Reader) = 0; virtual StringRef getFileNameForFileOffset(uint32_t FileOffset) = 0; - virtual StringTableRef getStringTable() = 0; + virtual DebugStringTableSubsectionRef getStringTable() = 0; }; } // end namespace codeview diff --git a/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h b/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h index 7c7f16bd1c7..6aeb0a5479c 100644 --- a/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h +++ b/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h @@ -12,7 +12,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" -#include "llvm/DebugInfo/CodeView/StringTable.h" +#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" #include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/Endian.h" @@ -52,7 +52,7 @@ private: Error readEpilogue(BinaryStreamReader &Reader); const PDBStringTableHeader *Header = nullptr; - codeview::StringTableRef Strings; + codeview::DebugStringTableSubsectionRef Strings; FixedStreamArray IDs; uint32_t ByteSize = 0; uint32_t NameCount = 0; diff --git a/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h b/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h index 6f85e7a4a07..0faa02dc452 100644 --- a/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h @@ -16,7 +16,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringRef.h" -#include "llvm/DebugInfo/CodeView/StringTable.h" +#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" #include "llvm/Support/Error.h" #include @@ -41,8 +41,10 @@ public: uint32_t calculateSerializedSize() const; Error commit(BinaryStreamWriter &Writer) const; - codeview::StringTable &getStrings() { return Strings; } - const codeview::StringTable &getStrings() const { return Strings; } + codeview::DebugStringTableSubsection &getStrings() { return Strings; } + const codeview::DebugStringTableSubsection &getStrings() const { + return Strings; + } private: uint32_t calculateHashTableSize() const; @@ -51,7 +53,7 @@ private: Error writeHashTable(BinaryStreamWriter &Writer) const; Error writeEpilogue(BinaryStreamWriter &Writer) const; - codeview::StringTable Strings; + codeview::DebugStringTableSubsection Strings; }; } // end namespace pdb diff --git a/lib/DebugInfo/CodeView/CMakeLists.txt b/lib/DebugInfo/CodeView/CMakeLists.txt index 845b2922bba..410b89bc949 100644 --- a/lib/DebugInfo/CodeView/CMakeLists.txt +++ b/lib/DebugInfo/CodeView/CMakeLists.txt @@ -8,13 +8,15 @@ add_llvm_library(LLVMDebugInfoCodeView LazyRandomTypeCollection.cpp Line.cpp DebugChecksumsSubsection.cpp + DebugFrameDataSubsection.cpp + DebugInlineeLinesSubsection.cpp + DebugLinesSubsection.cpp + DebugStringTableSubsection.cpp DebugSubsection.cpp DebugSubsectionRecord.cpp DebugSubsectionVisitor.cpp - DebugInlineeLinesSubsection.cpp - DebugLinesSubsection.cpp + DebugSymbolsSubsection.cpp RecordSerialization.cpp - StringTable.cpp SymbolRecordMapping.cpp SymbolDumper.cpp SymbolSerializer.cpp diff --git a/lib/DebugInfo/CodeView/DebugChecksumsSubsection.cpp b/lib/DebugInfo/CodeView/DebugChecksumsSubsection.cpp index 9e19b4dab14..1a85a339f8c 100644 --- a/lib/DebugInfo/CodeView/DebugChecksumsSubsection.cpp +++ b/lib/DebugInfo/CodeView/DebugChecksumsSubsection.cpp @@ -10,7 +10,7 @@ #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h" #include "llvm/DebugInfo/CodeView/CodeViewError.h" -#include "llvm/DebugInfo/CodeView/StringTable.h" +#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" #include "llvm/Support/BinaryStreamReader.h" using namespace llvm; @@ -48,8 +48,13 @@ Error DebugChecksumsSubsectionRef::initialize(BinaryStreamReader Reader) { return Error::success(); } +Error DebugChecksumsSubsectionRef::initialize(BinaryStreamRef Section) { + BinaryStreamReader Reader(Section); + return initialize(Reader); +} -DebugChecksumsSubsection::DebugChecksumsSubsection(StringTable &Strings) +DebugChecksumsSubsection::DebugChecksumsSubsection( + DebugStringTableSubsection &Strings) : DebugSubsection(DebugSubsectionKind::FileChecksums), Strings(Strings) {} void DebugChecksumsSubsection::addChecksum(StringRef FileName, @@ -75,11 +80,11 @@ void DebugChecksumsSubsection::addChecksum(StringRef FileName, SerializedSize += Len; } -uint32_t DebugChecksumsSubsection::calculateSerializedLength() { +uint32_t DebugChecksumsSubsection::calculateSerializedSize() const { return SerializedSize; } -Error DebugChecksumsSubsection::commit(BinaryStreamWriter &Writer) { +Error DebugChecksumsSubsection::commit(BinaryStreamWriter &Writer) const { for (const auto &FC : Checksums) { FileChecksumEntryHeader Header; Header.ChecksumKind = uint8_t(FC.Kind); diff --git a/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp b/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp new file mode 100644 index 00000000000..fd558aa9cc8 --- /dev/null +++ b/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp @@ -0,0 +1,44 @@ +//===- DebugFrameDataSubsection.cpp -----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h" +#include "llvm/DebugInfo/CodeView/CodeViewError.h" + +using namespace llvm; +using namespace llvm::codeview; + +Error DebugFrameDataSubsectionRef::initialize(BinaryStreamReader Reader) { + if (auto EC = Reader.readObject(RelocPtr)) + return EC; + if (Reader.bytesRemaining() % sizeof(FrameData) != 0) + return make_error(cv_error_code::corrupt_record, + "Invalid frame data record format!"); + + uint32_t Count = Reader.bytesRemaining() / sizeof(FrameData); + if (auto EC = Reader.readArray(Frames, Count)) + return EC; + return Error::success(); +} + +uint32_t DebugFrameDataSubsection::calculateSerializedSize() const { + return 4 + sizeof(FrameData) * Frames.size(); +} + +Error DebugFrameDataSubsection::commit(BinaryStreamWriter &Writer) const { + if (auto EC = Writer.writeInteger(0)) + return EC; + + if (auto EC = Writer.writeArray(makeArrayRef(Frames))) + return EC; + return Error::success(); +} + +void DebugFrameDataSubsection::addFrameData(const FrameData &Frame) { + Frames.push_back(Frame); +} diff --git a/lib/DebugInfo/CodeView/DebugInlineeLinesSubsection.cpp b/lib/DebugInfo/CodeView/DebugInlineeLinesSubsection.cpp index a565a6a64be..520a0ee4454 100644 --- a/lib/DebugInfo/CodeView/DebugInlineeLinesSubsection.cpp +++ b/lib/DebugInfo/CodeView/DebugInlineeLinesSubsection.cpp @@ -11,8 +11,8 @@ #include "llvm/DebugInfo/CodeView/CodeViewError.h" #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" -#include "llvm/DebugInfo/CodeView/StringTable.h" using namespace llvm; using namespace llvm::codeview; @@ -61,7 +61,7 @@ DebugInlineeLinesSubsection::DebugInlineeLinesSubsection( : DebugSubsection(DebugSubsectionKind::InlineeLines), Checksums(Checksums), HasExtraFiles(HasExtraFiles) {} -uint32_t DebugInlineeLinesSubsection::calculateSerializedLength() { +uint32_t DebugInlineeLinesSubsection::calculateSerializedSize() const { // 4 bytes for the signature uint32_t Size = sizeof(InlineeLinesSignature); @@ -78,7 +78,7 @@ uint32_t DebugInlineeLinesSubsection::calculateSerializedLength() { return Size; } -Error DebugInlineeLinesSubsection::commit(BinaryStreamWriter &Writer) { +Error DebugInlineeLinesSubsection::commit(BinaryStreamWriter &Writer) const { InlineeLinesSignature Sig = InlineeLinesSignature::Normal; if (HasExtraFiles) Sig = InlineeLinesSignature::ExtraFiles; diff --git a/lib/DebugInfo/CodeView/DebugLinesSubsection.cpp b/lib/DebugInfo/CodeView/DebugLinesSubsection.cpp index c97384520c8..2fce06ca2a1 100644 --- a/lib/DebugInfo/CodeView/DebugLinesSubsection.cpp +++ b/lib/DebugInfo/CodeView/DebugLinesSubsection.cpp @@ -11,8 +11,8 @@ #include "llvm/DebugInfo/CodeView/CodeViewError.h" #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" -#include "llvm/DebugInfo/CodeView/StringTable.h" using namespace llvm; using namespace llvm::codeview; @@ -68,7 +68,7 @@ bool DebugLinesSubsectionRef::hasColumnInfo() const { } DebugLinesSubsection::DebugLinesSubsection(DebugChecksumsSubsection &Checksums, - StringTable &Strings) + DebugStringTableSubsection &Strings) : DebugSubsection(DebugSubsectionKind::Lines), Checksums(Checksums) {} void DebugLinesSubsection::createBlock(StringRef FileName) { @@ -99,7 +99,7 @@ void DebugLinesSubsection::addLineAndColumnInfo(uint32_t Offset, B.Columns.push_back(CNE); } -Error DebugLinesSubsection::commit(BinaryStreamWriter &Writer) { +Error DebugLinesSubsection::commit(BinaryStreamWriter &Writer) const { LineFragmentHeader Header; Header.CodeSize = CodeSize; Header.Flags = hasColumnInfo() ? LF_HaveColumns : 0; @@ -133,7 +133,7 @@ Error DebugLinesSubsection::commit(BinaryStreamWriter &Writer) { return Error::success(); } -uint32_t DebugLinesSubsection::calculateSerializedLength() { +uint32_t DebugLinesSubsection::calculateSerializedSize() const { uint32_t Size = sizeof(LineFragmentHeader); for (const auto &B : Blocks) { Size += sizeof(LineBlockFragmentHeader); diff --git a/lib/DebugInfo/CodeView/StringTable.cpp b/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp similarity index 61% rename from lib/DebugInfo/CodeView/StringTable.cpp rename to lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp index 21f11204686..b8741eb0b67 100644 --- a/lib/DebugInfo/CodeView/StringTable.cpp +++ b/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp @@ -1,4 +1,4 @@ -//===- StringTable.cpp - CodeView String Table Reader/Writer ----*- C++ -*-===// +//===- DebugStringTableSubsection.cpp - CodeView String Table ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/DebugInfo/CodeView/StringTable.h" +#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" #include "llvm/Support/BinaryStream.h" #include "llvm/Support/BinaryStreamReader.h" @@ -16,14 +16,16 @@ using namespace llvm; using namespace llvm::codeview; -StringTableRef::StringTableRef() {} +DebugStringTableSubsectionRef::DebugStringTableSubsectionRef() + : DebugSubsectionRef(DebugSubsectionKind::StringTable) {} -Error StringTableRef::initialize(BinaryStreamRef Contents) { +Error DebugStringTableSubsectionRef::initialize(BinaryStreamRef Contents) { Stream = Contents; return Error::success(); } -Expected StringTableRef::getString(uint32_t Offset) const { +Expected +DebugStringTableSubsectionRef::getString(uint32_t Offset) const { BinaryStreamReader Reader(Stream); Reader.setOffset(Offset); StringRef Result; @@ -32,7 +34,10 @@ Expected StringTableRef::getString(uint32_t Offset) const { return Result; } -uint32_t StringTable::insert(StringRef S) { +DebugStringTableSubsection::DebugStringTableSubsection() + : DebugSubsection(DebugSubsectionKind::StringTable) {} + +uint32_t DebugStringTableSubsection::insert(StringRef S) { auto P = Strings.insert({S, StringSize}); // If a given string didn't exist in the string table, we want to increment @@ -42,9 +47,11 @@ uint32_t StringTable::insert(StringRef S) { return P.first->second; } -uint32_t StringTable::calculateSerializedSize() const { return StringSize; } +uint32_t DebugStringTableSubsection::calculateSerializedSize() const { + return StringSize; +} -Error StringTable::commit(BinaryStreamWriter &Writer) const { +Error DebugStringTableSubsection::commit(BinaryStreamWriter &Writer) const { assert(Writer.bytesRemaining() == StringSize); uint32_t MaxOffset = 1; @@ -62,9 +69,9 @@ Error StringTable::commit(BinaryStreamWriter &Writer) const { return Error::success(); } -uint32_t StringTable::size() const { return Strings.size(); } +uint32_t DebugStringTableSubsection::size() const { return Strings.size(); } -uint32_t StringTable::getStringId(StringRef S) const { +uint32_t DebugStringTableSubsection::getStringId(StringRef S) const { auto P = Strings.find(S); assert(P != Strings.end()); return P->second; diff --git a/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp b/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp index b66597ef256..511f36d0020 100644 --- a/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp +++ b/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp @@ -61,7 +61,7 @@ DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder( uint32_t DebugSubsectionRecordBuilder::calculateSerializedLength() { uint32_t Size = sizeof(DebugSubsectionHeader) + - alignTo(Frag.calculateSerializedLength(), 4); + alignTo(Frag.calculateSerializedSize(), 4); return Size; } diff --git a/lib/DebugInfo/CodeView/DebugSymbolsSubsection.cpp b/lib/DebugInfo/CodeView/DebugSymbolsSubsection.cpp new file mode 100644 index 00000000000..dc8ba8c929a --- /dev/null +++ b/lib/DebugInfo/CodeView/DebugSymbolsSubsection.cpp @@ -0,0 +1,34 @@ +//===- DebugSymbolsSubsection.cpp -------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h" + +using namespace llvm; +using namespace llvm::codeview; + +Error DebugSymbolsSubsectionRef::initialize(BinaryStreamReader Reader) { + return Reader.readArray(Records, Reader.getLength()); +} + +uint32_t DebugSymbolsSubsection::calculateSerializedSize() const { + return Length; +} + +Error DebugSymbolsSubsection::commit(BinaryStreamWriter &Writer) const { + for (const auto &Record : Records) { + if (auto EC = Writer.writeBytes(Record.RecordData)) + return EC; + } + return Error::success(); +} + +void DebugSymbolsSubsection::addSymbol(CVSymbol Symbol) { + Records.push_back(Symbol); + Length += Symbol.length(); +} \ No newline at end of file diff --git a/lib/DebugInfo/CodeView/SymbolDumper.cpp b/lib/DebugInfo/CodeView/SymbolDumper.cpp index 7d01c8c5f19..2f5a7d256c6 100644 --- a/lib/DebugInfo/CodeView/SymbolDumper.cpp +++ b/lib/DebugInfo/CodeView/SymbolDumper.cpp @@ -11,8 +11,8 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallString.h" #include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h" +#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" #include "llvm/DebugInfo/CodeView/EnumTables.h" -#include "llvm/DebugInfo/CodeView/StringTable.h" #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" #include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" @@ -369,7 +369,7 @@ Error CVSymbolDumperImpl::visitKnownRecord( DictScope S(W, "DefRangeSubfield"); if (ObjDelegate) { - StringTableRef Strings = ObjDelegate->getStringTable(); + DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable(); auto ExpectedProgram = Strings.getString(DefRangeSubfield.Program); if (!ExpectedProgram) { consumeError(ExpectedProgram.takeError()); @@ -390,7 +390,7 @@ Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, DictScope S(W, "DefRange"); if (ObjDelegate) { - StringTableRef Strings = ObjDelegate->getStringTable(); + DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable(); auto ExpectedProgram = Strings.getString(DefRange.Program); if (!ExpectedProgram) { consumeError(ExpectedProgram.takeError()); diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp index 0ad479d3221..663f7b4c8a8 100644 --- a/tools/llvm-readobj/COFFDumper.cpp +++ b/tools/llvm-readobj/COFFDumper.cpp @@ -13,7 +13,6 @@ //===----------------------------------------------------------------------===// #include "ARMWinEHPrinter.h" -#include "CodeView.h" #include "Error.h" #include "ObjDumper.h" #include "StackMapPrinter.h" @@ -25,12 +24,13 @@ #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h" #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h" #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" #include "llvm/DebugInfo/CodeView/Line.h" #include "llvm/DebugInfo/CodeView/RecordSerialization.h" -#include "llvm/DebugInfo/CodeView/StringTable.h" #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" #include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h" #include "llvm/DebugInfo/CodeView/SymbolDumper.h" @@ -157,9 +157,9 @@ private: bool RelocCached = false; RelocMapTy RelocMap; - VarStreamArray CVFileChecksumTable; + DebugChecksumsSubsectionRef CVFileChecksumTable; - StringTableRef CVStringTable; + DebugStringTableSubsectionRef CVStringTable; ScopedPrinter &Writer; BinaryByteStream TypeContents; @@ -200,7 +200,9 @@ public: return CD.getFileNameForFileOffset(FileOffset); } - StringTableRef getStringTable() override { return CD.CVStringTable; } + DebugStringTableSubsectionRef getStringTable() override { + return CD.CVStringTable; + } private: COFFDumper &CD; @@ -774,16 +776,14 @@ void COFFDumper::initializeFileAndStringTables(BinaryStreamReader &Reader) { StringRef Contents; error(Reader.readFixedString(Contents, SubSectionSize)); + BinaryStreamRef ST(Contents, support::little); switch (DebugSubsectionKind(SubType)) { - case DebugSubsectionKind::FileChecksums: { - BinaryStreamReader CSR(Contents, support::little); - error(CSR.readArray(CVFileChecksumTable, CSR.getLength())); + case DebugSubsectionKind::FileChecksums: + error(CVFileChecksumTable.initialize(ST)); break; - } - case DebugSubsectionKind::StringTable: { - BinaryStreamRef ST(Contents, support::little); + case DebugSubsectionKind::StringTable: error(CVStringTable.initialize(ST)); - } break; + break; default: break; } @@ -889,31 +889,30 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName, case DebugSubsectionKind::FrameData: { // First four bytes is a relocation against the function. BinaryStreamReader SR(Contents, llvm::support::little); - const uint32_t *CodePtr; - error(SR.readObject(CodePtr)); + + DebugFrameDataSubsectionRef FrameData; + error(FrameData.initialize(SR)); + StringRef LinkageName; error(resolveSymbolName(Obj->getCOFFSection(Section), SectionContents, - CodePtr, LinkageName)); + FrameData.getRelocPtr(), LinkageName)); W.printString("LinkageName", LinkageName); // To find the active frame description, search this array for the // smallest PC range that includes the current PC. - while (!SR.empty()) { - const FrameData *FD; - error(SR.readObject(FD)); - - StringRef FrameFunc = error(CVStringTable.getString(FD->FrameFunc)); + for (const auto &FD : FrameData) { + StringRef FrameFunc = error(CVStringTable.getString(FD.FrameFunc)); DictScope S(W, "FrameData"); - W.printHex("RvaStart", FD->RvaStart); - W.printHex("CodeSize", FD->CodeSize); - W.printHex("LocalSize", FD->LocalSize); - W.printHex("ParamsSize", FD->ParamsSize); - W.printHex("MaxStackSize", FD->MaxStackSize); + W.printHex("RvaStart", FD.RvaStart); + W.printHex("CodeSize", FD.CodeSize); + W.printHex("LocalSize", FD.LocalSize); + W.printHex("ParamsSize", FD.ParamsSize); + W.printHex("MaxStackSize", FD.MaxStackSize); W.printString("FrameFunc", FrameFunc); - W.printHex("PrologSize", FD->PrologSize); - W.printHex("SavedRegsSize", FD->SavedRegsSize); - W.printFlags("Flags", FD->Flags, makeArrayRef(FrameDataFlags)); + W.printHex("PrologSize", FD.PrologSize); + W.printHex("SavedRegsSize", FD.SavedRegsSize); + W.printFlags("Flags", FD.Flags, makeArrayRef(FrameDataFlags)); } break; } @@ -996,9 +995,9 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection, } void COFFDumper::printCodeViewFileChecksums(StringRef Subsection) { - BinaryStreamReader SR(Subsection, llvm::support::little); + BinaryStreamRef Stream(Subsection, llvm::support::little); DebugChecksumsSubsectionRef Checksums; - error(Checksums.initialize(SR)); + error(Checksums.initialize(Stream)); for (auto &FC : Checksums) { DictScope S(W, "FileChecksum"); @@ -1039,7 +1038,7 @@ StringRef COFFDumper::getFileNameForFileOffset(uint32_t FileOffset) { if (!CVFileChecksumTable.valid() || !CVStringTable.valid()) error(object_error::parse_failed); - auto Iter = CVFileChecksumTable.at(FileOffset); + auto Iter = CVFileChecksumTable.getArray().at(FileOffset); // Check if the file checksum table offset is valid. if (Iter == CVFileChecksumTable.end()) diff --git a/tools/llvm-readobj/CodeView.h b/tools/llvm-readobj/CodeView.h deleted file mode 100644 index cf713962eb7..00000000000 --- a/tools/llvm-readobj/CodeView.h +++ /dev/null @@ -1,54 +0,0 @@ -//===-- CodeView.h - On-disk record types for CodeView ----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// \brief This file provides data structures useful for consuming on-disk -/// CodeView. It is based on information published by Microsoft at -/// https://github.com/Microsoft/microsoft-pdb/. -/// -//===----------------------------------------------------------------------===// - -// FIXME: Find a home for this in include/llvm/DebugInfo/CodeView/. - -#ifndef LLVM_READOBJ_CODEVIEW_H -#define LLVM_READOBJ_CODEVIEW_H - -#include "llvm/DebugInfo/CodeView/CodeView.h" -#include "llvm/DebugInfo/CodeView/TypeIndex.h" -#include "llvm/Support/Endian.h" - -namespace llvm { -namespace codeview { - -using llvm::support::ulittle16_t; -using llvm::support::ulittle32_t; - -/// Data in the the SUBSEC_FRAMEDATA subection. -struct FrameData { - ulittle32_t RvaStart; - ulittle32_t CodeSize; - ulittle32_t LocalSize; - ulittle32_t ParamsSize; - ulittle32_t MaxStackSize; - ulittle32_t FrameFunc; - ulittle16_t PrologSize; - ulittle16_t SavedRegsSize; - ulittle32_t Flags; - enum : uint32_t { - HasSEH = 1 << 0, - HasEH = 1 << 1, - IsFunctionStart = 1 << 2, - }; -}; - - -} // namespace codeview -} // namespace llvm - -#endif // LLVM_READOBJ_CODEVIEW_H