Commit 77cfcd75 authored by David Blaikie's avatar David Blaikie
Browse files

DebugInfo: Use loclistx for DWARFv5 location lists to reduce the number of relocations

This only implements the non-dwo part, but loclistx is necessary to use
location lists in DWARFv5, so it's a precursor to that work - and
generally reduces relocations (only using one reloc, then
indexes/relative offsets for all location list references) in non-split
DWARF.
parent 97c742e6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -188,6 +188,7 @@ public:
  ///
  /// \returns anm optional absolute section offset value for the attribute.
  Optional<uint64_t> getRangesBaseAttribute() const;
  Optional<uint64_t> getLocBaseAttribute() const;

  /// Get the DW_AT_high_pc attribute value as an address.
  ///
+16 −0
Original line number Diff line number Diff line
@@ -200,6 +200,8 @@ class DWARFUnit {
  const DWARFDebugAbbrev *Abbrev;
  const DWARFSection *RangeSection;
  uint64_t RangeSectionBase;
  const DWARFSection *LocSection;
  uint64_t LocSectionBase;

  /// Location table of this unit.
  std::unique_ptr<DWARFLocationTable> LocTable;
@@ -219,6 +221,7 @@ class DWARFUnit {

  /// A table of range lists (DWARF v5 and later).
  Optional<DWARFDebugRnglistTable> RngListTable;
  Optional<DWARFListTableHeader> LoclistTableHeader;

  mutable const DWARFAbbreviationDeclarationSet *Abbrevs;
  llvm::Optional<object::SectionedAddress> BaseAddr;
@@ -305,6 +308,14 @@ public:
    RangeSection = RS;
    RangeSectionBase = Base;
  }
  void setLocSection(const DWARFSection *LS, uint64_t Base) {
    LocSection = LS;
    LocSectionBase = Base;
  }

  uint64_t getLocSectionBase() const {
    return LocSectionBase;
  }

  Optional<object::SectionedAddress>
  getAddrOffsetSectionItem(uint32_t Index) const;
@@ -421,6 +432,11 @@ public:
    return None;
  }

  Optional<uint64_t> getLoclistOffset(uint32_t Index) {
    if (LoclistTableHeader)
      return LoclistTableHeader->getOffsetEntry(Index);
    return None;
  }
  Expected<DWARFAddressRangesVector> collectAddressRanges();

  /// Returns subprogram DIE with address range encompassing the provided
+6 −0
Original line number Diff line number Diff line
@@ -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());
+5 −2
Original line number Diff line number Diff line
@@ -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));
}

+4 −1
Original line number Diff line number Diff line
@@ -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;
}

Loading