LLVM API Documentation

MCDwarf.h
Go to the documentation of this file.
00001 //===- MCDwarf.h - Machine Code Dwarf support -------------------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains the declaration of the MCDwarfFile to support the dwarf
00011 // .file directive and the .loc directive.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #ifndef LLVM_MC_MCDWARF_H
00016 #define LLVM_MC_MCDWARF_H
00017 
00018 #include "llvm/ADT/ArrayRef.h"
00019 #include "llvm/ADT/StringRef.h"
00020 #include "llvm/ADT/StringMap.h"
00021 #include "llvm/ADT/MapVector.h"
00022 #include "llvm/Support/Compiler.h"
00023 #include "llvm/Support/Dwarf.h"
00024 #include "llvm/Support/raw_ostream.h"
00025 #include <map>
00026 #include <vector>
00027 #include <string>
00028 #include <utility>
00029 
00030 namespace llvm {
00031 class MCAsmBackend;
00032 class MCContext;
00033 class MCSection;
00034 class MCStreamer;
00035 class MCSymbol;
00036 class SourceMgr;
00037 class SMLoc;
00038 
00039 /// MCDwarfFile - Instances of this class represent the name of the dwarf
00040 /// .file directive and its associated dwarf file number in the MC file,
00041 /// and MCDwarfFile's are created and unique'd by the MCContext class where
00042 /// the file number for each is its index into the vector of DwarfFiles (note
00043 /// index 0 is not used and not a valid dwarf file number).
00044 struct MCDwarfFile {
00045   // Name - the base name of the file without its directory path.
00046   // The StringRef references memory allocated in the MCContext.
00047   std::string Name;
00048 
00049   // DirIndex - the index into the list of directory names for this file name.
00050   unsigned DirIndex;
00051 };
00052 
00053 /// MCDwarfLoc - Instances of this class represent the information from a
00054 /// dwarf .loc directive.
00055 class MCDwarfLoc {
00056   // FileNum - the file number.
00057   unsigned FileNum;
00058   // Line - the line number.
00059   unsigned Line;
00060   // Column - the column position.
00061   unsigned Column;
00062   // Flags (see #define's below)
00063   unsigned Flags;
00064   // Isa
00065   unsigned Isa;
00066   // Discriminator
00067   unsigned Discriminator;
00068 
00069 // Flag that indicates the initial value of the is_stmt_start flag.
00070 #define DWARF2_LINE_DEFAULT_IS_STMT 1
00071 
00072 #define DWARF2_FLAG_IS_STMT (1 << 0)
00073 #define DWARF2_FLAG_BASIC_BLOCK (1 << 1)
00074 #define DWARF2_FLAG_PROLOGUE_END (1 << 2)
00075 #define DWARF2_FLAG_EPILOGUE_BEGIN (1 << 3)
00076 
00077 private: // MCContext manages these
00078   friend class MCContext;
00079   friend class MCLineEntry;
00080   MCDwarfLoc(unsigned fileNum, unsigned line, unsigned column, unsigned flags,
00081              unsigned isa, unsigned discriminator)
00082       : FileNum(fileNum), Line(line), Column(column), Flags(flags), Isa(isa),
00083         Discriminator(discriminator) {}
00084 
00085   // Allow the default copy constructor and assignment operator to be used
00086   // for an MCDwarfLoc object.
00087 
00088 public:
00089   /// getFileNum - Get the FileNum of this MCDwarfLoc.
00090   unsigned getFileNum() const { return FileNum; }
00091 
00092   /// getLine - Get the Line of this MCDwarfLoc.
00093   unsigned getLine() const { return Line; }
00094 
00095   /// getColumn - Get the Column of this MCDwarfLoc.
00096   unsigned getColumn() const { return Column; }
00097 
00098   /// getFlags - Get the Flags of this MCDwarfLoc.
00099   unsigned getFlags() const { return Flags; }
00100 
00101   /// getIsa - Get the Isa of this MCDwarfLoc.
00102   unsigned getIsa() const { return Isa; }
00103 
00104   /// getDiscriminator - Get the Discriminator of this MCDwarfLoc.
00105   unsigned getDiscriminator() const { return Discriminator; }
00106 
00107   /// setFileNum - Set the FileNum of this MCDwarfLoc.
00108   void setFileNum(unsigned fileNum) { FileNum = fileNum; }
00109 
00110   /// setLine - Set the Line of this MCDwarfLoc.
00111   void setLine(unsigned line) { Line = line; }
00112 
00113   /// setColumn - Set the Column of this MCDwarfLoc.
00114   void setColumn(unsigned column) { Column = column; }
00115 
00116   /// setFlags - Set the Flags of this MCDwarfLoc.
00117   void setFlags(unsigned flags) { Flags = flags; }
00118 
00119   /// setIsa - Set the Isa of this MCDwarfLoc.
00120   void setIsa(unsigned isa) { Isa = isa; }
00121 
00122   /// setDiscriminator - Set the Discriminator of this MCDwarfLoc.
00123   void setDiscriminator(unsigned discriminator) {
00124     Discriminator = discriminator;
00125   }
00126 };
00127 
00128 /// MCLineEntry - Instances of this class represent the line information for
00129 /// the dwarf line table entries.  Which is created after a machine
00130 /// instruction is assembled and uses an address from a temporary label
00131 /// created at the current address in the current section and the info from
00132 /// the last .loc directive seen as stored in the context.
00133 class MCLineEntry : public MCDwarfLoc {
00134   MCSymbol *Label;
00135 
00136 private:
00137   // Allow the default copy constructor and assignment operator to be used
00138   // for an MCLineEntry object.
00139 
00140 public:
00141   // Constructor to create an MCLineEntry given a symbol and the dwarf loc.
00142   MCLineEntry(MCSymbol *label, const MCDwarfLoc loc)
00143       : MCDwarfLoc(loc), Label(label) {}
00144 
00145   MCSymbol *getLabel() const { return Label; }
00146 
00147   // This is called when an instruction is assembled into the specified
00148   // section and if there is information from the last .loc directive that
00149   // has yet to have a line entry made for it is made.
00150   static void Make(MCStreamer *MCOS, const MCSection *Section);
00151 };
00152 
00153 /// MCLineSection - Instances of this class represent the line information
00154 /// for a compile unit where machine instructions have been assembled after seeing
00155 /// .loc directives.  This is the information used to build the dwarf line
00156 /// table for a section.
00157 class MCLineSection {
00158 public:
00159   // addLineEntry - adds an entry to this MCLineSection's line entries
00160   void addLineEntry(const MCLineEntry &LineEntry, const MCSection *Sec) {
00161     MCLineDivisions[Sec].push_back(LineEntry);
00162   }
00163 
00164   typedef std::vector<MCLineEntry> MCLineEntryCollection;
00165   typedef MCLineEntryCollection::iterator iterator;
00166   typedef MCLineEntryCollection::const_iterator const_iterator;
00167   typedef MapVector<const MCSection *, MCLineEntryCollection> MCLineDivisionMap;
00168 
00169 private:
00170   // A collection of MCLineEntry for each section.
00171   MCLineDivisionMap MCLineDivisions;
00172 
00173 public:
00174   // Returns the collection of MCLineEntry for a given Compile Unit ID.
00175   const MCLineDivisionMap &getMCLineEntries() const {
00176     return MCLineDivisions;
00177   }
00178 };
00179 
00180 struct MCDwarfLineTableHeader {
00181   MCSymbol *Label;
00182   SmallVector<std::string, 3> MCDwarfDirs;
00183   SmallVector<MCDwarfFile, 3> MCDwarfFiles;
00184   StringMap<unsigned> SourceIdMap;
00185   StringRef CompilationDir;
00186 
00187   MCDwarfLineTableHeader() : Label(nullptr) {}
00188   unsigned getFile(StringRef &Directory, StringRef &FileName,
00189                    unsigned FileNumber = 0);
00190   std::pair<MCSymbol *, MCSymbol *> Emit(MCStreamer *MCOS) const;
00191   std::pair<MCSymbol *, MCSymbol *>
00192   Emit(MCStreamer *MCOS, ArrayRef<char> SpecialOpcodeLengths) const;
00193 };
00194 
00195 class MCDwarfDwoLineTable {
00196   MCDwarfLineTableHeader Header;
00197 public:
00198   void setCompilationDir(StringRef CompilationDir) {
00199     Header.CompilationDir = CompilationDir;
00200   }
00201   unsigned getFile(StringRef Directory, StringRef FileName) {
00202     return Header.getFile(Directory, FileName);
00203   }
00204   void Emit(MCStreamer &MCOS) const;
00205 };
00206 
00207 class MCDwarfLineTable {
00208   MCDwarfLineTableHeader Header;
00209   MCLineSection MCLineSections;
00210 
00211 public:
00212   // This emits the Dwarf file and the line tables for all Compile Units.
00213   static void Emit(MCStreamer *MCOS);
00214 
00215   // This emits the Dwarf file and the line tables for a given Compile Unit.
00216   void EmitCU(MCStreamer *MCOS) const;
00217 
00218   unsigned getFile(StringRef &Directory, StringRef &FileName,
00219                    unsigned FileNumber = 0);
00220 
00221   MCSymbol *getLabel() const {
00222     return Header.Label;
00223   }
00224 
00225   void setLabel(MCSymbol *Label) {
00226     Header.Label = Label;
00227   }
00228 
00229   void setCompilationDir(StringRef CompilationDir) {
00230     Header.CompilationDir = CompilationDir;
00231   }
00232 
00233   const SmallVectorImpl<std::string> &getMCDwarfDirs() const {
00234     return Header.MCDwarfDirs;
00235   }
00236 
00237   SmallVectorImpl<std::string> &getMCDwarfDirs() {
00238     return Header.MCDwarfDirs;
00239   }
00240 
00241   const SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() const {
00242     return Header.MCDwarfFiles;
00243   }
00244 
00245   SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() {
00246     return Header.MCDwarfFiles;
00247   }
00248 
00249   const MCLineSection &getMCLineSections() const {
00250     return MCLineSections;
00251   }
00252   MCLineSection &getMCLineSections() {
00253     return MCLineSections;
00254   }
00255 };
00256 
00257 class MCDwarfLineAddr {
00258 public:
00259   /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
00260   static void Encode(MCContext &Context, int64_t LineDelta, uint64_t AddrDelta,
00261                      raw_ostream &OS);
00262 
00263   /// Utility function to emit the encoding to a streamer.
00264   static void Emit(MCStreamer *MCOS, int64_t LineDelta, uint64_t AddrDelta);
00265 };
00266 
00267 class MCGenDwarfInfo {
00268 public:
00269   //
00270   // When generating dwarf for assembly source files this emits the Dwarf
00271   // sections.
00272   //
00273   static void Emit(MCStreamer *MCOS);
00274 };
00275 
00276 // When generating dwarf for assembly source files this is the info that is
00277 // needed to be gathered for each symbol that will have a dwarf label.
00278 class MCGenDwarfLabelEntry {
00279 private:
00280   // Name of the symbol without a leading underbar, if any.
00281   StringRef Name;
00282   // The dwarf file number this symbol is in.
00283   unsigned FileNumber;
00284   // The line number this symbol is at.
00285   unsigned LineNumber;
00286   // The low_pc for the dwarf label is taken from this symbol.
00287   MCSymbol *Label;
00288 
00289 public:
00290   MCGenDwarfLabelEntry(StringRef name, unsigned fileNumber, unsigned lineNumber,
00291                        MCSymbol *label)
00292       : Name(name), FileNumber(fileNumber), LineNumber(lineNumber),
00293         Label(label) {}
00294 
00295   StringRef getName() const { return Name; }
00296   unsigned getFileNumber() const { return FileNumber; }
00297   unsigned getLineNumber() const { return LineNumber; }
00298   MCSymbol *getLabel() const { return Label; }
00299 
00300   // This is called when label is created when we are generating dwarf for
00301   // assembly source files.
00302   static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr,
00303                    SMLoc &Loc);
00304 };
00305 
00306 class MCCFIInstruction {
00307 public:
00308   enum OpType {
00309     OpSameValue,
00310     OpRememberState,
00311     OpRestoreState,
00312     OpOffset,
00313     OpDefCfaRegister,
00314     OpDefCfaOffset,
00315     OpDefCfa,
00316     OpRelOffset,
00317     OpAdjustCfaOffset,
00318     OpEscape,
00319     OpRestore,
00320     OpUndefined,
00321     OpRegister,
00322     OpWindowSave
00323   };
00324 
00325 private:
00326   OpType Operation;
00327   MCSymbol *Label;
00328   unsigned Register;
00329   union {
00330     int Offset;
00331     unsigned Register2;
00332   };
00333   std::vector<char> Values;
00334 
00335   MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int O, StringRef V)
00336       : Operation(Op), Label(L), Register(R), Offset(O),
00337         Values(V.begin(), V.end()) {
00338     assert(Op != OpRegister);
00339   }
00340 
00341   MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R1, unsigned R2)
00342       : Operation(Op), Label(L), Register(R1), Register2(R2) {
00343     assert(Op == OpRegister);
00344   }
00345 
00346 public:
00347   /// \brief .cfi_def_cfa defines a rule for computing CFA as: take address from
00348   /// Register and add Offset to it.
00349   static MCCFIInstruction createDefCfa(MCSymbol *L, unsigned Register,
00350                                        int Offset) {
00351     return MCCFIInstruction(OpDefCfa, L, Register, -Offset, "");
00352   }
00353 
00354   /// \brief .cfi_def_cfa_register modifies a rule for computing CFA. From now
00355   /// on Register will be used instead of the old one. Offset remains the same.
00356   static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register) {
00357     return MCCFIInstruction(OpDefCfaRegister, L, Register, 0, "");
00358   }
00359 
00360   /// \brief .cfi_def_cfa_offset modifies a rule for computing CFA. Register
00361   /// remains the same, but offset is new. Note that it is the absolute offset
00362   /// that will be added to a defined register to the compute CFA address.
00363   static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset) {
00364     return MCCFIInstruction(OpDefCfaOffset, L, 0, -Offset, "");
00365   }
00366 
00367   /// \brief .cfi_adjust_cfa_offset Same as .cfi_def_cfa_offset, but
00368   /// Offset is a relative value that is added/subtracted from the previous
00369   /// offset.
00370   static MCCFIInstruction createAdjustCfaOffset(MCSymbol *L, int Adjustment) {
00371     return MCCFIInstruction(OpAdjustCfaOffset, L, 0, Adjustment, "");
00372   }
00373 
00374   /// \brief .cfi_offset Previous value of Register is saved at offset Offset
00375   /// from CFA.
00376   static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register,
00377                                        int Offset) {
00378     return MCCFIInstruction(OpOffset, L, Register, Offset, "");
00379   }
00380 
00381   /// \brief .cfi_rel_offset Previous value of Register is saved at offset
00382   /// Offset from the current CFA register. This is transformed to .cfi_offset
00383   /// using the known displacement of the CFA register from the CFA.
00384   static MCCFIInstruction createRelOffset(MCSymbol *L, unsigned Register,
00385                                           int Offset) {
00386     return MCCFIInstruction(OpRelOffset, L, Register, Offset, "");
00387   }
00388 
00389   /// \brief .cfi_register Previous value of Register1 is saved in
00390   /// register Register2.
00391   static MCCFIInstruction createRegister(MCSymbol *L, unsigned Register1,
00392                                          unsigned Register2) {
00393     return MCCFIInstruction(OpRegister, L, Register1, Register2);
00394   }
00395 
00396   /// \brief .cfi_window_save SPARC register window is saved.
00397   static MCCFIInstruction createWindowSave(MCSymbol *L) {
00398     return MCCFIInstruction(OpWindowSave, L, 0, 0, "");
00399   }
00400 
00401   /// \brief .cfi_restore says that the rule for Register is now the same as it
00402   /// was at the beginning of the function, after all initial instructions added
00403   /// by .cfi_startproc were executed.
00404   static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register) {
00405     return MCCFIInstruction(OpRestore, L, Register, 0, "");
00406   }
00407 
00408   /// \brief .cfi_undefined From now on the previous value of Register can't be
00409   /// restored anymore.
00410   static MCCFIInstruction createUndefined(MCSymbol *L, unsigned Register) {
00411     return MCCFIInstruction(OpUndefined, L, Register, 0, "");
00412   }
00413 
00414   /// \brief .cfi_same_value Current value of Register is the same as in the
00415   /// previous frame. I.e., no restoration is needed.
00416   static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register) {
00417     return MCCFIInstruction(OpSameValue, L, Register, 0, "");
00418   }
00419 
00420   /// \brief .cfi_remember_state Save all current rules for all registers.
00421   static MCCFIInstruction createRememberState(MCSymbol *L) {
00422     return MCCFIInstruction(OpRememberState, L, 0, 0, "");
00423   }
00424 
00425   /// \brief .cfi_restore_state Restore the previously saved state.
00426   static MCCFIInstruction createRestoreState(MCSymbol *L) {
00427     return MCCFIInstruction(OpRestoreState, L, 0, 0, "");
00428   }
00429 
00430   /// \brief .cfi_escape Allows the user to add arbitrary bytes to the unwind
00431   /// info.
00432   static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals) {
00433     return MCCFIInstruction(OpEscape, L, 0, 0, Vals);
00434   }
00435 
00436   OpType getOperation() const { return Operation; }
00437   MCSymbol *getLabel() const { return Label; }
00438 
00439   unsigned getRegister() const {
00440     assert(Operation == OpDefCfa || Operation == OpOffset ||
00441            Operation == OpRestore || Operation == OpUndefined ||
00442            Operation == OpSameValue || Operation == OpDefCfaRegister ||
00443            Operation == OpRelOffset || Operation == OpRegister);
00444     return Register;
00445   }
00446 
00447   unsigned getRegister2() const {
00448     assert(Operation == OpRegister);
00449     return Register2;
00450   }
00451 
00452   int getOffset() const {
00453     assert(Operation == OpDefCfa || Operation == OpOffset ||
00454            Operation == OpRelOffset || Operation == OpDefCfaOffset ||
00455            Operation == OpAdjustCfaOffset);
00456     return Offset;
00457   }
00458 
00459   const StringRef getValues() const {
00460     assert(Operation == OpEscape);
00461     return StringRef(&Values[0], Values.size());
00462   }
00463 };
00464 
00465 struct MCDwarfFrameInfo {
00466   MCDwarfFrameInfo()
00467     : Begin(nullptr), End(nullptr), Personality(nullptr), Lsda(nullptr),
00468       Function(nullptr), Instructions(), PersonalityEncoding(), LsdaEncoding(0),
00469       CompactUnwindEncoding(0), IsSignalFrame(false), IsSimple(false) {}
00470   MCSymbol *Begin;
00471   MCSymbol *End;
00472   const MCSymbol *Personality;
00473   const MCSymbol *Lsda;
00474   const MCSymbol *Function;
00475   std::vector<MCCFIInstruction> Instructions;
00476   unsigned PersonalityEncoding;
00477   unsigned LsdaEncoding;
00478   uint32_t CompactUnwindEncoding;
00479   bool IsSignalFrame;
00480   bool IsSimple;
00481 };
00482 
00483 class MCDwarfFrameEmitter {
00484 public:
00485   //
00486   // This emits the frame info section.
00487   //
00488   static void Emit(MCStreamer &streamer, MCAsmBackend *MAB,
00489                    bool usingCFI, bool isEH);
00490   static void EmitAdvanceLoc(MCStreamer &Streamer, uint64_t AddrDelta);
00491   static void EncodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta,
00492                                raw_ostream &OS);
00493 };
00494 } // end namespace llvm
00495 
00496 #endif