DwarfFile.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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 "DwarfCompileUnit.h"
  11. #include "DwarfDebug.h"
  12. #include "DwarfUnit.h"
  13. #include "llvm/ADT/SmallVector.h"
  14. #include "llvm/CodeGen/AsmPrinter.h"
  15. #include "llvm/CodeGen/DIE.h"
  16. #include "llvm/IR/DebugInfoMetadata.h"
  17. #include "llvm/MC/MCStreamer.h"
  18. #include <algorithm>
  19. #include <cstdint>
  20. using namespace llvm;
  21. DwarfFile::DwarfFile(AsmPrinter *AP, StringRef Pref, BumpPtrAllocator &DA)
  22. : Asm(AP), Abbrevs(AbbrevAllocator), StrPool(DA, *Asm, Pref) {}
  23. void DwarfFile::addUnit(std::unique_ptr<DwarfCompileUnit> U) {
  24. CUs.push_back(std::move(U));
  25. }
  26. // Emit the various dwarf units to the unit section USection with
  27. // the abbreviations going into ASection.
  28. void DwarfFile::emitUnits(bool UseOffsets) {
  29. for (const auto &TheU : CUs)
  30. emitUnit(TheU.get(), UseOffsets);
  31. }
  32. void DwarfFile::emitUnit(DwarfUnit *TheU, bool UseOffsets) {
  33. if (TheU->getCUNode()->isDebugDirectivesOnly())
  34. return;
  35. DIE &Die = TheU->getUnitDie();
  36. MCSection *USection = TheU->getSection();
  37. Asm->OutStreamer->SwitchSection(USection);
  38. TheU->emitHeader(UseOffsets);
  39. Asm->emitDwarfDIE(Die);
  40. }
  41. // Compute the size and offset for each DIE.
  42. void DwarfFile::computeSizeAndOffsets() {
  43. // Offset from the first CU in the debug info section is 0 initially.
  44. unsigned SecOffset = 0;
  45. // Iterate over each compile unit and set the size and offsets for each
  46. // DIE within each compile unit. All offsets are CU relative.
  47. for (const auto &TheU : CUs) {
  48. if (TheU->getCUNode()->isDebugDirectivesOnly())
  49. continue;
  50. TheU->setDebugSectionOffset(SecOffset);
  51. SecOffset += computeSizeAndOffsetsForUnit(TheU.get());
  52. }
  53. }
  54. unsigned DwarfFile::computeSizeAndOffsetsForUnit(DwarfUnit *TheU) {
  55. // CU-relative offset is reset to 0 here.
  56. unsigned Offset = sizeof(int32_t) + // Length of Unit Info
  57. TheU->getHeaderSize(); // Unit-specific headers
  58. // The return value here is CU-relative, after laying out
  59. // all of the CU DIE.
  60. return computeSizeAndOffset(TheU->getUnitDie(), Offset);
  61. }
  62. // Compute the size and offset of a DIE. The offset is relative to start of the
  63. // CU. It returns the offset after laying out the DIE.
  64. unsigned DwarfFile::computeSizeAndOffset(DIE &Die, unsigned Offset) {
  65. return Die.computeOffsetsAndAbbrevs(Asm, Abbrevs, Offset);
  66. }
  67. void DwarfFile::emitAbbrevs(MCSection *Section) { Abbrevs.Emit(Asm, Section); }
  68. // Emit strings into a string section.
  69. void DwarfFile::emitStrings(MCSection *StrSection, MCSection *OffsetSection,
  70. bool UseRelativeOffsets) {
  71. StrPool.emit(*Asm, StrSection, OffsetSection, UseRelativeOffsets);
  72. }
  73. bool DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) {
  74. auto &ScopeVars = ScopeVariables[LS];
  75. const DILocalVariable *DV = Var->getVariable();
  76. if (unsigned ArgNum = DV->getArg()) {
  77. auto Cached = ScopeVars.Args.find(ArgNum);
  78. if (Cached == ScopeVars.Args.end())
  79. ScopeVars.Args[ArgNum] = Var;
  80. else {
  81. Cached->second->addMMIEntry(*Var);
  82. return false;
  83. }
  84. } else {
  85. ScopeVars.Locals.push_back(Var);
  86. }
  87. return true;
  88. }