@@ -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;
@@ -1634,9 +1649,6 @@ shouldSkipAttribute(bool Update,
16341649 // Since DW_AT_rnglists_base is used for only DW_FORM_rnglistx the
16351650 // DW_AT_rnglists_base is removed.
16361651 return !Update;
1637- case dwarf::DW_AT_str_offsets_base:
1638- // FIXME: Use the string offset table with Dwarf 5.
1639- return true ;
16401652 case dwarf::DW_AT_loclists_base:
16411653 // In case !Update the .debug_addr table is not generated/preserved.
16421654 // Thus instead of DW_FORM_loclistx the DW_FORM_sec_offset is used.
@@ -1803,6 +1815,14 @@ DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE,
18031815 }
18041816 }
18051817
1818+ if (Unit.getOrigUnit ().getVersion () >= 5 && !AttrInfo.AttrStrOffsetBaseSeen &&
1819+ Die->getTag () == dwarf::DW_TAG_compile_unit) {
1820+ // No DW_AT_str_offsets_base seen, add it to the DIE.
1821+ Die->addValue (DIEAlloc, dwarf::DW_AT_str_offsets_base,
1822+ dwarf::DW_FORM_sec_offset, DIEInteger (8 ));
1823+ OutOffset += 4 ;
1824+ }
1825+
18061826 DIEAbbrev NewAbbrev = Die->generateAbbrev ();
18071827 if (HasChildren)
18081828 NewAbbrev.setChildrenFlag (dwarf::DW_CHILDREN_yes);
@@ -1839,7 +1859,7 @@ DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE,
18391859// / entries and emit them in the output file. Update the relevant attributes
18401860// / to point at the new entries.
18411861void DWARFLinker::generateUnitRanges (CompileUnit &Unit, const DWARFFile &File,
1842- DebugAddrPool &AddrPool) const {
1862+ DebugDieValuePool &AddrPool) const {
18431863 if (LLVM_UNLIKELY (Options.Update ))
18441864 return ;
18451865
@@ -1981,13 +2001,14 @@ void DWARFLinker::DIECloner::emitDebugAddrSection(
19812001 if (DwarfVersion < 5 )
19822002 return ;
19832003
1984- if (AddrPool.Addrs .empty ())
2004+ if (AddrPool.DieValues .empty ())
19852005 return ;
19862006
19872007 MCSymbol *EndLabel = Emitter->emitDwarfDebugAddrsHeader (Unit);
19882008 patchAddrBase (*Unit.getOutputUnitDIE (),
19892009 DIEInteger (Emitter->getDebugAddrSectionSize ()));
1990- Emitter->emitDwarfDebugAddrs (AddrPool.Addrs , Unit.getOrigUnit ().getAddressByteSize ());
2010+ Emitter->emitDwarfDebugAddrs (AddrPool.DieValues ,
2011+ Unit.getOrigUnit ().getAddressByteSize ());
19912012 Emitter->emitDwarfDebugAddrsFooter (Unit, EndLabel);
19922013}
19932014
@@ -2701,6 +2722,7 @@ Error DWARFLinker::link() {
27012722 // reproducibility.
27022723 OffsetsStringPool DebugStrPool (StringsTranslator, true );
27032724 OffsetsStringPool DebugLineStrPool (StringsTranslator, false );
2725+ DebugDieValuePool StringOffsetPool;
27042726
27052727 // ODR Contexts for the optimize.
27062728 DeclContextTree ODRContexts;
@@ -2767,7 +2789,7 @@ Error DWARFLinker::link() {
27672789
27682790 for (auto &CU : OptContext.ModuleUnits ) {
27692791 if (Error Err = cloneModuleUnit (OptContext, CU, ODRContexts, DebugStrPool,
2770- DebugLineStrPool))
2792+ DebugLineStrPool, StringOffsetPool ))
27712793 reportWarning (toString (std::move (Err)), CU.File );
27722794 }
27732795 }
@@ -2864,7 +2886,7 @@ Error DWARFLinker::link() {
28642886 SizeByObject[OptContext.File .FileName ].Output =
28652887 DIECloner (*this , TheDwarfEmitter.get (), OptContext.File , DIEAlloc,
28662888 OptContext.CompileUnits , Options.Update , DebugStrPool,
2867- DebugLineStrPool)
2889+ DebugLineStrPool, StringOffsetPool )
28682890 .cloneAllCompileUnits (*OptContext.File .Dwarf , OptContext.File ,
28692891 OptContext.File .Dwarf ->isLittleEndian ());
28702892 }
@@ -2881,6 +2903,8 @@ Error DWARFLinker::link() {
28812903 if (TheDwarfEmitter != nullptr ) {
28822904 TheDwarfEmitter->emitAbbrevs (Abbreviations, Options.TargetDWARFVersion );
28832905 TheDwarfEmitter->emitStrings (DebugStrPool);
2906+ TheDwarfEmitter->emitStringOffsets (StringOffsetPool.DieValues ,
2907+ Options.TargetDWARFVersion );
28842908 TheDwarfEmitter->emitLineStrings (DebugLineStrPool);
28852909 for (AccelTableKind TableKind : Options.AccelTables ) {
28862910 switch (TableKind) {
@@ -2997,6 +3021,7 @@ Error DWARFLinker::cloneModuleUnit(LinkContext &Context, RefModuleUnit &Unit,
29973021 DeclContextTree &ODRContexts,
29983022 OffsetsStringPool &DebugStrPool,
29993023 OffsetsStringPool &DebugLineStrPool,
3024+ DebugDieValuePool &StringOffsetPool,
30003025 unsigned Indent) {
30013026 assert (Unit.Unit .get () != nullptr );
30023027
@@ -3023,7 +3048,7 @@ Error DWARFLinker::cloneModuleUnit(LinkContext &Context, RefModuleUnit &Unit,
30233048 CompileUnits.emplace_back (std::move (Unit.Unit ));
30243049 assert (TheDwarfEmitter);
30253050 DIECloner (*this , TheDwarfEmitter.get (), Unit.File , DIEAlloc, CompileUnits,
3026- Options.Update , DebugStrPool, DebugLineStrPool)
3051+ Options.Update , DebugStrPool, DebugLineStrPool, StringOffsetPool )
30273052 .cloneAllCompileUnits (*Unit.File .Dwarf , Unit.File ,
30283053 Unit.File .Dwarf ->isLittleEndian ());
30293054 return Error::success ();
0 commit comments