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