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/StringRef.h"
     19 #include "llvm/MC/MachineLocation.h"
     20 #include "llvm/MC/MCObjectWriter.h"
     21 #include "llvm/Support/raw_ostream.h"
     22 #include "llvm/Support/Dwarf.h"
     23 #include <vector>
     24 
     25 namespace llvm {
     26   class MCContext;
     27   class MCExpr;
     28   class MCSection;
     29   class MCSectionData;
     30   class MCStreamer;
     31   class MCSymbol;
     32   class MCObjectStreamer;
     33   class raw_ostream;
     34 
     35   /// MCDwarfFile - Instances of this class represent the name of the dwarf
     36   /// .file directive and its associated dwarf file number in the MC file,
     37   /// and MCDwarfFile's are created and unique'd by the MCContext class where
     38   /// the file number for each is its index into the vector of DwarfFiles (note
     39   /// index 0 is not used and not a valid dwarf file number).
     40   class MCDwarfFile {
     41     // Name - the base name of the file without its directory path.
     42     // The StringRef references memory allocated in the MCContext.
     43     StringRef Name;
     44 
     45     // DirIndex - the index into the list of directory names for this file name.
     46     unsigned DirIndex;
     47 
     48   private:  // MCContext creates and uniques these.
     49     friend class MCContext;
     50     MCDwarfFile(StringRef name, unsigned dirIndex)
     51       : Name(name), DirIndex(dirIndex) {}
     52 
     53     MCDwarfFile(const MCDwarfFile&);       // DO NOT IMPLEMENT
     54     void operator=(const MCDwarfFile&); // DO NOT IMPLEMENT
     55   public:
     56     /// getName - Get the base name of this MCDwarfFile.
     57     StringRef getName() const { return Name; }
     58 
     59     /// getDirIndex - Get the dirIndex of this MCDwarfFile.
     60     unsigned getDirIndex() const { return DirIndex; }
     61 
     62 
     63     /// print - Print the value to the stream \arg OS.
     64     void print(raw_ostream &OS) const;
     65 
     66     /// dump - Print the value to stderr.
     67     void dump() const;
     68   };
     69 
     70   inline raw_ostream &operator<<(raw_ostream &OS, const MCDwarfFile &DwarfFile){
     71     DwarfFile.print(OS);
     72     return OS;
     73   }
     74 
     75   /// MCDwarfLoc - Instances of this class represent the information from a
     76   /// dwarf .loc directive.
     77   class MCDwarfLoc {
     78     // FileNum - the file number.
     79     unsigned FileNum;
     80     // Line - the line number.
     81     unsigned Line;
     82     // Column - the column position.
     83     unsigned Column;
     84     // Flags (see #define's below)
     85     unsigned Flags;
     86     // Isa
     87     unsigned Isa;
     88     // Discriminator
     89     unsigned Discriminator;
     90 
     91 // Flag that indicates the initial value of the is_stmt_start flag.
     92 #define DWARF2_LINE_DEFAULT_IS_STMT     1
     93 
     94 #define DWARF2_FLAG_IS_STMT        (1 << 0)
     95 #define DWARF2_FLAG_BASIC_BLOCK    (1 << 1)
     96 #define DWARF2_FLAG_PROLOGUE_END   (1 << 2)
     97 #define DWARF2_FLAG_EPILOGUE_BEGIN (1 << 3)
     98 
     99   private:  // MCContext manages these
    100     friend class MCContext;
    101     friend class MCLineEntry;
    102     MCDwarfLoc(unsigned fileNum, unsigned line, unsigned column, unsigned flags,
    103                unsigned isa, unsigned discriminator)
    104       : FileNum(fileNum), Line(line), Column(column), Flags(flags), Isa(isa),
    105         Discriminator(discriminator) {}
    106 
    107     // Allow the default copy constructor and assignment operator to be used
    108     // for an MCDwarfLoc object.
    109 
    110   public:
    111     /// getFileNum - Get the FileNum of this MCDwarfLoc.
    112     unsigned getFileNum() const { return FileNum; }
    113 
    114     /// getLine - Get the Line of this MCDwarfLoc.
    115     unsigned getLine() const { return Line; }
    116 
    117     /// getColumn - Get the Column of this MCDwarfLoc.
    118     unsigned getColumn() const { return Column; }
    119 
    120     /// getFlags - Get the Flags of this MCDwarfLoc.
    121     unsigned getFlags() const { return Flags; }
    122 
    123     /// getIsa - Get the Isa of this MCDwarfLoc.
    124     unsigned getIsa() const { return Isa; }
    125 
    126     /// getDiscriminator - Get the Discriminator of this MCDwarfLoc.
    127     unsigned getDiscriminator() const { return Discriminator; }
    128 
    129     /// setFileNum - Set the FileNum of this MCDwarfLoc.
    130     void setFileNum(unsigned fileNum) { FileNum = fileNum; }
    131 
    132     /// setLine - Set the Line of this MCDwarfLoc.
    133     void setLine(unsigned line) { Line = line; }
    134 
    135     /// setColumn - Set the Column of this MCDwarfLoc.
    136     void setColumn(unsigned column) { Column = column; }
    137 
    138     /// setFlags - Set the Flags of this MCDwarfLoc.
    139     void setFlags(unsigned flags) { Flags = flags; }
    140 
    141     /// setIsa - Set the Isa of this MCDwarfLoc.
    142     void setIsa(unsigned isa) { Isa = isa; }
    143 
    144     /// setDiscriminator - Set the Discriminator of this MCDwarfLoc.
    145     void setDiscriminator(unsigned discriminator) {
    146       Discriminator = discriminator;
    147     }
    148   };
    149 
    150   /// MCLineEntry - Instances of this class represent the line information for
    151   /// the dwarf line table entries.  Which is created after a machine
    152   /// instruction is assembled and uses an address from a temporary label
    153   /// created at the current address in the current section and the info from
    154   /// the last .loc directive seen as stored in the context.
    155   class MCLineEntry : public MCDwarfLoc {
    156     MCSymbol *Label;
    157 
    158   private:
    159     // Allow the default copy constructor and assignment operator to be used
    160     // for an MCLineEntry object.
    161 
    162   public:
    163     // Constructor to create an MCLineEntry given a symbol and the dwarf loc.
    164     MCLineEntry(MCSymbol *label, const MCDwarfLoc loc) : MCDwarfLoc(loc),
    165                 Label(label) {}
    166 
    167     MCSymbol *getLabel() const { return Label; }
    168 
    169     // This is called when an instruction is assembled into the specified
    170     // section and if there is information from the last .loc directive that
    171     // has yet to have a line entry made for it is made.
    172     static void Make(MCStreamer *MCOS, const MCSection *Section);
    173   };
    174 
    175   /// MCLineSection - Instances of this class represent the line information
    176   /// for a section where machine instructions have been assembled after seeing
    177   /// .loc directives.  This is the information used to build the dwarf line
    178   /// table for a section.
    179   class MCLineSection {
    180 
    181   private:
    182     MCLineSection(const MCLineSection&);  // DO NOT IMPLEMENT
    183     void operator=(const MCLineSection&); // DO NOT IMPLEMENT
    184 
    185   public:
    186     // Constructor to create an MCLineSection with an empty MCLineEntries
    187     // vector.
    188     MCLineSection() {}
    189 
    190     // addLineEntry - adds an entry to this MCLineSection's line entries
    191     void addLineEntry(const MCLineEntry &LineEntry) {
    192       MCLineEntries.push_back(LineEntry);
    193     }
    194 
    195     typedef std::vector<MCLineEntry> MCLineEntryCollection;
    196     typedef MCLineEntryCollection::iterator iterator;
    197     typedef MCLineEntryCollection::const_iterator const_iterator;
    198 
    199   private:
    200     MCLineEntryCollection MCLineEntries;
    201 
    202   public:
    203     const MCLineEntryCollection *getMCLineEntries() const {
    204       return &MCLineEntries;
    205     }
    206   };
    207 
    208   class MCDwarfFileTable {
    209   public:
    210     //
    211     // This emits the Dwarf file and the line tables.
    212     //
    213     static void Emit(MCStreamer *MCOS);
    214   };
    215 
    216   class MCDwarfLineAddr {
    217   public:
    218     /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
    219     static void Encode(int64_t LineDelta, uint64_t AddrDelta, raw_ostream &OS);
    220 
    221     /// Utility function to emit the encoding to a streamer.
    222     static void Emit(MCStreamer *MCOS,
    223                      int64_t LineDelta,uint64_t AddrDelta);
    224 
    225     /// Utility function to write the encoding to an object writer.
    226     static void Write(MCObjectWriter *OW,
    227                       int64_t LineDelta, uint64_t AddrDelta);
    228   };
    229 
    230   class MCCFIInstruction {
    231   public:
    232     enum OpType { SameValue, Remember, Restore, Move, RelMove };
    233   private:
    234     OpType Operation;
    235     MCSymbol *Label;
    236     // Move to & from location.
    237     MachineLocation Destination;
    238     MachineLocation Source;
    239   public:
    240     MCCFIInstruction(OpType Op, MCSymbol *L)
    241       : Operation(Op), Label(L) {
    242       assert(Op == Remember || Op == Restore);
    243     }
    244     MCCFIInstruction(OpType Op, MCSymbol *L, unsigned Register)
    245       : Operation(Op), Label(L), Destination(Register) {
    246       assert(Op == SameValue);
    247     }
    248     MCCFIInstruction(MCSymbol *L, const MachineLocation &D,
    249                      const MachineLocation &S)
    250       : Operation(Move), Label(L), Destination(D), Source(S) {
    251     }
    252     MCCFIInstruction(OpType Op, MCSymbol *L, const MachineLocation &D,
    253                      const MachineLocation &S)
    254       : Operation(Op), Label(L), Destination(D), Source(S) {
    255       assert(Op == RelMove);
    256     }
    257     OpType getOperation() const { return Operation; }
    258     MCSymbol *getLabel() const { return Label; }
    259     const MachineLocation &getDestination() const { return Destination; }
    260     const MachineLocation &getSource() const { return Source; }
    261   };
    262 
    263   struct MCDwarfFrameInfo {
    264     MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0),
    265                          Function(0), Instructions(), PersonalityEncoding(),
    266                          LsdaEncoding(0), CompactUnwindEncoding(0) {}
    267     MCSymbol *Begin;
    268     MCSymbol *End;
    269     const MCSymbol *Personality;
    270     const MCSymbol *Lsda;
    271     const MCSymbol *Function;
    272     std::vector<MCCFIInstruction> Instructions;
    273     unsigned PersonalityEncoding;
    274     unsigned LsdaEncoding;
    275     uint32_t CompactUnwindEncoding;
    276   };
    277 
    278   class MCDwarfFrameEmitter {
    279   public:
    280     //
    281     // This emits the frame info section.
    282     //
    283     static void Emit(MCStreamer &streamer, bool usingCFI,
    284                      bool isEH);
    285     static void EmitAdvanceLoc(MCStreamer &Streamer, uint64_t AddrDelta);
    286     static void EncodeAdvanceLoc(uint64_t AddrDelta, raw_ostream &OS);
    287   };
    288 } // end namespace llvm
    289 
    290 #endif
    291