Path: blob/main/contrib/llvm-project/llvm/lib/DWARFLinker/Parallel/DWARFEmitterImpl.cpp
35292 views
//===- DWARFEmitterImpl.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 "DWARFEmitterImpl.h"9#include "DWARFLinkerCompileUnit.h"10#include "llvm/MC/MCAsmBackend.h"11#include "llvm/MC/MCCodeEmitter.h"12#include "llvm/MC/MCObjectWriter.h"13#include "llvm/MC/MCSubtargetInfo.h"14#include "llvm/MC/MCTargetOptions.h"15#include "llvm/MC/MCTargetOptionsCommandFlags.h"16#include "llvm/MC/TargetRegistry.h"17#include "llvm/Support/FormattedStream.h"1819using namespace llvm;20using namespace dwarf_linker;21using namespace dwarf_linker::parallel;2223Error DwarfEmitterImpl::init(Triple TheTriple,24StringRef Swift5ReflectionSegmentName) {25std::string ErrorStr;26std::string TripleName;2728// Get the target.29const Target *TheTarget =30TargetRegistry::lookupTarget(TripleName, TheTriple, ErrorStr);31if (!TheTarget)32return createStringError(std::errc::invalid_argument, ErrorStr.c_str());33TripleName = TheTriple.getTriple();3435// Create all the MC Objects.36MRI.reset(TheTarget->createMCRegInfo(TripleName));37if (!MRI)38return createStringError(std::errc::invalid_argument,39"no register info for target %s",40TripleName.c_str());4142MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags();43MCOptions.AsmVerbose = true;44MCOptions.MCUseDwarfDirectory = MCTargetOptions::EnableDwarfDirectory;45MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));46if (!MAI)47return createStringError(std::errc::invalid_argument,48"no asm info for target %s", TripleName.c_str());4950MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", ""));51if (!MSTI)52return createStringError(std::errc::invalid_argument,53"no subtarget info for target %s",54TripleName.c_str());5556MC.reset(new MCContext(TheTriple, MAI.get(), MRI.get(), MSTI.get(), nullptr,57nullptr, true, Swift5ReflectionSegmentName));58MOFI.reset(TheTarget->createMCObjectFileInfo(*MC, /*PIC=*/false, false));59MC->setObjectFileInfo(MOFI.get());6061MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, MCOptions);62if (!MAB)63return createStringError(std::errc::invalid_argument,64"no asm backend for target %s",65TripleName.c_str());6667MII.reset(TheTarget->createMCInstrInfo());68if (!MII)69return createStringError(std::errc::invalid_argument,70"no instr info info for target %s",71TripleName.c_str());7273MCE = TheTarget->createMCCodeEmitter(*MII, *MC);74if (!MCE)75return createStringError(std::errc::invalid_argument,76"no code emitter for target %s",77TripleName.c_str());7879switch (OutFileType) {80case DWARFLinker::OutputFileType::Assembly: {81MIP = TheTarget->createMCInstPrinter(TheTriple, MAI->getAssemblerDialect(),82*MAI, *MII, *MRI);83MS = TheTarget->createAsmStreamer(84*MC, std::make_unique<formatted_raw_ostream>(OutFile), MIP,85std::unique_ptr<MCCodeEmitter>(MCE),86std::unique_ptr<MCAsmBackend>(MAB));87break;88}89case DWARFLinker::OutputFileType::Object: {90MS = TheTarget->createMCObjectStreamer(91TheTriple, *MC, std::unique_ptr<MCAsmBackend>(MAB),92MAB->createObjectWriter(OutFile), std::unique_ptr<MCCodeEmitter>(MCE),93*MSTI);94break;95}96}9798if (!MS)99return createStringError(std::errc::invalid_argument,100"no object streamer for target %s",101TripleName.c_str());102103// Finally create the AsmPrinter we'll use to emit the DIEs.104TM.reset(TheTarget->createTargetMachine(TripleName, "", "", TargetOptions(),105std::nullopt));106if (!TM)107return createStringError(std::errc::invalid_argument,108"no target machine for target %s",109TripleName.c_str());110111Asm.reset(TheTarget->createAsmPrinter(*TM, std::unique_ptr<MCStreamer>(MS)));112if (!Asm)113return createStringError(std::errc::invalid_argument,114"no asm printer for target %s",115TripleName.c_str());116Asm->setDwarfUsesRelocationsAcrossSections(false);117118DebugInfoSectionSize = 0;119120return Error::success();121}122123void DwarfEmitterImpl::emitAbbrevs(124const SmallVector<std::unique_ptr<DIEAbbrev>> &Abbrevs,125unsigned DwarfVersion) {126MS->switchSection(MOFI->getDwarfAbbrevSection());127MC->setDwarfVersion(DwarfVersion);128Asm->emitDwarfAbbrevs(Abbrevs);129}130131void DwarfEmitterImpl::emitCompileUnitHeader(DwarfUnit &Unit) {132MS->switchSection(MOFI->getDwarfInfoSection());133MC->setDwarfVersion(Unit.getVersion());134135// Emit size of content not including length itself. The size has already136// been computed in CompileUnit::computeOffsets(). Subtract 4 to that size to137// account for the length field.138Asm->emitInt32(Unit.getUnitSize() - 4);139Asm->emitInt16(Unit.getVersion());140141if (Unit.getVersion() >= 5) {142Asm->emitInt8(dwarf::DW_UT_compile);143Asm->emitInt8(Unit.getFormParams().AddrSize);144// Proper offset to the abbreviations table will be set later.145Asm->emitInt32(0);146DebugInfoSectionSize += 12;147} else {148// Proper offset to the abbreviations table will be set later.149Asm->emitInt32(0);150Asm->emitInt8(Unit.getFormParams().AddrSize);151DebugInfoSectionSize += 11;152}153}154155void DwarfEmitterImpl::emitDIE(DIE &Die) {156MS->switchSection(MOFI->getDwarfInfoSection());157Asm->emitDwarfDIE(Die);158DebugInfoSectionSize += Die.getSize();159}160161void DwarfEmitterImpl::emitDebugNames(DWARF5AccelTable &Table,162DebugNamesUnitsOffsets &CUOffsets,163CompUnitIDToIdx &CUidToIdx) {164if (CUOffsets.empty())165return;166167Asm->OutStreamer->switchSection(MOFI->getDwarfDebugNamesSection());168dwarf::Form Form =169DIEInteger::BestForm(/*IsSigned*/ false, (uint64_t)CUidToIdx.size() - 1);170// FIXME: add support for type units + .debug_names. For now the behavior is171// unsuported.172emitDWARF5AccelTable(173Asm.get(), Table, CUOffsets,174[&](const DWARF5AccelTableData &Entry)175-> std::optional<DWARF5AccelTable::UnitIndexAndEncoding> {176if (CUidToIdx.size() > 1)177return {{CUidToIdx[Entry.getUnitID()],178{dwarf::DW_IDX_compile_unit, Form}}};179return std::nullopt;180});181}182183void DwarfEmitterImpl::emitAppleNamespaces(184AccelTable<AppleAccelTableStaticOffsetData> &Table) {185Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamespaceSection());186auto *SectionBegin = Asm->createTempSymbol("namespac_begin");187Asm->OutStreamer->emitLabel(SectionBegin);188emitAppleAccelTable(Asm.get(), Table, "namespac", SectionBegin);189}190191void DwarfEmitterImpl::emitAppleNames(192AccelTable<AppleAccelTableStaticOffsetData> &Table) {193Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamesSection());194auto *SectionBegin = Asm->createTempSymbol("names_begin");195Asm->OutStreamer->emitLabel(SectionBegin);196emitAppleAccelTable(Asm.get(), Table, "names", SectionBegin);197}198199void DwarfEmitterImpl::emitAppleObjc(200AccelTable<AppleAccelTableStaticOffsetData> &Table) {201Asm->OutStreamer->switchSection(MOFI->getDwarfAccelObjCSection());202auto *SectionBegin = Asm->createTempSymbol("objc_begin");203Asm->OutStreamer->emitLabel(SectionBegin);204emitAppleAccelTable(Asm.get(), Table, "objc", SectionBegin);205}206207void DwarfEmitterImpl::emitAppleTypes(208AccelTable<AppleAccelTableStaticTypeData> &Table) {209Asm->OutStreamer->switchSection(MOFI->getDwarfAccelTypesSection());210auto *SectionBegin = Asm->createTempSymbol("types_begin");211Asm->OutStreamer->emitLabel(SectionBegin);212emitAppleAccelTable(Asm.get(), Table, "types", SectionBegin);213}214215216