AsmPrinterDwarf.cpp 11 KB

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