Coverage Report

Created: 2018-07-19 03:59

/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
5.34k
#define DWARF2_LINE_DEFAULT_IS_STMT 1
79
80
1.86M
#define DWARF2_FLAG_IS_STMT (1 << 0)
81
1.05M
#define DWARF2_FLAG_BASIC_BLOCK (1 << 1)
82
1.09M
#define DWARF2_FLAG_PROLOGUE_END (1 << 2)
83
1.05M
#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
88.3k
        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.32M
  unsigned getFileNum() const { return FileNum; }
100
101
  /// Get the Line of this MCDwarfLoc.
102
4.62M
  unsigned getLine() const { return Line; }
103
104
  /// Get the Column of this MCDwarfLoc.
105
1.95M
  unsigned getColumn() const { return Column; }
106
107
  /// Get the Flags of this MCDwarfLoc.
108
4.63M
  unsigned getFlags() const { return Flags; }
109
110
  /// Get the Isa of this MCDwarfLoc.
111
1.05M
  unsigned getIsa() const { return Isa; }
112
113
  /// Get the Discriminator of this MCDwarfLoc.
114
1.05M
  unsigned getDiscriminator() const { return Discriminator; }
115
116
  /// Set the FileNum of this MCDwarfLoc.
117
1.05M
  void setFileNum(unsigned fileNum) { FileNum = fileNum; }
118
119
  /// Set the Line of this MCDwarfLoc.
120
1.05M
  void setLine(unsigned line) { Line = line; }
121
122
  /// Set the Column of this MCDwarfLoc.
123
1.05M
  void setColumn(unsigned column) {
124
1.05M
    assert(column <= UINT16_MAX);
125
1.05M
    Column = column;
126
1.05M
  }
127
128
  /// Set the Flags of this MCDwarfLoc.
129
1.05M
  void setFlags(unsigned flags) {
130
1.05M
    assert(flags <= UINT8_MAX);
131
1.05M
    Flags = flags;
132
1.05M
  }
133
134
  /// Set the Isa of this MCDwarfLoc.
135
1.05M
  void setIsa(unsigned isa) {
136
1.05M
    assert(isa <= UINT8_MAX);
137
1.05M
    Isa = isa;
138
1.05M
  }
139
140
  /// Set the Discriminator of this MCDwarfLoc.
141
1.05M
  void setDiscriminator(unsigned discriminator) {
142
1.05M
    Discriminator = discriminator;
143
1.05M
  }
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.05M
      : MCDwarfLoc(loc), Label(label) {}
162
163
1.05M
  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.05M
  void addLineEntry(const MCDwarfLineEntry &LineEntry, MCSection *Sec) {
179
1.05M
    MCLineDivisions[Sec].push_back(LineEntry);
180
1.05M
  }
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.36k
  const MCLineDivisionMap &getMCLineEntries() const {
194
2.36k
    return MCLineDivisions;
195
2.36k
  }
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
34.6k
  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
3
  void resetMD5Usage() {
238
3
    HasAllMD5 = true;
239
3
    HasAnyMD5 = false;
240
3
  }
241
14.9k
  void trackMD5Usage(bool MD5Used) {
242
14.9k
    HasAllMD5 &= MD5Used;
243
14.9k
    HasAnyMD5 |= MD5Used;
244
14.9k
  }
245
131
  bool isMD5UsageConsistent() const {
246
131
    return MCDwarfFiles.empty() || 
(HasAllMD5 == HasAnyMD5)129
;
247
131
  }
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.24k
                   MD5::MD5Result *Checksum, Optional<StringRef> Source) {
306
2.24k
    Header.CompilationDir = Directory;
307
2.24k
    Header.RootFile.Name = FileName;
308
2.24k
    Header.RootFile.DirIndex = 0;
309
2.24k
    Header.RootFile.Checksum = Checksum;
310
2.24k
    Header.RootFile.Source = Source;
311
2.24k
    Header.trackMD5Usage(Checksum);
312
2.24k
    Header.HasSource = Source.hasValue();
313
2.24k
  }
