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