Coverage Report

Created: 2019-02-20 07:29

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/MC/MCDwarf.h
Line
Count
Source (jump to first uncovered line)
1
//===- MCDwarf.h - Machine Code Dwarf support -------------------*- C++ -*-===//
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
// This file contains the declaration of the MCDwarfFile to support the dwarf
10
// .file directive and the .loc directive.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_MC_MCDWARF_H
15
#define LLVM_MC_MCDWARF_H
16
17
#include "llvm/ADT/MapVector.h"
18
#include "llvm/ADT/Optional.h"
19
#include "llvm/ADT/SmallVector.h"
20
#include "llvm/ADT/StringMap.h"
21
#include "llvm/ADT/StringRef.h"
22
#include "llvm/MC/MCSection.h"
23
#include "llvm/Support/Error.h"
24
#include "llvm/Support/MD5.h"
25
#include <cassert>
26
#include <cstdint>
27
#include <string>
28
#include <utility>
29
#include <vector>
30
31
namespace llvm {
32
33
template <typename T> class ArrayRef;
34
class MCAsmBackend;
35
class MCContext;
36
class MCDwarfLineStr;
37
class MCObjectStreamer;
38
class MCStreamer;
39
class MCSymbol;
40
class raw_ostream;
41
class SMLoc;
42
class SourceMgr;
43
44
/// Instances of this class represent the name of the dwarf
45
/// .file directive and its associated dwarf file number in the MC file,
46
/// and MCDwarfFile's are created and uniqued by the MCContext class where
47
/// the file number for each is its index into the vector of DwarfFiles (note
48
/// index 0 is not used and not a valid dwarf file number).
49
struct MCDwarfFile {
50
  // The base name of the file without its directory path.
51
  std::string Name;
52
53
  // The index into the list of directory names for this file name.
54
  unsigned DirIndex;
55
56
  /// The MD5 checksum, if there is one. Non-owning pointer to data allocated
57
  /// in MCContext.
58
  MD5::MD5Result *Checksum = nullptr;
59
60
  /// The source code of the file. Non-owning reference to data allocated in
61
  /// MCContext.
62
  Optional<StringRef> Source;
63
};
64
65
/// Instances of this class represent the information from a
66
/// dwarf .loc directive.
67
class MCDwarfLoc {
68
  uint32_t FileNum;
69
  uint32_t Line;
70
  uint16_t Column;
71
  // Flags (see #define's below)
72
  uint8_t Flags;
73
  uint8_t Isa;
74
  uint32_t Discriminator;
75
76
// Flag that indicates the initial value of the is_stmt_start flag.
77
5.94k
#define DWARF2_LINE_DEFAULT_IS_STMT 1
78
79
1.83M
#define DWARF2_FLAG_IS_STMT (1 << 0)
80
1.03M
#define DWARF2_FLAG_BASIC_BLOCK (1 << 1)
81
1.07M
#define DWARF2_FLAG_PROLOGUE_END (1 << 2)
82
1.03M
#define DWARF2_FLAG_EPILOGUE_BEGIN (1 << 3)
83
84
private: // MCContext manages these
85
  friend class MCContext;
86
  friend class MCDwarfLineEntry;
87
88
  MCDwarfLoc(unsigned fileNum, unsigned line, unsigned column, unsigned flags,
89
             unsigned isa, unsigned discriminator)
90
      : FileNum(fileNum), Line(line), Column(column), Flags(flags), Isa(isa),
91
95.9k
        Discriminator(discriminator) {}
92
93
  // Allow the default copy constructor and assignment operator to be used
94
  // for an MCDwarfLoc object.
95
96
public:
97
  /// Get the FileNum of this MCDwarfLoc.
98
1.31M
  unsigned getFileNum() const { return FileNum; }
99
100
  /// Get the Line of this MCDwarfLoc.
101
4.48M
  unsigned getLine() const { return Line; }
102
103
  /// Get the Column of this MCDwarfLoc.
104
1.94M
  unsigned getColumn() const { return Column; }
105
106
  /// Get the Flags of this MCDwarfLoc.
107
4.55M
  unsigned getFlags() const { return Flags; }
108
109
  /// Get the Isa of this MCDwarfLoc.
110
1.03M
  unsigned getIsa() const { return Isa; }
111
112
  /// Get the Discriminator of this MCDwarfLoc.
113
1.03M
  unsigned getDiscriminator() const { return Discriminator; }
114
115
  /// Set the FileNum of this MCDwarfLoc.
116
1.03M
  void setFileNum(unsigned fileNum) { FileNum = fileNum; }
117
118
  /// Set the Line of this MCDwarfLoc.
119
1.03M
  void setLine(unsigned line) { Line = line; }
120
121
  /// Set the Column of this MCDwarfLoc.
122
1.03M
  void setColumn(unsigned column) {
123
1.03M
    assert(column <= UINT16_MAX);
124
1.03M
    Column = column;
125
1.03M
  }
126
127
  /// Set the Flags of this MCDwarfLoc.
128
1.03M
  void setFlags(unsigned flags) {
129
1.03M
    assert(flags <= UINT8_MAX);
130
1.03M
    Flags = flags;
131
1.03M
  }
132
133
  /// Set the Isa of this MCDwarfLoc.
134
1.03M
  void setIsa(unsigned isa) {
135
1.03M
    assert(isa <= UINT8_MAX);
136
1.03M
    Isa = isa;
137
1.03M
  }
138
139
  /// Set the Discriminator of this MCDwarfLoc.
140
1.03M
  void setDiscriminator(unsigned discriminator) {
141
1.03M
    Discriminator = discriminator;
142
1.03M
  }
143
};
144
145
/// Instances of this class represent the line information for
146
/// the dwarf line table entries.  Which is created after a machine
147
/// instruction is assembled and uses an address from a temporary label
148
/// created at the current address in the current section and the info from
149
/// the last .loc directive seen as stored in the context.
150
class MCDwarfLineEntry : public MCDwarfLoc {
151
  MCSymbol *Label;
152
153
private:
154
  // Allow the default copy constructor and assignment operator to be used
155
  // for an MCDwarfLineEntry object.
156
157
public:
158
  // Constructor to create an MCDwarfLineEntry given a symbol and the dwarf loc.
159
  MCDwarfLineEntry(MCSymbol *label, const MCDwarfLoc loc)
160
1.03M
      : MCDwarfLoc(loc), Label(label) {}
161
162
1.03M
  MCSymbol *getLabel() const { return Label; }
163
164
  // This is called when an instruction is assembled into the specified
165
  // section and if there is information from the last .loc directive that
166
  // has yet to have a line entry made for it is made.
167
  static void Make(MCObjectStreamer *MCOS, MCSection *Section);
168
};
169
170
/// Instances of this class represent the line information for a compile
171
/// unit where machine instructions have been assembled after seeing .loc
172
/// directives.  This is the information used to build the dwarf line
173
/// table for a section.
174
class MCLineSection {
175
public:
176
  // Add an entry to this MCLineSection's line entries.
177
1.03M
  void addLineEntry(const MCDwarfLineEntry &LineEntry, MCSection *Sec) {
178
1.03M
    MCLineDivisions[Sec].push_back(LineEntry);
179
1.03M
  }
180
181
  using MCDwarfLineEntryCollection = std::vector<MCDwarfLineEntry>;
182
  using iterator = MCDwarfLineEntryCollection::iterator;
183
  using const_iterator = MCDwarfLineEntryCollection::const_iterator;
184
  using MCLineDivisionMap = MapVector<MCSection *, MCDwarfLineEntryCollection>;
185
186
private:
187
  // A collection of MCDwarfLineEntry for each section.
188
  MCLineDivisionMap MCLineDivisions;
189
190
public:
191
  // Returns the collection of MCDwarfLineEntry for a given Compile Unit ID.
192
2.31k
  const MCLineDivisionMap &getMCLineEntries() const {
193
2.31k
    return MCLineDivisions;
194
2.31k
  }
195
};
196
197
0
struct MCDwarfLineTableParams {
198
  /// First special line opcode - leave room for the standard opcodes.
199
  /// Note: If you want to change this, you'll have to update the
200
  /// "StandardOpcodeLengths" table that is emitted in
201
  /// \c Emit().
202
  uint8_t DWARF2LineOpcodeBase = 13;
203
  /// Minimum line offset in a special line info. opcode.  The value
204
  /// -5 was chosen to give a reasonable range of values.
205
  int8_t DWARF2LineBase = -5;
206
  /// Range of line offsets in a special line info. opcode.
207
  uint8_t DWARF2LineRange = 14;
208
};
209
210
struct MCDwarfLineTableHeader {
211
  MCSymbol *Label = nullptr;
212
  SmallVector<std::string, 3> MCDwarfDirs;
213
  SmallVector<MCDwarfFile, 3> MCDwarfFiles;
214
  StringMap<unsigned> SourceIdMap;
215
  std::string CompilationDir;
216
  MCDwarfFile RootFile;
217
  bool HasSource = false;
218
private:
219
  bool HasAllMD5 = true;
220
  bool HasAnyMD5 = false;
221
222
public:
223
36.4k
  MCDwarfLineTableHeader() = default;
224
225
  Expected<unsigned> tryGetFile(StringRef &Directory, StringRef &FileName,
226
                                MD5::MD5Result *Checksum,
227
                                Optional<StringRef> &Source,
228
                                unsigned FileNumber = 0);
229
  std::pair<MCSymbol *, MCSymbol *>
230
  Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
231
       Optional<MCDwarfLineStr> &LineStr) const;
232
  std::pair<MCSymbol *, MCSymbol *>
233
  Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
234
       ArrayRef<char> SpecialOpcodeLengths,
235
       Optional<MCDwarfLineStr> &LineStr) const;