314
315
3
  void resetRootFile() {
316
3
    assert(Header.MCDwarfFiles.empty());
317
3
    Header.RootFile.Name.clear();
318
3
    Header.resetMD5Usage();
319
3
    Header.HasSource = false;
320
3
  }
321
322
1
  bool hasRootFile() const { return !Header.RootFile.Name.empty(); }
323
324
  // Report whether MD5 usage has been consistent (all-or-none).
325
131
  bool isMD5UsageConsistent() const { return Header.isMD5UsageConsistent(); }
326
327
5.41k
  MCSymbol *getLabel() const {
328
5.41k
    return Header.Label;
329
5.41k
  }
330
331
2.54k
  void setLabel(MCSymbol *Label) {
332
2.54k
    Header.Label = Label;
333
2.54k
  }
334
335
0
  const SmallVectorImpl<std::string> &getMCDwarfDirs() const {
336
0
    return Header.MCDwarfDirs;
337
0
  }
338
339
2.39k
  SmallVectorImpl<std::string> &getMCDwarfDirs() {
340
2.39k
    return Header.MCDwarfDirs;
341
2.39k
  }
342
343
3.49k
  const SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() const {
344
3.49k
    return Header.MCDwarfFiles;
345
3.49k
  }
346
347
6.45k
  SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() {
348
6.45k
    return Header.MCDwarfFiles;
349
6.45k
  }
350
351
0
  const MCLineSection &getMCLineSections() const {
352
0
    return MCLineSections;
353
0
  }
354
1.05M
  MCLineSection &getMCLineSections() {
355
1.05M
    return MCLineSections;
356
1.05M
  }
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 emit the encoding to a streamer.
366
  static void Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
367
                   int64_t LineDelta, uint64_t AddrDelta);
368
};
369
370
class MCGenDwarfInfo {
371
public:
372
  //
373
  // When generating dwarf for assembly source files this emits the Dwarf
374
  // sections.
375
  //
376
  static void Emit(MCStreamer *MCOS);
377
};
378
379
// When generating dwarf for assembly source files this is the info that is
380
// needed to be gathered for each symbol that will have a dwarf label.
381
class MCGenDwarfLabelEntry {
382
private:
383
  // Name of the symbol without a leading underbar, if any.
384
  StringRef Name;
385
  // The dwarf file number this symbol is in.
386
  unsigned FileNumber;
387
  // The line number this symbol is at.
388
  unsigned LineNumber;
389
  // The low_pc for the dwarf label is taken from this symbol.
390
  MCSymbol *Label;
391
392
public:
393
  MCGenDwarfLabelEntry(StringRef name, unsigned fileNumber, unsigned lineNumber,
394
                       MCSymbol *label)
395
      : Name(name), FileNumber(fileNumber), LineNumber(lineNumber),
396
78
        Label(label) {}
397
398
77
  StringRef getName() const { return Name; }
399
77
  unsigned getFileNumber() const { return FileNumber; }
400
77
  unsigned getLineNumber() const { return LineNumber; }
401
77
  MCSymbol *getLabel() const { return Label; }
402
403
  // This is called when label is created when we are generating dwarf for
404
  // assembly source files.
405
  static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr,
406
                   SMLoc &Loc);
407
};
408
409
class MCCFIInstruction {
410
public:
411
  enum OpType {
412
    OpSameValue,
413
    OpRememberState,
414
    OpRestoreState,
415
    OpOffset,
416
    OpDefCfaRegister,
417
    OpDefCfaOffset,
418
    OpDefCfa,
419
    OpRelOffset,
420
    OpAdjustCfaOffset,
421
    OpEscape,
422
    OpRestore,
423
    OpUndefined,
424
    OpRegister,
425
    OpWindowSave,
426
    OpGnuArgsSize
427
  };
428
429
private:
430
  OpType Operation;
431
  MCSymbol *Label;
432
  unsigned Register;
433
  union {
434
    int Offset;
435
    unsigned Register2;
436
  };
437
  std::vector<char> Values;
438
439
  MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int O, StringRef V)
