aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/DebugInfo/CodeView
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-01-20 11:41:25 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-01-20 11:41:25 +0000
commitd9484dd61cc151c4f34c31e07f693fefa66316b5 (patch)
treeab0560b3da293f1fafd3269c59692e929418f5c2 /contrib/llvm/lib/DebugInfo/CodeView
parent79e0962d4c3cf1f0acf359a9d69cb3ac68c414c4 (diff)
parentd8e91e46262bc44006913e6796843909f1ac7bcd (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')
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp2
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/CodeViewError.cpp35
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp2
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp32
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp2
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/EnumTables.cpp2
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp8
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp36
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp94
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp74
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp3
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/TypeIndex.cpp3
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/TypeRecordHelpers.cpp53
-rw-r--r--contrib/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp115
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;
+}