summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DIE.cpp6
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp7
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp5
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDie.cpp11
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp5
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp25
6 files changed, 56 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp
index f4134da48ca..c4d5b717b25 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp
@@ -798,6 +798,8 @@ void DIEBlock::print(raw_ostream &O) const {
//===----------------------------------------------------------------------===//
unsigned DIELocList::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
+ if (Form == dwarf::DW_FORM_loclistx)
+ return getULEB128Size(Index);
if (Form == dwarf::DW_FORM_data4)
return 4;
if (Form == dwarf::DW_FORM_sec_offset)
@@ -808,6 +810,10 @@ unsigned DIELocList::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
/// EmitValue - Emit label value.
///
void DIELocList::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
+ if (Form == dwarf::DW_FORM_loclistx) {
+ AP->EmitULEB128(Index);
+ return;
+ }
DwarfDebug *DD = AP->getDwarfDebug();
MCSymbol *Label = DD->getDebugLocs().getList(Index).Label;
AP->emitDwarfSymbolReference(Label, /*ForceOffset*/ DD->useSplitDwarf());
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index a61c98ec1c1..9578e01abdd 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -1220,8 +1220,11 @@ void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die,
/// Add a Dwarf loclistptr attribute data and value.
void DwarfCompileUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute,
unsigned Index) {
- dwarf::Form Form = DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset
- : dwarf::DW_FORM_data4;
+ dwarf::Form Form = dwarf::DW_FORM_data4;
+ if (DD->getDwarfVersion() == 4)
+ Form =dwarf::DW_FORM_sec_offset;
+ if (DD->getDwarfVersion() >= 5)
+ Form =dwarf::DW_FORM_loclistx;
Die.addValue(DIEValueAllocator, Attribute, Form, DIELocList(Index));
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index c240099910e..d9b5eb1d6d0 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -2323,9 +2323,12 @@ static MCSymbol *emitLoclistsTableHeader(AsmPrinter *Asm,
// FIXME: Generate the offsets table and use DW_FORM_loclistx with the
// DW_AT_loclists_base attribute. Until then set the number of offsets to 0.
Asm->OutStreamer->AddComment("Offset entry count");
- Asm->emitInt32(0);
+ Asm->emitInt32(DebugLocs.getLists().size());
Asm->OutStreamer->EmitLabel(DebugLocs.getSym());
+ for (const auto &List : DebugLocs.getLists())
+ Asm->EmitLabelDifference(List.Label, DebugLocs.getSym(), 4);
+
return TableEnd;
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index 49a7f7dc2a5..7fa72b1bb57 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -96,6 +96,13 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue,
uint64_t Offset = *FormValue.getAsSectionOffset();
+ if (FormValue.getForm() == DW_FORM_loclistx) {
+ FormValue.dump(OS, DumpOpts);
+ if (auto LoclistOffset = U->getLoclistOffset(Offset))
+ Offset = *LoclistOffset + U->getLocSectionBase();
+ else
+ return;
+ }
U->getLocationTable().dumpLocationList(&Offset, OS, U->getBaseAddress(),
MRI, U, LLDumpOpts, Indent);
return;
@@ -409,6 +416,10 @@ Optional<uint64_t> DWARFDie::getRangesBaseAttribute() const {
return toSectionOffset(find({DW_AT_rnglists_base, DW_AT_GNU_ranges_base}));
}
+Optional<uint64_t> DWARFDie::getLocBaseAttribute() const {
+ return toSectionOffset(find(DW_AT_loclists_base));
+}
+
Optional<uint64_t> DWARFDie::getHighPC(uint64_t LowPC) const {
if (auto FormValue = find(DW_AT_high_pc)) {
if (auto Address = FormValue->getAsAddress()) {
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp
index 26090638b34..820f530a3e3 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp
@@ -312,6 +312,7 @@ bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
case DW_FORM_udata:
case DW_FORM_ref_udata:
case DW_FORM_rnglistx:
+ case DW_FORM_loclistx:
Value.uval = Data.getULEB128(OffsetPtr);
break;
case DW_FORM_string:
@@ -551,6 +552,10 @@ void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
OS << format("indexed (0x%x) rangelist = ", (uint32_t)UValue);
break;
+ case DW_FORM_loclistx:
+ OS << format("indexed (0x%x) loclist = ", (uint32_t)UValue);
+ break;
+
// Should be formatted to 64-bit for DWARF64.
case DW_FORM_sec_offset:
AddrOS << format("0x%08x", (uint32_t)UValue);
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index e5cba5e50b3..2eb7d2f945a 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -352,6 +352,7 @@ void DWARFUnit::clear() {
Abbrevs = nullptr;
BaseAddr.reset();
RangeSectionBase = 0;
+ LocSectionBase = 0;
AddrOffsetSectionBase = 0;
clearDIEs(false);
DWO.reset();
@@ -442,11 +443,13 @@ Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
if (!IsDWO) {
assert(AddrOffsetSectionBase == 0);
assert(RangeSectionBase == 0);
+ assert(LocSectionBase == 0);
AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_addr_base), 0);
if (!AddrOffsetSectionBase)
AddrOffsetSectionBase =
toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base), 0);
RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);
+ LocSectionBase = toSectionOffset(UnitDie.find(DW_AT_loclists_base), 0);
}
// In general, in DWARF v5 and beyond we derive the start of the unit's
@@ -498,6 +501,28 @@ Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
if (IsDWO && RngListTable)
RangeSectionBase = RngListTable->getHeaderSize();
}
+
+ // FIXME: add loclists.dwo support
+ setLocSection(&Context.getDWARFObj().getLoclistsSection(),
+ toSectionOffset(UnitDie.find(DW_AT_loclists_base), 0));
+
+ if (LocSection->Data.size()) {
+ LoclistTableHeader.emplace(".debug_loclists", "locations");
+ uint64_t Offset = LocSectionBase;
+ uint64_t HeaderSize = DWARFListTableHeader::getHeaderSize(Header.getFormat());
+ 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 (Error E = LoclistTableHeader->extract(Data, &Offset))
+ return createStringError(errc::invalid_argument,
+ "parsing a loclist table: " +
+ toString(std::move(E)));
+ }
}
// Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
OpenPOWER on IntegriCloud