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