This patch creates skeleton implementation for the DWARFLinkerParallel. It also integrates DWARFLinkerParallel into dsymutil and llvm-dwarfutil, so that empty DWARFLinker::link() can be called. To do this new command line option is added "--linker apple/llvm". Additionally it changes existing DWARFLinker interfaces/implementations to be compatible: use Error for error reporting for the DWARFStreamer, make DWARFFile to owner of referenced resources, other small refactorings. Differential Revision: https://reviews.llvm.org/D147952
132 lines
4.9 KiB
C++
132 lines
4.9 KiB
C++
//===- 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
|