@@ -1014,32 +1014,36 @@ void DWARFLinker::assignAbbrev(DIEAbbrev &Abbrev) {
10141014unsigned DWARFLinker::DIECloner::cloneStringAttribute (DIE &Die,
10151015 AttributeSpec AttrSpec,
10161016 const DWARFFormValue &Val,
1017- const DWARFUnit &,
1017+ const DWARFUnit &U ,
10181018 AttributesInfo &Info) {
10191019 std::optional<const char *> String = dwarf::toString (Val);
10201020 if (!String)
10211021 return 0 ;
1022-
10231022 DwarfStringPoolEntryRef StringEntry;
10241023 if (AttrSpec.Form == dwarf::DW_FORM_line_strp) {
10251024 StringEntry = DebugLineStrPool.getEntry (*String);
10261025 } else {
10271026 StringEntry = DebugStrPool.getEntry (*String);
1028-
10291027 // Update attributes info.
10301028 if (AttrSpec.Attr == dwarf::DW_AT_name)
10311029 Info.Name = StringEntry;
10321030 else if (AttrSpec.Attr == dwarf::DW_AT_MIPS_linkage_name ||
10331031 AttrSpec.Attr == dwarf::DW_AT_linkage_name)
10341032 Info.MangledName = StringEntry;
1035-
1033+ if (U.getVersion () >= 5 ) {
1034+ // Switch everything to DW_FORM_strx strings.
1035+ auto StringOffsetIndex =
1036+ StringOffsetPool.getValueIndex (StringEntry.getOffset ());
1037+ return Die
1038+ .addValue (DIEAlloc, dwarf::Attribute (AttrSpec.Attr ),
1039+ dwarf::DW_FORM_strx, DIEInteger (StringOffsetIndex))
1040+ ->sizeOf (U.getFormParams ());
1041+ }
10361042 // Switch everything to out of line strings.
10371043 AttrSpec.Form = dwarf::DW_FORM_strp;
10381044 }
1039-
10401045 Die.addValue (DIEAlloc, dwarf::Attribute (AttrSpec.Attr ), AttrSpec.Form ,
10411046 DIEInteger (StringEntry.getOffset ()));
1042-
10431047 return 4 ;
10441048}
10451049
@@ -1359,7 +1363,7 @@ unsigned DWARFLinker::DIECloner::cloneAddressAttribute(
13591363 return Unit.getOrigUnit ().getAddressByteSize ();
13601364 }
13611365
1362- auto AddrIndex = AddrPool.getAddrIndex (*Addr);
1366+ auto AddrIndex = AddrPool.getValueIndex (*Addr);
13631367
13641368 return Die
13651369 .addValue (DIEAlloc, static_cast <dwarf::Attribute>(AttrSpec.Attr ),
@@ -1391,6 +1395,17 @@ unsigned DWARFLinker::DIECloner::cloneScalarAttribute(
13911395 }
13921396 }
13931397
1398+ if (AttrSpec.Attr == dwarf::DW_AT_str_offsets_base) {
1399+ // DWARFLinker generates common .debug_str_offsets table used for all
1400+ // compile units. The offset to the common .debug_str_offsets table is 8 on
1401+ // DWARF32.
1402+ Info.AttrStrOffsetBaseSeen = true ;
1403+ return Die
1404+ .addValue (DIEAlloc, dwarf::DW_AT_str_offsets_base,
1405+ dwarf::DW_FORM_sec_offset, DIEInteger (8 ))
1406+ ->sizeOf (Unit.getOrigUnit ().getFormParams ());
1407+ }
1408+
13941409 if (LLVM_UNLIKELY (Linker.Options .Update )) {
13951410 if (auto OptionalValue = Val.getAsUnsignedConstant ())
13961411 Value = *OptionalValue;
@@ -1608,9 +1623,6 @@ shouldSkipAttribute(bool Update,
16081623 // Since DW_AT_rnglists_base is used for only DW_FORM_rnglistx the
16091624 // DW_AT_rnglists_base is removed.
16101625 return !Update;
1611- case dwarf::DW_AT_str_offsets_base:
1612- // FIXME: Use the string offset table with Dwarf 5.
1613- return true ;
16141626 case dwarf::DW_AT_loclists_base:
16151627 // In case !Update the .debug_addr table is not generated/preserved.
16161628 // Thus instead of DW_FORM_loclistx the DW_FORM_sec_offset is used.
@@ -1777,6 +1789,14 @@ DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE,
17771789 }
17781790 }
17791791
1792+ if (Unit.getOrigUnit ().getVersion () >= 5 && !AttrInfo.AttrStrOffsetBaseSeen &&
1793+ Die->getTag () == dwarf::DW_TAG_compile_unit) {
1794+ // No DW_AT_str_offsets_base seen, add it to the DIE.
1795+ Die->addValue (DIEAlloc, dwarf::DW_AT_str_offsets_base,
1796+ dwarf::DW_FORM_sec_offset, DIEInteger (8 ));
1797+ OutOffset += 4 ;
1798+ }
1799+
17801800 DIEAbbrev NewAbbrev = Die->generateAbbrev ();
17811801 if (HasChildren)
17821802 NewAbbrev.setChildrenFlag (dwarf::DW_CHILDREN_yes);
@@ -1812,8 +1832,8 @@ DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE,
18121832// / Patch the input object file relevant debug_ranges or debug_rnglists
18131833// / entries and emit them in the output file. Update the relevant attributes
18141834// / to point at the new entries.
1815- void DWARFLinker::generateUnitRanges (CompileUnit &Unit,
1816- const DWARFFile &File ) const {
1835+ void DWARFLinker::generateUnitRanges (CompileUnit &Unit, const DWARFFile &File,
1836+ DebugDieValuePool &AddrPool ) const {
18171837 if (LLVM_UNLIKELY (Options.Update ))
18181838 return ;
18191839
@@ -1866,14 +1886,14 @@ void DWARFLinker::generateUnitRanges(CompileUnit &Unit,
18661886 }
18671887
18681888 // Emit linked ranges.
1869- TheDwarfEmitter->emitDwarfDebugRangeListFragment (Unit, LinkedRanges,
1870- AttributePatch);
1889+ TheDwarfEmitter->emitDwarfDebugRangeListFragment (
1890+ Unit, LinkedRanges, AttributePatch, AddrPool );
18711891 }
18721892
18731893 // Emit ranges for Unit AT_ranges attribute.
18741894 if (UnitRngListAttribute.has_value ())
18751895 TheDwarfEmitter->emitDwarfDebugRangeListFragment (
1876- Unit, LinkedFunctionRanges, *UnitRngListAttribute);
1896+ Unit, LinkedFunctionRanges, *UnitRngListAttribute, AddrPool );
18771897
18781898 // Emit ranges footer.
18791899 TheDwarfEmitter->emitDwarfDebugRangeListFooter (Unit, EndLabel);
@@ -1955,13 +1975,14 @@ void DWARFLinker::DIECloner::emitDebugAddrSection(
19551975 if (DwarfVersion < 5 )
19561976 return ;
19571977
1958- if (AddrPool.Addrs .empty ())
1978+ if (AddrPool.DieValues .empty ())
19591979 return ;
19601980
19611981 MCSymbol *EndLabel = Emitter->emitDwarfDebugAddrsHeader (Unit);
19621982 patchAddrBase (*Unit.getOutputUnitDIE (),
19631983 DIEInteger (Emitter->getDebugAddrSectionSize ()));
1964- Emitter->emitDwarfDebugAddrs (AddrPool.Addrs , Unit.getOrigUnit ().getAddressByteSize ());
1984+ Emitter->emitDwarfDebugAddrs (AddrPool.DieValues ,
1985+ Unit.getOrigUnit ().getAddressByteSize ());
19651986 Emitter->emitDwarfDebugAddrsFooter (Unit, EndLabel);
19661987}
19671988
@@ -2515,7 +2536,7 @@ uint64_t DWARFLinker::DIECloner::cloneAllCompileUnits(
25152536 if (LLVM_UNLIKELY (Linker.Options .Update ))
25162537 continue ;
25172538
2518- Linker.generateUnitRanges (*CurrentUnit, File);
2539+ Linker.generateUnitRanges (*CurrentUnit, File, AddrPool );
25192540
25202541 auto ProcessExpr = [&](SmallVectorImpl<uint8_t > &SrcBytes,
25212542 SmallVectorImpl<uint8_t > &OutBytes,
@@ -2612,6 +2633,7 @@ Error DWARFLinker::link() {
26122633 // reproducibility.
26132634 OffsetsStringPool DebugStrPool (StringsTranslator, true );
26142635 OffsetsStringPool DebugLineStrPool (StringsTranslator, false );
2636+ DebugDieValuePool StringOffsetPool;
26152637
26162638 // ODR Contexts for the optimize.
26172639 DeclContextTree ODRContexts;
@@ -2675,7 +2697,7 @@ Error DWARFLinker::link() {
26752697
26762698 for (auto &CU : OptContext.ModuleUnits ) {
26772699 if (Error Err = cloneModuleUnit (OptContext, CU, ODRContexts, DebugStrPool,
2678- DebugLineStrPool))
2700+ DebugLineStrPool, StringOffsetPool ))
26792701 reportWarning (toString (std::move (Err)), CU.File );
26802702 }
26812703 }
@@ -2772,7 +2794,7 @@ Error DWARFLinker::link() {
27722794 SizeByObject[OptContext.File .FileName ].Output =
27732795 DIECloner (*this , TheDwarfEmitter.get (), OptContext.File , DIEAlloc,
27742796 OptContext.CompileUnits , Options.Update , DebugStrPool,
2775- DebugLineStrPool)
2797+ DebugLineStrPool, StringOffsetPool )
27762798 .cloneAllCompileUnits (*OptContext.File .Dwarf , OptContext.File ,
27772799 OptContext.File .Dwarf ->isLittleEndian ());
27782800 }
@@ -2789,6 +2811,8 @@ Error DWARFLinker::link() {
27892811 if (TheDwarfEmitter != nullptr ) {
27902812 TheDwarfEmitter->emitAbbrevs (Abbreviations, Options.TargetDWARFVersion );
27912813 TheDwarfEmitter->emitStrings (DebugStrPool);
2814+ TheDwarfEmitter->emitStringOffsets (StringOffsetPool.DieValues ,
2815+ Options.TargetDWARFVersion );
27922816 TheDwarfEmitter->emitLineStrings (DebugLineStrPool);
27932817 for (AccelTableKind TableKind : Options.AccelTables ) {
27942818 switch (TableKind) {
@@ -2905,6 +2929,7 @@ Error DWARFLinker::cloneModuleUnit(LinkContext &Context, RefModuleUnit &Unit,
29052929 DeclContextTree &ODRContexts,
29062930 OffsetsStringPool &DebugStrPool,
29072931 OffsetsStringPool &DebugLineStrPool,
2932+ DebugDieValuePool &StringOffsetPool,
29082933 unsigned Indent) {
29092934 assert (Unit.Unit .get () != nullptr );
29102935
@@ -2931,7 +2956,7 @@ Error DWARFLinker::cloneModuleUnit(LinkContext &Context, RefModuleUnit &Unit,
29312956 CompileUnits.emplace_back (std::move (Unit.Unit ));
29322957 assert (TheDwarfEmitter);
29332958 DIECloner (*this , TheDwarfEmitter.get (), Unit.File , DIEAlloc, CompileUnits,
2934- Options.Update , DebugStrPool, DebugLineStrPool)
2959+ Options.Update , DebugStrPool, DebugLineStrPool, StringOffsetPool )
29352960 .cloneAllCompileUnits (*Unit.File .Dwarf , Unit.File ,
29362961 Unit.File .Dwarf ->isLittleEndian ());
29372962 return Error::success ();
0 commit comments