LLVM API Documentation
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/ArrayRef.h" 00019 #include "llvm/ADT/StringRef.h" 00020 #include "llvm/ADT/StringMap.h" 00021 #include "llvm/ADT/MapVector.h" 00022 #include "llvm/Support/Compiler.h" 00023 #include "llvm/Support/Dwarf.h" 00024 #include "llvm/Support/raw_ostream.h" 00025 #include <map> 00026 #include <vector> 00027 #include <string> 00028 #include <utility> 00029 00030 namespace llvm { 00031 class MCAsmBackend; 00032 class MCContext; 00033 class MCObjectStreamer; 00034 class MCSection; 00035 class MCStreamer; 00036 class MCSymbol; 00037 class SourceMgr; 00038 class SMLoc; 00039 00040 /// MCDwarfFile - Instances of this class represent the name of the dwarf 00041 /// .file directive and its associated dwarf file number in the MC file, 00042 /// and MCDwarfFile's are created and unique'd by the MCContext class where 00043 /// the file number for each is its index into the vector of DwarfFiles (note 00044 /// index 0 is not used and not a valid dwarf file number). 00045 struct MCDwarfFile { 00046 // Name - the base name of the file without its directory path. 00047 // The StringRef references memory allocated in the MCContext. 00048 std::string Name; 00049 00050 // DirIndex - the index into the list of directory names for this file name. 00051 unsigned DirIndex; 00052 }; 00053 00054 /// MCDwarfLoc - Instances of this class represent the information from a 00055 /// dwarf .loc directive. 00056 class MCDwarfLoc { 00057 // FileNum - the file number. 00058 unsigned FileNum; 00059 // Line - the line number. 00060 unsigned Line; 00061 // Column - the column position. 00062 unsigned Column; 00063 // Flags (see #define's below) 00064 unsigned Flags; 00065 // Isa 00066 unsigned Isa; 00067 // Discriminator 00068 unsigned Discriminator; 00069 00070 // Flag that indicates the initial value of the is_stmt_start flag. 00071 #define DWARF2_LINE_DEFAULT_IS_STMT 1 00072 00073 #define DWARF2_FLAG_IS_STMT (1 << 0) 00074 #define DWARF2_FLAG_BASIC_BLOCK (1 << 1) 00075 #define DWARF2_FLAG_PROLOGUE_END (1 << 2) 00076 #define DWARF2_FLAG_EPILOGUE_BEGIN (1 << 3) 00077 00078 private: // MCContext manages these 00079 friend class MCContext; 00080 friend class MCLineEntry; 00081 MCDwarfLoc(unsigned fileNum, unsigned line, unsigned column, unsigned flags, 00082 unsigned isa, unsigned discriminator) 00083 : FileNum(fileNum), Line(line), Column(column), Flags(flags), Isa(isa), 00084 Discriminator(discriminator) {} 00085 00086 // Allow the default copy constructor and assignment operator to be used 00087 // for an MCDwarfLoc object. 00088 00089 public: 00090 /// getFileNum - Get the FileNum of this MCDwarfLoc. 00091 unsigned getFileNum() const { return FileNum; } 00092 00093 /// getLine - Get the Line of this MCDwarfLoc. 00094 unsigned getLine() const { return Line; } 00095 00096 /// getColumn - Get the Column of this MCDwarfLoc. 00097 unsigned getColumn() const { return Column; } 00098 00099 /// getFlags - Get the Flags of this MCDwarfLoc. 00100 unsigned getFlags() const { return Flags; } 00101 00102 /// getIsa - Get the Isa of this MCDwarfLoc. 00103 unsigned getIsa() const { return Isa; } 00104 00105 /// getDiscriminator - Get the Discriminator of this MCDwarfLoc. 00106 unsigned getDiscriminator() const { return Discriminator; } 00107 00108 /// setFileNum - Set the FileNum of this MCDwarfLoc. 00109 void setFileNum(unsigned fileNum) { FileNum = fileNum; } 00110 00111 /// setLine - Set the Line of this MCDwarfLoc. 00112 void setLine(unsigned line) { Line = line; } 00113 00114 /// setColumn - Set the Column of this MCDwarfLoc. 00115 void setColumn(unsigned column) { Column = column; } 00116 00117 /// setFlags - Set the Flags of this MCDwarfLoc. 00118 void setFlags(unsigned flags) { Flags = flags; } 00119 00120 /// setIsa - Set the Isa of this MCDwarfLoc. 00121 void setIsa(unsigned isa) { Isa = isa; } 00122 00123 /// setDiscriminator - Set the Discriminator of this MCDwarfLoc. 00124 void setDiscriminator(unsigned discriminator) { 00125 Discriminator = discriminator; 00126 } 00127 }; 00128 00129 /// MCLineEntry - Instances of this class represent the line information for 00130 /// the dwarf line table entries. Which is created after a machine 00131 /// instruction is assembled and uses an address from a temporary label 00132 /// created at the current address in the current section and the info from 00133 /// the last .loc directive seen as stored in the context. 00134 class MCLineEntry : public MCDwarfLoc { 00135 MCSymbol *Label; 00136 00137 private: 00138 // Allow the default copy constructor and assignment operator to be used 00139 // for an MCLineEntry object. 00140 00141 public: 00142 // Constructor to create an MCLineEntry given a symbol and the dwarf loc. 00143 MCLineEntry(MCSymbol *label, const MCDwarfLoc loc) 00144 : MCDwarfLoc(loc), Label(label) {} 00145 00146 MCSymbol *getLabel() const { return Label; } 00147 00148 // This is called when an instruction is assembled into the specified 00149 // section and if there is information from the last .loc directive that 00150 // has yet to have a line entry made for it is made. 00151 static void Make(MCObjectStreamer *MCOS, const MCSection *Section); 00152 }; 00153 00154 /// MCLineSection - Instances of this class represent the line information 00155 /// for a compile unit where machine instructions have been assembled after seeing 00156 /// .loc directives. This is the information used to build the dwarf line 00157 /// table for a section. 00158 class MCLineSection { 00159 public: 00160 // addLineEntry - adds an entry to this MCLineSection's line entries 00161 void addLineEntry(const MCLineEntry &LineEntry, const MCSection *Sec) { 00162 MCLineDivisions[Sec].push_back(LineEntry); 00163 } 00164 00165 typedef std::vector<MCLineEntry> MCLineEntryCollection; 00166 typedef MCLineEntryCollection::iterator iterator; 00167 typedef MCLineEntryCollection::const_iterator const_iterator; 00168 typedef MapVector<const MCSection *, MCLineEntryCollection> MCLineDivisionMap; 00169 00170 private: 00171 // A collection of MCLineEntry for each section. 00172 MCLineDivisionMap MCLineDivisions; 00173 00174 public: 00175 // Returns the collection of MCLineEntry for a given Compile Unit ID. 00176 const MCLineDivisionMap &getMCLineEntries() const { 00177 return MCLineDivisions; 00178 } 00179 }; 00180 00181 struct MCDwarfLineTableHeader { 00182 MCSymbol *Label; 00183 SmallVector<std::string, 3> MCDwarfDirs; 00184 SmallVector<MCDwarfFile, 3> MCDwarfFiles; 00185 StringMap<unsigned> SourceIdMap; 00186 StringRef CompilationDir; 00187 00188 MCDwarfLineTableHeader() : Label(nullptr) {} 00189 unsigned getFile(StringRef &Directory, StringRef &FileName, 00190 unsigned FileNumber = 0); 00191 std::pair<MCSymbol *, MCSymbol *> Emit(MCStreamer *MCOS) const; 00192 std::pair<MCSymbol *, MCSymbol *> 00193 Emit(MCStreamer *MCOS, ArrayRef<char> SpecialOpcodeLengths) const; 00194 }; 00195 00196 class MCDwarfDwoLineTable { 00197 MCDwarfLineTableHeader Header; 00198 public: 00199 void setCompilationDir(StringRef CompilationDir) { 00200 Header.CompilationDir = CompilationDir; 00201 } 00202 unsigned getFile(StringRef Directory, StringRef FileName) { 00203 return Header.getFile(Directory, FileName); 00204 } 00205 void Emit(MCStreamer &MCOS) const; 00206 }; 00207 00208 class MCDwarfLineTable { 00209 MCDwarfLineTableHeader Header; 00210 MCLineSection MCLineSections; 00211 00212 public: 00213 // This emits the Dwarf file and the line tables for all Compile Units. 00214 static void Emit(MCObjectStreamer *MCOS); 00215 00216 // This emits the Dwarf file and the line tables for a given Compile Unit. 00217 void EmitCU(MCObjectStreamer *MCOS) const; 00218 00219 unsigned getFile(StringRef &Directory, StringRef &FileName, 00220 unsigned FileNumber = 0); 00221 00222 MCSymbol *getLabel() const { 00223 return Header.Label; 00224 } 00225 00226 void setLabel(MCSymbol *Label) { 00227 Header.Label = Label; 00228 } 00229 00230 void setCompilationDir(StringRef CompilationDir) { 00231 Header.CompilationDir = CompilationDir; 00232 } 00233 00234 const SmallVectorImpl<std::string> &getMCDwarfDirs() const { 00235 return Header.MCDwarfDirs; 00236 } 00237 00238 SmallVectorImpl<std::string> &getMCDwarfDirs() { 00239 return Header.MCDwarfDirs; 00240 } 00241 00242 const SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() const { 00243 return Header.MCDwarfFiles; 00244 } 00245 00246 SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() { 00247 return Header.MCDwarfFiles; 00248 } 00249 00250 const MCLineSection &getMCLineSections() const { 00251 return MCLineSections; 00252 } 00253 MCLineSection &getMCLineSections() { 00254 return MCLineSections; 00255 } 00256 }; 00257 00258 class MCDwarfLineAddr { 00259 public: 00260 /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas. 00261 static void Encode(MCContext &Context, int64_t LineDelta, uint64_t AddrDelta, 00262 raw_ostream &OS); 00263 00264 /// Utility function to emit the encoding to a streamer. 00265 static void Emit(MCStreamer *MCOS, int64_t LineDelta, uint64_t AddrDelta); 00266 }; 00267 00268 class MCGenDwarfInfo { 00269 public: 00270 // 00271 // When generating dwarf for assembly source files this emits the Dwarf 00272 // sections. 00273 // 00274 static void Emit(MCStreamer *MCOS); 00275 }; 00276 00277 // When generating dwarf for assembly source files this is the info that is 00278 // needed to be gathered for each symbol that will have a dwarf label. 00279 class MCGenDwarfLabelEntry { 00280 private: 00281 // Name of the symbol without a leading underbar, if any. 00282 StringRef Name; 00283 // The dwarf file number this symbol is in. 00284 unsigned FileNumber; 00285 // The line number this symbol is at. 00286 unsigned LineNumber; 00287 // The low_pc for the dwarf label is taken from this symbol. 00288 MCSymbol *Label; 00289 00290 public: 00291 MCGenDwarfLabelEntry(StringRef name, unsigned fileNumber, unsigned lineNumber, 00292 MCSymbol *label) 00293 : Name(name), FileNumber(fileNumber), LineNumber(lineNumber), 00294 Label(label) {} 00295 00296 StringRef getName() const { return Name; } 00297 unsigned getFileNumber() const { return FileNumber; } 00298 unsigned getLineNumber() const { return LineNumber; } 00299 MCSymbol *getLabel() const { return Label; } 00300 00301 // This is called when label is created when we are generating dwarf for 00302 // assembly source files. 00303 static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr, 00304 SMLoc &Loc); 00305 }; 00306 00307 class MCCFIInstruction { 00308 public: 00309 enum OpType { 00310 OpSameValue, 00311 OpRememberState, 00312 OpRestoreState, 00313 OpOffset, 00314 OpDefCfaRegister, 00315 OpDefCfaOffset, 00316 OpDefCfa, 00317 OpRelOffset, 00318 OpAdjustCfaOffset, 00319 OpEscape, 00320 OpRestore, 00321 OpUndefined, 00322 OpRegister, 00323 OpWindowSave 00324 }; 00325 00326 private: 00327 OpType Operation; 00328 MCSymbol *Label; 00329 unsigned Register; 00330 union { 00331 int Offset; 00332 unsigned Register2; 00333 }; 00334 std::vector<char> Values; 00335 00336 MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int O, StringRef V) 00337 : Operation(Op), Label(L), Register(R), Offset(O), 00338 Values(V.begin(), V.end()) { 00339 assert(Op != OpRegister); 00340 } 00341 00342 MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R1, unsigned R2) 00343 : Operation(Op), Label(L), Register(R1), Register2(R2) { 00344 assert(Op == OpRegister); 00345 } 00346 00347 public: 00348 /// \brief .cfi_def_cfa defines a rule for computing CFA as: take address from 00349 /// Register and add Offset to it. 00350 static MCCFIInstruction createDefCfa(MCSymbol *L, unsigned Register, 00351 int Offset) { 00352 return MCCFIInstruction(OpDefCfa, L, Register, -Offset, ""); 00353 } 00354 00355 /// \brief .cfi_def_cfa_register modifies a rule for computing CFA. From now 00356 /// on Register will be used instead of the old one. Offset remains the same. 00357 static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register) { 00358 return MCCFIInstruction(OpDefCfaRegister, L, Register, 0, ""); 00359 } 00360 00361 /// \brief .cfi_def_cfa_offset modifies a rule for computing CFA. Register 00362 /// remains the same, but offset is new. Note that it is the absolute offset 00363 /// that will be added to a defined register to the compute CFA address. 00364 static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset) { 00365 return MCCFIInstruction(OpDefCfaOffset, L, 0, -Offset, ""); 00366 } 00367 00368 /// \brief .cfi_adjust_cfa_offset Same as .cfi_def_cfa_offset, but 00369 /// Offset is a relative value that is added/subtracted from the previous 00370 /// offset. 00371 static MCCFIInstruction createAdjustCfaOffset(MCSymbol *L, int Adjustment) { 00372 return MCCFIInstruction(OpAdjustCfaOffset, L, 0, Adjustment, ""); 00373 } 00374 00375 /// \brief .cfi_offset Previous value of Register is saved at offset Offset 00376 /// from CFA. 00377 static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, 00378 int Offset) { 00379 return MCCFIInstruction(OpOffset, L, Register, Offset, ""); 00380 } 00381 00382 /// \brief .cfi_rel_offset Previous value of Register is saved at offset 00383 /// Offset from the current CFA register. This is transformed to .cfi_offset 00384 /// using the known displacement of the CFA register from the CFA. 00385 static MCCFIInstruction createRelOffset(MCSymbol *L, unsigned Register, 00386 int Offset) { 00387 return MCCFIInstruction(OpRelOffset, L, Register, Offset, ""); 00388 } 00389 00390 /// \brief .cfi_register Previous value of Register1 is saved in 00391 /// register Register2. 00392 static MCCFIInstruction createRegister(MCSymbol *L, unsigned Register1, 00393 unsigned Register2) { 00394 return MCCFIInstruction(OpRegister, L, Register1, Register2); 00395 } 00396 00397 /// \brief .cfi_window_save SPARC register window is saved. 00398 static MCCFIInstruction createWindowSave(MCSymbol *L) { 00399 return MCCFIInstruction(OpWindowSave, L, 0, 0, ""); 00400 } 00401 00402 /// \brief .cfi_restore says that the rule for Register is now the same as it 00403 /// was at the beginning of the function, after all initial instructions added 00404 /// by .cfi_startproc were executed. 00405 static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register) { 00406 return MCCFIInstruction(OpRestore, L, Register, 0, ""); 00407 } 00408 00409 /// \brief .cfi_undefined From now on the previous value of Register can't be 00410 /// restored anymore. 00411 static MCCFIInstruction createUndefined(MCSymbol *L, unsigned Register) { 00412 return MCCFIInstruction(OpUndefined, L, Register, 0, ""); 00413 } 00414 00415 /// \brief .cfi_same_value Current value of Register is the same as in the 00416 /// previous frame. I.e., no restoration is needed. 00417 static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register) { 00418 return MCCFIInstruction(OpSameValue, L, Register, 0, ""); 00419 } 00420 00421 /// \brief .cfi_remember_state Save all current rules for all registers. 00422 static MCCFIInstruction createRememberState(MCSymbol *L) { 00423 return MCCFIInstruction(OpRememberState, L, 0, 0, ""); 00424 } 00425 00426 /// \brief .cfi_restore_state Restore the previously saved state. 00427 static MCCFIInstruction createRestoreState(MCSymbol *L) { 00428 return MCCFIInstruction(OpRestoreState, L, 0, 0, ""); 00429 } 00430 00431 /// \brief .cfi_escape Allows the user to add arbitrary bytes to the unwind 00432 /// info. 00433 static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals) { 00434 return MCCFIInstruction(OpEscape, L, 0, 0, Vals); 00435 } 00436 00437 OpType getOperation() const { return Operation; } 00438 MCSymbol *getLabel() const { return Label; } 00439 00440 unsigned getRegister() const { 00441 assert(Operation == OpDefCfa || Operation == OpOffset || 00442 Operation == OpRestore || Operation == OpUndefined || 00443 Operation == OpSameValue || Operation == OpDefCfaRegister || 00444 Operation == OpRelOffset || Operation == OpRegister); 00445 return Register; 00446 } 00447 00448 unsigned getRegister2() const { 00449 assert(Operation == OpRegister); 00450 return Register2; 00451 } 00452 00453 int getOffset() const { 00454 assert(Operation == OpDefCfa || Operation == OpOffset || 00455 Operation == OpRelOffset || Operation == OpDefCfaOffset || 00456 Operation == OpAdjustCfaOffset); 00457 return Offset; 00458 } 00459 00460 StringRef getValues() const { 00461 assert(Operation == OpEscape); 00462 return StringRef(&Values[0], Values.size()); 00463 } 00464 }; 00465 00466 struct MCDwarfFrameInfo { 00467 MCDwarfFrameInfo() 00468 : Begin(nullptr), End(nullptr), Personality(nullptr), Lsda(nullptr), 00469 Instructions(), PersonalityEncoding(), LsdaEncoding(0), 00470 CompactUnwindEncoding(0), IsSignalFrame(false), IsSimple(false) {} 00471 MCSymbol *Begin; 00472 MCSymbol *End; 00473 const MCSymbol *Personality; 00474 const MCSymbol *Lsda; 00475 std::vector<MCCFIInstruction> Instructions; 00476 unsigned PersonalityEncoding; 00477 unsigned LsdaEncoding; 00478 uint32_t CompactUnwindEncoding; 00479 bool IsSignalFrame; 00480 bool IsSimple; 00481 }; 00482 00483 class MCDwarfFrameEmitter { 00484 public: 00485 // 00486 // This emits the frame info section. 00487 // 00488 static void Emit(MCObjectStreamer &streamer, MCAsmBackend *MAB, bool isEH); 00489 static void EmitAdvanceLoc(MCObjectStreamer &Streamer, uint64_t AddrDelta); 00490 static void EncodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta, 00491 raw_ostream &OS); 00492 }; 00493 } // end namespace llvm 00494 00495 #endif