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