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