LLVM API Documentation

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/StringRef.h"
00019 #include "llvm/Support/Compiler.h"
00020 #include "llvm/Support/Dwarf.h"
00021 #include "llvm/Support/raw_ostream.h"
00022 #include <map>
00023 #include <vector>
00024 
00025 namespace llvm {
00026   class MCContext;
00027   class MCObjectWriter;
00028   class MCSection;
00029   class MCStreamer;
00030   class MCSymbol;
00031   class SourceMgr;
00032   class SMLoc;
00033 
00034   /// MCDwarfFile - Instances of this class represent the name of the dwarf
00035   /// .file directive and its associated dwarf file number in the MC file,
00036   /// and MCDwarfFile's are created and unique'd by the MCContext class where
00037   /// the file number for each is its index into the vector of DwarfFiles (note
00038   /// index 0 is not used and not a valid dwarf file number).
00039   class MCDwarfFile {
00040     // Name - the base name of the file without its directory path.
00041     // The StringRef references memory allocated in the MCContext.
00042     StringRef Name;
00043 
00044     // DirIndex - the index into the list of directory names for this file name.
00045     unsigned DirIndex;
00046 
00047   private:  // MCContext creates and uniques these.
00048     friend class MCContext;
00049     MCDwarfFile(StringRef name, unsigned dirIndex)
00050       : Name(name), DirIndex(dirIndex) {}
00051 
00052     MCDwarfFile(const MCDwarfFile&) LLVM_DELETED_FUNCTION;
00053     void operator=(const MCDwarfFile&) LLVM_DELETED_FUNCTION;
00054   public:
00055     /// getName - Get the base name of this MCDwarfFile.
00056     StringRef getName() const { return Name; }
00057 
00058     /// getDirIndex - Get the dirIndex of this MCDwarfFile.
00059     unsigned getDirIndex() const { return DirIndex; }
00060 
00061 
00062     /// print - Print the value to the stream \p OS.
00063     void print(raw_ostream &OS) const;
00064 
00065     /// dump - Print the value to stderr.
00066     void dump() const;
00067   };
00068 
00069   inline raw_ostream &operator<<(raw_ostream &OS, const MCDwarfFile &DwarfFile){
00070     DwarfFile.print(OS);
00071     return OS;
00072   }
00073 
00074   /// MCDwarfLoc - Instances of this class represent the information from a
00075   /// dwarf .loc directive.
00076   class MCDwarfLoc {
00077     // FileNum - the file number.
00078     unsigned FileNum;
00079     // Line - the line number.
00080     unsigned Line;
00081     // Column - the column position.
00082     unsigned Column;
00083     // Flags (see #define's below)
00084     unsigned Flags;
00085     // Isa
00086     unsigned Isa;
00087     // Discriminator
00088     unsigned Discriminator;
00089 
00090 // Flag that indicates the initial value of the is_stmt_start flag.
00091 #define DWARF2_LINE_DEFAULT_IS_STMT     1
00092 
00093 #define DWARF2_FLAG_IS_STMT        (1 << 0)
00094 #define DWARF2_FLAG_BASIC_BLOCK    (1 << 1)
00095 #define DWARF2_FLAG_PROLOGUE_END   (1 << 2)
00096 #define DWARF2_FLAG_EPILOGUE_BEGIN (1 << 3)
00097 
00098   private:  // MCContext manages these
00099     friend class MCContext;
00100     friend class MCLineEntry;
00101     MCDwarfLoc(unsigned fileNum, unsigned line, unsigned column, unsigned flags,
00102                unsigned isa, unsigned discriminator)
00103       : FileNum(fileNum), Line(line), Column(column), Flags(flags), Isa(isa),
00104         Discriminator(discriminator) {}
00105 
00106     // Allow the default copy constructor and assignment operator to be used
00107     // for an MCDwarfLoc object.
00108 
00109   public:
00110     /// getFileNum - Get the FileNum of this MCDwarfLoc.
00111     unsigned getFileNum() const { return FileNum; }
00112 
00113     /// getLine - Get the Line of this MCDwarfLoc.
00114     unsigned getLine() const { return Line; }
00115 
00116     /// getColumn - Get the Column of this MCDwarfLoc.
00117     unsigned getColumn() const { return Column; }
00118 
00119     /// getFlags - Get the Flags of this MCDwarfLoc.
00120     unsigned getFlags() const { return Flags; }
00121 
00122     /// getIsa - Get the Isa of this MCDwarfLoc.
00123     unsigned getIsa() const { return Isa; }
00124 
00125     /// getDiscriminator - Get the Discriminator of this MCDwarfLoc.
00126     unsigned getDiscriminator() const { return Discriminator; }
00127 
00128     /// setFileNum - Set the FileNum of this MCDwarfLoc.
00129     void setFileNum(unsigned fileNum) { FileNum = fileNum; }
00130 
00131     /// setLine - Set the Line of this MCDwarfLoc.
00132     void setLine(unsigned line) { Line = line; }
00133 
00134     /// setColumn - Set the Column of this MCDwarfLoc.
00135     void setColumn(unsigned column) { Column = column; }
00136 
00137     /// setFlags - Set the Flags of this MCDwarfLoc.
00138     void setFlags(unsigned flags) { Flags = flags; }
00139 
00140     /// setIsa - Set the Isa of this MCDwarfLoc.
00141     void setIsa(unsigned isa) { Isa = isa; }
00142 
00143     /// setDiscriminator - Set the Discriminator of this MCDwarfLoc.
00144     void setDiscriminator(unsigned discriminator) {
00145       Discriminator = discriminator;
00146     }
00147   };
00148 
00149   /// MCLineEntry - Instances of this class represent the line information for
00150   /// the dwarf line table entries.  Which is created after a machine
00151   /// instruction is assembled and uses an address from a temporary label
00152   /// created at the current address in the current section and the info from
00153   /// the last .loc directive seen as stored in the context.
00154   class MCLineEntry : public MCDwarfLoc {
00155     MCSymbol *Label;
00156 
00157   private:
00158     // Allow the default copy constructor and assignment operator to be used
00159     // for an MCLineEntry object.
00160 
00161   public:
00162     // Constructor to create an MCLineEntry given a symbol and the dwarf loc.
00163     MCLineEntry(MCSymbol *label, const MCDwarfLoc loc) : MCDwarfLoc(loc),
00164                 Label(label) {}
00165 
00166     MCSymbol *getLabel() const { return Label; }
00167 
00168     // This is called when an instruction is assembled into the specified
00169     // section and if there is information from the last .loc directive that
00170     // has yet to have a line entry made for it is made.
00171     static void Make(MCStreamer *MCOS, const MCSection *Section);
00172   };
00173 
00174   /// MCLineSection - Instances of this class represent the line information
00175   /// for a section where machine instructions have been assembled after seeing
00176   /// .loc directives.  This is the information used to build the dwarf line
00177   /// table for a section.
00178   class MCLineSection {
00179 
00180   private:
00181     MCLineSection(const MCLineSection&) LLVM_DELETED_FUNCTION;
00182     void operator=(const MCLineSection&) LLVM_DELETED_FUNCTION;
00183 
00184   public:
00185     // Constructor to create an MCLineSection with an empty MCLineEntries
00186     // vector.
00187     MCLineSection() {}
00188 
00189     // addLineEntry - adds an entry to this MCLineSection's line entries
00190     void addLineEntry(const MCLineEntry &LineEntry, unsigned CUID) {
00191       MCLineDivisions[CUID].push_back(LineEntry);
00192     }
00193 
00194     typedef std::vector<MCLineEntry> MCLineEntryCollection;
00195     typedef MCLineEntryCollection::iterator iterator;
00196     typedef MCLineEntryCollection::const_iterator const_iterator;
00197     typedef std::map<unsigned, MCLineEntryCollection> MCLineDivisionMap;
00198 
00199   private:
00200     // A collection of MCLineEntry for each Compile Unit ID.
00201     MCLineDivisionMap MCLineDivisions;
00202 
00203   public:
00204     // Returns whether MCLineSection contains entries for a given Compile
00205     // Unit ID.
00206     bool containEntriesForID(unsigned CUID) const {
00207       return MCLineDivisions.count(CUID);
00208     }
00209     // Returns the collection of MCLineEntry for a given Compile Unit ID.
00210     const MCLineEntryCollection &getMCLineEntries(unsigned CUID) const {
00211       MCLineDivisionMap::const_iterator CIter = MCLineDivisions.find(CUID);
00212       assert(CIter != MCLineDivisions.end());
00213       return CIter->second;
00214     }
00215   };
00216 
00217   class MCDwarfFileTable {
00218   public:
00219     //
00220     // This emits the Dwarf file and the line tables for all Compile Units.
00221     //
00222     static const MCSymbol *Emit(MCStreamer *MCOS);
00223     //
00224     // This emits the Dwarf file and the line tables for a given Compile Unit.
00225     //
00226     static const MCSymbol *EmitCU(MCStreamer *MCOS, unsigned ID);
00227   };
00228 
00229   class MCDwarfLineAddr {
00230   public:
00231     /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
00232     static void Encode(int64_t LineDelta, uint64_t AddrDelta, raw_ostream &OS);
00233 
00234     /// Utility function to emit the encoding to a streamer.
00235     static void Emit(MCStreamer *MCOS,
00236                      int64_t LineDelta,uint64_t AddrDelta);
00237 
00238     /// Utility function to write the encoding to an object writer.
00239     static void Write(MCObjectWriter *OW,
00240                       int64_t LineDelta, uint64_t AddrDelta);
00241   };
00242 
00243   class MCGenDwarfInfo {
00244   public:
00245     //
00246     // When generating dwarf for assembly source files this emits the Dwarf
00247     // sections.
00248     //
00249     static void Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol);
00250   };
00251 
00252   // When generating dwarf for assembly source files this is the info that is
00253   // needed to be gathered for each symbol that will have a dwarf label.
00254   class MCGenDwarfLabelEntry {
00255   private:
00256     // Name of the symbol without a leading underbar, if any.
00257     StringRef Name;
00258     // The dwarf file number this symbol is in.
00259     unsigned FileNumber;
00260     // The line number this symbol is at.
00261     unsigned LineNumber;
00262     // The low_pc for the dwarf label is taken from this symbol.
00263     MCSymbol *Label;
00264 
00265   public:
00266     MCGenDwarfLabelEntry(StringRef name, unsigned fileNumber,
00267                          unsigned lineNumber, MCSymbol *label) :
00268       Name(name), FileNumber(fileNumber), LineNumber(lineNumber), Label(label){}
00269 
00270     StringRef getName() const { return Name; }
00271     unsigned getFileNumber() const { return FileNumber; }
00272     unsigned getLineNumber() const { return LineNumber; }
00273     MCSymbol *getLabel() const { return Label; }
00274 
00275     // This is called when label is created when we are generating dwarf for
00276     // assembly source files.
00277     static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr,
00278                      SMLoc &Loc);
00279   };
00280 
00281   class MCCFIInstruction {
00282   public:
00283     enum OpType { OpSameValue, OpRememberState, OpRestoreState, OpOffset,
00284                   OpDefCfaRegister, OpDefCfaOffset, OpDefCfa, OpRelOffset,
00285                   OpAdjustCfaOffset, OpEscape, OpRestore, OpUndefined,
00286                   OpRegister };
00287   private:
00288     OpType Operation;
00289     MCSymbol *Label;
00290     unsigned Register;
00291     union {
00292       int Offset;
00293       unsigned Register2;
00294     };
00295     std::vector<char> Values;
00296 
00297     MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int O, StringRef V) :
00298       Operation(Op), Label(L), Register(R), Offset(O),
00299       Values(V.begin(), V.end()) {
00300       assert(Op != OpRegister);
00301     }
00302 
00303     MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R1, unsigned R2) :
00304       Operation(Op), Label(L), Register(R1), Register2(R2) {
00305       assert(Op == OpRegister);
00306     }
00307 
00308   public:
00309     static MCCFIInstruction
00310     createOffset(MCSymbol *L, unsigned Register, int Offset) {
00311       return MCCFIInstruction(OpOffset, L, Register, Offset, "");
00312     }
00313 
00314     static MCCFIInstruction
00315     createDefCfaRegister(MCSymbol *L, unsigned Register) {
00316       return MCCFIInstruction(OpDefCfaRegister, L, Register, 0, "");
00317     }
00318 
00319     static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset) {
00320       return MCCFIInstruction(OpDefCfaOffset, L, 0, -Offset, "");
00321     }
00322 
00323     static MCCFIInstruction
00324     createDefCfa(MCSymbol *L, unsigned Register, int Offset) {
00325       return MCCFIInstruction(OpDefCfa, L, Register, -Offset, "");
00326     }
00327 
00328     static MCCFIInstruction createUndefined(MCSymbol *L, unsigned Register) {
00329       return MCCFIInstruction(OpUndefined, L, Register, 0, "");
00330     }
00331 
00332     static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register) {
00333       return MCCFIInstruction(OpRestore, L, Register, 0, "");
00334     }
00335 
00336     static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register) {
00337       return MCCFIInstruction(OpSameValue, L, Register, 0, "");
00338     }
00339 
00340     static MCCFIInstruction createRestoreState(MCSymbol *L) {
00341       return MCCFIInstruction(OpRestoreState, L, 0, 0, "");
00342     }
00343 
00344     static MCCFIInstruction createRememberState(MCSymbol *L) {
00345       return MCCFIInstruction(OpRememberState, L, 0, 0, "");
00346     }
00347 
00348     static MCCFIInstruction
00349     createRelOffset(MCSymbol *L, unsigned Register, int Offset) {
00350       return MCCFIInstruction(OpRelOffset, L, Register, Offset, "");
00351     }
00352 
00353     static MCCFIInstruction
00354     createAdjustCfaOffset(MCSymbol *L, int Adjustment) {
00355       return MCCFIInstruction(OpAdjustCfaOffset, L, 0, Adjustment, "");
00356     }
00357 
00358     static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals) {
00359       return MCCFIInstruction(OpEscape, L, 0, 0, Vals);
00360     }
00361 
00362    static MCCFIInstruction
00363    createRegister(MCSymbol *L, unsigned Register1, unsigned Register2) {
00364       return MCCFIInstruction(OpRegister, L, Register1, Register2);
00365     }
00366 
00367     OpType getOperation() const { return Operation; }
00368     MCSymbol *getLabel() const { return Label; }
00369 
00370     unsigned getRegister() const {
00371       assert(Operation == OpDefCfa || Operation == OpOffset ||
00372              Operation == OpRestore || Operation == OpUndefined ||
00373              Operation == OpSameValue || Operation == OpDefCfaRegister ||
00374              Operation == OpRelOffset || Operation == OpRegister);
00375       return Register;
00376     }
00377 
00378     unsigned getRegister2() const {
00379       assert(Operation == OpRegister);
00380       return Register2;
00381     }
00382 
00383     int getOffset() const {
00384       assert(Operation == OpDefCfa || Operation == OpOffset ||
00385              Operation == OpRelOffset || Operation == OpDefCfaOffset ||
00386              Operation == OpAdjustCfaOffset);
00387       return Offset;
00388     }
00389 
00390     const StringRef getValues() const {
00391       assert(Operation == OpEscape);
00392       return StringRef(&Values[0], Values.size());
00393     }
00394   };
00395 
00396   struct MCDwarfFrameInfo {
00397     MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0),
00398                          Function(0), Instructions(), PersonalityEncoding(),
00399                          LsdaEncoding(0), CompactUnwindEncoding(0),
00400                          IsSignalFrame(false) {}
00401     MCSymbol *Begin;
00402     MCSymbol *End;
00403     const MCSymbol *Personality;
00404     const MCSymbol *Lsda;
00405     const MCSymbol *Function;
00406     std::vector<MCCFIInstruction> Instructions;
00407     unsigned PersonalityEncoding;
00408     unsigned LsdaEncoding;
00409     uint32_t CompactUnwindEncoding;
00410     bool IsSignalFrame;
00411   };
00412 
00413   class MCDwarfFrameEmitter {
00414   public:
00415     //
00416     // This emits the frame info section.
00417     //
00418     static void Emit(MCStreamer &streamer, bool usingCFI,
00419                      bool isEH);
00420     static void EmitAdvanceLoc(MCStreamer &Streamer, uint64_t AddrDelta);
00421     static void EncodeAdvanceLoc(uint64_t AddrDelta, raw_ostream &OS);
00422   };
00423 } // end namespace llvm
00424 
00425 #endif