summaryrefslogtreecommitdiff
path: root/lib/DebugInfo
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-01-19 10:01:25 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-01-19 10:01:25 +0000
commitd8e91e46262bc44006913e6796843909f1ac7bcd (patch)
tree7d0c143d9b38190e0fa0180805389da22cd834c5 /lib/DebugInfo
parentb7eb8e35e481a74962664b63dfb09483b200209a (diff)
Notes
Diffstat (limited to 'lib/DebugInfo')
-rw-r--r--lib/DebugInfo/CodeView/CMakeLists.txt4
-rw-r--r--lib/DebugInfo/CodeView/CVSymbolVisitor.cpp2
-rw-r--r--lib/DebugInfo/CodeView/CodeViewError.cpp35
-rw-r--r--lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp2
-rw-r--r--lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp32
-rw-r--r--lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp2
-rw-r--r--lib/DebugInfo/CodeView/EnumTables.cpp2
-rw-r--r--lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp8
-rw-r--r--lib/DebugInfo/CodeView/SymbolDumper.cpp36
-rw-r--r--lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp94
-rw-r--r--lib/DebugInfo/CodeView/SymbolRecordMapping.cpp74
-rw-r--r--lib/DebugInfo/CodeView/TypeDumpVisitor.cpp3
-rw-r--r--lib/DebugInfo/CodeView/TypeIndex.cpp3
-rw-r--r--lib/DebugInfo/CodeView/TypeRecordHelpers.cpp53
-rw-r--r--lib/DebugInfo/CodeView/TypeStreamMerger.cpp115
-rw-r--r--lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp54
-rw-r--r--lib/DebugInfo/DWARF/DWARFContext.cpp406
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugAddr.cpp2
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugAranges.cpp13
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugFrame.cpp34
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugLine.cpp59
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugLoc.cpp105
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp12
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp21
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp113
-rw-r--r--lib/DebugInfo/DWARF/DWARFDie.cpp167
-rw-r--r--lib/DebugInfo/DWARF/DWARFExpression.cpp1
-rw-r--r--lib/DebugInfo/DWARF/DWARFFormValue.cpp82
-rw-r--r--lib/DebugInfo/DWARF/DWARFGdbIndex.cpp23
-rw-r--r--lib/DebugInfo/DWARF/DWARFListTable.cpp34
-rw-r--r--lib/DebugInfo/DWARF/DWARFUnit.cpp350
-rw-r--r--lib/DebugInfo/DWARF/DWARFUnitIndex.cpp29
-rw-r--r--lib/DebugInfo/DWARF/DWARFVerifier.cpp342
-rw-r--r--lib/DebugInfo/MSF/MSFError.cpp30
-rw-r--r--lib/DebugInfo/PDB/CMakeLists.txt15
-rw-r--r--lib/DebugInfo/PDB/DIA/DIADataStream.cpp22
-rw-r--r--lib/DebugInfo/PDB/DIA/DIAEnumDebugStreams.cpp7
-rw-r--r--lib/DebugInfo/PDB/DIA/DIAEnumFrameData.cpp42
-rw-r--r--lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp10
-rw-r--r--lib/DebugInfo/PDB/DIA/DIAEnumLineNumbers.cpp7
-rw-r--r--lib/DebugInfo/PDB/DIA/DIAEnumSectionContribs.cpp7
-rw-r--r--lib/DebugInfo/PDB/DIA/DIAEnumSourceFiles.cpp7
-rw-r--r--lib/DebugInfo/PDB/DIA/DIAEnumSymbols.cpp7
-rw-r--r--lib/DebugInfo/PDB/DIA/DIAEnumTables.cpp12
-rw-r--r--lib/DebugInfo/PDB/DIA/DIAError.cpp31
-rw-r--r--lib/DebugInfo/PDB/DIA/DIAFrameData.cpp53
-rw-r--r--lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp464
-rw-r--r--lib/DebugInfo/PDB/DIA/DIASectionContrib.cpp2
-rw-r--r--lib/DebugInfo/PDB/DIA/DIASession.cpp25
-rw-r--r--lib/DebugInfo/PDB/DIA/DIASourceFile.cpp14
-rw-r--r--lib/DebugInfo/PDB/DIA/DIATable.cpp17
-rw-r--r--lib/DebugInfo/PDB/GenericError.cpp55
-rw-r--r--lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp32
-rw-r--r--lib/DebugInfo/PDB/Native/DbiStream.cpp2
-rw-r--r--lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp45
-rw-r--r--lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp53
-rw-r--r--lib/DebugInfo/PDB/Native/GlobalsStream.cpp68
-rw-r--r--lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp11
-rw-r--r--lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp20
-rw-r--r--lib/DebugInfo/PDB/Native/NativeBuiltinSymbol.cpp47
-rw-r--r--lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp19
-rw-r--r--lib/DebugInfo/PDB/Native/NativeEnumGlobals.cpp55
-rw-r--r--lib/DebugInfo/PDB/Native/NativeEnumModules.cpp23
-rw-r--r--lib/DebugInfo/PDB/Native/NativeEnumSymbol.cpp108
-rw-r--r--lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp62
-rw-r--r--lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp60
-rw-r--r--lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp96
-rw-r--r--lib/DebugInfo/PDB/Native/NativeSession.cpp140
-rw-r--r--lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp123
-rw-r--r--lib/DebugInfo/PDB/Native/NativeTypeArray.cpp67
-rw-r--r--lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp47
-rw-r--r--lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp382
-rw-r--r--lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp200
-rw-r--r--lib/DebugInfo/PDB/Native/NativeTypePointer.cpp194
-rw-r--r--lib/DebugInfo/PDB/Native/NativeTypeTypedef.cpp27
-rw-r--r--lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp221
-rw-r--r--lib/DebugInfo/PDB/Native/NativeTypeVTShape.cpp35
-rw-r--r--lib/DebugInfo/PDB/Native/PDBFile.cpp6
-rw-r--r--lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp34
-rw-r--r--lib/DebugInfo/PDB/Native/RawError.cpp30
-rw-r--r--lib/DebugInfo/PDB/Native/SymbolCache.cpp299
-rw-r--r--lib/DebugInfo/PDB/Native/TpiHashing.cpp43
-rw-r--r--lib/DebugInfo/PDB/Native/TpiStream.cpp85
-rw-r--r--lib/DebugInfo/PDB/PDB.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBExtras.cpp43
-rw-r--r--lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp3
-rw-r--r--lib/DebugInfo/PDB/PDBSymbol.cpp77
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolBlock.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolCompiland.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolCustom.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolData.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolExe.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolFunc.cpp10
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolLabel.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolThunk.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp7
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp11
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp6
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolUnknown.cpp4
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp6
-rw-r--r--lib/DebugInfo/Symbolize/Symbolize.cpp3
119 files changed, 4271 insertions, 1828 deletions
diff --git a/lib/DebugInfo/CodeView/CMakeLists.txt b/lib/DebugInfo/CodeView/CMakeLists.txt
index 0515788d85ef..1610ca469575 100644
--- a/lib/DebugInfo/CodeView/CMakeLists.txt
+++ b/lib/DebugInfo/CodeView/CMakeLists.txt
@@ -27,13 +27,15 @@ add_llvm_library(LLVMDebugInfoCodeView
RecordSerialization.cpp
SimpleTypeSerializer.cpp
StringsAndChecksums.cpp
- SymbolRecordMapping.cpp
SymbolDumper.cpp
+ SymbolRecordHelpers.cpp
+ SymbolRecordMapping.cpp
SymbolSerializer.cpp
TypeDumpVisitor.cpp
TypeIndex.cpp
TypeIndexDiscovery.cpp
TypeHashing.cpp
+ TypeRecordHelpers.cpp
TypeRecordMapping.cpp
TypeStreamMerger.cpp
TypeTableCollection.cpp
diff --git a/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp b/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp
index 44a67743169e..cbcaa5692828 100644
--- a/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp
+++ b/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/lib/DebugInfo/CodeView/CodeViewError.cpp b/lib/DebugInfo/CodeView/CodeViewError.cpp
index 8de266b836b4..2a9753add311 100644
--- a/lib/DebugInfo/CodeView/CodeViewError.cpp
+++ b/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/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp b/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp
index bf9dd7c86862..4001741f560a 100644
--- a/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp
+++ b/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/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp b/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp
index fd558aa9cc8a..5881bf177a55 100644
--- a/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp
+++ b/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/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp b/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp
index d2acc9a21003..9b251f5931b3 100644
--- a/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp
+++ b/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/lib/DebugInfo/CodeView/EnumTables.cpp b/lib/DebugInfo/CodeView/EnumTables.cpp
index d8301cab1657..ef4e42f79ebc 100644
--- a/lib/DebugInfo/CodeView/EnumTables.cpp
+++ b/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/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp b/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
index ca8007411cad..ddcad8c631d7 100644
--- a/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
+++ b/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/lib/DebugInfo/CodeView/SymbolDumper.cpp b/lib/DebugInfo/CodeView/SymbolDumper.cpp
index f8bf961f22a1..04e0bab745d3 100644
--- a/lib/DebugInfo/CodeView/SymbolDumper.cpp
+++ b/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/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp b/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp
new file mode 100644
index 000000000000..01746138ad1f
--- /dev/null
+++ b/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/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp b/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp
index e77c8e8f02f5..2af8205cebc3 100644
--- a/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp
+++ b/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/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp b/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
index 7c68c9167c98..f5d3bea43a14 100644
--- a/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
+++ b/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/lib/DebugInfo/CodeView/TypeIndex.cpp b/lib/DebugInfo/CodeView/TypeIndex.cpp
index 24fe5fcb28d4..332d67470da5 100644
--- a/lib/DebugInfo/CodeView/TypeIndex.cpp
+++ b/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/lib/DebugInfo/CodeView/TypeRecordHelpers.cpp b/lib/DebugInfo/CodeView/TypeRecordHelpers.cpp
new file mode 100644
index 000000000000..2a66474cf5b6
--- /dev/null
+++ b/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/lib/DebugInfo/CodeView/TypeStreamMerger.cpp b/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
index 2e29c9d7dfa0..bae11ce6a6a1 100644
--- a/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
+++ b/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;
+}
diff --git a/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp b/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
index 4582e036f9fc..54daf34ff253 100644
--- a/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
+++ b/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
@@ -14,6 +14,7 @@
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DJB.h"
+#include "llvm/Support/Errc.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/ScopedPrinter.h"
@@ -45,9 +46,9 @@ llvm::Error AppleAcceleratorTable::extract() {
uint32_t Offset = 0;
// Check that we can at least read the header.
- if (!AccelSection.isValidOffset(offsetof(Header, HeaderDataLength)+4))
- return make_error<StringError>("Section too small: cannot read header.",
- inconvertibleErrorCode());
+ if (!AccelSection.isValidOffset(offsetof(Header, HeaderDataLength) + 4))
+ return createStringError(errc::illegal_byte_sequence,
+ "Section too small: cannot read header.");
Hdr.Magic = AccelSection.getU32(&Offset);
Hdr.Version = AccelSection.getU16(&Offset);
@@ -62,9 +63,9 @@ llvm::Error AppleAcceleratorTable::extract() {
// equal to the size for an empty table and hence pointer after the section.
if (!AccelSection.isValidOffset(sizeof(Hdr) + Hdr.HeaderDataLength +
Hdr.BucketCount * 4 + Hdr.HashCount * 8 - 1))
- return make_error<StringError>(
- "Section too small: cannot read buckets and hashes.",
- inconvertibleErrorCode());
+ return createStringError(
+ errc::illegal_byte_sequence,
+ "Section too small: cannot read buckets and hashes.");
HdrData.DIEOffsetBase = AccelSection.getU32(&Offset);
uint32_t NumAtoms = AccelSection.getU32(&Offset);
@@ -380,8 +381,8 @@ llvm::Error DWARFDebugNames::Header::extract(const DWARFDataExtractor &AS,
uint32_t *Offset) {
// Check that we can read the fixed-size part.
if (!AS.isValidOffset(*Offset + sizeof(HeaderPOD) - 1))
- return make_error<StringError>("Section too small: cannot read header.",
- inconvertibleErrorCode());
+ return createStringError(errc::illegal_byte_sequence,
+ "Section too small: cannot read header.");
UnitLength = AS.getU32(Offset);
Version = AS.getU16(Offset);
@@ -395,9 +396,9 @@ llvm::Error DWARFDebugNames::Header::extract(const DWARFDataExtractor &AS,
AugmentationStringSize = alignTo(AS.getU32(Offset), 4);
if (!AS.isValidOffsetForDataOfSize(*Offset, AugmentationStringSize))
- return make_error<StringError>(
- "Section too small: cannot read header augmentation.",
- inconvertibleErrorCode());
+ return createStringError(
+ errc::illegal_byte_sequence,
+ "Section too small: cannot read header augmentation.");
AugmentationString.resize(AugmentationStringSize);
AS.getU8(Offset, reinterpret_cast<uint8_t *>(AugmentationString.data()),
AugmentationStringSize);
@@ -439,8 +440,8 @@ DWARFDebugNames::Abbrev DWARFDebugNames::AbbrevMapInfo::getTombstoneKey() {
Expected<DWARFDebugNames::AttributeEncoding>
DWARFDebugNames::NameIndex::extractAttributeEncoding(uint32_t *Offset) {
if (*Offset >= EntriesBase) {
- return make_error<StringError>("Incorrectly terminated abbreviation table.",
- inconvertibleErrorCode());
+ return createStringError(errc::illegal_byte_sequence,
+ "Incorrectly terminated abbreviation table.");
}
uint32_t Index = Section.AccelSection.getULEB128(Offset);
@@ -465,8 +466,8 @@ DWARFDebugNames::NameIndex::extractAttributeEncodings(uint32_t *Offset) {
Expected<DWARFDebugNames::Abbrev>
DWARFDebugNames::NameIndex::extractAbbrev(uint32_t *Offset) {
if (*Offset >= EntriesBase) {
- return make_error<StringError>("Incorrectly terminated abbreviation table.",
- inconvertibleErrorCode());
+ return createStringError(errc::illegal_byte_sequence,
+ "Incorrectly terminated abbreviation table.");
}
uint32_t Code = Section.AccelSection.getULEB128(Offset);
@@ -501,9 +502,8 @@ Error DWARFDebugNames::NameIndex::extract() {
Offset += Hdr.NameCount * 4;
if (!AS.isValidOffsetForDataOfSize(Offset, Hdr.AbbrevTableSize))
- return make_error<StringError>(
- "Section too small: cannot read abbreviations.",
- inconvertibleErrorCode());
+ return createStringError(errc::illegal_byte_sequence,
+ "Section too small: cannot read abbreviations.");
EntriesBase = Offset + Hdr.AbbrevTableSize;
@@ -514,10 +514,9 @@ Error DWARFDebugNames::NameIndex::extract() {
if (isSentinel(*AbbrevOr))
return Error::success();
- if (!Abbrevs.insert(std::move(*AbbrevOr)).second) {
- return make_error<StringError>("Duplicate abbreviation code.",
- inconvertibleErrorCode());
- }
+ if (!Abbrevs.insert(std::move(*AbbrevOr)).second)
+ return createStringError(errc::invalid_argument,
+ "Duplicate abbreviation code.");
}
}
DWARFDebugNames::Entry::Entry(const NameIndex &NameIdx, const Abbrev &Abbr)
@@ -600,8 +599,8 @@ Expected<DWARFDebugNames::Entry>
DWARFDebugNames::NameIndex::getEntry(uint32_t *Offset) const {
const DWARFDataExtractor &AS = Section.AccelSection;
if (!AS.isValidOffset(*Offset))
- return make_error<StringError>("Incorrectly terminated entry list.",
- inconvertibleErrorCode());
+ return createStringError(errc::illegal_byte_sequence,
+ "Incorrectly terminated entry list.");
uint32_t AbbrevCode = AS.getULEB128(Offset);
if (AbbrevCode == 0)
@@ -609,16 +608,15 @@ DWARFDebugNames::NameIndex::getEntry(uint32_t *Offset) const {
const auto AbbrevIt = Abbrevs.find_as(AbbrevCode);
if (AbbrevIt == Abbrevs.end())
- return make_error<StringError>("Invalid abbreviation.",
- inconvertibleErrorCode());
+ return createStringError(errc::invalid_argument, "Invalid abbreviation.");
Entry E(*this, *AbbrevIt);
dwarf::FormParams FormParams = {Hdr.Version, 0, dwarf::DwarfFormat::DWARF32};
for (auto &Value : E.Values) {
if (!Value.extractValue(AS, Offset, FormParams))
- return make_error<StringError>("Error extracting index attribute values.",
- inconvertibleErrorCode());
+ return createStringError(errc::io_error,
+ "Error extracting index attribute values.");
}
return std::move(E);
}
diff --git a/lib/DebugInfo/DWARF/DWARFContext.cpp b/lib/DebugInfo/DWARF/DWARFContext.cpp
index 9d2554ff9e2e..e6620ee3dd1d 100644
--- a/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -99,22 +99,18 @@ using ContributionCollection =
// Collect all the contributions to the string offsets table from all units,
// sort them by their starting offsets and remove duplicates.
static ContributionCollection
-collectContributionData(DWARFContext::cu_iterator_range CUs,
- DWARFContext::tu_section_iterator_range TUSs) {
+collectContributionData(DWARFContext::unit_iterator_range Units) {
ContributionCollection Contributions;
- for (const auto &CU : CUs)
- Contributions.push_back(CU->getStringOffsetsTableContribution());
- for (const auto &TUS : TUSs)
- for (const auto &TU : TUS)
- Contributions.push_back(TU->getStringOffsetsTableContribution());
-
+ for (const auto &U : Units)
+ Contributions.push_back(U->getStringOffsetsTableContribution());
// Sort the contributions so that any invalid ones are placed at
// the start of the contributions vector. This way they are reported
// first.
- llvm::sort(Contributions.begin(), Contributions.end(),
+ llvm::sort(Contributions,
[](const Optional<StrOffsetsContributionDescriptor> &L,
const Optional<StrOffsetsContributionDescriptor> &R) {
- if (L && R) return L->Base < R->Base;
+ if (L && R)
+ return L->Base < R->Base;
return R.hasValue();
});
@@ -136,9 +132,8 @@ collectContributionData(DWARFContext::cu_iterator_range CUs,
static void dumpDWARFv5StringOffsetsSection(
raw_ostream &OS, StringRef SectionName, const DWARFObject &Obj,
const DWARFSection &StringOffsetsSection, StringRef StringSection,
- DWARFContext::cu_iterator_range CUs,
- DWARFContext::tu_section_iterator_range TUSs, bool LittleEndian) {
- auto Contributions = collectContributionData(CUs, TUSs);
+ DWARFContext::unit_iterator_range Units, bool LittleEndian) {
+ auto Contributions = collectContributionData(Units);
DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);
DataExtractor StrData(StringSection, LittleEndian, 0);
uint64_t SectionSize = StringOffsetsSection.Data.size();
@@ -215,18 +210,18 @@ static void dumpDWARFv5StringOffsetsSection(
// a header containing size and version number. Alternatively, it may be a
// monolithic series of string offsets, as generated by the pre-DWARF v5
// implementation of split DWARF.
-static void dumpStringOffsetsSection(
- raw_ostream &OS, StringRef SectionName, const DWARFObject &Obj,
- const DWARFSection &StringOffsetsSection, StringRef StringSection,
- DWARFContext::cu_iterator_range CUs,
- DWARFContext::tu_section_iterator_range TUSs, bool LittleEndian,
- unsigned MaxVersion) {
+static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName,
+ const DWARFObject &Obj,
+ const DWARFSection &StringOffsetsSection,
+ StringRef StringSection,
+ DWARFContext::unit_iterator_range Units,
+ bool LittleEndian, unsigned MaxVersion) {
// If we have at least one (compile or type) unit with DWARF v5 or greater,
// we assume that the section is formatted like a DWARF v5 string offsets
// section.
if (MaxVersion >= 5)
dumpDWARFv5StringOffsetsSection(OS, SectionName, Obj, StringOffsetsSection,
- StringSection, CUs, TUSs, LittleEndian);
+ StringSection, Units, LittleEndian);
else {
DataExtractor strOffsetExt(StringOffsetsSection.Data, LittleEndian, 0);
uint32_t offset = 0;
@@ -254,19 +249,12 @@ static void dumpStringOffsetsSection(
static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData,
DIDumpOptions DumpOpts, uint16_t Version,
uint8_t AddrSize) {
- // TODO: Make this more general: add callback types to Error.h, create
- // implementation and make all DWARF classes use them.
- static auto WarnCallback = [](Error Warn) {
- handleAllErrors(std::move(Warn), [](ErrorInfoBase &Info) {
- WithColor::warning() << Info.message() << '\n';
- });
- };
uint32_t Offset = 0;
while (AddrData.isValidOffset(Offset)) {
DWARFDebugAddrTable AddrTable;
uint32_t TableOffset = Offset;
- if (Error Err = AddrTable.extract(AddrData, &Offset, Version,
- AddrSize, WarnCallback)) {
+ if (Error Err = AddrTable.extract(AddrData, &Offset, Version, AddrSize,
+ DWARFContext::dumpWarning)) {
WithColor::error() << toString(std::move(Err)) << '\n';
// Keep going after an error, if we can, assuming that the length field
// could be read. If it couldn't, stop reading the section.
@@ -281,9 +269,11 @@ static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData,
}
// Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5).
-static void dumpRnglistsSection(raw_ostream &OS,
- DWARFDataExtractor &rnglistData,
- DIDumpOptions DumpOpts) {
+static void
+dumpRnglistsSection(raw_ostream &OS, DWARFDataExtractor &rnglistData,
+ llvm::function_ref<Optional<SectionedAddress>(uint32_t)>
+ LookupPooledAddress,
+ DIDumpOptions DumpOpts) {
uint32_t Offset = 0;
while (rnglistData.isValidOffset(Offset)) {
llvm::DWARFDebugRnglistTable Rnglists;
@@ -297,16 +287,36 @@ static void dumpRnglistsSection(raw_ostream &OS,
break;
Offset = TableOffset + Length;
} else {
- Rnglists.dump(OS, DumpOpts);
+ Rnglists.dump(OS, LookupPooledAddress, DumpOpts);
}
}
}
+static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
+ DWARFDataExtractor Data,
+ const MCRegisterInfo *MRI,
+ Optional<uint64_t> DumpOffset) {
+ uint32_t Offset = 0;
+ DWARFDebugLoclists Loclists;
+
+ DWARFListTableHeader Header(".debug_loclists", "locations");
+ if (Error E = Header.extract(Data, &Offset)) {
+ WithColor::error() << toString(std::move(E)) << '\n';
+ return;
+ }
+
+ Header.dump(OS, DumpOpts);
+ DataExtractor LocData(Data.getData().drop_front(Offset),
+ Data.isLittleEndian(), Header.getAddrSize());
+
+ Loclists.parse(LocData, Header.getVersion());
+ Loclists.dump(OS, 0, MRI, DumpOffset);
+}
+
void DWARFContext::dump(
raw_ostream &OS, DIDumpOptions DumpOpts,
std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets) {
- Optional<uint64_t> DumpOffset;
uint64_t DumpType = DumpOpts.DumpType;
StringRef Extension = sys::path::extension(DObj->getFileName());
@@ -323,13 +333,13 @@ void DWARFContext::dump(
bool Explicit = DumpType != DIDT_All && !IsDWO;
bool ExplicitDWO = Explicit && IsDWO;
auto shouldDump = [&](bool Explicit, const char *Name, unsigned ID,
- StringRef Section) {
- DumpOffset = DumpOffsets[ID];
+ StringRef Section) -> Optional<uint64_t> * {
unsigned Mask = 1U << ID;
bool Should = (DumpType & Mask) && (Explicit || !Section.empty());
- if (Should)
- OS << "\n" << Name << " contents:\n";
- return Should;
+ if (!Should)
+ return nullptr;
+ OS << "\n" << Name << " contents:\n";
+ return &DumpOffsets[ID];
};
// Dump individual sections.
@@ -340,57 +350,63 @@ void DWARFContext::dump(
DObj->getAbbrevDWOSection()))
getDebugAbbrevDWO()->dump(OS);
- auto dumpDebugInfo = [&](bool IsExplicit, const char *Name,
- DWARFSection Section, cu_iterator_range CUs) {
- if (shouldDump(IsExplicit, Name, DIDT_ID_DebugInfo, Section.Data)) {
- if (DumpOffset)
- getDIEForOffset(DumpOffset.getValue())
+ auto dumpDebugInfo = [&](const char *Name, unit_iterator_range Units) {
+ OS << '\n' << Name << " contents:\n";
+ if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugInfo])
+ for (const auto &U : Units)
+ U->getDIEForOffset(DumpOffset.getValue())
.dump(OS, 0, DumpOpts.noImplicitRecursion());
- else
- for (const auto &CU : CUs)
- CU->dump(OS, DumpOpts);
- }
+ else
+ for (const auto &U : Units)
+ U->dump(OS, DumpOpts);
};
- dumpDebugInfo(Explicit, ".debug_info", DObj->getInfoSection(),
- compile_units());
- dumpDebugInfo(ExplicitDWO, ".debug_info.dwo", DObj->getInfoDWOSection(),
- dwo_compile_units());
+ if ((DumpType & DIDT_DebugInfo)) {
+ if (Explicit || getNumCompileUnits())
+ dumpDebugInfo(".debug_info", info_section_units());
+ if (ExplicitDWO || getNumDWOCompileUnits())
+ dumpDebugInfo(".debug_info.dwo", dwo_info_section_units());
+ }
- auto dumpDebugType = [&](const char *Name,
- tu_section_iterator_range TUSections) {
+ auto dumpDebugType = [&](const char *Name, unit_iterator_range Units) {
OS << '\n' << Name << " contents:\n";
- DumpOffset = DumpOffsets[DIDT_ID_DebugTypes];
- for (const auto &TUS : TUSections)
- for (const auto &TU : TUS)
- if (DumpOffset)
- TU->getDIEForOffset(*DumpOffset)
- .dump(OS, 0, DumpOpts.noImplicitRecursion());
- else
- TU->dump(OS, DumpOpts);
+ for (const auto &U : Units)
+ if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugTypes])
+ U->getDIEForOffset(*DumpOffset)
+ .dump(OS, 0, DumpOpts.noImplicitRecursion());
+ else
+ U->dump(OS, DumpOpts);
};
if ((DumpType & DIDT_DebugTypes)) {
if (Explicit || getNumTypeUnits())
- dumpDebugType(".debug_types", type_unit_sections());
+ dumpDebugType(".debug_types", types_section_units());
if (ExplicitDWO || getNumDWOTypeUnits())
- dumpDebugType(".debug_types.dwo", dwo_type_unit_sections());
+ dumpDebugType(".debug_types.dwo", dwo_types_section_units());
}
- if (shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,
- DObj->getLocSection().Data)) {
- getDebugLoc()->dump(OS, getRegisterInfo(), DumpOffset);
+ if (const auto *Off = shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,
+ DObj->getLocSection().Data)) {
+ getDebugLoc()->dump(OS, getRegisterInfo(), *Off);
+ }
+ if (const auto *Off =
+ shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists,
+ DObj->getLoclistsSection().Data)) {
+ DWARFDataExtractor Data(*DObj, DObj->getLoclistsSection(), isLittleEndian(),
+ 0);
+ dumpLoclistsSection(OS, DumpOpts, Data, getRegisterInfo(), *Off);
}
- if (shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc,
- DObj->getLocDWOSection().Data)) {
- getDebugLocDWO()->dump(OS, getRegisterInfo(), DumpOffset);
+ if (const auto *Off =
+ shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc,
+ DObj->getLocDWOSection().Data)) {
+ getDebugLocDWO()->dump(OS, 0, getRegisterInfo(), *Off);
}
- if (shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
- DObj->getDebugFrameSection()))
- getDebugFrame()->dump(OS, getRegisterInfo(), DumpOffset);
+ if (const auto *Off = shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
+ DObj->getDebugFrameSection()))
+ getDebugFrame()->dump(OS, getRegisterInfo(), *Off);
- if (shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
- DObj->getEHFrameSection()))
- getEHFrame()->dump(OS, getRegisterInfo(), DumpOffset);
+ if (const auto *Off = shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
+ DObj->getEHFrameSection()))
+ getEHFrame()->dump(OS, getRegisterInfo(), *Off);
if (DumpType & DIDT_DebugMacro) {
if (Explicit || !getDebugMacro()->empty()) {
@@ -409,38 +425,41 @@ void DWARFContext::dump(
}
auto DumpLineSection = [&](DWARFDebugLine::SectionParser Parser,
- DIDumpOptions DumpOpts) {
+ DIDumpOptions DumpOpts,
+ Optional<uint64_t> DumpOffset) {
while (!Parser.done()) {
if (DumpOffset && Parser.getOffset() != *DumpOffset) {
- Parser.skip();
+ Parser.skip(dumpWarning);
continue;
}
OS << "debug_line[" << format("0x%8.8x", Parser.getOffset()) << "]\n";
if (DumpOpts.Verbose) {
- Parser.parseNext(DWARFDebugLine::warn, DWARFDebugLine::warn, &OS);
+ Parser.parseNext(dumpWarning, dumpWarning, &OS);
} else {
- DWARFDebugLine::LineTable LineTable = Parser.parseNext();
+ DWARFDebugLine::LineTable LineTable =
+ Parser.parseNext(dumpWarning, dumpWarning);
LineTable.dump(OS, DumpOpts);
}
}
};
- if (shouldDump(Explicit, ".debug_line", DIDT_ID_DebugLine,
- DObj->getLineSection().Data)) {
+ if (const auto *Off = shouldDump(Explicit, ".debug_line", DIDT_ID_DebugLine,
+ DObj->getLineSection().Data)) {
DWARFDataExtractor LineData(*DObj, DObj->getLineSection(), isLittleEndian(),
0);
DWARFDebugLine::SectionParser Parser(LineData, *this, compile_units(),
- type_unit_sections());
- DumpLineSection(Parser, DumpOpts);
+ type_units());
+ DumpLineSection(Parser, DumpOpts, *Off);
}
- if (shouldDump(ExplicitDWO, ".debug_line.dwo", DIDT_ID_DebugLine,
- DObj->getLineDWOSection().Data)) {
+ if (const auto *Off =
+ shouldDump(ExplicitDWO, ".debug_line.dwo", DIDT_ID_DebugLine,
+ DObj->getLineDWOSection().Data)) {
DWARFDataExtractor LineData(*DObj, DObj->getLineDWOSection(),
isLittleEndian(), 0);
DWARFDebugLine::SectionParser Parser(LineData, *this, dwo_compile_units(),
- dwo_type_unit_sections());
- DumpLineSection(Parser, DumpOpts);
+ dwo_type_units());
+ DumpLineSection(Parser, DumpOpts, *Off);
}
if (shouldDump(Explicit, ".debug_cu_index", DIDT_ID_DebugCUIndex,
@@ -509,56 +528,64 @@ void DWARFContext::dump(
}
}
+ auto LookupPooledAddress = [&](uint32_t Index) -> Optional<SectionedAddress> {
+ const auto &CUs = compile_units();
+ auto I = CUs.begin();
+ if (I == CUs.end())
+ return None;
+ return (*I)->getAddrOffsetSectionItem(Index);
+ };
+
if (shouldDump(Explicit, ".debug_rnglists", DIDT_ID_DebugRnglists,
DObj->getRnglistsSection().Data)) {
DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsSection(),
isLittleEndian(), 0);
- dumpRnglistsSection(OS, RnglistData, DumpOpts);
+ dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);
}
if (shouldDump(ExplicitDWO, ".debug_rnglists.dwo", DIDT_ID_DebugRnglists,
DObj->getRnglistsDWOSection().Data)) {
DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsDWOSection(),
isLittleEndian(), 0);
- dumpRnglistsSection(OS, RnglistData, DumpOpts);
+ dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);
}
if (shouldDump(Explicit, ".debug_pubnames", DIDT_ID_DebugPubnames,
- DObj->getPubNamesSection()))
- DWARFDebugPubTable(DObj->getPubNamesSection(), isLittleEndian(), false)
+ DObj->getPubNamesSection().Data))
+ DWARFDebugPubTable(*DObj, DObj->getPubNamesSection(), isLittleEndian(), false)
.dump(OS);
if (shouldDump(Explicit, ".debug_pubtypes", DIDT_ID_DebugPubtypes,
- DObj->getPubTypesSection()))
- DWARFDebugPubTable(DObj->getPubTypesSection(), isLittleEndian(), false)
+ DObj->getPubTypesSection().Data))
+ DWARFDebugPubTable(*DObj, DObj->getPubTypesSection(), isLittleEndian(), false)
.dump(OS);
if (shouldDump(Explicit, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames,
- DObj->getGnuPubNamesSection()))
- DWARFDebugPubTable(DObj->getGnuPubNamesSection(), isLittleEndian(),
+ DObj->getGnuPubNamesSection().Data))
+ DWARFDebugPubTable(*DObj, DObj->getGnuPubNamesSection(), isLittleEndian(),
true /* GnuStyle */)
.dump(OS);
if (shouldDump(Explicit, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes,
- DObj->getGnuPubTypesSection()))
- DWARFDebugPubTable(DObj->getGnuPubTypesSection(), isLittleEndian(),
+ DObj->getGnuPubTypesSection().Data))
+ DWARFDebugPubTable(*DObj, DObj->getGnuPubTypesSection(), isLittleEndian(),
true /* GnuStyle */)
.dump(OS);
if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets,
DObj->getStringOffsetSection().Data))
- dumpStringOffsetsSection(
- OS, "debug_str_offsets", *DObj, DObj->getStringOffsetSection(),
- DObj->getStringSection(), compile_units(), type_unit_sections(),
- isLittleEndian(), getMaxVersion());
+ dumpStringOffsetsSection(OS, "debug_str_offsets", *DObj,
+ DObj->getStringOffsetSection(),
+ DObj->getStringSection(), normal_units(),
+ isLittleEndian(), getMaxVersion());
if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
DObj->getStringOffsetDWOSection().Data))
- dumpStringOffsetsSection(
- OS, "debug_str_offsets.dwo", *DObj, DObj->getStringOffsetDWOSection(),
- DObj->getStringDWOSection(), dwo_compile_units(),
- dwo_type_unit_sections(), isLittleEndian(), getMaxVersion());
+ dumpStringOffsetsSection(OS, "debug_str_offsets.dwo", *DObj,
+ DObj->getStringOffsetDWOSection(),
+ DObj->getStringDWOSection(), dwo_units(),
+ isLittleEndian(), getMaxDWOVersion());
- if (shouldDump(Explicit, ".gnu_index", DIDT_ID_GdbIndex,
+ if (shouldDump(Explicit, ".gdb_index", DIDT_ID_GdbIndex,
DObj->getGdbIndexSection())) {
getGdbIndex().dump(OS);
}
@@ -584,11 +611,12 @@ void DWARFContext::dump(
}
DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
- DWOCUs.parseDWO(*this, DObj->getInfoDWOSection(), true);
+ parseDWOUnits(LazyParse);
if (const auto &CUI = getCUIndex()) {
if (const auto *R = CUI.getFromHash(Hash))
- return DWOCUs.getUnitForIndexEntry(*R);
+ return dyn_cast_or_null<DWARFCompileUnit>(
+ DWOUnits.getUnitForIndexEntry(*R));
return nullptr;
}
@@ -607,14 +635,14 @@ DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
continue;
}
if (DWOCU->getDWOId() == Hash)
- return DWOCU.get();
+ return dyn_cast<DWARFCompileUnit>(DWOCU.get());
}
return nullptr;
}
DWARFDie DWARFContext::getDIEForOffset(uint32_t Offset) {
- parseCompileUnits();
- if (auto *CU = CUs.getUnitForOffset(Offset))
+ parseNormalUnits();
+ if (auto *CU = NormalUnits.getUnitForOffset(Offset))
return CU->getDIEForOffset(Offset);
return DWARFDie();
}
@@ -690,26 +718,28 @@ const DWARFDebugLoc *DWARFContext::getDebugLoc() {
return Loc.get();
Loc.reset(new DWARFDebugLoc);
- // Assume all compile units have the same address byte size.
+ // Assume all units have the same address byte size.
if (getNumCompileUnits()) {
DWARFDataExtractor LocData(*DObj, DObj->getLocSection(), isLittleEndian(),
- getCompileUnitAtIndex(0)->getAddressByteSize());
+ getUnitAtIndex(0)->getAddressByteSize());
Loc->parse(LocData);
}
return Loc.get();
}
-const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() {
+const DWARFDebugLoclists *DWARFContext::getDebugLocDWO() {
if (LocDWO)
return LocDWO.get();
- LocDWO.reset(new DWARFDebugLocDWO());
+ LocDWO.reset(new DWARFDebugLoclists());
// Assume all compile units have the same address byte size.
- if (getNumCompileUnits()) {
- DataExtractor LocData(DObj->getLocDWOSection().Data, isLittleEndian(),
- getCompileUnitAtIndex(0)->getAddressByteSize());
- LocDWO->parse(LocData);
- }
+ // FIXME: We don't need AddressSize for split DWARF since relocatable
+ // addresses cannot appear there. At the moment DWARFExpression requires it.
+ DataExtractor LocData(DObj->getLocDWOSection().Data, isLittleEndian(), 4);
+ // Use version 4. DWO does not support the DWARF v5 .debug_loclists yet and
+ // that means we are parsing the new style .debug_loc (pre-standatized version
+ // of the .debug_loclists).
+ LocDWO->parse(LocData, 4 /* Version */);
return LocDWO.get();
}
@@ -737,7 +767,7 @@ const DWARFDebugFrame *DWARFContext::getDebugFrame() {
// http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
DWARFDataExtractor debugFrameData(DObj->getDebugFrameSection(),
isLittleEndian(), DObj->getAddressSize());
- DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */));
+ DebugFrame.reset(new DWARFDebugFrame(getArch(), false /* IsEH */));
DebugFrame->parse(debugFrameData);
return DebugFrame.get();
}
@@ -748,7 +778,7 @@ const DWARFDebugFrame *DWARFContext::getEHFrame() {
DWARFDataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(),
DObj->getAddressSize());
- DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */));
+ DebugFrame.reset(new DWARFDebugFrame(getArch(), true /* IsEH */));
DebugFrame->parse(debugFrameData);
return DebugFrame.get();
}
@@ -806,9 +836,9 @@ const AppleAcceleratorTable &DWARFContext::getAppleObjC() {
const DWARFDebugLine::LineTable *
DWARFContext::getLineTableForUnit(DWARFUnit *U) {
Expected<const DWARFDebugLine::LineTable *> ExpectedLineTable =
- getLineTableForUnit(U, DWARFDebugLine::warn);
+ getLineTableForUnit(U, dumpWarning);
if (!ExpectedLineTable) {
- DWARFDebugLine::warn(ExpectedLineTable.takeError());
+ dumpWarning(ExpectedLineTable.takeError());
return nullptr;
}
return *ExpectedLineTable;
@@ -843,35 +873,34 @@ Expected<const DWARFDebugLine::LineTable *> DWARFContext::getLineTableForUnit(
RecoverableErrorCallback);
}
-void DWARFContext::parseCompileUnits() {
- CUs.parse(*this, DObj->getInfoSection());
-}
-
-void DWARFContext::parseTypeUnits() {
- if (!TUs.empty())
+void DWARFContext::parseNormalUnits() {
+ if (!NormalUnits.empty())
return;
+ DObj->forEachInfoSections([&](const DWARFSection &S) {
+ NormalUnits.addUnitsForSection(*this, S, DW_SECT_INFO);
+ });
+ NormalUnits.finishedInfoUnits();
DObj->forEachTypesSections([&](const DWARFSection &S) {
- TUs.emplace_back();
- TUs.back().parse(*this, S);
+ NormalUnits.addUnitsForSection(*this, S, DW_SECT_TYPES);
});
}
-void DWARFContext::parseDWOCompileUnits() {
- DWOCUs.parseDWO(*this, DObj->getInfoDWOSection());
-}
-
-void DWARFContext::parseDWOTypeUnits() {
- if (!DWOTUs.empty())
+void DWARFContext::parseDWOUnits(bool Lazy) {
+ if (!DWOUnits.empty())
return;
+ DObj->forEachInfoDWOSections([&](const DWARFSection &S) {
+ DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_INFO, Lazy);
+ });
+ DWOUnits.finishedInfoUnits();
DObj->forEachTypesDWOSections([&](const DWARFSection &S) {
- DWOTUs.emplace_back();
- DWOTUs.back().parseDWO(*this, S);
+ DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_TYPES, Lazy);
});
}
DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
- parseCompileUnits();
- return CUs.getUnitForOffset(Offset);
+ parseNormalUnits();
+ return dyn_cast_or_null<DWARFCompileUnit>(
+ NormalUnits.getUnitForOffset(Offset));
}
DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
@@ -1213,19 +1242,20 @@ class DWARFObjInMemory final : public DWARFObject {
const object::ObjectFile *Obj = nullptr;
std::vector<SectionName> SectionNames;
- using TypeSectionMap = MapVector<object::SectionRef, DWARFSectionMap,
+ using InfoSectionMap = MapVector<object::SectionRef, DWARFSectionMap,
std::map<object::SectionRef, unsigned>>;
- TypeSectionMap TypesSections;
- TypeSectionMap TypesDWOSections;
+ InfoSectionMap InfoSections;
+ InfoSectionMap TypesSections;
+ InfoSectionMap InfoDWOSections;
+ InfoSectionMap TypesDWOSections;
- DWARFSectionMap InfoSection;
DWARFSectionMap LocSection;
+ DWARFSectionMap LocListsSection;
DWARFSectionMap LineSection;
DWARFSectionMap RangeSection;
DWARFSectionMap RnglistsSection;
DWARFSectionMap StringOffsetSection;
- DWARFSectionMap InfoDWOSection;
DWARFSectionMap LineDWOSection;
DWARFSectionMap LocDWOSection;
DWARFSectionMap StringOffsetDWOSection;
@@ -1237,16 +1267,19 @@ class DWARFObjInMemory final : public DWARFObject {
DWARFSectionMap AppleNamespacesSection;
DWARFSectionMap AppleObjCSection;
DWARFSectionMap DebugNamesSection;
+ DWARFSectionMap PubNamesSection;
+ DWARFSectionMap PubTypesSection;
+ DWARFSectionMap GnuPubNamesSection;
+ DWARFSectionMap GnuPubTypesSection;
DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
return StringSwitch<DWARFSectionMap *>(Name)
- .Case("debug_info", &InfoSection)
.Case("debug_loc", &LocSection)
+ .Case("debug_loclists", &LocListsSection)
.Case("debug_line", &LineSection)
.Case("debug_str_offsets", &StringOffsetSection)
.Case("debug_ranges", &RangeSection)
.Case("debug_rnglists", &RnglistsSection)
- .Case("debug_info.dwo", &InfoDWOSection)
.Case("debug_loc.dwo", &LocDWOSection)
.Case("debug_line.dwo", &LineDWOSection)
.Case("debug_names", &DebugNamesSection)
@@ -1254,6 +1287,10 @@ class DWARFObjInMemory final : public DWARFObject {
.Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
.Case("debug_addr", &AddrSection)
.Case("apple_names", &AppleNamesSection)
+ .Case("debug_pubnames", &PubNamesSection)
+ .Case("debug_pubtypes", &PubTypesSection)
+ .Case("debug_gnu_pubnames", &GnuPubNamesSection)
+ .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
.Case("apple_types", &AppleTypesSection)
.Case("apple_namespaces", &AppleNamespacesSection)
.Case("apple_namespac", &AppleNamespacesSection)
@@ -1267,12 +1304,8 @@ class DWARFObjInMemory final : public DWARFObject {
StringRef EHFrameSection;
StringRef StringSection;
StringRef MacinfoSection;
- StringRef PubNamesSection;
- StringRef PubTypesSection;
- StringRef GnuPubNamesSection;
StringRef AbbrevDWOSection;
StringRef StringDWOSection;
- StringRef GnuPubTypesSection;
StringRef CUIndexSection;
StringRef GdbIndexSection;
StringRef TUIndexSection;
@@ -1292,10 +1325,6 @@ class DWARFObjInMemory final : public DWARFObject {
.Case("eh_frame", &EHFrameSection)
.Case("debug_str", &StringSection)
.Case("debug_macinfo", &MacinfoSection)
- .Case("debug_pubnames", &PubNamesSection)
- .Case("debug_pubtypes", &PubTypesSection)
- .Case("debug_gnu_pubnames", &GnuPubNamesSection)
- .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
.Case("debug_abbrev.dwo", &AbbrevDWOSection)
.Case("debug_str.dwo", &StringDWOSection)
.Case("debug_cu_index", &CUIndexSection)
@@ -1335,6 +1364,16 @@ public:
for (const auto &SecIt : Sections) {
if (StringRef *SectionData = mapSectionToMember(SecIt.first()))
*SectionData = SecIt.second->getBuffer();
+ else if (SecIt.first() == "debug_info")
+ // Find debug_info and debug_types data by section rather than name as
+ // there are multiple, comdat grouped, of these sections.
+ InfoSections[SectionRef()].Data = SecIt.second->getBuffer();
+ else if (SecIt.first() == "debug_info.dwo")
+ InfoDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
+ else if (SecIt.first() == "debug_types")
+ TypesSections[SectionRef()].Data = SecIt.second->getBuffer();
+ else if (SecIt.first() == "debug_types.dwo")
+ TypesDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
}
}
DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
@@ -1389,9 +1428,13 @@ public:
// FIXME: Use the other dwo range section when we emit it.
RangeDWOSection.Data = Data;
}
+ } else if (Name == "debug_info") {
+ // Find debug_info and debug_types data by section rather than name as
+ // there are multiple, comdat grouped, of these sections.
+ InfoSections[Section].Data = Data;
+ } else if (Name == "debug_info.dwo") {
+ InfoDWOSections[Section].Data = Data;
} else if (Name == "debug_types") {
- // Find debug_types data by section rather than name as there are
- // multiple, comdat grouped, debug_types sections.
TypesSections[Section].Data = Data;
} else if (Name == "debug_types.dwo") {
TypesDWOSections[Section].Data = Data;
@@ -1426,9 +1469,16 @@ public:
DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName);
RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr;
if (!Map) {
- // Find debug_types relocs by section rather than name as there are
- // multiple, comdat grouped, debug_types sections.
- if (RelSecName == "debug_types")
+ // Find debug_info and debug_types relocs by section rather than name
+ // as there are multiple, comdat grouped, of these sections.
+ if (RelSecName == "debug_info")
+ Map = &static_cast<DWARFSectionMap &>(InfoSections[*RelocatedSection])
+ .Relocs;
+ else if (RelSecName == "debug_info.dwo")
+ Map = &static_cast<DWARFSectionMap &>(
+ InfoDWOSections[*RelocatedSection])
+ .Relocs;
+ else if (RelSecName == "debug_types")
Map =
&static_cast<DWARFSectionMap &>(TypesSections[*RelocatedSection])
.Relocs;
@@ -1526,8 +1576,10 @@ public:
StringRef getLineStringSection() const override { return LineStringSection; }
// Sections for DWARF5 split dwarf proposal.
- const DWARFSection &getInfoDWOSection() const override {
- return InfoDWOSection;
+ void forEachInfoDWOSections(
+ function_ref<void(const DWARFSection &)> F) const override {
+ for (auto &P : InfoDWOSections)
+ F(P.second);
}
void forEachTypesDWOSections(
function_ref<void(const DWARFSection &)> F) const override {
@@ -1537,6 +1589,7 @@ public:
StringRef getAbbrevSection() const override { return AbbrevSection; }
const DWARFSection &getLocSection() const override { return LocSection; }
+ const DWARFSection &getLoclistsSection() const override { return LocListsSection; }
StringRef getARangeSection() const override { return ARangeSection; }
StringRef getDebugFrameSection() const override { return DebugFrameSection; }
StringRef getEHFrameSection() const override { return EHFrameSection; }
@@ -1547,12 +1600,12 @@ public:
return RnglistsSection;
}
StringRef getMacinfoSection() const override { return MacinfoSection; }
- StringRef getPubNamesSection() const override { return PubNamesSection; }
- StringRef getPubTypesSection() const override { return PubTypesSection; }
- StringRef getGnuPubNamesSection() const override {
+ const DWARFSection &getPubNamesSection() const override { return PubNamesSection; }
+ const DWARFSection &getPubTypesSection() const override { return PubTypesSection; }
+ const DWARFSection &getGnuPubNamesSection() const override {
return GnuPubNamesSection;
}
- StringRef getGnuPubTypesSection() const override {
+ const DWARFSection &getGnuPubTypesSection() const override {
return GnuPubTypesSection;
}
const DWARFSection &getAppleNamesSection() const override {
@@ -1573,7 +1626,11 @@ public:
StringRef getFileName() const override { return FileName; }
uint8_t getAddressSize() const override { return AddressSize; }
- const DWARFSection &getInfoSection() const override { return InfoSection; }
+ void forEachInfoSections(
+ function_ref<void(const DWARFSection &)> F) const override {
+ for (auto &P : InfoSections)
+ F(P.second);
+ }
void forEachTypesSections(
function_ref<void(const DWARFSection &)> F) const override {
for (auto &P : TypesSections)
@@ -1609,7 +1666,8 @@ Error DWARFContext::loadRegisterInfo(const object::ObjectFile &Obj) {
const Target *TheTarget =
TargetRegistry::lookupTarget(TT.str(), TargetLookupError);
if (!TargetLookupError.empty())
- return make_error<StringError>(TargetLookupError, inconvertibleErrorCode());
+ return createStringError(errc::invalid_argument,
+ TargetLookupError.c_str());
RegInfo.reset(TheTarget->createMCRegInfo(TT.str()));
return Error::success();
}
@@ -1627,3 +1685,9 @@ uint8_t DWARFContext::getCUAddrSize() {
}
return Addr;
}
+
+void DWARFContext::dumpWarning(Error Warning) {
+ handleAllErrors(std::move(Warning), [](ErrorInfoBase &Info) {
+ WithColor::warning() << Info.message() << '\n';
+ });
+}
diff --git a/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp b/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp
index 7085ca067ba6..22759bfac26c 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp
@@ -148,7 +148,7 @@ void DWARFDebugAddrTable::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
HeaderData.Length, HeaderData.Version, HeaderData.AddrSize,
HeaderData.SegSize);
- static const char *Fmt32 = "0x%8.8" PRIx32;
+ static const char *Fmt32 = "0x%8.8" PRIx64;
static const char *Fmt64 = "0x%16.16" PRIx64;
std::string AddrFmt = "\n";
std::string AddrFmtVerbose = " => ";
diff --git a/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp b/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
index 19bfcaed2021..e8c5dec821b4 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
@@ -12,6 +12,7 @@
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/WithColor.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
@@ -53,10 +54,12 @@ void DWARFDebugAranges::generate(DWARFContext *CTX) {
for (const auto &CU : CTX->compile_units()) {
uint32_t CUOffset = CU->getOffset();
if (ParsedCUOffsets.insert(CUOffset).second) {
- DWARFAddressRangesVector CURanges;
- CU->collectAddressRanges(CURanges);
- for (const auto &R : CURanges)
- appendRange(CUOffset, R.LowPC, R.HighPC);
+ Expected<DWARFAddressRangesVector> CURanges = CU->collectAddressRanges();
+ if (!CURanges)
+ WithColor::error() << toString(CURanges.takeError()) << '\n';
+ else
+ for (const auto &R : *CURanges)
+ appendRange(CUOffset, R.LowPC, R.HighPC);
}
}
@@ -80,7 +83,7 @@ void DWARFDebugAranges::appendRange(uint32_t CUOffset, uint64_t LowPC,
void DWARFDebugAranges::construct() {
std::multiset<uint32_t> ValidCUs; // Maintain the set of CUs describing
// a current address range.
- llvm::sort(Endpoints.begin(), Endpoints.end());
+ llvm::sort(Endpoints);
uint64_t PrevAddress = -1ULL;
for (const auto &E : Endpoints) {
if (PrevAddress < E.Address && !ValidCUs.empty()) {
diff --git a/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
index 73333395f4c1..ba55ffc28174 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
@@ -16,6 +16,7 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/Errc.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
@@ -47,9 +48,9 @@ Error CFIProgram::parse(DataExtractor Data, uint32_t *Offset,
uint64_t Op1 = Opcode & DWARF_CFI_PRIMARY_OPERAND_MASK;
switch (Primary) {
default:
- return make_error<StringError>(
- "Invalid primary CFI opcode",
- std::make_error_code(std::errc::illegal_byte_sequence));
+ return createStringError(errc::illegal_byte_sequence,
+ "Invalid primary CFI opcode 0x%" PRIx8,
+ Primary);
case DW_CFA_advance_loc:
case DW_CFA_restore:
addInstruction(Primary, Op1);
@@ -62,9 +63,9 @@ Error CFIProgram::parse(DataExtractor Data, uint32_t *Offset,
// Extended opcode - its value is Opcode itself.
switch (Opcode) {
default:
- return make_error<StringError>(
- "Invalid extended CFI opcode",
- std::make_error_code(std::errc::illegal_byte_sequence));
+ return createStringError(errc::illegal_byte_sequence,
+ "Invalid extended CFI opcode 0x%" PRIx8,
+ Opcode);
case DW_CFA_nop:
case DW_CFA_remember_state:
case DW_CFA_restore_state:
@@ -224,7 +225,7 @@ void CFIProgram::printOperand(raw_ostream &OS, const MCRegisterInfo *MRI,
switch (Type) {
case OT_Unset: {
OS << " Unsupported " << (OperandIdx ? "second" : "first") << " operand to";
- auto OpcodeName = CallFrameString(Opcode);
+ auto OpcodeName = CallFrameString(Opcode, Arch);
if (!OpcodeName.empty())
OS << " " << OpcodeName;
else
@@ -278,7 +279,7 @@ void CFIProgram::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK)
Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK;
OS.indent(2 * IndentLevel);
- OS << CallFrameString(Opcode) << ":";
+ OS << CallFrameString(Opcode, Arch) << ":";
for (unsigned i = 0; i < Instr.Ops.size(); ++i)
printOperand(OS, MRI, IsEH, Instr, i, Instr.Ops[i]);
OS << '\n';
@@ -324,8 +325,9 @@ void FDE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const {
OS << "\n";
}
-DWARFDebugFrame::DWARFDebugFrame(bool IsEH, uint64_t EHFrameAddress)
- : IsEH(IsEH), EHFrameAddress(EHFrameAddress) {}
+DWARFDebugFrame::DWARFDebugFrame(Triple::ArchType Arch,
+ bool IsEH, uint64_t EHFrameAddress)
+ : Arch(Arch), IsEH(IsEH), EHFrameAddress(EHFrameAddress) {}
DWARFDebugFrame::~DWARFDebugFrame() = default;
@@ -395,7 +397,8 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
uint8_t SegmentDescriptorSize = Version < 4 ? 0 : Data.getU8(&Offset);
uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset);
int64_t DataAlignmentFactor = Data.getSLEB128(&Offset);
- uint64_t ReturnAddressRegister = Data.getULEB128(&Offset);
+ uint64_t ReturnAddressRegister =
+ Version == 1 ? Data.getU8(&Offset) : Data.getULEB128(&Offset);
// Parse the augmentation data for EH CIEs
StringRef AugmentationData("");
@@ -443,6 +446,11 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
StartAugmentationOffset = Offset;
EndAugmentationOffset = Offset +
static_cast<uint32_t>(*AugmentationLength);
+ break;
+ case 'B':
+ // B-Key is used for signing functions associated with this
+ // augmentation string
+ break;
}
}
@@ -459,7 +467,7 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
StartOffset, Length, Version, AugmentationString, AddressSize,
SegmentDescriptorSize, CodeAlignmentFactor, DataAlignmentFactor,
ReturnAddressRegister, AugmentationData, FDEPointerEncoding,
- LSDAPointerEncoding, Personality, PersonalityEncoding);
+ LSDAPointerEncoding, Personality, PersonalityEncoding, Arch);
CIEs[StartOffset] = Cie.get();
Entries.emplace_back(std::move(Cie));
} else {
@@ -511,7 +519,7 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer,
InitialLocation, AddressRange,
- Cie, LSDAAddress));
+ Cie, LSDAAddress, Arch));
}
if (Error E =
diff --git a/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index 53a8e193ef56..1d621ff244f3 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -15,6 +15,7 @@
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
+#include "llvm/Support/Errc.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/WithColor.h"
@@ -273,24 +274,6 @@ parseV5DirFileTables(const DWARFDataExtractor &DebugLineData,
return true;
}
-template <typename... Ts>
-static std::string formatErrorString(char const *Fmt, const Ts &... Vals) {
- std::string Buffer;
- raw_string_ostream Stream(Buffer);
- Stream << format(Fmt, Vals...);
- return Stream.str();
-}
-
-template <typename... Ts>
-static Error createError(char const *Fmt, const Ts &... Vals) {
- return make_error<StringError>(formatErrorString(Fmt, Vals...),
- inconvertibleErrorCode());
-}
-
-static Error createError(char const *Msg) {
- return make_error<StringError>(Msg, inconvertibleErrorCode());
-}
-
Error DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData,
uint32_t *OffsetPtr,
const DWARFContext &Ctx,
@@ -303,14 +286,15 @@ Error DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData,
FormParams.Format = dwarf::DWARF64;
TotalLength = DebugLineData.getU64(OffsetPtr);
} else if (TotalLength >= 0xffffff00) {
- return createError(
+ return createStringError(errc::invalid_argument,
"parsing line table prologue at offset 0x%8.8" PRIx64
" unsupported reserved unit length found of value 0x%8.8" PRIx64,
PrologueOffset, TotalLength);
}
FormParams.Version = DebugLineData.getU16(OffsetPtr);
if (getVersion() < 2)
- return createError("parsing line table prologue at offset 0x%8.8" PRIx64
+ return createStringError(errc::not_supported,
+ "parsing line table prologue at offset 0x%8.8" PRIx64
" found unsupported version 0x%2.2" PRIx16,
PrologueOffset, getVersion());
@@ -342,7 +326,7 @@ Error DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData,
if (!parseV5DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset,
FormParams, Ctx, U, ContentTypes,
IncludeDirectories, FileNames)) {
- return createError(
+ return createStringError(errc::invalid_argument,
"parsing line table prologue at 0x%8.8" PRIx64
" found an invalid directory or file table description at"
" 0x%8.8" PRIx64,
@@ -353,7 +337,8 @@ Error DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData,
ContentTypes, IncludeDirectories, FileNames);
if (*OffsetPtr != EndPrologueOffset)
- return createError("parsing line table prologue at 0x%8.8" PRIx64
+ return createStringError(errc::invalid_argument,
+ "parsing line table prologue at 0x%8.8" PRIx64
" should have ended at 0x%8.8" PRIx64
" but it ended at 0x%8.8" PRIx64,
PrologueOffset, EndPrologueOffset, (uint64_t)*OffsetPtr);
@@ -470,7 +455,7 @@ Expected<const DWARFDebugLine::LineTable *> DWARFDebugLine::getOrParseLineTable(
DWARFDataExtractor &DebugLineData, uint32_t Offset, const DWARFContext &Ctx,
const DWARFUnit *U, std::function<void(Error)> RecoverableErrorCallback) {
if (!DebugLineData.isValidOffset(Offset))
- return createError("offset 0x%8.8" PRIx32
+ return createStringError(errc::invalid_argument, "offset 0x%8.8" PRIx32
" is not a valid debug line section offset",
Offset);
@@ -575,7 +560,8 @@ Error DWARFDebugLine::LineTable::parse(
if (DebugLineData.getAddressSize() == 0)
DebugLineData.setAddressSize(Len - 1);
else if (DebugLineData.getAddressSize() != Len - 1) {
- return createError("mismatching address size at offset 0x%8.8" PRIx32
+ return createStringError(errc::invalid_argument,
+ "mismatching address size at offset 0x%8.8" PRIx32
" expected 0x%2.2" PRIx8 " found 0x%2.2" PRIx64,
ExtOffset, DebugLineData.getAddressSize(),
Len - 1);
@@ -640,7 +626,8 @@ Error DWARFDebugLine::LineTable::parse(
// Make sure the stated and parsed lengths are the same.
// Otherwise we have an unparseable line-number program.
if (*OffsetPtr - ExtOffset != Len)
- return createError("unexpected line op length at offset 0x%8.8" PRIx32
+ return createStringError(errc::illegal_byte_sequence,
+ "unexpected line op length at offset 0x%8.8" PRIx32
" expected 0x%2.2" PRIx64 " found 0x%2.2" PRIx32,
ExtOffset, Len, *OffsetPtr - ExtOffset);
} else if (Opcode < Prologue.OpcodeBase) {
@@ -847,11 +834,12 @@ Error DWARFDebugLine::LineTable::parse(
if (!State.Sequence.Empty)
RecoverableErrorCallback(
- createError("last sequence in debug line table is not terminated!"));
+ createStringError(errc::illegal_byte_sequence,
+ "last sequence in debug line table is not terminated!"));
// Sort all sequences so that address lookup will work faster.
if (!Sequences.empty()) {
- llvm::sort(Sequences.begin(), Sequences.end(), Sequence::orderByLowPC);
+ llvm::sort(Sequences, Sequence::orderByLowPC);
// Note: actually, instruction address ranges of sequences should not
// overlap (in shared objects and executables). If they do, the address
// lookup would still work, though, but result would be ambiguous.
@@ -1047,17 +1035,16 @@ bool DWARFDebugLine::LineTable::getFileLineInfoForAddress(
// line-table section.
static DWARFDebugLine::SectionParser::LineToUnitMap
buildLineToUnitMap(DWARFDebugLine::SectionParser::cu_range CUs,
- DWARFDebugLine::SectionParser::tu_range TUSections) {
+ DWARFDebugLine::SectionParser::tu_range TUs) {
DWARFDebugLine::SectionParser::LineToUnitMap LineToUnit;
for (const auto &CU : CUs)
if (auto CUDIE = CU->getUnitDIE())
if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list)))
LineToUnit.insert(std::make_pair(*StmtOffset, &*CU));
- for (const auto &TUS : TUSections)
- for (const auto &TU : TUS)
- if (auto TUDIE = TU->getUnitDIE())
- if (auto StmtOffset = toSectionOffset(TUDIE.find(DW_AT_stmt_list)))
- LineToUnit.insert(std::make_pair(*StmtOffset, &*TU));
+ for (const auto &TU : TUs)
+ if (auto TUDIE = TU->getUnitDIE())
+ if (auto StmtOffset = toSectionOffset(TUDIE.find(DW_AT_stmt_list)))
+ LineToUnit.insert(std::make_pair(*StmtOffset, &*TU));
return LineToUnit;
}
@@ -1125,9 +1112,3 @@ void DWARFDebugLine::SectionParser::moveToNextTable(uint32_t OldOffset,
Done = true;
}
}
-
-void DWARFDebugLine::warn(Error Err) {
- handleAllErrors(std::move(Err), [](ErrorInfoBase &Info) {
- WithColor::warning() << Info.message() << '\n';
- });
-}
diff --git a/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
index 617b914ecce9..f8b5ff6ec8fb 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
@@ -124,7 +124,7 @@ DWARFDebugLoc::parseOneLocationList(DWARFDataExtractor Data, unsigned *Offset) {
StringRef str = Data.getData().substr(*Offset, Bytes);
*Offset += Bytes;
E.Loc.reserve(str.size());
- std::copy(str.begin(), str.end(), std::back_inserter(E.Loc));
+ llvm::copy(str, std::back_inserter(E.Loc));
LL.Entries.push_back(std::move(E));
}
}
@@ -144,51 +144,74 @@ void DWARFDebugLoc::parse(const DWARFDataExtractor &data) {
WithColor::error() << "failed to consume entire .debug_loc section\n";
}
-Optional<DWARFDebugLocDWO::LocationList>
-DWARFDebugLocDWO::parseOneLocationList(DataExtractor Data, unsigned *Offset) {
+Optional<DWARFDebugLoclists::LocationList>
+DWARFDebugLoclists::parseOneLocationList(DataExtractor Data, unsigned *Offset,
+ unsigned Version) {
LocationList LL;
LL.Offset = *Offset;
// dwarf::DW_LLE_end_of_list_entry is 0 and indicates the end of the list.
while (auto Kind =
static_cast<dwarf::LocationListEntry>(Data.getU8(Offset))) {
- if (Kind != dwarf::DW_LLE_startx_length) {
+
+ Entry E;
+ E.Kind = Kind;
+ switch (Kind) {
+ case dwarf::DW_LLE_startx_length:
+ E.Value0 = Data.getULEB128(Offset);
+ // Pre-DWARF 5 has different interpretation of the length field. We have
+ // to support both pre- and standartized styles for the compatibility.
+ if (Version < 5)
+ E.Value1 = Data.getU32(Offset);
+ else
+ E.Value1 = Data.getULEB128(Offset);
+ break;
+ case dwarf::DW_LLE_start_length:
+ E.Value0 = Data.getAddress(Offset);
+ E.Value1 = Data.getULEB128(Offset);
+ break;
+ case dwarf::DW_LLE_offset_pair:
+ E.Value0 = Data.getULEB128(Offset);
+ E.Value1 = Data.getULEB128(Offset);
+ break;
+ case dwarf::DW_LLE_base_address:
+ E.Value0 = Data.getAddress(Offset);
+ break;
+ default:
WithColor::error() << "dumping support for LLE of kind " << (int)Kind
<< " not implemented\n";
return None;
}
- Entry E;
- E.Start = Data.getULEB128(Offset);
- E.Length = Data.getU32(Offset);
-
- unsigned Bytes = Data.getU16(Offset);
- // A single location description describing the location of the object...
- StringRef str = Data.getData().substr(*Offset, Bytes);
- *Offset += Bytes;
- E.Loc.resize(str.size());
- std::copy(str.begin(), str.end(), E.Loc.begin());
+ if (Kind != dwarf::DW_LLE_base_address) {
+ unsigned Bytes = Data.getU16(Offset);
+ // A single location description describing the location of the object...
+ StringRef str = Data.getData().substr(*Offset, Bytes);
+ *Offset += Bytes;
+ E.Loc.resize(str.size());
+ llvm::copy(str, E.Loc.begin());
+ }
LL.Entries.push_back(std::move(E));
}
return LL;
}
-void DWARFDebugLocDWO::parse(DataExtractor data) {
+void DWARFDebugLoclists::parse(DataExtractor data, unsigned Version) {
IsLittleEndian = data.isLittleEndian();
AddressSize = data.getAddressSize();
uint32_t Offset = 0;
while (data.isValidOffset(Offset)) {
- if (auto LL = parseOneLocationList(data, &Offset))
+ if (auto LL = parseOneLocationList(data, &Offset, Version))
Locations.push_back(std::move(*LL));
else
return;
}
}
-DWARFDebugLocDWO::LocationList const *
-DWARFDebugLocDWO::getLocationListAtOffset(uint64_t Offset) const {
+DWARFDebugLoclists::LocationList const *
+DWARFDebugLoclists::getLocationListAtOffset(uint64_t Offset) const {
auto It = std::lower_bound(
Locations.begin(), Locations.end(), Offset,
[](const LocationList &L, uint64_t Offset) { return L.Offset < Offset; });
@@ -197,23 +220,49 @@ DWARFDebugLocDWO::getLocationListAtOffset(uint64_t Offset) const {
return nullptr;
}
-void DWARFDebugLocDWO::LocationList::dump(raw_ostream &OS, bool IsLittleEndian,
- unsigned AddressSize,
- const MCRegisterInfo *MRI,
- unsigned Indent) const {
+void DWARFDebugLoclists::LocationList::dump(raw_ostream &OS, uint64_t BaseAddr,
+ bool IsLittleEndian,
+ unsigned AddressSize,
+ const MCRegisterInfo *MRI,
+ unsigned Indent) const {
for (const Entry &E : Entries) {
- OS << '\n';
- OS.indent(Indent);
- OS << "Addr idx " << E.Start << " (w/ length " << E.Length << "): ";
+ switch (E.Kind) {
+ case dwarf::DW_LLE_startx_length:
+ OS << '\n';
+ OS.indent(Indent);
+ OS << "Addr idx " << E.Value0 << " (w/ length " << E.Value1 << "): ";
+ break;
+ case dwarf::DW_LLE_start_length:
+ OS << '\n';
+ OS.indent(Indent);
+ OS << format("[0x%*.*" PRIx64 ", 0x%*.*" PRIx64 "): ", AddressSize * 2,
+ AddressSize * 2, E.Value0, AddressSize * 2, AddressSize * 2,
+ E.Value0 + E.Value1);
+ break;
+ case dwarf::DW_LLE_offset_pair:
+ OS << '\n';
+ OS.indent(Indent);
+ OS << format("[0x%*.*" PRIx64 ", 0x%*.*" PRIx64 "): ", AddressSize * 2,
+ AddressSize * 2, BaseAddr + E.Value0, AddressSize * 2,
+ AddressSize * 2, BaseAddr + E.Value1);
+ break;
+ case dwarf::DW_LLE_base_address:
+ BaseAddr = E.Value0;
+ break;
+ default:
+ llvm_unreachable("unreachable locations list kind");
+ }
+
dumpExpression(OS, E.Loc, IsLittleEndian, AddressSize, MRI);
}
}
-void DWARFDebugLocDWO::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
- Optional<uint64_t> Offset) const {
+void DWARFDebugLoclists::dump(raw_ostream &OS, uint64_t BaseAddr,
+ const MCRegisterInfo *MRI,
+ Optional<uint64_t> Offset) const {
auto DumpLocationList = [&](const LocationList &L) {
OS << format("0x%8.8x: ", L.Offset);
- L.dump(OS, IsLittleEndian, AddressSize, MRI, /*Indent=*/12);
+ L.dump(OS, BaseAddr, IsLittleEndian, AddressSize, MRI, /*Indent=*/12);
OS << "\n\n";
};
diff --git a/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp b/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp
index de8b6e543fab..abd1ad59a9c1 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Support/DataExtractor.h"
@@ -18,10 +19,11 @@
using namespace llvm;
using namespace dwarf;
-DWARFDebugPubTable::DWARFDebugPubTable(StringRef Data, bool LittleEndian,
- bool GnuStyle)
+DWARFDebugPubTable::DWARFDebugPubTable(const DWARFObject &Obj,
+ const DWARFSection &Sec,
+ bool LittleEndian, bool GnuStyle)
: GnuStyle(GnuStyle) {
- DataExtractor PubNames(Data, LittleEndian, 0);
+ DWARFDataExtractor PubNames(Obj, Sec, LittleEndian, 0);
uint32_t Offset = 0;
while (PubNames.isValidOffset(Offset)) {
Sets.push_back({});
@@ -29,10 +31,10 @@ DWARFDebugPubTable::DWARFDebugPubTable(StringRef Data, bool LittleEndian,
SetData.Length = PubNames.getU32(&Offset);
SetData.Version = PubNames.getU16(&Offset);
- SetData.Offset = PubNames.getU32(&Offset);
+ SetData.Offset = PubNames.getRelocatedValue(4, &Offset);
SetData.Size = PubNames.getU32(&Offset);
- while (Offset < Data.size()) {
+ while (Offset < Sec.Data.size()) {
uint32_t DieRef = PubNames.getU32(&Offset);
if (DieRef == 0)
break;
diff --git a/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp b/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
index a565718debd0..dfb913000a46 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
@@ -9,6 +9,7 @@
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/Support/Errc.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <cinttypes>
@@ -16,15 +17,6 @@
using namespace llvm;
-// FIXME: There are several versions of this. Consolidate them.
-template <typename... Ts>
-static Error createError(char const *Fmt, const Ts &... Vals) {
- std::string Buffer;
- raw_string_ostream Stream(Buffer);
- Stream << format(Fmt, Vals...);
- return make_error<StringError>(Stream.str(), inconvertibleErrorCode());
-}
-
void DWARFDebugRangeList::clear() {
Offset = -1U;
AddressSize = 0;
@@ -35,11 +27,13 @@ Error DWARFDebugRangeList::extract(const DWARFDataExtractor &data,
uint32_t *offset_ptr) {
clear();
if (!data.isValidOffset(*offset_ptr))
- return createError("invalid range list offset 0x%" PRIx32, *offset_ptr);
+ return createStringError(errc::invalid_argument,
+ "invalid range list offset 0x%" PRIx32, *offset_ptr);
AddressSize = data.getAddressSize();
if (AddressSize != 4 && AddressSize != 8)
- return createError("invalid address size: %d", AddressSize);
+ return createStringError(errc::invalid_argument,
+ "invalid address size: %" PRIu8, AddressSize);
Offset = *offset_ptr;
while (true) {
RangeListEntry Entry;
@@ -53,7 +47,8 @@ Error DWARFDebugRangeList::extract(const DWARFDataExtractor &data,
// Check that both values were extracted correctly.
if (*offset_ptr != prev_offset + 2 * AddressSize) {
clear();
- return createError("invalid range list entry at offset 0x%" PRIx32,
+ return createStringError(errc::invalid_argument,
+ "invalid range list entry at offset 0x%" PRIx32,
prev_offset);
}
if (Entry.isEndOfListEntry())
@@ -74,7 +69,7 @@ void DWARFDebugRangeList::dump(raw_ostream &OS) const {
}
DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges(
- llvm::Optional<BaseAddress> BaseAddr) const {
+ llvm::Optional<SectionedAddress> BaseAddr) const {
DWARFAddressRangesVector Res;
for (const RangeListEntry &RLE : Entries) {
if (RLE.isBaseAddressSelectionEntry(AddressSize)) {
diff --git a/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp b/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
index b19c808a8fb3..60c6eb30857f 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
@@ -10,28 +10,13 @@
#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
-template <typename... Ts>
-static Error createError(char const *Fmt, const Ts &... Vals) {
- std::string Buffer;
- raw_string_ostream Stream(Buffer);
- Stream << format(Fmt, Vals...);
- return make_error<StringError>(Stream.str(), inconvertibleErrorCode());
-}
-
-namespace llvm { // workaround for gcc bug
-template <>
-Error DWARFListType<RangeListEntry>::createError(const char *Fmt, const char *s,
- uint32_t Val) {
- return ::createError(Fmt, s, Val);
-}
-}
-
Error RangeListEntry::extract(DWARFDataExtractor Data, uint32_t End,
uint32_t *OffsetPtr) {
Offset = *OffsetPtr;
@@ -47,31 +32,49 @@ Error RangeListEntry::extract(DWARFDataExtractor Data, uint32_t End,
Value0 = Value1 = 0;
break;
// TODO: Support other encodings.
- case dwarf::DW_RLE_base_addressx:
- return createError("unsupported rnglists encoding DW_RLE_base_addressx "
- "at offset 0x%" PRIx32,
- *OffsetPtr - 1);
+ case dwarf::DW_RLE_base_addressx: {
+ uint32_t PreviousOffset = *OffsetPtr - 1;
+ Value0 = Data.getULEB128(OffsetPtr);
+ if (End < *OffsetPtr)
+ return createStringError(
+ errc::invalid_argument,
+ "read past end of table when reading "
+ "DW_RLE_base_addressx encoding at offset 0x%" PRIx32,
+ PreviousOffset);
+ break;
+ }
case dwarf::DW_RLE_startx_endx:
- return createError("unsupported rnglists encoding DW_RLE_startx_endx at "
+ return createStringError(errc::not_supported,
+ "unsupported rnglists encoding DW_RLE_startx_endx at "
"offset 0x%" PRIx32,
*OffsetPtr - 1);
- case dwarf::DW_RLE_startx_length:
- return createError("unsupported rnglists encoding DW_RLE_startx_length "
- "at offset 0x%" PRIx32,
- *OffsetPtr - 1);
+ case dwarf::DW_RLE_startx_length: {
+ uint32_t PreviousOffset = *OffsetPtr - 1;
+ Value0 = Data.getULEB128(OffsetPtr);
+ Value1 = Data.getULEB128(OffsetPtr);
+ if (End < *OffsetPtr)
+ return createStringError(
+ errc::invalid_argument,
+ "read past end of table when reading "
+ "DW_RLE_startx_length encoding at offset 0x%" PRIx32,
+ PreviousOffset);
+ break;
+ }
case dwarf::DW_RLE_offset_pair: {
uint32_t PreviousOffset = *OffsetPtr - 1;
Value0 = Data.getULEB128(OffsetPtr);
Value1 = Data.getULEB128(OffsetPtr);
if (End < *OffsetPtr)
- return createError("read past end of table when reading "
+ return createStringError(errc::invalid_argument,
+ "read past end of table when reading "
"DW_RLE_offset_pair encoding at offset 0x%" PRIx32,
PreviousOffset);
break;
}
case dwarf::DW_RLE_base_address: {
if ((End - *OffsetPtr) < Data.getAddressSize())
- return createError("insufficient space remaining in table for "
+ return createStringError(errc::invalid_argument,
+ "insufficient space remaining in table for "
"DW_RLE_base_address encoding at offset 0x%" PRIx32,
*OffsetPtr - 1);
Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex);
@@ -79,7 +82,8 @@ Error RangeListEntry::extract(DWARFDataExtractor Data, uint32_t End,
}
case dwarf::DW_RLE_start_end: {
if ((End - *OffsetPtr) < unsigned(Data.getAddressSize() * 2))
- return createError("insufficient space remaining in table for "
+ return createStringError(errc::invalid_argument,
+ "insufficient space remaining in table for "
"DW_RLE_start_end encoding "
"at offset 0x%" PRIx32,
*OffsetPtr - 1);
@@ -92,13 +96,15 @@ Error RangeListEntry::extract(DWARFDataExtractor Data, uint32_t End,
Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex);
Value1 = Data.getULEB128(OffsetPtr);
if (End < *OffsetPtr)
- return createError("read past end of table when reading "
+ return createStringError(errc::invalid_argument,
+ "read past end of table when reading "
"DW_RLE_start_length encoding at offset 0x%" PRIx32,
PreviousOffset);
break;
}
default:
- return createError("unknown rnglists encoding 0x%" PRIx32
+ return createStringError(errc::not_supported,
+ "unknown rnglists encoding 0x%" PRIx32
" at offset 0x%" PRIx32,
uint32_t(Encoding), *OffsetPtr - 1);
}
@@ -107,12 +113,19 @@ Error RangeListEntry::extract(DWARFDataExtractor Data, uint32_t End,
return Error::success();
}
-DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
- llvm::Optional<BaseAddress> BaseAddr) const {
+DWARFAddressRangesVector
+DWARFDebugRnglist::getAbsoluteRanges(llvm::Optional<SectionedAddress> BaseAddr,
+ DWARFUnit &U) const {
DWARFAddressRangesVector Res;
for (const RangeListEntry &RLE : Entries) {
if (RLE.EntryKind == dwarf::DW_RLE_end_of_list)
break;
+ if (RLE.EntryKind == dwarf::DW_RLE_base_addressx) {
+ BaseAddr = U.getAddrOffsetSectionItem(RLE.Value0);
+ if (!BaseAddr)
+ BaseAddr = {RLE.Value0, -1ULL};
+ continue;
+ }
if (RLE.EntryKind == dwarf::DW_RLE_base_address) {
BaseAddr = {RLE.Value0, RLE.SectionIndex};
continue;
@@ -140,6 +153,15 @@ DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
E.LowPC = RLE.Value0;
E.HighPC = E.LowPC + RLE.Value1;
break;
+ case dwarf::DW_RLE_startx_length: {
+ auto Start = U.getAddrOffsetSectionItem(RLE.Value0);
+ if (!Start)
+ Start = {0, -1ULL};
+ E.SectionIndex = Start->SectionIndex;
+ E.LowPC = Start->Address;
+ E.HighPC = E.LowPC + RLE.Value1;
+ break;
+ }
default:
// Unsupported encodings should have been reported during extraction,
// so we should not run into any here.
@@ -150,9 +172,11 @@ DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
return Res;
}
-void RangeListEntry::dump(raw_ostream &OS, uint8_t AddrSize,
- uint8_t MaxEncodingStringLength,
- uint64_t &CurrentBase, DIDumpOptions DumpOpts) const {
+void RangeListEntry::dump(
+ raw_ostream &OS, uint8_t AddrSize, uint8_t MaxEncodingStringLength,
+ uint64_t &CurrentBase, DIDumpOptions DumpOpts,
+ llvm::function_ref<Optional<SectionedAddress>(uint32_t)>
+ LookupPooledAddress) const {
auto PrintRawEntry = [](raw_ostream &OS, const RangeListEntry &Entry,
uint8_t AddrSize, DIDumpOptions DumpOpts) {
if (DumpOpts.Verbose) {
@@ -179,6 +203,17 @@ void RangeListEntry::dump(raw_ostream &OS, uint8_t AddrSize,
case dwarf::DW_RLE_end_of_list:
OS << (DumpOpts.Verbose ? "" : "<End of list>");
break;
+ // case dwarf::DW_RLE_base_addressx:
+ case dwarf::DW_RLE_base_addressx: {
+ if (auto SA = LookupPooledAddress(Value0))
+ CurrentBase = SA->Address;
+ else
+ CurrentBase = Value0;
+ if (!DumpOpts.Verbose)
+ return;
+ OS << format(" 0x%*.*" PRIx64, AddrSize * 2, AddrSize * 2, Value0);
+ break;
+ }
case dwarf::DW_RLE_base_address:
// In non-verbose mode we do not print anything for this entry.
CurrentBase = Value0;
@@ -198,6 +233,14 @@ void RangeListEntry::dump(raw_ostream &OS, uint8_t AddrSize,
case dwarf::DW_RLE_start_end:
DWARFAddressRange(Value0, Value1).dump(OS, AddrSize, DumpOpts);
break;
+ case dwarf::DW_RLE_startx_length: {
+ PrintRawEntry(OS, *this, AddrSize, DumpOpts);
+ uint64_t Start = 0;
+ if (auto SA = LookupPooledAddress(Value0))
+ Start = SA->Address;
+ DWARFAddressRange(Start, Start + Value1).dump(OS, AddrSize, DumpOpts);
+ break;
+ } break;
default:
llvm_unreachable("Unsupported range list encoding");
}
diff --git a/lib/DebugInfo/DWARF/DWARFDie.cpp b/lib/DebugInfo/DWARF/DWARFDie.cpp
index 904ceab7b286..81ef0c8c7aec 100644
--- a/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -59,25 +59,19 @@ static void dumpRanges(const DWARFObject &Obj, raw_ostream &OS,
const DWARFAddressRangesVector &Ranges,
unsigned AddressSize, unsigned Indent,
const DIDumpOptions &DumpOpts) {
+ if (!DumpOpts.ShowAddresses)
+ return;
+
ArrayRef<SectionName> SectionNames;
if (DumpOpts.Verbose)
SectionNames = Obj.getSectionNames();
for (const DWARFAddressRange &R : Ranges) {
-
OS << '\n';
OS.indent(Indent);
R.dump(OS, AddressSize);
- if (SectionNames.empty() || R.SectionIndex == -1ULL)
- continue;
-
- StringRef Name = SectionNames[R.SectionIndex].Name;
- OS << " \"" << Name << '\"';
-
- // Print section index if name is not unique.
- if (!SectionNames[R.SectionIndex].IsNameUnique)
- OS << format(" [%" PRIu64 "]", R.SectionIndex);
+ DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, R.SectionIndex);
}
}
@@ -99,27 +93,45 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue,
FormValue.dump(OS, DumpOpts);
if (FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) {
- const DWARFSection &LocSection = Obj.getLocSection();
- const DWARFSection &LocDWOSection = Obj.getLocDWOSection();
uint32_t Offset = *FormValue.getAsSectionOffset();
- if (!LocSection.Data.empty()) {
+ if (!U->isDWOUnit() && !U->getLocSection()->Data.empty()) {
DWARFDebugLoc DebugLoc;
- DWARFDataExtractor Data(Obj, LocSection, Ctx.isLittleEndian(),
+ DWARFDataExtractor Data(Obj, *U->getLocSection(), Ctx.isLittleEndian(),
Obj.getAddressSize());
auto LL = DebugLoc.parseOneLocationList(Data, &Offset);
if (LL) {
uint64_t BaseAddr = 0;
- if (Optional<BaseAddress> BA = U->getBaseAddress())
+ if (Optional<SectionedAddress> BA = U->getBaseAddress())
BaseAddr = BA->Address;
LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, BaseAddr,
Indent);
} else
OS << "error extracting location list.";
- } else if (!LocDWOSection.Data.empty()) {
- DataExtractor Data(LocDWOSection.Data, Ctx.isLittleEndian(), 0);
- auto LL = DWARFDebugLocDWO::parseOneLocationList(Data, &Offset);
+ return;
+ }
+
+ bool UseLocLists = !U->isDWOUnit();
+ StringRef LoclistsSectionData =
+ UseLocLists ? Obj.getLoclistsSection().Data : U->getLocSectionData();
+
+ if (!LoclistsSectionData.empty()) {
+ DataExtractor Data(LoclistsSectionData, Ctx.isLittleEndian(),
+ Obj.getAddressSize());
+
+ // Old-style location list were used in DWARF v4 (.debug_loc.dwo section).
+ // Modern locations list (.debug_loclists) are used starting from v5.
+ // Ideally we should take the version from the .debug_loclists section
+ // header, but using CU's version for simplicity.
+ auto LL = DWARFDebugLoclists::parseOneLocationList(
+ Data, &Offset, UseLocLists ? U->getVersion() : 4);
+
+ uint64_t BaseAddr = 0;
+ if (Optional<SectionedAddress> BA = U->getBaseAddress())
+ BaseAddr = BA->Address;
+
if (LL)
- LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, Indent);
+ LL->dump(OS, BaseAddr, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI,
+ Indent);
else
OS << "error extracting location list.";
}
@@ -134,10 +146,54 @@ static void dumpTypeTagName(raw_ostream &OS, dwarf::Tag T) {
OS << TagStr.substr(7, TagStr.size() - 12) << " ";
}
-/// Recursively dump the DIE type name when applicable.
-static void dumpTypeName(raw_ostream &OS, const DWARFDie &Die) {
- DWARFDie D = Die.getAttributeValueAsReferencedDie(DW_AT_type);
+static void dumpArrayType(raw_ostream &OS, const DWARFDie &D) {
+ Optional<uint64_t> Bound;
+ for (const DWARFDie &C : D.children())
+ if (C.getTag() == DW_TAG_subrange_type) {
+ Optional<uint64_t> LB;
+ Optional<uint64_t> Count;
+ Optional<uint64_t> UB;
+ Optional<unsigned> DefaultLB;
+ if (Optional<DWARFFormValue> L = C.find(DW_AT_lower_bound))
+ LB = L->getAsUnsignedConstant();
+ if (Optional<DWARFFormValue> CountV = C.find(DW_AT_count))
+ Count = CountV->getAsUnsignedConstant();
+ if (Optional<DWARFFormValue> UpperV = C.find(DW_AT_upper_bound))
+ UB = UpperV->getAsUnsignedConstant();
+ if (Optional<DWARFFormValue> LV =
+ D.getDwarfUnit()->getUnitDIE().find(DW_AT_language))
+ if (Optional<uint64_t> LC = LV->getAsUnsignedConstant())
+ if ((DefaultLB =
+ LanguageLowerBound(static_cast<dwarf::SourceLanguage>(*LC))))
+ if (LB && *LB == *DefaultLB)
+ LB = None;
+ if (!LB && !Count && !UB)
+ OS << "[]";
+ else if (!LB && (Count || UB) && DefaultLB)
+ OS << '[' << (Count ? *Count : *UB - *DefaultLB + 1) << ']';
+ else {
+ OS << "[[";
+ if (LB)
+ OS << *LB;
+ else
+ OS << '?';
+ OS << ", ";
+ if (Count)
+ if (LB)
+ OS << *LB + *Count;
+ else
+ OS << "? + " << *Count;
+ else if (UB)
+ OS << *UB + 1;
+ else
+ OS << '?';
+ OS << ")]";
+ }
+ }
+}
+/// Recursively dump the DIE type name when applicable.
+static void dumpTypeName(raw_ostream &OS, const DWARFDie &D) {
if (!D.isValid())
return;
@@ -155,22 +211,46 @@ static void dumpTypeName(raw_ostream &OS, const DWARFDie &Die) {
case DW_TAG_ptr_to_member_type:
case DW_TAG_reference_type:
case DW_TAG_rvalue_reference_type:
+ case DW_TAG_subroutine_type:
break;
default:
dumpTypeTagName(OS, T);
}
// Follow the DW_AT_type if possible.
- dumpTypeName(OS, D);
+ DWARFDie TypeDie = D.getAttributeValueAsReferencedDie(DW_AT_type);
+ dumpTypeName(OS, TypeDie);
switch (T) {
- case DW_TAG_array_type:
- OS << "[]";
+ case DW_TAG_subroutine_type: {
+ if (!TypeDie)
+ OS << "void";
+ OS << '(';
+ bool First = true;
+ for (const DWARFDie &C : D.children()) {
+ if (C.getTag() == DW_TAG_formal_parameter) {
+ if (!First)
+ OS << ", ";
+ First = false;
+ dumpTypeName(OS, C.getAttributeValueAsReferencedDie(DW_AT_type));
+ }
+ }
+ OS << ')';
+ break;
+ }
+ case DW_TAG_array_type: {
+ dumpArrayType(OS, D);
break;
+ }
case DW_TAG_pointer_type:
OS << '*';
break;
case DW_TAG_ptr_to_member_type:
+ if (DWARFDie Cont =
+ D.getAttributeValueAsReferencedDie(DW_AT_containing_type)) {
+ dumpTypeName(OS << ' ', Cont);
+ OS << "::";
+ }
OS << '*';
break;
case DW_TAG_reference_type:
@@ -244,16 +324,19 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
else
formValue.dump(OS, DumpOpts);
+ std::string Space = DumpOpts.ShowAddresses ? " " : "";
+
// We have dumped the attribute raw value. For some attributes
// having both the raw value and the pretty-printed value is
// interesting. These attributes are handled below.
if (Attr == DW_AT_specification || Attr == DW_AT_abstract_origin) {
- if (const char *Name = Die.getAttributeValueAsReferencedDie(Attr).getName(
- DINameKind::LinkageName))
- OS << " \"" << Name << '\"';
+ if (const char *Name =
+ Die.getAttributeValueAsReferencedDie(formValue).getName(
+ DINameKind::LinkageName))
+ OS << Space << "\"" << Name << '\"';
} else if (Attr == DW_AT_type) {
- OS << " \"";
- dumpTypeName(OS, Die);
+ OS << Space << "\"";
+ dumpTypeName(OS, Die.getAttributeValueAsReferencedDie(formValue));
OS << '"';
} else if (Attr == DW_AT_APPLE_property_attribute) {
if (Optional<uint64_t> OptVal = formValue.getAsUnsignedConstant())
@@ -262,10 +345,9 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
const DWARFObject &Obj = Die.getDwarfUnit()->getContext().getDWARFObj();
// For DW_FORM_rnglistx we need to dump the offset separately, since
// we have only dumped the index so far.
- Optional<DWARFFormValue> Value = Die.find(DW_AT_ranges);
- if (Value && Value->getForm() == DW_FORM_rnglistx)
+ if (formValue.getForm() == DW_FORM_rnglistx)
if (auto RangeListOffset =
- U->getRnglistOffset(*Value->getAsSectionOffset())) {
+ U->getRnglistOffset(*formValue.getAsSectionOffset())) {
DWARFFormValue FV(dwarf::DW_FORM_sec_offset);
FV.setUValue(*RangeListOffset);
FV.dump(OS, DumpOpts);
@@ -349,8 +431,15 @@ DWARFDie::findRecursively(ArrayRef<dwarf::Attribute> Attrs) const {
DWARFDie
DWARFDie::getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const {
- if (auto SpecRef = toReference(find(Attr))) {
- if (auto SpecUnit = U->getUnitSection().getUnitForOffset(*SpecRef))
+ if (Optional<DWARFFormValue> F = find(Attr))
+ return getAttributeValueAsReferencedDie(*F);
+ return DWARFDie();
+}
+
+DWARFDie
+DWARFDie::getAttributeValueAsReferencedDie(const DWARFFormValue &V) const {
+ if (auto SpecRef = toReference(V)) {
+ if (auto SpecUnit = U->getUnitVector().getUnitForOffset(*SpecRef))
return SpecUnit->getDIEForOffset(*SpecRef);
}
return DWARFDie();
@@ -377,13 +466,13 @@ Optional<uint64_t> DWARFDie::getHighPC(uint64_t LowPC) const {
bool DWARFDie::getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC,
uint64_t &SectionIndex) const {
auto F = find(DW_AT_low_pc);
- auto LowPcAddr = toAddress(F);
+ auto LowPcAddr = toSectionedAddress(F);
if (!LowPcAddr)
return false;
- if (auto HighPcAddr = getHighPC(*LowPcAddr)) {
- LowPC = *LowPcAddr;
+ if (auto HighPcAddr = getHighPC(LowPcAddr->Address)) {
+ LowPC = LowPcAddr->Address;
HighPC = *HighPcAddr;
- SectionIndex = F->getSectionIndex();
+ SectionIndex = LowPcAddr->SectionIndex;
return true;
}
return false;
diff --git a/lib/DebugInfo/DWARF/DWARFExpression.cpp b/lib/DebugInfo/DWARF/DWARFExpression.cpp
index a9ea26c476ca..2df4456053fb 100644
--- a/lib/DebugInfo/DWARF/DWARFExpression.cpp
+++ b/lib/DebugInfo/DWARF/DWARFExpression.cpp
@@ -94,6 +94,7 @@ static DescVector getDescriptions() {
Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeBlock);
Descriptions[DW_OP_stack_value] = Desc(Op::Dwarf3);
Descriptions[DW_OP_GNU_push_tls_address] = Desc(Op::Dwarf3);
+ Descriptions[DW_OP_addrx] = Desc(Op::Dwarf4, Op::SizeLEB);
Descriptions[DW_OP_GNU_addr_index] = Desc(Op::Dwarf4, Op::SizeLEB);
Descriptions[DW_OP_GNU_const_index] = Desc(Op::Dwarf4, Op::SizeLEB);
return Descriptions;
diff --git a/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/lib/DebugInfo/DWARF/DWARFFormValue.cpp
index 1aa43c6b6517..7719fea63120 100644
--- a/lib/DebugInfo/DWARF/DWARFFormValue.cpp
+++ b/lib/DebugInfo/DWARF/DWARFFormValue.cpp
@@ -308,6 +308,7 @@ bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
break;
case DW_FORM_GNU_addr_index:
case DW_FORM_GNU_str_index:
+ case DW_FORM_addrx:
case DW_FORM_strx:
Value.uval = Data.getULEB128(OffsetPtr);
break;
@@ -330,6 +331,29 @@ bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
return true;
}
+void DWARFFormValue::dumpSectionedAddress(raw_ostream &OS,
+ DIDumpOptions DumpOpts,
+ SectionedAddress SA) const {
+ OS << format("0x%016" PRIx64, SA.Address);
+ dumpAddressSection(U->getContext().getDWARFObj(), OS, DumpOpts,
+ SA.SectionIndex);
+}
+
+void DWARFFormValue::dumpAddressSection(const DWARFObject &Obj, raw_ostream &OS,
+ DIDumpOptions DumpOpts,
+ uint64_t SectionIndex) {
+ if (!DumpOpts.Verbose || SectionIndex == -1ULL)
+ return;
+ ArrayRef<SectionName> SectionNames = Obj.getSectionNames();
+ const auto &SecRef = SectionNames[SectionIndex];
+
+ OS << " \"" << SecRef.Name << '\"';
+
+ // Print section index if name is not unique.
+ if (!SecRef.IsNameUnique)
+ OS << format(" [%" PRIu64 "]", SectionIndex);
+}
+
void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
uint64_t UValue = Value.uval;
bool CURelativeOffset = false;
@@ -338,15 +362,21 @@ void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
: nulls();
switch (Form) {
case DW_FORM_addr:
- AddrOS << format("0x%016" PRIx64, UValue);
+ dumpSectionedAddress(AddrOS, DumpOpts, {Value.uval, Value.SectionIndex});
break;
+ case DW_FORM_addrx:
+ case DW_FORM_addrx1:
+ case DW_FORM_addrx2:
+ case DW_FORM_addrx3:
+ case DW_FORM_addrx4:
case DW_FORM_GNU_addr_index: {
- AddrOS << format(" indexed (%8.8x) address = ", (uint32_t)UValue);
- uint64_t Address;
+ Optional<SectionedAddress> A = U->getAddrOffsetSectionItem(UValue);
+ if (!A || DumpOpts.Verbose)
+ AddrOS << format("indexed (%8.8x) address = ", (uint32_t)UValue);
if (U == nullptr)
OS << "<invalid dwarf unit>";
- else if (U->getAddrOffsetSectionItem(UValue, Address))
- AddrOS << format("0x%016" PRIx64, Address);
+ else if (A)
+ dumpSectionedAddress(AddrOS, DumpOpts, *A);
else
OS << "<no .debug_addr section>";
break;
@@ -387,16 +417,16 @@ void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
switch (Form) {
case DW_FORM_exprloc:
case DW_FORM_block:
- OS << format("<0x%" PRIx64 "> ", UValue);
+ AddrOS << format("<0x%" PRIx64 "> ", UValue);
break;
case DW_FORM_block1:
- OS << format("<0x%2.2x> ", (uint8_t)UValue);
+ AddrOS << format("<0x%2.2x> ", (uint8_t)UValue);
break;
case DW_FORM_block2:
- OS << format("<0x%4.4x> ", (uint16_t)UValue);
+ AddrOS << format("<0x%4.4x> ", (uint16_t)UValue);
break;
case DW_FORM_block4:
- OS << format("<0x%8.8x> ", (uint32_t)UValue);
+ AddrOS << format("<0x%8.8x> ", (uint32_t)UValue);
break;
default:
break;
@@ -407,7 +437,7 @@ void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
// UValue contains size of block
const uint8_t *EndDataPtr = DataPtr + UValue;
while (DataPtr < EndDataPtr) {
- OS << format("%2.2x ", *DataPtr);
+ AddrOS << format("%2.2x ", *DataPtr);
++DataPtr;
}
} else
@@ -438,7 +468,7 @@ void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
case DW_FORM_strx4:
case DW_FORM_GNU_str_index:
if (DumpOpts.Verbose)
- OS << format(" indexed (%8.8x) string = ", (uint32_t)UValue);
+ OS << format("indexed (%8.8x) string = ", (uint32_t)UValue);
dumpString(OS);
break;
case DW_FORM_GNU_strp_alt:
@@ -501,8 +531,9 @@ void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
if (CURelativeOffset) {
if (DumpOpts.Verbose)
OS << " => {";
- WithColor(OS, HighlightColor::Address).get()
- << format("0x%8.8" PRIx64, UValue + (U ? U->getOffset() : 0));
+ if (DumpOpts.ShowAddresses)
+ WithColor(OS, HighlightColor::Address).get()
+ << format("0x%8.8" PRIx64, UValue + (U ? U->getOffset() : 0));
if (DumpOpts.Verbose)
OS << "}";
}
@@ -536,10 +567,12 @@ Optional<const char *> DWARFFormValue::getAsCString() const {
if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx ||
Form == DW_FORM_strx1 || Form == DW_FORM_strx2 || Form == DW_FORM_strx3 ||
Form == DW_FORM_strx4) {
- uint64_t StrOffset;
- if (!U || !U->getStringOffsetSectionItem(Offset, StrOffset))
+ if (!U)
+ return None;
+ Optional<uint64_t> StrOffset = U->getStringOffsetSectionItem(Offset);
+ if (!StrOffset)
return None;
- Offset = StrOffset;
+ Offset = *StrOffset;
}
// Prefer the Unit's string extractor, because for .dwo it will point to
// .debug_str.dwo, while the Context's extractor always uses .debug_str.
@@ -554,16 +587,23 @@ Optional<const char *> DWARFFormValue::getAsCString() const {
}
Optional<uint64_t> DWARFFormValue::getAsAddress() const {
+ if (auto SA = getAsSectionedAddress())
+ return SA->Address;
+ return None;
+}
+Optional<SectionedAddress> DWARFFormValue::getAsSectionedAddress() const {
if (!isFormClass(FC_Address))
return None;
- if (Form == DW_FORM_GNU_addr_index) {
+ if (Form == DW_FORM_GNU_addr_index || Form == DW_FORM_addrx) {
uint32_t Index = Value.uval;
- uint64_t Result;
- if (!U || !U->getAddrOffsetSectionItem(Index, Result))
+ if (!U)
+ return None;
+ Optional<SectionedAddress> SA = U->getAddrOffsetSectionItem(Index);
+ if (!SA)
return None;
- return Result;
+ return SA;
}
- return Value.uval;
+ return {{Value.uval, Value.SectionIndex}};
}
Optional<uint64_t> DWARFFormValue::getAsReference() const {
diff --git a/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp b/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
index ebd6104ab878..1abd931e3b8b 100644
--- a/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
+++ b/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
@@ -11,6 +11,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
@@ -33,6 +34,16 @@ void DWARFGdbIndex::dumpCUList(raw_ostream &OS) const {
CU.Length);
}
+void DWARFGdbIndex::dumpTUList(raw_ostream &OS) const {
+ OS << formatv("\n Types CU list offset = {0:x}, has {1} entries:\n",
+ TuListOffset, TuList.size());
+ uint32_t I = 0;
+ for (const TypeUnitEntry &TU : TuList)
+ OS << formatv(" {0}: offset = {1:x8}, type_offset = {2:x8}, "
+ "type_signature = {3:x16}\n",
+ I++, TU.Offset, TU.TypeOffset, TU.TypeSignature);
+}
+
void DWARFGdbIndex::dumpAddressArea(raw_ostream &OS) const {
OS << format("\n Address area offset = 0x%x, has %" PRId64 " entries:",
AddressAreaOffset, (uint64_t)AddressArea.size())
@@ -94,6 +105,7 @@ void DWARFGdbIndex::dump(raw_ostream &OS) {
if (HasContent) {
OS << " Version = " << Version << '\n';
dumpCUList(OS);
+ dumpTUList(OS);
dumpAddressArea(OS);
dumpSymbolTable(OS);
dumpConstantPool(OS);
@@ -127,9 +139,14 @@ bool DWARFGdbIndex::parseImpl(DataExtractor Data) {
// CU Types are no longer needed as DWARF skeleton type units never made it
// into the standard.
- uint32_t CuTypesListSize = (AddressAreaOffset - CuTypesOffset) / 24;
- if (CuTypesListSize != 0)
- return false;
+ uint32_t TuListSize = (AddressAreaOffset - CuTypesOffset) / 24;
+ TuList.resize(TuListSize);
+ for (uint32_t I = 0; I < TuListSize; ++I) {
+ uint64_t CuOffset = Data.getU64(&Offset);
+ uint64_t TypeOffset = Data.getU64(&Offset);
+ uint64_t Signature = Data.getU64(&Offset);
+ TuList[I] = {CuOffset, TypeOffset, Signature};
+ }
uint32_t AddressAreaSize = (SymbolTableOffset - AddressAreaOffset) / 20;
AddressArea.reserve(AddressAreaSize);
diff --git a/lib/DebugInfo/DWARF/DWARFListTable.cpp b/lib/DebugInfo/DWARF/DWARFListTable.cpp
index 559afc7559bd..462c036d73ad 100644
--- a/lib/DebugInfo/DWARF/DWARFListTable.cpp
+++ b/lib/DebugInfo/DWARF/DWARFListTable.cpp
@@ -9,42 +9,39 @@
#include "llvm/DebugInfo/DWARF/DWARFListTable.h"
#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
-template <typename... Ts>
-static Error createError(char const *Fmt, const Ts &... Vals) {
- std::string Buffer;
- raw_string_ostream Stream(Buffer);
- Stream << format(Fmt, Vals...);
- return make_error<StringError>(Stream.str(), inconvertibleErrorCode());
-}
-
Error DWARFListTableHeader::extract(DWARFDataExtractor Data,
uint32_t *OffsetPtr) {
HeaderOffset = *OffsetPtr;
// Read and verify the length field.
if (!Data.isValidOffsetForDataOfSize(*OffsetPtr, sizeof(uint32_t)))
- return createError("section is not large enough to contain a "
+ return createStringError(errc::invalid_argument,
+ "section is not large enough to contain a "
"%s table length at offset 0x%" PRIx32,
SectionName.data(), *OffsetPtr);
// TODO: Add support for DWARF64.
HeaderData.Length = Data.getU32(OffsetPtr);
if (HeaderData.Length == 0xffffffffu)
- return createError("DWARF64 is not supported in %s at offset 0x%" PRIx32,
+ return createStringError(errc::not_supported,
+ "DWARF64 is not supported in %s at offset 0x%" PRIx32,
SectionName.data(), HeaderOffset);
Format = dwarf::DwarfFormat::DWARF32;
if (HeaderData.Length + sizeof(uint32_t) < sizeof(Header))
- return createError("%s table at offset 0x%" PRIx32
+ return createStringError(errc::invalid_argument,
+ "%s table at offset 0x%" PRIx32
" has too small length (0x%" PRIx32
") to contain a complete header",
SectionName.data(), HeaderOffset, length());
uint32_t End = HeaderOffset + length();
if (!Data.isValidOffsetForDataOfSize(HeaderOffset, End - HeaderOffset))
- return createError("section is not large enough to contain a %s table "
+ return createStringError(errc::invalid_argument,
+ "section is not large enough to contain a %s table "
"of length 0x%" PRIx32 " at offset 0x%" PRIx32,
SectionName.data(), length(), HeaderOffset);
@@ -55,20 +52,23 @@ Error DWARFListTableHeader::extract(DWARFDataExtractor Data,
// Perform basic validation of the remaining header fields.
if (HeaderData.Version != 5)
- return createError("unrecognised %s table version %" PRIu16
+ return createStringError(errc::invalid_argument,
+ "unrecognised %s table version %" PRIu16
" in table at offset 0x%" PRIx32,
SectionName.data(), HeaderData.Version, HeaderOffset);
if (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8)
- return createError("%s table at offset 0x%" PRIx32
- " has unsupported address size %hhu",
+ return createStringError(errc::not_supported,
+ "%s table at offset 0x%" PRIx32
+ " has unsupported address size %" PRIu8,
SectionName.data(), HeaderOffset, HeaderData.AddrSize);
if (HeaderData.SegSize != 0)
- return createError("%s table at offset 0x%" PRIx32
+ return createStringError(errc::not_supported,
+ "%s table at offset 0x%" PRIx32
" has unsupported segment selector size %" PRIu8,
SectionName.data(), HeaderOffset, HeaderData.SegSize);
if (End < HeaderOffset + sizeof(HeaderData) +
HeaderData.OffsetEntryCount * sizeof(uint32_t))
- return createError(
+ return createStringError(errc::invalid_argument,
"%s table at offset 0x%" PRIx32 " has more offset entries (%" PRIu32
") than there is space for",
SectionName.data(), HeaderOffset, HeaderData.OffsetEntryCount);
diff --git a/lib/DebugInfo/DWARF/DWARFUnit.cpp b/lib/DebugInfo/DWARF/DWARFUnit.cpp
index 3b408857d29f..80234665bdeb 100644
--- a/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -11,13 +11,16 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
+#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/Errc.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/WithColor.h"
#include <algorithm>
@@ -31,34 +34,161 @@
using namespace llvm;
using namespace dwarf;
-void DWARFUnitSectionBase::parse(DWARFContext &C, const DWARFSection &Section) {
+void DWARFUnitVector::addUnitsForSection(DWARFContext &C,
+ const DWARFSection &Section,
+ DWARFSectionKind SectionKind) {
const DWARFObject &D = C.getDWARFObj();
- parseImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangeSection(),
- D.getStringSection(), D.getStringOffsetSection(),
- &D.getAddrSection(), D.getLineSection(), D.isLittleEndian(), false,
- false);
+ addUnitsImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangeSection(),
+ &D.getLocSection(), D.getStringSection(),
+ D.getStringOffsetSection(), &D.getAddrSection(),
+ D.getLineSection(), D.isLittleEndian(), false, false,
+ SectionKind);
}
-void DWARFUnitSectionBase::parseDWO(DWARFContext &C,
- const DWARFSection &DWOSection, bool Lazy) {
+void DWARFUnitVector::addUnitsForDWOSection(DWARFContext &C,
+ const DWARFSection &DWOSection,
+ DWARFSectionKind SectionKind,
+ bool Lazy) {
const DWARFObject &D = C.getDWARFObj();
- parseImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangeDWOSection(),
- D.getStringDWOSection(), D.getStringOffsetDWOSection(),
- &D.getAddrSection(), D.getLineDWOSection(), C.isLittleEndian(),
- true, Lazy);
+ addUnitsImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangeDWOSection(),
+ &D.getLocDWOSection(), D.getStringDWOSection(),
+ D.getStringOffsetDWOSection(), &D.getAddrSection(),
+ D.getLineDWOSection(), C.isLittleEndian(), true, Lazy,
+ SectionKind);
+}
+
+void DWARFUnitVector::addUnitsImpl(
+ DWARFContext &Context, const DWARFObject &Obj, const DWARFSection &Section,
+ const DWARFDebugAbbrev *DA, const DWARFSection *RS,
+ const DWARFSection *LocSection, StringRef SS, const DWARFSection &SOS,
+ const DWARFSection *AOS, const DWARFSection &LS, bool LE, bool IsDWO,
+ bool Lazy, DWARFSectionKind SectionKind) {
+ DWARFDataExtractor Data(Obj, Section, LE, 0);
+ // Lazy initialization of Parser, now that we have all section info.
+ if (!Parser) {
+ Parser = [=, &Context, &Obj, &Section, &SOS,
+ &LS](uint32_t Offset, DWARFSectionKind SectionKind,
+ const DWARFSection *CurSection,
+ const DWARFUnitIndex::Entry *IndexEntry)
+ -> std::unique_ptr<DWARFUnit> {
+ const DWARFSection &InfoSection = CurSection ? *CurSection : Section;
+ DWARFDataExtractor Data(Obj, InfoSection, LE, 0);
+ if (!Data.isValidOffset(Offset))
+ return nullptr;
+ const DWARFUnitIndex *Index = nullptr;
+ if (IsDWO)
+ Index = &getDWARFUnitIndex(Context, SectionKind);
+ DWARFUnitHeader Header;
+ if (!Header.extract(Context, Data, &Offset, SectionKind, Index,
+ IndexEntry))
+ return nullptr;
+ std::unique_ptr<DWARFUnit> U;
+ if (Header.isTypeUnit())
+ U = llvm::make_unique<DWARFTypeUnit>(Context, InfoSection, Header, DA,
+ RS, LocSection, SS, SOS, AOS, LS,
+ LE, IsDWO, *this);
+ else
+ U = llvm::make_unique<DWARFCompileUnit>(Context, InfoSection, Header,
+ DA, RS, LocSection, SS, SOS,
+ AOS, LS, LE, IsDWO, *this);
+ return U;
+ };
+ }
+ if (Lazy)
+ return;
+ // Find a reasonable insertion point within the vector. We skip over
+ // (a) units from a different section, (b) units from the same section
+ // but with lower offset-within-section. This keeps units in order
+ // within a section, although not necessarily within the object file,
+ // even if we do lazy parsing.
+ auto I = this->begin();
+ uint32_t Offset = 0;
+ while (Data.isValidOffset(Offset)) {
+ if (I != this->end() &&
+ (&(*I)->getInfoSection() != &Section || (*I)->getOffset() == Offset)) {
+ ++I;
+ continue;
+ }
+ auto U = Parser(Offset, SectionKind, &Section, nullptr);
+ // If parsing failed, we're done with this section.
+ if (!U)
+ break;
+ Offset = U->getNextUnitOffset();
+ I = std::next(this->insert(I, std::move(U)));
+ }
+}
+
+DWARFUnit *DWARFUnitVector::addUnit(std::unique_ptr<DWARFUnit> Unit) {
+ auto I = std::upper_bound(begin(), end(), Unit,
+ [](const std::unique_ptr<DWARFUnit> &LHS,
+ const std::unique_ptr<DWARFUnit> &RHS) {
+ return LHS->getOffset() < RHS->getOffset();
+ });
+ return this->insert(I, std::move(Unit))->get();
+}
+
+DWARFUnit *DWARFUnitVector::getUnitForOffset(uint32_t Offset) const {
+ auto end = begin() + getNumInfoUnits();
+ auto *CU =
+ std::upper_bound(begin(), end, Offset,
+ [](uint32_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
+ return LHS < RHS->getNextUnitOffset();
+ });
+ if (CU != end && (*CU)->getOffset() <= Offset)
+ return CU->get();
+ return nullptr;
+}
+
+DWARFUnit *
+DWARFUnitVector::getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) {
+ const auto *CUOff = E.getOffset(DW_SECT_INFO);
+ if (!CUOff)
+ return nullptr;
+
+ auto Offset = CUOff->Offset;
+ auto end = begin() + getNumInfoUnits();
+
+ auto *CU =
+ std::upper_bound(begin(), end, CUOff->Offset,
+ [](uint32_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
+ return LHS < RHS->getNextUnitOffset();
+ });
+ if (CU != end && (*CU)->getOffset() <= Offset)
+ return CU->get();
+
+ if (!Parser)
+ return nullptr;
+
+ auto U = Parser(Offset, DW_SECT_INFO, nullptr, &E);
+ if (!U)
+ U = nullptr;
+
+ auto *NewCU = U.get();
+ this->insert(CU, std::move(U));
+ ++NumInfoUnits;
+ return NewCU;
}
DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
- const DWARFUnitHeader &Header,
- const DWARFDebugAbbrev *DA, const DWARFSection *RS,
+ const DWARFUnitHeader &Header, const DWARFDebugAbbrev *DA,
+ const DWARFSection *RS, const DWARFSection *LocSection,
StringRef SS, const DWARFSection &SOS,
const DWARFSection *AOS, const DWARFSection &LS, bool LE,
- bool IsDWO, const DWARFUnitSectionBase &UnitSection)
+ bool IsDWO, const DWARFUnitVector &UnitVector)
: Context(DC), InfoSection(Section), Header(Header), Abbrev(DA),
- RangeSection(RS), LineSection(LS), StringSection(SS),
- StringOffsetSection(SOS), AddrOffsetSection(AOS), isLittleEndian(LE),
- isDWO(IsDWO), UnitSection(UnitSection) {
+ RangeSection(RS), LocSection(LocSection), LineSection(LS),
+ StringSection(SS), StringOffsetSection(SOS), AddrOffsetSection(AOS),
+ isLittleEndian(LE), IsDWO(IsDWO), UnitVector(UnitVector) {
clear();
+ // For split DWARF we only need to keep track of the location list section's
+ // data (no relocations), and if we are reading a package file, we need to
+ // adjust the location list data based on the index entries.
+ if (IsDWO) {
+ LocSectionData = LocSection->Data;
+ if (auto *IndexEntry = Header.getIndexEntry())
+ if (const auto *C = IndexEntry->getOffset(DW_SECT_LOC))
+ LocSectionData = LocSectionData.substr(C->Offset, C->Length);
+ }
}
DWARFUnit::~DWARFUnit() = default;
@@ -68,38 +198,50 @@ DWARFDataExtractor DWARFUnit::getDebugInfoExtractor() const {
getAddressByteSize());
}
-bool DWARFUnit::getAddrOffsetSectionItem(uint32_t Index,
- uint64_t &Result) const {
+Optional<SectionedAddress>
+DWARFUnit::getAddrOffsetSectionItem(uint32_t Index) const {
+ if (IsDWO) {
+ auto R = Context.info_section_units();
+ auto I = R.begin();
+ // Surprising if a DWO file has more than one skeleton unit in it - this
+ // probably shouldn't be valid, but if a use case is found, here's where to
+ // support it (probably have to linearly search for the matching skeleton CU
+ // here)
+ if (I != R.end() && std::next(I) == R.end())
+ return (*I)->getAddrOffsetSectionItem(Index);
+ }
uint32_t Offset = AddrOffsetSectionBase + Index * getAddressByteSize();
if (AddrOffsetSection->Data.size() < Offset + getAddressByteSize())
- return false;
+ return None;
DWARFDataExtractor DA(Context.getDWARFObj(), *AddrOffsetSection,
isLittleEndian, getAddressByteSize());
- Result = DA.getRelocatedAddress(&Offset);
- return true;
+ uint64_t Section;
+ uint64_t Address = DA.getRelocatedAddress(&Offset, &Section);
+ return {{Address, Section}};
}
-bool DWARFUnit::getStringOffsetSectionItem(uint32_t Index,
- uint64_t &Result) const {
+Optional<uint64_t> DWARFUnit::getStringOffsetSectionItem(uint32_t Index) const {
if (!StringOffsetsTableContribution)
- return false;
+ return None;
unsigned ItemSize = getDwarfStringOffsetsByteSize();
uint32_t Offset = getStringOffsetsBase() + Index * ItemSize;
if (StringOffsetSection.Data.size() < Offset + ItemSize)
- return false;
+ return None;
DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
isLittleEndian, 0);
- Result = DA.getRelocatedValue(ItemSize, &Offset);
- return true;
+ return DA.getRelocatedValue(ItemSize, &Offset);
}
bool DWARFUnitHeader::extract(DWARFContext &Context,
const DWARFDataExtractor &debug_info,
uint32_t *offset_ptr,
DWARFSectionKind SectionKind,
- const DWARFUnitIndex *Index) {
+ const DWARFUnitIndex *Index,
+ const DWARFUnitIndex::Entry *Entry) {
Offset = *offset_ptr;
- IndexEntry = Index ? Index->getFromOffset(*offset_ptr) : nullptr;
+ IndexEntry = Entry;
+ if (!IndexEntry && Index)
+ IndexEntry = Index->getFromOffset(*offset_ptr);
Length = debug_info.getU32(offset_ptr);
// FIXME: Support DWARF64.
unsigned SizeOfLength = 4;
@@ -166,13 +308,10 @@ parseRngListTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {
// We are expected to be called with Offset 0 or pointing just past the table
// header, which is 12 bytes long for DWARF32.
if (Offset > 0) {
- if (Offset < 12U) {
- std::string Buffer;
- raw_string_ostream Stream(Buffer);
- Stream << format(
- "Did not detect a valid range list table with base = 0x%x", Offset);
- return make_error<StringError>(Stream.str(), inconvertibleErrorCode());
- }
+ if (Offset < 12U)
+ return createStringError(errc::invalid_argument, "Did not detect a valid"
+ " range list table with base = 0x%" PRIu32,
+ Offset);
Offset -= 12U;
}
llvm::DWARFDebugRnglistTable Table;
@@ -274,11 +413,13 @@ size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
DWARFDie UnitDie = getUnitDIE();
if (Optional<uint64_t> DWOId = toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id)))
Header.setDWOId(*DWOId);
- if (!isDWO) {
+ if (!IsDWO) {
assert(AddrOffsetSectionBase == 0);
assert(RangeSectionBase == 0);
- AddrOffsetSectionBase =
- toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base), 0);
+ AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_addr_base), 0);
+ if (!AddrOffsetSectionBase)
+ AddrOffsetSectionBase =
+ toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base), 0);
RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);
}
@@ -289,27 +430,19 @@ size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
// offsets table starting at offset 0 of the debug_str_offsets.dwo section.
// In both cases we need to determine the format of the contribution,
// which may differ from the unit's format.
- uint64_t StringOffsetsContributionBase =
- isDWO ? 0 : toSectionOffset(UnitDie.find(DW_AT_str_offsets_base), 0);
- auto IndexEntry = Header.getIndexEntry();
- if (IndexEntry)
- if (const auto *C = IndexEntry->getOffset(DW_SECT_STR_OFFSETS))
- StringOffsetsContributionBase += C->Offset;
-
DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
isLittleEndian, 0);
- if (isDWO)
+ if (IsDWO)
StringOffsetsTableContribution =
- determineStringOffsetsTableContributionDWO(
- DA, StringOffsetsContributionBase);
+ determineStringOffsetsTableContributionDWO(DA);
else if (getVersion() >= 5)
- StringOffsetsTableContribution = determineStringOffsetsTableContribution(
- DA, StringOffsetsContributionBase);
+ StringOffsetsTableContribution =
+ determineStringOffsetsTableContribution(DA);
// DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to
// describe address ranges.
if (getVersion() >= 5) {
- if (isDWO)
+ if (IsDWO)
setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(), 0);
else
setRangesSection(&Context.getDWARFObj().getRnglistsSection(),
@@ -329,20 +462,20 @@ size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
// In a split dwarf unit, there is no DW_AT_rnglists_base attribute.
// Adjust RangeSectionBase to point past the table header.
- if (isDWO && RngListTable)
+ if (IsDWO && RngListTable)
RangeSectionBase = RngListTable->getHeaderSize();
}
}
// Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
// skeleton CU DIE, so that DWARF users not aware of it are not broken.
- }
+ }
return DieArray.size();
}
bool DWARFUnit::parseDWO() {
- if (isDWO)
+ if (IsDWO)
return false;
if (DWO.get())
return false;
@@ -412,12 +545,12 @@ DWARFUnit::findRnglistFromOffset(uint32_t Offset) {
isLittleEndian, RngListTable->getAddrSize());
auto RangeListOrError = RngListTable->findList(RangesData, Offset);
if (RangeListOrError)
- return RangeListOrError.get().getAbsoluteRanges(getBaseAddress());
+ return RangeListOrError.get().getAbsoluteRanges(getBaseAddress(), *this);
return RangeListOrError.takeError();
}
- return make_error<StringError>("missing or invalid range list table",
- inconvertibleErrorCode());
+ return createStringError(errc::invalid_argument,
+ "missing or invalid range list table");
}
Expected<DWARFAddressRangesVector>
@@ -425,51 +558,26 @@ DWARFUnit::findRnglistFromIndex(uint32_t Index) {
if (auto Offset = getRnglistOffset(Index))
return findRnglistFromOffset(*Offset + RangeSectionBase);
- std::string Buffer;
- raw_string_ostream Stream(Buffer);
if (RngListTable)
- Stream << format("invalid range list table index %d", Index);
+ return createStringError(errc::invalid_argument,
+ "invalid range list table index %d", Index);
else
- Stream << "missing or invalid range list table";
- return make_error<StringError>(Stream.str(), inconvertibleErrorCode());
+ return createStringError(errc::invalid_argument,
+ "missing or invalid range list table");
}
-void DWARFUnit::collectAddressRanges(DWARFAddressRangesVector &CURanges) {
+Expected<DWARFAddressRangesVector> DWARFUnit::collectAddressRanges() {
DWARFDie UnitDie = getUnitDIE();
if (!UnitDie)
- return;
+ return createStringError(errc::invalid_argument, "No unit DIE");
+
// First, check if unit DIE describes address ranges for the whole unit.
auto CUDIERangesOrError = UnitDie.getAddressRanges();
- if (CUDIERangesOrError) {
- if (!CUDIERangesOrError.get().empty()) {
- CURanges.insert(CURanges.end(), CUDIERangesOrError.get().begin(),
- CUDIERangesOrError.get().end());
- return;
- }
- } else
- WithColor::error() << "decoding address ranges: "
- << toString(CUDIERangesOrError.takeError()) << '\n';
-
- // This function is usually called if there in no .debug_aranges section
- // in order to produce a compile unit level set of address ranges that
- // is accurate. If the DIEs weren't parsed, then we don't want all dies for
- // all compile units to stay loaded when they weren't needed. So we can end
- // up parsing the DWARF and then throwing them all away to keep memory usage
- // down.
- const bool ClearDIEs = extractDIEsIfNeeded(false) > 1;
- getUnitDIE().collectChildrenAddressRanges(CURanges);
-
- // Collect address ranges from DIEs in .dwo if necessary.
- bool DWOCreated = parseDWO();
- if (DWO)
- DWO->collectAddressRanges(CURanges);
- if (DWOCreated)
- DWO.reset();
-
- // Keep memory down by clearing DIEs if this generate function
- // caused them to be parsed.
- if (ClearDIEs)
- clearDIEs(true);
+ if (!CUDIERangesOrError)
+ return createStringError(errc::invalid_argument,
+ "decoding address ranges: %s",
+ toString(CUDIERangesOrError.takeError()).c_str());
+ return *CUDIERangesOrError;
}
void DWARFUnit::updateAddressDieMap(DWARFDie Die) {
@@ -637,15 +745,13 @@ const DWARFAbbreviationDeclarationSet *DWARFUnit::getAbbreviations() const {
return Abbrevs;
}
-llvm::Optional<BaseAddress> DWARFUnit::getBaseAddress() {
+llvm::Optional<SectionedAddress> DWARFUnit::getBaseAddress() {
if (BaseAddr)
return BaseAddr;
DWARFDie UnitDie = getUnitDIE();
Optional<DWARFFormValue> PC = UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc});
- if (Optional<uint64_t> Addr = toAddress(PC))
- BaseAddr = {*Addr, PC->getSectionIndex()};
-
+ BaseAddr = toSectionedAddress(PC);
return BaseAddr;
}
@@ -660,7 +766,7 @@ StrOffsetsContributionDescriptor::validateContributionSize(
if (ValidationSize >= Size)
if (DA.isValidOffsetForDataOfSize((uint32_t)Base, ValidationSize))
return *this;
- return Optional<StrOffsetsContributionDescriptor>();
+ return None;
}
// Look for a DWARF64-formatted contribution to the string offsets table
@@ -668,18 +774,17 @@ StrOffsetsContributionDescriptor::validateContributionSize(
static Optional<StrOffsetsContributionDescriptor>
parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {
if (!DA.isValidOffsetForDataOfSize(Offset, 16))
- return Optional<StrOffsetsContributionDescriptor>();
+ return None;
if (DA.getU32(&Offset) != 0xffffffff)
- return Optional<StrOffsetsContributionDescriptor>();
+ return None;
uint64_t Size = DA.getU64(&Offset);
uint8_t Version = DA.getU16(&Offset);
(void)DA.getU16(&Offset); // padding
// The encoded length includes the 2-byte version field and the 2-byte
// padding, so we need to subtract them out when we populate the descriptor.
- return StrOffsetsContributionDescriptor(Offset, Size - 4, Version, DWARF64);
- //return Optional<StrOffsetsContributionDescriptor>(Descriptor);
+ return {{Offset, Size - 4, Version, DWARF64}};
}
// Look for a DWARF32-formatted contribution to the string offsets table
@@ -687,22 +792,20 @@ parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {
static Optional<StrOffsetsContributionDescriptor>
parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {
if (!DA.isValidOffsetForDataOfSize(Offset, 8))
- return Optional<StrOffsetsContributionDescriptor>();
+ return None;
uint32_t ContributionSize = DA.getU32(&Offset);
if (ContributionSize >= 0xfffffff0)
- return Optional<StrOffsetsContributionDescriptor>();
+ return None;
uint8_t Version = DA.getU16(&Offset);
(void)DA.getU16(&Offset); // padding
// The encoded length includes the 2-byte version field and the 2-byte
// padding, so we need to subtract them out when we populate the descriptor.
- return StrOffsetsContributionDescriptor(Offset, ContributionSize - 4, Version,
- DWARF32);
- //return Optional<StrOffsetsContributionDescriptor>(Descriptor);
+ return {{Offset, ContributionSize - 4, Version, DWARF32}};
}
Optional<StrOffsetsContributionDescriptor>
-DWARFUnit::determineStringOffsetsTableContribution(DWARFDataExtractor &DA,
- uint64_t Offset) {
+DWARFUnit::determineStringOffsetsTableContribution(DWARFDataExtractor &DA) {
+ auto Offset = toSectionOffset(getUnitDIE().find(DW_AT_str_offsets_base), 0);
Optional<StrOffsetsContributionDescriptor> Descriptor;
// Attempt to find a DWARF64 contribution 16 bytes before the base.
if (Offset >= 16)
@@ -715,8 +818,13 @@ DWARFUnit::determineStringOffsetsTableContribution(DWARFDataExtractor &DA,
}
Optional<StrOffsetsContributionDescriptor>
-DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA,
- uint64_t Offset) {
+DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor & DA) {
+ uint64_t Offset = 0;
+ auto IndexEntry = Header.getIndexEntry();
+ const auto *C =
+ IndexEntry ? IndexEntry->getOffset(DW_SECT_STR_OFFSETS) : nullptr;
+ if (C)
+ Offset = C->Offset;
if (getVersion() >= 5) {
// Look for a valid contribution at the given offset.
auto Descriptor =
@@ -728,15 +836,9 @@ DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA,
// Prior to DWARF v5, we derive the contribution size from the
// index table (in a package file). In a .dwo file it is simply
// the length of the string offsets section.
- uint64_t Size = 0;
- auto IndexEntry = Header.getIndexEntry();
if (!IndexEntry)
- Size = StringOffsetSection.Data.size();
- else if (const auto *C = IndexEntry->getOffset(DW_SECT_STR_OFFSETS))
- Size = C->Length;
- // Return a descriptor with the given offset as base, version 4 and
- // DWARF32 format.
- //return Optional<StrOffsetsContributionDescriptor>(
- //StrOffsetsContributionDescriptor(Offset, Size, 4, DWARF32));
- return StrOffsetsContributionDescriptor(Offset, Size, 4, DWARF32);
+ return {{0, StringOffsetSection.Data.size(), 4, DWARF32}};
+ if (C)
+ return {{C->Offset, C->Length, 4, DWARF32}};
+ return None;
}
diff --git a/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp b/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
index 17f17572a309..84b6c4b81817 100644
--- a/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
+++ b/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
@@ -164,14 +164,27 @@ DWARFUnitIndex::Entry::getOffset() const {
const DWARFUnitIndex::Entry *
DWARFUnitIndex::getFromOffset(uint32_t Offset) const {
- for (uint32_t i = 0; i != Header.NumBuckets; ++i)
- if (const auto &Contribs = Rows[i].Contributions) {
- const auto &InfoContrib = Contribs[InfoColumn];
- if (InfoContrib.Offset <= Offset &&
- Offset < (InfoContrib.Offset + InfoContrib.Length))
- return &Rows[i];
- }
- return nullptr;
+ if (OffsetLookup.empty()) {
+ for (uint32_t i = 0; i != Header.NumBuckets; ++i)
+ if (Rows[i].Contributions)
+ OffsetLookup.push_back(&Rows[i]);
+ llvm::sort(OffsetLookup, [&](Entry *E1, Entry *E2) {
+ return E1->Contributions[InfoColumn].Offset <
+ E2->Contributions[InfoColumn].Offset;
+ });
+ }
+ auto I =
+ llvm::upper_bound(OffsetLookup, Offset, [&](uint32_t Offset, Entry *E2) {
+ return Offset < E2->Contributions[InfoColumn].Offset;
+ });
+ if (I == OffsetLookup.begin())
+ return nullptr;
+ --I;
+ const auto *E = *I;
+ const auto &InfoContrib = E->Contributions[InfoColumn];
+ if ((InfoContrib.Offset + InfoContrib.Length) <= Offset)
+ return nullptr;
+ return E;
}
const DWARFUnitIndex::Entry *DWARFUnitIndex::getFromHash(uint64_t S) const {
diff --git a/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index 82d52c467bc0..f8370178b627 100644
--- a/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -6,7 +6,6 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-
#include "llvm/DebugInfo/DWARF/DWARFVerifier.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
@@ -93,7 +92,7 @@ bool DWARFVerifier::DieRangeInfo::intersects(const DieRangeInfo &RHS) const {
auto End = Ranges.end();
auto Iter = findRange(RHS.Ranges.front());
for (const auto &R : RHS.Ranges) {
- if(Iter == End)
+ if (Iter == End)
return false;
if (R.HighPC <= Iter->LowPC)
continue;
@@ -156,14 +155,14 @@ bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData,
OffsetStart);
if (!ValidLength)
note() << "The length for this unit is too "
- "large for the .debug_info provided.\n";
+ "large for the .debug_info provided.\n";
if (!ValidVersion)
note() << "The 16 bit unit header version is not valid.\n";
if (!ValidType)
note() << "The unit type encoding is not valid.\n";
if (!ValidAbbrevOffset)
note() << "The offset into the .debug_abbrev section is "
- "not valid.\n";
+ "not valid.\n";
if (!ValidAddrSize)
note() << "The address size is unsupported.\n";
}
@@ -171,24 +170,38 @@ bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData,
return Success;
}
-bool DWARFVerifier::verifyUnitContents(DWARFUnit &Unit, uint8_t UnitType) {
- uint32_t NumUnitErrors = 0;
+unsigned DWARFVerifier::verifyUnitContents(DWARFUnit &Unit) {
+ unsigned NumUnitErrors = 0;
unsigned NumDies = Unit.getNumDIEs();
for (unsigned I = 0; I < NumDies; ++I) {
auto Die = Unit.getDIEAtIndex(I);
+
if (Die.getTag() == DW_TAG_null)
continue;
+
+ bool HasTypeAttr = false;
for (auto AttrValue : Die.attributes()) {
NumUnitErrors += verifyDebugInfoAttribute(Die, AttrValue);
NumUnitErrors += verifyDebugInfoForm(Die, AttrValue);
+ HasTypeAttr |= (AttrValue.Attr == DW_AT_type);
+ }
+
+ if (!HasTypeAttr && (Die.getTag() == DW_TAG_formal_parameter ||
+ Die.getTag() == DW_TAG_variable ||
+ Die.getTag() == DW_TAG_array_type)) {
+ error() << "DIE with tag " << TagString(Die.getTag())
+ << " is missing type attribute:\n";
+ dump(Die) << '\n';
+ NumUnitErrors++;
}
+ NumUnitErrors += verifyDebugInfoCallSite(Die);
}
DWARFDie Die = Unit.getUnitDIE(/* ExtractUnitDIEOnly = */ false);
if (!Die) {
error() << "Compilation unit without DIE.\n";
NumUnitErrors++;
- return NumUnitErrors == 0;
+ return NumUnitErrors;
}
if (!dwarf::isUnitType(Die.getTag())) {
@@ -197,8 +210,8 @@ bool DWARFVerifier::verifyUnitContents(DWARFUnit &Unit, uint8_t UnitType) {
NumUnitErrors++;
}
- if (UnitType != 0 &&
- !DWARFUnit::isMatchingUnitTypeAndTag(UnitType, Die.getTag())) {
+ uint8_t UnitType = Unit.getUnitType();
+ if (!DWARFUnit::isMatchingUnitTypeAndTag(UnitType, Die.getTag())) {
error() << "Compilation unit type (" << dwarf::UnitTypeString(UnitType)
<< ") and root DIE (" << dwarf::TagString(Die.getTag())
<< ") do not match.\n";
@@ -208,7 +221,39 @@ bool DWARFVerifier::verifyUnitContents(DWARFUnit &Unit, uint8_t UnitType) {
DieRangeInfo RI;
NumUnitErrors += verifyDieRanges(Die, RI);
- return NumUnitErrors == 0;
+ return NumUnitErrors;
+}
+
+unsigned DWARFVerifier::verifyDebugInfoCallSite(const DWARFDie &Die) {
+ if (Die.getTag() != DW_TAG_call_site)
+ return 0;
+
+ DWARFDie Curr = Die.getParent();
+ for (; Curr.isValid() && !Curr.isSubprogramDIE(); Curr = Die.getParent()) {
+ if (Curr.getTag() == DW_TAG_inlined_subroutine) {
+ error() << "Call site entry nested within inlined subroutine:";
+ Curr.dump(OS);
+ return 1;
+ }
+ }
+
+ if (!Curr.isValid()) {
+ error() << "Call site entry not nested within a valid subprogram:";
+ Die.dump(OS);
+ return 1;
+ }
+
+ Optional<DWARFFormValue> CallAttr =
+ Curr.find({DW_AT_call_all_calls, DW_AT_call_all_source_calls,
+ DW_AT_call_all_tail_calls});
+ if (!CallAttr) {
+ error() << "Subprogram with call site entry has no DW_AT_call attribute:";
+ Curr.dump(OS);
+ Die.dump(OS, /*indent*/ 1);
+ return 1;
+ }
+
+ return 0;
}
unsigned DWARFVerifier::verifyAbbrevSection(const DWARFDebugAbbrev *Abbrev) {
@@ -252,20 +297,18 @@ bool DWARFVerifier::handleDebugAbbrev() {
return NumErrors == 0;
}
-bool DWARFVerifier::handleDebugInfo() {
- OS << "Verifying .debug_info Unit Header Chain...\n";
-
+unsigned DWARFVerifier::verifyUnitSection(const DWARFSection &S,
+ DWARFSectionKind SectionKind) {
const DWARFObject &DObj = DCtx.getDWARFObj();
- DWARFDataExtractor DebugInfoData(DObj, DObj.getInfoSection(),
- DCtx.isLittleEndian(), 0);
- uint32_t NumDebugInfoErrors = 0;
+ DWARFDataExtractor DebugInfoData(DObj, S, DCtx.isLittleEndian(), 0);
+ unsigned NumDebugInfoErrors = 0;
uint32_t OffsetStart = 0, Offset = 0, UnitIdx = 0;
uint8_t UnitType = 0;
bool isUnitDWARF64 = false;
bool isHeaderChainValid = true;
bool hasDIE = DebugInfoData.isValidOffset(Offset);
- DWARFUnitSection<DWARFTypeUnit> TUSection{};
- DWARFUnitSection<DWARFCompileUnit> CUSection{};
+ DWARFUnitVector TypeUnitVector;
+ DWARFUnitVector CompileUnitVector;
while (hasDIE) {
OffsetStart = Offset;
if (!verifyUnitHeader(DebugInfoData, &Offset, UnitIdx, UnitType,
@@ -275,46 +318,64 @@ bool DWARFVerifier::handleDebugInfo() {
break;
} else {
DWARFUnitHeader Header;
- Header.extract(DCtx, DebugInfoData, &OffsetStart);
- std::unique_ptr<DWARFUnit> Unit;
+ Header.extract(DCtx, DebugInfoData, &OffsetStart, SectionKind);
+ DWARFUnit *Unit;
switch (UnitType) {
case dwarf::DW_UT_type:
case dwarf::DW_UT_split_type: {
- Unit.reset(new DWARFTypeUnit(
- DCtx, DObj.getInfoSection(), Header, DCtx.getDebugAbbrev(),
- &DObj.getRangeSection(), DObj.getStringSection(),
+ Unit = TypeUnitVector.addUnit(llvm::make_unique<DWARFTypeUnit>(
+ DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangeSection(),
+ &DObj.getLocSection(), DObj.getStringSection(),
DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(),
- DObj.getLineSection(), DCtx.isLittleEndian(), false, TUSection));
+ DObj.getLineSection(), DCtx.isLittleEndian(), false,
+ TypeUnitVector));
break;
}
case dwarf::DW_UT_skeleton:
case dwarf::DW_UT_split_compile:
case dwarf::DW_UT_compile:
case dwarf::DW_UT_partial:
- // UnitType = 0 means that we are
- // verifying a compile unit in DWARF v4.
+ // UnitType = 0 means that we are verifying a compile unit in DWARF v4.
case 0: {
- Unit.reset(new DWARFCompileUnit(
- DCtx, DObj.getInfoSection(), Header, DCtx.getDebugAbbrev(),
- &DObj.getRangeSection(), DObj.getStringSection(),
+ Unit = CompileUnitVector.addUnit(llvm::make_unique<DWARFCompileUnit>(
+ DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangeSection(),
+ &DObj.getLocSection(), DObj.getStringSection(),
DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(),
- DObj.getLineSection(), DCtx.isLittleEndian(), false, CUSection));
+ DObj.getLineSection(), DCtx.isLittleEndian(), false,
+ CompileUnitVector));
break;
}
default: { llvm_unreachable("Invalid UnitType."); }
}
- if (!verifyUnitContents(*Unit, UnitType))
- ++NumDebugInfoErrors;
+ NumDebugInfoErrors += verifyUnitContents(*Unit);
}
hasDIE = DebugInfoData.isValidOffset(Offset);
++UnitIdx;
}
if (UnitIdx == 0 && !hasDIE) {
- warn() << ".debug_info is empty.\n";
+ warn() << "Section is empty.\n";
isHeaderChainValid = true;
}
+ if (!isHeaderChainValid)
+ ++NumDebugInfoErrors;
NumDebugInfoErrors += verifyDebugInfoReferences();
- return (isHeaderChainValid && NumDebugInfoErrors == 0);
+ return NumDebugInfoErrors;
+}
+
+bool DWARFVerifier::handleDebugInfo() {
+ const DWARFObject &DObj = DCtx.getDWARFObj();
+ unsigned NumErrors = 0;
+
+ OS << "Verifying .debug_info Unit Header Chain...\n";
+ DObj.forEachInfoSections([&](const DWARFSection &S) {
+ NumErrors += verifyUnitSection(S, DW_SECT_INFO);
+ });
+
+ OS << "Verifying .debug_types Unit Header Chain...\n";
+ DObj.forEachTypesSections([&](const DWARFSection &S) {
+ NumErrors += verifyUnitSection(S, DW_SECT_TYPES);
+ });
+ return NumErrors == 0;
}
unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die,
@@ -336,20 +397,42 @@ unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die,
// Build RI for this DIE and check that ranges within this DIE do not
// overlap.
DieRangeInfo RI(Die);
- for (auto Range : Ranges) {
- if (!Range.valid()) {
- ++NumErrors;
- error() << "Invalid address range " << Range << "\n";
- continue;
- }
- // Verify that ranges don't intersect.
- const auto IntersectingRange = RI.insert(Range);
- if (IntersectingRange != RI.Ranges.end()) {
- ++NumErrors;
- error() << "DIE has overlapping address ranges: " << Range << " and "
- << *IntersectingRange << "\n";
- break;
+ // TODO support object files better
+ //
+ // Some object file formats (i.e. non-MachO) support COMDAT. ELF in
+ // particular does so by placing each function into a section. The DWARF data
+ // for the function at that point uses a section relative DW_FORM_addrp for
+ // the DW_AT_low_pc and a DW_FORM_data4 for the offset as the DW_AT_high_pc.
+ // In such a case, when the Die is the CU, the ranges will overlap, and we
+ // will flag valid conflicting ranges as invalid.
+ //
+ // For such targets, we should read the ranges from the CU and partition them
+ // by the section id. The ranges within a particular section should be
+ // disjoint, although the ranges across sections may overlap. We would map
+ // the child die to the entity that it references and the section with which
+ // it is associated. The child would then be checked against the range
+ // information for the associated section.
+ //
+ // For now, simply elide the range verification for the CU DIEs if we are
+ // processing an object file.
+
+ if (!IsObjectFile || IsMachOObject || Die.getTag() != DW_TAG_compile_unit) {
+ for (auto Range : Ranges) {
+ if (!Range.valid()) {
+ ++NumErrors;
+ error() << "Invalid address range " << Range << "\n";
+ continue;
+ }
+
+ // Verify that ranges don't intersect.
+ const auto IntersectingRange = RI.insert(Range);
+ if (IntersectingRange != RI.Ranges.end()) {
+ ++NumErrors;
+ error() << "DIE has overlapping address ranges: " << Range << " and "
+ << *IntersectingRange << "\n";
+ break;
+ }
}
}
@@ -358,9 +441,8 @@ unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die,
if (IntersectingChild != ParentRI.Children.end()) {
++NumErrors;
error() << "DIEs have overlapping address ranges:";
- Die.dump(OS, 0);
- IntersectingChild->Die.dump(OS, 0);
- OS << "\n";
+ dump(Die);
+ dump(IntersectingChild->Die) << '\n';
}
// Verify that ranges are contained within their parent.
@@ -370,9 +452,8 @@ unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die,
if (ShouldBeContained && !ParentRI.contains(RI)) {
++NumErrors;
error() << "DIE address ranges are not contained in its parent's ranges:";
- ParentRI.Die.dump(OS, 0);
- Die.dump(OS, 2);
- OS << "\n";
+ dump(ParentRI.Die);
+ dump(Die, 2) << '\n';
}
// Recursively check children.
@@ -388,8 +469,7 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
auto ReportError = [&](const Twine &TitleMsg) {
++NumErrors;
error() << TitleMsg << '\n';
- Die.dump(OS, 0, DumpOpts);
- OS << "\n";
+ dump(Die) << '\n';
};
const DWARFObject &DObj = DCtx.getDWARFObj();
@@ -438,7 +518,33 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
}
break;
}
-
+ case DW_AT_specification:
+ case DW_AT_abstract_origin: {
+ if (auto ReferencedDie = Die.getAttributeValueAsReferencedDie(Attr)) {
+ auto DieTag = Die.getTag();
+ auto RefTag = ReferencedDie.getTag();
+ if (DieTag == RefTag)
+ break;
+ if (DieTag == DW_TAG_inlined_subroutine && RefTag == DW_TAG_subprogram)
+ break;
+ if (DieTag == DW_TAG_variable && RefTag == DW_TAG_member)
+ break;
+ ReportError("DIE with tag " + TagString(DieTag) + " has " +
+ AttributeString(Attr) +
+ " that points to DIE with "
+ "incompatible tag " +
+ TagString(RefTag));
+ }
+ break;
+ }
+ case DW_AT_type: {
+ DWARFDie TypeDie = Die.getAttributeValueAsReferencedDie(DW_AT_type);
+ if (TypeDie && !isType(TypeDie.getTag())) {
+ ReportError("DIE has " + AttributeString(Attr) +
+ " with incompatible tag " + TagString(TypeDie.getTag()));
+ }
+ break;
+ }
default:
break;
}
@@ -448,6 +554,7 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
DWARFAttribute &AttrValue) {
const DWARFObject &DObj = DCtx.getDWARFObj();
+ auto DieCU = Die.getDwarfUnit();
unsigned NumErrors = 0;
const auto Form = AttrValue.Value.getForm();
switch (Form) {
@@ -460,7 +567,6 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
Optional<uint64_t> RefVal = AttrValue.Value.getAsReference();
assert(RefVal);
if (RefVal) {
- auto DieCU = Die.getDwarfUnit();
auto CUSize = DieCU->getNextUnitOffset() - DieCU->getOffset();
auto CUOffset = AttrValue.Value.getRawUValue();
if (CUOffset >= CUSize) {
@@ -470,7 +576,7 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
<< " is invalid (must be less than CU size of "
<< format("0x%08" PRIx32, CUSize) << "):\n";
Die.dump(OS, 0, DumpOpts);
- OS << "\n";
+ dump(Die) << '\n';
} else {
// Valid reference, but we will verify it points to an actual
// DIE later.
@@ -485,12 +591,11 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
Optional<uint64_t> RefVal = AttrValue.Value.getAsReference();
assert(RefVal);
if (RefVal) {
- if (*RefVal >= DObj.getInfoSection().Data.size()) {
+ if (*RefVal >= DieCU->getInfoSection().Data.size()) {
++NumErrors;
error() << "DW_FORM_ref_addr offset beyond .debug_info "
"bounds:\n";
- Die.dump(OS, 0, DumpOpts);
- OS << "\n";
+ dump(Die) << '\n';
} else {
// Valid reference, but we will verify it points to an actual
// DIE later.
@@ -505,8 +610,46 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
if (SecOffset && *SecOffset >= DObj.getStringSection().size()) {
++NumErrors;
error() << "DW_FORM_strp offset beyond .debug_str bounds:\n";
- Die.dump(OS, 0, DumpOpts);
- OS << "\n";
+ dump(Die) << '\n';
+ }
+ break;
+ }
+ case DW_FORM_strx:
+ case DW_FORM_strx1:
+ case DW_FORM_strx2:
+ case DW_FORM_strx3:
+ case DW_FORM_strx4: {
+ auto Index = AttrValue.Value.getRawUValue();
+ auto DieCU = Die.getDwarfUnit();
+ // Check that we have a valid DWARF v5 string offsets table.
+ if (!DieCU->getStringOffsetsTableContribution()) {
+ ++NumErrors;
+ error() << FormEncodingString(Form)
+ << " used without a valid string offsets table:\n";
+ dump(Die) << '\n';
+ break;
+ }
+ // Check that the index is within the bounds of the section.
+ unsigned ItemSize = DieCU->getDwarfStringOffsetsByteSize();
+ // Use a 64-bit type to calculate the offset to guard against overflow.
+ uint64_t Offset =
+ (uint64_t)DieCU->getStringOffsetsBase() + Index * ItemSize;
+ if (DObj.getStringOffsetSection().Data.size() < Offset + ItemSize) {
+ ++NumErrors;
+ error() << FormEncodingString(Form) << " uses index "
+ << format("%" PRIu64, Index) << ", which is too large:\n";
+ dump(Die) << '\n';
+ break;
+ }
+ // Check that the string offset is valid.
+ uint64_t StringOffset = *DieCU->getStringOffsetSectionItem(Index);
+ if (StringOffset >= DObj.getStringSection().size()) {
+ ++NumErrors;
+ error() << FormEncodingString(Form) << " uses index "
+ << format("%" PRIu64, Index)
+ << ", but the referenced string"
+ " offset is beyond .debug_str bounds:\n";
+ dump(Die) << '\n';
}
break;
}
@@ -528,11 +671,8 @@ unsigned DWARFVerifier::verifyDebugInfoReferences() {
++NumErrors;
error() << "invalid DIE reference " << format("0x%08" PRIx64, Pair.first)
<< ". Offset is in between DIEs:\n";
- for (auto Offset : Pair.second) {
- auto ReferencingDie = DCtx.getDIEForOffset(Offset);
- ReferencingDie.dump(OS, 0, DumpOpts);
- OS << "\n";
- }
+ for (auto Offset : Pair.second)
+ dump(DCtx.getDIEForOffset(Offset)) << '\n';
OS << "\n";
}
return NumErrors;
@@ -555,8 +695,7 @@ void DWARFVerifier::verifyDebugLineStmtOffsets() {
++NumDebugLineErrors;
error() << ".debug_line[" << format("0x%08" PRIx32, LineTableOffset)
<< "] was not able to be parsed for CU:\n";
- Die.dump(OS, 0, DumpOpts);
- OS << '\n';
+ dump(Die) << '\n';
continue;
}
} else {
@@ -573,9 +712,8 @@ void DWARFVerifier::verifyDebugLineStmtOffsets() {
<< format("0x%08" PRIx32, Iter->second.getOffset()) << " and "
<< format("0x%08" PRIx32, Die.getOffset())
<< ", have the same DW_AT_stmt_list section offset:\n";
- Iter->second.dump(OS, 0, DumpOpts);
- Die.dump(OS, 0, DumpOpts);
- OS << '\n';
+ dump(Iter->second);
+ dump(Die) << '\n';
// Already verified this line table before, no need to do it again.
continue;
}
@@ -671,6 +809,16 @@ void DWARFVerifier::verifyDebugLineRows() {
}
}
+DWARFVerifier::DWARFVerifier(raw_ostream &S, DWARFContext &D,
+ DIDumpOptions DumpOpts)
+ : OS(S), DCtx(D), DumpOpts(std::move(DumpOpts)), IsObjectFile(false),
+ IsMachOObject(false) {
+ if (const auto *F = DCtx.getDWARFObj().getFile()) {
+ IsObjectFile = F->isRelocatableObject();
+ IsMachOObject = F->isMachO();
+ }
+}
+
bool DWARFVerifier::handleDebugLine() {
NumDebugLineErrors = 0;
OS << "Verifying .debug_line...\n";
@@ -816,8 +964,8 @@ DWARFVerifier::verifyDebugNamesCULists(const DWARFDebugNames &AccelTable) {
if (Iter->second != NotIndexed) {
error() << formatv("Name Index @ {0:x} references a CU @ {1:x}, but "
- "this CU is already indexed by Name Index @ {2:x}\n",
- NI.getUnitOffset(), Offset, Iter->second);
+ "this CU is already indexed by Name Index @ {2:x}\n",
+ NI.getUnitOffset(), Offset, Iter->second);
continue;
}
Iter->second = NI.getUnitOffset();
@@ -1048,16 +1196,19 @@ DWARFVerifier::verifyNameIndexAbbrevs(const DWARFDebugNames::NameIndex &NI) {
return NumErrors;
}
-static SmallVector<StringRef, 2> getNames(const DWARFDie &DIE) {
+static SmallVector<StringRef, 2> getNames(const DWARFDie &DIE,
+ bool IncludeLinkageName = true) {
SmallVector<StringRef, 2> Result;
if (const char *Str = DIE.getName(DINameKind::ShortName))
Result.emplace_back(Str);
else if (DIE.getTag() == dwarf::DW_TAG_namespace)
Result.emplace_back("(anonymous namespace)");
- if (const char *Str = DIE.getName(DINameKind::LinkageName)) {
- if (Result.empty() || Result[0] != Str)
- Result.emplace_back(Str);
+ if (IncludeLinkageName) {
+ if (const char *Str = DIE.getName(DINameKind::LinkageName)) {
+ if (Result.empty() || Result[0] != Str)
+ Result.emplace_back(Str);
+ }
}
return Result;
@@ -1200,7 +1351,9 @@ unsigned DWARFVerifier::verifyNameIndexCompleteness(
// "If a subprogram or inlined subroutine is included, and has a
// DW_AT_linkage_name attribute, there will be an additional index entry for
// the linkage name."
- auto EntryNames = getNames(Die);
+ auto IncludeLinkageName = Die.getTag() == DW_TAG_subprogram ||
+ Die.getTag() == DW_TAG_inlined_subroutine;
+ auto EntryNames = getNames(Die, IncludeLinkageName);
if (EntryNames.empty())
return 0;
@@ -1212,8 +1365,9 @@ unsigned DWARFVerifier::verifyNameIndexCompleteness(
// make sure we catch any missing items, we instead blacklist all TAGs that we
// know shouldn't be indexed.
switch (Die.getTag()) {
- // Compile unit has a name but it shouldn't be indexed.
+ // Compile units and modules have names but shouldn't be indexed.
case DW_TAG_compile_unit:
+ case DW_TAG_module:
return 0;
// Function and template parameters are not globally visible, so we shouldn't
@@ -1315,11 +1469,12 @@ unsigned DWARFVerifier::verifyDebugNames(const DWARFSection &AccelSection,
if (NumErrors > 0)
return NumErrors;
- for (const std::unique_ptr<DWARFCompileUnit> &CU : DCtx.compile_units()) {
+ for (const std::unique_ptr<DWARFUnit> &U : DCtx.compile_units()) {
if (const DWARFDebugNames::NameIndex *NI =
- AccelTable.getCUNameIndex(CU->getOffset())) {
+ AccelTable.getCUNameIndex(U->getOffset())) {
+ auto *CU = cast<DWARFCompileUnit>(U.get());
for (const DWARFDebugInfoEntry &Die : CU->dies())
- NumErrors += verifyNameIndexCompleteness(DWARFDie(CU.get(), &Die), *NI);
+ NumErrors += verifyNameIndexCompleteness(DWARFDie(CU, &Die), *NI);
}
}
return NumErrors;
@@ -1330,17 +1485,17 @@ bool DWARFVerifier::handleAccelTables() {
DataExtractor StrData(D.getStringSection(), DCtx.isLittleEndian(), 0);
unsigned NumErrors = 0;
if (!D.getAppleNamesSection().Data.empty())
- NumErrors +=
- verifyAppleAccelTable(&D.getAppleNamesSection(), &StrData, ".apple_names");
+ NumErrors += verifyAppleAccelTable(&D.getAppleNamesSection(), &StrData,
+ ".apple_names");
if (!D.getAppleTypesSection().Data.empty())
- NumErrors +=
- verifyAppleAccelTable(&D.getAppleTypesSection(), &StrData, ".apple_types");
+ NumErrors += verifyAppleAccelTable(&D.getAppleTypesSection(), &StrData,
+ ".apple_types");
if (!D.getAppleNamespacesSection().Data.empty())
NumErrors += verifyAppleAccelTable(&D.getAppleNamespacesSection(), &StrData,
- ".apple_namespaces");
+ ".apple_namespaces");
if (!D.getAppleObjCSection().Data.empty())
- NumErrors +=
- verifyAppleAccelTable(&D.getAppleObjCSection(), &StrData, ".apple_objc");
+ NumErrors += verifyAppleAccelTable(&D.getAppleObjCSection(), &StrData,
+ ".apple_objc");
if (!D.getDebugNamesSection().Data.empty())
NumErrors += verifyDebugNames(D.getDebugNamesSection(), StrData);
@@ -1352,3 +1507,8 @@ raw_ostream &DWARFVerifier::error() const { return WithColor::error(OS); }
raw_ostream &DWARFVerifier::warn() const { return WithColor::warning(OS); }
raw_ostream &DWARFVerifier::note() const { return WithColor::note(OS); }
+
+raw_ostream &DWARFVerifier::dump(const DWARFDie &Die, unsigned indent) const {
+ Die.dump(OS, indent, DumpOpts);
+ return OS;
+}
diff --git a/lib/DebugInfo/MSF/MSFError.cpp b/lib/DebugInfo/MSF/MSFError.cpp
index 1b8294e47e75..bfac6bebba3f 100644
--- a/lib/DebugInfo/MSF/MSFError.cpp
+++ b/lib/DebugInfo/MSF/MSFError.cpp
@@ -14,14 +14,12 @@
using namespace llvm;
using namespace llvm::msf;
-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 MSFErrorCategory : public std::error_category {
public:
const char *name() const noexcept override { return "llvm.msf"; }
-
std::string message(int Condition) const override {
switch (static_cast<msf_error_code>(Condition)) {
case msf_error_code::unspecified:
@@ -41,30 +39,8 @@ public:
llvm_unreachable("Unrecognized msf_error_code");
}
};
-} // end anonymous namespace
-
-static ManagedStatic<MSFErrorCategory> Category;
-
-char MSFError::ID = 0;
-
-MSFError::MSFError(msf_error_code C) : MSFError(C, "") {}
-
-MSFError::MSFError(const std::string &Context)
- : MSFError(msf_error_code::unspecified, Context) {}
-
-MSFError::MSFError(msf_error_code C, const std::string &Context) : Code(C) {
- ErrMsg = "MSF Error: ";
- std::error_code EC = convertToErrorCode();
- if (Code != msf_error_code::unspecified)
- ErrMsg += EC.message() + " ";
- if (!Context.empty())
- ErrMsg += Context;
-}
-
-void MSFError::log(raw_ostream &OS) const { OS << ErrMsg << "\n"; }
-const std::string &MSFError::getErrorMessage() const { return ErrMsg; }
+static llvm::ManagedStatic<MSFErrorCategory> MSFCategory;
+const std::error_category &llvm::msf::MSFErrCategory() { return *MSFCategory; }
-std::error_code MSFError::convertToErrorCode() const {
- return std::error_code(static_cast<int>(Code), *Category);
-}
+char MSFError::ID;
diff --git a/lib/DebugInfo/PDB/CMakeLists.txt b/lib/DebugInfo/PDB/CMakeLists.txt
index f6a529a69a8b..d9d379f6d091 100644
--- a/lib/DebugInfo/PDB/CMakeLists.txt
+++ b/lib/DebugInfo/PDB/CMakeLists.txt
@@ -14,6 +14,7 @@ if(LLVM_ENABLE_DIA_SDK)
add_pdb_impl_folder(DIA
DIA/DIADataStream.cpp
DIA/DIAEnumDebugStreams.cpp
+ DIA/DIAEnumFrameData.cpp
DIA/DIAEnumInjectedSources.cpp
DIA/DIAEnumLineNumbers.cpp
DIA/DIAEnumSectionContribs.cpp
@@ -21,6 +22,7 @@ if(LLVM_ENABLE_DIA_SDK)
DIA/DIAEnumSymbols.cpp
DIA/DIAEnumTables.cpp
DIA/DIAError.cpp
+ DIA/DIAFrameData.cpp
DIA/DIAInjectedSource.cpp
DIA/DIALineNumber.cpp
DIA/DIARawSymbol.cpp
@@ -46,13 +48,21 @@ add_pdb_impl_folder(Native
Native/InfoStream.cpp
Native/InfoStreamBuilder.cpp
Native/ModuleDebugStream.cpp
- Native/NativeBuiltinSymbol.cpp
Native/NativeCompilandSymbol.cpp
+ Native/NativeEnumGlobals.cpp
Native/NativeEnumModules.cpp
- Native/NativeEnumSymbol.cpp
Native/NativeEnumTypes.cpp
Native/NativeExeSymbol.cpp
Native/NativeRawSymbol.cpp
+ Native/NativeSymbolEnumerator.cpp
+ Native/NativeTypeArray.cpp
+ Native/NativeTypeBuiltin.cpp
+ Native/NativeTypeEnum.cpp
+ Native/NativeTypeFunctionSig.cpp
+ Native/NativeTypePointer.cpp
+ Native/NativeTypeTypedef.cpp
+ Native/NativeTypeUDT.cpp
+ Native/NativeTypeVTShape.cpp
Native/NamedStreamMap.cpp
Native/NativeSession.cpp
Native/PDBFile.cpp
@@ -62,6 +72,7 @@ add_pdb_impl_folder(Native
Native/PublicsStream.cpp
Native/GSIStreamBuilder.cpp
Native/RawError.cpp
+ Native/SymbolCache.cpp
Native/SymbolStream.cpp
Native/TpiHashing.cpp
Native/TpiStream.cpp
diff --git a/lib/DebugInfo/PDB/DIA/DIADataStream.cpp b/lib/DebugInfo/PDB/DIA/DIADataStream.cpp
index 7eabed8cad48..6a10513fad97 100644
--- a/lib/DebugInfo/PDB/DIA/DIADataStream.cpp
+++ b/lib/DebugInfo/PDB/DIA/DIADataStream.cpp
@@ -8,8 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/DIA/DIADataStream.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/Support/ConvertUTF.h"
+#include "llvm/DebugInfo/PDB/DIA/DIAUtils.h"
using namespace llvm;
using namespace llvm::pdb;
@@ -23,16 +22,7 @@ uint32_t DIADataStream::getRecordCount() const {
}
std::string DIADataStream::getName() const {
- CComBSTR Name16;
- if (S_OK != StreamData->get_name(&Name16))
- return std::string();
-
- std::string Name8;
- llvm::ArrayRef<char> Name16Bytes(reinterpret_cast<char *>(Name16.m_str),
- Name16.ByteLength());
- if (!llvm::convertUTF16ToUTF8String(Name16Bytes, Name8))
- return std::string();
- return Name8;
+ return invokeBstrMethod(*StreamData, &IDiaEnumDebugStreamData::get_name);
}
llvm::Optional<DIADataStream::RecordType>
@@ -65,11 +55,3 @@ bool DIADataStream::getNext(RecordType &Record) {
}
void DIADataStream::reset() { StreamData->Reset(); }
-
-DIADataStream *DIADataStream::clone() const {
- CComPtr<IDiaEnumDebugStreamData> EnumeratorClone;
- if (S_OK != StreamData->Clone(&EnumeratorClone))
- return nullptr;
-
- return new DIADataStream(EnumeratorClone);
-}
diff --git a/lib/DebugInfo/PDB/DIA/DIAEnumDebugStreams.cpp b/lib/DebugInfo/PDB/DIA/DIAEnumDebugStreams.cpp
index f62c4991fe33..d2451f13e6cb 100644
--- a/lib/DebugInfo/PDB/DIA/DIAEnumDebugStreams.cpp
+++ b/lib/DebugInfo/PDB/DIA/DIAEnumDebugStreams.cpp
@@ -45,10 +45,3 @@ std::unique_ptr<IPDBDataStream> DIAEnumDebugStreams::getNext() {
}
void DIAEnumDebugStreams::reset() { Enumerator->Reset(); }
-
-DIAEnumDebugStreams *DIAEnumDebugStreams::clone() const {
- CComPtr<IDiaEnumDebugStreams> EnumeratorClone;
- if (S_OK != Enumerator->Clone(&EnumeratorClone))
- return nullptr;
- return new DIAEnumDebugStreams(EnumeratorClone);
-}
diff --git a/lib/DebugInfo/PDB/DIA/DIAEnumFrameData.cpp b/lib/DebugInfo/PDB/DIA/DIAEnumFrameData.cpp
new file mode 100644
index 000000000000..f873f3525df5
--- /dev/null
+++ b/lib/DebugInfo/PDB/DIA/DIAEnumFrameData.cpp
@@ -0,0 +1,42 @@
+//==- DIAEnumFrameData.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/PDB/DIA/DIAEnumFrameData.h"
+#include "llvm/DebugInfo/PDB/DIA/DIAFrameData.h"
+#include "llvm/DebugInfo/PDB/DIA/DIASession.h"
+
+using namespace llvm::pdb;
+
+DIAEnumFrameData::DIAEnumFrameData(CComPtr<IDiaEnumFrameData> DiaEnumerator)
+ : Enumerator(DiaEnumerator) {}
+
+uint32_t DIAEnumFrameData::getChildCount() const {
+ LONG Count = 0;
+ return (S_OK == Enumerator->get_Count(&Count)) ? Count : 0;
+}
+
+std::unique_ptr<IPDBFrameData>
+DIAEnumFrameData::getChildAtIndex(uint32_t Index) const {
+ CComPtr<IDiaFrameData> Item;
+ if (S_OK != Enumerator->Item(Index, &Item))
+ return nullptr;
+
+ return std::unique_ptr<IPDBFrameData>(new DIAFrameData(Item));
+}
+
+std::unique_ptr<IPDBFrameData> DIAEnumFrameData::getNext() {
+ CComPtr<IDiaFrameData> Item;
+ ULONG NumFetched = 0;
+ if (S_OK != Enumerator->Next(1, &Item, &NumFetched))
+ return nullptr;
+
+ return std::unique_ptr<IPDBFrameData>(new DIAFrameData(Item));
+}
+
+void DIAEnumFrameData::reset() { Enumerator->Reset(); }
diff --git a/lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp b/lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp
index d7c908e04593..6c361b81e33d 100644
--- a/lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp
+++ b/lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp
@@ -15,9 +15,8 @@ using namespace llvm;
using namespace llvm::pdb;
DIAEnumInjectedSources::DIAEnumInjectedSources(
- const DIASession &PDBSession,
CComPtr<IDiaEnumInjectedSources> DiaEnumerator)
- : Session(PDBSession), Enumerator(DiaEnumerator) {}
+ : Enumerator(DiaEnumerator) {}
uint32_t DIAEnumInjectedSources::getChildCount() const {
LONG Count = 0;
@@ -43,10 +42,3 @@ std::unique_ptr<IPDBInjectedSource> DIAEnumInjectedSources::getNext() {
}
void DIAEnumInjectedSources::reset() { Enumerator->Reset(); }
-
-DIAEnumInjectedSources *DIAEnumInjectedSources::clone() const {
- CComPtr<IDiaEnumInjectedSources> EnumeratorClone;
- if (S_OK != Enumerator->Clone(&EnumeratorClone))
- return nullptr;
- return new DIAEnumInjectedSources(Session, EnumeratorClone);
-}
diff --git a/lib/DebugInfo/PDB/DIA/DIAEnumLineNumbers.cpp b/lib/DebugInfo/PDB/DIA/DIAEnumLineNumbers.cpp
index 796ce214b383..0820d9dc7c9f 100644
--- a/lib/DebugInfo/PDB/DIA/DIAEnumLineNumbers.cpp
+++ b/lib/DebugInfo/PDB/DIA/DIAEnumLineNumbers.cpp
@@ -42,10 +42,3 @@ std::unique_ptr<IPDBLineNumber> DIAEnumLineNumbers::getNext() {
}
void DIAEnumLineNumbers::reset() { Enumerator->Reset(); }
-
-DIAEnumLineNumbers *DIAEnumLineNumbers::clone() const {
- CComPtr<IDiaEnumLineNumbers> EnumeratorClone;
- if (S_OK != Enumerator->Clone(&EnumeratorClone))
- return nullptr;
- return new DIAEnumLineNumbers(EnumeratorClone);
-}
diff --git a/lib/DebugInfo/PDB/DIA/DIAEnumSectionContribs.cpp b/lib/DebugInfo/PDB/DIA/DIAEnumSectionContribs.cpp
index 1f405f049198..90c857aa5713 100644
--- a/lib/DebugInfo/PDB/DIA/DIAEnumSectionContribs.cpp
+++ b/lib/DebugInfo/PDB/DIA/DIAEnumSectionContribs.cpp
@@ -45,10 +45,3 @@ std::unique_ptr<IPDBSectionContrib> DIAEnumSectionContribs::getNext() {
}
void DIAEnumSectionContribs::reset() { Enumerator->Reset(); }
-
-DIAEnumSectionContribs *DIAEnumSectionContribs::clone() const {
- CComPtr<IDiaEnumSectionContribs> EnumeratorClone;
- if (S_OK != Enumerator->Clone(&EnumeratorClone))
- return nullptr;
- return new DIAEnumSectionContribs(Session, EnumeratorClone);
-}
diff --git a/lib/DebugInfo/PDB/DIA/DIAEnumSourceFiles.cpp b/lib/DebugInfo/PDB/DIA/DIAEnumSourceFiles.cpp
index b9311d060128..06595e7ec1c8 100644
--- a/lib/DebugInfo/PDB/DIA/DIAEnumSourceFiles.cpp
+++ b/lib/DebugInfo/PDB/DIA/DIAEnumSourceFiles.cpp
@@ -42,10 +42,3 @@ std::unique_ptr<IPDBSourceFile> DIAEnumSourceFiles::getNext() {
}
void DIAEnumSourceFiles::reset() { Enumerator->Reset(); }
-
-DIAEnumSourceFiles *DIAEnumSourceFiles::clone() const {
- CComPtr<IDiaEnumSourceFiles> EnumeratorClone;
- if (S_OK != Enumerator->Clone(&EnumeratorClone))
- return nullptr;
- return new DIAEnumSourceFiles(Session, EnumeratorClone);
-}
diff --git a/lib/DebugInfo/PDB/DIA/DIAEnumSymbols.cpp b/lib/DebugInfo/PDB/DIA/DIAEnumSymbols.cpp
index 266638530c2f..48bc32767e6c 100644
--- a/lib/DebugInfo/PDB/DIA/DIAEnumSymbols.cpp
+++ b/lib/DebugInfo/PDB/DIA/DIAEnumSymbols.cpp
@@ -46,10 +46,3 @@ std::unique_ptr<PDBSymbol> DIAEnumSymbols::getNext() {
}
void DIAEnumSymbols::reset() { Enumerator->Reset(); }
-
-DIAEnumSymbols *DIAEnumSymbols::clone() const {
- CComPtr<IDiaEnumSymbols> EnumeratorClone;
- if (S_OK != Enumerator->Clone(&EnumeratorClone))
- return nullptr;
- return new DIAEnumSymbols(Session, EnumeratorClone);
-}
diff --git a/lib/DebugInfo/PDB/DIA/DIAEnumTables.cpp b/lib/DebugInfo/PDB/DIA/DIAEnumTables.cpp
index 511b55585ebd..6fa096156d48 100644
--- a/lib/DebugInfo/PDB/DIA/DIAEnumTables.cpp
+++ b/lib/DebugInfo/PDB/DIA/DIAEnumTables.cpp
@@ -13,9 +13,8 @@
using namespace llvm;
using namespace llvm::pdb;
-DIAEnumTables::DIAEnumTables(
- CComPtr<IDiaEnumTables> DiaEnumerator)
- : Enumerator(DiaEnumerator) {}
+DIAEnumTables::DIAEnumTables(CComPtr<IDiaEnumTables> DiaEnumerator)
+ : Enumerator(DiaEnumerator) {}
uint32_t DIAEnumTables::getChildCount() const {
LONG Count = 0;
@@ -44,10 +43,3 @@ std::unique_ptr<IPDBTable> DIAEnumTables::getNext() {
}
void DIAEnumTables::reset() { Enumerator->Reset(); }
-
-DIAEnumTables *DIAEnumTables::clone() const {
- CComPtr<IDiaEnumTables> EnumeratorClone;
- if (S_OK != Enumerator->Clone(&EnumeratorClone))
- return nullptr;
- return new DIAEnumTables(EnumeratorClone);
-}
diff --git a/lib/DebugInfo/PDB/DIA/DIAError.cpp b/lib/DebugInfo/PDB/DIA/DIAError.cpp
index 0da877b0fbad..819651f77787 100644
--- a/lib/DebugInfo/PDB/DIA/DIAError.cpp
+++ b/lib/DebugInfo/PDB/DIA/DIAError.cpp
@@ -11,14 +11,13 @@ using namespace llvm::pdb;
class DIAErrorCategory : public std::error_category {
public:
const char *name() const noexcept override { return "llvm.pdb.dia"; }
-
std::string message(int Condition) const override {
switch (static_cast<dia_error_code>(Condition)) {
case dia_error_code::could_not_create_impl:
- return "Failed to connect to DIA at runtime. Verify that Visual Studio "
+ return "Failed to connect to DIA at runtime. Verify that Visual Studio "
"is properly installed, or that msdiaXX.dll is in your PATH.";
case dia_error_code::invalid_file_format:
- return "Unable to load PDB. The file has an unrecognized format.";
+ return "Unable to load PDB. The file has an unrecognized format.";
case dia_error_code::invalid_parameter:
return "The parameter is incorrect.";
case dia_error_code::already_loaded:
@@ -32,27 +31,7 @@ public:
}
};
-static ManagedStatic<DIAErrorCategory> Category;
-
-char DIAError::ID = 0;
-
-DIAError::DIAError(dia_error_code C) : DIAError(C, "") {}
-
-DIAError::DIAError(StringRef Context)
- : DIAError(dia_error_code::unspecified, Context) {}
-
-DIAError::DIAError(dia_error_code C, StringRef Context) : Code(C) {
- ErrMsg = "DIA Error: ";
- std::error_code EC = convertToErrorCode();
- ErrMsg += EC.message() + " ";
- if (!Context.empty())
- ErrMsg += Context;
-}
-
-void DIAError::log(raw_ostream &OS) const { OS << ErrMsg << "\n"; }
-
-StringRef DIAError::getErrorMessage() const { return ErrMsg; }
+static llvm::ManagedStatic<DIAErrorCategory> DIACategory;
+const std::error_category &llvm::pdb::DIAErrCategory() { return *DIACategory; }
-std::error_code DIAError::convertToErrorCode() const {
- return std::error_code(static_cast<int>(Code), *Category);
-}
+char DIAError::ID;
diff --git a/lib/DebugInfo/PDB/DIA/DIAFrameData.cpp b/lib/DebugInfo/PDB/DIA/DIAFrameData.cpp
new file mode 100644
index 000000000000..533cce7923c0
--- /dev/null
+++ b/lib/DebugInfo/PDB/DIA/DIAFrameData.cpp
@@ -0,0 +1,53 @@
+//===- DIAFrameData.cpp - DIA impl. of IPDBFrameData -------------- 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/PDB/DIA/DIAFrameData.h"
+#include "llvm/DebugInfo/PDB/DIA/DIASession.h"
+#include "llvm/DebugInfo/PDB/DIA/DIAUtils.h"
+
+using namespace llvm::pdb;
+
+DIAFrameData::DIAFrameData(CComPtr<IDiaFrameData> DiaFrameData)
+ : FrameData(DiaFrameData) {}
+
+template <typename ArgType>
+ArgType
+PrivateGetDIAValue(IDiaFrameData *FrameData,
+ HRESULT (__stdcall IDiaFrameData::*Method)(ArgType *)) {
+ ArgType Value;
+ if (S_OK == (FrameData->*Method)(&Value))
+ return static_cast<ArgType>(Value);
+
+ return ArgType();
+}
+
+uint32_t DIAFrameData::getAddressOffset() const {
+ return PrivateGetDIAValue(FrameData, &IDiaFrameData::get_addressOffset);
+}
+
+uint32_t DIAFrameData::getAddressSection() const {
+ return PrivateGetDIAValue(FrameData, &IDiaFrameData::get_addressSection);
+}
+
+uint32_t DIAFrameData::getLengthBlock() const {
+ return PrivateGetDIAValue(FrameData, &IDiaFrameData::get_lengthBlock);
+}
+
+std::string DIAFrameData::getProgram() const {
+ return invokeBstrMethod(*FrameData, &IDiaFrameData::get_program);
+}
+
+uint32_t DIAFrameData::getRelativeVirtualAddress() const {
+ return PrivateGetDIAValue(FrameData,
+ &IDiaFrameData::get_relativeVirtualAddress);
+}
+
+uint64_t DIAFrameData::getVirtualAddress() const {
+ return PrivateGetDIAValue(FrameData, &IDiaFrameData::get_virtualAddress);
+}
diff --git a/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp b/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
index 7d6cb254e1d1..cd4d00a13b18 100644
--- a/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
+++ b/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
@@ -15,6 +15,7 @@
#include "llvm/DebugInfo/PDB/DIA/DIAEnumSymbols.h"
#include "llvm/DebugInfo/PDB/DIA/DIALineNumber.h"
#include "llvm/DebugInfo/PDB/DIA/DIASession.h"
+#include "llvm/DebugInfo/PDB/DIA/DIAUtils.h"
#include "llvm/DebugInfo/PDB/PDBExtras.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
@@ -115,16 +116,7 @@ RetType PrivateGetDIAValue(IDiaSymbol *Symbol,
std::string
PrivateGetDIAValue(IDiaSymbol *Symbol,
HRESULT (__stdcall IDiaSymbol::*Method)(BSTR *)) {
- CComBSTR Result16;
- if (S_OK != (Symbol->*Method)(&Result16))
- return std::string();
-
- const char *SrcBytes = reinterpret_cast<const char *>(Result16.m_str);
- llvm::ArrayRef<char> SrcByteArray(SrcBytes, Result16.ByteLength());
- std::string Result8;
- if (!llvm::convertUTF16ToUTF8String(SrcByteArray, Result8))
- return std::string();
- return Result8;
+ return invokeBstrMethod(*Symbol, Method);
}
codeview::GUID
@@ -141,16 +133,33 @@ PrivateGetDIAValue(IDiaSymbol *Symbol,
return IdResult;
}
+template <typename PrintType, typename ArgType>
+void DumpDIAValueAs(llvm::raw_ostream &OS, int Indent, StringRef Name,
+ IDiaSymbol *Symbol,
+ HRESULT (__stdcall IDiaSymbol::*Method)(ArgType *)) {
+ ArgType Value;
+ if (S_OK == (Symbol->*Method)(&Value))
+ dumpSymbolField(OS, Name, static_cast<PrintType>(Value), Indent);
+}
+
+void DumpDIAIdValue(llvm::raw_ostream &OS, int Indent, StringRef Name,
+ IDiaSymbol *Symbol,
+ HRESULT (__stdcall IDiaSymbol::*Method)(DWORD *),
+ const IPDBSession &Session, PdbSymbolIdField FieldId,
+ PdbSymbolIdField ShowFlags, PdbSymbolIdField RecurseFlags) {
+ DWORD Value;
+ if (S_OK == (Symbol->*Method)(&Value))
+ dumpSymbolIdField(OS, Name, Value, Indent, Session, FieldId, ShowFlags,
+ RecurseFlags);
+}
+
template <typename ArgType>
void DumpDIAValue(llvm::raw_ostream &OS, int Indent, StringRef Name,
IDiaSymbol *Symbol,
HRESULT (__stdcall IDiaSymbol::*Method)(ArgType *)) {
ArgType Value;
- if (S_OK == (Symbol->*Method)(&Value)) {
- OS << "\n";
- OS.indent(Indent);
- OS << Name << ": " << Value;
- }
+ if (S_OK == (Symbol->*Method)(&Value))
+ dumpSymbolField(OS, Name, Value, Indent);
}
void DumpDIAValue(llvm::raw_ostream &OS, int Indent, StringRef Name,
@@ -162,11 +171,8 @@ void DumpDIAValue(llvm::raw_ostream &OS, int Indent, StringRef Name,
const char *Bytes = reinterpret_cast<const char *>(Value);
ArrayRef<char> ByteArray(Bytes, ::SysStringByteLen(Value));
std::string Result;
- if (llvm::convertUTF16ToUTF8String(ByteArray, Result)) {
- OS << "\n";
- OS.indent(Indent);
- OS << Name << ": " << Result;
- }
+ if (llvm::convertUTF16ToUTF8String(ByteArray, Result))
+ dumpSymbolField(OS, Name, Result, Indent);
::SysFreeString(Value);
}
@@ -177,12 +183,11 @@ void DumpDIAValue(llvm::raw_ostream &OS, int Indent, StringRef Name,
Value.vt = VT_EMPTY;
if (S_OK != (Symbol->*Method)(&Value))
return;
- OS << "\n";
- OS.indent(Indent);
Variant V = VariantFromVARIANT(Value);
- OS << Name << ": " << V;
-}
+
+ dumpSymbolField(OS, Name, V, Indent);
}
+} // namespace
namespace llvm {
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const GUID &G) {
@@ -191,182 +196,203 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const GUID &G) {
A.format(OS, "");
return OS;
}
-}
+} // namespace llvm
DIARawSymbol::DIARawSymbol(const DIASession &PDBSession,
CComPtr<IDiaSymbol> DiaSymbol)
: Session(PDBSession), Symbol(DiaSymbol) {}
+#define RAW_ID_METHOD_DUMP(Stream, Method, Session, FieldId, ShowFlags, \
+ RecurseFlags) \
+ DumpDIAIdValue(Stream, Indent, StringRef{#Method}, Symbol, \
+ &IDiaSymbol::get_##Method, Session, FieldId, ShowFlags, \
+ RecurseFlags);
+
#define RAW_METHOD_DUMP(Stream, Method) \
- DumpDIAValue(Stream, Indent, StringRef(#Method), Symbol, &IDiaSymbol::Method);
-
-void DIARawSymbol::dump(raw_ostream &OS, int Indent) const {
- RAW_METHOD_DUMP(OS, get_access)
- RAW_METHOD_DUMP(OS, get_addressOffset)
- RAW_METHOD_DUMP(OS, get_addressSection)
- RAW_METHOD_DUMP(OS, get_age)
- RAW_METHOD_DUMP(OS, get_arrayIndexTypeId)
- RAW_METHOD_DUMP(OS, get_backEndMajor)
- RAW_METHOD_DUMP(OS, get_backEndMinor)
- RAW_METHOD_DUMP(OS, get_backEndBuild)
- RAW_METHOD_DUMP(OS, get_backEndQFE)
- RAW_METHOD_DUMP(OS, get_baseDataOffset)
- RAW_METHOD_DUMP(OS, get_baseDataSlot)
- RAW_METHOD_DUMP(OS, get_baseSymbolId)
- RAW_METHOD_DUMP(OS, get_baseType)
- RAW_METHOD_DUMP(OS, get_bitPosition)
- RAW_METHOD_DUMP(OS, get_callingConvention)
- RAW_METHOD_DUMP(OS, get_classParentId)
- RAW_METHOD_DUMP(OS, get_compilerName)
- RAW_METHOD_DUMP(OS, get_count)
- RAW_METHOD_DUMP(OS, get_countLiveRanges)
- RAW_METHOD_DUMP(OS, get_frontEndMajor)
- RAW_METHOD_DUMP(OS, get_frontEndMinor)
- RAW_METHOD_DUMP(OS, get_frontEndBuild)
- RAW_METHOD_DUMP(OS, get_frontEndQFE)
- RAW_METHOD_DUMP(OS, get_lexicalParentId)
- RAW_METHOD_DUMP(OS, get_libraryName)
- RAW_METHOD_DUMP(OS, get_liveRangeStartAddressOffset)
- RAW_METHOD_DUMP(OS, get_liveRangeStartAddressSection)
- RAW_METHOD_DUMP(OS, get_liveRangeStartRelativeVirtualAddress)
- RAW_METHOD_DUMP(OS, get_localBasePointerRegisterId)
- RAW_METHOD_DUMP(OS, get_lowerBoundId)
- RAW_METHOD_DUMP(OS, get_memorySpaceKind)
- RAW_METHOD_DUMP(OS, get_name)
- RAW_METHOD_DUMP(OS, get_numberOfAcceleratorPointerTags)
- RAW_METHOD_DUMP(OS, get_numberOfColumns)
- RAW_METHOD_DUMP(OS, get_numberOfModifiers)
- RAW_METHOD_DUMP(OS, get_numberOfRegisterIndices)
- RAW_METHOD_DUMP(OS, get_numberOfRows)
- RAW_METHOD_DUMP(OS, get_objectFileName)
- RAW_METHOD_DUMP(OS, get_oemId)
- RAW_METHOD_DUMP(OS, get_oemSymbolId)
- RAW_METHOD_DUMP(OS, get_offsetInUdt)
- RAW_METHOD_DUMP(OS, get_platform)
- RAW_METHOD_DUMP(OS, get_rank)
- RAW_METHOD_DUMP(OS, get_registerId)
- RAW_METHOD_DUMP(OS, get_registerType)
- RAW_METHOD_DUMP(OS, get_relativeVirtualAddress)
- RAW_METHOD_DUMP(OS, get_samplerSlot)
- RAW_METHOD_DUMP(OS, get_signature)
- RAW_METHOD_DUMP(OS, get_sizeInUdt)
- RAW_METHOD_DUMP(OS, get_slot)
- RAW_METHOD_DUMP(OS, get_sourceFileName)
- RAW_METHOD_DUMP(OS, get_stride)
- RAW_METHOD_DUMP(OS, get_subTypeId)
- RAW_METHOD_DUMP(OS, get_symbolsFileName)
- RAW_METHOD_DUMP(OS, get_symIndexId)
- RAW_METHOD_DUMP(OS, get_targetOffset)
- RAW_METHOD_DUMP(OS, get_targetRelativeVirtualAddress)
- RAW_METHOD_DUMP(OS, get_targetVirtualAddress)
- RAW_METHOD_DUMP(OS, get_targetSection)
- RAW_METHOD_DUMP(OS, get_textureSlot)
- RAW_METHOD_DUMP(OS, get_timeStamp)
- RAW_METHOD_DUMP(OS, get_token)
- RAW_METHOD_DUMP(OS, get_typeId)
- RAW_METHOD_DUMP(OS, get_uavSlot)
- RAW_METHOD_DUMP(OS, get_undecoratedName)
- RAW_METHOD_DUMP(OS, get_unmodifiedTypeId)
- RAW_METHOD_DUMP(OS, get_upperBoundId)
- RAW_METHOD_DUMP(OS, get_virtualBaseDispIndex)
- RAW_METHOD_DUMP(OS, get_virtualBaseOffset)
- RAW_METHOD_DUMP(OS, get_virtualTableShapeId)
- RAW_METHOD_DUMP(OS, get_dataKind)
- RAW_METHOD_DUMP(OS, get_symTag)
- RAW_METHOD_DUMP(OS, get_guid)
- RAW_METHOD_DUMP(OS, get_offset)
- RAW_METHOD_DUMP(OS, get_thisAdjust)
- RAW_METHOD_DUMP(OS, get_virtualBasePointerOffset)
- RAW_METHOD_DUMP(OS, get_locationType)
- RAW_METHOD_DUMP(OS, get_machineType)
- RAW_METHOD_DUMP(OS, get_thunkOrdinal)
- RAW_METHOD_DUMP(OS, get_length)
- RAW_METHOD_DUMP(OS, get_liveRangeLength)
- RAW_METHOD_DUMP(OS, get_virtualAddress)
- RAW_METHOD_DUMP(OS, get_udtKind)
- RAW_METHOD_DUMP(OS, get_constructor)
- RAW_METHOD_DUMP(OS, get_customCallingConvention)
- RAW_METHOD_DUMP(OS, get_farReturn)
- RAW_METHOD_DUMP(OS, get_code)
- RAW_METHOD_DUMP(OS, get_compilerGenerated)
- RAW_METHOD_DUMP(OS, get_constType)
- RAW_METHOD_DUMP(OS, get_editAndContinueEnabled)
- RAW_METHOD_DUMP(OS, get_function)
- RAW_METHOD_DUMP(OS, get_stride)
- RAW_METHOD_DUMP(OS, get_noStackOrdering)
- RAW_METHOD_DUMP(OS, get_hasAlloca)
- RAW_METHOD_DUMP(OS, get_hasAssignmentOperator)
- RAW_METHOD_DUMP(OS, get_isCTypes)
- RAW_METHOD_DUMP(OS, get_hasCastOperator)
- RAW_METHOD_DUMP(OS, get_hasDebugInfo)
- RAW_METHOD_DUMP(OS, get_hasEH)
- RAW_METHOD_DUMP(OS, get_hasEHa)
- RAW_METHOD_DUMP(OS, get_hasInlAsm)
- RAW_METHOD_DUMP(OS, get_framePointerPresent)
- RAW_METHOD_DUMP(OS, get_inlSpec)
- RAW_METHOD_DUMP(OS, get_interruptReturn)
- RAW_METHOD_DUMP(OS, get_hasLongJump)
- RAW_METHOD_DUMP(OS, get_hasManagedCode)
- RAW_METHOD_DUMP(OS, get_hasNestedTypes)
- RAW_METHOD_DUMP(OS, get_noInline)
- RAW_METHOD_DUMP(OS, get_noReturn)
- RAW_METHOD_DUMP(OS, get_optimizedCodeDebugInfo)
- RAW_METHOD_DUMP(OS, get_overloadedOperator)
- RAW_METHOD_DUMP(OS, get_hasSEH)
- RAW_METHOD_DUMP(OS, get_hasSecurityChecks)
- RAW_METHOD_DUMP(OS, get_hasSetJump)
- RAW_METHOD_DUMP(OS, get_strictGSCheck)
- RAW_METHOD_DUMP(OS, get_isAcceleratorGroupSharedLocal)
- RAW_METHOD_DUMP(OS, get_isAcceleratorPointerTagLiveRange)
- RAW_METHOD_DUMP(OS, get_isAcceleratorStubFunction)
- RAW_METHOD_DUMP(OS, get_isAggregated)
- RAW_METHOD_DUMP(OS, get_intro)
- RAW_METHOD_DUMP(OS, get_isCVTCIL)
- RAW_METHOD_DUMP(OS, get_isConstructorVirtualBase)
- RAW_METHOD_DUMP(OS, get_isCxxReturnUdt)
- RAW_METHOD_DUMP(OS, get_isDataAligned)
- RAW_METHOD_DUMP(OS, get_isHLSLData)
- RAW_METHOD_DUMP(OS, get_isHotpatchable)
- RAW_METHOD_DUMP(OS, get_indirectVirtualBaseClass)
- RAW_METHOD_DUMP(OS, get_isInterfaceUdt)
- RAW_METHOD_DUMP(OS, get_intrinsic)
- RAW_METHOD_DUMP(OS, get_isLTCG)
- RAW_METHOD_DUMP(OS, get_isLocationControlFlowDependent)
- RAW_METHOD_DUMP(OS, get_isMSILNetmodule)
- RAW_METHOD_DUMP(OS, get_isMatrixRowMajor)
- RAW_METHOD_DUMP(OS, get_managed)
- RAW_METHOD_DUMP(OS, get_msil)
- RAW_METHOD_DUMP(OS, get_isMultipleInheritance)
- RAW_METHOD_DUMP(OS, get_isNaked)
- RAW_METHOD_DUMP(OS, get_nested)
- RAW_METHOD_DUMP(OS, get_isOptimizedAway)
- RAW_METHOD_DUMP(OS, get_packed)
- RAW_METHOD_DUMP(OS, get_isPointerBasedOnSymbolValue)
- RAW_METHOD_DUMP(OS, get_isPointerToDataMember)
- RAW_METHOD_DUMP(OS, get_isPointerToMemberFunction)
- RAW_METHOD_DUMP(OS, get_pure)
- RAW_METHOD_DUMP(OS, get_RValueReference)
- RAW_METHOD_DUMP(OS, get_isRefUdt)
- RAW_METHOD_DUMP(OS, get_reference)
- RAW_METHOD_DUMP(OS, get_restrictedType)
- RAW_METHOD_DUMP(OS, get_isReturnValue)
- RAW_METHOD_DUMP(OS, get_isSafeBuffers)
- RAW_METHOD_DUMP(OS, get_scoped)
- RAW_METHOD_DUMP(OS, get_isSdl)
- RAW_METHOD_DUMP(OS, get_isSingleInheritance)
- RAW_METHOD_DUMP(OS, get_isSplitted)
- RAW_METHOD_DUMP(OS, get_isStatic)
- RAW_METHOD_DUMP(OS, get_isStripped)
- RAW_METHOD_DUMP(OS, get_unalignedType)
- RAW_METHOD_DUMP(OS, get_notReached)
- RAW_METHOD_DUMP(OS, get_isValueUdt)
- RAW_METHOD_DUMP(OS, get_virtual)
- RAW_METHOD_DUMP(OS, get_virtualBaseClass)
- RAW_METHOD_DUMP(OS, get_isVirtualInheritance)
- RAW_METHOD_DUMP(OS, get_volatileType)
- RAW_METHOD_DUMP(OS, get_wasInlined)
- RAW_METHOD_DUMP(OS, get_unused)
- RAW_METHOD_DUMP(OS, get_value)
+ DumpDIAValue(Stream, Indent, StringRef{#Method}, Symbol, \
+ &IDiaSymbol::get_##Method);
+
+#define RAW_METHOD_DUMP_AS(Stream, Method, Type) \
+ DumpDIAValueAs<Type>(Stream, Indent, StringRef{#Method}, Symbol, \
+ &IDiaSymbol::get_##Method);
+
+void DIARawSymbol::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+ RAW_ID_METHOD_DUMP(OS, symIndexId, Session, PdbSymbolIdField::SymIndexId,
+ ShowIdFields, RecurseIdFields);
+ RAW_METHOD_DUMP_AS(OS, symTag, PDB_SymType);
+
+ RAW_METHOD_DUMP(OS, access);
+ RAW_METHOD_DUMP(OS, addressOffset);
+ RAW_METHOD_DUMP(OS, addressSection);
+ RAW_METHOD_DUMP(OS, age);
+ RAW_METHOD_DUMP(OS, arrayIndexTypeId);
+ RAW_METHOD_DUMP(OS, backEndMajor);
+ RAW_METHOD_DUMP(OS, backEndMinor);
+ RAW_METHOD_DUMP(OS, backEndBuild);
+ RAW_METHOD_DUMP(OS, backEndQFE);
+ RAW_METHOD_DUMP(OS, baseDataOffset);
+ RAW_METHOD_DUMP(OS, baseDataSlot);
+ RAW_METHOD_DUMP(OS, baseSymbolId);
+ RAW_METHOD_DUMP_AS(OS, baseType, PDB_BuiltinType);
+ RAW_METHOD_DUMP(OS, bitPosition);
+ RAW_METHOD_DUMP_AS(OS, callingConvention, PDB_CallingConv);
+ RAW_ID_METHOD_DUMP(OS, classParentId, Session, PdbSymbolIdField::ClassParent,
+ ShowIdFields, RecurseIdFields);
+ RAW_METHOD_DUMP(OS, compilerName);
+ RAW_METHOD_DUMP(OS, count);
+ RAW_METHOD_DUMP(OS, countLiveRanges);
+ RAW_METHOD_DUMP(OS, frontEndMajor);
+ RAW_METHOD_DUMP(OS, frontEndMinor);
+ RAW_METHOD_DUMP(OS, frontEndBuild);
+ RAW_METHOD_DUMP(OS, frontEndQFE);
+ RAW_ID_METHOD_DUMP(OS, lexicalParentId, Session,
+ PdbSymbolIdField::LexicalParent, ShowIdFields,
+ RecurseIdFields);
+ RAW_METHOD_DUMP(OS, libraryName);
+ RAW_METHOD_DUMP(OS, liveRangeStartAddressOffset);
+ RAW_METHOD_DUMP(OS, liveRangeStartAddressSection);
+ RAW_METHOD_DUMP(OS, liveRangeStartRelativeVirtualAddress);
+ RAW_METHOD_DUMP(OS, localBasePointerRegisterId);
+ RAW_METHOD_DUMP(OS, lowerBoundId);
+ RAW_METHOD_DUMP(OS, memorySpaceKind);
+ RAW_METHOD_DUMP(OS, name);
+ RAW_METHOD_DUMP(OS, numberOfAcceleratorPointerTags);
+ RAW_METHOD_DUMP(OS, numberOfColumns);
+ RAW_METHOD_DUMP(OS, numberOfModifiers);
+ RAW_METHOD_DUMP(OS, numberOfRegisterIndices);
+ RAW_METHOD_DUMP(OS, numberOfRows);
+ RAW_METHOD_DUMP(OS, objectFileName);
+ RAW_METHOD_DUMP(OS, oemId);
+ RAW_METHOD_DUMP(OS, oemSymbolId);
+ RAW_METHOD_DUMP(OS, offsetInUdt);
+ RAW_METHOD_DUMP(OS, platform);
+ RAW_METHOD_DUMP(OS, rank);
+ RAW_METHOD_DUMP(OS, registerId);
+ RAW_METHOD_DUMP(OS, registerType);
+ RAW_METHOD_DUMP(OS, relativeVirtualAddress);
+ RAW_METHOD_DUMP(OS, samplerSlot);
+ RAW_METHOD_DUMP(OS, signature);
+ RAW_METHOD_DUMP(OS, sizeInUdt);
+ RAW_METHOD_DUMP(OS, slot);
+ RAW_METHOD_DUMP(OS, sourceFileName);
+ RAW_METHOD_DUMP(OS, stride);
+ RAW_METHOD_DUMP(OS, subTypeId);
+ RAW_METHOD_DUMP(OS, symbolsFileName);
+ RAW_METHOD_DUMP(OS, targetOffset);
+ RAW_METHOD_DUMP(OS, targetRelativeVirtualAddress);
+ RAW_METHOD_DUMP(OS, targetVirtualAddress);
+ RAW_METHOD_DUMP(OS, targetSection);
+ RAW_METHOD_DUMP(OS, textureSlot);
+ RAW_METHOD_DUMP(OS, timeStamp);
+ RAW_METHOD_DUMP(OS, token);
+ RAW_ID_METHOD_DUMP(OS, typeId, Session, PdbSymbolIdField::Type, ShowIdFields,
+ RecurseIdFields);
+ RAW_METHOD_DUMP(OS, uavSlot);
+ RAW_METHOD_DUMP(OS, undecoratedName);
+ RAW_ID_METHOD_DUMP(OS, unmodifiedTypeId, Session,
+ PdbSymbolIdField::UnmodifiedType, ShowIdFields,
+ RecurseIdFields);
+ RAW_METHOD_DUMP(OS, upperBoundId);
+ RAW_METHOD_DUMP(OS, virtualBaseDispIndex);
+ RAW_METHOD_DUMP(OS, virtualBaseOffset);
+ RAW_METHOD_DUMP(OS, virtualTableShapeId);
+ RAW_METHOD_DUMP_AS(OS, dataKind, PDB_DataKind);
+ RAW_METHOD_DUMP(OS, guid);
+ RAW_METHOD_DUMP(OS, offset);
+ RAW_METHOD_DUMP(OS, thisAdjust);
+ RAW_METHOD_DUMP(OS, virtualBasePointerOffset);
+ RAW_METHOD_DUMP_AS(OS, locationType, PDB_LocType);
+ RAW_METHOD_DUMP(OS, machineType);
+ RAW_METHOD_DUMP(OS, thunkOrdinal);
+ RAW_METHOD_DUMP(OS, length);
+ RAW_METHOD_DUMP(OS, liveRangeLength);
+ RAW_METHOD_DUMP(OS, virtualAddress);
+ RAW_METHOD_DUMP_AS(OS, udtKind, PDB_UdtType);
+ RAW_METHOD_DUMP(OS, constructor);
+ RAW_METHOD_DUMP(OS, customCallingConvention);
+ RAW_METHOD_DUMP(OS, farReturn);
+ RAW_METHOD_DUMP(OS, code);
+ RAW_METHOD_DUMP(OS, compilerGenerated);
+ RAW_METHOD_DUMP(OS, constType);
+ RAW_METHOD_DUMP(OS, editAndContinueEnabled);
+ RAW_METHOD_DUMP(OS, function);
+ RAW_METHOD_DUMP(OS, stride);
+ RAW_METHOD_DUMP(OS, noStackOrdering);
+ RAW_METHOD_DUMP(OS, hasAlloca);
+ RAW_METHOD_DUMP(OS, hasAssignmentOperator);
+ RAW_METHOD_DUMP(OS, isCTypes);
+ RAW_METHOD_DUMP(OS, hasCastOperator);
+ RAW_METHOD_DUMP(OS, hasDebugInfo);
+ RAW_METHOD_DUMP(OS, hasEH);
+ RAW_METHOD_DUMP(OS, hasEHa);
+ RAW_METHOD_DUMP(OS, hasInlAsm);
+ RAW_METHOD_DUMP(OS, framePointerPresent);
+ RAW_METHOD_DUMP(OS, inlSpec);
+ RAW_METHOD_DUMP(OS, interruptReturn);
+ RAW_METHOD_DUMP(OS, hasLongJump);
+ RAW_METHOD_DUMP(OS, hasManagedCode);
+ RAW_METHOD_DUMP(OS, hasNestedTypes);
+ RAW_METHOD_DUMP(OS, noInline);
+ RAW_METHOD_DUMP(OS, noReturn);
+ RAW_METHOD_DUMP(OS, optimizedCodeDebugInfo);
+ RAW_METHOD_DUMP(OS, overloadedOperator);
+ RAW_METHOD_DUMP(OS, hasSEH);
+ RAW_METHOD_DUMP(OS, hasSecurityChecks);
+ RAW_METHOD_DUMP(OS, hasSetJump);
+ RAW_METHOD_DUMP(OS, strictGSCheck);
+ RAW_METHOD_DUMP(OS, isAcceleratorGroupSharedLocal);
+ RAW_METHOD_DUMP(OS, isAcceleratorPointerTagLiveRange);
+ RAW_METHOD_DUMP(OS, isAcceleratorStubFunction);
+ RAW_METHOD_DUMP(OS, isAggregated);
+ RAW_METHOD_DUMP(OS, intro);
+ RAW_METHOD_DUMP(OS, isCVTCIL);
+ RAW_METHOD_DUMP(OS, isConstructorVirtualBase);
+ RAW_METHOD_DUMP(OS, isCxxReturnUdt);
+ RAW_METHOD_DUMP(OS, isDataAligned);
+ RAW_METHOD_DUMP(OS, isHLSLData);
+ RAW_METHOD_DUMP(OS, isHotpatchable);
+ RAW_METHOD_DUMP(OS, indirectVirtualBaseClass);
+ RAW_METHOD_DUMP(OS, isInterfaceUdt);
+ RAW_METHOD_DUMP(OS, intrinsic);
+ RAW_METHOD_DUMP(OS, isLTCG);
+ RAW_METHOD_DUMP(OS, isLocationControlFlowDependent);
+ RAW_METHOD_DUMP(OS, isMSILNetmodule);
+ RAW_METHOD_DUMP(OS, isMatrixRowMajor);
+ RAW_METHOD_DUMP(OS, managed);
+ RAW_METHOD_DUMP(OS, msil);
+ RAW_METHOD_DUMP(OS, isMultipleInheritance);
+ RAW_METHOD_DUMP(OS, isNaked);
+ RAW_METHOD_DUMP(OS, nested);
+ RAW_METHOD_DUMP(OS, isOptimizedAway);
+ RAW_METHOD_DUMP(OS, packed);
+ RAW_METHOD_DUMP(OS, isPointerBasedOnSymbolValue);
+ RAW_METHOD_DUMP(OS, isPointerToDataMember);
+ RAW_METHOD_DUMP(OS, isPointerToMemberFunction);
+ RAW_METHOD_DUMP(OS, pure);
+ RAW_METHOD_DUMP(OS, RValueReference);
+ RAW_METHOD_DUMP(OS, isRefUdt);
+ RAW_METHOD_DUMP(OS, reference);
+ RAW_METHOD_DUMP(OS, restrictedType);
+ RAW_METHOD_DUMP(OS, isReturnValue);
+ RAW_METHOD_DUMP(OS, isSafeBuffers);
+ RAW_METHOD_DUMP(OS, scoped);
+ RAW_METHOD_DUMP(OS, isSdl);
+ RAW_METHOD_DUMP(OS, isSingleInheritance);
+ RAW_METHOD_DUMP(OS, isSplitted);
+ RAW_METHOD_DUMP(OS, isStatic);
+ RAW_METHOD_DUMP(OS, isStripped);
+ RAW_METHOD_DUMP(OS, unalignedType);
+ RAW_METHOD_DUMP(OS, notReached);
+ RAW_METHOD_DUMP(OS, isValueUdt);
+ RAW_METHOD_DUMP(OS, virtual);
+ RAW_METHOD_DUMP(OS, virtualBaseClass);
+ RAW_METHOD_DUMP(OS, isVirtualInheritance);
+ RAW_METHOD_DUMP(OS, volatileType);
+ RAW_METHOD_DUMP(OS, wasInlined);
+ RAW_METHOD_DUMP(OS, unused);
+ RAW_METHOD_DUMP(OS, value);
}
std::unique_ptr<IPDBEnumSymbols>
@@ -414,9 +440,8 @@ DIARawSymbol::findChildrenByAddr(PDB_SymType Type, StringRef Name,
wchar_t *Name16Str = reinterpret_cast<wchar_t *>(Name16.data());
CComPtr<IDiaEnumSymbols> DiaEnumerator;
- if (S_OK !=
- Symbol->findChildrenExByAddr(EnumVal, Name16Str, CompareFlags, Section,
- Offset, &DiaEnumerator))
+ if (S_OK != Symbol->findChildrenExByAddr(EnumVal, Name16Str, CompareFlags,
+ Section, Offset, &DiaEnumerator))
return nullptr;
return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
@@ -434,9 +459,8 @@ DIARawSymbol::findChildrenByVA(PDB_SymType Type, StringRef Name,
wchar_t *Name16Str = reinterpret_cast<wchar_t *>(Name16.data());
CComPtr<IDiaEnumSymbols> DiaEnumerator;
- if (S_OK !=
- Symbol->findChildrenExByVA(EnumVal, Name16Str, CompareFlags, VA,
- &DiaEnumerator))
+ if (S_OK != Symbol->findChildrenExByVA(EnumVal, Name16Str, CompareFlags, VA,
+ &DiaEnumerator))
return nullptr;
return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
@@ -453,9 +477,8 @@ DIARawSymbol::findChildrenByRVA(PDB_SymType Type, StringRef Name,
wchar_t *Name16Str = reinterpret_cast<wchar_t *>(Name16.data());
CComPtr<IDiaEnumSymbols> DiaEnumerator;
- if (S_OK !=
- Symbol->findChildrenExByRVA(EnumVal, Name16Str, CompareFlags, RVA,
- &DiaEnumerator))
+ if (S_OK != Symbol->findChildrenExByRVA(EnumVal, Name16Str, CompareFlags, RVA,
+ &DiaEnumerator))
return nullptr;
return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
@@ -500,7 +523,8 @@ std::unique_ptr<IPDBEnumLineNumbers>
DIARawSymbol::findInlineeLinesByAddr(uint32_t Section, uint32_t Offset,
uint32_t Length) const {
CComPtr<IDiaEnumLineNumbers> DiaEnumerator;
- if (S_OK != Symbol->findInlineeLinesByAddr(Section, Offset, Length, &DiaEnumerator))
+ if (S_OK !=
+ Symbol->findInlineeLinesByAddr(Section, Offset, Length, &DiaEnumerator))
return nullptr;
return llvm::make_unique<DIAEnumLineNumbers>(DiaEnumerator);
@@ -536,8 +560,7 @@ void DIARawSymbol::getDataBytes(llvm::SmallVector<uint8_t, 32> &bytes) const {
Symbol->get_dataBytes(DataSize, &DataSize, bytes.data());
}
-std::string
-DIARawSymbol::getUndecoratedNameEx(PDB_UndnameFlags Flags) const {
+std::string DIARawSymbol::getUndecoratedNameEx(PDB_UndnameFlags Flags) const {
CComBSTR Result16;
if (S_OK != Symbol->get_undecoratedNameEx((DWORD)Flags, &Result16))
return std::string();
@@ -567,7 +590,7 @@ uint32_t DIARawSymbol::getAge() const {
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_age);
}
-uint32_t DIARawSymbol::getArrayIndexTypeId() const {
+SymIndexId DIARawSymbol::getArrayIndexTypeId() const {
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_arrayIndexTypeId);
}
@@ -586,7 +609,7 @@ uint32_t DIARawSymbol::getBaseDataSlot() const {
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_baseDataSlot);
}
-uint32_t DIARawSymbol::getBaseSymbolId() const {
+SymIndexId DIARawSymbol::getBaseSymbolId() const {
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_baseSymbolId);
}
@@ -604,7 +627,7 @@ PDB_CallingConv DIARawSymbol::getCallingConvention() const {
Symbol, &IDiaSymbol::get_callingConvention);
}
-uint32_t DIARawSymbol::getClassParentId() const {
+SymIndexId DIARawSymbol::getClassParentId() const {
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_classParentId);
}
@@ -631,7 +654,7 @@ PDB_Lang DIARawSymbol::getLanguage() const {
return PrivateGetDIAValue<DWORD, PDB_Lang>(Symbol, &IDiaSymbol::get_language);
}
-uint32_t DIARawSymbol::getLexicalParentId() const {
+SymIndexId DIARawSymbol::getLexicalParentId() const {
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_lexicalParentId);
}
@@ -659,7 +682,7 @@ codeview::RegisterId DIARawSymbol::getLocalBasePointerRegisterId() const {
Symbol, &IDiaSymbol::get_localBasePointerRegisterId);
}
-uint32_t DIARawSymbol::getLowerBoundId() const {
+SymIndexId DIARawSymbol::getLowerBoundId() const {
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_lowerBoundId);
}
@@ -700,7 +723,7 @@ uint32_t DIARawSymbol::getOemId() const {
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_oemId);
}
-uint32_t DIARawSymbol::getOemSymbolId() const {
+SymIndexId DIARawSymbol::getOemSymbolId() const {
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_oemSymbolId);
}
@@ -749,8 +772,7 @@ std::string DIARawSymbol::getSourceFileName() const {
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_sourceFileName);
}
-std::unique_ptr<IPDBLineNumber>
-DIARawSymbol::getSrcLineOnTypeDefn() const {
+std::unique_ptr<IPDBLineNumber> DIARawSymbol::getSrcLineOnTypeDefn() const {
CComPtr<IDiaLineNumber> LineNumber;
if (FAILED(Symbol->getSrcLineOnTypeDefn(&LineNumber)) || !LineNumber)
return nullptr;
@@ -762,7 +784,7 @@ uint32_t DIARawSymbol::getStride() const {
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_stride);
}
-uint32_t DIARawSymbol::getSubTypeId() const {
+SymIndexId DIARawSymbol::getSubTypeId() const {
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_subTypeId);
}
@@ -770,7 +792,7 @@ std::string DIARawSymbol::getSymbolsFileName() const {
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_symbolsFileName);
}
-uint32_t DIARawSymbol::getSymIndexId() const {
+SymIndexId DIARawSymbol::getSymIndexId() const {
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_symIndexId);
}
@@ -803,7 +825,7 @@ uint32_t DIARawSymbol::getToken() const {
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_token);
}
-uint32_t DIARawSymbol::getTypeId() const {
+SymIndexId DIARawSymbol::getTypeId() const {
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_typeId);
}
@@ -815,11 +837,11 @@ std::string DIARawSymbol::getUndecoratedName() const {
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_undecoratedName);
}
-uint32_t DIARawSymbol::getUnmodifiedTypeId() const {
+SymIndexId DIARawSymbol::getUnmodifiedTypeId() const {
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_unmodifiedTypeId);
}
-uint32_t DIARawSymbol::getUpperBoundId() const {
+SymIndexId DIARawSymbol::getUpperBoundId() const {
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_upperBoundId);
}
@@ -840,7 +862,7 @@ uint32_t DIARawSymbol::getVirtualBaseOffset() const {
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_virtualBaseOffset);
}
-uint32_t DIARawSymbol::getVirtualTableShapeId() const {
+SymIndexId DIARawSymbol::getVirtualTableShapeId() const {
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_virtualTableShapeId);
}
@@ -852,7 +874,7 @@ DIARawSymbol::getVirtualBaseTableType() const {
auto RawVT = llvm::make_unique<DIARawSymbol>(Session, TableType);
auto Pointer =
- llvm::make_unique<PDBSymbolTypePointer>(Session, std::move(RawVT));
+ PDBSymbol::createAs<PDBSymbolTypePointer>(Session, std::move(RawVT));
return unique_dyn_cast<PDBSymbolTypeBuiltin>(Pointer->getPointeeType());
}
diff --git a/lib/DebugInfo/PDB/DIA/DIASectionContrib.cpp b/lib/DebugInfo/PDB/DIA/DIASectionContrib.cpp
index b7dc49f53e23..8e233ca15161 100644
--- a/lib/DebugInfo/PDB/DIA/DIASectionContrib.cpp
+++ b/lib/DebugInfo/PDB/DIA/DIASectionContrib.cpp
@@ -25,7 +25,7 @@ std::unique_ptr<PDBSymbolCompiland> DIASectionContrib::getCompiland() const {
return nullptr;
auto RawSymbol = llvm::make_unique<DIARawSymbol>(Session, Symbol);
- return llvm::make_unique<PDBSymbolCompiland>(Session, std::move(RawSymbol));
+ return PDBSymbol::createAs<PDBSymbolCompiland>(Session, std::move(RawSymbol));
}
template <typename ArgType>
diff --git a/lib/DebugInfo/PDB/DIA/DIASession.cpp b/lib/DebugInfo/PDB/DIA/DIASession.cpp
index d81f59400eb3..bd375e172ac0 100644
--- a/lib/DebugInfo/PDB/DIA/DIASession.cpp
+++ b/lib/DebugInfo/PDB/DIA/DIASession.cpp
@@ -9,6 +9,7 @@
#include "llvm/DebugInfo/PDB/DIA/DIASession.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h"
+#include "llvm/DebugInfo/PDB/DIA/DIAEnumFrameData.h"
#include "llvm/DebugInfo/PDB/DIA/DIAEnumInjectedSources.h"
#include "llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h"
#include "llvm/DebugInfo/PDB/DIA/DIAEnumSectionContribs.h"
@@ -42,7 +43,7 @@ static Error ErrorFromHResult(HRESULT Result, const char *Str, Ts &&... Args) {
switch (Result) {
case E_PDB_NOT_FOUND:
- return make_error<GenericError>(generic_error_code::invalid_path, Context);
+ return errorCodeToError(std::error_code(ENOENT, std::generic_category()));
case E_PDB_FORMAT:
return make_error<DIAError>(dia_error_code::invalid_file_format, Context);
case E_INVALIDARG:
@@ -71,8 +72,7 @@ static Error LoadDIA(CComPtr<IDiaDataSource> &DiaDataSource) {
// If the CoCreateInstance call above failed, msdia*.dll is not registered.
// Try loading the DLL corresponding to the #included DIA SDK.
#if !defined(_MSC_VER)
- return llvm::make_error<GenericError>(
- "DIA is only supported when using MSVC.");
+ return llvm::make_error<PDBError>(pdb_error_code::dia_failed_loading);
#else
const wchar_t *msdia_dll = nullptr;
#if _MSC_VER >= 1900 && _MSC_VER < 2000
@@ -104,7 +104,7 @@ Error DIASession::createFromPdb(StringRef Path,
llvm::SmallVector<UTF16, 128> Path16;
if (!llvm::convertUTF8ToUTF16String(Path, Path16))
- return make_error<GenericError>(generic_error_code::invalid_path);
+ return make_error<PDBError>(pdb_error_code::invalid_utf8_path, Path);
const wchar_t *Path16Str = reinterpret_cast<const wchar_t *>(Path16.data());
HRESULT HR;
@@ -130,7 +130,7 @@ Error DIASession::createFromExe(StringRef Path,
llvm::SmallVector<UTF16, 128> Path16;
if (!llvm::convertUTF8ToUTF16String(Path, Path16))
- return make_error<GenericError>(generic_error_code::invalid_path, Path);
+ return make_error<PDBError>(pdb_error_code::invalid_utf8_path, Path);
const wchar_t *Path16Str = reinterpret_cast<const wchar_t *>(Path16.data());
HRESULT HR;
@@ -188,7 +188,8 @@ bool DIASession::addressForRVA(uint32_t RVA, uint32_t &Section,
return false;
}
-std::unique_ptr<PDBSymbol> DIASession::getSymbolById(uint32_t SymbolId) const {
+std::unique_ptr<PDBSymbol>
+DIASession::getSymbolById(SymIndexId SymbolId) const {
CComPtr<IDiaSymbol> LocatedSymbol;
if (S_OK != Session->symbolById(SymbolId, &LocatedSymbol))
return nullptr;
@@ -407,7 +408,7 @@ DIASession::getInjectedSources() const {
if (!Files)
return nullptr;
- return llvm::make_unique<DIAEnumInjectedSources>(*this, Files);
+ return llvm::make_unique<DIAEnumInjectedSources>(Files);
}
std::unique_ptr<IPDBEnumSectionContribs>
@@ -419,3 +420,13 @@ DIASession::getSectionContribs() const {
return llvm::make_unique<DIAEnumSectionContribs>(*this, Sections);
}
+
+std::unique_ptr<IPDBEnumFrameData>
+DIASession::getFrameData() const {
+ CComPtr<IDiaEnumFrameData> FD =
+ getTableEnumerator<IDiaEnumFrameData>(*Session);
+ if (!FD)
+ return nullptr;
+
+ return llvm::make_unique<DIAEnumFrameData>(FD);
+}
diff --git a/lib/DebugInfo/PDB/DIA/DIASourceFile.cpp b/lib/DebugInfo/PDB/DIA/DIASourceFile.cpp
index 8605f55b402c..d3e408166a87 100644
--- a/lib/DebugInfo/PDB/DIA/DIASourceFile.cpp
+++ b/lib/DebugInfo/PDB/DIA/DIASourceFile.cpp
@@ -8,12 +8,11 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/DIA/DIASourceFile.h"
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
#include "llvm/DebugInfo/PDB/DIA/DIAEnumSymbols.h"
#include "llvm/DebugInfo/PDB/DIA/DIASession.h"
+#include "llvm/DebugInfo/PDB/DIA/DIAUtils.h"
#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
-#include "llvm/Support/ConvertUTF.h"
using namespace llvm;
using namespace llvm::pdb;
@@ -23,16 +22,7 @@ DIASourceFile::DIASourceFile(const DIASession &PDBSession,
: Session(PDBSession), SourceFile(DiaSourceFile) {}
std::string DIASourceFile::getFileName() const {
- CComBSTR FileName16;
- HRESULT Result = SourceFile->get_fileName(&FileName16);
- if (S_OK != Result)
- return std::string();
-
- std::string FileName8;
- llvm::ArrayRef<char> FileNameBytes(reinterpret_cast<char *>(FileName16.m_str),
- FileName16.ByteLength());
- llvm::convertUTF16ToUTF8String(FileNameBytes, FileName8);
- return FileName8;
+ return invokeBstrMethod(*SourceFile, &IDiaSourceFile::get_fileName);
}
uint32_t DIASourceFile::getUniqueId() const {
diff --git a/lib/DebugInfo/PDB/DIA/DIATable.cpp b/lib/DebugInfo/PDB/DIA/DIATable.cpp
index 5705c2370dc6..6017081b2cb6 100644
--- a/lib/DebugInfo/PDB/DIA/DIATable.cpp
+++ b/lib/DebugInfo/PDB/DIA/DIATable.cpp
@@ -8,14 +8,12 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/DIA/DIATable.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/Support/ConvertUTF.h"
+#include "llvm/DebugInfo/PDB/DIA/DIAUtils.h"
using namespace llvm;
using namespace llvm::pdb;
-DIATable::DIATable(CComPtr<IDiaTable> DiaTable)
- : Table(DiaTable) {}
+DIATable::DIATable(CComPtr<IDiaTable> DiaTable) : Table(DiaTable) {}
uint32_t DIATable::getItemCount() const {
LONG Count = 0;
@@ -23,16 +21,7 @@ uint32_t DIATable::getItemCount() const {
}
std::string DIATable::getName() const {
- CComBSTR Name16;
- if (S_OK != Table->get_name(&Name16))
- return std::string();
-
- std::string Name8;
- llvm::ArrayRef<char> Name16Bytes(reinterpret_cast<char *>(Name16.m_str),
- Name16.ByteLength());
- if (!llvm::convertUTF16ToUTF8String(Name16Bytes, Name8))
- return std::string();
- return Name8;
+ return invokeBstrMethod(*Table, &IDiaTable::get_name);
}
PDB_TableType DIATable::getTableType() const {
diff --git a/lib/DebugInfo/PDB/GenericError.cpp b/lib/DebugInfo/PDB/GenericError.cpp
index 2a677b9abe2d..256952073e88 100644
--- a/lib/DebugInfo/PDB/GenericError.cpp
+++ b/lib/DebugInfo/PDB/GenericError.cpp
@@ -14,55 +14,34 @@
using namespace llvm;
using namespace llvm::pdb;
-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 GenericErrorCategory : public std::error_category {
+class PDBErrorCategory : public std::error_category {
public:
const char *name() const noexcept override { return "llvm.pdb"; }
-
std::string message(int Condition) const override {
- switch (static_cast<generic_error_code>(Condition)) {
- case generic_error_code::unspecified:
+ switch (static_cast<pdb_error_code>(Condition)) {
+ case pdb_error_code::unspecified:
return "An unknown error has occurred.";
- case generic_error_code::type_server_not_found:
- return "Type server PDB was not found.";
- case generic_error_code::dia_sdk_not_present:
- return "LLVM was not compiled with support for DIA. This usually means "
+ case pdb_error_code::dia_sdk_not_present:
+ return "LLVM was not compiled with support for DIA. This usually means "
"that you are not using MSVC, or your Visual Studio "
- "installation "
- "is corrupt.";
- case generic_error_code::invalid_path:
- return "Unable to load PDB. Make sure the file exists and is readable.";
+ "installation is corrupt.";
+ case pdb_error_code::dia_failed_loading:
+ return "DIA is only supported when using MSVC.";
+ case pdb_error_code::invalid_utf8_path:
+ return "The PDB file path is an invalid UTF8 sequence.";
+ case pdb_error_code::signature_out_of_date:
+ return "The signature does not match; the file(s) might be out of date.";
+ case pdb_error_code::external_cmdline_ref:
+ return "The path to this file must be provided on the command-line.";
}
llvm_unreachable("Unrecognized generic_error_code");
}
};
-} // end anonymous namespace
-
-static ManagedStatic<GenericErrorCategory> Category;
-
-char GenericError::ID = 0;
-
-GenericError::GenericError(generic_error_code C) : GenericError(C, "") {}
-
-GenericError::GenericError(StringRef Context)
- : GenericError(generic_error_code::unspecified, Context) {}
-
-GenericError::GenericError(generic_error_code C, StringRef Context) : Code(C) {
- ErrMsg = "PDB Error: ";
- std::error_code EC = convertToErrorCode();
- if (Code != generic_error_code::unspecified)
- ErrMsg += EC.message() + " ";
- if (!Context.empty())
- ErrMsg += Context;
-}
-
-void GenericError::log(raw_ostream &OS) const { OS << ErrMsg << "\n"; }
-StringRef GenericError::getErrorMessage() const { return ErrMsg; }
+static llvm::ManagedStatic<PDBErrorCategory> PDBCategory;
+const std::error_category &llvm::pdb::PDBErrCategory() { return *PDBCategory; }
-std::error_code GenericError::convertToErrorCode() const {
- return std::error_code(static_cast<int>(Code), *Category);
-}
+char PDBError::ID;
diff --git a/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp b/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
index b97f1e90bcf8..ab93efc839a9 100644
--- a/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
+++ b/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
@@ -19,7 +19,6 @@
#include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h"
#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
-#include "llvm/Support/BinaryItemStream.h"
#include "llvm/Support/BinaryStreamWriter.h"
using namespace llvm;
@@ -66,12 +65,22 @@ void DbiModuleDescriptorBuilder::setFirstSectionContrib(
}
void DbiModuleDescriptorBuilder::addSymbol(CVSymbol Symbol) {
- Symbols.push_back(Symbol);
- // Symbols written to a PDB file are required to be 4 byte aligned. The same
+ // Defer to the bulk API. It does the same thing.
+ addSymbolsInBulk(Symbol.data());
+}
+
+void DbiModuleDescriptorBuilder::addSymbolsInBulk(
+ ArrayRef<uint8_t> BulkSymbols) {
+ // Do nothing for empty runs of symbols.
+ if (BulkSymbols.empty())
+ return;
+
+ Symbols.push_back(BulkSymbols);
+ // Symbols written to a PDB file are required to be 4 byte aligned. The same
// is not true of object files.
- assert(Symbol.length() % alignOf(CodeViewContainer::Pdb) == 0 &&
+ assert(BulkSymbols.size() % alignOf(CodeViewContainer::Pdb) == 0 &&
"Invalid Symbol alignment!");
- SymbolByteSize += Symbol.length();
+ SymbolByteSize += BulkSymbols.size();
}
void DbiModuleDescriptorBuilder::addSourceFile(StringRef Path) {
@@ -145,16 +154,13 @@ Error DbiModuleDescriptorBuilder::commit(BinaryStreamWriter &ModiWriter,
if (auto EC =
SymbolWriter.writeInteger<uint32_t>(COFF::DEBUG_SECTION_MAGIC))
return EC;
- BinaryItemStream<CVSymbol> Records(llvm::support::endianness::little);
- Records.setItems(Symbols);
- BinaryStreamRef RecordsRef(Records);
- if (auto EC = SymbolWriter.writeStreamRef(RecordsRef))
- return EC;
- if (auto EC = SymbolWriter.padToAlignment(4))
- return EC;
- // TODO: Write C11 Line data
+ for (ArrayRef<uint8_t> Syms : Symbols) {
+ if (auto EC = SymbolWriter.writeBytes(Syms))
+ return EC;
+ }
assert(SymbolWriter.getOffset() % alignOf(CodeViewContainer::Pdb) == 0 &&
"Invalid debug section alignment!");
+ // TODO: Write C11 Line data
for (const auto &Builder : C13Builders) {
assert(Builder && "Empty C13 Fragment Builder!");
if (auto EC = Builder->commit(SymbolWriter))
diff --git a/lib/DebugInfo/PDB/Native/DbiStream.cpp b/lib/DebugInfo/PDB/Native/DbiStream.cpp
index edaa783398ca..60ac17b655a7 100644
--- a/lib/DebugInfo/PDB/Native/DbiStream.cpp
+++ b/lib/DebugInfo/PDB/Native/DbiStream.cpp
@@ -197,7 +197,7 @@ PDB_Machine DbiStream::getMachineType() const {
return static_cast<PDB_Machine>(Machine);
}
-FixedStreamArray<object::coff_section> DbiStream::getSectionHeaders() {
+FixedStreamArray<object::coff_section> DbiStream::getSectionHeaders() const {
return SectionHeaders;
}
diff --git a/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp b/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
index f6043bfd7cf9..094216ea800a 100644
--- a/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
+++ b/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
@@ -11,6 +11,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h"
@@ -74,10 +75,27 @@ void DbiStreamBuilder::setPublicsStreamIndex(uint32_t Index) {
PublicsStreamIndex = Index;
}
+void DbiStreamBuilder::addNewFpoData(const codeview::FrameData &FD) {
+ if (!NewFpoData.hasValue())
+ NewFpoData.emplace(false);
+
+ NewFpoData->addFrameData(FD);
+}
+
+void DbiStreamBuilder::addOldFpoData(const object::FpoData &FD) {
+ OldFpoData.push_back(FD);
+}
+
Error DbiStreamBuilder::addDbgStream(pdb::DbgHeaderType Type,
ArrayRef<uint8_t> Data) {
+ assert(Type != DbgHeaderType::NewFPO &&
+ "NewFPO data should be written via addFrameData()!");
+
DbgStreams[(int)Type].emplace();
- DbgStreams[(int)Type]->Data = Data;
+ DbgStreams[(int)Type]->Size = Data.size();
+ DbgStreams[(int)Type]->WriteFn = [Data](BinaryStreamWriter &Writer) {
+ return Writer.writeArray(Data);
+ };
return Error::success();
}
@@ -272,10 +290,30 @@ Error DbiStreamBuilder::finalize() {
}
Error DbiStreamBuilder::finalizeMsfLayout() {
+ if (NewFpoData.hasValue()) {
+ DbgStreams[(int)DbgHeaderType::NewFPO].emplace();
+ DbgStreams[(int)DbgHeaderType::NewFPO]->Size =
+ NewFpoData->calculateSerializedSize();
+ DbgStreams[(int)DbgHeaderType::NewFPO]->WriteFn =
+ [this](BinaryStreamWriter &Writer) {
+ return NewFpoData->commit(Writer);
+ };
+ }
+
+ if (!OldFpoData.empty()) {
+ DbgStreams[(int)DbgHeaderType::FPO].emplace();
+ DbgStreams[(int)DbgHeaderType::FPO]->Size =
+ sizeof(object::FpoData) * OldFpoData.size();
+ DbgStreams[(int)DbgHeaderType::FPO]->WriteFn =
+ [this](BinaryStreamWriter &Writer) {
+ return Writer.writeArray(makeArrayRef(OldFpoData));
+ };
+ }
+
for (auto &S : DbgStreams) {
if (!S.hasValue())
continue;
- auto ExpectedIndex = Msf.addStream(S->Data.size());
+ auto ExpectedIndex = Msf.addStream(S->Size);
if (!ExpectedIndex)
return ExpectedIndex.takeError();
S->StreamNumber = *ExpectedIndex;
@@ -406,7 +444,8 @@ Error DbiStreamBuilder::commit(const msf::MSFLayout &Layout,
auto WritableStream = WritableMappedBlockStream::createIndexedStream(
Layout, MsfBuffer, Stream->StreamNumber, Allocator);
BinaryStreamWriter DbgStreamWriter(*WritableStream);
- if (auto EC = DbgStreamWriter.writeArray(Stream->Data))
+
+ if (auto EC = Stream->WriteFn(DbgStreamWriter))
return EC;
}
diff --git a/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp b/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
index 58efc2256ae1..57da7003da2b 100644
--- a/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
+++ b/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
@@ -9,6 +9,7 @@
#include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/DebugInfo/CodeView/RecordName.h"
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
@@ -20,6 +21,7 @@
#include "llvm/DebugInfo/PDB/Native/Hash.h"
#include "llvm/Support/BinaryItemStream.h"
#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/xxhash.h"
#include <algorithm>
#include <vector>
@@ -29,8 +31,27 @@ using namespace llvm::pdb;
using namespace llvm::codeview;
struct llvm::pdb::GSIHashStreamBuilder {
+ struct UdtDenseMapInfo {
+ static inline CVSymbol getEmptyKey() {
+ static CVSymbol Empty;
+ return Empty;
+ }
+ static inline CVSymbol getTombstoneKey() {
+ static CVSymbol Tombstone(static_cast<SymbolKind>(-1),
+ ArrayRef<uint8_t>());
+ return Tombstone;
+ }
+ static unsigned getHashValue(const CVSymbol &Val) {
+ return xxHash64(Val.RecordData);
+ }
+ static bool isEqual(const CVSymbol &LHS, const CVSymbol &RHS) {
+ return LHS.RecordData == RHS.RecordData;
+ }
+ };
+
std::vector<CVSymbol> Records;
uint32_t StreamIndex;
+ llvm::DenseSet<CVSymbol, UdtDenseMapInfo> UdtHashes;
std::vector<PSHashRecord> HashRecords;
std::array<support::ulittle32_t, (IPHR_HASH + 32) / 32> HashBitmap;
std::vector<support::ulittle32_t> HashBuckets;
@@ -42,10 +63,18 @@ struct llvm::pdb::GSIHashStreamBuilder {
template <typename T> void addSymbol(const T &Symbol, MSFBuilder &Msf) {
T Copy(Symbol);
- Records.push_back(SymbolSerializer::writeOneSymbol(Copy, Msf.getAllocator(),
- CodeViewContainer::Pdb));
+ addSymbol(SymbolSerializer::writeOneSymbol(Copy, Msf.getAllocator(),
+ CodeViewContainer::Pdb));
+ }
+ void addSymbol(const CVSymbol &Symbol) {
+ if (Symbol.kind() == S_UDT) {
+ auto Iter = UdtHashes.insert(Symbol);
+ if (!Iter.second)
+ return;
+ }
+
+ Records.push_back(Symbol);
}
- void addSymbol(const CVSymbol &Symbol) { Records.push_back(Symbol); }
};
uint32_t GSIHashStreamBuilder::calculateSerializedLength() const {
@@ -144,11 +173,10 @@ void GSIHashStreamBuilder::finalizeBuckets(uint32_t RecordZeroOffset) {
// can properly early-out when it detects the record won't be found. The
// algorithm used here corredsponds to the function
// caseInsensitiveComparePchPchCchCch in the reference implementation.
- llvm::sort(Bucket.begin(), Bucket.end(),
- [](const std::pair<StringRef, PSHashRecord> &Left,
- const std::pair<StringRef, PSHashRecord> &Right) {
- return gsiRecordLess(Left.first, Right.first);
- });
+ llvm::sort(Bucket, [](const std::pair<StringRef, PSHashRecord> &Left,
+ const std::pair<StringRef, PSHashRecord> &Right) {
+ return gsiRecordLess(Left.first, Right.first);
+ });
for (const auto &Entry : Bucket)
HashRecords.push_back(Entry.second);
@@ -273,10 +301,6 @@ void GSIStreamBuilder::addGlobalSymbol(const ConstantSym &Sym) {
GSH->addSymbol(Sym, Msf);
}
-void GSIStreamBuilder::addGlobalSymbol(const UDTSym &Sym) {
- GSH->addSymbol(Sym, Msf);
-}
-
void GSIStreamBuilder::addGlobalSymbol(const codeview::CVSymbol &Sym) {
GSH->addSymbol(Sym);
}
@@ -310,13 +334,14 @@ Error GSIStreamBuilder::commitPublicsHashStream(
PublicsStreamHeader Header;
// FIXME: Fill these in. They are for incremental linking.
+ Header.SymHash = PSH->calculateSerializedLength();
+ Header.AddrMap = PSH->Records.size() * 4;
Header.NumThunks = 0;
Header.SizeOfThunk = 0;
Header.ISectThunkTable = 0;
+ memset(Header.Padding, 0, sizeof(Header.Padding));
Header.OffThunkTable = 0;
Header.NumSections = 0;
- Header.SymHash = PSH->calculateSerializedLength();
- Header.AddrMap = PSH->Records.size() * 4;
if (auto EC = Writer.writeObject(Header))
return EC;
diff --git a/lib/DebugInfo/PDB/Native/GlobalsStream.cpp b/lib/DebugInfo/PDB/Native/GlobalsStream.cpp
index 36076f436ad0..e36319566821 100644
--- a/lib/DebugInfo/PDB/Native/GlobalsStream.cpp
+++ b/lib/DebugInfo/PDB/Native/GlobalsStream.cpp
@@ -20,7 +20,11 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
+
+#include "llvm/DebugInfo/CodeView/RecordName.h"
+#include "llvm/DebugInfo/PDB/Native/Hash.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Error.h"
#include <algorithm>
@@ -41,6 +45,43 @@ Error GlobalsStream::reload() {
return Error::success();
}
+std::vector<std::pair<uint32_t, codeview::CVSymbol>>
+GlobalsStream::findRecordsByName(StringRef Name,
+ const SymbolStream &Symbols) const {
+ std::vector<std::pair<uint32_t, codeview::CVSymbol>> Result;
+
+ // Hash the name to figure out which bucket this goes into.
+ size_t ExpandedBucketIndex = hashStringV1(Name) % IPHR_HASH;
+ int32_t CompressedBucketIndex = GlobalsTable.BucketMap[ExpandedBucketIndex];
+ if (CompressedBucketIndex == -1)
+ return Result;
+
+ uint32_t LastBucketIndex = GlobalsTable.HashBuckets.size() - 1;
+ uint32_t StartRecordIndex =
+ GlobalsTable.HashBuckets[CompressedBucketIndex] / 12;
+ uint32_t EndRecordIndex = 0;
+ if (LLVM_LIKELY(uint32_t(CompressedBucketIndex) < LastBucketIndex)) {
+ EndRecordIndex = GlobalsTable.HashBuckets[CompressedBucketIndex + 1];
+ } else {
+ // If this is the last bucket, it consists of all hash records until the end
+ // of the HashRecords array.
+ EndRecordIndex = GlobalsTable.HashRecords.size() * 12;
+ }
+
+ EndRecordIndex /= 12;
+
+ assert(EndRecordIndex <= GlobalsTable.HashRecords.size());
+ while (StartRecordIndex < EndRecordIndex) {
+ PSHashRecord PSH = GlobalsTable.HashRecords[StartRecordIndex];
+ uint32_t Off = PSH.Off - 1;
+ codeview::CVSymbol Record = Symbols.readRecord(Off);
+ if (codeview::getSymbolName(Record) == Name)
+ Result.push_back(std::make_pair(Off, std::move(Record)));
+ ++StartRecordIndex;
+ }
+ return Result;
+}
+
static Error checkHashHdrVersion(const GSIHashHeader *HashHdr) {
if (HashHdr->VerHdr != GSIHashHeader::HdrVersion)
return make_error<RawError>(
@@ -86,7 +127,9 @@ static Error readGSIHashRecords(FixedStreamArray<PSHashRecord> &HashRecords,
static Error
readGSIHashBuckets(FixedStreamArray<support::ulittle32_t> &HashBuckets,
- ArrayRef<uint8_t> &HashBitmap, const GSIHashHeader *HashHdr,
+ FixedStreamArray<support::ulittle32_t> &HashBitmap,
+ const GSIHashHeader *HashHdr,
+ MutableArrayRef<int32_t> BucketMap,
BinaryStreamReader &Reader) {
if (auto EC = checkHashHdrVersion(HashHdr))
return EC;
@@ -94,13 +137,27 @@ readGSIHashBuckets(FixedStreamArray<support::ulittle32_t> &HashBuckets,
// Before the actual hash buckets, there is a bitmap of length determined by
// IPHR_HASH.
size_t BitmapSizeInBits = alignTo(IPHR_HASH + 1, 32);
- uint32_t NumBitmapEntries = BitmapSizeInBits / 8;
- if (auto EC = Reader.readBytes(HashBitmap, NumBitmapEntries))
+ uint32_t NumBitmapEntries = BitmapSizeInBits / 32;
+ if (auto EC = Reader.readArray(HashBitmap, NumBitmapEntries))
return joinErrors(std::move(EC),
make_error<RawError>(raw_error_code::corrupt_file,
"Could not read a bitmap."));
+ uint32_t NumBuckets1 = 0;
+ uint32_t CompressedBucketIdx = 0;
+ for (uint32_t I = 0; I <= IPHR_HASH; ++I) {
+ uint8_t WordIdx = I / 32;
+ uint8_t BitIdx = I % 32;
+ bool IsSet = HashBitmap[WordIdx] & (1U << BitIdx);
+ if (IsSet) {
+ ++NumBuckets1;
+ BucketMap[I] = CompressedBucketIdx++;
+ } else {
+ BucketMap[I] = -1;
+ }
+ }
+
uint32_t NumBuckets = 0;
- for (uint8_t B : HashBitmap)
+ for (uint32_t B : HashBitmap)
NumBuckets += countPopulation(B);
// Hash buckets follow.
@@ -118,7 +175,8 @@ Error GSIHashTable::read(BinaryStreamReader &Reader) {
if (auto EC = readGSIHashRecords(HashRecords, HashHdr, Reader))
return EC;
if (HashHdr->HrSize > 0)
- if (auto EC = readGSIHashBuckets(HashBuckets, HashBitmap, HashHdr, Reader))
+ if (auto EC = readGSIHashBuckets(HashBuckets, HashBitmap, HashHdr,
+ BucketMap, Reader))
return EC;
return Error::success();
}
diff --git a/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp b/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp
index 54d6835f1121..3b5a2accdba6 100644
--- a/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp
+++ b/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp
@@ -32,15 +32,20 @@ InfoStreamBuilder::InfoStreamBuilder(msf::MSFBuilder &Msf,
void InfoStreamBuilder::setVersion(PdbRaw_ImplVer V) { Ver = V; }
+void InfoStreamBuilder::addFeature(PdbRaw_FeatureSig Sig) {
+ Features.push_back(Sig);
+}
+
+void InfoStreamBuilder::setHashPDBContentsToGUID(bool B) {
+ HashPDBContentsToGUID = B;
+}
+
void InfoStreamBuilder::setAge(uint32_t A) { Age = A; }
void InfoStreamBuilder::setSignature(uint32_t S) { Signature = S; }
void InfoStreamBuilder::setGuid(GUID G) { Guid = G; }
-void InfoStreamBuilder::addFeature(PdbRaw_FeatureSig Sig) {
- Features.push_back(Sig);
-}
Error InfoStreamBuilder::finalizeMsfLayout() {
uint32_t Length = sizeof(InfoStreamHeader) +
diff --git a/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp b/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp
index 2e1f61c7a25d..8c97f4a012f0 100644
--- a/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp
+++ b/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp
@@ -11,7 +11,9 @@
#include "llvm/ADT/iterator_range.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
+#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
#include "llvm/Support/BinaryStreamReader.h"
@@ -47,7 +49,8 @@ Error ModuleDebugStreamRef::reload() {
if (auto EC = Reader.readInteger(Signature))
return EC;
- if (auto EC = Reader.readSubstream(SymbolsSubstream, SymbolSize - 4))
+ Reader.setOffset(0);
+ if (auto EC = Reader.readSubstream(SymbolsSubstream, SymbolSize))
return EC;
if (auto EC = Reader.readSubstream(C11LinesSubstream, C11Size))
return EC;
@@ -55,8 +58,8 @@ Error ModuleDebugStreamRef::reload() {
return EC;
BinaryStreamReader SymbolReader(SymbolsSubstream.StreamData);
- if (auto EC =
- SymbolReader.readArray(SymbolArray, SymbolReader.bytesRemaining()))
+ if (auto EC = SymbolReader.readArray(
+ SymbolArray, SymbolReader.bytesRemaining(), sizeof(uint32_t)))
return EC;
BinaryStreamReader SubsectionsReader(C13LinesSubstream.StreamData);
@@ -76,6 +79,11 @@ Error ModuleDebugStreamRef::reload() {
return Error::success();
}
+const codeview::CVSymbolArray
+ModuleDebugStreamRef::getSymbolArrayForScope(uint32_t ScopeBegin) const {
+ return limitSymbolArrayToScope(SymbolArray, ScopeBegin);
+}
+
BinarySubstreamRef ModuleDebugStreamRef::getSymbolsSubstream() const {
return SymbolsSubstream;
}
@@ -97,6 +105,12 @@ ModuleDebugStreamRef::symbols(bool *HadError) const {
return make_range(SymbolArray.begin(HadError), SymbolArray.end());
}
+CVSymbol ModuleDebugStreamRef::readSymbolAtOffset(uint32_t Offset) const {
+ auto Iter = SymbolArray.at(Offset);
+ assert(Iter != SymbolArray.end());
+ return *Iter;
+}
+
iterator_range<ModuleDebugStreamRef::DebugSubsectionIterator>
ModuleDebugStreamRef::subsections() const {
return make_range(Subsections.begin(), Subsections.end());
diff --git a/lib/DebugInfo/PDB/Native/NativeBuiltinSymbol.cpp b/lib/DebugInfo/PDB/Native/NativeBuiltinSymbol.cpp
deleted file mode 100644
index 4644ddcf24e3..000000000000
--- a/lib/DebugInfo/PDB/Native/NativeBuiltinSymbol.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-//===- NativeBuiltinSymbol.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/PDB/Native/NativeBuiltinSymbol.h"
-
-
-namespace llvm {
-namespace pdb {
-
-NativeBuiltinSymbol::NativeBuiltinSymbol(NativeSession &PDBSession,
- SymIndexId Id, PDB_BuiltinType T,
- uint64_t L)
- : NativeRawSymbol(PDBSession, Id), Session(PDBSession), Type(T), Length(L) {
-}
-
-NativeBuiltinSymbol::~NativeBuiltinSymbol() {}
-
-std::unique_ptr<NativeRawSymbol> NativeBuiltinSymbol::clone() const {
- return llvm::make_unique<NativeBuiltinSymbol>(Session, SymbolId, Type, Length);
-}
-
-void NativeBuiltinSymbol::dump(raw_ostream &OS, int Indent) const {
- // TODO: Apparently nothing needs this yet.
-}
-
-PDB_SymType NativeBuiltinSymbol::getSymTag() const {
- return PDB_SymType::BuiltinType;
-}
-
-PDB_BuiltinType NativeBuiltinSymbol::getBuiltinType() const { return Type; }
-
-bool NativeBuiltinSymbol::isConstType() const { return false; }
-
-uint64_t NativeBuiltinSymbol::getLength() const { return Length; }
-
-bool NativeBuiltinSymbol::isUnalignedType() const { return false; }
-
-bool NativeBuiltinSymbol::isVolatileType() const { return false; }
-
-} // namespace pdb
-} // namespace llvm
diff --git a/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp b/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp
index 7132a99a9f16..efa70b0e7bd8 100644
--- a/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp
+++ b/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
#include "llvm/ADT/STLExtras.h"
@@ -17,21 +18,31 @@ namespace pdb {
NativeCompilandSymbol::NativeCompilandSymbol(NativeSession &Session,
SymIndexId SymbolId,
DbiModuleDescriptor MI)
- : NativeRawSymbol(Session, SymbolId), Module(MI) {}
+ : NativeRawSymbol(Session, PDB_SymType::Compiland, SymbolId), Module(MI) {}
PDB_SymType NativeCompilandSymbol::getSymTag() const {
return PDB_SymType::Compiland;
}
-std::unique_ptr<NativeRawSymbol> NativeCompilandSymbol::clone() const {
- return llvm::make_unique<NativeCompilandSymbol>(Session, SymbolId, Module);
+void NativeCompilandSymbol::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+
+ dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
+ PdbSymbolIdField::LexicalParent, ShowIdFields,
+ RecurseIdFields);
+ dumpSymbolField(OS, "libraryName", getLibraryName(), Indent);
+ dumpSymbolField(OS, "name", getName(), Indent);
+ dumpSymbolField(OS, "editAndContinueEnabled", isEditAndContinueEnabled(),
+ Indent);
}
bool NativeCompilandSymbol::isEditAndContinueEnabled() const {
return Module.hasECInfo();
}
-uint32_t NativeCompilandSymbol::getLexicalParentId() const { return 0; }
+SymIndexId NativeCompilandSymbol::getLexicalParentId() const { return 0; }
// The usage of getObjFileName for getLibraryName and getModuleName for getName
// may seem backwards, but it is consistent with DIA, which is what this API
diff --git a/lib/DebugInfo/PDB/Native/NativeEnumGlobals.cpp b/lib/DebugInfo/PDB/Native/NativeEnumGlobals.cpp
new file mode 100644
index 000000000000..6eece3df2db3
--- /dev/null
+++ b/lib/DebugInfo/PDB/Native/NativeEnumGlobals.cpp
@@ -0,0 +1,55 @@
+//==- NativeEnumGlobals.cpp - Native Global Enumerator impl ------*- 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/PDB/Native/NativeEnumGlobals.h"
+
+#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeEnumGlobals::NativeEnumGlobals(NativeSession &PDBSession,
+ std::vector<codeview::SymbolKind> Kinds)
+ : Index(0), Session(PDBSession) {
+ GlobalsStream &GS = cantFail(Session.getPDBFile().getPDBGlobalsStream());
+ SymbolStream &SS = cantFail(Session.getPDBFile().getPDBSymbolStream());
+ for (uint32_t Off : GS.getGlobalsTable()) {
+ CVSymbol S = SS.readRecord(Off);
+ if (!llvm::is_contained(Kinds, S.kind()))
+ continue;
+ MatchOffsets.push_back(Off);
+ }
+}
+
+uint32_t NativeEnumGlobals::getChildCount() const {
+ return static_cast<uint32_t>(MatchOffsets.size());
+}
+
+std::unique_ptr<PDBSymbol>
+NativeEnumGlobals::getChildAtIndex(uint32_t N) const {
+ if (N >= MatchOffsets.size())
+ return nullptr;
+
+ SymIndexId Id =
+ Session.getSymbolCache().getOrCreateGlobalSymbolByOffset(MatchOffsets[N]);
+ return Session.getSymbolCache().getSymbolById(Id);
+}
+
+std::unique_ptr<PDBSymbol> NativeEnumGlobals::getNext() {
+ return getChildAtIndex(Index++);
+}
+
+void NativeEnumGlobals::reset() { Index = 0; }
diff --git a/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp b/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp
index a65782e2d4fc..6e4d56443a07 100644
--- a/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp
+++ b/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp
@@ -10,42 +10,35 @@
#include "llvm/DebugInfo/PDB/Native/NativeEnumModules.h"
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
-#include "llvm/DebugInfo/PDB/Native/DbiModuleList.h"
#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
namespace llvm {
namespace pdb {
-NativeEnumModules::NativeEnumModules(NativeSession &PDBSession,
- const DbiModuleList &Modules,
- uint32_t Index)
- : Session(PDBSession), Modules(Modules), Index(Index) {}
+NativeEnumModules::NativeEnumModules(NativeSession &PDBSession, uint32_t Index)
+ : Session(PDBSession), Index(Index) {}
uint32_t NativeEnumModules::getChildCount() const {
- return static_cast<uint32_t>(Modules.getModuleCount());
+ return Session.getSymbolCache().getNumCompilands();
}
std::unique_ptr<PDBSymbol>
-NativeEnumModules::getChildAtIndex(uint32_t Index) const {
- if (Index >= Modules.getModuleCount())
- return nullptr;
- return Session.createCompilandSymbol(Modules.getModuleDescriptor(Index));
+NativeEnumModules::getChildAtIndex(uint32_t N) const {
+ return Session.getSymbolCache().getOrCreateCompiland(N);
}
std::unique_ptr<PDBSymbol> NativeEnumModules::getNext() {
- if (Index >= Modules.getModuleCount())
+ if (Index >= getChildCount())
return nullptr;
return getChildAtIndex(Index++);
}
void NativeEnumModules::reset() { Index = 0; }
-NativeEnumModules *NativeEnumModules::clone() const {
- return new NativeEnumModules(Session, Modules, Index);
-}
-
}
}
diff --git a/lib/DebugInfo/PDB/Native/NativeEnumSymbol.cpp b/lib/DebugInfo/PDB/Native/NativeEnumSymbol.cpp
deleted file mode 100644
index 38d65917306a..000000000000
--- a/lib/DebugInfo/PDB/Native/NativeEnumSymbol.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-//===- NativeEnumSymbol.cpp - info about enum type --------------*- 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/PDB/Native/NativeEnumSymbol.h"
-
-#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
-
-#include <cassert>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-NativeEnumSymbol::NativeEnumSymbol(NativeSession &Session, SymIndexId Id,
- const codeview::CVType &CVT)
- : NativeRawSymbol(Session, Id), CV(CVT),
- Record(codeview::TypeRecordKind::Enum) {
- assert(CV.kind() == codeview::TypeLeafKind::LF_ENUM);
- cantFail(visitTypeRecord(CV, *this));
-}
-
-NativeEnumSymbol::~NativeEnumSymbol() {}
-
-std::unique_ptr<NativeRawSymbol> NativeEnumSymbol::clone() const {
- return llvm::make_unique<NativeEnumSymbol>(Session, SymbolId, CV);
-}
-
-std::unique_ptr<IPDBEnumSymbols>
-NativeEnumSymbol::findChildren(PDB_SymType Type) const {
- switch (Type) {
- case PDB_SymType::Data: {
- // TODO(amccarth): Provide an actual implementation.
- return nullptr;
- }
- default:
- return nullptr;
- }
-}
-
-Error NativeEnumSymbol::visitKnownRecord(codeview::CVType &CVR,
- codeview::EnumRecord &ER) {
- Record = ER;
- return Error::success();
-}
-
-Error NativeEnumSymbol::visitKnownMember(codeview::CVMemberRecord &CVM,
- codeview::EnumeratorRecord &R) {
- return Error::success();
-}
-
-PDB_SymType NativeEnumSymbol::getSymTag() const { return PDB_SymType::Enum; }
-
-uint32_t NativeEnumSymbol::getClassParentId() const { return 0xFFFFFFFF; }
-
-uint32_t NativeEnumSymbol::getUnmodifiedTypeId() const { return 0; }
-
-bool NativeEnumSymbol::hasConstructor() const {
- return bool(Record.getOptions() &
- codeview::ClassOptions::HasConstructorOrDestructor);
-}
-
-bool NativeEnumSymbol::hasAssignmentOperator() const {
- return bool(Record.getOptions() &
- codeview::ClassOptions::HasOverloadedAssignmentOperator);
-}
-
-bool NativeEnumSymbol::hasCastOperator() const {
- return bool(Record.getOptions() &
- codeview::ClassOptions::HasConversionOperator);
-}
-
-uint64_t NativeEnumSymbol::getLength() const {
- const auto Id = Session.findSymbolByTypeIndex(Record.getUnderlyingType());
- const auto UnderlyingType =
- Session.getConcreteSymbolById<PDBSymbolTypeBuiltin>(Id);
- return UnderlyingType ? UnderlyingType->getLength() : 0;
-}
-
-std::string NativeEnumSymbol::getName() const { return Record.getName(); }
-
-bool NativeEnumSymbol::isNested() const {
- return bool(Record.getOptions() & codeview::ClassOptions::Nested);
-}
-
-bool NativeEnumSymbol::hasOverloadedOperator() const {
- return bool(Record.getOptions() &
- codeview::ClassOptions::HasOverloadedOperator);
-}
-
-bool NativeEnumSymbol::isPacked() const {
- return bool(Record.getOptions() & codeview::ClassOptions::Packed);
-}
-
-bool NativeEnumSymbol::isScoped() const {
- return bool(Record.getOptions() & codeview::ClassOptions::Scoped);
-}
-
-uint32_t NativeEnumSymbol::getTypeId() const {
- return Session.findSymbolByTypeIndex(Record.getUnderlyingType());
-}
diff --git a/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp b/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp
index 36a68a1c62de..288a9128147a 100644
--- a/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp
+++ b/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp
@@ -9,39 +9,58 @@
#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
-#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
-namespace llvm {
-namespace pdb {
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
NativeEnumTypes::NativeEnumTypes(NativeSession &PDBSession,
- codeview::LazyRandomTypeCollection &Types,
- codeview::TypeLeafKind Kind)
- : Matches(), Index(0), Session(PDBSession), Kind(Kind) {
- for (auto Index = Types.getFirst(); Index;
- Index = Types.getNext(Index.getValue())) {
- if (Types.getType(Index.getValue()).kind() == Kind)
- Matches.push_back(Index.getValue());
+ LazyRandomTypeCollection &Types,
+ std::vector<codeview::TypeLeafKind> Kinds)
+ : Matches(), Index(0), Session(PDBSession) {
+ Optional<TypeIndex> TI = Types.getFirst();
+ while (TI) {
+ CVType CVT = Types.getType(*TI);
+ TypeLeafKind K = CVT.kind();
+ if (llvm::is_contained(Kinds, K)) {
+ // Don't add forward refs, we'll find those later while enumerating.
+ if (!isUdtForwardRef(CVT))
+ Matches.push_back(*TI);
+ } else if (K == TypeLeafKind::LF_MODIFIER) {
+ TypeIndex ModifiedTI = getModifiedType(CVT);
+ if (!ModifiedTI.isSimple()) {
+ CVType UnmodifiedCVT = Types.getType(ModifiedTI);
+ // LF_MODIFIERs point to forward refs, but don't worry about that
+ // here. We're pushing the TypeIndex of the LF_MODIFIER itself,
+ // so we'll worry about resolving forward refs later.
+ if (llvm::is_contained(Kinds, UnmodifiedCVT.kind()))
+ Matches.push_back(*TI);
+ }
+ }
+ TI = Types.getNext(*TI);
}
}
-NativeEnumTypes::NativeEnumTypes(
- NativeSession &PDBSession, const std::vector<codeview::TypeIndex> &Matches,
- codeview::TypeLeafKind Kind)
- : Matches(Matches), Index(0), Session(PDBSession), Kind(Kind) {}
+NativeEnumTypes::NativeEnumTypes(NativeSession &PDBSession,
+ std::vector<codeview::TypeIndex> Indices)
+ : Matches(std::move(Indices)), Index(0), Session(PDBSession) {}
uint32_t NativeEnumTypes::getChildCount() const {
return static_cast<uint32_t>(Matches.size());
}
-std::unique_ptr<PDBSymbol>
-NativeEnumTypes::getChildAtIndex(uint32_t Index) const {
- if (Index < Matches.size())
- return Session.createEnumSymbol(Matches[Index]);
+std::unique_ptr<PDBSymbol> NativeEnumTypes::getChildAtIndex(uint32_t N) const {
+ if (N < Matches.size()) {
+ SymIndexId Id = Session.getSymbolCache().findSymbolByTypeIndex(Matches[N]);
+ return Session.getSymbolCache().getSymbolById(Id);
+ }
return nullptr;
}
@@ -50,10 +69,3 @@ std::unique_ptr<PDBSymbol> NativeEnumTypes::getNext() {
}
void NativeEnumTypes::reset() { Index = 0; }
-
-NativeEnumTypes *NativeEnumTypes::clone() const {
- return new NativeEnumTypes(Session, Matches, Kind);
-}
-
-} // namespace pdb
-} // namespace llvm
diff --git a/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp b/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp
index e8b06065fc60..6dde5d08a500 100644
--- a/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp
+++ b/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp
@@ -12,34 +12,53 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
+#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumModules.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
-namespace llvm {
-namespace pdb {
+using namespace llvm;
+using namespace llvm::pdb;
-NativeExeSymbol::NativeExeSymbol(NativeSession &Session, SymIndexId SymbolId)
- : NativeRawSymbol(Session, SymbolId), File(Session.getPDBFile()) {}
+static DbiStream *getDbiStreamPtr(NativeSession &Session) {
+ Expected<DbiStream &> DbiS = Session.getPDBFile().getPDBDbiStream();
+ if (DbiS)
+ return &DbiS.get();
-std::unique_ptr<NativeRawSymbol> NativeExeSymbol::clone() const {
- return llvm::make_unique<NativeExeSymbol>(Session, SymbolId);
+ consumeError(DbiS.takeError());
+ return nullptr;
}
+NativeExeSymbol::NativeExeSymbol(NativeSession &Session, SymIndexId SymbolId)
+ : NativeRawSymbol(Session, PDB_SymType::Exe, SymbolId),
+ Dbi(getDbiStreamPtr(Session)) {}
+
std::unique_ptr<IPDBEnumSymbols>
NativeExeSymbol::findChildren(PDB_SymType Type) const {
switch (Type) {
case PDB_SymType::Compiland: {
- auto Dbi = File.getPDBDbiStream();
- if (Dbi) {
- const DbiModuleList &Modules = Dbi->modules();
- return std::unique_ptr<IPDBEnumSymbols>(
- new NativeEnumModules(Session, Modules));
- }
- consumeError(Dbi.takeError());
+ return std::unique_ptr<IPDBEnumSymbols>(new NativeEnumModules(Session));
break;
}
+ case PDB_SymType::ArrayType:
+ return Session.getSymbolCache().createTypeEnumerator(codeview::LF_ARRAY);
case PDB_SymType::Enum:
- return Session.createTypeEnumerator(codeview::LF_ENUM);
+ return Session.getSymbolCache().createTypeEnumerator(codeview::LF_ENUM);
+ case PDB_SymType::PointerType:
+ return Session.getSymbolCache().createTypeEnumerator(codeview::LF_POINTER);
+ case PDB_SymType::UDT:
+ return Session.getSymbolCache().createTypeEnumerator(
+ {codeview::LF_STRUCTURE, codeview::LF_CLASS, codeview::LF_UNION,
+ codeview::LF_INTERFACE});
+ case PDB_SymType::VTableShape:
+ return Session.getSymbolCache().createTypeEnumerator(codeview::LF_VTSHAPE);
+ case PDB_SymType::FunctionSig:
+ return Session.getSymbolCache().createTypeEnumerator(
+ {codeview::LF_PROCEDURE, codeview::LF_MFUNCTION});
+ case PDB_SymType::Typedef:
+ return Session.getSymbolCache().createGlobalsEnumerator(codeview::S_UDT);
+
default:
break;
}
@@ -47,7 +66,7 @@ NativeExeSymbol::findChildren(PDB_SymType Type) const {
}
uint32_t NativeExeSymbol::getAge() const {
- auto IS = File.getPDBInfoStream();
+ auto IS = Session.getPDBFile().getPDBInfoStream();
if (IS)
return IS->getAge();
consumeError(IS.takeError());
@@ -55,11 +74,11 @@ uint32_t NativeExeSymbol::getAge() const {
}
std::string NativeExeSymbol::getSymbolsFileName() const {
- return File.getFilePath();
+ return Session.getPDBFile().getFilePath();
}
codeview::GUID NativeExeSymbol::getGuid() const {
- auto IS = File.getPDBInfoStream();
+ auto IS = Session.getPDBFile().getPDBInfoStream();
if (IS)
return IS->getGuid();
consumeError(IS.takeError());
@@ -67,7 +86,7 @@ codeview::GUID NativeExeSymbol::getGuid() const {
}
bool NativeExeSymbol::hasCTypes() const {
- auto Dbi = File.getPDBDbiStream();
+ auto Dbi = Session.getPDBFile().getPDBDbiStream();
if (Dbi)
return Dbi->hasCTypes();
consumeError(Dbi.takeError());
@@ -75,12 +94,9 @@ bool NativeExeSymbol::hasCTypes() const {
}
bool NativeExeSymbol::hasPrivateSymbols() const {
- auto Dbi = File.getPDBDbiStream();
+ auto Dbi = Session.getPDBFile().getPDBDbiStream();
if (Dbi)
return !Dbi->isStripped();
consumeError(Dbi.takeError());
return false;
}
-
-} // namespace pdb
-} // namespace llvm
diff --git a/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp b/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
index a4b029596314..62950cb3e52a 100644
--- a/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
+++ b/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
@@ -7,82 +7,92 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
+#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+#include "llvm/Support/FormatVariadic.h"
using namespace llvm;
using namespace llvm::pdb;
-NativeRawSymbol::NativeRawSymbol(NativeSession &PDBSession, SymIndexId SymbolId)
- : Session(PDBSession), SymbolId(SymbolId) {}
+NativeRawSymbol::NativeRawSymbol(NativeSession &PDBSession, PDB_SymType Tag,
+ SymIndexId SymbolId)
+ : Session(PDBSession), Tag(Tag), SymbolId(SymbolId) {}
-void NativeRawSymbol::dump(raw_ostream &OS, int Indent) const {}
+void NativeRawSymbol::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+ dumpSymbolIdField(OS, "symIndexId", SymbolId, Indent, Session,
+ PdbSymbolIdField::SymIndexId, ShowIdFields,
+ RecurseIdFields);
+ dumpSymbolField(OS, "symTag", Tag, Indent);
+}
std::unique_ptr<IPDBEnumSymbols>
NativeRawSymbol::findChildren(PDB_SymType Type) const {
- return nullptr;
+ return llvm::make_unique<NullEnumerator<PDBSymbol>>();
}
std::unique_ptr<IPDBEnumSymbols>
NativeRawSymbol::findChildren(PDB_SymType Type, StringRef Name,
PDB_NameSearchFlags Flags) const {
- return nullptr;
+ return llvm::make_unique<NullEnumerator<PDBSymbol>>();
}
std::unique_ptr<IPDBEnumSymbols>
NativeRawSymbol::findChildrenByAddr(PDB_SymType Type, StringRef Name,
PDB_NameSearchFlags Flags, uint32_t Section, uint32_t Offset) const {
- return nullptr;
+ return llvm::make_unique<NullEnumerator<PDBSymbol>>();
}
std::unique_ptr<IPDBEnumSymbols>
NativeRawSymbol::findChildrenByVA(PDB_SymType Type, StringRef Name,
PDB_NameSearchFlags Flags, uint64_t VA) const {
- return nullptr;
+ return llvm::make_unique<NullEnumerator<PDBSymbol>>();
}
std::unique_ptr<IPDBEnumSymbols>
NativeRawSymbol::findChildrenByRVA(PDB_SymType Type, StringRef Name,
PDB_NameSearchFlags Flags, uint32_t RVA) const {
- return nullptr;
+ return llvm::make_unique<NullEnumerator<PDBSymbol>>();
}
std::unique_ptr<IPDBEnumSymbols>
NativeRawSymbol::findInlineFramesByAddr(uint32_t Section,
uint32_t Offset) const {
- return nullptr;
+ return llvm::make_unique<NullEnumerator<PDBSymbol>>();
}
std::unique_ptr<IPDBEnumSymbols>
NativeRawSymbol::findInlineFramesByRVA(uint32_t RVA) const {
- return nullptr;
+ return llvm::make_unique<NullEnumerator<PDBSymbol>>();
}
std::unique_ptr<IPDBEnumSymbols>
NativeRawSymbol::findInlineFramesByVA(uint64_t VA) const {
- return nullptr;
+ return llvm::make_unique<NullEnumerator<PDBSymbol>>();
}
std::unique_ptr<IPDBEnumLineNumbers>
NativeRawSymbol::findInlineeLines() const {
- return nullptr;
+ return llvm::make_unique<NullEnumerator<IPDBLineNumber>>();
}
std::unique_ptr<IPDBEnumLineNumbers>
NativeRawSymbol::findInlineeLinesByAddr(uint32_t Section, uint32_t Offset,
uint32_t Length) const {
- return nullptr;
+ return llvm::make_unique<NullEnumerator<IPDBLineNumber>>();
}
std::unique_ptr<IPDBEnumLineNumbers>
NativeRawSymbol::findInlineeLinesByRVA(uint32_t RVA, uint32_t Length) const {
- return nullptr;
+ return llvm::make_unique<NullEnumerator<IPDBLineNumber>>();
}
std::unique_ptr<IPDBEnumLineNumbers>
NativeRawSymbol::findInlineeLinesByVA(uint64_t VA, uint32_t Length) const {
- return nullptr;
+ return llvm::make_unique<NullEnumerator<IPDBLineNumber>>();
}
void NativeRawSymbol::getDataBytes(SmallVector<uint8_t, 32> &bytes) const {
@@ -105,9 +115,7 @@ uint32_t NativeRawSymbol::getAge() const {
return 0;
}
-uint32_t NativeRawSymbol::getArrayIndexTypeId() const {
- return 0;
-}
+SymIndexId NativeRawSymbol::getArrayIndexTypeId() const { return 0; }
void NativeRawSymbol::getBackEndVersion(VersionInfo &Version) const {
Version.Major = 0;
@@ -124,9 +132,7 @@ uint32_t NativeRawSymbol::getBaseDataSlot() const {
return 0;
}
-uint32_t NativeRawSymbol::getBaseSymbolId() const {
- return 0;
-}
+SymIndexId NativeRawSymbol::getBaseSymbolId() const { return 0; }
PDB_BuiltinType NativeRawSymbol::getBuiltinType() const {
return PDB_BuiltinType::None;
@@ -140,9 +146,7 @@ PDB_CallingConv NativeRawSymbol::getCallingConvention() const {
return PDB_CallingConv::FarStdCall;
}
-uint32_t NativeRawSymbol::getClassParentId() const {
- return 0;
-}
+SymIndexId NativeRawSymbol::getClassParentId() const { return 0; }
std::string NativeRawSymbol::getCompilerName() const {
return {};
@@ -167,9 +171,7 @@ PDB_Lang NativeRawSymbol::getLanguage() const {
return PDB_Lang::Cobol;
}
-uint32_t NativeRawSymbol::getLexicalParentId() const {
- return 0;
-}
+SymIndexId NativeRawSymbol::getLexicalParentId() const { return 0; }
std::string NativeRawSymbol::getLibraryName() const {
return {};
@@ -188,12 +190,10 @@ uint32_t NativeRawSymbol::getLiveRangeStartRelativeVirtualAddress() const {
}
codeview::RegisterId NativeRawSymbol::getLocalBasePointerRegisterId() const {
- return codeview::RegisterId::CVRegEAX;
+ return codeview::RegisterId::EAX;
}
-uint32_t NativeRawSymbol::getLowerBoundId() const {
- return 0;
-}
+SymIndexId NativeRawSymbol::getLowerBoundId() const { return 0; }
uint32_t NativeRawSymbol::getMemorySpaceKind() const {
return 0;
@@ -231,9 +231,7 @@ uint32_t NativeRawSymbol::getOemId() const {
return 0;
}
-uint32_t NativeRawSymbol::getOemSymbolId() const {
- return 0;
-}
+SymIndexId NativeRawSymbol::getOemSymbolId() const { return 0; }
uint32_t NativeRawSymbol::getOffsetInUdt() const {
return 0;
@@ -248,7 +246,7 @@ uint32_t NativeRawSymbol::getRank() const {
}
codeview::RegisterId NativeRawSymbol::getRegisterId() const {
- return codeview::RegisterId::CVRegEAX;
+ return codeview::RegisterId::EAX;
}
uint32_t NativeRawSymbol::getRegisterType() const {
@@ -288,13 +286,11 @@ uint32_t NativeRawSymbol::getStride() const {
return 0;
}
-uint32_t NativeRawSymbol::getSubTypeId() const {
- return 0;
-}
+SymIndexId NativeRawSymbol::getSubTypeId() const { return 0; }
std::string NativeRawSymbol::getSymbolsFileName() const { return {}; }
-uint32_t NativeRawSymbol::getSymIndexId() const { return SymbolId; }
+SymIndexId NativeRawSymbol::getSymIndexId() const { return SymbolId; }
uint32_t NativeRawSymbol::getTargetOffset() const {
return 0;
@@ -324,9 +320,7 @@ uint32_t NativeRawSymbol::getToken() const {
return 0;
}
-uint32_t NativeRawSymbol::getTypeId() const {
- return 0;
-}
+SymIndexId NativeRawSymbol::getTypeId() const { return 0; }
uint32_t NativeRawSymbol::getUavSlot() const {
return 0;
@@ -341,13 +335,9 @@ std::string NativeRawSymbol::getUndecoratedNameEx(
return {};
}
-uint32_t NativeRawSymbol::getUnmodifiedTypeId() const {
- return 0;
-}
+SymIndexId NativeRawSymbol::getUnmodifiedTypeId() const { return 0; }
-uint32_t NativeRawSymbol::getUpperBoundId() const {
- return 0;
-}
+SymIndexId NativeRawSymbol::getUpperBoundId() const { return 0; }
Variant NativeRawSymbol::getValue() const {
return Variant();
@@ -361,9 +351,7 @@ uint32_t NativeRawSymbol::getVirtualBaseOffset() const {
return 0;
}
-uint32_t NativeRawSymbol::getVirtualTableShapeId() const {
- return 0;
-}
+SymIndexId NativeRawSymbol::getVirtualTableShapeId() const { return 0; }
std::unique_ptr<PDBSymbolTypeBuiltin>
NativeRawSymbol::getVirtualBaseTableType() const {
@@ -374,9 +362,7 @@ PDB_DataKind NativeRawSymbol::getDataKind() const {
return PDB_DataKind::Unknown;
}
-PDB_SymType NativeRawSymbol::getSymTag() const {
- return PDB_SymType::None;
-}
+PDB_SymType NativeRawSymbol::getSymTag() const { return Tag; }
codeview::GUID NativeRawSymbol::getGuid() const { return codeview::GUID{{0}}; }
diff --git a/lib/DebugInfo/PDB/Native/NativeSession.cpp b/lib/DebugInfo/PDB/Native/NativeSession.cpp
index 086da13135c5..7807e312365c 100644
--- a/lib/DebugInfo/PDB/Native/NativeSession.cpp
+++ b/lib/DebugInfo/PDB/Native/NativeSession.cpp
@@ -11,16 +11,16 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/DebugInfo/PDB/GenericError.h"
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
-#include "llvm/DebugInfo/PDB/Native/NativeBuiltinSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
-#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
#include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
@@ -40,31 +40,19 @@ using namespace llvm;
using namespace llvm::msf;
using namespace llvm::pdb;
-namespace {
-// Maps codeview::SimpleTypeKind of a built-in type to the parameters necessary
-// to instantiate a NativeBuiltinSymbol for that type.
-static const struct BuiltinTypeEntry {
- codeview::SimpleTypeKind Kind;
- PDB_BuiltinType Type;
- uint32_t Size;
-} BuiltinTypes[] = {
- {codeview::SimpleTypeKind::Int32, PDB_BuiltinType::Int, 4},
- {codeview::SimpleTypeKind::UInt32, PDB_BuiltinType::UInt, 4},
- {codeview::SimpleTypeKind::UInt32Long, PDB_BuiltinType::UInt, 4},
- {codeview::SimpleTypeKind::UInt64Quad, PDB_BuiltinType::UInt, 8},
- {codeview::SimpleTypeKind::NarrowCharacter, PDB_BuiltinType::Char, 1},
- {codeview::SimpleTypeKind::SignedCharacter, PDB_BuiltinType::Char, 1},
- {codeview::SimpleTypeKind::UnsignedCharacter, PDB_BuiltinType::UInt, 1},
- {codeview::SimpleTypeKind::UInt16Short, PDB_BuiltinType::UInt, 2},
- {codeview::SimpleTypeKind::Boolean8, PDB_BuiltinType::Bool, 1}
- // This table can be grown as necessary, but these are the only types we've
- // needed so far.
-};
-} // namespace
+static DbiStream *getDbiStreamPtr(PDBFile &File) {
+ Expected<DbiStream &> DbiS = File.getPDBDbiStream();
+ if (DbiS)
+ return &DbiS.get();
+
+ consumeError(DbiS.takeError());
+ return nullptr;
+}
NativeSession::NativeSession(std::unique_ptr<PDBFile> PdbFile,
std::unique_ptr<BumpPtrAllocator> Allocator)
- : Pdb(std::move(PdbFile)), Allocator(std::move(Allocator)) {}
+ : Pdb(std::move(PdbFile)), Allocator(std::move(Allocator)),
+ Cache(*this, getDbiStreamPtr(*Pdb)) {}
NativeSession::~NativeSession() = default;
@@ -92,97 +80,17 @@ Error NativeSession::createFromExe(StringRef Path,
return make_error<RawError>(raw_error_code::feature_unsupported);
}
-std::unique_ptr<PDBSymbolCompiland>
-NativeSession::createCompilandSymbol(DbiModuleDescriptor MI) {
- const auto Id = static_cast<SymIndexId>(SymbolCache.size());
- SymbolCache.push_back(
- llvm::make_unique<NativeCompilandSymbol>(*this, Id, MI));
- return llvm::make_unique<PDBSymbolCompiland>(
- *this, std::unique_ptr<IPDBRawSymbol>(SymbolCache[Id]->clone()));
-}
-
-std::unique_ptr<PDBSymbolTypeEnum>
-NativeSession::createEnumSymbol(codeview::TypeIndex Index) {
- const auto Id = findSymbolByTypeIndex(Index);
- return llvm::make_unique<PDBSymbolTypeEnum>(
- *this, std::unique_ptr<IPDBRawSymbol>(SymbolCache[Id]->clone()));
-}
-
-std::unique_ptr<IPDBEnumSymbols>
-NativeSession::createTypeEnumerator(codeview::TypeLeafKind Kind) {
- auto Tpi = Pdb->getPDBTpiStream();
- if (!Tpi) {
- consumeError(Tpi.takeError());
- return nullptr;
- }
- auto &Types = Tpi->typeCollection();
- return std::unique_ptr<IPDBEnumSymbols>(
- new NativeEnumTypes(*this, Types, codeview::LF_ENUM));
-}
-
-SymIndexId NativeSession::findSymbolByTypeIndex(codeview::TypeIndex Index) {
- // First see if it's already in our cache.
- const auto Entry = TypeIndexToSymbolId.find(Index);
- if (Entry != TypeIndexToSymbolId.end())
- return Entry->second;
-
- // Symbols for built-in types are created on the fly.
- if (Index.isSimple()) {
- // FIXME: We will eventually need to handle pointers to other simple types,
- // which are still simple types in the world of CodeView TypeIndexes.
- if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct)
- return 0;
- const auto Kind = Index.getSimpleKind();
- const auto It =
- std::find_if(std::begin(BuiltinTypes), std::end(BuiltinTypes),
- [Kind](const BuiltinTypeEntry &Builtin) {
- return Builtin.Kind == Kind;
- });
- if (It == std::end(BuiltinTypes))
- return 0;
- SymIndexId Id = SymbolCache.size();
- SymbolCache.emplace_back(
- llvm::make_unique<NativeBuiltinSymbol>(*this, Id, It->Type, It->Size));
- TypeIndexToSymbolId[Index] = Id;
- return Id;
- }
-
- // We need to instantiate and cache the desired type symbol.
- auto Tpi = Pdb->getPDBTpiStream();
- if (!Tpi) {
- consumeError(Tpi.takeError());
- return 0;
- }
- auto &Types = Tpi->typeCollection();
- const auto &I = Types.getType(Index);
- const auto Id = static_cast<SymIndexId>(SymbolCache.size());
- // TODO(amccarth): Make this handle all types, not just LF_ENUMs.
- assert(I.kind() == codeview::LF_ENUM);
- SymbolCache.emplace_back(llvm::make_unique<NativeEnumSymbol>(*this, Id, I));
- TypeIndexToSymbolId[Index] = Id;
- return Id;
-}
-
uint64_t NativeSession::getLoadAddress() const { return 0; }
bool NativeSession::setLoadAddress(uint64_t Address) { return false; }
std::unique_ptr<PDBSymbolExe> NativeSession::getGlobalScope() {
- const auto Id = static_cast<SymIndexId>(SymbolCache.size());
- SymbolCache.push_back(llvm::make_unique<NativeExeSymbol>(*this, Id));
- auto RawSymbol = SymbolCache[Id]->clone();
- auto PdbSymbol(PDBSymbol::create(*this, std::move(RawSymbol)));
- std::unique_ptr<PDBSymbolExe> ExeSymbol(
- static_cast<PDBSymbolExe *>(PdbSymbol.release()));
- return ExeSymbol;
+ return PDBSymbol::createAs<PDBSymbolExe>(*this, getNativeGlobalScope());
}
std::unique_ptr<PDBSymbol>
-NativeSession::getSymbolById(uint32_t SymbolId) const {
- // If the caller has a SymbolId, it'd better be in our SymbolCache.
- return SymbolId < SymbolCache.size()
- ? PDBSymbol::create(*this, SymbolCache[SymbolId]->clone())
- : nullptr;
+NativeSession::getSymbolById(SymIndexId SymbolId) const {
+ return Cache.getSymbolById(SymbolId);
}
bool NativeSession::addressForVA(uint64_t VA, uint32_t &Section,
@@ -291,3 +199,19 @@ std::unique_ptr<IPDBEnumSectionContribs>
NativeSession::getSectionContribs() const {
return nullptr;
}
+
+std::unique_ptr<IPDBEnumFrameData>
+NativeSession::getFrameData() const {
+ return nullptr;
+}
+
+void NativeSession::initializeExeSymbol() {
+ if (ExeSymbol == 0)
+ ExeSymbol = Cache.createSymbol<NativeExeSymbol>();
+}
+
+NativeExeSymbol &NativeSession::getNativeGlobalScope() const {
+ const_cast<NativeSession &>(*this).initializeExeSymbol();
+
+ return Cache.getNativeSymbolById<NativeExeSymbol>(ExeSymbol);
+}
diff --git a/lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp b/lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp
new file mode 100644
index 000000000000..6ebb8cae3a65
--- /dev/null
+++ b/lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp
@@ -0,0 +1,123 @@
+//===- NativeSymbolEnumerator.cpp - info about enumerators ------*- 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/PDB/Native/NativeSymbolEnumerator.h"
+
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeSymbolEnumerator::NativeSymbolEnumerator(
+ NativeSession &Session, SymIndexId Id, const NativeTypeEnum &Parent,
+ codeview::EnumeratorRecord Record)
+ : NativeRawSymbol(Session, PDB_SymType::Data, Id), Parent(Parent),
+ Record(std::move(Record)) {}
+
+NativeSymbolEnumerator::~NativeSymbolEnumerator() {}
+
+void NativeSymbolEnumerator::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+ dumpSymbolIdField(OS, "classParentId", getClassParentId(), Indent, Session,
+ PdbSymbolIdField::ClassParent, ShowIdFields,
+ RecurseIdFields);
+ dumpSymbolIdField(OS, "lexicalParentId", getLexicalParentId(), Indent,
+ Session, PdbSymbolIdField::LexicalParent, ShowIdFields,
+ RecurseIdFields);
+ dumpSymbolField(OS, "name", getName(), Indent);
+ dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
+ PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
+ dumpSymbolField(OS, "dataKind", getDataKind(), Indent);
+ dumpSymbolField(OS, "locationType", getLocationType(), Indent);
+ dumpSymbolField(OS, "constType", isConstType(), Indent);
+ dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
+ dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
+ dumpSymbolField(OS, "value", getValue(), Indent);
+}
+
+SymIndexId NativeSymbolEnumerator::getClassParentId() const {
+ return Parent.getSymIndexId();
+}
+
+SymIndexId NativeSymbolEnumerator::getLexicalParentId() const { return 0; }
+
+std::string NativeSymbolEnumerator::getName() const { return Record.Name; }
+
+SymIndexId NativeSymbolEnumerator::getTypeId() const {
+ return Parent.getTypeId();
+}
+
+PDB_DataKind NativeSymbolEnumerator::getDataKind() const {
+ return PDB_DataKind::Constant;
+}
+
+PDB_LocType NativeSymbolEnumerator::getLocationType() const {
+ return PDB_LocType::Constant;
+}
+
+bool NativeSymbolEnumerator::isConstType() const { return false; }
+
+bool NativeSymbolEnumerator::isVolatileType() const { return false; }
+
+bool NativeSymbolEnumerator::isUnalignedType() const { return false; }
+
+Variant NativeSymbolEnumerator::getValue() const {
+ const NativeTypeBuiltin &BT = Parent.getUnderlyingBuiltinType();
+
+ switch (BT.getBuiltinType()) {
+ case PDB_BuiltinType::Int:
+ case PDB_BuiltinType::Long:
+ case PDB_BuiltinType::Char: {
+ assert(Record.Value.isSignedIntN(BT.getLength() * 8));
+ int64_t N = Record.Value.getSExtValue();
+ switch (BT.getLength()) {
+ case 1:
+ return Variant{static_cast<int8_t>(N)};
+ case 2:
+ return Variant{static_cast<int16_t>(N)};
+ case 4:
+ return Variant{static_cast<int32_t>(N)};
+ case 8:
+ return Variant{static_cast<int64_t>(N)};
+ }
+ break;
+ }
+ case PDB_BuiltinType::UInt:
+ case PDB_BuiltinType::ULong: {
+ assert(Record.Value.isIntN(BT.getLength() * 8));
+ uint64_t U = Record.Value.getZExtValue();
+ switch (BT.getLength()) {
+ case 1:
+ return Variant{static_cast<uint8_t>(U)};
+ case 2:
+ return Variant{static_cast<uint16_t>(U)};
+ case 4:
+ return Variant{static_cast<uint32_t>(U)};
+ case 8:
+ return Variant{static_cast<uint64_t>(U)};
+ }
+ break;
+ }
+ case PDB_BuiltinType::Bool: {
+ assert(Record.Value.isIntN(BT.getLength() * 8));
+ uint64_t U = Record.Value.getZExtValue();
+ return Variant{static_cast<bool>(U)};
+ }
+ default:
+ assert(false && "Invalid enumeration type");
+ break;
+ }
+
+ return Variant{Record.Value.getSExtValue()};
+}
diff --git a/lib/DebugInfo/PDB/Native/NativeTypeArray.cpp b/lib/DebugInfo/PDB/Native/NativeTypeArray.cpp
new file mode 100644
index 000000000000..a52561728a98
--- /dev/null
+++ b/lib/DebugInfo/PDB/Native/NativeTypeArray.cpp
@@ -0,0 +1,67 @@
+//===- NativeTypeArray.cpp - info about arrays ------------------*- 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/PDB/Native/NativeTypeArray.h"
+
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeTypeArray::NativeTypeArray(NativeSession &Session, SymIndexId Id,
+ codeview::TypeIndex TI,
+ codeview::ArrayRecord Record)
+ : NativeRawSymbol(Session, PDB_SymType::ArrayType, Id), Record(Record),
+ Index(TI) {}
+NativeTypeArray::~NativeTypeArray() {}
+
+void NativeTypeArray::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+
+ dumpSymbolField(OS, "arrayIndexTypeId", getArrayIndexTypeId(), Indent);
+ dumpSymbolIdField(OS, "elementTypeId", getTypeId(), Indent, Session,
+ PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
+
+ dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
+ PdbSymbolIdField::LexicalParent, ShowIdFields,
+ RecurseIdFields);
+ dumpSymbolField(OS, "length", getLength(), Indent);
+ dumpSymbolField(OS, "count", getCount(), Indent);
+ dumpSymbolField(OS, "constType", isConstType(), Indent);
+ dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
+ dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
+}
+
+SymIndexId NativeTypeArray::getArrayIndexTypeId() const {
+ return Session.getSymbolCache().findSymbolByTypeIndex(Record.getIndexType());
+}
+
+bool NativeTypeArray::isConstType() const { return false; }
+
+bool NativeTypeArray::isUnalignedType() const { return false; }
+
+bool NativeTypeArray::isVolatileType() const { return false; }
+
+uint32_t NativeTypeArray::getCount() const {
+ NativeRawSymbol &Element =
+ Session.getSymbolCache().getNativeSymbolById(getTypeId());
+ return getLength() / Element.getLength();
+}
+
+SymIndexId NativeTypeArray::getTypeId() const {
+ return Session.getSymbolCache().findSymbolByTypeIndex(
+ Record.getElementType());
+}
+
+uint64_t NativeTypeArray::getLength() const { return Record.Size; } \ No newline at end of file
diff --git a/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp b/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp
new file mode 100644
index 000000000000..7b0f13f3c075
--- /dev/null
+++ b/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp
@@ -0,0 +1,47 @@
+//===- NativeTypeBuiltin.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/PDB/Native/NativeTypeBuiltin.h"
+#include "llvm/Support/FormatVariadic.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeTypeBuiltin::NativeTypeBuiltin(NativeSession &PDBSession, SymIndexId Id,
+ ModifierOptions Mods, PDB_BuiltinType T,
+ uint64_t L)
+ : NativeRawSymbol(PDBSession, PDB_SymType::BuiltinType, Id),
+ Session(PDBSession), Mods(Mods), Type(T), Length(L) {}
+
+NativeTypeBuiltin::~NativeTypeBuiltin() {}
+
+void NativeTypeBuiltin::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {}
+
+PDB_SymType NativeTypeBuiltin::getSymTag() const {
+ return PDB_SymType::BuiltinType;
+}
+
+PDB_BuiltinType NativeTypeBuiltin::getBuiltinType() const { return Type; }
+
+bool NativeTypeBuiltin::isConstType() const {
+ return (Mods & ModifierOptions::Const) != ModifierOptions::None;
+}
+
+uint64_t NativeTypeBuiltin::getLength() const { return Length; }
+
+bool NativeTypeBuiltin::isUnalignedType() const {
+ return (Mods & ModifierOptions::Unaligned) != ModifierOptions::None;
+}
+
+bool NativeTypeBuiltin::isVolatileType() const {
+ return (Mods & ModifierOptions::Volatile) != ModifierOptions::None;
+}
diff --git a/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp b/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp
new file mode 100644
index 000000000000..37176fe083b9
--- /dev/null
+++ b/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp
@@ -0,0 +1,382 @@
+//===- NativeTypeEnum.cpp - info about enum type ----------------*- 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/PDB/Native/NativeTypeEnum.h"
+
+#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSymbolEnumerator.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+
+#include "llvm/Support/FormatVariadic.h"
+
+#include <cassert>
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+namespace {
+// Yea, this is a pretty terrible class name. But if we have an enum:
+//
+// enum Foo {
+// A,
+// B
+// };
+//
+// then A and B are the "enumerators" of the "enum" Foo. And we need
+// to enumerate them.
+class NativeEnumEnumEnumerators : public IPDBEnumSymbols, TypeVisitorCallbacks {
+public:
+ NativeEnumEnumEnumerators(NativeSession &Session,
+ const NativeTypeEnum &ClassParent);
+
+ uint32_t getChildCount() const override;
+ std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override;
+ std::unique_ptr<PDBSymbol> getNext() override;
+ void reset() override;
+
+private:
+ Error visitKnownMember(CVMemberRecord &CVM,
+ EnumeratorRecord &Record) override;
+ Error visitKnownMember(CVMemberRecord &CVM,
+ ListContinuationRecord &Record) override;
+
+ NativeSession &Session;
+ const NativeTypeEnum &ClassParent;
+ std::vector<EnumeratorRecord> Enumerators;
+ Optional<TypeIndex> ContinuationIndex;
+ uint32_t Index = 0;
+};
+} // namespace
+
+NativeEnumEnumEnumerators::NativeEnumEnumEnumerators(
+ NativeSession &Session, const NativeTypeEnum &ClassParent)
+ : Session(Session), ClassParent(ClassParent) {
+ TpiStream &Tpi = cantFail(Session.getPDBFile().getPDBTpiStream());
+ LazyRandomTypeCollection &Types = Tpi.typeCollection();
+
+ ContinuationIndex = ClassParent.getEnumRecord().FieldList;
+ while (ContinuationIndex) {
+ CVType FieldList = Types.getType(*ContinuationIndex);
+ assert(FieldList.kind() == LF_FIELDLIST);
+ ContinuationIndex.reset();
+ cantFail(visitMemberRecordStream(FieldList.data(), *this));
+ }
+}
+
+Error NativeEnumEnumEnumerators::visitKnownMember(CVMemberRecord &CVM,
+ EnumeratorRecord &Record) {
+ Enumerators.push_back(Record);
+ return Error::success();
+}
+
+Error NativeEnumEnumEnumerators::visitKnownMember(
+ CVMemberRecord &CVM, ListContinuationRecord &Record) {
+ ContinuationIndex = Record.ContinuationIndex;
+ return Error::success();
+}
+
+uint32_t NativeEnumEnumEnumerators::getChildCount() const {
+ return Enumerators.size();
+}
+
+std::unique_ptr<PDBSymbol>
+NativeEnumEnumEnumerators::getChildAtIndex(uint32_t Index) const {
+ if (Index >= getChildCount())
+ return nullptr;
+
+ SymIndexId Id = Session.getSymbolCache()
+ .getOrCreateFieldListMember<NativeSymbolEnumerator>(
+ ClassParent.getEnumRecord().FieldList, Index,
+ ClassParent, Enumerators[Index]);
+ return Session.getSymbolCache().getSymbolById(Id);
+}
+
+std::unique_ptr<PDBSymbol> NativeEnumEnumEnumerators::getNext() {
+ if (Index >= getChildCount())
+ return nullptr;
+
+ return getChildAtIndex(Index++);
+}
+
+void NativeEnumEnumEnumerators::reset() { Index = 0; }
+
+NativeTypeEnum::NativeTypeEnum(NativeSession &Session, SymIndexId Id,
+ TypeIndex Index, EnumRecord Record)
+ : NativeRawSymbol(Session, PDB_SymType::Enum, Id), Index(Index),
+ Record(std::move(Record)) {}
+
+NativeTypeEnum::NativeTypeEnum(NativeSession &Session, SymIndexId Id,
+ NativeTypeEnum &UnmodifiedType,
+ codeview::ModifierRecord Modifier)
+ : NativeRawSymbol(Session, PDB_SymType::Enum, Id),
+ UnmodifiedType(&UnmodifiedType), Modifiers(std::move(Modifier)) {}
+
+NativeTypeEnum::~NativeTypeEnum() {}
+
+void NativeTypeEnum::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+
+ dumpSymbolField(OS, "baseType", static_cast<uint32_t>(getBuiltinType()),
+ Indent);
+ dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
+ PdbSymbolIdField::LexicalParent, ShowIdFields,
+ RecurseIdFields);
+ dumpSymbolField(OS, "name", getName(), Indent);
+ dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
+ PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
+ if (Modifiers.hasValue())
+ dumpSymbolIdField(OS, "unmodifiedTypeId", getUnmodifiedTypeId(), Indent,
+ Session, PdbSymbolIdField::UnmodifiedType, ShowIdFields,
+ RecurseIdFields);
+ dumpSymbolField(OS, "length", getLength(), Indent);
+ dumpSymbolField(OS, "constructor", hasConstructor(), Indent);
+ dumpSymbolField(OS, "constType", isConstType(), Indent);
+ dumpSymbolField(OS, "hasAssignmentOperator", hasAssignmentOperator(), Indent);
+ dumpSymbolField(OS, "hasCastOperator", hasCastOperator(), Indent);
+ dumpSymbolField(OS, "hasNestedTypes", hasNestedTypes(), Indent);
+ dumpSymbolField(OS, "overloadedOperator", hasOverloadedOperator(), Indent);
+ dumpSymbolField(OS, "isInterfaceUdt", isInterfaceUdt(), Indent);
+ dumpSymbolField(OS, "intrinsic", isIntrinsic(), Indent);
+ dumpSymbolField(OS, "nested", isNested(), Indent);
+ dumpSymbolField(OS, "packed", isPacked(), Indent);
+ dumpSymbolField(OS, "isRefUdt", isRefUdt(), Indent);
+ dumpSymbolField(OS, "scoped", isScoped(), Indent);
+ dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
+ dumpSymbolField(OS, "isValueUdt", isValueUdt(), Indent);
+ dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+NativeTypeEnum::findChildren(PDB_SymType Type) const {
+ if (Type != PDB_SymType::Data)
+ return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+
+ const NativeTypeEnum *ClassParent = nullptr;
+ if (!Modifiers)
+ ClassParent = this;
+ else
+ ClassParent = UnmodifiedType;
+ return llvm::make_unique<NativeEnumEnumEnumerators>(Session, *ClassParent);
+}
+
+PDB_SymType NativeTypeEnum::getSymTag() const { return PDB_SymType::Enum; }
+
+PDB_BuiltinType NativeTypeEnum::getBuiltinType() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->getBuiltinType();
+
+ Session.getSymbolCache().findSymbolByTypeIndex(Record->getUnderlyingType());
+
+ codeview::TypeIndex Underlying = Record->getUnderlyingType();
+
+ // This indicates a corrupt record.
+ if (!Underlying.isSimple() ||
+ Underlying.getSimpleMode() != SimpleTypeMode::Direct) {
+ return PDB_BuiltinType::None;
+ }
+
+ switch (Underlying.getSimpleKind()) {
+ case SimpleTypeKind::Boolean128:
+ case SimpleTypeKind::Boolean64:
+ case SimpleTypeKind::Boolean32:
+ case SimpleTypeKind::Boolean16:
+ case SimpleTypeKind::Boolean8:
+ return PDB_BuiltinType::Bool;
+ case SimpleTypeKind::NarrowCharacter:
+ case SimpleTypeKind::UnsignedCharacter:
+ case SimpleTypeKind::SignedCharacter:
+ return PDB_BuiltinType::Char;
+ case SimpleTypeKind::WideCharacter:
+ return PDB_BuiltinType::WCharT;
+ case SimpleTypeKind::Character16:
+ return PDB_BuiltinType::Char16;
+ case SimpleTypeKind::Character32:
+ return PDB_BuiltinType::Char32;
+ case SimpleTypeKind::Int128:
+ case SimpleTypeKind::Int128Oct:
+ case SimpleTypeKind::Int16:
+ case SimpleTypeKind::Int16Short:
+ case SimpleTypeKind::Int32:
+ case SimpleTypeKind::Int32Long:
+ case SimpleTypeKind::Int64:
+ case SimpleTypeKind::Int64Quad:
+ return PDB_BuiltinType::Int;
+ case SimpleTypeKind::UInt128:
+ case SimpleTypeKind::UInt128Oct:
+ case SimpleTypeKind::UInt16:
+ case SimpleTypeKind::UInt16Short:
+ case SimpleTypeKind::UInt32:
+ case SimpleTypeKind::UInt32Long:
+ case SimpleTypeKind::UInt64:
+ case SimpleTypeKind::UInt64Quad:
+ return PDB_BuiltinType::UInt;
+ case SimpleTypeKind::HResult:
+ return PDB_BuiltinType::HResult;
+ case SimpleTypeKind::Complex16:
+ case SimpleTypeKind::Complex32:
+ case SimpleTypeKind::Complex32PartialPrecision:
+ case SimpleTypeKind::Complex64:
+ case SimpleTypeKind::Complex80:
+ case SimpleTypeKind::Complex128:
+ return PDB_BuiltinType::Complex;
+ case SimpleTypeKind::Float16:
+ case SimpleTypeKind::Float32:
+ case SimpleTypeKind::Float32PartialPrecision:
+ case SimpleTypeKind::Float48:
+ case SimpleTypeKind::Float64:
+ case SimpleTypeKind::Float80:
+ case SimpleTypeKind::Float128:
+ return PDB_BuiltinType::Float;
+ default:
+ return PDB_BuiltinType::None;
+ }
+ llvm_unreachable("Unreachable");
+}
+
+SymIndexId NativeTypeEnum::getUnmodifiedTypeId() const {
+ return UnmodifiedType ? UnmodifiedType->getSymIndexId() : 0;
+}
+
+bool NativeTypeEnum::hasConstructor() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->hasConstructor();
+
+ return bool(Record->getOptions() &
+ codeview::ClassOptions::HasConstructorOrDestructor);
+}
+
+bool NativeTypeEnum::hasAssignmentOperator() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->hasAssignmentOperator();
+
+ return bool(Record->getOptions() &
+ codeview::ClassOptions::HasOverloadedAssignmentOperator);
+}
+
+bool NativeTypeEnum::hasNestedTypes() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->hasNestedTypes();
+
+ return bool(Record->getOptions() &
+ codeview::ClassOptions::ContainsNestedClass);
+}
+
+bool NativeTypeEnum::isIntrinsic() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->isIntrinsic();
+
+ return bool(Record->getOptions() & codeview::ClassOptions::Intrinsic);
+}
+
+bool NativeTypeEnum::hasCastOperator() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->hasCastOperator();
+
+ return bool(Record->getOptions() &
+ codeview::ClassOptions::HasConversionOperator);
+}
+
+uint64_t NativeTypeEnum::getLength() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->getLength();
+
+ const auto Id = Session.getSymbolCache().findSymbolByTypeIndex(
+ Record->getUnderlyingType());
+ const auto UnderlyingType =
+ Session.getConcreteSymbolById<PDBSymbolTypeBuiltin>(Id);
+ return UnderlyingType ? UnderlyingType->getLength() : 0;
+}
+
+std::string NativeTypeEnum::getName() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->getName();
+
+ return Record->getName();
+}
+
+bool NativeTypeEnum::isNested() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->isNested();
+
+ return bool(Record->getOptions() & codeview::ClassOptions::Nested);
+}
+
+bool NativeTypeEnum::hasOverloadedOperator() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->hasOverloadedOperator();
+
+ return bool(Record->getOptions() &
+ codeview::ClassOptions::HasOverloadedOperator);
+}
+
+bool NativeTypeEnum::isPacked() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->isPacked();
+
+ return bool(Record->getOptions() & codeview::ClassOptions::Packed);
+}
+
+bool NativeTypeEnum::isScoped() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->isScoped();
+
+ return bool(Record->getOptions() & codeview::ClassOptions::Scoped);
+}
+
+SymIndexId NativeTypeEnum::getTypeId() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->getTypeId();
+
+ return Session.getSymbolCache().findSymbolByTypeIndex(
+ Record->getUnderlyingType());
+}
+
+bool NativeTypeEnum::isRefUdt() const { return false; }
+
+bool NativeTypeEnum::isValueUdt() const { return false; }
+
+bool NativeTypeEnum::isInterfaceUdt() const { return false; }
+
+bool NativeTypeEnum::isConstType() const {
+ if (!Modifiers)
+ return false;
+ return ((Modifiers->getModifiers() & ModifierOptions::Const) !=
+ ModifierOptions::None);
+}
+
+bool NativeTypeEnum::isVolatileType() const {
+ if (!Modifiers)
+ return false;
+ return ((Modifiers->getModifiers() & ModifierOptions::Volatile) !=
+ ModifierOptions::None);
+}
+
+bool NativeTypeEnum::isUnalignedType() const {
+ if (!Modifiers)
+ return false;
+ return ((Modifiers->getModifiers() & ModifierOptions::Unaligned) !=
+ ModifierOptions::None);
+}
+
+const NativeTypeBuiltin &NativeTypeEnum::getUnderlyingBuiltinType() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->getUnderlyingBuiltinType();
+
+ return Session.getSymbolCache().getNativeSymbolById<NativeTypeBuiltin>(
+ getTypeId());
+}
diff --git a/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp b/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp
new file mode 100644
index 000000000000..a9590fffdb87
--- /dev/null
+++ b/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp
@@ -0,0 +1,200 @@
+//===- NativeTypeFunctionSig.cpp - info about function signature -*- 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/PDB/Native/NativeTypeFunctionSig.h"
+
+#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
+#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
+#include "llvm/DebugInfo/PDB/PDBExtras.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+namespace {
+// This is kind of a silly class, hence why we keep it private to the file.
+// It's only purpose is to wrap the real type record. I guess this is so that
+// we can have the lexical parent point to the function instead of the global
+// scope.
+class NativeTypeFunctionArg : public NativeRawSymbol {
+public:
+ NativeTypeFunctionArg(NativeSession &Session,
+ std::unique_ptr<PDBSymbol> RealType)
+ : NativeRawSymbol(Session, PDB_SymType::FunctionArg, 0),
+ RealType(std::move(RealType)) {}
+
+ void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const override {
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+
+ dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
+ PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
+ }
+
+ SymIndexId getTypeId() const override { return RealType->getSymIndexId(); }
+
+ std::unique_ptr<PDBSymbol> RealType;
+};
+
+class NativeEnumFunctionArgs : public IPDBEnumChildren<PDBSymbol> {
+public:
+ NativeEnumFunctionArgs(NativeSession &Session,
+ std::unique_ptr<NativeEnumTypes> TypeEnumerator)
+ : Session(Session), TypeEnumerator(std::move(TypeEnumerator)) {}
+
+ uint32_t getChildCount() const override {
+ return TypeEnumerator->getChildCount();
+ }
+ std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override {
+ return wrap(TypeEnumerator->getChildAtIndex(Index));
+ }
+ std::unique_ptr<PDBSymbol> getNext() override {
+ return wrap(TypeEnumerator->getNext());
+ }
+
+ void reset() override { TypeEnumerator->reset(); }
+
+private:
+ std::unique_ptr<PDBSymbol> wrap(std::unique_ptr<PDBSymbol> S) const {
+ if (!S)
+ return nullptr;
+ auto NTFA = llvm::make_unique<NativeTypeFunctionArg>(Session, std::move(S));
+ return PDBSymbol::create(Session, std::move(NTFA));
+ }
+ NativeSession &Session;
+ std::unique_ptr<NativeEnumTypes> TypeEnumerator;
+};
+} // namespace
+
+NativeTypeFunctionSig::NativeTypeFunctionSig(NativeSession &Session,
+ SymIndexId Id,
+ codeview::TypeIndex Index,
+ codeview::ProcedureRecord Proc)
+ : NativeRawSymbol(Session, PDB_SymType::FunctionSig, Id),
+ Proc(std::move(Proc)), Index(Index), IsMemberFunction(false) {}
+
+NativeTypeFunctionSig::NativeTypeFunctionSig(
+ NativeSession &Session, SymIndexId Id, codeview::TypeIndex Index,
+ codeview::MemberFunctionRecord MemberFunc)
+ : NativeRawSymbol(Session, PDB_SymType::FunctionSig, Id),
+ MemberFunc(std::move(MemberFunc)), Index(Index), IsMemberFunction(true) {}
+
+void NativeTypeFunctionSig::initialize() {
+ if (IsMemberFunction) {
+ ClassParentId =
+ Session.getSymbolCache().findSymbolByTypeIndex(MemberFunc.ClassType);
+ initializeArgList(MemberFunc.ArgumentList);
+ } else {
+ initializeArgList(Proc.ArgumentList);
+ }
+}
+
+NativeTypeFunctionSig::~NativeTypeFunctionSig() {}
+
+void NativeTypeFunctionSig::initializeArgList(codeview::TypeIndex ArgListTI) {
+ TpiStream &Tpi = cantFail(Session.getPDBFile().getPDBTpiStream());
+ CVType CVT = Tpi.typeCollection().getType(ArgListTI);
+
+ cantFail(TypeDeserializer::deserializeAs<ArgListRecord>(CVT, ArgList));
+}
+
+void NativeTypeFunctionSig::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+
+ dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
+ PdbSymbolIdField::LexicalParent, ShowIdFields,
+ RecurseIdFields);
+
+ dumpSymbolField(OS, "callingConvention", getCallingConvention(), Indent);
+ dumpSymbolField(OS, "count", getCount(), Indent);
+ dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
+ PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
+ if (IsMemberFunction)
+ dumpSymbolField(OS, "thisAdjust", getThisAdjust(), Indent);
+ dumpSymbolField(OS, "constructor", hasConstructor(), Indent);
+ dumpSymbolField(OS, "constType", isConstType(), Indent);
+ dumpSymbolField(OS, "isConstructorVirtualBase", isConstructorVirtualBase(),
+ Indent);
+ dumpSymbolField(OS, "isCxxReturnUdt", isCxxReturnUdt(), Indent);
+ dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
+ dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+NativeTypeFunctionSig::findChildren(PDB_SymType Type) const {
+ if (Type != PDB_SymType::FunctionArg)
+ return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+
+ auto NET = llvm::make_unique<NativeEnumTypes>(Session,
+ /* copy */ ArgList.ArgIndices);
+ return std::unique_ptr<IPDBEnumSymbols>(
+ new NativeEnumFunctionArgs(Session, std::move(NET)));
+}
+
+SymIndexId NativeTypeFunctionSig::getClassParentId() const {
+ if (!IsMemberFunction)
+ return 0;
+
+ return ClassParentId;
+}
+
+PDB_CallingConv NativeTypeFunctionSig::getCallingConvention() const {
+ return IsMemberFunction ? MemberFunc.CallConv : Proc.CallConv;
+}
+
+uint32_t NativeTypeFunctionSig::getCount() const {
+ return IsMemberFunction ? (1 + MemberFunc.getParameterCount())
+ : Proc.getParameterCount();
+}
+
+SymIndexId NativeTypeFunctionSig::getTypeId() const {
+ TypeIndex ReturnTI =
+ IsMemberFunction ? MemberFunc.getReturnType() : Proc.getReturnType();
+
+ SymIndexId Result = Session.getSymbolCache().findSymbolByTypeIndex(ReturnTI);
+ return Result;
+}
+
+int32_t NativeTypeFunctionSig::getThisAdjust() const {
+ return IsMemberFunction ? MemberFunc.getThisPointerAdjustment() : 0;
+}
+
+bool NativeTypeFunctionSig::hasConstructor() const {
+ if (!IsMemberFunction)
+ return false;
+
+ return (MemberFunc.getOptions() & FunctionOptions::Constructor) !=
+ FunctionOptions::None;
+}
+
+bool NativeTypeFunctionSig::isConstType() const { return false; }
+
+bool NativeTypeFunctionSig::isConstructorVirtualBase() const {
+ if (!IsMemberFunction)
+ return false;
+
+ return (MemberFunc.getOptions() &
+ FunctionOptions::ConstructorWithVirtualBases) !=
+ FunctionOptions::None;
+}
+
+bool NativeTypeFunctionSig::isCxxReturnUdt() const {
+ FunctionOptions Options =
+ IsMemberFunction ? MemberFunc.getOptions() : Proc.getOptions();
+ return (Options & FunctionOptions::CxxReturnUdt) != FunctionOptions::None;
+}
+
+bool NativeTypeFunctionSig::isUnalignedType() const { return false; }
+
+bool NativeTypeFunctionSig::isVolatileType() const { return false; }
diff --git a/lib/DebugInfo/PDB/Native/NativeTypePointer.cpp b/lib/DebugInfo/PDB/Native/NativeTypePointer.cpp
new file mode 100644
index 000000000000..bd8ecb6c4007
--- /dev/null
+++ b/lib/DebugInfo/PDB/Native/NativeTypePointer.cpp
@@ -0,0 +1,194 @@
+//===- NativeTypePointer.cpp - info about pointer type ----------*- 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/PDB/Native/NativeTypePointer.h"
+
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+
+#include <cassert>
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeTypePointer::NativeTypePointer(NativeSession &Session, SymIndexId Id,
+ codeview::TypeIndex TI)
+ : NativeRawSymbol(Session, PDB_SymType::PointerType, Id), TI(TI) {
+ assert(TI.isSimple());
+ assert(TI.getSimpleMode() != SimpleTypeMode::Direct);
+}
+
+NativeTypePointer::NativeTypePointer(NativeSession &Session, SymIndexId Id,
+ codeview::TypeIndex TI,
+ codeview::PointerRecord Record)
+ : NativeRawSymbol(Session, PDB_SymType::PointerType, Id), TI(TI),
+ Record(std::move(Record)) {}
+
+NativeTypePointer::~NativeTypePointer() {}
+
+void NativeTypePointer::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+
+ if (isMemberPointer()) {
+ dumpSymbolIdField(OS, "classParentId", getClassParentId(), Indent, Session,
+ PdbSymbolIdField::ClassParent, ShowIdFields,
+ RecurseIdFields);
+ }
+ dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
+ PdbSymbolIdField::LexicalParent, ShowIdFields,
+ RecurseIdFields);
+ dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
+ PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
+ dumpSymbolField(OS, "length", getLength(), Indent);
+ dumpSymbolField(OS, "constType", isConstType(), Indent);
+ dumpSymbolField(OS, "isPointerToDataMember", isPointerToDataMember(), Indent);
+ dumpSymbolField(OS, "isPointerToMemberFunction", isPointerToMemberFunction(),
+ Indent);
+ dumpSymbolField(OS, "RValueReference", isRValueReference(), Indent);
+ dumpSymbolField(OS, "reference", isReference(), Indent);
+ dumpSymbolField(OS, "restrictedType", isRestrictedType(), Indent);
+ if (isMemberPointer()) {
+ if (isSingleInheritance())
+ dumpSymbolField(OS, "isSingleInheritance", 1, Indent);
+ else if (isMultipleInheritance())
+ dumpSymbolField(OS, "isMultipleInheritance", 1, Indent);
+ else if (isVirtualInheritance())
+ dumpSymbolField(OS, "isVirtualInheritance", 1, Indent);
+ }
+ dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
+ dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
+}
+
+SymIndexId NativeTypePointer::getClassParentId() const {
+ if (!isMemberPointer())
+ return 0;
+
+ assert(Record);
+ const MemberPointerInfo &MPI = Record->getMemberInfo();
+ return Session.getSymbolCache().findSymbolByTypeIndex(MPI.ContainingType);
+}
+
+uint64_t NativeTypePointer::getLength() const {
+ if (Record)
+ return Record->getSize();
+
+ switch (TI.getSimpleMode()) {
+ case SimpleTypeMode::NearPointer:
+ case SimpleTypeMode::FarPointer:
+ case SimpleTypeMode::HugePointer:
+ return 2;
+ case SimpleTypeMode::NearPointer32:
+ case SimpleTypeMode::FarPointer32:
+ return 4;
+ case SimpleTypeMode::NearPointer64:
+ return 8;
+ case SimpleTypeMode::NearPointer128:
+ return 16;
+ default:
+ assert(false && "invalid simple type mode!");
+ }
+ return 0;
+}
+
+SymIndexId NativeTypePointer::getTypeId() const {
+ // This is the pointee SymIndexId.
+ TypeIndex Referent = Record ? Record->ReferentType : TI.makeDirect();
+
+ return Session.getSymbolCache().findSymbolByTypeIndex(Referent);
+}
+
+bool NativeTypePointer::isReference() const {
+ if (!Record)
+ return false;
+ return Record->getMode() == PointerMode::LValueReference;
+}
+
+bool NativeTypePointer::isRValueReference() const {
+ if (!Record)
+ return false;
+ return Record->getMode() == PointerMode::RValueReference;
+}
+
+bool NativeTypePointer::isPointerToDataMember() const {
+ if (!Record)
+ return false;
+ return Record->getMode() == PointerMode::PointerToDataMember;
+}
+
+bool NativeTypePointer::isPointerToMemberFunction() const {
+ if (!Record)
+ return false;
+ return Record->getMode() == PointerMode::PointerToMemberFunction;
+}
+
+bool NativeTypePointer::isConstType() const {
+ if (!Record)
+ return false;
+ return (Record->getOptions() & PointerOptions::Const) != PointerOptions::None;
+}
+
+bool NativeTypePointer::isRestrictedType() const {
+ if (!Record)
+ return false;
+ return (Record->getOptions() & PointerOptions::Restrict) !=
+ PointerOptions::None;
+}
+
+bool NativeTypePointer::isVolatileType() const {
+ if (!Record)
+ return false;
+ return (Record->getOptions() & PointerOptions::Volatile) !=
+ PointerOptions::None;
+}
+
+bool NativeTypePointer::isUnalignedType() const {
+ if (!Record)
+ return false;
+ return (Record->getOptions() & PointerOptions::Unaligned) !=
+ PointerOptions::None;
+}
+
+static inline bool isInheritanceKind(const MemberPointerInfo &MPI,
+ PointerToMemberRepresentation P1,
+ PointerToMemberRepresentation P2) {
+ return (MPI.getRepresentation() == P1 || MPI.getRepresentation() == P2);
+}
+
+bool NativeTypePointer::isSingleInheritance() const {
+ if (!isMemberPointer())
+ return false;
+ return isInheritanceKind(
+ Record->getMemberInfo(),
+ PointerToMemberRepresentation::SingleInheritanceData,
+ PointerToMemberRepresentation::SingleInheritanceFunction);
+}
+
+bool NativeTypePointer::isMultipleInheritance() const {
+ if (!isMemberPointer())
+ return false;
+ return isInheritanceKind(
+ Record->getMemberInfo(),
+ PointerToMemberRepresentation::MultipleInheritanceData,
+ PointerToMemberRepresentation::MultipleInheritanceFunction);
+}
+
+bool NativeTypePointer::isVirtualInheritance() const {
+ if (!isMemberPointer())
+ return false;
+ return isInheritanceKind(
+ Record->getMemberInfo(),
+ PointerToMemberRepresentation::VirtualInheritanceData,
+ PointerToMemberRepresentation::VirtualInheritanceFunction);
+}
+
+bool NativeTypePointer::isMemberPointer() const {
+ return isPointerToDataMember() || isPointerToMemberFunction();
+}
diff --git a/lib/DebugInfo/PDB/Native/NativeTypeTypedef.cpp b/lib/DebugInfo/PDB/Native/NativeTypeTypedef.cpp
new file mode 100644
index 000000000000..60b373282267
--- /dev/null
+++ b/lib/DebugInfo/PDB/Native/NativeTypeTypedef.cpp
@@ -0,0 +1,27 @@
+#include "llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeTypeTypedef::NativeTypeTypedef(NativeSession &Session, SymIndexId Id,
+ codeview::UDTSym Typedef)
+ : NativeRawSymbol(Session, PDB_SymType::Typedef, Id),
+ Record(std::move(Typedef)) {}
+
+NativeTypeTypedef::~NativeTypeTypedef() {}
+
+void NativeTypeTypedef::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+ dumpSymbolField(OS, "name", getName(), Indent);
+ dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
+ PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
+}
+
+std::string NativeTypeTypedef::getName() const { return Record.Name; }
+
+SymIndexId NativeTypeTypedef::getTypeId() const {
+ return Session.getSymbolCache().findSymbolByTypeIndex(Record.Type);
+}
diff --git a/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp b/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp
new file mode 100644
index 000000000000..3abf91dcc6a3
--- /dev/null
+++ b/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp
@@ -0,0 +1,221 @@
+//===- NativeTypeUDT.cpp - info about class/struct type ---------*- 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/PDB/Native/NativeTypeUDT.h"
+
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+
+#include <cassert>
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id,
+ codeview::TypeIndex TI, codeview::ClassRecord CR)
+ : NativeRawSymbol(Session, PDB_SymType::UDT, Id), Index(TI),
+ Class(std::move(CR)), Tag(Class.getPointer()) {}
+
+NativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id,
+ codeview::TypeIndex TI, codeview::UnionRecord UR)
+ : NativeRawSymbol(Session, PDB_SymType::UDT, Id), Index(TI),
+ Union(std::move(UR)), Tag(Union.getPointer()) {}
+
+NativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id,
+ NativeTypeUDT &UnmodifiedType,
+ codeview::ModifierRecord Modifier)
+ : NativeRawSymbol(Session, PDB_SymType::UDT, Id),
+ UnmodifiedType(&UnmodifiedType), Modifiers(std::move(Modifier)) {}
+
+NativeTypeUDT::~NativeTypeUDT() {}
+
+void NativeTypeUDT::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+
+ dumpSymbolField(OS, "name", getName(), Indent);
+ dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
+ PdbSymbolIdField::LexicalParent, ShowIdFields,
+ RecurseIdFields);
+ if (Modifiers.hasValue())
+ dumpSymbolIdField(OS, "unmodifiedTypeId", getUnmodifiedTypeId(), Indent,
+ Session, PdbSymbolIdField::UnmodifiedType, ShowIdFields,
+ RecurseIdFields);
+ if (getUdtKind() != PDB_UdtType::Union)
+ dumpSymbolField(OS, "virtualTableShapeId", getVirtualTableShapeId(),
+ Indent);
+ dumpSymbolField(OS, "length", getLength(), Indent);
+ dumpSymbolField(OS, "udtKind", getUdtKind(), Indent);
+ dumpSymbolField(OS, "constructor", hasConstructor(), Indent);
+ dumpSymbolField(OS, "constType", isConstType(), Indent);
+ dumpSymbolField(OS, "hasAssignmentOperator", hasAssignmentOperator(), Indent);
+ dumpSymbolField(OS, "hasCastOperator", hasCastOperator(), Indent);
+ dumpSymbolField(OS, "hasNestedTypes", hasNestedTypes(), Indent);
+ dumpSymbolField(OS, "overloadedOperator", hasOverloadedOperator(), Indent);
+ dumpSymbolField(OS, "isInterfaceUdt", isInterfaceUdt(), Indent);
+ dumpSymbolField(OS, "intrinsic", isIntrinsic(), Indent);
+ dumpSymbolField(OS, "nested", isNested(), Indent);
+ dumpSymbolField(OS, "packed", isPacked(), Indent);
+ dumpSymbolField(OS, "isRefUdt", isRefUdt(), Indent);
+ dumpSymbolField(OS, "scoped", isScoped(), Indent);
+ dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
+ dumpSymbolField(OS, "isValueUdt", isValueUdt(), Indent);
+ dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
+}
+
+std::string NativeTypeUDT::getName() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->getName();
+
+ return Tag->getName();
+}
+
+SymIndexId NativeTypeUDT::getLexicalParentId() const { return 0; }
+
+SymIndexId NativeTypeUDT::getUnmodifiedTypeId() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->getSymIndexId();
+
+ return 0;
+}
+
+SymIndexId NativeTypeUDT::getVirtualTableShapeId() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->getVirtualTableShapeId();
+
+ if (Class)
+ return Session.getSymbolCache().findSymbolByTypeIndex(Class->VTableShape);
+
+ return 0;
+}
+
+uint64_t NativeTypeUDT::getLength() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->getLength();
+
+ if (Class)
+ return Class->getSize();
+
+ return Union->getSize();
+}
+
+PDB_UdtType NativeTypeUDT::getUdtKind() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->getUdtKind();
+
+ switch (Tag->Kind) {
+ case TypeRecordKind::Class:
+ return PDB_UdtType::Class;
+ case TypeRecordKind::Union:
+ return PDB_UdtType::Union;
+ case TypeRecordKind::Struct:
+ return PDB_UdtType::Struct;
+ case TypeRecordKind::Interface:
+ return PDB_UdtType::Interface;
+ default:
+ llvm_unreachable("Unexected udt kind");
+ }
+}
+
+bool NativeTypeUDT::hasConstructor() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->hasConstructor();
+
+ return (Tag->Options & ClassOptions::HasConstructorOrDestructor) !=
+ ClassOptions::None;
+}
+
+bool NativeTypeUDT::isConstType() const {
+ if (!Modifiers)
+ return false;
+ return (Modifiers->Modifiers & ModifierOptions::Const) !=
+ ModifierOptions::None;
+}
+
+bool NativeTypeUDT::hasAssignmentOperator() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->hasAssignmentOperator();
+
+ return (Tag->Options & ClassOptions::HasOverloadedAssignmentOperator) !=
+ ClassOptions::None;
+}
+
+bool NativeTypeUDT::hasCastOperator() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->hasCastOperator();
+
+ return (Tag->Options & ClassOptions::HasConversionOperator) !=
+ ClassOptions::None;
+}
+
+bool NativeTypeUDT::hasNestedTypes() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->hasNestedTypes();
+
+ return (Tag->Options & ClassOptions::ContainsNestedClass) !=
+ ClassOptions::None;
+}
+
+bool NativeTypeUDT::hasOverloadedOperator() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->hasOverloadedOperator();
+
+ return (Tag->Options & ClassOptions::HasOverloadedOperator) !=
+ ClassOptions::None;
+}
+
+bool NativeTypeUDT::isInterfaceUdt() const { return false; }
+
+bool NativeTypeUDT::isIntrinsic() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->isIntrinsic();
+
+ return (Tag->Options & ClassOptions::Intrinsic) != ClassOptions::None;
+}
+
+bool NativeTypeUDT::isNested() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->isNested();
+
+ return (Tag->Options & ClassOptions::Nested) != ClassOptions::None;
+}
+
+bool NativeTypeUDT::isPacked() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->isPacked();
+
+ return (Tag->Options & ClassOptions::Packed) != ClassOptions::None;
+}
+
+bool NativeTypeUDT::isRefUdt() const { return false; }
+
+bool NativeTypeUDT::isScoped() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->isScoped();
+
+ return (Tag->Options & ClassOptions::Scoped) != ClassOptions::None;
+}
+
+bool NativeTypeUDT::isValueUdt() const { return false; }
+
+bool NativeTypeUDT::isUnalignedType() const {
+ if (!Modifiers)
+ return false;
+ return (Modifiers->Modifiers & ModifierOptions::Unaligned) !=
+ ModifierOptions::None;
+}
+
+bool NativeTypeUDT::isVolatileType() const {
+ if (!Modifiers)
+ return false;
+ return (Modifiers->Modifiers & ModifierOptions::Volatile) !=
+ ModifierOptions::None;
+}
diff --git a/lib/DebugInfo/PDB/Native/NativeTypeVTShape.cpp b/lib/DebugInfo/PDB/Native/NativeTypeVTShape.cpp
new file mode 100644
index 000000000000..837fe19ec88c
--- /dev/null
+++ b/lib/DebugInfo/PDB/Native/NativeTypeVTShape.cpp
@@ -0,0 +1,35 @@
+#include "llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h"
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+// Create a pointer record for a non-simple type.
+NativeTypeVTShape::NativeTypeVTShape(NativeSession &Session, SymIndexId Id,
+ codeview::TypeIndex TI,
+ codeview::VFTableShapeRecord SR)
+ : NativeRawSymbol(Session, PDB_SymType::VTableShape, Id), TI(TI),
+ Record(std::move(SR)) {}
+
+NativeTypeVTShape::~NativeTypeVTShape() {}
+
+void NativeTypeVTShape::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+
+ dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
+ PdbSymbolIdField::LexicalParent, ShowIdFields,
+ RecurseIdFields);
+ dumpSymbolField(OS, "count", getCount(), Indent);
+ dumpSymbolField(OS, "constType", isConstType(), Indent);
+ dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
+ dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
+}
+
+bool NativeTypeVTShape::isConstType() const { return false; }
+
+bool NativeTypeVTShape::isVolatileType() const { return false; }
+
+bool NativeTypeVTShape::isUnalignedType() const { return false; }
+
+uint32_t NativeTypeVTShape::getCount() const { return Record.Slots.size(); }
diff --git a/lib/DebugInfo/PDB/Native/PDBFile.cpp b/lib/DebugInfo/PDB/Native/PDBFile.cpp
index 78b11937f051..a1f8786ff12f 100644
--- a/lib/DebugInfo/PDB/Native/PDBFile.cpp
+++ b/lib/DebugInfo/PDB/Native/PDBFile.cpp
@@ -125,7 +125,7 @@ Error PDBFile::parseFileHeaders() {
if (auto EC = Reader.readObject(SB)) {
consumeError(std::move(EC));
return make_error<RawError>(raw_error_code::corrupt_file,
- "Does not contain superblock");
+ "MSF superblock is missing");
}
if (auto EC = msf::validateSuperBlock(*SB))
@@ -401,7 +401,9 @@ uint32_t PDBFile::getPointerSize() {
return 4;
}
-bool PDBFile::hasPDBDbiStream() const { return StreamDBI < getNumStreams(); }
+bool PDBFile::hasPDBDbiStream() const {
+ return StreamDBI < getNumStreams() && getStreamByteSize(StreamDBI) > 0;
+}
bool PDBFile::hasPDBGlobalsStream() {
auto DbiS = getPDBDbiStream();
diff --git a/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp b/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
index e164e7cf1c52..e0ceb7499ee5 100644
--- a/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
+++ b/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
@@ -12,7 +12,6 @@
#include "llvm/ADT/BitVector.h"
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
-#include "llvm/DebugInfo/PDB/GenericError.h"
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h"
#include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h"
@@ -26,6 +25,7 @@
#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/JamCRC.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/xxhash.h"
using namespace llvm;
using namespace llvm::codeview;
@@ -262,13 +262,14 @@ void PDBFileBuilder::commitInjectedSources(WritableBinaryStream &MsfBuffer,
}
}
-Error PDBFileBuilder::commit(StringRef Filename) {
+Error PDBFileBuilder::commit(StringRef Filename, codeview::GUID *Guid) {
assert(!Filename.empty());
if (auto EC = finalizeMsfLayout())
return EC;
MSFLayout Layout;
- auto ExpectedMsfBuffer = Msf->commit(Filename, Layout);
+ Expected<FileBufferByteStream> ExpectedMsfBuffer =
+ Msf->commit(Filename, Layout);
if (!ExpectedMsfBuffer)
return ExpectedMsfBuffer.takeError();
FileBufferByteStream Buffer = std::move(*ExpectedMsfBuffer);
@@ -330,11 +331,28 @@ Error PDBFileBuilder::commit(StringRef Filename) {
// Set the build id at the very end, after every other byte of the PDB
// has been written.
- // FIXME: Use a hash of the PDB rather than time(nullptr) for the signature.
- H->Age = Info->getAge();
- H->Guid = Info->getGuid();
- Optional<uint32_t> Sig = Info->getSignature();
- H->Signature = Sig.hasValue() ? *Sig : time(nullptr);
+ if (Info->hashPDBContentsToGUID()) {
+ // Compute a hash of all sections of the output file.
+ uint64_t Digest =
+ xxHash64({Buffer.getBufferStart(), Buffer.getBufferEnd()});
+
+ H->Age = 1;
+
+ memcpy(H->Guid.Guid, &Digest, 8);
+ // xxhash only gives us 8 bytes, so put some fixed data in the other half.
+ memcpy(H->Guid.Guid + 8, "LLD PDB.", 8);
+
+ // Put the hash in the Signature field too.
+ H->Signature = static_cast<uint32_t>(Digest);
+
+ // Return GUID to caller.
+ memcpy(Guid, H->Guid.Guid, 16);
+ } else {
+ H->Age = Info->getAge();
+ H->Guid = Info->getGuid();
+ Optional<uint32_t> Sig = Info->getSignature();
+ H->Signature = Sig.hasValue() ? *Sig : time(nullptr);
+ }
return Buffer.commit();
}
diff --git a/lib/DebugInfo/PDB/Native/RawError.cpp b/lib/DebugInfo/PDB/Native/RawError.cpp
index 548289fff3df..dec9797088f2 100644
--- a/lib/DebugInfo/PDB/Native/RawError.cpp
+++ b/lib/DebugInfo/PDB/Native/RawError.cpp
@@ -5,14 +5,12 @@
using namespace llvm;
using namespace llvm::pdb;
-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 RawErrorCategory : public std::error_category {
public:
const char *name() const noexcept override { return "llvm.pdb.raw"; }
-
std::string message(int Condition) const override {
switch (static_cast<raw_error_code>(Condition)) {
case raw_error_code::unspecified:
@@ -46,30 +44,8 @@ public:
llvm_unreachable("Unrecognized raw_error_code");
}
};
-} // end anonymous namespace
-
-static ManagedStatic<RawErrorCategory> Category;
-
-char RawError::ID = 0;
-
-RawError::RawError(raw_error_code C) : RawError(C, "") {}
-
-RawError::RawError(const std::string &Context)
- : RawError(raw_error_code::unspecified, Context) {}
-
-RawError::RawError(raw_error_code C, const std::string &Context) : Code(C) {
- ErrMsg = "Native PDB Error: ";
- std::error_code EC = convertToErrorCode();
- if (Code != raw_error_code::unspecified)
- ErrMsg += EC.message() + " ";
- if (!Context.empty())
- ErrMsg += Context;
-}
-
-void RawError::log(raw_ostream &OS) const { OS << ErrMsg << "\n"; }
-const std::string &RawError::getErrorMessage() const { return ErrMsg; }
+static llvm::ManagedStatic<RawErrorCategory> RawCategory;
+const std::error_category &llvm::pdb::RawErrCategory() { return *RawCategory; }
-std::error_code RawError::convertToErrorCode() const {
- return std::error_code(static_cast<int>(Code), *Category);
-}
+char RawError::ID;
diff --git a/lib/DebugInfo/PDB/Native/SymbolCache.cpp b/lib/DebugInfo/PDB/Native/SymbolCache.cpp
new file mode 100644
index 000000000000..5cdd628312fe
--- /dev/null
+++ b/lib/DebugInfo/PDB/Native/SymbolCache.cpp
@@ -0,0 +1,299 @@
+#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
+
+#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
+#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
+#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
+#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeEnumGlobals.h"
+#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
+#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeArray.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypePointer.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeUDT.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+// Maps codeview::SimpleTypeKind of a built-in type to the parameters necessary
+// to instantiate a NativeBuiltinSymbol for that type.
+static const struct BuiltinTypeEntry {
+ codeview::SimpleTypeKind Kind;
+ PDB_BuiltinType Type;
+ uint32_t Size;
+} BuiltinTypes[] = {
+ {codeview::SimpleTypeKind::None, PDB_BuiltinType::None, 0},
+ {codeview::SimpleTypeKind::Void, PDB_BuiltinType::Void, 0},
+ {codeview::SimpleTypeKind::HResult, PDB_BuiltinType::HResult, 4},
+ {codeview::SimpleTypeKind::Int16Short, PDB_BuiltinType::Int, 2},
+ {codeview::SimpleTypeKind::UInt16Short, PDB_BuiltinType::UInt, 2},
+ {codeview::SimpleTypeKind::Int32, PDB_BuiltinType::Int, 4},
+ {codeview::SimpleTypeKind::UInt32, PDB_BuiltinType::UInt, 4},
+ {codeview::SimpleTypeKind::Int32Long, PDB_BuiltinType::Int, 4},
+ {codeview::SimpleTypeKind::UInt32Long, PDB_BuiltinType::UInt, 4},
+ {codeview::SimpleTypeKind::Int64Quad, PDB_BuiltinType::Int, 8},
+ {codeview::SimpleTypeKind::UInt64Quad, PDB_BuiltinType::UInt, 8},
+ {codeview::SimpleTypeKind::NarrowCharacter, PDB_BuiltinType::Char, 1},
+ {codeview::SimpleTypeKind::WideCharacter, PDB_BuiltinType::WCharT, 2},
+ {codeview::SimpleTypeKind::Character16, PDB_BuiltinType::Char16, 2},
+ {codeview::SimpleTypeKind::Character32, PDB_BuiltinType::Char32, 4},
+ {codeview::SimpleTypeKind::SignedCharacter, PDB_BuiltinType::Char, 1},
+ {codeview::SimpleTypeKind::UnsignedCharacter, PDB_BuiltinType::UInt, 1},
+ {codeview::SimpleTypeKind::Float32, PDB_BuiltinType::Float, 4},
+ {codeview::SimpleTypeKind::Float64, PDB_BuiltinType::Float, 8},
+ {codeview::SimpleTypeKind::Float80, PDB_BuiltinType::Float, 10},
+ {codeview::SimpleTypeKind::Boolean8, PDB_BuiltinType::Bool, 1},
+ // This table can be grown as necessary, but these are the only types we've
+ // needed so far.
+};
+
+SymbolCache::SymbolCache(NativeSession &Session, DbiStream *Dbi)
+ : Session(Session), Dbi(Dbi) {
+ // Id 0 is reserved for the invalid symbol.
+ Cache.push_back(nullptr);
+
+ if (Dbi)
+ Compilands.resize(Dbi->modules().getModuleCount());
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+SymbolCache::createTypeEnumerator(TypeLeafKind Kind) {
+ return createTypeEnumerator(std::vector<TypeLeafKind>{Kind});
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+SymbolCache::createTypeEnumerator(std::vector<TypeLeafKind> Kinds) {
+ auto Tpi = Session.getPDBFile().getPDBTpiStream();
+ if (!Tpi) {
+ consumeError(Tpi.takeError());
+ return nullptr;
+ }
+ auto &Types = Tpi->typeCollection();
+ return std::unique_ptr<IPDBEnumSymbols>(
+ new NativeEnumTypes(Session, Types, std::move(Kinds)));
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+SymbolCache::createGlobalsEnumerator(codeview::SymbolKind Kind) {
+ return std::unique_ptr<IPDBEnumSymbols>(
+ new NativeEnumGlobals(Session, {Kind}));
+}
+
+SymIndexId SymbolCache::createSimpleType(TypeIndex Index,
+ ModifierOptions Mods) {
+ if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct)
+ return createSymbol<NativeTypePointer>(Index);
+
+ const auto Kind = Index.getSimpleKind();
+ const auto It = std::find_if(
+ std::begin(BuiltinTypes), std::end(BuiltinTypes),
+ [Kind](const BuiltinTypeEntry &Builtin) { return Builtin.Kind == Kind; });
+ if (It == std::end(BuiltinTypes))
+ return 0;
+ return createSymbol<NativeTypeBuiltin>(Mods, It->Type, It->Size);
+}
+
+SymIndexId
+SymbolCache::createSymbolForModifiedType(codeview::TypeIndex ModifierTI,
+ codeview::CVType CVT) {
+ ModifierRecord Record;
+ if (auto EC = TypeDeserializer::deserializeAs<ModifierRecord>(CVT, Record)) {
+ consumeError(std::move(EC));
+ return 0;
+ }
+
+ if (Record.ModifiedType.isSimple())
+ return createSimpleType(Record.ModifiedType, Record.Modifiers);
+
+ // Make sure we create and cache a record for the unmodified type.
+ SymIndexId UnmodifiedId = findSymbolByTypeIndex(Record.ModifiedType);
+ NativeRawSymbol &UnmodifiedNRS = *Cache[UnmodifiedId];
+
+ switch (UnmodifiedNRS.getSymTag()) {
+ case PDB_SymType::Enum:
+ return createSymbol<NativeTypeEnum>(
+ static_cast<NativeTypeEnum &>(UnmodifiedNRS), std::move(Record));
+ case PDB_SymType::UDT:
+ return createSymbol<NativeTypeUDT>(
+ static_cast<NativeTypeUDT &>(UnmodifiedNRS), std::move(Record));
+ default:
+ // No other types can be modified. (LF_POINTER, for example, records
+ // its modifiers a different way.
+ assert(false && "Invalid LF_MODIFIER record");
+ break;
+ }
+ return 0;
+}
+
+SymIndexId SymbolCache::findSymbolByTypeIndex(codeview::TypeIndex Index) {
+ // First see if it's already in our cache.
+ const auto Entry = TypeIndexToSymbolId.find(Index);
+ if (Entry != TypeIndexToSymbolId.end())
+ return Entry->second;
+
+ // Symbols for built-in types are created on the fly.
+ if (Index.isSimple()) {
+ SymIndexId Result = createSimpleType(Index, ModifierOptions::None);
+ assert(TypeIndexToSymbolId.count(Index) == 0);
+ TypeIndexToSymbolId[Index] = Result;
+ return Result;
+ }
+
+ // We need to instantiate and cache the desired type symbol.
+ auto Tpi = Session.getPDBFile().getPDBTpiStream();
+ if (!Tpi) {
+ consumeError(Tpi.takeError());
+ return 0;
+ }
+ codeview::LazyRandomTypeCollection &Types = Tpi->typeCollection();
+ codeview::CVType CVT = Types.getType(Index);
+
+ if (isUdtForwardRef(CVT)) {
+ Expected<TypeIndex> EFD = Tpi->findFullDeclForForwardRef(Index);
+
+ if (!EFD)
+ consumeError(EFD.takeError());
+ else if (*EFD != Index) {
+ assert(!isUdtForwardRef(Types.getType(*EFD)));
+ SymIndexId Result = findSymbolByTypeIndex(*EFD);
+ // Record a mapping from ForwardRef -> SymIndex of complete type so that
+ // we'll take the fast path next time.
+ assert(TypeIndexToSymbolId.count(Index) == 0);
+ TypeIndexToSymbolId[Index] = Result;
+ return Result;
+ }
+ }
+
+ // At this point if we still have a forward ref udt it means the full decl was
+ // not in the PDB. We just have to deal with it and use the forward ref.
+ SymIndexId Id = 0;
+ switch (CVT.kind()) {
+ case codeview::LF_ENUM:
+ Id = createSymbolForType<NativeTypeEnum, EnumRecord>(Index, std::move(CVT));
+ break;
+ case codeview::LF_ARRAY:
+ Id = createSymbolForType<NativeTypeArray, ArrayRecord>(Index,
+ std::move(CVT));
+ break;
+ case codeview::LF_CLASS:
+ case codeview::LF_STRUCTURE:
+ case codeview::LF_INTERFACE:
+ Id = createSymbolForType<NativeTypeUDT, ClassRecord>(Index, std::move(CVT));
+ break;
+ case codeview::LF_UNION:
+ Id = createSymbolForType<NativeTypeUDT, UnionRecord>(Index, std::move(CVT));
+ break;
+ case codeview::LF_POINTER:
+ Id = createSymbolForType<NativeTypePointer, PointerRecord>(Index,
+ std::move(CVT));
+ break;
+ case codeview::LF_MODIFIER:
+ Id = createSymbolForModifiedType(Index, std::move(CVT));
+ break;
+ case codeview::LF_PROCEDURE:
+ Id = createSymbolForType<NativeTypeFunctionSig, ProcedureRecord>(
+ Index, std::move(CVT));
+ break;
+ case codeview::LF_MFUNCTION:
+ Id = createSymbolForType<NativeTypeFunctionSig, MemberFunctionRecord>(
+ Index, std::move(CVT));
+ break;
+ case codeview::LF_VTSHAPE:
+ Id = createSymbolForType<NativeTypeVTShape, VFTableShapeRecord>(
+ Index, std::move(CVT));
+ break;
+ default:
+ Id = createSymbolPlaceholder();
+ break;
+ }
+ if (Id != 0) {
+ assert(TypeIndexToSymbolId.count(Index) == 0);
+ TypeIndexToSymbolId[Index] = Id;
+ }
+ return Id;
+}
+
+std::unique_ptr<PDBSymbol>
+SymbolCache::getSymbolById(SymIndexId SymbolId) const {
+ assert(SymbolId < Cache.size());
+
+ // Id 0 is reserved.
+ if (SymbolId == 0 || SymbolId >= Cache.size())
+ return nullptr;
+
+ // Make sure to handle the case where we've inserted a placeholder symbol
+ // for types we don't yet suppport.
+ NativeRawSymbol *NRS = Cache[SymbolId].get();
+ if (!NRS)
+ return nullptr;
+
+ return PDBSymbol::create(Session, *NRS);
+}
+
+NativeRawSymbol &SymbolCache::getNativeSymbolById(SymIndexId SymbolId) const {
+ return *Cache[SymbolId];
+}
+
+uint32_t SymbolCache::getNumCompilands() const {
+ if (!Dbi)
+ return 0;
+
+ return Dbi->modules().getModuleCount();
+}
+
+SymIndexId SymbolCache::getOrCreateGlobalSymbolByOffset(uint32_t Offset) {
+ auto Iter = GlobalOffsetToSymbolId.find(Offset);
+ if (Iter != GlobalOffsetToSymbolId.end())
+ return Iter->second;
+
+ SymbolStream &SS = cantFail(Session.getPDBFile().getPDBSymbolStream());
+ CVSymbol CVS = SS.readRecord(Offset);
+ SymIndexId Id = 0;
+ switch (CVS.kind()) {
+ case SymbolKind::S_UDT: {
+ UDTSym US = cantFail(SymbolDeserializer::deserializeAs<UDTSym>(CVS));
+ Id = createSymbol<NativeTypeTypedef>(std::move(US));
+ break;
+ }
+ default:
+ Id = createSymbolPlaceholder();
+ break;
+ }
+ if (Id != 0) {
+ assert(GlobalOffsetToSymbolId.count(Offset) == 0);
+ GlobalOffsetToSymbolId[Offset] = Id;
+ }
+
+ return Id;
+}
+
+std::unique_ptr<PDBSymbolCompiland>
+SymbolCache::getOrCreateCompiland(uint32_t Index) {
+ if (!Dbi)
+ return nullptr;
+
+ if (Index >= Compilands.size())
+ return nullptr;
+
+ if (Compilands[Index] == 0) {
+ const DbiModuleList &Modules = Dbi->modules();
+ Compilands[Index] =
+ createSymbol<NativeCompilandSymbol>(Modules.getModuleDescriptor(Index));
+ }
+
+ return Session.getConcreteSymbolById<PDBSymbolCompiland>(Compilands[Index]);
+}
diff --git a/lib/DebugInfo/PDB/Native/TpiHashing.cpp b/lib/DebugInfo/PDB/Native/TpiHashing.cpp
index 77a2d57a8369..18708826ffc7 100644
--- a/lib/DebugInfo/PDB/Native/TpiHashing.cpp
+++ b/lib/DebugInfo/PDB/Native/TpiHashing.cpp
@@ -50,6 +50,32 @@ static Expected<uint32_t> getHashForUdt(const CVType &Rec) {
}
template <typename T>
+static Expected<TagRecordHash> getTagRecordHashForUdt(const CVType &Rec) {
+ T Deserialized;
+ if (auto E = TypeDeserializer::deserializeAs(const_cast<CVType &>(Rec),
+ Deserialized))
+ return std::move(E);
+
+ ClassOptions Opts = Deserialized.getOptions();
+
+ bool ForwardRef = bool(Opts & ClassOptions::ForwardReference);
+
+ uint32_t ThisRecordHash = getHashForUdt(Deserialized, Rec.data());
+
+ // If we don't have a forward ref we can't compute the hash of it from the
+ // full record because it requires hashing the entire buffer.
+ if (!ForwardRef)
+ return TagRecordHash{std::move(Deserialized), ThisRecordHash, 0};
+
+ bool Scoped = bool(Opts & ClassOptions::Scoped);
+
+ StringRef NameToHash =
+ Scoped ? Deserialized.getUniqueName() : Deserialized.getName();
+ uint32_t FullHash = hashStringV1(NameToHash);
+ return TagRecordHash{std::move(Deserialized), FullHash, ThisRecordHash};
+}
+
+template <typename T>
static Expected<uint32_t> getSourceLineHash(const CVType &Rec) {
T Deserialized;
if (auto E = TypeDeserializer::deserializeAs(const_cast<CVType &>(Rec),
@@ -60,6 +86,23 @@ static Expected<uint32_t> getSourceLineHash(const CVType &Rec) {
return hashStringV1(StringRef(Buf, 4));
}
+Expected<TagRecordHash> llvm::pdb::hashTagRecord(const codeview::CVType &Type) {
+ switch (Type.kind()) {
+ case LF_CLASS:
+ case LF_STRUCTURE:
+ case LF_INTERFACE:
+ return getTagRecordHashForUdt<ClassRecord>(Type);
+ case LF_UNION:
+ return getTagRecordHashForUdt<UnionRecord>(Type);
+ case LF_ENUM:
+ return getTagRecordHashForUdt<EnumRecord>(Type);
+ default:
+ assert(false && "Type is not a tag record!");
+ }
+ return make_error<StringError>("Invalid record type",
+ inconvertibleErrorCode());
+}
+
Expected<uint32_t> llvm::pdb::hashTypeRecord(const CVType &Rec) {
switch (Rec.kind()) {
case LF_CLASS:
diff --git a/lib/DebugInfo/PDB/Native/TpiStream.cpp b/lib/DebugInfo/PDB/Native/TpiStream.cpp
index 0680b673380a..f234d446e6a0 100644
--- a/lib/DebugInfo/PDB/Native/TpiStream.cpp
+++ b/lib/DebugInfo/PDB/Native/TpiStream.cpp
@@ -11,8 +11,11 @@
#include "llvm/ADT/iterator_range.h"
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
+#include "llvm/DebugInfo/CodeView/RecordName.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Native/Hash.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
@@ -140,6 +143,88 @@ uint16_t TpiStream::getTypeHashStreamAuxIndex() const {
uint32_t TpiStream::getNumHashBuckets() const { return Header->NumHashBuckets; }
uint32_t TpiStream::getHashKeySize() const { return Header->HashKeySize; }
+void TpiStream::buildHashMap() {
+ if (!HashMap.empty())
+ return;
+ if (HashValues.empty())
+ return;
+
+ HashMap.resize(Header->NumHashBuckets);
+
+ TypeIndex TIB{Header->TypeIndexBegin};
+ TypeIndex TIE{Header->TypeIndexEnd};
+ while (TIB < TIE) {
+ uint32_t HV = HashValues[TIB.toArrayIndex()];
+ HashMap[HV].push_back(TIB++);
+ }
+}
+
+std::vector<TypeIndex> TpiStream::findRecordsByName(StringRef Name) const {
+ if (!supportsTypeLookup())
+ const_cast<TpiStream*>(this)->buildHashMap();
+
+ uint32_t Bucket = hashStringV1(Name) % Header->NumHashBuckets;
+ if (Bucket > HashMap.size())
+ return {};
+
+ std::vector<TypeIndex> Result;
+ for (TypeIndex TI : HashMap[Bucket]) {
+ std::string ThisName = computeTypeName(*Types, TI);
+ if (ThisName == Name)
+ Result.push_back(TI);
+ }
+ return Result;
+}
+
+bool TpiStream::supportsTypeLookup() const { return !HashMap.empty(); }
+
+Expected<TypeIndex>
+TpiStream::findFullDeclForForwardRef(TypeIndex ForwardRefTI) const {
+ if (!supportsTypeLookup())
+ const_cast<TpiStream*>(this)->buildHashMap();
+
+ CVType F = Types->getType(ForwardRefTI);
+ if (!isUdtForwardRef(F))
+ return ForwardRefTI;
+
+ Expected<TagRecordHash> ForwardTRH = hashTagRecord(F);
+ if (!ForwardTRH)
+ return ForwardTRH.takeError();
+
+ uint32_t BucketIdx = ForwardTRH->FullRecordHash % Header->NumHashBuckets;
+
+ for (TypeIndex TI : HashMap[BucketIdx]) {
+ CVType CVT = Types->getType(TI);
+ if (CVT.kind() != F.kind())
+ continue;
+
+ Expected<TagRecordHash> FullTRH = hashTagRecord(CVT);
+ if (!FullTRH)
+ return FullTRH.takeError();
+ if (ForwardTRH->FullRecordHash != FullTRH->FullRecordHash)
+ continue;
+ TagRecord &ForwardTR = ForwardTRH->getRecord();
+ TagRecord &FullTR = FullTRH->getRecord();
+
+ if (!ForwardTR.hasUniqueName()) {
+ if (ForwardTR.getName() == FullTR.getName())
+ return TI;
+ continue;
+ }
+
+ if (!FullTR.hasUniqueName())
+ continue;
+ if (ForwardTR.getUniqueName() == FullTR.getUniqueName())
+ return TI;
+ }
+ return ForwardRefTI;
+}
+
+codeview::CVType TpiStream::getType(codeview::TypeIndex Index) {
+ assert(!Index.isSimple());
+ return Types->getType(Index);
+}
+
BinarySubstreamRef TpiStream::getTypeRecordsSubstream() const {
return TypeRecordsSubstream;
}
diff --git a/lib/DebugInfo/PDB/PDB.cpp b/lib/DebugInfo/PDB/PDB.cpp
index 40f5ae9ba845..fc1ad8bcd7cd 100644
--- a/lib/DebugInfo/PDB/PDB.cpp
+++ b/lib/DebugInfo/PDB/PDB.cpp
@@ -29,7 +29,7 @@ Error llvm::pdb::loadDataForPDB(PDB_ReaderType Type, StringRef Path,
MemoryBuffer::getFileOrSTDIN(Path, /*FileSize=*/-1,
/*RequiresNullTerminator=*/false);
if (!ErrorOrBuffer)
- return make_error<GenericError>(generic_error_code::invalid_path, Path);
+ return errorCodeToError(ErrorOrBuffer.getError());
return NativeSession::createFromPdb(std::move(*ErrorOrBuffer), Session);
}
@@ -37,7 +37,7 @@ Error llvm::pdb::loadDataForPDB(PDB_ReaderType Type, StringRef Path,
#if LLVM_ENABLE_DIA_SDK
return DIASession::createFromPdb(Path, Session);
#else
- return make_error<GenericError>("DIA is not installed on the system");
+ return make_error<PDBError>(pdb_error_code::dia_sdk_not_present);
#endif
}
@@ -50,6 +50,6 @@ Error llvm::pdb::loadDataForEXE(PDB_ReaderType Type, StringRef Path,
#if LLVM_ENABLE_DIA_SDK
return DIASession::createFromExe(Path, Session);
#else
- return make_error<GenericError>("DIA is not installed on the system");
+ return make_error<PDBError>(pdb_error_code::dia_sdk_not_present);
#endif
}
diff --git a/lib/DebugInfo/PDB/PDBExtras.cpp b/lib/DebugInfo/PDB/PDBExtras.cpp
index a4e316417f96..0d8af232cd92 100644
--- a/lib/DebugInfo/PDB/PDBExtras.cpp
+++ b/lib/DebugInfo/PDB/PDBExtras.cpp
@@ -43,6 +43,33 @@ raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
}
raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
+ const PDB_BuiltinType &Type) {
+ switch (Type) {
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, None, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Void, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Char, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, WCharT, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Int, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, UInt, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Float, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, BCD, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Bool, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Long, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, ULong, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Currency, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Date, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Variant, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Complex, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Bitfield, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, BSTR, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, HResult, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Char16, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Char32, OS)
+ }
+ return OS;
+}
+
+raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
const PDB_CallingConv &Conv) {
OS << "__";
switch (Conv) {
@@ -202,8 +229,20 @@ raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const PDB_SymType &Tag) {
CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, CustomType, OS)
CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, ManagedType, OS)
CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Dimension, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, CallSite, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, InlineSite, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, BaseInterface, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, VectorType, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, MatrixType, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, HLSLType, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Caller, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Callee, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Export, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, HeapAllocationSite, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, CoffGroup, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Inlinee, OS)
default:
- OS << "Unknown";
+ OS << "Unknown SymTag " << uint32_t(Tag);
}
return OS;
}
@@ -293,7 +332,7 @@ raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const Variant &Value) {
OS << Value.Value.Single;
break;
case PDB_VariantType::UInt16:
- OS << Value.Value.Double;
+ OS << Value.Value.UInt16;
break;
case PDB_VariantType::UInt32:
OS << Value.Value.UInt32;
diff --git a/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp b/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp
index c62796507a01..951909295d13 100644
--- a/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp
+++ b/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/IPDBDataStream.h"
+#include "llvm/DebugInfo/PDB/IPDBFrameData.h"
#include "llvm/DebugInfo/PDB/IPDBInjectedSource.h"
#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
@@ -35,3 +36,5 @@ IPDBTable::~IPDBTable() = default;
IPDBInjectedSource::~IPDBInjectedSource() = default;
IPDBSectionContrib::~IPDBSectionContrib() = default;
+
+IPDBFrameData::~IPDBFrameData() = default;
diff --git a/lib/DebugInfo/PDB/PDBSymbol.cpp b/lib/DebugInfo/PDB/PDBSymbol.cpp
index 74010c2dd7dd..d492edafdafe 100644
--- a/lib/DebugInfo/PDB/PDBSymbol.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbol.cpp
@@ -50,23 +50,20 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbol::PDBSymbol(const IPDBSession &PDBSession,
- std::unique_ptr<IPDBRawSymbol> Symbol)
- : Session(PDBSession), RawSymbol(std::move(Symbol)) {}
+PDBSymbol::PDBSymbol(const IPDBSession &PDBSession) : Session(PDBSession) {}
-PDBSymbol::PDBSymbol(PDBSymbol &Symbol)
- : Session(Symbol.Session), RawSymbol(std::move(Symbol.RawSymbol)) {}
+PDBSymbol::PDBSymbol(PDBSymbol &&Other)
+ : Session(Other.Session), RawSymbol(std::move(Other.RawSymbol)) {}
PDBSymbol::~PDBSymbol() = default;
#define FACTORY_SYMTAG_CASE(Tag, Type) \
case PDB_SymType::Tag: \
- return std::unique_ptr<PDBSymbol>(new Type(PDBSession, std::move(Symbol)));
+ return std::unique_ptr<PDBSymbol>(new Type(PDBSession));
std::unique_ptr<PDBSymbol>
-PDBSymbol::create(const IPDBSession &PDBSession,
- std::unique_ptr<IPDBRawSymbol> Symbol) {
- switch (Symbol->getSymTag()) {
+PDBSymbol::createSymbol(const IPDBSession &PDBSession, PDB_SymType Tag) {
+ switch (Tag) {
FACTORY_SYMTAG_CASE(Exe, PDBSymbolExe)
FACTORY_SYMTAG_CASE(Compiland, PDBSymbolCompiland)
FACTORY_SYMTAG_CASE(CompilandDetails, PDBSymbolCompilandDetails)
@@ -98,18 +95,35 @@ PDBSymbol::create(const IPDBSession &PDBSession,
FACTORY_SYMTAG_CASE(ManagedType, PDBSymbolTypeManaged)
FACTORY_SYMTAG_CASE(Dimension, PDBSymbolTypeDimension)
default:
- return std::unique_ptr<PDBSymbol>(
- new PDBSymbolUnknown(PDBSession, std::move(Symbol)));
+ return std::unique_ptr<PDBSymbol>(new PDBSymbolUnknown(PDBSession));
}
}
-void PDBSymbol::defaultDump(raw_ostream &OS, int Indent) const {
- RawSymbol->dump(OS, Indent);
+std::unique_ptr<PDBSymbol>
+PDBSymbol::create(const IPDBSession &PDBSession,
+ std::unique_ptr<IPDBRawSymbol> RawSymbol) {
+ auto SymbolPtr = createSymbol(PDBSession, RawSymbol->getSymTag());
+ SymbolPtr->RawSymbol = RawSymbol.get();
+ SymbolPtr->OwnedRawSymbol = std::move(RawSymbol);
+ return SymbolPtr;
+}
+
+std::unique_ptr<PDBSymbol> PDBSymbol::create(const IPDBSession &PDBSession,
+ IPDBRawSymbol &RawSymbol) {
+ auto SymbolPtr = createSymbol(PDBSession, RawSymbol.getSymTag());
+ SymbolPtr->RawSymbol = &RawSymbol;
+ return SymbolPtr;
+}
+
+void PDBSymbol::defaultDump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowFlags,
+ PdbSymbolIdField RecurseFlags) const {
+ RawSymbol->dump(OS, Indent, ShowFlags, RecurseFlags);
}
void PDBSymbol::dumpProperties() const {
outs() << "\n";
- defaultDump(outs(), 0);
+ defaultDump(outs(), 0, PdbSymbolIdField::All, PdbSymbolIdField::None);
outs().flush();
}
@@ -123,10 +137,6 @@ void PDBSymbol::dumpChildStats() const {
outs().flush();
}
-std::unique_ptr<PDBSymbol> PDBSymbol::clone() const {
- return Session.getSymbolById(getSymIndexId());
-}
-
PDB_SymType PDBSymbol::getSymTag() const { return RawSymbol->getSymTag(); }
uint32_t PDBSymbol::getSymIndexId() const { return RawSymbol->getSymIndexId(); }
@@ -172,3 +182,34 @@ PDBSymbol::getChildStats(TagStats &Stats) const {
std::unique_ptr<PDBSymbol> PDBSymbol::getSymbolByIdHelper(uint32_t Id) const {
return Session.getSymbolById(Id);
}
+
+void llvm::pdb::dumpSymbolIdField(raw_ostream &OS, StringRef Name,
+ SymIndexId Value, int Indent,
+ const IPDBSession &Session,
+ PdbSymbolIdField FieldId,
+ PdbSymbolIdField ShowFlags,
+ PdbSymbolIdField RecurseFlags) {
+ if ((FieldId & ShowFlags) == PdbSymbolIdField::None)
+ return;
+
+ OS << "\n";
+ OS.indent(Indent);
+ OS << Name << ": " << Value;
+ // Don't recurse unless the user requested it.
+ if ((FieldId & RecurseFlags) == PdbSymbolIdField::None)
+ return;
+ // And obviously don't recurse on the symbol itself.
+ if (FieldId == PdbSymbolIdField::SymIndexId)
+ return;
+
+ auto Child = Session.getSymbolById(Value);
+
+ // It could have been a placeholder symbol for a type we don't yet support,
+ // so just exit in that case.
+ if (!Child)
+ return;
+
+ // Don't recurse more than once, so pass PdbSymbolIdField::None) for the
+ // recurse flags.
+ Child->defaultDump(OS, Indent + 2, ShowFlags, PdbSymbolIdField::None);
+}
diff --git a/lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp b/lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp
index 3648272e1d0e..cb1a9bee8024 100644
--- a/lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp
@@ -16,12 +16,6 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolAnnotation::PDBSymbolAnnotation(const IPDBSession &PDBSession,
- std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::Annotation);
-}
-
void PDBSymbolAnnotation::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
}
diff --git a/lib/DebugInfo/PDB/PDBSymbolBlock.cpp b/lib/DebugInfo/PDB/PDBSymbolBlock.cpp
index 7076b4aec347..13eec9734d02 100644
--- a/lib/DebugInfo/PDB/PDBSymbolBlock.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolBlock.cpp
@@ -17,10 +17,4 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolBlock::PDBSymbolBlock(const IPDBSession &PDBSession,
- std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::Block);
-}
-
void PDBSymbolBlock::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
diff --git a/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp b/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp
index 8798c7b9db88..bbc5e6dd2a17 100644
--- a/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp
@@ -22,12 +22,6 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolCompiland::PDBSymbolCompiland(const IPDBSession &PDBSession,
- std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::Compiland);
-}
-
void PDBSymbolCompiland::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
}
diff --git a/lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp b/lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp
index f73cd36d057a..bdd8535a3ef3 100644
--- a/lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp
@@ -17,12 +17,6 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolCompilandDetails::PDBSymbolCompilandDetails(
- const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::CompilandDetails);
-}
-
void PDBSymbolCompilandDetails::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
}
diff --git a/lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp b/lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp
index df696fa8c5f2..f88df2df6be4 100644
--- a/lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp
@@ -18,12 +18,6 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolCompilandEnv::PDBSymbolCompilandEnv(
- const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::CompilandEnv);
-}
-
std::string PDBSymbolCompilandEnv::getValue() const {
Variant Value = RawSymbol->getValue();
if (Value.Type != PDB_VariantType::String)
diff --git a/lib/DebugInfo/PDB/PDBSymbolCustom.cpp b/lib/DebugInfo/PDB/PDBSymbolCustom.cpp
index a7b69a755941..10a21806adb6 100644
--- a/lib/DebugInfo/PDB/PDBSymbolCustom.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolCustom.cpp
@@ -18,12 +18,6 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolCustom::PDBSymbolCustom(const IPDBSession &PDBSession,
- std::unique_ptr<IPDBRawSymbol> CustomSymbol)
- : PDBSymbol(PDBSession, std::move(CustomSymbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::Custom);
-}
-
void PDBSymbolCustom::getDataBytes(llvm::SmallVector<uint8_t, 32> &bytes) {
RawSymbol->getDataBytes(bytes);
}
diff --git a/lib/DebugInfo/PDB/PDBSymbolData.cpp b/lib/DebugInfo/PDB/PDBSymbolData.cpp
index ae4a8038ccd7..7de94670bcb3 100644
--- a/lib/DebugInfo/PDB/PDBSymbolData.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolData.cpp
@@ -17,12 +17,6 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolData::PDBSymbolData(const IPDBSession &PDBSession,
- std::unique_ptr<IPDBRawSymbol> DataSymbol)
- : PDBSymbol(PDBSession, std::move(DataSymbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::Data);
-}
-
void PDBSymbolData::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
std::unique_ptr<IPDBEnumLineNumbers> PDBSymbolData::getLineNumbers() const {
diff --git a/lib/DebugInfo/PDB/PDBSymbolExe.cpp b/lib/DebugInfo/PDB/PDBSymbolExe.cpp
index 7417167b61ad..eb409412af59 100644
--- a/lib/DebugInfo/PDB/PDBSymbolExe.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolExe.cpp
@@ -17,12 +17,6 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolExe::PDBSymbolExe(const IPDBSession &PDBSession,
- std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::Exe);
-}
-
void PDBSymbolExe::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
uint32_t PDBSymbolExe::getPointerByteSize() const {
diff --git a/lib/DebugInfo/PDB/PDBSymbolFunc.cpp b/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
index 37ca1abe86e9..75063cb3e7f8 100644
--- a/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
@@ -69,10 +69,6 @@ public:
void reset() override { CurIter = Args.empty() ? Args.end() : Args.begin(); }
- FunctionArgEnumerator *clone() const override {
- return new FunctionArgEnumerator(Session, Func);
- }
-
private:
typedef std::vector<std::unique_ptr<PDBSymbolData>> ArgListType;
const IPDBSession &Session;
@@ -82,12 +78,6 @@ private:
};
}
-PDBSymbolFunc::PDBSymbolFunc(const IPDBSession &PDBSession,
- std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::Function);
-}
-
std::unique_ptr<IPDBEnumChildren<PDBSymbolData>>
PDBSymbolFunc::getArguments() const {
return llvm::make_unique<FunctionArgEnumerator>(Session, *this);
diff --git a/lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp b/lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp
index 4a4195beb4ea..af8aafa7be96 100644
--- a/lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp
@@ -17,12 +17,6 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolFuncDebugEnd::PDBSymbolFuncDebugEnd(
- const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::FuncDebugEnd);
-}
-
void PDBSymbolFuncDebugEnd::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
}
diff --git a/lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp b/lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp
index a448a404dc4a..77b510873bea 100644
--- a/lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp
@@ -17,12 +17,6 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolFuncDebugStart::PDBSymbolFuncDebugStart(
- const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::FuncDebugStart);
-}
-
void PDBSymbolFuncDebugStart::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
}
diff --git a/lib/DebugInfo/PDB/PDBSymbolLabel.cpp b/lib/DebugInfo/PDB/PDBSymbolLabel.cpp
index a67a20d8e352..c802b97925e6 100644
--- a/lib/DebugInfo/PDB/PDBSymbolLabel.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolLabel.cpp
@@ -16,10 +16,4 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolLabel::PDBSymbolLabel(const IPDBSession &PDBSession,
- std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::Label);
-}
-
void PDBSymbolLabel::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
diff --git a/lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp b/lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp
index dbec16fcbaac..a2dd2ab92dd9 100644
--- a/lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp
@@ -17,12 +17,6 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolPublicSymbol::PDBSymbolPublicSymbol(
- const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::PublicSymbol);
-}
-
void PDBSymbolPublicSymbol::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
}
diff --git a/lib/DebugInfo/PDB/PDBSymbolThunk.cpp b/lib/DebugInfo/PDB/PDBSymbolThunk.cpp
index b2648197f9cc..d227e3a7a60c 100644
--- a/lib/DebugInfo/PDB/PDBSymbolThunk.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolThunk.cpp
@@ -16,10 +16,4 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolThunk::PDBSymbolThunk(const IPDBSession &PDBSession,
- std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::Thunk);
-}
-
void PDBSymbolThunk::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp
index ba40f65ef40f..a2064d1ac1eb 100644
--- a/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp
@@ -16,12 +16,6 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolTypeArray::PDBSymbolTypeArray(const IPDBSession &PDBSession,
- std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::ArrayType);
-}
-
void PDBSymbolTypeArray::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
}
diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp
index 0fdf8b6d0f77..f0376c05557f 100644
--- a/lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp
@@ -17,12 +17,6 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolTypeBaseClass::PDBSymbolTypeBaseClass(
- const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::BaseClass);
-}
-
void PDBSymbolTypeBaseClass::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
}
diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp
index 0bf563af7df5..a9f59e5f9d4d 100644
--- a/lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp
@@ -16,12 +16,6 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolTypeBuiltin::PDBSymbolTypeBuiltin(
- const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::BuiltinType);
-}
-
void PDBSymbolTypeBuiltin::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
}
diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp
index 726e7e1cdbb4..cfb347fbac55 100644
--- a/lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp
@@ -17,12 +17,6 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolTypeCustom::PDBSymbolTypeCustom(const IPDBSession &PDBSession,
- std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::CustomType);
-}
-
void PDBSymbolTypeCustom::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
}
diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp
index 6c84b984d210..4eb48997635a 100644
--- a/lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp
@@ -17,13 +17,6 @@
using namespace llvm;
using namespace llvm::pdb;
-
-PDBSymbolTypeDimension::PDBSymbolTypeDimension(
- const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::Dimension);
-}
-
void PDBSymbolTypeDimension::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
}
diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp
index f9c3067c20bf..2e88d9eb284a 100644
--- a/lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp
@@ -17,10 +17,4 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolTypeEnum::PDBSymbolTypeEnum(const IPDBSession &PDBSession,
- std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::Enum);
-}
-
void PDBSymbolTypeEnum::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp
index c01877287888..00d2d51aa8a7 100644
--- a/lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp
@@ -17,12 +17,6 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolTypeFriend::PDBSymbolTypeFriend(const IPDBSession &PDBSession,
- std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::Friend);
-}
-
void PDBSymbolTypeFriend::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
}
diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp
index 4d5cd63f6857..0399e110d592 100644
--- a/lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp
@@ -16,12 +16,6 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolTypeFunctionArg::PDBSymbolTypeFunctionArg(
- const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::FunctionArg);
-}
-
void PDBSymbolTypeFunctionArg::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
}
diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp
index 8fd3b49155c9..c0564d3941dd 100644
--- a/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp
@@ -56,23 +56,12 @@ public:
void reset() override { Enumerator->reset(); }
- MyType *clone() const override {
- std::unique_ptr<ArgEnumeratorType> Clone(Enumerator->clone());
- return new FunctionArgEnumerator(Session, std::move(Clone));
- }
-
private:
const IPDBSession &Session;
std::unique_ptr<ArgEnumeratorType> Enumerator;
};
}
-PDBSymbolTypeFunctionSig::PDBSymbolTypeFunctionSig(
- const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::FunctionSig);
-}
-
std::unique_ptr<IPDBEnumSymbols>
PDBSymbolTypeFunctionSig::getArguments() const {
return llvm::make_unique<FunctionArgEnumerator>(Session, *this);
diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp
index 7cfba823b4fa..1faaf9c67a2c 100644
--- a/lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp
@@ -17,12 +17,6 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolTypeManaged::PDBSymbolTypeManaged(
- const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::ManagedType);
-}
-
void PDBSymbolTypeManaged::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
}
diff --git a/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp b/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp
index 69819811d61f..cf5a369116a9 100644
--- a/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp
@@ -17,12 +17,6 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolTypePointer::PDBSymbolTypePointer(
- const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::PointerType);
-}
-
void PDBSymbolTypePointer::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
}
diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp
index 102b540e0fef..1838f1612b49 100644
--- a/lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp
@@ -16,12 +16,6 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolTypeTypedef::PDBSymbolTypeTypedef(
- const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::Typedef);
-}
-
void PDBSymbolTypeTypedef::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
}
diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp
index 715ae15e1a7a..2f5222f34fe4 100644
--- a/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp
@@ -23,10 +23,4 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolTypeUDT::PDBSymbolTypeUDT(const IPDBSession &PDBSession,
- std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::UDT);
-}
-
void PDBSymbolTypeUDT::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp
index 9a21855f57f0..0262f91e8336 100644
--- a/lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp
@@ -16,12 +16,6 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolTypeVTable::PDBSymbolTypeVTable(const IPDBSession &PDBSession,
- std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::VTable);
-}
-
void PDBSymbolTypeVTable::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
}
diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp
index ddc0574617c5..16c3a3606981 100644
--- a/lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp
@@ -17,12 +17,6 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolTypeVTableShape::PDBSymbolTypeVTableShape(
- const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::VTableShape);
-}
-
void PDBSymbolTypeVTableShape::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
}
diff --git a/lib/DebugInfo/PDB/PDBSymbolUnknown.cpp b/lib/DebugInfo/PDB/PDBSymbolUnknown.cpp
index fdbe845f455a..7bcf9457a2b6 100644
--- a/lib/DebugInfo/PDB/PDBSymbolUnknown.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolUnknown.cpp
@@ -17,8 +17,4 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolUnknown::PDBSymbolUnknown(const IPDBSession &PDBSession,
- std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {}
-
void PDBSymbolUnknown::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
diff --git a/lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp b/lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp
index f40578f4372a..ecf2126f8802 100644
--- a/lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp
@@ -17,12 +17,6 @@
using namespace llvm;
using namespace llvm::pdb;
-PDBSymbolUsingNamespace::PDBSymbolUsingNamespace(
- const IPDBSession &PDBSession, std::unique_ptr<IPDBRawSymbol> Symbol)
- : PDBSymbol(PDBSession, std::move(Symbol)) {
- assert(RawSymbol->getSymTag() == PDB_SymType::UsingNamespace);
-}
-
void PDBSymbolUsingNamespace::dump(PDBSymDumper &Dumper) const {
Dumper.dump(*this);
}
diff --git a/lib/DebugInfo/Symbolize/Symbolize.cpp b/lib/DebugInfo/Symbolize/Symbolize.cpp
index f760a0ef65c4..59a85d6c3fcf 100644
--- a/lib/DebugInfo/Symbolize/Symbolize.cpp
+++ b/lib/DebugInfo/Symbolize/Symbolize.cpp
@@ -410,7 +410,8 @@ LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName,
Objects.first->getFileName(), Session)) {
Modules.insert(
std::make_pair(ModuleName, std::unique_ptr<SymbolizableModule>()));
- return std::move(Err);
+ // Return along the PDB filename to provide more context
+ return createFileError(PDBFileName, std::move(Err));
}
Context.reset(new PDBContext(*CoffObject, std::move(Session)));
}