MCDwarf.h 16 KB

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