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