static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue, DWARFUnit *U, unsigned Indent, DIDumpOptions DumpOpts) { DWARFContext &Ctx = U->getContext(); const DWARFObject &Obj = Ctx.getDWARFObj(); const MCRegisterInfo *MRI = Ctx.getRegisterInfo(); if (FormValue.isFormClass(DWARFFormValue::FC_Block) || FormValue.isFormClass(DWARFFormValue::FC_Exprloc)) { ArrayRef<uint8_t> Expr = *FormValue.getAsBlock(); DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()), Ctx.isLittleEndian(), 0); DWARFExpression(Data, U->getVersion(), U->getAddressByteSize()) .print(OS, MRI); return; } FormValue.dump(OS, DumpOpts); if (FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) { const DWARFSection &LocSection = Obj.getLocSection(); const DWARFSection &LocDWOSection = Obj.getLocDWOSection(); uint32_t Offset = *FormValue.getAsSectionOffset(); if (!LocSection.Data.empty()) { DWARFDebugLoc DebugLoc; DWARFDataExtractor Data(Obj, LocSection, Ctx.isLittleEndian(), Obj.getAddressSize()); auto LL = DebugLoc.parseOneLocationList(Data, &Offset); if (LL) { uint64_t BaseAddr = 0; if (Optional<BaseAddress> BA = U->getBaseAddress()) BaseAddr = BA->Address; LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, BaseAddr, Indent); } else OS << "error extracting location list."; } else if (!LocDWOSection.Data.empty()) { DataExtractor Data(LocDWOSection.Data, Ctx.isLittleEndian(), 0); auto LL = DWARFDebugLocDWO::parseOneLocationList(Data, &Offset); if (LL) LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, Indent); else OS << "error extracting location list."; } } }
static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue, DWARFUnit *U, unsigned Indent, DIDumpOptions DumpOpts) { DWARFContext &Ctx = U->getContext(); const DWARFObject &Obj = Ctx.getDWARFObj(); const MCRegisterInfo *MRI = Ctx.getRegisterInfo(); if (FormValue.isFormClass(DWARFFormValue::FC_Block) || FormValue.isFormClass(DWARFFormValue::FC_Exprloc)) { ArrayRef<uint8_t> Expr = *FormValue.getAsBlock(); DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()), Ctx.isLittleEndian(), 0); DWARFExpression(Data, U->getVersion(), U->getAddressByteSize()) .print(OS, MRI, U); return; } FormValue.dump(OS, DumpOpts); if (FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) { uint32_t Offset = *FormValue.getAsSectionOffset(); if (!U->isDWOUnit() && !U->getLocSection()->Data.empty()) { DWARFDebugLoc DebugLoc; DWARFDataExtractor Data(Obj, *U->getLocSection(), Ctx.isLittleEndian(), Obj.getAddressSize()); auto LL = DebugLoc.parseOneLocationList(Data, &Offset); if (LL) { uint64_t BaseAddr = 0; if (Optional<object::SectionedAddress> BA = U->getBaseAddress()) BaseAddr = BA->Address; LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, U, BaseAddr, Indent); } else OS << "error extracting location list."; return; } bool UseLocLists = !U->isDWOUnit(); StringRef LoclistsSectionData = UseLocLists ? Obj.getLoclistsSection().Data : U->getLocSectionData(); if (!LoclistsSectionData.empty()) { DataExtractor Data(LoclistsSectionData, Ctx.isLittleEndian(), Obj.getAddressSize()); // Old-style location list were used in DWARF v4 (.debug_loc.dwo section). // Modern locations list (.debug_loclists) are used starting from v5. // Ideally we should take the version from the .debug_loclists section // header, but using CU's version for simplicity. auto LL = DWARFDebugLoclists::parseOneLocationList( Data, &Offset, UseLocLists ? U->getVersion() : 4); uint64_t BaseAddr = 0; if (Optional<object::SectionedAddress> BA = U->getBaseAddress()) BaseAddr = BA->Address; if (LL) LL->dump(OS, BaseAddr, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, U, Indent); else OS << "error extracting location list."; } } }