440
      : Operation(Op), Label(L), Register(R), Offset(O),
441
965k
        Values(V.begin(), V.end()) {
442
965k
    assert(Op != OpRegister);
443
965k
  }
444
445
  MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R1, unsigned R2)
446
903
      : Operation(Op), Label(L), Register(R1), Register2(R2) {
447
903
    assert(Op == OpRegister);
448
903
  }
449
450
public:
451
  /// .cfi_def_cfa defines a rule for computing CFA as: take address from
452
  /// Register and add Offset to it.
453
  static MCCFIInstruction createDefCfa(MCSymbol *L, unsigned Register,
454
121k
                                       int Offset) {
455
121k
    return MCCFIInstruction(OpDefCfa, L, Register, -Offset, "");
456
121k
  }
457
458
  /// .cfi_def_cfa_register modifies a rule for computing CFA. From now
459
  /// on Register will be used instead of the old one. Offset remains the same.
460
52.1k
  static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register) {
461
52.1k
    return MCCFIInstruction(OpDefCfaRegister, L, Register, 0, "");
462
52.1k
  }
463
464
  /// .cfi_def_cfa_offset modifies a rule for computing CFA. Register
465
  /// remains the same, but offset is new. Note that it is the absolute offset
466
  /// that will be added to a defined register to the compute CFA address.
467
96.8k
  static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset) {
468
96.8k
    return MCCFIInstruction(OpDefCfaOffset, L, 0, -Offset, "");
469
96.8k
  }
470
471
  /// .cfi_adjust_cfa_offset Same as .cfi_def_cfa_offset, but
472
  /// Offset is a relative value that is added/subtracted from the previous
473
  /// offset.
474
5.34k
  static MCCFIInstruction createAdjustCfaOffset(MCSymbol *L, int Adjustment) {
475
5.34k
    return MCCFIInstruction(OpAdjustCfaOffset, L, 0, Adjustment, "");
476
5.34k
  }
477
478
  /// .cfi_offset Previous value of Register is saved at offset Offset
479
  /// from CFA.
480
  static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register,
481
688k
                                       int Offset) {
482
688k
    return MCCFIInstruction(OpOffset, L, Register, Offset, "");
483
688k
  }
484
485
  /// .cfi_rel_offset Previous value of Register is saved at offset
486
  /// Offset from the current CFA register. This is transformed to .cfi_offset
487
  /// using the known displacement of the CFA register from the CFA.
488
  static MCCFIInstruction createRelOffset(MCSymbol *L, unsigned Register,
489
169
                                          int Offset) {
490
169
    return MCCFIInstruction(OpRelOffset, L, Register, Offset, "");
491
169
  }
492
493
  /// .cfi_register Previous value of Register1 is saved in
494
  /// register Register2.
495
  static MCCFIInstruction createRegister(MCSymbol *L, unsigned Register1,
496
903
                                         unsigned Register2) {
497
903
    return MCCFIInstruction(OpRegister, L, Register1, Register2);
498
903
  }
499
500
  /// .cfi_window_save SPARC register window is saved.
501
902
  static MCCFIInstruction createWindowSave(MCSymbol *L) {
502
902
    return MCCFIInstruction(OpWindowSave, L, 0, 0, "");
503
902
  }
504
505
  /// .cfi_restore says that the rule for Register is now the same as it
506
  /// was at the beginning of the function, after all initial instructions added
507
  /// by .cfi_startproc were executed.
508
168
  static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register) {
509
168
    return MCCFIInstruction(OpRestore, L, Register, 0, "");
510
168
  }
511
512
  /// .cfi_undefined From now on the previous value of Register can't be
513
  /// restored anymore.
514
2
  static MCCFIInstruction createUndefined(MCSymbol *L, unsigned Register) {
515
2
    return MCCFIInstruction(OpUndefined, L, Register, 0, "");
516
2
  }
