brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.1 KiB · 9222235 Raw
216 lines · cpp
1//===- DWARFEmitterImpl.cpp -----------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "DWARFEmitterImpl.h"10#include "DWARFLinkerCompileUnit.h"11#include "llvm/MC/MCAsmBackend.h"12#include "llvm/MC/MCCodeEmitter.h"13#include "llvm/MC/MCInstPrinter.h"14#include "llvm/MC/MCObjectWriter.h"15#include "llvm/MC/MCSubtargetInfo.h"16#include "llvm/MC/MCTargetOptions.h"17#include "llvm/MC/MCTargetOptionsCommandFlags.h"18#include "llvm/MC/TargetRegistry.h"19#include "llvm/Support/FormattedStream.h"20 21using namespace llvm;22using namespace dwarf_linker;23using namespace dwarf_linker::parallel;24 25Error DwarfEmitterImpl::init(Triple TheTriple,26                             StringRef Swift5ReflectionSegmentName) {27  std::string ErrorStr;28  std::string TripleName;29 30  // Get the target.31  const Target *TheTarget =32      TargetRegistry::lookupTarget(TripleName, TheTriple, ErrorStr);33  if (!TheTarget)34    return createStringError(std::errc::invalid_argument, ErrorStr.c_str());35  TripleName = TheTriple.getTriple();36 37  // Create all the MC Objects.38  MRI.reset(TheTarget->createMCRegInfo(TheTriple));39  if (!MRI)40    return createStringError(std::errc::invalid_argument,41                             "no register info for target %s",42                             TripleName.c_str());43 44  MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags();45  MCOptions.AsmVerbose = true;46  MCOptions.MCUseDwarfDirectory = MCTargetOptions::EnableDwarfDirectory;47  MAI.reset(TheTarget->createMCAsmInfo(*MRI, TheTriple, MCOptions));48  if (!MAI)49    return createStringError(std::errc::invalid_argument,50                             "no asm info for target %s", TripleName.c_str());51 52  MSTI.reset(TheTarget->createMCSubtargetInfo(TheTriple, "", ""));53  if (!MSTI)54    return createStringError(std::errc::invalid_argument,55                             "no subtarget info for target %s",56                             TripleName.c_str());57 58  MC.reset(new MCContext(TheTriple, MAI.get(), MRI.get(), MSTI.get(), nullptr,59                         nullptr, true, Swift5ReflectionSegmentName));60  MOFI.reset(TheTarget->createMCObjectFileInfo(*MC, /*PIC=*/false, false));61  MC->setObjectFileInfo(MOFI.get());62 63  MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, MCOptions);64  if (!MAB)65    return createStringError(std::errc::invalid_argument,66                             "no asm backend for target %s",67                             TripleName.c_str());68 69  MII.reset(TheTarget->createMCInstrInfo());70  if (!MII)71    return createStringError(std::errc::invalid_argument,72                             "no instr info info for target %s",73                             TripleName.c_str());74 75  MCE = TheTarget->createMCCodeEmitter(*MII, *MC);76  if (!MCE)77    return createStringError(std::errc::invalid_argument,78                             "no code emitter for target %s",79                             TripleName.c_str());80 81  switch (OutFileType) {82  case DWARFLinker::OutputFileType::Assembly: {83    std::unique_ptr<MCInstPrinter> MIP(TheTarget->createMCInstPrinter(84        TheTriple, MAI->getAssemblerDialect(), *MAI, *MII, *MRI));85    MS = TheTarget->createAsmStreamer(86        *MC, std::make_unique<formatted_raw_ostream>(OutFile), std::move(MIP),87        std::unique_ptr<MCCodeEmitter>(MCE),88        std::unique_ptr<MCAsmBackend>(MAB));89    break;90  }91  case DWARFLinker::OutputFileType::Object: {92    MS = TheTarget->createMCObjectStreamer(93        TheTriple, *MC, std::unique_ptr<MCAsmBackend>(MAB),94        MAB->createObjectWriter(OutFile), std::unique_ptr<MCCodeEmitter>(MCE),95        *MSTI);96    break;97  }98  }99 100  if (!MS)101    return createStringError(std::errc::invalid_argument,102                             "no object streamer for target %s",103                             TripleName.c_str());104 105  // Finally create the AsmPrinter we'll use to emit the DIEs.106  TM.reset(TheTarget->createTargetMachine(TheTriple, "", "", TargetOptions(),107                                          std::nullopt));108  if (!TM)109    return createStringError(std::errc::invalid_argument,110                             "no target machine for target %s",111                             TripleName.c_str());112 113  Asm.reset(TheTarget->createAsmPrinter(*TM, std::unique_ptr<MCStreamer>(MS)));114  if (!Asm)115    return createStringError(std::errc::invalid_argument,116                             "no asm printer for target %s",117                             TripleName.c_str());118  Asm->setDwarfUsesRelocationsAcrossSections(false);119 120  DebugInfoSectionSize = 0;121 122  return Error::success();123}124 125void DwarfEmitterImpl::emitAbbrevs(126    const SmallVector<std::unique_ptr<DIEAbbrev>> &Abbrevs,127    unsigned DwarfVersion) {128  MS->switchSection(MOFI->getDwarfAbbrevSection());129  MC->setDwarfVersion(DwarfVersion);130  Asm->emitDwarfAbbrevs(Abbrevs);131}132 133void DwarfEmitterImpl::emitCompileUnitHeader(DwarfUnit &Unit) {134  MS->switchSection(MOFI->getDwarfInfoSection());135  MC->setDwarfVersion(Unit.getVersion());136 137  // Emit size of content not including length itself. The size has already138  // been computed in CompileUnit::computeOffsets(). Subtract 4 to that size to139  // account for the length field.140  Asm->emitInt32(Unit.getUnitSize() - 4);141  Asm->emitInt16(Unit.getVersion());142 143  if (Unit.getVersion() >= 5) {144    Asm->emitInt8(dwarf::DW_UT_compile);145    Asm->emitInt8(Unit.getFormParams().AddrSize);146    // Proper offset to the abbreviations table will be set later.147    Asm->emitInt32(0);148    DebugInfoSectionSize += 12;149  } else {150    // Proper offset to the abbreviations table will be set later.151    Asm->emitInt32(0);152    Asm->emitInt8(Unit.getFormParams().AddrSize);153    DebugInfoSectionSize += 11;154  }155}156 157void DwarfEmitterImpl::emitDIE(DIE &Die) {158  MS->switchSection(MOFI->getDwarfInfoSection());159  Asm->emitDwarfDIE(Die);160  DebugInfoSectionSize += Die.getSize();161}162 163void DwarfEmitterImpl::emitDebugNames(DWARF5AccelTable &Table,164                                      DebugNamesUnitsOffsets &CUOffsets,165                                      CompUnitIDToIdx &CUidToIdx) {166  if (CUOffsets.empty())167    return;168 169  Asm->OutStreamer->switchSection(MOFI->getDwarfDebugNamesSection());170  dwarf::Form Form =171      DIEInteger::BestForm(/*IsSigned*/ false, (uint64_t)CUidToIdx.size() - 1);172  // FIXME: add support for type units + .debug_names. For now the behavior is173  // unsuported.174  emitDWARF5AccelTable(175      Asm.get(), Table, CUOffsets,176      [&](const DWARF5AccelTableData &Entry)177          -> std::optional<DWARF5AccelTable::UnitIndexAndEncoding> {178        if (CUidToIdx.size() > 1)179          return {{CUidToIdx[Entry.getUnitID()],180                   {dwarf::DW_IDX_compile_unit, Form}}};181        return std::nullopt;182      });183}184 185void DwarfEmitterImpl::emitAppleNamespaces(186    AccelTable<AppleAccelTableStaticOffsetData> &Table) {187  Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamespaceSection());188  auto *SectionBegin = Asm->createTempSymbol("namespac_begin");189  Asm->OutStreamer->emitLabel(SectionBegin);190  emitAppleAccelTable(Asm.get(), Table, "namespac", SectionBegin);191}192 193void DwarfEmitterImpl::emitAppleNames(194    AccelTable<AppleAccelTableStaticOffsetData> &Table) {195  Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamesSection());196  auto *SectionBegin = Asm->createTempSymbol("names_begin");197  Asm->OutStreamer->emitLabel(SectionBegin);198  emitAppleAccelTable(Asm.get(), Table, "names", SectionBegin);199}200 201void DwarfEmitterImpl::emitAppleObjc(202    AccelTable<AppleAccelTableStaticOffsetData> &Table) {203  Asm->OutStreamer->switchSection(MOFI->getDwarfAccelObjCSection());204  auto *SectionBegin = Asm->createTempSymbol("objc_begin");205  Asm->OutStreamer->emitLabel(SectionBegin);206  emitAppleAccelTable(Asm.get(), Table, "objc", SectionBegin);207}208 209void DwarfEmitterImpl::emitAppleTypes(210    AccelTable<AppleAccelTableStaticTypeData> &Table) {211  Asm->OutStreamer->switchSection(MOFI->getDwarfAccelTypesSection());212  auto *SectionBegin = Asm->createTempSymbol("types_begin");213  Asm->OutStreamer->emitLabel(SectionBegin);214  emitAppleAccelTable(Asm.get(), Table, "types", SectionBegin);215}216