Path: blob/main/contrib/llvm-project/llvm/lib/DWARFLinker/Parallel/DWARFLinkerUnit.cpp
35291 views
//===- DWARFLinkerUnit.cpp ------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "DWARFLinkerUnit.h"9#include "DWARFEmitterImpl.h"10#include "DebugLineSectionEmitter.h"1112using namespace llvm;13using namespace dwarf_linker;14using namespace dwarf_linker::parallel;1516void DwarfUnit::assignAbbrev(DIEAbbrev &Abbrev) {17// Check the set for priors.18FoldingSetNodeID ID;19Abbrev.Profile(ID);20void *InsertToken;2122DIEAbbrev *InSet = AbbreviationsSet.FindNodeOrInsertPos(ID, InsertToken);23// If it's newly added.24if (InSet) {25// Assign existing abbreviation number.26Abbrev.setNumber(InSet->getNumber());27} else {28// Add to abbreviation list.29Abbreviations.push_back(30std::make_unique<DIEAbbrev>(Abbrev.getTag(), Abbrev.hasChildren()));31for (const auto &Attr : Abbrev.getData())32Abbreviations.back()->AddAttribute(Attr);33AbbreviationsSet.InsertNode(Abbreviations.back().get(), InsertToken);34// Assign the unique abbreviation number.35Abbrev.setNumber(Abbreviations.size());36Abbreviations.back()->setNumber(Abbreviations.size());37}38}3940Error DwarfUnit::emitAbbreviations() {41const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs = getAbbreviations();42if (Abbrevs.empty())43return Error::success();4445SectionDescriptor &AbbrevSection =46getOrCreateSectionDescriptor(DebugSectionKind::DebugAbbrev);4748// For each abbreviation.49for (const auto &Abbrev : Abbrevs)50emitDwarfAbbrevEntry(*Abbrev, AbbrevSection);5152// Mark end of abbreviations.53encodeULEB128(0, AbbrevSection.OS);5455return Error::success();56}5758void DwarfUnit::emitDwarfAbbrevEntry(const DIEAbbrev &Abbrev,59SectionDescriptor &AbbrevSection) {60// Emit the abbreviations code (base 1 index.)61encodeULEB128(Abbrev.getNumber(), AbbrevSection.OS);6263// Emit the abbreviations data.64// Emit its Dwarf tag type.65encodeULEB128(Abbrev.getTag(), AbbrevSection.OS);6667// Emit whether it has children DIEs.68encodeULEB128((unsigned)Abbrev.hasChildren(), AbbrevSection.OS);6970// For each attribute description.71const SmallVectorImpl<DIEAbbrevData> &Data = Abbrev.getData();72for (const DIEAbbrevData &AttrData : Data) {73// Emit attribute type.74encodeULEB128(AttrData.getAttribute(), AbbrevSection.OS);7576// Emit form type.77encodeULEB128(AttrData.getForm(), AbbrevSection.OS);7879// Emit value for DW_FORM_implicit_const.80if (AttrData.getForm() == dwarf::DW_FORM_implicit_const)81encodeSLEB128(AttrData.getValue(), AbbrevSection.OS);82}8384// Mark end of abbreviation.85encodeULEB128(0, AbbrevSection.OS);86encodeULEB128(0, AbbrevSection.OS);87}8889Error DwarfUnit::emitDebugInfo(const Triple &TargetTriple) {90DIE *OutUnitDIE = getOutUnitDIE();91if (OutUnitDIE == nullptr)92return Error::success();9394// FIXME: Remove dependence on DwarfEmitterImpl/AsmPrinter and emit DIEs95// directly.9697SectionDescriptor &OutSection =98getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);99DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object, OutSection.OS);100if (Error Err = Emitter.init(TargetTriple, "__DWARF"))101return Err;102103// Emit compile unit header.104Emitter.emitCompileUnitHeader(*this);105size_t OffsetToAbbreviationTableOffset =106(getFormParams().Version >= 5) ? 8 : 6;107OutSection.notePatch(DebugOffsetPatch{108OffsetToAbbreviationTableOffset,109&getOrCreateSectionDescriptor(DebugSectionKind::DebugAbbrev)});110111// Emit DIEs.112Emitter.emitDIE(*OutUnitDIE);113Emitter.finish();114115// Set start offset ans size for .debug_info section.116OutSection.setSizesForSectionCreatedByAsmPrinter();117return Error::success();118}119120Error DwarfUnit::emitDebugLine(const Triple &TargetTriple,121const DWARFDebugLine::LineTable &OutLineTable) {122DebugLineSectionEmitter DebugLineEmitter(TargetTriple, *this);123124return DebugLineEmitter.emit(OutLineTable);125}126127Error DwarfUnit::emitDebugStringOffsetSection() {128if (getVersion() < 5)129return Error::success();130131if (DebugStringIndexMap.empty())132return Error::success();133134SectionDescriptor &OutDebugStrOffsetsSection =135getOrCreateSectionDescriptor(DebugSectionKind::DebugStrOffsets);136137// Emit section header.138139// Emit length.140OutDebugStrOffsetsSection.emitUnitLength(0xBADDEF);141uint64_t OffsetAfterSectionLength = OutDebugStrOffsetsSection.OS.tell();142143// Emit version.144OutDebugStrOffsetsSection.emitIntVal(5, 2);145146// Emit padding.147OutDebugStrOffsetsSection.emitIntVal(0, 2);148149// Emit index to offset map.150for (const StringEntry *String : DebugStringIndexMap.getValues()) {151// Note patch for string offset value.152OutDebugStrOffsetsSection.notePatch(153DebugStrPatch{{OutDebugStrOffsetsSection.OS.tell()}, String});154155// Emit placeholder for offset value.156OutDebugStrOffsetsSection.emitOffset(0xBADDEF);157}158159// Patch section length.160OutDebugStrOffsetsSection.apply(161OffsetAfterSectionLength -162OutDebugStrOffsetsSection.getFormParams().getDwarfOffsetByteSize(),163dwarf::DW_FORM_sec_offset,164OutDebugStrOffsetsSection.OS.tell() - OffsetAfterSectionLength);165166return Error::success();167}168169/// Emit the pubnames or pubtypes section contribution for \p170/// Unit into \p Sec. The data is provided in \p Info.171std::optional<uint64_t>172DwarfUnit::emitPubAcceleratorEntry(SectionDescriptor &OutSection,173const DwarfUnit::AccelInfo &Info,174std::optional<uint64_t> LengthOffset) {175if (!LengthOffset) {176// Emit the header.177OutSection.emitIntVal(0xBADDEF,178getFormParams().getDwarfOffsetByteSize()); // Length179LengthOffset = OutSection.OS.tell();180181OutSection.emitIntVal(dwarf::DW_PUBNAMES_VERSION, 2); // Version182183OutSection.notePatch(DebugOffsetPatch{184OutSection.OS.tell(),185&getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo)});186OutSection.emitOffset(0xBADDEF); // Unit offset187188OutSection.emitIntVal(getUnitSize(), 4); // Size189}190OutSection.emitOffset(Info.OutOffset);191192// Emit the string itself.193OutSection.emitInplaceString(Info.String->first());194195return LengthOffset;196}197198/// Emit .debug_pubnames and .debug_pubtypes for \p Unit.199void DwarfUnit::emitPubAccelerators() {200std::optional<uint64_t> NamesLengthOffset;201std::optional<uint64_t> TypesLengthOffset;202203forEachAcceleratorRecord([&](const DwarfUnit::AccelInfo &Info) {204if (Info.AvoidForPubSections)205return;206207switch (Info.Type) {208case DwarfUnit::AccelType::Name: {209NamesLengthOffset = emitPubAcceleratorEntry(210getOrCreateSectionDescriptor(DebugSectionKind::DebugPubNames), Info,211NamesLengthOffset);212} break;213case DwarfUnit::AccelType::Type: {214TypesLengthOffset = emitPubAcceleratorEntry(215getOrCreateSectionDescriptor(DebugSectionKind::DebugPubTypes), Info,216TypesLengthOffset);217} break;218default: {219// Nothing to do.220} break;221}222});223224if (NamesLengthOffset) {225SectionDescriptor &OutSection =226getOrCreateSectionDescriptor(DebugSectionKind::DebugPubNames);227OutSection.emitIntVal(0, 4); // End marker.228229OutSection.apply(*NamesLengthOffset -230OutSection.getFormParams().getDwarfOffsetByteSize(),231dwarf::DW_FORM_sec_offset,232OutSection.OS.tell() - *NamesLengthOffset);233}234235if (TypesLengthOffset) {236SectionDescriptor &OutSection =237getOrCreateSectionDescriptor(DebugSectionKind::DebugPubTypes);238OutSection.emitIntVal(0, 4); // End marker.239240OutSection.apply(*TypesLengthOffset -241OutSection.getFormParams().getDwarfOffsetByteSize(),242dwarf::DW_FORM_sec_offset,243OutSection.OS.tell() - *TypesLengthOffset);244}245}246247248