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