diff options
Diffstat (limited to 'include/llvm/DebugInfo')
126 files changed, 2153 insertions, 1879 deletions
diff --git a/include/llvm/DebugInfo/CodeView/CVRecord.h b/include/llvm/DebugInfo/CodeView/CVRecord.h index a327d450db550..487f3b6446fa5 100644 --- a/include/llvm/DebugInfo/CodeView/CVRecord.h +++ b/include/llvm/DebugInfo/CodeView/CVRecord.h @@ -14,8 +14,8 @@ #include "llvm/ADT/Optional.h" #include "llvm/DebugInfo/CodeView/CodeViewError.h" #include "llvm/DebugInfo/CodeView/RecordSerialization.h" -#include "llvm/DebugInfo/MSF/StreamReader.h" -#include "llvm/DebugInfo/MSF/StreamRef.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include <cstdint> @@ -48,15 +48,13 @@ public: } // end namespace codeview -namespace msf { - template <typename Kind> struct VarStreamArrayExtractor<codeview::CVRecord<Kind>> { - Error operator()(ReadableStreamRef Stream, uint32_t &Len, + Error operator()(BinaryStreamRef Stream, uint32_t &Len, codeview::CVRecord<Kind> &Item) const { using namespace codeview; const RecordPrefix *Prefix = nullptr; - StreamReader Reader(Stream); + BinaryStreamReader Reader(Stream); uint32_t Offset = Reader.getOffset(); if (auto EC = Reader.readObject(Prefix)) @@ -76,8 +74,6 @@ struct VarStreamArrayExtractor<codeview::CVRecord<Kind>> { } }; -} // end namespace msf - } // end namespace llvm #endif // LLVM_DEBUGINFO_CODEVIEW_RECORDITERATOR_H diff --git a/include/llvm/DebugInfo/CodeView/CVTypeDumper.h b/include/llvm/DebugInfo/CodeView/CVTypeDumper.h index e1dd6a10b5a16..02f14ea2107b2 100644 --- a/include/llvm/DebugInfo/CodeView/CVTypeDumper.h +++ b/include/llvm/DebugInfo/CodeView/CVTypeDumper.h @@ -22,10 +22,14 @@ namespace llvm { namespace codeview { +class TypeServerHandler; + /// Dumper for CodeView type streams found in COFF object files and PDB files. class CVTypeDumper { public: - explicit CVTypeDumper(TypeDatabase &TypeDB) : TypeDB(TypeDB) {} + explicit CVTypeDumper(TypeDatabase &TypeDB, + TypeServerHandler *Handler = nullptr) + : TypeDB(TypeDB), Handler(Handler) {} /// Dumps one type record. Returns false if there was a type parsing error, /// and true otherwise. This should be called in order, since the dumper @@ -48,6 +52,7 @@ public: private: TypeDatabase &TypeDB; + TypeServerHandler *Handler; }; } // end namespace codeview diff --git a/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h b/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h index d1b0363a4133d..e9012db7602d2 100644 --- a/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h +++ b/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h @@ -10,9 +10,10 @@ #ifndef LLVM_DEBUGINFO_CODEVIEW_CVTYPEVISITOR_H #define LLVM_DEBUGINFO_CODEVIEW_CVTYPEVISITOR_H -#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/TinyPtrVector.h" #include "llvm/DebugInfo/CodeView/CVRecord.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/CodeView/TypeServerHandler.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" #include "llvm/Support/Error.h" @@ -23,18 +24,23 @@ class CVTypeVisitor { public: explicit CVTypeVisitor(TypeVisitorCallbacks &Callbacks); + void addTypeServerHandler(TypeServerHandler &Handler); + Error visitTypeRecord(CVType &Record); Error visitMemberRecord(CVMemberRecord &Record); /// Visits the type records in Data. Sets the error flag on parse failures. Error visitTypeStream(const CVTypeArray &Types); + Error visitTypeStream(CVTypeRange Types); Error visitFieldListMemberStream(ArrayRef<uint8_t> FieldList); - Error visitFieldListMemberStream(msf::StreamReader Reader); + Error visitFieldListMemberStream(BinaryStreamReader Reader); private: /// The interface to the class that gets notified of each visitation. TypeVisitorCallbacks &Callbacks; + + TinyPtrVector<TypeServerHandler *> Handlers; }; } // end namespace codeview diff --git a/include/llvm/DebugInfo/CodeView/CodeView.h b/include/llvm/DebugInfo/CodeView/CodeView.h index e21cfa3d030ae..2791c9dc37465 100644 --- a/include/llvm/DebugInfo/CodeView/CodeView.h +++ b/include/llvm/DebugInfo/CodeView/CodeView.h @@ -275,6 +275,12 @@ enum class MethodOptions : uint16_t { }; CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(MethodOptions) +/// Equivalent to CV_LABEL_TYPE_e. +enum class LabelType : uint16_t { + Near = 0x0, + Far = 0x4, +}; + /// Equivalent to CV_modifier_t. /// TODO: Add flag for _Atomic modifier enum class ModifierOptions : uint16_t { diff --git a/include/llvm/DebugInfo/CodeView/CodeViewError.h b/include/llvm/DebugInfo/CodeView/CodeViewError.h index 0556fd0e19f26..586a720ce6e40 100644 --- a/include/llvm/DebugInfo/CodeView/CodeViewError.h +++ b/include/llvm/DebugInfo/CodeView/CodeViewError.h @@ -21,6 +21,7 @@ enum class cv_error_code { insufficient_buffer, operation_unsupported, corrupt_record, + no_records, unknown_member_record, }; diff --git a/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h b/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h index 5a036b9d5b6cd..b3976826a316c 100644 --- a/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h +++ b/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h @@ -17,8 +17,8 @@ #include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/CodeView/CodeViewError.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" -#include "llvm/DebugInfo/MSF/StreamReader.h" -#include "llvm/DebugInfo/MSF/StreamWriter.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/BinaryStreamWriter.h" #include "llvm/Support/Error.h" #include <cassert> #include <cstdint> @@ -33,8 +33,8 @@ class CodeViewRecordIO { } public: - explicit CodeViewRecordIO(msf::StreamReader &Reader) : Reader(&Reader) {} - explicit CodeViewRecordIO(msf::StreamWriter &Writer) : Writer(&Writer) {} + explicit CodeViewRecordIO(BinaryStreamReader &Reader) : Reader(&Reader) {} + explicit CodeViewRecordIO(BinaryStreamWriter &Writer) : Writer(&Writer) {} Error beginRecord(Optional<uint32_t> MaxLength); Error endRecord(); @@ -160,8 +160,8 @@ private: SmallVector<RecordLimit, 2> Limits; - msf::StreamReader *Reader = nullptr; - msf::StreamWriter *Writer = nullptr; + BinaryStreamReader *Reader = nullptr; + BinaryStreamWriter *Writer = nullptr; }; } // end namespace codeview diff --git a/include/llvm/DebugInfo/CodeView/Formatters.h b/include/llvm/DebugInfo/CodeView/Formatters.h new file mode 100644 index 0000000000000..37a91098a8b65 --- /dev/null +++ b/include/llvm/DebugInfo/CodeView/Formatters.h @@ -0,0 +1,40 @@ +//===- Formatters.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_FORMATTERS_H +#define LLVM_DEBUGINFO_CODEVIEW_FORMATTERS_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/FormatAdapters.h" + +namespace llvm { +namespace codeview { +namespace detail { +class GuidAdapter final : public llvm::FormatAdapter<ArrayRef<uint8_t>> { + ArrayRef<uint8_t> Guid; + +public: + explicit GuidAdapter(ArrayRef<uint8_t> Guid); + explicit GuidAdapter(StringRef Guid); + void format(llvm::raw_ostream &Stream, StringRef Style); +}; +} + +inline detail::GuidAdapter fmt_guid(StringRef Item) { + return detail::GuidAdapter(Item); +} + +inline detail::GuidAdapter fmt_guid(ArrayRef<uint8_t> Item) { + return detail::GuidAdapter(Item); +} +} +} + +#endif diff --git a/include/llvm/DebugInfo/CodeView/ModuleSubstream.h b/include/llvm/DebugInfo/CodeView/ModuleSubstream.h index 8860ae42fc091..a1c5c93cc3f8e 100644 --- a/include/llvm/DebugInfo/CodeView/ModuleSubstream.h +++ b/include/llvm/DebugInfo/CodeView/ModuleSubstream.h @@ -11,8 +11,8 @@ #define LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAM_H #include "llvm/DebugInfo/CodeView/CodeView.h" -#include "llvm/DebugInfo/MSF/StreamArray.h" -#include "llvm/DebugInfo/MSF/StreamRef.h" +#include "llvm/Support/BinaryStreamArray.h" +#include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" @@ -59,23 +59,22 @@ struct ColumnNumberEntry { class ModuleSubstream { public: ModuleSubstream(); - ModuleSubstream(ModuleSubstreamKind Kind, msf::ReadableStreamRef Data); - static Error initialize(msf::ReadableStreamRef Stream, ModuleSubstream &Info); + ModuleSubstream(ModuleSubstreamKind Kind, BinaryStreamRef Data); + static Error initialize(BinaryStreamRef Stream, ModuleSubstream &Info); uint32_t getRecordLength() const; ModuleSubstreamKind getSubstreamKind() const; - msf::ReadableStreamRef getRecordData() const; + BinaryStreamRef getRecordData() const; private: ModuleSubstreamKind Kind; - msf::ReadableStreamRef Data; + BinaryStreamRef Data; }; -typedef msf::VarStreamArray<ModuleSubstream> ModuleSubstreamArray; +typedef VarStreamArray<ModuleSubstream> ModuleSubstreamArray; } // namespace codeview -namespace msf { template <> struct VarStreamArrayExtractor<codeview::ModuleSubstream> { - Error operator()(ReadableStreamRef Stream, uint32_t &Length, + Error operator()(BinaryStreamRef Stream, uint32_t &Length, codeview::ModuleSubstream &Info) const { if (auto EC = codeview::ModuleSubstream::initialize(Stream, Info)) return EC; @@ -83,7 +82,6 @@ template <> struct VarStreamArrayExtractor<codeview::ModuleSubstream> { return Error::success(); } }; -} // namespace msf } // namespace llvm #endif // LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAM_H diff --git a/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h b/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h index f9927d6609333..1a40654a3f337 100644 --- a/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h +++ b/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h @@ -15,9 +15,9 @@ #include "llvm/DebugInfo/CodeView/CodeViewError.h" #include "llvm/DebugInfo/CodeView/Line.h" #include "llvm/DebugInfo/CodeView/ModuleSubstream.h" -#include "llvm/DebugInfo/MSF/StreamArray.h" -#include "llvm/DebugInfo/MSF/StreamReader.h" -#include "llvm/DebugInfo/MSF/StreamRef.h" +#include "llvm/Support/BinaryStreamArray.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include <cstdint> @@ -28,8 +28,8 @@ namespace codeview { struct LineColumnEntry { support::ulittle32_t NameIndex; - msf::FixedStreamArray<LineNumberEntry> LineNumbers; - msf::FixedStreamArray<ColumnNumberEntry> Columns; + FixedStreamArray<LineNumberEntry> LineNumbers; + FixedStreamArray<ColumnNumberEntry> Columns; }; struct FileChecksumEntry { @@ -38,49 +38,47 @@ struct FileChecksumEntry { ArrayRef<uint8_t> Checksum; // The bytes of the checksum. }; -typedef msf::VarStreamArray<LineColumnEntry> LineInfoArray; -typedef msf::VarStreamArray<FileChecksumEntry> FileChecksumArray; +typedef VarStreamArray<LineColumnEntry> LineInfoArray; +typedef VarStreamArray<FileChecksumEntry> FileChecksumArray; class IModuleSubstreamVisitor { public: virtual ~IModuleSubstreamVisitor() = default; virtual Error visitUnknown(ModuleSubstreamKind Kind, - msf::ReadableStreamRef Data) = 0; - virtual Error visitSymbols(msf::ReadableStreamRef Data); - virtual Error visitLines(msf::ReadableStreamRef Data, + BinaryStreamRef Data) = 0; + virtual Error visitSymbols(BinaryStreamRef Data); + virtual Error visitLines(BinaryStreamRef Data, const LineSubstreamHeader *Header, const LineInfoArray &Lines); - virtual Error visitStringTable(msf::ReadableStreamRef Data); - virtual Error visitFileChecksums(msf::ReadableStreamRef Data, + virtual Error visitStringTable(BinaryStreamRef Data); + virtual Error visitFileChecksums(BinaryStreamRef Data, const FileChecksumArray &Checksums); - virtual Error visitFrameData(msf::ReadableStreamRef Data); - virtual Error visitInlineeLines(msf::ReadableStreamRef Data); - virtual Error visitCrossScopeImports(msf::ReadableStreamRef Data); - virtual Error visitCrossScopeExports(msf::ReadableStreamRef Data); - virtual Error visitILLines(msf::ReadableStreamRef Data); - virtual Error visitFuncMDTokenMap(msf::ReadableStreamRef Data); - virtual Error visitTypeMDTokenMap(msf::ReadableStreamRef Data); - virtual Error visitMergedAssemblyInput(msf::ReadableStreamRef Data); - virtual Error visitCoffSymbolRVA(msf::ReadableStreamRef Data); + virtual Error visitFrameData(BinaryStreamRef Data); + virtual Error visitInlineeLines(BinaryStreamRef Data); + virtual Error visitCrossScopeImports(BinaryStreamRef Data); + virtual Error visitCrossScopeExports(BinaryStreamRef Data); + virtual Error visitILLines(BinaryStreamRef Data); + virtual Error visitFuncMDTokenMap(BinaryStreamRef Data); + virtual Error visitTypeMDTokenMap(BinaryStreamRef Data); + virtual Error visitMergedAssemblyInput(BinaryStreamRef Data); + virtual Error visitCoffSymbolRVA(BinaryStreamRef Data); }; Error visitModuleSubstream(const ModuleSubstream &R, IModuleSubstreamVisitor &V); } // end namespace codeview -namespace msf { - template <> class VarStreamArrayExtractor<codeview::LineColumnEntry> { public: VarStreamArrayExtractor(const codeview::LineSubstreamHeader *Header) : Header(Header) {} - Error operator()(ReadableStreamRef Stream, uint32_t &Len, + Error operator()(BinaryStreamRef Stream, uint32_t &Len, codeview::LineColumnEntry &Item) const { using namespace codeview; const LineFileBlockHeader *BlockHeader; - StreamReader Reader(Stream); + BinaryStreamReader Reader(Stream); if (auto EC = Reader.readObject(BlockHeader)) return EC; bool HasColumn = Header->Flags & LineFlags::HaveColumns; @@ -113,11 +111,11 @@ private: template <> class VarStreamArrayExtractor<codeview::FileChecksumEntry> { public: - Error operator()(ReadableStreamRef Stream, uint32_t &Len, + Error operator()(BinaryStreamRef Stream, uint32_t &Len, codeview::FileChecksumEntry &Item) const { using namespace codeview; const FileChecksum *Header; - StreamReader Reader(Stream); + BinaryStreamReader Reader(Stream); if (auto EC = Reader.readObject(Header)) return EC; Item.FileNameOffset = Header->FileNameOffset; @@ -129,8 +127,6 @@ public: } }; -} // end namespace msf - } // end namespace llvm #endif // LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAMVISITOR_H diff --git a/include/llvm/DebugInfo/CodeView/RecordSerialization.h b/include/llvm/DebugInfo/CodeView/RecordSerialization.h index 97b6f561bb973..58449c2c7565b 100644 --- a/include/llvm/DebugInfo/CodeView/RecordSerialization.h +++ b/include/llvm/DebugInfo/CodeView/RecordSerialization.h @@ -15,7 +15,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/CodeViewError.h" -#include "llvm/DebugInfo/MSF/StreamReader.h" +#include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include <cinttypes> @@ -41,37 +41,37 @@ struct RecordPrefix { StringRef getBytesAsCharacters(ArrayRef<uint8_t> LeafData); StringRef getBytesAsCString(ArrayRef<uint8_t> LeafData); -inline Error consume(msf::StreamReader &Reader) { return Error::success(); } +inline Error consume(BinaryStreamReader &Reader) { return Error::success(); } /// Decodes a numeric "leaf" value. These are integer literals encountered in /// the type stream. If the value is positive and less than LF_NUMERIC (1 << /// 15), it is emitted directly in Data. Otherwise, it has a tag like LF_CHAR /// that indicates the bitwidth and sign of the numeric data. -Error consume(msf::StreamReader &Reader, APSInt &Num); +Error consume(BinaryStreamReader &Reader, APSInt &Num); /// Decodes a numeric leaf value that is known to be a particular type. -Error consume_numeric(msf::StreamReader &Reader, uint64_t &Value); +Error consume_numeric(BinaryStreamReader &Reader, uint64_t &Value); /// Decodes signed and unsigned fixed-length integers. -Error consume(msf::StreamReader &Reader, uint32_t &Item); -Error consume(msf::StreamReader &Reader, int32_t &Item); +Error consume(BinaryStreamReader &Reader, uint32_t &Item); +Error consume(BinaryStreamReader &Reader, int32_t &Item); /// Decodes a null terminated string. -Error consume(msf::StreamReader &Reader, StringRef &Item); +Error consume(BinaryStreamReader &Reader, StringRef &Item); Error consume(StringRef &Data, APSInt &Num); Error consume(StringRef &Data, uint32_t &Item); /// Decodes an arbitrary object whose layout matches that of the underlying /// byte sequence, and returns a pointer to the object. -template <typename T> Error consume(msf::StreamReader &Reader, T *&Item) { +template <typename T> Error consume(BinaryStreamReader &Reader, T *&Item) { return Reader.readObject(Item); } template <typename T, typename U> struct serialize_conditional_impl { serialize_conditional_impl(T &Item, U Func) : Item(Item), Func(Func) {} - Error deserialize(msf::StreamReader &Reader) const { + Error deserialize(BinaryStreamReader &Reader) const { if (!Func()) return Error::success(); return consume(Reader, Item); @@ -89,7 +89,7 @@ serialize_conditional_impl<T, U> serialize_conditional(T &Item, U Func) { template <typename T, typename U> struct serialize_array_impl { serialize_array_impl(ArrayRef<T> &Item, U Func) : Item(Item), Func(Func) {} - Error deserialize(msf::StreamReader &Reader) const { + Error deserialize(BinaryStreamReader &Reader) const { return Reader.readArray(Item, Func()); } @@ -100,7 +100,7 @@ template <typename T, typename U> struct serialize_array_impl { template <typename T> struct serialize_vector_tail_impl { serialize_vector_tail_impl(std::vector<T> &Item) : Item(Item) {} - Error deserialize(msf::StreamReader &Reader) const { + Error deserialize(BinaryStreamReader &Reader) const { T Field; // Stop when we run out of bytes or we hit record padding bytes. while (!Reader.empty() && Reader.peek() < LF_PAD0) { @@ -118,14 +118,14 @@ struct serialize_null_term_string_array_impl { serialize_null_term_string_array_impl(std::vector<StringRef> &Item) : Item(Item) {} - Error deserialize(msf::StreamReader &Reader) const { + Error deserialize(BinaryStreamReader &Reader) const { if (Reader.empty()) return make_error<CodeViewError>(cv_error_code::insufficient_buffer, "Null terminated string is empty!"); while (Reader.peek() != 0) { StringRef Field; - if (auto EC = Reader.readZeroString(Field)) + if (auto EC = Reader.readCString(Field)) return EC; Item.push_back(Field); } @@ -138,7 +138,7 @@ struct serialize_null_term_string_array_impl { template <typename T> struct serialize_arrayref_tail_impl { serialize_arrayref_tail_impl(ArrayRef<T> &Item) : Item(Item) {} - Error deserialize(msf::StreamReader &Reader) const { + Error deserialize(BinaryStreamReader &Reader) const { uint32_t Count = Reader.bytesRemaining() / sizeof(T); return Reader.readArray(Item, Count); } @@ -149,7 +149,7 @@ template <typename T> struct serialize_arrayref_tail_impl { template <typename T> struct serialize_numeric_impl { serialize_numeric_impl(T &Item) : Item(Item) {} - Error deserialize(msf::StreamReader &Reader) const { + Error deserialize(BinaryStreamReader &Reader) const { return consume_numeric(Reader, Item); } @@ -201,42 +201,42 @@ template <typename T> serialize_numeric_impl<T> serialize_numeric(T &Item) { #define CV_NUMERIC_FIELD(I) serialize_numeric(I) template <typename T, typename U> -Error consume(msf::StreamReader &Reader, +Error consume(BinaryStreamReader &Reader, const serialize_conditional_impl<T, U> &Item) { return Item.deserialize(Reader); } template <typename T, typename U> -Error consume(msf::StreamReader &Reader, +Error consume(BinaryStreamReader &Reader, const serialize_array_impl<T, U> &Item) { return Item.deserialize(Reader); } -inline Error consume(msf::StreamReader &Reader, +inline Error consume(BinaryStreamReader &Reader, const serialize_null_term_string_array_impl &Item) { return Item.deserialize(Reader); } template <typename T> -Error consume(msf::StreamReader &Reader, +Error consume(BinaryStreamReader &Reader, const serialize_vector_tail_impl<T> &Item) { return Item.deserialize(Reader); } template <typename T> -Error consume(msf::StreamReader &Reader, +Error consume(BinaryStreamReader &Reader, const serialize_arrayref_tail_impl<T> &Item) { return Item.deserialize(Reader); } template <typename T> -Error consume(msf::StreamReader &Reader, +Error consume(BinaryStreamReader &Reader, const serialize_numeric_impl<T> &Item) { return Item.deserialize(Reader); } template <typename T, typename U, typename... Args> -Error consume(msf::StreamReader &Reader, T &&X, U &&Y, Args &&... Rest) { +Error consume(BinaryStreamReader &Reader, T &&X, U &&Y, Args &&... Rest) { if (auto EC = consume(Reader, X)) return EC; return consume(Reader, Y, std::forward<Args>(Rest)...); diff --git a/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h b/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h index 13c2bb14ecf59..c1a5152930fff 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h +++ b/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h @@ -15,8 +15,8 @@ #include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h" #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h" #include "llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h" -#include "llvm/DebugInfo/MSF/ByteStream.h" -#include "llvm/DebugInfo/MSF/StreamReader.h" +#include "llvm/Support/BinaryByteStream.h" +#include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/Error.h" namespace llvm { @@ -25,10 +25,11 @@ class SymbolVisitorDelegate; class SymbolDeserializer : public SymbolVisitorCallbacks { struct MappingInfo { explicit MappingInfo(ArrayRef<uint8_t> RecordData) - : Stream(RecordData), Reader(Stream), Mapping(Reader) {} + : Stream(RecordData, llvm::support::little), Reader(Stream), + Mapping(Reader) {} - msf::ByteStream Stream; - msf::StreamReader Reader; + BinaryByteStream Stream; + BinaryStreamReader Reader; SymbolRecordMapping Mapping; }; diff --git a/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/include/llvm/DebugInfo/CodeView/SymbolRecord.h index 57772d39e972b..c5a5549bf818a 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolRecord.h +++ b/include/llvm/DebugInfo/CodeView/SymbolRecord.h @@ -13,13 +13,13 @@ #include "llvm/ADT/APSInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" -#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/DebugInfo/CodeView/CVRecord.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/RecordSerialization.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" -#include "llvm/DebugInfo/MSF/StreamArray.h" +#include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include <cstddef> @@ -176,7 +176,7 @@ struct BinaryAnnotationIterator { return Data == Other.Data; } - bool operator!=(BinaryAnnotationIterator Other) const { + bool operator!=(const BinaryAnnotationIterator &Other) const { return !(*this == Other); } @@ -938,7 +938,7 @@ public: }; typedef CVRecord<SymbolKind> CVSymbol; -typedef msf::VarStreamArray<CVSymbol> CVSymbolArray; +typedef VarStreamArray<CVSymbol> CVSymbolArray; } // end namespace codeview } // end namespace llvm diff --git a/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h b/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h index 1bd14ed1347ab..0a1837a0d935f 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h +++ b/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h @@ -14,16 +14,14 @@ #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h" namespace llvm { -namespace msf { -class StreamReader; -class StreamWriter; -} +class BinaryStreamReader; +class BinaryStreamWriter; namespace codeview { class SymbolRecordMapping : public SymbolVisitorCallbacks { public: - explicit SymbolRecordMapping(msf::StreamReader &Reader) : IO(Reader) {} - explicit SymbolRecordMapping(msf::StreamWriter &Writer) : IO(Writer) {} + explicit SymbolRecordMapping(BinaryStreamReader &Reader) : IO(Reader) {} + explicit SymbolRecordMapping(BinaryStreamWriter &Writer) : IO(Writer) {} Error visitSymbolBegin(CVSymbol &Record) override; Error visitSymbolEnd(CVSymbol &Record) override; diff --git a/include/llvm/DebugInfo/CodeView/SymbolSerializer.h b/include/llvm/DebugInfo/CodeView/SymbolSerializer.h index 4eb914e7ae6bd..f2e99bd833260 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolSerializer.h +++ b/include/llvm/DebugInfo/CodeView/SymbolSerializer.h @@ -12,8 +12,6 @@ #include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h" #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h" -#include "llvm/DebugInfo/MSF/ByteStream.h" -#include "llvm/DebugInfo/MSF/StreamWriter.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" @@ -21,14 +19,19 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/BinaryByteStream.h" +#include "llvm/Support/BinaryStreamWriter.h" #include "llvm/Support/Error.h" namespace llvm { +class BinaryStreamWriter; namespace codeview { class SymbolSerializer : public SymbolVisitorCallbacks { - uint32_t RecordStart = 0; - msf::StreamWriter &Writer; + BumpPtrAllocator &Storage; + std::vector<uint8_t> RecordBuffer; + MutableBinaryByteStream Stream; + BinaryStreamWriter Writer; SymbolRecordMapping Mapping; Optional<SymbolKind> CurrentSymbol; @@ -42,40 +45,10 @@ class SymbolSerializer : public SymbolVisitorCallbacks { } public: - explicit SymbolSerializer(msf::StreamWriter &Writer) - : Writer(Writer), Mapping(Writer) {} + explicit SymbolSerializer(BumpPtrAllocator &Storage); - virtual Error visitSymbolBegin(CVSymbol &Record) override { - assert(!CurrentSymbol.hasValue() && "Already in a symbol mapping!"); - - RecordStart = Writer.getOffset(); - if (auto EC = writeRecordPrefix(Record.kind())) - return EC; - - CurrentSymbol = Record.kind(); - if (auto EC = Mapping.visitSymbolBegin(Record)) - return EC; - - return Error::success(); - } - - virtual Error visitSymbolEnd(CVSymbol &Record) override { - assert(CurrentSymbol.hasValue() && "Not in a symbol mapping!"); - - if (auto EC = Mapping.visitSymbolEnd(Record)) - return EC; - - uint32_t RecordEnd = Writer.getOffset(); - Writer.setOffset(RecordStart); - uint16_t Length = RecordEnd - Writer.getOffset() - 2; - if (auto EC = Writer.writeInteger(Length)) - return EC; - - Writer.setOffset(RecordEnd); - CurrentSymbol.reset(); - - return Error::success(); - } + virtual Error visitSymbolBegin(CVSymbol &Record) override; + virtual Error visitSymbolEnd(CVSymbol &Record) override; #define SYMBOL_RECORD(EnumName, EnumVal, Name) \ virtual Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \ diff --git a/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h b/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h index 2b468a289fd82..2bef3f61adfcc 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h +++ b/include/llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h @@ -15,9 +15,7 @@ namespace llvm { -namespace msf { -class StreamReader; -} // end namespace msf +class BinaryStreamReader; namespace codeview { @@ -25,7 +23,7 @@ class SymbolVisitorDelegate { public: virtual ~SymbolVisitorDelegate() = default; - virtual uint32_t getRecordOffset(msf::StreamReader Reader) = 0; + virtual uint32_t getRecordOffset(BinaryStreamReader Reader) = 0; virtual StringRef getFileNameForFileOffset(uint32_t FileOffset) = 0; virtual StringRef getStringTable() = 0; }; diff --git a/include/llvm/DebugInfo/CodeView/TypeDatabase.h b/include/llvm/DebugInfo/CodeView/TypeDatabase.h index cccc2868ffb5f..54ad862cfa7e5 100644 --- a/include/llvm/DebugInfo/CodeView/TypeDatabase.h +++ b/include/llvm/DebugInfo/CodeView/TypeDatabase.h @@ -27,13 +27,15 @@ public: TypeIndex getNextTypeIndex() const; /// Records the name of a type, and reserves its type index. - void recordType(StringRef Name, CVType Data); + void recordType(StringRef Name, const CVType &Data); /// Saves the name in a StringSet and creates a stable StringRef. StringRef saveTypeName(StringRef TypeName); StringRef getTypeName(TypeIndex Index) const; + const CVType &getTypeRecord(TypeIndex Index) const; + bool containsTypeIndex(TypeIndex Index) const; uint32_t size() const; diff --git a/include/llvm/DebugInfo/CodeView/TypeDeserializer.h b/include/llvm/DebugInfo/CodeView/TypeDeserializer.h index dc5eaf82845bb..0e34437891702 100644 --- a/include/llvm/DebugInfo/CodeView/TypeDeserializer.h +++ b/include/llvm/DebugInfo/CodeView/TypeDeserializer.h @@ -16,8 +16,8 @@ #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/DebugInfo/CodeView/TypeRecordMapping.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" -#include "llvm/DebugInfo/MSF/ByteStream.h" -#include "llvm/DebugInfo/MSF/StreamReader.h" +#include "llvm/Support/BinaryByteStream.h" +#include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/Error.h" #include <cassert> #include <cstdint> @@ -29,10 +29,11 @@ namespace codeview { class TypeDeserializer : public TypeVisitorCallbacks { struct MappingInfo { explicit MappingInfo(ArrayRef<uint8_t> RecordData) - : Stream(RecordData), Reader(Stream), Mapping(Reader) {} + : Stream(RecordData, llvm::support::little), Reader(Stream), + Mapping(Reader) {} - msf::ByteStream Stream; - msf::StreamReader Reader; + BinaryByteStream Stream; + BinaryStreamReader Reader; TypeRecordMapping Mapping; }; @@ -72,16 +73,16 @@ private: class FieldListDeserializer : public TypeVisitorCallbacks { struct MappingInfo { - explicit MappingInfo(msf::StreamReader &R) + explicit MappingInfo(BinaryStreamReader &R) : Reader(R), Mapping(Reader), StartOffset(0) {} - msf::StreamReader &Reader; + BinaryStreamReader &Reader; TypeRecordMapping Mapping; uint32_t StartOffset; }; public: - explicit FieldListDeserializer(msf::StreamReader &Reader) : Mapping(Reader) { + explicit FieldListDeserializer(BinaryStreamReader &Reader) : Mapping(Reader) { CVType FieldList; FieldList.Type = TypeLeafKind::LF_FIELDLIST; consumeError(Mapping.Mapping.visitTypeBegin(FieldList)); diff --git a/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h b/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h index a466e42981582..00bb09137e488 100644 --- a/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h +++ b/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h @@ -28,8 +28,16 @@ public: TypeDumpVisitor(TypeDatabase &TypeDB, ScopedPrinter *W, bool PrintRecordBytes) : W(W), PrintRecordBytes(PrintRecordBytes), TypeDB(TypeDB) {} + /// When dumping types from an IPI stream in a PDB, a type index may refer to + /// a type or an item ID. The dumper will lookup the "name" of the index in + /// the item database if appropriate. If ItemDB is null, it will use TypeDB, + /// which is correct when dumping types from an object file (/Z7). + void setItemDB(TypeDatabase &DB) { ItemDB = &DB; } + void printTypeIndex(StringRef FieldName, TypeIndex TI) const; + void printItemIndex(StringRef FieldName, TypeIndex TI) const; + /// Action to take on unknown types. By default, they are ignored. Error visitUnknownType(CVType &Record) override; Error visitUnknownMember(CVMemberRecord &Record) override; @@ -54,11 +62,17 @@ private: void printMemberAttributes(MemberAccess Access, MethodKind Kind, MethodOptions Options); + /// Get the database of indices for the stream that we are dumping. If ItemDB + /// is set, then we must be dumping an item (IPI) stream. This will also + /// always get the appropriate DB for printing item names. + TypeDatabase &getSourceDB() const { return ItemDB ? *ItemDB : TypeDB; } + ScopedPrinter *W; bool PrintRecordBytes = false; TypeDatabase &TypeDB; + TypeDatabase *ItemDB = nullptr; }; } // end namespace codeview diff --git a/include/llvm/DebugInfo/CodeView/TypeRecord.h b/include/llvm/DebugInfo/CodeView/TypeRecord.h index 4f1c047815d29..1f10872c87680 100644 --- a/include/llvm/DebugInfo/CodeView/TypeRecord.h +++ b/include/llvm/DebugInfo/CodeView/TypeRecord.h @@ -18,7 +18,7 @@ #include "llvm/DebugInfo/CodeView/CVRecord.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" -#include "llvm/DebugInfo/MSF/StreamArray.h" +#include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/Endian.h" #include <algorithm> #include <cstdint> @@ -26,9 +26,7 @@ namespace llvm { -namespace msf { -class StreamReader; -} // end namespace msf +class BinaryStreamReader; namespace codeview { @@ -42,7 +40,8 @@ struct CVMemberRecord { TypeLeafKind Kind; ArrayRef<uint8_t> Data; }; -typedef msf::VarStreamArray<CVType> CVTypeArray; +typedef VarStreamArray<CVType> CVTypeArray; +typedef iterator_range<CVTypeArray::Iterator> CVTypeRange; /// Equvalent to CV_fldattr_t in cvinfo.h. struct MemberAttributes { @@ -106,10 +105,6 @@ public: PointerToMemberRepresentation Representation) : ContainingType(ContainingType), Representation(Representation) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getContainingType() const { return ContainingType; } PointerToMemberRepresentation getRepresentation() const { return Representation; @@ -139,10 +134,6 @@ public: : TypeRecord(TypeRecordKind::Modifier), ModifiedType(ModifiedType), Modifiers(Modifiers) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getModifiedType() const { return ModifiedType; } ModifierOptions getModifiers() const { return Modifiers; } @@ -161,10 +152,6 @@ public: CallConv(CallConv), Options(Options), ParameterCount(ParameterCount), ArgumentList(ArgumentList) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getReturnType() const { return ReturnType; } CallingConvention getCallConv() const { return CallConv; } FunctionOptions getOptions() const { return Options; } @@ -193,10 +180,6 @@ public: ArgumentList(ArgumentList), ThisPointerAdjustment(ThisPointerAdjustment) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getReturnType() const { return ReturnType; } TypeIndex getClassType() const { return ClassType; } TypeIndex getThisType() const { return ThisType; } @@ -216,6 +199,16 @@ public: int32_t ThisPointerAdjustment; }; +// LF_LABEL +class LabelRecord : public TypeRecord { +public: + explicit LabelRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} + + LabelRecord(LabelType Mode) : TypeRecord(TypeRecordKind::Label), Mode(Mode) {} + + LabelType Mode; +}; + // LF_MFUNC_ID class MemberFuncIdRecord : public TypeRecord { public: @@ -225,10 +218,6 @@ public: : TypeRecord(TypeRecordKind::MemberFuncId), ClassType(ClassType), FunctionType(FunctionType), Name(Name) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getClassType() const { return ClassType; } TypeIndex getFunctionType() const { return FunctionType; } StringRef getName() const { return Name; } @@ -237,17 +226,26 @@ public: StringRef Name; }; -// LF_ARGLIST, LF_SUBSTR_LIST +// LF_ARGLIST class ArgListRecord : public TypeRecord { public: explicit ArgListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} ArgListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices) - : TypeRecord(Kind), StringIndices(Indices) {} + : TypeRecord(Kind), ArgIndices(Indices) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); + ArrayRef<TypeIndex> getIndices() const { return ArgIndices; } + + std::vector<TypeIndex> ArgIndices; +}; + +// LF_SUBSTR_LIST +class StringListRecord : public TypeRecord { +public: + explicit StringListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} + + StringListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices) + : TypeRecord(Kind), StringIndices(Indices) {} ArrayRef<TypeIndex> getIndices() const { return StringIndices; } @@ -290,10 +288,6 @@ public: : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType), Attrs(Attrs), MemberInfo(Member) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getReferentType() const { return ReferentType; } PointerKind getPointerKind() const { @@ -356,10 +350,6 @@ public: NestedTypeRecord(TypeIndex Type, StringRef Name) : TypeRecord(TypeRecordKind::NestedType), Type(Type), Name(Name) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getNestedType() const { return Type; } StringRef getName() const { return Name; } @@ -374,10 +364,6 @@ public: explicit FieldListRecord(ArrayRef<uint8_t> Data) : TypeRecord(TypeRecordKind::FieldList), Data(Data) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap) { return false; } - ArrayRef<uint8_t> Data; }; @@ -390,10 +376,6 @@ public: : TypeRecord(TypeRecordKind::Array), ElementType(ElementType), IndexType(IndexType), Size(Size), Name(Name) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getElementType() const { return ElementType; } TypeIndex getIndexType() const { return IndexType; } uint64_t getSize() const { return Size; } @@ -414,10 +396,6 @@ protected: FieldList(FieldList), Name(Name), UniqueName(UniqueName) {} public: - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - static const int HfaKindShift = 11; static const int HfaKindMask = 0x1800; static const int WinRTKindShift = 14; @@ -451,10 +429,6 @@ public: : TagRecord(Kind, MemberCount, Options, FieldList, Name, UniqueName), DerivationList(DerivationList), VTableShape(VTableShape), Size(Size) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - HfaKind getHfa() const { uint16_t Value = static_cast<uint16_t>(Options); Value = (Value & HfaKindMask) >> HfaKindShift; @@ -506,9 +480,6 @@ public: UniqueName), UnderlyingType(UnderlyingType) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getUnderlyingType() const { return UnderlyingType; } TypeIndex UnderlyingType; }; @@ -521,10 +492,6 @@ public: : TypeRecord(TypeRecordKind::BitField), Type(Type), BitSize(BitSize), BitOffset(BitOffset) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getType() const { return Type; } uint8_t getBitOffset() const { return BitOffset; } uint8_t getBitSize() const { return BitSize; } @@ -542,10 +509,6 @@ public: explicit VFTableShapeRecord(std::vector<VFTableSlotKind> Slots) : TypeRecord(TypeRecordKind::VFTableShape), Slots(std::move(Slots)) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - ArrayRef<VFTableSlotKind> getSlots() const { if (!SlotsRef.empty()) return SlotsRef; @@ -565,10 +528,6 @@ public: : TypeRecord(TypeRecordKind::TypeServer2), Guid(Guid), Age(Age), Name(Name) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - StringRef getGuid() const { return Guid; } uint32_t getAge() const { return Age; } @@ -587,10 +546,6 @@ public: StringIdRecord(TypeIndex Id, StringRef String) : TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getId() const { return Id; } StringRef getString() const { return String; } @@ -606,10 +561,6 @@ public: : TypeRecord(TypeRecordKind::FuncId), ParentScope(ParentScope), FunctionType(FunctionType), Name(Name) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getParentScope() const { return ParentScope; } TypeIndex getFunctionType() const { return FunctionType; } @@ -629,10 +580,6 @@ public: : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT), SourceFile(SourceFile), LineNumber(LineNumber) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getUDT() const { return UDT; } TypeIndex getSourceFile() const { return SourceFile; } uint32_t getLineNumber() const { return LineNumber; } @@ -651,8 +598,6 @@ public: : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT), SourceFile(SourceFile), LineNumber(LineNumber), Module(Module) {} - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getUDT() const { return UDT; } TypeIndex getSourceFile() const { return SourceFile; } uint32_t getLineNumber() const { return LineNumber; } @@ -672,10 +617,6 @@ public: : TypeRecord(TypeRecordKind::BuildInfo), ArgIndices(ArgIndices.begin(), ArgIndices.end()) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - ArrayRef<TypeIndex> getArgs() const { return ArgIndices; } SmallVector<TypeIndex, 4> ArgIndices; }; @@ -693,10 +634,6 @@ public: MethodNames.insert(MethodNames.end(), Methods.begin(), Methods.end()); } - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getCompleteClass() const { return CompleteClass; } TypeIndex getOverriddenVTable() const { return OverriddenVFTable; } uint32_t getVFPtrOffset() const { return VFPtrOffset; } @@ -725,10 +662,6 @@ public: : TypeRecord(TypeRecordKind::OneMethod), Type(Type), Attrs(Access, MK, Options), VFTableOffset(VFTableOffset), Name(Name) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getType() const { return Type; } MethodKind getMethodKind() const { return Attrs.getMethodKind(); } MethodOptions getOptions() const { return Attrs.getFlags(); } @@ -754,10 +687,6 @@ public: MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods) : TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - ArrayRef<OneMethodRecord> getMethods() const { return Methods; } std::vector<OneMethodRecord> Methods; }; @@ -771,10 +700,6 @@ public: : TypeRecord(TypeRecordKind::OverloadedMethod), NumOverloads(NumOverloads), MethodList(MethodList), Name(Name) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - uint16_t getNumOverloads() const { return NumOverloads; } TypeIndex getMethodList() const { return MethodList; } StringRef getName() const { return Name; } @@ -796,10 +721,6 @@ public: : TypeRecord(TypeRecordKind::DataMember), Attrs(Access), Type(Type), FieldOffset(Offset), Name(Name) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - MemberAccess getAccess() const { return Attrs.getAccess(); } TypeIndex getType() const { return Type; } uint64_t getFieldOffset() const { return FieldOffset; } @@ -822,10 +743,6 @@ public: : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Access), Type(Type), Name(Name) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - MemberAccess getAccess() const { return Attrs.getAccess(); } TypeIndex getType() const { return Type; } StringRef getName() const { return Name; } @@ -846,10 +763,6 @@ public: : TypeRecord(TypeRecordKind::Enumerator), Attrs(Access), Value(std::move(Value)), Name(Name) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - MemberAccess getAccess() const { return Attrs.getAccess(); } APSInt getValue() const { return Value; } StringRef getName() const { return Name; } @@ -866,10 +779,6 @@ public: VFPtrRecord(TypeIndex Type) : TypeRecord(TypeRecordKind::VFPtr), Type(Type) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex getType() const { return Type; } TypeIndex Type; @@ -886,10 +795,6 @@ public: : TypeRecord(TypeRecordKind::BaseClass), Attrs(Access), Type(Type), Offset(Offset) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - MemberAccess getAccess() const { return Attrs.getAccess(); } TypeIndex getBaseType() const { return Type; } uint64_t getBaseOffset() const { return Offset; } @@ -914,10 +819,6 @@ public: : TypeRecord(Kind), Attrs(Access), BaseType(BaseType), VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {} - /// Rewrite member type indices with IndexMap. Returns false if a type index - /// is not in the map. - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - MemberAccess getAccess() const { return Attrs.getAccess(); } TypeIndex getBaseType() const { return BaseType; } TypeIndex getVBPtrType() const { return VBPtrType; } @@ -942,8 +843,6 @@ public: TypeIndex getContinuationIndex() const { return ContinuationIndex; } - bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap); - TypeIndex ContinuationIndex; }; diff --git a/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h b/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h index fe470a72abbb1..924ca0470fad4 100644 --- a/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h +++ b/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h @@ -16,15 +16,14 @@ #include "llvm/Support/Error.h" namespace llvm { -namespace msf { -class StreamReader; -class StreamWriter; -} +class BinaryStreamReader; +class BinaryStreamWriter; + namespace codeview { class TypeRecordMapping : public TypeVisitorCallbacks { public: - explicit TypeRecordMapping(msf::StreamReader &Reader) : IO(Reader) {} - explicit TypeRecordMapping(msf::StreamWriter &Writer) : IO(Writer) {} + explicit TypeRecordMapping(BinaryStreamReader &Reader) : IO(Reader) {} + explicit TypeRecordMapping(BinaryStreamWriter &Writer) : IO(Writer) {} Error visitTypeBegin(CVType &Record) override; Error visitTypeEnd(CVType &Record) override; diff --git a/include/llvm/DebugInfo/CodeView/TypeRecords.def b/include/llvm/DebugInfo/CodeView/TypeRecords.def index c98dbac21a7a0..8c193bb13cb7e 100644 --- a/include/llvm/DebugInfo/CodeView/TypeRecords.def +++ b/include/llvm/DebugInfo/CodeView/TypeRecords.def @@ -41,6 +41,7 @@ TYPE_RECORD(LF_POINTER, 0x1002, Pointer) TYPE_RECORD(LF_MODIFIER, 0x1001, Modifier) TYPE_RECORD(LF_PROCEDURE, 0x1008, Procedure) TYPE_RECORD(LF_MFUNCTION, 0x1009, MemberFunction) +TYPE_RECORD(LF_LABEL, 0x000e, Label) TYPE_RECORD(LF_ARGLIST, 0x1201, ArgList) TYPE_RECORD(LF_FIELDLIST, 0x1203, FieldList) @@ -79,9 +80,7 @@ MEMBER_RECORD(LF_INDEX, 0x1404, ListContinuation) TYPE_RECORD(LF_FUNC_ID, 0x1601, FuncId) TYPE_RECORD(LF_MFUNC_ID, 0x1602, MemberFuncId) TYPE_RECORD(LF_BUILDINFO, 0x1603, BuildInfo) -// FIXME: We reuse the structure of ArgListRecord for substring lists, but it -// makes for confusing dumper output. -TYPE_RECORD_ALIAS(LF_SUBSTR_LIST, 0x1604, StringList, ArgList) +TYPE_RECORD(LF_SUBSTR_LIST, 0x1604, StringList) TYPE_RECORD(LF_STRING_ID, 0x1605, StringId) TYPE_RECORD(LF_UDT_SRC_LINE, 0x1606, UdtSourceLine) TYPE_RECORD(LF_UDT_MOD_SRC_LINE, 0x1607, UdtModSourceLine) @@ -103,7 +102,6 @@ CV_TYPE(LF_MFUNCTION_16t, 0x0009) CV_TYPE(LF_COBOL0_16t, 0x000b) CV_TYPE(LF_COBOL1, 0x000c) CV_TYPE(LF_BARRAY_16t, 0x000d) -CV_TYPE(LF_LABEL, 0x000e) CV_TYPE(LF_NULLLEAF, 0x000f) // LF_NULL CV_TYPE(LF_NOTTRAN, 0x0010) CV_TYPE(LF_DIMARRAY_16t, 0x0011) diff --git a/include/llvm/DebugInfo/CodeView/TypeSerializer.h b/include/llvm/DebugInfo/CodeView/TypeSerializer.h index e059221946384..1f4873c4f9693 100644 --- a/include/llvm/DebugInfo/CodeView/TypeSerializer.h +++ b/include/llvm/DebugInfo/CodeView/TypeSerializer.h @@ -12,8 +12,8 @@ #include "llvm/DebugInfo/CodeView/TypeRecordMapping.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" -#include "llvm/DebugInfo/MSF/ByteStream.h" -#include "llvm/DebugInfo/MSF/StreamWriter.h" +#include "llvm/Support/BinaryByteStream.h" +#include "llvm/Support/BinaryStreamWriter.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" @@ -56,8 +56,8 @@ class TypeSerializer : public TypeVisitorCallbacks { Optional<TypeLeafKind> TypeKind; Optional<TypeLeafKind> MemberKind; std::vector<uint8_t> RecordBuffer; - msf::MutableByteStream Stream; - msf::StreamWriter Writer; + MutableBinaryByteStream Stream; + BinaryStreamWriter Writer; TypeRecordMapping Mapping; RecordList SeenRecords; diff --git a/include/llvm/DebugInfo/CodeView/TypeServerHandler.h b/include/llvm/DebugInfo/CodeView/TypeServerHandler.h new file mode 100644 index 0000000000000..35f06eaf6eb40 --- /dev/null +++ b/include/llvm/DebugInfo/CodeView/TypeServerHandler.h @@ -0,0 +1,36 @@ +//===- TypeServerHandler.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_TYPESERVERHANDLER_H +#define LLVM_DEBUGINFO_CODEVIEW_TYPESERVERHANDLER_H + +#include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/Support/Error.h" + +namespace llvm { +namespace codeview { +class TypeVisitorCallbacks; + +class TypeServerHandler { +public: + virtual ~TypeServerHandler() {} + + /// Handle a TypeServer record. If the implementation returns true + /// the record will not be processed by the top-level visitor. If + /// it returns false, it will be processed. If it returns an Error, + /// then the top-level visitor will fail. + virtual Expected<bool> handle(TypeServer2Record &TS, + TypeVisitorCallbacks &Callbacks) { + return false; + } +}; +} +} + +#endif diff --git a/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h b/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h index af396c79d0741..2246f197e7843 100644 --- a/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h +++ b/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h @@ -13,12 +13,17 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" +#include "llvm/Support/Error.h" namespace llvm { namespace codeview { +class TypeServerHandler; + /// Merges one type stream into another. Returns true on success. -bool mergeTypeStreams(TypeTableBuilder &DestStream, const CVTypeArray &Types); +Error mergeTypeStreams(TypeTableBuilder &DestIdStream, + TypeTableBuilder &DestTypeStream, + TypeServerHandler *Handler, const CVTypeArray &Types); } // end namespace codeview } // end namespace llvm diff --git a/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h b/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h index 4e6d81ece318b..102bee4b0801e 100644 --- a/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h +++ b/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h @@ -121,6 +121,12 @@ public: } return Index; } + + /// Stop building the record. + void reset() { + if (auto EC = TempSerializer.visitTypeEnd(Type)) + consumeError(std::move(EC)); + } }; } // end namespace codeview diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h index 804419c517dfc..e3386a8dcd24c 100644 --- a/include/llvm/DebugInfo/DIContext.h +++ b/include/llvm/DebugInfo/DIContext.h @@ -1,4 +1,4 @@ -//===-- DIContext.h ---------------------------------------------*- C++ -*-===// +//===- DIContext.h ----------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -32,26 +32,28 @@ class raw_ostream; struct DILineInfo { std::string FileName; std::string FunctionName; - uint32_t Line; - uint32_t Column; + uint32_t Line = 0; + uint32_t Column = 0; + uint32_t StartLine = 0; // DWARF-specific. - uint32_t Discriminator; + uint32_t Discriminator = 0; - DILineInfo() - : FileName("<invalid>"), FunctionName("<invalid>"), Line(0), Column(0), - Discriminator(0) {} + DILineInfo() : FileName("<invalid>"), FunctionName("<invalid>") {} bool operator==(const DILineInfo &RHS) const { return Line == RHS.Line && Column == RHS.Column && - FileName == RHS.FileName && FunctionName == RHS.FunctionName; + FileName == RHS.FileName && FunctionName == RHS.FunctionName && + StartLine == RHS.StartLine && Discriminator == RHS.Discriminator; } bool operator!=(const DILineInfo &RHS) const { return !(*this == RHS); } bool operator<(const DILineInfo &RHS) const { - return std::tie(FileName, FunctionName, Line, Column) < - std::tie(RHS.FileName, RHS.FunctionName, RHS.Line, RHS.Column); + return std::tie(FileName, FunctionName, Line, Column, StartLine, + Discriminator) < + std::tie(RHS.FileName, RHS.FunctionName, RHS.Line, RHS.Column, + RHS.StartLine, RHS.Discriminator); } }; @@ -86,10 +88,10 @@ public: /// DIGlobal - container for description of a global variable. struct DIGlobal { std::string Name; - uint64_t Start; - uint64_t Size; + uint64_t Start = 0; + uint64_t Size = 0; - DIGlobal() : Name("<invalid>"), Start(0), Size(0) {} + DIGlobal() : Name("<invalid>") {} }; /// A DINameKind is passed to name search methods to specify a @@ -175,8 +177,8 @@ private: /// on the fly. class LoadedObjectInfo { protected: - LoadedObjectInfo(const LoadedObjectInfo &) = default; LoadedObjectInfo() = default; + LoadedObjectInfo(const LoadedObjectInfo &) = default; public: virtual ~LoadedObjectInfo() = default; diff --git a/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h b/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h index db9bd506be897..7324f6e3eb387 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h +++ b/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h @@ -1,4 +1,4 @@ -//===-- DWARFAbbreviationDeclaration.h --------------------------*- C++ -*-===// +//===- DWARFAbbreviationDeclaration.h ---------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,17 +7,22 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H -#define LLVM_LIB_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H +#ifndef LLVM_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H +#define LLVM_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H +#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/DataExtractor.h" #include "llvm/Support/Dwarf.h" +#include <cassert> +#include <cstddef> +#include <cstdint> + namespace llvm { -class DWARFUnit; class DWARFFormValue; +class DWARFUnit; class raw_ostream; class DWARFAbbreviationDeclaration { @@ -25,6 +30,7 @@ public: struct AttributeSpec { AttributeSpec(dwarf::Attribute A, dwarf::Form F, Optional<int64_t> V) : Attr(A), Form(F), ByteSizeOrValue(V) {} + dwarf::Attribute Attr; dwarf::Form Form; /// The following field is used for ByteSize for non-implicit_const @@ -41,9 +47,11 @@ public: /// * Form == DW_FORM_implicit_const: /// ByteSizeOrValue contains value for the implicit_const attribute. Optional<int64_t> ByteSizeOrValue; + bool isImplicitConst() const { return Form == dwarf::DW_FORM_implicit_const; } + /// Get the fixed byte size of this Form if possible. This function might /// use the DWARFUnit to calculate the size of the Form, like for /// DW_AT_address and DW_AT_ref_addr, so this isn't just an accessor for @@ -55,6 +63,7 @@ public: DWARFAbbreviationDeclaration(); uint32_t getCode() const { return Code; } + uint8_t getCodeByteSize() const { return CodeByteSize; } dwarf::Tag getTag() const { return Tag; } bool hasChildren() const { return HasChildren; } @@ -66,9 +75,17 @@ public: } dwarf::Form getFormByIndex(uint32_t idx) const { - if (idx < AttributeSpecs.size()) - return AttributeSpecs[idx].Form; - return dwarf::Form(0); + assert(idx < AttributeSpecs.size()); + return AttributeSpecs[idx].Form; + } + + size_t getNumAttributes() const { + return AttributeSpecs.size(); + } + + dwarf::Attribute getAttrByIndex(uint32_t idx) const { + assert(idx < AttributeSpecs.size()); + return AttributeSpecs[idx].Attr; } /// Get the index of the specified attribute. @@ -109,16 +126,16 @@ private: /// abbreviation declaration. struct FixedSizeInfo { /// The fixed byte size for fixed size forms. - uint16_t NumBytes; + uint16_t NumBytes = 0; /// Number of DW_FORM_address forms in this abbrevation declaration. - uint8_t NumAddrs; + uint8_t NumAddrs = 0; /// Number of DW_FORM_ref_addr forms in this abbrevation declaration. - uint8_t NumRefAddrs; + uint8_t NumRefAddrs = 0; /// Number of 4 byte in DWARF32 and 8 byte in DWARF64 forms. - uint8_t NumDwarfOffsets; - /// Constructor - FixedSizeInfo() - : NumBytes(0), NumAddrs(0), NumRefAddrs(0), NumDwarfOffsets(0) {} + uint8_t NumDwarfOffsets = 0; + + FixedSizeInfo() = default; + /// Calculate the fixed size in bytes given a DWARFUnit. /// /// \param U the DWARFUnit to use when determing the byte size. @@ -138,6 +155,6 @@ private: Optional<FixedSizeInfo> FixedAttributeSize; }; -} +} // end namespace llvm -#endif +#endif // LLVM_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h b/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h index 63343728fa99a..f95a013d75523 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h +++ b/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h @@ -1,4 +1,4 @@ -//===--- DWARFAcceleratorTable.h --------------------------------*- C++ -*-===// +//===- DWARFAcceleratorTable.h ----------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,19 +7,21 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFACCELERATORTABLE_H -#define LLVM_LIB_DEBUGINFO_DWARFACCELERATORTABLE_H +#ifndef LLVM_DEBUGINFO_DWARFACCELERATORTABLE_H +#define LLVM_DEBUGINFO_DWARFACCELERATORTABLE_H #include "llvm/ADT/SmallVector.h" -#include "llvm/DebugInfo/DWARF/DWARFFormValue.h" #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" +#include "llvm/Support/DataExtractor.h" #include "llvm/Support/Dwarf.h" #include <cstdint> +#include <utility> namespace llvm { -class DWARFAcceleratorTable { +class raw_ostream; +class DWARFAcceleratorTable { struct Header { uint32_t Magic; uint16_t Version; @@ -41,6 +43,7 @@ class DWARFAcceleratorTable { DataExtractor AccelSection; DataExtractor StringSection; const RelocAddrMap& Relocs; + public: DWARFAcceleratorTable(DataExtractor AccelSection, DataExtractor StringSection, const RelocAddrMap &Relocs) @@ -50,6 +53,6 @@ public: void dump(raw_ostream &OS) const; }; -} +} // end namespace llvm -#endif +#endif // LLVM_DEBUGINFO_DWARFACCELERATORTABLE_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFAttribute.h b/include/llvm/DebugInfo/DWARF/DWARFAttribute.h new file mode 100644 index 0000000000000..5919aaddea409 --- /dev/null +++ b/include/llvm/DebugInfo/DWARF/DWARFAttribute.h @@ -0,0 +1,56 @@ +//===- DWARFAttribute.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_DWARFATTRIBUTE_H +#define LLVM_DEBUGINFO_DWARFATTRIBUTE_H + +#include "llvm/DebugInfo/DWARF/DWARFFormValue.h" +#include "llvm/Support/Dwarf.h" +#include <cstdint> + +namespace llvm { + +//===----------------------------------------------------------------------===// +/// Encapsulates a DWARF attribute value and all of the data required to +/// describe the attribute value. +/// +/// This class is designed to be used by clients that want to iterate across all +/// attributes in a DWARFDie. +struct DWARFAttribute { + /// The debug info/types offset for this attribute. + uint32_t Offset = 0; + /// The debug info/types section byte size of the data for this attribute. + uint32_t ByteSize = 0; + /// The attribute enumeration of this attribute. + dwarf::Attribute Attr; + /// The form and value for this attribute. + DWARFFormValue Value; + + DWARFAttribute(uint32_t O, dwarf::Attribute A = dwarf::Attribute(0), + dwarf::Form F = dwarf::Form(0)) : Attr(A), Value(F) {} + + bool isValid() const { + return Offset != 0 && Attr != dwarf::Attribute(0); + } + + explicit operator bool() const { + return isValid(); + } + + void clear() { + Offset = 0; + ByteSize = 0; + Attr = dwarf::Attribute(0); + Value = DWARFFormValue(); + } +}; + +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_DWARFATTRIBUTE_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h b/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h index bba3abe6e9e96..b2a4d247ccc6b 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h @@ -1,4 +1,4 @@ -//===-- DWARFCompileUnit.h --------------------------------------*- C++ -*-===// +//===- DWARFCompileUnit.h ---------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,10 +7,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFCOMPILEUNIT_H -#define LLVM_LIB_DEBUGINFO_DWARFCOMPILEUNIT_H +#ifndef LLVM_DEBUGINFO_DWARFCOMPILEUNIT_H +#define LLVM_DEBUGINFO_DWARFCOMPILEUNIT_H #include "llvm/DebugInfo/DWARF/DWARFUnit.h" +#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" namespace llvm { @@ -23,12 +24,15 @@ public: const DWARFUnitIndex::Entry *Entry) : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, UnitSection, Entry) {} - void dump(raw_ostream &OS); - static const DWARFSectionKind Section = DW_SECT_INFO; + // VTable anchor. ~DWARFCompileUnit() override; + + void dump(raw_ostream &OS); + + static const DWARFSectionKind Section = DW_SECT_INFO; }; -} +} // end namespace llvm -#endif +#endif // LLVM_DEBUGINFO_DWARFCOMPILEUNIT_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFContext.h b/include/llvm/DebugInfo/DWARF/DWARFContext.h index ef310e7040054..f941cdd1060a5 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -1,4 +1,4 @@ -//===-- DWARFContext.h ------------------------------------------*- C++ -*-===// +//===- DWARFContext.h -------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,14 +7,15 @@ // //===----------------------------------------------------------------------===/ -#ifndef LLVM_LIB_DEBUGINFO_DWARFCONTEXT_H -#define LLVM_LIB_DEBUGINFO_DWARFCONTEXT_H +#ifndef LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H +#define LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/iterator_range.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/DIContext.h" #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h" @@ -30,6 +31,7 @@ #include "llvm/DebugInfo/DWARF/DWARFUnit.h" #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" #include "llvm/Object/ObjectFile.h" +#include "llvm/Support/Host.h" #include <cstdint> #include <deque> #include <map> @@ -38,6 +40,9 @@ namespace llvm { +class MemoryBuffer; +class raw_ostream; + // In place of applying the relocations to the data we've read from disk we use // a separate mapping table to the side and checking that at locations in the // dwarf where we expect relocated values. This adds a bit of complexity to the @@ -293,10 +298,16 @@ class DWARFContextInMemory : public DWARFContext { SmallVector<SmallString<32>, 4> UncompressedSections; + StringRef *MapSectionToMember(StringRef Name); + public: DWARFContextInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr); + DWARFContextInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, + uint8_t AddrSize, + bool isLittleEndian = sys::IsLittleEndianHost); + bool isLittleEndian() const override { return IsLittleEndian; } uint8_t getAddressSize() const override { return AddressSize; } const DWARFSection &getInfoSection() override { return InfoSection; } @@ -321,20 +332,26 @@ public: // Sections for DWARF5 split dwarf proposal. const DWARFSection &getInfoDWOSection() override { return InfoDWOSection; } + const TypeSectionMap &getTypesDWOSections() override { return TypesDWOSections; } + StringRef getAbbrevDWOSection() override { return AbbrevDWOSection; } const DWARFSection &getLineDWOSection() override { return LineDWOSection; } const DWARFSection &getLocDWOSection() override { return LocDWOSection; } StringRef getStringDWOSection() override { return StringDWOSection; } + StringRef getStringOffsetDWOSection() override { return StringOffsetDWOSection; } + StringRef getRangeDWOSection() override { return RangeDWOSection; } + StringRef getAddrSection() override { return AddrSection; } + StringRef getCUIndexSection() override { return CUIndexSection; } StringRef getGdbIndexSection() override { return GdbIndexSection; } StringRef getTUIndexSection() override { return TUIndexSection; } @@ -342,4 +359,4 @@ public: } // end namespace llvm -#endif // LLVM_LIB_DEBUGINFO_DWARFCONTEXT_H +#endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h b/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h index f732deef548c8..9f86fe5083896 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h @@ -1,4 +1,4 @@ -//===-- DWARFDebugAbbrev.h --------------------------------------*- C++ -*-===// +//===- DWARFDebugAbbrev.h ---------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,10 +7,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGABBREV_H -#define LLVM_LIB_DEBUGINFO_DWARFDEBUGABBREV_H +#ifndef LLVM_DEBUGINFO_DWARFDEBUGABBREV_H +#define LLVM_DEBUGINFO_DWARFDEBUGABBREV_H #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h" +#include "llvm/Support/DataExtractor.h" +#include <cstdint> #include <map> #include <vector> @@ -76,6 +78,6 @@ private: void clear(); }; -} +} // end namespace llvm -#endif +#endif // LLVM_DEBUGINFO_DWARFDEBUGABBREV_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h b/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h index 5a602392add81..40eb7e9a88364 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h @@ -1,4 +1,4 @@ -//===-- DWARFDebugArangeSet.h -----------------------------------*- C++ -*-===// +//===- DWARFDebugArangeSet.h ------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,11 +7,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGARANGESET_H -#define LLVM_LIB_DEBUGINFO_DWARFDEBUGARANGESET_H +#ifndef LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H +#define LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H #include "llvm/ADT/iterator_range.h" #include "llvm/Support/DataExtractor.h" +#include <cstdint> #include <vector> namespace llvm { @@ -40,6 +41,7 @@ public: struct Descriptor { uint64_t Address; uint64_t Length; + uint64_t getEndAddress() const { return Address + Length; } }; @@ -53,6 +55,7 @@ private: public: DWARFDebugArangeSet() { clear(); } + void clear(); bool extract(DataExtractor data, uint32_t *offset_ptr); void dump(raw_ostream &OS) const; @@ -67,6 +70,6 @@ public: } }; -} +} // end namespace llvm -#endif +#endif // LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h b/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h index 791f010a8892b..c06771d6afb43 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h @@ -1,4 +1,4 @@ -//===-- DWARFDebugAranges.h -------------------------------------*- C++ -*-===// +//===- DWARFDebugAranges.h --------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,11 +7,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGARANGES_H -#define LLVM_LIB_DEBUGINFO_DWARFDEBUGARANGES_H +#ifndef LLVM_DEBUGINFO_DWARFDEBUGARANGES_H +#define LLVM_DEBUGINFO_DWARFDEBUGARANGES_H #include "llvm/ADT/DenseSet.h" #include "llvm/Support/DataExtractor.h" +#include <cstdint> #include <vector> namespace llvm { @@ -42,6 +43,7 @@ private: else Length = HighPC - LowPC; } + uint64_t HighPC() const { if (Length) return LowPC + Length; @@ -51,6 +53,7 @@ private: bool containsAddress(uint64_t Address) const { return LowPC <= Address && Address < HighPC(); } + bool operator<(const Range &other) const { return LowPC < other.LowPC; } @@ -73,7 +76,6 @@ private: } }; - typedef std::vector<Range> RangeColl; typedef RangeColl::const_iterator RangeCollIterator; @@ -82,6 +84,6 @@ private: DenseSet<uint32_t> ParsedCUOffsets; }; -} +} // end namespace llvm -#endif +#endif // LLVM_DEBUGINFO_DWARFDEBUGARANGES_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h b/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h index cd76c909ddaef..e0a779bb81823 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h @@ -1,4 +1,4 @@ -//===-- DWARFDebugFrame.h - Parsing of .debug_frame -------------*- C++ -*-===// +//===- DWARFDebugFrame.h - Parsing of .debug_frame --------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,23 +7,24 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGFRAME_H -#define LLVM_LIB_DEBUGINFO_DWARFDEBUGFRAME_H +#ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H +#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H #include "llvm/Support/DataExtractor.h" -#include "llvm/Support/raw_ostream.h" #include <memory> #include <vector> namespace llvm { class FrameEntry; +class raw_ostream; /// \brief A parsed .debug_frame or .eh_frame section /// class DWARFDebugFrame { // True if this is parsing an eh_frame section. bool IsEH; + public: DWARFDebugFrame(bool IsEH); ~DWARFDebugFrame(); @@ -39,7 +40,6 @@ private: std::vector<std::unique_ptr<FrameEntry>> Entries; }; +} // end namespace llvm -} // namespace llvm - -#endif +#endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGFRAME_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h b/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h index f36f470980b1a..fc2423a2708b8 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h @@ -1,4 +1,4 @@ -//===-- DWARFDebugInfoEntry.h -----------------------------------*- C++ -*-===// +//===- DWARFDebugInfoEntry.h ------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,43 +7,37 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGINFOENTRY_H -#define LLVM_LIB_DEBUGINFO_DWARFDEBUGINFOENTRY_H +#ifndef LLVM_DEBUGINFO_DWARFDEBUGINFOENTRY_H +#define LLVM_DEBUGINFO_DWARFDEBUGINFOENTRY_H -#include "llvm/ADT/SmallVector.h" -#include "llvm/DebugInfo/DIContext.h" #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h" -#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" -#include "llvm/Support/DataTypes.h" #include "llvm/Support/Dwarf.h" +#include <cstdint> namespace llvm { -class DWARFDebugAranges; -class DWARFCompileUnit; +class DataExtractor; class DWARFUnit; -class DWARFContext; -class DWARFFormValue; -struct DWARFDebugInfoEntryInlinedChain; /// DWARFDebugInfoEntry - A DIE with only the minimum required data. class DWARFDebugInfoEntry { /// Offset within the .debug_info of the start of this entry. - uint32_t Offset; + uint32_t Offset = 0; /// The integer depth of this DIE within the compile unit DIEs where the /// compile/type unit DIE has a depth of zero. - uint32_t Depth; + uint32_t Depth = 0; + + const DWARFAbbreviationDeclaration *AbbrevDecl = nullptr; - const DWARFAbbreviationDeclaration *AbbrevDecl; public: - DWARFDebugInfoEntry() - : Offset(0), Depth(0), AbbrevDecl(nullptr) {} + DWARFDebugInfoEntry() = default; /// Extracts a debug info entry, which is a child of a given unit, /// starting at a given offset. If DIE can't be extracted, returns false and /// doesn't change OffsetPtr. bool extractFast(const DWARFUnit &U, uint32_t *OffsetPtr); + /// High performance extraction should use this call. bool extractFast(const DWARFUnit &U, uint32_t *OffsetPtr, const DataExtractor &DebugInfoData, @@ -52,15 +46,18 @@ public: uint32_t getOffset() const { return Offset; } uint32_t getDepth() const { return Depth; } + dwarf::Tag getTag() const { return AbbrevDecl ? AbbrevDecl->getTag() : dwarf::DW_TAG_null; } + bool hasChildren() const { return AbbrevDecl && AbbrevDecl->hasChildren(); } + const DWARFAbbreviationDeclaration *getAbbreviationDeclarationPtr() const { return AbbrevDecl; } }; -} +} // end namespace llvm -#endif +#endif // LLVM_DEBUGINFO_DWARFDEBUGINFOENTRY_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h index 878f1c76ebf67..e5bb24707b638 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h @@ -1,4 +1,4 @@ -//===-- DWARFDebugLine.h ----------------------------------------*- C++ -*-===// +//===- DWARFDebugLine.h -----------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,12 +7,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGLINE_H -#define LLVM_LIB_DEBUGINFO_DWARFDEBUGLINE_H +#ifndef LLVM_DEBUGINFO_DWARFDEBUGLINE_H +#define LLVM_DEBUGINFO_DWARFDEBUGLINE_H #include "llvm/DebugInfo/DIContext.h" #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" #include "llvm/Support/DataExtractor.h" +#include <cstdint> #include <map> #include <string> #include <vector> @@ -24,13 +25,14 @@ class raw_ostream; class DWARFDebugLine { public: DWARFDebugLine(const RelocAddrMap* LineInfoRelocMap) : RelocMap(LineInfoRelocMap) {} + struct FileNameEntry { - FileNameEntry() : Name(nullptr), DirIdx(0), ModTime(0), Length(0) {} + FileNameEntry() = default; - const char *Name; - uint64_t DirIdx; - uint64_t ModTime; - uint64_t Length; + const char *Name = nullptr; + uint64_t DirIdx = 0; + uint64_t ModTime = 0; + uint64_t Length = 0; }; struct Prologue { @@ -64,9 +66,11 @@ public: std::vector<FileNameEntry> FileNames; bool IsDWARF64; + uint32_t sizeofTotalLength() const { return IsDWARF64 ? 12 : 4; } + uint32_t sizeofPrologueLength() const { return IsDWARF64 ? 8 : 4; } @@ -76,10 +80,12 @@ public: return PrologueLength + sizeofTotalLength() + sizeof(Version) + sizeofPrologueLength(); } + // Length of the line table data in bytes (not including the prologue). uint32_t getStatementTableLength() const { return TotalLength + sizeofTotalLength() - getLength(); } + int32_t getMaxLineIncrementForSpecialOpcode() const { return LineBase + (int8_t)LineRange - 1; } @@ -146,6 +152,8 @@ public: // compilation unit may consist of multiple sequences, which are not // guaranteed to be in the order of ascending instruction address. struct Sequence { + Sequence(); + // Sequence describes instructions at address range [LowPC, HighPC) // and is described by line table rows [FirstRowIndex, LastRowIndex). uint64_t LowPC; @@ -154,15 +162,16 @@ public: unsigned LastRowIndex; bool Empty; - Sequence(); void reset(); static bool orderByLowPC(const Sequence& LHS, const Sequence& RHS) { return LHS.LowPC < RHS.LowPC; } + bool isValid() const { return !Empty && (LowPC < HighPC) && (FirstRowIndex < LastRowIndex); } + bool containsPC(uint64_t pc) const { return (LowPC <= pc && pc < HighPC); } @@ -177,6 +186,7 @@ public: void appendRow(const DWARFDebugLine::Row &R) { Rows.push_back(R); } + void appendSequence(const DWARFDebugLine::Sequence &S) { Sequences.push_back(S); } @@ -249,6 +259,7 @@ private: const RelocAddrMap *RelocMap; LineTableMapTy LineTableMap; }; -} -#endif +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_DWARFDEBUGLINE_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h index bd44c2e5aab9b..6d4cd8d1b5a3c 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h @@ -1,4 +1,4 @@ -//===-- DWARFDebugLoc.h -----------------------------------------*- C++ -*-===// +//===- DWARFDebugLoc.h ------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,12 +7,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGLOC_H -#define LLVM_LIB_DEBUGINFO_DWARFDEBUGLOC_H +#ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGLOC_H +#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGLOC_H #include "llvm/ADT/SmallVector.h" #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" #include "llvm/Support/DataExtractor.h" +#include <cstdint> namespace llvm { @@ -49,8 +50,10 @@ class DWARFDebugLoc { public: DWARFDebugLoc(const RelocAddrMap &LocRelocMap) : RelocMap(LocRelocMap) {} + /// Print the location lists found within the debug_loc section. void dump(raw_ostream &OS) const; + /// Parse the debug_loc section accessible via the 'data' parameter using the /// specified address size to interpret the address ranges. void parse(DataExtractor data, unsigned AddressSize); @@ -76,6 +79,7 @@ public: void parse(DataExtractor data); void dump(raw_ostream &OS) const; }; -} -#endif +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGLOC_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h b/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h index 5a0352dacdb9e..85d98b45afcd5 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h @@ -1,4 +1,4 @@ -//===-- DWARFDebugMacro.h ---------------------------------------*- C++ -*-===// +//===- DWARFDebugMacro.h ----------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -50,6 +50,7 @@ public: /// Print the macro list found within the debug_macinfo section. void dump(raw_ostream &OS) const; + /// Parse the debug_macinfo section accessible via the 'data' parameter. void parse(DataExtractor data); }; diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h b/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h index 2b23837e32d69..9d36bb7ad211c 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h @@ -1,4 +1,4 @@ -//===-- DWARFDebugPubTable.h ------------------------------------*- C++ -*-===// +//===- DWARFDebugPubTable.h -------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,13 +7,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGPUBTABLE_H -#define LLVM_LIB_DEBUGINFO_DWARFDEBUGPUBTABLE_H +#ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGPUBTABLE_H +#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGPUBTABLE_H -#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/Support/DataExtractor.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/Dwarf.h" +#include <cstdint> #include <vector> namespace llvm { @@ -28,7 +28,7 @@ public: uint32_t SecOffset; /// An entry of the various gnu_pub* debug sections. - llvm::dwarf::PubIndexEntryDescriptor Descriptor; + dwarf::PubIndexEntryDescriptor Descriptor; /// The name of the object as given by the DW_AT_name attribute of the /// referenced DIE. @@ -68,10 +68,12 @@ private: public: DWARFDebugPubTable(StringRef Data, bool LittleEndian, bool GnuStyle); + void dump(StringRef Name, raw_ostream &OS) const; ArrayRef<Set> getData() { return Sets; } }; -} -#endif +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGPUBTABLE_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h b/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h index c930bd603d4d5..018a049a3ed81 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h @@ -1,4 +1,4 @@ -//===-- DWARFDebugRangeList.h -----------------------------------*- C++ -*-===// +//===- DWARFDebugRangeList.h ------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,10 +7,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFDEBUGRANGELIST_H -#define LLVM_LIB_DEBUGINFO_DWARFDEBUGRANGELIST_H +#ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGRANGELIST_H +#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGRANGELIST_H #include "llvm/Support/DataExtractor.h" +#include <cassert> +#include <cstdint> +#include <utility> #include <vector> namespace llvm { @@ -34,12 +37,14 @@ public: // address past the end of the address range. The ending address must // be greater than or equal to the beginning address. uint64_t EndAddress; + // The end of any given range list is marked by an end of list entry, // which consists of a 0 for the beginning address offset // and a 0 for the ending address offset. bool isEndOfListEntry() const { return (StartAddress == 0) && (EndAddress == 0); } + // A base address selection entry consists of: // 1. The value of the largest representable address offset // (for example, 0xffffffff when the size of an address is 32 bits). @@ -63,6 +68,7 @@ private: public: DWARFDebugRangeList() { clear(); } + void clear(); void dump(raw_ostream &OS) const; bool extract(DataExtractor data, uint32_t *offset_ptr); @@ -74,6 +80,6 @@ public: DWARFAddressRangesVector getAbsoluteRanges(uint64_t BaseAddress) const; }; -} // namespace llvm +} // end namespace llvm -#endif // LLVM_DEBUGINFO_DWARFDEBUGRANGELIST_H +#endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGRANGELIST_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFDie.h b/include/llvm/DebugInfo/DWARF/DWARFDie.h index e335e28b39d73..33e24fe3adc90 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDie.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDie.h @@ -1,4 +1,4 @@ -//===-- DWARFDie.h --------------------------------------------------------===// +//===- DWARFDie.h -----------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,18 +7,25 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFDIE_H -#define LLVM_LIB_DEBUGINFO_DWARFDIE_H +#ifndef LLVM_DEBUGINFO_DWARFDIE_H +#define LLVM_DEBUGINFO_DWARFDIE_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" #include "llvm/ADT/Optional.h" +#include "llvm/DebugInfo/DIContext.h" +#include "llvm/DebugInfo/DWARF/DWARFAttribute.h" #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h" +#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" +#include "llvm/Support/Dwarf.h" +#include <cassert> +#include <cstdint> +#include <iterator> namespace llvm { class DWARFUnit; -class DWARFDebugInfoEntry; class raw_ostream; //===----------------------------------------------------------------------===// @@ -34,10 +41,11 @@ class raw_ostream; /// also simplifies the attribute extraction calls by not having to specify the /// DWARFUnit for each call. class DWARFDie { - DWARFUnit *U; - const DWARFDebugInfoEntry *Die; + DWARFUnit *U = nullptr; + const DWARFDebugInfoEntry *Die = nullptr; + public: - DWARFDie() : U(nullptr), Die(nullptr) {} + DWARFDie() = default; DWARFDie(DWARFUnit *Unit, const DWARFDebugInfoEntry * D) : U(Unit), Die(D) {} bool isValid() const { return U && Die; } @@ -45,7 +53,6 @@ public: const DWARFDebugInfoEntry *getDebugInfoEntry() const { return Die; } DWARFUnit *getDwarfUnit() const { return U; } - /// Get the abbreviation declaration for this DIE. /// /// \returns the abbreviation declaration or NULL for null tags. @@ -78,6 +85,7 @@ public: bool isNULL() const { return getAbbreviationDeclarationPtr() == nullptr; } + /// Returns true if DIE represents a subprogram (not inlined). bool isSubprogramDIE() const; @@ -123,76 +131,33 @@ public: /// \param Attr the attribute to extract. /// \returns an optional DWARFFormValue that will have the form value if the /// attribute was successfully extracted. - Optional<DWARFFormValue> getAttributeValue(dwarf::Attribute Attr) const; - - /// Extract the specified attribute from this DIE as a C string. - /// - /// Extract an attribute value from this DIE only. This call doesn't look - /// for the attribute value in any DW_AT_specification or - /// DW_AT_abstract_origin referenced DIEs. - /// - /// \param Attr the attribute to extract. - /// \param FailValue the value to return if this DIE doesn't have this - /// attribute. - /// \returns the NULL terminated C string value owned by the DWARF section - /// that contains the string or FailValue if the attribute doesn't exist or - /// if the attribute's form isn't a form that describes an string. - const char *getAttributeValueAsString(dwarf::Attribute Attr, - const char *FailValue) const; + Optional<DWARFFormValue> find(dwarf::Attribute Attr) const; - /// Extract the specified attribute from this DIE as an address. - /// - /// Extract an attribute value from this DIE only. This call doesn't look - /// for the attribute value in any DW_AT_specification or - /// DW_AT_abstract_origin referenced DIEs. - /// - /// \param Attr the attribute to extract. - /// \returns an optional value for the attribute. - Optional<uint64_t> getAttributeValueAsAddress(dwarf::Attribute Attr) const; - - /// Extract the specified attribute from this DIE as a signed integer. - /// - /// Extract an attribute value from this DIE only. This call doesn't look - /// for the attribute value in any DW_AT_specification or - /// DW_AT_abstract_origin referenced DIEs. - /// - /// \param Attr the attribute to extract. - /// \returns an optional value for the attribute. - Optional<int64_t> - getAttributeValueAsSignedConstant(dwarf::Attribute Attr) const; - - /// Extract the specified attribute from this DIE as an unsigned integer. - /// - /// Extract an attribute value from this DIE only. This call doesn't look - /// for the attribute value in any DW_AT_specification or - /// DW_AT_abstract_origin referenced DIEs. - /// - /// \param Attr the attribute to extract. - /// \returns an optional value for the attribute. - Optional<uint64_t> - getAttributeValueAsUnsignedConstant(dwarf::Attribute Attr) const; + /// Extract the first value of any attribute in Attrs from this DIE. + /// + /// Extract the first attribute that matches from this DIE only. This call + /// doesn't look for the attribute value in any DW_AT_specification or + /// DW_AT_abstract_origin referenced DIEs. The attributes will be searched + /// linearly in the order they are specified within Attrs. + /// + /// \param Attrs an array of DWARF attribute to look for. + /// \returns an optional that has a valid DWARFFormValue for the first + /// matching attribute in Attrs, or None if none of the attributes in Attrs + /// exist in this DIE. + Optional<DWARFFormValue> find(ArrayRef<dwarf::Attribute> Attrs) const; + + /// Extract the first value of any attribute in Attrs from this DIE and + /// recurse into any DW_AT_specification or DW_AT_abstract_origin referenced + /// DIEs. + /// + /// \param Attrs an array of DWARF attribute to look for. + /// \returns an optional that has a valid DWARFFormValue for the first + /// matching attribute in Attrs, or None if none of the attributes in Attrs + /// exist in this DIE or in any DW_AT_specification or DW_AT_abstract_origin + /// DIEs. + Optional<DWARFFormValue> + findRecursively(ArrayRef<dwarf::Attribute> Attrs) const; - /// Extract the specified attribute from this DIE as absolute DIE Offset. - /// - /// Extract an attribute value from this DIE only. This call doesn't look - /// for the attribute value in any DW_AT_specification or - /// DW_AT_abstract_origin referenced DIEs. - /// - /// \param Attr the attribute to extract. - /// \returns an optional value for the attribute. - Optional<uint64_t> getAttributeValueAsReference(dwarf::Attribute Attr) const; - - /// Extract the specified attribute from this DIE as absolute section offset. - /// - /// Extract an attribute value from this DIE only. This call doesn't look - /// for the attribute value in any DW_AT_specification or - /// DW_AT_abstract_origin referenced DIEs. - /// - /// \param Attr the attribute to extract. - /// \returns an optional value for the attribute. - Optional<uint64_t> - getAttributeValueAsSectionOffset(dwarf::Attribute Attr) const; - /// Extract the specified attribute from this DIE as the referenced DIE. /// /// Regardless of the reference type, return the correct DWARFDie instance if @@ -266,6 +231,12 @@ public: /// references if necessary. Returns null if no name is found. const char *getName(DINameKind Kind) const; + /// Returns the declaration line (start line) for a DIE, assuming it specifies + /// a subprogram. This may be fetched from specification or abstract origin + /// for this subprogram by resolving DW_AT_sepcification or + /// DW_AT_abstract_origin references if necessary. + uint64_t getDeclLine() const; + /// Retrieves values of DW_AT_call_file, DW_AT_call_line and DW_AT_call_column /// from DIE (or zeroes if they are missing). This function looks for /// DW_AT_call attributes in this DIE only, it will not resolve the attribute @@ -286,14 +257,47 @@ public: getInlinedChainForAddress(const uint64_t Address, SmallVectorImpl<DWARFDie> &InlinedChain) const; + class attribute_iterator; + + /// Get an iterator range to all attributes in the current DIE only. + /// + /// \returns an iterator range for the attributes of the current DIE. + iterator_range<attribute_iterator> attributes() const; + class iterator; iterator begin() const; iterator end() const; iterator_range<iterator> children() const; }; - +class DWARFDie::attribute_iterator : + public iterator_facade_base<attribute_iterator, std::forward_iterator_tag, + const DWARFAttribute> { + /// The DWARF DIE we are extracting attributes from. + DWARFDie Die; + /// The value vended to clients via the operator*() or operator->(). + DWARFAttribute AttrValue; + /// The attribute index within the abbreviation declaration in Die. + uint32_t Index; + + /// Update the attribute index and attempt to read the attribute value. If the + /// attribute is able to be read, update AttrValue and the Index member + /// variable. If the attribute value is not able to be read, an appropriate + /// error will be set if the Err member variable is non-NULL and the iterator + /// will be set to the end value so iteration stops. + void updateForIndex(const DWARFAbbreviationDeclaration &AbbrDecl, uint32_t I); + +public: + attribute_iterator() = delete; + explicit attribute_iterator(DWARFDie D, bool End); + + attribute_iterator &operator++(); + explicit operator bool() const { return AttrValue.isValid(); } + const DWARFAttribute &operator*() const { return AttrValue; } + bool operator==(const attribute_iterator &X) const { return Index == X.Index; } +}; + inline bool operator==(const DWARFDie &LHS, const DWARFDie &RHS) { return LHS.getDebugInfoEntry() == RHS.getDebugInfoEntry() && LHS.getDwarfUnit() == RHS.getDwarfUnit(); @@ -313,16 +317,19 @@ class DWARFDie::iterator : public iterator_facade_base<iterator, } public: iterator() = default; + explicit iterator(DWARFDie D) : Die(D) { // If we start out with only a Null DIE then invalidate. skipNull(); } + iterator &operator++() { Die = Die.getSibling(); // Don't include the NULL die when iterating. skipNull(); return *this; } + explicit operator bool() const { return Die.isValid(); } const DWARFDie &operator*() const { return Die; } bool operator==(const iterator &X) const { return Die == X.Die; } @@ -344,4 +351,4 @@ inline iterator_range<DWARFDie::iterator> DWARFDie::children() const { } // end namespace llvm -#endif // LLVM_LIB_DEBUGINFO_DWARFDIE_H +#endif // LLVM_DEBUGINFO_DWARFDIE_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h index 1b7659dfb04ac..c8d7a0c1ac7a3 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h +++ b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h @@ -1,4 +1,4 @@ -//===-- DWARFFormValue.h ----------------------------------------*- C++ -*-===// +//===- DWARFFormValue.h -----------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -10,13 +10,15 @@ #ifndef LLVM_DEBUGINFO_DWARFFORMVALUE_H #define LLVM_DEBUGINFO_DWARFFORMVALUE_H +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/DataExtractor.h" #include "llvm/Support/Dwarf.h" +#include <cstdint> namespace llvm { -template <typename T> class ArrayRef; class DWARFUnit; class raw_ostream; @@ -37,7 +39,7 @@ public: private: struct ValueType { - ValueType() : data(nullptr) { + ValueType() { uval = 0; } @@ -46,20 +48,27 @@ private: int64_t sval; const char* cstr; }; - const uint8_t* data; + const uint8_t* data = nullptr; }; dwarf::Form Form; // Form for this value. ValueType Value; // Contains all data for the form. - const DWARFUnit *U; // Remember the DWARFUnit at extract time. + const DWARFUnit *U = nullptr; // Remember the DWARFUnit at extract time. public: - DWARFFormValue(dwarf::Form F = dwarf::Form(0)) : Form(F), U(nullptr) {} + DWARFFormValue(dwarf::Form F = dwarf::Form(0)) : Form(F) {} + dwarf::Form getForm() const { return Form; } void setForm(dwarf::Form F) { Form = F; } void setUValue(uint64_t V) { Value.uval = V; } void setSValue(int64_t V) { Value.sval = V; } void setPValue(const char *V) { Value.cstr = V; } + + void setBlockValue(const ArrayRef<uint8_t> &Data) { + Value.data = Data.data(); + setUValue(Data.size()); + } + bool isFormClass(FormClass FC) const; const DWARFUnit *getUnit() const { return U; } void dump(raw_ostream &OS) const; @@ -72,6 +81,7 @@ public: /// \returns whether the extraction succeeded. bool extractValue(const DataExtractor &Data, uint32_t *OffsetPtr, const DWARFUnit *U); + bool isInlinedCStr() const { return Value.data != nullptr && Value.data == (const uint8_t*)Value.cstr; } @@ -87,6 +97,7 @@ public: Optional<ArrayRef<uint8_t>> getAsBlock() const; Optional<uint64_t> getAsCStringOffset() const; Optional<uint64_t> getAsReferenceUVal() const; + /// Get the fixed byte size for a given form. /// /// If the form always has a fixed valid byte size that doesn't depend on a @@ -105,6 +116,7 @@ public: /// and was needed to calculate the byte size. static Optional<uint8_t> getFixedByteSize(dwarf::Form Form, const DWARFUnit *U = nullptr); + /// Get the fixed byte size for a given form. /// /// If the form has a fixed byte size given a valid DWARF version and address @@ -133,6 +145,7 @@ public: /// \returns true on success, false if the form was not skipped. bool skipValue(DataExtractor debug_info_data, uint32_t *offset_ptr, const DWARFUnit *U) const; + /// Skip a form in \p debug_info_data at offset specified by \p offset_ptr. /// /// Skips the bytes for this form in the debug info and updates the offset. @@ -145,6 +158,7 @@ public: /// \returns true on success, false if the form was not skipped. static bool skipValue(dwarf::Form form, DataExtractor debug_info_data, uint32_t *offset_ptr, const DWARFUnit *U); + /// Skip a form in \p debug_info_data at offset specified by \p offset_ptr. /// /// Skips the bytes for this form in the debug info and updates the offset. @@ -164,6 +178,154 @@ private: void dumpString(raw_ostream &OS) const; }; -} +namespace dwarf { + + /// Take an optional DWARFFormValue and try to extract a string value from it. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \returns an optional value that contains a value if the form value + /// was valid and was a string. + inline Optional<const char*> toString(const Optional<DWARFFormValue>& V) { + if (V) + return V->getAsCString(); + return None; + } + + /// Take an optional DWARFFormValue and extract a string value from it. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \param Default the default value to return in case of failure. + /// \returns the string value or Default if the V doesn't have a value or the + /// form value's encoding wasn't a string. + inline const char* + toString(const Optional<DWARFFormValue>& V, const char *Default) { + return toString(V).getValueOr(Default); + } + + /// Take an optional DWARFFormValue and try to extract an unsigned constant. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \returns an optional value that contains a value if the form value + /// was valid and has a unsigned constant form. + inline Optional<uint64_t> toUnsigned(const Optional<DWARFFormValue>& V) { + if (V) + return V->getAsUnsignedConstant(); + return None; + } + + /// Take an optional DWARFFormValue and extract a unsigned constant. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \param Default the default value to return in case of failure. + /// \returns the extracted unsigned value or Default if the V doesn't have a + /// value or the form value's encoding wasn't an unsigned constant form. + inline uint64_t + toUnsigned(const Optional<DWARFFormValue>& V, uint64_t Default) { + return toUnsigned(V).getValueOr(Default); + } + + /// Take an optional DWARFFormValue and try to extract an reference. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \returns an optional value that contains a value if the form value + /// was valid and has a reference form. + inline Optional<uint64_t> toReference(const Optional<DWARFFormValue>& V) { + if (V) + return V->getAsReference(); + return None; + } + + /// Take an optional DWARFFormValue and extract a reference. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \param Default the default value to return in case of failure. + /// \returns the extracted reference value or Default if the V doesn't have a + /// value or the form value's encoding wasn't a reference form. + inline uint64_t + toReference(const Optional<DWARFFormValue>& V, uint64_t Default) { + return toReference(V).getValueOr(Default); + } + + /// Take an optional DWARFFormValue and try to extract an signed constant. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \returns an optional value that contains a value if the form value + /// was valid and has a signed constant form. + inline Optional<int64_t> toSigned(const Optional<DWARFFormValue>& V) { + if (V) + return V->getAsSignedConstant(); + return None; + } + + /// Take an optional DWARFFormValue and extract a signed integer. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \param Default the default value to return in case of failure. + /// \returns the extracted signed integer value or Default if the V doesn't + /// have a value or the form value's encoding wasn't a signed integer form. + inline int64_t + toSigned(const Optional<DWARFFormValue>& V, int64_t Default) { + return toSigned(V).getValueOr(Default); + } + + /// Take an optional DWARFFormValue and try to extract an address. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \returns an optional value that contains a value if the form value + /// was valid and has a address form. + inline Optional<uint64_t> toAddress(const Optional<DWARFFormValue>& V) { + if (V) + return V->getAsAddress(); + return None; + } + + /// Take an optional DWARFFormValue and extract a address. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \param Default the default value to return in case of failure. + /// \returns the extracted address value or Default if the V doesn't have a + /// value or the form value's encoding wasn't an address form. + inline uint64_t + toAddress(const Optional<DWARFFormValue>& V, uint64_t Default) { + return toAddress(V).getValueOr(Default); + } + + /// Take an optional DWARFFormValue and try to extract an section offset. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \returns an optional value that contains a value if the form value + /// was valid and has a section offset form. + inline Optional<uint64_t> toSectionOffset(const Optional<DWARFFormValue>& V) { + if (V) + return V->getAsSectionOffset(); + return None; + } + + /// Take an optional DWARFFormValue and extract a section offset. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \param Default the default value to return in case of failure. + /// \returns the extracted section offset value or Default if the V doesn't + /// have a value or the form value's encoding wasn't a section offset form. + inline uint64_t + toSectionOffset(const Optional<DWARFFormValue>& V, uint64_t Default) { + return toSectionOffset(V).getValueOr(Default); + } + + /// Take an optional DWARFFormValue and try to extract block data. + /// + /// \param V and optional DWARFFormValue to attempt to extract the value from. + /// \returns an optional value that contains a value if the form value + /// was valid and has a block form. + inline Optional<ArrayRef<uint8_t>> + toBlock(const Optional<DWARFFormValue>& V) { + if (V) + return V->getAsBlock(); + return None; + } + +} // end namespace dwarf + +} // end namespace llvm -#endif +#endif // LLVM_DEBUGINFO_DWARFFORMVALUE_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFGdbIndex.h b/include/llvm/DebugInfo/DWARF/DWARFGdbIndex.h index 66041be965661..7a52218663b9d 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFGdbIndex.h +++ b/include/llvm/DebugInfo/DWARF/DWARFGdbIndex.h @@ -1,4 +1,4 @@ -//===-- DWARFGdbIndex.h -----------------------------------------*- C++ -*-===// +//===- DWARFGdbIndex.h ------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,14 +7,19 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFGDBINDEX_H -#define LLVM_LIB_DEBUGINFO_DWARFGDBINDEX_H +#ifndef LLVM_DEBUGINFO_DWARF_DWARFGDBINDEX_H +#define LLVM_DEBUGINFO_DWARF_DWARFGDBINDEX_H +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/DataExtractor.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/raw_ostream.h" +#include <cstdint> +#include <utility> namespace llvm { + +class raw_ostream; + class DWARFGdbIndex { uint32_t Version; @@ -63,6 +68,7 @@ public: bool HasContent = false; bool HasError = false; }; -} -#endif // LLVM_LIB_DEBUGINFO_DWARFGDBINDEX_H +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_DWARF_DWARFGDBINDEX_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h b/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h index d7fe3032e5054..af01bddeed153 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h +++ b/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h @@ -1,4 +1,4 @@ -//===-- DWARFRelocMap.h -----------------------------------------*- C++ -*-===// +//===- DWARFRelocMap.h ------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,16 +7,17 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFRELOCMAP_H -#define LLVM_LIB_DEBUGINFO_DWARFRELOCMAP_H +#ifndef LLVM_DEBUGINFO_DWARF_DWARFRELOCMAP_H +#define LLVM_DEBUGINFO_DWARF_DWARFRELOCMAP_H #include "llvm/ADT/DenseMap.h" +#include <cstdint> +#include <utility> namespace llvm { -typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t> > RelocAddrMap; +typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t>> RelocAddrMap; -} // namespace llvm - -#endif +} // end namespace llvm +#endif // LLVM_DEBUGINFO_DWARF_DWARFRELOCMAP_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFSection.h b/include/llvm/DebugInfo/DWARF/DWARFSection.h index 3e27b529e97bf..2b8a53a4c93ea 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFSection.h +++ b/include/llvm/DebugInfo/DWARF/DWARFSection.h @@ -1,4 +1,4 @@ -//===-- DWARFSection.h ------------------------------------------*- C++ -*-===// +//===- DWARFSection.h -------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,11 +7,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFSECTION_H -#define LLVM_LIB_DEBUGINFO_DWARFSECTION_H +#ifndef LLVM_DEBUGINFO_DWARF_DWARFSECTION_H +#define LLVM_DEBUGINFO_DWARF_DWARFSECTION_H -#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" namespace llvm { @@ -20,6 +20,6 @@ struct DWARFSection { RelocAddrMap Relocs; }; -} +} // end namespace llvm -#endif +#endif // LLVM_DEBUGINFO_DWARF_DWARFSECTION_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h b/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h index 4f1e1292a1f1b..703316005887c 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h @@ -1,4 +1,4 @@ -//===-- DWARFTypeUnit.h -----------------------------------------*- C++ -*-===// +//===- DWARFTypeUnit.h ------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,17 +7,27 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFTYPEUNIT_H -#define LLVM_LIB_DEBUGINFO_DWARFTYPEUNIT_H +#ifndef LLVM_DEBUGINFO_DWARF_DWARFTYPEUNIT_H +#define LLVM_DEBUGINFO_DWARF_DWARFTYPEUNIT_H +#include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/DWARF/DWARFUnit.h" +#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" +#include "llvm/Support/DataExtractor.h" +#include <cstdint> namespace llvm { +class DWARFContext; +class DWARFDebugAbbrev; +struct DWARFSection; +class raw_ostream; + class DWARFTypeUnit : public DWARFUnit { private: uint64_t TypeHash; uint32_t TypeOffset; + public: DWARFTypeUnit(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, @@ -26,9 +36,11 @@ public: const DWARFUnitIndex::Entry *Entry) : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, UnitSection, Entry) {} + uint32_t getHeaderSize() const override { return DWARFUnit::getHeaderSize() + 12; } + void dump(raw_ostream &OS, bool Brief = false); static const DWARFSectionKind Section = DW_SECT_TYPES; @@ -36,7 +48,6 @@ protected: bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) override; }; -} - -#endif +} // end namespace llvm +#endif // LLVM_DEBUGINFO_DWARF_DWARFTYPEUNIT_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h index db7b59be90c2a..40eb4434bd61e 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -1,4 +1,4 @@ -//===-- DWARFUnit.h ---------------------------------------------*- C++ -*-===// +//===- DWARFUnit.h ----------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,32 +7,37 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFUNIT_H -#define LLVM_LIB_DEBUGINFO_DWARFUNIT_H +#ifndef LLVM_DEBUGINFO_DWARF_DWARFUNIT_H +#define LLVM_DEBUGINFO_DWARF_DWARFUNIT_H -#include "llvm/ADT/Optional.h" #include "llvm/ADT/iterator_range.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h" +#include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h" #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" #include "llvm/DebugInfo/DWARF/DWARFDie.h" #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" #include "llvm/DebugInfo/DWARF/DWARFSection.h" #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" +#include "llvm/Object/Binary.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Support/DataExtractor.h" +#include "llvm/Support/Dwarf.h" +#include <algorithm> +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <memory> #include <vector> namespace llvm { -namespace object { -class ObjectFile; -} - +class DWARFAbbreviationDeclarationSet; class DWARFContext; class DWARFDebugAbbrev; class DWARFUnit; -class StringRef; -class raw_ostream; /// Base class for all DWARFUnitSection classes. This provides the /// functionality common to all unit types. @@ -47,12 +52,12 @@ public: DWARFUnitIndex *Index = nullptr); protected: + ~DWARFUnitSectionBase() = default; + virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, StringRef SOS, StringRef AOS, StringRef LS, bool isLittleEndian, bool isDWO) = 0; - - ~DWARFUnitSectionBase() = default; }; const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context, @@ -65,7 +70,7 @@ class DWARFUnitSection final : public SmallVector<std::unique_ptr<UnitType>, 1>, bool Parsed = false; public: - typedef llvm::SmallVectorImpl<std::unique_ptr<UnitType>> UnitVector; + typedef SmallVectorImpl<std::unique_ptr<UnitType>> UnitVector; typedef typename UnitVector::iterator iterator; typedef llvm::iterator_range<typename UnitVector::iterator> iterator_range; @@ -122,8 +127,9 @@ class DWARFUnit { uint32_t Offset; uint32_t Length; - uint16_t Version; const DWARFAbbreviationDeclarationSet *Abbrevs; + uint16_t Version; + uint8_t UnitType; uint8_t AddrSize; uint64_t BaseAddr; // The compile unit debug information entry items. @@ -134,9 +140,11 @@ class DWARFUnit { class DWOHolder { object::OwningBinary<object::ObjectFile> DWOFile; std::unique_ptr<DWARFContext> DWOContext; - DWARFUnit *DWOU; + DWARFUnit *DWOU = nullptr; + public: DWOHolder(StringRef DWOPath); + DWARFUnit *getUnit() const { return DWOU; } }; std::unique_ptr<DWOHolder> DWO; @@ -151,8 +159,9 @@ class DWARFUnit { protected: virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr); + /// Size in bytes of the unit header. - virtual uint32_t getHeaderSize() const { return 11; } + virtual uint32_t getHeaderSize() const { return Version <= 4 ? 11 : 12; } public: DWARFUnit(DWARFContext &Context, const DWARFSection &Section, @@ -168,10 +177,12 @@ public: StringRef getLineSection() const { return LineSection; } StringRef getStringSection() const { return StringSection; } StringRef getStringOffsetSection() const { return StringOffsetSection; } + void setAddrOffsetSection(StringRef AOS, uint32_t Base) { AddrOffsetSection = AOS; AddrOffsetSectionBase = Base; } + void setRangesSection(StringRef RS, uint32_t Base) { RangeSection = RS; RangeSectionBase = Base; @@ -184,6 +195,7 @@ public: DataExtractor getDebugInfoExtractor() const { return DataExtractor(InfoSection.Data, isLittleEndian, AddrSize); } + DataExtractor getStringExtractor() const { return DataExtractor(StringSection, false, 0); } @@ -202,23 +214,30 @@ public: uint32_t getNextUnitOffset() const { return Offset + Length + 4; } uint32_t getLength() const { return Length; } uint16_t getVersion() const { return Version; } + dwarf::DwarfFormat getFormat() const { return dwarf::DwarfFormat::DWARF32; // FIXME: Support DWARF64. } + const DWARFAbbreviationDeclarationSet *getAbbreviations() const { return Abbrevs; } + + uint8_t getUnitType() const { return UnitType; } uint8_t getAddressByteSize() const { return AddrSize; } + uint8_t getRefAddrByteSize() const { if (Version == 2) return AddrSize; return getDwarfOffsetByteSize(); } + uint8_t getDwarfOffsetByteSize() const { if (getFormat() == dwarf::DwarfFormat::DWARF64) return 8; return 4; } + uint64_t getBaseAddress() const { return BaseAddr; } void setBaseAddress(uint64_t base_addr) { @@ -308,9 +327,11 @@ private: /// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it /// hasn't already been done. Returns the number of DIEs parsed at this call. size_t extractDIEsIfNeeded(bool CUDieOnly); + /// extractDIEsToVector - Appends all parsed DIEs to a vector. void extractDIEsToVector(bool AppendCUDie, bool AppendNonCUDIEs, std::vector<DWARFDebugInfoEntry> &DIEs) const; + /// clearDIEs - Clear parsed DIEs to keep memory usage low. void clearDIEs(bool KeepCUDie); @@ -324,6 +345,6 @@ private: DWARFDie getSubprogramForAddress(uint64_t Address); }; -} +} // end namespace llvm -#endif +#endif // LLVM_DEBUGINFO_DWARF_DWARFUNIT_H diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h b/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h index 9f051cd7081c6..8e2ce023695bf 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h +++ b/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h @@ -1,4 +1,4 @@ -//===-- DWARFUnitIndex.h --------------------------------------------------===// +//===- DWARFUnitIndex.h -----------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,17 +7,19 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFUNITINDEX_H -#define LLVM_LIB_DEBUGINFO_DWARFUNITINDEX_H +#ifndef LLVM_DEBUGINFO_DWARF_DWARFUNITINDEX_H +#define LLVM_DEBUGINFO_DWARF_DWARFUNITINDEX_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/DataExtractor.h" -#include "llvm/Support/Format.h" -#include "llvm/Support/raw_ostream.h" #include <cstdint> +#include <memory> namespace llvm { +class raw_ostream; + enum DWARFSectionKind { DW_SECT_INFO = 1, DW_SECT_TYPES, @@ -57,9 +59,11 @@ public: public: const SectionContribution *getOffset(DWARFSectionKind Sec) const; const SectionContribution *getOffset() const; + const SectionContribution *getOffsets() const { return Contributions.get(); } + uint64_t getSignature() const { return Signature; } }; @@ -72,21 +76,26 @@ private: std::unique_ptr<Entry[]> Rows; static StringRef getColumnHeader(DWARFSectionKind DS); + bool parseImpl(DataExtractor IndexData); public: - bool parse(DataExtractor IndexData); DWARFUnitIndex(DWARFSectionKind InfoColumnKind) : InfoColumnKind(InfoColumnKind) {} + + bool parse(DataExtractor IndexData); void dump(raw_ostream &OS) const; const Entry *getFromOffset(uint32_t Offset) const; + ArrayRef<DWARFSectionKind> getColumnKinds() const { return makeArrayRef(ColumnKinds.get(), Header.NumColumns); } + ArrayRef<Entry> getRows() const { return makeArrayRef(Rows.get(), Header.NumBuckets); } }; -} -#endif +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_DWARF_DWARFUNITINDEX_H diff --git a/include/llvm/DebugInfo/MSF/ByteStream.h b/include/llvm/DebugInfo/MSF/ByteStream.h deleted file mode 100644 index 547844be5e5d4..0000000000000 --- a/include/llvm/DebugInfo/MSF/ByteStream.h +++ /dev/null @@ -1,169 +0,0 @@ -//===- ByteStream.h - Reads stream data from a byte sequence ----*- 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_MSF_BYTESTREAM_H -#define LLVM_DEBUGINFO_MSF_BYTESTREAM_H - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/DebugInfo/MSF/MSFError.h" -#include "llvm/DebugInfo/MSF/StreamInterface.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/FileOutputBuffer.h" -#include "llvm/Support/MemoryBuffer.h" -#include <algorithm> -#include <cstdint> -#include <cstring> -#include <memory> - -namespace llvm { -namespace msf { - -class ByteStream : public ReadableStream { -public: - ByteStream() = default; - explicit ByteStream(ArrayRef<uint8_t> Data) : Data(Data) {} - explicit ByteStream(StringRef Data) - : Data(Data.bytes_begin(), Data.bytes_end()) {} - - Error readBytes(uint32_t Offset, uint32_t Size, - ArrayRef<uint8_t> &Buffer) const override { - if (Offset > Data.size()) - return make_error<MSFError>(msf_error_code::insufficient_buffer); - if (Data.size() < Size + Offset) - return make_error<MSFError>(msf_error_code::insufficient_buffer); - Buffer = Data.slice(Offset, Size); - return Error::success(); - } - - Error readLongestContiguousChunk(uint32_t Offset, - ArrayRef<uint8_t> &Buffer) const override { - if (Offset >= Data.size()) - return make_error<MSFError>(msf_error_code::insufficient_buffer); - Buffer = Data.slice(Offset); - return Error::success(); - } - - uint32_t getLength() const override { return Data.size(); } - - ArrayRef<uint8_t> data() const { return Data; } - - StringRef str() const { - const char *CharData = reinterpret_cast<const char *>(Data.data()); - return StringRef(CharData, Data.size()); - } - -protected: - ArrayRef<uint8_t> Data; -}; - -// MemoryBufferByteStream behaves like a read-only ByteStream, but has its data -// backed by an llvm::MemoryBuffer. It also owns the underlying MemoryBuffer. -class MemoryBufferByteStream : public ByteStream { -public: - explicit MemoryBufferByteStream(std::unique_ptr<MemoryBuffer> Buffer) - : ByteStream(ArrayRef<uint8_t>(Buffer->getBuffer().bytes_begin(), - Buffer->getBuffer().bytes_end())), - MemBuffer(std::move(Buffer)) {} - - std::unique_ptr<MemoryBuffer> MemBuffer; -}; - -class MutableByteStream : public WritableStream { -public: - MutableByteStream() = default; - explicit MutableByteStream(MutableArrayRef<uint8_t> Data) - : Data(Data), ImmutableStream(Data) {} - - Error readBytes(uint32_t Offset, uint32_t Size, - ArrayRef<uint8_t> &Buffer) const override { - return ImmutableStream.readBytes(Offset, Size, Buffer); - } - - Error readLongestContiguousChunk(uint32_t Offset, - ArrayRef<uint8_t> &Buffer) const override { - return ImmutableStream.readLongestContiguousChunk(Offset, Buffer); - } - - uint32_t getLength() const override { return ImmutableStream.getLength(); } - - Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) const override { - if (Buffer.empty()) - return Error::success(); - - if (Data.size() < Buffer.size()) - return make_error<MSFError>(msf_error_code::insufficient_buffer); - if (Offset > Buffer.size() - Data.size()) - return make_error<MSFError>(msf_error_code::insufficient_buffer); - - uint8_t *DataPtr = const_cast<uint8_t *>(Data.data()); - ::memcpy(DataPtr + Offset, Buffer.data(), Buffer.size()); - return Error::success(); - } - - Error commit() const override { return Error::success(); } - - MutableArrayRef<uint8_t> data() const { return Data; } - -private: - MutableArrayRef<uint8_t> Data; - ByteStream ImmutableStream; -}; - -// A simple adapter that acts like a ByteStream but holds ownership over -// and underlying FileOutputBuffer. -class FileBufferByteStream : public WritableStream { -private: - class StreamImpl : public MutableByteStream { - public: - StreamImpl(std::unique_ptr<FileOutputBuffer> Buffer) - : MutableByteStream(MutableArrayRef<uint8_t>(Buffer->getBufferStart(), - Buffer->getBufferEnd())), - FileBuffer(std::move(Buffer)) {} - - Error commit() const override { - if (FileBuffer->commit()) - return llvm::make_error<MSFError>(msf_error_code::not_writable); - return Error::success(); - } - - private: - std::unique_ptr<FileOutputBuffer> FileBuffer; - }; - -public: - explicit FileBufferByteStream(std::unique_ptr<FileOutputBuffer> Buffer) - : Impl(std::move(Buffer)) {} - - Error readBytes(uint32_t Offset, uint32_t Size, - ArrayRef<uint8_t> &Buffer) const override { - return Impl.readBytes(Offset, Size, Buffer); - } - - Error readLongestContiguousChunk(uint32_t Offset, - ArrayRef<uint8_t> &Buffer) const override { - return Impl.readLongestContiguousChunk(Offset, Buffer); - } - - uint32_t getLength() const override { return Impl.getLength(); } - - Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const override { - return Impl.writeBytes(Offset, Data); - } - - Error commit() const override { return Impl.commit(); } - -private: - StreamImpl Impl; -}; - -} // end namespace msf -} // end namespace llvm - -#endif // LLVM_DEBUGINFO_MSF_BYTESTREAM_H diff --git a/include/llvm/DebugInfo/MSF/MappedBlockStream.h b/include/llvm/DebugInfo/MSF/MappedBlockStream.h index fff4e9cecef5e..c91f6f725c806 100644 --- a/include/llvm/DebugInfo/MSF/MappedBlockStream.h +++ b/include/llvm/DebugInfo/MSF/MappedBlockStream.h @@ -15,8 +15,10 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" #include "llvm/DebugInfo/MSF/MSFStreamLayout.h" -#include "llvm/DebugInfo/MSF/StreamInterface.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/BinaryStream.h" +#include "llvm/Support/BinaryStream.h" +#include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include <cstdint> @@ -37,29 +39,33 @@ struct MSFLayout; /// the MSF. MappedBlockStream provides methods for reading from and writing /// to one of these streams transparently, as if it were a contiguous sequence /// of bytes. -class MappedBlockStream : public ReadableStream { +class MappedBlockStream : public BinaryStream { friend class WritableMappedBlockStream; public: static std::unique_ptr<MappedBlockStream> createStream(uint32_t BlockSize, uint32_t NumBlocks, - const MSFStreamLayout &Layout, const ReadableStream &MsfData); + const MSFStreamLayout &Layout, BinaryStreamRef MsfData); static std::unique_ptr<MappedBlockStream> - createIndexedStream(const MSFLayout &Layout, const ReadableStream &MsfData, + createIndexedStream(const MSFLayout &Layout, BinaryStreamRef MsfData, uint32_t StreamIndex); static std::unique_ptr<MappedBlockStream> - createFpmStream(const MSFLayout &Layout, const ReadableStream &MsfData); + createFpmStream(const MSFLayout &Layout, BinaryStreamRef MsfData); static std::unique_ptr<MappedBlockStream> - createDirectoryStream(const MSFLayout &Layout, const ReadableStream &MsfData); + createDirectoryStream(const MSFLayout &Layout, BinaryStreamRef MsfData); + + llvm::support::endianness getEndian() const override { + return llvm::support::little; + } Error readBytes(uint32_t Offset, uint32_t Size, - ArrayRef<uint8_t> &Buffer) const override; + ArrayRef<uint8_t> &Buffer) override; Error readLongestContiguousChunk(uint32_t Offset, - ArrayRef<uint8_t> &Buffer) const override; + ArrayRef<uint8_t> &Buffer) override; - uint32_t getLength() const override; + uint32_t getLength() override; uint32_t getNumBytesCopied() const; @@ -74,51 +80,56 @@ public: protected: MappedBlockStream(uint32_t BlockSize, uint32_t NumBlocks, const MSFStreamLayout &StreamLayout, - const ReadableStream &MsfData); + BinaryStreamRef MsfData); private: const MSFStreamLayout &getStreamLayout() const { return StreamLayout; } void fixCacheAfterWrite(uint32_t Offset, ArrayRef<uint8_t> Data) const; - Error readBytes(uint32_t Offset, MutableArrayRef<uint8_t> Buffer) const; + Error readBytes(uint32_t Offset, MutableArrayRef<uint8_t> Buffer); bool tryReadContiguously(uint32_t Offset, uint32_t Size, - ArrayRef<uint8_t> &Buffer) const; + ArrayRef<uint8_t> &Buffer); const uint32_t BlockSize; const uint32_t NumBlocks; const MSFStreamLayout StreamLayout; - const ReadableStream &MsfData; + BinaryStreamRef MsfData; typedef MutableArrayRef<uint8_t> CacheEntry; - mutable llvm::BumpPtrAllocator Pool; - mutable DenseMap<uint32_t, std::vector<CacheEntry>> CacheMap; + llvm::BumpPtrAllocator Pool; + DenseMap<uint32_t, std::vector<CacheEntry>> CacheMap; }; -class WritableMappedBlockStream : public WritableStream { +class WritableMappedBlockStream : public WritableBinaryStream { public: static std::unique_ptr<WritableMappedBlockStream> createStream(uint32_t BlockSize, uint32_t NumBlocks, - const MSFStreamLayout &Layout, const WritableStream &MsfData); + const MSFStreamLayout &Layout, WritableBinaryStreamRef MsfData); static std::unique_ptr<WritableMappedBlockStream> - createIndexedStream(const MSFLayout &Layout, const WritableStream &MsfData, + createIndexedStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData, uint32_t StreamIndex); static std::unique_ptr<WritableMappedBlockStream> - createDirectoryStream(const MSFLayout &Layout, const WritableStream &MsfData); + createDirectoryStream(const MSFLayout &Layout, + WritableBinaryStreamRef MsfData); static std::unique_ptr<WritableMappedBlockStream> - createFpmStream(const MSFLayout &Layout, const WritableStream &MsfData); + createFpmStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData); + + llvm::support::endianness getEndian() const override { + return llvm::support::little; + } Error readBytes(uint32_t Offset, uint32_t Size, - ArrayRef<uint8_t> &Buffer) const override; + ArrayRef<uint8_t> &Buffer) override; Error readLongestContiguousChunk(uint32_t Offset, - ArrayRef<uint8_t> &Buffer) const override; - uint32_t getLength() const override; + ArrayRef<uint8_t> &Buffer) override; + uint32_t getLength() override; - Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) const override; + Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) override; - Error commit() const override; + Error commit() override; const MSFStreamLayout &getStreamLayout() const { return ReadInterface.getStreamLayout(); @@ -130,12 +141,12 @@ public: protected: WritableMappedBlockStream(uint32_t BlockSize, uint32_t NumBlocks, const MSFStreamLayout &StreamLayout, - const WritableStream &MsfData); + WritableBinaryStreamRef MsfData); private: MappedBlockStream ReadInterface; - const WritableStream &WriteInterface; + WritableBinaryStreamRef WriteInterface; }; } // end namespace pdb diff --git a/include/llvm/DebugInfo/MSF/SequencedItemStream.h b/include/llvm/DebugInfo/MSF/SequencedItemStream.h deleted file mode 100644 index 1949beef9fff6..0000000000000 --- a/include/llvm/DebugInfo/MSF/SequencedItemStream.h +++ /dev/null @@ -1,93 +0,0 @@ -//===- SequencedItemStream.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_MSF_SEQUENCEDITEMSTREAM_H -#define LLVM_DEBUGINFO_MSF_SEQUENCEDITEMSTREAM_H - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/DebugInfo/MSF/MSFError.h" -#include "llvm/DebugInfo/MSF/StreamInterface.h" -#include "llvm/Support/Error.h" -#include <cstddef> -#include <cstdint> - -namespace llvm { -namespace msf { - -template <typename T> struct SequencedItemTraits { - static size_t length(const T &Item) = delete; - static ArrayRef<uint8_t> bytes(const T &Item) = delete; -}; - -/// SequencedItemStream represents a sequence of objects stored in a -/// standard container but for which it is useful to view as a stream of -/// contiguous bytes. An example of this might be if you have a std::vector -/// of TPI records, where each record contains a byte sequence that -/// represents that one record serialized, but where each consecutive item -/// might not be allocated immediately after the previous item. Using a -/// SequencedItemStream, we can adapt the VarStreamArray class to trivially -/// extract one item at a time, allowing the data to be used anywhere a -/// VarStreamArray could be used. -template <typename T, typename Traits = SequencedItemTraits<T>> -class SequencedItemStream : public ReadableStream { -public: - SequencedItemStream() = default; - - Error readBytes(uint32_t Offset, uint32_t Size, - ArrayRef<uint8_t> &Buffer) const override { - auto ExpectedIndex = translateOffsetIndex(Offset); - if (!ExpectedIndex) - return ExpectedIndex.takeError(); - const auto &Item = Items[*ExpectedIndex]; - if (Size > Traits::length(Item)) - return make_error<MSFError>(msf_error_code::insufficient_buffer); - Buffer = Traits::bytes(Item).take_front(Size); - return Error::success(); - } - - Error readLongestContiguousChunk(uint32_t Offset, - ArrayRef<uint8_t> &Buffer) const override { - auto ExpectedIndex = translateOffsetIndex(Offset); - if (!ExpectedIndex) - return ExpectedIndex.takeError(); - Buffer = Traits::bytes(Items[*ExpectedIndex]); - return Error::success(); - } - - void setItems(ArrayRef<T> ItemArray) { Items = ItemArray; } - - uint32_t getLength() const override { - uint32_t Size = 0; - for (const auto &Item : Items) - Size += Traits::length(Item); - return Size; - } - -private: - Expected<uint32_t> translateOffsetIndex(uint32_t Offset) const { - uint32_t CurrentOffset = 0; - uint32_t CurrentIndex = 0; - for (const auto &Item : Items) { - if (CurrentOffset >= Offset) - break; - CurrentOffset += Traits::length(Item); - ++CurrentIndex; - } - if (CurrentOffset != Offset) - return make_error<MSFError>(msf_error_code::insufficient_buffer); - return CurrentIndex; - } - - ArrayRef<T> Items; -}; - -} // end namespace msf -} // end namespace llvm - -#endif // LLVM_DEBUGINFO_MSF_SEQUENCEDITEMSTREAM_H diff --git a/include/llvm/DebugInfo/MSF/StreamArray.h b/include/llvm/DebugInfo/MSF/StreamArray.h deleted file mode 100644 index 5dfeb8c524af3..0000000000000 --- a/include/llvm/DebugInfo/MSF/StreamArray.h +++ /dev/null @@ -1,304 +0,0 @@ -//===- StreamArray.h - Array backed by an arbitrary stream ------*- 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_MSF_STREAMARRAY_H -#define LLVM_DEBUGINFO_MSF_STREAMARRAY_H - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/iterator.h" -#include "llvm/DebugInfo/MSF/StreamRef.h" -#include "llvm/Support/Error.h" -#include <cassert> -#include <cstdint> - -namespace llvm { -namespace msf { - -/// VarStreamArrayExtractor is intended to be specialized to provide customized -/// extraction logic. On input it receives a StreamRef pointing to the -/// beginning of the next record, but where the length of the record is not yet -/// known. Upon completion, it should return an appropriate Error instance if -/// a record could not be extracted, or if one could be extracted it should -/// return success and set Len to the number of bytes this record occupied in -/// the underlying stream, and it should fill out the fields of the value type -/// Item appropriately to represent the current record. -/// -/// You can specialize this template for your own custom value types to avoid -/// having to specify a second template argument to VarStreamArray (documented -/// below). -template <typename T> struct VarStreamArrayExtractor { - // Method intentionally deleted. You must provide an explicit specialization - // with the following method implemented. - Error operator()(ReadableStreamRef Stream, uint32_t &Len, - T &Item) const = delete; -}; - -/// VarStreamArray represents an array of variable length records backed by a -/// stream. This could be a contiguous sequence of bytes in memory, it could -/// be a file on disk, or it could be a PDB stream where bytes are stored as -/// discontiguous blocks in a file. Usually it is desirable to treat arrays -/// as contiguous blocks of memory, but doing so with large PDB files, for -/// example, could mean allocating huge amounts of memory just to allow -/// re-ordering of stream data to be contiguous before iterating over it. By -/// abstracting this out, we need not duplicate this memory, and we can -/// iterate over arrays in arbitrarily formatted streams. Elements are parsed -/// lazily on iteration, so there is no upfront cost associated with building -/// a VarStreamArray, no matter how large it may be. -/// -/// You create a VarStreamArray by specifying a ValueType and an Extractor type. -/// If you do not specify an Extractor type, it expects you to specialize -/// VarStreamArrayExtractor<T> for your ValueType. -/// -/// By default an Extractor is default constructed in the class, but in some -/// cases you might find it useful for an Extractor to maintain state across -/// extractions. In this case you can provide your own Extractor through a -/// secondary constructor. The following examples show various ways of -/// creating a VarStreamArray. -/// -/// // Will use VarStreamArrayExtractor<MyType> as the extractor. -/// VarStreamArray<MyType> MyTypeArray; -/// -/// // Will use a default-constructed MyExtractor as the extractor. -/// VarStreamArray<MyType, MyExtractor> MyTypeArray2; -/// -/// // Will use the specific instance of MyExtractor provided. -/// // MyExtractor need not be default-constructible in this case. -/// MyExtractor E(SomeContext); -/// VarStreamArray<MyType, MyExtractor> MyTypeArray3(E); -/// -template <typename ValueType, typename Extractor> class VarStreamArrayIterator; - -template <typename ValueType, - typename Extractor = VarStreamArrayExtractor<ValueType>> - -class VarStreamArray { - friend class VarStreamArrayIterator<ValueType, Extractor>; - -public: - typedef VarStreamArrayIterator<ValueType, Extractor> Iterator; - - VarStreamArray() = default; - explicit VarStreamArray(const Extractor &E) : E(E) {} - - explicit VarStreamArray(ReadableStreamRef Stream) : Stream(Stream) {} - VarStreamArray(ReadableStreamRef Stream, const Extractor &E) - : Stream(Stream), E(E) {} - - VarStreamArray(const VarStreamArray<ValueType, Extractor> &Other) - : Stream(Other.Stream), E(Other.E) {} - - Iterator begin(bool *HadError = nullptr) const { - return Iterator(*this, E, HadError); - } - - Iterator end() const { return Iterator(E); } - - const Extractor &getExtractor() const { return E; } - - ReadableStreamRef getUnderlyingStream() const { return Stream; } - -private: - ReadableStreamRef Stream; - Extractor E; -}; - -template <typename ValueType, typename Extractor> -class VarStreamArrayIterator - : public iterator_facade_base<VarStreamArrayIterator<ValueType, Extractor>, - std::forward_iterator_tag, ValueType> { - typedef VarStreamArrayIterator<ValueType, Extractor> IterType; - typedef VarStreamArray<ValueType, Extractor> ArrayType; - -public: - VarStreamArrayIterator(const ArrayType &Array, const Extractor &E, - bool *HadError = nullptr) - : IterRef(Array.Stream), Array(&Array), HadError(HadError), Extract(E) { - if (IterRef.getLength() == 0) - moveToEnd(); - else { - auto EC = Extract(IterRef, ThisLen, ThisValue); - if (EC) { - consumeError(std::move(EC)); - markError(); - } - } - } - VarStreamArrayIterator() = default; - explicit VarStreamArrayIterator(const Extractor &E) : Extract(E) {} - ~VarStreamArrayIterator() = default; - - bool operator==(const IterType &R) const { - if (Array && R.Array) { - // Both have a valid array, make sure they're same. - assert(Array == R.Array); - return IterRef == R.IterRef; - } - - // Both iterators are at the end. - if (!Array && !R.Array) - return true; - - // One is not at the end and one is. - return false; - } - - const ValueType &operator*() const { - assert(Array && !HasError); - return ThisValue; - } - - IterType &operator++() { - // We are done with the current record, discard it so that we are - // positioned at the next record. - IterRef = IterRef.drop_front(ThisLen); - if (IterRef.getLength() == 0) { - // There is nothing after the current record, we must make this an end - // iterator. - moveToEnd(); - } else { - // There is some data after the current record. - auto EC = Extract(IterRef, ThisLen, ThisValue); - if (EC) { - consumeError(std::move(EC)); - markError(); - } else if (ThisLen == 0) { - // An empty record? Make this an end iterator. - moveToEnd(); - } - } - return *this; - } - -private: - void moveToEnd() { - Array = nullptr; - ThisLen = 0; - } - void markError() { - moveToEnd(); - HasError = true; - if (HadError != nullptr) - *HadError = true; - } - - ValueType ThisValue; - ReadableStreamRef IterRef; - const ArrayType *Array{nullptr}; - uint32_t ThisLen{0}; - bool HasError{false}; - bool *HadError{nullptr}; - Extractor Extract; -}; - -template <typename T> class FixedStreamArrayIterator; - -template <typename T> class FixedStreamArray { - friend class FixedStreamArrayIterator<T>; - -public: - FixedStreamArray() = default; - FixedStreamArray(ReadableStreamRef Stream) : Stream(Stream) { - assert(Stream.getLength() % sizeof(T) == 0); - } - - bool operator==(const FixedStreamArray<T> &Other) const { - return Stream == Other.Stream; - } - - bool operator!=(const FixedStreamArray<T> &Other) const { - return !(*this == Other); - } - - FixedStreamArray &operator=(const FixedStreamArray &) = default; - - const T &operator[](uint32_t Index) const { - assert(Index < size()); - uint32_t Off = Index * sizeof(T); - ArrayRef<uint8_t> Data; - if (auto EC = Stream.readBytes(Off, sizeof(T), Data)) { - assert(false && "Unexpected failure reading from stream"); - // This should never happen since we asserted that the stream length was - // an exact multiple of the element size. - consumeError(std::move(EC)); - } - return *reinterpret_cast<const T *>(Data.data()); - } - - uint32_t size() const { return Stream.getLength() / sizeof(T); } - - bool empty() const { return size() == 0; } - - FixedStreamArrayIterator<T> begin() const { - return FixedStreamArrayIterator<T>(*this, 0); - } - - FixedStreamArrayIterator<T> end() const { - return FixedStreamArrayIterator<T>(*this, size()); - } - - ReadableStreamRef getUnderlyingStream() const { return Stream; } - -private: - ReadableStreamRef Stream; -}; - -template <typename T> -class FixedStreamArrayIterator - : public iterator_facade_base<FixedStreamArrayIterator<T>, - std::random_access_iterator_tag, T> { - -public: - FixedStreamArrayIterator(const FixedStreamArray<T> &Array, uint32_t Index) - : Array(Array), Index(Index) {} - - FixedStreamArrayIterator<T> & - operator=(const FixedStreamArrayIterator<T> &Other) { - Array = Other.Array; - Index = Other.Index; - return *this; - } - - const T &operator*() const { return Array[Index]; } - - bool operator==(const FixedStreamArrayIterator<T> &R) const { - assert(Array == R.Array); - return (Index == R.Index) && (Array == R.Array); - } - - FixedStreamArrayIterator<T> &operator+=(std::ptrdiff_t N) { - Index += N; - return *this; - } - - FixedStreamArrayIterator<T> &operator-=(std::ptrdiff_t N) { - assert(Index >= N); - Index -= N; - return *this; - } - - std::ptrdiff_t operator-(const FixedStreamArrayIterator<T> &R) const { - assert(Array == R.Array); - assert(Index >= R.Index); - return Index - R.Index; - } - - bool operator<(const FixedStreamArrayIterator<T> &RHS) const { - assert(Array == RHS.Array); - return Index < RHS.Index; - } - -private: - FixedStreamArray<T> Array; - uint32_t Index; -}; - -} // namespace msf -} // namespace llvm - -#endif // LLVM_DEBUGINFO_MSF_STREAMARRAY_H diff --git a/include/llvm/DebugInfo/MSF/StreamInterface.h b/include/llvm/DebugInfo/MSF/StreamInterface.h deleted file mode 100644 index 09782d8e3b303..0000000000000 --- a/include/llvm/DebugInfo/MSF/StreamInterface.h +++ /dev/null @@ -1,53 +0,0 @@ -//===- StreamInterface.h - Base interface for a stream of data --*- 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_MSF_STREAMINTERFACE_H -#define LLVM_DEBUGINFO_MSF_STREAMINTERFACE_H - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/Support/Error.h" -#include <cstdint> - -namespace llvm { -namespace msf { - -class ReadableStream { -public: - virtual ~ReadableStream() = default; - - // Given an offset into the stream and a number of bytes, attempt to read - // the bytes and set the output ArrayRef to point to a reference into the - // stream, without copying any data. - virtual Error readBytes(uint32_t Offset, uint32_t Size, - ArrayRef<uint8_t> &Buffer) const = 0; - - // Given an offset into the stream, read as much as possible without copying - // any data. - virtual Error readLongestContiguousChunk(uint32_t Offset, - ArrayRef<uint8_t> &Buffer) const = 0; - - virtual uint32_t getLength() const = 0; -}; - -class WritableStream : public ReadableStream { -public: - ~WritableStream() override = default; - - // Attempt to write the given bytes into the stream at the desired offset. - // This will always necessitate a copy. Cannot shrink or grow the stream, - // only writes into existing allocated space. - virtual Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const = 0; - - virtual Error commit() const = 0; -}; - -} // end namespace msf -} // end namespace llvm - -#endif // LLVM_DEBUGINFO_MSF_STREAMINTERFACE_H diff --git a/include/llvm/DebugInfo/MSF/StreamReader.h b/include/llvm/DebugInfo/MSF/StreamReader.h deleted file mode 100644 index fc2ca78dc18f4..0000000000000 --- a/include/llvm/DebugInfo/MSF/StreamReader.h +++ /dev/null @@ -1,121 +0,0 @@ -//===- StreamReader.h - Reads bytes and objects from a stream ---*- 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_MSF_STREAMREADER_H -#define LLVM_DEBUGINFO_MSF_STREAMREADER_H - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/DebugInfo/MSF/MSFError.h" -#include "llvm/DebugInfo/MSF/StreamArray.h" -#include "llvm/DebugInfo/MSF/StreamInterface.h" -#include "llvm/DebugInfo/MSF/StreamRef.h" -#include "llvm/Support/Endian.h" -#include "llvm/Support/Error.h" - -#include <string> - -namespace llvm { -namespace msf { - -class StreamReader { -public: - StreamReader(ReadableStreamRef Stream); - - Error readLongestContiguousChunk(ArrayRef<uint8_t> &Buffer); - Error readBytes(ArrayRef<uint8_t> &Buffer, uint32_t Size); - Error readInteger(uint8_t &Dest); - Error readInteger(uint16_t &Dest); - Error readInteger(uint32_t &Dest); - Error readInteger(uint64_t &Dest); - Error readInteger(int8_t &Dest); - Error readInteger(int16_t &Dest); - Error readInteger(int32_t &Dest); - Error readInteger(int64_t &Dest); - Error readZeroString(StringRef &Dest); - Error readFixedString(StringRef &Dest, uint32_t Length); - Error readStreamRef(ReadableStreamRef &Ref); - Error readStreamRef(ReadableStreamRef &Ref, uint32_t Length); - - template <typename T> Error readEnum(T &Dest) { - typename std::underlying_type<T>::type N; - if (auto EC = readInteger(N)) - return EC; - Dest = static_cast<T>(N); - return Error::success(); - } - - template <typename T> Error readObject(const T *&Dest) { - ArrayRef<uint8_t> Buffer; - if (auto EC = readBytes(Buffer, sizeof(T))) - return EC; - Dest = reinterpret_cast<const T *>(Buffer.data()); - return Error::success(); - } - - template <typename T> - Error readArray(ArrayRef<T> &Array, uint32_t NumElements) { - ArrayRef<uint8_t> Bytes; - if (NumElements == 0) { - Array = ArrayRef<T>(); - return Error::success(); - } - - if (NumElements > UINT32_MAX / sizeof(T)) - return make_error<MSFError>(msf_error_code::insufficient_buffer); - - if (auto EC = readBytes(Bytes, NumElements * sizeof(T))) - return EC; - Array = ArrayRef<T>(reinterpret_cast<const T *>(Bytes.data()), NumElements); - return Error::success(); - } - - template <typename T, typename U> - Error readArray(VarStreamArray<T, U> &Array, uint32_t Size) { - ReadableStreamRef S; - if (auto EC = readStreamRef(S, Size)) - return EC; - Array = VarStreamArray<T, U>(S, Array.getExtractor()); - return Error::success(); - } - - template <typename T> - Error readArray(FixedStreamArray<T> &Array, uint32_t NumItems) { - if (NumItems == 0) { - Array = FixedStreamArray<T>(); - return Error::success(); - } - uint32_t Length = NumItems * sizeof(T); - if (Length / sizeof(T) != NumItems) - return make_error<MSFError>(msf_error_code::invalid_format); - if (Offset + Length > Stream.getLength()) - return make_error<MSFError>(msf_error_code::insufficient_buffer); - ReadableStreamRef View = Stream.slice(Offset, Length); - Array = FixedStreamArray<T>(View); - Offset += Length; - return Error::success(); - } - - bool empty() const { return bytesRemaining() == 0; } - void setOffset(uint32_t Off) { Offset = Off; } - uint32_t getOffset() const { return Offset; } - uint32_t getLength() const { return Stream.getLength(); } - uint32_t bytesRemaining() const { return getLength() - getOffset(); } - - Error skip(uint32_t Amount); - - uint8_t peek() const; - -private: - ReadableStreamRef Stream; - uint32_t Offset; -}; -} // namespace msf -} // namespace llvm - -#endif // LLVM_DEBUGINFO_MSF_STREAMREADER_H diff --git a/include/llvm/DebugInfo/MSF/StreamRef.h b/include/llvm/DebugInfo/MSF/StreamRef.h deleted file mode 100644 index eee71e53a39b0..0000000000000 --- a/include/llvm/DebugInfo/MSF/StreamRef.h +++ /dev/null @@ -1,135 +0,0 @@ -//===- StreamRef.h - A copyable reference to a stream -----------*- 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_MSF_STREAMREF_H -#define LLVM_DEBUGINFO_MSF_STREAMREF_H - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/DebugInfo/MSF/MSFError.h" -#include "llvm/DebugInfo/MSF/StreamInterface.h" -#include "llvm/Support/Error.h" -#include <algorithm> -#include <cstdint> - -namespace llvm { -namespace msf { - -template <class StreamType, class RefType> class StreamRefBase { -public: - StreamRefBase() : Stream(nullptr), ViewOffset(0), Length(0) {} - StreamRefBase(const StreamType &Stream, uint32_t Offset, uint32_t Length) - : Stream(&Stream), ViewOffset(Offset), Length(Length) {} - - uint32_t getLength() const { return Length; } - const StreamType *getStream() const { return Stream; } - - RefType drop_front(uint32_t N) const { - if (!Stream) - return RefType(); - - N = std::min(N, Length); - return RefType(*Stream, ViewOffset + N, Length - N); - } - - RefType keep_front(uint32_t N) const { - if (!Stream) - return RefType(); - N = std::min(N, Length); - return RefType(*Stream, ViewOffset, N); - } - - RefType slice(uint32_t Offset, uint32_t Len) const { - return drop_front(Offset).keep_front(Len); - } - - bool operator==(const RefType &Other) const { - if (Stream != Other.Stream) - return false; - if (ViewOffset != Other.ViewOffset) - return false; - if (Length != Other.Length) - return false; - return true; - } - -protected: - const StreamType *Stream; - uint32_t ViewOffset; - uint32_t Length; -}; - -class ReadableStreamRef - : public StreamRefBase<ReadableStream, ReadableStreamRef> { -public: - ReadableStreamRef() = default; - ReadableStreamRef(const ReadableStream &Stream) - : StreamRefBase(Stream, 0, Stream.getLength()) {} - ReadableStreamRef(const ReadableStream &Stream, uint32_t Offset, - uint32_t Length) - : StreamRefBase(Stream, Offset, Length) {} - - // Use StreamRef.slice() instead. - ReadableStreamRef(const ReadableStreamRef &S, uint32_t Offset, - uint32_t Length) = delete; - - Error readBytes(uint32_t Offset, uint32_t Size, - ArrayRef<uint8_t> &Buffer) const { - if (ViewOffset + Offset < Offset) - return make_error<MSFError>(msf_error_code::insufficient_buffer); - if (Size + Offset > Length) - return make_error<MSFError>(msf_error_code::insufficient_buffer); - return Stream->readBytes(ViewOffset + Offset, Size, Buffer); - } - - // Given an offset into the stream, read as much as possible without copying - // any data. - Error readLongestContiguousChunk(uint32_t Offset, - ArrayRef<uint8_t> &Buffer) const { - if (Offset >= Length) - return make_error<MSFError>(msf_error_code::insufficient_buffer); - - if (auto EC = Stream->readLongestContiguousChunk(Offset, Buffer)) - return EC; - // This StreamRef might refer to a smaller window over a larger stream. In - // that case we will have read out more bytes than we should return, because - // we should not read past the end of the current view. - uint32_t MaxLength = Length - Offset; - if (Buffer.size() > MaxLength) - Buffer = Buffer.slice(0, MaxLength); - return Error::success(); - } -}; - -class WritableStreamRef - : public StreamRefBase<WritableStream, WritableStreamRef> { -public: - WritableStreamRef() = default; - WritableStreamRef(const WritableStream &Stream) - : StreamRefBase(Stream, 0, Stream.getLength()) {} - WritableStreamRef(const WritableStream &Stream, uint32_t Offset, - uint32_t Length) - : StreamRefBase(Stream, Offset, Length) {} - - // Use StreamRef.slice() instead. - WritableStreamRef(const WritableStreamRef &S, uint32_t Offset, - uint32_t Length) = delete; - - Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Data) const { - if (Data.size() + Offset > Length) - return make_error<MSFError>(msf_error_code::insufficient_buffer); - return Stream->writeBytes(ViewOffset + Offset, Data); - } - - Error commit() const { return Stream->commit(); } -}; - -} // end namespace msf -} // end namespace llvm - -#endif // LLVM_DEBUGINFO_MSF_STREAMREF_H diff --git a/include/llvm/DebugInfo/MSF/StreamWriter.h b/include/llvm/DebugInfo/MSF/StreamWriter.h deleted file mode 100644 index 2bb14434dd83c..0000000000000 --- a/include/llvm/DebugInfo/MSF/StreamWriter.h +++ /dev/null @@ -1,92 +0,0 @@ -//===- StreamWriter.h - Writes bytes and objects to a stream ----*- 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_MSF_STREAMWRITER_H -#define LLVM_DEBUGINFO_MSF_STREAMWRITER_H - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/DebugInfo/MSF/MSFError.h" -#include "llvm/DebugInfo/MSF/StreamArray.h" -#include "llvm/DebugInfo/MSF/StreamRef.h" -#include "llvm/Support/Error.h" -#include <cstdint> -#include <type_traits> - -namespace llvm { -namespace msf { - -class StreamWriter { -public: - StreamWriter() = default; - explicit StreamWriter(WritableStreamRef Stream); - - Error writeBytes(ArrayRef<uint8_t> Buffer); - Error writeInteger(uint8_t Int); - Error writeInteger(uint16_t Dest); - Error writeInteger(uint32_t Dest); - Error writeInteger(uint64_t Dest); - Error writeInteger(int8_t Int); - Error writeInteger(int16_t Dest); - Error writeInteger(int32_t Dest); - Error writeInteger(int64_t Dest); - Error writeZeroString(StringRef Str); - Error writeFixedString(StringRef Str); - Error writeStreamRef(ReadableStreamRef Ref); - Error writeStreamRef(ReadableStreamRef Ref, uint32_t Size); - - template <typename T> Error writeEnum(T Num) { - return writeInteger( - static_cast<typename std::underlying_type<T>::type>(Num)); - } - - template <typename T> Error writeObject(const T &Obj) { - static_assert(!std::is_pointer<T>::value, - "writeObject should not be used with pointers, to write " - "the pointed-to value dereference the pointer before calling " - "writeObject"); - return writeBytes( - ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&Obj), sizeof(T))); - } - - template <typename T> Error writeArray(ArrayRef<T> Array) { - if (Array.empty()) - return Error::success(); - - if (Array.size() > UINT32_MAX / sizeof(T)) - return make_error<MSFError>(msf_error_code::insufficient_buffer); - - return writeBytes( - ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Array.data()), - Array.size() * sizeof(T))); - } - - template <typename T, typename U> - Error writeArray(VarStreamArray<T, U> Array) { - return writeStreamRef(Array.getUnderlyingStream()); - } - - template <typename T> Error writeArray(FixedStreamArray<T> Array) { - return writeStreamRef(Array.getUnderlyingStream()); - } - - void setOffset(uint32_t Off) { Offset = Off; } - uint32_t getOffset() const { return Offset; } - uint32_t getLength() const { return Stream.getLength(); } - uint32_t bytesRemaining() const { return getLength() - getOffset(); } - -private: - WritableStreamRef Stream; - uint32_t Offset = 0; -}; - -} // end namespace msf -} // end namespace llvm - -#endif // LLVM_DEBUGINFO_MSF_STREAMWRITER_H diff --git a/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h b/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h index 9bf0738315653..9713dce362d28 100644 --- a/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h +++ b/include/llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h @@ -34,12 +34,11 @@ public: std::unique_ptr<ChildType> getChildAtIndex(uint32_t Index) const override { std::unique_ptr<PDBSymbol> Child = Enumerator->getChildAtIndex(Index); - return make_concrete_child(std::move(Child)); + return unique_dyn_cast_or_null<ChildType>(Child); } std::unique_ptr<ChildType> getNext() override { - std::unique_ptr<PDBSymbol> Child = Enumerator->getNext(); - return make_concrete_child(std::move(Child)); + return unique_dyn_cast_or_null<ChildType>(Enumerator->getNext()); } void reset() override { Enumerator->reset(); } @@ -50,11 +49,6 @@ public: } private: - std::unique_ptr<ChildType> - make_concrete_child(std::unique_ptr<PDBSymbol> Child) const { - ChildType *ConcreteChild = dyn_cast_or_null<ChildType>(Child.release()); - return std::unique_ptr<ChildType>(ConcreteChild); - } std::unique_ptr<IPDBEnumSymbols> Enumerator; }; diff --git a/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h b/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h index 1e40c46f8a27e..c0633cbdfa521 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h @@ -102,6 +102,7 @@ public: uint32_t getVirtualBaseDispIndex() const override; uint32_t getVirtualBaseOffset() const override; uint32_t getVirtualTableShapeId() const override; + std::unique_ptr<PDBSymbolTypeVTable> getVirtualBaseTableType() const override; PDB_DataKind getDataKind() const override; PDB_SymType getSymTag() const override; PDB_UniqueId getGuid() const override; diff --git a/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h b/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h index 49866b8bb2f22..4c28e194bc70d 100644 --- a/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h +++ b/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h @@ -21,6 +21,9 @@ class raw_ostream; namespace pdb { +class PDBSymbolTypeVTable; +class PDBSymbolTypeVTableShape; + /// IPDBRawSymbol defines an interface used to represent an arbitrary symbol. /// It exposes a monolithic interface consisting of accessors for the union of /// all properties that are valid for any symbol type. This interface is then @@ -110,6 +113,8 @@ public: virtual Variant getValue() const = 0; virtual uint32_t getVirtualBaseDispIndex() const = 0; virtual uint32_t getVirtualBaseOffset() const = 0; + virtual std::unique_ptr<PDBSymbolTypeVTable> + getVirtualBaseTableType() const = 0; virtual uint32_t getVirtualTableShapeId() const = 0; virtual PDB_DataKind getDataKind() const = 0; virtual PDB_SymType getSymTag() const = 0; diff --git a/include/llvm/DebugInfo/PDB/IPDBSession.h b/include/llvm/DebugInfo/PDB/IPDBSession.h index 15e97ac198e55..85d9fe1248599 100644 --- a/include/llvm/DebugInfo/PDB/IPDBSession.h +++ b/include/llvm/DebugInfo/PDB/IPDBSession.h @@ -10,6 +10,7 @@ #ifndef LLVM_DEBUGINFO_PDB_IPDBSESSION_H #define LLVM_DEBUGINFO_PDB_IPDBSESSION_H +#include "PDBSymbol.h" #include "PDBTypes.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Casting.h" @@ -33,15 +34,7 @@ public: template <typename T> std::unique_ptr<T> getConcreteSymbolById(uint32_t SymbolId) const { - auto Symbol(getSymbolById(SymbolId)); - if (!Symbol) - return nullptr; - - T *ConcreteSymbol = dyn_cast<T>(Symbol.get()); - if (!ConcreteSymbol) - return nullptr; - (void)Symbol.release(); - return std::unique_ptr<T>(ConcreteSymbol); + return unique_dyn_cast_or_null<T>(getSymbolById(SymbolId)); } virtual std::unique_ptr<PDBSymbol> diff --git a/include/llvm/DebugInfo/PDB/Raw/DbiStream.h b/include/llvm/DebugInfo/PDB/Native/DbiStream.h index c97ca32ab43d1..f49f5aaefacad 100644 --- a/include/llvm/DebugInfo/PDB/Raw/DbiStream.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiStream.h @@ -12,13 +12,15 @@ #include "llvm/DebugInfo/CodeView/ModuleSubstream.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" -#include "llvm/DebugInfo/MSF/StreamArray.h" -#include "llvm/DebugInfo/MSF/StreamRef.h" +#include "llvm/DebugInfo/PDB/Native/ModInfo.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/DebugInfo/PDB/Raw/ModInfo.h" -#include "llvm/DebugInfo/PDB/Raw/NameHashTable.h" -#include "llvm/DebugInfo/PDB/Raw/RawConstants.h" -#include "llvm/DebugInfo/PDB/Raw/RawTypes.h" +#include "llvm/Support/BinaryStreamArray.h" +#include "llvm/Support/BinaryStreamArray.h" +#include "llvm/Support/BinaryStreamRef.h" +#include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" @@ -70,11 +72,11 @@ public: Expected<StringRef> getFileNameForIndex(uint32_t Index) const; - msf::FixedStreamArray<object::coff_section> getSectionHeaders(); + FixedStreamArray<object::coff_section> getSectionHeaders(); - msf::FixedStreamArray<object::FpoData> getFpoRecords(); + FixedStreamArray<object::FpoData> getFpoRecords(); - msf::FixedStreamArray<SecMapEntry> getSectionMap() const; + FixedStreamArray<SecMapEntry> getSectionMap() const; void visitSectionContributions(ISectionContribVisitor &Visitor) const; private: @@ -89,30 +91,30 @@ private: std::unique_ptr<msf::MappedBlockStream> Stream; std::vector<ModuleInfoEx> ModuleInfos; - NameHashTable ECNames; + StringTable ECNames; - msf::ReadableStreamRef ModInfoSubstream; - msf::ReadableStreamRef SecContrSubstream; - msf::ReadableStreamRef SecMapSubstream; - msf::ReadableStreamRef FileInfoSubstream; - msf::ReadableStreamRef TypeServerMapSubstream; - msf::ReadableStreamRef ECSubstream; + BinaryStreamRef ModInfoSubstream; + BinaryStreamRef SecContrSubstream; + BinaryStreamRef SecMapSubstream; + BinaryStreamRef FileInfoSubstream; + BinaryStreamRef TypeServerMapSubstream; + BinaryStreamRef ECSubstream; - msf::ReadableStreamRef NamesBuffer; + BinaryStreamRef NamesBuffer; - msf::FixedStreamArray<support::ulittle16_t> DbgStreams; + FixedStreamArray<support::ulittle16_t> DbgStreams; PdbRaw_DbiSecContribVer SectionContribVersion; - msf::FixedStreamArray<SectionContrib> SectionContribs; - msf::FixedStreamArray<SectionContrib2> SectionContribs2; - msf::FixedStreamArray<SecMapEntry> SectionMap; - msf::FixedStreamArray<support::little32_t> FileNameOffsets; + FixedStreamArray<SectionContrib> SectionContribs; + FixedStreamArray<SectionContrib2> SectionContribs2; + FixedStreamArray<SecMapEntry> SectionMap; + FixedStreamArray<support::little32_t> FileNameOffsets; std::unique_ptr<msf::MappedBlockStream> SectionHeaderStream; - msf::FixedStreamArray<object::coff_section> SectionHeaders; + FixedStreamArray<object::coff_section> SectionHeaders; std::unique_ptr<msf::MappedBlockStream> FpoStream; - msf::FixedStreamArray<object::FpoData> FpoRecords; + FixedStreamArray<object::FpoData> FpoRecords; const DbiStreamHeader *Header; }; diff --git a/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h b/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h index 99a3ac7fb1da2..16426bd93847a 100644 --- a/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h @@ -14,11 +14,11 @@ #include "llvm/ADT/StringSet.h" #include "llvm/Support/Error.h" -#include "llvm/DebugInfo/MSF/ByteStream.h" -#include "llvm/DebugInfo/MSF/StreamReader.h" +#include "llvm/DebugInfo/PDB/Native/PDBFile.h" +#include "llvm/DebugInfo/PDB/Native/RawConstants.h" #include "llvm/DebugInfo/PDB/PDBTypes.h" -#include "llvm/DebugInfo/PDB/Raw/PDBFile.h" -#include "llvm/DebugInfo/PDB/Raw/RawConstants.h" +#include "llvm/Support/BinaryByteStream.h" +#include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/Endian.h" namespace llvm { @@ -31,11 +31,13 @@ struct coff_section; namespace pdb { class DbiStream; struct DbiStreamHeader; +class ModInfoBuilder; class PDBFile; class DbiStreamBuilder { public: DbiStreamBuilder(msf::MSFBuilder &Msf); + ~DbiStreamBuilder(); DbiStreamBuilder(const DbiStreamBuilder &) = delete; DbiStreamBuilder &operator=(const DbiStreamBuilder &) = delete; @@ -55,13 +57,12 @@ public: uint32_t calculateSerializedLength() const; - Error addModuleInfo(StringRef ObjFile, StringRef Module); + Expected<ModInfoBuilder &> addModuleInfo(StringRef ModuleName); Error addModuleSourceFile(StringRef Module, StringRef File); Error finalizeMsfLayout(); - Error commit(const msf::MSFLayout &Layout, - const msf::WritableStream &Buffer); + Error commit(const msf::MSFLayout &Layout, WritableBinaryStreamRef MsfBuffer); // A helper function to create Section Contributions from COFF input // section headers. @@ -89,12 +90,6 @@ private: Error generateModiSubstream(); Error generateFileInfoSubstream(); - struct ModuleInfo { - std::vector<StringRef> SourceFiles; - StringRef Obj; - StringRef Mod; - }; - msf::MSFBuilder &Msf; BumpPtrAllocator &Allocator; @@ -108,14 +103,13 @@ private: const DbiStreamHeader *Header; - StringMap<std::unique_ptr<ModuleInfo>> ModuleInfos; - std::vector<ModuleInfo *> ModuleInfoList; + StringMap<std::unique_ptr<ModInfoBuilder>> ModiMap; + std::vector<ModInfoBuilder *> ModiList; StringMap<uint32_t> SourceFileNames; - msf::WritableStreamRef NamesBuffer; - msf::MutableByteStream ModInfoBuffer; - msf::MutableByteStream FileInfoBuffer; + WritableBinaryStreamRef NamesBuffer; + MutableBinaryByteStream FileInfoBuffer; ArrayRef<SectionContrib> SectionContribs; ArrayRef<SecMapEntry> SectionMap; llvm::SmallVector<DebugStream, (int)DbgHeaderType::Max> DbgStreams; diff --git a/include/llvm/DebugInfo/PDB/Raw/EnumTables.h b/include/llvm/DebugInfo/PDB/Native/EnumTables.h index c018445630fed..c018445630fed 100644 --- a/include/llvm/DebugInfo/PDB/Raw/EnumTables.h +++ b/include/llvm/DebugInfo/PDB/Native/EnumTables.h diff --git a/include/llvm/DebugInfo/PDB/Native/Formatters.h b/include/llvm/DebugInfo/PDB/Native/Formatters.h new file mode 100644 index 0000000000000..183f0ad8307e3 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/Formatters.h @@ -0,0 +1,52 @@ +//===- Formatters.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_PDB_NATIVE_FORMATTERS_H +#define LLVM_DEBUGINFO_PDB_NATIVE_FORMATTERS_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/CodeView/Formatters.h" +#include "llvm/DebugInfo/PDB/Native/RawConstants.h" +#include "llvm/DebugInfo/PDB/Native/RawTypes.h" +#include "llvm/Support/FormatProviders.h" + +#define FORMAT_CASE(Value, Name) \ + case Value: \ + Stream << Name; \ + break; + +namespace llvm { +template <> struct format_provider<pdb::PDB_UniqueId> { + static void format(const pdb::PDB_UniqueId &V, llvm::raw_ostream &Stream, + StringRef Style) { + codeview::fmt_guid(V.Guid).format(Stream, Style); + } +}; + +template <> struct format_provider<pdb::PdbRaw_ImplVer> { + static void format(const pdb::PdbRaw_ImplVer &V, llvm::raw_ostream &Stream, + StringRef Style) { + switch (V) { + FORMAT_CASE(pdb::PdbRaw_ImplVer::PdbImplVC110, "VC110") + FORMAT_CASE(pdb::PdbRaw_ImplVer::PdbImplVC140, "VC140") + FORMAT_CASE(pdb::PdbRaw_ImplVer::PdbImplVC2, "VC2") + FORMAT_CASE(pdb::PdbRaw_ImplVer::PdbImplVC4, "VC4") + FORMAT_CASE(pdb::PdbRaw_ImplVer::PdbImplVC41, "VC41") + FORMAT_CASE(pdb::PdbRaw_ImplVer::PdbImplVC50, "VC50") + FORMAT_CASE(pdb::PdbRaw_ImplVer::PdbImplVC70, "VC70") + FORMAT_CASE(pdb::PdbRaw_ImplVer::PdbImplVC70Dep, "VC70Dep") + FORMAT_CASE(pdb::PdbRaw_ImplVer::PdbImplVC80, "VC80") + FORMAT_CASE(pdb::PdbRaw_ImplVer::PdbImplVC98, "VC98") + } + } +}; +} + +#endif diff --git a/include/llvm/DebugInfo/PDB/Raw/GlobalsStream.h b/include/llvm/DebugInfo/PDB/Native/GlobalsStream.h index 175f093cf53c9..dcea3d3be0ab8 100644 --- a/include/llvm/DebugInfo/PDB/Raw/GlobalsStream.h +++ b/include/llvm/DebugInfo/PDB/Native/GlobalsStream.h @@ -11,10 +11,10 @@ #define LLVM_DEBUGINFO_PDB_RAW_GLOBALS_STREAM_H #include "llvm/DebugInfo/MSF/MappedBlockStream.h" -#include "llvm/DebugInfo/MSF/StreamArray.h" +#include "llvm/DebugInfo/PDB/Native/RawConstants.h" +#include "llvm/DebugInfo/PDB/Native/RawTypes.h" #include "llvm/DebugInfo/PDB/PDBTypes.h" -#include "llvm/DebugInfo/PDB/Raw/RawConstants.h" -#include "llvm/DebugInfo/PDB/Raw/RawTypes.h" +#include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/Error.h" namespace llvm { @@ -27,15 +27,15 @@ public: explicit GlobalsStream(std::unique_ptr<msf::MappedBlockStream> Stream); ~GlobalsStream(); Error commit(); - msf::FixedStreamArray<support::ulittle32_t> getHashBuckets() const { + FixedStreamArray<support::ulittle32_t> getHashBuckets() const { return HashBuckets; } uint32_t getNumBuckets() const { return NumBuckets; } Error reload(); private: - msf::FixedStreamArray<support::ulittle32_t> HashBuckets; - msf::FixedStreamArray<PSHashRecord> HashRecords; + FixedStreamArray<support::ulittle32_t> HashBuckets; + FixedStreamArray<PSHashRecord> HashRecords; uint32_t NumBuckets; std::unique_ptr<msf::MappedBlockStream> Stream; }; diff --git a/include/llvm/DebugInfo/PDB/Raw/Hash.h b/include/llvm/DebugInfo/PDB/Native/Hash.h index 0340554d7b0b3..0340554d7b0b3 100644 --- a/include/llvm/DebugInfo/PDB/Raw/Hash.h +++ b/include/llvm/DebugInfo/PDB/Native/Hash.h diff --git a/include/llvm/DebugInfo/PDB/Native/HashTable.h b/include/llvm/DebugInfo/PDB/Native/HashTable.h new file mode 100644 index 0000000000000..46eefa968e523 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/HashTable.h @@ -0,0 +1,106 @@ +//===- HashTable.h - PDB Hash Table -----------------------------*- 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_PDB_RAW_HASHTABLE_H +#define LLVM_DEBUGINFO_PDB_RAW_HASHTABLE_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SparseBitVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator.h" +#include "llvm/Support/BinaryStreamArray.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/BinaryStreamWriter.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/MathExtras.h" + +#include <cstdint> +#include <utility> + +namespace llvm { +namespace pdb { + +class HashTableIterator; + +class HashTable { + friend class HashTableIterator; + struct Header { + support::ulittle32_t Size; + support::ulittle32_t Capacity; + }; + + typedef std::vector<std::pair<uint32_t, uint32_t>> BucketList; + +public: + HashTable(); + explicit HashTable(uint32_t Capacity); + + Error load(BinaryStreamReader &Stream); + + uint32_t calculateSerializedLength() const; + Error commit(BinaryStreamWriter &Writer) const; + + void clear(); + + uint32_t capacity() const; + uint32_t size() const; + + HashTableIterator begin() const; + HashTableIterator end() const; + HashTableIterator find(uint32_t K); + + void set(uint32_t K, uint32_t V); + void remove(uint32_t K); + uint32_t get(uint32_t K); + +protected: + bool isPresent(uint32_t K) const { return Present.test(K); } + bool isDeleted(uint32_t K) const { return Deleted.test(K); } + BucketList Buckets; + mutable SparseBitVector<> Present; + mutable SparseBitVector<> Deleted; + +private: + static uint32_t maxLoad(uint32_t capacity); + void grow(); + + static Error readSparseBitVector(BinaryStreamReader &Stream, + SparseBitVector<> &V); + static Error writeSparseBitVector(BinaryStreamWriter &Writer, + SparseBitVector<> &Vec); +}; + +class HashTableIterator + : public iterator_facade_base<HashTableIterator, std::forward_iterator_tag, + std::pair<uint32_t, uint32_t>> { + friend class HashTable; + HashTableIterator(const HashTable &Map, uint32_t Index, bool IsEnd); + +public: + HashTableIterator(const HashTable &Map); + + HashTableIterator &operator=(const HashTableIterator &R); + bool operator==(const HashTableIterator &R) const; + const std::pair<uint32_t, uint32_t> &operator*() const; + HashTableIterator &operator++(); + +private: + bool isEnd() const { return IsEnd; } + uint32_t index() const { return Index; } + + const HashTable *Map; + uint32_t Index; + bool IsEnd; +}; + +} // end namespace pdb +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_RAW_HASHTABLE_H diff --git a/include/llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h b/include/llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h index fb00d6ad4bc78..fb00d6ad4bc78 100644 --- a/include/llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h +++ b/include/llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h diff --git a/include/llvm/DebugInfo/PDB/Raw/InfoStream.h b/include/llvm/DebugInfo/PDB/Native/InfoStream.h index 6b8b94ff1a362..1c38c2b6194fc 100644 --- a/include/llvm/DebugInfo/PDB/Raw/InfoStream.h +++ b/include/llvm/DebugInfo/PDB/Native/InfoStream.h @@ -10,11 +10,12 @@ #ifndef LLVM_DEBUGINFO_PDB_RAW_PDBINFOSTREAM_H #define LLVM_DEBUGINFO_PDB_RAW_PDBINFOSTREAM_H +#include "llvm/ADT/BitmaskEnum.h" #include "llvm/ADT/StringMap.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" +#include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h" +#include "llvm/DebugInfo/PDB/Native/RawConstants.h" #include "llvm/DebugInfo/PDB/PDBTypes.h" -#include "llvm/DebugInfo/PDB/Raw/NameMap.h" -#include "llvm/DebugInfo/PDB/Raw/RawConstants.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" @@ -32,10 +33,18 @@ public: Error reload(); + uint32_t getStreamSize() const; + PdbRaw_ImplVer getVersion() const; uint32_t getSignature() const; uint32_t getAge() const; PDB_UniqueId getGuid() const; + uint32_t getNamedStreamMapByteSize() const; + + PdbRaw_Features getFeatures() const; + ArrayRef<PdbRaw_FeatureSig> getFeatureSignatures() const; + + const NamedStreamMap &getNamedStreams() const; uint32_t getNamedStreamIndex(llvm::StringRef Name) const; iterator_range<StringMapConstIterator<uint32_t>> named_streams() const; @@ -61,7 +70,12 @@ private: // universally unique. PDB_UniqueId Guid; - NameMap NamedStreams; + std::vector<PdbRaw_FeatureSig> FeatureSignatures; + PdbRaw_Features Features = PdbFeatureNone; + + uint32_t NamedStreamMapByteSize = 0; + + NamedStreamMap NamedStreams; }; } } diff --git a/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h b/include/llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h index cb60b1eb69bd6..90c28a90d2523 100644 --- a/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h @@ -13,22 +13,24 @@ #include "llvm/ADT/Optional.h" #include "llvm/Support/Error.h" +#include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h" +#include "llvm/DebugInfo/PDB/Native/PDBFile.h" +#include "llvm/DebugInfo/PDB/Native/RawConstants.h" #include "llvm/DebugInfo/PDB/PDBTypes.h" -#include "llvm/DebugInfo/PDB/Raw/NameMapBuilder.h" -#include "llvm/DebugInfo/PDB/Raw/PDBFile.h" -#include "llvm/DebugInfo/PDB/Raw/RawConstants.h" namespace llvm { +class WritableBinaryStreamRef; + namespace msf { class MSFBuilder; -class StreamWriter; } namespace pdb { class PDBFile; +class NamedStreamMap; class InfoStreamBuilder { public: - InfoStreamBuilder(msf::MSFBuilder &Msf); + InfoStreamBuilder(msf::MSFBuilder &Msf, NamedStreamMap &NamedStreams); InfoStreamBuilder(const InfoStreamBuilder &) = delete; InfoStreamBuilder &operator=(const InfoStreamBuilder &) = delete; @@ -36,25 +38,25 @@ public: void setSignature(uint32_t S); void setAge(uint32_t A); void setGuid(PDB_UniqueId G); + void addFeature(PdbRaw_FeatureSig Sig); - NameMapBuilder &getNamedStreamsBuilder(); - - uint32_t calculateSerializedLength() const; + uint32_t finalize(); Error finalizeMsfLayout(); Error commit(const msf::MSFLayout &Layout, - const msf::WritableStream &Buffer) const; + WritableBinaryStreamRef Buffer) const; private: msf::MSFBuilder &Msf; + std::vector<PdbRaw_FeatureSig> Features; PdbRaw_ImplVer Ver; uint32_t Sig; uint32_t Age; PDB_UniqueId Guid; - NameMapBuilder NamedStreams; + NamedStreamMap &NamedStreams; }; } } diff --git a/include/llvm/DebugInfo/PDB/Raw/ModInfo.h b/include/llvm/DebugInfo/PDB/Native/ModInfo.h index bf5cf53b3313a..d26d0d6184496 100644 --- a/include/llvm/DebugInfo/PDB/Raw/ModInfo.h +++ b/include/llvm/DebugInfo/PDB/Native/ModInfo.h @@ -11,9 +11,9 @@ #define LLVM_DEBUGINFO_PDB_RAW_MODINFO_H #include "llvm/ADT/StringRef.h" -#include "llvm/DebugInfo/MSF/StreamArray.h" -#include "llvm/DebugInfo/MSF/StreamRef.h" -#include "llvm/DebugInfo/PDB/Raw/RawTypes.h" +#include "llvm/DebugInfo/PDB/Native/RawTypes.h" +#include "llvm/Support/BinaryStreamArray.h" +#include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/Error.h" #include <cstdint> #include <vector> @@ -30,7 +30,7 @@ public: ModInfo(const ModInfo &Info); ~ModInfo(); - static Error initialize(msf::ReadableStreamRef Stream, ModInfo &Info); + static Error initialize(BinaryStreamRef Stream, ModInfo &Info); bool hasECInfo() const; uint16_t getTypeServerIndex() const; @@ -63,10 +63,8 @@ struct ModuleInfoEx { } // end namespace pdb -namespace msf { - template <> struct VarStreamArrayExtractor<pdb::ModInfo> { - Error operator()(ReadableStreamRef Stream, uint32_t &Length, + Error operator()(BinaryStreamRef Stream, uint32_t &Length, pdb::ModInfo &Info) const { if (auto EC = pdb::ModInfo::initialize(Stream, Info)) return EC; @@ -75,8 +73,6 @@ template <> struct VarStreamArrayExtractor<pdb::ModInfo> { } }; -} // end namespace msf - } // end namespace llvm #endif // LLVM_DEBUGINFO_PDB_RAW_MODINFO_H diff --git a/include/llvm/DebugInfo/PDB/Native/ModInfoBuilder.h b/include/llvm/DebugInfo/PDB/Native/ModInfoBuilder.h new file mode 100644 index 0000000000000..605fd2483c3b8 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/ModInfoBuilder.h @@ -0,0 +1,74 @@ +//===- ModInfoBuilder.h - PDB module information ----------------*- 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_PDB_RAW_MODINFOBUILDER_H +#define LLVM_DEBUGINFO_PDB_RAW_MODINFOBUILDER_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/CodeView/SymbolRecord.h" +#include "llvm/DebugInfo/PDB/Native/RawTypes.h" +#include "llvm/Support/Error.h" +#include <cstdint> +#include <string> +#include <vector> + +namespace llvm { +class BinaryStreamWriter; + +namespace msf { +class MSFBuilder; +struct MSFLayout; +} +namespace pdb { + +class ModInfoBuilder { + friend class DbiStreamBuilder; + +public: + ModInfoBuilder(StringRef ModuleName, uint32_t ModIndex, msf::MSFBuilder &Msf); + + ModInfoBuilder(const ModInfoBuilder &) = delete; + ModInfoBuilder &operator=(const ModInfoBuilder &) = delete; + + void setObjFileName(StringRef Name); + void addSymbol(codeview::CVSymbol Symbol); + + uint16_t getStreamIndex() const; + StringRef getModuleName() const { return ModuleName; } + StringRef getObjFileName() const { return ObjFileName; } + + ArrayRef<std::string> source_files() const { + return makeArrayRef(SourceFiles); + } + + uint32_t calculateSerializedLength() const; + + void finalize(); + Error finalizeMsfLayout(); + + Error commit(BinaryStreamWriter &ModiWriter, const msf::MSFLayout &MsfLayout, + WritableBinaryStreamRef MsfBuffer); + +private: + void addSourceFile(StringRef Path); + msf::MSFBuilder &MSF; + + uint32_t SymbolByteSize = 0; + std::string ModuleName; + std::string ObjFileName; + std::vector<std::string> SourceFiles; + std::vector<codeview::CVSymbol> Symbols; + ModuleInfoHeader Layout; +}; + +} // end namespace pdb + +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_RAW_MODINFOBUILDER_H diff --git a/include/llvm/DebugInfo/PDB/Raw/ModStream.h b/include/llvm/DebugInfo/PDB/Native/ModStream.h index d5e7a6830d8d6..d65e195dbb95b 100644 --- a/include/llvm/DebugInfo/PDB/Raw/ModStream.h +++ b/include/llvm/DebugInfo/PDB/Native/ModStream.h @@ -15,8 +15,8 @@ #include "llvm/DebugInfo/CodeView/ModuleSubstream.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" -#include "llvm/DebugInfo/MSF/StreamArray.h" -#include "llvm/DebugInfo/MSF/StreamRef.h" +#include "llvm/Support/BinaryStreamArray.h" +#include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/Error.h" namespace llvm { @@ -50,9 +50,9 @@ private: std::unique_ptr<msf::MappedBlockStream> Stream; codeview::CVSymbolArray SymbolsSubstream; - msf::ReadableStreamRef LinesSubstream; - msf::ReadableStreamRef C13LinesSubstream; - msf::ReadableStreamRef GlobalRefsSubstream; + BinaryStreamRef LinesSubstream; + BinaryStreamRef C13LinesSubstream; + BinaryStreamRef GlobalRefsSubstream; codeview::ModuleSubstreamArray LineInfo; }; diff --git a/include/llvm/DebugInfo/PDB/Native/NamedStreamMap.h b/include/llvm/DebugInfo/PDB/Native/NamedStreamMap.h new file mode 100644 index 0000000000000..d4206503e7dca --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/NamedStreamMap.h @@ -0,0 +1,55 @@ +//===- NamedStreamMap.h - PDB Named Stream Map ------------------*- 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_PDB_RAW_PDBNAMEDSTREAMMAP_H +#define LLVM_DEBUGINFO_PDB_RAW_PDBNAMEDSTREAMMAP_H + +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/PDB/Native/HashTable.h" +#include "llvm/Support/Error.h" +#include <cstdint> + +namespace llvm { +class BinaryStreamReader; +class BinaryStreamWriter; + +namespace pdb { +class NamedStreamMapBuilder; +class NamedStreamMap { + struct FinalizationInfo { + uint32_t StringDataBytes = 0; + uint32_t SerializedLength = 0; + }; + friend NamedStreamMapBuilder; + +public: + NamedStreamMap(); + + Error load(BinaryStreamReader &Stream); + Error commit(BinaryStreamWriter &Writer) const; + uint32_t finalize(); + + uint32_t size() const; + bool get(StringRef Stream, uint32_t &StreamNo) const; + void set(StringRef Stream, uint32_t StreamNo); + void remove(StringRef Stream); + + iterator_range<StringMapConstIterator<uint32_t>> entries() const; + +private: + Optional<FinalizationInfo> FinalizedInfo; + HashTable FinalizedHashTable; + StringMap<uint32_t> Mapping; +}; + +} // end namespace pdb +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_RAW_PDBNAMEDSTREAMMAP_H diff --git a/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h b/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h new file mode 100644 index 0000000000000..8eeaf3e0ea49b --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h @@ -0,0 +1,35 @@ +//===- NativeCompilandSymbol.h - native impl for compiland syms -*- 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_PDB_NATIVE_NATIVECOMPILANDSYMBOL_H +#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVECOMPILANDSYMBOL_H + +#include "llvm/DebugInfo/PDB/Native/ModInfo.h" +#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" + +namespace llvm { +namespace pdb { + +class NativeCompilandSymbol : public NativeRawSymbol { +public: + NativeCompilandSymbol(NativeSession &Session, const ModuleInfoEx &MI); + PDB_SymType getSymTag() const override; + bool isEditAndContinueEnabled() const override; + uint32_t getLexicalParentId() const override; + std::string getLibraryName() const override; + std::string getName() const override; + +private: + ModuleInfoEx Module; +}; + +} // namespace pdb +} // namespace llvm + +#endif diff --git a/include/llvm/DebugInfo/PDB/Native/NativeEnumModules.h b/include/llvm/DebugInfo/PDB/Native/NativeEnumModules.h new file mode 100644 index 0000000000000..60a55ee50cc48 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/NativeEnumModules.h @@ -0,0 +1,41 @@ +//==- NativeEnumModules.h - Native Module Enumerator impl --------*- 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_PDB_NATIVE_NATIVEENUMMODULES_H +#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMMODULES_H + +#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" +#include "llvm/DebugInfo/PDB/Native/ModInfo.h" +#include "llvm/DebugInfo/PDB/PDBSymbol.h" +namespace llvm { +namespace pdb { + +class NativeSession; + +class NativeEnumModules : public IPDBEnumChildren<PDBSymbol> { +public: + explicit NativeEnumModules(NativeSession &Session, + ArrayRef<ModuleInfoEx> Modules, + uint32_t Index = 0); + + uint32_t getChildCount() const override; + std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override; + std::unique_ptr<PDBSymbol> getNext() override; + void reset() override; + NativeEnumModules *clone() const override; + +private: + NativeSession &Session; + ArrayRef<ModuleInfoEx> Modules; + uint32_t Index; +}; +} +} + +#endif diff --git a/include/llvm/DebugInfo/PDB/Native/NativeExeSymbol.h b/include/llvm/DebugInfo/PDB/Native/NativeExeSymbol.h new file mode 100644 index 0000000000000..9516810539b6b --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/NativeExeSymbol.h @@ -0,0 +1,39 @@ +//===- NativeExeSymbol.h - native impl for PDBSymbolExe ---------*- 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_PDB_NATIVE_NATIVEEXESYMBOL_H +#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEEXESYMBOL_H + +#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" +#include "llvm/DebugInfo/PDB/Native/NativeSession.h" + +namespace llvm { +namespace pdb { + +class NativeExeSymbol : public NativeRawSymbol { +public: + NativeExeSymbol(NativeSession &Session); + + std::unique_ptr<IPDBEnumSymbols> + findChildren(PDB_SymType Type) const override; + + uint32_t getAge() const override; + std::string getSymbolsFileName() const override; + PDB_UniqueId getGuid() const override; + bool hasCTypes() const override; + bool hasPrivateSymbols() const override; + +private: + PDBFile &File; +}; + +} // namespace pdb +} // namespace llvm + +#endif diff --git a/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h b/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h new file mode 100644 index 0000000000000..cffb5d09d225b --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h @@ -0,0 +1,208 @@ +//===- NativeRawSymbol.h - Native implementation of IPDBRawSymbol - 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_PDB_NATIVE_NATIVERAWSYMBOL_H +#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVERAWSYMBOL_H + +#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h" + +namespace llvm { +namespace pdb { + +class NativeSession; + +class NativeRawSymbol : public IPDBRawSymbol { +public: + explicit NativeRawSymbol(NativeSession &PDBSession); + + void dump(raw_ostream &OS, int Indent) const override; + + std::unique_ptr<IPDBEnumSymbols> + findChildren(PDB_SymType Type) const override; + std::unique_ptr<IPDBEnumSymbols> + findChildren(PDB_SymType Type, StringRef Name, + PDB_NameSearchFlags Flags) const override; + std::unique_ptr<IPDBEnumSymbols> + findChildrenByRVA(PDB_SymType Type, StringRef Name, PDB_NameSearchFlags Flags, + uint32_t RVA) const override; + std::unique_ptr<IPDBEnumSymbols> + findInlineFramesByRVA(uint32_t RVA) const override; + + void getDataBytes(llvm::SmallVector<uint8_t, 32> &Bytes) const override; + void getFrontEndVersion(VersionInfo &Version) const override; + void getBackEndVersion(VersionInfo &Version) const override; + PDB_MemberAccess getAccess() const override; + uint32_t getAddressOffset() const override; + uint32_t getAddressSection() const override; + uint32_t getAge() const override; + uint32_t getArrayIndexTypeId() const override; + uint32_t getBaseDataOffset() const override; + uint32_t getBaseDataSlot() const override; + uint32_t getBaseSymbolId() const override; + PDB_BuiltinType getBuiltinType() const override; + uint32_t getBitPosition() const override; + PDB_CallingConv getCallingConvention() const override; + uint32_t getClassParentId() const override; + std::string getCompilerName() const override; + uint32_t getCount() const override; + uint32_t getCountLiveRanges() const override; + PDB_Lang getLanguage() const override; + uint32_t getLexicalParentId() const override; + std::string getLibraryName() const override; + uint32_t getLiveRangeStartAddressOffset() const override; + uint32_t getLiveRangeStartAddressSection() const override; + uint32_t getLiveRangeStartRelativeVirtualAddress() const override; + codeview::RegisterId getLocalBasePointerRegisterId() const override; + uint32_t getLowerBoundId() const override; + uint32_t getMemorySpaceKind() const override; + std::string getName() const override; + uint32_t getNumberOfAcceleratorPointerTags() const override; + uint32_t getNumberOfColumns() const override; + uint32_t getNumberOfModifiers() const override; + uint32_t getNumberOfRegisterIndices() const override; + uint32_t getNumberOfRows() const override; + std::string getObjectFileName() const override; + uint32_t getOemId() const override; + uint32_t getOemSymbolId() const override; + uint32_t getOffsetInUdt() const override; + PDB_Cpu getPlatform() const override; + uint32_t getRank() const override; + codeview::RegisterId getRegisterId() const override; + uint32_t getRegisterType() const override; + uint32_t getRelativeVirtualAddress() const override; + uint32_t getSamplerSlot() const override; + uint32_t getSignature() const override; + uint32_t getSizeInUdt() const override; + uint32_t getSlot() const override; + std::string getSourceFileName() const override; + uint32_t getStride() const override; + uint32_t getSubTypeId() const override; + std::string getSymbolsFileName() const override; + uint32_t getSymIndexId() const override; + uint32_t getTargetOffset() const override; + uint32_t getTargetRelativeVirtualAddress() const override; + uint64_t getTargetVirtualAddress() const override; + uint32_t getTargetSection() const override; + uint32_t getTextureSlot() const override; + uint32_t getTimeStamp() const override; + uint32_t getToken() const override; + uint32_t getTypeId() const override; + uint32_t getUavSlot() const override; + std::string getUndecoratedName() const override; + uint32_t getUnmodifiedTypeId() const override; + uint32_t getUpperBoundId() const override; + Variant getValue() const override; + uint32_t getVirtualBaseDispIndex() const override; + uint32_t getVirtualBaseOffset() const override; + uint32_t getVirtualTableShapeId() const override; + std::unique_ptr<PDBSymbolTypeVTable> getVirtualBaseTableType() const override; + PDB_DataKind getDataKind() const override; + PDB_SymType getSymTag() const override; + PDB_UniqueId getGuid() const override; + int32_t getOffset() const override; + int32_t getThisAdjust() const override; + int32_t getVirtualBasePointerOffset() const override; + PDB_LocType getLocationType() const override; + PDB_Machine getMachineType() const override; + codeview::ThunkOrdinal getThunkOrdinal() const override; + uint64_t getLength() const override; + uint64_t getLiveRangeLength() const override; + uint64_t getVirtualAddress() const override; + PDB_UdtType getUdtKind() const override; + bool hasConstructor() const override; + bool hasCustomCallingConvention() const override; + bool hasFarReturn() const override; + bool isCode() const override; + bool isCompilerGenerated() const override; + bool isConstType() const override; + bool isEditAndContinueEnabled() const override; + bool isFunction() const override; + bool getAddressTaken() const override; + bool getNoStackOrdering() const override; + bool hasAlloca() const override; + bool hasAssignmentOperator() const override; + bool hasCTypes() const override; + bool hasCastOperator() const override; + bool hasDebugInfo() const override; + bool hasEH() const override; + bool hasEHa() const override; + bool hasInlAsm() const override; + bool hasInlineAttribute() const override; + bool hasInterruptReturn() const override; + bool hasFramePointer() const override; + bool hasLongJump() const override; + bool hasManagedCode() const override; + bool hasNestedTypes() const override; + bool hasNoInlineAttribute() const override; + bool hasNoReturnAttribute() const override; + bool hasOptimizedCodeDebugInfo() const override; + bool hasOverloadedOperator() const override; + bool hasSEH() const override; + bool hasSecurityChecks() const override; + bool hasSetJump() const override; + bool hasStrictGSCheck() const override; + bool isAcceleratorGroupSharedLocal() const override; + bool isAcceleratorPointerTagLiveRange() const override; + bool isAcceleratorStubFunction() const override; + bool isAggregated() const override; + bool isIntroVirtualFunction() const override; + bool isCVTCIL() const override; + bool isConstructorVirtualBase() const override; + bool isCxxReturnUdt() const override; + bool isDataAligned() const override; + bool isHLSLData() const override; + bool isHotpatchable() const override; + bool isIndirectVirtualBaseClass() const override; + bool isInterfaceUdt() const override; + bool isIntrinsic() const override; + bool isLTCG() const override; + bool isLocationControlFlowDependent() const override; + bool isMSILNetmodule() const override; + bool isMatrixRowMajor() const override; + bool isManagedCode() const override; + bool isMSILCode() const override; + bool isMultipleInheritance() const override; + bool isNaked() const override; + bool isNested() const override; + bool isOptimizedAway() const override; + bool isPacked() const override; + bool isPointerBasedOnSymbolValue() const override; + bool isPointerToDataMember() const override; + bool isPointerToMemberFunction() const override; + bool isPureVirtual() const override; + bool isRValueReference() const override; + bool isRefUdt() const override; + bool isReference() const override; + bool isRestrictedType() const override; + bool isReturnValue() const override; + bool isSafeBuffers() const override; + bool isScoped() const override; + bool isSdl() const override; + bool isSingleInheritance() const override; + bool isSplitted() const override; + bool isStatic() const override; + bool hasPrivateSymbols() const override; + bool isUnalignedType() const override; + bool isUnreached() const override; + bool isValueUdt() const override; + bool isVirtual() const override; + bool isVirtualBaseClass() const override; + bool isVirtualInheritance() const override; + bool isVolatileType() const override; + bool wasInlined() const override; + std::string getUnused() const override; + +protected: + NativeSession &Session; +}; + +} +} + +#endif diff --git a/include/llvm/DebugInfo/PDB/Raw/RawSession.h b/include/llvm/DebugInfo/PDB/Native/NativeSession.h index 5a6c469fcc8e8..e6da266f796d5 100644 --- a/include/llvm/DebugInfo/PDB/Raw/RawSession.h +++ b/include/llvm/DebugInfo/PDB/Native/NativeSession.h @@ -1,4 +1,4 @@ -//===- RawSession.h - Native implementation of IPDBSession ------*- C++ -*-===// +//===- NativeSession.h - Native implementation of IPDBSession ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -19,11 +19,11 @@ namespace llvm { namespace pdb { class PDBFile; -class RawSession : public IPDBSession { +class NativeSession : public IPDBSession { public: - RawSession(std::unique_ptr<PDBFile> PdbFile, - std::unique_ptr<BumpPtrAllocator> Allocator); - ~RawSession() override; + NativeSession(std::unique_ptr<PDBFile> PdbFile, + std::unique_ptr<BumpPtrAllocator> Allocator); + ~NativeSession() override; static Error createFromPdb(StringRef Path, std::unique_ptr<IPDBSession> &Session); diff --git a/include/llvm/DebugInfo/PDB/Raw/PDBFile.h b/include/llvm/DebugInfo/PDB/Native/PDBFile.h index 29f5b2163d83f..fbca62d6e9d93 100644 --- a/include/llvm/DebugInfo/PDB/Raw/PDBFile.h +++ b/include/llvm/DebugInfo/PDB/Native/PDBFile.h @@ -13,9 +13,8 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/DebugInfo/MSF/IMSFFile.h" #include "llvm/DebugInfo/MSF/MSFCommon.h" -#include "llvm/DebugInfo/MSF/StreamArray.h" -#include "llvm/DebugInfo/MSF/StreamInterface.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include "llvm/Support/MathExtras.h" @@ -24,6 +23,8 @@ namespace llvm { +class BinaryStream; + namespace msf { class MappedBlockStream; } @@ -32,7 +33,7 @@ namespace pdb { class DbiStream; class GlobalsStream; class InfoStream; -class NameHashTable; +class StringTable; class PDBFileBuilder; class PublicsStream; class SymbolStream; @@ -42,10 +43,13 @@ class PDBFile : public msf::IMSFFile { friend PDBFileBuilder; public: - PDBFile(std::unique_ptr<msf::ReadableStream> PdbFileBuffer, + PDBFile(StringRef Path, std::unique_ptr<BinaryStream> PdbFileBuffer, BumpPtrAllocator &Allocator); ~PDBFile() override; + StringRef getFileDirectory() const; + StringRef getFilePath() const; + uint32_t getFreeBlockMapBlock() const; uint32_t getUnknown1() const; @@ -77,7 +81,7 @@ public: } const msf::MSFLayout &getMsfLayout() const { return ContainerLayout; } - const msf::ReadableStream &getMsfBuffer() const { return *Buffer; } + BinaryStreamRef getMsfBuffer() const { return *Buffer; } ArrayRef<support::ulittle32_t> getDirectoryBlockArray() const; @@ -91,7 +95,7 @@ public: Expected<TpiStream &> getPDBIpiStream(); Expected<PublicsStream &> getPDBPublicsStream(); Expected<SymbolStream &> getPDBSymbolStream(); - Expected<NameHashTable &> getStringTable(); + Expected<StringTable &> getStringTable(); BumpPtrAllocator &getAllocator() { return Allocator; } @@ -104,14 +108,16 @@ public: bool hasPDBTpiStream() const; bool hasStringTable(); - private: - Expected<std::unique_ptr<msf::MappedBlockStream>> safelyCreateIndexedStream( - const msf::MSFLayout &Layout, const msf::ReadableStream &MsfData, - uint32_t StreamIndex) const; +private: + Expected<std::unique_ptr<msf::MappedBlockStream>> + safelyCreateIndexedStream(const msf::MSFLayout &Layout, + BinaryStreamRef MsfData, + uint32_t StreamIndex) const; + std::string FilePath; BumpPtrAllocator &Allocator; - std::unique_ptr<msf::ReadableStream> Buffer; + std::unique_ptr<BinaryStream> Buffer; std::vector<uint32_t> FpmPages; msf::MSFLayout ContainerLayout; @@ -125,7 +131,7 @@ public: std::unique_ptr<SymbolStream> Symbols; std::unique_ptr<msf::MappedBlockStream> DirectoryStream; std::unique_ptr<msf::MappedBlockStream> StringTableStream; - std::unique_ptr<NameHashTable> StringTable; + std::unique_ptr<StringTable> Strings; }; } } diff --git a/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h b/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h index 27fc4b53b6492..3898af5afc9e4 100644 --- a/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h @@ -13,8 +13,10 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/Optional.h" -#include "llvm/DebugInfo/PDB/Raw/PDBFile.h" -#include "llvm/DebugInfo/PDB/Raw/RawConstants.h" +#include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h" +#include "llvm/DebugInfo/PDB/Native/PDBFile.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" @@ -44,11 +46,13 @@ public: DbiStreamBuilder &getDbiBuilder(); TpiStreamBuilder &getTpiBuilder(); TpiStreamBuilder &getIpiBuilder(); + StringTableBuilder &getStringTableBuilder(); Error commit(StringRef Filename); private: - Expected<msf::MSFLayout> finalizeMsfLayout() const; + Error addNamedStream(StringRef Name, uint32_t Size); + Expected<msf::MSFLayout> finalizeMsfLayout(); BumpPtrAllocator &Allocator; @@ -57,6 +61,9 @@ private: std::unique_ptr<DbiStreamBuilder> Dbi; std::unique_ptr<TpiStreamBuilder> Tpi; std::unique_ptr<TpiStreamBuilder> Ipi; + + StringTableBuilder Strings; + NamedStreamMap NamedStreams; }; } } diff --git a/include/llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h b/include/llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h new file mode 100644 index 0000000000000..d965e1008e95a --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h @@ -0,0 +1,48 @@ +//===- PDBTypeServerHandler.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_PDB_PDBTYPESERVERHANDLER_H +#define LLVM_DEBUGINFO_PDB_PDBTYPESERVERHANDLER_H + +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" +#include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/CodeView/TypeServerHandler.h" +#include "llvm/DebugInfo/PDB/Native/NativeSession.h" +#include "llvm/DebugInfo/PDB/PDBTypes.h" + +#include <memory> +#include <string> + +namespace llvm { +namespace pdb { +class NativeSession; + +class PDBTypeServerHandler : public codeview::TypeServerHandler { +public: + PDBTypeServerHandler(bool RevisitAlways = false); + + void addSearchPath(StringRef Path); + Expected<bool> handle(codeview::TypeServer2Record &TS, + codeview::TypeVisitorCallbacks &Callbacks) override; + +private: + Expected<bool> handleInternal(PDBFile &File, + codeview::TypeVisitorCallbacks &Callbacks); + + bool RevisitAlways; + std::unique_ptr<NativeSession> Session; + SmallVector<SmallString<64>, 4> SearchPaths; +}; +} +} + +#endif diff --git a/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h b/include/llvm/DebugInfo/PDB/Native/PublicsStream.h index 577f2986ff240..4a541edd6a7b4 100644 --- a/include/llvm/DebugInfo/PDB/Raw/PublicsStream.h +++ b/include/llvm/DebugInfo/PDB/Native/PublicsStream.h @@ -12,11 +12,10 @@ #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" -#include "llvm/DebugInfo/MSF/StreamArray.h" +#include "llvm/DebugInfo/PDB/Native/RawConstants.h" +#include "llvm/DebugInfo/PDB/Native/RawTypes.h" #include "llvm/DebugInfo/PDB/PDBTypes.h" -#include "llvm/DebugInfo/PDB/Raw/RawConstants.h" -#include "llvm/DebugInfo/PDB/Raw/RawTypes.h" - +#include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/Error.h" namespace llvm { @@ -38,16 +37,16 @@ public: uint32_t getNumBuckets() const { return NumBuckets; } iterator_range<codeview::CVSymbolArray::Iterator> getSymbols(bool *HadError) const; - msf::FixedStreamArray<support::ulittle32_t> getHashBuckets() const { + FixedStreamArray<support::ulittle32_t> getHashBuckets() const { return HashBuckets; } - msf::FixedStreamArray<support::ulittle32_t> getAddressMap() const { + FixedStreamArray<support::ulittle32_t> getAddressMap() const { return AddressMap; } - msf::FixedStreamArray<support::ulittle32_t> getThunkMap() const { + FixedStreamArray<support::ulittle32_t> getThunkMap() const { return ThunkMap; } - msf::FixedStreamArray<SectionOffset> getSectionOffsets() const { + FixedStreamArray<SectionOffset> getSectionOffsets() const { return SectionOffsets; } @@ -59,11 +58,11 @@ private: std::unique_ptr<msf::MappedBlockStream> Stream; uint32_t NumBuckets = 0; ArrayRef<uint8_t> Bitmap; - msf::FixedStreamArray<PSHashRecord> HashRecords; - msf::FixedStreamArray<support::ulittle32_t> HashBuckets; - msf::FixedStreamArray<support::ulittle32_t> AddressMap; - msf::FixedStreamArray<support::ulittle32_t> ThunkMap; - msf::FixedStreamArray<SectionOffset> SectionOffsets; + FixedStreamArray<PSHashRecord> HashRecords; + FixedStreamArray<support::ulittle32_t> HashBuckets; + FixedStreamArray<support::ulittle32_t> AddressMap; + FixedStreamArray<support::ulittle32_t> ThunkMap; + FixedStreamArray<SectionOffset> SectionOffsets; const HeaderInfo *Header; const GSIHashHeader *HashHdr; diff --git a/include/llvm/DebugInfo/PDB/Raw/RawConstants.h b/include/llvm/DebugInfo/PDB/Native/RawConstants.h index af114ff524916..f5d4df8feb2ed 100644 --- a/include/llvm/DebugInfo/PDB/Raw/RawConstants.h +++ b/include/llvm/DebugInfo/PDB/Native/RawConstants.h @@ -10,6 +10,7 @@ #ifndef LLVM_DEBUGINFO_PDB_RAW_PDBRAWCONSTANTS_H #define LLVM_DEBUGINFO_PDB_RAW_PDBRAWCONSTANTS_H +#include "llvm/ADT/BitmaskEnum.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include <cstdint> @@ -32,6 +33,21 @@ enum PdbRaw_ImplVer : uint32_t { PdbImplVC140 = 20140508, }; +enum class PdbRaw_FeatureSig : uint32_t { + VC110 = PdbImplVC110, + VC140 = PdbImplVC140, + NoTypeMerge = 0x4D544F4E, + MinimalDebugInfo = 0x494E494D, +}; + +enum PdbRaw_Features : uint32_t { + PdbFeatureNone = 0x0, + PdbFeatureContainsIdStream = 0x1, + PdbFeatureMinimalDebugInfo = 0x2, + PdbFeatureNoTypeMerging = 0x4, + LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ PdbFeatureNoTypeMerging) +}; + enum PdbRaw_DbiVer : uint32_t { PdbDbiVC41 = 930803, PdbDbiV50 = 19960307, diff --git a/include/llvm/DebugInfo/PDB/Raw/RawError.h b/include/llvm/DebugInfo/PDB/Native/RawError.h index f96b8066bbe56..3624a7682e387 100644 --- a/include/llvm/DebugInfo/PDB/Raw/RawError.h +++ b/include/llvm/DebugInfo/PDB/Native/RawError.h @@ -28,6 +28,7 @@ enum class raw_error_code { duplicate_entry, no_entry, not_writable, + stream_too_long, invalid_tpi_hash, }; diff --git a/include/llvm/DebugInfo/PDB/Raw/RawTypes.h b/include/llvm/DebugInfo/PDB/Native/RawTypes.h index d404b3994dbce..1b2631efce70e 100644 --- a/include/llvm/DebugInfo/PDB/Raw/RawTypes.h +++ b/include/llvm/DebugInfo/PDB/Native/RawTypes.h @@ -266,6 +266,10 @@ struct PDB_UniqueId { uint8_t Guid[16]; }; +inline bool operator==(const PDB_UniqueId &LHS, const PDB_UniqueId &RHS) { + return 0 == ::memcmp(LHS.Guid, RHS.Guid, sizeof(LHS.Guid)); +} + // The header preceeding the global TPI stream. // This corresponds to `HDR` in PDB/dbi/tpi.h. struct TpiStreamHeader { @@ -302,6 +306,15 @@ struct InfoStreamHeader { PDB_UniqueId Guid; }; +/// The header preceeding the /names stream. +struct StringTableHeader { + support::ulittle32_t Signature; + support::ulittle32_t HashVersion; + support::ulittle32_t ByteSize; +}; + +const uint32_t StringTableSignature = 0xEFFEEFFE; + } // namespace pdb } // namespace llvm diff --git a/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h b/include/llvm/DebugInfo/PDB/Native/StringTable.h index 00d022d4d8e27..dd5e30e618270 100644 --- a/include/llvm/DebugInfo/PDB/Raw/NameHashTable.h +++ b/include/llvm/DebugInfo/PDB/Native/StringTable.h @@ -1,4 +1,4 @@ -//===- NameHashTable.h - PDB Name Hash Table --------------------*- C++ -*-===// +//===- StringTable.h - PDB String Table -------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,29 +7,30 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DEBUGINFO_PDB_RAW_NAMEHASHTABLE_H -#define LLVM_DEBUGINFO_PDB_RAW_NAMEHASHTABLE_H +#ifndef LLVM_DEBUGINFO_PDB_RAW_STRINGTABLE_H +#define LLVM_DEBUGINFO_PDB_RAW_STRINGTABLE_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" -#include "llvm/DebugInfo/MSF/StreamArray.h" -#include "llvm/DebugInfo/MSF/StreamRef.h" +#include "llvm/Support/BinaryStreamArray.h" +#include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include <cstdint> #include <vector> namespace llvm { -namespace msf { -class StreamReader; -} +class BinaryStreamReader; + namespace pdb { -class NameHashTable { +class StringTable { public: - NameHashTable(); + StringTable(); + + Error load(BinaryStreamReader &Stream); - Error load(msf::StreamReader &Stream); + uint32_t getByteSize() const; uint32_t getNameCount() const { return NameCount; } uint32_t getHashVersion() const { return HashVersion; } @@ -38,17 +39,18 @@ public: StringRef getStringForID(uint32_t ID) const; uint32_t getIDForString(StringRef Str) const; - msf::FixedStreamArray<support::ulittle32_t> name_ids() const; + FixedStreamArray<support::ulittle32_t> name_ids() const; private: - msf::ReadableStreamRef NamesBuffer; - msf::FixedStreamArray<support::ulittle32_t> IDs; - uint32_t Signature; - uint32_t HashVersion; - uint32_t NameCount; + BinaryStreamRef NamesBuffer; + FixedStreamArray<support::ulittle32_t> IDs; + uint32_t ByteSize = 0; + uint32_t Signature = 0; + uint32_t HashVersion = 0; + uint32_t NameCount = 0; }; } // end namespace pdb } // end namespace llvm -#endif // LLVM_DEBUGINFO_PDB_RAW_NAMEHASHTABLE_H +#endif // LLVM_DEBUGINFO_PDB_RAW_STRINGTABLE_H diff --git a/include/llvm/DebugInfo/PDB/Native/StringTableBuilder.h b/include/llvm/DebugInfo/PDB/Native/StringTableBuilder.h new file mode 100644 index 0000000000000..dd0f40b1978d8 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/StringTableBuilder.h @@ -0,0 +1,44 @@ +//===- 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 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 diff --git a/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h b/include/llvm/DebugInfo/PDB/Native/SymbolStream.h index 41d5e6ad64a0e..41d5e6ad64a0e 100644 --- a/include/llvm/DebugInfo/PDB/Raw/SymbolStream.h +++ b/include/llvm/DebugInfo/PDB/Native/SymbolStream.h diff --git a/include/llvm/DebugInfo/PDB/Raw/TpiHashing.h b/include/llvm/DebugInfo/PDB/Native/TpiHashing.h index 67a4952fcdfe2..dd2698c354a20 100644 --- a/include/llvm/DebugInfo/PDB/Raw/TpiHashing.h +++ b/include/llvm/DebugInfo/PDB/Native/TpiHashing.h @@ -15,8 +15,8 @@ #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" -#include "llvm/DebugInfo/MSF/StreamArray.h" -#include "llvm/DebugInfo/PDB/Raw/RawError.h" +#include "llvm/DebugInfo/PDB/Native/RawError.h" +#include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include <cstdint> @@ -57,7 +57,7 @@ private: class TpiHashVerifier : public codeview::TypeVisitorCallbacks { public: - TpiHashVerifier(msf::FixedStreamArray<support::ulittle32_t> &HashValues, + TpiHashVerifier(FixedStreamArray<support::ulittle32_t> &HashValues, uint32_t NumHashBuckets) : HashValues(HashValues), NumHashBuckets(NumHashBuckets) {} @@ -83,7 +83,7 @@ private: utohexstr(codeview::TypeIndex::FirstNonSimpleIndex + Index)); } - msf::FixedStreamArray<support::ulittle32_t> HashValues; + FixedStreamArray<support::ulittle32_t> HashValues; codeview::CVType RawRecord; uint32_t NumHashBuckets; uint32_t Index = -1; diff --git a/include/llvm/DebugInfo/PDB/Raw/TpiStream.h b/include/llvm/DebugInfo/PDB/Native/TpiStream.h index de21abe4c8172..62dde0ef08b76 100644 --- a/include/llvm/DebugInfo/PDB/Raw/TpiStream.h +++ b/include/llvm/DebugInfo/PDB/Native/TpiStream.h @@ -11,10 +11,11 @@ #define LLVM_DEBUGINFO_PDB_RAW_PDBTPISTREAM_H #include "llvm/DebugInfo/CodeView/TypeRecord.h" -#include "llvm/DebugInfo/MSF/StreamArray.h" +#include "llvm/DebugInfo/PDB/Native/HashTable.h" +#include "llvm/DebugInfo/PDB/Native/RawConstants.h" +#include "llvm/DebugInfo/PDB/Native/RawTypes.h" #include "llvm/DebugInfo/PDB/PDBTypes.h" -#include "llvm/DebugInfo/PDB/Raw/RawConstants.h" -#include "llvm/DebugInfo/PDB/Raw/RawTypes.h" +#include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Error.h" @@ -45,11 +46,11 @@ public: uint32_t getHashKeySize() const; uint32_t NumHashBuckets() const; - msf::FixedStreamArray<support::ulittle32_t> getHashValues() const; - msf::FixedStreamArray<TypeIndexOffset> getTypeIndexOffsets() const; - msf::FixedStreamArray<TypeIndexOffset> getHashAdjustments() const; + FixedStreamArray<support::ulittle32_t> getHashValues() const; + FixedStreamArray<TypeIndexOffset> getTypeIndexOffsets() const; + HashTable &getHashAdjusters(); - iterator_range<codeview::CVTypeArray::Iterator> types(bool *HadError) const; + codeview::CVTypeRange types(bool *HadError) const; Error commit(); @@ -61,10 +62,10 @@ private: codeview::CVTypeArray TypeRecords; - std::unique_ptr<msf::ReadableStream> HashStream; - msf::FixedStreamArray<support::ulittle32_t> HashValues; - msf::FixedStreamArray<TypeIndexOffset> TypeIndexOffsets; - msf::FixedStreamArray<TypeIndexOffset> HashAdjustments; + std::unique_ptr<BinaryStream> HashStream; + FixedStreamArray<support::ulittle32_t> HashValues; + FixedStreamArray<TypeIndexOffset> TypeIndexOffsets; + HashTable HashAdjusters; const TpiStreamHeader *Header; }; diff --git a/include/llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h b/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h index f9a642126f531..a29ed0b610d36 100644 --- a/include/llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h @@ -12,31 +12,33 @@ #include "llvm/ADT/Optional.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" -#include "llvm/DebugInfo/MSF/ByteStream.h" -#include "llvm/DebugInfo/MSF/SequencedItemStream.h" -#include "llvm/DebugInfo/PDB/Raw/RawConstants.h" +#include "llvm/DebugInfo/PDB/Native/RawConstants.h" +#include "llvm/DebugInfo/PDB/Native/RawTypes.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/BinaryByteStream.h" +#include "llvm/Support/BinaryItemStream.h" +#include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/Error.h" #include <vector> namespace llvm { -namespace codeview { -class TypeRecord; -} -namespace msf { -class ByteStream; -class MSFBuilder; -struct MSFLayout; -class ReadableStreamRef; -class WritableStream; +class BinaryByteStream; +class WritableBinaryStreamRef; -template <> struct SequencedItemTraits<llvm::codeview::CVType> { +template <> struct BinaryItemTraits<llvm::codeview::CVType> { static size_t length(const codeview::CVType &Item) { return Item.length(); } static ArrayRef<uint8_t> bytes(const codeview::CVType &Item) { return Item.data(); } }; + +namespace codeview { +class TypeRecord; +} +namespace msf { +class MSFBuilder; +struct MSFLayout; } namespace pdb { class PDBFile; @@ -52,26 +54,30 @@ public: TpiStreamBuilder &operator=(const TpiStreamBuilder &) = delete; void setVersionHeader(PdbRaw_TpiVer Version); - void addTypeRecord(const codeview::CVType &Record); + void addTypeRecord(ArrayRef<uint8_t> Type, Optional<uint32_t> Hash); Error finalizeMsfLayout(); - Error commit(const msf::MSFLayout &Layout, const msf::WritableStream &Buffer); + Error commit(const msf::MSFLayout &Layout, WritableBinaryStreamRef Buffer); - uint32_t calculateSerializedLength() const; + uint32_t calculateSerializedLength(); private: uint32_t calculateHashBufferSize() const; + uint32_t calculateIndexOffsetSize() const; Error finalize(); msf::MSFBuilder &Msf; BumpPtrAllocator &Allocator; + size_t TypeRecordBytes = 0; + Optional<PdbRaw_TpiVer> VerHeader; - std::vector<codeview::CVType> TypeRecords; - msf::SequencedItemStream<codeview::CVType> TypeRecordStream; + std::vector<ArrayRef<uint8_t>> TypeRecords; + std::vector<uint32_t> TypeHashes; + std::vector<TypeIndexOffset> TypeIndexOffsets; uint32_t HashStreamIndex = kInvalidStreamIndex; - std::unique_ptr<msf::ByteStream> HashValueStream; + std::unique_ptr<BinaryByteStream> HashValueStream; const TpiStreamHeader *Header; uint32_t Idx; diff --git a/include/llvm/DebugInfo/PDB/PDBExtras.h b/include/llvm/DebugInfo/PDB/PDBExtras.h index 5a7422d9e9e4a..fc5787556a6d1 100644 --- a/include/llvm/DebugInfo/PDB/PDBExtras.h +++ b/include/llvm/DebugInfo/PDB/PDBExtras.h @@ -30,8 +30,8 @@ raw_ostream &operator<<(raw_ostream &OS, const PDB_Checksum &Checksum); raw_ostream &operator<<(raw_ostream &OS, const PDB_Lang &Lang); raw_ostream &operator<<(raw_ostream &OS, const PDB_SymType &Tag); raw_ostream &operator<<(raw_ostream &OS, const PDB_MemberAccess &Access); +raw_ostream &operator<<(raw_ostream &OS, const PDB_UniqueId &Guid); raw_ostream &operator<<(raw_ostream &OS, const PDB_UdtType &Type); -raw_ostream &operator<<(raw_ostream &OS, const PDB_UniqueId &Id); raw_ostream &operator<<(raw_ostream &OS, const PDB_Machine &Machine); raw_ostream &operator<<(raw_ostream &OS, const Variant &Value); diff --git a/include/llvm/DebugInfo/PDB/PDBSymDumper.h b/include/llvm/DebugInfo/PDB/PDBSymDumper.h index 095c33cfe8b58..c976935c48e02 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymDumper.h +++ b/include/llvm/DebugInfo/PDB/PDBSymDumper.h @@ -54,6 +54,22 @@ public: virtual void dump(const PDBSymbolUnknown &Symbol); virtual void dump(const PDBSymbolUsingNamespace &Symbol); + virtual void dumpRight(const PDBSymbolTypeArray &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeBaseClass &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeBuiltin &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeCustom &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeDimension &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeEnum &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeFriend &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeFunctionArg &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeFunctionSig &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeManaged &Symbol) {} + virtual void dumpRight(const PDBSymbolTypePointer &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeTypedef &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeUDT &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeVTable &Symbol) {} + virtual void dumpRight(const PDBSymbolTypeVTableShape &Symbol) {} + private: bool RequireImpl; }; diff --git a/include/llvm/DebugInfo/PDB/PDBSymbol.h b/include/llvm/DebugInfo/PDB/PDBSymbol.h index bf51188065407..b114b7afb0b03 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbol.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbol.h @@ -22,6 +22,23 @@ return RawSymbol->MethodName(); \ } +#define FORWARD_CONCRETE_SYMBOL_ID_METHOD_WITH_NAME(ConcreteType, PrivateName, \ + PublicName) \ + auto PublicName##Id() const->decltype(RawSymbol->PrivateName##Id()) { \ + return RawSymbol->PrivateName##Id(); \ + } \ + std::unique_ptr<ConcreteType> PublicName() const { \ + uint32_t Id = PublicName##Id(); \ + return getConcreteSymbolByIdHelper<ConcreteType>(Id); \ + } + +#define FORWARD_SYMBOL_ID_METHOD_WITH_NAME(PrivateName, PublicName) \ + FORWARD_CONCRETE_SYMBOL_ID_METHOD_WITH_NAME(PDBSymbol, PrivateName, \ + PublicName) + +#define FORWARD_SYMBOL_ID_METHOD(MethodName) \ + FORWARD_SYMBOL_ID_METHOD_WITH_NAME(MethodName, MethodName) + namespace llvm { class StringRef; @@ -29,6 +46,7 @@ class raw_ostream; namespace pdb { class IPDBRawSymbol; +class IPDBSession; #define DECLARE_PDB_SYMBOL_CONCRETE_TYPE(TagValue) \ static const PDB_SymType Tag = TagValue; \ @@ -44,6 +62,7 @@ class PDBSymbol { protected: PDBSymbol(const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol); + PDBSymbol(PDBSymbol &Symbol); public: static std::unique_ptr<PDBSymbol> @@ -56,7 +75,14 @@ public: /// unknown properties, but individual implementations of PDBSymbol may /// override the behavior to only dump known fields. virtual void dump(PDBSymDumper &Dumper) const = 0; + + /// For certain PDBSymbolTypes, dumps additional information for the type that + /// normally goes on the right side of the symbol. + virtual void dumpRight(PDBSymDumper &Dumper) const {} + void defaultDump(raw_ostream &OS, int Indent) const; + void dumpProperties() const; + void dumpChildStats() const; PDB_SymType getSymTag() const; uint32_t getSymIndexId() const; @@ -66,6 +92,8 @@ public: return Enumerator->getNext(); } + std::unique_ptr<PDBSymbol> clone() const; + template <typename T> std::unique_ptr<ConcreteSymbolEnumerator<T>> findAllChildren() const { auto BaseIter = RawSymbol->findChildren(T::Tag); @@ -91,8 +119,15 @@ public: std::unique_ptr<IPDBEnumSymbols> getChildStats(TagStats &Stats) const; protected: + std::unique_ptr<PDBSymbol> getSymbolByIdHelper(uint32_t Id) const; + + template <typename ConcreteType> + std::unique_ptr<ConcreteType> getConcreteSymbolByIdHelper(uint32_t Id) const { + return unique_dyn_cast_or_null<ConcreteType>(getSymbolByIdHelper(Id)); + } + const IPDBSession &Session; - const std::unique_ptr<IPDBRawSymbol> RawSymbol; + std::unique_ptr<IPDBRawSymbol> RawSymbol; }; } // namespace llvm diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h b/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h index d0ff62ca7c3f5..d81da1eaa0237 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h @@ -30,7 +30,7 @@ public: FORWARD_SYMBOL_METHOD(getAddressOffset) FORWARD_SYMBOL_METHOD(getAddressSection) FORWARD_SYMBOL_METHOD(getLength) - FORWARD_SYMBOL_METHOD(getLexicalParentId) + FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(getLocationType) FORWARD_SYMBOL_METHOD(getName) FORWARD_SYMBOL_METHOD(getRelativeVirtualAddress) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h b/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h index f1983b3f7bf5b..26788017cf32e 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h @@ -29,7 +29,7 @@ public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(isEditAndContinueEnabled) - FORWARD_SYMBOL_METHOD(getLexicalParentId) + FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(getLibraryName) FORWARD_SYMBOL_METHOD(getName) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h b/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h index bb4a78f68e2f7..dba50c42cf818 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h @@ -46,7 +46,7 @@ public: FORWARD_SYMBOL_METHOD(isLTCG) FORWARD_SYMBOL_METHOD(isMSILNetmodule) FORWARD_SYMBOL_METHOD(getLanguage) - FORWARD_SYMBOL_METHOD(getLexicalParentId) + FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(getPlatform) FORWARD_SYMBOL_METHOD(getSourceFileName) }; diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h b/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h index a71a0ba2df589..7868f0459086b 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h @@ -26,7 +26,7 @@ public: void dump(PDBSymDumper &Dumper) const override; - FORWARD_SYMBOL_METHOD(getLexicalParentId) + FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(getName) std::string getValue() const; }; diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolData.h b/include/llvm/DebugInfo/PDB/PDBSymbolData.h index 36f32ab51c110..ad4285df4d44e 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolData.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolData.h @@ -26,8 +26,6 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Data) - std::unique_ptr<PDBSymbol> getType() const; - void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getAccess) @@ -35,14 +33,14 @@ public: FORWARD_SYMBOL_METHOD(getAddressSection) FORWARD_SYMBOL_METHOD(getAddressTaken) FORWARD_SYMBOL_METHOD(getBitPosition) - FORWARD_SYMBOL_METHOD(getClassParentId) + FORWARD_SYMBOL_ID_METHOD(getClassParent) FORWARD_SYMBOL_METHOD(isCompilerGenerated) FORWARD_SYMBOL_METHOD(isConstType) FORWARD_SYMBOL_METHOD(getDataKind) FORWARD_SYMBOL_METHOD(isAggregated) FORWARD_SYMBOL_METHOD(isSplitted) FORWARD_SYMBOL_METHOD(getLength) - FORWARD_SYMBOL_METHOD(getLexicalParentId) + FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(getLocationType) FORWARD_SYMBOL_METHOD(getName) FORWARD_SYMBOL_METHOD(getOffset) @@ -50,7 +48,7 @@ public: FORWARD_SYMBOL_METHOD(getRelativeVirtualAddress) FORWARD_SYMBOL_METHOD(getSlot) FORWARD_SYMBOL_METHOD(getToken) - FORWARD_SYMBOL_METHOD(getTypeId) + FORWARD_SYMBOL_ID_METHOD(getType) FORWARD_SYMBOL_METHOD(isUnalignedType) FORWARD_SYMBOL_METHOD(getValue) FORWARD_SYMBOL_METHOD(getVirtualAddress) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolExe.h b/include/llvm/DebugInfo/PDB/PDBSymbolExe.h index 5b3f50d153eb6..2c2d74665040e 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolExe.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolExe.h @@ -37,6 +37,8 @@ public: FORWARD_SYMBOL_METHOD(getSignature) FORWARD_SYMBOL_METHOD(getSymbolsFileName) + uint32_t getPointerByteSize() const; + private: void dumpChildren(raw_ostream &OS, StringRef Label, PDB_SymType ChildType, int Indent) const; diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h b/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h index 7170bcbe846c6..c2f02ea6f126c 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h @@ -11,6 +11,7 @@ #define LLVM_DEBUGINFO_PDB_PDBSYMBOLFUNC_H #include "PDBSymbol.h" +#include "PDBSymbolTypeFunctionSig.h" #include "PDBTypes.h" namespace llvm { @@ -26,8 +27,8 @@ public: void dump(PDBSymDumper &Dumper) const override; - std::unique_ptr<PDBSymbolTypeFunctionSig> getSignature() const; - std::unique_ptr<PDBSymbolTypeUDT> getClassParent() const; + bool isDestructor() const; + std::unique_ptr<IPDBEnumChildren<PDBSymbolData>> getArguments() const; DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Function) @@ -35,7 +36,7 @@ public: FORWARD_SYMBOL_METHOD(getAccess) FORWARD_SYMBOL_METHOD(getAddressOffset) FORWARD_SYMBOL_METHOD(getAddressSection) - FORWARD_SYMBOL_METHOD(getClassParentId) + FORWARD_SYMBOL_ID_METHOD(getClassParent) FORWARD_SYMBOL_METHOD(isCompilerGenerated) FORWARD_SYMBOL_METHOD(isConstType) FORWARD_SYMBOL_METHOD(hasCustomCallingConvention) @@ -54,7 +55,7 @@ public: FORWARD_SYMBOL_METHOD(isNaked) FORWARD_SYMBOL_METHOD(isStatic) FORWARD_SYMBOL_METHOD(getLength) - FORWARD_SYMBOL_METHOD(getLexicalParentId) + FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(getLocalBasePointerRegisterId) FORWARD_SYMBOL_METHOD(getLocationType) FORWARD_SYMBOL_METHOD(getName) @@ -67,7 +68,8 @@ public: FORWARD_SYMBOL_METHOD(isPureVirtual) FORWARD_SYMBOL_METHOD(getRelativeVirtualAddress) FORWARD_SYMBOL_METHOD(getToken) - FORWARD_SYMBOL_METHOD(getTypeId) + FORWARD_CONCRETE_SYMBOL_ID_METHOD_WITH_NAME(PDBSymbolTypeFunctionSig, getType, + getSignature) FORWARD_SYMBOL_METHOD(isUnalignedType) FORWARD_SYMBOL_METHOD(getUndecoratedName) FORWARD_SYMBOL_METHOD(isVirtual) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h b/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h index 464389503bef2..3341bd9b30fd9 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h @@ -34,7 +34,7 @@ public: FORWARD_SYMBOL_METHOD(hasFarReturn) FORWARD_SYMBOL_METHOD(hasInterruptReturn) FORWARD_SYMBOL_METHOD(isStatic) - FORWARD_SYMBOL_METHOD(getLexicalParentId) + FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(getLocationType) FORWARD_SYMBOL_METHOD(hasNoInlineAttribute) FORWARD_SYMBOL_METHOD(hasNoReturnAttribute) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h b/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h index c2e3dd39be6cf..6729838597c88 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h @@ -33,7 +33,7 @@ public: FORWARD_SYMBOL_METHOD(hasFarReturn) FORWARD_SYMBOL_METHOD(hasInterruptReturn) FORWARD_SYMBOL_METHOD(isStatic) - FORWARD_SYMBOL_METHOD(getLexicalParentId) + FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(getLocationType) FORWARD_SYMBOL_METHOD(hasNoInlineAttribute) FORWARD_SYMBOL_METHOD(hasNoReturnAttribute) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h b/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h index 3aeae10b47bcd..c2b1c28c929ea 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h @@ -32,7 +32,7 @@ public: FORWARD_SYMBOL_METHOD(hasCustomCallingConvention) FORWARD_SYMBOL_METHOD(hasFarReturn) FORWARD_SYMBOL_METHOD(hasInterruptReturn) - FORWARD_SYMBOL_METHOD(getLexicalParentId) + FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(getLocationType) FORWARD_SYMBOL_METHOD(getName) FORWARD_SYMBOL_METHOD(hasNoInlineAttribute) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h b/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h index be0734445973f..c9e6ee67c575b 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h @@ -32,7 +32,7 @@ public: FORWARD_SYMBOL_METHOD(isCode) FORWARD_SYMBOL_METHOD(isFunction) FORWARD_SYMBOL_METHOD(getLength) - FORWARD_SYMBOL_METHOD(getLexicalParentId) + FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(getLocationType) FORWARD_SYMBOL_METHOD(isManagedCode) FORWARD_SYMBOL_METHOD(isMSILCode) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h b/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h index 63f7a09fc881d..614fad86caa84 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h @@ -30,12 +30,12 @@ public: FORWARD_SYMBOL_METHOD(getAccess) FORWARD_SYMBOL_METHOD(getAddressOffset) FORWARD_SYMBOL_METHOD(getAddressSection) - FORWARD_SYMBOL_METHOD(getClassParentId) + FORWARD_SYMBOL_ID_METHOD(getClassParent) FORWARD_SYMBOL_METHOD(isConstType) FORWARD_SYMBOL_METHOD(isIntroVirtualFunction) FORWARD_SYMBOL_METHOD(isStatic) FORWARD_SYMBOL_METHOD(getLength) - FORWARD_SYMBOL_METHOD(getLexicalParentId) + FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(getName) FORWARD_SYMBOL_METHOD(isPureVirtual) FORWARD_SYMBOL_METHOD(getRelativeVirtualAddress) @@ -44,7 +44,7 @@ public: FORWARD_SYMBOL_METHOD(getTargetVirtualAddress) FORWARD_SYMBOL_METHOD(getTargetSection) FORWARD_SYMBOL_METHOD(getThunkOrdinal) - FORWARD_SYMBOL_METHOD(getTypeId) + FORWARD_SYMBOL_ID_METHOD(getType) FORWARD_SYMBOL_METHOD(isUnalignedType) FORWARD_SYMBOL_METHOD(isVirtual) FORWARD_SYMBOL_METHOD(getVirtualAddress) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h index 57db03661fb7e..39b7d3b300ea0 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h @@ -25,17 +25,16 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::ArrayType) - std::unique_ptr<PDBSymbol> getElementType() const; - void dump(PDBSymDumper &Dumper) const override; + void dumpRight(PDBSymDumper &Dumper) const override; - FORWARD_SYMBOL_METHOD(getArrayIndexTypeId) + FORWARD_SYMBOL_ID_METHOD(getArrayIndexType) FORWARD_SYMBOL_METHOD(isConstType) FORWARD_SYMBOL_METHOD(getCount) FORWARD_SYMBOL_METHOD(getLength) - FORWARD_SYMBOL_METHOD(getLexicalParentId) + FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(getRank) - FORWARD_SYMBOL_METHOD(getTypeId) + FORWARD_SYMBOL_ID_METHOD_WITH_NAME(getType, getElementType) FORWARD_SYMBOL_METHOD(isUnalignedType) FORWARD_SYMBOL_METHOD(isVolatileType) }; diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h index aaa3ab7988d71..d607a3d811702 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h @@ -13,6 +13,9 @@ #include "PDBSymbol.h" #include "PDBTypes.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h" + namespace llvm { class raw_ostream; @@ -28,7 +31,7 @@ public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getAccess) - FORWARD_SYMBOL_METHOD(getClassParentId) + FORWARD_SYMBOL_ID_METHOD(getClassParent) FORWARD_SYMBOL_METHOD(hasConstructor) FORWARD_SYMBOL_METHOD(isConstType) FORWARD_SYMBOL_METHOD(hasAssignmentOperator) @@ -36,14 +39,14 @@ public: FORWARD_SYMBOL_METHOD(hasNestedTypes) FORWARD_SYMBOL_METHOD(isIndirectVirtualBaseClass) FORWARD_SYMBOL_METHOD(getLength) - FORWARD_SYMBOL_METHOD(getLexicalParentId) + FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(getName) FORWARD_SYMBOL_METHOD(isNested) FORWARD_SYMBOL_METHOD(getOffset) FORWARD_SYMBOL_METHOD(hasOverloadedOperator) FORWARD_SYMBOL_METHOD(isPacked) FORWARD_SYMBOL_METHOD(isScoped) - FORWARD_SYMBOL_METHOD(getTypeId) + FORWARD_SYMBOL_ID_METHOD(getType) FORWARD_SYMBOL_METHOD(getUdtKind) FORWARD_SYMBOL_METHOD(isUnalignedType) @@ -51,7 +54,7 @@ public: FORWARD_SYMBOL_METHOD(getVirtualBaseDispIndex) FORWARD_SYMBOL_METHOD(getVirtualBasePointerOffset) // FORWARD_SYMBOL_METHOD(getVirtualBaseTableType) - FORWARD_SYMBOL_METHOD(getVirtualTableShapeId) + FORWARD_SYMBOL_ID_METHOD(getVirtualTableShape) FORWARD_SYMBOL_METHOD(isVolatileType) }; diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h index c8f59f1f140a1..5b1863c42a04b 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h @@ -30,7 +30,7 @@ public: FORWARD_SYMBOL_METHOD(getBuiltinType) FORWARD_SYMBOL_METHOD(isConstType) FORWARD_SYMBOL_METHOD(getLength) - FORWARD_SYMBOL_METHOD(getLexicalParentId) + FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(isUnalignedType) FORWARD_SYMBOL_METHOD(isVolatileType) }; diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h index ade2887bac14b..c5ae3c51162c6 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h @@ -11,6 +11,7 @@ #define LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPEENUM_H #include "PDBSymbol.h" +#include "PDBSymbolTypeBuiltin.h" #include "PDBTypes.h" namespace llvm { @@ -27,25 +28,22 @@ public: void dump(PDBSymDumper &Dumper) const override; - std::unique_ptr<PDBSymbolTypeUDT> getClassParent() const; - std::unique_ptr<PDBSymbolTypeBuiltin> getUnderlyingType() const; - FORWARD_SYMBOL_METHOD(getBuiltinType) - FORWARD_SYMBOL_METHOD(getClassParentId) - FORWARD_SYMBOL_METHOD(getUnmodifiedTypeId) + FORWARD_SYMBOL_ID_METHOD(getClassParent) FORWARD_SYMBOL_METHOD(hasConstructor) FORWARD_SYMBOL_METHOD(isConstType) FORWARD_SYMBOL_METHOD(hasAssignmentOperator) FORWARD_SYMBOL_METHOD(hasCastOperator) FORWARD_SYMBOL_METHOD(hasNestedTypes) FORWARD_SYMBOL_METHOD(getLength) - FORWARD_SYMBOL_METHOD(getLexicalParentId) + FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(getName) FORWARD_SYMBOL_METHOD(isNested) FORWARD_SYMBOL_METHOD(hasOverloadedOperator) FORWARD_SYMBOL_METHOD(isPacked) FORWARD_SYMBOL_METHOD(isScoped) - FORWARD_SYMBOL_METHOD(getTypeId) + FORWARD_CONCRETE_SYMBOL_ID_METHOD_WITH_NAME(PDBSymbolTypeBuiltin, getType, + getUnderlyingType) FORWARD_SYMBOL_METHOD(isUnalignedType) FORWARD_SYMBOL_METHOD(isVolatileType) }; diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h index 196d149ed2a20..24c13128111f7 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h @@ -27,9 +27,9 @@ public: void dump(PDBSymDumper &Dumper) const override; - FORWARD_SYMBOL_METHOD(getClassParentId) + FORWARD_SYMBOL_ID_METHOD(getClassParent) FORWARD_SYMBOL_METHOD(getName) - FORWARD_SYMBOL_METHOD(getTypeId) + FORWARD_SYMBOL_ID_METHOD(getType) }; } // namespace llvm diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h index 5561341d7e777..3855999c473f5 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h @@ -27,9 +27,9 @@ public: void dump(PDBSymDumper &Dumper) const override; - FORWARD_SYMBOL_METHOD(getClassParentId) - FORWARD_SYMBOL_METHOD(getLexicalParentId) - FORWARD_SYMBOL_METHOD(getTypeId) + FORWARD_SYMBOL_ID_METHOD(getClassParent) + FORWARD_SYMBOL_ID_METHOD(getLexicalParent) + FORWARD_SYMBOL_ID_METHOD(getType) }; } // namespace llvm diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h index 516011ff8b3dc..8de54e70701dd 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h @@ -25,22 +25,21 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::FunctionSig) - std::unique_ptr<PDBSymbol> getReturnType() const; std::unique_ptr<IPDBEnumSymbols> getArguments() const; - std::unique_ptr<PDBSymbol> getClassParent() const; void dump(PDBSymDumper &Dumper) const override; + void dumpRight(PDBSymDumper &Dumper) const override; void dumpArgList(raw_ostream &OS) const; FORWARD_SYMBOL_METHOD(getCallingConvention) - FORWARD_SYMBOL_METHOD(getClassParentId) - FORWARD_SYMBOL_METHOD(getUnmodifiedTypeId) + FORWARD_SYMBOL_ID_METHOD(getClassParent) + FORWARD_SYMBOL_ID_METHOD(getUnmodifiedType) FORWARD_SYMBOL_METHOD(isConstType) FORWARD_SYMBOL_METHOD(getCount) - FORWARD_SYMBOL_METHOD(getLexicalParentId) + FORWARD_SYMBOL_ID_METHOD(getLexicalParent) // FORWARD_SYMBOL_METHOD(getObjectPointerType) FORWARD_SYMBOL_METHOD(getThisAdjust) - FORWARD_SYMBOL_METHOD(getTypeId) + FORWARD_SYMBOL_ID_METHOD_WITH_NAME(getType, getReturnType) FORWARD_SYMBOL_METHOD(isUnalignedType) FORWARD_SYMBOL_METHOD(isVolatileType) }; diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h index 7a57272adb791..c502d4e77afee 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h @@ -25,15 +25,14 @@ public: DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::PointerType) - std::unique_ptr<PDBSymbol> getPointeeType() const; - void dump(PDBSymDumper &Dumper) const override; + void dumpRight(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(isConstType) FORWARD_SYMBOL_METHOD(getLength) - FORWARD_SYMBOL_METHOD(getLexicalParentId) + FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(isReference) - FORWARD_SYMBOL_METHOD(getTypeId) + FORWARD_SYMBOL_ID_METHOD_WITH_NAME(getType, getPointeeType) FORWARD_SYMBOL_METHOD(isUnalignedType) FORWARD_SYMBOL_METHOD(isVolatileType) }; diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h index 5ed4f8d21d902..16c1d1b88c6d0 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h @@ -28,24 +28,24 @@ public: void dump(PDBSymDumper &Dumper) const override; FORWARD_SYMBOL_METHOD(getBuiltinType) - FORWARD_SYMBOL_METHOD(getClassParentId) + FORWARD_SYMBOL_ID_METHOD(getClassParent) FORWARD_SYMBOL_METHOD(hasConstructor) FORWARD_SYMBOL_METHOD(isConstType) FORWARD_SYMBOL_METHOD(hasAssignmentOperator) FORWARD_SYMBOL_METHOD(hasCastOperator) FORWARD_SYMBOL_METHOD(hasNestedTypes) FORWARD_SYMBOL_METHOD(getLength) - FORWARD_SYMBOL_METHOD(getLexicalParentId) + FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(getName) FORWARD_SYMBOL_METHOD(isNested) FORWARD_SYMBOL_METHOD(hasOverloadedOperator) FORWARD_SYMBOL_METHOD(isPacked) FORWARD_SYMBOL_METHOD(isReference) FORWARD_SYMBOL_METHOD(isScoped) - FORWARD_SYMBOL_METHOD(getTypeId) + FORWARD_SYMBOL_ID_METHOD(getType) FORWARD_SYMBOL_METHOD(getUdtKind) FORWARD_SYMBOL_METHOD(isUnalignedType) - FORWARD_SYMBOL_METHOD(getVirtualTableShapeId) + FORWARD_SYMBOL_ID_METHOD(getVirtualTableShape) FORWARD_SYMBOL_METHOD(isVolatileType) }; diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h index 1874dfef34f7f..e9e7fe8c9865c 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h @@ -10,7 +10,9 @@ #ifndef LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPEUDT_H #define LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPEUDT_H +#include "IPDBSession.h" #include "PDBSymbol.h" +#include "PDBSymbolTypeBaseClass.h" #include "PDBTypes.h" namespace llvm { @@ -18,24 +20,30 @@ namespace llvm { class raw_ostream; namespace pdb { + class PDBSymbolTypeUDT : public PDBSymbol { public: PDBSymbolTypeUDT(const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> UDTSymbol); + std::unique_ptr<PDBSymbolTypeUDT> clone() const { + return getSession().getConcreteSymbolById<PDBSymbolTypeUDT>( + getSymIndexId()); + } + DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::UDT) void dump(PDBSymDumper &Dumper) const override; - FORWARD_SYMBOL_METHOD(getClassParentId) - FORWARD_SYMBOL_METHOD(getUnmodifiedTypeId) + FORWARD_SYMBOL_ID_METHOD(getClassParent) + FORWARD_SYMBOL_ID_METHOD(getUnmodifiedType) FORWARD_SYMBOL_METHOD(hasConstructor) FORWARD_SYMBOL_METHOD(isConstType) FORWARD_SYMBOL_METHOD(hasAssignmentOperator) FORWARD_SYMBOL_METHOD(hasCastOperator) FORWARD_SYMBOL_METHOD(hasNestedTypes) FORWARD_SYMBOL_METHOD(getLength) - FORWARD_SYMBOL_METHOD(getLexicalParentId) + FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(getName) FORWARD_SYMBOL_METHOD(isNested) FORWARD_SYMBOL_METHOD(hasOverloadedOperator) @@ -43,7 +51,7 @@ public: FORWARD_SYMBOL_METHOD(isScoped) FORWARD_SYMBOL_METHOD(getUdtKind) FORWARD_SYMBOL_METHOD(isUnalignedType) - FORWARD_SYMBOL_METHOD(getVirtualTableShapeId) + FORWARD_SYMBOL_ID_METHOD(getVirtualTableShape) FORWARD_SYMBOL_METHOD(isVolatileType) }; } diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h index baf7ab79d60e6..e270c2b7eb952 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h @@ -27,10 +27,11 @@ public: void dump(PDBSymDumper &Dumper) const override; - FORWARD_SYMBOL_METHOD(getClassParentId) + FORWARD_SYMBOL_ID_METHOD(getClassParent) + FORWARD_SYMBOL_METHOD(getOffset) FORWARD_SYMBOL_METHOD(isConstType) - FORWARD_SYMBOL_METHOD(getLexicalParentId) - FORWARD_SYMBOL_METHOD(getTypeId) + FORWARD_SYMBOL_ID_METHOD(getLexicalParent) + FORWARD_SYMBOL_ID_METHOD(getType) FORWARD_SYMBOL_METHOD(isUnalignedType) FORWARD_SYMBOL_METHOD(isVolatileType) }; diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h index 431fc1ac86257..8acaabea5bb88 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h @@ -29,7 +29,7 @@ public: FORWARD_SYMBOL_METHOD(isConstType) FORWARD_SYMBOL_METHOD(getCount) - FORWARD_SYMBOL_METHOD(getLexicalParentId) + FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(isUnalignedType) FORWARD_SYMBOL_METHOD(isVolatileType) }; diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h b/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h index a273fe159c126..70fbd5b84c34e 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h @@ -27,7 +27,7 @@ public: void dump(PDBSymDumper &Dumper) const override; - FORWARD_SYMBOL_METHOD(getLexicalParentId) + FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(getName) }; diff --git a/include/llvm/DebugInfo/PDB/PDBTypes.h b/include/llvm/DebugInfo/PDB/PDBTypes.h index 0d232f15d7458..dd2fc4f2c55f7 100644 --- a/include/llvm/DebugInfo/PDB/PDBTypes.h +++ b/include/llvm/DebugInfo/PDB/PDBTypes.h @@ -12,7 +12,7 @@ #include "llvm/Config/llvm-config.h" #include "llvm/DebugInfo/CodeView/CodeView.h" -#include "llvm/DebugInfo/PDB/Raw/RawTypes.h" +#include "llvm/DebugInfo/PDB/Native/RawTypes.h" #include <cstdint> #include <cstring> #include <functional> @@ -68,10 +68,10 @@ class PDBSymbolTypeDimension; class PDBSymbolUnknown; /// Specifies which PDB reader implementation is to be used. Only a value -/// of PDB_ReaderType::DIA is supported. +/// of PDB_ReaderType::DIA is currently supported, but Native is in the works. enum class PDB_ReaderType { DIA = 0, - Raw = 1, + Native = 1, }; /// An enumeration indicating the type of data contained in this table. diff --git a/include/llvm/DebugInfo/PDB/Raw/NameMap.h b/include/llvm/DebugInfo/PDB/Raw/NameMap.h deleted file mode 100644 index de1163bc30797..0000000000000 --- a/include/llvm/DebugInfo/PDB/Raw/NameMap.h +++ /dev/null @@ -1,44 +0,0 @@ -//===- NameMap.h - PDB Name Map ---------------------------------*- 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_PDB_RAW_PDBNAMEMAP_H -#define LLVM_DEBUGINFO_PDB_RAW_PDBNAMEMAP_H - -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Error.h" -#include <cstdint> - -namespace llvm { -namespace msf { -class StreamReader; -class StreamWriter; -} -namespace pdb { -class NameMapBuilder; -class NameMap { - friend NameMapBuilder; - -public: - NameMap(); - - Error load(msf::StreamReader &Stream); - - bool tryGetValue(StringRef Name, uint32_t &Value) const; - - iterator_range<StringMapConstIterator<uint32_t>> entries() const; - -private: - StringMap<uint32_t> Mapping; -}; - -} // end namespace pdb -} // end namespace llvm - -#endif // LLVM_DEBUGINFO_PDB_RAW_PDBNAMEMAP_H diff --git a/include/llvm/DebugInfo/PDB/Raw/NameMapBuilder.h b/include/llvm/DebugInfo/PDB/Raw/NameMapBuilder.h deleted file mode 100644 index f5244ac21808f..0000000000000 --- a/include/llvm/DebugInfo/PDB/Raw/NameMapBuilder.h +++ /dev/null @@ -1,45 +0,0 @@ -//===- NameMapBuilder.h - PDB Name Map Builder ------------------*- 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_PDB_RAW_PDBNAMEMAPBUILDER_H -#define LLVM_DEBUGINFO_PDB_RAW_PDBNAMEMAPBUILDER_H - -#include "llvm/ADT/StringMap.h" -#include "llvm/Support/Error.h" - -#include <cstdint> -#include <memory> - -namespace llvm { -namespace msf { -class StreamWriter; -} -namespace pdb { -class NameMap; - -class NameMapBuilder { -public: - NameMapBuilder(); - - void addMapping(StringRef Name, uint32_t Mapping); - - Expected<std::unique_ptr<NameMap>> build(); - Error commit(msf::StreamWriter &Writer) const; - - uint32_t calculateSerializedLength() const; - -private: - StringMap<uint32_t> Map; - uint32_t StringDataBytes = 0; -}; - -} // end namespace pdb -} // end namespace llvm - -#endif // LLVM_DEBUGINFO_PDB_RAW_PDBNAMEMAPBUILDER_H diff --git a/include/llvm/DebugInfo/PDB/UDTLayout.h b/include/llvm/DebugInfo/PDB/UDTLayout.h new file mode 100644 index 0000000000000..e3dcba50bd1ae --- /dev/null +++ b/include/llvm/DebugInfo/PDB/UDTLayout.h @@ -0,0 +1,180 @@ +//===- UDTLayout.h - UDT layout info ----------------------------*- 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_PDB_UDTLAYOUT_H +#define LLVM_DEBUGINFO_PDB_UDTLAYOUT_H + +#include "PDBSymbol.h" +#include "PDBTypes.h" + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/BitVector.h" + +#include <list> +#include <memory> + +namespace llvm { + +class raw_ostream; + +namespace pdb { + +class PDBSymTypeBaseClass; +class PDBSymbolData; +class PDBSymbolTypeUDT; +class PDBSymbolTypeVTable; + +class ClassLayout; +class BaseClassLayout; +class StorageItemBase; +class UDTLayoutBase; + +class StorageItemBase { +public: + StorageItemBase(const UDTLayoutBase &Parent, const PDBSymbol &Symbol, + const std::string &Name, uint32_t OffsetInParent, + uint32_t Size); + virtual ~StorageItemBase() {} + + virtual uint32_t deepPaddingSize() const; + + const UDTLayoutBase &getParent() const { return Parent; } + StringRef getName() const { return Name; } + uint32_t getOffsetInParent() const { return OffsetInParent; } + uint32_t getSize() const { return SizeOf; } + const PDBSymbol &getSymbol() const { return Symbol; } + +protected: + const UDTLayoutBase &Parent; + const PDBSymbol &Symbol; + BitVector UsedBytes; + std::string Name; + uint32_t OffsetInParent = 0; + uint32_t SizeOf = 0; +}; + +class DataMemberLayoutItem : public StorageItemBase { +public: + DataMemberLayoutItem(const UDTLayoutBase &Parent, + std::unique_ptr<PDBSymbolData> DataMember); + + virtual uint32_t deepPaddingSize() const; + + const PDBSymbolData &getDataMember(); + bool hasUDTLayout() const; + const ClassLayout &getUDTLayout() const; + +private: + std::unique_ptr<PDBSymbolData> DataMember; + std::unique_ptr<ClassLayout> UdtLayout; +}; + +class VTableLayoutItem : public StorageItemBase { +public: + VTableLayoutItem(const UDTLayoutBase &Parent, + std::unique_ptr<PDBSymbolTypeVTable> VTable); + ArrayRef<PDBSymbolFunc *> funcs() const { return VTableFuncs; } + + uint32_t getElementSize() const { return ElementSize; } + + void setFunction(uint32_t Index, PDBSymbolFunc &Func) { + VTableFuncs[Index] = &Func; + } + +private: + uint32_t ElementSize = 0; + std::unique_ptr<PDBSymbolTypeVTableShape> Shape; + std::unique_ptr<PDBSymbolTypeVTable> VTable; + std::vector<PDBSymbolFunc *> VTableFuncs; +}; + +class UDTLayoutBase { + template <typename T> using UniquePtrVector = std::vector<std::unique_ptr<T>>; + +public: + UDTLayoutBase(const PDBSymbol &Symbol, const std::string &Name, + uint32_t Size); + + uint32_t shallowPaddingSize() const; + uint32_t deepPaddingSize() const; + + const BitVector &usedBytes() const { return UsedBytes; } + + uint32_t getClassSize() const { return SizeOf; } + + ArrayRef<std::unique_ptr<StorageItemBase>> layout_items() const { + return ChildStorage; + } + + VTableLayoutItem *findVTableAtOffset(uint32_t RelativeOffset); + + StringRef getUDTName() const { return Name; } + + ArrayRef<BaseClassLayout *> bases() const { return BaseClasses; } + ArrayRef<std::unique_ptr<PDBSymbolTypeBaseClass>> vbases() const { + return VirtualBases; + } + + ArrayRef<std::unique_ptr<PDBSymbolFunc>> funcs() const { return Funcs; } + + ArrayRef<std::unique_ptr<PDBSymbol>> other_items() const { return Other; } + + const PDBSymbol &getSymbolBase() const { return SymbolBase; } + +protected: + void initializeChildren(const PDBSymbol &Sym); + + void addChildToLayout(std::unique_ptr<StorageItemBase> Child); + void addVirtualOverride(PDBSymbolFunc &Func); + void addVirtualIntro(PDBSymbolFunc &Func); + + const PDBSymbol &SymbolBase; + std::string Name; + uint32_t SizeOf = 0; + + BitVector UsedBytes; + UniquePtrVector<PDBSymbol> Other; + UniquePtrVector<PDBSymbolFunc> Funcs; + UniquePtrVector<PDBSymbolTypeBaseClass> VirtualBases; + UniquePtrVector<StorageItemBase> ChildStorage; + std::vector<std::list<StorageItemBase *>> ChildrenPerByte; + std::vector<BaseClassLayout *> BaseClasses; + VTableLayoutItem *VTable = nullptr; +}; + +class ClassLayout : public UDTLayoutBase { +public: + explicit ClassLayout(const PDBSymbolTypeUDT &UDT); + explicit ClassLayout(std::unique_ptr<PDBSymbolTypeUDT> UDT); + + ClassLayout(ClassLayout &&Other) = default; + + const PDBSymbolTypeUDT &getClass() const { return UDT; } + +private: + std::unique_ptr<PDBSymbolTypeUDT> OwnedStorage; + const PDBSymbolTypeUDT &UDT; +}; + +class BaseClassLayout : public UDTLayoutBase, public StorageItemBase { +public: + BaseClassLayout(const UDTLayoutBase &Parent, + std::unique_ptr<PDBSymbolTypeBaseClass> Base); + + const PDBSymbolTypeBaseClass &getBase() const { return *Base; } + bool isVirtualBase() const { return IsVirtualBase; } + +private: + std::unique_ptr<PDBSymbolTypeBaseClass> Base; + bool IsVirtualBase; +}; +} +} // namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_UDTLAYOUT_H diff --git a/include/llvm/DebugInfo/Symbolize/DIPrinter.h b/include/llvm/DebugInfo/Symbolize/DIPrinter.h index 49f86eae01cf0..ab82be3706d83 100644 --- a/include/llvm/DebugInfo/Symbolize/DIPrinter.h +++ b/include/llvm/DebugInfo/Symbolize/DIPrinter.h @@ -29,15 +29,18 @@ class DIPrinter { bool PrintFunctionNames; bool PrintPretty; int PrintSourceContext; + bool Verbose; void print(const DILineInfo &Info, bool Inlined); void printContext(const std::string &FileName, int64_t Line); public: DIPrinter(raw_ostream &OS, bool PrintFunctionNames = true, - bool PrintPretty = false, int PrintSourceContext = 0) + bool PrintPretty = false, int PrintSourceContext = 0, + bool Verbose = false) : OS(OS), PrintFunctionNames(PrintFunctionNames), - PrintPretty(PrintPretty), PrintSourceContext(PrintSourceContext) {} + PrintPretty(PrintPretty), PrintSourceContext(PrintSourceContext), + Verbose(Verbose) {} DIPrinter &operator<<(const DILineInfo &Info); DIPrinter &operator<<(const DIInliningInfo &Info); |