diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.h b/llvm/include/llvm/BinaryFormat/Dwarf.h index 095804779fa98..bd097996dd901 100644 --- a/llvm/include/llvm/BinaryFormat/Dwarf.h +++ b/llvm/include/llvm/BinaryFormat/Dwarf.h @@ -1116,6 +1116,10 @@ struct FormParams { return getDwarfOffsetByteSize(); } + inline uint64_t getDwarfMaxOffset() const { + return (getDwarfOffsetByteSize() == 4) ? UINT32_MAX : UINT64_MAX; + } + /// The size of a reference is determined by the DWARF 32/64-bit format. uint8_t getDwarfOffsetByteSize() const { return dwarf::getDwarfOffsetByteSize(Format); diff --git a/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h b/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h index 0f45a34070a67..53858342db2e0 100644 --- a/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h +++ b/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h @@ -85,7 +85,7 @@ class DwarfEmitter { virtual MCSymbol *emitDwarfDebugRangeListHeader(const CompileUnit &Unit) = 0; /// Emit debug ranges (.debug_ranges, .debug_rnglists) fragment. - virtual void emitDwarfDebugRangeListFragment( + virtual Error emitDwarfDebugRangeListFragment( const CompileUnit &Unit, const AddressRanges &LinkedRanges, PatchLocation Patch, DebugDieValuePool &AddrPool) = 0; @@ -97,7 +97,7 @@ class DwarfEmitter { virtual MCSymbol *emitDwarfDebugLocListHeader(const CompileUnit &Unit) = 0; /// Emit debug locations (.debug_loc, .debug_loclists) fragment. - virtual void emitDwarfDebugLocListFragment( + virtual Error emitDwarfDebugLocListFragment( const CompileUnit &Unit, const DWARFLocationExpressionsVector &LinkedLocationExpression, PatchLocation Patch, DebugDieValuePool &AddrPool) = 0; @@ -596,13 +596,13 @@ class LLVM_ABI DWARFLinker : public DWARFLinkerBase { /// Construct the output DIE tree by cloning the DIEs we /// chose to keep above. If there are no valid relocs, then there's /// nothing to clone/emit. - LLVM_ABI uint64_t cloneAllCompileUnits(DWARFContext &DwarfContext, - const DWARFFile &File, - bool IsLittleEndian); + LLVM_ABI Expected cloneAllCompileUnits(DWARFContext &DwarfContext, + const DWARFFile &File, + bool IsLittleEndian); /// Emit the .debug_addr section for the \p Unit. - LLVM_ABI void emitDebugAddrSection(CompileUnit &Unit, - const uint16_t DwarfVersion) const; + LLVM_ABI Error emitDebugAddrSection(CompileUnit &Unit, + const uint16_t DwarfVersion) const; using ExpressionHandlerRef = function_ref &, SmallVectorImpl &, @@ -610,9 +610,9 @@ class LLVM_ABI DWARFLinker : public DWARFLinkerBase { /// Compute and emit debug locations (.debug_loc, .debug_loclists) /// for \p Unit, patch the attributes referencing it. - LLVM_ABI void generateUnitLocations(CompileUnit &Unit, - const DWARFFile &File, - ExpressionHandlerRef ExprHandler); + LLVM_ABI Error generateUnitLocations(CompileUnit &Unit, + const DWARFFile &File, + ExpressionHandlerRef ExprHandler); private: using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec; @@ -729,7 +729,7 @@ class LLVM_ABI DWARFLinker : public DWARFLinkerBase { /// Clone and emit the line table for the specified \p Unit. /// Translate directories and file names if necessary. /// Relocate address ranges. - void generateLineTableForUnit(CompileUnit &Unit); + Error generateLineTableForUnit(CompileUnit &Unit); }; /// Assign an abbreviation number to \p Abbrev @@ -737,8 +737,8 @@ class LLVM_ABI DWARFLinker : public DWARFLinkerBase { /// 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, - DebugDieValuePool &AddrPool) const; + Error generateUnitRanges(CompileUnit &Unit, const DWARFFile &File, + DebugDieValuePool &AddrPool) const; /// Emit the accelerator entries for \p Unit. void emitAcceleratorEntriesForUnit(CompileUnit &Unit); diff --git a/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h b/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h index 03fc7290aacca..6de3e9ca1fc86 100644 --- a/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h +++ b/llvm/include/llvm/DWARFLinker/Classic/DWARFStreamer.h @@ -106,10 +106,10 @@ class LLVM_ABI DwarfStreamer : public DwarfEmitter { MCSymbol *emitDwarfDebugRangeListHeader(const CompileUnit &Unit) override; /// Emit debug ranges(.debug_ranges, .debug_rnglists) fragment. - void emitDwarfDebugRangeListFragment(const CompileUnit &Unit, - const AddressRanges &LinkedRanges, - PatchLocation Patch, - DebugDieValuePool &AddrPool) override; + Error emitDwarfDebugRangeListFragment(const CompileUnit &Unit, + const AddressRanges &LinkedRanges, + PatchLocation Patch, + DebugDieValuePool &AddrPool) override; /// Emit debug ranges(.debug_ranges, .debug_rnglists) footer. void emitDwarfDebugRangeListFooter(const CompileUnit &Unit, @@ -130,7 +130,7 @@ class LLVM_ABI DwarfStreamer : public DwarfEmitter { MCSymbol *EndLabel) override; /// Emit debug ranges(.debug_loc, .debug_loclists) fragment. - void emitDwarfDebugLocListFragment( + Error emitDwarfDebugLocListFragment( const CompileUnit &Unit, const DWARFLocationExpressionsVector &LinkedLocationExpression, PatchLocation Patch, DebugDieValuePool &AddrPool) override; @@ -222,6 +222,15 @@ class LLVM_ABI DwarfStreamer : public DwarfEmitter { WarningHandler(Warning, Context, nullptr); } + Expected clampSecOffset(uint64_t Offset, dwarf::FormParams FP, + StringRef Section) { + if (Offset <= FP.getDwarfMaxOffset()) + return Offset; + return createStringError(Section + " section offset 0x" + + Twine::utohexstr(Offset) + " exceeds the " + + dwarf::FormatString(FP.Format) + " limit"); + } + MCSection *getMCSection(DebugSectionKind SecKind); void emitMacroTableImpl(const DWARFDebugMacro *MacroTable, @@ -229,24 +238,24 @@ class LLVM_ABI DwarfStreamer : public DwarfEmitter { OffsetsStringPool &StringPool, uint64_t &OutOffset); /// Emit piece of .debug_ranges for \p LinkedRanges. - void emitDwarfDebugRangesTableFragment(const CompileUnit &Unit, - const AddressRanges &LinkedRanges, - PatchLocation Patch); + Error 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, - DebugDieValuePool &AddrPool); + Error emitDwarfDebugRngListsTableFragment(const CompileUnit &Unit, + const AddressRanges &LinkedRanges, + PatchLocation Patch, + DebugDieValuePool &AddrPool); /// Emit piece of .debug_loc for \p LinkedRanges. - void emitDwarfDebugLocTableFragment( + Error emitDwarfDebugLocTableFragment( const CompileUnit &Unit, const DWARFLocationExpressionsVector &LinkedLocationExpression, PatchLocation Patch); /// Emit piece of .debug_loclists for \p LinkedRanges. - void emitDwarfDebugLocListsTableFragment( + Error emitDwarfDebugLocListsTableFragment( const CompileUnit &Unit, const DWARFLocationExpressionsVector &LinkedLocationExpression, PatchLocation Patch, DebugDieValuePool &AddrPool); diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp index ba2dfa1521130..ff8395e3c9e1b 100644 --- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp +++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp @@ -2002,10 +2002,10 @@ DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE, /// 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::generateUnitRanges(CompileUnit &Unit, const DWARFFile &File, - DebugDieValuePool &AddrPool) const { +Error DWARFLinker::generateUnitRanges(CompileUnit &Unit, const DWARFFile &File, + DebugDieValuePool &AddrPool) const { if (LLVM_UNLIKELY(Options.Update)) - return; + return Error::success(); const auto &FunctionRanges = Unit.getFunctionRanges(); @@ -2056,31 +2056,35 @@ void DWARFLinker::generateUnitRanges(CompileUnit &Unit, const DWARFFile &File, } // Emit linked ranges. - TheDwarfEmitter->emitDwarfDebugRangeListFragment( - Unit, LinkedRanges, AttributePatch, AddrPool); + if (Error E = TheDwarfEmitter->emitDwarfDebugRangeListFragment( + Unit, LinkedRanges, AttributePatch, AddrPool)) + return E; } // Emit ranges for Unit AT_ranges attribute. if (UnitRngListAttribute.has_value()) - TheDwarfEmitter->emitDwarfDebugRangeListFragment( - Unit, LinkedFunctionRanges, *UnitRngListAttribute, AddrPool); + if (Error E = TheDwarfEmitter->emitDwarfDebugRangeListFragment( + Unit, LinkedFunctionRanges, *UnitRngListAttribute, AddrPool)) + return E; // Emit ranges footer. TheDwarfEmitter->emitDwarfDebugRangeListFooter(Unit, EndLabel); } + + return Error::success(); } -void DWARFLinker::DIECloner::generateUnitLocations( +Error DWARFLinker::DIECloner::generateUnitLocations( CompileUnit &Unit, const DWARFFile &File, ExpressionHandlerRef ExprHandler) { if (LLVM_UNLIKELY(Linker.Options.Update)) - return; + return Error::success(); const LocListAttributesTy &AllLocListAttributes = Unit.getLocationAttributes(); if (AllLocListAttributes.empty()) - return; + return Error::success(); // Emit locations list table header. MCSymbol *EndLabel = Emitter->emitDwarfDebugLocListHeader(Unit); @@ -2117,12 +2121,15 @@ void DWARFLinker::DIECloner::generateUnitLocations( } // Emit locations list table fragment corresponding to the CurLocAttr. - Emitter->emitDwarfDebugLocListFragment(Unit, LinkedLocationExpressions, - CurLocAttr, AddrPool); + if (Error E = Emitter->emitDwarfDebugLocListFragment( + Unit, LinkedLocationExpressions, CurLocAttr, AddrPool)) + return E; } // Emit locations list table footer. Emitter->emitDwarfDebugLocListFooter(Unit, EndLabel); + + return Error::success(); } static void patchAddrBase(DIE &Die, DIEInteger Offset) { @@ -2135,24 +2142,31 @@ static void patchAddrBase(DIE &Die, DIEInteger Offset) { llvm_unreachable("Didn't find a DW_AT_addr_base in cloned DIE!"); } -void DWARFLinker::DIECloner::emitDebugAddrSection( +Error DWARFLinker::DIECloner::emitDebugAddrSection( CompileUnit &Unit, const uint16_t DwarfVersion) const { if (LLVM_UNLIKELY(Linker.Options.Update)) - return; + return Error::success(); if (DwarfVersion < 5) - return; + return Error::success(); if (AddrPool.getValues().empty()) - return; + return Error::success(); MCSymbol *EndLabel = Emitter->emitDwarfDebugAddrsHeader(Unit); - patchAddrBase(*Unit.getOutputUnitDIE(), - DIEInteger(Emitter->getDebugAddrSectionSize())); + uint64_t AddrOffset = Emitter->getDebugAddrSectionSize(); + dwarf::FormParams FP = Unit.getOrigUnit().getFormParams(); + if (AddrOffset > FP.getDwarfMaxOffset()) + return createStringError(".debug_addr section offset 0x" + + Twine::utohexstr(AddrOffset) + " exceeds the " + + dwarf::FormatString(FP.Format) + " limit"); + patchAddrBase(*Unit.getOutputUnitDIE(), DIEInteger(AddrOffset)); Emitter->emitDwarfDebugAddrs(AddrPool.getValues(), Unit.getOrigUnit().getAddressByteSize()); Emitter->emitDwarfDebugAddrsFooter(Unit, EndLabel); + + return Error::success(); } /// A helper struct to help keep track of the association between the input and @@ -2228,19 +2242,26 @@ void DWARFLinker::DIECloner::rememberUnitForMacroOffset(CompileUnit &Unit) { } } -void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) { +Error DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) { if (LLVM_UNLIKELY(Emitter == nullptr)) - return; + return Error::success(); // Check whether DW_AT_stmt_list attribute is presented. DWARFDie CUDie = Unit.getOrigUnit().getUnitDIE(); auto StmtList = dwarf::toSectionOffset(CUDie.find(dwarf::DW_AT_stmt_list)); if (!StmtList) - return; + return Error::success(); // Update the cloned DW_AT_stmt_list with the correct debug_line offset. - if (auto *OutputDIE = Unit.getOutputUnitDIE()) - patchStmtList(*OutputDIE, DIEInteger(Emitter->getLineSectionSize())); + if (auto *OutputDIE = Unit.getOutputUnitDIE()) { + uint64_t StmtOffset = Emitter->getLineSectionSize(); + dwarf::FormParams FP = Unit.getOrigUnit().getFormParams(); + if (StmtOffset > FP.getDwarfMaxOffset()) + return createStringError(".debug_line section offset 0x" + + Twine::utohexstr(StmtOffset) + " exceeds the " + + dwarf::FormatString(FP.Format) + " limit"); + patchStmtList(*OutputDIE, DIEInteger(StmtOffset)); + } if (const DWARFDebugLine::LineTable *LT = ObjFile.Dwarf->getLineTableForUnit(&Unit.getOrigUnit())) { @@ -2404,6 +2425,8 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) { } else Linker.reportWarning("Cann't load line table.", ObjFile); + + return Error::success(); } void DWARFLinker::emitAcceleratorEntriesForUnit(CompileUnit &Unit) { @@ -2783,7 +2806,7 @@ Error DWARFLinker::loadClangModule(ObjFileLoaderTy Loader, return Error::success(); } -uint64_t DWARFLinker::DIECloner::cloneAllCompileUnits( +Expected DWARFLinker::DIECloner::cloneAllCompileUnits( DWARFContext &DwarfContext, const DWARFFile &File, bool IsLittleEndian) { uint64_t OutputDebugInfoSize = (Emitter == nullptr) ? 0 : Emitter->getDebugInfoSectionSize(); @@ -2811,14 +2834,16 @@ uint64_t DWARFLinker::DIECloner::cloneAllCompileUnits( if (Emitter != nullptr) { - generateLineTableForUnit(*CurrentUnit); + if (Error E = generateLineTableForUnit(*CurrentUnit)) + return E; Linker.emitAcceleratorEntriesForUnit(*CurrentUnit); if (LLVM_UNLIKELY(Linker.Options.Update)) continue; - Linker.generateUnitRanges(*CurrentUnit, File, AddrPool); + if (Error E = Linker.generateUnitRanges(*CurrentUnit, File, AddrPool)) + return E; auto ProcessExpr = [&](SmallVectorImpl &SrcBytes, SmallVectorImpl &OutBytes, @@ -2832,8 +2857,10 @@ uint64_t DWARFLinker::DIECloner::cloneAllCompileUnits( File, *CurrentUnit, OutBytes, RelocAdjustment, IsLittleEndian); }; - generateUnitLocations(*CurrentUnit, File, ProcessExpr); - emitDebugAddrSection(*CurrentUnit, DwarfVersion); + if (Error E = generateUnitLocations(*CurrentUnit, File, ProcessExpr)) + return E; + if (Error E = emitDebugAddrSection(*CurrentUnit, DwarfVersion)) + return E; } AddrPool.clear(); } @@ -3041,7 +3068,7 @@ Error DWARFLinker::link() { // Note, although this loop runs in serial, it can run in parallel with // the analyzeContextInfo loop so long as we process files with indices >= // than those processed by analyzeContextInfo. - auto CloneLambda = [&](size_t I) { + auto CloneLambda = [&](size_t I, llvm::Error &CE) { auto &OptContext = ObjectContexts[I]; if (OptContext.Skip || !OptContext.File.Dwarf) return; @@ -3073,12 +3100,17 @@ Error DWARFLinker::link() { LLVM_UNLIKELY(Options.Update)) { SizeByObject[OptContext.File.FileName].Input = getDebugInfoSize(*OptContext.File.Dwarf); - SizeByObject[OptContext.File.FileName].Output = + Expected SizeOrErr = DIECloner(*this, TheDwarfEmitter, OptContext.File, DIEAlloc, OptContext.CompileUnits, Options.Update, DebugStrPool, DebugLineStrPool, StringOffsetPool) .cloneAllCompileUnits(*OptContext.File.Dwarf, OptContext.File, OptContext.File.Dwarf->isLittleEndian()); + if (!SizeOrErr) { + CE = SizeOrErr.takeError(); + return; + } + SizeByObject[OptContext.File.FileName].Output = *SizeOrErr; } if ((TheDwarfEmitter != nullptr) && !OptContext.CompileUnits.empty() && LLVM_LIKELY(!Options.Update)) @@ -3126,7 +3158,7 @@ Error DWARFLinker::link() { } }; - auto CloneAll = [&]() { + auto CloneAll = [&](llvm::Error &CE) { for (unsigned I = 0, E = NumObjects; I != E; ++I) { { std::unique_lock LockGuard(ProcessedFilesMutex); @@ -3136,27 +3168,37 @@ Error DWARFLinker::link() { } } - CloneLambda(I); + CloneLambda(I, CE); + if (CE) + return; } EmitLambda(); }; + Error CE = Error::success(); + // To limit memory usage in the single threaded case, analyze and clone are // run sequentially so the OptContext is freed after processing each object // in endDebugObject. if (Options.Threads == 1) { for (unsigned I = 0, E = NumObjects; I != E; ++I) { AnalyzeLambda(I); - CloneLambda(I); + CloneLambda(I, CE); + if (CE) + break; } - EmitLambda(); + if (!CE) + EmitLambda(); } else { DefaultThreadPool Pool(hardware_concurrency(2)); Pool.async(AnalyzeAll); - Pool.async(CloneAll); + Pool.async(CloneAll, std::reference_wrapper(CE)); Pool.wait(); } + if (CE) + return CE; + if (Options.Statistics) { // Create a vector sorted in descending order by output size. std::vector> Sorted; @@ -3237,10 +3279,14 @@ Error DWARFLinker::cloneModuleUnit(LinkContext &Context, RefModuleUnit &Unit, UnitListTy CompileUnits; CompileUnits.emplace_back(std::move(Unit.Unit)); assert(TheDwarfEmitter); - DIECloner(*this, TheDwarfEmitter, Unit.File, DIEAlloc, CompileUnits, - Options.Update, DebugStrPool, DebugLineStrPool, StringOffsetPool) - .cloneAllCompileUnits(*Unit.File.Dwarf, Unit.File, - Unit.File.Dwarf->isLittleEndian()); + Expected SizeOrErr = + DIECloner(*this, TheDwarfEmitter, Unit.File, DIEAlloc, CompileUnits, + Options.Update, DebugStrPool, DebugLineStrPool, + StringOffsetPool) + .cloneAllCompileUnits(*Unit.File.Dwarf, Unit.File, + Unit.File.Dwarf->isLittleEndian()); + if (!SizeOrErr) + return SizeOrErr.takeError(); return Error::success(); } diff --git a/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp b/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp index 4e4d86e5cb8d1..996b9aa1f9126 100644 --- a/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp +++ b/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp @@ -472,10 +472,14 @@ void DwarfStreamer::emitDwarfDebugArangesTable( Asm->OutStreamer->emitLabel(EndLabel); } -void DwarfStreamer::emitDwarfDebugRangesTableFragment( +Error DwarfStreamer::emitDwarfDebugRangesTableFragment( const CompileUnit &Unit, const AddressRanges &LinkedRanges, PatchLocation Patch) { - Patch.set(RangesSectionSize); + Expected Offset = clampSecOffset( + RangesSectionSize, Unit.getOrigUnit().getFormParams(), ".debug_ranges"); + if (!Offset) + return Offset.takeError(); + Patch.set(*Offset); // Make .debug_ranges to be current section. MS->switchSection(MC->getObjectFileInfo()->getDwarfRangesSection()); @@ -500,6 +504,7 @@ void DwarfStreamer::emitDwarfDebugRangesTableFragment( RangesSectionSize += AddressSize; RangesSectionSize += AddressSize; + return Error::success(); } MCSymbol * @@ -538,15 +543,15 @@ DwarfStreamer::emitDwarfDebugRangeListHeader(const CompileUnit &Unit) { return EndLabel; } -void DwarfStreamer::emitDwarfDebugRangeListFragment( +Error DwarfStreamer::emitDwarfDebugRangeListFragment( const CompileUnit &Unit, const AddressRanges &LinkedRanges, PatchLocation Patch, DebugDieValuePool &AddrPool) { if (Unit.getOrigUnit().getVersion() < 5) { - emitDwarfDebugRangesTableFragment(Unit, LinkedRanges, Patch); - return; + return emitDwarfDebugRangesTableFragment(Unit, LinkedRanges, Patch); } - emitDwarfDebugRngListsTableFragment(Unit, LinkedRanges, Patch, AddrPool); + return emitDwarfDebugRngListsTableFragment(Unit, LinkedRanges, Patch, + AddrPool); } void DwarfStreamer::emitDwarfDebugRangeListFooter(const CompileUnit &Unit, @@ -561,10 +566,15 @@ void DwarfStreamer::emitDwarfDebugRangeListFooter(const CompileUnit &Unit, Asm->OutStreamer->emitLabel(EndLabel); } -void DwarfStreamer::emitDwarfDebugRngListsTableFragment( +Error DwarfStreamer::emitDwarfDebugRngListsTableFragment( const CompileUnit &Unit, const AddressRanges &LinkedRanges, PatchLocation Patch, DebugDieValuePool &AddrPool) { - Patch.set(RngListsSectionSize); + Expected Offset = + clampSecOffset(RngListsSectionSize, Unit.getOrigUnit().getFormParams(), + ".debug_rnglists"); + if (!Offset) + return Offset.takeError(); + Patch.set(*Offset); // Make .debug_rnglists to be current section. MS->switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection()); @@ -597,6 +607,7 @@ void DwarfStreamer::emitDwarfDebugRngListsTableFragment( // Emit the terminator entry. MS->emitInt8(dwarf::DW_RLE_end_of_list); RngListsSectionSize += 1; + return Error::success(); } /// Emit debug locations(.debug_loc, .debug_loclists) header. @@ -636,17 +647,17 @@ MCSymbol *DwarfStreamer::emitDwarfDebugLocListHeader(const CompileUnit &Unit) { } /// Emit debug locations(.debug_loc, .debug_loclists) fragment. -void DwarfStreamer::emitDwarfDebugLocListFragment( +Error DwarfStreamer::emitDwarfDebugLocListFragment( const CompileUnit &Unit, const DWARFLocationExpressionsVector &LinkedLocationExpression, PatchLocation Patch, DebugDieValuePool &AddrPool) { if (Unit.getOrigUnit().getVersion() < 5) { - emitDwarfDebugLocTableFragment(Unit, LinkedLocationExpression, Patch); - return; + return emitDwarfDebugLocTableFragment(Unit, LinkedLocationExpression, + Patch); } - emitDwarfDebugLocListsTableFragment(Unit, LinkedLocationExpression, Patch, - AddrPool); + return emitDwarfDebugLocListsTableFragment(Unit, LinkedLocationExpression, + Patch, AddrPool); } /// Emit debug locations(.debug_loc, .debug_loclists) footer. @@ -663,11 +674,15 @@ void DwarfStreamer::emitDwarfDebugLocListFooter(const CompileUnit &Unit, } /// Emit piece of .debug_loc for \p LinkedLocationExpression. -void DwarfStreamer::emitDwarfDebugLocTableFragment( +Error DwarfStreamer::emitDwarfDebugLocTableFragment( const CompileUnit &Unit, const DWARFLocationExpressionsVector &LinkedLocationExpression, PatchLocation Patch) { - Patch.set(LocSectionSize); + Expected Offset = clampSecOffset( + LocSectionSize, Unit.getOrigUnit().getFormParams(), ".debug_loc"); + if (!Offset) + return Offset.takeError(); + Patch.set(*Offset); // Make .debug_loc to be current section. MS->switchSection(MC->getObjectFileInfo()->getDwarfLocSection()); @@ -700,6 +715,7 @@ void DwarfStreamer::emitDwarfDebugLocTableFragment( LocSectionSize += AddressSize; LocSectionSize += AddressSize; + return Error::success(); } /// Emit .debug_addr header. @@ -754,11 +770,16 @@ void DwarfStreamer::emitDwarfDebugAddrsFooter(const CompileUnit &Unit, } /// Emit piece of .debug_loclists for \p LinkedLocationExpression. -void DwarfStreamer::emitDwarfDebugLocListsTableFragment( +Error DwarfStreamer::emitDwarfDebugLocListsTableFragment( const CompileUnit &Unit, const DWARFLocationExpressionsVector &LinkedLocationExpression, PatchLocation Patch, DebugDieValuePool &AddrPool) { - Patch.set(LocListsSectionSize); + Expected Offset = + clampSecOffset(LocListsSectionSize, Unit.getOrigUnit().getFormParams(), + ".debug_loclists"); + if (!Offset) + return Offset.takeError(); + Patch.set(*Offset); // Make .debug_loclists the current section. MS->switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection()); @@ -805,6 +826,7 @@ void DwarfStreamer::emitDwarfDebugLocListsTableFragment( // Emit the terminator entry. MS->emitInt8(dwarf::DW_LLE_end_of_list); LocListsSectionSize += 1; + return Error::success(); } void DwarfStreamer::emitLineTableForUnit(