Line data Source code
1 : //===- lib/MC/MCDwarf.cpp - MCDwarf implementation ------------------------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 :
10 : #include "llvm/MC/MCDwarf.h"
11 : #include "llvm/ADT/ArrayRef.h"
12 : #include "llvm/ADT/DenseMap.h"
13 : #include "llvm/ADT/Hashing.h"
14 : #include "llvm/ADT/Optional.h"
15 : #include "llvm/ADT/STLExtras.h"
16 : #include "llvm/ADT/SmallString.h"
17 : #include "llvm/ADT/SmallVector.h"
18 : #include "llvm/ADT/StringRef.h"
19 : #include "llvm/ADT/Twine.h"
20 : #include "llvm/BinaryFormat/Dwarf.h"
21 : #include "llvm/Config/config.h"
22 : #include "llvm/MC/MCAsmInfo.h"
23 : #include "llvm/MC/MCContext.h"
24 : #include "llvm/MC/MCExpr.h"
25 : #include "llvm/MC/MCObjectFileInfo.h"
26 : #include "llvm/MC/MCObjectStreamer.h"
27 : #include "llvm/MC/MCRegisterInfo.h"
28 : #include "llvm/MC/MCSection.h"
29 : #include "llvm/MC/MCStreamer.h"
30 : #include "llvm/MC/MCSymbol.h"
31 : #include "llvm/MC/StringTableBuilder.h"
32 : #include "llvm/Support/Casting.h"
33 : #include "llvm/Support/Endian.h"
34 : #include "llvm/Support/EndianStream.h"
35 : #include "llvm/Support/ErrorHandling.h"
36 : #include "llvm/Support/LEB128.h"
37 : #include "llvm/Support/MathExtras.h"
38 : #include "llvm/Support/Path.h"
39 : #include "llvm/Support/SourceMgr.h"
40 : #include "llvm/Support/raw_ostream.h"
41 : #include <cassert>
42 : #include <cstdint>
43 : #include <string>
44 : #include <utility>
45 : #include <vector>
46 :
47 : using namespace llvm;
48 :
49 : /// Manage the .debug_line_str section contents, if we use it.
50 76 : class llvm::MCDwarfLineStr {
51 : MCSymbol *LineStrLabel = nullptr;
52 : StringTableBuilder LineStrings{StringTableBuilder::DWARF};
53 : bool UseRelocs = false;
54 :
55 : public:
56 : /// Construct an instance that can emit .debug_line_str (for use in a normal
57 : /// v5 line table).
58 38 : explicit MCDwarfLineStr(MCContext &Ctx) {
59 38 : UseRelocs = Ctx.getAsmInfo()->doesDwarfUseRelocationsAcrossSections();
60 38 : if (UseRelocs)
61 33 : LineStrLabel =
62 33 : Ctx.getObjectFileInfo()->getDwarfLineStrSection()->getBeginSymbol();
63 38 : }
64 :
65 : /// Emit a reference to the string.
66 : void emitRef(MCStreamer *MCOS, StringRef Path);
67 :
68 : /// Emit the .debug_line_str section if appropriate.
69 : void emitSection(MCStreamer *MCOS);
70 : };
71 :
72 : static inline uint64_t ScaleAddrDelta(MCContext &Context, uint64_t AddrDelta) {
73 5299905 : unsigned MinInsnLength = Context.getAsmInfo()->getMinInstAlignment();
74 5299905 : if (MinInsnLength == 1)
75 : return AddrDelta;
76 298 : if (AddrDelta % MinInsnLength != 0) {
77 : // TODO: report this error, but really only once.
78 : ;
79 : }
80 298 : return AddrDelta / MinInsnLength;
81 : }
82 :
83 : //
84 : // This is called when an instruction is assembled into the specified section
85 : // and if there is information from the last .loc directive that has yet to have
86 : // a line entry made for it is made.
87 : //
88 44584385 : void MCDwarfLineEntry::Make(MCObjectStreamer *MCOS, MCSection *Section) {
89 44584385 : if (!MCOS->getContext().getDwarfLocSeen())
90 43963434 : return;
91 :
92 : // Create a symbol at in the current section for use in the line entry.
93 620951 : MCSymbol *LineSym = MCOS->getContext().createTempSymbol();
94 : // Set the value of the symbol to use for the MCDwarfLineEntry.
95 620951 : MCOS->EmitLabel(LineSym);
96 :
97 : // Get the current .loc info saved in the context.
98 620951 : const MCDwarfLoc &DwarfLoc = MCOS->getContext().getCurrentDwarfLoc();
99 :
100 : // Create a (local) line entry with the symbol and the current .loc info.
101 : MCDwarfLineEntry LineEntry(LineSym, DwarfLoc);
102 :
103 : // clear DwarfLocSeen saying the current .loc info is now used.
104 : MCOS->getContext().clearDwarfLocSeen();
105 :
106 : // Add the line entry to this section's entries.
107 620951 : MCOS->getContext()
108 620951 : .getMCDwarfLineTable(MCOS->getContext().getDwarfCompileUnitID())
109 : .getMCLineSections()
110 620951 : .addLineEntry(LineEntry, Section);
111 : }
112 :
113 : //
114 : // This helper routine returns an expression of End - Start + IntVal .
115 : //
116 636524 : static inline const MCExpr *MakeStartMinusEndExpr(const MCStreamer &MCOS,
117 : const MCSymbol &Start,
118 : const MCSymbol &End,
119 : int IntVal) {
120 : MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
121 : const MCExpr *Res =
122 636524 : MCSymbolRefExpr::create(&End, Variant, MCOS.getContext());
123 : const MCExpr *RHS =
124 636524 : MCSymbolRefExpr::create(&Start, Variant, MCOS.getContext());
125 : const MCExpr *Res1 =
126 636524 : MCBinaryExpr::create(MCBinaryExpr::Sub, Res, RHS, MCOS.getContext());
127 : const MCExpr *Res2 =
128 636524 : MCConstantExpr::create(IntVal, MCOS.getContext());
129 : const MCExpr *Res3 =
130 636523 : MCBinaryExpr::create(MCBinaryExpr::Sub, Res1, Res2, MCOS.getContext());
131 636524 : return Res3;
132 : }
133 :
134 : //
135 : // This helper routine returns an expression of Start + IntVal .
136 : //
137 : static inline const MCExpr *
138 148 : makeStartPlusIntExpr(MCContext &Ctx, const MCSymbol &Start, int IntVal) {
139 : MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
140 148 : const MCExpr *LHS = MCSymbolRefExpr::create(&Start, Variant, Ctx);
141 148 : const MCExpr *RHS = MCConstantExpr::create(IntVal, Ctx);
142 148 : const MCExpr *Res = MCBinaryExpr::create(MCBinaryExpr::Add, LHS, RHS, Ctx);
143 148 : return Res;
144 : }
145 :
146 : //
147 : // This emits the Dwarf line table for the specified section from the entries
148 : // in the LineSection.
149 : //
150 : static inline void
151 8072 : EmitDwarfLineTable(MCObjectStreamer *MCOS, MCSection *Section,
152 : const MCLineSection::MCDwarfLineEntryCollection &LineEntries) {
153 : unsigned FileNum = 1;
154 : unsigned LastLine = 1;
155 : unsigned Column = 0;
156 : unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
157 : unsigned Isa = 0;
158 : unsigned Discriminator = 0;
159 : MCSymbol *LastLabel = nullptr;
160 :
161 : // Loop through each MCDwarfLineEntry and encode the dwarf line number table.
162 629023 : for (const MCDwarfLineEntry &LineEntry : LineEntries) {
163 620951 : int64_t LineDelta = static_cast<int64_t>(LineEntry.getLine()) - LastLine;
164 :
165 620951 : if (FileNum != LineEntry.getFileNum()) {
166 : FileNum = LineEntry.getFileNum();
167 276536 : MCOS->EmitIntValue(dwarf::DW_LNS_set_file, 1);
168 276536 : MCOS->EmitULEB128IntValue(FileNum);
169 : }
170 1241902 : if (Column != LineEntry.getColumn()) {
171 : Column = LineEntry.getColumn();
172 534864 : MCOS->EmitIntValue(dwarf::DW_LNS_set_column, 1);
173 534864 : MCOS->EmitULEB128IntValue(Column);
174 : }
175 620951 : if (Discriminator != LineEntry.getDiscriminator() &&
176 16 : MCOS->getContext().getDwarfVersion() >= 4) {
177 : Discriminator = LineEntry.getDiscriminator();
178 16 : unsigned Size = getULEB128Size(Discriminator);
179 16 : MCOS->EmitIntValue(dwarf::DW_LNS_extended_op, 1);
180 16 : MCOS->EmitULEB128IntValue(Size + 1);
181 16 : MCOS->EmitIntValue(dwarf::DW_LNE_set_discriminator, 1);
182 16 : MCOS->EmitULEB128IntValue(Discriminator);
183 : }
184 1241902 : if (Isa != LineEntry.getIsa()) {
185 : Isa = LineEntry.getIsa();
186 0 : MCOS->EmitIntValue(dwarf::DW_LNS_set_isa, 1);
187 0 : MCOS->EmitULEB128IntValue(Isa);
188 : }
189 1241902 : if ((LineEntry.getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) {
190 : Flags = LineEntry.getFlags();
191 184632 : MCOS->EmitIntValue(dwarf::DW_LNS_negate_stmt, 1);
192 : }
193 620951 : if (LineEntry.getFlags() & DWARF2_FLAG_BASIC_BLOCK)
194 0 : MCOS->EmitIntValue(dwarf::DW_LNS_set_basic_block, 1);
195 620951 : if (LineEntry.getFlags() & DWARF2_FLAG_PROLOGUE_END)
196 9124 : MCOS->EmitIntValue(dwarf::DW_LNS_set_prologue_end, 1);
197 620951 : if (LineEntry.getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN)
198 0 : MCOS->EmitIntValue(dwarf::DW_LNS_set_epilogue_begin, 1);
199 :
200 620951 : MCSymbol *Label = LineEntry.getLabel();
201 :
202 : // At this point we want to emit/create the sequence to encode the delta in
203 : // line numbers and the increment of the address from the previous Label
204 : // and the current Label.
205 620951 : const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo();
206 620951 : MCOS->EmitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label,
207 : asmInfo->getCodePointerSize());
208 :
209 : Discriminator = 0;
210 620951 : LastLine = LineEntry.getLine();
211 : LastLabel = Label;
212 : }
213 :
214 : // Emit a DW_LNE_end_sequence for the end of the section.
215 : // Use the section end label to compute the address delta and use INT64_MAX
216 : // as the line delta which is the signal that this is actually a
217 : // DW_LNE_end_sequence.
218 8072 : MCSymbol *SectionEnd = MCOS->endSection(Section);
219 :
220 : // Switch back the dwarf line section, in case endSection had to switch the
221 : // section.
222 8072 : MCContext &Ctx = MCOS->getContext();
223 8072 : MCOS->SwitchSection(Ctx.getObjectFileInfo()->getDwarfLineSection());
224 :
225 8072 : const MCAsmInfo *AsmInfo = Ctx.getAsmInfo();
226 8072 : MCOS->EmitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd,
227 : AsmInfo->getCodePointerSize());
228 8072 : }
229 :
230 : //
231 : // This emits the Dwarf file and the line tables.
232 : //
233 12356 : void MCDwarfLineTable::Emit(MCObjectStreamer *MCOS,
234 : MCDwarfLineTableParams Params) {
235 12356 : MCContext &context = MCOS->getContext();
236 :
237 : auto &LineTables = context.getMCDwarfLineTables();
238 :
239 : // Bail out early so we don't switch to the debug_line section needlessly and
240 : // in doing so create an unnecessary (if empty) section.
241 12356 : if (LineTables.empty())
242 11504 : return;
243 :
244 : // In a v5 non-split line table, put the strings in a separate section.
245 : Optional<MCDwarfLineStr> LineStr;
246 852 : if (context.getDwarfVersion() >= 5)
247 76 : LineStr = MCDwarfLineStr(context);
248 :
249 : // Switch to the section where the table will be emitted into.
250 852 : MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection());
251 :
252 : // Handle the rest of the Compile Units.
253 2012 : for (const auto &CUIDTablePair : LineTables) {
254 1159 : CUIDTablePair.second.EmitCU(MCOS, Params, LineStr);
255 : }
256 :
257 853 : if (LineStr)
258 38 : LineStr->emitSection(MCOS);
259 : }
260 :
261 37 : void MCDwarfDwoLineTable::Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params,
262 : MCSection *Section) const {
263 37 : if (Header.MCDwarfFiles.empty())
264 30 : return;
265 : Optional<MCDwarfLineStr> NoLineStr(None);
266 7 : MCOS.SwitchSection(Section);
267 14 : MCOS.EmitLabel(Header.Emit(&MCOS, Params, None, NoLineStr).second);
268 : }
269 :
270 : std::pair<MCSymbol *, MCSymbol *>
271 1159 : MCDwarfLineTableHeader::Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
272 : Optional<MCDwarfLineStr> &LineStr) const {
273 : static const char StandardOpcodeLengths[] = {
274 : 0, // length of DW_LNS_copy
275 : 1, // length of DW_LNS_advance_pc
276 : 1, // length of DW_LNS_advance_line
277 : 1, // length of DW_LNS_set_file
278 : 1, // length of DW_LNS_set_column
279 : 0, // length of DW_LNS_negate_stmt
280 : 0, // length of DW_LNS_set_basic_block
281 : 0, // length of DW_LNS_const_add_pc
282 : 1, // length of DW_LNS_fixed_advance_pc
283 : 0, // length of DW_LNS_set_prologue_end
284 : 0, // length of DW_LNS_set_epilogue_begin
285 : 1 // DW_LNS_set_isa
286 : };
287 : assert(array_lengthof(StandardOpcodeLengths) >=
288 : (Params.DWARF2LineOpcodeBase - 1U));
289 : return Emit(
290 : MCOS, Params,
291 1159 : makeArrayRef(StandardOpcodeLengths, Params.DWARF2LineOpcodeBase - 1),
292 1159 : LineStr);
293 : }
294 :
295 636821 : static const MCExpr *forceExpAbs(MCStreamer &OS, const MCExpr* Expr) {
296 636821 : MCContext &Context = OS.getContext();
297 : assert(!isa<MCSymbolRefExpr>(Expr));
298 636821 : if (Context.getAsmInfo()->hasAggressiveSymbolFolding())
299 : return Expr;
300 :
301 2017 : MCSymbol *ABS = Context.createTempSymbol();
302 2017 : OS.EmitAssignment(ABS, Expr);
303 2017 : return MCSymbolRefExpr::create(ABS, Context);
304 : }
305 :
306 636821 : static void emitAbsValue(MCStreamer &OS, const MCExpr *Value, unsigned Size) {
307 636821 : const MCExpr *ABS = forceExpAbs(OS, Value);
308 636821 : OS.EmitValue(ABS, Size);
309 636822 : }
310 :
311 38 : void MCDwarfLineStr::emitSection(MCStreamer *MCOS) {
312 : // Switch to the .debug_line_str section.
313 38 : MCOS->SwitchSection(
314 38 : MCOS->getContext().getObjectFileInfo()->getDwarfLineStrSection());
315 : // Emit the strings without perturbing the offsets we used.
316 38 : LineStrings.finalizeInOrder();
317 : SmallString<0> Data;
318 38 : Data.resize(LineStrings.getSize());
319 38 : LineStrings.write((uint8_t *)Data.data());
320 76 : MCOS->EmitBinaryData(Data.str());
321 38 : }
322 :
323 163 : void MCDwarfLineStr::emitRef(MCStreamer *MCOS, StringRef Path) {
324 : int RefSize = 4; // FIXME: Support DWARF-64
325 163 : size_t Offset = LineStrings.add(Path);
326 163 : if (UseRelocs) {
327 148 : MCContext &Ctx = MCOS->getContext();
328 148 : MCOS->EmitValue(makeStartPlusIntExpr(Ctx, *LineStrLabel, Offset), RefSize);
329 : } else
330 15 : MCOS->EmitIntValue(Offset, RefSize);
331 163 : }
332 :
333 1118 : void MCDwarfLineTableHeader::emitV2FileDirTables(MCStreamer *MCOS) const {
334 : // First the directory table.
335 2638 : for (auto &Dir : MCDwarfDirs) {
336 3040 : MCOS->EmitBytes(Dir); // The DirectoryName, and...
337 3040 : MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator.
338 : }
339 1118 : MCOS->EmitIntValue(0, 1); // Terminate the directory list.
340 :
341 : // Second the file table.
342 7029 : for (unsigned i = 1; i < MCDwarfFiles.size(); i++) {
343 : assert(!MCDwarfFiles[i].Name.empty());
344 11822 : MCOS->EmitBytes(MCDwarfFiles[i].Name); // FileName and...
345 11822 : MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator.
346 5911 : MCOS->EmitULEB128IntValue(MCDwarfFiles[i].DirIndex); // Directory number.
347 5911 : MCOS->EmitIntValue(0, 1); // Last modification timestamp (always 0).
348 5911 : MCOS->EmitIntValue(0, 1); // File size (always 0).
349 : }
350 1118 : MCOS->EmitIntValue(0, 1); // Terminate the file list.
351 1118 : }
352 :
353 103 : static void emitOneV5FileEntry(MCStreamer *MCOS, const MCDwarfFile &DwarfFile,
354 : bool EmitMD5, bool HasSource,
355 : Optional<MCDwarfLineStr> &LineStr) {
356 : assert(!DwarfFile.Name.empty());
357 103 : if (LineStr)
358 99 : LineStr->emitRef(MCOS, DwarfFile.Name);
359 : else {
360 8 : MCOS->EmitBytes(DwarfFile.Name); // FileName and...
361 8 : MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator.
362 : }
363 103 : MCOS->EmitULEB128IntValue(DwarfFile.DirIndex); // Directory number.
364 103 : if (EmitMD5) {
365 61 : MD5::MD5Result *Cksum = DwarfFile.Checksum;
366 61 : MCOS->EmitBinaryData(
367 : StringRef(reinterpret_cast<const char *>(Cksum->Bytes.data()),
368 61 : Cksum->Bytes.size()));
369 : }
370 103 : if (HasSource) {
371 9 : if (LineStr)
372 9 : LineStr->emitRef(MCOS, DwarfFile.Source.getValueOr(StringRef()));
373 : else {
374 0 : MCOS->EmitBytes(
375 0 : DwarfFile.Source.getValueOr(StringRef())); // Source and...
376 0 : MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator.
377 : }
378 : }
379 103 : }
380 :
381 48 : void MCDwarfLineTableHeader::emitV5FileDirTables(
382 : MCStreamer *MCOS, Optional<MCDwarfLineStr> &LineStr,
383 : StringRef CtxCompilationDir) const {
384 : // The directory format, which is just a list of the directory paths. In a
385 : // non-split object, these are references to .debug_line_str; in a split
386 : // object, they are inline strings.
387 48 : MCOS->EmitIntValue(1, 1);
388 48 : MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_path);
389 48 : MCOS->EmitULEB128IntValue(LineStr ? dwarf::DW_FORM_line_strp
390 48 : : dwarf::DW_FORM_string);
391 96 : MCOS->EmitULEB128IntValue(MCDwarfDirs.size() + 1);
392 : // Try not to emit an empty compilation directory.
393 : const StringRef CompDir =
394 48 : CompilationDir.empty() ? CtxCompilationDir : StringRef(CompilationDir);
395 48 : if (LineStr) {
396 : // Record path strings, emit references here.
397 46 : LineStr->emitRef(MCOS, CompDir);
398 55 : for (const auto &Dir : MCDwarfDirs)
399 9 : LineStr->emitRef(MCOS, Dir);
400 : } else {
401 : // The list of directory paths. Compilation directory comes first.
402 2 : MCOS->EmitBytes(CompDir);
403 4 : MCOS->EmitBytes(StringRef("\0", 1));
404 2 : for (const auto &Dir : MCDwarfDirs) {
405 0 : MCOS->EmitBytes(Dir); // The DirectoryName, and...
406 0 : MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator.
407 : }
408 : }
409 :
410 : // The file format, which is the inline null-terminated filename and a
411 : // directory index. We don't track file size/timestamp so don't emit them
412 : // in the v5 table. Emit MD5 checksums and source if we have them.
413 : uint64_t Entries = 2;
414 48 : if (HasAllMD5)
415 : Entries += 1;
416 48 : if (HasSource)
417 3 : Entries += 1;
418 48 : MCOS->EmitIntValue(Entries, 1);
419 48 : MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_path);
420 48 : MCOS->EmitULEB128IntValue(LineStr ? dwarf::DW_FORM_line_strp
421 48 : : dwarf::DW_FORM_string);
422 48 : MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_directory_index);
423 48 : MCOS->EmitULEB128IntValue(dwarf::DW_FORM_udata);
424 48 : if (HasAllMD5) {
425 29 : MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_MD5);
426 29 : MCOS->EmitULEB128IntValue(dwarf::DW_FORM_data16);
427 : }
428 48 : if (HasSource) {
429 3 : MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_LLVM_source);
430 3 : MCOS->EmitULEB128IntValue(LineStr ? dwarf::DW_FORM_line_strp
431 3 : : dwarf::DW_FORM_string);
432 : }
433 : // Then the counted list of files. The root file is file #0, then emit the
434 : // files as provide by .file directives. To accommodate assembler source
435 : // written for DWARF v4 but trying to emit v5, if we didn't see a root file
436 : // explicitly, replicate file #1.
437 96 : MCOS->EmitULEB128IntValue(MCDwarfFiles.size());
438 51 : emitOneV5FileEntry(MCOS, RootFile.Name.empty() ? MCDwarfFiles[1] : RootFile,
439 48 : HasAllMD5, HasSource, LineStr);
440 103 : for (unsigned i = 1; i < MCDwarfFiles.size(); ++i)
441 110 : emitOneV5FileEntry(MCOS, MCDwarfFiles[i], HasAllMD5, HasSource, LineStr);
442 48 : }
443 :
444 : std::pair<MCSymbol *, MCSymbol *>
445 1165 : MCDwarfLineTableHeader::Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
446 : ArrayRef<char> StandardOpcodeLengths,
447 : Optional<MCDwarfLineStr> &LineStr) const {
448 1165 : MCContext &context = MCOS->getContext();
449 :
450 : // Create a symbol at the beginning of the line table.
451 1165 : MCSymbol *LineStartSym = Label;
452 1165 : if (!LineStartSym)
453 113 : LineStartSym = context.createTempSymbol();
454 : // Set the value of the symbol, as we are at the start of the line table.
455 1165 : MCOS->EmitLabel(LineStartSym);
456 :
457 : // Create a symbol for the end of the section (to be set when we get there).
458 1166 : MCSymbol *LineEndSym = context.createTempSymbol();
459 :
460 : // The first 4 bytes is the total length of the information for this
461 : // compilation unit (not including these 4 bytes for the length).
462 1166 : emitAbsValue(*MCOS,
463 : MakeStartMinusEndExpr(*MCOS, *LineStartSym, *LineEndSym, 4), 4);
464 :
465 : // Next 2 bytes is the Version.
466 1166 : unsigned LineTableVersion = context.getDwarfVersion();
467 1166 : MCOS->EmitIntValue(LineTableVersion, 2);
468 :
469 : // Keep track of the bytes between the very start and where the header length
470 : // comes out.
471 : unsigned PreHeaderLengthBytes = 4 + 2;
472 :
473 : // In v5, we get address info next.
474 1166 : if (LineTableVersion >= 5) {
475 48 : MCOS->EmitIntValue(context.getAsmInfo()->getCodePointerSize(), 1);
476 48 : MCOS->EmitIntValue(0, 1); // Segment selector; same as EmitGenDwarfAranges.
477 : PreHeaderLengthBytes += 2;
478 : }
479 :
480 : // Create a symbol for the end of the prologue (to be set when we get there).
481 1166 : MCSymbol *ProEndSym = context.createTempSymbol(); // Lprologue_end
482 :
483 : // Length of the prologue, is the next 4 bytes. This is actually the length
484 : // from after the length word, to the end of the prologue.
485 1166 : emitAbsValue(*MCOS,
486 : MakeStartMinusEndExpr(*MCOS, *LineStartSym, *ProEndSym,
487 1166 : (PreHeaderLengthBytes + 4)),
488 : 4);
489 :
490 : // Parameters of the state machine, are next.
491 1166 : MCOS->EmitIntValue(context.getAsmInfo()->getMinInstAlignment(), 1);
492 : // maximum_operations_per_instruction
493 : // For non-VLIW architectures this field is always 1.
494 : // FIXME: VLIW architectures need to update this field accordingly.
495 1166 : if (LineTableVersion >= 4)
496 1059 : MCOS->EmitIntValue(1, 1);
497 1166 : MCOS->EmitIntValue(DWARF2_LINE_DEFAULT_IS_STMT, 1);
498 1166 : MCOS->EmitIntValue(Params.DWARF2LineBase, 1);
499 1166 : MCOS->EmitIntValue(Params.DWARF2LineRange, 1);
500 1166 : MCOS->EmitIntValue(StandardOpcodeLengths.size() + 1, 1);
501 :
502 : // Standard opcode lengths
503 15074 : for (char Length : StandardOpcodeLengths)
504 13908 : MCOS->EmitIntValue(Length, 1);
505 :
506 : // Put out the directory and file tables. The formats vary depending on
507 : // the version.
508 1166 : if (LineTableVersion >= 5)
509 48 : emitV5FileDirTables(MCOS, LineStr, context.getCompilationDir());
510 : else
511 1118 : emitV2FileDirTables(MCOS);
512 :
513 : // This is the end of the prologue, so set the value of the symbol at the
514 : // end of the prologue (that was used in a previous expression).
515 1166 : MCOS->EmitLabel(ProEndSym);
516 :
517 1166 : return std::make_pair(LineStartSym, LineEndSym);
518 : }
519 :
520 1159 : void MCDwarfLineTable::EmitCU(MCObjectStreamer *MCOS,
521 : MCDwarfLineTableParams Params,
522 : Optional<MCDwarfLineStr> &LineStr) const {
523 1159 : MCSymbol *LineEndSym = Header.Emit(MCOS, Params, LineStr).second;
524 :
525 : // Put out the line tables.
526 9231 : for (const auto &LineSec : MCLineSections.getMCLineEntries())
527 8072 : EmitDwarfLineTable(MCOS, LineSec.first, LineSec.second);
528 :
529 : // This is the end of the section, so set the value of the symbol at the end
530 : // of this section (that was used in a previous expression).
531 1159 : MCOS->EmitLabel(LineEndSym);
532 1159 : }
533 :
534 892573 : Expected<unsigned> MCDwarfLineTable::tryGetFile(StringRef &Directory,
535 : StringRef &FileName,
536 : MD5::MD5Result *Checksum,
537 : Optional<StringRef> Source,
538 : unsigned FileNumber) {
539 892573 : return Header.tryGetFile(Directory, FileName, Checksum, Source, FileNumber);
540 : }
541 :
542 : Expected<unsigned>
543 892611 : MCDwarfLineTableHeader::tryGetFile(StringRef &Directory,
544 : StringRef &FileName,
545 : MD5::MD5Result *Checksum,
546 : Optional<StringRef> &Source,
547 : unsigned FileNumber) {
548 : if (Directory == CompilationDir)
549 889219 : Directory = "";
550 892611 : if (FileName.empty()) {
551 232 : FileName = "<stdin>";
552 232 : Directory = "";
553 : }
554 : assert(!FileName.empty());
555 : // Keep track of whether any or all files have an MD5 checksum.
556 : // If any files have embedded source, they all must.
557 892611 : if (MCDwarfFiles.empty()) {
558 1466 : trackMD5Usage(Checksum);
559 1466 : HasSource = (Source != None);
560 : }
561 892611 : if (FileNumber == 0) {
562 : // File numbers start with 1 and/or after any file numbers
563 : // allocated by inline-assembler .file directives.
564 892476 : FileNumber = MCDwarfFiles.empty() ? 1 : MCDwarfFiles.size();
565 : SmallString<256> Buffer;
566 : auto IterBool = SourceIdMap.insert(
567 892476 : std::make_pair((Directory + Twine('\0') + FileName).toStringRef(Buffer),
568 892476 : FileNumber));
569 892476 : if (!IterBool.second)
570 : return IterBool.first->second;
571 : }
572 : // Make space for this FileNumber in the MCDwarfFiles vector if needed.
573 6362 : if (FileNumber >= MCDwarfFiles.size())
574 6360 : MCDwarfFiles.resize(FileNumber + 1);
575 :
576 : // Get the new MCDwarfFile slot for this FileNumber.
577 : MCDwarfFile &File = MCDwarfFiles[FileNumber];
578 :
579 : // It is an error to see the same number more than once.
580 6362 : if (!File.Name.empty())
581 0 : return make_error<StringError>("file number already allocated",
582 0 : inconvertibleErrorCode());
583 :
584 : // If any files have embedded source, they all must.
585 12724 : if (HasSource != (Source != None))
586 0 : return make_error<StringError>("inconsistent use of embedded source",
587 0 : inconvertibleErrorCode());
588 :
589 6362 : if (Directory.empty()) {
590 : // Separate the directory part from the basename of the FileName.
591 6010 : StringRef tFileName = sys::path::filename(FileName);
592 6009 : if (!tFileName.empty()) {
593 6010 : Directory = sys::path::parent_path(FileName);
594 6010 : if (!Directory.empty())
595 5376 : FileName = tFileName;
596 : }
597 : }
598 :
599 : // Find or make an entry in the MCDwarfDirs vector for this Directory.
600 : // Capture directory name.
601 : unsigned DirIndex;
602 6361 : if (Directory.empty()) {
603 : // For FileNames with no directories a DirIndex of 0 is used.
604 : DirIndex = 0;
605 : } else {
606 : DirIndex = 0;
607 20045 : for (unsigned End = MCDwarfDirs.size(); DirIndex < End; DirIndex++) {
608 18227 : if (Directory == MCDwarfDirs[DirIndex])
609 : break;
610 : }
611 5727 : if (DirIndex >= MCDwarfDirs.size())
612 5454 : MCDwarfDirs.push_back(Directory);
613 : // The DirIndex is one based, as DirIndex of 0 is used for FileNames with
614 : // no directories. MCDwarfDirs[] is unlike MCDwarfFiles[] in that the
615 : // directory names are stored at MCDwarfDirs[DirIndex-1] where FileNames
616 : // are stored at MCDwarfFiles[FileNumber].Name .
617 5727 : DirIndex++;
618 : }
619 :
620 6361 : File.Name = FileName;
621 6361 : File.DirIndex = DirIndex;
622 6361 : File.Checksum = Checksum;
623 6361 : trackMD5Usage(Checksum);
624 : File.Source = Source;
625 6361 : if (Source)
626 13 : HasSource = true;
627 :
628 : // return the allocated FileNumber.
629 : return FileNumber;
630 : }
631 :
632 : /// Utility function to emit the encoding to a streamer.
633 8412 : void MCDwarfLineAddr::Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
634 : int64_t LineDelta, uint64_t AddrDelta) {
635 8412 : MCContext &Context = MCOS->getContext();
636 : SmallString<256> Tmp;
637 : raw_svector_ostream OS(Tmp);
638 8412 : MCDwarfLineAddr::Encode(Context, Params, LineDelta, AddrDelta, OS);
639 16824 : MCOS->EmitBytes(OS.str());
640 8412 : }
641 :
642 : /// Given a special op, return the address skip amount (in units of
643 : /// DWARF2_LINE_MIN_INSN_LENGTH).
644 0 : static uint64_t SpecialAddr(MCDwarfLineTableParams Params, uint64_t op) {
645 2390757 : return (op - Params.DWARF2LineOpcodeBase) / Params.DWARF2LineRange;
646 : }
647 :
648 : /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
649 2390757 : void MCDwarfLineAddr::Encode(MCContext &Context, MCDwarfLineTableParams Params,
650 : int64_t LineDelta, uint64_t AddrDelta,
651 : raw_ostream &OS) {
652 : uint64_t Temp, Opcode;
653 : bool NeedCopy = false;
654 :
655 : // The maximum address skip amount that can be encoded with a special op.
656 : uint64_t MaxSpecialAddrDelta = SpecialAddr(Params, 255);
657 :
658 : // Scale the address delta by the minimum instruction length.
659 : AddrDelta = ScaleAddrDelta(Context, AddrDelta);
660 :
661 : // A LineDelta of INT64_MAX is a signal that this is actually a
662 : // DW_LNE_end_sequence. We cannot use special opcodes here, since we want the
663 : // end_sequence to emit the matrix entry.
664 2390757 : if (LineDelta == INT64_MAX) {
665 30162 : if (AddrDelta == MaxSpecialAddrDelta)
666 : OS << char(dwarf::DW_LNS_const_add_pc);
667 30050 : else if (AddrDelta) {
668 : OS << char(dwarf::DW_LNS_advance_pc);
669 29805 : encodeULEB128(AddrDelta, OS);
670 : }
671 : OS << char(dwarf::DW_LNS_extended_op);
672 : OS << char(1);
673 : OS << char(dwarf::DW_LNE_end_sequence);
674 30162 : return;
675 : }
676 :
677 : // Bias the line delta by the base.
678 2360595 : Temp = LineDelta - Params.DWARF2LineBase;
679 :
680 : // If the line increment is out of range of a special opcode, we must encode
681 : // it with DW_LNS_advance_line.
682 2360595 : if (Temp >= Params.DWARF2LineRange ||
683 666013 : Temp + Params.DWARF2LineOpcodeBase > 255) {
684 : OS << char(dwarf::DW_LNS_advance_line);
685 1694583 : encodeSLEB128(LineDelta, OS);
686 :
687 : LineDelta = 0;
688 1694583 : Temp = 0 - Params.DWARF2LineBase;
689 : NeedCopy = true;
690 : }
691 :
692 : // Use DW_LNS_copy instead of a "line +0, addr +0" special opcode.
693 2360595 : if (LineDelta == 0 && AddrDelta == 0) {
694 : OS << char(dwarf::DW_LNS_copy);
695 12501 : return;
696 : }
697 :
698 : // Bias the opcode by the special opcode base.
699 2348094 : Temp += Params.DWARF2LineOpcodeBase;
700 :
701 : // Avoid overflow when addr_delta is large.
702 2348094 : if (AddrDelta < 256 + MaxSpecialAddrDelta) {
703 : // Try using a special opcode.
704 2348043 : Opcode = Temp + AddrDelta * Params.DWARF2LineRange;
705 2348043 : if (Opcode <= 255) {
706 1792483 : OS << char(Opcode);
707 1792483 : return;
708 : }
709 :
710 : // Try using DW_LNS_const_add_pc followed by special op.
711 555560 : Opcode = Temp + (AddrDelta - MaxSpecialAddrDelta) * Params.DWARF2LineRange;
712 555560 : if (Opcode <= 255) {
713 : OS << char(dwarf::DW_LNS_const_add_pc);
714 470892 : OS << char(Opcode);
715 470892 : return;
716 : }
717 : }
718 :
719 : // Otherwise use DW_LNS_advance_pc.
720 : OS << char(dwarf::DW_LNS_advance_pc);
721 84719 : encodeULEB128(AddrDelta, OS);
722 :
723 84719 : if (NeedCopy)
724 : OS << char(dwarf::DW_LNS_copy);
725 : else {
726 : assert(Temp <= 255 && "Buggy special opcode encoding.");
727 23486 : OS << char(Temp);
728 : }
729 : }
730 :
731 0 : bool MCDwarfLineAddr::FixedEncode(MCContext &Context,
732 : MCDwarfLineTableParams Params,
733 : int64_t LineDelta, uint64_t AddrDelta,
734 : raw_ostream &OS,
735 : uint32_t *Offset, uint32_t *Size) {
736 0 : if (LineDelta != INT64_MAX) {
737 : OS << char(dwarf::DW_LNS_advance_line);
738 0 : encodeSLEB128(LineDelta, OS);
739 : }
740 :
741 : // Use address delta to adjust address or use absolute address to adjust
742 : // address.
743 : bool SetDelta;
744 : // According to DWARF spec., the DW_LNS_fixed_advance_pc opcode takes a
745 : // single uhalf (unencoded) operand. So, the maximum value of AddrDelta
746 : // is 65535. We set a conservative upper bound for it for relaxation.
747 0 : if (AddrDelta > 60000) {
748 0 : const MCAsmInfo *asmInfo = Context.getAsmInfo();
749 0 : unsigned AddrSize = asmInfo->getCodePointerSize();
750 :
751 : OS << char(dwarf::DW_LNS_extended_op);
752 0 : encodeULEB128(1 + AddrSize, OS);
753 : OS << char(dwarf::DW_LNE_set_address);
754 : // Generate fixup for the address.
755 0 : *Offset = OS.tell();
756 0 : *Size = AddrSize;
757 : SetDelta = false;
758 : std::vector<uint8_t> FillData;
759 0 : FillData.insert(FillData.begin(), AddrSize, 0);
760 0 : OS.write(reinterpret_cast<char *>(FillData.data()), AddrSize);
761 : } else {
762 : OS << char(dwarf::DW_LNS_fixed_advance_pc);
763 : // Generate fixup for 2-bytes address delta.
764 0 : *Offset = OS.tell();
765 0 : *Size = 2;
766 : SetDelta = true;
767 : OS << char(0);
768 : OS << char(0);
769 : }
770 :
771 0 : if (LineDelta == INT64_MAX) {
772 : OS << char(dwarf::DW_LNS_extended_op);
773 : OS << char(1);
774 : OS << char(dwarf::DW_LNE_end_sequence);
775 : } else {
776 : OS << char(dwarf::DW_LNS_copy);
777 : }
778 :
779 0 : return SetDelta;
780 : }
781 :
782 : // Utility function to write a tuple for .debug_abbrev.
783 : static void EmitAbbrev(MCStreamer *MCOS, uint64_t Name, uint64_t Form) {
784 537 : MCOS->EmitULEB128IntValue(Name);
785 537 : MCOS->EmitULEB128IntValue(Form);
786 : }
787 :
788 : // When generating dwarf for assembly source files this emits
789 : // the data for .debug_abbrev section which contains three DIEs.
790 36 : static void EmitGenDwarfAbbrev(MCStreamer *MCOS) {
791 36 : MCContext &context = MCOS->getContext();
792 36 : MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfAbbrevSection());
793 :
794 : // DW_TAG_compile_unit DIE abbrev (1).
795 36 : MCOS->EmitULEB128IntValue(1);
796 36 : MCOS->EmitULEB128IntValue(dwarf::DW_TAG_compile_unit);
797 36 : MCOS->EmitIntValue(dwarf::DW_CHILDREN_yes, 1);
798 36 : EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, context.getDwarfVersion() >= 4
799 : ? dwarf::DW_FORM_sec_offset
800 : : dwarf::DW_FORM_data4);
801 36 : if (context.getGenDwarfSectionSyms().size() > 1 &&
802 5 : context.getDwarfVersion() >= 3) {
803 3 : EmitAbbrev(MCOS, dwarf::DW_AT_ranges, context.getDwarfVersion() >= 4
804 : ? dwarf::DW_FORM_sec_offset
805 : : dwarf::DW_FORM_data4);
806 : } else {
807 : EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
808 : EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
809 : }
810 : EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
811 36 : if (!context.getCompilationDir().empty())
812 : EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
813 : StringRef DwarfDebugFlags = context.getDwarfDebugFlags();
814 36 : if (!DwarfDebugFlags.empty())
815 : EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string);
816 : EmitAbbrev(MCOS, dwarf::DW_AT_producer, dwarf::DW_FORM_string);
817 : EmitAbbrev(MCOS, dwarf::DW_AT_language, dwarf::DW_FORM_data2);
818 : EmitAbbrev(MCOS, 0, 0);
819 :
820 : // DW_TAG_label DIE abbrev (2).
821 36 : MCOS->EmitULEB128IntValue(2);
822 36 : MCOS->EmitULEB128IntValue(dwarf::DW_TAG_label);
823 36 : MCOS->EmitIntValue(dwarf::DW_CHILDREN_yes, 1);
824 : EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
825 : EmitAbbrev(MCOS, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data4);
826 : EmitAbbrev(MCOS, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data4);
827 : EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
828 : EmitAbbrev(MCOS, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag);
829 : EmitAbbrev(MCOS, 0, 0);
830 :
831 : // DW_TAG_unspecified_parameters DIE abbrev (3).
832 36 : MCOS->EmitULEB128IntValue(3);
833 36 : MCOS->EmitULEB128IntValue(dwarf::DW_TAG_unspecified_parameters);
834 36 : MCOS->EmitIntValue(dwarf::DW_CHILDREN_no, 1);
835 : EmitAbbrev(MCOS, 0, 0);
836 :
837 : // Terminate the abbreviations for this compilation unit.
838 36 : MCOS->EmitIntValue(0, 1);
839 36 : }
840 :
841 : // When generating dwarf for assembly source files this emits the data for
842 : // .debug_aranges section. This section contains a header and a table of pairs
843 : // of PointerSize'ed values for the address and size of section(s) with line
844 : // table entries.
845 36 : static void EmitGenDwarfAranges(MCStreamer *MCOS,
846 : const MCSymbol *InfoSectionSymbol) {
847 36 : MCContext &context = MCOS->getContext();
848 :
849 : auto &Sections = context.getGenDwarfSectionSyms();
850 :
851 36 : MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection());
852 :
853 : // This will be the length of the .debug_aranges section, first account for
854 : // the size of each item in the header (see below where we emit these items).
855 : int Length = 4 + 2 + 4 + 1 + 1;
856 :
857 : // Figure the padding after the header before the table of address and size
858 : // pairs who's values are PointerSize'ed.
859 36 : const MCAsmInfo *asmInfo = context.getAsmInfo();
860 36 : int AddrSize = asmInfo->getCodePointerSize();
861 36 : int Pad = 2 * AddrSize - (Length & (2 * AddrSize - 1));
862 36 : if (Pad == 2 * AddrSize)
863 : Pad = 0;
864 36 : Length += Pad;
865 :
866 : // Add the size of the pair of PointerSize'ed values for the address and size
867 : // of each section we have in the table.
868 36 : Length += 2 * AddrSize * Sections.size();
869 : // And the pair of terminating zeros.
870 36 : Length += 2 * AddrSize;
871 :
872 : // Emit the header for this section.
873 : // The 4 byte length not including the 4 byte value for the length.
874 36 : MCOS->EmitIntValue(Length - 4, 4);
875 : // The 2 byte version, which is 2.
876 36 : MCOS->EmitIntValue(2, 2);
877 : // The 4 byte offset to the compile unit in the .debug_info from the start
878 : // of the .debug_info.
879 36 : if (InfoSectionSymbol)
880 32 : MCOS->EmitSymbolValue(InfoSectionSymbol, 4,
881 32 : asmInfo->needsDwarfSectionOffsetDirective());
882 : else
883 4 : MCOS->EmitIntValue(0, 4);
884 : // The 1 byte size of an address.
885 36 : MCOS->EmitIntValue(AddrSize, 1);
886 : // The 1 byte size of a segment descriptor, we use a value of zero.
887 36 : MCOS->EmitIntValue(0, 1);
888 : // Align the header with the padding if needed, before we put out the table.
889 180 : for(int i = 0; i < Pad; i++)
890 144 : MCOS->EmitIntValue(0, 1);
891 :
892 : // Now emit the table of pairs of PointerSize'ed values for the section
893 : // addresses and sizes.
894 77 : for (MCSection *Sec : Sections) {
895 41 : const MCSymbol *StartSymbol = Sec->getBeginSymbol();
896 41 : MCSymbol *EndSymbol = Sec->getEndSymbol(context);
897 : assert(StartSymbol && "StartSymbol must not be NULL");
898 : assert(EndSymbol && "EndSymbol must not be NULL");
899 :
900 82 : const MCExpr *Addr = MCSymbolRefExpr::create(
901 41 : StartSymbol, MCSymbolRefExpr::VK_None, context);
902 41 : const MCExpr *Size = MakeStartMinusEndExpr(*MCOS,
903 : *StartSymbol, *EndSymbol, 0);
904 41 : MCOS->EmitValue(Addr, AddrSize);
905 41 : emitAbsValue(*MCOS, Size, AddrSize);
906 : }
907 :
908 : // And finally the pair of terminating zeros.
909 36 : MCOS->EmitIntValue(0, AddrSize);
910 36 : MCOS->EmitIntValue(0, AddrSize);
911 36 : }
912 :
913 : // When generating dwarf for assembly source files this emits the data for
914 : // .debug_info section which contains three parts. The header, the compile_unit
915 : // DIE and a list of label DIEs.
916 36 : static void EmitGenDwarfInfo(MCStreamer *MCOS,
917 : const MCSymbol *AbbrevSectionSymbol,
918 : const MCSymbol *LineSectionSymbol,
919 : const MCSymbol *RangesSectionSymbol) {
920 36 : MCContext &context = MCOS->getContext();
921 :
922 36 : MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
923 :
924 : // Create a symbol at the start and end of this section used in here for the
925 : // expression to calculate the length in the header.
926 36 : MCSymbol *InfoStart = context.createTempSymbol();
927 36 : MCOS->EmitLabel(InfoStart);
928 36 : MCSymbol *InfoEnd = context.createTempSymbol();
929 :
930 : // First part: the header.
931 :
932 : // The 4 byte total length of the information for this compilation unit, not
933 : // including these 4 bytes.
934 36 : const MCExpr *Length = MakeStartMinusEndExpr(*MCOS, *InfoStart, *InfoEnd, 4);
935 36 : emitAbsValue(*MCOS, Length, 4);
936 :
937 : // The 2 byte DWARF version.
938 36 : MCOS->EmitIntValue(context.getDwarfVersion(), 2);
939 :
940 : // The DWARF v5 header has unit type, address size, abbrev offset.
941 : // Earlier versions have abbrev offset, address size.
942 36 : const MCAsmInfo &AsmInfo = *context.getAsmInfo();
943 36 : int AddrSize = AsmInfo.getCodePointerSize();
944 36 : if (context.getDwarfVersion() >= 5) {
945 2 : MCOS->EmitIntValue(dwarf::DW_UT_compile, 1);
946 2 : MCOS->EmitIntValue(AddrSize, 1);
947 : }
948 : // The 4 byte offset to the debug abbrevs from the start of the .debug_abbrev,
949 : // it is at the start of that section so this is zero.
950 36 : if (AbbrevSectionSymbol == nullptr)
951 4 : MCOS->EmitIntValue(0, 4);
952 : else
953 32 : MCOS->EmitSymbolValue(AbbrevSectionSymbol, 4,
954 32 : AsmInfo.needsDwarfSectionOffsetDirective());
955 36 : if (context.getDwarfVersion() <= 4)
956 34 : MCOS->EmitIntValue(AddrSize, 1);
957 :
958 : // Second part: the compile_unit DIE.
959 :
960 : // The DW_TAG_compile_unit DIE abbrev (1).
961 36 : MCOS->EmitULEB128IntValue(1);
962 :
963 : // DW_AT_stmt_list, a 4 byte offset from the start of the .debug_line section,
964 : // which is at the start of that section so this is zero.
965 36 : if (LineSectionSymbol)
966 32 : MCOS->EmitSymbolValue(LineSectionSymbol, 4,
967 32 : AsmInfo.needsDwarfSectionOffsetDirective());
968 : else
969 4 : MCOS->EmitIntValue(0, 4);
970 :
971 36 : if (RangesSectionSymbol) {
972 : // There are multiple sections containing code, so we must use the
973 : // .debug_ranges sections.
974 :
975 : // AT_ranges, the 4 byte offset from the start of the .debug_ranges section
976 : // to the address range list for this compilation unit.
977 3 : MCOS->EmitSymbolValue(RangesSectionSymbol, 4);
978 : } else {
979 : // If we only have one non-empty code section, we can use the simpler
980 : // AT_low_pc and AT_high_pc attributes.
981 :
982 : // Find the first (and only) non-empty text section
983 : auto &Sections = context.getGenDwarfSectionSyms();
984 : const auto TextSection = Sections.begin();
985 : assert(TextSection != Sections.end() && "No text section found");
986 :
987 33 : MCSymbol *StartSymbol = (*TextSection)->getBeginSymbol();
988 33 : MCSymbol *EndSymbol = (*TextSection)->getEndSymbol(context);
989 : assert(StartSymbol && "StartSymbol must not be NULL");
990 : assert(EndSymbol && "EndSymbol must not be NULL");
991 :
992 : // AT_low_pc, the first address of the default .text section.
993 66 : const MCExpr *Start = MCSymbolRefExpr::create(
994 33 : StartSymbol, MCSymbolRefExpr::VK_None, context);
995 33 : MCOS->EmitValue(Start, AddrSize);
996 :
997 : // AT_high_pc, the last address of the default .text section.
998 66 : const MCExpr *End = MCSymbolRefExpr::create(
999 33 : EndSymbol, MCSymbolRefExpr::VK_None, context);
1000 33 : MCOS->EmitValue(End, AddrSize);
1001 : }
1002 :
1003 : // AT_name, the name of the source file. Reconstruct from the first directory
1004 : // and file table entries.
1005 : const SmallVectorImpl<std::string> &MCDwarfDirs = context.getMCDwarfDirs();
1006 36 : if (MCDwarfDirs.size() > 0) {
1007 52 : MCOS->EmitBytes(MCDwarfDirs[0]);
1008 26 : MCOS->EmitBytes(sys::path::get_separator());
1009 : }
1010 : const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles =
1011 36 : MCOS->getContext().getMCDwarfFiles();
1012 72 : MCOS->EmitBytes(MCDwarfFiles[1].Name);
1013 36 : MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
1014 :
1015 : // AT_comp_dir, the working directory the assembly was done in.
1016 36 : if (!context.getCompilationDir().empty()) {
1017 36 : MCOS->EmitBytes(context.getCompilationDir());
1018 36 : MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
1019 : }
1020 :
1021 : // AT_APPLE_flags, the command line arguments of the assembler tool.
1022 36 : StringRef DwarfDebugFlags = context.getDwarfDebugFlags();
1023 36 : if (!DwarfDebugFlags.empty()){
1024 0 : MCOS->EmitBytes(DwarfDebugFlags);
1025 0 : MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
1026 : }
1027 :
1028 : // AT_producer, the version of the assembler tool.
1029 36 : StringRef DwarfDebugProducer = context.getDwarfDebugProducer();
1030 36 : if (!DwarfDebugProducer.empty())
1031 1 : MCOS->EmitBytes(DwarfDebugProducer);
1032 : else
1033 70 : MCOS->EmitBytes(StringRef("llvm-mc (based on LLVM " PACKAGE_VERSION ")"));
1034 36 : MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
1035 :
1036 : // AT_language, a 4 byte value. We use DW_LANG_Mips_Assembler as the dwarf2
1037 : // draft has no standard code for assembler.
1038 36 : MCOS->EmitIntValue(dwarf::DW_LANG_Mips_Assembler, 2);
1039 :
1040 : // Third part: the list of label DIEs.
1041 :
1042 : // Loop on saved info for dwarf labels and create the DIEs for them.
1043 : const std::vector<MCGenDwarfLabelEntry> &Entries =
1044 36 : MCOS->getContext().getMCGenDwarfLabelEntries();
1045 85 : for (const auto &Entry : Entries) {
1046 : // The DW_TAG_label DIE abbrev (2).
1047 49 : MCOS->EmitULEB128IntValue(2);
1048 :
1049 : // AT_name, of the label without any leading underbar.
1050 49 : MCOS->EmitBytes(Entry.getName());
1051 49 : MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
1052 :
1053 : // AT_decl_file, index into the file table.
1054 49 : MCOS->EmitIntValue(Entry.getFileNumber(), 4);
1055 :
1056 : // AT_decl_line, source line number.
1057 49 : MCOS->EmitIntValue(Entry.getLineNumber(), 4);
1058 :
1059 : // AT_low_pc, start address of the label.
1060 98 : const MCExpr *AT_low_pc = MCSymbolRefExpr::create(Entry.getLabel(),
1061 49 : MCSymbolRefExpr::VK_None, context);
1062 49 : MCOS->EmitValue(AT_low_pc, AddrSize);
1063 :
1064 : // DW_AT_prototyped, a one byte flag value of 0 saying we have no prototype.
1065 49 : MCOS->EmitIntValue(0, 1);
1066 :
1067 : // The DW_TAG_unspecified_parameters DIE abbrev (3).
1068 49 : MCOS->EmitULEB128IntValue(3);
1069 :
1070 : // Add the NULL DIE terminating the DW_TAG_unspecified_parameters DIE's.
1071 49 : MCOS->EmitIntValue(0, 1);
1072 : }
1073 :
1074 : // Add the NULL DIE terminating the Compile Unit DIE's.
1075 36 : MCOS->EmitIntValue(0, 1);
1076 :
1077 : // Now set the value of the symbol at the end of the info section.
1078 36 : MCOS->EmitLabel(InfoEnd);
1079 36 : }
1080 :
1081 : // When generating dwarf for assembly source files this emits the data for
1082 : // .debug_ranges section. We only emit one range list, which spans all of the
1083 : // executable sections of this file.
1084 3 : static void EmitGenDwarfRanges(MCStreamer *MCOS) {
1085 3 : MCContext &context = MCOS->getContext();
1086 : auto &Sections = context.getGenDwarfSectionSyms();
1087 :
1088 3 : const MCAsmInfo *AsmInfo = context.getAsmInfo();
1089 3 : int AddrSize = AsmInfo->getCodePointerSize();
1090 :
1091 3 : MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection());
1092 :
1093 9 : for (MCSection *Sec : Sections) {
1094 6 : const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1095 6 : MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1096 : assert(StartSymbol && "StartSymbol must not be NULL");
1097 : assert(EndSymbol && "EndSymbol must not be NULL");
1098 :
1099 : // Emit a base address selection entry for the start of this section
1100 12 : const MCExpr *SectionStartAddr = MCSymbolRefExpr::create(
1101 6 : StartSymbol, MCSymbolRefExpr::VK_None, context);
1102 6 : MCOS->emitFill(AddrSize, 0xFF);
1103 6 : MCOS->EmitValue(SectionStartAddr, AddrSize);
1104 :
1105 : // Emit a range list entry spanning this section
1106 6 : const MCExpr *SectionSize = MakeStartMinusEndExpr(*MCOS,
1107 : *StartSymbol, *EndSymbol, 0);
1108 6 : MCOS->EmitIntValue(0, AddrSize);
1109 6 : emitAbsValue(*MCOS, SectionSize, AddrSize);
1110 : }
1111 :
1112 : // Emit end of list entry
1113 3 : MCOS->EmitIntValue(0, AddrSize);
1114 3 : MCOS->EmitIntValue(0, AddrSize);
1115 3 : }
1116 :
1117 : //
1118 : // When generating dwarf for assembly source files this emits the Dwarf
1119 : // sections.
1120 : //
1121 39 : void MCGenDwarfInfo::Emit(MCStreamer *MCOS) {
1122 39 : MCContext &context = MCOS->getContext();
1123 :
1124 : // Create the dwarf sections in this order (.debug_line already created).
1125 39 : const MCAsmInfo *AsmInfo = context.getAsmInfo();
1126 : bool CreateDwarfSectionSymbols =
1127 39 : AsmInfo->doesDwarfUseRelocationsAcrossSections();
1128 : MCSymbol *LineSectionSymbol = nullptr;
1129 39 : if (CreateDwarfSectionSymbols)
1130 35 : LineSectionSymbol = MCOS->getDwarfLineTableSymbol(0);
1131 : MCSymbol *AbbrevSectionSymbol = nullptr;
1132 : MCSymbol *InfoSectionSymbol = nullptr;
1133 : MCSymbol *RangesSectionSymbol = nullptr;
1134 :
1135 : // Create end symbols for each section, and remove empty sections
1136 39 : MCOS->getContext().finalizeDwarfSections(*MCOS);
1137 :
1138 : // If there are no sections to generate debug info for, we don't need
1139 : // to do anything
1140 78 : if (MCOS->getContext().getGenDwarfSectionSyms().empty())
1141 : return;
1142 :
1143 : // We only use the .debug_ranges section if we have multiple code sections,
1144 : // and we are emitting a DWARF version which supports it.
1145 : const bool UseRangesSection =
1146 36 : MCOS->getContext().getGenDwarfSectionSyms().size() > 1 &&
1147 5 : MCOS->getContext().getDwarfVersion() >= 3;
1148 36 : CreateDwarfSectionSymbols |= UseRangesSection;
1149 :
1150 36 : MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
1151 36 : if (CreateDwarfSectionSymbols) {
1152 32 : InfoSectionSymbol = context.createTempSymbol();
1153 32 : MCOS->EmitLabel(InfoSectionSymbol);
1154 : }
1155 36 : MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfAbbrevSection());
1156 36 : if (CreateDwarfSectionSymbols) {
1157 32 : AbbrevSectionSymbol = context.createTempSymbol();
1158 32 : MCOS->EmitLabel(AbbrevSectionSymbol);
1159 : }
1160 36 : if (UseRangesSection) {
1161 3 : MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection());
1162 3 : if (CreateDwarfSectionSymbols) {
1163 3 : RangesSectionSymbol = context.createTempSymbol();
1164 3 : MCOS->EmitLabel(RangesSectionSymbol);
1165 : }
1166 : }
1167 :
1168 : assert((RangesSectionSymbol != nullptr) || !UseRangesSection);
1169 :
1170 36 : MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection());
1171 :
1172 : // Output the data for .debug_aranges section.
1173 36 : EmitGenDwarfAranges(MCOS, InfoSectionSymbol);
1174 :
1175 36 : if (UseRangesSection)
1176 3 : EmitGenDwarfRanges(MCOS);
1177 :
1178 : // Output the data for .debug_abbrev section.
1179 36 : EmitGenDwarfAbbrev(MCOS);
1180 :
1181 : // Output the data for .debug_info section.
1182 36 : EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol,
1183 : RangesSectionSymbol);
1184 : }
1185 :
1186 : //
1187 : // When generating dwarf for assembly source files this is called when symbol
1188 : // for a label is created. If this symbol is not a temporary and is in the
1189 : // section that dwarf is being generated for, save the needed info to create
1190 : // a dwarf label.
1191 : //
1192 56 : void MCGenDwarfLabelEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS,
1193 : SourceMgr &SrcMgr, SMLoc &Loc) {
1194 : // We won't create dwarf labels for temporary symbols.
1195 56 : if (Symbol->isTemporary())
1196 6 : return;
1197 54 : MCContext &context = MCOS->getContext();
1198 : // We won't create dwarf labels for symbols in sections that we are not
1199 : // generating debug info for.
1200 54 : if (!context.getGenDwarfSectionSyms().count(MCOS->getCurrentSectionOnly()))
1201 : return;
1202 :
1203 : // The dwarf label's name does not have the symbol name's leading
1204 : // underbar if any.
1205 50 : StringRef Name = Symbol->getName();
1206 : if (Name.startswith("_"))
1207 28 : Name = Name.substr(1, Name.size()-1);
1208 :
1209 : // Get the dwarf file number to be used for the dwarf label.
1210 50 : unsigned FileNumber = context.getGenDwarfFileNumber();
1211 :
1212 : // Finding the line number is the expensive part which is why we just don't
1213 : // pass it in as for some symbols we won't create a dwarf label.
1214 50 : unsigned CurBuffer = SrcMgr.FindBufferContainingLoc(Loc);
1215 50 : unsigned LineNumber = SrcMgr.FindLineNumber(Loc, CurBuffer);
1216 :
1217 : // We create a temporary symbol for use for the AT_high_pc and AT_low_pc
1218 : // values so that they don't have things like an ARM thumb bit from the
1219 : // original symbol. So when used they won't get a low bit set after
1220 : // relocation.
1221 50 : MCSymbol *Label = context.createTempSymbol();
1222 50 : MCOS->EmitLabel(Label);
1223 :
1224 : // Create and entry for the info and add it to the other entries.
1225 50 : MCOS->getContext().addMCGenDwarfLabelEntry(
1226 50 : MCGenDwarfLabelEntry(Name, FileNumber, LineNumber, Label));
1227 : }
1228 :
1229 : static int getDataAlignmentFactor(MCStreamer &streamer) {
1230 970177 : MCContext &context = streamer.getContext();
1231 970177 : const MCAsmInfo *asmInfo = context.getAsmInfo();
1232 970177 : int size = asmInfo->getCalleeSaveStackSlotSize();
1233 970177 : if (asmInfo->isStackGrowthDirectionUp())
1234 : return size;
1235 : else
1236 970177 : return -size;
1237 : }
1238 :
1239 515378 : static unsigned getSizeForEncoding(MCStreamer &streamer,
1240 : unsigned symbolEncoding) {
1241 515378 : MCContext &context = streamer.getContext();
1242 515378 : unsigned format = symbolEncoding & 0x0f;
1243 515378 : switch (format) {
1244 0 : default: llvm_unreachable("Unknown Encoding");
1245 1256 : case dwarf::DW_EH_PE_absptr:
1246 : case dwarf::DW_EH_PE_signed:
1247 1256 : return context.getAsmInfo()->getCodePointerSize();
1248 : case dwarf::DW_EH_PE_udata2:
1249 : case dwarf::DW_EH_PE_sdata2:
1250 : return 2;
1251 513336 : case dwarf::DW_EH_PE_udata4:
1252 : case dwarf::DW_EH_PE_sdata4:
1253 513336 : return 4;
1254 768 : case dwarf::DW_EH_PE_udata8:
1255 : case dwarf::DW_EH_PE_sdata8:
1256 768 : return 8;
1257 : }
1258 : }
1259 :
1260 254555 : static void emitFDESymbol(MCObjectStreamer &streamer, const MCSymbol &symbol,
1261 : unsigned symbolEncoding, bool isEH) {
1262 254555 : MCContext &context = streamer.getContext();
1263 254555 : const MCAsmInfo *asmInfo = context.getAsmInfo();
1264 254555 : const MCExpr *v = asmInfo->getExprForFDESymbol(&symbol,
1265 : symbolEncoding,
1266 254555 : streamer);
1267 254555 : unsigned size = getSizeForEncoding(streamer, symbolEncoding);
1268 254555 : if (asmInfo->doDwarfFDESymbolsUseAbsDiff() && isEH)
1269 298 : emitAbsValue(streamer, v, size);
1270 : else
1271 254257 : streamer.EmitValue(v, size);
1272 254555 : }
1273 :
1274 3055 : static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol,
1275 : unsigned symbolEncoding) {
1276 3055 : MCContext &context = streamer.getContext();
1277 3055 : const MCAsmInfo *asmInfo = context.getAsmInfo();
1278 3055 : const MCExpr *v = asmInfo->getExprForPersonalitySymbol(&symbol,
1279 : symbolEncoding,
1280 3055 : streamer);
1281 3055 : unsigned size = getSizeForEncoding(streamer, symbolEncoding);
1282 3055 : streamer.EmitValue(v, size);
1283 3055 : }
1284 :
1285 : namespace {
1286 :
1287 : class FrameEmitterImpl {
1288 : int CFAOffset = 0;
1289 : int InitialCFAOffset = 0;
1290 : bool IsEH;
1291 : MCObjectStreamer &Streamer;
1292 :
1293 : public:
1294 : FrameEmitterImpl(bool IsEH, MCObjectStreamer &Streamer)
1295 6992 : : IsEH(IsEH), Streamer(Streamer) {}
1296 :
1297 : /// Emit the unwind information in a compact way.
1298 : void EmitCompactUnwind(const MCDwarfFrameInfo &frame);
1299 :
1300 : const MCSymbol &EmitCIE(const MCDwarfFrameInfo &F);
1301 : void EmitFDE(const MCSymbol &cieStart, const MCDwarfFrameInfo &frame,
1302 : bool LastInSection, const MCSymbol &SectionStart);
1303 : void EmitCFIInstructions(ArrayRef<MCCFIInstruction> Instrs,
1304 : MCSymbol *BaseLabel);
1305 : void EmitCFIInstruction(const MCCFIInstruction &Instr);
1306 : };
1307 :
1308 : } // end anonymous namespace
1309 :
1310 : static void emitEncodingByte(MCObjectStreamer &Streamer, unsigned Encoding) {
1311 15928 : Streamer.EmitIntValue(Encoding, 1);
1312 : }
1313 :
1314 960224 : void FrameEmitterImpl::EmitCFIInstruction(const MCCFIInstruction &Instr) {
1315 960224 : int dataAlignmentFactor = getDataAlignmentFactor(Streamer);
1316 960224 : auto *MRI = Streamer.getContext().getRegisterInfo();
1317 :
1318 960224 : switch (Instr.getOperation()) {
1319 14 : case MCCFIInstruction::OpRegister: {
1320 14 : unsigned Reg1 = Instr.getRegister();
1321 14 : unsigned Reg2 = Instr.getRegister2();
1322 14 : if (!IsEH) {
1323 2 : Reg1 = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg1);
1324 2 : Reg2 = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg2);
1325 : }
1326 14 : Streamer.EmitIntValue(dwarf::DW_CFA_register, 1);
1327 14 : Streamer.EmitULEB128IntValue(Reg1);
1328 14 : Streamer.EmitULEB128IntValue(Reg2);
1329 14 : return;
1330 : }
1331 14 : case MCCFIInstruction::OpWindowSave:
1332 14 : Streamer.EmitIntValue(dwarf::DW_CFA_GNU_window_save, 1);
1333 14 : return;
1334 :
1335 1 : case MCCFIInstruction::OpUndefined: {
1336 1 : unsigned Reg = Instr.getRegister();
1337 1 : Streamer.EmitIntValue(dwarf::DW_CFA_undefined, 1);
1338 1 : Streamer.EmitULEB128IntValue(Reg);
1339 1 : return;
1340 : }
1341 281799 : case MCCFIInstruction::OpAdjustCfaOffset:
1342 : case MCCFIInstruction::OpDefCfaOffset: {
1343 : const bool IsRelative =
1344 : Instr.getOperation() == MCCFIInstruction::OpAdjustCfaOffset;
1345 :
1346 281799 : Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_offset, 1);
1347 :
1348 281799 : if (IsRelative)
1349 26220 : CFAOffset += Instr.getOffset();
1350 : else
1351 255579 : CFAOffset = -Instr.getOffset();
1352 :
1353 281799 : Streamer.EmitULEB128IntValue(CFAOffset);
1354 :
1355 281799 : return;
1356 : }
1357 241895 : case MCCFIInstruction::OpDefCfa: {
1358 241895 : unsigned Reg = Instr.getRegister();
1359 241895 : if (!IsEH)
1360 103 : Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1361 241895 : Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1);
1362 241895 : Streamer.EmitULEB128IntValue(Reg);
1363 241895 : CFAOffset = -Instr.getOffset();
1364 241895 : Streamer.EmitULEB128IntValue(CFAOffset);
1365 :
1366 241895 : return;
1367 : }
1368 197871 : case MCCFIInstruction::OpDefCfaRegister: {
1369 197871 : unsigned Reg = Instr.getRegister();
1370 197871 : if (!IsEH)
1371 24 : Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1372 197871 : Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1);
1373 197871 : Streamer.EmitULEB128IntValue(Reg);
1374 :
1375 197871 : return;
1376 : }
1377 233882 : case MCCFIInstruction::OpOffset:
1378 : case MCCFIInstruction::OpRelOffset: {
1379 : const bool IsRelative =
1380 : Instr.getOperation() == MCCFIInstruction::OpRelOffset;
1381 :
1382 233882 : unsigned Reg = Instr.getRegister();
1383 233882 : if (!IsEH)
1384 135 : Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1385 :
1386 233882 : int Offset = Instr.getOffset();
1387 233882 : if (IsRelative)
1388 3 : Offset -= CFAOffset;
1389 233882 : Offset = Offset / dataAlignmentFactor;
1390 :
1391 233882 : if (Offset < 0) {
1392 3 : Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended_sf, 1);
1393 3 : Streamer.EmitULEB128IntValue(Reg);
1394 3 : Streamer.EmitSLEB128IntValue(Offset);
1395 233879 : } else if (Reg < 64) {
1396 233879 : Streamer.EmitIntValue(dwarf::DW_CFA_offset + Reg, 1);
1397 233879 : Streamer.EmitULEB128IntValue(Offset);
1398 : } else {
1399 0 : Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended, 1);
1400 0 : Streamer.EmitULEB128IntValue(Reg);
1401 0 : Streamer.EmitULEB128IntValue(Offset);
1402 : }
1403 : return;
1404 : }
1405 2 : case MCCFIInstruction::OpRememberState:
1406 2 : Streamer.EmitIntValue(dwarf::DW_CFA_remember_state, 1);
1407 2 : return;
1408 2 : case MCCFIInstruction::OpRestoreState:
1409 2 : Streamer.EmitIntValue(dwarf::DW_CFA_restore_state, 1);
1410 2 : return;
1411 4 : case MCCFIInstruction::OpSameValue: {
1412 4 : unsigned Reg = Instr.getRegister();
1413 4 : Streamer.EmitIntValue(dwarf::DW_CFA_same_value, 1);
1414 4 : Streamer.EmitULEB128IntValue(Reg);
1415 4 : return;
1416 : }
1417 1 : case MCCFIInstruction::OpRestore: {
1418 1 : unsigned Reg = Instr.getRegister();
1419 1 : if (!IsEH)
1420 0 : Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1421 1 : Streamer.EmitIntValue(dwarf::DW_CFA_restore | Reg, 1);
1422 1 : return;
1423 : }
1424 4737 : case MCCFIInstruction::OpGnuArgsSize:
1425 4737 : Streamer.EmitIntValue(dwarf::DW_CFA_GNU_args_size, 1);
1426 4737 : Streamer.EmitULEB128IntValue(Instr.getOffset());
1427 4737 : return;
1428 :
1429 2 : case MCCFIInstruction::OpEscape:
1430 4 : Streamer.EmitBytes(Instr.getValues());
1431 2 : return;
1432 : }
1433 0 : llvm_unreachable("Unhandled case in switch");
1434 : }
1435 :
1436 : /// Emit frame instructions to describe the layout of the frame.
1437 218015 : void FrameEmitterImpl::EmitCFIInstructions(ArrayRef<MCCFIInstruction> Instrs,
1438 : MCSymbol *BaseLabel) {
1439 1178239 : for (const MCCFIInstruction &Instr : Instrs) {
1440 960224 : MCSymbol *Label = Instr.getLabel();
1441 : // Throw out move if the label is invalid.
1442 1900721 : if (Label && !Label->isDefined()) continue; // Not emitted, in dead code.
1443 :
1444 : // Advance row if new location.
1445 960224 : if (BaseLabel && Label) {
1446 : MCSymbol *ThisSym = Label;
1447 940497 : if (ThisSym != BaseLabel) {
1448 940497 : Streamer.EmitDwarfAdvanceFrameAddr(BaseLabel, ThisSym);
1449 : BaseLabel = ThisSym;
1450 : }
1451 : }
1452 :
1453 960224 : EmitCFIInstruction(Instr);
1454 : }
1455 218015 : }
1456 :
1457 : /// Emit the unwind information in a compact way.
1458 0 : void FrameEmitterImpl::EmitCompactUnwind(const MCDwarfFrameInfo &Frame) {
1459 0 : MCContext &Context = Streamer.getContext();
1460 0 : const MCObjectFileInfo *MOFI = Context.getObjectFileInfo();
1461 :
1462 : // range-start range-length compact-unwind-enc personality-func lsda
1463 : // _foo LfooEnd-_foo 0x00000023 0 0
1464 : // _bar LbarEnd-_bar 0x00000025 __gxx_personality except_tab1
1465 : //
1466 : // .section __LD,__compact_unwind,regular,debug
1467 : //
1468 : // # compact unwind for _foo
1469 : // .quad _foo
1470 : // .set L1,LfooEnd-_foo
1471 : // .long L1
1472 : // .long 0x01010001
1473 : // .quad 0
1474 : // .quad 0
1475 : //
1476 : // # compact unwind for _bar
1477 : // .quad _bar
1478 : // .set L2,LbarEnd-_bar
1479 : // .long L2
1480 : // .long 0x01020011
1481 : // .quad __gxx_personality
1482 : // .quad except_tab1
1483 :
1484 0 : uint32_t Encoding = Frame.CompactUnwindEncoding;
1485 0 : if (!Encoding) return;
1486 0 : bool DwarfEHFrameOnly = (Encoding == MOFI->getCompactUnwindDwarfEHFrameOnly());
1487 :
1488 : // The encoding needs to know we have an LSDA.
1489 0 : if (!DwarfEHFrameOnly && Frame.Lsda)
1490 0 : Encoding |= 0x40000000;
1491 :
1492 : // Range Start
1493 0 : unsigned FDEEncoding = MOFI->getFDEEncoding();
1494 0 : unsigned Size = getSizeForEncoding(Streamer, FDEEncoding);
1495 0 : Streamer.EmitSymbolValue(Frame.Begin, Size);
1496 :
1497 : // Range Length
1498 0 : const MCExpr *Range = MakeStartMinusEndExpr(Streamer, *Frame.Begin,
1499 0 : *Frame.End, 0);
1500 0 : emitAbsValue(Streamer, Range, 4);
1501 :
1502 : // Compact Encoding
1503 0 : Size = getSizeForEncoding(Streamer, dwarf::DW_EH_PE_udata4);
1504 0 : Streamer.EmitIntValue(Encoding, Size);
1505 :
1506 : // Personality Function
1507 0 : Size = getSizeForEncoding(Streamer, dwarf::DW_EH_PE_absptr);
1508 0 : if (!DwarfEHFrameOnly && Frame.Personality)
1509 0 : Streamer.EmitSymbolValue(Frame.Personality, Size);
1510 : else
1511 0 : Streamer.EmitIntValue(0, Size); // No personality fn
1512 :
1513 : // LSDA
1514 0 : Size = getSizeForEncoding(Streamer, Frame.LsdaEncoding);
1515 0 : if (!DwarfEHFrameOnly && Frame.Lsda)
1516 0 : Streamer.EmitSymbolValue(Frame.Lsda, Size);
1517 : else
1518 0 : Streamer.EmitIntValue(0, Size); // No LSDA
1519 : }
1520 :
1521 : static unsigned getCIEVersion(bool IsEH, unsigned DwarfVersion) {
1522 9953 : if (IsEH)
1523 : return 1;
1524 : switch (DwarfVersion) {
1525 : case 2:
1526 : return 1;
1527 : case 3:
1528 : return 3;
1529 : case 4:
1530 : case 5:
1531 : return 4;
1532 : }
1533 0 : llvm_unreachable("Unknown version");
1534 : }
1535 :
1536 9953 : const MCSymbol &FrameEmitterImpl::EmitCIE(const MCDwarfFrameInfo &Frame) {
1537 9953 : MCContext &context = Streamer.getContext();
1538 9953 : const MCRegisterInfo *MRI = context.getRegisterInfo();
1539 9953 : const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
1540 :
1541 9953 : MCSymbol *sectionStart = context.createTempSymbol();
1542 9953 : Streamer.EmitLabel(sectionStart);
1543 :
1544 9953 : MCSymbol *sectionEnd = context.createTempSymbol();
1545 :
1546 : // Length
1547 : const MCExpr *Length =
1548 9953 : MakeStartMinusEndExpr(Streamer, *sectionStart, *sectionEnd, 4);
1549 9953 : emitAbsValue(Streamer, Length, 4);
1550 :
1551 : // CIE ID
1552 9953 : unsigned CIE_ID = IsEH ? 0 : -1;
1553 9953 : Streamer.EmitIntValue(CIE_ID, 4);
1554 :
1555 : // Version
1556 9953 : uint8_t CIEVersion = getCIEVersion(IsEH, context.getDwarfVersion());
1557 9953 : Streamer.EmitIntValue(CIEVersion, 1);
1558 :
1559 : // Augmentation String
1560 : SmallString<8> Augmentation;
1561 9953 : if (IsEH) {
1562 : Augmentation += "z";
1563 9856 : if (Frame.Personality)
1564 : Augmentation += "P";
1565 9856 : if (Frame.Lsda)
1566 : Augmentation += "L";
1567 : Augmentation += "R";
1568 9856 : if (Frame.IsSignalFrame)
1569 : Augmentation += "S";
1570 19712 : Streamer.EmitBytes(Augmentation);
1571 : }
1572 9953 : Streamer.EmitIntValue(0, 1);
1573 :
1574 9953 : if (CIEVersion >= 4) {
1575 : // Address Size
1576 79 : Streamer.EmitIntValue(context.getAsmInfo()->getCodePointerSize(), 1);
1577 :
1578 : // Segment Descriptor Size
1579 79 : Streamer.EmitIntValue(0, 1);
1580 : }
1581 :
1582 : // Code Alignment Factor
1583 9953 : Streamer.EmitULEB128IntValue(context.getAsmInfo()->getMinInstAlignment());
1584 :
1585 : // Data Alignment Factor
1586 19906 : Streamer.EmitSLEB128IntValue(getDataAlignmentFactor(Streamer));
1587 :
1588 : // Return Address Register
1589 9953 : unsigned RAReg = Frame.RAReg;
1590 9953 : if (RAReg == static_cast<unsigned>(INT_MAX))
1591 9951 : RAReg = MRI->getDwarfRegNum(MRI->getRARegister(), IsEH);
1592 :
1593 9953 : if (CIEVersion == 1) {
1594 : assert(RAReg <= 255 &&
1595 : "DWARF 2 encodes return_address_register in one byte");
1596 9868 : Streamer.EmitIntValue(RAReg, 1);
1597 : } else {
1598 85 : Streamer.EmitULEB128IntValue(RAReg);
1599 : }
1600 :
1601 : // Augmentation Data Length (optional)
1602 : unsigned augmentationLength = 0;
1603 9953 : if (IsEH) {
1604 9856 : if (Frame.Personality) {
1605 : // Personality Encoding
1606 : augmentationLength += 1;
1607 : // Personality
1608 3055 : augmentationLength +=
1609 3055 : getSizeForEncoding(Streamer, Frame.PersonalityEncoding);
1610 : }
1611 9856 : if (Frame.Lsda)
1612 3017 : augmentationLength += 1;
1613 : // Encoding of the FDE pointers
1614 9856 : augmentationLength += 1;
1615 :
1616 9856 : Streamer.EmitULEB128IntValue(augmentationLength);
1617 :
1618 : // Augmentation Data (optional)
1619 9856 : if (Frame.Personality) {
1620 : // Personality Encoding
1621 3055 : emitEncodingByte(Streamer, Frame.PersonalityEncoding);
1622 : // Personality
1623 3055 : EmitPersonality(Streamer, *Frame.Personality, Frame.PersonalityEncoding);
1624 : }
1625 :
1626 9856 : if (Frame.Lsda)
1627 3017 : emitEncodingByte(Streamer, Frame.LsdaEncoding);
1628 :
1629 : // Encoding of the FDE pointers
1630 9856 : emitEncodingByte(Streamer, MOFI->getFDEEncoding());
1631 : }
1632 :
1633 : // Initial Instructions
1634 :
1635 9953 : const MCAsmInfo *MAI = context.getAsmInfo();
1636 9953 : if (!Frame.IsSimple) {
1637 : const std::vector<MCCFIInstruction> &Instructions =
1638 : MAI->getInitialFrameState();
1639 9952 : EmitCFIInstructions(Instructions, nullptr);
1640 : }
1641 :
1642 9953 : InitialCFAOffset = CFAOffset;
1643 :
1644 : // Padding
1645 9953 : Streamer.EmitValueToAlignment(IsEH ? 4 : MAI->getCodePointerSize());
1646 :
1647 9953 : Streamer.EmitLabel(sectionEnd);
1648 9953 : return *sectionStart;
1649 : }
1650 :
1651 208063 : void FrameEmitterImpl::EmitFDE(const MCSymbol &cieStart,
1652 : const MCDwarfFrameInfo &frame,
1653 : bool LastInSection,
1654 : const MCSymbol &SectionStart) {
1655 208063 : MCContext &context = Streamer.getContext();
1656 208063 : MCSymbol *fdeStart = context.createTempSymbol();
1657 208063 : MCSymbol *fdeEnd = context.createTempSymbol();
1658 208063 : const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
1659 :
1660 208063 : CFAOffset = InitialCFAOffset;
1661 :
1662 : // Length
1663 208063 : const MCExpr *Length = MakeStartMinusEndExpr(Streamer, *fdeStart, *fdeEnd, 0);
1664 208063 : emitAbsValue(Streamer, Length, 4);
1665 :
1666 208063 : Streamer.EmitLabel(fdeStart);
1667 :
1668 : // CIE Pointer
1669 208063 : const MCAsmInfo *asmInfo = context.getAsmInfo();
1670 208063 : if (IsEH) {
1671 : const MCExpr *offset =
1672 207917 : MakeStartMinusEndExpr(Streamer, cieStart, *fdeStart, 0);
1673 207917 : emitAbsValue(Streamer, offset, 4);
1674 146 : } else if (!asmInfo->doesDwarfUseRelocationsAcrossSections()) {
1675 : const MCExpr *offset =
1676 34 : MakeStartMinusEndExpr(Streamer, SectionStart, cieStart, 0);
1677 34 : emitAbsValue(Streamer, offset, 4);
1678 : } else {
1679 112 : Streamer.EmitSymbolValue(&cieStart, 4);
1680 : }
1681 :
1682 : // PC Begin
1683 : unsigned PCEncoding =
1684 208063 : IsEH ? MOFI->getFDEEncoding() : (unsigned)dwarf::DW_EH_PE_absptr;
1685 208063 : unsigned PCSize = getSizeForEncoding(Streamer, PCEncoding);
1686 208063 : emitFDESymbol(Streamer, *frame.Begin, PCEncoding, IsEH);
1687 :
1688 : // PC Range
1689 : const MCExpr *Range =
1690 208063 : MakeStartMinusEndExpr(Streamer, *frame.Begin, *frame.End, 0);
1691 208063 : emitAbsValue(Streamer, Range, PCSize);
1692 :
1693 208063 : if (IsEH) {
1694 : // Augmentation Data Length
1695 : unsigned augmentationLength = 0;
1696 :
1697 207917 : if (frame.Lsda)
1698 46492 : augmentationLength += getSizeForEncoding(Streamer, frame.LsdaEncoding);
1699 :
1700 207917 : Streamer.EmitULEB128IntValue(augmentationLength);
1701 :
1702 : // Augmentation Data
1703 207917 : if (frame.Lsda)
1704 46492 : emitFDESymbol(Streamer, *frame.Lsda, frame.LsdaEncoding, true);
1705 : }
1706 :
1707 : // Call Frame Instructions
1708 416126 : EmitCFIInstructions(frame.Instructions, frame.Begin);
1709 :
1710 : // Padding
1711 : // The size of a .eh_frame section has to be a multiple of the alignment
1712 : // since a null CIE is interpreted as the end. Old systems overaligned
1713 : // .eh_frame, so we do too and account for it in the last FDE.
1714 208063 : unsigned Align = LastInSection ? asmInfo->getCodePointerSize() : PCSize;
1715 208063 : Streamer.EmitValueToAlignment(Align);
1716 :
1717 208063 : Streamer.EmitLabel(fdeEnd);
1718 208063 : }
1719 :
1720 : namespace {
1721 :
1722 : struct CIEKey {
1723 : static const CIEKey getEmptyKey() {
1724 : return CIEKey(nullptr, 0, -1, false, false, static_cast<unsigned>(INT_MAX));
1725 : }
1726 :
1727 : static const CIEKey getTombstoneKey() {
1728 : return CIEKey(nullptr, -1, 0, false, false, static_cast<unsigned>(INT_MAX));
1729 : }
1730 :
1731 : CIEKey(const MCSymbol *Personality, unsigned PersonalityEncoding,
1732 : unsigned LSDAEncoding, bool IsSignalFrame, bool IsSimple,
1733 : unsigned RAReg)
1734 : : Personality(Personality), PersonalityEncoding(PersonalityEncoding),
1735 : LsdaEncoding(LSDAEncoding), IsSignalFrame(IsSignalFrame),
1736 : IsSimple(IsSimple), RAReg(RAReg) {}
1737 :
1738 : explicit CIEKey(const MCDwarfFrameInfo &Frame)
1739 208063 : : Personality(Frame.Personality),
1740 208063 : PersonalityEncoding(Frame.PersonalityEncoding),
1741 416126 : LsdaEncoding(Frame.LsdaEncoding), IsSignalFrame(Frame.IsSignalFrame),
1742 832252 : IsSimple(Frame.IsSimple), RAReg(Frame.RAReg) {}
1743 :
1744 : const MCSymbol *Personality;
1745 : unsigned PersonalityEncoding;
1746 : unsigned LsdaEncoding;
1747 : bool IsSignalFrame;
1748 : bool IsSimple;
1749 : unsigned RAReg;
1750 : };
1751 :
1752 : } // end anonymous namespace
1753 :
1754 : namespace llvm {
1755 :
1756 : template <> struct DenseMapInfo<CIEKey> {
1757 : static CIEKey getEmptyKey() { return CIEKey::getEmptyKey(); }
1758 : static CIEKey getTombstoneKey() { return CIEKey::getTombstoneKey(); }
1759 :
1760 : static unsigned getHashValue(const CIEKey &Key) {
1761 : return static_cast<unsigned>(
1762 415834 : hash_combine(Key.Personality, Key.PersonalityEncoding, Key.LsdaEncoding,
1763 207917 : Key.IsSignalFrame, Key.IsSimple, Key.RAReg));
1764 : }
1765 :
1766 : static bool isEqual(const CIEKey &LHS, const CIEKey &RHS) {
1767 210989 : return LHS.Personality == RHS.Personality &&
1768 215215 : LHS.PersonalityEncoding == RHS.PersonalityEncoding &&
1769 : LHS.LsdaEncoding == RHS.LsdaEncoding &&
1770 : LHS.IsSignalFrame == RHS.IsSignalFrame &&
1771 430298 : LHS.IsSimple == RHS.IsSimple &&
1772 : LHS.RAReg == RHS.RAReg;
1773 : }
1774 : };
1775 :
1776 : } // end namespace llvm
1777 :
1778 6992 : void MCDwarfFrameEmitter::Emit(MCObjectStreamer &Streamer, MCAsmBackend *MAB,
1779 : bool IsEH) {
1780 6992 : Streamer.generateCompactUnwindEncodings(MAB);
1781 :
1782 6992 : MCContext &Context = Streamer.getContext();
1783 6992 : const MCObjectFileInfo *MOFI = Context.getObjectFileInfo();
1784 6992 : const MCAsmInfo *AsmInfo = Context.getAsmInfo();
1785 : FrameEmitterImpl Emitter(IsEH, Streamer);
1786 : ArrayRef<MCDwarfFrameInfo> FrameArray = Streamer.getDwarfFrameInfos();
1787 :
1788 : // Emit the compact unwind info if available.
1789 6992 : bool NeedsEHFrameSection = !MOFI->getSupportsCompactUnwindWithoutEHFrame();
1790 6992 : if (IsEH && MOFI->getCompactUnwindSection()) {
1791 : bool SectionEmitted = false;
1792 199 : for (const MCDwarfFrameInfo &Frame : FrameArray) {
1793 125 : if (Frame.CompactUnwindEncoding == 0) continue;
1794 79 : if (!SectionEmitted) {
1795 50 : Streamer.SwitchSection(MOFI->getCompactUnwindSection());
1796 50 : Streamer.EmitValueToAlignment(AsmInfo->getCodePointerSize());
1797 : SectionEmitted = true;
1798 : }
1799 79 : NeedsEHFrameSection |=
1800 158 : Frame.CompactUnwindEncoding ==
1801 79 : MOFI->getCompactUnwindDwarfEHFrameOnly();
1802 79 : Emitter.EmitCompactUnwind(Frame);
1803 : }
1804 : }
1805 :
1806 6992 : if (!NeedsEHFrameSection) return;
1807 :
1808 : MCSection &Section =
1809 6887 : IsEH ? *const_cast<MCObjectFileInfo *>(MOFI)->getEHFrameSection()
1810 6984 : : *MOFI->getDwarfFrameSection();
1811 :
1812 6984 : Streamer.SwitchSection(&Section);
1813 6984 : MCSymbol *SectionStart = Context.createTempSymbol();
1814 6984 : Streamer.EmitLabel(SectionStart);
1815 :
1816 : DenseMap<CIEKey, const MCSymbol *> CIEStarts;
1817 :
1818 6984 : const MCSymbol *DummyDebugKey = nullptr;
1819 6984 : bool CanOmitDwarf = MOFI->getOmitDwarfIfHaveCompactUnwind();
1820 215054 : for (auto I = FrameArray.begin(), E = FrameArray.end(); I != E;) {
1821 : const MCDwarfFrameInfo &Frame = *I;
1822 208070 : ++I;
1823 208070 : if (CanOmitDwarf && Frame.CompactUnwindEncoding !=
1824 9 : MOFI->getCompactUnwindDwarfEHFrameOnly())
1825 : // Don't generate an EH frame if we don't need one. I.e., it's taken care
1826 : // of by the compact unwind encoding.
1827 7 : continue;
1828 :
1829 : CIEKey Key(Frame);
1830 208063 : const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey;
1831 208063 : if (!CIEStart)
1832 9953 : CIEStart = &Emitter.EmitCIE(Frame);
1833 :
1834 208063 : Emitter.EmitFDE(*CIEStart, Frame, I == E, *SectionStart);
1835 : }
1836 : }
1837 :
1838 348 : void MCDwarfFrameEmitter::EmitAdvanceLoc(MCObjectStreamer &Streamer,
1839 : uint64_t AddrDelta) {
1840 348 : MCContext &Context = Streamer.getContext();
1841 : SmallString<256> Tmp;
1842 : raw_svector_ostream OS(Tmp);
1843 348 : MCDwarfFrameEmitter::EncodeAdvanceLoc(Context, AddrDelta, OS);
1844 696 : Streamer.EmitBytes(OS.str());
1845 348 : }
1846 :
1847 2909148 : void MCDwarfFrameEmitter::EncodeAdvanceLoc(MCContext &Context,
1848 : uint64_t AddrDelta,
1849 : raw_ostream &OS) {
1850 : // Scale the address delta by the minimum instruction length.
1851 : AddrDelta = ScaleAddrDelta(Context, AddrDelta);
1852 :
1853 : support::endianness E =
1854 2909148 : Context.getAsmInfo()->isLittleEndian() ? support::little : support::big;
1855 2909148 : if (AddrDelta == 0) {
1856 : } else if (isUIntN(6, AddrDelta)) {
1857 1873662 : uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;
1858 1873662 : OS << Opcode;
1859 357560 : } else if (isUInt<8>(AddrDelta)) {
1860 : OS << uint8_t(dwarf::DW_CFA_advance_loc1);
1861 166553 : OS << uint8_t(AddrDelta);
1862 191007 : } else if (isUInt<16>(AddrDelta)) {
1863 : OS << uint8_t(dwarf::DW_CFA_advance_loc2);
1864 381408 : support::endian::write<uint16_t>(OS, AddrDelta, E);
1865 : } else {
1866 : assert(isUInt<32>(AddrDelta));
1867 : OS << uint8_t(dwarf::DW_CFA_advance_loc4);
1868 606 : support::endian::write<uint32_t>(OS, AddrDelta, E);
1869 : }
1870 2909148 : }
|