LLVM 22.0.0git
DWARFEmitterImpl.cpp
Go to the documentation of this file.
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-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "DWARFEmitterImpl.h"
20
21using namespace llvm;
22using namespace dwarf_linker;
23using namespace dwarf_linker::parallel;
24
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(TripleName));
39 if (!MRI)
40 return createStringError(std::errc::invalid_argument,
41 "no register info for target %s",
42 TripleName.c_str());
43
45 MCOptions.AsmVerbose = true;
47 MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, 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(TripleName, "", ""));
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) {
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 }
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
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
134 MS->switchSection(MOFI->getDwarfInfoSection());
135 MC->setDwarfVersion(Unit.getVersion());
136
137 // Emit size of content not including length itself. The size has already
138 // been computed in CompileUnit::computeOffsets(). Subtract 4 to that size to
139 // 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
158 MS->switchSection(MOFI->getDwarfInfoSection());
159 Asm->emitDwarfDIE(Die);
160 DebugInfoSectionSize += Die.getSize();
161}
162
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 is
173 // unsuported.
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
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
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
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
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}
This class holds an abstract representation of an Accelerator Table, consisting of a sequence of buck...
Definition: AccelTable.h:203
static dwarf::Form BestForm(bool IsSigned, uint64_t Int)
Choose the best form for integer.
Definition: DIE.h:176
A structured debug information entry.
Definition: DIE.h:828
unsigned getSize() const
Definition: DIE.h:871
The Data class implementation for DWARF v5 accelerator table.
Definition: AccelTable.h:293
unsigned size() const
Definition: DenseMap.h:120
Lightweight error class with error context and mandatory checking.
Definition: Error.h:159
static ErrorSuccess success()
Create a success value.
Definition: Error.h:336
std::unique_ptr< MCObjectWriter > createObjectWriter(raw_pwrite_stream &OS) const
Create a new MCObjectWriter instance for use by the assembler backend to emit the final object file.
Context object for machine code objects.
Definition: MCContext.h:83
virtual void switchSection(MCSection *Section, uint32_t Subsec=0)
Set the current section where code is being emitted to Section.
DwarfDirectory MCUseDwarfDirectory
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
Target - Wrapper for Target specific information.
TargetMachine * createTargetMachine(const Triple &TT, StringRef CPU, StringRef Features, const TargetOptions &Options, std::optional< Reloc::Model > RM, std::optional< CodeModel::Model > CM=std::nullopt, CodeGenOptLevel OL=CodeGenOptLevel::Default, bool JIT=false) const
createTargetMachine - Create a target specific machine implementation for the specified Triple.
MCCodeEmitter * createMCCodeEmitter(const MCInstrInfo &II, MCContext &Ctx) const
createMCCodeEmitter - Create a target specific code emitter.
MCObjectFileInfo * createMCObjectFileInfo(MCContext &Ctx, bool PIC, bool LargeCodeModel=false) const
Create a MCObjectFileInfo implementation for the specified target triple.
MCSubtargetInfo * createMCSubtargetInfo(StringRef TheTriple, StringRef CPU, StringRef Features) const
createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
MCAsmBackend * createMCAsmBackend(const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options) const
createMCAsmBackend - Create a target specific assembly parser.
LLVM_ABI MCStreamer * createAsmStreamer(MCContext &Ctx, std::unique_ptr< formatted_raw_ostream > OS, std::unique_ptr< MCInstPrinter > IP, std::unique_ptr< MCCodeEmitter > CE, std::unique_ptr< MCAsmBackend > TAB) const
MCRegisterInfo * createMCRegInfo(StringRef TT) const
createMCRegInfo - Create a MCRegisterInfo implementation.
LLVM_ABI MCStreamer * createMCObjectStreamer(const Triple &T, MCContext &Ctx, std::unique_ptr< MCAsmBackend > TAB, std::unique_ptr< MCObjectWriter > OW, std::unique_ptr< MCCodeEmitter > Emitter, const MCSubtargetInfo &STI) const
Create a target specific MCStreamer.
MCAsmInfo * createMCAsmInfo(const MCRegisterInfo &MRI, StringRef TheTriple, const MCTargetOptions &Options) const
createMCAsmInfo - Create a MCAsmInfo implementation for the specified target triple.
MCInstPrinter * createMCInstPrinter(const Triple &T, unsigned SyntaxVariant, const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI) const
AsmPrinter * createAsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > &&Streamer) const
createAsmPrinter - Create a target specific assembly printer pass.
MCInstrInfo * createMCInstrInfo() const
createMCInstrInfo - Create a MCInstrInfo implementation.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:47
const std::string & getTriple() const
Definition: Triple.h:477
void emitCompileUnitHeader(DwarfUnit &Unit)
Emit compile unit header.
Error init(Triple TheTriple, StringRef Swift5ReflectionSegmentName)
Initialize AsmPrinter data.
void emitAppleNames(AccelTable< AppleAccelTableStaticOffsetData > &Table)
Emits .apple_names section according to the specified Table.
void emitAbbrevs(const SmallVector< std::unique_ptr< DIEAbbrev > > &Abbrevs, unsigned DwarfVersion)
Emit abbreviations.
void emitAppleTypes(AccelTable< AppleAccelTableStaticTypeData > &Table)
Emits .apple_types section according to the specified Table.
void emitDIE(DIE &Die)
Emit DIE recursively.
void emitAppleNamespaces(AccelTable< AppleAccelTableStaticOffsetData > &Table)
Emits .apple_namespaces section according to the specified Table.
void emitDebugNames(DWARF5AccelTable &Table, DebugNamesUnitsOffsets &CUOffsets, CompUnitIDToIdx &UnitIDToIdxMap)
Emits .debug_names section according to the specified Table.
void emitAppleObjc(AccelTable< AppleAccelTableStaticOffsetData > &Table)
Emits .apple_objc section according to the specified Table.
Base class for all Dwarf units(Compile unit/Type table unit).
std::vector< std::variant< MCSymbol *, uint64_t > > DebugNamesUnitsOffsets
LLVM_ABI MCTargetOptions InitMCTargetOptionsFromFlags()
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1305
void emitAppleAccelTable(AsmPrinter *Asm, AccelTable< DataT > &Contents, StringRef Prefix, const MCSymbol *SecBegin)
Emit an Apple Accelerator Table consisting of entries in the specified AccelTable.
Definition: AccelTable.h:452
LLVM_ABI void emitDWARF5AccelTable(AsmPrinter *Asm, DWARF5AccelTable &Contents, const DwarfDebug &DD, ArrayRef< std::unique_ptr< DwarfCompileUnit > > CUs)
Definition: AccelTable.cpp:642
static const Target * lookupTarget(StringRef TripleStr, std::string &Error)
lookupTarget - Lookup a target based on a target triple.