This patch adds support of DWARFv5 .debug_rnglists table.
As DWARFLinker resolves relocations, it is able to always
use DW_FORM_addr instead of DW_FORM_addrx. DW_FORM_addrx
helps to minimize number of relocations, it is also used for
split DWARF. Both of these cases are not relevant for the
DWARFLinker. Thus, this patch converts all DW_FORM_addrx
forms into the DW_FORM_addr. And, as the result, it converts
range lists of DW_FORM_rnglistx form into the DW_FORM_sec_offset.
For the --update case all DW_FORM_addrx, DW_FORM_rnglistx
are preserved as is.
Reviewed By: aprantl
Differential Revision: https://reviews.llvm.org/D143903
virtual void
emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table) = 0;
- /// Emit piece of .debug_ranges for \p Ranges.
+ /// Emit debug ranges(.debug_ranges, .debug_rnglists) header.
+ virtual MCSymbol *emitDwarfDebugRangeListHeader(const CompileUnit &Unit) = 0;
+
+ /// Emit debug ranges(.debug_ranges, .debug_rnglists) fragment.
virtual void
- emitDwarfDebugRangesTableFragment(const CompileUnit &Unit,
- const AddressRanges &LinkedRanges) = 0;
+ emitDwarfDebugRangeListFragment(const CompileUnit &Unit,
+ const AddressRanges &LinkedRanges,
+ PatchLocation Patch) = 0;
+
+ /// Emit debug ranges(.debug_ranges, .debug_rnglists) footer.
+ virtual void emitDwarfDebugRangeListFooter(const CompileUnit &Unit,
+ MCSymbol *EndLabel) = 0;
- /// Emit .debug_aranges entries for \p Unit and if \p DoRangesSection is true,
- /// also emit the .debug_ranges entries for the DW_TAG_compile_unit's
- /// DW_AT_ranges attribute.
- virtual void emitUnitRangesEntries(CompileUnit &Unit,
- bool DoRangesSection) = 0;
+ /// Emit .debug_aranges entries for \p Unit
+ virtual void
+ emitDwarfDebugArangesTable(const CompileUnit &Unit,
+ const AddressRanges &LinkedRanges) = 0;
/// Copy the .debug_line over to the updated binary while unobfuscating the
/// file names and directories.
/// Returns size of generated .debug_ranges section.
virtual uint64_t getRangesSectionSize() const = 0;
+ /// Returns size of generated .debug_rnglists section.
+ virtual uint64_t getRngListsSectionSize() const = 0;
+
/// Returns size of generated .debug_info section.
virtual uint64_t getDebugInfoSectionSize() const = 0;
/// Assign an abbreviation number to \p Abbrev
void assignAbbrev(DIEAbbrev &Abbrev);
- /// Compute and emit .debug_ranges section for \p Unit, and
- /// patch the attributes referencing it.
- void patchRangesForUnit(const CompileUnit &Unit, DWARFContext &Dwarf,
- const DWARFFile &File) const;
-
- /// Generate and emit the DW_AT_ranges attribute for a compile_unit if it had
- /// one.
- void generateUnitRanges(CompileUnit &Unit) const;
+ /// Compute and emit debug ranges(.debug_aranges, .debug_ranges,
+ /// .debug_rnglists) for \p Unit, patch the attributes referencing it.
+ void generateUnitRanges(CompileUnit &Unit, const DWARFFile &File) const;
/// Extract the line tables from the original dwarf, extract the relevant
/// parts according to the linked function ranges and emit the result in the
}
};
+using RngListAttributesTy = SmallVector<PatchLocation>;
+
/// Stores all information relating to a compile unit, be it in its original
/// instance in the object file to its brand new cloned and generated DIE tree.
class CompileUnit {
uint64_t getHighPc() const { return HighPc; }
bool hasLabelAt(uint64_t Addr) const { return Labels.count(Addr); }
- std::optional<PatchLocation> getUnitRangesAttribute() const {
- return UnitRangeAttribute;
- }
-
const RangesTy &getFunctionRanges() const { return Ranges; }
- const std::vector<PatchLocation> &getRangesAttributes() const {
- return RangeAttributes;
+ const RngListAttributesTy &getRangesAttributes() { return RangeAttributes; }
+
+ std::optional<PatchLocation> getUnitRangesAttribute() const {
+ return UnitRangeAttribute;
}
const std::vector<std::pair<PatchLocation, int64_t>> &
/// The DW_AT_low_pc of each DW_TAG_label.
SmallDenseMap<uint64_t, uint64_t, 1> Labels;
- /// DW_AT_ranges attributes to patch after we have gathered
- /// all the unit's function addresses.
+ /// 'rnglist'(DW_AT_ranges, DW_AT_start_scope) attributes to patch after
+ /// we have gathered all the unit's function addresses.
/// @{
- std::vector<PatchLocation> RangeAttributes;
+ RngListAttributesTy RangeAttributes;
std::optional<PatchLocation> UnitRangeAttribute;
/// @}
llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind,
StringRef Buffer, uint32_t Alignment, uint32_t Size);
- /// Emit piece of .debug_ranges for \p Ranges.
- virtual void
- emitDwarfDebugRangesTableFragment(const CompileUnit &Unit,
- const AddressRanges &LinkedRanges) override;
+ /// Emit debug ranges(.debug_ranges, .debug_rnglists) header.
+ MCSymbol *emitDwarfDebugRangeListHeader(const CompileUnit &Unit) override;
- /// Emit debug_aranges entries for \p Unit and if \p DoRangesSection is true,
- /// also emit the debug_ranges entries for the DW_TAG_compile_unit's
- /// DW_AT_ranges attribute.
- void emitUnitRangesEntries(CompileUnit &Unit, bool DoRangesSection) override;
+ /// Emit debug ranges(.debug_ranges, .debug_rnglists) fragment.
+ void emitDwarfDebugRangeListFragment(const CompileUnit &Unit,
+ const AddressRanges &LinkedRanges,
+ PatchLocation Patch) override;
+
+ /// Emit debug ranges(.debug_ranges, .debug_rnglists) footer.
+ void emitDwarfDebugRangeListFooter(const CompileUnit &Unit,
+ MCSymbol *EndLabel) override;
+
+ /// Emit .debug_aranges entries for \p Unit
+ void emitDwarfDebugArangesTable(const CompileUnit &Unit,
+ const AddressRanges &LinkedRanges) override;
uint64_t getRangesSectionSize() const override { return RangesSectionSize; }
+ uint64_t getRngListsSectionSize() const override {
+ return RngListsSectionSize;
+ }
+
/// Emit the debug_loc contribution for \p Unit by copying the entries from
/// \p Dwarf and offsetting them. Update the location attributes to point to
/// the new entries.
void emitMacroTableImpl(const DWARFDebugMacro *MacroTable,
const Offset2UnitMap &UnitMacroMap,
OffsetsStringPool &StringPool, uint64_t &OutOffset);
- void emitDwarfDebugArangesTable(const CompileUnit &Unit,
- const AddressRanges &LinkedRanges);
+
+ /// Emit piece of .debug_ranges for \p LinkedRanges.
+ void emitDwarfDebugRangesTableFragment(const CompileUnit &Unit,
+ const AddressRanges &LinkedRanges,
+ PatchLocation Patch);
+
+ /// Emit piece of .debug_rnglists for \p LinkedRanges.
+ void emitDwarfDebugRngListsTableFragment(const CompileUnit &Unit,
+ const AddressRanges &LinkedRanges,
+ PatchLocation Patch);
/// \defgroup MCObjects MC layer objects constructed by the streamer
/// @{
std::function<StringRef(StringRef Input)> Translator;
uint64_t RangesSectionSize = 0;
+ uint64_t RngListsSectionSize = 0;
uint64_t LocSectionSize = 0;
uint64_t LineSectionSize = 0;
uint64_t FrameSectionSize = 0;
dwarf::Form Form = AttrSpec.Form;
- // FIXME: Generation of DWARFv5 .debug_addr table is not supported yet.
- // Convert attribute into the dwarf::DW_FORM_addr.
+ // DWARFLinker does not use addrx forms since it generates relocated
+ // addresses. Replace DW_FORM_addrx with DW_FORM_addr here.
if (Form == dwarf::DW_FORM_addrx)
Form = dwarf::DW_FORM_addr;
return AttrSize;
}
- if (AttrSpec.Attr == dwarf::DW_AT_high_pc &&
- Die.getTag() == dwarf::DW_TAG_compile_unit) {
+ [[maybe_unused]] dwarf::Form OriginalForm = AttrSpec.Form;
+ if (AttrSpec.Form == dwarf::DW_FORM_rnglistx) {
+ // DWARFLinker does not generate .debug_addr table. Thus we need to change
+ // all "addrx" related forms to "addr" version. Change DW_FORM_rnglistx
+ // to DW_FORM_sec_offset here.
+ std::optional<uint64_t> Index = Val.getAsSectionOffset();
+ if (!Index) {
+ Linker.reportWarning("Cannot read the attribute. Dropping.", File,
+ &InputDIE);
+ return 0;
+ }
+ std::optional<uint64_t> Offset =
+ Unit.getOrigUnit().getRnglistOffset(*Index);
+ if (!Offset) {
+ Linker.reportWarning("Cannot read the attribute. Dropping.", File,
+ &InputDIE);
+ return 0;
+ }
+
+ Value = *Offset;
+ AttrSpec.Form = dwarf::DW_FORM_sec_offset;
+ AttrSize = Unit.getOrigUnit().getFormParams().getDwarfOffsetByteSize();
+ } else if (AttrSpec.Attr == dwarf::DW_AT_high_pc &&
+ Die.getTag() == dwarf::DW_TAG_compile_unit) {
std::optional<uint64_t> LowPC = Unit.getLowPc();
if (!LowPC)
return 0;
PatchLocation Patch =
Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
dwarf::Form(AttrSpec.Form), DIEInteger(Value));
- if (AttrSpec.Attr == dwarf::DW_AT_ranges) {
+ if (AttrSpec.Attr == dwarf::DW_AT_ranges ||
+ AttrSpec.Attr == dwarf::DW_AT_start_scope) {
Unit.noteRangeAttribute(Die, Patch);
Info.HasRanges = true;
}
-
// A more generic way to check for location attributes would be
// nice, but it's very unlikely that any other attribute needs a
// location list.
} else if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value)
Info.IsDeclaration = true;
+ // check that all dwarf::DW_FORM_rnglistx are handled previously.
+ assert((Info.HasRanges || (OriginalForm != dwarf::DW_FORM_rnglistx)) &&
+ "Unhandled DW_FORM_rnglistx attribute");
+
return AttrSize;
}
case dwarf::DW_FORM_sec_offset:
case dwarf::DW_FORM_flag:
case dwarf::DW_FORM_flag_present:
+ case dwarf::DW_FORM_rnglistx:
return cloneScalarAttribute(Die, InputDIE, File, Unit, AttrSpec, Val,
AttrSize, Info);
default:
case dwarf::DW_AT_high_pc:
case dwarf::DW_AT_ranges:
return !Update && SkipPC;
+ case dwarf::DW_AT_addr_base:
+ // In case !Update the .debug_addr table is not generated/preserved.
+ return !Update;
+ case dwarf::DW_AT_rnglists_base:
+ // In case !Update the .debug_addr table is not generated/preserved.
+ // Thus instead of DW_FORM_rnglistx the DW_FORM_sec_offset is used.
+ // Since DW_AT_rnglists_base is used for only DW_FORM_rnglistx the
+ // DW_AT_rnglists_base is removed.
+ return !Update;
case dwarf::DW_AT_str_offsets_base:
// FIXME: Use the string offset table with Dwarf 5.
return true;
return Die;
}
-/// Patch the input object file relevant debug_ranges entries
-/// and emit them in the output file. Update the relevant attributes
+/// Patch the input object file relevant debug_ranges or debug_rnglists
+/// entries and emit them in the output file. Update the relevant attributes
/// to point at the new entries.
-void DWARFLinker::patchRangesForUnit(const CompileUnit &Unit,
- DWARFContext &OrigDwarf,
+void DWARFLinker::generateUnitRanges(CompileUnit &Unit,
const DWARFFile &File) const {
- DWARFDebugRangeList RangeList;
- const auto &FunctionRanges = Unit.getFunctionRanges();
- unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
- DWARFDataExtractor RangeExtractor(OrigDwarf.getDWARFObj(),
- OrigDwarf.getDWARFObj().getRangesSection(),
- OrigDwarf.isLittleEndian(), AddressSize);
- std::optional<AddressRangeValuePair> CachedRange;
- DWARFUnit &OrigUnit = Unit.getOrigUnit();
- auto OrigUnitDie = OrigUnit.getUnitDIE(false);
- uint64_t UnitBaseAddress =
- dwarf::toAddress(OrigUnitDie.find(dwarf::DW_AT_low_pc), 0);
-
- for (const auto &RangeAttribute : Unit.getRangesAttributes()) {
- uint64_t Offset = RangeAttribute.get();
- RangeAttribute.set(TheDwarfEmitter->getRangesSectionSize());
- if (Error E = RangeList.extract(RangeExtractor, &Offset)) {
- llvm::consumeError(std::move(E));
- reportWarning("invalid range list ignored.", File);
- RangeList.clear();
- }
- const auto &Entries = RangeList.getEntries();
-
- uint64_t BaseAddress = UnitBaseAddress;
- AddressRanges LinkedRanges;
-
- if (!Entries.empty()) {
- for (const auto &Range : Entries) {
- if (Range.isBaseAddressSelectionEntry(
- Unit.getOrigUnit().getAddressByteSize())) {
- BaseAddress = Range.EndAddress;
- continue;
- }
+ if (LLVM_UNLIKELY(Options.Update))
+ return;
- if (!CachedRange ||
- !CachedRange->Range.contains(Range.StartAddress + BaseAddress))
- CachedRange = FunctionRanges.getRangeThatContains(Range.StartAddress +
- BaseAddress);
+ const auto &FunctionRanges = Unit.getFunctionRanges();
- // All range entries should lie in the function range.
- if (!CachedRange) {
- reportWarning("inconsistent range data.", File);
- continue;
+ // Build set of linked address ranges for unit function ranges.
+ AddressRanges LinkedFunctionRanges;
+ for (const AddressRangeValuePair &Range : FunctionRanges)
+ LinkedFunctionRanges.insert(
+ {Range.Range.start() + Range.Value, Range.Range.end() + Range.Value});
+
+ // Emit LinkedFunctionRanges into .debug_aranges
+ if (!LinkedFunctionRanges.empty())
+ TheDwarfEmitter->emitDwarfDebugArangesTable(Unit, LinkedFunctionRanges);
+
+ RngListAttributesTy AllRngListAttributes = Unit.getRangesAttributes();
+ std::optional<PatchLocation> UnitRngListAttribute =
+ Unit.getUnitRangesAttribute();
+
+ if (!AllRngListAttributes.empty() || UnitRngListAttribute) {
+ std::optional<AddressRangeValuePair> CachedRange;
+ MCSymbol *EndLabel = TheDwarfEmitter->emitDwarfDebugRangeListHeader(Unit);
+
+ // Read original address ranges, apply relocation value, emit linked address
+ // ranges.
+ for (PatchLocation &AttributePatch : AllRngListAttributes) {
+ // Get ranges from the source DWARF corresponding to the current
+ // attribute.
+ AddressRanges LinkedRanges;
+ if (Expected<DWARFAddressRangesVector> OriginalRanges =
+ Unit.getOrigUnit().findRnglistFromOffset(AttributePatch.get())) {
+ // Apply relocation adjustment.
+ for (const auto &Range : *OriginalRanges) {
+ if (!CachedRange || !CachedRange->Range.contains(Range.LowPC))
+ CachedRange = FunctionRanges.getRangeThatContains(Range.LowPC);
+
+ // All range entries should lie in the function range.
+ if (!CachedRange) {
+ reportWarning("inconsistent range data.", File);
+ continue;
+ }
+
+ // Store range for emiting.
+ LinkedRanges.insert({Range.LowPC + CachedRange->Value,
+ Range.HighPC + CachedRange->Value});
}
-
- LinkedRanges.insert(
- {Range.StartAddress + BaseAddress + CachedRange->Value,
- Range.EndAddress + BaseAddress + CachedRange->Value});
+ } else {
+ llvm::consumeError(OriginalRanges.takeError());
+ reportWarning("invalid range list ignored.", File);
}
+
+ // Emit linked ranges.
+ TheDwarfEmitter->emitDwarfDebugRangeListFragment(Unit, LinkedRanges,
+ AttributePatch);
}
- TheDwarfEmitter->emitDwarfDebugRangesTableFragment(Unit, LinkedRanges);
- }
-}
+ // Emit ranges for Unit AT_ranges attribute.
+ if (UnitRngListAttribute.has_value())
+ TheDwarfEmitter->emitDwarfDebugRangeListFragment(
+ Unit, LinkedFunctionRanges, *UnitRngListAttribute);
-/// Generate the debug_aranges entries for \p Unit and if the
-/// unit has a DW_AT_ranges attribute, also emit the debug_ranges
-/// contribution for this attribute.
-/// FIXME: this could actually be done right in patchRangesForUnit,
-/// but for the sake of initial bit-for-bit compatibility with legacy
-/// dsymutil, we have to do it in a delayed pass.
-void DWARFLinker::generateUnitRanges(CompileUnit &Unit) const {
- auto Attr = Unit.getUnitRangesAttribute();
- if (Attr)
- Attr->set(TheDwarfEmitter->getRangesSectionSize());
- TheDwarfEmitter->emitUnitRangesEntries(Unit, static_cast<bool>(Attr));
+ // Emit ranges footer.
+ TheDwarfEmitter->emitDwarfDebugRangeListFooter(Unit, EndLabel);
+ }
}
/// Insert the new line info sequence \p Seq into the current
if (LLVM_UNLIKELY(Linker.Options.Update))
continue;
- Linker.patchRangesForUnit(*CurrentUnit, DwarfContext, File);
+ Linker.generateUnitRanges(*CurrentUnit, File);
+
auto ProcessExpr = [&](StringRef Bytes,
SmallVectorImpl<uint8_t> &Buffer) {
DWARFUnit &OrigUnit = CurrentUnit->getOrigUnit();
// Emit all the compile unit's debug information.
for (auto &CurrentUnit : CompileUnits) {
- if (LLVM_LIKELY(!Linker.Options.Update))
- Linker.generateUnitRanges(*CurrentUnit);
-
CurrentUnit->fixupForwardReferences();
if (!CurrentUnit->getOutputUnitDIE())
Dwarf.getDWARFObj().getFrameSection().Data, "debug_frame");
TheDwarfEmitter->emitSectionContents(Dwarf.getDWARFObj().getArangesSection(),
"debug_aranges");
+ TheDwarfEmitter->emitSectionContents(
+ Dwarf.getDWARFObj().getAddrSection().Data, "debug_addr");
+ TheDwarfEmitter->emitSectionContents(
+ Dwarf.getDWARFObj().getRnglistsSection().Data, "debug_rnglists");
}
void DWARFLinker::addObjectFile(DWARFFile &File, objFileLoader Loader,
// support or update references to these tables. Thus we report warning
// and skip corresponding object file.
if (!OptContext.File.Dwarf->getDWARFObj()
- .getRnglistsSection()
- .Data.empty()) {
- reportWarning("'.debug_rnglists' is not currently supported: file "
- "will be skipped",
- OptContext.File);
- OptContext.Skip = true;
- continue;
- }
-
- if (!OptContext.File.Dwarf->getDWARFObj()
.getLoclistsSection()
.Data.empty()) {
reportWarning("'.debug_loclists' is not currently supported: file "
}
void CompileUnit::noteRangeAttribute(const DIE &Die, PatchLocation Attr) {
- if (Die.getTag() != dwarf::DW_TAG_compile_unit)
- RangeAttributes.push_back(Attr);
- else
+ if (Die.getTag() == dwarf::DW_TAG_compile_unit) {
UnitRangeAttribute = Attr;
+ return;
+ }
+
+ RangeAttributes.emplace_back(Attr);
}
void CompileUnit::noteLocationAttribute(PatchLocation Attr, int64_t PcOffset) {
Asm->setDwarfUsesRelocationsAcrossSections(false);
RangesSectionSize = 0;
+ RngListsSectionSize = 0;
LocSectionSize = 0;
LineSectionSize = 0;
FrameSectionSize = 0;
.Case("debug_frame", MC->getObjectFileInfo()->getDwarfFrameSection())
.Case("debug_aranges",
MC->getObjectFileInfo()->getDwarfARangesSection())
+ .Case("debug_addr", MC->getObjectFileInfo()->getDwarfAddrSection())
+ .Case("debug_rnglists",
+ MC->getObjectFileInfo()->getDwarfRnglistsSection())
.Default(nullptr);
if (Section) {
}
void DwarfStreamer::emitDwarfDebugRangesTableFragment(
- const CompileUnit &Unit, const AddressRanges &LinkedRanges) {
- unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
+ const CompileUnit &Unit, const AddressRanges &LinkedRanges,
+ PatchLocation Patch) {
+ Patch.set(RangesSectionSize);
// Make .debug_ranges to be current section.
MS->switchSection(MC->getObjectFileInfo()->getDwarfRangesSection());
+ unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
// Emit ranges.
uint64_t BaseAddress = 0;
RangesSectionSize += AddressSize;
}
-/// Emit the debug_aranges contribution of a unit and
-/// if \p DoDebugRanges is true the debug_range contents for a
-/// compile_unit level DW_AT_ranges attribute (Which are basically the
-/// same thing with a different base address).
-/// Just aggregate all the ranges gathered inside that unit.
-void DwarfStreamer::emitUnitRangesEntries(CompileUnit &Unit,
- bool DoDebugRanges) {
- const RangesTy &FunctionRanges = Unit.getFunctionRanges();
-
- // Linked addresses might end up in a different order.
- // Build linked address ranges.
- AddressRanges LinkedRanges;
- for (const AddressRangeValuePair &Range : FunctionRanges)
- LinkedRanges.insert(
- {Range.Range.start() + Range.Value, Range.Range.end() + Range.Value});
-
- if (!FunctionRanges.empty())
- emitDwarfDebugArangesTable(Unit, LinkedRanges);
-
- if (DoDebugRanges)
- emitDwarfDebugRangesTableFragment(Unit, LinkedRanges);
+MCSymbol *
+DwarfStreamer::emitDwarfDebugRangeListHeader(const CompileUnit &Unit) {
+ if (Unit.getOrigUnit().getVersion() < 5)
+ return nullptr;
+
+ // Make .debug_rnglists to be current section.
+ MS->switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection());
+
+ MCSymbol *BeginLabel = Asm->createTempSymbol("Brnglists");
+ MCSymbol *EndLabel = Asm->createTempSymbol("Ernglists");
+ unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
+
+ // Length
+ Asm->emitLabelDifference(EndLabel, BeginLabel, sizeof(uint32_t));
+ Asm->OutStreamer->emitLabel(BeginLabel);
+ RngListsSectionSize += sizeof(uint32_t);
+
+ // Version.
+ MS->emitInt16(5);
+ RngListsSectionSize += sizeof(uint16_t);
+
+ // Address size.
+ MS->emitInt8(AddressSize);
+ RngListsSectionSize++;
+
+ // Seg_size
+ MS->emitInt8(0);
+ RngListsSectionSize++;
+
+ // Offset entry count
+ MS->emitInt32(0);
+ RngListsSectionSize += sizeof(uint32_t);
+
+ return EndLabel;
+}
+
+void DwarfStreamer::emitDwarfDebugRangeListFragment(
+ const CompileUnit &Unit, const AddressRanges &LinkedRanges,
+ PatchLocation Patch) {
+ if (Unit.getOrigUnit().getVersion() < 5) {
+ emitDwarfDebugRangesTableFragment(Unit, LinkedRanges, Patch);
+ return;
+ }
+
+ emitDwarfDebugRngListsTableFragment(Unit, LinkedRanges, Patch);
+}
+
+void DwarfStreamer::emitDwarfDebugRangeListFooter(const CompileUnit &Unit,
+ MCSymbol *EndLabel) {
+ if (Unit.getOrigUnit().getVersion() < 5)
+ return;
+
+ // Make .debug_rnglists to be current section.
+ MS->switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection());
+
+ if (EndLabel != nullptr)
+ Asm->OutStreamer->emitLabel(EndLabel);
+}
+
+void DwarfStreamer::emitDwarfDebugRngListsTableFragment(
+ const CompileUnit &Unit, const AddressRanges &LinkedRanges,
+ PatchLocation Patch) {
+ Patch.set(RngListsSectionSize);
+
+ // Make .debug_rnglists to be current section.
+ MS->switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection());
+
+ unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
+
+ for (const AddressRange &Range : LinkedRanges) {
+ // Emit type of entry.
+ MS->emitInt8(dwarf::DW_RLE_start_length);
+ RngListsSectionSize += 1;
+
+ // Emit start address.
+ MS->emitIntValue(Range.start(), AddressSize);
+ RngListsSectionSize += AddressSize;
+
+ // Emit length of the range.
+ RngListsSectionSize += MS->emitSLEB128IntValue(Range.end() - Range.start());
+ }
+
+ // Emit the terminator entry.
+ MS->emitInt8(dwarf::DW_RLE_end_of_list);
+ RngListsSectionSize += 1;
}
/// Emit location lists for \p Unit and update attributes to point to the new
## Test that DWARF5 DW_FORM_addrx is correctly recognized
-## and converted into the DW_FORM_addr
+## and converted into the DW_FORM_addr or just preserved
+## in case --update.
## $ cat dwarf5-addrx.c
## __attribute__ ((optnone)) int foo1 ( ) {
RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/dwarf5/dwarf5-addrx.out -o %t.dSYM 2>&1 | FileCheck %s --allow-empty
RUN: llvm-dwarfdump --verify %t.dSYM 2>&1 | FileCheck %s
-CHECK-NOT: error:
RUN: llvm-dwarfdump --verbose %t.dSYM | FileCheck %s --check-prefix DWARF
+
+RUN: dsymutil --update -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/dwarf5/dwarf5-addrx.out -o %t.dSYM 2>&1 | FileCheck %s --allow-empty
+RUN: llvm-dwarfdump --verify %t.dSYM 2>&1 | FileCheck %s
+
+RUN: llvm-dwarfdump --verbose %t.dSYM | FileCheck %s --check-prefix UPDATE-DWARF
+
+CHECK-NOT: error:
+
DWARF: DW_TAG_compile_unit
DWARF: DW_AT_name [DW_FORM_strp] {{.*}} "dwarf5-addrx.c"
DWARF: DW_AT_low_pc [DW_FORM_addr] (0x0000000100000eb0)
DWARF: DW_AT_high_pc [DW_FORM_data4] (0x00000103)
-DWARF: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008)
DWARF: DW_TAG_subprogram
DWARF: DW_AT_low_pc [DW_FORM_addr] (0x0000000100000eb0)
DWARF: DW_AT_high_pc [DW_FORM_data4] (0x00000010)
DWARF: DW_AT_low_pc [DW_FORM_addr] (0x0000000100000f30)
DWARF: DW_AT_high_pc [DW_FORM_data4] (0x00000083)
DWARF: DW_AT_name [DW_FORM_strp] {{.*}} "main"
+DWARF-NOT: .debug_addr contents
+
+UPDATE-DWARF: DW_TAG_compile_unit
+UPDATE-DWARF: DW_AT_name [DW_FORM_strp] {{.*}} "dwarf5-addrx.c"
+UPDATE-DWARF: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0x0000000000000000)
+UPDATE-DWARF: DW_AT_high_pc [DW_FORM_data4] (0x00000103)
+UPDATE-DWARF: DW_TAG_subprogram
+UPDATE-DWARF: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0x0000000000000000)
+UPDATE-DWARF: DW_AT_high_pc [DW_FORM_data4] (0x00000010)
+UPDATE-DWARF: DW_AT_name [DW_FORM_strp] {{.*}} "foo1"
+UPDATE-DWARF: DW_TAG_subprogram
+UPDATE-DWARF: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000001) address = 0x0000000000000010)
+UPDATE-DWARF: DW_AT_high_pc [DW_FORM_data4] (0x00000010)
+UPDATE-DWARF: DW_AT_name [DW_FORM_strp] {{.*}} "foo2"
+UPDATE-DWARF: DW_TAG_subprogram
+UPDATE-DWARF: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000002) address = 0x0000000000000020)
+UPDATE-DWARF: DW_AT_high_pc [DW_FORM_data4] (0x00000010)
+UPDATE-DWARF: DW_AT_name [DW_FORM_strp] {{.*}} "foo3"
+UPDATE-DWARF: DW_TAG_subprogram
+UPDATE-DWARF: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000003) address = 0x0000000000000030)
+UPDATE-DWARF: DW_AT_high_pc [DW_FORM_data4] (0x00000010)
+UPDATE-DWARF: DW_AT_name [DW_FORM_strp] {{.*}} "foo4"
+UPDATE-DWARF: DW_TAG_subprogram
+UPDATE-DWARF: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000004) address = 0x0000000000000040)
+UPDATE-DWARF: DW_AT_high_pc [DW_FORM_data4] (0x00000010)
+UPDATE-DWARF: DW_AT_name [DW_FORM_strp] {{.*}} "foo5"
+UPDATE-DWARF: DW_TAG_subprogram
+UPDATE-DWARF: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000005) address = 0x0000000000000050)
+UPDATE-DWARF: DW_AT_high_pc [DW_FORM_data4] (0x00000010)
+UPDATE-DWARF: DW_AT_name [DW_FORM_strp] {{.*}} "foo6"
+UPDATE-DWARF: DW_TAG_subprogram
+UPDATE-DWARF: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000006) address = 0x0000000000000060)
+UPDATE-DWARF: DW_AT_high_pc [DW_FORM_data4] (0x00000010)
+UPDATE-DWARF: DW_AT_name [DW_FORM_strp] {{.*}} "foo7"
+UPDATE-DWARF: DW_TAG_subprogram
+UPDATE-DWARF: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000007) address = 0x0000000000000070)
+UPDATE-DWARF: DW_AT_high_pc [DW_FORM_data4] (0x00000010)
+UPDATE-DWARF: DW_AT_name [DW_FORM_strp] {{.*}} "foo8"
+UPDATE-DWARF: DW_TAG_subprogram
+UPDATE-DWARF: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000008) address = 0x0000000000000080)
+UPDATE-DWARF: DW_AT_high_pc [DW_FORM_data4] (0x00000083)
+UPDATE-DWARF: DW_AT_name [DW_FORM_strp] {{.*}} "main"
+UPDATE-DWARF: .debug_addr contents:
+UPDATE-DWARF: 0x00000000: Address table header: length = 0x0000004c, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00
+UPDATE-DWARF: Addrs: [
+UPDATE-DWARF: 0x0000000000000000
+UPDATE-DWARF: 0x0000000000000010
+UPDATE-DWARF: 0x0000000000000020
+UPDATE-DWARF: 0x0000000000000030
+UPDATE-DWARF: 0x0000000000000040
+UPDATE-DWARF: 0x0000000000000050
+UPDATE-DWARF: 0x0000000000000060
+UPDATE-DWARF: 0x0000000000000070
+UPDATE-DWARF: 0x0000000000000080
+UPDATE-DWARF: ]
--- /dev/null
+## This test checks that .debug_rnglists table correclty handled
+## and transformed into the DW_FORM_sec_offset form in case
+## --no-update. Or correctly preservedi in --update case.
+
+## cat dwarf5-rnglists.c
+##
+## #include <stdio.h>
+##
+## int g1;
+##
+## int main ( int argv, char** argc ) {
+##
+## if ( argv > 10 ) {
+## volatile int a = 0x4;
+##
+## if ( g1 ) {
+## volatile int b = 0;
+## return b;
+## }
+##
+## volatile int c = 7;
+## } else if ( g1 ) {
+## volatile int a = 0x5;
+## }
+##
+## return 0;
+## }
+
+## $ clang -gdwarf-5 dwarf5-rnglists.c -c -O2 -o dwarf5-rnglists.o
+## $ clang -gdwarf-5 dwarf5-rnglists.o -o dwarf5-rnglists
+
+#RUN: dsymutil -oso-prepend-path %p/../Inputs -y %s -o %t.dSYM
+#RUN: llvm-dwarfdump --verify %t.dSYM | FileCheck %s
+#RUN: llvm-dwarfdump -a --verbose %t.dSYM | FileCheck %s --check-prefix DWARF-CHECK
+#
+#RUN: dsymutil --update -oso-prepend-path %p/../Inputs -y %s -o %t.dSYM
+#RUN: llvm-dwarfdump --verify %t.dSYM | FileCheck %s
+#RUN: llvm-dwarfdump -a --verbose %t.dSYM | FileCheck %s --check-prefix UPD-DWARF-CHECK
+
+#CHECK: No errors.
+
+#DWARF-CHECK: DW_TAG_compile_unit
+#DWARF-CHECK: DW_TAG_lexical_block
+#DWARF-CHECK: DW_AT_ranges [DW_FORM_sec_offset] (0x0000000c
+#DWARF-CHECK: [0x0000000100000f79, 0x0000000100000f96)
+#DWARF-CHECK: [0x0000000100000fad, 0x0000000100000fb4))
+#DWARF-CHECK-NOT: debug_addr
+#DWARF-CHECK: .debug_rnglists contents:
+#DWARF-CHECK: 0x00000000: range list header: length = 0x0000001d, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000
+#DWARF-CHECK: ranges:
+#DWARF-CHECK: 0x0000000c: [DW_RLE_start_length]: 0x0000000100000f79, 0x000000000000001d => [0x0000000100000f79, 0x0000000100000f96)
+#DWARF-CHECK: 0x00000016: [DW_RLE_start_length]: 0x0000000100000fad, 0x0000000000000007 => [0x0000000100000fad, 0x0000000100000fb4)
+#DWARF-CHECK: 0x00000020: [DW_RLE_end_of_list ]
+#DWARF-CHECK-NOT: debug_addr
+#
+#UPD-DWARF-CHECK: DW_TAG_compile_unit
+#UPD-DWARF-CHECK: DW_TAG_lexical_block
+#UPD-DWARF-CHECK: DW_AT_ranges [DW_FORM_rnglistx] (indexed (0x0) rangelist = 0x00000010
+#UPD-DWARF-CHECK: [0x0000000000000009, 0x0000000000000026)
+#UPD-DWARF-CHECK: [0x000000000000003d, 0x0000000000000044))
+#UPD-DWARF-CHECK: .debug_addr contents:
+#UPD-DWARF-CHECK: 0x00000000: Address table header: length = 0x00000024, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00
+#UPD-DWARF-CHECK: Addrs: [
+#UPD-DWARF-CHECK: 0x0000000000000000
+#UPD-DWARF-CHECK: 0x0000000000000000
+#UPD-DWARF-CHECK: 0x000000000000001c
+#UPD-DWARF-CHECK: 0x0000000000000034
+#UPD-DWARF-CHECK: ]
+
+#UPD-DWARF-CHECK: .debug_rnglists contents:
+#UPD-DWARF-CHECK: 0x00000000: range list header: length = 0x00000013, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000001
+#UPD-DWARF-CHECK: offsets: [
+#UPD-DWARF-CHECK: 0x00000004 => 0x00000010
+#UPD-DWARF-CHECK: ]
+#UPD-DWARF-CHECK: ranges:
+#UPD-DWARF-CHECK: 0x00000010: [DW_RLE_offset_pair]: 0x0000000000000009, 0x0000000000000026 => [0x0000000000000009, 0x0000000000000026)
+#UPD-DWARF-CHECK: 0x00000013: [DW_RLE_offset_pair]: 0x000000000000003d, 0x0000000000000044 => [0x000000000000003d, 0x0000000000000044)
+#UPD-DWARF-CHECK: 0x00000016: [DW_RLE_end_of_list]
+
+---
+triple: 'x86_64-apple-darwin'
+objects:
+ - filename: 'dwarf5-rnglists.o'
+ timestamp: 1676048242
+ symbols:
+ - { sym: _main, objAddr: 0x0, binAddr: 0x100000F70, size: 0x48 }
+ - { sym: _g1, binAddr: 0x100001000, size: 0x0 }
OBJ: DW_AT_name ("b")
OBJ: DW_AT_type (0x000000af "_Bool")
-DSYM: 0x00000095: DW_TAG_base_type
+DSYM: 0x0000008d: DW_TAG_base_type
DSYM: DW_AT_name ("DW_ATE_unsigned_1")
DSYM: DW_AT_encoding (DW_ATE_unsigned)
DSYM: DW_AT_byte_size (0x01)
-DSYM: 0x000000bc: DW_TAG_formal_parameter
-DSYM: DW_AT_location (DW_OP_breg2 RCX+0, DW_OP_constu 0xff, DW_OP_and, DW_OP_convert (0x00000095) "DW_ATE_unsigned_1", DW_OP_convert (0x0000009c) "DW_ATE_unsigned_8", DW_OP_stack_value)
+DSYM: 0x000000b4: DW_TAG_formal_parameter
+DSYM: DW_AT_location (DW_OP_breg2 RCX+0, DW_OP_constu 0xff, DW_OP_and, DW_OP_convert (0x0000008d) "DW_ATE_unsigned_1", DW_OP_convert (0x00000094) "DW_ATE_unsigned_8", DW_OP_stack_value)
DSYM: DW_AT_name ("b")
-DSYM: DW_AT_type (0x000000da "_Bool")
+DSYM: DW_AT_type (0x000000d2 "_Bool")
-## Test that DWARF5 DW_FORM_addrx is correctly recognized
-## and converted into the DW_FORM_addr
+## Test that DWARFv5 DW_FORM_addrx is correctly recognized
+## and converted into the DW_FORM_addr in --garbage-collection
+## case or correctly preserved in --no-garbage-collection case.
# RUN: yaml2obj %s -o %t.o
# RUN: llvm-dwarfutil %t.o %t1
# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s
# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix DWARF-CHECK
+#
+# RUN: llvm-dwarfutil --no-garbage-collection %t.o %t1
+# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s
+# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix UPD-DWARF-CHECK
+#
+# RUN: llvm-dwarfutil --no-garbage-collection --build-accelerator=DWARF %t.o %t1
+# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s
+# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix UPD-DWARF-CHECK
#CHECK: No errors.
#DWARF-CHECK: DW_AT_name [DW_FORM_strp] {{.*}} "CU1"
#DWARF-CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000001130)
#DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000030)
-#DWARF-CHECK: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008)
#DWARF-CHECK: DW_TAG_subprogram
#DWARF-CHECK: DW_AT_name [DW_FORM_strp] {{.*}} "foo1"
#DWARF-CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000001130)
#DWARF-CHECK: DW_AT_name [DW_FORM_strp] {{.*}} "foo3"
#DWARF-CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000001150)
#DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000010)
+#DWARF-CHECK=NOT: .debug_addr contents:
+
+#UPD-DWARF-CHECK: DW_TAG_compile_unit
+#UPD-DWARF-CHECK: DW_AT_name {{.*}}"CU1"
+#UPD-DWARF-CHECK: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0x0000000000001130)
+#UPD-DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000030)
+#UPD-DWARF-CHECK: DW_TAG_subprogram
+#UPD-DWARF-CHECK: DW_AT_name {{.*}}"foo1"
+#UPD-DWARF-CHECK: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0x0000000000001130)
+#UPD-DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000010)
+#UPD-DWARF-CHECK: DW_TAG_subprogram
+#UPD-DWARF-CHECK: DW_AT_name {{.*}}"foo2"
+#UPD-DWARF-CHECK: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000001) address = 0x0000000000001140)
+#UPD-DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000010)
+#UPD-DWARF-CHECK: DW_TAG_subprogram
+#UPD-DWARF-CHECK: DW_AT_name {{.*}}"foo3"
+#UPD-DWARF-CHECK: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000002) address = 0x0000000000001150)
+#UPD-DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000010)
+#UPD-DWARF-CHECK: .debug_addr contents:
+#UPD-DWARF-CHECK: 0x00000000: Address table header: length = 0x0000001c, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00
+#UPD-DWARF-CHECK: Addrs: [
+#UPD-DWARF-CHECK: 0x0000000000001130
+#UPD-DWARF-CHECK: 0x0000000000001140
+#UPD-DWARF-CHECK: 0x0000000000001150
+#UPD-DWARF-CHECK: ]
--- !ELF
FileHeader:
--- /dev/null
+## Test that DWARFv5 .debug_rnglists is correctly recognized
+## and converted into the DW_FORM_sec_offset form in --garbage-collection
+## case or correctly preserved in --no-garbage-collection case.
+
+# RUN: yaml2obj %s -o %t.o
+
+# RUN: llvm-dwarfutil %t.o %t1
+# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s
+# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix DWARF-CHECK
+
+# RUN: llvm-dwarfutil --no-garbage-collection %t.o %t1
+# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s
+# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix UPD-DWARF-CHECK
+
+# RUN: llvm-dwarfutil --no-garbage-collection --build-accelerator=DWARF %t.o %t1
+# RUN: llvm-dwarfdump -verify %t1 | FileCheck %s
+# RUN: llvm-dwarfdump -a --verbose %t1 | FileCheck %s --check-prefix UPD-DWARF-CHECK
+
+#CHECK: No errors.
+
+#DWARF-CHECK: DW_TAG_compile_unit
+#DWARF-CHECK: DW_AT_name [DW_FORM_strp] {{.*}} "CU1"
+#DWARF-CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000001130)
+#DWARF-CHECK: DW_AT_ranges [DW_FORM_sec_offset] (0x[[CURANGE_OFF:[0-9a-f]*]]
+#DWARF-CHECK: [0x0000000000001130, 0x0000000000001170))
+#DWARF-CHECK: DW_TAG_subprogram
+#DWARF-CHECK: DW_AT_name [DW_FORM_strp] {{.*}} "foo1"
+#DWARF-CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000001130)
+#DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000010)
+#DWARF-CHECK: DW_TAG_lexical_block
+#DWARF-CHECK: DW_AT_ranges [DW_FORM_sec_offset] (0x[[F1RANGE_OFF:[0-9a-f]*]]
+#DWARF-CHECK: [0x0000000000001130, 0x0000000000001140))
+#DWARF-CHECK: DW_TAG_subprogram
+#DWARF-CHECK: DW_AT_name [DW_FORM_strp] {{.*}} "foo2"
+#DWARF-CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000001140)
+#DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000010)
+#DWARF-CHECK: DW_TAG_lexical_block
+#DWARF-CHECK: DW_AT_ranges [DW_FORM_sec_offset] (0x[[F2RANGE_OFF:[0-9a-f]*]]
+#DWARF-CHECK: [0x0000000000001140, 0x0000000000001150))
+#DWARF-CHECK: DW_TAG_subprogram
+#DWARF-CHECK: DW_AT_name [DW_FORM_strp] {{.*}} "foo3"
+#DWARF-CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000001150)
+#DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000010)
+#DWARF-CHECK: DW_TAG_lexical_block
+#DWARF-CHECK: DW_AT_ranges [DW_FORM_sec_offset] (0x[[F3RANGE_OFF:[0-9a-f]*]]
+#DWARF-CHECK: [0x0000000000001150, 0x0000000000001160))
+#DWARF-CHECK: DW_TAG_subprogram
+#DWARF-CHECK: DW_AT_name [DW_FORM_strp] {{.*}} "foo4"
+#DWARF-CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000001160)
+#DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000010)
+#DWARF-CHECK: DW_TAG_lexical_block
+#DWARF-CHECK: DW_AT_ranges [DW_FORM_sec_offset] (0x[[F4RANGE_OFF:[0-9a-f]*]]
+#DWARF-CHECK: [0x0000000000001160, 0x0000000000001170))
+#DWARF-CHECK-NOT: .debug_addr contents:
+#DWARF-CHECK: .debug_aranges contents:
+#DWARF-CHECK: Address Range Header: length = 0x0000002c, format = DWARF32, version = 0x0002, cu_offset = 0x00000000, addr_size = 0x08, seg_size = 0x00
+#DWARF-CHECK: [0x0000000000001130, 0x0000000000001170)
+#DWARF-CHECK-NOT: .debug_addr contents:
+#DWARF-CHECK: .debug_rnglists contents:
+#DWARF-CHECK: 0x00000000: range list header: length = 0x00000040, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000
+#DWARF-CHECK: ranges:
+#DWARF-CHECK: 0x[[F1RANGE_OFF]]: [DW_RLE_start_length]: 0x0000000000001130, 0x0000000000000010 => [0x0000000000001130, 0x0000000000001140)
+#DWARF-CHECK: {{.*}} [DW_RLE_end_of_list ]
+#DWARF-CHECK: 0x[[F2RANGE_OFF]]: [DW_RLE_start_length]: 0x0000000000001140, 0x0000000000000010 => [0x0000000000001140, 0x0000000000001150)
+#DWARF-CHECK: {{.*}} [DW_RLE_end_of_list ]
+#DWARF-CHECK: 0x[[F3RANGE_OFF]]: [DW_RLE_start_length]: 0x0000000000001150, 0x0000000000000010 => [0x0000000000001150, 0x0000000000001160)
+#DWARF-CHECK: {{.*}} [DW_RLE_end_of_list ]
+#DWARF-CHECK: 0x[[F4RANGE_OFF]]: [DW_RLE_start_length]: 0x0000000000001160, 0x0000000000000010 => [0x0000000000001160, 0x0000000000001170)
+#DWARF-CHECK: {{.*}} [DW_RLE_end_of_list ]
+#DWARF-CHECK: 0x[[CURANGE_OFF]]: [DW_RLE_start_length]: 0x0000000000001130, 0x0000000000000040 => [0x0000000000001130, 0x0000000000001170)
+#DWARF-CHECK: {{.*}} [DW_RLE_end_of_list ]
+#DWARF-CHECK-NOT: .debug_addr contents:
+
+#UPD-DWARF-CHECK: DW_TAG_compile_unit
+#UPD-DWARF-CHECK: DW_AT_name {{.*}}"CU1"
+#UPD-DWARF-CHECK: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0x0000000000001130)
+#UPD-DWARF-CHECK: DW_AT_ranges [DW_FORM_rnglistx] (indexed (0x4) rangelist = 0x0000003e
+#UPD-DWARF-CHECK: [0x0000000000001130, 0x0000000000001170))
+#UPD-DWARF-CHECK: DW_TAG_subprogram
+#UPD-DWARF-CHECK: DW_AT_name {{.*}}"foo1"
+#UPD-DWARF-CHECK: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0x0000000000001130)
+#UPD-DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000010)
+#UPD-DWARF-CHECK: DW_TAG_lexical_block
+#UPD-DWARF-CHECK: DW_AT_ranges [DW_FORM_rnglistx] (indexed (0x0) rangelist = 0x00000020
+#UPD-DWARF-CHECK: [0x0000000000001130, 0x0000000000001140))
+#UPD-DWARF-CHECK: DW_TAG_subprogram
+#UPD-DWARF-CHECK: DW_AT_name {{.*}}"foo2"
+#UPD-DWARF-CHECK: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000001) address = 0x0000000000001140)
+#UPD-DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000010)
+#UPD-DWARF-CHECK: DW_TAG_lexical_block
+#UPD-DWARF-CHECK: DW_AT_ranges [DW_FORM_rnglistx] (indexed (0x1) rangelist = 0x00000024
+#UPD-DWARF-CHECK: [0x0000000000001140, 0x0000000000001150))
+#UPD-DWARF-CHECK: DW_TAG_subprogram
+#UPD-DWARF-CHECK: DW_AT_name {{.*}}"foo3"
+#UPD-DWARF-CHECK: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000002) address = 0x0000000000001150)
+#UPD-DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000010)
+#UPD-DWARF-CHECK: DW_TAG_lexical_block
+#UPD-DWARF-CHECK: DW_AT_ranges [DW_FORM_sec_offset] (0x00000028
+#UPD-DWARF-CHECK: [0x0000000000001150, 0x0000000000001160))
+#UPD-DWARF-CHECK: DW_TAG_subprogram
+#UPD-DWARF-CHECK: DW_AT_name {{.*}}"foo4"
+#UPD-DWARF-CHECK: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000003) address = 0x0000000000001160)
+#UPD-DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000010)
+#UPD-DWARF-CHECK: DW_TAG_lexical_block
+#UPD-DWARF-CHECK: DW_AT_ranges [DW_FORM_sec_offset] (0x00000033
+#UPD-DWARF-CHECK: [0x0000000000001160, 0x0000000000001170))
+#UPD-DWARF-CHECK: .debug_addr contents:
+#UPD-DWARF-CHECK: 0x00000000: Address table header: length = 0x00000024, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00
+#UPD-DWARF-CHECK: Addrs: [
+#UPD-DWARF-CHECK: 0x0000000000001130
+#UPD-DWARF-CHECK: 0x0000000000001140
+#UPD-DWARF-CHECK: 0x0000000000001150
+#UPD-DWARF-CHECK: 0x0000000000001160
+#UPD-DWARF-CHECK: ]
+#UPD-DWARF-CHECK: .debug_rnglists contents:
+#UPD-DWARF-CHECK: 0x00000000: range list header: length = 0x0000003e, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000005
+#UPD-DWARF-CHECK: offsets: [
+#UPD-DWARF-CHECK: 0x00000014 => 0x00000020
+#UPD-DWARF-CHECK: 0x00000018 => 0x00000024
+#UPD-DWARF-CHECK: 0x0000001c => 0x00000028
+#UPD-DWARF-CHECK: 0x00000027 => 0x00000033
+#UPD-DWARF-CHECK: 0x00000032 => 0x0000003e
+#UPD-DWARF-CHECK: ]
+#UPD-DWARF-CHECK: ranges:
+#UPD-DWARF-CHECK: 0x00000020: [DW_RLE_startx_length]: 0x0000000000000000, 0x0000000000000010 => [0x0000000000001130, 0x0000000000001140)
+#UPD-DWARF-CHECK: 0x00000023: [DW_RLE_end_of_list ]
+#UPD-DWARF-CHECK: 0x00000024: [DW_RLE_startx_length]: 0x0000000000000001, 0x0000000000000010 => [0x0000000000001140, 0x0000000000001150)
+#UPD-DWARF-CHECK: 0x00000027: [DW_RLE_end_of_list ]
+#UPD-DWARF-CHECK: 0x00000028: [DW_RLE_start_length ]: 0x0000000000001150, 0x0000000000000010 => [0x0000000000001150, 0x0000000000001160)
+#UPD-DWARF-CHECK: 0x00000032: [DW_RLE_end_of_list ]
+#UPD-DWARF-CHECK: 0x00000033: [DW_RLE_start_length ]: 0x0000000000001160, 0x0000000000000010 => [0x0000000000001160, 0x0000000000001170)
+#UPD-DWARF-CHECK: 0x0000003d: [DW_RLE_end_of_list ]
+#UPD-DWARF-CHECK: 0x0000003e: [DW_RLE_startx_length]: 0x0000000000000000, 0x0000000000000040 => [0x0000000000001130, 0x0000000000001170)
+#UPD-DWARF-CHECK: 0x00000041: [DW_RLE_end_of_list ]
+
+## Following yaml description has Content of the .debug_rnglists exactly like above data ^^^^^^
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1130
+ Size: 0x70
+ - Name: .debug_rnglists
+ Type: SHT_PROGBITS
+ Flags: [ ]
+ Content: "3e000000050008000500000014000000180000001c000000270000003200000003001000030110000750110000000000001000076011000000000000100003004000"
+DWARF:
+ debug_abbrev:
+ - Table:
+ - Tag: DW_TAG_compile_unit
+ Children: DW_CHILDREN_yes
+ Attributes:
+ - Attribute: DW_AT_producer
+ Form: DW_FORM_string
+ - Attribute: DW_AT_language
+ Form: DW_FORM_data2
+ - Attribute: DW_AT_name
+ Form: DW_FORM_string
+ - Attribute: DW_AT_low_pc
+ Form: DW_FORM_addrx
+ - Attribute: DW_AT_ranges
+ Form: DW_FORM_rnglistx
+ - Attribute: DW_AT_rnglists_base
+ Form: DW_FORM_sec_offset
+ - Attribute: DW_AT_addr_base
+ Form: DW_FORM_sec_offset
+ - Tag: DW_TAG_subprogram
+ Children: DW_CHILDREN_yes
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_string
+ - Attribute: DW_AT_low_pc
+ Form: DW_FORM_addrx
+ - Attribute: DW_AT_high_pc
+ Form: DW_FORM_data8
+ - Attribute: DW_AT_type
+ Form: DW_FORM_ref4
+ - Tag: DW_TAG_lexical_block
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_ranges
+ Form: DW_FORM_rnglistx
+ - Tag: DW_TAG_lexical_block
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_ranges
+ Form: DW_FORM_sec_offset
+ - Tag: DW_TAG_base_type
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_name
+ Form: DW_FORM_string
+ debug_info:
+ - Version: 5
+ UnitType: DW_UT_compile
+ Entries:
+ - AbbrCode: 1
+ Values:
+ - CStr: by_hand
+ - Value: 0x04
+ - CStr: CU1
+ - Value: 0x0
+ - Value: 0x4
+ - Value: 0xc
+ - Value: 0x8
+ - AbbrCode: 2
+ Values:
+ - CStr: foo1
+ - Value: 0x00
+ - Value: 0x10
+ - Value: 0x83
+ - AbbrCode: 3
+ Values:
+ - Value: 0x00
+ - AbbrCode: 0
+ - AbbrCode: 2
+ Values:
+ - CStr: foo2
+ - Value: 0x01
+ - Value: 0x10
+ - Value: 0x83
+ - AbbrCode: 3
+ Values:
+ - Value: 0x01
+ - AbbrCode: 0
+ - AbbrCode: 2
+ Values:
+ - CStr: foo3
+ - Value: 0x02
+ - Value: 0x10
+ - Value: 0x83
+ - AbbrCode: 4
+ Values:
+ - Value: 0x28
+ - AbbrCode: 0
+ - AbbrCode: 2
+ Values:
+ - CStr: foo4
+ - Value: 0x03
+ - Value: 0x10
+ - Value: 0x83
+ - AbbrCode: 4
+ Values:
+ - Value: 0x33
+ - AbbrCode: 0
+ - AbbrCode: 5
+ Values:
+ - CStr: int
+ - AbbrCode: 0
+ debug_addr:
+ - Version: 5
+ AddressSize: 0x08
+ Entries:
+ - Address: 0x1130
+ - Address: 0x1140
+ - Address: 0x1150
+ - Address: 0x1160
+...
+++ /dev/null
-## This test checks the warning message displayed if input file
-## contains .debug_rnglists section.
-
-# RUN: yaml2obj %s -o %t.o
-
-# RUN: llvm-dwarfutil --garbage-collection %t.o %t1 2>&1 | FileCheck %s -DFILE=%t.o
-
-# CHECK: [[FILE]]: warning: '.debug_rnglists' is not currently supported: file will be skipped
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_X86_64
-Sections:
- - Name: .text
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
- Address: 0x1000
- AddressAlign: 0x0000000000000010
- Content: "FFFFFFFF"
- - Name: .debug_rnglists
- Type: SHT_PROGBITS
- Flags: [ ]
- Content: "0000"
-DWARF:
- debug_abbrev:
- - Table:
- - Tag: DW_TAG_compile_unit
- Children: DW_CHILDREN_yes
- Attributes:
- - Attribute: DW_AT_producer
- Form: DW_FORM_string
- - Attribute: DW_AT_language
- Form: DW_FORM_data2
- - Attribute: DW_AT_name
- Form: DW_FORM_string
- - Attribute: DW_AT_low_pc
- Form: DW_FORM_addr
- - Attribute: DW_AT_high_pc
- Form: DW_FORM_data8
- debug_info:
- - Version: 4
- Entries:
- - AbbrCode: 1
- Values:
- - CStr: by_hand
- - Value: 0x04
- - CStr: CU1
- - Value: 0x1000
- - Value: 0x4
- - AbbrCode: 0
-...