SourcePrinter.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. //===-- SourcePrinter.h - source interleaving utilities --------*- C++ -*-===//
  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. #ifndef LLVM_TOOLS_LLVM_OBJDUMP_SOURCEPRINTER_H
  9. #define LLVM_TOOLS_LLVM_OBJDUMP_SOURCEPRINTER_H
  10. #include "llvm/ADT/IndexedMap.h"
  11. #include "llvm/ADT/StringSet.h"
  12. #include "llvm/DebugInfo/DWARF/DWARFContext.h"
  13. #include "llvm/DebugInfo/Symbolize/Symbolize.h"
  14. #include "llvm/Support/FormattedStream.h"
  15. #include <unordered_map>
  16. #include <vector>
  17. namespace llvm {
  18. namespace objdump {
  19. /// Stores a single expression representing the location of a source-level
  20. /// variable, along with the PC range for which that expression is valid.
  21. struct LiveVariable {
  22. DWARFLocationExpression LocExpr;
  23. const char *VarName;
  24. DWARFUnit *Unit;
  25. const DWARFDie FuncDie;
  26. LiveVariable(const DWARFLocationExpression &LocExpr, const char *VarName,
  27. DWARFUnit *Unit, const DWARFDie FuncDie)
  28. : LocExpr(LocExpr), VarName(VarName), Unit(Unit), FuncDie(FuncDie) {}
  29. bool liveAtAddress(object::SectionedAddress Addr);
  30. void print(raw_ostream &OS, const MCRegisterInfo &MRI) const;
  31. };
  32. /// Helper class for printing source variable locations alongside disassembly.
  33. class LiveVariablePrinter {
  34. // Information we want to track about one column in which we are printing a
  35. // variable live range.
  36. struct Column {
  37. unsigned VarIdx = NullVarIdx;
  38. bool LiveIn = false;
  39. bool LiveOut = false;
  40. bool MustDrawLabel = false;
  41. bool isActive() const { return VarIdx != NullVarIdx; }
  42. static constexpr unsigned NullVarIdx = std::numeric_limits<unsigned>::max();
  43. };
  44. // All live variables we know about in the object/image file.
  45. std::vector<LiveVariable> LiveVariables;
  46. // The columns we are currently drawing.
  47. IndexedMap<Column> ActiveCols;
  48. const MCRegisterInfo &MRI;
  49. const MCSubtargetInfo &STI;
  50. void addVariable(DWARFDie FuncDie, DWARFDie VarDie);
  51. void addFunction(DWARFDie D);
  52. // Get the column number (in characters) at which the first live variable
  53. // line should be printed.
  54. unsigned getIndentLevel() const;
  55. // Indent to the first live-range column to the right of the currently
  56. // printed line, and return the index of that column.
  57. // TODO: formatted_raw_ostream uses "column" to mean a number of characters
  58. // since the last \n, and we use it to mean the number of slots in which we
  59. // put live variable lines. Pick a less overloaded word.
  60. unsigned moveToFirstVarColumn(formatted_raw_ostream &OS);
  61. unsigned findFreeColumn();
  62. public:
  63. LiveVariablePrinter(const MCRegisterInfo &MRI, const MCSubtargetInfo &STI)
  64. : ActiveCols(Column()), MRI(MRI), STI(STI) {}
  65. void dump() const;
  66. void addCompileUnit(DWARFDie D);
  67. /// Update to match the state of the instruction between ThisAddr and
  68. /// NextAddr. In the common case, any live range active at ThisAddr is
  69. /// live-in to the instruction, and any live range active at NextAddr is
  70. /// live-out of the instruction. If IncludeDefinedVars is false, then live
  71. /// ranges starting at NextAddr will be ignored.
  72. void update(object::SectionedAddress ThisAddr,
  73. object::SectionedAddress NextAddr, bool IncludeDefinedVars);
  74. enum class LineChar {
  75. RangeStart,
  76. RangeMid,
  77. RangeEnd,
  78. LabelVert,
  79. LabelCornerNew,
  80. LabelCornerActive,
  81. LabelHoriz,
  82. };
  83. const char *getLineChar(LineChar C) const;
  84. /// Print live ranges to the right of an existing line. This assumes the
  85. /// line is not an instruction, so doesn't start or end any live ranges, so
  86. /// we only need to print active ranges or empty columns. If AfterInst is
  87. /// true, this is being printed after the last instruction fed to update(),
  88. /// otherwise this is being printed before it.
  89. void printAfterOtherLine(formatted_raw_ostream &OS, bool AfterInst);
  90. /// Print any live variable range info needed to the right of a
  91. /// non-instruction line of disassembly. This is where we print the variable
  92. /// names and expressions, with thin line-drawing characters connecting them
  93. /// to the live range which starts at the next instruction. If MustPrint is
  94. /// true, we have to print at least one line (with the continuation of any
  95. /// already-active live ranges) because something has already been printed
  96. /// earlier on this line.
  97. void printBetweenInsts(formatted_raw_ostream &OS, bool MustPrint);
  98. /// Print the live variable ranges to the right of a disassembled instruction.
  99. void printAfterInst(formatted_raw_ostream &OS);
  100. };
  101. class SourcePrinter {
  102. protected:
  103. DILineInfo OldLineInfo;
  104. const object::ObjectFile *Obj = nullptr;
  105. std::unique_ptr<symbolize::LLVMSymbolizer> Symbolizer;
  106. // File name to file contents of source.
  107. std::unordered_map<std::string, std::unique_ptr<MemoryBuffer>> SourceCache;
  108. // Mark the line endings of the cached source.
  109. std::unordered_map<std::string, std::vector<StringRef>> LineCache;
  110. // Keep track of missing sources.
  111. StringSet<> MissingSources;
  112. // Only emit 'invalid debug info' warning once.
  113. bool WarnedInvalidDebugInfo = false;
  114. private:
  115. bool cacheSource(const DILineInfo &LineInfoFile);
  116. void printLines(formatted_raw_ostream &OS, const DILineInfo &LineInfo,
  117. StringRef Delimiter, LiveVariablePrinter &LVP);
  118. void printSources(formatted_raw_ostream &OS, const DILineInfo &LineInfo,
  119. StringRef ObjectFilename, StringRef Delimiter,
  120. LiveVariablePrinter &LVP);
  121. public:
  122. SourcePrinter() = default;
  123. SourcePrinter(const object::ObjectFile *Obj, StringRef DefaultArch);
  124. virtual ~SourcePrinter() = default;
  125. virtual void printSourceLine(formatted_raw_ostream &OS,
  126. object::SectionedAddress Address,
  127. StringRef ObjectFilename,
  128. LiveVariablePrinter &LVP,
  129. StringRef Delimiter = "; ");
  130. };
  131. } // namespace objdump
  132. } // namespace llvm
  133. #endif