236
1
  void resetMD5Usage() {
237
1
    HasAllMD5 = true;
238
1
    HasAnyMD5 = false;
239
1
  }
240
14.8k
  void trackMD5Usage(bool MD5Used) {
241
14.8k
    HasAllMD5 &= MD5Used;
242
14.8k
    HasAnyMD5 |= MD5Used;
243
14.8k
  }
244
141
  bool isMD5UsageConsistent() const {
245
141
    return MCDwarfFiles.empty() || 
(HasAllMD5 == HasAnyMD5)137
;
246
141
  }
247
248
private:
249
  void emitV2FileDirTables(MCStreamer *MCOS) const;
250
  void emitV5FileDirTables(MCStreamer *MCOS, Optional<MCDwarfLineStr> &LineStr,
251
                           StringRef CtxCompilationDir) const;
252
};
253
254
class MCDwarfDwoLineTable {
255
  MCDwarfLineTableHeader Header;
256
257
public:
258
  void maybeSetRootFile(StringRef Directory, StringRef FileName,
259
24
                        MD5::MD5Result *Checksum, Optional<StringRef> Source) {
260
24
    if (!Header.RootFile.Name.empty())
261
16
      return;
262
8
    Header.CompilationDir = Directory;
263
8
    Header.RootFile.Name = FileName;
264
8
    Header.RootFile.DirIndex = 0;
265
8
    Header.RootFile.Checksum = Checksum;
266
8
    Header.RootFile.Source = Source;
267
8
    Header.trackMD5Usage(Checksum);
268
8
    Header.HasSource = Source.hasValue();
269
8
  }
270
271
  unsigned getFile(StringRef Directory, StringRef FileName,
272
36
                   MD5::MD5Result *Checksum, Optional<StringRef> Source) {
273
36
    return cantFail(Header.tryGetFile(Directory, FileName, Checksum, Source));
274
36
  }
275
276
  void Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params,
277
            MCSection *Section) const;
