namespace llvm {
-struct BaseAddress;
class raw_ostream;
class DWARFDebugRangeList {
/// list. Has to be passed base address of the compile unit referencing this
/// range list.
DWARFAddressRangesVector
- getAbsoluteRanges(llvm::Optional<BaseAddress> BaseAddr) const;
+ getAbsoluteRanges(llvm::Optional<SectionedAddress> BaseAddr) const;
};
} // end namespace llvm
public:
/// Build a DWARFAddressRangesVector from a rangelist.
DWARFAddressRangesVector
- getAbsoluteRanges(llvm::Optional<BaseAddress> BaseAddr) const;
+ getAbsoluteRanges(llvm::Optional<SectionedAddress> BaseAddr) const;
};
class DWARFDebugRnglistTable : public DWARFListTableBase<DWARFDebugRnglist> {
Optional<int64_t> getAsSignedConstant() const;
Optional<const char *> getAsCString() const;
Optional<uint64_t> getAsAddress() const;
+ Optional<SectionedAddress> getAsSectionedAddress() const;
Optional<uint64_t> getAsSectionOffset() const;
Optional<ArrayRef<uint8_t>> getAsBlock() const;
Optional<uint64_t> getAsCStringOffset() const;
return None;
}
+inline Optional<SectionedAddress>
+toSectionedAddress(const Optional<DWARFFormValue> &V) {
+ if (V)
+ return V->getAsSectionedAddress();
+ return None;
+}
+
/// Take an optional DWARFFormValue and extract a address.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
bool IsNameUnique;
};
+struct SectionedAddress {
+ uint64_t Address;
+ uint64_t SectionIndex;
+};
+
} // end namespace llvm
#endif // LLVM_DEBUGINFO_DWARF_DWARFSECTION_H
};
/// Represents base address of the CU.
-struct BaseAddress {
- uint64_t Address;
- uint64_t SectionIndex;
-};
-
/// Represents a unit's contribution to the string offsets table.
struct StrOffsetsContributionDescriptor {
uint64_t Base = 0;
Optional<DWARFDebugRnglistTable> RngListTable;
mutable const DWARFAbbreviationDeclarationSet *Abbrevs;
- llvm::Optional<BaseAddress> BaseAddr;
+ llvm::Optional<SectionedAddress> BaseAddr;
/// The compile unit debug information entry items.
std::vector<DWARFDebugInfoEntry> DieArray;
RangeSectionBase = Base;
}
- bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
+ Optional<SectionedAddress> getAddrOffsetSectionItem(uint32_t Index) const;
bool getStringOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
DWARFDataExtractor getDebugInfoExtractor() const;
llvm_unreachable("Invalid UnitType.");
}
- llvm::Optional<BaseAddress> getBaseAddress();
+ llvm::Optional<SectionedAddress> getBaseAddress();
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) {
extractDIEsIfNeeded(ExtractUnitDIEOnly);
// Emit addresses into the section given.
void AddressPool::emit(AsmPrinter &Asm, MCSection *AddrSection) {
+ if (isEmpty())
+ return;
+
// Start the dwarf addr section.
Asm.OutStreamer->SwitchSection(AddrSection);
// It is referenced via DW_AT_addr_base.
Asm.OutStreamer->EmitLabel(AddressTableBaseSym);
- if (Pool.empty())
- return;
-
// Order the address pool entries by ID
SmallVector<const MCExpr *, 64> Entries(Pool.size());
case dwarf::DW_FORM_GNU_addr_index:
case dwarf::DW_FORM_ref_udata:
case dwarf::DW_FORM_strx:
+ case dwarf::DW_FORM_addrx:
case dwarf::DW_FORM_udata:
Asm->EmitULEB128(Integer);
return;
case dwarf::DW_FORM_GNU_addr_index:
case dwarf::DW_FORM_ref_udata:
case dwarf::DW_FORM_strx:
+ case dwarf::DW_FORM_addrx:
case dwarf::DW_FORM_udata:
return getULEB128Size(Integer);
case dwarf::DW_FORM_sdata:
// pool from the skeleton - maybe even in non-fission (possibly fewer
// relocations by sharing them in the pool, but we have other ideas about how
// to reduce the number of relocations as well/instead).
- if (!DD->useSplitDwarf() || !Skeleton)
+ if ((!DD->useSplitDwarf() || !Skeleton) && DD->getDwarfVersion() < 5)
return addLocalLabelAddress(Die, Attribute, Label);
if (Label)
DD->addArangeLabel(SymbolCU(this, Label));
unsigned idx = DD->getAddressPool().getIndex(Label);
- Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_GNU_addr_index,
+ Die.addValue(DIEValueAllocator, Attribute,
+ DD->getDwarfVersion() >= 5 ? dwarf::DW_FORM_addrx
+ : dwarf::DW_FORM_GNU_addr_index,
DIEInteger(idx));
}
SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
dwarf::DW_FORM_data8, ID);
}
- // We don't keep track of which addresses are used in which CU so this
- // is a bit pessimistic under LTO.
- if (!AddrPool.isEmpty())
- SkCU->addAddrTableBase();
if (getDwarfVersion() < 5 && !SkCU->getRangeLists().empty()) {
const MCSymbol *Sym = TLOF.getDwarfRangesSection()->getBeginSymbol();
// .subsections_via_symbols in mach-o. This would mean turning on
// ranges for all subprogram DIEs for mach-o.
DwarfCompileUnit &U = SkCU ? *SkCU : TheCU;
+
+ // We don't keep track of which addresses are used in which CU so this
+ // is a bit pessimistic under LTO.
+ if (!AddrPool.isEmpty())
+ U.addAddrTableBase();
+
if (unsigned NumRanges = TheCU.getRanges().size()) {
if (NumRanges > 1 && useRangesSection())
// A DW_AT_low_pc attribute may also be specified in combination with
emitDebugInfoDWO();
emitDebugAbbrevDWO();
emitDebugLineDWO();
- emitDebugAddr();
}
+ emitDebugAddr();
+
// Emit info into the dwarf accelerator table sections.
switch (getAccelTableKind()) {
case AccelTableKind::Apple:
OffSec, /* UseRelativeOffsets = */ false);
}
-// Emit DWO addresses.
+// Emit address pool.
void DwarfDebug::emitDebugAddr() {
- assert(useSplitDwarf() && "No split dwarf?");
AddrPool.emit(*Asm, Asm->getObjFileLowering().getDwarfAddrSection());
}
void DwarfUnit::addAddrTableBase() {
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
MCSymbol *Label = DD->getAddressPool().getLabel();
- addSectionLabel(getUnitDie(), dwarf::DW_AT_GNU_addr_base, Label,
- TLOF.getDwarfAddrSection()->getBeginSymbol());
+ addSectionLabel(getUnitDie(),
+ getDwarfVersion() >= 5 ? dwarf::DW_AT_addr_base
+ : dwarf::DW_AT_GNU_addr_base,
+ Label, TLOF.getDwarfAddrSection()->getBeginSymbol());
}
}
DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges(
- llvm::Optional<BaseAddress> BaseAddr) const {
+ llvm::Optional<SectionedAddress> BaseAddr) const {
DWARFAddressRangesVector Res;
for (const RangeListEntry &RLE : Entries) {
if (RLE.isBaseAddressSelectionEntry(AddressSize)) {
}
DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
- llvm::Optional<BaseAddress> BaseAddr) const {
+ llvm::Optional<SectionedAddress> BaseAddr) const {
DWARFAddressRangesVector Res;
for (const RangeListEntry &RLE : Entries) {
if (RLE.EntryKind == dwarf::DW_RLE_end_of_list)
auto LL = DebugLoc.parseOneLocationList(Data, &Offset);
if (LL) {
uint64_t BaseAddr = 0;
- if (Optional<BaseAddress> BA = U->getBaseAddress())
+ if (Optional<SectionedAddress> BA = U->getBaseAddress())
BaseAddr = BA->Address;
LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, BaseAddr,
Indent);
break;
case DW_FORM_GNU_addr_index:
case DW_FORM_GNU_str_index:
+ case DW_FORM_addrx:
case DW_FORM_strx:
Value.uval = Data.getULEB128(OffsetPtr);
break;
case DW_FORM_addr:
AddrOS << format("0x%016" PRIx64, UValue);
break;
+ case DW_FORM_addrx:
+ case DW_FORM_addrx1:
+ case DW_FORM_addrx2:
+ case DW_FORM_addrx3:
+ case DW_FORM_addrx4:
case DW_FORM_GNU_addr_index: {
AddrOS << format(" indexed (%8.8x) address = ", (uint32_t)UValue);
- uint64_t Address;
if (U == nullptr)
OS << "<invalid dwarf unit>";
- else if (U->getAddrOffsetSectionItem(UValue, Address))
- AddrOS << format("0x%016" PRIx64, Address);
+ else if (Optional<SectionedAddress> A = U->getAddrOffsetSectionItem(UValue))
+ AddrOS << format("0x%016" PRIx64, A->Address);
else
OS << "<no .debug_addr section>";
break;
}
Optional<uint64_t> DWARFFormValue::getAsAddress() const {
+ if (auto SA = getAsSectionedAddress())
+ return SA->Address;
+ return None;
+}
+Optional<SectionedAddress> DWARFFormValue::getAsSectionedAddress() const {
if (!isFormClass(FC_Address))
return None;
- if (Form == DW_FORM_GNU_addr_index) {
+ if (Form == DW_FORM_GNU_addr_index || Form == DW_FORM_addrx) {
uint32_t Index = Value.uval;
- uint64_t Result;
- if (!U || !U->getAddrOffsetSectionItem(Index, Result))
+ if (!U)
+ return None;
+ Optional<SectionedAddress> SA = U->getAddrOffsetSectionItem(Index);
+ if (!SA)
return None;
- return Result;
+ return SA;
}
- return Value.uval;
+ return {{Value.uval, Value.SectionIndex}};
}
Optional<uint64_t> DWARFFormValue::getAsReference() const {
getAddressByteSize());
}
-bool DWARFUnit::getAddrOffsetSectionItem(uint32_t Index,
- uint64_t &Result) const {
+Optional<SectionedAddress>
+DWARFUnit::getAddrOffsetSectionItem(uint32_t Index) const {
uint32_t Offset = AddrOffsetSectionBase + Index * getAddressByteSize();
if (AddrOffsetSection->Data.size() < Offset + getAddressByteSize())
- return false;
+ return None;
DWARFDataExtractor DA(Context.getDWARFObj(), *AddrOffsetSection,
isLittleEndian, getAddressByteSize());
- Result = DA.getRelocatedAddress(&Offset);
- return true;
+ uint64_t Section;
+ uint64_t Address = DA.getRelocatedAddress(&Offset, &Section);
+ return {{Address, Section}};
}
bool DWARFUnit::getStringOffsetSectionItem(uint32_t Index,
if (!isDWO) {
assert(AddrOffsetSectionBase == 0);
assert(RangeSectionBase == 0);
- AddrOffsetSectionBase =
- toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base), 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);
}
return Abbrevs;
}
-llvm::Optional<BaseAddress> DWARFUnit::getBaseAddress() {
+llvm::Optional<SectionedAddress> DWARFUnit::getBaseAddress() {
if (BaseAddr)
return BaseAddr;
DWARFDie UnitDie = getUnitDIE();
Optional<DWARFFormValue> PC = UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc});
- if (Optional<uint64_t> Addr = toAddress(PC))
- BaseAddr = {*Addr, PC->getSectionIndex()};
-
+ BaseAddr = toSectionedAddress(PC);
return BaseAddr;
}
; DWARF5: DW_TAG_compile_unit
; DWARF5-NOT: DW_TAG_{{.*}}
; DWARF5: DW_AT_GNU_dwo_name{{.*}}test.dwo
-; DWARF5: DW_AT_GNU_addr_base{{.*}}0x00000008
+; DWARF5: DW_AT_addr_base{{.*}}0x00000008
+; DWARF5: DW_AT_low_pc [DW_FORM_addrx] ( indexed (00000000) address = 0x0000000000000000)
; DWARF5: .debug_addr contents:
; DWARF5-NEXT: 0x00000000: Addr Section: length = 0x0000000c, version = 0x0005, addr_size = 0x04, seg_size = 0x00
; DWARF5-NEXT: Addrs: [
; CHECK-NEXT: DW_AT_GNU_dwo_name
; CHECK-NEXT: DW_AT_comp_dir
; CHECK-NEXT: DW_AT_GNU_dwo_id
+; CHECK-NEXT: DW_AT_GNU_ranges_base
; CHECK-NEXT: DW_AT_GNU_addr_base [DW_FORM_sec_offset] (0x00000000)
; CHECK: .debug_info.dwo contents: