diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-20 11:41:25 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-20 11:41:25 +0000 |
commit | d9484dd61cc151c4f34c31e07f693fefa66316b5 (patch) | |
tree | ab0560b3da293f1fafd3269c59692e929418f5c2 /contrib/llvm/lib/DebugInfo/CodeView | |
parent | 79e0962d4c3cf1f0acf359a9d69cb3ac68c414c4 (diff) | |
parent | d8e91e46262bc44006913e6796843909f1ac7bcd (diff) |
Merge llvm trunk r351319, resolve conflicts, and update FREEBSD-Xlist.
Notes
Notes:
svn path=/projects/clang800-import/; revision=343210
Diffstat (limited to 'contrib/llvm/lib/DebugInfo/CodeView')
14 files changed, 378 insertions, 83 deletions
diff --git a/contrib/llvm/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp b/contrib/llvm/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp index 44a67743169e..cbcaa5692828 100644 --- a/contrib/llvm/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp +++ b/contrib/llvm/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp @@ -75,7 +75,7 @@ Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols) { Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols, uint32_t InitialOffset) { for (auto I : Symbols) { - if (auto EC = visitSymbolRecord(I, InitialOffset)) + if (auto EC = visitSymbolRecord(I, InitialOffset + Symbols.skew())) return EC; InitialOffset += I.length(); } diff --git a/contrib/llvm/lib/DebugInfo/CodeView/CodeViewError.cpp b/contrib/llvm/lib/DebugInfo/CodeView/CodeViewError.cpp index 8de266b836b4..2a9753add311 100644 --- a/contrib/llvm/lib/DebugInfo/CodeView/CodeViewError.cpp +++ b/contrib/llvm/lib/DebugInfo/CodeView/CodeViewError.cpp @@ -14,25 +14,23 @@ using namespace llvm; using namespace llvm::codeview; -namespace { // FIXME: This class is only here to support the transition to llvm::Error. It // will be removed once this transition is complete. Clients should prefer to // deal with the Error value directly, rather than converting to error_code. class CodeViewErrorCategory : public std::error_category { public: const char *name() const noexcept override { return "llvm.codeview"; } - std::string message(int Condition) const override { switch (static_cast<cv_error_code>(Condition)) { case cv_error_code::unspecified: - return "An unknown error has occurred."; + return "An unknown CodeView error has occurred."; case cv_error_code::insufficient_buffer: return "The buffer is not large enough to read the requested number of " "bytes."; case cv_error_code::corrupt_record: return "The CodeView record is corrupted."; case cv_error_code::no_records: - return "There are no records"; + return "There are no records."; case cv_error_code::operation_unsupported: return "The requested operation is not supported."; case cv_error_code::unknown_member_record: @@ -41,31 +39,10 @@ public: llvm_unreachable("Unrecognized cv_error_code"); } }; -} // end anonymous namespace - -static ManagedStatic<CodeViewErrorCategory> Category; - -char CodeViewError::ID = 0; - -CodeViewError::CodeViewError(cv_error_code C) : CodeViewError(C, "") {} -CodeViewError::CodeViewError(const std::string &Context) - : CodeViewError(cv_error_code::unspecified, Context) {} - -CodeViewError::CodeViewError(cv_error_code C, const std::string &Context) - : Code(C) { - ErrMsg = "CodeView Error: "; - std::error_code EC = convertToErrorCode(); - if (Code != cv_error_code::unspecified) - ErrMsg += EC.message() + " "; - if (!Context.empty()) - ErrMsg += Context; +static llvm::ManagedStatic<CodeViewErrorCategory> CodeViewErrCategory; +const std::error_category &llvm::codeview::CVErrorCategory() { + return *CodeViewErrCategory; } -void CodeViewError::log(raw_ostream &OS) const { OS << ErrMsg << "\n"; } - -const std::string &CodeViewError::getErrorMessage() const { return ErrMsg; } - -std::error_code CodeViewError::convertToErrorCode() const { - return std::error_code(static_cast<int>(Code), *Category); -} +char CodeViewError::ID; diff --git a/contrib/llvm/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp b/contrib/llvm/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp index bf9dd7c86862..4001741f560a 100644 --- a/contrib/llvm/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp +++ b/contrib/llvm/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp @@ -79,7 +79,7 @@ Error DebugCrossModuleImportsSubsection::commit( for (const auto &M : Mappings) Ids.push_back(&M); - llvm::sort(Ids.begin(), Ids.end(), [this](const T &L1, const T &L2) { + llvm::sort(Ids, [this](const T &L1, const T &L2) { return Strings.getIdForString(L1->getKey()) < Strings.getIdForString(L2->getKey()); }); diff --git a/contrib/llvm/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp b/contrib/llvm/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp index fd558aa9cc8a..5881bf177a55 100644 --- a/contrib/llvm/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp +++ b/contrib/llvm/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp @@ -14,8 +14,11 @@ using namespace llvm; using namespace llvm::codeview; Error DebugFrameDataSubsectionRef::initialize(BinaryStreamReader Reader) { - if (auto EC = Reader.readObject(RelocPtr)) - return EC; + if (Reader.bytesRemaining() % sizeof(FrameData) != 0) { + if (auto EC = Reader.readObject(RelocPtr)) + return EC; + } + if (Reader.bytesRemaining() % sizeof(FrameData) != 0) return make_error<CodeViewError>(cv_error_code::corrupt_record, "Invalid frame data record format!"); @@ -26,15 +29,30 @@ Error DebugFrameDataSubsectionRef::initialize(BinaryStreamReader Reader) { return Error::success(); } +Error DebugFrameDataSubsectionRef::initialize(BinaryStreamRef Section) { + BinaryStreamReader Reader(Section); + return initialize(Reader); +} + uint32_t DebugFrameDataSubsection::calculateSerializedSize() const { - return 4 + sizeof(FrameData) * Frames.size(); + uint32_t Size = sizeof(FrameData) * Frames.size(); + if (IncludeRelocPtr) + Size += sizeof(uint32_t); + return Size; } Error DebugFrameDataSubsection::commit(BinaryStreamWriter &Writer) const { - if (auto EC = Writer.writeInteger<uint32_t>(0)) - return EC; - - if (auto EC = Writer.writeArray(makeArrayRef(Frames))) + if (IncludeRelocPtr) { + if (auto EC = Writer.writeInteger<uint32_t>(0)) + return EC; + } + + std::vector<FrameData> SortedFrames(Frames.begin(), Frames.end()); + std::sort(SortedFrames.begin(), SortedFrames.end(), + [](const FrameData &LHS, const FrameData &RHS) { + return LHS.RvaStart < RHS.RvaStart; + }); + if (auto EC = Writer.writeArray(makeArrayRef(SortedFrames))) return EC; return Error::success(); } diff --git a/contrib/llvm/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp b/contrib/llvm/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp index d2acc9a21003..9b251f5931b3 100644 --- a/contrib/llvm/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp +++ b/contrib/llvm/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp @@ -91,7 +91,7 @@ std::vector<uint32_t> DebugStringTableSubsection::sortedIds() const { Result.reserve(IdToString.size()); for (const auto &Entry : IdToString) Result.push_back(Entry.first); - llvm::sort(Result.begin(), Result.end()); + llvm::sort(Result); return Result; } diff --git a/contrib/llvm/lib/DebugInfo/CodeView/EnumTables.cpp b/contrib/llvm/lib/DebugInfo/CodeView/EnumTables.cpp index d8301cab1657..ef4e42f79ebc 100644 --- a/contrib/llvm/lib/DebugInfo/CodeView/EnumTables.cpp +++ b/contrib/llvm/lib/DebugInfo/CodeView/EnumTables.cpp @@ -200,6 +200,8 @@ static const EnumEntry<uint32_t> FrameProcSymFlagNames[] = { CV_ENUM_CLASS_ENT(FrameProcedureOptions, Inlined), CV_ENUM_CLASS_ENT(FrameProcedureOptions, StrictSecurityChecks), CV_ENUM_CLASS_ENT(FrameProcedureOptions, SafeBuffers), + CV_ENUM_CLASS_ENT(FrameProcedureOptions, EncodedLocalBasePointerMask), + CV_ENUM_CLASS_ENT(FrameProcedureOptions, EncodedParamBasePointerMask), CV_ENUM_CLASS_ENT(FrameProcedureOptions, ProfileGuidedOptimization), CV_ENUM_CLASS_ENT(FrameProcedureOptions, ValidProfileCounts), CV_ENUM_CLASS_ENT(FrameProcedureOptions, OptimizedForSpeed), diff --git a/contrib/llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp b/contrib/llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp index ca8007411cad..ddcad8c631d7 100644 --- a/contrib/llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp +++ b/contrib/llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp @@ -89,6 +89,8 @@ uint32_t LazyRandomTypeCollection::getOffsetOfType(TypeIndex Index) { } CVType LazyRandomTypeCollection::getType(TypeIndex Index) { + assert(!Index.isSimple()); + auto EC = ensureTypeExists(Index); error(std::move(EC)); assert(contains(Index)); @@ -97,6 +99,9 @@ CVType LazyRandomTypeCollection::getType(TypeIndex Index) { } Optional<CVType> LazyRandomTypeCollection::tryGetType(TypeIndex Index) { + if (Index.isSimple()) + return None; + if (auto EC = ensureTypeExists(Index)) { consumeError(std::move(EC)); return None; @@ -151,6 +156,7 @@ Error LazyRandomTypeCollection::ensureTypeExists(TypeIndex TI) { } void LazyRandomTypeCollection::ensureCapacityFor(TypeIndex Index) { + assert(!Index.isSimple()); uint32_t MinSize = Index.toArrayIndex() + 1; if (MinSize <= capacity()) @@ -163,6 +169,7 @@ void LazyRandomTypeCollection::ensureCapacityFor(TypeIndex Index) { } Error LazyRandomTypeCollection::visitRangeForType(TypeIndex TI) { + assert(!TI.isSimple()); if (PartialOffsets.empty()) return fullScanForType(TI); @@ -217,6 +224,7 @@ Optional<TypeIndex> LazyRandomTypeCollection::getNext(TypeIndex Prev) { } Error LazyRandomTypeCollection::fullScanForType(TypeIndex TI) { + assert(!TI.isSimple()); assert(PartialOffsets.empty()); TypeIndex CurrentTI = TypeIndex::fromArrayIndex(0); diff --git a/contrib/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp b/contrib/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp index f8bf961f22a1..04e0bab745d3 100644 --- a/contrib/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp +++ b/contrib/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp @@ -32,8 +32,8 @@ namespace { class CVSymbolDumperImpl : public SymbolVisitorCallbacks { public: CVSymbolDumperImpl(TypeCollection &Types, SymbolDumpDelegate *ObjDelegate, - ScopedPrinter &W, bool PrintRecordBytes) - : Types(Types), ObjDelegate(ObjDelegate), W(W), + ScopedPrinter &W, CPUType CPU, bool PrintRecordBytes) + : Types(Types), ObjDelegate(ObjDelegate), W(W), CompilationCPUType(CPU), PrintRecordBytes(PrintRecordBytes), InFunctionScope(false) {} /// CVSymbolVisitor overrides. @@ -46,6 +46,8 @@ public: Error visitSymbolEnd(CVSymbol &Record) override; Error visitUnknownSymbol(CVSymbol &Record) override; + CPUType getCompilationCPUType() const { return CompilationCPUType; } + private: void printLocalVariableAddrRange(const LocalVariableAddrRange &Range, uint32_t RelocationOffset); @@ -56,6 +58,9 @@ private: SymbolDumpDelegate *ObjDelegate; ScopedPrinter &W; + /// Save the machine or CPU type when dumping a compile symbols. + CPUType CompilationCPUType = CPUType::X64; + bool PrintRecordBytes; bool InFunctionScope; }; @@ -235,6 +240,7 @@ Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, W.printEnum("Language", Compile2.getLanguage(), getSourceLanguageNames()); W.printFlags("Flags", Compile2.getFlags(), getCompileSym2FlagNames()); W.printEnum("Machine", unsigned(Compile2.Machine), getCPUTypeNames()); + CompilationCPUType = Compile2.Machine; std::string FrontendVersion; { raw_string_ostream Out(FrontendVersion); @@ -255,9 +261,11 @@ Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, Compile3Sym &Compile3) { - W.printEnum("Language", Compile3.getLanguage(), getSourceLanguageNames()); - W.printFlags("Flags", Compile3.getFlags(), getCompileSym3FlagNames()); + W.printEnum("Language", uint8_t(Compile3.getLanguage()), getSourceLanguageNames()); + W.printFlags("Flags", uint32_t(Compile3.getFlags()), + getCompileSym3FlagNames()); W.printEnum("Machine", unsigned(Compile3.Machine), getCPUTypeNames()); + CompilationCPUType = Compile3.Machine; std::string FrontendVersion; { raw_string_ostream Out(FrontendVersion); @@ -415,6 +423,12 @@ Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, FrameProc.SectionIdOfExceptionHandler); W.printFlags("Flags", static_cast<uint32_t>(FrameProc.Flags), getFrameProcSymFlagNames()); + W.printEnum("LocalFramePtrReg", + uint16_t(FrameProc.getLocalFramePtrReg(CompilationCPUType)), + getRegisterNames()); + W.printEnum("ParamFramePtrReg", + uint16_t(FrameProc.getParamFramePtrReg(CompilationCPUType)), + getRegisterNames()); return Error::success(); } @@ -625,21 +639,27 @@ Error CVSymbolDumperImpl::visitUnknownSymbol(CVSymbol &CVR) { Error CVSymbolDumper::dump(CVRecord<SymbolKind> &Record) { SymbolVisitorCallbackPipeline Pipeline; SymbolDeserializer Deserializer(ObjDelegate.get(), Container); - CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, PrintRecordBytes); + CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, CompilationCPUType, + PrintRecordBytes); Pipeline.addCallbackToPipeline(Deserializer); Pipeline.addCallbackToPipeline(Dumper); CVSymbolVisitor Visitor(Pipeline); - return Visitor.visitSymbolRecord(Record); + auto Err = Visitor.visitSymbolRecord(Record); + CompilationCPUType = Dumper.getCompilationCPUType(); + return Err; } Error CVSymbolDumper::dump(const CVSymbolArray &Symbols) { SymbolVisitorCallbackPipeline Pipeline; SymbolDeserializer Deserializer(ObjDelegate.get(), Container); - CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, PrintRecordBytes); + CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, CompilationCPUType, + PrintRecordBytes); Pipeline.addCallbackToPipeline(Deserializer); Pipeline.addCallbackToPipeline(Dumper); CVSymbolVisitor Visitor(Pipeline); - return Visitor.visitSymbolStream(Symbols); + auto Err = Visitor.visitSymbolStream(Symbols); + CompilationCPUType = Dumper.getCompilationCPUType(); + return Err; } diff --git a/contrib/llvm/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp b/contrib/llvm/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp new file mode 100644 index 000000000000..01746138ad1f --- /dev/null +++ b/contrib/llvm/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp @@ -0,0 +1,94 @@ +//===- SymbolRecordHelpers.cpp ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h" + +#include "llvm/ADT/SmallVector.h" +#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" + +using namespace llvm; +using namespace llvm::codeview; + +template <typename RecordT> RecordT createRecord(const CVSymbol &sym) { + RecordT record(static_cast<SymbolRecordKind>(sym.kind())); + cantFail(SymbolDeserializer::deserializeAs<RecordT>(sym, record)); + return record; +} + +uint32_t llvm::codeview::getScopeEndOffset(const CVSymbol &Sym) { + assert(symbolOpensScope(Sym.kind())); + switch (Sym.kind()) { + case SymbolKind::S_GPROC32: + case SymbolKind::S_LPROC32: + case SymbolKind::S_GPROC32_ID: + case SymbolKind::S_LPROC32_ID: + case SymbolKind::S_LPROC32_DPC: + case SymbolKind::S_LPROC32_DPC_ID: { + ProcSym Proc = createRecord<ProcSym>(Sym); + return Proc.End; + } + case SymbolKind::S_BLOCK32: { + BlockSym Block = createRecord<BlockSym>(Sym); + return Block.End; + } + case SymbolKind::S_THUNK32: { + Thunk32Sym Thunk = createRecord<Thunk32Sym>(Sym); + return Thunk.End; + } + case SymbolKind::S_INLINESITE: { + InlineSiteSym Site = createRecord<InlineSiteSym>(Sym); + return Site.End; + } + default: + assert(false && "Unknown record type"); + return 0; + } +} + +uint32_t +llvm::codeview::getScopeParentOffset(const llvm::codeview::CVSymbol &Sym) { + assert(symbolOpensScope(Sym.kind())); + switch (Sym.kind()) { + case SymbolKind::S_GPROC32: + case SymbolKind::S_LPROC32: + case SymbolKind::S_GPROC32_ID: + case SymbolKind::S_LPROC32_ID: + case SymbolKind::S_LPROC32_DPC: + case SymbolKind::S_LPROC32_DPC_ID: { + ProcSym Proc = createRecord<ProcSym>(Sym); + return Proc.Parent; + } + case SymbolKind::S_BLOCK32: { + BlockSym Block = createRecord<BlockSym>(Sym); + return Block.Parent; + } + case SymbolKind::S_THUNK32: { + Thunk32Sym Thunk = createRecord<Thunk32Sym>(Sym); + return Thunk.Parent; + } + case SymbolKind::S_INLINESITE: { + InlineSiteSym Site = createRecord<InlineSiteSym>(Sym); + return Site.Parent; + } + default: + assert(false && "Unknown record type"); + return 0; + } +} + +CVSymbolArray +llvm::codeview::limitSymbolArrayToScope(const CVSymbolArray &Symbols, + uint32_t ScopeBegin) { + CVSymbol Opener = *Symbols.at(ScopeBegin); + assert(symbolOpensScope(Opener.kind())); + uint32_t EndOffset = getScopeEndOffset(Opener); + CVSymbol Closer = *Symbols.at(EndOffset); + EndOffset += Closer.RecordData.size(); + return Symbols.substream(ScopeBegin, EndOffset); +} diff --git a/contrib/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp b/contrib/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp index e77c8e8f02f5..2af8205cebc3 100644 --- a/contrib/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp +++ b/contrib/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp @@ -471,3 +471,77 @@ Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, return Error::success(); } + +RegisterId codeview::decodeFramePtrReg(EncodedFramePtrReg EncodedReg, + CPUType CPU) { + assert(unsigned(EncodedReg) < 4); + switch (CPU) { + // FIXME: Add ARM and AArch64 variants here. + default: + break; + case CPUType::Intel8080: + case CPUType::Intel8086: + case CPUType::Intel80286: + case CPUType::Intel80386: + case CPUType::Intel80486: + case CPUType::Pentium: + case CPUType::PentiumPro: + case CPUType::Pentium3: + switch (EncodedReg) { + case EncodedFramePtrReg::None: return RegisterId::NONE; + case EncodedFramePtrReg::StackPtr: return RegisterId::VFRAME; + case EncodedFramePtrReg::FramePtr: return RegisterId::EBP; + case EncodedFramePtrReg::BasePtr: return RegisterId::EBX; + } + llvm_unreachable("bad encoding"); + case CPUType::X64: + switch (EncodedReg) { + case EncodedFramePtrReg::None: return RegisterId::NONE; + case EncodedFramePtrReg::StackPtr: return RegisterId::RSP; + case EncodedFramePtrReg::FramePtr: return RegisterId::RBP; + case EncodedFramePtrReg::BasePtr: return RegisterId::R13; + } + llvm_unreachable("bad encoding"); + } + return RegisterId::NONE; +} + +EncodedFramePtrReg codeview::encodeFramePtrReg(RegisterId Reg, CPUType CPU) { + switch (CPU) { + // FIXME: Add ARM and AArch64 variants here. + default: + break; + case CPUType::Intel8080: + case CPUType::Intel8086: + case CPUType::Intel80286: + case CPUType::Intel80386: + case CPUType::Intel80486: + case CPUType::Pentium: + case CPUType::PentiumPro: + case CPUType::Pentium3: + switch (Reg) { + case RegisterId::VFRAME: + return EncodedFramePtrReg::StackPtr; + case RegisterId::EBP: + return EncodedFramePtrReg::FramePtr; + case RegisterId::EBX: + return EncodedFramePtrReg::BasePtr; + default: + break; + } + break; + case CPUType::X64: + switch (Reg) { + case RegisterId::RSP: + return EncodedFramePtrReg::StackPtr; + case RegisterId::RBP: + return EncodedFramePtrReg::FramePtr; + case RegisterId::R13: + return EncodedFramePtrReg::BasePtr; + default: + break; + } + break; + } + return EncodedFramePtrReg::None; +} diff --git a/contrib/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp b/contrib/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp index 7c68c9167c98..f5d3bea43a14 100644 --- a/contrib/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp +++ b/contrib/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp @@ -361,7 +361,6 @@ Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, TypeServer2Record &TS) { Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) { printTypeIndex("PointeeType", Ptr.getReferentType()); - W->printHex("PointerAttributes", uint32_t(Ptr.getOptions())); W->printEnum("PtrType", unsigned(Ptr.getPointerKind()), makeArrayRef(PtrKindNames)); W->printEnum("PtrMode", unsigned(Ptr.getMode()), makeArrayRef(PtrModeNames)); @@ -371,6 +370,8 @@ Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) { W->printNumber("IsVolatile", Ptr.isVolatile()); W->printNumber("IsUnaligned", Ptr.isUnaligned()); W->printNumber("IsRestrict", Ptr.isRestrict()); + W->printNumber("IsThisPtr&", Ptr.isLValueReferenceThisPtr()); + W->printNumber("IsThisPtr&&", Ptr.isRValueReferenceThisPtr()); W->printNumber("SizeOf", Ptr.getSize()); if (Ptr.isPointerToMember()) { diff --git a/contrib/llvm/lib/DebugInfo/CodeView/TypeIndex.cpp b/contrib/llvm/lib/DebugInfo/CodeView/TypeIndex.cpp index 24fe5fcb28d4..332d67470da5 100644 --- a/contrib/llvm/lib/DebugInfo/CodeView/TypeIndex.cpp +++ b/contrib/llvm/lib/DebugInfo/CodeView/TypeIndex.cpp @@ -74,6 +74,9 @@ StringRef TypeIndex::simpleTypeName(TypeIndex TI) { if (TI.isNoneType()) return "<no type>"; + if (TI == TypeIndex::NullptrT()) + return "std::nullptr_t"; + // This is a simple type. for (const auto &SimpleTypeName : SimpleTypeNames) { if (SimpleTypeName.Kind == TI.getSimpleKind()) { diff --git a/contrib/llvm/lib/DebugInfo/CodeView/TypeRecordHelpers.cpp b/contrib/llvm/lib/DebugInfo/CodeView/TypeRecordHelpers.cpp new file mode 100644 index 000000000000..2a66474cf5b6 --- /dev/null +++ b/contrib/llvm/lib/DebugInfo/CodeView/TypeRecordHelpers.cpp @@ -0,0 +1,53 @@ +//===- TypeRecordHelpers.cpp ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h" + +#include "llvm/ADT/SmallVector.h" +#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h" +#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" + +using namespace llvm; +using namespace llvm::codeview; + +template <typename RecordT> static ClassOptions getUdtOptions(CVType CVT) { + RecordT Record; + if (auto EC = TypeDeserializer::deserializeAs<RecordT>(CVT, Record)) { + consumeError(std::move(EC)); + return ClassOptions::None; + } + return Record.getOptions(); +} + +bool llvm::codeview::isUdtForwardRef(CVType CVT) { + ClassOptions UdtOptions = ClassOptions::None; + switch (CVT.kind()) { + case LF_STRUCTURE: + case LF_CLASS: + case LF_INTERFACE: + UdtOptions = getUdtOptions<ClassRecord>(std::move(CVT)); + break; + case LF_ENUM: + UdtOptions = getUdtOptions<EnumRecord>(std::move(CVT)); + break; + case LF_UNION: + UdtOptions = getUdtOptions<UnionRecord>(std::move(CVT)); + break; + default: + return false; + } + return (UdtOptions & ClassOptions::ForwardReference) != ClassOptions::None; +} + +TypeIndex llvm::codeview::getModifiedType(const CVType &CVT) { + assert(CVT.kind() == LF_MODIFIER); + SmallVector<TypeIndex, 1> Refs; + discoverTypeIndices(CVT, Refs); + return Refs.front(); +} diff --git a/contrib/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp b/contrib/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp index 2e29c9d7dfa0..bae11ce6a6a1 100644 --- a/contrib/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp +++ b/contrib/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp @@ -12,6 +12,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h" #include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h" +#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" @@ -63,7 +64,12 @@ class TypeStreamMerger { public: explicit TypeStreamMerger(SmallVectorImpl<TypeIndex> &SourceToDest) : IndexMap(SourceToDest) { - SourceToDest.clear(); + // When dealing with precompiled headers objects, all data in SourceToDest + // belongs to the precompiled headers object, and is assumed to be already + // remapped to the target PDB. Any forthcoming type that will be merged in + // might potentially back-reference this data. We also don't want to resolve + // twice the types in the precompiled object. + CurIndex += SourceToDest.size(); } static const TypeIndex Untranslated; @@ -71,7 +77,7 @@ public: // Local hashing entry points Error mergeTypesAndIds(MergingTypeTableBuilder &DestIds, MergingTypeTableBuilder &DestTypes, - const CVTypeArray &IdsAndTypes); + const CVTypeArray &IdsAndTypes, Optional<uint32_t> &S); Error mergeIdRecords(MergingTypeTableBuilder &Dest, ArrayRef<TypeIndex> TypeSourceToDest, const CVTypeArray &Ids); @@ -82,13 +88,15 @@ public: Error mergeTypesAndIds(GlobalTypeTableBuilder &DestIds, GlobalTypeTableBuilder &DestTypes, const CVTypeArray &IdsAndTypes, - ArrayRef<GloballyHashedType> Hashes); + ArrayRef<GloballyHashedType> Hashes, + Optional<uint32_t> &S); Error mergeIdRecords(GlobalTypeTableBuilder &Dest, ArrayRef<TypeIndex> TypeSourceToDest, const CVTypeArray &Ids, ArrayRef<GloballyHashedType> Hashes); Error mergeTypeRecords(GlobalTypeTableBuilder &Dest, const CVTypeArray &Types, - ArrayRef<GloballyHashedType> Hashes); + ArrayRef<GloballyHashedType> Hashes, + Optional<uint32_t> &S); private: Error doit(const CVTypeArray &Types); @@ -156,6 +164,8 @@ private: return llvm::make_error<CodeViewError>(cv_error_code::corrupt_record); } + Expected<bool> shouldRemapType(const CVType &Type); + Optional<Error> LastError; bool UseGlobalHashes = false; @@ -185,6 +195,8 @@ private: /// Temporary storage that we use to copy a record's data while re-writing /// its type indices. SmallVector<uint8_t, 256> RemapStorage; + + Optional<uint32_t> PCHSignature; }; } // end anonymous namespace @@ -261,22 +273,27 @@ Error TypeStreamMerger::mergeIdRecords(MergingTypeTableBuilder &Dest, Error TypeStreamMerger::mergeTypesAndIds(MergingTypeTableBuilder &DestIds, MergingTypeTableBuilder &DestTypes, - const CVTypeArray &IdsAndTypes) { + const CVTypeArray &IdsAndTypes, + Optional<uint32_t> &S) { DestIdStream = &DestIds; DestTypeStream = &DestTypes; UseGlobalHashes = false; - return doit(IdsAndTypes); + auto Err = doit(IdsAndTypes); + S = PCHSignature; + return Err; } // Global hashing entry points Error TypeStreamMerger::mergeTypeRecords(GlobalTypeTableBuilder &Dest, const CVTypeArray &Types, - ArrayRef<GloballyHashedType> Hashes) { + ArrayRef<GloballyHashedType> Hashes, + Optional<uint32_t> &S) { DestGlobalTypeStream = &Dest; UseGlobalHashes = true; GlobalHashes = Hashes; - - return doit(Types); + auto Err = doit(Types); + S = PCHSignature; + return Err; } Error TypeStreamMerger::mergeIdRecords(GlobalTypeTableBuilder &Dest, @@ -294,12 +311,15 @@ Error TypeStreamMerger::mergeIdRecords(GlobalTypeTableBuilder &Dest, Error TypeStreamMerger::mergeTypesAndIds(GlobalTypeTableBuilder &DestIds, GlobalTypeTableBuilder &DestTypes, const CVTypeArray &IdsAndTypes, - ArrayRef<GloballyHashedType> Hashes) { + ArrayRef<GloballyHashedType> Hashes, + Optional<uint32_t> &S) { DestGlobalIdStream = &DestIds; DestGlobalTypeStream = &DestTypes; UseGlobalHashes = true; GlobalHashes = Hashes; - return doit(IdsAndTypes); + auto Err = doit(IdsAndTypes); + S = PCHSignature; + return Err; } Error TypeStreamMerger::doit(const CVTypeArray &Types) { @@ -326,7 +346,7 @@ Error TypeStreamMerger::doit(const CVTypeArray &Types) { "second pass found more bad indices"); if (!LastError && NumBadIndices == BadIndicesRemaining) { return llvm::make_error<CodeViewError>( - cv_error_code::corrupt_record, "input type graph contains cycles"); + cv_error_code::corrupt_record, "Input type graph contains cycles"); } } @@ -345,25 +365,30 @@ Error TypeStreamMerger::remapAllTypes(const CVTypeArray &Types) { } Error TypeStreamMerger::remapType(const CVType &Type) { - auto DoSerialize = - [this, Type](MutableArrayRef<uint8_t> Storage) -> ArrayRef<uint8_t> { - return remapIndices(Type, Storage); - }; + auto R = shouldRemapType(Type); + if (!R) + return R.takeError(); TypeIndex DestIdx = Untranslated; - if (LLVM_LIKELY(UseGlobalHashes)) { - GlobalTypeTableBuilder &Dest = - isIdRecord(Type.kind()) ? *DestGlobalIdStream : *DestGlobalTypeStream; - GloballyHashedType H = GlobalHashes[CurIndex.toArrayIndex()]; - DestIdx = Dest.insertRecordAs(H, Type.RecordData.size(), DoSerialize); - } else { - MergingTypeTableBuilder &Dest = - isIdRecord(Type.kind()) ? *DestIdStream : *DestTypeStream; - - RemapStorage.resize(Type.RecordData.size()); - ArrayRef<uint8_t> Result = DoSerialize(RemapStorage); - if (!Result.empty()) - DestIdx = Dest.insertRecordBytes(Result); + if (*R) { + auto DoSerialize = + [this, Type](MutableArrayRef<uint8_t> Storage) -> ArrayRef<uint8_t> { + return remapIndices(Type, Storage); + }; + if (LLVM_LIKELY(UseGlobalHashes)) { + GlobalTypeTableBuilder &Dest = + isIdRecord(Type.kind()) ? *DestGlobalIdStream : *DestGlobalTypeStream; + GloballyHashedType H = GlobalHashes[CurIndex.toArrayIndex()]; + DestIdx = Dest.insertRecordAs(H, Type.RecordData.size(), DoSerialize); + } else { + MergingTypeTableBuilder &Dest = + isIdRecord(Type.kind()) ? *DestIdStream : *DestTypeStream; + + RemapStorage.resize(Type.RecordData.size()); + ArrayRef<uint8_t> Result = DoSerialize(RemapStorage); + if (!Result.empty()) + DestIdx = Dest.insertRecordBytes(Result); + } } addMapping(DestIdx); @@ -418,25 +443,28 @@ Error llvm::codeview::mergeIdRecords(MergingTypeTableBuilder &Dest, Error llvm::codeview::mergeTypeAndIdRecords( MergingTypeTableBuilder &DestIds, MergingTypeTableBuilder &DestTypes, - SmallVectorImpl<TypeIndex> &SourceToDest, const CVTypeArray &IdsAndTypes) { + SmallVectorImpl<TypeIndex> &SourceToDest, const CVTypeArray &IdsAndTypes, + Optional<uint32_t> &PCHSignature) { TypeStreamMerger M(SourceToDest); - return M.mergeTypesAndIds(DestIds, DestTypes, IdsAndTypes); + return M.mergeTypesAndIds(DestIds, DestTypes, IdsAndTypes, PCHSignature); } Error llvm::codeview::mergeTypeAndIdRecords( GlobalTypeTableBuilder &DestIds, GlobalTypeTableBuilder &DestTypes, SmallVectorImpl<TypeIndex> &SourceToDest, const CVTypeArray &IdsAndTypes, - ArrayRef<GloballyHashedType> Hashes) { + ArrayRef<GloballyHashedType> Hashes, Optional<uint32_t> &PCHSignature) { TypeStreamMerger M(SourceToDest); - return M.mergeTypesAndIds(DestIds, DestTypes, IdsAndTypes, Hashes); + return M.mergeTypesAndIds(DestIds, DestTypes, IdsAndTypes, Hashes, + PCHSignature); } Error llvm::codeview::mergeTypeRecords(GlobalTypeTableBuilder &Dest, SmallVectorImpl<TypeIndex> &SourceToDest, const CVTypeArray &Types, - ArrayRef<GloballyHashedType> Hashes) { + ArrayRef<GloballyHashedType> Hashes, + Optional<uint32_t> &PCHSignature) { TypeStreamMerger M(SourceToDest); - return M.mergeTypeRecords(Dest, Types, Hashes); + return M.mergeTypeRecords(Dest, Types, Hashes, PCHSignature); } Error llvm::codeview::mergeIdRecords(GlobalTypeTableBuilder &Dest, @@ -447,3 +475,20 @@ Error llvm::codeview::mergeIdRecords(GlobalTypeTableBuilder &Dest, TypeStreamMerger M(SourceToDest); return M.mergeIdRecords(Dest, Types, Ids, Hashes); } + +Expected<bool> TypeStreamMerger::shouldRemapType(const CVType &Type) { + // For object files containing precompiled types, we need to extract the + // signature, through EndPrecompRecord. This is done here for performance + // reasons, to avoid re-parsing the Types stream. + if (Type.kind() == LF_ENDPRECOMP) { + EndPrecompRecord EP; + if (auto EC = TypeDeserializer::deserializeAs(const_cast<CVType &>(Type), + EP)) + return joinErrors(std::move(EC), errorCorruptRecord()); + if (PCHSignature.hasValue()) + return errorCorruptRecord(); + PCHSignature.emplace(EP.getSignature()); + return false; + } + return true; +} |