278
};
279
280
class MCDwarfLineTable {
281
  MCDwarfLineTableHeader Header;
282
  MCLineSection MCLineSections;
283
284
public:
285
  // This emits the Dwarf file and the line tables for all Compile Units.
286
  static void Emit(MCObjectStreamer *MCOS, MCDwarfLineTableParams Params);
287
288
  // This emits the Dwarf file and the line tables for a given Compile Unit.
289
  void EmitCU(MCObjectStreamer *MCOS, MCDwarfLineTableParams Params,
290
              Optional<MCDwarfLineStr> &LineStr) const;
291
292
  Expected<unsigned> tryGetFile(StringRef &Directory, StringRef &FileName,
293
                                MD5::MD5Result *Checksum,
294
                                Optional<StringRef> Source,
295
                                unsigned FileNumber = 0);
296
  unsigned getFile(StringRef &Directory, StringRef &FileName,
297
                   MD5::MD5Result *Checksum, Optional<StringRef> &Source,
298
                   unsigned FileNumber = 0) {
299
    return cantFail(tryGetFile(Directory, FileName, Checksum, Source,
300
                               FileNumber));
301
  }
302
303
  void setRootFile(StringRef Directory, StringRef FileName,
304
2.17k
                   MD5::MD5Result *Checksum, Optional<StringRef> Source) {
305
2.17k
    Header.CompilationDir = Directory;
306
2.17k
    Header.RootFile.Name = FileName;
307
2.17k
    Header.RootFile.DirIndex = 0;
308
2.17k
    Header.RootFile.Checksum = Checksum;
309
2.17k
    Header.RootFile.Source = Source;
310
2.17k
    Header.trackMD5Usage(Checksum);
311
2.17k
    Header.HasSource = Source.hasValue();
312
2.17k
  }
313
314
1
  void resetRootFile() {
315
1
    assert(Header.MCDwarfFiles.empty());
316
1
    Header.RootFile.Name.clear();
317
1
    Header.resetMD5Usage();
318
1
    Header.HasSource = false;
319
1
  }
320
321
1
  bool hasRootFile() const { return !Header.RootFile.Name.empty(); }
322
323
  // Report whether MD5 usage has been consistent (all-or-none).
324
141
  bool isMD5UsageConsistent() const { return Header.isMD5UsageConsistent(); }
325
326
5.60k
  MCSymbol *getLabel() const {
327
5.60k
    return Header.Label;
328
5.60k
  }
329
330
2.58k
  void setLabel(MCSymbol *Label) {
331
2.58k
    Header.Label = Label;
332
2.58k
  }
333
334
0
  const SmallVectorImpl<std::string> &getMCDwarfDirs() const {
335
0
    return Header.MCDwarfDirs;
336
0
  }
337
338
2.37k
  SmallVectorImpl<std::string> &getMCDwarfDirs() {
339
2.37k
    return Header.MCDwarfDirs;
340
2.37k
  }
341
342
3.45k
  const SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() const {
343
3.45k
    return Header.MCDwarfFiles;
344
3.45k
  }
345
346
7.42k
  SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() {
347
7.42k
    return Header.MCDwarfFiles;
348
7.42k
  }
349
350
0
  const MCLineSection &getMCLineSections() const {
351
0
    return MCLineSections;
352
0
  }
353
1.03M
  MCLineSection &getMCLineSections() {
354
1.03M
    return MCLineSections;
355
1.03M
  }
356
};
357
358
class MCDwarfLineAddr {
359
public:
360
  /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
361
  static void Encode(MCContext &Context, MCDwarfLineTableParams Params,
362
                     int64_t LineDelta, uint64_t AddrDelta, raw_ostream &OS);
363
364
  /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas using
365
  /// fixed length operands.
366
  static bool FixedEncode(MCContext &Context,
367
                          MCDwarfLineTableParams Params,
368
                          int64_t LineDelta, uint64_t AddrDelta,
369
                          raw_ostream &OS, uint32_t *Offset, uint32_t *Size);
370
371
  /// Utility function to emit the encoding to a streamer.
372
  static void Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
373
                   int64_t LineDelta, uint64_t AddrDelta);
