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