aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/DebugInfo
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-02-16 20:13:02 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-02-16 20:13:02 +0000
commitb60736ec1405bb0a8dd40989f67ef4c93da068ab (patch)
tree5c43fbb7c9fc45f0f87e0e6795a86267dbd12f9d /llvm/lib/DebugInfo
parentcfca06d7963fa0909f90483b42a6d7d194d01e08 (diff)
Diffstat (limited to 'llvm/lib/DebugInfo')
-rw-r--r--llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp2
-rw-r--r--llvm/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp7
-rw-r--r--llvm/lib/DebugInfo/CodeView/EnumTables.cpp12
-rw-r--r--llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp10
-rw-r--r--llvm/lib/DebugInfo/CodeView/RecordName.cpp8
-rw-r--r--llvm/lib/DebugInfo/CodeView/RecordSerialization.cpp2
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp3
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp2
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp2
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp5
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp7
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFContext.cpp113
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp14
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp27
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp3
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp53
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp3
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp84
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp14
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp14
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp7
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp139
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDie.cpp39
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp29
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp8
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp4
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp9
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp7
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp194
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp8
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp42
-rw-r--r--llvm/lib/DebugInfo/GSYM/GsymCreator.cpp2
-rw-r--r--llvm/lib/DebugInfo/MSF/MSFBuilder.cpp6
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp81
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp10
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeEnumSymbols.cpp41
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeFunctionSymbol.cpp98
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeInlineSiteSymbol.cpp177
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp7
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativePublicSymbol.cpp6
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp81
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp195
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp62
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBContext.cpp39
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBExtras.cpp16
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp4
-rw-r--r--llvm/lib/DebugInfo/PDB/PDBSymbol.cpp17
-rw-r--r--llvm/lib/DebugInfo/PDB/UDTLayout.cpp8
-rw-r--r--llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp6
-rw-r--r--llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp9
-rw-r--r--llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h6
-rw-r--r--llvm/lib/DebugInfo/Symbolize/Symbolize.cpp19
56 files changed, 1168 insertions, 601 deletions
diff --git a/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp b/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
index 49761b9dce88..c272985cf2d4 100644
--- a/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
+++ b/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
@@ -273,7 +273,6 @@ Error CodeViewRecordIO::mapStringZVectorZ(std::vector<StringRef> &Value,
void CodeViewRecordIO::emitEncodedSignedInteger(const int64_t &Value,
const Twine &Comment) {
- assert(Value < 0 && "Encoded integer is not signed!");
if (Value >= std::numeric_limits<int8_t>::min()) {
Streamer->emitIntValue(LF_CHAR, 2);
emitComment(Comment);
@@ -322,7 +321,6 @@ void CodeViewRecordIO::emitEncodedUnsignedInteger(const uint64_t &Value,
}
Error CodeViewRecordIO::writeEncodedSignedInteger(const int64_t &Value) {
- assert(Value < 0 && "Encoded integer is not signed!");
if (Value >= std::numeric_limits<int8_t>::min()) {
if (auto EC = Writer->writeInteger<uint16_t>(LF_CHAR))
return EC;
diff --git a/llvm/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp b/llvm/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp
index be8c32d5b294..9bc69abea102 100644
--- a/llvm/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp
+++ b/llvm/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp
@@ -47,10 +47,9 @@ Error DebugFrameDataSubsection::commit(BinaryStreamWriter &Writer) const {
}
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;
- });
+ llvm::sort(SortedFrames, [](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/llvm/lib/DebugInfo/CodeView/EnumTables.cpp b/llvm/lib/DebugInfo/CodeView/EnumTables.cpp
index 82f6713a88f5..949707bf5475 100644
--- a/llvm/lib/DebugInfo/CodeView/EnumTables.cpp
+++ b/llvm/lib/DebugInfo/CodeView/EnumTables.cpp
@@ -39,6 +39,14 @@ static const EnumEntry<uint16_t> RegisterNames_X86[] = {
#undef CV_REGISTERS_X86
};
+static const EnumEntry<uint16_t> RegisterNames_ARM[] = {
+#define CV_REGISTERS_ARM
+#define CV_REGISTER(name, val) CV_ENUM_CLASS_ENT(RegisterId, name),
+#include "llvm/DebugInfo/CodeView/CodeViewRegisters.def"
+#undef CV_REGISTER
+#undef CV_REGISTERS_ARM
+};
+
static const EnumEntry<uint16_t> RegisterNames_ARM64[] = {
#define CV_REGISTERS_ARM64
#define CV_REGISTER(name, val) CV_ENUM_CLASS_ENT(RegisterId, name),
@@ -434,7 +442,9 @@ ArrayRef<EnumEntry<TypeLeafKind>> getTypeLeafNames() {
}
ArrayRef<EnumEntry<uint16_t>> getRegisterNames(CPUType Cpu) {
- if (Cpu == CPUType::ARM64) {
+ if (Cpu == CPUType::ARMNT) {
+ return makeArrayRef(RegisterNames_ARM);
+ } else if (Cpu == CPUType::ARM64) {
return makeArrayRef(RegisterNames_ARM64);
}
return makeArrayRef(RegisterNames_X86);
diff --git a/llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp b/llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
index 06b20ba33eec..c0fc3e0ef65a 100644
--- a/llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
+++ b/llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
@@ -172,10 +172,10 @@ Error LazyRandomTypeCollection::visitRangeForType(TypeIndex TI) {
if (PartialOffsets.empty())
return fullScanForType(TI);
- auto Next = std::upper_bound(PartialOffsets.begin(), PartialOffsets.end(), TI,
- [](TypeIndex Value, const TypeIndexOffset &IO) {
- return Value < IO.Type;
- });
+ auto Next = llvm::upper_bound(PartialOffsets, TI,
+ [](TypeIndex Value, const TypeIndexOffset &IO) {
+ return Value < IO.Type;
+ });
assert(Next != PartialOffsets.begin());
auto Prev = std::prev(Next);
@@ -185,7 +185,7 @@ Error LazyRandomTypeCollection::visitRangeForType(TypeIndex TI) {
// They've asked us to fetch a type index, but the entry we found in the
// partial offsets array has already been visited. Since we visit an entire
// block every time, that means this record should have been previously
- // discovered. Ultimately, this means this is a request for a non-existant
+ // discovered. Ultimately, this means this is a request for a non-existent
// type index.
return make_error<CodeViewError>("Invalid type index");
}
diff --git a/llvm/lib/DebugInfo/CodeView/RecordName.cpp b/llvm/lib/DebugInfo/CodeView/RecordName.cpp
index 47b5498181b7..1ca899789bef 100644
--- a/llvm/lib/DebugInfo/CodeView/RecordName.cpp
+++ b/llvm/lib/DebugInfo/CodeView/RecordName.cpp
@@ -9,6 +9,7 @@
#include "llvm/DebugInfo/CodeView/RecordName.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
@@ -77,9 +78,10 @@ Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArgListRecord &Args) {
uint32_t Size = Indices.size();
Name = "(";
for (uint32_t I = 0; I < Size; ++I) {
- assert(Indices[I] < CurrentTypeIndex);
-
- Name.append(Types.getTypeName(Indices[I]));
+ if (Indices[I] < CurrentTypeIndex)
+ Name.append(Types.getTypeName(Indices[I]));
+ else
+ Name.append("<unknown 0x" + utohexstr(Indices[I].getIndex()) + ">");
if (I + 1 != Size)
Name.append(", ");
}
diff --git a/llvm/lib/DebugInfo/CodeView/RecordSerialization.cpp b/llvm/lib/DebugInfo/CodeView/RecordSerialization.cpp
index e7f032f9c670..63ce302a4e09 100644
--- a/llvm/lib/DebugInfo/CodeView/RecordSerialization.cpp
+++ b/llvm/lib/DebugInfo/CodeView/RecordSerialization.cpp
@@ -34,7 +34,7 @@ StringRef llvm::codeview::getBytesAsCString(ArrayRef<uint8_t> LeafData) {
}
Error llvm::codeview::consume(BinaryStreamReader &Reader, APSInt &Num) {
- // Used to avoid overload ambiguity on APInt construtor.
+ // Used to avoid overload ambiguity on APInt constructor.
bool FalseVal = false;
uint16_t Short;
if (auto EC = Reader.readInteger(Short))
diff --git a/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp b/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
index e84e1c9cea78..682747a2b81f 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
@@ -5,8 +5,9 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
+#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Endian.h"
diff --git a/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp b/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
index bb71c86a0609..7ac376156146 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
@@ -232,7 +232,7 @@ Error TypeRecordMapping::visitMemberBegin(CVMemberRecord &Record) {
// The largest possible subrecord is one in which there is a record prefix,
// followed by the subrecord, followed by a continuation, and that entire
- // sequence spaws `MaxRecordLength` bytes. So the record's length is
+ // sequence spawns `MaxRecordLength` bytes. So the record's length is
// calculated as follows.
constexpr uint32_t ContinuationLength = 8;
diff --git a/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp b/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
index 8c4b640bcd19..587a68142a4a 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
@@ -38,7 +38,7 @@ namespace {
/// 0x1000.
///
/// Type records are only allowed to use type indices smaller than their own, so
-/// a type stream is effectively a topologically sorted DAG. Cycles occuring in
+/// a type stream is effectively a topologically sorted DAG. Cycles occurring in
/// the type graph of the source program are resolved with forward declarations
/// of composite types. This class implements the following type stream merging
/// algorithm, which relies on this DAG structure:
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp b/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
index ddf307de2221..25d2e852a7fe 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
@@ -18,8 +18,9 @@ void DWARFAddressRange::dump(raw_ostream &OS, uint32_t AddressSize,
const DWARFObject *Obj) const {
OS << (DumpOpts.DisplayRawContents ? " " : "[");
- OS << format("0x%*.*" PRIx64 ", ", AddressSize * 2, AddressSize * 2, LowPC)
- << format("0x%*.*" PRIx64, AddressSize * 2, AddressSize * 2, HighPC);
+ DWARFFormValue::dumpAddress(OS, AddressSize, LowPC);
+ OS << ", ";
+ DWARFFormValue::dumpAddress(OS, AddressSize, HighPC);
OS << (DumpOpts.DisplayRawContents ? "" : ")");
if (Obj)
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
index 9bd134105c9b..2b08120ef4dc 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
@@ -22,9 +22,10 @@ void DWARFCompileUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
<< ", version = " << format("0x%04x", getVersion());
if (getVersion() >= 5)
OS << ", unit_type = " << dwarf::UnitTypeString(getUnitType());
- OS << ", abbr_offset = "
- << format("0x%04" PRIx64, getAbbreviations()->getOffset())
- << ", addr_size = " << format("0x%02x", getAddressByteSize());
+ OS << ", abbr_offset = " << format("0x%04" PRIx64, getAbbrOffset());
+ if (!getAbbreviations())
+ OS << " (invalid)";
+ OS << ", addr_size = " << format("0x%02x", getAddressByteSize());
if (getVersion() >= 5 && getUnitType() != dwarf::DW_UT_compile)
OS << ", DWO_id = " << format("0x%016" PRIx64, *getDWOId());
OS << " (next unit at " << format("0x%08" PRIx64, getNextUnitOffset())
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index bf6219497770..749d738af9c1 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -255,7 +255,7 @@ static void dumpRnglistsSection(
break;
Offset = TableOffset + Length;
} else {
- Rnglists.dump(OS, LookupPooledAddress, DumpOpts);
+ Rnglists.dump(rnglistData, OS, LookupPooledAddress, DumpOpts);
}
}
}
@@ -316,7 +316,7 @@ static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
return;
}
- Header.dump(OS, DumpOpts);
+ Header.dump(Data, OS, DumpOpts);
uint64_t EndOffset = Header.length() + Header.getHeaderOffset();
Data.setAddressSize(Header.getAddrSize());
@@ -457,7 +457,7 @@ void DWARFContext::dump(
shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
DObj->getFrameSection().Data)) {
if (Expected<const DWARFDebugFrame *> DF = getDebugFrame())
- (*DF)->dump(OS, getRegisterInfo(), *Off);
+ (*DF)->dump(OS, DumpOpts, getRegisterInfo(), *Off);
else
RecoverableErrorHandler(DF.takeError());
}
@@ -466,7 +466,7 @@ void DWARFContext::dump(
shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
DObj->getEHFrameSection().Data)) {
if (Expected<const DWARFDebugFrame *> DF = getEHFrame())
- (*DF)->dump(OS, getRegisterInfo(), *Off);
+ (*DF)->dump(OS, DumpOpts, getRegisterInfo(), *Off);
else
RecoverableErrorHandler(DF.takeError());
}
@@ -502,7 +502,8 @@ void DWARFContext::dump(
0);
DWARFDebugArangeSet set;
while (arangesData.isValidOffset(offset)) {
- if (Error E = set.extract(arangesData, &offset)) {
+ if (Error E =
+ set.extract(arangesData, &offset, DumpOpts.WarningHandler)) {
RecoverableErrorHandler(std::move(E));
break;
}
@@ -525,12 +526,29 @@ void DWARFContext::dump(
}
};
+ auto DumpStrSection = [&](StringRef Section) {
+ DataExtractor StrData(Section, isLittleEndian(), 0);
+ uint64_t Offset = 0;
+ uint64_t StrOffset = 0;
+ while (StrData.isValidOffset(Offset)) {
+ Error Err = Error::success();
+ const char *CStr = StrData.getCStr(&Offset, &Err);
+ if (Err) {
+ DumpOpts.WarningHandler(std::move(Err));
+ return;
+ }
+ OS << format("0x%8.8" PRIx64 ": \"", StrOffset);
+ OS.write_escaped(CStr);
+ OS << "\"\n";
+ StrOffset = Offset;
+ }
+ };
+
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_units());
+ DWARFDebugLine::SectionParser Parser(LineData, *this, normal_units());
DumpLineSection(Parser, DumpOpts, *Off);
}
@@ -539,8 +557,7 @@ void DWARFContext::dump(
DObj->getLineDWOSection().Data)) {
DWARFDataExtractor LineData(*DObj, DObj->getLineDWOSection(),
isLittleEndian(), 0);
- DWARFDebugLine::SectionParser Parser(LineData, *this, dwo_compile_units(),
- dwo_type_units());
+ DWARFDebugLine::SectionParser Parser(LineData, *this, dwo_units());
DumpLineSection(Parser, DumpOpts, *Off);
}
@@ -555,37 +572,16 @@ void DWARFContext::dump(
}
if (shouldDump(Explicit, ".debug_str", DIDT_ID_DebugStr,
- DObj->getStrSection())) {
- DataExtractor strData(DObj->getStrSection(), isLittleEndian(), 0);
- uint64_t offset = 0;
- uint64_t strOffset = 0;
- while (const char *s = strData.getCStr(&offset)) {
- OS << format("0x%8.8" PRIx64 ": \"%s\"\n", strOffset, s);
- strOffset = offset;
- }
- }
+ DObj->getStrSection()))
+ DumpStrSection(DObj->getStrSection());
+
if (shouldDump(ExplicitDWO, ".debug_str.dwo", DIDT_ID_DebugStr,
- DObj->getStrDWOSection())) {
- DataExtractor strDWOData(DObj->getStrDWOSection(), isLittleEndian(), 0);
- uint64_t offset = 0;
- uint64_t strDWOOffset = 0;
- while (const char *s = strDWOData.getCStr(&offset)) {
- OS << format("0x%8.8" PRIx64 ": \"%s\"\n", strDWOOffset, s);
- strDWOOffset = offset;
- }
- }
+ DObj->getStrDWOSection()))
+ DumpStrSection(DObj->getStrDWOSection());
+
if (shouldDump(Explicit, ".debug_line_str", DIDT_ID_DebugLineStr,
- DObj->getLineStrSection())) {
- DataExtractor strData(DObj->getLineStrSection(), isLittleEndian(), 0);
- uint64_t offset = 0;
- uint64_t strOffset = 0;
- while (const char *s = strData.getCStr(&offset)) {
- OS << format("0x%8.8" PRIx64 ": \"", strOffset);
- OS.write_escaped(s);
- OS << "\"\n";
- strOffset = offset;
- }
- }
+ DObj->getLineStrSection()))
+ DumpStrSection(DObj->getLineStrSection());
if (shouldDump(Explicit, ".debug_addr", DIDT_ID_DebugAddr,
DObj->getAddrSection().Data)) {
@@ -1038,7 +1034,9 @@ DWARFContext::DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address) {
static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU,
uint64_t Address,
FunctionNameKind Kind,
+ DILineInfoSpecifier::FileLineInfoKind FileNameKind,
std::string &FunctionName,
+ std::string &StartFile,
uint32_t &StartLine) {
// The address may correspond to instruction in some inlined function,
// so we have to build the chain of inlined functions and take the
@@ -1055,6 +1053,11 @@ static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU,
FunctionName = Name;
FoundResult = true;
}
+ std::string DeclFile = DIE.getDeclFile(FileNameKind);
+ if (!DeclFile.empty()) {
+ StartFile = DeclFile;
+ FoundResult = true;
+ }
if (auto DeclLineResult = DIE.getDeclLine()) {
StartLine = DeclLineResult;
FoundResult = true;
@@ -1226,8 +1229,9 @@ DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address,
if (!CU)
return Result;
- getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind,
- Result.FunctionName, Result.StartLine);
+ getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind, Spec.FLIKind,
+ Result.FunctionName,
+ Result.StartFileName, Result.StartLine);
if (Spec.FLIKind != FileLineInfoKind::None) {
if (const DWARFLineTable *LineTable = getLineTableForUnit(CU)) {
LineTable->getFileLineInfoForAddress(
@@ -1246,15 +1250,17 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange(
return Lines;
uint32_t StartLine = 0;
+ std::string StartFileName;
std::string FunctionName(DILineInfo::BadString);
- getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind,
- FunctionName, StartLine);
+ getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind, Spec.FLIKind,
+ FunctionName, StartFileName, StartLine);
// If the Specifier says we don't need FileLineInfo, just
// return the top-most function at the starting address.
if (Spec.FLIKind == FileLineInfoKind::None) {
DILineInfo Result;
Result.FunctionName = FunctionName;
+ Result.StartFileName = StartFileName;
Result.StartLine = StartLine;
Lines.push_back(std::make_pair(Address.Address, Result));
return Lines;
@@ -1278,6 +1284,7 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange(
Result.FunctionName = FunctionName;
Result.Line = Row.Line;
Result.Column = Row.Column;
+ Result.StartFileName = StartFileName;
Result.StartLine = StartLine;
Lines.push_back(std::make_pair(Row.Address.Address, Result));
}
@@ -1320,6 +1327,7 @@ DWARFContext::getInliningInfoForAddress(object::SectionedAddress Address,
Frame.FunctionName = Name;
if (auto DeclLineResult = FunctionDIE.getDeclLine())
Frame.StartLine = DeclLineResult;
+ Frame.StartFileName = FunctionDIE.getDeclFile(Spec.FLIKind);
if (Spec.FLIKind != FileLineInfoKind::None) {
if (i == 0) {
// For the topmost frame, initialize the line table of this
@@ -1701,16 +1709,17 @@ public:
// FIXME: Use the other dwo range section when we emit it.
RangesDWOSection.Data = Data;
}
- } else if (Name == "debug_info") {
+ } else if (InfoSectionMap *Sections =
+ StringSwitch<InfoSectionMap *>(Name)
+ .Case("debug_info", &InfoSections)
+ .Case("debug_info.dwo", &InfoDWOSections)
+ .Case("debug_types", &TypesSections)
+ .Case("debug_types.dwo", &TypesDWOSections)
+ .Default(nullptr)) {
// 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") {
- TypesSections[Section].Data = Data;
- } else if (Name == "debug_types.dwo") {
- TypesDWOSections[Section].Data = Data;
+ DWARFSectionMap &S = (*Sections)[Section];
+ S.Data = Data;
}
if (RelocatedSection == Obj.section_end())
@@ -1771,7 +1780,7 @@ public:
// Symbol to [address, section index] cache mapping.
std::map<SymbolRef, SymInfo> AddrCache;
- bool (*Supports)(uint64_t);
+ SupportsRelocation Supports;
RelocationResolver Resolver;
std::tie(Supports, Resolver) = getRelocationResolver(Obj);
for (const RelocationRef &Reloc : Section.relocations()) {
@@ -1989,6 +1998,6 @@ uint8_t DWARFContext::getCUAddrSize() {
// first compile unit. In practice the address size field is repeated across
// various DWARF headers (at least in version 5) to make it easier to dump
// them independently, not to enable varying the address size.
- unit_iterator_range CUs = compile_units();
+ auto CUs = compile_units();
return CUs.empty() ? 0 : (*CUs.begin())->getAddressByteSize();
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
index 886fe1dff976..da6f6ad903f4 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
@@ -53,14 +53,16 @@ uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint64_t *Off,
ErrorAsOutParameter ErrAsOut(Err);
Optional<RelocAddrEntry> E = Obj->find(*Section, *Off);
- uint64_t A = getUnsigned(Off, Size, Err);
+ uint64_t LocData = getUnsigned(Off, Size, Err);
if (!E || (Err && *Err))
- return A;
+ return LocData;
if (SecNdx)
*SecNdx = E->SectionIndex;
- uint64_t R = E->Resolver(E->Reloc, E->SymbolValue, A);
+
+ uint64_t R =
+ object::resolveRelocation(E->Resolver, E->Reloc, E->SymbolValue, LocData);
if (E->Reloc2)
- R = E->Resolver(*E->Reloc2, E->SymbolValue2, R);
+ R = object::resolveRelocation(E->Resolver, *E->Reloc2, E->SymbolValue2, R);
return R;
}
@@ -104,10 +106,10 @@ DWARFDataExtractor::getEncodedPointer(uint64_t *Offset, uint8_t Encoding,
Result = getSigned(Offset, 2);
break;
case dwarf::DW_EH_PE_sdata4:
- Result = getSigned(Offset, 4);
+ Result = SignExtend64<32>(getRelocatedValue(4, Offset));
break;
case dwarf::DW_EH_PE_sdata8:
- Result = getSigned(Offset, 8);
+ Result = getRelocatedValue(8, Offset);
break;
default:
return None;
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp
index 608fc0388af0..598e3ecee30e 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp
@@ -8,6 +8,7 @@
#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
@@ -20,9 +21,11 @@ using namespace llvm;
void DWARFDebugArangeSet::Descriptor::dump(raw_ostream &OS,
uint32_t AddressSize) const {
- OS << format("[0x%*.*" PRIx64 ", ", AddressSize * 2, AddressSize * 2, Address)
- << format(" 0x%*.*" PRIx64 ")", AddressSize * 2, AddressSize * 2,
- getEndAddress());
+ OS << '[';
+ DWARFFormValue::dumpAddress(OS, AddressSize, Address);
+ OS << ", ";
+ DWARFFormValue::dumpAddress(OS, AddressSize, getEndAddress());
+ OS << ')';
}
void DWARFDebugArangeSet::clear() {
@@ -32,7 +35,8 @@ void DWARFDebugArangeSet::clear() {
}
Error DWARFDebugArangeSet::extract(DWARFDataExtractor data,
- uint64_t *offset_ptr) {
+ uint64_t *offset_ptr,
+ function_ref<void(Error)> WarningHandler) {
assert(data.isValidOffset(*offset_ptr));
ArangeDescriptors.clear();
Offset = *offset_ptr;
@@ -132,19 +136,20 @@ Error DWARFDebugArangeSet::extract(DWARFDataExtractor data,
uint64_t end_offset = Offset + full_length;
while (*offset_ptr < end_offset) {
+ uint64_t EntryOffset = *offset_ptr;
arangeDescriptor.Address = data.getUnsigned(offset_ptr, HeaderData.AddrSize);
arangeDescriptor.Length = data.getUnsigned(offset_ptr, HeaderData.AddrSize);
- if (arangeDescriptor.Length == 0) {
- // Each set of tuples is terminated by a 0 for the address and 0
- // for the length.
- if (arangeDescriptor.Address == 0 && *offset_ptr == end_offset)
+ // Each set of tuples is terminated by a 0 for the address and 0
+ // for the length.
+ if (arangeDescriptor.Length == 0 && arangeDescriptor.Address == 0) {
+ if (*offset_ptr == end_offset)
return ErrorSuccess();
- return createStringError(
+ WarningHandler(createStringError(
errc::invalid_argument,
"address range table at offset 0x%" PRIx64
- " has an invalid tuple (length = 0) at offset 0x%" PRIx64,
- Offset, *offset_ptr - tuple_size);
+ " has a premature terminator entry at offset 0x%" PRIx64,
+ Offset, EntryOffset));
}
ArangeDescriptors.push_back(arangeDescriptor);
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
index e8ed63075055..e0db469752cd 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
@@ -28,7 +28,8 @@ void DWARFDebugAranges::extract(
DWARFDebugArangeSet Set;
while (DebugArangesData.isValidOffset(Offset)) {
- if (Error E = Set.extract(DebugArangesData, &Offset)) {
+ if (Error E =
+ Set.extract(DebugArangesData, &Offset, RecoverableErrorHandler)) {
RecoverableErrorHandler(std::move(E));
return;
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
index 0a1b75592290..b74ecac681f3 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
@@ -12,6 +12,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataExtractor.h"
@@ -29,6 +30,18 @@
using namespace llvm;
using namespace dwarf;
+static void printRegister(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
+ unsigned RegNum) {
+ if (MRI) {
+ if (Optional<unsigned> LLVMRegNum = MRI->getLLVMRegNum(RegNum, IsEH)) {
+ if (const char *RegName = MRI->getName(*LLVMRegNum)) {
+ OS << RegName;
+ return;
+ }
+ }
+ }
+ OS << "reg" << RegNum;
+}
// See DWARF standard v3, section 7.23
const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
@@ -221,9 +234,10 @@ ArrayRef<CFIProgram::OperandType[2]> CFIProgram::getOperandTypes() {
}
/// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.
-void CFIProgram::printOperand(raw_ostream &OS, const MCRegisterInfo *MRI,
- bool IsEH, const Instruction &Instr,
- unsigned OperandIdx, uint64_t Operand) const {
+void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
+ const MCRegisterInfo *MRI, bool IsEH,
+ const Instruction &Instr, unsigned OperandIdx,
+ uint64_t Operand) const {
assert(OperandIdx < 2);
uint8_t Opcode = Instr.Opcode;
OperandType Type = getOperandTypes()[Opcode][OperandIdx];
@@ -268,17 +282,19 @@ void CFIProgram::printOperand(raw_ostream &OS, const MCRegisterInfo *MRI,
OS << format(" %" PRId64 "*data_alignment_factor" , Operand);
break;
case OT_Register:
- OS << format(" reg%" PRId64, Operand);
+ OS << ' ';
+ printRegister(OS, MRI, IsEH, Operand);
break;
case OT_Expression:
assert(Instr.Expression && "missing DWARFExpression object");
OS << " ";
- Instr.Expression->print(OS, MRI, nullptr, IsEH);
+ Instr.Expression->print(OS, DumpOpts, MRI, nullptr, IsEH);
break;
}
}
-void CFIProgram::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
+void CFIProgram::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
+ const MCRegisterInfo *MRI, bool IsEH,
unsigned IndentLevel) const {
for (const auto &Instr : Instructions) {
uint8_t Opcode = Instr.Opcode;
@@ -287,7 +303,7 @@ void CFIProgram::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
OS.indent(2 * IndentLevel);
OS << CallFrameString(Opcode, Arch) << ":";
for (unsigned i = 0; i < Instr.Ops.size(); ++i)
- printOperand(OS, MRI, IsEH, Instr, i, Instr.Ops[i]);
+ printOperand(OS, DumpOpts, MRI, IsEH, Instr, i, Instr.Ops[i]);
OS << '\n';
}
}
@@ -304,7 +320,8 @@ constexpr uint64_t getCIEId(bool IsDWARF64, bool IsEH) {
return DW_CIE_ID;
}
-void CIE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const {
+void CIE::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
+ const MCRegisterInfo *MRI, bool IsEH) const {
// A CIE with a zero length is a terminator entry in the .eh_frame section.
if (IsEH && Length == 0) {
OS << format("%08" PRIx64, Offset) << " ZERO terminator\n";
@@ -336,11 +353,12 @@ void CIE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const {
OS << "\n";
}
OS << "\n";
- CFIs.dump(OS, MRI, IsEH);
+ CFIs.dump(OS, DumpOpts, MRI, IsEH);
OS << "\n";
}
-void FDE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const {
+void FDE::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
+ const MCRegisterInfo *MRI, bool IsEH) const {
OS << format("%08" PRIx64, Offset)
<< format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length)
<< format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8, CIEPointer)
@@ -354,7 +372,7 @@ void FDE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const {
OS << " Format: " << FormatString(IsDWARF64) << "\n";
if (LSDAAddress)
OS << format(" LSDA Address: %016" PRIx64 "\n", *LSDAAddress);
- CFIs.dump(OS, MRI, IsEH);
+ CFIs.dump(OS, DumpOpts, MRI, IsEH);
OS << "\n";
}
@@ -521,9 +539,9 @@ Error DWARFDebugFrame::parse(DWARFDataExtractor Data) {
"parsing FDE data at 0x%" PRIx64
" failed due to missing CIE",
StartOffset);
- if (auto Val = Data.getEncodedPointer(
- &Offset, Cie->getFDEPointerEncoding(),
- EHFrameAddress ? EHFrameAddress + Offset : 0)) {
+ if (auto Val =
+ Data.getEncodedPointer(&Offset, Cie->getFDEPointerEncoding(),
+ EHFrameAddress + Offset)) {
InitialLocation = *Val;
}
if (auto Val = Data.getEncodedPointer(
@@ -583,15 +601,16 @@ FrameEntry *DWARFDebugFrame::getEntryAtOffset(uint64_t Offset) const {
return nullptr;
}
-void DWARFDebugFrame::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
+void DWARFDebugFrame::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
+ const MCRegisterInfo *MRI,
Optional<uint64_t> Offset) const {
if (Offset) {
if (auto *Entry = getEntryAtOffset(*Offset))
- Entry->dump(OS, MRI, IsEH);
+ Entry->dump(OS, DumpOpts, MRI, IsEH);
return;
}
OS << "\n";
for (const auto &Entry : Entries)
- Entry->dump(OS, MRI, IsEH);
+ Entry->dump(OS, DumpOpts, MRI, IsEH);
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
index 87eab34d58ee..2b7d0c3363a1 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
@@ -38,7 +38,8 @@ bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U, uint64_t *OffsetPtr,
AbbrevDecl = nullptr;
return true;
}
- AbbrevDecl = U.getAbbreviations()->getAbbreviationDeclaration(AbbrCode);
+ if (const auto *AbbrevSet = U.getAbbreviations())
+ AbbrevDecl = AbbrevSet->getAbbreviationDeclaration(AbbrCode);
if (nullptr == AbbrevDecl) {
// Restore the original offset.
*OffsetPtr = Offset;
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index 3ca21e97888c..bda41b1f34e9 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -79,6 +79,18 @@ bool DWARFDebugLine::Prologue::hasFileAtIndex(uint64_t FileIndex) const {
return FileIndex != 0 && FileIndex <= FileNames.size();
}
+Optional<uint64_t> DWARFDebugLine::Prologue::getLastValidFileIndex() const {
+ if (FileNames.empty())
+ return None;
+ uint16_t DwarfVersion = getVersion();
+ assert(DwarfVersion != 0 &&
+ "line table prologue has no dwarf version information");
+ // In DWARF v5 the file names are 0-indexed.
+ if (DwarfVersion >= 5)
+ return FileNames.size() - 1;
+ return FileNames.size();
+}
+
const llvm::DWARFDebugLine::FileNameEntry &
DWARFDebugLine::Prologue::getFileNameEntry(uint64_t Index) const {
uint16_t DwarfVersion = getVersion();
@@ -771,6 +783,18 @@ Error DWARFDebugLine::LineTable::parse(
*OS << '\n';
Row::dumpTableHeader(*OS, /*Indent=*/Verbose ? 12 : 0);
}
+ bool TombstonedAddress = false;
+ auto EmitRow = [&] {
+ if (!TombstonedAddress) {
+ if (Verbose) {
+ *OS << "\n";
+ OS->indent(12);
+ }
+ if (OS)
+ State.Row.dump(*OS);
+ State.appendRowToMatrix();
+ }
+ };
while (*OffsetPtr < EndOffset) {
DataExtractor::Cursor Cursor(*OffsetPtr);
@@ -822,13 +846,7 @@ Error DWARFDebugLine::LineTable::parse(
// No need to test the Cursor is valid here, since it must be to get
// into this code path - if it were invalid, the default case would be
// followed.
- if (Verbose) {
- *OS << "\n";
- OS->indent(12);
- }
- if (OS)
- State.Row.dump(*OS);
- State.appendRowToMatrix();
+ EmitRow();
State.resetRowAndSequence();
break;
@@ -870,13 +888,20 @@ Error DWARFDebugLine::LineTable::parse(
State.Row.Address.Address = TableData.getRelocatedAddress(
Cursor, &State.Row.Address.SectionIndex);
+ uint64_t Tombstone =
+ dwarf::computeTombstoneAddress(OpcodeAddressSize);
+ TombstonedAddress = State.Row.Address.Address == Tombstone;
+
// Restore the address size if the extractor already had it.
if (ExtractorAddressSize != 0)
TableData.setAddressSize(ExtractorAddressSize);
}
- if (Cursor && Verbose)
- *OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address.Address);
+ if (Cursor && Verbose) {
+ *OS << " (";
+ DWARFFormValue::dumpAddress(*OS, OpcodeAddressSize, State.Row.Address.Address);
+ *OS << ')';
+ }
}
break;
@@ -969,13 +994,7 @@ Error DWARFDebugLine::LineTable::parse(
case DW_LNS_copy:
// Takes no arguments. Append a row to the matrix using the
// current values of the state-machine registers.
- if (Verbose) {
- *OS << "\n";
- OS->indent(12);
- }
- if (OS)
- State.Row.dump(*OS);
- State.appendRowToMatrix();
+ EmitRow();
break;
case DW_LNS_advance_pc:
@@ -1140,15 +1159,9 @@ Error DWARFDebugLine::LineTable::parse(
ParsingState::AddrAndLineDelta Delta =
State.handleSpecialOpcode(Opcode, OpcodeOffset);
- if (Verbose) {
- *OS << "address += " << Delta.Address << ", line += " << Delta.Line
- << "\n";
- OS->indent(12);
- }
- if (OS)
- State.Row.dump(*OS);
-
- State.appendRowToMatrix();
+ if (Verbose)
+ *OS << "address += " << Delta.Address << ", line += " << Delta.Line;
+ EmitRow();
*OffsetPtr = Cursor.tell();
}
@@ -1406,25 +1419,20 @@ bool DWARFDebugLine::LineTable::getFileLineInfoForAddress(
// Therefore, collect up handles on all the Units that point into the
// line-table section.
static DWARFDebugLine::SectionParser::LineToUnitMap
-buildLineToUnitMap(DWARFDebugLine::SectionParser::cu_range CUs,
- DWARFDebugLine::SectionParser::tu_range TUs) {
+buildLineToUnitMap(DWARFUnitVector::iterator_range Units) {
DWARFDebugLine::SectionParser::LineToUnitMap LineToUnit;
- for (const auto &CU : CUs)
- if (auto CUDIE = CU->getUnitDIE())
+ for (const auto &U : Units)
+ if (auto CUDIE = U->getUnitDIE())
if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list)))
- LineToUnit.insert(std::make_pair(*StmtOffset, &*CU));
- 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));
+ LineToUnit.insert(std::make_pair(*StmtOffset, &*U));
return LineToUnit;
}
-DWARFDebugLine::SectionParser::SectionParser(DWARFDataExtractor &Data,
- const DWARFContext &C,
- cu_range CUs, tu_range TUs)
+DWARFDebugLine::SectionParser::SectionParser(
+ DWARFDataExtractor &Data, const DWARFContext &C,
+ DWARFUnitVector::iterator_range Units)
: DebugLineData(Data), Context(C) {
- LineToUnit = buildLineToUnitMap(CUs, TUs);
+ LineToUnit = buildLineToUnitMap(Units);
if (!DebugLineData.isValidOffset(Offset))
Done = true;
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
index f38126364401..cdffb36741c8 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
@@ -106,15 +106,16 @@ DWARFLocationInterpreter::Interpret(const DWARFLocationEntry &E) {
}
}
-static void dumpExpression(raw_ostream &OS, ArrayRef<uint8_t> Data,
- bool IsLittleEndian, unsigned AddressSize,
- const MCRegisterInfo *MRI, DWARFUnit *U) {
+static void dumpExpression(raw_ostream &OS, DIDumpOptions DumpOpts,
+ ArrayRef<uint8_t> Data, bool IsLittleEndian,
+ unsigned AddressSize, const MCRegisterInfo *MRI,
+ DWARFUnit *U) {
DWARFDataExtractor Extractor(Data, IsLittleEndian, AddressSize);
// Note. We do not pass any format to DWARFExpression, even if the
// corresponding unit is known. For now, there is only one operation,
// DW_OP_call_ref, which depends on the format; it is rarely used, and
// is unexpected in location tables.
- DWARFExpression(Extractor, AddressSize).print(OS, MRI, U);
+ DWARFExpression(Extractor, AddressSize).print(OS, DumpOpts, MRI, U);
}
bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS,
@@ -154,8 +155,8 @@ bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS,
E.Kind != dwarf::DW_LLE_base_addressx &&
E.Kind != dwarf::DW_LLE_end_of_list) {
OS << ": ";
- dumpExpression(OS, E.Loc, Data.isLittleEndian(), Data.getAddressSize(),
- MRI, U);
+ dumpExpression(OS, DumpOpts, E.Loc, Data.isLittleEndian(),
+ Data.getAddressSize(), MRI, U);
}
return true;
});
@@ -259,7 +260,6 @@ void DWARFDebugLoc::dumpRawEntry(const DWARFLocationEntry &Entry,
Value1 = Entry.Value1;
break;
case dwarf::DW_LLE_end_of_list:
- Value0 = Value1 = 0;
return;
default:
llvm_unreachable("Not possible in DWARF4!");
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
index f920d69cc43f..80ffd81b3403 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
@@ -40,7 +40,7 @@ void DWARFDebugMacro::dump(raw_ostream &OS) const {
unsigned IndLevel = 0;
for (const auto &Macros : MacroLists) {
OS << format("0x%08" PRIx64 ":\n", Macros.Offset);
- if (Macros.Header.Version >= 5)
+ if (Macros.IsDebugMacro)
Macros.Header.dumpMacroHeader(OS);
for (const Entry &E : Macros.Macros) {
// There should not be DW_MACINFO_end_file when IndLevel is Zero. However,
@@ -52,8 +52,10 @@ void DWARFDebugMacro::dump(raw_ostream &OS) const {
OS << " ";
IndLevel += (E.Type == DW_MACINFO_start_file);
// Based on which version we are handling choose appropriate macro forms.
- if (Macros.Header.Version >= 5)
- WithColor(OS, HighlightColor::Macro).get() << MacroString(E.Type);
+ if (Macros.IsDebugMacro)
+ WithColor(OS, HighlightColor::Macro).get()
+ << (Macros.Header.Version < 5 ? GnuMacroString(E.Type)
+ : MacroString(E.Type));
else
WithColor(OS, HighlightColor::Macro).get() << MacinfoString(E.Type);
switch (E.Type) {
@@ -67,6 +69,9 @@ void DWARFDebugMacro::dump(raw_ostream &OS) const {
// DW_MACRO_start_file == DW_MACINFO_start_file
// DW_MACRO_end_file == DW_MACINFO_end_file
// For readability/uniformity we are using DW_MACRO_*.
+ //
+ // The GNU .debug_macro extension's entries have the same encoding
+ // as DWARF 5's DW_MACRO_* entries, so we only use the latter here.
case DW_MACRO_define:
case DW_MACRO_undef:
case DW_MACRO_define_strp:
@@ -97,7 +102,7 @@ void DWARFDebugMacro::dump(raw_ostream &OS) const {
}
Error DWARFDebugMacro::parseImpl(
- Optional<DWARFUnitVector::iterator_range> Units,
+ Optional<DWARFUnitVector::compile_unit_range> Units,
Optional<DataExtractor> StringExtractor, DWARFDataExtractor Data,
bool IsMacro) {
uint64_t Offset = 0;
@@ -118,6 +123,7 @@ Error DWARFDebugMacro::parseImpl(
MacroLists.emplace_back();
M = &MacroLists.back();
M->Offset = Offset;
+ M->IsDebugMacro = IsMacro;
if (IsMacro) {
auto Err = M->Header.parseMacroHeader(Data, &Offset);
if (Err)
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
index 1a1857d8cd79..dc7da5d9348f 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
@@ -70,6 +70,9 @@ void DWARFDebugRangeList::dump(raw_ostream &OS) const {
DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges(
llvm::Optional<object::SectionedAddress> BaseAddr) const {
DWARFAddressRangesVector Res;
+ // debug_addr can't use the max integer tombstone because that's used for the
+ // base address specifier entry - so use max-1.
+ uint64_t Tombstone = dwarf::computeTombstoneAddress(AddressSize) - 1;
for (const RangeListEntry &RLE : Entries) {
if (RLE.isBaseAddressSelectionEntry(AddressSize)) {
BaseAddr = {RLE.EndAddress, RLE.SectionIndex};
@@ -78,12 +81,16 @@ DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges(
DWARFAddressRange E;
E.LowPC = RLE.StartAddress;
+ if (E.LowPC == Tombstone)
+ continue;
E.HighPC = RLE.EndAddress;
E.SectionIndex = RLE.SectionIndex;
// Base address of a range list entry is determined by the closest preceding
// base address selection entry in the same range list. It defaults to the
// base address of the compilation unit if there is no such entry.
if (BaseAddr) {
+ if (BaseAddr->Address == Tombstone)
+ continue;
E.LowPC += BaseAddr->Address;
E.HighPC += BaseAddr->Address;
if (E.SectionIndex == -1ULL)
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
index 9ae4c5b73ebe..d12acca1962e 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
@@ -8,6 +8,7 @@
#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"
@@ -16,114 +17,87 @@
using namespace llvm;
-Error RangeListEntry::extract(DWARFDataExtractor Data, uint64_t End,
- uint64_t *OffsetPtr) {
+Error RangeListEntry::extract(DWARFDataExtractor Data, uint64_t *OffsetPtr) {
Offset = *OffsetPtr;
SectionIndex = -1ULL;
// The caller should guarantee that we have at least 1 byte available, so
// we just assert instead of revalidate.
- assert(*OffsetPtr < End &&
+ assert(*OffsetPtr < Data.size() &&
"not enough space to extract a rangelist encoding");
uint8_t Encoding = Data.getU8(OffsetPtr);
+ DataExtractor::Cursor C(*OffsetPtr);
switch (Encoding) {
case dwarf::DW_RLE_end_of_list:
Value0 = Value1 = 0;
break;
// TODO: Support other encodings.
case dwarf::DW_RLE_base_addressx: {
- uint64_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%" PRIx64,
- PreviousOffset);
+ Value0 = Data.getULEB128(C);
break;
}
case dwarf::DW_RLE_startx_endx:
- return createStringError(errc::not_supported,
- "unsupported rnglists encoding DW_RLE_startx_endx at "
- "offset 0x%" PRIx64,
- *OffsetPtr - 1);
+ Value0 = Data.getULEB128(C);
+ Value1 = Data.getULEB128(C);
+ break;
case dwarf::DW_RLE_startx_length: {
- uint64_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%" PRIx64,
- PreviousOffset);
+ Value0 = Data.getULEB128(C);
+ Value1 = Data.getULEB128(C);
break;
}
case dwarf::DW_RLE_offset_pair: {
- uint64_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_offset_pair encoding at offset 0x%" PRIx64,
- PreviousOffset);
+ Value0 = Data.getULEB128(C);
+ Value1 = Data.getULEB128(C);
break;
}
case dwarf::DW_RLE_base_address: {
- if ((End - *OffsetPtr) < Data.getAddressSize())
- return createStringError(errc::invalid_argument,
- "insufficient space remaining in table for "
- "DW_RLE_base_address encoding at offset 0x%" PRIx64,
- *OffsetPtr - 1);
- Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex);
+ Value0 = Data.getRelocatedAddress(C, &SectionIndex);
break;
}
case dwarf::DW_RLE_start_end: {
- if ((End - *OffsetPtr) < unsigned(Data.getAddressSize() * 2))
- return createStringError(errc::invalid_argument,
- "insufficient space remaining in table for "
- "DW_RLE_start_end encoding "
- "at offset 0x%" PRIx64,
- *OffsetPtr - 1);
- Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex);
- Value1 = Data.getRelocatedAddress(OffsetPtr);
+ Value0 = Data.getRelocatedAddress(C, &SectionIndex);
+ Value1 = Data.getRelocatedAddress(C);
break;
}
case dwarf::DW_RLE_start_length: {
- uint64_t PreviousOffset = *OffsetPtr - 1;
- Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex);
- Value1 = Data.getULEB128(OffsetPtr);
- if (End < *OffsetPtr)
- return createStringError(errc::invalid_argument,
- "read past end of table when reading "
- "DW_RLE_start_length encoding at offset 0x%" PRIx64,
- PreviousOffset);
+ Value0 = Data.getRelocatedAddress(C, &SectionIndex);
+ Value1 = Data.getULEB128(C);
break;
}
default:
+ consumeError(C.takeError());
return createStringError(errc::not_supported,
- "unknown rnglists encoding 0x%" PRIx32
- " at offset 0x%" PRIx64,
- uint32_t(Encoding), *OffsetPtr - 1);
+ "unknown rnglists encoding 0x%" PRIx32
+ " at offset 0x%" PRIx64,
+ uint32_t(Encoding), Offset);
+ }
+
+ if (!C) {
+ consumeError(C.takeError());
+ return createStringError(
+ errc::invalid_argument,
+ "read past end of table when reading %s encoding at offset 0x%" PRIx64,
+ dwarf::RLEString(Encoding).data(), Offset);
}
+ *OffsetPtr = C.tell();
EntryKind = Encoding;
return Error::success();
}
DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
llvm::Optional<object::SectionedAddress> BaseAddr, DWARFUnit &U) const {
- return getAbsoluteRanges(BaseAddr, [&](uint32_t Index) {
- return U.getAddrOffsetSectionItem(Index);
- });
+ return getAbsoluteRanges(
+ BaseAddr, U.getAddressByteSize(),
+ [&](uint32_t Index) { return U.getAddrOffsetSectionItem(Index); });
}
DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
- Optional<object::SectionedAddress> BaseAddr,
+ Optional<object::SectionedAddress> BaseAddr, uint8_t AddressByteSize,
function_ref<Optional<object::SectionedAddress>(uint32_t)>
LookupPooledAddress) const {
DWARFAddressRangesVector Res;
+ uint64_t Tombstone = dwarf::computeTombstoneAddress(AddressByteSize);
for (const RangeListEntry &RLE : Entries) {
if (RLE.EntryKind == dwarf::DW_RLE_end_of_list)
break;
@@ -146,8 +120,12 @@ DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
switch (RLE.EntryKind) {
case dwarf::DW_RLE_offset_pair:
E.LowPC = RLE.Value0;
+ if (E.LowPC == Tombstone)
+ continue;
E.HighPC = RLE.Value1;
if (BaseAddr) {
+ if (BaseAddr->Address == Tombstone)
+ continue;
E.LowPC += BaseAddr->Address;
E.HighPC += BaseAddr->Address;
}
@@ -169,11 +147,26 @@ DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
E.HighPC = E.LowPC + RLE.Value1;
break;
}
+ case dwarf::DW_RLE_startx_endx: {
+ auto Start = LookupPooledAddress(RLE.Value0);
+ if (!Start)
+ Start = {0, -1ULL};
+ auto End = LookupPooledAddress(RLE.Value1);
+ if (!End)
+ End = {0, -1ULL};
+ // FIXME: Some error handling if Start.SectionIndex != End.SectionIndex
+ E.SectionIndex = Start->SectionIndex;
+ E.LowPC = Start->Address;
+ E.HighPC = End->Address;
+ break;
+ }
default:
// Unsupported encodings should have been reported during extraction,
// so we should not run into any here.
llvm_unreachable("Unsupported range list encoding");
}
+ if (E.LowPC == Tombstone)
+ continue;
Res.push_back(E);
}
return Res;
@@ -206,6 +199,8 @@ void RangeListEntry::dump(
OS << ": ";
}
+ uint64_t Tombstone = dwarf::computeTombstoneAddress(AddrSize);
+
switch (EntryKind) {
case dwarf::DW_RLE_end_of_list:
OS << (DumpOpts.Verbose ? "" : "<End of list>");
@@ -217,7 +212,7 @@ void RangeListEntry::dump(
CurrentBase = Value0;
if (!DumpOpts.Verbose)
return;
- OS << format(" 0x%*.*" PRIx64, AddrSize * 2, AddrSize * 2, Value0);
+ DWARFFormValue::dumpAddress(OS << ' ', AddrSize, Value0);
break;
}
case dwarf::DW_RLE_base_address:
@@ -225,7 +220,7 @@ void RangeListEntry::dump(
CurrentBase = Value0;
if (!DumpOpts.Verbose)
return;
- OS << format(" 0x%*.*" PRIx64, AddrSize * 2, AddrSize * 2, Value0);
+ DWARFFormValue::dumpAddress(OS << ' ', AddrSize, Value0);
break;
case dwarf::DW_RLE_start_length:
PrintRawEntry(OS, *this, AddrSize, DumpOpts);
@@ -233,8 +228,11 @@ void RangeListEntry::dump(
break;
case dwarf::DW_RLE_offset_pair:
PrintRawEntry(OS, *this, AddrSize, DumpOpts);
- DWARFAddressRange(Value0 + CurrentBase, Value1 + CurrentBase)
- .dump(OS, AddrSize, DumpOpts);
+ if (CurrentBase != Tombstone)
+ DWARFAddressRange(Value0 + CurrentBase, Value1 + CurrentBase)
+ .dump(OS, AddrSize, DumpOpts);
+ else
+ OS << "dead code";
break;
case dwarf::DW_RLE_start_end:
DWARFAddressRange(Value0, Value1).dump(OS, AddrSize, DumpOpts);
@@ -247,6 +245,17 @@ void RangeListEntry::dump(
DWARFAddressRange(Start, Start + Value1).dump(OS, AddrSize, DumpOpts);
break;
}
+ case dwarf::DW_RLE_startx_endx: {
+ PrintRawEntry(OS, *this, AddrSize, DumpOpts);
+ uint64_t Start = 0;
+ if (auto SA = LookupPooledAddress(Value0))
+ Start = SA->Address;
+ uint64_t End = 0;
+ if (auto SA = LookupPooledAddress(Value1))
+ End = SA->Address;
+ DWARFAddressRange(Start, End).dump(OS, AddrSize, DumpOpts);
+ break;
+ }
default:
llvm_unreachable("Unsupported range list encoding");
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index 81a6b5dcd5e7..427f6f4942c3 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -80,7 +80,7 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue,
DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()),
Ctx.isLittleEndian(), 0);
DWARFExpression(Data, U->getAddressByteSize(), U->getFormParams().Format)
- .print(OS, MRI, U);
+ .print(OS, DumpOpts, MRI, U);
return;
}
@@ -113,7 +113,6 @@ static void dumpTypeTagName(raw_ostream &OS, dwarf::Tag T) {
}
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;
@@ -269,13 +268,23 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
WithColor(OS, Color) << Name;
else if (Attr == DW_AT_decl_line || Attr == DW_AT_call_line)
OS << *FormValue.getAsUnsignedConstant();
- else if (Attr == DW_AT_high_pc && !DumpOpts.ShowForm && !DumpOpts.Verbose &&
- FormValue.getAsUnsignedConstant()) {
+ else if (Attr == DW_AT_low_pc &&
+ (FormValue.getAsAddress() ==
+ dwarf::computeTombstoneAddress(U->getAddressByteSize()))) {
+ if (DumpOpts.Verbose) {
+ FormValue.dump(OS, DumpOpts);
+ OS << " (";
+ }
+ OS << "dead code";
+ if (DumpOpts.Verbose)
+ OS << ')';
+ } else if (Attr == DW_AT_high_pc && !DumpOpts.ShowForm && !DumpOpts.Verbose &&
+ FormValue.getAsUnsignedConstant()) {
if (DumpOpts.ShowAddresses) {
// Print the actual address rather than the offset.
uint64_t LowPC, HighPC, Index;
if (Die.getLowAndHighPC(LowPC, HighPC, Index))
- OS << format("0x%016" PRIx64, HighPC);
+ DWARFFormValue::dumpAddress(OS, U->getAddressByteSize(), HighPC);
else
FormValue.dump(OS, DumpOpts);
}
@@ -368,8 +377,7 @@ DWARFDie::findRecursively(ArrayRef<dwarf::Attribute> Attrs) const {
Seen.insert(*this);
while (!Worklist.empty()) {
- DWARFDie Die = Worklist.back();
- Worklist.pop_back();
+ DWARFDie Die = Worklist.pop_back_val();
if (!Die.isValid())
continue;
@@ -416,6 +424,9 @@ Optional<uint64_t> DWARFDie::getLocBaseAttribute() const {
}
Optional<uint64_t> DWARFDie::getHighPC(uint64_t LowPC) const {
+ uint64_t Tombstone = dwarf::computeTombstoneAddress(U->getAddressByteSize());
+ if (LowPC == Tombstone)
+ return None;
if (auto FormValue = find(DW_AT_high_pc)) {
if (auto Address = FormValue->getAsAddress()) {
// High PC is an address.
@@ -467,8 +478,7 @@ void DWARFDie::collectChildrenAddressRanges(
return;
if (isSubprogramDIE()) {
if (auto DIERangesOrError = getAddressRanges())
- Ranges.insert(Ranges.end(), DIERangesOrError.get().begin(),
- DIERangesOrError.get().end());
+ llvm::append_range(Ranges, DIERangesOrError.get());
else
llvm::consumeError(DIERangesOrError.takeError());
}
@@ -558,6 +568,17 @@ uint64_t DWARFDie::getDeclLine() const {
return toUnsigned(findRecursively(DW_AT_decl_line), 0);
}
+std::string
+DWARFDie::getDeclFile(DILineInfoSpecifier::FileLineInfoKind Kind) const {
+ std::string FileName;
+ if (auto DeclFile = toUnsigned(findRecursively(DW_AT_decl_file))) {
+ if (const auto *LT = U->getContext().getLineTableForUnit(U)) {
+ LT->getFileNameByIndex(*DeclFile, U->getCompilationDir(), Kind, FileName);
+ }
+ }
+ return FileName;
+}
+
void DWARFDie::getCallerFrame(uint32_t &CallFile, uint32_t &CallLine,
uint32_t &CallColumn,
uint32_t &CallDiscriminator) const {
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
index de5e11e084f4..811716111be5 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
@@ -204,11 +204,15 @@ bool DWARFExpression::Operation::extract(DataExtractor Data,
}
static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS,
- uint64_t Operands[2], unsigned Operand) {
+ DIDumpOptions DumpOpts, uint64_t Operands[2],
+ unsigned Operand) {
assert(Operand < 2 && "operand out of bounds");
auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]);
if (Die && Die.getTag() == dwarf::DW_TAG_base_type) {
- OS << format(" (0x%08" PRIx64 ")", U->getOffset() + Operands[Operand]);
+ OS << " (";
+ if (DumpOpts.Verbose)
+ OS << format("0x%08" PRIx64 " -> ", Operands[Operand]);
+ OS << format("0x%08" PRIx64 ")", U->getOffset() + Operands[Operand]);
if (auto Name = Die.find(dwarf::DW_AT_name))
OS << " \"" << Name->getAsCString() << "\"";
} else {
@@ -217,7 +221,8 @@ static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS,
}
}
-static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, uint8_t Opcode,
+static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS,
+ DIDumpOptions DumpOpts, uint8_t Opcode,
uint64_t Operands[2],
const MCRegisterInfo *MRI, bool isEH) {
if (!MRI)
@@ -243,7 +248,7 @@ static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, uint8_t Opcode,
OS << ' ' << RegName;
if (Opcode == DW_OP_regval_type)
- prettyPrintBaseTypeRef(U, OS, Operands, 1);
+ prettyPrintBaseTypeRef(U, OS, DumpOpts, Operands, 1);
return true;
}
}
@@ -251,11 +256,10 @@ static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, uint8_t Opcode,
return false;
}
-bool DWARFExpression::Operation::print(raw_ostream &OS,
+bool DWARFExpression::Operation::print(raw_ostream &OS, DIDumpOptions DumpOpts,
const DWARFExpression *Expr,
const MCRegisterInfo *RegInfo,
- DWARFUnit *U,
- bool isEH) {
+ DWARFUnit *U, bool isEH) {
if (Error) {
OS << "<decoding error>";
return false;
@@ -269,7 +273,7 @@ bool DWARFExpression::Operation::print(raw_ostream &OS,
(Opcode >= DW_OP_reg0 && Opcode <= DW_OP_reg31) ||
Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
Opcode == DW_OP_regval_type)
- if (prettyPrintRegisterOp(U, OS, Opcode, Operands, RegInfo, isEH))
+ if (prettyPrintRegisterOp(U, OS, DumpOpts, Opcode, Operands, RegInfo, isEH))
return true;
for (unsigned Operand = 0; Operand < 2; ++Operand) {
@@ -286,7 +290,7 @@ bool DWARFExpression::Operation::print(raw_ostream &OS,
if (Opcode == DW_OP_convert && Operands[Operand] == 0)
OS << " 0x0";
else
- prettyPrintBaseTypeRef(U, OS, Operands, Operand);
+ prettyPrintBaseTypeRef(U, OS, DumpOpts, Operands, Operand);
} else if (Size == Operation::WasmLocationArg) {
assert(Operand == 1);
switch (Operands[0]) {
@@ -311,11 +315,12 @@ bool DWARFExpression::Operation::print(raw_ostream &OS,
return true;
}
-void DWARFExpression::print(raw_ostream &OS, const MCRegisterInfo *RegInfo,
- DWARFUnit *U, bool IsEH) const {
+void DWARFExpression::print(raw_ostream &OS, DIDumpOptions DumpOpts,
+ const MCRegisterInfo *RegInfo, DWARFUnit *U,
+ bool IsEH) const {
uint32_t EntryValExprSize = 0;
for (auto &Op : *this) {
- if (!Op.print(OS, this, RegInfo, U, IsEH)) {
+ if (!Op.print(OS, DumpOpts, this, RegInfo, U, IsEH)) {
uint64_t FailOffset = Op.getEndOffset();
while (FailOffset < Data.getData().size())
OS << format(" %02x", Data.getU8(&FailOffset));
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp
index a7da5acc380b..7a84605211fb 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp
@@ -358,10 +358,16 @@ bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
return !errorToBool(std::move(Err));
}
+void DWARFFormValue::dumpAddress(raw_ostream &OS, uint8_t AddressSize,
+ uint64_t Address) {
+ uint8_t HexDigits = AddressSize * 2;
+ OS << format("0x%*.*" PRIx64, HexDigits, HexDigits, Address);
+}
+
void DWARFFormValue::dumpSectionedAddress(raw_ostream &OS,
DIDumpOptions DumpOpts,
object::SectionedAddress SA) const {
- OS << format("0x%016" PRIx64, SA.Address);
+ dumpAddress(OS, U->getAddressByteSize(), SA.Address);
dumpAddressSection(U->getContext().getDWARFObj(), OS, DumpOpts,
SA.SectionIndex);
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp b/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
index 252b58e5a591..ace7000f07b2 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
@@ -71,8 +71,8 @@ void DWARFGdbIndex::dumpSymbolTable(raw_ostream &OS) const {
StringRef Name = ConstantPoolStrings.substr(
ConstantPoolOffset - StringPoolOffset + E.NameOffset);
- auto CuVector = std::find_if(
- ConstantPoolVectors.begin(), ConstantPoolVectors.end(),
+ auto CuVector = llvm::find_if(
+ ConstantPoolVectors,
[&](const std::pair<uint32_t, SmallVector<uint32_t, 0>> &V) {
return V.first == E.VecOffset;
});
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp b/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp
index 2124a49bef60..c876af1e9b51 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp
@@ -71,12 +71,12 @@ Error DWARFListTableHeader::extract(DWARFDataExtractor Data,
") than there is space for",
SectionName.data(), HeaderOffset, HeaderData.OffsetEntryCount);
Data.setAddressSize(HeaderData.AddrSize);
- for (uint32_t I = 0; I < HeaderData.OffsetEntryCount; ++I)
- Offsets.push_back(Data.getRelocatedValue(OffsetByteSize, OffsetPtr));
+ *OffsetPtr += HeaderData.OffsetEntryCount * OffsetByteSize;
return Error::success();
}
-void DWARFListTableHeader::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
+void DWARFListTableHeader::dump(DataExtractor Data, raw_ostream &OS,
+ DIDumpOptions DumpOpts) const {
if (DumpOpts.Verbose)
OS << format("0x%8.8" PRIx64 ": ", HeaderOffset);
int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format);
@@ -91,7 +91,8 @@ void DWARFListTableHeader::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
if (HeaderData.OffsetEntryCount > 0) {
OS << "offsets: [";
- for (const auto &Off : Offsets) {
+ for (uint32_t I = 0; I < HeaderData.OffsetEntryCount; ++I) {
+ auto Off = *getOffsetEntry(Data, I);
OS << format("\n0x%0*" PRIx64, OffsetDumpWidth, Off);
if (DumpOpts.Verbose)
OS << format(" => 0x%08" PRIx64,
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
index c219f34bbc31..a301b65dd444 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
@@ -36,9 +36,10 @@ void DWARFTypeUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
<< ", version = " << format("0x%04x", getVersion());
if (getVersion() >= 5)
OS << ", unit_type = " << dwarf::UnitTypeString(getUnitType());
- OS << ", abbr_offset = "
- << format("0x%04" PRIx64, getAbbreviations()->getOffset())
- << ", addr_size = " << format("0x%02x", getAddressByteSize())
+ OS << ", abbr_offset = " << format("0x%04" PRIx64, getAbbrOffset());
+ if (!getAbbreviations())
+ OS << " (invalid)";
+ OS << ", addr_size = " << format("0x%02x", getAddressByteSize())
<< ", name = '" << Name << "'"
<< ", type_signature = " << format("0x%016" PRIx64, getTypeHash())
<< ", type_offset = " << format("0x%04" PRIx64, getTypeOffset())
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index a6d44f04e468..8493950a29b2 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -181,31 +181,6 @@ DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
StringOffsetSection(SOS), AddrOffsetSection(AOS), isLittleEndian(LE),
IsDWO(IsDWO), UnitVector(UnitVector) {
clear();
- if (IsDWO) {
- // If we are reading a package file, we need to adjust the location list
- // data based on the index entries.
- StringRef Data = Header.getVersion() >= 5
- ? Context.getDWARFObj().getLoclistsDWOSection().Data
- : LocSection->Data;
- if (auto *IndexEntry = Header.getIndexEntry())
- if (const auto *C = IndexEntry->getContribution(
- Header.getVersion() >= 5 ? DW_SECT_LOCLISTS : DW_SECT_EXT_LOC))
- Data = Data.substr(C->Offset, C->Length);
-
- DWARFDataExtractor DWARFData(Data, isLittleEndian, getAddressByteSize());
- LocTable =
- std::make_unique<DWARFDebugLoclists>(DWARFData, Header.getVersion());
- } else if (Header.getVersion() >= 5) {
- LocTable = std::make_unique<DWARFDebugLoclists>(
- DWARFDataExtractor(Context.getDWARFObj(),
- Context.getDWARFObj().getLoclistsSection(),
- isLittleEndian, getAddressByteSize()),
- Header.getVersion());
- } else {
- LocTable = std::make_unique<DWARFDebugLoc>(
- DWARFDataExtractor(Context.getDWARFObj(), *LocSection, isLittleEndian,
- getAddressByteSize()));
- }
}
DWARFUnit::~DWARFUnit() = default;
@@ -219,13 +194,12 @@ Optional<object::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);
+ if (hasSingleElement(R))
+ return (*R.begin())->getAddrOffsetSectionItem(Index);
}
if (!AddrOffsetSectionBase)
return None;
@@ -492,8 +466,8 @@ Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
// describe address ranges.
if (getVersion() >= 5) {
// In case of DWP, the base offset from the index has to be added.
- uint64_t ContributionBaseOffset = 0;
if (IsDWO) {
+ uint64_t ContributionBaseOffset = 0;
if (auto *IndexEntry = Header.getIndexEntry())
if (auto *Contrib = IndexEntry->getContribution(DW_SECT_RNGLISTS))
ContributionBaseOffset = Contrib->Offset;
@@ -503,67 +477,36 @@ Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
DWARFListTableHeader::getHeaderSize(Header.getFormat()));
} else
setRangesSection(&Context.getDWARFObj().getRnglistsSection(),
- toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0));
- if (RangeSection->Data.size()) {
- // Parse the range list table header. Individual range lists are
- // extracted lazily.
- DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
- isLittleEndian, 0);
- auto TableOrError = parseListTableHeader<DWARFDebugRnglistTable>(
- RangesDA, RangeSectionBase, Header.getFormat());
- if (!TableOrError)
- return createStringError(errc::invalid_argument,
- "parsing a range list table: " +
- toString(TableOrError.takeError()));
-
- RngListTable = TableOrError.get();
-
- // In a split dwarf unit, there is no DW_AT_rnglists_base attribute.
- // Adjust RangeSectionBase to point past the table header.
- if (IsDWO && RngListTable)
- RangeSectionBase =
- ContributionBaseOffset + RngListTable->getHeaderSize();
- }
-
- // In a split dwarf unit, there is no DW_AT_loclists_base attribute.
- // Setting LocSectionBase to point past the table header.
- if (IsDWO) {
- auto &DWOSection = Context.getDWARFObj().getLoclistsDWOSection();
- if (DWOSection.Data.empty())
- return Error::success();
- setLocSection(&DWOSection,
- DWARFListTableHeader::getHeaderSize(Header.getFormat()));
- } else if (auto X = UnitDie.find(DW_AT_loclists_base)) {
- setLocSection(&Context.getDWARFObj().getLoclistsSection(),
- toSectionOffset(X, 0));
- } else {
- return Error::success();
- }
+ toSectionOffset(UnitDie.find(DW_AT_rnglists_base),
+ DWARFListTableHeader::getHeaderSize(
+ Header.getFormat())));
+ }
- if (LocSection) {
- if (IsDWO)
- LoclistTableHeader.emplace(".debug_loclists.dwo", "locations");
- else
- LoclistTableHeader.emplace(".debug_loclists", "locations");
+ if (IsDWO) {
+ // If we are reading a package file, we need to adjust the location list
+ // data based on the index entries.
+ StringRef Data = Header.getVersion() >= 5
+ ? Context.getDWARFObj().getLoclistsDWOSection().Data
+ : Context.getDWARFObj().getLocDWOSection().Data;
+ if (auto *IndexEntry = Header.getIndexEntry())
+ if (const auto *C = IndexEntry->getContribution(
+ Header.getVersion() >= 5 ? DW_SECT_LOCLISTS : DW_SECT_EXT_LOC))
+ Data = Data.substr(C->Offset, C->Length);
- uint64_t HeaderSize = DWARFListTableHeader::getHeaderSize(Header.getFormat());
- uint64_t Offset = getLocSectionBase();
- DWARFDataExtractor Data(Context.getDWARFObj(), *LocSection,
- isLittleEndian, getAddressByteSize());
- if (Offset < HeaderSize)
- return createStringError(errc::invalid_argument,
- "did not detect a valid"
- " list table with base = 0x%" PRIx64 "\n",
- Offset);
- Offset -= HeaderSize;
- if (auto *IndexEntry = Header.getIndexEntry())
- if (const auto *Contrib = IndexEntry->getContribution(DW_SECT_LOCLISTS))
- Offset += Contrib->Offset;
- if (Error E = LoclistTableHeader->extract(Data, &Offset))
- return createStringError(errc::invalid_argument,
- "parsing a loclist table: " +
- toString(std::move(E)));
- }
+ DWARFDataExtractor DWARFData(Data, isLittleEndian, getAddressByteSize());
+ LocTable =
+ std::make_unique<DWARFDebugLoclists>(DWARFData, Header.getVersion());
+ LocSectionBase = DWARFListTableHeader::getHeaderSize(Header.getFormat());
+ } else if (getVersion() >= 5) {
+ LocTable = std::make_unique<DWARFDebugLoclists>(
+ DWARFDataExtractor(Context.getDWARFObj(),
+ Context.getDWARFObj().getLoclistsSection(),
+ isLittleEndian, getAddressByteSize()),
+ getVersion());
+ } else {
+ LocTable = std::make_unique<DWARFDebugLoc>(DWARFDataExtractor(
+ Context.getDWARFObj(), Context.getDWARFObj().getLocSection(),
+ isLittleEndian, getAddressByteSize()));
}
// Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
@@ -606,19 +549,8 @@ bool DWARFUnit::parseDWO() {
if (AddrOffsetSectionBase)
DWO->setAddrOffsetSection(AddrOffsetSection, *AddrOffsetSectionBase);
if (getVersion() >= 5) {
- DWO->setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(), 0);
- DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
- isLittleEndian, 0);
- if (auto TableOrError = parseListTableHeader<DWARFDebugRnglistTable>(
- RangesDA, RangeSectionBase, Header.getFormat()))
- DWO->RngListTable = TableOrError.get();
- else
- Context.getRecoverableErrorHandler()(createStringError(
- errc::invalid_argument, "parsing a range list table: %s",
- toString(TableOrError.takeError()).c_str()));
-
- if (DWO->RngListTable)
- DWO->RangeSectionBase = DWO->RngListTable->getHeaderSize();
+ DWO->setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(),
+ DWARFListTableHeader::getHeaderSize(getFormat()));
} else {
auto DWORangesBase = UnitDie.getRangesBaseAttribute();
DWO->setRangesSection(RangeSection, DWORangesBase ? *DWORangesBase : 0);
@@ -642,17 +574,13 @@ DWARFUnit::findRnglistFromOffset(uint64_t Offset) {
return std::move(E);
return RangeList.getAbsoluteRanges(getBaseAddress());
}
- if (RngListTable) {
- DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
- isLittleEndian, RngListTable->getAddrSize());
- auto RangeListOrError = RngListTable->findList(RangesData, Offset);
- if (RangeListOrError)
- return RangeListOrError.get().getAbsoluteRanges(getBaseAddress(), *this);
- return RangeListOrError.takeError();
- }
-
- return createStringError(errc::invalid_argument,
- "missing or invalid range list table");
+ DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
+ isLittleEndian, Header.getAddressByteSize());
+ DWARFDebugRnglistTable RnglistTable;
+ auto RangeListOrError = RnglistTable.findList(RangesData, Offset);
+ if (RangeListOrError)
+ return RangeListOrError.get().getAbsoluteRanges(getBaseAddress(), *this);
+ return RangeListOrError.takeError();
}
Expected<DWARFAddressRangesVector>
@@ -660,12 +588,10 @@ DWARFUnit::findRnglistFromIndex(uint32_t Index) {
if (auto Offset = getRnglistOffset(Index))
return findRnglistFromOffset(*Offset);
- if (RngListTable)
- return createStringError(errc::invalid_argument,
- "invalid range list table index %d", Index);
-
return createStringError(errc::invalid_argument,
- "missing or invalid range list table");
+ "invalid range list table index %d (possibly "
+ "missing the entire range list table)",
+ Index);
}
Expected<DWARFAddressRangesVector> DWARFUnit::collectAddressRanges() {
@@ -995,11 +921,35 @@ 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.
- if (!IndexEntry)
- return {Optional<StrOffsetsContributionDescriptor>(
- {0, StringOffsetSection.Data.size(), 4, Header.getFormat()})};
+ StrOffsetsContributionDescriptor Desc;
if (C)
- return {Optional<StrOffsetsContributionDescriptor>(
- {C->Offset, C->Length, 4, Header.getFormat()})};
+ Desc = StrOffsetsContributionDescriptor(C->Offset, C->Length, 4,
+ Header.getFormat());
+ else if (!IndexEntry && !StringOffsetSection.Data.empty())
+ Desc = StrOffsetsContributionDescriptor(0, StringOffsetSection.Data.size(),
+ 4, Header.getFormat());
+ else
+ return None;
+ auto DescOrError = Desc.validateContributionSize(DA);
+ if (!DescOrError)
+ return DescOrError.takeError();
+ return *DescOrError;
+}
+
+Optional<uint64_t> DWARFUnit::getRnglistOffset(uint32_t Index) {
+ DataExtractor RangesData(RangeSection->Data, isLittleEndian,
+ getAddressByteSize());
+ DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
+ isLittleEndian, 0);
+ if (Optional<uint64_t> Off = llvm::DWARFListTableHeader::getOffsetEntry(
+ RangesData, RangeSectionBase, getFormat(), Index))
+ return *Off + RangeSectionBase;
+ return None;
+}
+
+Optional<uint64_t> DWARFUnit::getLoclistOffset(uint32_t Index) {
+ if (Optional<uint64_t> Off = llvm::DWARFListTableHeader::getOffsetEntry(
+ LocTable->getData(), LocSectionBase, getFormat(), Index))
+ return *Off + LocSectionBase;
return None;
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
index 3d4cecce27db..d27fd08db14e 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
@@ -286,10 +286,14 @@ const DWARFUnitIndex::Entry *DWARFUnitIndex::getFromHash(uint64_t S) const {
auto H = S & Mask;
auto HP = ((S >> 32) & Mask) | 1;
- while (Rows[H].getSignature() != S && Rows[H].getSignature() != 0)
+ // The spec says "while 0 is a valid hash value, the row index in a used slot
+ // will always be non-zero". Loop until we find a match or an empty slot.
+ while (Rows[H].getSignature() != S && Rows[H].Index != nullptr)
H = (H + HP) & Mask;
- if (Rows[H].getSignature() != S)
+ // If the slot is empty, we don't care whether the signature matches (it could
+ // be zero and still match the zeros in the empty slot).
+ if (Rows[H].Index == nullptr)
return nullptr;
return &Rows[H];
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index 3a83317a73a3..ac624ec8b80f 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -172,6 +172,15 @@ unsigned DWARFVerifier::verifyUnitContents(DWARFUnit &Unit) {
NumUnitErrors += verifyDebugInfoForm(Die, AttrValue);
}
+ if (Die.hasChildren()) {
+ if (Die.getFirstChild().isValid() &&
+ Die.getFirstChild().getTag() == DW_TAG_null) {
+ warn() << dwarf::TagString(Die.getTag())
+ << " has DW_CHILDREN_yes but DIE has no children: ";
+ Die.dump(OS);
+ }
+ }
+
NumUnitErrors += verifyDebugInfoCallSite(Die);
}
@@ -538,6 +547,39 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
}
break;
}
+ case DW_AT_call_file:
+ case DW_AT_decl_file: {
+ if (auto FileIdx = AttrValue.Value.getAsUnsignedConstant()) {
+ DWARFUnit *U = Die.getDwarfUnit();
+ const auto *LT = U->getContext().getLineTableForUnit(U);
+ if (LT) {
+ if (!LT->hasFileAtIndex(*FileIdx)) {
+ bool IsZeroIndexed = LT->Prologue.getVersion() >= 5;
+ if (Optional<uint64_t> LastFileIdx = LT->getLastValidFileIndex()) {
+ ReportError("DIE has " + AttributeString(Attr) +
+ " with an invalid file index " +
+ llvm::formatv("{0}", *FileIdx) +
+ " (valid values are [" + (IsZeroIndexed ? "0-" : "1-") +
+ llvm::formatv("{0}", *LastFileIdx) + "])");
+ } else {
+ ReportError("DIE has " + AttributeString(Attr) +
+ " with an invalid file index " +
+ llvm::formatv("{0}", *FileIdx) +
+ " (the file table in the prologue is empty)");
+ }
+ }
+ } else {
+ ReportError("DIE has " + AttributeString(Attr) +
+ " that references a file with index " +
+ llvm::formatv("{0}", *FileIdx) +
+ " and the compile unit has no line table");
+ }
+ } else {
+ ReportError("DIE has " + AttributeString(Attr) +
+ " with invalid encoding");
+ }
+ break;
+ }
default:
break;
}
diff --git a/llvm/lib/DebugInfo/GSYM/GsymCreator.cpp b/llvm/lib/DebugInfo/GSYM/GsymCreator.cpp
index 7d9b72c6283d..2001478e8047 100644
--- a/llvm/lib/DebugInfo/GSYM/GsymCreator.cpp
+++ b/llvm/lib/DebugInfo/GSYM/GsymCreator.cpp
@@ -169,7 +169,7 @@ llvm::Error GsymCreator::finalize(llvm::raw_ostream &OS) {
Finalized = true;
// Sort function infos so we can emit sorted functions.
- llvm::sort(Funcs.begin(), Funcs.end());
+ llvm::sort(Funcs);
// Don't let the string table indexes change by finalizing in order.
StrTab.finalizeInOrder();
diff --git a/llvm/lib/DebugInfo/MSF/MSFBuilder.cpp b/llvm/lib/DebugInfo/MSF/MSFBuilder.cpp
index c6fe764ab7e0..f946dd4860ac 100644
--- a/llvm/lib/DebugInfo/MSF/MSFBuilder.cpp
+++ b/llvm/lib/DebugInfo/MSF/MSFBuilder.cpp
@@ -204,8 +204,7 @@ Error MSFBuilder::setStreamSize(uint32_t Idx, uint32_t Size) {
if (auto EC = allocateBlocks(AddedBlocks, AddedBlockList))
return EC;
auto &CurrentBlocks = StreamData[Idx].second;
- CurrentBlocks.insert(CurrentBlocks.end(), AddedBlockList.begin(),
- AddedBlockList.end());
+ llvm::append_range(CurrentBlocks, AddedBlockList);
} else if (OldBlocks > NewBlocks) {
// For shrinking, free all the Blocks in the Block map, update the stream
// data, then shrink the directory.
@@ -268,8 +267,7 @@ Expected<MSFLayout> MSFBuilder::generateLayout() {
ExtraBlocks.resize(NumExtraBlocks);
if (auto EC = allocateBlocks(NumExtraBlocks, ExtraBlocks))
return std::move(EC);
- DirectoryBlocks.insert(DirectoryBlocks.end(), ExtraBlocks.begin(),
- ExtraBlocks.end());
+ llvm::append_range(DirectoryBlocks, ExtraBlocks);
} else if (NumDirectoryBlocks < DirectoryBlocks.size()) {
uint32_t NumUnnecessaryBlocks = DirectoryBlocks.size() - NumDirectoryBlocks;
for (auto B :
diff --git a/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
index 73801ea1dd1b..b6f11a942a26 100644
--- a/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
@@ -74,7 +74,7 @@ void DbiModuleDescriptorBuilder::addSymbolsInBulk(
if (BulkSymbols.empty())
return;
- Symbols.push_back(BulkSymbols);
+ Symbols.push_back(SymbolListWrapper(BulkSymbols));
// Symbols written to a PDB file are required to be 4 byte aligned. The same
// is not true of object files.
assert(BulkSymbols.size() % alignOf(CodeViewContainer::Pdb) == 0 &&
@@ -82,6 +82,18 @@ void DbiModuleDescriptorBuilder::addSymbolsInBulk(
SymbolByteSize += BulkSymbols.size();
}
+void DbiModuleDescriptorBuilder::addUnmergedSymbols(void *SymSrc,
+ uint32_t SymLength) {
+ assert(SymLength > 0);
+ Symbols.push_back(SymbolListWrapper(SymSrc, SymLength));
+
+ // Symbols written to a PDB file are required to be 4 byte aligned. The same
+ // is not true of object files.
+ assert(SymLength % alignOf(CodeViewContainer::Pdb) == 0 &&
+ "Invalid Symbol alignment!");
+ SymbolByteSize += SymLength;
+}
+
void DbiModuleDescriptorBuilder::addSourceFile(StringRef Path) {
SourceFiles.push_back(std::string(Path));
}
@@ -131,9 +143,7 @@ Error DbiModuleDescriptorBuilder::finalizeMsfLayout() {
return Error::success();
}
-Error DbiModuleDescriptorBuilder::commit(BinaryStreamWriter &ModiWriter,
- const msf::MSFLayout &MsfLayout,
- WritableBinaryStreamRef MsfBuffer) {
+Error DbiModuleDescriptorBuilder::commit(BinaryStreamWriter &ModiWriter) {
// We write the Modi record to the `ModiWriter`, but we additionally write its
// symbol stream to a brand new stream.
if (auto EC = ModiWriter.writeObject(Layout))
@@ -144,34 +154,55 @@ Error DbiModuleDescriptorBuilder::commit(BinaryStreamWriter &ModiWriter,
return EC;
if (auto EC = ModiWriter.padToAlignment(sizeof(uint32_t)))
return EC;
+ return Error::success();
+}
- if (Layout.ModDiStream != kInvalidStreamIndex) {
- auto NS = WritableMappedBlockStream::createIndexedStream(
- MsfLayout, MsfBuffer, Layout.ModDiStream, MSF.getAllocator());
- WritableBinaryStreamRef Ref(*NS);
- BinaryStreamWriter SymbolWriter(Ref);
- // Write the symbols.
- if (auto EC =
- SymbolWriter.writeInteger<uint32_t>(COFF::DEBUG_SECTION_MAGIC))
- return EC;
- for (ArrayRef<uint8_t> Syms : Symbols) {
- if (auto EC = SymbolWriter.writeBytes(Syms))
+Error DbiModuleDescriptorBuilder::commitSymbolStream(
+ const msf::MSFLayout &MsfLayout, WritableBinaryStreamRef MsfBuffer) {
+ if (Layout.ModDiStream == kInvalidStreamIndex)
+ return Error::success();
+
+ auto NS = WritableMappedBlockStream::createIndexedStream(
+ MsfLayout, MsfBuffer, Layout.ModDiStream, MSF.getAllocator());
+ WritableBinaryStreamRef Ref(*NS);
+ BinaryStreamWriter SymbolWriter(Ref);
+ // Write the symbols.
+ if (auto EC = SymbolWriter.writeInteger<uint32_t>(COFF::DEBUG_SECTION_MAGIC))
+ return EC;
+ for (const SymbolListWrapper &Sym : Symbols) {
+ if (Sym.NeedsToBeMerged) {
+ assert(MergeSymsCallback);
+ if (auto EC = MergeSymsCallback(MergeSymsCtx, Sym.SymPtr, SymbolWriter))
return EC;
- }
- assert(SymbolWriter.getOffset() % alignOf(CodeViewContainer::Pdb) == 0 &&
- "Invalid debug section alignment!");
- // TODO: Write C11 Line data
- for (const auto &Builder : C13Builders) {
- if (auto EC = Builder.commit(SymbolWriter, CodeViewContainer::Pdb))
+ } else {
+ if (auto EC = SymbolWriter.writeBytes(Sym.asArray()))
return EC;
}
+ }
+
+ // Apply the string table fixups.
+ auto SavedOffset = SymbolWriter.getOffset();
+ for (const StringTableFixup &Fixup : StringTableFixups) {
+ SymbolWriter.setOffset(Fixup.SymOffsetOfReference);
+ if (auto E = SymbolWriter.writeInteger<uint32_t>(Fixup.StrTabOffset))
+ return E;
+ }
+ SymbolWriter.setOffset(SavedOffset);
- // TODO: Figure out what GlobalRefs substream actually is and populate it.
- if (auto EC = SymbolWriter.writeInteger<uint32_t>(0))
+ assert(SymbolWriter.getOffset() % alignOf(CodeViewContainer::Pdb) == 0 &&
+ "Invalid debug section alignment!");
+ // TODO: Write C11 Line data
+ for (const auto &Builder : C13Builders) {
+ if (auto EC = Builder.commit(SymbolWriter, CodeViewContainer::Pdb))
return EC;
- if (SymbolWriter.bytesRemaining() > 0)
- return make_error<RawError>(raw_error_code::stream_too_long);
}
+
+ // TODO: Figure out what GlobalRefs substream actually is and populate it.
+ if (auto EC = SymbolWriter.writeInteger<uint32_t>(0))
+ return EC;
+ if (SymbolWriter.bytesRemaining() > 0)
+ return make_error<RawError>(raw_error_code::stream_too_long);
+
return Error::success();
}
diff --git a/llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
index 627aef7506fd..98a8acaffd60 100644
--- a/llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
@@ -18,6 +18,7 @@
#include "llvm/DebugInfo/PDB/Native/RawError.h"
#include "llvm/Object/COFF.h"
#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Parallel.h"
using namespace llvm;
using namespace llvm::codeview;
@@ -394,10 +395,17 @@ Error DbiStreamBuilder::commit(const msf::MSFLayout &Layout,
return EC;
for (auto &M : ModiList) {
- if (auto EC = M->commit(Writer, Layout, MsfBuffer))
+ if (auto EC = M->commit(Writer))
return EC;
}
+ // Commit symbol streams. This is a lot of data, so do it in parallel.
+ if (auto EC = parallelForEachError(
+ ModiList, [&](std::unique_ptr<DbiModuleDescriptorBuilder> &M) {
+ return M->commitSymbolStream(Layout, MsfBuffer);
+ }))
+ return EC;
+
if (!SectionContribs.empty()) {
if (auto EC = Writer.writeEnum(DbiSecContribVer60))
return EC;
diff --git a/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
index 4e58489f1401..52df26b67916 100644
--- a/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
@@ -162,7 +162,7 @@ static int gsiRecordCmp(StringRef S1, StringRef S2) {
if (LLVM_UNLIKELY(!isAsciiString(S1) || !isAsciiString(S2)))
return memcmp(S1.data(), S2.data(), LS);
- // Both strings are ascii, perform a case-insenstive comparison.
+ // Both strings are ascii, perform a case-insensitive comparison.
return S1.compare_lower(S2.data());
}
diff --git a/llvm/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp b/llvm/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
index 4a88391494cd..1d873b87b347 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
@@ -116,7 +116,7 @@ StringMap<uint32_t> NamedStreamMap::entries() const {
uint32_t NamedStreamMap::appendStringData(StringRef S) {
uint32_t Offset = NamesBuffer.size();
- NamesBuffer.insert(NamesBuffer.end(), S.begin(), S.end());
+ llvm::append_range(NamesBuffer, S);
NamesBuffer.push_back('\0');
return Offset;
}
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeEnumSymbols.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeEnumSymbols.cpp
new file mode 100644
index 000000000000..feede1dbc958
--- /dev/null
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeEnumSymbols.cpp
@@ -0,0 +1,41 @@
+//==- NativeEnumSymbols.cpp - Native Symbol Enumerator impl ------*- C++ -*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbols.h"
+
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.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"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeEnumSymbols::NativeEnumSymbols(NativeSession &PDBSession,
+ std::vector<SymIndexId> Symbols)
+ : Symbols(std::move(Symbols)), Index(0), Session(PDBSession) {}
+
+uint32_t NativeEnumSymbols::getChildCount() const {
+ return static_cast<uint32_t>(Symbols.size());
+}
+
+std::unique_ptr<PDBSymbol>
+NativeEnumSymbols::getChildAtIndex(uint32_t N) const {
+ if (N < Symbols.size()) {
+ return Session.getSymbolCache().getSymbolById(Symbols[N]);
+ }
+ return nullptr;
+}
+
+std::unique_ptr<PDBSymbol> NativeEnumSymbols::getNext() {
+ return getChildAtIndex(Index++);
+}
+
+void NativeEnumSymbols::reset() { Index = 0; }
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeFunctionSymbol.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeFunctionSymbol.cpp
index 2537daa7493c..7f3b35c297b4 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeFunctionSymbol.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeFunctionSymbol.cpp
@@ -8,7 +8,9 @@
#include "llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h"
+#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbols.h"
#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
@@ -18,8 +20,10 @@ using namespace llvm::pdb;
NativeFunctionSymbol::NativeFunctionSymbol(NativeSession &Session,
SymIndexId Id,
- const codeview::ProcSym &Sym)
- : NativeRawSymbol(Session, PDB_SymType::Data, Id), Sym(Sym) {}
+ const codeview::ProcSym &Sym,
+ uint32_t Offset)
+ : NativeRawSymbol(Session, PDB_SymType::Function, Id), Sym(Sym),
+ RecordOffset(Offset) {}
NativeFunctionSymbol::~NativeFunctionSymbol() {}
@@ -42,10 +46,6 @@ std::string NativeFunctionSymbol::getName() const {
return std::string(Sym.Name);
}
-PDB_SymType NativeFunctionSymbol::getSymTag() const {
- return PDB_SymType::Function;
-}
-
uint64_t NativeFunctionSymbol::getLength() const { return Sym.CodeSize; }
uint32_t NativeFunctionSymbol::getRelativeVirtualAddress() const {
@@ -55,3 +55,89 @@ uint32_t NativeFunctionSymbol::getRelativeVirtualAddress() const {
uint64_t NativeFunctionSymbol::getVirtualAddress() const {
return Session.getVAFromSectOffset(Sym.Segment, Sym.CodeOffset);
}
+
+static bool inlineSiteContainsAddress(InlineSiteSym &IS,
+ uint32_t OffsetInFunc) {
+ // Returns true if inline site contains the offset.
+ bool Found = false;
+ uint32_t CodeOffset = 0;
+ for (auto &Annot : IS.annotations()) {
+ switch (Annot.OpCode) {
+ case BinaryAnnotationsOpCode::CodeOffset:
+ case BinaryAnnotationsOpCode::ChangeCodeOffset:
+ case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
+ CodeOffset += Annot.U1;
+ if (OffsetInFunc >= CodeOffset)
+ Found = true;
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeLength:
+ CodeOffset += Annot.U1;
+ if (Found && OffsetInFunc < CodeOffset)
+ return true;
+ Found = false;
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
+ CodeOffset += Annot.U2;
+ if (OffsetInFunc >= CodeOffset && OffsetInFunc < CodeOffset + Annot.U1)
+ return true;
+ Found = false;
+ break;
+ default:
+ break;
+ }
+ }
+ return false;
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+NativeFunctionSymbol::findInlineFramesByVA(uint64_t VA) const {
+ uint16_t Modi;
+ if (!Session.moduleIndexForVA(VA, Modi))
+ return nullptr;
+
+ Expected<ModuleDebugStreamRef> ModS = Session.getModuleDebugStream(Modi);
+ if (!ModS) {
+ consumeError(ModS.takeError());
+ return nullptr;
+ }
+ CVSymbolArray Syms = ModS->getSymbolArray();
+
+ // Search for inline sites. There should be one matching top level inline
+ // site. Then search in its nested inline sites.
+ std::vector<SymIndexId> Frames;
+ uint32_t CodeOffset = VA - getVirtualAddress();
+ auto Start = Syms.at(RecordOffset);
+ auto End = Syms.at(Sym.End);
+ while (Start != End) {
+ bool Found = false;
+ // Find matching inline site within Start and End.
+ for (; Start != End; ++Start) {
+ if (Start->kind() != S_INLINESITE)
+ continue;
+
+ InlineSiteSym IS =
+ cantFail(SymbolDeserializer::deserializeAs<InlineSiteSym>(*Start));
+ if (inlineSiteContainsAddress(IS, CodeOffset)) {
+ // Insert frames in reverse order.
+ SymIndexId Id = Session.getSymbolCache().getOrCreateInlineSymbol(
+ IS, getVirtualAddress(), Modi, Start.offset());
+ Frames.insert(Frames.begin(), Id);
+
+ // Update offsets to search within this inline site.
+ ++Start;
+ End = Syms.at(IS.End);
+ Found = true;
+ break;
+ }
+
+ Start = Syms.at(IS.End);
+ if (Start == End)
+ break;
+ }
+
+ if (!Found)
+ break;
+ }
+
+ return std::make_unique<NativeEnumSymbols>(Session, std::move(Frames));
+}
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeInlineSiteSymbol.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeInlineSiteSymbol.cpp
new file mode 100644
index 000000000000..8314353c3890
--- /dev/null
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeInlineSiteSymbol.cpp
@@ -0,0 +1,177 @@
+//===- NativeInlineSiteSymbol.cpp - info about inline sites -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeInlineSiteSymbol.h"
+
+#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
+#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeInlineSiteSymbol::NativeInlineSiteSymbol(
+ NativeSession &Session, SymIndexId Id, const codeview::InlineSiteSym &Sym,
+ uint64_t ParentAddr)
+ : NativeRawSymbol(Session, PDB_SymType::InlineSite, Id), Sym(Sym),
+ ParentAddr(ParentAddr) {}
+
+NativeInlineSiteSymbol::~NativeInlineSiteSymbol() {}
+
+void NativeInlineSiteSymbol::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+ dumpSymbolField(OS, "name", getName(), Indent);
+}
+
+static Optional<InlineeSourceLine>
+findInlineeByTypeIndex(TypeIndex Id, ModuleDebugStreamRef &ModS) {
+ for (const auto &SS : ModS.getSubsectionsArray()) {
+ if (SS.kind() != DebugSubsectionKind::InlineeLines)
+ continue;
+
+ DebugInlineeLinesSubsectionRef InlineeLines;
+ BinaryStreamReader Reader(SS.getRecordData());
+ if (auto EC = InlineeLines.initialize(Reader)) {
+ consumeError(std::move(EC));
+ continue;
+ }
+
+ for (const InlineeSourceLine &Line : InlineeLines)
+ if (Line.Header->Inlinee == Id)
+ return Line;
+ }
+ return None;
+}
+
+std::string NativeInlineSiteSymbol::getName() const {
+ auto Tpi = Session.getPDBFile().getPDBTpiStream();
+ if (!Tpi) {
+ consumeError(Tpi.takeError());
+ return "";
+ }
+ auto Ipi = Session.getPDBFile().getPDBIpiStream();
+ if (!Ipi) {
+ consumeError(Ipi.takeError());
+ return "";
+ }
+
+ LazyRandomTypeCollection &Types = Tpi->typeCollection();
+ LazyRandomTypeCollection &Ids = Ipi->typeCollection();
+ CVType InlineeType = Ids.getType(Sym.Inlinee);
+ std::string QualifiedName;
+ if (InlineeType.kind() == LF_MFUNC_ID) {
+ MemberFuncIdRecord MFRecord;
+ cantFail(TypeDeserializer::deserializeAs<MemberFuncIdRecord>(InlineeType,
+ MFRecord));
+ TypeIndex ClassTy = MFRecord.getClassType();
+ QualifiedName.append(std::string(Types.getTypeName(ClassTy)));
+ QualifiedName.append("::");
+ } else if (InlineeType.kind() == LF_FUNC_ID) {
+ FuncIdRecord FRecord;
+ cantFail(
+ TypeDeserializer::deserializeAs<FuncIdRecord>(InlineeType, FRecord));
+ TypeIndex ParentScope = FRecord.getParentScope();
+ if (!ParentScope.isNoneType()) {
+ QualifiedName.append(std::string(Ids.getTypeName(ParentScope)));
+ QualifiedName.append("::");
+ }
+ }
+
+ QualifiedName.append(std::string(Ids.getTypeName(Sym.Inlinee)));
+ return QualifiedName;
+}
+
+void NativeInlineSiteSymbol::getLineOffset(uint32_t OffsetInFunc,
+ uint32_t &LineOffset,
+ uint32_t &FileOffset) const {
+ LineOffset = 0;
+ FileOffset = 0;
+ uint32_t CodeOffset = 0;
+ for (const auto &Annot : Sym.annotations()) {
+ switch (Annot.OpCode) {
+ case BinaryAnnotationsOpCode::CodeOffset:
+ case BinaryAnnotationsOpCode::ChangeCodeOffset:
+ case BinaryAnnotationsOpCode::ChangeCodeLength:
+ CodeOffset += Annot.U1;
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
+ CodeOffset += Annot.U2;
+ break;
+ case BinaryAnnotationsOpCode::ChangeLineOffset:
+ case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
+ CodeOffset += Annot.U1;
+ LineOffset += Annot.S1;
+ break;
+ case BinaryAnnotationsOpCode::ChangeFile:
+ FileOffset = Annot.U1;
+ break;
+ default:
+ break;
+ }
+
+ if (CodeOffset >= OffsetInFunc)
+ return;
+ }
+}
+
+std::unique_ptr<IPDBEnumLineNumbers>
+NativeInlineSiteSymbol::findInlineeLinesByVA(uint64_t VA,
+ uint32_t Length) const {
+ uint16_t Modi;
+ if (!Session.moduleIndexForVA(VA, Modi))
+ return nullptr;
+
+ Expected<ModuleDebugStreamRef> ModS = Session.getModuleDebugStream(Modi);
+ if (!ModS) {
+ consumeError(ModS.takeError());
+ return nullptr;
+ }
+
+ Expected<DebugChecksumsSubsectionRef> Checksums =
+ ModS->findChecksumsSubsection();
+ if (!Checksums) {
+ consumeError(Checksums.takeError());
+ return nullptr;
+ }
+
+ // Get the line number offset and source file offset.
+ uint32_t SrcLineOffset;
+ uint32_t SrcFileOffset;
+ getLineOffset(VA - ParentAddr, SrcLineOffset, SrcFileOffset);
+
+ // Get line info from inlinee line table.
+ Optional<InlineeSourceLine> Inlinee =
+ findInlineeByTypeIndex(Sym.Inlinee, ModS.get());
+
+ if (!Inlinee)
+ return nullptr;
+
+ uint32_t SrcLine = Inlinee->Header->SourceLineNum + SrcLineOffset;
+ uint32_t SrcCol = 0; // Inline sites don't seem to have column info.
+ uint32_t FileChecksumOffset =
+ (SrcFileOffset == 0) ? Inlinee->Header->FileID : SrcFileOffset;
+
+ auto ChecksumIter = Checksums->getArray().at(FileChecksumOffset);
+ uint32_t SrcFileId =
+ Session.getSymbolCache().getOrCreateSourceFile(*ChecksumIter);
+
+ uint32_t LineSect, LineOff;
+ Session.addressForVA(VA, LineSect, LineOff);
+ NativeLineNumber LineNum(Session, SrcLine, SrcCol, LineSect, LineOff, Length,
+ SrcFileId, Modi);
+ auto SrcFile = Session.getSymbolCache().getSourceFileById(SrcFileId);
+ std::vector<NativeLineNumber> Lines{LineNum};
+
+ return std::make_unique<NativeEnumLineNumbers>(std::move(Lines));
+}
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp
index 2535e09baf62..155ed0cdb828 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp
@@ -15,9 +15,10 @@ NativeLineNumber::NativeLineNumber(const NativeSession &Session,
const codeview::LineInfo Line,
uint32_t ColumnNumber, uint32_t Section,
uint32_t Offset, uint32_t Length,
- uint32_t SrcFileId)
+ uint32_t SrcFileId, uint32_t CompilandId)
: Session(Session), Line(Line), ColumnNumber(ColumnNumber),
- Section(Section), Offset(Offset), Length(Length), SrcFileId(SrcFileId) {}
+ Section(Section), Offset(Offset), Length(Length), SrcFileId(SrcFileId),
+ CompilandId(CompilandId) {}
uint32_t NativeLineNumber::getLineNumber() const { return Line.getStartLine(); }
@@ -45,6 +46,6 @@ uint32_t NativeLineNumber::getLength() const { return Length; }
uint32_t NativeLineNumber::getSourceFileId() const { return SrcFileId; }
-uint32_t NativeLineNumber::getCompilandId() const { return 0; }
+uint32_t NativeLineNumber::getCompilandId() const { return CompilandId; }
bool NativeLineNumber::isStatement() const { return Line.isStatement(); }
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativePublicSymbol.cpp b/llvm/lib/DebugInfo/PDB/Native/NativePublicSymbol.cpp
index 7086af7e67a2..1265e688b867 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativePublicSymbol.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativePublicSymbol.cpp
@@ -18,7 +18,7 @@ using namespace llvm::pdb;
NativePublicSymbol::NativePublicSymbol(NativeSession &Session, SymIndexId Id,
const codeview::PublicSym32 &Sym)
- : NativeRawSymbol(Session, PDB_SymType::Data, Id), Sym(Sym) {}
+ : NativeRawSymbol(Session, PDB_SymType::PublicSymbol, Id), Sym(Sym) {}
NativePublicSymbol::~NativePublicSymbol() {}
@@ -39,10 +39,6 @@ std::string NativePublicSymbol::getName() const {
return std::string(Sym.Name);
}
-PDB_SymType NativePublicSymbol::getSymTag() const {
- return PDB_SymType::PublicSymbol;
-}
-
uint32_t NativePublicSymbol::getRelativeVirtualAddress() const {
return Session.getRVAFromSectOffset(Sym.Segment, Sym.Offset);
}
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp
index ac8449df44ff..5d7946cdc2f7 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp
@@ -13,6 +13,7 @@
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
+#include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumInjectedSources.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
@@ -56,7 +57,7 @@ static DbiStream *getDbiStreamPtr(PDBFile &File) {
NativeSession::NativeSession(std::unique_ptr<PDBFile> PdbFile,
std::unique_ptr<BumpPtrAllocator> Allocator)
: Pdb(std::move(PdbFile)), Allocator(std::move(Allocator)),
- Cache(*this, getDbiStreamPtr(*Pdb)) {}
+ Cache(*this, getDbiStreamPtr(*Pdb)), AddrToModuleIndex(IMapAllocator) {}
NativeSession::~NativeSession() = default;
@@ -255,6 +256,9 @@ std::unique_ptr<PDBSymbol> NativeSession::findSymbolByRVA(uint32_t RVA,
std::unique_ptr<PDBSymbol>
NativeSession::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
PDB_SymType Type) {
+ if (AddrToModuleIndex.empty())
+ parseSectionContribs();
+
return Cache.findSymbolBySectOffset(Sect, Offset, Type);
}
@@ -272,14 +276,14 @@ NativeSession::findLineNumbersByAddress(uint64_t Address,
std::unique_ptr<IPDBEnumLineNumbers>
NativeSession::findLineNumbersByRVA(uint32_t RVA, uint32_t Length) const {
- return findLineNumbersByAddress(getLoadAddress() + RVA, Length);
+ return Cache.findLineNumbersByVA(getLoadAddress() + RVA, Length);
}
std::unique_ptr<IPDBEnumLineNumbers>
NativeSession::findLineNumbersBySectOffset(uint32_t Section, uint32_t Offset,
uint32_t Length) const {
uint64_t VA = getVAFromSectOffset(Section, Offset);
- return findLineNumbersByAddress(VA, Length);
+ return Cache.findLineNumbersByVA(VA, Length);
}
std::unique_ptr<IPDBEnumSourceFiles>
@@ -386,3 +390,74 @@ uint64_t NativeSession::getVAFromSectOffset(uint32_t Section,
uint32_t Offset) const {
return LoadAddress + getRVAFromSectOffset(Section, Offset);
}
+
+bool NativeSession::moduleIndexForVA(uint64_t VA, uint16_t &ModuleIndex) const {
+ ModuleIndex = 0;
+ auto Iter = AddrToModuleIndex.find(VA);
+ if (Iter == AddrToModuleIndex.end())
+ return false;
+ ModuleIndex = Iter.value();
+ return true;
+}
+
+bool NativeSession::moduleIndexForSectOffset(uint32_t Sect, uint32_t Offset,
+ uint16_t &ModuleIndex) const {
+ ModuleIndex = 0;
+ auto Iter = AddrToModuleIndex.find(getVAFromSectOffset(Sect, Offset));
+ if (Iter == AddrToModuleIndex.end())
+ return false;
+ ModuleIndex = Iter.value();
+ return true;
+}
+
+void NativeSession::parseSectionContribs() {
+ auto Dbi = Pdb->getPDBDbiStream();
+ if (!Dbi)
+ return;
+
+ class Visitor : public ISectionContribVisitor {
+ NativeSession &Session;
+ IMap &AddrMap;
+
+ public:
+ Visitor(NativeSession &Session, IMap &AddrMap)
+ : Session(Session), AddrMap(AddrMap) {}
+ void visit(const SectionContrib &C) override {
+ if (C.Size == 0)
+ return;
+
+ uint64_t VA = Session.getVAFromSectOffset(C.ISect, C.Off);
+ uint64_t End = VA + C.Size;
+
+ // Ignore overlapping sections based on the assumption that a valid
+ // PDB file should not have overlaps.
+ if (!AddrMap.overlaps(VA, End))
+ AddrMap.insert(VA, End, C.Imod);
+ }
+ void visit(const SectionContrib2 &C) override { visit(C.Base); }
+ };
+
+ Visitor V(*this, AddrToModuleIndex);
+ Dbi->visitSectionContributions(V);
+}
+
+Expected<ModuleDebugStreamRef>
+NativeSession::getModuleDebugStream(uint32_t Index) const {
+ auto *Dbi = getDbiStreamPtr(*Pdb);
+ assert(Dbi && "Dbi stream not present");
+
+ DbiModuleDescriptor Modi = Dbi->modules().getModuleDescriptor(Index);
+
+ uint16_t ModiStream = Modi.getModuleStreamIndex();
+ if (ModiStream == kInvalidStreamIndex)
+ return make_error<RawError>("Module stream not present");
+
+ std::unique_ptr<msf::MappedBlockStream> ModStreamData =
+ Pdb->createIndexedStream(ModiStream);
+
+ ModuleDebugStreamRef ModS(Modi, std::move(ModStreamData));
+ if (auto EC = ModS.reload())
+ return std::move(EC);
+
+ return std::move(ModS);
+}
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp
index 6473207e058a..fd813dee6b9f 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp
@@ -1,4 +1,4 @@
-//===- NativeSourceFile.cpp - Native line number implementaiton -*- C++ -*-===//
+//===- NativeSourceFile.cpp - Native line number implementation -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp
index b0be7f76e86e..917ec14e58d6 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp
@@ -120,7 +120,7 @@ PDB_UdtType NativeTypeUDT::getUdtKind() const {
case TypeRecordKind::Interface:
return PDB_UdtType::Interface;
default:
- llvm_unreachable("Unexected udt kind");
+ llvm_unreachable("Unexpected udt kind");
}
}
diff --git a/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp b/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp
index 9f15907b519e..fd9a0deb54d6 100644
--- a/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp
@@ -1,5 +1,6 @@
#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
+#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
@@ -10,8 +11,10 @@
#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumGlobals.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h"
+#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbols.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
#include "llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeInlineSiteSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativePublicSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
@@ -68,7 +71,7 @@ static const struct BuiltinTypeEntry {
};
SymbolCache::SymbolCache(NativeSession &Session, DbiStream *Dbi)
- : Session(Session), Dbi(Dbi), AddrToModuleIndex(IMapAllocator) {
+ : Session(Session), Dbi(Dbi) {
// Id 0 is reserved for the invalid symbol.
Cache.push_back(nullptr);
SourceFiles.push_back(nullptr);
@@ -101,14 +104,15 @@ SymbolCache::createGlobalsEnumerator(codeview::SymbolKind Kind) {
}
SymIndexId SymbolCache::createSimpleType(TypeIndex Index,
- ModifierOptions Mods) {
+ ModifierOptions Mods) const {
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; });
+ const auto It =
+ llvm::find_if(BuiltinTypes, [Kind](const BuiltinTypeEntry &Builtin) {
+ return Builtin.Kind == Kind;
+ });
if (It == std::end(BuiltinTypes))
return 0;
return createSymbol<NativeTypeBuiltin>(Mods, It->Type, It->Size);
@@ -116,7 +120,7 @@ SymIndexId SymbolCache::createSimpleType(TypeIndex Index,
SymIndexId
SymbolCache::createSymbolForModifiedType(codeview::TypeIndex ModifierTI,
- codeview::CVType CVT) {
+ codeview::CVType CVT) const {
ModifierRecord Record;
if (auto EC = TypeDeserializer::deserializeAs<ModifierRecord>(CVT, Record)) {
consumeError(std::move(EC));
@@ -146,7 +150,7 @@ SymbolCache::createSymbolForModifiedType(codeview::TypeIndex ModifierTI,
return 0;
}
-SymIndexId SymbolCache::findSymbolByTypeIndex(codeview::TypeIndex Index) {
+SymIndexId SymbolCache::findSymbolByTypeIndex(codeview::TypeIndex Index) const {
// First see if it's already in our cache.
const auto Entry = TypeIndexToSymbolId.find(Index);
if (Entry != TypeIndexToSymbolId.end())
@@ -243,7 +247,7 @@ SymbolCache::getSymbolById(SymIndexId SymbolId) const {
return nullptr;
// Make sure to handle the case where we've inserted a placeholder symbol
- // for types we don't yet suppport.
+ // for types we don't yet support.
NativeRawSymbol *NRS = Cache[SymbolId].get();
if (!NRS)
return nullptr;
@@ -288,39 +292,36 @@ SymIndexId SymbolCache::getOrCreateGlobalSymbolByOffset(uint32_t Offset) {
return Id;
}
-Expected<ModuleDebugStreamRef>
-SymbolCache::getModuleDebugStream(uint32_t Index) const {
- assert(Dbi && "Dbi stream not present");
-
- DbiModuleDescriptor Modi = Dbi->modules().getModuleDescriptor(Index);
-
- uint16_t ModiStream = Modi.getModuleStreamIndex();
- if (ModiStream == kInvalidStreamIndex)
- return make_error<RawError>("Module stream not present");
-
- std::unique_ptr<msf::MappedBlockStream> ModStreamData =
- Session.getPDBFile().createIndexedStream(ModiStream);
-
- ModuleDebugStreamRef ModS(Modi, std::move(ModStreamData));
- if (auto EC = ModS.reload())
- return std::move(EC);
+SymIndexId SymbolCache::getOrCreateInlineSymbol(InlineSiteSym Sym,
+ uint64_t ParentAddr,
+ uint16_t Modi,
+ uint32_t RecordOffset) const {
+ auto Iter = SymTabOffsetToSymbolId.find({Modi, RecordOffset});
+ if (Iter != SymTabOffsetToSymbolId.end())
+ return Iter->second;
- return std::move(ModS);
+ SymIndexId Id = createSymbol<NativeInlineSiteSymbol>(Sym, ParentAddr);
+ SymTabOffsetToSymbolId.insert({{Modi, RecordOffset}, Id});
+ return Id;
}
std::unique_ptr<PDBSymbol>
SymbolCache::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
PDB_SymType Type) {
- if (AddrToModuleIndex.empty())
- parseSectionContribs();
-
switch (Type) {
case PDB_SymType::Function:
return findFunctionSymbolBySectOffset(Sect, Offset);
case PDB_SymType::PublicSymbol:
return findPublicSymbolBySectOffset(Sect, Offset);
+ case PDB_SymType::Compiland: {
+ uint16_t Modi;
+ if (!Session.moduleIndexForSectOffset(Sect, Offset, Modi))
+ return nullptr;
+ return getOrCreateCompiland(Modi);
+ }
case PDB_SymType::None: {
- // FIXME: Implement for PDB_SymType::Data.
+ // FIXME: Implement for PDB_SymType::Data. The symbolizer calls this but
+ // only uses it to find the symbol length.
if (auto Sym = findFunctionSymbolBySectOffset(Sect, Offset))
return Sym;
return nullptr;
@@ -332,18 +333,19 @@ SymbolCache::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
std::unique_ptr<PDBSymbol>
SymbolCache::findFunctionSymbolBySectOffset(uint32_t Sect, uint32_t Offset) {
- auto Iter = AddressToFunctionSymId.find({Sect, Offset});
- if (Iter != AddressToFunctionSymId.end())
+ auto Iter = AddressToSymbolId.find({Sect, Offset});
+ if (Iter != AddressToSymbolId.end())
return getSymbolById(Iter->second);
if (!Dbi)
return nullptr;
- auto Modi = getModuleIndexForAddr(Session.getVAFromSectOffset(Sect, Offset));
- if (!Modi)
+ uint16_t Modi;
+ if (!Session.moduleIndexForSectOffset(Sect, Offset, Modi))
return nullptr;
- auto ExpectedModS = getModuleDebugStream(*Modi);
+ Expected<ModuleDebugStreamRef> ExpectedModS =
+ Session.getModuleDebugStream(Modi);
if (!ExpectedModS) {
consumeError(ExpectedModS.takeError());
return nullptr;
@@ -357,8 +359,14 @@ SymbolCache::findFunctionSymbolBySectOffset(uint32_t Sect, uint32_t Offset) {
auto PS = cantFail(SymbolDeserializer::deserializeAs<ProcSym>(*I));
if (Sect == PS.Segment && Offset >= PS.CodeOffset &&
Offset < PS.CodeOffset + PS.CodeSize) {
- SymIndexId Id = createSymbol<NativeFunctionSymbol>(PS);
- AddressToFunctionSymId.insert({{Sect, Offset}, Id});
+ // Check if the symbol is already cached.
+ auto Found = AddressToSymbolId.find({PS.Segment, PS.CodeOffset});
+ if (Found != AddressToSymbolId.end())
+ return getSymbolById(Found->second);
+
+ // Otherwise, create a new symbol.
+ SymIndexId Id = createSymbol<NativeFunctionSymbol>(PS, I.offset());
+ AddressToSymbolId.insert({{PS.Segment, PS.CodeOffset}, Id});
return getSymbolById(Id);
}
@@ -418,9 +426,16 @@ SymbolCache::findPublicSymbolBySectOffset(uint32_t Sect, uint32_t Offset) {
consumeError(Sym.takeError());
return nullptr;
}
+
+ // Check if the symbol is already cached.
auto PS = cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym.get()));
+ auto Found = AddressToPublicSymId.find({PS.Segment, PS.Offset});
+ if (Found != AddressToPublicSymId.end())
+ return getSymbolById(Found->second);
+
+ // Otherwise, create a new symbol.
SymIndexId Id = createSymbol<NativePublicSymbol>(PS);
- AddressToPublicSymId.insert({{Sect, Offset}, Id});
+ AddressToPublicSymId.insert({{PS.Segment, PS.Offset}, Id});
return getSymbolById(Id);
}
@@ -435,7 +450,8 @@ SymbolCache::findLineTable(uint16_t Modi) const {
// If there is an error or there are no lines, just return the
// empty vector.
- Expected<ModuleDebugStreamRef> ExpectedModS = getModuleDebugStream(Modi);
+ Expected<ModuleDebugStreamRef> ExpectedModS =
+ Session.getModuleDebugStream(Modi);
if (!ExpectedModS) {
consumeError(ExpectedModS.takeError());
return ModuleLineTable;
@@ -466,11 +482,19 @@ SymbolCache::findLineTable(uint16_t Modi) const {
auto ColIt = Group.Columns.begin();
auto ColsEnd = Group.Columns.end();
+ // Add a line to mark the beginning of this section.
+ uint64_t StartAddr =
+ Session.getVAFromSectOffset(RelocSegment, RelocOffset);
+ LineInfo FirstLine(Group.LineNumbers.front().Flags);
+ uint32_t ColNum =
+ (Lines.hasColumnInfo()) ? Group.Columns.front().StartColumn : 0;
+ Entries.push_back({StartAddr, FirstLine, ColNum, Group.NameIndex, false});
+
for (const LineNumberEntry &LN : Group.LineNumbers) {
uint64_t VA =
Session.getVAFromSectOffset(RelocSegment, RelocOffset + LN.Offset);
LineInfo Line(LN.Flags);
- uint32_t ColNum = 0;
+ ColNum = 0;
if (Lines.hasColumnInfo() && ColIt != ColsEnd) {
ColNum = ColIt->StartColumn;
@@ -480,36 +504,31 @@ SymbolCache::findLineTable(uint16_t Modi) const {
}
// Add a terminal entry line to mark the end of this subsection.
- uint64_t VA = Session.getVAFromSectOffset(
- RelocSegment, RelocOffset + Lines.header()->CodeSize);
+ uint64_t EndAddr = StartAddr + Lines.header()->CodeSize;
LineInfo LastLine(Group.LineNumbers.back().Flags);
- uint32_t ColNum =
- (Lines.hasColumnInfo()) ? Group.Columns.back().StartColumn : 0;
- Entries.push_back({VA, LastLine, ColNum, Group.NameIndex, true});
+ ColNum = (Lines.hasColumnInfo()) ? Group.Columns.back().StartColumn : 0;
+ Entries.push_back({EndAddr, LastLine, ColNum, Group.NameIndex, true});
EntryList.push_back(Entries);
}
}
// Sort EntryList, and add flattened contents to the line table.
- std::sort(EntryList.begin(), EntryList.end(),
- [](const std::vector<LineTableEntry> &LHS,
- const std::vector<LineTableEntry> &RHS) {
- return LHS[0].Addr < RHS[0].Addr;
- });
+ llvm::sort(EntryList, [](const std::vector<LineTableEntry> &LHS,
+ const std::vector<LineTableEntry> &RHS) {
+ return LHS[0].Addr < RHS[0].Addr;
+ });
for (size_t I = 0; I < EntryList.size(); ++I)
- ModuleLineTable.insert(ModuleLineTable.end(), EntryList[I].begin(),
- EntryList[I].end());
+ llvm::append_range(ModuleLineTable, EntryList[I]);
return ModuleLineTable;
}
std::unique_ptr<IPDBEnumLineNumbers>
SymbolCache::findLineNumbersByVA(uint64_t VA, uint32_t Length) const {
- Optional<uint16_t> MaybeModi = getModuleIndexForAddr(VA);
- if (!MaybeModi)
+ uint16_t Modi;
+ if (!Session.moduleIndexForVA(VA, Modi))
return nullptr;
- uint16_t Modi = *MaybeModi;
std::vector<LineTableEntry> Lines = findLineTable(Modi);
if (Lines.empty())
@@ -528,7 +547,8 @@ SymbolCache::findLineNumbersByVA(uint64_t VA, uint32_t Length) const {
--LineIter;
}
- Expected<ModuleDebugStreamRef> ExpectedModS = getModuleDebugStream(Modi);
+ Expected<ModuleDebugStreamRef> ExpectedModS =
+ Session.getModuleDebugStream(Modi);
if (!ExpectedModS) {
consumeError(ExpectedModS.takeError());
return nullptr;
@@ -542,34 +562,8 @@ SymbolCache::findLineNumbersByVA(uint64_t VA, uint32_t Length) const {
// Populate a vector of NativeLineNumbers that have addresses in the given
// address range.
- Optional<uint16_t> EndModi = getModuleIndexForAddr(VA + Length);
- if (!EndModi)
- return nullptr;
std::vector<NativeLineNumber> LineNumbers;
- while (Modi <= *EndModi) {
- // If we reached the end of the current module, increment Modi and get the
- // new line table and checksums array.
- if (LineIter == Lines.end()) {
- ++Modi;
-
- ExpectedModS = getModuleDebugStream(Modi);
- if (!ExpectedModS) {
- consumeError(ExpectedModS.takeError());
- break;
- }
- ExpectedChecksums = ExpectedModS->findChecksumsSubsection();
- if (!ExpectedChecksums) {
- consumeError(ExpectedChecksums.takeError());
- break;
- }
-
- Lines = findLineTable(Modi);
- LineIter = Lines.begin();
-
- if (Lines.empty())
- continue;
- }
-
+ while (LineIter != Lines.end()) {
if (LineIter->IsTerminalEntry) {
++LineIter;
continue;
@@ -587,7 +581,7 @@ SymbolCache::findLineNumbersByVA(uint64_t VA, uint32_t Length) const {
ExpectedChecksums->getArray().at(LineIter->FileNameIndex);
uint32_t SrcFileId = getOrCreateSourceFile(*ChecksumIter);
NativeLineNumber LineNum(Session, LineIter->Line, LineIter->ColumnNumber,
- LineSect, LineOff, LineLength, SrcFileId);
+ LineSect, LineOff, LineLength, SrcFileId, Modi);
LineNumbers.push_back(LineNum);
++LineIter;
}
@@ -636,39 +630,4 @@ SymbolCache::getOrCreateSourceFile(const FileChecksumEntry &Checksums) const {
return Id;
}
-void SymbolCache::parseSectionContribs() {
- if (!Dbi)
- return;
- class Visitor : public ISectionContribVisitor {
- NativeSession &Session;
- IMap &AddrMap;
-
- public:
- Visitor(NativeSession &Session, IMap &AddrMap)
- : Session(Session), AddrMap(AddrMap) {}
- void visit(const SectionContrib &C) override {
- if (C.Size == 0)
- return;
-
- uint64_t VA = Session.getVAFromSectOffset(C.ISect, C.Off);
- uint64_t End = VA + C.Size;
-
- // Ignore overlapping sections based on the assumption that a valid
- // PDB file should not have overlaps.
- if (!AddrMap.overlaps(VA, End))
- AddrMap.insert(VA, End, C.Imod);
- }
- void visit(const SectionContrib2 &C) override { visit(C.Base); }
- };
-
- Visitor V(Session, AddrToModuleIndex);
- Dbi->visitSectionContributions(V);
-}
-
-Optional<uint16_t> SymbolCache::getModuleIndexForAddr(uint64_t Addr) const {
- auto Iter = AddrToModuleIndex.find(Addr);
- if (Iter == AddrToModuleIndex.end())
- return None;
- return Iter.value();
-}
diff --git a/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
index 51a1f0a544e3..5f4f497690b6 100644
--- a/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
@@ -25,6 +25,7 @@
#include "llvm/Support/Error.h"
#include <algorithm>
#include <cstdint>
+#include <numeric>
using namespace llvm;
using namespace llvm::msf;
@@ -41,39 +42,68 @@ void TpiStreamBuilder::setVersionHeader(PdbRaw_TpiVer Version) {
VerHeader = Version;
}
+void TpiStreamBuilder::updateTypeIndexOffsets(ArrayRef<uint16_t> Sizes) {
+ // If we just crossed an 8KB threshold, add a type index offset.
+ for (uint16_t Size : Sizes) {
+ size_t NewSize = TypeRecordBytes + Size;
+ constexpr size_t EightKB = 8 * 1024;
+ if (NewSize / EightKB > TypeRecordBytes / EightKB || TypeRecordCount == 0) {
+ TypeIndexOffsets.push_back(
+ {codeview::TypeIndex(codeview::TypeIndex::FirstNonSimpleIndex +
+ TypeRecordCount),
+ ulittle32_t(TypeRecordBytes)});
+ }
+ ++TypeRecordCount;
+ TypeRecordBytes = NewSize;
+ }
+}
+
void TpiStreamBuilder::addTypeRecord(ArrayRef<uint8_t> Record,
Optional<uint32_t> Hash) {
- // If we just crossed an 8KB threshold, add a type index offset.
assert(((Record.size() & 3) == 0) &&
"The type record's size is not a multiple of 4 bytes which will "
"cause misalignment in the output TPI stream!");
- size_t NewSize = TypeRecordBytes + Record.size();
- constexpr size_t EightKB = 8 * 1024;
- if (NewSize / EightKB > TypeRecordBytes / EightKB || TypeRecords.empty()) {
- TypeIndexOffsets.push_back(
- {codeview::TypeIndex(codeview::TypeIndex::FirstNonSimpleIndex +
- TypeRecords.size()),
- ulittle32_t(TypeRecordBytes)});
- }
- TypeRecordBytes = NewSize;
+ assert(Record.size() <= codeview::MaxRecordLength);
+ uint16_t OneSize = (uint16_t)Record.size();
+ updateTypeIndexOffsets(makeArrayRef(&OneSize, 1));
- TypeRecords.push_back(Record);
+ TypeRecBuffers.push_back(Record);
+ // FIXME: Require it.
if (Hash)
TypeHashes.push_back(*Hash);
}
+void TpiStreamBuilder::addTypeRecords(ArrayRef<uint8_t> Types,
+ ArrayRef<uint16_t> Sizes,
+ ArrayRef<uint32_t> Hashes) {
+ // Ignore empty type buffers. There should be no hashes or sizes in this case.
+ if (Types.empty()) {
+ assert(Sizes.empty() && Hashes.empty());
+ return;
+ }
+
+ assert(((Types.size() & 3) == 0) &&
+ "The type record's size is not a multiple of 4 bytes which will "
+ "cause misalignment in the output TPI stream!");
+ assert(Sizes.size() == Hashes.size() && "sizes and hashes should be in sync");
+ assert(std::accumulate(Sizes.begin(), Sizes.end(), 0U) == Types.size() &&
+ "sizes of type records should sum to the size of the types");
+ updateTypeIndexOffsets(Sizes);
+
+ TypeRecBuffers.push_back(Types);
+ llvm::append_range(TypeHashes, Hashes);
+}
+
Error TpiStreamBuilder::finalize() {
if (Header)
return Error::success();
TpiStreamHeader *H = Allocator.Allocate<TpiStreamHeader>();
- uint32_t Count = TypeRecords.size();
-
H->Version = VerHeader;
H->HeaderSize = sizeof(TpiStreamHeader);
H->TypeIndexBegin = codeview::TypeIndex::FirstNonSimpleIndex;
- H->TypeIndexEnd = H->TypeIndexBegin + Count;
+ H->TypeIndexEnd = H->TypeIndexBegin + TypeRecordCount;
H->TypeRecordBytes = TypeRecordBytes;
H->HashStreamIndex = HashStreamIndex;
@@ -104,7 +134,7 @@ uint32_t TpiStreamBuilder::calculateSerializedLength() {
}
uint32_t TpiStreamBuilder::calculateHashBufferSize() const {
- assert((TypeRecords.size() == TypeHashes.size() || TypeHashes.empty()) &&
+ assert((TypeRecordCount == TypeHashes.size() || TypeHashes.empty()) &&
"either all or no type records should have hashes");
return TypeHashes.size() * sizeof(ulittle32_t);
}
@@ -155,7 +185,7 @@ Error TpiStreamBuilder::commit(const msf::MSFLayout &Layout,
if (auto EC = Writer.writeObject(*Header))
return EC;
- for (auto Rec : TypeRecords) {
+ for (auto Rec : TypeRecBuffers) {
assert(!Rec.empty() && "Attempting to write an empty type record shifts "
"all offsets in the TPI stream!");
assert(((Rec.size() & 3) == 0) &&
diff --git a/llvm/lib/DebugInfo/PDB/PDBContext.cpp b/llvm/lib/DebugInfo/PDB/PDBContext.cpp
index e452f1d4ced7..0ebb70e010d5 100644
--- a/llvm/lib/DebugInfo/PDB/PDBContext.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBContext.cpp
@@ -86,8 +86,43 @@ DIInliningInfo
PDBContext::getInliningInfoForAddress(object::SectionedAddress Address,
DILineInfoSpecifier Specifier) {
DIInliningInfo InlineInfo;
- DILineInfo Frame = getLineInfoForAddress(Address, Specifier);
- InlineInfo.addFrame(Frame);
+ DILineInfo CurrentLine = getLineInfoForAddress(Address, Specifier);
+
+ // Find the function at this address.
+ std::unique_ptr<PDBSymbol> ParentFunc =
+ Session->findSymbolByAddress(Address.Address, PDB_SymType::Function);
+ if (!ParentFunc) {
+ InlineInfo.addFrame(CurrentLine);
+ return InlineInfo;
+ }
+
+ auto Frames = ParentFunc->findInlineFramesByVA(Address.Address);
+ if (!Frames || Frames->getChildCount() == 0) {
+ InlineInfo.addFrame(CurrentLine);
+ return InlineInfo;
+ }
+
+ while (auto Frame = Frames->getNext()) {
+ uint32_t Length = 1;
+ auto LineNumbers = Frame->findInlineeLinesByVA(Address.Address, Length);
+ if (!LineNumbers || LineNumbers->getChildCount() == 0)
+ break;
+
+ std::unique_ptr<IPDBLineNumber> Line = LineNumbers->getNext();
+ assert(Line);
+
+ DILineInfo LineInfo;
+ LineInfo.FunctionName = Frame->getName();
+ auto SourceFile = Session->getSourceFileById(Line->getSourceFileId());
+ if (SourceFile &&
+ Specifier.FLIKind != DILineInfoSpecifier::FileLineInfoKind::None)
+ LineInfo.FileName = SourceFile->getFileName();
+ LineInfo.Line = Line->getLineNumber();
+ LineInfo.Column = Line->getColumnNumber();
+ InlineInfo.addFrame(LineInfo);
+ }
+
+ InlineInfo.addFrame(CurrentLine);
return InlineInfo;
}
diff --git a/llvm/lib/DebugInfo/PDB/PDBExtras.cpp b/llvm/lib/DebugInfo/PDB/PDBExtras.cpp
index 354a99476c4b..25962e5152eb 100644
--- a/llvm/lib/DebugInfo/PDB/PDBExtras.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBExtras.cpp
@@ -118,7 +118,21 @@ raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const PDB_DataKind &Data) {
raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
const llvm::codeview::CPURegister &CpuReg) {
- if (CpuReg.Cpu == llvm::codeview::CPUType::ARM64) {
+ if (CpuReg.Cpu == llvm::codeview::CPUType::ARMNT) {
+ switch (CpuReg.Reg) {
+#define CV_REGISTERS_ARM
+#define CV_REGISTER(name, val) \
+ case codeview::RegisterId::name: \
+ OS << #name; \
+ return OS;
+#include "llvm/DebugInfo/CodeView/CodeViewRegisters.def"
+#undef CV_REGISTER
+#undef CV_REGISTERS_ARM
+
+ default:
+ break;
+ }
+ } else if (CpuReg.Cpu == llvm::codeview::CPUType::ARM64) {
switch (CpuReg.Reg) {
#define CV_REGISTERS_ARM64
#define CV_REGISTER(name, val) \
diff --git a/llvm/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp b/llvm/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp
index 8eb3311b09e3..d51091d80933 100644
--- a/llvm/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp
@@ -1,4 +1,4 @@
-//===- PDBInterfaceAnchors.h - defines class anchor funcions ----*- C++ -*-===//
+//===- PDBInterfaceAnchors.h - defines class anchor functions ---*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
// Class anchors are necessary per the LLVM Coding style guide, to ensure that
// the vtable is only generated in this object file, and not in every object
-// file that incldues the corresponding header.
+// file that includes the corresponding header.
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/IPDBDataStream.h"
diff --git a/llvm/lib/DebugInfo/PDB/PDBSymbol.cpp b/llvm/lib/DebugInfo/PDB/PDBSymbol.cpp
index 34c8ac41d45b..d6bc7ee9c951 100644
--- a/llvm/lib/DebugInfo/PDB/PDBSymbol.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDBSymbol.cpp
@@ -161,10 +161,27 @@ PDBSymbol::findChildrenByRVA(PDB_SymType Type, StringRef Name,
}
std::unique_ptr<IPDBEnumSymbols>
+PDBSymbol::findInlineFramesByVA(uint64_t VA) const {
+ return RawSymbol->findInlineFramesByVA(VA);
+}
+
+std::unique_ptr<IPDBEnumSymbols>
PDBSymbol::findInlineFramesByRVA(uint32_t RVA) const {
return RawSymbol->findInlineFramesByRVA(RVA);
}
+std::unique_ptr<IPDBEnumLineNumbers>
+PDBSymbol::findInlineeLinesByVA(uint64_t VA, uint32_t Length) const {
+ return RawSymbol->findInlineeLinesByVA(VA, Length);
+}
+
+std::unique_ptr<IPDBEnumLineNumbers>
+PDBSymbol::findInlineeLinesByRVA(uint32_t RVA, uint32_t Length) const {
+ return RawSymbol->findInlineeLinesByRVA(RVA, Length);
+}
+
+std::string PDBSymbol::getName() const { return RawSymbol->getName(); }
+
std::unique_ptr<IPDBEnumSymbols>
PDBSymbol::getChildStats(TagStats &Stats) const {
std::unique_ptr<IPDBEnumSymbols> Result(findAllChildren());
diff --git a/llvm/lib/DebugInfo/PDB/UDTLayout.cpp b/llvm/lib/DebugInfo/PDB/UDTLayout.cpp
index a8e1d0a619ca..55854bb49888 100644
--- a/llvm/lib/DebugInfo/PDB/UDTLayout.cpp
+++ b/llvm/lib/DebugInfo/PDB/UDTLayout.cpp
@@ -289,10 +289,10 @@ void UDTLayoutBase::addChildToLayout(std::unique_ptr<LayoutItemBase> Child) {
UsedBytes |= ChildBytes;
if (ChildBytes.count() > 0) {
- auto Loc = std::upper_bound(LayoutItems.begin(), LayoutItems.end(), Begin,
- [](uint32_t Off, const LayoutItemBase *Item) {
- return (Off < Item->getOffsetInParent());
- });
+ auto Loc = llvm::upper_bound(
+ LayoutItems, Begin, [](uint32_t Off, const LayoutItemBase *Item) {
+ return (Off < Item->getOffsetInParent());
+ });
LayoutItems.insert(Loc, Child.get());
}
diff --git a/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp b/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
index 10352237763c..01dc31d84965 100644
--- a/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
@@ -84,8 +84,10 @@ void DIPrinter::print(const DILineInfo &Info, bool Inlined) {
return;
}
OS << " Filename: " << Filename << "\n";
- if (Info.StartLine)
- OS << "Function start line: " << Info.StartLine << "\n";
+ if (Info.StartLine) {
+ OS << " Function start filename: " << Info.StartFileName << "\n";
+ OS << " Function start line: " << Info.StartLine << "\n";
+ }
OS << " Line: " << Info.Line << "\n";
OS << " Column: " << Info.Column << "\n";
if (Info.Discriminator)
diff --git a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
index 84524195fa8a..93d05e4e27bf 100644
--- a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
@@ -12,24 +12,15 @@
#include "SymbolizableObjectFile.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/BinaryFormat/COFF.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
-#include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/SymbolSize.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/DataExtractor.h"
-#include "llvm/Support/Error.h"
#include <algorithm>
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <system_error>
-#include <utility>
-#include <vector>
using namespace llvm;
using namespace object;
diff --git a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
index 0ba304ee4c61..be3c66df056f 100644
--- a/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
+++ b/llvm/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
@@ -15,12 +15,12 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
-#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/Error.h"
#include <cstdint>
-#include <map>
#include <memory>
#include <string>
-#include <system_error>
+#include <utility>
+#include <vector>
namespace llvm {
diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
index 1d767a2b0d88..da157a5a2554 100644
--- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
@@ -16,6 +16,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/Config/config.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/PDB/PDB.h"
#include "llvm/DebugInfo/PDB/PDBContext.h"
@@ -286,10 +287,8 @@ bool darwinDsymMatchesBinary(const MachOObjectFile *DbgObj,
}
template <typename ELFT>
-Optional<ArrayRef<uint8_t>> getBuildID(const ELFFile<ELFT> *Obj) {
- if (!Obj)
- return {};
- auto PhdrsOrErr = Obj->program_headers();
+Optional<ArrayRef<uint8_t>> getBuildID(const ELFFile<ELFT> &Obj) {
+ auto PhdrsOrErr = Obj.program_headers();
if (!PhdrsOrErr) {
consumeError(PhdrsOrErr.takeError());
return {};
@@ -298,7 +297,7 @@ Optional<ArrayRef<uint8_t>> getBuildID(const ELFFile<ELFT> *Obj) {
if (P.p_type != ELF::PT_NOTE)
continue;
Error Err = Error::success();
- for (auto N : Obj->notes(P, Err))
+ for (auto N : Obj.notes(P, Err))
if (N.getType() == ELF::NT_GNU_BUILD_ID && N.getName() == ELF::ELF_NOTE_GNU)
return N.getDesc();
consumeError(std::move(Err));
@@ -555,9 +554,9 @@ LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) {
if (!EC && DebugInfo != nullptr && !PDBFileName.empty()) {
using namespace pdb;
std::unique_ptr<IPDBSession> Session;
- PDB_ReaderType ReaderType = Opts.UseNativePDBReader
- ? PDB_ReaderType::Native
- : PDB_ReaderType::DIA;
+
+ PDB_ReaderType ReaderType =
+ Opts.UseDIA ? PDB_ReaderType::DIA : PDB_ReaderType::Native;
if (auto Err = loadDataForEXE(ReaderType, Objects.first->getFileName(),
Session)) {
Modules.emplace(ModuleName, std::unique_ptr<SymbolizableModule>());
@@ -590,10 +589,8 @@ StringRef demanglePE32ExternCFunc(StringRef SymbolName) {
if (Front != '?') {
size_t AtPos = SymbolName.rfind('@');
if (AtPos != StringRef::npos &&
- std::all_of(SymbolName.begin() + AtPos + 1, SymbolName.end(),
- [](char C) { return C >= '0' && C <= '9'; })) {
+ all_of(drop_begin(SymbolName, AtPos + 1), isDigit))
SymbolName = SymbolName.substr(0, AtPos);
- }
}
// Remove any ending '@' for vectorcall.