374
};
375
376
class MCGenDwarfInfo {
377
public:
378
  //
379
  // When generating dwarf for assembly source files this emits the Dwarf
380
  // sections.
381
  //
382
  static void Emit(MCStreamer *MCOS);
383
};
384
385
// When generating dwarf for assembly source files this is the info that is
386
// needed to be gathered for each symbol that will have a dwarf label.
387
class MCGenDwarfLabelEntry {
388
private:
389
  // Name of the symbol without a leading underbar, if any.
390
  StringRef Name;
391
  // The dwarf file number this symbol is in.
392
  unsigned FileNumber;
393
  // The line number this symbol is at.
394
  unsigned LineNumber;
395
  // The low_pc for the dwarf label is taken from this symbol.
396
  MCSymbol *Label;
397
398
public:
399
  MCGenDwarfLabelEntry(StringRef name, unsigned fileNumber, unsigned lineNumber,
400
                       MCSymbol *label)
401
      : Name(name), FileNumber(fileNumber), LineNumber(lineNumber),
402
121
        Label(label) {}
403
404
120
  StringRef getName() const { return Name; }
405
120
  unsigned getFileNumber() const { return FileNumber; }
406
120
  unsigned getLineNumber() const { return LineNumber; }
407
120
  MCSymbol *getLabel() const { return Label; }
408
409
  // This is called when label is created when we are generating dwarf for
410
  // assembly source files.
411
  static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr,
412
                   SMLoc &Loc);
