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