diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-05-03 20:26:11 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-05-03 20:26:11 +0000 |
commit | 148779df305667b6942fee7e758fdf81a6498f38 (patch) | |
tree | 976d85fb9cb4bc8ed54348b045f742be90e10c57 /include/llvm/DebugInfo | |
parent | a303c417bbdb53703c2c17398b08486bde78f1f6 (diff) |
Notes
Diffstat (limited to 'include/llvm/DebugInfo')
19 files changed, 327 insertions, 105 deletions
diff --git a/include/llvm/DebugInfo/CodeView/CVRecord.h b/include/llvm/DebugInfo/CodeView/CVRecord.h index 086d6dff11c53..ac8aaafeadc1b 100644 --- a/include/llvm/DebugInfo/CodeView/CVRecord.h +++ b/include/llvm/DebugInfo/CodeView/CVRecord.h @@ -53,7 +53,7 @@ struct VarStreamArrayExtractor<codeview::CVRecord<Kind>> { typedef void ContextType; static Error extract(BinaryStreamRef Stream, uint32_t &Len, - codeview::CVRecord<Kind> &Item, void *Ctx) { + codeview::CVRecord<Kind> &Item) { using namespace codeview; const RecordPrefix *Prefix = nullptr; BinaryStreamReader Reader(Stream); diff --git a/include/llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h b/include/llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h index a5a3b851b8415..6c08c9aa21370 100644 --- a/include/llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h +++ b/include/llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h @@ -21,6 +21,8 @@ namespace llvm { namespace codeview { +class StringTable; + struct FileChecksumEntry { uint32_t FileNameOffset; // Byte offset of filename in global stringtable. FileChecksumKind Kind; // The type of checksum. @@ -35,7 +37,7 @@ public: typedef void ContextType; static Error extract(BinaryStreamRef Stream, uint32_t &Len, - codeview::FileChecksumEntry &Item, void *Ctx); + codeview::FileChecksumEntry &Item); }; } @@ -55,8 +57,8 @@ public: Error initialize(BinaryStreamReader Reader); - Iterator begin() const { return Checksums.begin(); } - Iterator end() const { return Checksums.end(); } + Iterator begin() { return Checksums.begin(); } + Iterator end() { return Checksums.end(); } const FileChecksumArray &getArray() const { return Checksums; } @@ -66,20 +68,22 @@ private: class ModuleDebugFileChecksumFragment final : public ModuleDebugFragment { public: - ModuleDebugFileChecksumFragment(); + explicit ModuleDebugFileChecksumFragment(StringTable &Strings); static bool classof(const ModuleDebugFragment *S) { return S->kind() == ModuleDebugFragmentKind::FileChecksums; } - void addChecksum(uint32_t StringTableOffset, FileChecksumKind Kind, + void addChecksum(StringRef FileName, FileChecksumKind Kind, ArrayRef<uint8_t> Bytes); uint32_t calculateSerializedLength() override; Error commit(BinaryStreamWriter &Writer) override; - uint32_t mapChecksumOffset(uint32_t StringTableOffset) const; + uint32_t mapChecksumOffset(StringRef FileName) const; private: + StringTable &Strings; + DenseMap<uint32_t, uint32_t> OffsetMap; uint32_t SerializedSize = 0; llvm::BumpPtrAllocator Storage; diff --git a/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h b/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h index b98c8605592c7..f68f21b224f19 100644 --- a/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h +++ b/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h @@ -57,8 +57,6 @@ private: ModuleDebugFragment &Frag; }; -typedef VarStreamArray<ModuleDebugFragmentRecord> ModuleDebugFragmentArray; - } // namespace codeview template <> @@ -66,13 +64,17 @@ struct VarStreamArrayExtractor<codeview::ModuleDebugFragmentRecord> { typedef void ContextType; static Error extract(BinaryStreamRef Stream, uint32_t &Length, - codeview::ModuleDebugFragmentRecord &Info, void *Ctx) { + codeview::ModuleDebugFragmentRecord &Info) { if (auto EC = codeview::ModuleDebugFragmentRecord::initialize(Stream, Info)) return EC; Length = Info.getRecordLength(); return Error::success(); } }; + +namespace codeview { +typedef VarStreamArray<ModuleDebugFragmentRecord> ModuleDebugFragmentArray; +} } // namespace llvm #endif // LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTRECORD_H diff --git a/include/llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h b/include/llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h index 177367c111c30..348497cbf7f2a 100644 --- a/include/llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h +++ b/include/llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h @@ -20,6 +20,8 @@ namespace llvm { namespace codeview { class ModuleDebugInlineeLineFragmentRef; +class ModuleDebugFileChecksumFragment; +class StringTable; enum class InlineeLinesSignature : uint32_t { Normal, // CV_INLINEE_SOURCE_LINE_SIGNATURE @@ -42,11 +44,10 @@ struct InlineeSourceLine { } template <> struct VarStreamArrayExtractor<codeview::InlineeSourceLine> { - typedef codeview::ModuleDebugInlineeLineFragmentRef ContextType; + typedef bool ContextType; static Error extract(BinaryStreamRef Stream, uint32_t &Len, - codeview::InlineeSourceLine &Item, - ContextType *Fragment); + codeview::InlineeSourceLine &Item, bool HasExtraFiles); }; namespace codeview { @@ -74,7 +75,8 @@ private: class ModuleDebugInlineeLineFragment final : public ModuleDebugFragment { public: - explicit ModuleDebugInlineeLineFragment(bool HasExtraFiles); + ModuleDebugInlineeLineFragment(ModuleDebugFileChecksumFragment &Checksums, + bool HasExtraFiles); static bool classof(const ModuleDebugFragment *S) { return S->kind() == ModuleDebugFragmentKind::InlineeLines; @@ -83,11 +85,12 @@ public: Error commit(BinaryStreamWriter &Writer) override; uint32_t calculateSerializedLength() override; - void addInlineSite(TypeIndex FuncId, uint32_t FileOffset, - uint32_t SourceLine); - void addExtraFile(uint32_t FileOffset); + void addInlineSite(TypeIndex FuncId, StringRef FileName, uint32_t SourceLine); + void addExtraFile(StringRef FileName); private: + ModuleDebugFileChecksumFragment &Checksums; + bool HasExtraFiles = false; uint32_t ExtraFileCount = 0; diff --git a/include/llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h b/include/llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h index dcfe86dd85030..3124236b8fb1b 100644 --- a/include/llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h +++ b/include/llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h @@ -19,6 +19,9 @@ namespace llvm { namespace codeview { +class ModuleDebugFileChecksumFragment; +class StringTable; + // Corresponds to the `CV_DebugSLinesHeader_t` structure. struct LineFragmentHeader { support::ulittle32_t RelocOffset; // Code offset of line contribution. @@ -61,10 +64,10 @@ struct LineColumnEntry { class LineColumnExtractor { public: - typedef const LineFragmentHeader ContextType; + typedef const LineFragmentHeader *ContextType; static Error extract(BinaryStreamRef Stream, uint32_t &Len, - LineColumnEntry &Item, const LineFragmentHeader *Header); + LineColumnEntry &Item, const LineFragmentHeader *Ctx); }; class ModuleDebugLineFragmentRef final : public ModuleDebugFragmentRef { @@ -104,13 +107,14 @@ class ModuleDebugLineFragment final : public ModuleDebugFragment { }; public: - ModuleDebugLineFragment(); + ModuleDebugLineFragment(ModuleDebugFileChecksumFragment &Checksums, + StringTable &Strings); static bool classof(const ModuleDebugFragment *S) { return S->kind() == ModuleDebugFragmentKind::Lines; } - void createBlock(uint32_t ChecksumBufferOffset); + void createBlock(StringRef FileName); void addLineInfo(uint32_t Offset, const LineInfo &Line); void addLineAndColumnInfo(uint32_t Offset, const LineInfo &Line, uint32_t ColStart, uint32_t ColEnd); @@ -125,6 +129,8 @@ public: bool hasColumnInfo() const; private: + ModuleDebugFileChecksumFragment &Checksums; + uint16_t RelocOffset = 0; uint16_t RelocSegment = 0; uint32_t CodeSize = 0; diff --git a/include/llvm/DebugInfo/CodeView/StringTable.h b/include/llvm/DebugInfo/CodeView/StringTable.h new file mode 100644 index 0000000000000..05dc02ee849f3 --- /dev/null +++ b/include/llvm/DebugInfo/CodeView/StringTable.h @@ -0,0 +1,75 @@ +//===- StringTable.h - CodeView String Table Reader/Writer ------*- 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_STRINGTABLE_H +#define LLVM_DEBUGINFO_CODEVIEW_STRINGTABLE_H + +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" + +#include "llvm/Support/BinaryStreamRef.h" +#include "llvm/Support/Error.h" + +#include <stdint.h> + +namespace llvm { + +class BinaryStreamReader; +class BinaryStreamRef; +class BinaryStreamWriter; + +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 { +public: + StringTableRef(); + + Error initialize(BinaryStreamRef Contents); + + Expected<StringRef> getString(uint32_t Offset) const; + + bool valid() const { return Stream.valid(); } + +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 { +public: + // If string S does not exist in the string table, insert it. + // Returns the ID for S. + uint32_t insert(StringRef S); + + // 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 size() const; + + StringMap<uint32_t>::const_iterator begin() const { return Strings.begin(); } + + StringMap<uint32_t>::const_iterator end() const { return Strings.end(); } + +private: + StringMap<uint32_t> Strings; + uint32_t StringSize = 1; +}; +} +} + +#endif diff --git a/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h b/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h index 2bef3f61adfcc..96c8a47a36690 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h +++ b/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h @@ -19,13 +19,15 @@ class BinaryStreamReader; namespace codeview { +class StringTableRef; + class SymbolVisitorDelegate { public: virtual ~SymbolVisitorDelegate() = default; virtual uint32_t getRecordOffset(BinaryStreamReader Reader) = 0; virtual StringRef getFileNameForFileOffset(uint32_t FileOffset) = 0; - virtual StringRef getStringTable() = 0; + virtual StringTableRef getStringTable() = 0; }; } // end namespace codeview diff --git a/include/llvm/DebugInfo/DWARF/DWARFContext.h b/include/llvm/DebugInfo/DWARF/DWARFContext.h index 3c04c6716ea39..b9f3425d5deb3 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -172,6 +172,9 @@ public: return DWOCUs[index].get(); } + /// Get a DIE given an exact offset. + DWARFDie getDIEForOffset(uint32_t Offset); + const DWARFUnitIndex &getCUIndex(); DWARFGdbIndex &getGdbIndex(); const DWARFUnitIndex &getTUIndex(); diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h index dd0e2648bf309..e21245b97b730 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h @@ -30,7 +30,7 @@ public: struct FileNameEntry { FileNameEntry() = default; - const char *Name = nullptr; + StringRef Name = StringRef(); uint64_t DirIdx = 0; uint64_t ModTime = 0; uint64_t Length = 0; @@ -44,6 +44,10 @@ public: uint64_t TotalLength; /// Version identifier for the statement information format. uint16_t Version; + /// In v5, size in bytes of an address (or segment offset). + uint8_t AddressSize; + /// In v5, size in bytes of a segment selector. + uint8_t SegSelectorSize; /// The number of bytes following the prologue_length field to the beginning /// of the first byte of the statement program itself. uint64_t PrologueLength; @@ -63,7 +67,7 @@ public: /// The number assigned to the first special opcode. uint8_t OpcodeBase; std::vector<uint8_t> StandardOpcodeLengths; - std::vector<const char *> IncludeDirectories; + std::vector<StringRef> IncludeDirectories; std::vector<FileNameEntry> FileNames; bool IsDWARF64; @@ -100,7 +104,7 @@ public: void postAppend(); void reset(bool DefaultIsStmt); void dump(raw_ostream &OS) const; - + static void dumpTableHeader(raw_ostream &OS); static bool orderByAddress(const Row &LHS, const Row &RHS) { return LHS.Address < RHS.Address; } diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h index e29ba523238c1..68e541bac73c6 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -312,9 +312,9 @@ public: [](const DWARFDebugInfoEntry &LHS, uint32_t Offset) { return LHS.getOffset() < Offset; }); - if (it == DieArray.end()) - return DWARFDie(); - return DWARFDie(this, &*it); + if (it != DieArray.end() && it->getOffset() == Offset) + return DWARFDie(this, &*it); + return DWARFDie(); } uint32_t getLineTableOffset() const { diff --git a/include/llvm/DebugInfo/DWARF/DWARFVerifier.h b/include/llvm/DebugInfo/DWARF/DWARFVerifier.h new file mode 100644 index 0000000000000..8e12bcd2c8e27 --- /dev/null +++ b/include/llvm/DebugInfo/DWARF/DWARFVerifier.h @@ -0,0 +1,98 @@ +//===- DWARFVerifier.h ----------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_DWARF_DWARFVERIFIER_H +#define LLVM_DEBUGINFO_DWARF_DWARFVERIFIER_H + +#include <cstdint> +#include <map> +#include <set> + +namespace llvm { +class raw_ostream; +struct DWARFAttribute; +class DWARFContext; +class DWARFDie; +class DWARFUnit; + +/// A class that verifies DWARF debug information given a DWARF Context. +class DWARFVerifier { + raw_ostream &OS; + DWARFContext &DCtx; + /// A map that tracks all references (converted absolute references) so we + /// can verify each reference points to a valid DIE and not an offset that + /// lies between to valid DIEs. + std::map<uint64_t, std::set<uint32_t>> ReferenceToDIEOffsets; + uint32_t NumDebugInfoErrors; + uint32_t NumDebugLineErrors; + + /// Verifies the attribute's DWARF attribute and its value. + /// + /// This function currently checks for: + /// - DW_AT_ranges values is a valid .debug_ranges offset + /// - DW_AT_stmt_list is a valid .debug_line offset + /// + /// @param Die The DWARF DIE that owns the attribute value + /// @param AttrValue The DWARF attribute value to check + void verifyDebugInfoAttribute(DWARFDie &Die, DWARFAttribute &AttrValue); + + /// Verifies the attribute's DWARF form. + /// + /// This function currently checks for: + /// - All DW_FORM_ref values that are CU relative have valid CU offsets + /// - All DW_FORM_ref_addr values have valid .debug_info offsets + /// - All DW_FORM_strp values have valid .debug_str offsets + /// + /// @param Die The DWARF DIE that owns the attribute value + /// @param AttrValue The DWARF attribute value to check + void verifyDebugInfoForm(DWARFDie &Die, DWARFAttribute &AttrValue); + + /// Verifies the all valid references that were found when iterating through + /// all of the DIE attributes. + /// + /// This function will verify that all references point to DIEs whose DIE + /// offset matches. This helps to ensure if a DWARF link phase moved things + /// around, that it doesn't create invalid references by failing to relocate + /// CU relative and absolute references. + void veifyDebugInfoReferences(); + + /// Verify the the DW_AT_stmt_list encoding and value and ensure that no + /// compile units that have the same DW_AT_stmt_list value. + void verifyDebugLineStmtOffsets(); + + /// Verify that all of the rows in the line table are valid. + /// + /// This function currently checks for: + /// - addresses within a sequence that decrease in value + /// - invalid file indexes + void verifyDebugLineRows(); + +public: + DWARFVerifier(raw_ostream &S, DWARFContext &D) + : OS(S), DCtx(D), NumDebugInfoErrors(0), NumDebugLineErrors(0) {} + /// Verify the information in the .debug_info section. + /// + /// Any errors are reported to the stream that was this object was + /// constructed with. + /// + /// @return True if the .debug_info verifies successfully, false otherwise. + bool handleDebugInfo(); + + /// Verify the information in the .debug_line section. + /// + /// Any errors are reported to the stream that was this object was + /// constructed with. + /// + /// @return True if the .debug_line verifies successfully, false otherwise. + bool handleDebugLine(); +}; + +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H diff --git a/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h b/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h index 879cb4285cd7a..d1f791b9daede 100644 --- a/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h @@ -66,7 +66,7 @@ struct ModuleInfoEx { template <> struct VarStreamArrayExtractor<pdb::DbiModuleDescriptor> { typedef void ContextType; static Error extract(BinaryStreamRef Stream, uint32_t &Length, - pdb::DbiModuleDescriptor &Info, void *Ctx) { + pdb::DbiModuleDescriptor &Info) { if (auto EC = pdb::DbiModuleDescriptor::initialize(Stream, Info)) return EC; Length = Info.getRecordLength(); diff --git a/include/llvm/DebugInfo/PDB/Native/DbiStream.h b/include/llvm/DebugInfo/PDB/Native/DbiStream.h index 84ae57f2e23ac..08262e47f77f5 100644 --- a/include/llvm/DebugInfo/PDB/Native/DbiStream.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiStream.h @@ -13,9 +13,9 @@ #include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" +#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h" #include "llvm/DebugInfo/PDB/Native/RawConstants.h" #include "llvm/DebugInfo/PDB/Native/RawTypes.h" -#include "llvm/DebugInfo/PDB/Native/StringTable.h" #include "llvm/DebugInfo/PDB/PDBTypes.h" #include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/BinaryStreamArray.h" @@ -91,7 +91,7 @@ private: std::unique_ptr<msf::MappedBlockStream> Stream; std::vector<ModuleInfoEx> ModuleInfos; - StringTable ECNames; + PDBStringTable ECNames; BinaryStreamRef ModInfoSubstream; BinaryStreamRef SecContrSubstream; diff --git a/include/llvm/DebugInfo/PDB/Native/PDBFile.h b/include/llvm/DebugInfo/PDB/Native/PDBFile.h index fbca62d6e9d93..3bed67141c56a 100644 --- a/include/llvm/DebugInfo/PDB/Native/PDBFile.h +++ b/include/llvm/DebugInfo/PDB/Native/PDBFile.h @@ -33,7 +33,7 @@ namespace pdb { class DbiStream; class GlobalsStream; class InfoStream; -class StringTable; +class PDBStringTable; class PDBFileBuilder; class PublicsStream; class SymbolStream; @@ -95,7 +95,7 @@ public: Expected<TpiStream &> getPDBIpiStream(); Expected<PublicsStream &> getPDBPublicsStream(); Expected<SymbolStream &> getPDBSymbolStream(); - Expected<StringTable &> getStringTable(); + Expected<PDBStringTable &> getStringTable(); BumpPtrAllocator &getAllocator() { return Allocator; } @@ -106,7 +106,7 @@ public: bool hasPDBPublicsStream(); bool hasPDBSymbolStream(); bool hasPDBTpiStream() const; - bool hasStringTable(); + bool hasPDBStringTable(); private: Expected<std::unique_ptr<msf::MappedBlockStream>> @@ -131,7 +131,7 @@ private: std::unique_ptr<SymbolStream> Symbols; std::unique_ptr<msf::MappedBlockStream> DirectoryStream; std::unique_ptr<msf::MappedBlockStream> StringTableStream; - std::unique_ptr<StringTable> Strings; + std::unique_ptr<PDBStringTable> Strings; }; } } diff --git a/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h b/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h index 3898af5afc9e4..cd7d3b0637933 100644 --- a/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h @@ -15,8 +15,8 @@ #include "llvm/ADT/Optional.h" #include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" +#include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h" #include "llvm/DebugInfo/PDB/Native/RawConstants.h" -#include "llvm/DebugInfo/PDB/Native/StringTableBuilder.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" @@ -46,12 +46,14 @@ public: DbiStreamBuilder &getDbiBuilder(); TpiStreamBuilder &getTpiBuilder(); TpiStreamBuilder &getIpiBuilder(); - StringTableBuilder &getStringTableBuilder(); + PDBStringTableBuilder &getStringTableBuilder(); Error commit(StringRef Filename); -private: + Expected<uint32_t> getNamedStreamIndex(StringRef Name) const; Error addNamedStream(StringRef Name, uint32_t Size); + +private: Expected<msf::MSFLayout> finalizeMsfLayout(); BumpPtrAllocator &Allocator; @@ -62,7 +64,7 @@ private: std::unique_ptr<TpiStreamBuilder> Tpi; std::unique_ptr<TpiStreamBuilder> Ipi; - StringTableBuilder Strings; + PDBStringTableBuilder Strings; NamedStreamMap NamedStreams; }; } diff --git a/include/llvm/DebugInfo/PDB/Native/StringTable.h b/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h index dd5e30e618270..7c7f16bd1c732 100644 --- a/include/llvm/DebugInfo/PDB/Native/StringTable.h +++ b/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h @@ -1,4 +1,4 @@ -//===- StringTable.h - PDB String Table -------------------------*- C++ -*-===// +//===- PDBStringTable.h - PDB String Table -----------------------*- C++-*-===// // // The LLVM Compiler Infrastructure // @@ -7,11 +7,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DEBUGINFO_PDB_RAW_STRINGTABLE_H -#define LLVM_DEBUGINFO_PDB_RAW_STRINGTABLE_H +#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBSTRINGTABLE_H +#define LLVM_DEBUGINFO_PDB_RAW_PDBSTRINGTABLE_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/CodeView/StringTable.h" #include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/Endian.h" @@ -22,31 +23,38 @@ namespace llvm { class BinaryStreamReader; +namespace msf { +class MappedBlockStream; +} + namespace pdb { -class StringTable { -public: - StringTable(); +struct PDBStringTableHeader; - Error load(BinaryStreamReader &Stream); +class PDBStringTable { +public: + Error reload(BinaryStreamReader &Reader); uint32_t getByteSize() const; + uint32_t getNameCount() const; + uint32_t getHashVersion() const; + uint32_t getSignature() const; - uint32_t getNameCount() const { return NameCount; } - uint32_t getHashVersion() const { return HashVersion; } - uint32_t getSignature() const { return Signature; } - - StringRef getStringForID(uint32_t ID) const; - uint32_t getIDForString(StringRef Str) const; + Expected<StringRef> getStringForID(uint32_t ID) const; + Expected<uint32_t> getIDForString(StringRef Str) const; FixedStreamArray<support::ulittle32_t> name_ids() const; private: - BinaryStreamRef NamesBuffer; + Error readHeader(BinaryStreamReader &Reader); + Error readStrings(BinaryStreamReader &Reader); + Error readHashTable(BinaryStreamReader &Reader); + Error readEpilogue(BinaryStreamReader &Reader); + + const PDBStringTableHeader *Header = nullptr; + codeview::StringTableRef Strings; FixedStreamArray<support::ulittle32_t> IDs; uint32_t ByteSize = 0; - uint32_t Signature = 0; - uint32_t HashVersion = 0; uint32_t NameCount = 0; }; diff --git a/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h b/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h new file mode 100644 index 0000000000000..6f85e7a4a0741 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h @@ -0,0 +1,60 @@ +//===- PDBStringTableBuilder.h - PDB String Table Builder -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file creates the "/names" stream. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBSTRINGTABLEBUILDER_H +#define LLVM_DEBUGINFO_PDB_RAW_PDBSTRINGTABLEBUILDER_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/CodeView/StringTable.h" +#include "llvm/Support/Error.h" +#include <vector> + +namespace llvm { +class BinaryStreamWriter; +class WritableBinaryStreamRef; + +namespace msf { +struct MSFLayout; +} + +namespace pdb { + +class PDBFileBuilder; + +class PDBStringTableBuilder { +public: + // If string S does not exist in the string table, insert it. + // Returns the ID for S. + uint32_t insert(StringRef S); + + uint32_t calculateSerializedSize() const; + Error commit(BinaryStreamWriter &Writer) const; + + codeview::StringTable &getStrings() { return Strings; } + const codeview::StringTable &getStrings() const { return Strings; } + +private: + uint32_t calculateHashTableSize() const; + Error writeHeader(BinaryStreamWriter &Writer) const; + Error writeStrings(BinaryStreamWriter &Writer) const; + Error writeHashTable(BinaryStreamWriter &Writer) const; + Error writeEpilogue(BinaryStreamWriter &Writer) const; + + codeview::StringTable Strings; +}; + +} // end namespace pdb +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_RAW_PDBSTRINGTABLEBUILDER_H diff --git a/include/llvm/DebugInfo/PDB/Native/RawTypes.h b/include/llvm/DebugInfo/PDB/Native/RawTypes.h index e1c6cf0021d5e..93622d0a43949 100644 --- a/include/llvm/DebugInfo/PDB/Native/RawTypes.h +++ b/include/llvm/DebugInfo/PDB/Native/RawTypes.h @@ -307,13 +307,13 @@ struct InfoStreamHeader { }; /// The header preceeding the /names stream. -struct StringTableHeader { - support::ulittle32_t Signature; - support::ulittle32_t HashVersion; - support::ulittle32_t ByteSize; +struct PDBStringTableHeader { + support::ulittle32_t Signature; // PDBStringTableSignature + support::ulittle32_t HashVersion; // 1 or 2 + support::ulittle32_t ByteSize; // Number of bytes of names buffer. }; -const uint32_t StringTableSignature = 0xEFFEEFFE; +const uint32_t PDBStringTableSignature = 0xEFFEEFFE; } // namespace pdb } // namespace llvm diff --git a/include/llvm/DebugInfo/PDB/Native/StringTableBuilder.h b/include/llvm/DebugInfo/PDB/Native/StringTableBuilder.h deleted file mode 100644 index 9c4b12e33ba05..0000000000000 --- a/include/llvm/DebugInfo/PDB/Native/StringTableBuilder.h +++ /dev/null @@ -1,45 +0,0 @@ -//===- StringTableBuilder.h - PDB String Table Builder ----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file creates the "/names" stream. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_PDB_RAW_STRINGTABLEBUILDER_H -#define LLVM_DEBUGINFO_PDB_RAW_STRINGTABLEBUILDER_H - -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Error.h" -#include <vector> - -namespace llvm { -class BinaryStreamWriter; - -namespace pdb { - -class StringTableBuilder { -public: - // If string S does not exist in the string table, insert it. - // Returns the ID for S. - uint32_t insert(StringRef S); - uint32_t getStringIndex(StringRef S); - - uint32_t finalize(); - Error commit(BinaryStreamWriter &Writer) const; - -private: - DenseMap<StringRef, uint32_t> Strings; - uint32_t StringSize = 1; -}; - -} // end namespace pdb -} // end namespace llvm - -#endif // LLVM_DEBUGINFO_PDB_RAW_STRINGTABLEBUILDER_H |