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