1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
|
#pragma once
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
//===- DwarfStreamer.h ------------------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DWARFLINKER_DWARFSTREAMER_H
#define LLVM_DWARFLINKER_DWARFSTREAMER_H
#include "llvm/BinaryFormat/Swift.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/DWARFLinker/DWARFLinker.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Target/TargetMachine.h"
namespace llvm {
template <typename DataT> class AccelTable;
enum class OutputFileType {
Object,
Assembly,
};
/// User of DwarfStreamer should call initialization code
/// for AsmPrinter:
///
/// InitializeAllTargetInfos();
/// InitializeAllTargetMCs();
/// InitializeAllTargets();
/// InitializeAllAsmPrinters();
class MCCodeEmitter;
class DWARFDebugMacro;
/// The Dwarf streaming logic.
///
/// All interactions with the MC layer that is used to build the debug
/// information binary representation are handled in this class.
class DwarfStreamer : public DwarfEmitter {
public:
DwarfStreamer(OutputFileType OutFileType, raw_pwrite_stream &OutFile,
std::function<StringRef(StringRef Input)> Translator,
messageHandler Error, messageHandler Warning)
: OutFile(OutFile), OutFileType(OutFileType), Translator(Translator),
ErrorHandler(Error), WarningHandler(Warning) {}
bool init(Triple TheTriple, StringRef Swift5ReflectionSegmentName);
/// Dump the file to the disk.
void finish();
AsmPrinter &getAsmPrinter() const { return *Asm; }
/// Set the current output section to debug_info and change
/// the MC Dwarf version to \p DwarfVersion.
void switchToDebugInfoSection(unsigned DwarfVersion);
/// Emit the compilation unit header for \p Unit in the
/// debug_info section.
///
/// As a side effect, this also switches the current Dwarf version
/// of the MC layer to the one of U.getOrigUnit().
void emitCompileUnitHeader(CompileUnit &Unit, unsigned DwarfVersion) override;
/// Recursively emit the DIE tree rooted at \p Die.
void emitDIE(DIE &Die) override;
/// Emit the abbreviation table \p Abbrevs to the debug_abbrev section.
void emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
unsigned DwarfVersion) override;
/// Emit DIE containing warnings.
void emitPaperTrailWarningsDie(DIE &Die) override;
/// Emit contents of section SecName From Obj.
void emitSectionContents(StringRef SecData, StringRef SecName) override;
/// Emit the string table described by \p Pool.
void emitStrings(const NonRelocatableStringpool &Pool) override;
/// Emit the swift_ast section stored in \p Buffer.
void emitSwiftAST(StringRef Buffer);
/// Emit the swift reflection section stored in \p Buffer.
void emitSwiftReflectionSection(
llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind,
StringRef Buffer, uint32_t Alignment, uint32_t Size);
/// Emit piece of .debug_ranges for \p Ranges.
virtual void
emitDwarfDebugRangesTableFragment(const CompileUnit &Unit,
const AddressRanges &LinkedRanges) override;
/// Emit debug_aranges entries for \p Unit and if \p DoRangesSection is true,
/// also emit the debug_ranges entries for the DW_TAG_compile_unit's
/// DW_AT_ranges attribute.
void emitUnitRangesEntries(CompileUnit &Unit, bool DoRangesSection) override;
uint64_t getRangesSectionSize() const override { return RangesSectionSize; }
/// Emit the debug_loc contribution for \p Unit by copying the entries from
/// \p Dwarf and offsetting them. Update the location attributes to point to
/// the new entries.
void emitLocationsForUnit(
const CompileUnit &Unit, DWARFContext &Dwarf,
std::function<void(StringRef, SmallVectorImpl<uint8_t> &)> ProcessExpr)
override;
/// Emit the line table described in \p Rows into the debug_line section.
void emitLineTableForUnit(MCDwarfLineTableParams Params,
StringRef PrologueBytes, unsigned MinInstLength,
std::vector<DWARFDebugLine::Row> &Rows,
unsigned AdddressSize) override;
/// Copy the debug_line over to the updated binary while unobfuscating the
/// file names and directories.
void translateLineTable(DataExtractor LineData, uint64_t Offset) override;
uint64_t getLineSectionSize() const override { return LineSectionSize; }
/// Emit the .debug_pubnames contribution for \p Unit.
void emitPubNamesForUnit(const CompileUnit &Unit) override;
/// Emit the .debug_pubtypes contribution for \p Unit.
void emitPubTypesForUnit(const CompileUnit &Unit) override;
/// Emit a CIE.
void emitCIE(StringRef CIEBytes) override;
/// Emit an FDE with data \p Bytes.
void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint64_t Address,
StringRef Bytes) override;
/// Emit DWARF debug names.
void emitDebugNames(AccelTable<DWARF5AccelTableStaticData> &Table) override;
/// Emit Apple namespaces accelerator table.
void emitAppleNamespaces(
AccelTable<AppleAccelTableStaticOffsetData> &Table) override;
/// Emit Apple names accelerator table.
void
emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> &Table) override;
/// Emit Apple Objective-C accelerator table.
void
emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> &Table) override;
/// Emit Apple type accelerator table.
void
emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table) override;
uint64_t getFrameSectionSize() const override { return FrameSectionSize; }
uint64_t getDebugInfoSectionSize() const override {
return DebugInfoSectionSize;
}
uint64_t getDebugMacInfoSectionSize() const override {
return MacInfoSectionSize;
}
uint64_t getDebugMacroSectionSize() const override {
return MacroSectionSize;
}
void emitMacroTables(DWARFContext *Context,
const Offset2UnitMap &UnitMacroMap,
OffsetsStringPool &StringPool) override;
private:
inline void error(const Twine &Error, StringRef Context = "") {
if (ErrorHandler)
ErrorHandler(Error, Context, nullptr);
}
inline void warn(const Twine &Warning, StringRef Context = "") {
if (WarningHandler)
WarningHandler(Warning, Context, nullptr);
}
void emitMacroTableImpl(const DWARFDebugMacro *MacroTable,
const Offset2UnitMap &UnitMacroMap,
OffsetsStringPool &StringPool, uint64_t &OutOffset);
void emitDwarfDebugArangesTable(const CompileUnit &Unit,
const AddressRanges &LinkedRanges);
/// \defgroup MCObjects MC layer objects constructed by the streamer
/// @{
std::unique_ptr<MCRegisterInfo> MRI;
std::unique_ptr<MCAsmInfo> MAI;
std::unique_ptr<MCObjectFileInfo> MOFI;
std::unique_ptr<MCContext> MC;
MCAsmBackend *MAB; // Owned by MCStreamer
std::unique_ptr<MCInstrInfo> MII;
std::unique_ptr<MCSubtargetInfo> MSTI;
MCInstPrinter *MIP; // Owned by AsmPrinter
MCCodeEmitter *MCE; // Owned by MCStreamer
MCStreamer *MS; // Owned by AsmPrinter
std::unique_ptr<TargetMachine> TM;
std::unique_ptr<AsmPrinter> Asm;
/// @}
/// The output file we stream the linked Dwarf to.
raw_pwrite_stream &OutFile;
OutputFileType OutFileType = OutputFileType::Object;
std::function<StringRef(StringRef Input)> Translator;
uint64_t RangesSectionSize = 0;
uint64_t LocSectionSize = 0;
uint64_t LineSectionSize = 0;
uint64_t FrameSectionSize = 0;
uint64_t DebugInfoSectionSize = 0;
uint64_t MacInfoSectionSize = 0;
uint64_t MacroSectionSize = 0;
/// Keep track of emitted CUs and their Unique ID.
struct EmittedUnit {
unsigned ID;
MCSymbol *LabelBegin;
};
std::vector<EmittedUnit> EmittedUnits;
/// Emit the pubnames or pubtypes section contribution for \p
/// Unit into \p Sec. The data is provided in \p Names.
void emitPubSectionForUnit(MCSection *Sec, StringRef Name,
const CompileUnit &Unit,
const std::vector<CompileUnit::AccelInfo> &Names);
messageHandler ErrorHandler = nullptr;
messageHandler WarningHandler = nullptr;
};
} // end namespace llvm
#endif // LLVM_DWARFLINKER_DWARFSTREAMER_H
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
|