Coverage Report

Created: 2019-07-24 05:18

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