xref: /llvm-project/llvm/lib/DWARFLinker/Parallel/DWARFLinkerUnit.cpp (revision 83845b178eaea271da66f95bacec9d2878ef60e7)
12357e899Savl-llvm //===- DWARFLinkerUnit.cpp ------------------------------------------------===//
22357e899Savl-llvm //
32357e899Savl-llvm // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42357e899Savl-llvm // See https://llvm.org/LICENSE.txt for license information.
52357e899Savl-llvm // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62357e899Savl-llvm //
72357e899Savl-llvm //===----------------------------------------------------------------------===//
82357e899Savl-llvm 
92357e899Savl-llvm #include "DWARFLinkerUnit.h"
102357e899Savl-llvm #include "DWARFEmitterImpl.h"
112357e899Savl-llvm #include "DebugLineSectionEmitter.h"
122357e899Savl-llvm 
132357e899Savl-llvm using namespace llvm;
142357e899Savl-llvm using namespace dwarf_linker;
152357e899Savl-llvm using namespace dwarf_linker::parallel;
162357e899Savl-llvm 
172357e899Savl-llvm void DwarfUnit::assignAbbrev(DIEAbbrev &Abbrev) {
182357e899Savl-llvm   // Check the set for priors.
192357e899Savl-llvm   FoldingSetNodeID ID;
202357e899Savl-llvm   Abbrev.Profile(ID);
212357e899Savl-llvm   void *InsertToken;
222357e899Savl-llvm 
232357e899Savl-llvm   DIEAbbrev *InSet = AbbreviationsSet.FindNodeOrInsertPos(ID, InsertToken);
242357e899Savl-llvm   // If it's newly added.
252357e899Savl-llvm   if (InSet) {
262357e899Savl-llvm     // Assign existing abbreviation number.
272357e899Savl-llvm     Abbrev.setNumber(InSet->getNumber());
282357e899Savl-llvm   } else {
292357e899Savl-llvm     // Add to abbreviation list.
302357e899Savl-llvm     Abbreviations.push_back(
312357e899Savl-llvm         std::make_unique<DIEAbbrev>(Abbrev.getTag(), Abbrev.hasChildren()));
322357e899Savl-llvm     for (const auto &Attr : Abbrev.getData())
332357e899Savl-llvm       Abbreviations.back()->AddAttribute(Attr);
342357e899Savl-llvm     AbbreviationsSet.InsertNode(Abbreviations.back().get(), InsertToken);
352357e899Savl-llvm     // Assign the unique abbreviation number.
362357e899Savl-llvm     Abbrev.setNumber(Abbreviations.size());
372357e899Savl-llvm     Abbreviations.back()->setNumber(Abbreviations.size());
382357e899Savl-llvm   }
392357e899Savl-llvm }
402357e899Savl-llvm 
412357e899Savl-llvm Error DwarfUnit::emitAbbreviations() {
422357e899Savl-llvm   const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs = getAbbreviations();
432357e899Savl-llvm   if (Abbrevs.empty())
442357e899Savl-llvm     return Error::success();
452357e899Savl-llvm 
462357e899Savl-llvm   SectionDescriptor &AbbrevSection =
472357e899Savl-llvm       getOrCreateSectionDescriptor(DebugSectionKind::DebugAbbrev);
482357e899Savl-llvm 
492357e899Savl-llvm   // For each abbreviation.
502357e899Savl-llvm   for (const auto &Abbrev : Abbrevs)
512357e899Savl-llvm     emitDwarfAbbrevEntry(*Abbrev, AbbrevSection);
522357e899Savl-llvm 
532357e899Savl-llvm   // Mark end of abbreviations.
542357e899Savl-llvm   encodeULEB128(0, AbbrevSection.OS);
552357e899Savl-llvm 
562357e899Savl-llvm   return Error::success();
572357e899Savl-llvm }
582357e899Savl-llvm 
592357e899Savl-llvm void DwarfUnit::emitDwarfAbbrevEntry(const DIEAbbrev &Abbrev,
602357e899Savl-llvm                                      SectionDescriptor &AbbrevSection) {
612357e899Savl-llvm   // Emit the abbreviations code (base 1 index.)
622357e899Savl-llvm   encodeULEB128(Abbrev.getNumber(), AbbrevSection.OS);
632357e899Savl-llvm 
642357e899Savl-llvm   // Emit the abbreviations data.
652357e899Savl-llvm   // Emit its Dwarf tag type.
662357e899Savl-llvm   encodeULEB128(Abbrev.getTag(), AbbrevSection.OS);
672357e899Savl-llvm 
682357e899Savl-llvm   // Emit whether it has children DIEs.
692357e899Savl-llvm   encodeULEB128((unsigned)Abbrev.hasChildren(), AbbrevSection.OS);
702357e899Savl-llvm 
712357e899Savl-llvm   // For each attribute description.
722357e899Savl-llvm   const SmallVectorImpl<DIEAbbrevData> &Data = Abbrev.getData();
73*83845b17SKazu Hirata   for (const DIEAbbrevData &AttrData : Data) {
742357e899Savl-llvm     // Emit attribute type.
752357e899Savl-llvm     encodeULEB128(AttrData.getAttribute(), AbbrevSection.OS);
762357e899Savl-llvm 
772357e899Savl-llvm     // Emit form type.
782357e899Savl-llvm     encodeULEB128(AttrData.getForm(), AbbrevSection.OS);
792357e899Savl-llvm 
802357e899Savl-llvm     // Emit value for DW_FORM_implicit_const.
812357e899Savl-llvm     if (AttrData.getForm() == dwarf::DW_FORM_implicit_const)
822357e899Savl-llvm       encodeSLEB128(AttrData.getValue(), AbbrevSection.OS);
832357e899Savl-llvm   }
842357e899Savl-llvm 
852357e899Savl-llvm   // Mark end of abbreviation.
862357e899Savl-llvm   encodeULEB128(0, AbbrevSection.OS);
872357e899Savl-llvm   encodeULEB128(0, AbbrevSection.OS);
882357e899Savl-llvm }
892357e899Savl-llvm 
902357e899Savl-llvm Error DwarfUnit::emitDebugInfo(const Triple &TargetTriple) {
912357e899Savl-llvm   DIE *OutUnitDIE = getOutUnitDIE();
922357e899Savl-llvm   if (OutUnitDIE == nullptr)
932357e899Savl-llvm     return Error::success();
942357e899Savl-llvm 
952357e899Savl-llvm   // FIXME: Remove dependence on DwarfEmitterImpl/AsmPrinter and emit DIEs
962357e899Savl-llvm   // directly.
972357e899Savl-llvm 
982357e899Savl-llvm   SectionDescriptor &OutSection =
992357e899Savl-llvm       getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
1002357e899Savl-llvm   DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object, OutSection.OS);
1012357e899Savl-llvm   if (Error Err = Emitter.init(TargetTriple, "__DWARF"))
1022357e899Savl-llvm     return Err;
1032357e899Savl-llvm 
1042357e899Savl-llvm   // Emit compile unit header.
1052357e899Savl-llvm   Emitter.emitCompileUnitHeader(*this);
1062357e899Savl-llvm   size_t OffsetToAbbreviationTableOffset =
1072357e899Savl-llvm       (getFormParams().Version >= 5) ? 8 : 6;
1082357e899Savl-llvm   OutSection.notePatch(DebugOffsetPatch{
1092357e899Savl-llvm       OffsetToAbbreviationTableOffset,
1102357e899Savl-llvm       &getOrCreateSectionDescriptor(DebugSectionKind::DebugAbbrev)});
1112357e899Savl-llvm 
1122357e899Savl-llvm   // Emit DIEs.
1132357e899Savl-llvm   Emitter.emitDIE(*OutUnitDIE);
1142357e899Savl-llvm   Emitter.finish();
1152357e899Savl-llvm 
1162357e899Savl-llvm   // Set start offset ans size for .debug_info section.
1172357e899Savl-llvm   OutSection.setSizesForSectionCreatedByAsmPrinter();
1182357e899Savl-llvm   return Error::success();
1192357e899Savl-llvm }
1202357e899Savl-llvm 
1212357e899Savl-llvm Error DwarfUnit::emitDebugLine(const Triple &TargetTriple,
1222357e899Savl-llvm                                const DWARFDebugLine::LineTable &OutLineTable) {
1232357e899Savl-llvm   DebugLineSectionEmitter DebugLineEmitter(TargetTriple, *this);
1242357e899Savl-llvm 
1252357e899Savl-llvm   return DebugLineEmitter.emit(OutLineTable);
1262357e899Savl-llvm }
1272357e899Savl-llvm 
1282357e899Savl-llvm Error DwarfUnit::emitDebugStringOffsetSection() {
1292357e899Savl-llvm   if (getVersion() < 5)
1302357e899Savl-llvm     return Error::success();
1312357e899Savl-llvm 
1322357e899Savl-llvm   if (DebugStringIndexMap.empty())
1332357e899Savl-llvm     return Error::success();
1342357e899Savl-llvm 
1352357e899Savl-llvm   SectionDescriptor &OutDebugStrOffsetsSection =
1362357e899Savl-llvm       getOrCreateSectionDescriptor(DebugSectionKind::DebugStrOffsets);
1372357e899Savl-llvm 
1382357e899Savl-llvm   // Emit section header.
1392357e899Savl-llvm 
1402357e899Savl-llvm   //   Emit length.
1412357e899Savl-llvm   OutDebugStrOffsetsSection.emitUnitLength(0xBADDEF);
1422357e899Savl-llvm   uint64_t OffsetAfterSectionLength = OutDebugStrOffsetsSection.OS.tell();
1432357e899Savl-llvm 
1442357e899Savl-llvm   //   Emit version.
1452357e899Savl-llvm   OutDebugStrOffsetsSection.emitIntVal(5, 2);
1462357e899Savl-llvm 
1472357e899Savl-llvm   //   Emit padding.
1482357e899Savl-llvm   OutDebugStrOffsetsSection.emitIntVal(0, 2);
1492357e899Savl-llvm 
1502357e899Savl-llvm   //   Emit index to offset map.
1512357e899Savl-llvm   for (const StringEntry *String : DebugStringIndexMap.getValues()) {
1522357e899Savl-llvm     // Note patch for string offset value.
1532357e899Savl-llvm     OutDebugStrOffsetsSection.notePatch(
1542357e899Savl-llvm         DebugStrPatch{{OutDebugStrOffsetsSection.OS.tell()}, String});
1552357e899Savl-llvm 
1562357e899Savl-llvm     // Emit placeholder for offset value.
1572357e899Savl-llvm     OutDebugStrOffsetsSection.emitOffset(0xBADDEF);
1582357e899Savl-llvm   }
1592357e899Savl-llvm 
1602357e899Savl-llvm   // Patch section length.
1612357e899Savl-llvm   OutDebugStrOffsetsSection.apply(
1622357e899Savl-llvm       OffsetAfterSectionLength -
1632357e899Savl-llvm           OutDebugStrOffsetsSection.getFormParams().getDwarfOffsetByteSize(),
1642357e899Savl-llvm       dwarf::DW_FORM_sec_offset,
1652357e899Savl-llvm       OutDebugStrOffsetsSection.OS.tell() - OffsetAfterSectionLength);
1662357e899Savl-llvm 
1672357e899Savl-llvm   return Error::success();
1682357e899Savl-llvm }
1692357e899Savl-llvm 
1702357e899Savl-llvm /// Emit the pubnames or pubtypes section contribution for \p
1712357e899Savl-llvm /// Unit into \p Sec. The data is provided in \p Info.
1722357e899Savl-llvm std::optional<uint64_t>
1732357e899Savl-llvm DwarfUnit::emitPubAcceleratorEntry(SectionDescriptor &OutSection,
1742357e899Savl-llvm                                    const DwarfUnit::AccelInfo &Info,
1752357e899Savl-llvm                                    std::optional<uint64_t> LengthOffset) {
1762357e899Savl-llvm   if (!LengthOffset) {
1772357e899Savl-llvm     // Emit the header.
1782357e899Savl-llvm     OutSection.emitIntVal(0xBADDEF,
1792357e899Savl-llvm                           getFormParams().getDwarfOffsetByteSize()); // Length
1802357e899Savl-llvm     LengthOffset = OutSection.OS.tell();
1812357e899Savl-llvm 
1822357e899Savl-llvm     OutSection.emitIntVal(dwarf::DW_PUBNAMES_VERSION, 2); // Version
1832357e899Savl-llvm 
1842357e899Savl-llvm     OutSection.notePatch(DebugOffsetPatch{
1852357e899Savl-llvm         OutSection.OS.tell(),
1862357e899Savl-llvm         &getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo)});
1872357e899Savl-llvm     OutSection.emitOffset(0xBADDEF); // Unit offset
1882357e899Savl-llvm 
1892357e899Savl-llvm     OutSection.emitIntVal(getUnitSize(), 4); // Size
1902357e899Savl-llvm   }
1912357e899Savl-llvm   OutSection.emitOffset(Info.OutOffset);
1922357e899Savl-llvm 
1932357e899Savl-llvm   // Emit the string itself.
1942357e899Savl-llvm   OutSection.emitInplaceString(Info.String->first());
1952357e899Savl-llvm 
1962357e899Savl-llvm   return LengthOffset;
1972357e899Savl-llvm }
1982357e899Savl-llvm 
1992357e899Savl-llvm /// Emit .debug_pubnames and .debug_pubtypes for \p Unit.
2002357e899Savl-llvm void DwarfUnit::emitPubAccelerators() {
2012357e899Savl-llvm   std::optional<uint64_t> NamesLengthOffset;
2022357e899Savl-llvm   std::optional<uint64_t> TypesLengthOffset;
2032357e899Savl-llvm 
2042357e899Savl-llvm   forEachAcceleratorRecord([&](const DwarfUnit::AccelInfo &Info) {
2052357e899Savl-llvm     if (Info.AvoidForPubSections)
2062357e899Savl-llvm       return;
2072357e899Savl-llvm 
2082357e899Savl-llvm     switch (Info.Type) {
2092357e899Savl-llvm     case DwarfUnit::AccelType::Name: {
2102357e899Savl-llvm       NamesLengthOffset = emitPubAcceleratorEntry(
2112357e899Savl-llvm           getOrCreateSectionDescriptor(DebugSectionKind::DebugPubNames), Info,
2122357e899Savl-llvm           NamesLengthOffset);
2132357e899Savl-llvm     } break;
2142357e899Savl-llvm     case DwarfUnit::AccelType::Type: {
2152357e899Savl-llvm       TypesLengthOffset = emitPubAcceleratorEntry(
2162357e899Savl-llvm           getOrCreateSectionDescriptor(DebugSectionKind::DebugPubTypes), Info,
2172357e899Savl-llvm           TypesLengthOffset);
2182357e899Savl-llvm     } break;
2192357e899Savl-llvm     default: {
2202357e899Savl-llvm       // Nothing to do.
2212357e899Savl-llvm     } break;
2222357e899Savl-llvm     }
2232357e899Savl-llvm   });
2242357e899Savl-llvm 
2252357e899Savl-llvm   if (NamesLengthOffset) {
2262357e899Savl-llvm     SectionDescriptor &OutSection =
2272357e899Savl-llvm         getOrCreateSectionDescriptor(DebugSectionKind::DebugPubNames);
2282357e899Savl-llvm     OutSection.emitIntVal(0, 4); // End marker.
2292357e899Savl-llvm 
2302357e899Savl-llvm     OutSection.apply(*NamesLengthOffset -
2312357e899Savl-llvm                          OutSection.getFormParams().getDwarfOffsetByteSize(),
2322357e899Savl-llvm                      dwarf::DW_FORM_sec_offset,
2332357e899Savl-llvm                      OutSection.OS.tell() - *NamesLengthOffset);
2342357e899Savl-llvm   }
2352357e899Savl-llvm 
2362357e899Savl-llvm   if (TypesLengthOffset) {
2372357e899Savl-llvm     SectionDescriptor &OutSection =
2382357e899Savl-llvm         getOrCreateSectionDescriptor(DebugSectionKind::DebugPubTypes);
2392357e899Savl-llvm     OutSection.emitIntVal(0, 4); // End marker.
2402357e899Savl-llvm 
2412357e899Savl-llvm     OutSection.apply(*TypesLengthOffset -
2422357e899Savl-llvm                          OutSection.getFormParams().getDwarfOffsetByteSize(),
2432357e899Savl-llvm                      dwarf::DW_FORM_sec_offset,
2442357e899Savl-llvm                      OutSection.OS.tell() - *TypesLengthOffset);
2452357e899Savl-llvm   }
2462357e899Savl-llvm }
247