Line data Source code
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 54639 : 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 : #define DWARF2_LINE_DEFAULT_IS_STMT 1
79 :
80 : #define DWARF2_FLAG_IS_STMT (1 << 0)
81 : #define DWARF2_FLAG_BASIC_BLOCK (1 << 1)
82 : #define DWARF2_FLAG_PROLOGUE_END (1 << 2)
83 : #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 39963 : : FileNum(fileNum), Line(line), Column(column), Flags(flags), Isa(isa),
92 39963 : 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 0 : unsigned getFileNum() const { return FileNum; }
100 :
101 : /// Get the Line of this MCDwarfLoc.
102 0 : unsigned getLine() const { return Line; }
103 :
104 : /// Get the Column of this MCDwarfLoc.
105 620951 : unsigned getColumn() const { return Column; }
106 :
107 : /// Get the Flags of this MCDwarfLoc.
108 622437 : unsigned getFlags() const { return Flags; }
109 :
110 : /// Get the Isa of this MCDwarfLoc.
111 620951 : unsigned getIsa() const { return Isa; }
112 :
113 : /// Get the Discriminator of this MCDwarfLoc.
114 0 : unsigned getDiscriminator() const { return Discriminator; }
115 :
116 : /// Set the FileNum of this MCDwarfLoc.
117 622487 : void setFileNum(unsigned fileNum) { FileNum = fileNum; }
118 :
119 : /// Set the Line of this MCDwarfLoc.
120 622487 : void setLine(unsigned line) { Line = line; }
121 :
122 : /// Set the Column of this MCDwarfLoc.
123 0 : void setColumn(unsigned column) {
124 : assert(column <= UINT16_MAX);
125 622487 : Column = column;
126 0 : }
127 :
128 : /// Set the Flags of this MCDwarfLoc.
129 0 : void setFlags(unsigned flags) {
130 : assert(flags <= UINT8_MAX);
131 622487 : Flags = flags;
132 0 : }
133 :
134 : /// Set the Isa of this MCDwarfLoc.
135 0 : void setIsa(unsigned isa) {
136 : assert(isa <= UINT8_MAX);
137 622487 : Isa = isa;
138 0 : }
139 :
140 : /// Set the Discriminator of this MCDwarfLoc.
141 0 : void setDiscriminator(unsigned discriminator) {
142 622487 : Discriminator = discriminator;
143 0 : }
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 620951 : : MCDwarfLoc(loc), Label(label) {}
162 :
163 0 : 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 : void addLineEntry(const MCDwarfLineEntry &LineEntry, MCSection *Sec) {
179 620951 : MCLineDivisions[Sec].push_back(LineEntry);
180 : }
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 : const MCLineDivisionMap &getMCLineEntries() const {
194 : return MCLineDivisions;
195 : }
196 : };
197 :
198 35564 : 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 53964 : 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 0 : void resetMD5Usage() {
238 1 : HasAllMD5 = true;
239 1 : HasAnyMD5 = false;
240 0 : }
241 : void trackMD5Usage(bool MD5Used) {
242 8876 : HasAllMD5 &= MD5Used;
243 8876 : HasAnyMD5 |= MD5Used;
244 : }
245 : bool isMD5UsageConsistent() const {
246 138 : return MCDwarfFiles.empty() || (HasAllMD5 == HasAnyMD5);
247 : }
248 :
249 : private:
250 : void emitV2FileDirTables(MCStreamer *MCOS) const;
251 : void emitV5FileDirTables(MCStreamer *MCOS, Optional<MCDwarfLineStr> &LineStr,
252 : StringRef CtxCompilationDir) const;
253 : };
254 :
255 26844 : class MCDwarfDwoLineTable {
256 : MCDwarfLineTableHeader Header;
257 :
258 : public:
259 24 : void maybeSetRootFile(StringRef Directory, StringRef FileName,
260 : MD5::MD5Result *Checksum, Optional<StringRef> Source) {
261 24 : if (!Header.RootFile.Name.empty())
262 : return;
263 16 : Header.CompilationDir = Directory;
264 8 : Header.RootFile.Name = FileName;
265 8 : Header.RootFile.DirIndex = 0;
266 8 : Header.RootFile.Checksum = Checksum;
267 : Header.RootFile.Source = Source;
268 8 : Header.trackMD5Usage(Checksum);
269 8 : Header.HasSource = Source.hasValue();
270 : }
271 :
272 : unsigned getFile(StringRef Directory, StringRef FileName,
273 : MD5::MD5Result *Checksum, Optional<StringRef> Source) {
274 72 : return cantFail(Header.tryGetFile(Directory, FileName, Checksum, Source));
275 : }
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 1042 : void setRootFile(StringRef Directory, StringRef FileName,
305 : MD5::MD5Result *Checksum, Optional<StringRef> Source) {
306 2084 : Header.CompilationDir = Directory;
307 1042 : Header.RootFile.Name = FileName;
308 1041 : Header.RootFile.DirIndex = 0;
309 1041 : Header.RootFile.Checksum = Checksum;
310 : Header.RootFile.Source = Source;
311 1041 : Header.trackMD5Usage(Checksum);
312 1041 : Header.HasSource = Source.hasValue();
313 1041 : }
314 :
315 : void resetRootFile() {
316 : assert(Header.MCDwarfFiles.empty());
317 : Header.RootFile.Name.clear();
318 : Header.resetMD5Usage();
319 1 : Header.HasSource = false;
320 : }
321 :
322 : bool hasRootFile() const { return !Header.RootFile.Name.empty(); }
323 :
324 : // Report whether MD5 usage has been consistent (all-or-none).
325 : bool isMD5UsageConsistent() const { return Header.isMD5UsageConsistent(); }
326 :
327 0 : MCSymbol *getLabel() const {
328 0 : return Header.Label;
329 : }
330 :
331 0 : void setLabel(MCSymbol *Label) {
332 1362 : Header.Label = Label;
333 0 : }
334 :
335 : const SmallVectorImpl<std::string> &getMCDwarfDirs() const {
336 : return Header.MCDwarfDirs;
337 : }
338 :
339 : SmallVectorImpl<std::string> &getMCDwarfDirs() {
340 : return Header.MCDwarfDirs;
341 : }
342 :
343 : const SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() const {
344 : return Header.MCDwarfFiles;
345 : }
346 :
347 : SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() {
348 : return Header.MCDwarfFiles;
349 : }
350 :
351 : const MCLineSection &getMCLineSections() const {
352 : return MCLineSections;
353 : }
354 : MCLineSection &getMCLineSections() {
355 : return MCLineSections;
356 : }
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 50 : : Name(name), FileNumber(fileNumber), LineNumber(lineNumber),
403 50 : Label(label) {}
404 :
405 0 : StringRef getName() const { return Name; }
406 0 : unsigned getFileNumber() const { return FileNumber; }
407 0 : unsigned getLineNumber() const { return LineNumber; }
408 0 : 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 7974883 : 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 1084167 : Values(V.begin(), V.end()) {
449 : assert(Op != OpRegister);
450 : }
451 :
452 : MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R1, unsigned R2)
453 908 : : Operation(Op), Label(L), Register(R1), Register2(R2) {
454 : assert(Op == OpRegister);
455 : }
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 : int Offset) {
462 432735 : return MCCFIInstruction(OpDefCfa, L, Register, -Offset, "");
463 : }
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 : static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register) {
468 : return MCCFIInstruction(OpDefCfaRegister, L, Register, 0, "");
469 : }
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 : static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset) {
475 543597 : return MCCFIInstruction(OpDefCfaOffset, L, 0, -Offset, "");
476 : }
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 : static MCCFIInstruction createAdjustCfaOffset(MCSymbol *L, int Adjustment) {
482 : return MCCFIInstruction(OpAdjustCfaOffset, L, 0, Adjustment, "");
483 : }
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 : int Offset) {
489 : return MCCFIInstruction(OpOffset, L, Register, Offset, "");
490 : }
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 : int Offset) {
497 : return MCCFIInstruction(OpRelOffset, L, Register, Offset, "");
498 : }
499 :
500 : /// .cfi_register Previous value of Register1 is saved in
501 : /// register Register2.
502 : static MCCFIInstruction createRegister(MCSymbol *L, unsigned Register1,
503 : unsigned Register2) {
504 : return MCCFIInstruction(OpRegister, L, Register1, Register2);
505 : }
506 :
507 : /// .cfi_window_save SPARC register window is saved.
508 : static MCCFIInstruction createWindowSave(MCSymbol *L) {
509 : return MCCFIInstruction(OpWindowSave, L, 0, 0, "");
510 : }
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 : static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register) {
516 : return MCCFIInstruction(OpRestore, L, Register, 0, "");
517 : }
518 :
519 : /// .cfi_undefined From now on the previous value of Register can't be
520 : /// restored anymore.
521 : static MCCFIInstruction createUndefined(MCSymbol *L, unsigned Register) {
522 : return MCCFIInstruction(OpUndefined, L, Register, 0, "");
523 : }
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 : static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register) {
528 : return MCCFIInstruction(OpSameValue, L, Register, 0, "");
529 : }
530 :
531 : /// .cfi_remember_state Save all current rules for all registers.
532 : static MCCFIInstruction createRememberState(MCSymbol *L) {
533 : return MCCFIInstruction(OpRememberState, L, 0, 0, "");
534 : }
535 :
536 : /// .cfi_restore_state Restore the previously saved state.
537 : static MCCFIInstruction createRestoreState(MCSymbol *L) {
538 : return MCCFIInstruction(OpRestoreState, L, 0, 0, "");
539 : }
540 :
541 : /// .cfi_escape Allows the user to add arbitrary bytes to the unwind
542 : /// info.
543 : static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals) {
544 : return MCCFIInstruction(OpEscape, L, 0, 0, Vals);
545 : }
546 :
547 : /// A special wrapper for .cfi_escape that indicates GNU_ARGS_SIZE
548 : static MCCFIInstruction createGnuArgsSize(MCSymbol *L, int Size) {
549 : return MCCFIInstruction(OpGnuArgsSize, L, 0, Size, "");
550 : }
551 :
552 0 : OpType getOperation() const { return Operation; }
553 0 : MCSymbol *getLabel() const { return Label; }
554 :
555 0 : unsigned getRegister() const {
556 : assert(Operation == OpDefCfa || Operation == OpOffset ||
557 : Operation == OpRestore || Operation == OpUndefined ||
558 : Operation == OpSameValue || Operation == OpDefCfaRegister ||
559 : Operation == OpRelOffset || Operation == OpRegister);
560 0 : return Register;
561 : }
562 :
563 0 : unsigned getRegister2() const {
564 : assert(Operation == OpRegister);
565 0 : return Register2;
566 : }
567 :
568 0 : int getOffset() const {
569 : assert(Operation == OpDefCfa || Operation == OpOffset ||
570 : Operation == OpRelOffset || Operation == OpDefCfaOffset ||
571 : Operation == OpAdjustCfaOffset || Operation == OpGnuArgsSize);
572 0 : return Offset;
573 : }
574 :
575 : StringRef getValues() const {
576 : assert(Operation == OpEscape);
577 6 : return StringRef(&Values[0], Values.size());
578 : }
579 : };
580 :
581 1059153 : struct MCDwarfFrameInfo {
582 634226 : 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
|