mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-07 14:33:15 +00:00
[dsymutil] Generate debug_aranges section.
This actually shares most of its implementation with the generation of the debug_ranges (the absence of 'a' is not a typo) contribution for the unit's DW_AT_ranges attribute. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@232246 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1d6cc768e5
commit
9786d3d019
@ -129,3 +129,13 @@ CHECK: DW_AT_frame_base [DW_FORM_block1] (<0x01> 56 )
|
|||||||
|
|
||||||
CHECK: NULL
|
CHECK: NULL
|
||||||
|
|
||||||
|
CHECK:.debug_aranges contents:
|
||||||
|
CHECK-NEXT:Address Range Header: length = 0x0000002c, version = 0x0002, cu_offset = 0x00000000, addr_size = 0x08, seg_size = 0x00
|
||||||
|
CHECK-NEXT:[0x0000000100000ea0 - 0x0000000100000ec4)
|
||||||
|
CHECK-NEXT:Address Range Header: length = 0x0000003c, version = 0x0002, cu_offset = 0x00000081, addr_size = 0x08, seg_size = 0x00
|
||||||
|
CHECK-NEXT:[0x0000000100000ed0 - 0x0000000100000f19)
|
||||||
|
CHECK-NEXT:[0x0000000100000f20 - 0x0000000100000f37)
|
||||||
|
CHECK-NEXT:Address Range Header: length = 0x0000003c, version = 0x0002, cu_offset = 0x00000126, addr_size = 0x08, seg_size = 0x00
|
||||||
|
CHECK-NEXT:[0x0000000100000f40 - 0x0000000100000f84)
|
||||||
|
CHECK-NEXT:[0x0000000100000f90 - 0x0000000100000fa9)
|
||||||
|
|
||||||
|
@ -105,3 +105,11 @@ CHECK: [0x0000000100000f9f - 0x0000000100000fa7))
|
|||||||
|
|
||||||
CHECK: NULL
|
CHECK: NULL
|
||||||
CHECK: NULL
|
CHECK: NULL
|
||||||
|
|
||||||
|
CHECK: .debug_aranges contents:
|
||||||
|
CHECK-NEXT: Address Range Header: length = 0x0000002c, version = 0x0002, cu_offset = 0x00000000, addr_size = 0x08, seg_size = 0x00
|
||||||
|
CHECK-NEXT: [0x0000000100000f40 - 0x0000000100000f4b)
|
||||||
|
CHECK-NEXT: Address Range Header: length = 0x0000002c, version = 0x0002, cu_offset = 0x00000077, addr_size = 0x08, seg_size = 0x00
|
||||||
|
CHECK-NEXT: [0x0000000100000f50 - 0x0000000100000f87)
|
||||||
|
CHECK-NEXT: Address Range Header: length = 0x0000002c, version = 0x0002, cu_offset = 0x0000011b, addr_size = 0x08, seg_size = 0x00
|
||||||
|
CHECK-NEXT: [0x0000000100000f90 - 0x0000000100000fb4)
|
||||||
|
@ -119,3 +119,11 @@ CHECK: DW_TAG_subprogram [11]
|
|||||||
CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000008a] = "inc")
|
CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000008a] = "inc")
|
||||||
CHECK: DW_AT_type [DW_FORM_ref_addr] (0x0000000000000063)
|
CHECK: DW_AT_type [DW_FORM_ref_addr] (0x0000000000000063)
|
||||||
CHECK: NULL
|
CHECK: NULL
|
||||||
|
|
||||||
|
CHECK: .debug_aranges contents:
|
||||||
|
CHECK-NEXT: Address Range Header: length = 0x0000002c, version = 0x0002, cu_offset = 0x00000000, addr_size = 0x08, seg_size = 0x00
|
||||||
|
CHECK-NEXT: [0x0000000100000f40 - 0x0000000100000f4b)
|
||||||
|
CHECK-NEXT: Address Range Header: length = 0x0000002c, version = 0x0002, cu_offset = 0x00000081, addr_size = 0x08, seg_size = 0x00
|
||||||
|
CHECK-NEXT: [0x0000000100000f50 - 0x0000000100000f89)
|
||||||
|
CHECK-NEXT: Address Range Header: length = 0x0000002c, version = 0x0002, cu_offset = 0x0000013a, addr_size = 0x08, seg_size = 0x00
|
||||||
|
CHECK-NEXT: [0x0000000100000f90 - 0x0000000100000fb4)
|
||||||
|
@ -361,8 +361,10 @@ public:
|
|||||||
const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries,
|
const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries,
|
||||||
unsigned AddressSize);
|
unsigned AddressSize);
|
||||||
|
|
||||||
/// \brief Emit debug_ranges entries for a DW_TAG_compile_unit's DW_AT_ranges.
|
/// \brief Emit debug_aranges entries for \p Unit and if \p
|
||||||
void emitUnitRangesEntries(CompileUnit &Unit);
|
/// 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);
|
||||||
|
|
||||||
uint32_t getRangesSectionSize() const { return RangesSectionSize; }
|
uint32_t getRangesSectionSize() const { return RangesSectionSize; }
|
||||||
};
|
};
|
||||||
@ -532,14 +534,13 @@ void DwarfStreamer::emitRangesEntries(
|
|||||||
RangesSectionSize += 2 * AddressSize;
|
RangesSectionSize += 2 * AddressSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Emit the debug_range contents for a compile_unit level
|
/// \brief Emit the debug_aranges contribution of a unit and
|
||||||
/// DW_AT_ranges attribute. Just aggregate all the ranges gathered
|
/// if \p DoDebugRanges is true the debug_range contents for a
|
||||||
/// inside that unit.
|
/// compile_unit level DW_AT_ranges attribute (Which are basically the
|
||||||
void DwarfStreamer::emitUnitRangesEntries(CompileUnit &Unit) {
|
/// same thing with a different base address).
|
||||||
MS->SwitchSection(MC->getObjectFileInfo()->getDwarfRangesSection());
|
/// Just aggregate all the ranges gathered inside that unit.
|
||||||
|
void DwarfStreamer::emitUnitRangesEntries(CompileUnit &Unit,
|
||||||
// Offset each range by the right amount.
|
bool DoDebugRanges) {
|
||||||
int64_t PcOffset = -Unit.getLowPc();
|
|
||||||
unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
|
unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
|
||||||
// Gather the ranges in a vector, so that we can simplify them. The
|
// Gather the ranges in a vector, so that we can simplify them. The
|
||||||
// IntervalMap will have coalesced the non-linked ranges, but here
|
// IntervalMap will have coalesced the non-linked ranges, but here
|
||||||
@ -548,19 +549,65 @@ void DwarfStreamer::emitUnitRangesEntries(CompileUnit &Unit) {
|
|||||||
const auto &FunctionRanges = Unit.getFunctionRanges();
|
const auto &FunctionRanges = Unit.getFunctionRanges();
|
||||||
for (auto Range = FunctionRanges.begin(), End = FunctionRanges.end();
|
for (auto Range = FunctionRanges.begin(), End = FunctionRanges.end();
|
||||||
Range != End; ++Range)
|
Range != End; ++Range)
|
||||||
Ranges.push_back(std::make_pair(Range.start() + Range.value() + PcOffset,
|
Ranges.push_back(std::make_pair(Range.start() + Range.value(),
|
||||||
Range.stop() + Range.value() + PcOffset));
|
Range.stop() + Range.value()));
|
||||||
|
|
||||||
// The object addresses where sorted, but again, the linked
|
// The object addresses where sorted, but again, the linked
|
||||||
// addresses might end up in a different order.
|
// addresses might end up in a different order.
|
||||||
std::sort(Ranges.begin(), Ranges.end());
|
std::sort(Ranges.begin(), Ranges.end());
|
||||||
|
|
||||||
|
if (!Ranges.empty()) {
|
||||||
|
MS->SwitchSection(MC->getObjectFileInfo()->getDwarfARangesSection());
|
||||||
|
|
||||||
|
MCSymbol *BeginLabel = Asm->GetTempSymbol("Barange", Unit.getUniqueID());
|
||||||
|
MCSymbol *EndLabel = Asm->GetTempSymbol("Earange", Unit.getUniqueID());
|
||||||
|
|
||||||
|
unsigned HeaderSize =
|
||||||
|
sizeof(int32_t) + // Size of contents (w/o this field
|
||||||
|
sizeof(int16_t) + // DWARF ARange version number
|
||||||
|
sizeof(int32_t) + // Offset of CU in the .debug_info section
|
||||||
|
sizeof(int8_t) + // Pointer Size (in bytes)
|
||||||
|
sizeof(int8_t); // Segment Size (in bytes)
|
||||||
|
|
||||||
|
unsigned TupleSize = AddressSize * 2;
|
||||||
|
unsigned Padding = OffsetToAlignment(HeaderSize, TupleSize);
|
||||||
|
|
||||||
|
Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); // Arange length
|
||||||
|
Asm->OutStreamer.EmitLabel(BeginLabel);
|
||||||
|
Asm->EmitInt16(dwarf::DW_ARANGES_VERSION); // Version number
|
||||||
|
Asm->EmitInt32(Unit.getStartOffset()); // Corresponding unit's offset
|
||||||
|
Asm->EmitInt8(AddressSize); // Address size
|
||||||
|
Asm->EmitInt8(0); // Segment size
|
||||||
|
|
||||||
|
Asm->OutStreamer.EmitFill(Padding, 0x0);
|
||||||
|
|
||||||
|
for (auto Range = Ranges.begin(), End = Ranges.end(); Range != End;
|
||||||
|
++Range) {
|
||||||
|
uint64_t RangeStart = Range->first;
|
||||||
|
MS->EmitIntValue(RangeStart, AddressSize);
|
||||||
|
while ((Range + 1) != End && Range->second == (Range + 1)->first)
|
||||||
|
++Range;
|
||||||
|
MS->EmitIntValue(Range->second - RangeStart, AddressSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Emit terminator
|
||||||
|
Asm->OutStreamer.EmitIntValue(0, AddressSize);
|
||||||
|
Asm->OutStreamer.EmitIntValue(0, AddressSize);
|
||||||
|
Asm->OutStreamer.EmitLabel(EndLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DoDebugRanges)
|
||||||
|
return;
|
||||||
|
|
||||||
|
MS->SwitchSection(MC->getObjectFileInfo()->getDwarfRangesSection());
|
||||||
|
// Offset each range by the right amount.
|
||||||
|
int64_t PcOffset = -Unit.getLowPc();
|
||||||
// Emit coalesced ranges.
|
// Emit coalesced ranges.
|
||||||
for (auto Range = Ranges.begin(), End = Ranges.end(); Range != End; ++Range) {
|
for (auto Range = Ranges.begin(), End = Ranges.end(); Range != End; ++Range) {
|
||||||
MS->EmitIntValue(Range->first, AddressSize);
|
MS->EmitIntValue(Range->first + PcOffset, AddressSize);
|
||||||
while (Range + 1 != End && Range->second == (Range + 1)->first)
|
while (Range + 1 != End && Range->second == (Range + 1)->first)
|
||||||
++Range;
|
++Range;
|
||||||
MS->EmitIntValue(Range->second, AddressSize);
|
MS->EmitIntValue(Range->second + PcOffset, AddressSize);
|
||||||
RangesSectionSize += 2 * AddressSize;
|
RangesSectionSize += 2 * AddressSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1707,16 +1754,17 @@ void DwarfLinker::patchRangesForUnit(const CompileUnit &Unit,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Generate the debug_ranges entries for \p Unit's
|
/// \brief Generate the debug_aranges entries for \p Unit and if the
|
||||||
/// DW_AT_ranges attribute if there is one.
|
/// 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,
|
/// FIXME: this could actually be done right in patchRangesForUnit,
|
||||||
/// but for the sake of initial bit-for-bit compatibility with legacy
|
/// but for the sake of initial bit-for-bit compatibility with legacy
|
||||||
/// dsymutil, we have to do it in a delayed pass.
|
/// dsymutil, we have to do it in a delayed pass.
|
||||||
void DwarfLinker::generateUnitRanges(CompileUnit &Unit) const {
|
void DwarfLinker::generateUnitRanges(CompileUnit &Unit) const {
|
||||||
if (DIEInteger *Attr = Unit.getUnitRangesAttribute()) {
|
DIEInteger *Attr = Unit.getUnitRangesAttribute();
|
||||||
|
if (Attr)
|
||||||
Attr->setValue(Streamer->getRangesSectionSize());
|
Attr->setValue(Streamer->getRangesSectionSize());
|
||||||
Streamer->emitUnitRangesEntries(Unit);
|
Streamer->emitUnitRangesEntries(Unit, Attr != nullptr);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DwarfLinker::link(const DebugMap &Map) {
|
bool DwarfLinker::link(const DebugMap &Map) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user