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; MCDwarfFile(StringRef name,unsigned dirIndex)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. getName()57 StringRef getName() const { return Name; } 58 59 /// getDirIndex - Get the dirIndex of this MCDwarfFile. getDirIndex()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; MCDwarfLoc(unsigned fileNum,unsigned line,unsigned column,unsigned flags,unsigned isa,unsigned discriminator)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. getFileNum()112 unsigned getFileNum() const { return FileNum; } 113 114 /// getLine - Get the Line of this MCDwarfLoc. getLine()115 unsigned getLine() const { return Line; } 116 117 /// getColumn - Get the Column of this MCDwarfLoc. getColumn()118 unsigned getColumn() const { return Column; } 119 120 /// getFlags - Get the Flags of this MCDwarfLoc. getFlags()121 unsigned getFlags() const { return Flags; } 122 123 /// getIsa - Get the Isa of this MCDwarfLoc. getIsa()124 unsigned getIsa() const { return Isa; } 125 126 /// getDiscriminator - Get the Discriminator of this MCDwarfLoc. getDiscriminator()127 unsigned getDiscriminator() const { return Discriminator; } 128 129 /// setFileNum - Set the FileNum of this MCDwarfLoc. setFileNum(unsigned fileNum)130 void setFileNum(unsigned fileNum) { FileNum = fileNum; } 131 132 /// setLine - Set the Line of this MCDwarfLoc. setLine(unsigned line)133 void setLine(unsigned line) { Line = line; } 134 135 /// setColumn - Set the Column of this MCDwarfLoc. setColumn(unsigned column)136 void setColumn(unsigned column) { Column = column; } 137 138 /// setFlags - Set the Flags of this MCDwarfLoc. setFlags(unsigned flags)139 void setFlags(unsigned flags) { Flags = flags; } 140 141 /// setIsa - Set the Isa of this MCDwarfLoc. setIsa(unsigned isa)142 void setIsa(unsigned isa) { Isa = isa; } 143 144 /// setDiscriminator - Set the Discriminator of this MCDwarfLoc. setDiscriminator(unsigned discriminator)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. MCLineEntry(MCSymbol * label,const MCDwarfLoc loc)164 MCLineEntry(MCSymbol *label, const MCDwarfLoc loc) : MCDwarfLoc(loc), 165 Label(label) {} 166 getLabel()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. MCLineSection()188 MCLineSection() {} 189 190 // addLineEntry - adds an entry to this MCLineSection's line entries addLineEntry(const MCLineEntry & LineEntry)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: getMCLineEntries()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: MCCFIInstruction(OpType Op,MCSymbol * L)240 MCCFIInstruction(OpType Op, MCSymbol *L) 241 : Operation(Op), Label(L) { 242 assert(Op == Remember || Op == Restore); 243 } MCCFIInstruction(OpType Op,MCSymbol * L,unsigned Register)244 MCCFIInstruction(OpType Op, MCSymbol *L, unsigned Register) 245 : Operation(Op), Label(L), Destination(Register) { 246 assert(Op == SameValue); 247 } MCCFIInstruction(MCSymbol * L,const MachineLocation & D,const MachineLocation & S)248 MCCFIInstruction(MCSymbol *L, const MachineLocation &D, 249 const MachineLocation &S) 250 : Operation(Move), Label(L), Destination(D), Source(S) { 251 } MCCFIInstruction(OpType Op,MCSymbol * L,const MachineLocation & D,const MachineLocation & S)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 } getOperation()257 OpType getOperation() const { return Operation; } getLabel()258 MCSymbol *getLabel() const { return Label; } getDestination()259 const MachineLocation &getDestination() const { return Destination; } getSource()260 const MachineLocation &getSource() const { return Source; } 261 }; 262 263 struct MCDwarfFrameInfo { MCDwarfFrameInfoMCDwarfFrameInfo264 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