Coverage Report

Created: 2018-09-23 16:00

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