AsmPrinterDwarf.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  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. using namespace llvm;
  30. #define DEBUG_TYPE "asm-printer"
  31. //===----------------------------------------------------------------------===//
  32. // Dwarf Emission Helper Routines
  33. //===----------------------------------------------------------------------===//
  34. /// EmitSLEB128 - emit the specified signed leb128 value.
  35. void AsmPrinter::EmitSLEB128(int64_t Value, const char *Desc) const {
  36. if (isVerbose() && Desc)
  37. OutStreamer->AddComment(Desc);
  38. OutStreamer->EmitSLEB128IntValue(Value);
  39. }
  40. void AsmPrinter::EmitULEB128(uint64_t Value, const char *Desc, unsigned PadTo) const {
  41. if (isVerbose() && Desc)
  42. OutStreamer->AddComment(Desc);
  43. OutStreamer->EmitULEB128IntValue(Value, PadTo);
  44. }
  45. /// Emit something like ".uleb128 Hi-Lo".
  46. void AsmPrinter::EmitLabelDifferenceAsULEB128(const MCSymbol *Hi,
  47. const MCSymbol *Lo) const {
  48. OutStreamer->emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
  49. }
  50. static const char *DecodeDWARFEncoding(unsigned Encoding) {
  51. switch (Encoding) {
  52. case dwarf::DW_EH_PE_absptr:
  53. return "absptr";
  54. case dwarf::DW_EH_PE_omit:
  55. return "omit";
  56. case dwarf::DW_EH_PE_pcrel:
  57. return "pcrel";
  58. case dwarf::DW_EH_PE_uleb128:
  59. return "uleb128";
  60. case dwarf::DW_EH_PE_sleb128:
  61. return "sleb128";
  62. case dwarf::DW_EH_PE_udata4:
  63. return "udata4";
  64. case dwarf::DW_EH_PE_udata8:
  65. return "udata8";
  66. case dwarf::DW_EH_PE_sdata4:
  67. return "sdata4";
  68. case dwarf::DW_EH_PE_sdata8:
  69. return "sdata8";
  70. case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4:
  71. return "pcrel udata4";
  72. case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4:
  73. return "pcrel sdata4";
  74. case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8:
  75. return "pcrel udata8";
  76. case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8:
  77. return "pcrel sdata8";
  78. case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4
  79. :
  80. return "indirect pcrel udata4";
  81. case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
  82. :
  83. return "indirect pcrel sdata4";
  84. case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8
  85. :
  86. return "indirect pcrel udata8";
  87. case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8
  88. :
  89. return "indirect pcrel sdata8";
  90. }
  91. return "<unknown encoding>";
  92. }
  93. /// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an
  94. /// encoding. If verbose assembly output is enabled, we output comments
  95. /// describing the encoding. Desc is an optional string saying what the
  96. /// encoding is specifying (e.g. "LSDA").
  97. void AsmPrinter::EmitEncodingByte(unsigned Val, const char *Desc) const {
  98. if (isVerbose()) {
  99. if (Desc)
  100. OutStreamer->AddComment(Twine(Desc) + " Encoding = " +
  101. Twine(DecodeDWARFEncoding(Val)));
  102. else
  103. OutStreamer->AddComment(Twine("Encoding = ") + DecodeDWARFEncoding(Val));
  104. }
  105. OutStreamer->EmitIntValue(Val, 1);
  106. }
  107. /// GetSizeOfEncodedValue - Return the size of the encoding in bytes.
  108. unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const {
  109. if (Encoding == dwarf::DW_EH_PE_omit)
  110. return 0;
  111. switch (Encoding & 0x07) {
  112. default:
  113. llvm_unreachable("Invalid encoded value.");
  114. case dwarf::DW_EH_PE_absptr:
  115. return MF->getDataLayout().getPointerSize();
  116. case dwarf::DW_EH_PE_udata2:
  117. return 2;
  118. case dwarf::DW_EH_PE_udata4:
  119. return 4;
  120. case dwarf::DW_EH_PE_udata8:
  121. return 8;
  122. }
  123. }
  124. void AsmPrinter::EmitTTypeReference(const GlobalValue *GV,
  125. unsigned Encoding) const {
  126. if (GV) {
  127. const TargetLoweringObjectFile &TLOF = getObjFileLowering();
  128. const MCExpr *Exp =
  129. TLOF.getTTypeGlobalReference(GV, Encoding, TM, MMI, *OutStreamer);
  130. OutStreamer->EmitValue(Exp, GetSizeOfEncodedValue(Encoding));
  131. } else
  132. OutStreamer->EmitIntValue(0, GetSizeOfEncodedValue(Encoding));
  133. }
  134. void AsmPrinter::emitDwarfSymbolReference(const MCSymbol *Label,
  135. bool ForceOffset) const {
  136. if (!ForceOffset) {
  137. // On COFF targets, we have to emit the special .secrel32 directive.
  138. if (MAI->needsDwarfSectionOffsetDirective()) {
  139. OutStreamer->EmitCOFFSecRel32(Label, /*Offset=*/0);
  140. return;
  141. }
  142. // If the format uses relocations with dwarf, refer to the symbol directly.
  143. if (MAI->doesDwarfUseRelocationsAcrossSections()) {
  144. OutStreamer->EmitSymbolValue(Label, 4);
  145. return;
  146. }
  147. }
  148. // Otherwise, emit it as a label difference from the start of the section.
  149. EmitLabelDifference(Label, Label->getSection().getBeginSymbol(), 4);
  150. }
  151. void AsmPrinter::emitDwarfStringOffset(DwarfStringPoolEntry S) const {
  152. if (MAI->doesDwarfUseRelocationsAcrossSections()) {
  153. assert(S.Symbol && "No symbol available");
  154. emitDwarfSymbolReference(S.Symbol);
  155. return;
  156. }
  157. // Just emit the offset directly; no need for symbol math.
  158. emitInt32(S.Offset);
  159. }
  160. void AsmPrinter::EmitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const {
  161. EmitLabelPlusOffset(Label, Offset, MAI->getCodePointerSize());
  162. }
  163. void AsmPrinter::EmitCallSiteOffset(const MCSymbol *Hi,
  164. const MCSymbol *Lo,
  165. unsigned Encoding) const {
  166. // The least significant 3 bits specify the width of the encoding
  167. if ((Encoding & 0x7) == dwarf::DW_EH_PE_uleb128)
  168. EmitLabelDifferenceAsULEB128(Hi, Lo);
  169. else
  170. EmitLabelDifference(Hi, Lo, GetSizeOfEncodedValue(Encoding));
  171. }
  172. void AsmPrinter::EmitCallSiteValue(uint64_t Value,
  173. unsigned Encoding) const {
  174. // The least significant 3 bits specify the width of the encoding
  175. if ((Encoding & 0x7) == dwarf::DW_EH_PE_uleb128)
  176. EmitULEB128(Value);
  177. else
  178. OutStreamer->EmitIntValue(Value, GetSizeOfEncodedValue(Encoding));
  179. }
  180. //===----------------------------------------------------------------------===//
  181. // Dwarf Lowering Routines
  182. //===----------------------------------------------------------------------===//
  183. void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const {
  184. switch (Inst.getOperation()) {
  185. default:
  186. llvm_unreachable("Unexpected instruction");
  187. case MCCFIInstruction::OpDefCfaOffset:
  188. OutStreamer->EmitCFIDefCfaOffset(Inst.getOffset());
  189. break;
  190. case MCCFIInstruction::OpAdjustCfaOffset:
  191. OutStreamer->EmitCFIAdjustCfaOffset(Inst.getOffset());
  192. break;
  193. case MCCFIInstruction::OpDefCfa:
  194. OutStreamer->EmitCFIDefCfa(Inst.getRegister(), Inst.getOffset());
  195. break;
  196. case MCCFIInstruction::OpDefCfaRegister:
  197. OutStreamer->EmitCFIDefCfaRegister(Inst.getRegister());
  198. break;
  199. case MCCFIInstruction::OpOffset:
  200. OutStreamer->EmitCFIOffset(Inst.getRegister(), Inst.getOffset());
  201. break;
  202. case MCCFIInstruction::OpRegister:
  203. OutStreamer->EmitCFIRegister(Inst.getRegister(), Inst.getRegister2());
  204. break;
  205. case MCCFIInstruction::OpWindowSave:
  206. OutStreamer->EmitCFIWindowSave();
  207. break;
  208. case MCCFIInstruction::OpNegateRAState:
  209. OutStreamer->EmitCFINegateRAState();
  210. break;
  211. case MCCFIInstruction::OpSameValue:
  212. OutStreamer->EmitCFISameValue(Inst.getRegister());
  213. break;
  214. case MCCFIInstruction::OpGnuArgsSize:
  215. OutStreamer->EmitCFIGnuArgsSize(Inst.getOffset());
  216. break;
  217. case MCCFIInstruction::OpEscape:
  218. OutStreamer->EmitCFIEscape(Inst.getValues());
  219. break;
  220. case MCCFIInstruction::OpRestore:
  221. OutStreamer->EmitCFIRestore(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 AsmPrinter::emitDwarfAbbrev(const DIEAbbrev &Abbrev) const {
  255. // Emit the abbreviations code (base 1 index.)
  256. EmitULEB128(Abbrev.getNumber(), "Abbreviation Code");
  257. // Emit the abbreviations data.
  258. Abbrev.Emit(this);
  259. }