AsmPrinterDwarf.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. //===-- AsmPrinterDwarf.cpp - AsmPrinter Dwarf Support --------------------===//
  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 implements the Dwarf emissions parts of AsmPrinter.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "ByteStreamer.h"
  14. #include "DwarfDebug.h"
  15. #include "DwarfExpression.h"
  16. #include "llvm/ADT/Twine.h"
  17. #include "llvm/CodeGen/AsmPrinter.h"
  18. #include "llvm/CodeGen/DIE.h"
  19. #include "llvm/CodeGen/MachineFunction.h"
  20. #include "llvm/CodeGen/MachineModuleInfo.h"
  21. #include "llvm/IR/DataLayout.h"
  22. #include "llvm/MC/MCAsmInfo.h"
  23. #include "llvm/MC/MCRegisterInfo.h"
  24. #include "llvm/MC/MCSection.h"
  25. #include "llvm/MC/MCStreamer.h"
  26. #include "llvm/MC/MCSymbol.h"
  27. #include "llvm/MC/MachineLocation.h"
  28. #include "llvm/Support/Dwarf.h"
  29. #include "llvm/Support/ErrorHandling.h"
  30. #include "llvm/Target/TargetLoweringObjectFile.h"
  31. #include "llvm/Target/TargetMachine.h"
  32. #include "llvm/Target/TargetSubtargetInfo.h"
  33. using namespace llvm;
  34. #define DEBUG_TYPE "asm-printer"
  35. //===----------------------------------------------------------------------===//
  36. // Dwarf Emission Helper Routines
  37. //===----------------------------------------------------------------------===//
  38. /// EmitSLEB128 - emit the specified signed leb128 value.
  39. void AsmPrinter::EmitSLEB128(int64_t Value, const char *Desc) const {
  40. if (isVerbose() && Desc)
  41. OutStreamer->AddComment(Desc);
  42. OutStreamer->EmitSLEB128IntValue(Value);
  43. }
  44. /// EmitULEB128 - emit the specified signed leb128 value.
  45. void AsmPrinter::EmitULEB128(uint64_t Value, const char *Desc,
  46. unsigned PadTo) const {
  47. if (isVerbose() && Desc)
  48. OutStreamer->AddComment(Desc);
  49. OutStreamer->EmitULEB128IntValue(Value, PadTo);
  50. }
  51. /// EmitCFAByte - Emit a .byte 42 directive for a DW_CFA_xxx value.
  52. void AsmPrinter::EmitCFAByte(unsigned Val) const {
  53. if (isVerbose()) {
  54. if (Val >= dwarf::DW_CFA_offset && Val < dwarf::DW_CFA_offset + 64)
  55. OutStreamer->AddComment("DW_CFA_offset + Reg (" +
  56. Twine(Val - dwarf::DW_CFA_offset) + ")");
  57. else
  58. OutStreamer->AddComment(dwarf::CallFrameString(Val));
  59. }
  60. OutStreamer->EmitIntValue(Val, 1);
  61. }
  62. static const char *DecodeDWARFEncoding(unsigned Encoding) {
  63. switch (Encoding) {
  64. case dwarf::DW_EH_PE_absptr:
  65. return "absptr";
  66. case dwarf::DW_EH_PE_omit:
  67. return "omit";
  68. case dwarf::DW_EH_PE_pcrel:
  69. return "pcrel";
  70. case dwarf::DW_EH_PE_udata4:
  71. return "udata4";
  72. case dwarf::DW_EH_PE_udata8:
  73. return "udata8";
  74. case dwarf::DW_EH_PE_sdata4:
  75. return "sdata4";
  76. case dwarf::DW_EH_PE_sdata8:
  77. return "sdata8";
  78. case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4:
  79. return "pcrel udata4";
  80. case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4:
  81. return "pcrel sdata4";
  82. case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8:
  83. return "pcrel udata8";
  84. case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8:
  85. return "pcrel sdata8";
  86. case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4
  87. :
  88. return "indirect pcrel udata4";
  89. case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
  90. :
  91. return "indirect pcrel sdata4";
  92. case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8
  93. :
  94. return "indirect pcrel udata8";
  95. case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8
  96. :
  97. return "indirect pcrel sdata8";
  98. }
  99. return "<unknown encoding>";
  100. }
  101. /// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an
  102. /// encoding. If verbose assembly output is enabled, we output comments
  103. /// describing the encoding. Desc is an optional string saying what the
  104. /// encoding is specifying (e.g. "LSDA").
  105. void AsmPrinter::EmitEncodingByte(unsigned Val, const char *Desc) const {
  106. if (isVerbose()) {
  107. if (Desc)
  108. OutStreamer->AddComment(Twine(Desc) + " Encoding = " +
  109. Twine(DecodeDWARFEncoding(Val)));
  110. else
  111. OutStreamer->AddComment(Twine("Encoding = ") + DecodeDWARFEncoding(Val));
  112. }
  113. OutStreamer->EmitIntValue(Val, 1);
  114. }
  115. /// GetSizeOfEncodedValue - Return the size of the encoding in bytes.
  116. unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const {
  117. if (Encoding == dwarf::DW_EH_PE_omit)
  118. return 0;
  119. switch (Encoding & 0x07) {
  120. default:
  121. llvm_unreachable("Invalid encoded value.");
  122. case dwarf::DW_EH_PE_absptr:
  123. return TM.getDataLayout()->getPointerSize();
  124. case dwarf::DW_EH_PE_udata2:
  125. return 2;
  126. case dwarf::DW_EH_PE_udata4:
  127. return 4;
  128. case dwarf::DW_EH_PE_udata8:
  129. return 8;
  130. }
  131. }
  132. void AsmPrinter::EmitTTypeReference(const GlobalValue *GV,
  133. unsigned Encoding) const {
  134. if (GV) {
  135. const TargetLoweringObjectFile &TLOF = getObjFileLowering();
  136. const MCExpr *Exp =
  137. TLOF.getTTypeGlobalReference(GV, Encoding, *Mang, TM, MMI,
  138. *OutStreamer);
  139. OutStreamer->EmitValue(Exp, GetSizeOfEncodedValue(Encoding));
  140. } else
  141. OutStreamer->EmitIntValue(0, GetSizeOfEncodedValue(Encoding));
  142. }
  143. void AsmPrinter::emitDwarfSymbolReference(const MCSymbol *Label,
  144. bool ForceOffset) const {
  145. if (!ForceOffset) {
  146. // On COFF targets, we have to emit the special .secrel32 directive.
  147. if (MAI->needsDwarfSectionOffsetDirective()) {
  148. OutStreamer->EmitCOFFSecRel32(Label);
  149. return;
  150. }
  151. // If the format uses relocations with dwarf, refer to the symbol directly.
  152. if (MAI->doesDwarfUseRelocationsAcrossSections()) {
  153. OutStreamer->EmitSymbolValue(Label, 4);
  154. return;
  155. }
  156. }
  157. // Otherwise, emit it as a label difference from the start of the section.
  158. EmitLabelDifference(Label, Label->getSection().getBeginSymbol(), 4);
  159. }
  160. void AsmPrinter::emitDwarfStringOffset(DwarfStringPoolEntryRef S) const {
  161. if (MAI->doesDwarfUseRelocationsAcrossSections()) {
  162. emitDwarfSymbolReference(S.getSymbol());
  163. return;
  164. }
  165. // Just emit the offset directly; no need for symbol math.
  166. EmitInt32(S.getOffset());
  167. }
  168. /// EmitDwarfRegOp - Emit dwarf register operation.
  169. void AsmPrinter::EmitDwarfRegOp(ByteStreamer &Streamer,
  170. const MachineLocation &MLoc) const {
  171. DebugLocDwarfExpression Expr(*MF->getSubtarget().getRegisterInfo(),
  172. getDwarfDebug()->getDwarfVersion(), Streamer);
  173. const MCRegisterInfo *MRI = MMI->getContext().getRegisterInfo();
  174. int Reg = MRI->getDwarfRegNum(MLoc.getReg(), false);
  175. if (Reg < 0) {
  176. // We assume that pointers are always in an addressable register.
  177. if (MLoc.isIndirect())
  178. // FIXME: We have no reasonable way of handling errors in here. The
  179. // caller might be in the middle of a dwarf expression. We should
  180. // probably assert that Reg >= 0 once debug info generation is more
  181. // mature.
  182. return Expr.EmitOp(dwarf::DW_OP_nop,
  183. "nop (could not find a dwarf register number)");
  184. // Attempt to find a valid super- or sub-register.
  185. if (!Expr.AddMachineRegPiece(MLoc.getReg()))
  186. Expr.EmitOp(dwarf::DW_OP_nop,
  187. "nop (could not find a dwarf register number)");
  188. return;
  189. }
  190. if (MLoc.isIndirect())
  191. Expr.AddRegIndirect(Reg, MLoc.getOffset());
  192. else
  193. Expr.AddReg(Reg);
  194. }
  195. //===----------------------------------------------------------------------===//
  196. // Dwarf Lowering Routines
  197. //===----------------------------------------------------------------------===//
  198. void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const {
  199. switch (Inst.getOperation()) {
  200. default:
  201. llvm_unreachable("Unexpected instruction");
  202. case MCCFIInstruction::OpDefCfaOffset:
  203. OutStreamer->EmitCFIDefCfaOffset(Inst.getOffset());
  204. break;
  205. case MCCFIInstruction::OpDefCfa:
  206. OutStreamer->EmitCFIDefCfa(Inst.getRegister(), Inst.getOffset());
  207. break;
  208. case MCCFIInstruction::OpDefCfaRegister:
  209. OutStreamer->EmitCFIDefCfaRegister(Inst.getRegister());
  210. break;
  211. case MCCFIInstruction::OpOffset:
  212. OutStreamer->EmitCFIOffset(Inst.getRegister(), Inst.getOffset());
  213. break;
  214. case MCCFIInstruction::OpRegister:
  215. OutStreamer->EmitCFIRegister(Inst.getRegister(), Inst.getRegister2());
  216. break;
  217. case MCCFIInstruction::OpWindowSave:
  218. OutStreamer->EmitCFIWindowSave();
  219. break;
  220. case MCCFIInstruction::OpSameValue:
  221. OutStreamer->EmitCFISameValue(Inst.getRegister());
  222. break;
  223. }
  224. }
  225. void AsmPrinter::emitDwarfDIE(const DIE &Die) const {
  226. // Emit the code (index) for the abbreviation.
  227. if (isVerbose())
  228. OutStreamer->AddComment("Abbrev [" + Twine(Die.getAbbrevNumber()) + "] 0x" +
  229. Twine::utohexstr(Die.getOffset()) + ":0x" +
  230. Twine::utohexstr(Die.getSize()) + " " +
  231. dwarf::TagString(Die.getTag()));
  232. EmitULEB128(Die.getAbbrevNumber());
  233. // Emit the DIE attribute values.
  234. for (const auto &V : Die.values()) {
  235. dwarf::Attribute Attr = V.getAttribute();
  236. assert(V.getForm() && "Too many attributes for DIE (check abbreviation)");
  237. if (isVerbose()) {
  238. OutStreamer->AddComment(dwarf::AttributeString(Attr));
  239. if (Attr == dwarf::DW_AT_accessibility)
  240. OutStreamer->AddComment(
  241. dwarf::AccessibilityString(V.getDIEInteger().getValue()));
  242. }
  243. // Emit an attribute using the defined form.
  244. V.EmitValue(this);
  245. }
  246. // Emit the DIE children if any.
  247. if (Die.hasChildren()) {
  248. for (auto &Child : Die.children())
  249. emitDwarfDIE(Child);
  250. OutStreamer->AddComment("End Of Children Mark");
  251. EmitInt8(0);
  252. }
  253. }
  254. void
  255. AsmPrinter::emitDwarfAbbrevs(const std::vector<DIEAbbrev *>& Abbrevs) const {
  256. // For each abbrevation.
  257. for (const DIEAbbrev *Abbrev : Abbrevs) {
  258. // Emit the abbrevations code (base 1 index.)
  259. EmitULEB128(Abbrev->getNumber(), "Abbreviation Code");
  260. // Emit the abbreviations data.
  261. Abbrev->Emit(this);
  262. }
  263. // Mark end of abbreviations.
  264. EmitULEB128(0, "EOM(3)");
  265. }