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