aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/DebugInfo/DWARF
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/DebugInfo/DWARF')
-rw-r--r--contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp5
-rw-r--r--contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp7
-rw-r--r--contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp113
-rw-r--r--contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp14
-rw-r--r--contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp16
-rw-r--r--contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp3
-rw-r--r--contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp53
-rw-r--r--contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp3
-rw-r--r--contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp84
-rw-r--r--contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp14
-rw-r--r--contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp14
-rw-r--r--contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp7
-rw-r--r--contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp139
-rw-r--r--contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp39
-rw-r--r--contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp29
-rw-r--r--contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp8
-rw-r--r--contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp4
-rw-r--r--contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp9
-rw-r--r--contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp7
-rw-r--r--contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp194
-rw-r--r--contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp42
21 files changed, 449 insertions, 355 deletions
diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
index ddf307de2221..25d2e852a7fe 100644
--- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
+++ b/contrib/llvm-project/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/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
index 9bd134105c9b..2b08120ef4dc 100644
--- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
+++ b/contrib/llvm-project/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/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index bf6219497770..749d738af9c1 100644
--- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/contrib/llvm-project/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/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
index 886fe1dff976..da6f6ad903f4 100644
--- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
+++ b/contrib/llvm-project/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/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp
index c3b039b05f30..598e3ecee30e 100644
--- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp
+++ b/contrib/llvm-project/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;
@@ -141,11 +145,11 @@ Error DWARFDebugArangeSet::extract(DWARFDataExtractor data,
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 a premature terminator entry at offset 0x%" PRIx64,
- Offset, EntryOffset);
+ Offset, EntryOffset));
}
ArangeDescriptors.push_back(arangeDescriptor);
diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
index e8ed63075055..e0db469752cd 100644
--- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
+++ b/contrib/llvm-project/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/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
index 0a1b75592290..b74ecac681f3 100644
--- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
+++ b/contrib/llvm-project/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/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
index 87eab34d58ee..2b7d0c3363a1 100644
--- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
+++ b/contrib/llvm-project/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/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index 3ca21e97888c..bda41b1f34e9 100644
--- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/contrib/llvm-project/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/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
index f38126364401..cdffb36741c8 100644
--- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
+++ b/contrib/llvm-project/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/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
index f920d69cc43f..80ffd81b3403 100644
--- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
+++ b/contrib/llvm-project/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/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
index 1a1857d8cd79..dc7da5d9348f 100644
--- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
+++ b/contrib/llvm-project/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/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
index 9ae4c5b73ebe..d12acca1962e 100644
--- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
+++ b/contrib/llvm-project/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/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index 81a6b5dcd5e7..427f6f4942c3 100644
--- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/contrib/llvm-project/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/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
index de5e11e084f4..811716111be5 100644
--- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
+++ b/contrib/llvm-project/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/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp
index a7da5acc380b..7a84605211fb 100644
--- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp
+++ b/contrib/llvm-project/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/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
index 252b58e5a591..ace7000f07b2 100644
--- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
+++ b/contrib/llvm-project/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/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp
index 2124a49bef60..c876af1e9b51 100644
--- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp
+++ b/contrib/llvm-project/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/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
index c219f34bbc31..a301b65dd444 100644
--- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
+++ b/contrib/llvm-project/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/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index a6d44f04e468..8493950a29b2 100644
--- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/contrib/llvm-project/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();
- }
+ toSectionOffset(UnitDie.find(DW_AT_rnglists_base),
+ DWARFListTableHeader::getHeaderSize(
+ Header.getFormat())));
+ }
- // 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();
- }
+ 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);
- if (LocSection) {
- if (IsDWO)
- LoclistTableHeader.emplace(".debug_loclists.dwo", "locations");
- else
- LoclistTableHeader.emplace(".debug_loclists", "locations");
-
- 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/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index 3a83317a73a3..ac624ec8b80f 100644
--- a/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/contrib/llvm-project/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;
}