| //===- DWARFEmitterImpl.cpp -----------------------------------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "DWARFEmitterImpl.h" |
| #include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h" |
| #include "llvm/MC/MCAsmBackend.h" |
| #include "llvm/MC/MCCodeEmitter.h" |
| #include "llvm/MC/MCObjectWriter.h" |
| #include "llvm/MC/MCSubtargetInfo.h" |
| #include "llvm/MC/MCTargetOptions.h" |
| #include "llvm/MC/MCTargetOptionsCommandFlags.h" |
| #include "llvm/MC/TargetRegistry.h" |
| #include "llvm/Support/FormattedStream.h" |
| |
| namespace llvm { |
| namespace dwarflinker_parallel { |
| |
| Error DwarfEmitterImpl::init(Triple TheTriple, |
| StringRef Swift5ReflectionSegmentName) { |
| std::string ErrorStr; |
| std::string TripleName; |
| |
| // Get the target. |
| const Target *TheTarget = |
| TargetRegistry::lookupTarget(TripleName, TheTriple, ErrorStr); |
| if (!TheTarget) |
| return createStringError(std::errc::invalid_argument, ErrorStr.c_str()); |
| TripleName = TheTriple.getTriple(); |
| |
| // Create all the MC Objects. |
| MRI.reset(TheTarget->createMCRegInfo(TripleName)); |
| if (!MRI) |
| return createStringError(std::errc::invalid_argument, |
| "no register info for target %s", |
| TripleName.c_str()); |
| |
| MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags(); |
| MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions)); |
| if (!MAI) |
| return createStringError(std::errc::invalid_argument, |
| "no asm info for target %s", TripleName.c_str()); |
| |
| MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", "")); |
| if (!MSTI) |
| return createStringError(std::errc::invalid_argument, |
| "no subtarget info for target %s", |
| TripleName.c_str()); |
| |
| MC.reset(new MCContext(TheTriple, MAI.get(), MRI.get(), MSTI.get(), nullptr, |
| nullptr, true, Swift5ReflectionSegmentName)); |
| MOFI.reset(TheTarget->createMCObjectFileInfo(*MC, /*PIC=*/false, false)); |
| MC->setObjectFileInfo(MOFI.get()); |
| |
| MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, MCOptions); |
| if (!MAB) |
| return createStringError(std::errc::invalid_argument, |
| "no asm backend for target %s", |
| TripleName.c_str()); |
| |
| MII.reset(TheTarget->createMCInstrInfo()); |
| if (!MII) |
| return createStringError(std::errc::invalid_argument, |
| "no instr info info for target %s", |
| TripleName.c_str()); |
| |
| MCE = TheTarget->createMCCodeEmitter(*MII, *MC); |
| if (!MCE) |
| return createStringError(std::errc::invalid_argument, |
| "no code emitter for target %s", |
| TripleName.c_str()); |
| |
| switch (OutFileType) { |
| case DWARFLinker::OutputFileType::Assembly: { |
| MIP = TheTarget->createMCInstPrinter(TheTriple, MAI->getAssemblerDialect(), |
| *MAI, *MII, *MRI); |
| MS = TheTarget->createAsmStreamer( |
| *MC, std::make_unique<formatted_raw_ostream>(OutFile), true, true, MIP, |
| std::unique_ptr<MCCodeEmitter>(MCE), std::unique_ptr<MCAsmBackend>(MAB), |
| true); |
| break; |
| } |
| case DWARFLinker::OutputFileType::Object: { |
| MS = TheTarget->createMCObjectStreamer( |
| TheTriple, *MC, std::unique_ptr<MCAsmBackend>(MAB), |
| MAB->createObjectWriter(OutFile), std::unique_ptr<MCCodeEmitter>(MCE), |
| *MSTI, MCOptions.MCRelaxAll, MCOptions.MCIncrementalLinkerCompatible, |
| /*DWARFMustBeAtTheEnd*/ false); |
| break; |
| } |
| } |
| |
| if (!MS) |
| return createStringError(std::errc::invalid_argument, |
| "no object streamer for target %s", |
| TripleName.c_str()); |
| |
| // Finally create the AsmPrinter we'll use to emit the DIEs. |
| TM.reset(TheTarget->createTargetMachine(TripleName, "", "", TargetOptions(), |
| std::nullopt)); |
| if (!TM) |
| return createStringError(std::errc::invalid_argument, |
| "no target machine for target %s", |
| TripleName.c_str()); |
| |
| Asm.reset(TheTarget->createAsmPrinter(*TM, std::unique_ptr<MCStreamer>(MS))); |
| if (!Asm) |
| return createStringError(std::errc::invalid_argument, |
| "no asm printer for target %s", |
| TripleName.c_str()); |
| Asm->setDwarfUsesRelocationsAcrossSections(false); |
| |
| RangesSectionSize = 0; |
| RngListsSectionSize = 0; |
| LocSectionSize = 0; |
| LocListsSectionSize = 0; |
| LineSectionSize = 0; |
| FrameSectionSize = 0; |
| DebugInfoSectionSize = 0; |
| MacInfoSectionSize = 0; |
| MacroSectionSize = 0; |
| |
| return Error::success(); |
| } |
| |
| } // end of namespace dwarflinker_parallel |
| } // namespace llvm |