413
};
414
415
class MCCFIInstruction {
416
public:
417
  enum OpType {
418
    OpSameValue,
419
    OpRememberState,
420
    OpRestoreState,
421
    OpOffset,
422
    OpDefCfaRegister,
423
    OpDefCfaOffset,
424
    OpDefCfa,
425
    OpRelOffset,
426
    OpAdjustCfaOffset,
427
    OpEscape,
428
    OpRestore,
429
    OpUndefined,
430
    OpRegister,
431
    OpWindowSave,
432
    OpNegateRAState,
433
    OpGnuArgsSize
434
  };
435
436
private:
437
  OpType Operation;
438
  MCSymbol *Label;
439
  unsigned Register;
440
  union {
441
    int Offset;
442
    unsigned Register2;
443
  };
444
  std::vector<char> Values;
445
446
  MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int O, StringRef V)
447
      : Operation(Op), Label(L), Register(R), Offset(O),
448
1.00M
        Values(V.begin(), V.end()) {
449
1.00M
    assert(Op != OpRegister);
450
1.00M
  }
451
452
  MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R1, unsigned R2)
453
911
      : Operation(Op), Label(L), Register(R1), Register2(R2) {
454
911
    assert(Op == OpRegister);
455
911
  }
456
457
public:
458
  /// .cfi_def_cfa defines a rule for computing CFA as: take address from
459
  /// Register and add Offset to it.
460
  static MCCFIInstruction createDefCfa(MCSymbol *L, unsigned Register,
461
128k
                                       int Offset) {
462
128k
    return MCCFIInstruction(OpDefCfa, L, Register, -Offset, "");
463
128k
  }
464
465
  /// .cfi_def_cfa_register modifies a rule for computing CFA. From now
466
  /// on Register will be used instead of the old one. Offset remains the same.
467
48.0k
  static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register) {
468
48.0k
    return MCCFIInstruction(OpDefCfaRegister, L, Register, 0, "");
469
48.0k
  }
470
471
  /// .cfi_def_cfa_offset modifies a rule for computing CFA. Register
472
  /// remains the same, but offset is new. Note that it is the absolute offset
473
  /// that will be added to a defined register to the compute CFA address.
474
95.3k
  static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset) {
475
95.3k
    return MCCFIInstruction(OpDefCfaOffset, L, 0, -Offset, "");
476
95.3k
  }
477
478
  /// .cfi_adjust_cfa_offset Same as .cfi_def_cfa_offset, but
479
  /// Offset is a relative value that is added/subtracted from the previous
480
  /// offset.
481
5.29k
  static MCCFIInstruction createAdjustCfaOffset(MCSymbol *L, int Adjustment) {
482
5.29k
    return MCCFIInstruction(OpAdjustCfaOffset, L, 0, Adjustment, "");
483
5.29k
  }
484
485
  /// .cfi_offset Previous value of Register is saved at offset Offset
486
  /// from CFA.
487
  static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register,
488
727k
                                       int Offset) {
489
727k
    return MCCFIInstruction(OpOffset, L, Register, Offset, "");
490
727k
  }
491
492
  /// .cfi_rel_offset Previous value of Register is saved at offset
493
  /// Offset from the current CFA register. This is transformed to .cfi_offset
494
  /// using the known displacement of the CFA register from the CFA.
495
  static MCCFIInstruction createRelOffset(MCSymbol *L, unsigned Register,
496
169
                                          int Offset) {
497
169
    return MCCFIInstruction(OpRelOffset, L, Register, Offset, "");
498
169
  }
499
500
  /// .cfi_register Previous value of Register1 is saved in
501
  /// register Register2.
502
  static MCCFIInstruction createRegister(MCSymbol *L, unsigned Register1,
503
911
                                         unsigned Register2) {
504
911
    return MCCFIInstruction(OpRegister, L, Register1, Register2);
505
911
  }
506
507
  /// .cfi_window_save SPARC register window is saved.
508
906
  static MCCFIInstruction createWindowSave(MCSymbol *L) {
509
906
    return MCCFIInstruction(OpWindowSave, L, 0, 0, "");
510
906
  }
511
512
  /// .cfi_negate_ra_state AArch64 negate RA state.
513
27
  static MCCFIInstruction createNegateRAState(MCSymbol *L) {
514
27
    return MCCFIInstruction(OpNegateRAState, L, 0, 0, "");
515
27
  }
516
517
  /// .cfi_restore says that the rule for Register is now the same as it
518
  /// was at the beginning of the function, after all initial instructions added
