AsmPrinterDwarf.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. //===-- AsmPrinterDwarf.cpp - AsmPrinter Dwarf Support --------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file implements the Dwarf emissions parts of AsmPrinter.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "llvm/ADT/Twine.h"
  13. #include "llvm/BinaryFormat/Dwarf.h"
  14. #include "llvm/CodeGen/AsmPrinter.h"
  15. #include "llvm/CodeGen/DIE.h"
  16. #include "llvm/CodeGen/MachineFunction.h"
  17. #include "llvm/IR/DataLayout.h"
  18. #include "llvm/MC/MCAsmInfo.h"
  19. #include "llvm/MC/MCDwarf.h"
  20. #include "llvm/MC/MCSection.h"
  21. #include "llvm/MC/MCStreamer.h"
  22. #include "llvm/MC/MCSymbol.h"
  23. #include "llvm/Support/ErrorHandling.h"
  24. #include "llvm/Target/TargetLoweringObjectFile.h"
  25. #include <cstdint>
  26. using namespace llvm;
  27. #define DEBUG_TYPE "asm-printer"
  28. //===----------------------------------------------------------------------===//
  29. // Dwarf Emission Helper Routines
  30. //===----------------------------------------------------------------------===//
  31. /// EmitSLEB128 - emit the specified signed leb128 value.
  32. void AsmPrinter::emitSLEB128(int64_t Value, const char *Desc) const {
  33. if (isVerbose() && Desc)
  34. OutStreamer->AddComment(Desc);
  35. OutStreamer->emitSLEB128IntValue(Value);
  36. }
  37. void AsmPrinter::emitULEB128(uint64_t Value, const char *Desc,
  38. unsigned PadTo) const {
  39. if (isVerbose() && Desc)
  40. OutStreamer->AddComment(Desc);
  41. OutStreamer->emitULEB128IntValue(Value, PadTo);
  42. }
  43. /// Emit something like ".uleb128 Hi-Lo".
  44. void AsmPrinter::emitLabelDifferenceAsULEB128(const MCSymbol *Hi,
  45. const MCSymbol *Lo) const {
  46. OutStreamer->emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
  47. }
  48. static const char *DecodeDWARFEncoding(unsigned Encoding) {
  49. switch (Encoding) {
  50. case dwarf::DW_EH_PE_absptr:
  51. return "absptr";
  52. case dwarf::DW_EH_PE_omit:
  53. return "omit";
  54. case dwarf::DW_EH_PE_pcrel:
  55. return "pcrel";
  56. case dwarf::DW_EH_PE_uleb128:
  57. return "uleb128";
  58. case dwarf::DW_EH_PE_sleb128:
  59. return "sleb128";
  60. case dwarf::DW_EH_PE_udata4:
  61. return "udata4";
  62. case dwarf::DW_EH_PE_udata8:
  63. return "udata8";
  64. case dwarf::DW_EH_PE_sdata4:
  65. return "sdata4";
  66. case dwarf::DW_EH_PE_sdata8:
  67. return "sdata8";
  68. case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4:
  69. return "pcrel udata4";
  70. case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4:
  71. return "pcrel sdata4";
  72. case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8:
  73. return "pcrel udata8";
  74. case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8:
  75. return "pcrel sdata8";
  76. case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4
  77. :
  78. return "indirect pcrel udata4";
  79. case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
  80. :
  81. return "indirect pcrel sdata4";
  82. case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8
  83. :
  84. return "indirect pcrel udata8";
  85. case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8
  86. :
  87. return "indirect pcrel sdata8";
  88. case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_datarel |
  89. dwarf::DW_EH_PE_sdata4:
  90. return "indirect datarel sdata4";
  91. case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_datarel |
  92. dwarf::DW_EH_PE_sdata8:
  93. return "indirect datarel sdata8";
  94. }
  95. return "<unknown encoding>";
  96. }
  97. /// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an
  98. /// encoding. If verbose assembly output is enabled, we output comments
  99. /// describing the encoding. Desc is an optional string saying what the
  100. /// encoding is specifying (e.g. "LSDA").
  101. void AsmPrinter::emitEncodingByte(unsigned Val, const char *Desc) const {
  102. if (isVerbose()) {
  103. if (Desc)
  104. OutStreamer->AddComment(Twine(Desc) + " Encoding = " +
  105. Twine(DecodeDWARFEncoding(Val)));
  106. else
  107. OutStreamer->AddComment(Twine("Encoding = ") + DecodeDWARFEncoding(Val));
  108. }
  109. OutStreamer->emitIntValue(Val, 1);
  110. }
  111. /// GetSizeOfEncodedValue - Return the size of the encoding in bytes.
  112. unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const {
  113. if (Encoding == dwarf::DW_EH_PE_omit)
  114. return 0;
  115. switch (Encoding & 0x07) {
  116. default:
  117. llvm_unreachable("Invalid encoded value.");
  118. case dwarf::DW_EH_PE_absptr:
  119. return MF->getDataLayout().getPointerSize();
  120. case dwarf::DW_EH_PE_udata2:
  121. return 2;
  122. case dwarf::DW_EH_PE_udata4:
  123. return 4;
  124. case dwarf::DW_EH_PE_udata8:
  125. return 8;
  126. }
  127. }
  128. void AsmPrinter::emitTTypeReference(const GlobalValue *GV, unsigned Encoding) {
  129. if (GV) {
  130. const TargetLoweringObjectFile &TLOF = getObjFileLowering();
  131. const MCExpr *Exp =
  132. TLOF.getTTypeGlobalReference(GV, Encoding, TM, MMI, *OutStreamer);
  133. OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding));
  134. } else
  135. OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));
  136. }
  137. void AsmPrinter::emitDwarfSymbolReference(const MCSymbol *Label,
  138. bool ForceOffset) const {
  139. if (!ForceOffset) {
  140. // On COFF targets, we have to emit the special .secrel32 directive.
  141. if (MAI->needsDwarfSectionOffsetDirective()) {
  142. assert(!isDwarf64() &&
  143. "emitting DWARF64 is not implemented for COFF targets");
  144. OutStreamer->emitCOFFSecRel32(Label, /*Offset=*/0);
  145. return;
  146. }
  147. // If the format uses relocations with dwarf, refer to the symbol directly.
  148. if (doesDwarfUseRelocationsAcrossSections()) {
  149. OutStreamer->emitSymbolValue(Label, getDwarfOffsetByteSize());
  150. return;
  151. }
  152. }
  153. // Otherwise, emit it as a label difference from the start of the section.
  154. emitLabelDifference(Label, Label->getSection().getBeginSymbol(),
  155. getDwarfOffsetByteSize());
  156. }
  157. void AsmPrinter::emitDwarfStringOffset(DwarfStringPoolEntry S) const {
  158. if (doesDwarfUseRelocationsAcrossSections()) {
  159. assert(S.Symbol && "No symbol available");
  160. emitDwarfSymbolReference(S.Symbol);
  161. return;
  162. }
  163. // Just emit the offset directly; no need for symbol math.
  164. OutStreamer->emitIntValue(S.Offset, getDwarfOffsetByteSize());
  165. }
  166. void AsmPrinter::emitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const {
  167. emitLabelPlusOffset(Label, Offset, getDwarfOffsetByteSize());
  168. }
  169. void AsmPrinter::emitDwarfLengthOrOffset(uint64_t Value) const {
  170. assert(isDwarf64() || Value <= UINT32_MAX);
  171. OutStreamer->emitIntValue(Value, getDwarfOffsetByteSize());
  172. }
  173. void AsmPrinter::emitDwarfUnitLength(uint64_t Length,
  174. const Twine &Comment) const {
  175. OutStreamer->emitDwarfUnitLength(Length, Comment);
  176. }
  177. MCSymbol *AsmPrinter::emitDwarfUnitLength(const Twine &Prefix,
  178. const Twine &Comment) const {
  179. return OutStreamer->emitDwarfUnitLength(Prefix, Comment);
  180. }
  181. void AsmPrinter::emitCallSiteOffset(const MCSymbol *Hi, const MCSymbol *Lo,
  182. unsigned Encoding) const {
  183. // The least significant 3 bits specify the width of the encoding
  184. if ((Encoding & 0x7) == dwarf::DW_EH_PE_uleb128)
  185. emitLabelDifferenceAsULEB128(Hi, Lo);
  186. else
  187. emitLabelDifference(Hi, Lo, GetSizeOfEncodedValue(Encoding));
  188. }
  189. void AsmPrinter::emitCallSiteValue(uint64_t Value, unsigned Encoding) const {
  190. // The least significant 3 bits specify the width of the encoding
  191. if ((Encoding & 0x7) == dwarf::DW_EH_PE_uleb128)
  192. emitULEB128(Value);
  193. else
  194. OutStreamer->emitIntValue(Value, GetSizeOfEncodedValue(Encoding));
  195. }
  196. //===----------------------------------------------------------------------===//
  197. // Dwarf Lowering Routines
  198. //===----------------------------------------------------------------------===//
  199. void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const {
  200. switch (Inst.getOperation()) {
  201. default:
  202. llvm_unreachable("Unexpected instruction");
  203. case MCCFIInstruction::OpDefCfaOffset:
  204. OutStreamer->emitCFIDefCfaOffset(Inst.getOffset());
  205. break;
  206. case MCCFIInstruction::OpAdjustCfaOffset:
  207. OutStreamer->emitCFIAdjustCfaOffset(Inst.getOffset());
  208. break;
  209. case MCCFIInstruction::OpDefCfa:
  210. OutStreamer->emitCFIDefCfa(Inst.getRegister(), Inst.getOffset());
  211. break;
  212. case MCCFIInstruction::OpDefCfaRegister:
  213. OutStreamer->emitCFIDefCfaRegister(Inst.getRegister());
  214. break;
  215. case MCCFIInstruction::OpLLVMDefAspaceCfa:
  216. OutStreamer->emitCFILLVMDefAspaceCfa(Inst.getRegister(), Inst.getOffset(),
  217. Inst.getAddressSpace());
  218. break;
  219. case MCCFIInstruction::OpOffset:
  220. OutStreamer->emitCFIOffset(Inst.getRegister(), Inst.getOffset());
  221. break;
  222. case MCCFIInstruction::OpRegister:
  223. OutStreamer->emitCFIRegister(Inst.getRegister(), Inst.getRegister2());
  224. break;
  225. case MCCFIInstruction::OpWindowSave:
  226. OutStreamer->emitCFIWindowSave();
  227. break;
  228. case MCCFIInstruction::OpNegateRAState:
  229. OutStreamer->emitCFINegateRAState();
  230. break;
  231. case MCCFIInstruction::OpSameValue:
  232. OutStreamer->emitCFISameValue(Inst.getRegister());
  233. break;
  234. case MCCFIInstruction::OpGnuArgsSize:
  235. OutStreamer->emitCFIGnuArgsSize(Inst.getOffset());
  236. break;
  237. case MCCFIInstruction::OpEscape:
  238. OutStreamer->AddComment(Inst.getComment());
  239. OutStreamer->emitCFIEscape(Inst.getValues());
  240. break;
  241. case MCCFIInstruction::OpRestore:
  242. OutStreamer->emitCFIRestore(Inst.getRegister());
  243. break;
  244. case MCCFIInstruction::OpUndefined:
  245. OutStreamer->emitCFIUndefined(Inst.getRegister());
  246. break;
  247. case MCCFIInstruction::OpRememberState:
  248. OutStreamer->emitCFIRememberState();
  249. break;
  250. case MCCFIInstruction::OpRestoreState:
  251. OutStreamer->emitCFIRestoreState();
  252. break;
  253. }
  254. }
  255. void AsmPrinter::emitDwarfDIE(const DIE &Die) const {
  256. // Emit the code (index) for the abbreviation.
  257. if (isVerbose())
  258. OutStreamer->AddComment("Abbrev [" + Twine(Die.getAbbrevNumber()) + "] 0x" +
  259. Twine::utohexstr(Die.getOffset()) + ":0x" +
  260. Twine::utohexstr(Die.getSize()) + " " +
  261. dwarf::TagString(Die.getTag()));
  262. emitULEB128(Die.getAbbrevNumber());
  263. // Emit the DIE attribute values.
  264. for (const auto &V : Die.values()) {
  265. dwarf::Attribute Attr = V.getAttribute();
  266. assert(V.getForm() && "Too many attributes for DIE (check abbreviation)");
  267. if (isVerbose()) {
  268. OutStreamer->AddComment(dwarf::AttributeString(Attr));
  269. if (Attr == dwarf::DW_AT_accessibility)
  270. OutStreamer->AddComment(
  271. dwarf::AccessibilityString(V.getDIEInteger().getValue()));
  272. }
  273. // Emit an attribute using the defined form.
  274. V.emitValue(this);
  275. }
  276. // Emit the DIE children if any.
  277. if (Die.hasChildren()) {
  278. for (const auto &Child : Die.children())
  279. emitDwarfDIE(Child);
  280. OutStreamer->AddComment("End Of Children Mark");
  281. emitInt8(0);
  282. }
  283. }
  284. void AsmPrinter::emitDwarfAbbrev(const DIEAbbrev &Abbrev) const {
  285. // Emit the abbreviations code (base 1 index.)
  286. emitULEB128(Abbrev.getNumber(), "Abbreviation Code");
  287. // Emit the abbreviations data.
  288. Abbrev.Emit(this);
  289. }