Coverage Report

Created: 2018-11-15 01:24

/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.15k
#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
93.7k
        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.65M
  unsigned getLine() const { return Line; }
103
104
  /// Get the Column of this MCDwarfLoc.
105
1.99M
  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.42k
  const MCLineDivisionMap &getMCLineEntries() const {
194
2.42k
    return MCLineDivisions;
195
2.42k
  }
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
36.1k
  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.2k
  void trackMD5Usage(bool MD5Used) {
242
15.2k
    HasAllMD5 &= MD5Used;
243
15.2k
    HasAnyMD5 |= MD5Used;
244
15.2k
  }
245
138
  bool isMD5UsageConsistent() const {
246
138
    return MCDwarfFiles.empty() || 
(HasAllMD5 == HasAnyMD5)134
;
247
138
  }
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.29k
                   MD5::MD5Result *Checksum, Optional<StringRef> Source) {
306
2.29k
    Header.CompilationDir = Directory;
307
2.29k
    Header.RootFile.Name = FileName;
308
2.29k
    Header.RootFile.DirIndex = 0;
309
2.29k
    Header.RootFile.Checksum = Checksum;
310
2.29k
    Header.RootFile.Source = Source;
311
2.29k
    Header.trackMD5Usage(Checksum);
312
2.29k
    Header.HasSource = Source.hasValue();
313
2.29k
  }
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
138
  bool isMD5UsageConsistent() const { return Header.isMD5UsageConsistent(); }
326
327
5.56k
  MCSymbol *getLabel() const {
328
5.56k
    return Header.Label;
329
5.56k
  }
330
331
2.61k
  void setLabel(MCSymbol *Label) {
332
2.61k
    Header.Label = Label;
333
2.61k
  }
334
335
0
  const SmallVectorImpl<std::string> &getMCDwarfDirs() const {
336
0
    return Header.MCDwarfDirs;
337
0
  }
338
339
2.46k
  SmallVectorImpl<std::string> &getMCDwarfDirs() {
340
2.46k
    return Header.MCDwarfDirs;
341
2.46k
  }
342
343
3.62k
  const SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() const {
344
3.62k
    return Header.MCDwarfFiles;
345
3.62k
  }
346
347
6.87k
  SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() {
348
6.87k
    return Header.MCDwarfFiles;
349
6.87k
  }
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
112
        Label(label) {}
404
405
111
  StringRef getName() const { return Name; }
406
111
  unsigned getFileNumber() const { return FileNumber; }
407
111
  unsigned getLineNumber() const { return LineNumber; }
408
111
  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
991k
        Values(V.begin(), V.end()) {
449
991k
    assert(Op != OpRegister);
450
991k
  }
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
125k
                                       int Offset) {
462
125k
    return MCCFIInstruction(OpDefCfa, L, Register, -Offset, "");
463
125k
  }
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
52.4k
  static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register) {
468
52.4k
    return MCCFIInstruction(OpDefCfaRegister, L, Register, 0, "");
469
52.4k
  }
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
98.9k
  static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset) {
475
98.9k
    return MCCFIInstruction(OpDefCfaOffset, L, 0, -Offset, "");
476
98.9k
  }
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.43k
  static MCCFIInstruction createAdjustCfaOffset(MCSymbol *L, int Adjustment) {
482
5.43k
    return MCCFIInstruction(OpAdjustCfaOffset, L, 0, Adjustment, "");
483
5.43k
  }
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
707k
                                       int Offset) {
489
707k
    return MCCFIInstruction(OpOffset, L, Register, Offset, "");
490
707k
  }
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_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
170
  static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register) {
516
170
    return MCCFIInstruction(OpRestore, L, Register, 0, "");
517
170
  }
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.48M
  OpType getOperation() const { return Operation; }
553
180k
  MCSymbol *getLabel() const { return Label; }
554
555
1.07M
  unsigned getRegister() const {
556
1.07M
    assert(Operation == OpDefCfa || Operation == OpOffset ||
557
1.07M
           Operation == OpRestore || Operation == OpUndefined ||
558
1.07M
           Operation == OpSameValue || Operation == OpDefCfaRegister ||
559
1.07M
           Operation == OpRelOffset || Operation == OpRegister);
560
1.07M
    return Register;
561
1.07M
  }
562
563
420
  unsigned getRegister2() const {
564
420
    assert(Operation == OpRegister);
565
420
    return Register2;
566
420
  }
567
568
607k
  int getOffset() const {
569
607k
    assert(Operation == OpDefCfa || Operation == OpOffset ||
570
607k
           Operation == OpRelOffset || Operation == OpDefCfaOffset ||
571
607k
           Operation == OpAdjustCfaOffset || Operation == OpGnuArgsSize);
572
607k
    return Offset;
573
607k
  }
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
180k
  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