519
  /// by .cfi_startproc were executed.
520
170
  static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register) {
521
170
    return MCCFIInstruction(OpRestore, L, Register, 0, "");
522
170
  }
523
524
  /// .cfi_undefined From now on the previous value of Register can't be
525
  /// restored anymore.
526
2
  static MCCFIInstruction createUndefined(MCSymbol *L, unsigned Register) {
527
2
    return MCCFIInstruction(OpUndefined, L, Register, 0, "");
528
2
  }
529
530
  /// .cfi_same_value Current value of Register is the same as in the
531
  /// previous frame. I.e., no restoration is needed.
532
121
  static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register) {
533
121
    return MCCFIInstruction(OpSameValue, L, Register, 0, "");
534
121
  }
535
536
  /// .cfi_remember_state Save all current rules for all registers.
537
31
  static MCCFIInstruction createRememberState(MCSymbol *L) {
538
31
    return MCCFIInstruction(OpRememberState, L, 0, 0, "");
539
31
  }
540
541
  /// .cfi_restore_state Restore the previously saved state.
542
31
  static MCCFIInstruction createRestoreState(MCSymbol *L) {
543
31
    return MCCFIInstruction(OpRestoreState, L, 0, 0, "");
544
31
  }
545
546
  /// .cfi_escape Allows the user to add arbitrary bytes to the unwind
547
  /// info.
548
7
  static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals) {
549
7
    return MCCFIInstruction(OpEscape, L, 0, 0, Vals);
550
7
  }
551
552
  /// A special wrapper for .cfi_escape that indicates GNU_ARGS_SIZE
553
79
  static MCCFIInstruction createGnuArgsSize(MCSymbol *L, int Size) {
554
79
    return MCCFIInstruction(OpGnuArgsSize, L, 0, Size, "");
555
79
  }
556
557
1.44M
  OpType getOperation() const { return Operation; }
558
174k
  MCSymbol *getLabel() const { return Label; }
559
560
1.06M
  unsigned getRegister() const {
561
1.06M
    assert(Operation == OpDefCfa || Operation == OpOffset ||
562
1.06M
           Operation == OpRestore || Operation == OpUndefined ||
563
1.06M
           Operation == OpSameValue || Operation == OpDefCfaRegister ||
564
1.06M
           Operation == OpRelOffset || Operation == OpRegister);
565
1.06M
    return Register;
566
1.06M
  }
567
568
420
  unsigned getRegister2() const {
569
420
    assert(Operation == OpRegister);
570
420
    return Register2;
571
420
  }
572
573
608k
  int getOffset() const {
574
608k
    assert(Operation == OpDefCfa || Operation == OpOffset ||
575
608k
           Operation == OpRelOffset || Operation == OpDefCfaOffset ||
576
608k
           Operation == OpAdjustCfaOffset || Operation == OpGnuArgsSize);
577
608k
    return Offset;
578
608k
  }
579
580
9
  StringRef getValues() const {
581
9
    assert(Operation == OpEscape);
582
9
    return StringRef(&Values[0], Values.size());
583
9
  }
584
};
585
586
struct MCDwarfFrameInfo {
587
170k
  MCDwarfFrameInfo() = default;
588
589
  MCSymbol *Begin = nullptr;
590
  MCSymbol *End = nullptr;
591
  const MCSymbol *Personality = nullptr;
592
  const MCSymbol *Lsda = nullptr;
593
  std::vector<MCCFIInstruction> Instructions;
594
  unsigned CurrentCfaRegister = 0;
595
  unsigned PersonalityEncoding = 0;
596
  unsigned LsdaEncoding = 0;
597
  uint32_t CompactUnwindEncoding = 0;
598
  bool IsSignalFrame = false;
599
  bool IsSimple = false;
600
  unsigned RAReg = static_cast<unsigned>(INT_MAX);
601
  bool IsBKeyFrame = false;
602
};
603
604
class MCDwarfFrameEmitter {
605
public:
606
  //
607
  // This emits the frame info section.
608
  //
609
  static void Emit(MCObjectStreamer &streamer, MCAsmBackend *MAB, bool isEH);
610
  static void EmitAdvanceLoc(MCObjectStreamer &Streamer, uint64_t AddrDelta);
611
  static void EncodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta,
612
                               raw_ostream &OS);
613
};
614
615
} // end namespace llvm
616
617
#endif // LLVM_MC_MCDWARF_H