@@ -3275,34 +3275,70 @@ static MCSymbol *emitLoclistsTableHeader(AsmPrinter *Asm,
32753275 return TableEnd;
32763276}
32773277
3278- template <typename Ranges, typename PayloadEmitter>
3279- static void emitRangeList (
3280- DwarfDebug &DD, AsmPrinter *Asm, MCSymbol *Sym, const Ranges &R,
3281- const DwarfCompileUnit &CU, unsigned BaseAddressx, unsigned OffsetPair,
3282- unsigned StartxLength, unsigned EndOfList,
3283- StringRef (*StringifyEnum)(unsigned ),
3284- bool ShouldUseBaseAddress,
3285- PayloadEmitter EmitPayload) {
3278+ namespace {
3279+
3280+ struct DebugLocSpanList {
3281+ MCSymbol *Label;
3282+ const DwarfCompileUnit *CU;
3283+ llvm::ArrayRef<llvm::DebugLocStream::Entry> Ranges;
3284+ };
3285+
3286+ template <typename DWARFSpanList> struct DwarfRangeListTraits {};
3287+
3288+ template <> struct DwarfRangeListTraits <DebugLocSpanList> {
3289+ static constexpr unsigned BaseAddressx = dwarf::DW_LLE_base_addressx;
3290+ static constexpr unsigned OffsetPair = dwarf::DW_LLE_offset_pair;
3291+ static constexpr unsigned StartxLength = dwarf::DW_LLE_startx_length;
3292+ static constexpr unsigned StartxEndx = dwarf::DW_LLE_startx_endx;
3293+ static constexpr unsigned EndOfList = dwarf::DW_LLE_end_of_list;
3294+
3295+ static StringRef StringifyRangeKind (unsigned Encoding) {
3296+ return llvm::dwarf::LocListEncodingString (Encoding);
3297+ }
3298+ };
3299+
3300+ template <> struct DwarfRangeListTraits <RangeSpanList> {
3301+ static constexpr unsigned BaseAddressx = dwarf::DW_RLE_base_addressx;
3302+ static constexpr unsigned OffsetPair = dwarf::DW_RLE_offset_pair;
3303+ static constexpr unsigned StartxLength = dwarf::DW_RLE_startx_length;
3304+ static constexpr unsigned StartxEndx = dwarf::DW_RLE_startx_endx;
3305+ static constexpr unsigned EndOfList = dwarf::DW_RLE_end_of_list;
3306+
3307+ static StringRef StringifyRangeKind (unsigned Encoding) {
3308+ return llvm::dwarf::RangeListEncodingString (Encoding);
3309+ }
3310+ };
3311+
3312+ } // namespace
3313+
3314+ template <
3315+ typename Ranges, typename PayloadEmitter,
3316+ std::enable_if_t <DwarfRangeListTraits<Ranges>::BaseAddressx, bool > = true >
3317+ static void emitRangeList (DwarfDebug &DD, AsmPrinter *Asm, const Ranges &R,
3318+ bool ShouldUseBaseAddress,
3319+ PayloadEmitter EmitPayload) {
32863320
32873321 auto Size = Asm->MAI ->getCodePointerSize ();
32883322 bool UseDwarf5 = DD.getDwarfVersion () >= 5 ;
32893323
32903324 // Emit our symbol so we can find the beginning of the range.
3291- Asm->OutStreamer ->emitLabel (Sym );
3325+ Asm->OutStreamer ->emitLabel (R. Label );
32923326
32933327 // Gather all the ranges that apply to the same section so they can share
32943328 // a base address entry.
3295- SmallMapVector<const MCSection *, std::vector<decltype (&*R.begin ())>, 16 >
3329+ SmallMapVector<const MCSection *, std::vector<decltype (&*R.Ranges .begin ())>,
3330+ 16 >
32963331 SectionRanges;
32973332
3298- for (const auto &Range : R)
3333+ for (const auto &Range : R. Ranges )
32993334 SectionRanges[&Range.Begin ->getSection ()].push_back (&Range);
33003335
3301- const MCSymbol *CUBase = CU. getBaseAddress ();
3336+ const MCSymbol *CUBase = R. CU -> getBaseAddress ();
33023337 bool BaseIsSet = false ;
33033338 for (const auto &P : SectionRanges) {
33043339 auto *Base = CUBase;
3305- if ((Asm->TM .getTargetTriple ().isNVPTX () && DD.tuneForGDB ())) {
3340+ if ((Asm->TM .getTargetTriple ().isNVPTX () && DD.tuneForGDB ()) ||
3341+ (DD.useSplitDwarf () && P.first ->isLinkerRelaxable ())) {
33063342 // PTX does not support subtracting labels from the code section in the
33073343 // debug_loc section. To work around this, the NVPTX backend needs the
33083344 // compile unit to have no low_pc in order to have a zero base_address
@@ -3327,8 +3363,10 @@ static void emitRangeList(
33273363 // * or, there's more than one entry to share the base address
33283364 Base = NewBase;
33293365 BaseIsSet = true ;
3330- Asm->OutStreamer ->AddComment (StringifyEnum (BaseAddressx));
3331- Asm->emitInt8 (BaseAddressx);
3366+ Asm->OutStreamer ->AddComment (
3367+ DwarfRangeListTraits<Ranges>::StringifyRangeKind (
3368+ DwarfRangeListTraits<Ranges>::BaseAddressx));
3369+ Asm->emitInt8 (DwarfRangeListTraits<Ranges>::BaseAddressx);
33323370 Asm->OutStreamer ->AddComment (" base address index" );
33333371 Asm->emitULEB128 (DD.getAddressPool ().getIndex (Base));
33343372 }
@@ -3339,16 +3377,57 @@ static void emitRangeList(
33393377 Asm->OutStreamer ->emitIntValue (0 , Size);
33403378 }
33413379
3342- for (const auto *RS : P.second ) {
3380+ if (DD.useSplitDwarf () && UseDwarf5) {
3381+ // In .dwo files, we must ensure no relocations are present. For
3382+ // .debug_ranges.dwo. this means that if there is at least one
3383+ // relocation between the start and end of a range, we must
3384+ // represent the range boundaries using indirect addresses from
3385+ // the .debug_addr section.
3386+ //
3387+ // The DWARFv5 specification (section 2.17.3) does not require
3388+ // range entries to be ordered. Therefore, we emit such range
3389+ // entries here to allow using more optimal formats (e.g.
3390+ // StartxLength) for other ranges.
3391+
3392+ auto RelaxableRanges = llvm::make_filter_range (P.second , [](auto &&RS) {
3393+ return llvm::isRangeRelaxable (RS->Begin , RS->End );
3394+ });
3395+
3396+ for (auto &&RS : RelaxableRanges) {
3397+ const auto *Begin = RS->Begin ;
3398+ const auto *End = RS->End ;
3399+ Asm->OutStreamer ->AddComment (
3400+ DwarfRangeListTraits<Ranges>::StringifyRangeKind (
3401+ DwarfRangeListTraits<Ranges>::StartxEndx));
3402+ Asm->emitInt8 (DwarfRangeListTraits<Ranges>::StartxEndx);
3403+ Asm->OutStreamer ->AddComment (" start index" );
3404+ Asm->emitULEB128 (DD.getAddressPool ().getIndex (Begin));
3405+ Asm->OutStreamer ->AddComment (" end index" );
3406+ Asm->emitULEB128 (DD.getAddressPool ().getIndex (End));
3407+ EmitPayload (*RS);
3408+ }
3409+ }
3410+
3411+ auto NonRelaxableRanges = llvm::make_filter_range (
3412+ P.second ,
3413+ [HasRelaxableRanges = DD.useSplitDwarf () && UseDwarf5](auto &&RS) {
3414+ if (!HasRelaxableRanges)
3415+ return true ;
3416+ return !llvm::isRangeRelaxable (RS->Begin , RS->End );
3417+ });
3418+
3419+ for (const auto *RS : NonRelaxableRanges) {
33433420 const MCSymbol *Begin = RS->Begin ;
33443421 const MCSymbol *End = RS->End ;
33453422 assert (Begin && " Range without a begin symbol?" );
33463423 assert (End && " Range without an end symbol?" );
33473424 if (Base) {
33483425 if (UseDwarf5) {
33493426 // Emit offset_pair when we have a base.
3350- Asm->OutStreamer ->AddComment (StringifyEnum (OffsetPair));
3351- Asm->emitInt8 (OffsetPair);
3427+ Asm->OutStreamer ->AddComment (
3428+ DwarfRangeListTraits<Ranges>::StringifyRangeKind (
3429+ DwarfRangeListTraits<Ranges>::OffsetPair));
3430+ Asm->emitInt8 (DwarfRangeListTraits<Ranges>::OffsetPair);
33523431 Asm->OutStreamer ->AddComment (" starting offset" );
33533432 Asm->emitLabelDifferenceAsULEB128 (Begin, Base);
33543433 Asm->OutStreamer ->AddComment (" ending offset" );
@@ -3358,8 +3437,10 @@ static void emitRangeList(
33583437 Asm->emitLabelDifference (End, Base, Size);
33593438 }
33603439 } else if (UseDwarf5) {
3361- Asm->OutStreamer ->AddComment (StringifyEnum (StartxLength));
3362- Asm->emitInt8 (StartxLength);
3440+ Asm->OutStreamer ->AddComment (
3441+ DwarfRangeListTraits<Ranges>::StringifyRangeKind (
3442+ DwarfRangeListTraits<Ranges>::StartxLength));
3443+ Asm->emitInt8 (DwarfRangeListTraits<Ranges>::StartxLength);
33633444 Asm->OutStreamer ->AddComment (" start index" );
33643445 Asm->emitULEB128 (DD.getAddressPool ().getIndex (Begin));
33653446 Asm->OutStreamer ->AddComment (" length" );
@@ -3373,8 +3454,10 @@ static void emitRangeList(
33733454 }
33743455
33753456 if (UseDwarf5) {
3376- Asm->OutStreamer ->AddComment (StringifyEnum (EndOfList));
3377- Asm->emitInt8 (EndOfList);
3457+ Asm->OutStreamer ->AddComment (
3458+ DwarfRangeListTraits<Ranges>::StringifyRangeKind (
3459+ DwarfRangeListTraits<Ranges>::EndOfList));
3460+ Asm->emitInt8 (DwarfRangeListTraits<Ranges>::EndOfList);
33783461 } else {
33793462 // Terminate the list with two 0 values.
33803463 Asm->OutStreamer ->emitIntValue (0 , Size);
@@ -3384,11 +3467,9 @@ static void emitRangeList(
33843467
33853468// Handles emission of both debug_loclist / debug_loclist.dwo
33863469static void emitLocList (DwarfDebug &DD, AsmPrinter *Asm, const DebugLocStream::List &List) {
3387- emitRangeList (DD, Asm, List.Label , DD.getDebugLocs ().getEntries (List),
3388- *List.CU , dwarf::DW_LLE_base_addressx,
3389- dwarf::DW_LLE_offset_pair, dwarf::DW_LLE_startx_length,
3390- dwarf::DW_LLE_end_of_list, llvm::dwarf::LocListEncodingString,
3391- /* ShouldUseBaseAddress */ true ,
3470+ DebugLocSpanList Ranges = {List.Label , List.CU ,
3471+ DD.getDebugLocs ().getEntries (List)};
3472+ emitRangeList (DD, Asm, Ranges, /* ShouldUseBaseAddress */ true ,
33923473 [&](const DebugLocStream::Entry &E) {
33933474 DD.emitDebugLocEntryLocation (E, List.CU );
33943475 });
@@ -3413,10 +3494,9 @@ void DwarfDebug::emitDebugLocImpl(MCSection *Sec) {
34133494
34143495// Emit locations into the .debug_loc/.debug_loclists section.
34153496void DwarfDebug::emitDebugLoc () {
3416- emitDebugLocImpl (
3417- getDwarfVersion () >= 5
3418- ? Asm->getObjFileLowering ().getDwarfLoclistsSection ()
3419- : Asm->getObjFileLowering ().getDwarfLocSection ());
3497+ emitDebugLocImpl (getDwarfVersion () >= 5
3498+ ? Asm->getObjFileLowering ().getDwarfLoclistsSection ()
3499+ : Asm->getObjFileLowering ().getDwarfLocSection ());
34203500}
34213501
34223502// Emit locations into the .debug_loc.dwo/.debug_loclists.dwo section.
@@ -3611,10 +3691,7 @@ void DwarfDebug::emitDebugARanges() {
36113691// / Emit a single range list. We handle both DWARF v5 and earlier.
36123692static void emitRangeList (DwarfDebug &DD, AsmPrinter *Asm,
36133693 const RangeSpanList &List) {
3614- emitRangeList (DD, Asm, List.Label , List.Ranges , *List.CU ,
3615- dwarf::DW_RLE_base_addressx, dwarf::DW_RLE_offset_pair,
3616- dwarf::DW_RLE_startx_length, dwarf::DW_RLE_end_of_list,
3617- llvm::dwarf::RangeListEncodingString,
3694+ emitRangeList (DD, Asm, List,
36183695 List.CU ->getCUNode ()->getRangesBaseAddress () ||
36193696 DD.getDwarfVersion () >= 5 ,
36203697 [](auto ) {});
0 commit comments