517
518
  /// .cfi_same_value Current value of Register is the same as in the
519
  /// previous frame. I.e., no restoration is needed.
520
121
  static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register) {
521
121
    return MCCFIInstruction(OpSameValue, L, Register, 0, "");
522
121
  }
523
524
  /// .cfi_remember_state Save all current rules for all registers.
525
31
  static MCCFIInstruction createRememberState(MCSymbol *L) {
526
31
    return MCCFIInstruction(OpRememberState, L, 0, 0, "");
527
31
  }
528
529
  /// .cfi_restore_state Restore the previously saved state.
530
31
  static MCCFIInstruction createRestoreState(MCSymbol *L) {
531
31
    return MCCFIInstruction(OpRestoreState, L, 0, 0, "");
532
31
  }
533
534
  /// .cfi_escape Allows the user to add arbitrary bytes to the unwind
535
  /// info.
536
3
  static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals) {
537
3
    return MCCFIInstruction(OpEscape, L, 0, 0, Vals);
538
3
  }
539
540
  /// A special wrapper for .cfi_escape that indicates GNU_ARGS_SIZE
541
76
  static MCCFIInstruction createGnuArgsSize(MCSymbol *L, int Size) {
542
76
    return MCCFIInstruction(OpGnuArgsSize, L, 0, Size, "");
543
76
  }
544
545
1.42M
  OpType getOperation() const { return Operation; }
546
174k
  MCSymbol *getLabel() const { return Label; }
547
548
1.03M
  unsigned getRegister() const {
549
1.03M
    assert(Operation == OpDefCfa || Operation == OpOffset ||
550
1.03M
           Operation == OpRestore || Operation == OpUndefined ||
551
1.03M
           Operation == OpSameValue || Operation == OpDefCfaRegister ||
552
1.03M
           Operation == OpRelOffset || Operation == OpRegister);
553
1.03M
    return Register;
554
1.03M
  }
555
556
414
  unsigned getRegister2() const {
557
414
    assert(Operation == OpRegister);
558
414
    return Register2;
559
414
  }
560
561
590k
  int getOffset() const {
562
590k
    assert(Operation == OpDefCfa || Operation == OpOffset ||
563
590k
           Operation == OpRelOffset || Operation == OpDefCfaOffset ||
564
590k
           Operation == OpAdjustCfaOffset || Operation == OpGnuArgsSize);
565
590k
    return Offset;
566
590k
  }
567
568
7
  StringRef getValues() const {
569
7
    assert(Operation == OpEscape);
570
7
    return StringRef(&Values[0], Values.size());
571
7
  }
572
};
573
574
struct MCDwarfFrameInfo {
575
170k
  MCDwarfFrameInfo() = default;
576
577
  MCSymbol *Begin = nullptr;
578
  MCSymbol *End = nullptr;
579
  const MCSymbol *Personality = nullptr;
580
  const MCSymbol *Lsda = nullptr;
581
  std::vector<MCCFIInstruction> Instructions;
582
  unsigned CurrentCfaRegister = 0;
583
  unsigned PersonalityEncoding = 0;
584
  unsigned LsdaEncoding = 0;
585
  uint32_t CompactUnwindEncoding = 0;
586
  bool IsSignalFrame = false;
587
  bool IsSimple = false;
588
  unsigned RAReg = static_cast<unsigned>(INT_MAX);
589
};
590
591
class MCDwarfFrameEmitter {
592
public:
593
  //
594
  // This emits the frame info section.
595
  //
596
  static void Emit(MCObjectStreamer &streamer, MCAsmBackend *MAB, bool isEH);
597
  static void EmitAdvanceLoc(MCObjectStreamer &Streamer, uint64_t AddrDelta);
598
  static void EncodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta,
599
                               raw_ostream &OS);
600
};
601
602
} // end namespace llvm
603
604
#endif // LLVM_MC_MCDWARF_H