2
0

DwarfFile.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. //===-- llvm/CodeGen/DwarfFile.cpp - Dwarf Debug Framework ----------------===//
  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. #include "DwarfFile.h"
  10. #include "DwarfDebug.h"
  11. #include "DwarfUnit.h"
  12. #include "llvm/ADT/STLExtras.h"
  13. #include "llvm/IR/DataLayout.h"
  14. #include "llvm/MC/MCStreamer.h"
  15. #include "llvm/Support/LEB128.h"
  16. #include "llvm/Target/TargetLoweringObjectFile.h"
  17. namespace llvm {
  18. DwarfFile::DwarfFile(AsmPrinter *AP, StringRef Pref, BumpPtrAllocator &DA)
  19. : Asm(AP), StrPool(DA, *Asm, Pref) {}
  20. DwarfFile::~DwarfFile() {
  21. for (DIEAbbrev *Abbrev : Abbreviations)
  22. Abbrev->~DIEAbbrev();
  23. }
  24. // Define a unique number for the abbreviation.
  25. //
  26. DIEAbbrev &DwarfFile::assignAbbrevNumber(DIE &Die) {
  27. FoldingSetNodeID ID;
  28. DIEAbbrev Abbrev = Die.generateAbbrev();
  29. Abbrev.Profile(ID);
  30. void *InsertPos;
  31. if (DIEAbbrev *Existing =
  32. AbbreviationsSet.FindNodeOrInsertPos(ID, InsertPos)) {
  33. Die.setAbbrevNumber(Existing->getNumber());
  34. return *Existing;
  35. }
  36. // Move the abbreviation to the heap and assign a number.
  37. DIEAbbrev *New = new (AbbrevAllocator) DIEAbbrev(std::move(Abbrev));
  38. Abbreviations.push_back(New);
  39. New->setNumber(Abbreviations.size());
  40. Die.setAbbrevNumber(Abbreviations.size());
  41. // Store it for lookup.
  42. AbbreviationsSet.InsertNode(New, InsertPos);
  43. return *New;
  44. }
  45. void DwarfFile::addUnit(std::unique_ptr<DwarfUnit> U) {
  46. CUs.push_back(std::move(U));
  47. }
  48. // Emit the various dwarf units to the unit section USection with
  49. // the abbreviations going into ASection.
  50. void DwarfFile::emitUnits(bool UseOffsets) {
  51. for (const auto &TheU : CUs) {
  52. DIE &Die = TheU->getUnitDie();
  53. MCSection *USection = TheU->getSection();
  54. Asm->OutStreamer->SwitchSection(USection);
  55. TheU->emitHeader(UseOffsets);
  56. Asm->emitDwarfDIE(Die);
  57. }
  58. }
  59. // Compute the size and offset for each DIE.
  60. void DwarfFile::computeSizeAndOffsets() {
  61. // Offset from the first CU in the debug info section is 0 initially.
  62. unsigned SecOffset = 0;
  63. // Iterate over each compile unit and set the size and offsets for each
  64. // DIE within each compile unit. All offsets are CU relative.
  65. for (const auto &TheU : CUs) {
  66. TheU->setDebugInfoOffset(SecOffset);
  67. // CU-relative offset is reset to 0 here.
  68. unsigned Offset = sizeof(int32_t) + // Length of Unit Info
  69. TheU->getHeaderSize(); // Unit-specific headers
  70. // EndOffset here is CU-relative, after laying out
  71. // all of the CU DIE.
  72. unsigned EndOffset = computeSizeAndOffset(TheU->getUnitDie(), Offset);
  73. SecOffset += EndOffset;
  74. }
  75. }
  76. // Compute the size and offset of a DIE. The offset is relative to start of the
  77. // CU. It returns the offset after laying out the DIE.
  78. unsigned DwarfFile::computeSizeAndOffset(DIE &Die, unsigned Offset) {
  79. // Record the abbreviation.
  80. const DIEAbbrev &Abbrev = assignAbbrevNumber(Die);
  81. // Set DIE offset
  82. Die.setOffset(Offset);
  83. // Start the size with the size of abbreviation code.
  84. Offset += getULEB128Size(Die.getAbbrevNumber());
  85. // Size the DIE attribute values.
  86. for (const auto &V : Die.values())
  87. // Size attribute value.
  88. Offset += V.SizeOf(Asm);
  89. // Size the DIE children if any.
  90. if (Die.hasChildren()) {
  91. (void)Abbrev;
  92. assert(Abbrev.hasChildren() && "Children flag not set");
  93. for (auto &Child : Die.children())
  94. Offset = computeSizeAndOffset(Child, Offset);
  95. // End of children marker.
  96. Offset += sizeof(int8_t);
  97. }
  98. Die.setSize(Offset - Die.getOffset());
  99. return Offset;
  100. }
  101. void DwarfFile::emitAbbrevs(MCSection *Section) {
  102. // Check to see if it is worth the effort.
  103. if (!Abbreviations.empty()) {
  104. // Start the debug abbrev section.
  105. Asm->OutStreamer->SwitchSection(Section);
  106. Asm->emitDwarfAbbrevs(Abbreviations);
  107. }
  108. }
  109. // Emit strings into a string section.
  110. void DwarfFile::emitStrings(MCSection *StrSection, MCSection *OffsetSection) {
  111. StrPool.emit(*Asm, StrSection, OffsetSection);
  112. }
  113. bool DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) {
  114. SmallVectorImpl<DbgVariable *> &Vars = ScopeVariables[LS];
  115. const DILocalVariable *DV = Var->getVariable();
  116. // Variables with positive arg numbers are parameters.
  117. if (unsigned ArgNum = DV->getArg()) {
  118. // Keep all parameters in order at the start of the variable list to ensure
  119. // function types are correct (no out-of-order parameters)
  120. //
  121. // This could be improved by only doing it for optimized builds (unoptimized
  122. // builds have the right order to begin with), searching from the back (this
  123. // would catch the unoptimized case quickly), or doing a binary search
  124. // rather than linear search.
  125. auto I = Vars.begin();
  126. while (I != Vars.end()) {
  127. unsigned CurNum = (*I)->getVariable()->getArg();
  128. // A local (non-parameter) variable has been found, insert immediately
  129. // before it.
  130. if (CurNum == 0)
  131. break;
  132. // A later indexed parameter has been found, insert immediately before it.
  133. if (CurNum > ArgNum)
  134. break;
  135. if (CurNum == ArgNum) {
  136. (*I)->addMMIEntry(*Var);
  137. return false;
  138. }
  139. ++I;
  140. }
  141. Vars.insert(I, Var);
  142. return true;
  143. }
  144. Vars.push_back(Var);
  145. return true;
  146. }
  147. }