summaryrefslogtreecommitdiff
path: root/lib/DebugInfo
diff options
context:
space:
mode:
Diffstat (limited to 'lib/DebugInfo')
-rw-r--r--lib/DebugInfo/CodeView/CMakeLists.txt2
-rw-r--r--lib/DebugInfo/CodeView/CVTypeVisitor.cpp41
-rw-r--r--lib/DebugInfo/CodeView/ModuleDebugUnknownFragment.cpp10
-rw-r--r--lib/DebugInfo/CodeView/RandomAccessTypeVisitor.cpp91
-rw-r--r--lib/DebugInfo/CodeView/TypeDatabase.cpp73
-rw-r--r--lib/DebugInfo/CodeView/TypeDatabaseVisitor.cpp65
-rw-r--r--lib/DebugInfo/CodeView/TypeDumpVisitor.cpp9
-rw-r--r--lib/DebugInfo/DWARF/DWARFContext.cpp25
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugAranges.cpp5
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp4
-rw-r--r--lib/DebugInfo/DWARF/DWARFDie.cpp12
-rw-r--r--lib/DebugInfo/DWARF/DWARFTypeUnit.cpp6
-rw-r--r--lib/DebugInfo/DWARF/DWARFUnit.cpp16
-rw-r--r--lib/DebugInfo/DWARF/DWARFVerifier.cpp8
-rw-r--r--lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp2
15 files changed, 275 insertions, 94 deletions
diff --git a/lib/DebugInfo/CodeView/CMakeLists.txt b/lib/DebugInfo/CodeView/CMakeLists.txt
index 410d5a3777d4..8d9353ae5f5e 100644
--- a/lib/DebugInfo/CodeView/CMakeLists.txt
+++ b/lib/DebugInfo/CodeView/CMakeLists.txt
@@ -13,7 +13,7 @@ add_llvm_library(LLVMDebugInfoCodeView
ModuleDebugFragmentVisitor.cpp
ModuleDebugInlineeLinesFragment.cpp
ModuleDebugLineFragment.cpp
- ModuleDebugUnknownFragment.cpp
+ RandomAccessTypeVisitor.cpp
RecordSerialization.cpp
StringTable.cpp
SymbolRecordMapping.cpp
diff --git a/lib/DebugInfo/CodeView/CVTypeVisitor.cpp b/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
index 0069ee3cc904..b6ed0453d9c4 100644
--- a/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
+++ b/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
@@ -26,8 +26,7 @@ CVTypeVisitor::CVTypeVisitor(TypeVisitorCallbacks &Callbacks)
: Callbacks(Callbacks) {}
template <typename T>
-static Error visitKnownRecord(CVTypeVisitor &Visitor, CVType &Record,
- TypeVisitorCallbacks &Callbacks) {
+static Error visitKnownRecord(CVType &Record, TypeVisitorCallbacks &Callbacks) {
TypeRecordKind RK = static_cast<TypeRecordKind>(Record.Type);
T KnownRecord(RK);
if (auto EC = Callbacks.visitKnownRecord(Record, KnownRecord))
@@ -76,7 +75,7 @@ void CVTypeVisitor::addTypeServerHandler(TypeServerHandler &Handler) {
Handlers.push_back(&Handler);
}
-Error CVTypeVisitor::visitTypeRecord(CVType &Record) {
+Expected<bool> CVTypeVisitor::handleTypeServer(CVType &Record) {
if (Record.Type == TypeLeafKind::LF_TYPESERVER2 && !Handlers.empty()) {
auto TS = deserializeTypeServerRecord(Record);
if (!TS)
@@ -90,16 +89,16 @@ Error CVTypeVisitor::visitTypeRecord(CVType &Record) {
// If the handler processed the record, return success.
if (*ExpectedResult)
- return Error::success();
+ return true;
// Otherwise keep searching for a handler, eventually falling out and
// using the default record handler.
}
}
+ return false;
+}
- if (auto EC = Callbacks.visitTypeBegin(Record))
- return EC;
-
+Error CVTypeVisitor::finishVisitation(CVType &Record) {
switch (Record.Type) {
default:
if (auto EC = Callbacks.visitUnknownType(Record))
@@ -107,7 +106,7 @@ Error CVTypeVisitor::visitTypeRecord(CVType &Record) {
break;
#define TYPE_RECORD(EnumName, EnumVal, Name) \
case EnumName: { \
- if (auto EC = visitKnownRecord<Name##Record>(*this, Record, Callbacks)) \
+ if (auto EC = visitKnownRecord<Name##Record>(Record, Callbacks)) \
return EC; \
break; \
}
@@ -124,6 +123,32 @@ Error CVTypeVisitor::visitTypeRecord(CVType &Record) {
return Error::success();
}
+Error CVTypeVisitor::visitTypeRecord(CVType &Record, TypeIndex Index) {
+ auto ExpectedResult = handleTypeServer(Record);
+ if (!ExpectedResult)
+ return ExpectedResult.takeError();
+ if (*ExpectedResult)
+ return Error::success();
+
+ if (auto EC = Callbacks.visitTypeBegin(Record, Index))
+ return EC;
+
+ return finishVisitation(Record);
+}
+
+Error CVTypeVisitor::visitTypeRecord(CVType &Record) {
+ auto ExpectedResult = handleTypeServer(Record);
+ if (!ExpectedResult)
+ return ExpectedResult.takeError();
+ if (*ExpectedResult)
+ return Error::success();
+
+ if (auto EC = Callbacks.visitTypeBegin(Record))
+ return EC;
+
+ return finishVisitation(Record);
+}
+
static Error visitMemberRecord(CVMemberRecord &Record,
TypeVisitorCallbacks &Callbacks) {
if (auto EC = Callbacks.visitMemberBegin(Record))
diff --git a/lib/DebugInfo/CodeView/ModuleDebugUnknownFragment.cpp b/lib/DebugInfo/CodeView/ModuleDebugUnknownFragment.cpp
deleted file mode 100644
index 9fd2cb8ed3e8..000000000000
--- a/lib/DebugInfo/CodeView/ModuleDebugUnknownFragment.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-//===- ModuleDebugUnknownFragment.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/ModuleDebugUnknownFragment.h" \ No newline at end of file
diff --git a/lib/DebugInfo/CodeView/RandomAccessTypeVisitor.cpp b/lib/DebugInfo/CodeView/RandomAccessTypeVisitor.cpp
new file mode 100644
index 000000000000..4cb9acbe07d9
--- /dev/null
+++ b/lib/DebugInfo/CodeView/RandomAccessTypeVisitor.cpp
@@ -0,0 +1,91 @@
+//===- RandomAccessTypeVisitor.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/RandomAccessTypeVisitor.h"
+
+#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
+#include "llvm/DebugInfo/CodeView/TypeServerHandler.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+RandomAccessTypeVisitor::RandomAccessTypeVisitor(
+ const CVTypeArray &Types, uint32_t NumRecords,
+ PartialOffsetArray PartialOffsets)
+ : Database(NumRecords), Types(Types), DatabaseVisitor(Database),
+ InternalVisitor(Pipeline), PartialOffsets(PartialOffsets) {
+ Pipeline.addCallbackToPipeline(Deserializer);
+ Pipeline.addCallbackToPipeline(DatabaseVisitor);
+
+ KnownOffsets.resize(Database.capacity());
+}
+
+Error RandomAccessTypeVisitor::visitTypeIndex(TypeIndex TI,
+ TypeVisitorCallbacks &Callbacks) {
+ assert(TI.toArrayIndex() < Database.capacity());
+
+ if (!Database.contains(TI)) {
+ if (auto EC = visitRangeForType(TI))
+ return EC;
+ }
+
+ assert(Database.contains(TI));
+ auto &Record = Database.getTypeRecord(TI);
+ CVTypeVisitor V(Callbacks);
+ return V.visitTypeRecord(Record, TI);
+}
+
+Error RandomAccessTypeVisitor::visitRangeForType(TypeIndex TI) {
+ if (PartialOffsets.empty()) {
+ TypeIndex TIB(TypeIndex::FirstNonSimpleIndex);
+ TypeIndex TIE = TIB + Database.capacity();
+ return visitRange(TIB, 0, TIE);
+ }
+
+ auto Next = std::upper_bound(PartialOffsets.begin(), PartialOffsets.end(), TI,
+ [](TypeIndex Value, const TypeIndexOffset &IO) {
+ return Value < IO.Type;
+ });
+
+ assert(Next != PartialOffsets.begin());
+ auto Prev = std::prev(Next);
+
+ TypeIndex TIB = Prev->Type;
+ TypeIndex TIE;
+ if (Next == PartialOffsets.end()) {
+ TIE = TypeIndex::fromArrayIndex(Database.capacity());
+ } else {
+ TIE = Next->Type;
+ }
+
+ if (auto EC = visitRange(TIB, Prev->Offset, TIE))
+ return EC;
+ return Error::success();
+}
+
+Error RandomAccessTypeVisitor::visitRange(TypeIndex Begin, uint32_t BeginOffset,
+ TypeIndex End) {
+
+ auto RI = Types.at(BeginOffset);
+ assert(RI != Types.end());
+
+ while (Begin != End) {
+ assert(!Database.contains(Begin));
+ if (auto EC = InternalVisitor.visitTypeRecord(*RI, Begin))
+ return EC;
+ KnownOffsets[Begin.toArrayIndex()] = BeginOffset;
+
+ BeginOffset += RI.getRecordLength();
+ ++Begin;
+ ++RI;
+ }
+
+ return Error::success();
+}
diff --git a/lib/DebugInfo/CodeView/TypeDatabase.cpp b/lib/DebugInfo/CodeView/TypeDatabase.cpp
index 5b8841041f88..7924440e5e29 100644
--- a/lib/DebugInfo/CodeView/TypeDatabase.cpp
+++ b/lib/DebugInfo/CodeView/TypeDatabase.cpp
@@ -65,20 +65,32 @@ static const SimpleTypeEntry SimpleTypeNames[] = {
{"__bool64*", SimpleTypeKind::Boolean64},
};
-TypeDatabase::TypeDatabase(uint32_t ExpectedSize) : TypeNameStorage(Allocator) {
- CVUDTNames.reserve(ExpectedSize);
- TypeRecords.reserve(ExpectedSize);
+TypeDatabase::TypeDatabase(uint32_t Capacity) : TypeNameStorage(Allocator) {
+ CVUDTNames.resize(Capacity);
+ TypeRecords.resize(Capacity);
+ ValidRecords.resize(Capacity);
}
-/// Gets the type index for the next type record.
-TypeIndex TypeDatabase::getNextTypeIndex() const {
- return TypeIndex(TypeIndex::FirstNonSimpleIndex + CVUDTNames.size());
+TypeIndex TypeDatabase::appendType(StringRef Name, const CVType &Data) {
+ TypeIndex TI;
+ TI = getAppendIndex();
+ if (TI.toArrayIndex() >= capacity())
+ grow();
+ recordType(Name, TI, Data);
+ return TI;
}
-/// Records the name of a type, and reserves its type index.
-void TypeDatabase::recordType(StringRef Name, const CVType &Data) {
- CVUDTNames.push_back(Name);
- TypeRecords.push_back(Data);
+void TypeDatabase::recordType(StringRef Name, TypeIndex Index,
+ const CVType &Data) {
+ uint32_t AI = Index.toArrayIndex();
+
+ assert(!contains(Index));
+ assert(AI < capacity());
+
+ CVUDTNames[AI] = Name;
+ TypeRecords[AI] = Data;
+ ValidRecords.set(AI);
+ ++Count;
}
/// Saves the name in a StringSet and creates a stable StringRef.
@@ -104,24 +116,47 @@ StringRef TypeDatabase::getTypeName(TypeIndex Index) const {
return "<unknown simple type>";
}
- uint32_t I = Index.getIndex() - TypeIndex::FirstNonSimpleIndex;
- if (I < CVUDTNames.size())
- return CVUDTNames[I];
+ if (contains(Index))
+ return CVUDTNames[Index.toArrayIndex()];
return "<unknown UDT>";
}
const CVType &TypeDatabase::getTypeRecord(TypeIndex Index) const {
- return TypeRecords[Index.getIndex() - TypeIndex::FirstNonSimpleIndex];
+ assert(contains(Index));
+ return TypeRecords[Index.toArrayIndex()];
}
CVType &TypeDatabase::getTypeRecord(TypeIndex Index) {
- return TypeRecords[Index.getIndex() - TypeIndex::FirstNonSimpleIndex];
+ assert(contains(Index));
+ return TypeRecords[Index.toArrayIndex()];
+}
+
+bool TypeDatabase::contains(TypeIndex Index) const {
+ uint32_t AI = Index.toArrayIndex();
+ if (AI >= capacity())
+ return false;
+
+ return ValidRecords.test(AI);
}
-bool TypeDatabase::containsTypeIndex(TypeIndex Index) const {
- uint32_t I = Index.getIndex() - TypeIndex::FirstNonSimpleIndex;
- return I < CVUDTNames.size();
+uint32_t TypeDatabase::size() const { return Count; }
+
+uint32_t TypeDatabase::capacity() const { return TypeRecords.size(); }
+
+void TypeDatabase::grow() {
+ TypeRecords.emplace_back();
+ CVUDTNames.emplace_back();
+ ValidRecords.resize(ValidRecords.size() + 1);
}
-uint32_t TypeDatabase::size() const { return CVUDTNames.size(); }
+bool TypeDatabase::empty() const { return size() == 0; }
+
+TypeIndex TypeDatabase::getAppendIndex() const {
+ if (empty())
+ return TypeIndex::fromArrayIndex(0);
+
+ int Index = ValidRecords.find_last();
+ assert(Index != -1);
+ return TypeIndex::fromArrayIndex(Index) + 1;
+}
diff --git a/lib/DebugInfo/CodeView/TypeDatabaseVisitor.cpp b/lib/DebugInfo/CodeView/TypeDatabaseVisitor.cpp
index c234afd2288b..8d97f8b1cb40 100644
--- a/lib/DebugInfo/CodeView/TypeDatabaseVisitor.cpp
+++ b/lib/DebugInfo/CodeView/TypeDatabaseVisitor.cpp
@@ -15,7 +15,7 @@ using namespace llvm;
using namespace llvm::codeview;
-Error TypeDatabaseVisitor::visitTypeBegin(CVRecord<TypeLeafKind> &Record) {
+Error TypeDatabaseVisitor::visitTypeBegin(CVType &Record) {
assert(!IsInFieldList);
// Reset Name to the empty string. If the visitor sets it, we know it.
Name = "";
@@ -28,6 +28,22 @@ Error TypeDatabaseVisitor::visitTypeBegin(CVRecord<TypeLeafKind> &Record) {
return Error::success();
}
+Error TypeDatabaseVisitor::visitTypeBegin(CVType &Record, TypeIndex Index) {
+ if (auto EC = visitTypeBegin(Record))
+ return EC;
+
+ CurrentTypeIndex = Index;
+ return Error::success();
+}
+
+StringRef TypeDatabaseVisitor::getTypeName(TypeIndex Index) const {
+ return TypeDB->getTypeName(Index);
+}
+
+StringRef TypeDatabaseVisitor::saveTypeName(StringRef Name) {
+ return TypeDB->saveTypeName(Name);
+}
+
Error TypeDatabaseVisitor::visitTypeEnd(CVType &CVR) {
if (CVR.Type == LF_FIELDLIST) {
assert(IsInFieldList);
@@ -39,7 +55,12 @@ Error TypeDatabaseVisitor::visitTypeEnd(CVType &CVR) {
// CVUDTNames is indexed by type index, and must have one entry for every
// type. Field list members are not recorded, and are only referenced by
// their containing field list record.
- TypeDB.recordType(Name, CVR);
+ if (CurrentTypeIndex)
+ TypeDB->recordType(Name, *CurrentTypeIndex, CVR);
+ else
+ TypeDB->appendType(Name, CVR);
+
+ CurrentTypeIndex.reset();
return Error::success();
}
@@ -73,13 +94,13 @@ Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, ArgListRecord &Args) {
uint32_t Size = Indices.size();
SmallString<256> TypeName("(");
for (uint32_t I = 0; I < Size; ++I) {
- StringRef ArgTypeName = TypeDB.getTypeName(Indices[I]);
+ StringRef ArgTypeName = getTypeName(Indices[I]);
TypeName.append(ArgTypeName);
if (I + 1 != Size)
TypeName.append(", ");
}
TypeName.push_back(')');
- Name = TypeDB.saveTypeName(TypeName);
+ Name = saveTypeName(TypeName);
return Error::success();
}
@@ -89,13 +110,13 @@ Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR,
uint32_t Size = Indices.size();
SmallString<256> TypeName("\"");
for (uint32_t I = 0; I < Size; ++I) {
- StringRef ArgTypeName = TypeDB.getTypeName(Indices[I]);
+ StringRef ArgTypeName = getTypeName(Indices[I]);
TypeName.append(ArgTypeName);
if (I + 1 != Size)
TypeName.append("\" \"");
}
TypeName.push_back('\"');
- Name = TypeDB.saveTypeName(TypeName);
+ Name = saveTypeName(TypeName);
return Error::success();
}
@@ -132,26 +153,26 @@ Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR,
Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR,
ProcedureRecord &Proc) {
- StringRef ReturnTypeName = TypeDB.getTypeName(Proc.getReturnType());
- StringRef ArgListTypeName = TypeDB.getTypeName(Proc.getArgumentList());
+ StringRef ReturnTypeName = getTypeName(Proc.getReturnType());
+ StringRef ArgListTypeName = getTypeName(Proc.getArgumentList());
SmallString<256> TypeName(ReturnTypeName);
TypeName.push_back(' ');
TypeName.append(ArgListTypeName);
- Name = TypeDB.saveTypeName(TypeName);
+ Name = saveTypeName(TypeName);
return Error::success();
}
Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR,
MemberFunctionRecord &MF) {
- StringRef ReturnTypeName = TypeDB.getTypeName(MF.getReturnType());
- StringRef ClassTypeName = TypeDB.getTypeName(MF.getClassType());
- StringRef ArgListTypeName = TypeDB.getTypeName(MF.getArgumentList());
+ StringRef ReturnTypeName = getTypeName(MF.getReturnType());
+ StringRef ClassTypeName = getTypeName(MF.getClassType());
+ StringRef ArgListTypeName = getTypeName(MF.getArgumentList());
SmallString<256> TypeName(ReturnTypeName);
TypeName.push_back(' ');
TypeName.append(ClassTypeName);
TypeName.append("::");
TypeName.append(ArgListTypeName);
- Name = TypeDB.saveTypeName(TypeName);
+ Name = saveTypeName(TypeName);
return Error::success();
}
@@ -171,13 +192,13 @@ Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
if (Ptr.isPointerToMember()) {
const MemberPointerInfo &MI = Ptr.getMemberInfo();
- StringRef PointeeName = TypeDB.getTypeName(Ptr.getReferentType());
- StringRef ClassName = TypeDB.getTypeName(MI.getContainingType());
+ StringRef PointeeName = getTypeName(Ptr.getReferentType());
+ StringRef ClassName = getTypeName(MI.getContainingType());
SmallString<256> TypeName(PointeeName);
TypeName.push_back(' ');
TypeName.append(ClassName);
TypeName.append("::*");
- Name = TypeDB.saveTypeName(TypeName);
+ Name = saveTypeName(TypeName);
} else {
SmallString<256> TypeName;
if (Ptr.isConst())
@@ -187,7 +208,7 @@ Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
if (Ptr.isUnaligned())
TypeName.append("__unaligned ");
- TypeName.append(TypeDB.getTypeName(Ptr.getReferentType()));
+ TypeName.append(getTypeName(Ptr.getReferentType()));
if (Ptr.getMode() == PointerMode::LValueReference)
TypeName.append("&");
@@ -197,7 +218,7 @@ Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
TypeName.append("*");
if (!TypeName.empty())
- Name = TypeDB.saveTypeName(TypeName);
+ Name = saveTypeName(TypeName);
}
return Error::success();
}
@@ -205,7 +226,7 @@ Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, ModifierRecord &Mod) {
uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
- StringRef ModifiedName = TypeDB.getTypeName(Mod.getModifiedType());
+ StringRef ModifiedName = getTypeName(Mod.getModifiedType());
SmallString<256> TypeName;
if (Mods & uint16_t(ModifierOptions::Const))
TypeName.append("const ");
@@ -214,14 +235,14 @@ Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, ModifierRecord &Mod) {
if (Mods & uint16_t(ModifierOptions::Unaligned))
TypeName.append("__unaligned ");
TypeName.append(ModifiedName);
- Name = TypeDB.saveTypeName(TypeName);
+ Name = saveTypeName(TypeName);
return Error::success();
}
Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR,
VFTableShapeRecord &Shape) {
- Name = TypeDB.saveTypeName("<vftable " + utostr(Shape.getEntryCount()) +
- " methods>");
+ Name =
+ saveTypeName("<vftable " + utostr(Shape.getEntryCount()) + " methods>");
return Error::success();
}
diff --git a/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp b/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
index 870d95221e7d..27a6e0987886 100644
--- a/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
+++ b/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
@@ -173,10 +173,13 @@ void TypeDumpVisitor::printItemIndex(StringRef FieldName, TypeIndex TI) const {
}
Error TypeDumpVisitor::visitTypeBegin(CVType &Record) {
+ TypeIndex TI = getSourceDB().getAppendIndex();
+ return visitTypeBegin(Record, TI);
+}
+
+Error TypeDumpVisitor::visitTypeBegin(CVType &Record, TypeIndex Index) {
W->startLine() << getLeafTypeName(Record.Type);
- W->getOStream() << " ("
- << HexNumber(getSourceDB().getNextTypeIndex().getIndex())
- << ")";
+ W->getOStream() << " (" << HexNumber(Index.getIndex()) << ")";
W->getOStream() << " {\n";
W->indent();
W->printEnum("TypeLeafKind", unsigned(Record.Type),
diff --git a/lib/DebugInfo/DWARF/DWARFContext.cpp b/lib/DebugInfo/DWARF/DWARFContext.cpp
index 246899ac12b9..59a060d143ff 100644
--- a/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -66,7 +66,7 @@ uint64_t llvm::getRelocatedValue(const DataExtractor &Data, uint32_t Size,
RelocAddrMap::const_iterator AI = Relocs->find(*Off);
if (AI == Relocs->end())
return Data.getUnsigned(Off, Size);
- return Data.getUnsigned(Off, Size) + AI->second.second;
+ return Data.getUnsigned(Off, Size) + AI->second.Value;
}
static void dumpAccelSection(raw_ostream &OS, StringRef Name,
@@ -905,16 +905,23 @@ static Error createError(const Twine &Reason, llvm::Error E) {
/// Returns the address of symbol relocation used against. Used for futher
/// relocations computation. Symbol's section load address is taken in account if
/// LoadedObjectInfo interface is provided.
-static Expected<uint64_t> getSymbolAddress(const object::ObjectFile &Obj,
- const RelocationRef &Reloc,
- const LoadedObjectInfo *L) {
+static Expected<uint64_t>
+getSymbolAddress(const object::ObjectFile &Obj, const RelocationRef &Reloc,
+ const LoadedObjectInfo *L,
+ std::map<SymbolRef, uint64_t> &Cache) {
uint64_t Ret = 0;
object::section_iterator RSec = Obj.section_end();
object::symbol_iterator Sym = Reloc.getSymbol();
+ std::map<SymbolRef, uint64_t>::iterator CacheIt = Cache.end();
// First calculate the address of the symbol or section as it appears
// in the object file
if (Sym != Obj.symbol_end()) {
+ bool New;
+ std::tie(CacheIt, New) = Cache.insert({*Sym, 0});
+ if (!New)
+ return CacheIt->second;
+
Expected<uint64_t> SymAddrOrErr = Sym->getAddress();
if (!SymAddrOrErr)
return createError("error: failed to compute symbol address: ",
@@ -943,6 +950,10 @@ static Expected<uint64_t> getSymbolAddress(const object::ObjectFile &Obj,
if (L && RSec != Obj.section_end())
if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec))
Ret += SectionLoadAddress - RSec->getAddress();
+
+ if (CacheIt != Cache.end())
+ CacheIt->second = Ret;
+
return Ret;
}
@@ -1075,6 +1086,7 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
continue;
}
+ std::map<SymbolRef, uint64_t> AddrCache;
if (Section.relocation_begin() != Section.relocation_end()) {
uint64_t SectionSize = RelocatedSection->getSize();
for (const RelocationRef &Reloc : Section.relocations()) {
@@ -1083,7 +1095,8 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
if (isRelocScattered(Obj, Reloc))
continue;
- Expected<uint64_t> SymAddrOrErr = getSymbolAddress(Obj, Reloc, L);
+ Expected<uint64_t> SymAddrOrErr =
+ getSymbolAddress(Obj, Reloc, L, AddrCache);
if (!SymAddrOrErr) {
errs() << toString(SymAddrOrErr.takeError()) << '\n';
continue;
@@ -1114,7 +1127,7 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
<< " at " << format("%p", Address)
<< " with width " << format("%d", R.Width)
<< "\n");
- Map->insert(std::make_pair(Address, std::make_pair(R.Width, R.Value)));
+ Map->insert({Address, {(uint8_t)R.Width, R.Value}});
}
}
}
diff --git a/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp b/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
index 0cf71f530446..6601393d7459 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
@@ -54,9 +54,8 @@ void DWARFDebugAranges::generate(DWARFContext *CTX) {
if (ParsedCUOffsets.insert(CUOffset).second) {
DWARFAddressRangesVector CURanges;
CU->collectAddressRanges(CURanges);
- for (const auto &R : CURanges) {
- appendRange(CUOffset, R.first, R.second);
- }
+ for (const auto &R : CURanges)
+ appendRange(CUOffset, R.LowPC, R.HighPC);
}
}
diff --git a/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp b/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
index 9380fe8fe85d..8da797750abd 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
@@ -69,8 +69,8 @@ DWARFDebugRangeList::getAbsoluteRanges(uint64_t BaseAddress) const {
if (RLE.isBaseAddressSelectionEntry(AddressSize)) {
BaseAddress = RLE.EndAddress;
} else {
- Res.push_back(std::make_pair(BaseAddress + RLE.StartAddress,
- BaseAddress + RLE.EndAddress));
+ Res.push_back(
+ {BaseAddress + RLE.StartAddress, BaseAddress + RLE.EndAddress});
}
}
return Res;
diff --git a/lib/DebugInfo/DWARF/DWARFDie.cpp b/lib/DebugInfo/DWARF/DWARFDie.cpp
index 24039eb35209..e3bd759ba94b 100644
--- a/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -60,8 +60,8 @@ static void dumpRanges(raw_ostream &OS, const DWARFAddressRangesVector& Ranges,
OS << '\n';
OS.indent(Indent);
OS << format("[0x%0*" PRIx64 " - 0x%0*" PRIx64 ")",
- AddressSize*2, Range.first,
- AddressSize*2, Range.second);
+ AddressSize*2, Range.LowPC,
+ AddressSize*2, Range.HighPC);
}
}
@@ -229,9 +229,9 @@ DWARFDie::getAddressRanges() const {
return DWARFAddressRangesVector();
// Single range specified by low/high PC.
uint64_t LowPC, HighPC;
- if (getLowAndHighPC(LowPC, HighPC)) {
- return DWARFAddressRangesVector(1, std::make_pair(LowPC, HighPC));
- }
+ if (getLowAndHighPC(LowPC, HighPC))
+ return {{LowPC, HighPC}};
+
// Multiple ranges from .debug_ranges section.
auto RangesOffset = toSectionOffset(find(DW_AT_ranges));
if (RangesOffset) {
@@ -257,7 +257,7 @@ DWARFDie::collectChildrenAddressRanges(DWARFAddressRangesVector& Ranges) const {
bool DWARFDie::addressRangeContainsAddress(const uint64_t Address) const {
for (const auto& R : getAddressRanges()) {
- if (R.first <= Address && Address < R.second)
+ if (R.LowPC <= Address && Address < R.HighPC)
return true;
}
return false;
diff --git a/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp b/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
index e0f819383289..25824f6eb83b 100644
--- a/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
+++ b/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
@@ -24,7 +24,11 @@ bool DWARFTypeUnit::extractImpl(DataExtractor debug_info,
return false;
TypeHash = debug_info.getU64(offset_ptr);
TypeOffset = debug_info.getU32(offset_ptr);
- return TypeOffset < getLength();
+ // TypeOffset is relative to the beginning of the header,
+ // so we have to account for the leading length field.
+ // FIXME: The size of the length field is 12 in DWARF64.
+ unsigned SizeOfLength = 4;
+ return TypeOffset < getLength() + SizeOfLength;
}
void DWARFTypeUnit::dump(raw_ostream &OS, bool SummarizeTypes) {
diff --git a/lib/DebugInfo/DWARF/DWARFUnit.cpp b/lib/DebugInfo/DWARF/DWARFUnit.cpp
index f50487fc3ba3..3835d4da9ae9 100644
--- a/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -349,18 +349,18 @@ void DWARFUnit::updateAddressDieMap(DWARFDie Die) {
if (Die.isSubroutineDIE()) {
for (const auto &R : Die.getAddressRanges()) {
// Ignore 0-sized ranges.
- if (R.first == R.second)
+ if (R.LowPC == R.HighPC)
continue;
- auto B = AddrDieMap.upper_bound(R.first);
- if (B != AddrDieMap.begin() && R.first < (--B)->second.first) {
+ auto B = AddrDieMap.upper_bound(R.LowPC);
+ if (B != AddrDieMap.begin() && R.LowPC < (--B)->second.first) {
// The range is a sub-range of existing ranges, we need to split the
// existing range.
- if (R.second < B->second.first)
- AddrDieMap[R.second] = B->second;
- if (R.first > B->first)
- AddrDieMap[B->first].first = R.first;
+ if (R.HighPC < B->second.first)
+ AddrDieMap[R.HighPC] = B->second;
+ if (R.LowPC > B->first)
+ AddrDieMap[B->first].first = R.LowPC;
}
- AddrDieMap[R.first] = std::make_pair(R.second, Die);
+ AddrDieMap[R.LowPC] = std::make_pair(R.HighPC, Die);
}
}
// Parent DIEs are added to the AddrDieMap prior to the Children DIEs to
diff --git a/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index 9494e876da15..8a544296f65c 100644
--- a/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -23,7 +23,7 @@ using namespace llvm;
using namespace dwarf;
using namespace object;
-void DWARFVerifier::verifyDebugInfoAttribute(DWARFDie &Die,
+void DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
DWARFAttribute &AttrValue) {
const auto Attr = AttrValue.Attr;
switch (Attr) {
@@ -68,7 +68,7 @@ void DWARFVerifier::verifyDebugInfoAttribute(DWARFDie &Die,
}
}
-void DWARFVerifier::verifyDebugInfoForm(DWARFDie &Die,
+void DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
DWARFAttribute &AttrValue) {
const auto Form = AttrValue.Value.getForm();
switch (Form) {
@@ -136,7 +136,7 @@ void DWARFVerifier::verifyDebugInfoForm(DWARFDie &Die,
}
}
-void DWARFVerifier::veifyDebugInfoReferences() {
+void DWARFVerifier::verifyDebugInfoReferences() {
// Take all references and make sure they point to an actual DIE by
// getting the DIE by offset and emitting an error
OS << "Verifying .debug_info references...\n";
@@ -172,7 +172,7 @@ bool DWARFVerifier::handleDebugInfo() {
}
}
}
- veifyDebugInfoReferences();
+ verifyDebugInfoReferences();
return NumDebugInfoErrors == 0;
}
diff --git a/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp b/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
index 375c35b11145..701a318511b8 100644
--- a/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
+++ b/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
@@ -109,7 +109,7 @@ uint32_t TpiStreamBuilder::calculateHashBufferSize() const {
}
uint32_t TpiStreamBuilder::calculateIndexOffsetSize() const {
- return TypeIndexOffsets.size() * sizeof(TypeIndexOffset);
+ return TypeIndexOffsets.size() * sizeof(codeview::TypeIndexOffset);
}
Error TpiStreamBuilder::finalizeMsfLayout() {