1 //===-- SourcePrinter.cpp -  source interleaving utilities ----------------===//
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 LiveVariablePrinter and SourcePrinter classes to
10 // keep track of DWARF info as the current address is updated, and print out the
11 // source file line and variable liveness as needed.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "SourcePrinter.h"
16 #include "llvm-objdump.h"
17 #include "llvm/ADT/SmallSet.h"
18 #include "llvm/ADT/StringSet.h"
19 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
20 #include "llvm/MC/MCSubtargetInfo.h"
21 #include "llvm/Support/FormatVariadic.h"
22 
23 #define DEBUG_TYPE "objdump"
24 
25 namespace llvm {
26 namespace objdump {
27 
28 unsigned getInstStartColumn(const MCSubtargetInfo &STI) {
29   return !ShowRawInsn ? 16 : STI.getTargetTriple().isX86() ? 40 : 24;
30 }
31 
32 bool LiveVariable::liveAtAddress(object::SectionedAddress Addr) {
33   if (LocExpr.Range == None)
34     return false;
35   return LocExpr.Range->SectionIndex == Addr.SectionIndex &&
36          LocExpr.Range->LowPC <= Addr.Address &&
37          LocExpr.Range->HighPC > Addr.Address;
38 }
39 
40 void LiveVariable::print(raw_ostream &OS, const MCRegisterInfo &MRI) const {
41   DataExtractor Data({LocExpr.Expr.data(), LocExpr.Expr.size()},
42                      Unit->getContext().isLittleEndian(), 0);
43   DWARFExpression Expression(Data, Unit->getAddressByteSize());
44   Expression.printCompact(OS, MRI);
45 }
46 
47 void LiveVariablePrinter::addVariable(DWARFDie FuncDie, DWARFDie VarDie) {
48   uint64_t FuncLowPC, FuncHighPC, SectionIndex;
49   FuncDie.getLowAndHighPC(FuncLowPC, FuncHighPC, SectionIndex);
50   const char *VarName = VarDie.getName(DINameKind::ShortName);
51   DWARFUnit *U = VarDie.getDwarfUnit();
52 
53   Expected<DWARFLocationExpressionsVector> Locs =
54       VarDie.getLocations(dwarf::DW_AT_location);
55   if (!Locs) {
56     // If the variable doesn't have any locations, just ignore it. We don't
57     // report an error or warning here as that could be noisy on optimised
58     // code.
59     consumeError(Locs.takeError());
60     return;
61   }
62 
63   for (const DWARFLocationExpression &LocExpr : *Locs) {
64     if (LocExpr.Range) {
65       LiveVariables.emplace_back(LocExpr, VarName, U, FuncDie);
66     } else {
67       // If the LocExpr does not have an associated range, it is valid for
68       // the whole of the function.
69       // TODO: technically it is not valid for any range covered by another
70       // LocExpr, does that happen in reality?
71       DWARFLocationExpression WholeFuncExpr{
72           DWARFAddressRange(FuncLowPC, FuncHighPC, SectionIndex), LocExpr.Expr};
73       LiveVariables.emplace_back(WholeFuncExpr, VarName, U, FuncDie);
74     }
75   }
76 }
77 
78 void LiveVariablePrinter::addFunction(DWARFDie D) {
79   for (const DWARFDie &Child : D.children()) {
80     if (Child.getTag() == dwarf::DW_TAG_variable ||
81         Child.getTag() == dwarf::DW_TAG_formal_parameter)
82       addVariable(D, Child);
83     else
84       addFunction(Child);
85   }
86 }
87 
88 // Get the column number (in characters) at which the first live variable
89 // line should be printed.
90 unsigned LiveVariablePrinter::getIndentLevel() const {
91   return DbgIndent + getInstStartColumn(STI);
92 }
93 
94 // Indent to the first live-range column to the right of the currently
95 // printed line, and return the index of that column.
96 // TODO: formatted_raw_ostream uses "column" to mean a number of characters
97 // since the last \n, and we use it to mean the number of slots in which we
98 // put live variable lines. Pick a less overloaded word.
99 unsigned LiveVariablePrinter::moveToFirstVarColumn(formatted_raw_ostream &OS) {
100   // Logical column number: column zero is the first column we print in, each
101   // logical column is 2 physical columns wide.
102   unsigned FirstUnprintedLogicalColumn =
103       std::max((int)(OS.getColumn() - getIndentLevel() + 1) / 2, 0);
104   // Physical column number: the actual column number in characters, with
105   // zero being the left-most side of the screen.
106   unsigned FirstUnprintedPhysicalColumn =
107       getIndentLevel() + FirstUnprintedLogicalColumn * 2;
108 
109   if (FirstUnprintedPhysicalColumn > OS.getColumn())
110     OS.PadToColumn(FirstUnprintedPhysicalColumn);
111 
112   return FirstUnprintedLogicalColumn;
113 }
114 
115 unsigned LiveVariablePrinter::findFreeColumn() {
116   for (unsigned ColIdx = 0; ColIdx < ActiveCols.size(); ++ColIdx)
117     if (!ActiveCols[ColIdx].isActive())
118       return ColIdx;
119 
120   size_t OldSize = ActiveCols.size();
121   ActiveCols.grow(std::max<size_t>(OldSize * 2, 1));
122   return OldSize;
123 }
124 
125 void LiveVariablePrinter::dump() const {
126   for (const LiveVariable &LV : LiveVariables) {
127     dbgs() << LV.VarName << " @ " << LV.LocExpr.Range << ": ";
128     LV.print(dbgs(), MRI);
129     dbgs() << "\n";
130   }
131 }
132 
133 void LiveVariablePrinter::addCompileUnit(DWARFDie D) {
134   if (D.getTag() == dwarf::DW_TAG_subprogram)
135     addFunction(D);
136   else
137     for (const DWARFDie &Child : D.children())
138       addFunction(Child);
139 }
140 
141 /// Update to match the state of the instruction between ThisAddr and
142 /// NextAddr. In the common case, any live range active at ThisAddr is
143 /// live-in to the instruction, and any live range active at NextAddr is
144 /// live-out of the instruction. If IncludeDefinedVars is false, then live
145 /// ranges starting at NextAddr will be ignored.
146 void LiveVariablePrinter::update(object::SectionedAddress ThisAddr,
147                                  object::SectionedAddress NextAddr,
148                                  bool IncludeDefinedVars) {
149   // First, check variables which have already been assigned a column, so
150   // that we don't change their order.
151   SmallSet<unsigned, 8> CheckedVarIdxs;
152   for (unsigned ColIdx = 0, End = ActiveCols.size(); ColIdx < End; ++ColIdx) {
153     if (!ActiveCols[ColIdx].isActive())
154       continue;
155     CheckedVarIdxs.insert(ActiveCols[ColIdx].VarIdx);
156     LiveVariable &LV = LiveVariables[ActiveCols[ColIdx].VarIdx];
157     ActiveCols[ColIdx].LiveIn = LV.liveAtAddress(ThisAddr);
158     ActiveCols[ColIdx].LiveOut = LV.liveAtAddress(NextAddr);
159     LLVM_DEBUG(dbgs() << "pass 1, " << ThisAddr.Address << "-"
160                       << NextAddr.Address << ", " << LV.VarName << ", Col "
161                       << ColIdx << ": LiveIn=" << ActiveCols[ColIdx].LiveIn
162                       << ", LiveOut=" << ActiveCols[ColIdx].LiveOut << "\n");
163 
164     if (!ActiveCols[ColIdx].LiveIn && !ActiveCols[ColIdx].LiveOut)
165       ActiveCols[ColIdx].VarIdx = Column::NullVarIdx;
166   }
167 
168   // Next, look for variables which don't already have a column, but which
169   // are now live.
170   if (IncludeDefinedVars) {
171     for (unsigned VarIdx = 0, End = LiveVariables.size(); VarIdx < End;
172          ++VarIdx) {
173       if (CheckedVarIdxs.count(VarIdx))
174         continue;
175       LiveVariable &LV = LiveVariables[VarIdx];
176       bool LiveIn = LV.liveAtAddress(ThisAddr);
177       bool LiveOut = LV.liveAtAddress(NextAddr);
178       if (!LiveIn && !LiveOut)
179         continue;
180 
181       unsigned ColIdx = findFreeColumn();
182       LLVM_DEBUG(dbgs() << "pass 2, " << ThisAddr.Address << "-"
183                         << NextAddr.Address << ", " << LV.VarName << ", Col "
184                         << ColIdx << ": LiveIn=" << LiveIn
185                         << ", LiveOut=" << LiveOut << "\n");
186       ActiveCols[ColIdx].VarIdx = VarIdx;
187       ActiveCols[ColIdx].LiveIn = LiveIn;
188       ActiveCols[ColIdx].LiveOut = LiveOut;
189       ActiveCols[ColIdx].MustDrawLabel = true;
190     }
191   }
192 }
193 
194 enum class LineChar {
195   RangeStart,
196   RangeMid,
197   RangeEnd,
198   LabelVert,
199   LabelCornerNew,
200   LabelCornerActive,
201   LabelHoriz,
202 };
203 const char *LiveVariablePrinter::getLineChar(LineChar C) const {
204   bool IsASCII = DbgVariables == DVASCII;
205   switch (C) {
206   case LineChar::RangeStart:
207     return IsASCII ? "^" : (const char *)u8"\u2548";
208   case LineChar::RangeMid:
209     return IsASCII ? "|" : (const char *)u8"\u2503";
210   case LineChar::RangeEnd:
211     return IsASCII ? "v" : (const char *)u8"\u253b";
212   case LineChar::LabelVert:
213     return IsASCII ? "|" : (const char *)u8"\u2502";
214   case LineChar::LabelCornerNew:
215     return IsASCII ? "/" : (const char *)u8"\u250c";
216   case LineChar::LabelCornerActive:
217     return IsASCII ? "|" : (const char *)u8"\u2520";
218   case LineChar::LabelHoriz:
219     return IsASCII ? "-" : (const char *)u8"\u2500";
220   }
221   llvm_unreachable("Unhandled LineChar enum");
222 }
223 
224 /// Print live ranges to the right of an existing line. This assumes the
225 /// line is not an instruction, so doesn't start or end any live ranges, so
226 /// we only need to print active ranges or empty columns. If AfterInst is
227 /// true, this is being printed after the last instruction fed to update(),
228 /// otherwise this is being printed before it.
229 void LiveVariablePrinter::printAfterOtherLine(formatted_raw_ostream &OS,
230                                               bool AfterInst) {
231   if (ActiveCols.size()) {
232     unsigned FirstUnprintedColumn = moveToFirstVarColumn(OS);
233     for (size_t ColIdx = FirstUnprintedColumn, End = ActiveCols.size();
234          ColIdx < End; ++ColIdx) {
235       if (ActiveCols[ColIdx].isActive()) {
236         if ((AfterInst && ActiveCols[ColIdx].LiveOut) ||
237             (!AfterInst && ActiveCols[ColIdx].LiveIn))
238           OS << getLineChar(LineChar::RangeMid);
239         else if (!AfterInst && ActiveCols[ColIdx].LiveOut)
240           OS << getLineChar(LineChar::LabelVert);
241         else
242           OS << " ";
243       }
244       OS << " ";
245     }
246   }
247   OS << "\n";
248 }
249 
250 /// Print any live variable range info needed to the right of a
251 /// non-instruction line of disassembly. This is where we print the variable
252 /// names and expressions, with thin line-drawing characters connecting them
253 /// to the live range which starts at the next instruction. If MustPrint is
254 /// true, we have to print at least one line (with the continuation of any
255 /// already-active live ranges) because something has already been printed
256 /// earlier on this line.
257 void LiveVariablePrinter::printBetweenInsts(formatted_raw_ostream &OS,
258                                             bool MustPrint) {
259   bool PrintedSomething = false;
260   for (unsigned ColIdx = 0, End = ActiveCols.size(); ColIdx < End; ++ColIdx) {
261     if (ActiveCols[ColIdx].isActive() && ActiveCols[ColIdx].MustDrawLabel) {
262       // First we need to print the live range markers for any active
263       // columns to the left of this one.
264       OS.PadToColumn(getIndentLevel());
265       for (unsigned ColIdx2 = 0; ColIdx2 < ColIdx; ++ColIdx2) {
266         if (ActiveCols[ColIdx2].isActive()) {
267           if (ActiveCols[ColIdx2].MustDrawLabel && !ActiveCols[ColIdx2].LiveIn)
268             OS << getLineChar(LineChar::LabelVert) << " ";
269           else
270             OS << getLineChar(LineChar::RangeMid) << " ";
271         } else
272           OS << "  ";
273       }
274 
275       // Then print the variable name and location of the new live range,
276       // with box drawing characters joining it to the live range line.
277       OS << getLineChar(ActiveCols[ColIdx].LiveIn ? LineChar::LabelCornerActive
278                                                   : LineChar::LabelCornerNew)
279          << getLineChar(LineChar::LabelHoriz) << " ";
280       WithColor(OS, raw_ostream::GREEN)
281           << LiveVariables[ActiveCols[ColIdx].VarIdx].VarName;
282       OS << " = ";
283       {
284         WithColor ExprColor(OS, raw_ostream::CYAN);
285         LiveVariables[ActiveCols[ColIdx].VarIdx].print(OS, MRI);
286       }
287 
288       // If there are any columns to the right of the expression we just
289       // printed, then continue their live range lines.
290       unsigned FirstUnprintedColumn = moveToFirstVarColumn(OS);
291       for (unsigned ColIdx2 = FirstUnprintedColumn, End = ActiveCols.size();
292            ColIdx2 < End; ++ColIdx2) {
293         if (ActiveCols[ColIdx2].isActive() && ActiveCols[ColIdx2].LiveIn)
294           OS << getLineChar(LineChar::RangeMid) << " ";
295         else
296           OS << "  ";
297       }
298 
299       OS << "\n";
300       PrintedSomething = true;
301     }
302   }
303 
304   for (unsigned ColIdx = 0, End = ActiveCols.size(); ColIdx < End; ++ColIdx)
305     if (ActiveCols[ColIdx].isActive())
306       ActiveCols[ColIdx].MustDrawLabel = false;
307 
308   // If we must print something (because we printed a line/column number),
309   // but don't have any new variables to print, then print a line which
310   // just continues any existing live ranges.
311   if (MustPrint && !PrintedSomething)
312     printAfterOtherLine(OS, false);
313 }
314 
315 /// Print the live variable ranges to the right of a disassembled instruction.
316 void LiveVariablePrinter::printAfterInst(formatted_raw_ostream &OS) {
317   if (!ActiveCols.size())
318     return;
319   unsigned FirstUnprintedColumn = moveToFirstVarColumn(OS);
320   for (unsigned ColIdx = FirstUnprintedColumn, End = ActiveCols.size();
321        ColIdx < End; ++ColIdx) {
322     if (!ActiveCols[ColIdx].isActive())
323       OS << "  ";
324     else if (ActiveCols[ColIdx].LiveIn && ActiveCols[ColIdx].LiveOut)
325       OS << getLineChar(LineChar::RangeMid) << " ";
326     else if (ActiveCols[ColIdx].LiveOut)
327       OS << getLineChar(LineChar::RangeStart) << " ";
328     else if (ActiveCols[ColIdx].LiveIn)
329       OS << getLineChar(LineChar::RangeEnd) << " ";
330     else
331       llvm_unreachable("var must be live in or out!");
332   }
333 }
334 
335 bool SourcePrinter::cacheSource(const DILineInfo &LineInfo) {
336   std::unique_ptr<MemoryBuffer> Buffer;
337   if (LineInfo.Source) {
338     Buffer = MemoryBuffer::getMemBuffer(*LineInfo.Source);
339   } else {
340     auto BufferOrError = MemoryBuffer::getFile(LineInfo.FileName);
341     if (!BufferOrError) {
342       if (MissingSources.insert(LineInfo.FileName).second)
343         reportWarning("failed to find source " + LineInfo.FileName,
344                       Obj->getFileName());
345       return false;
346     }
347     Buffer = std::move(*BufferOrError);
348   }
349   // Chomp the file to get lines
350   const char *BufferStart = Buffer->getBufferStart(),
351              *BufferEnd = Buffer->getBufferEnd();
352   std::vector<StringRef> &Lines = LineCache[LineInfo.FileName];
353   const char *Start = BufferStart;
354   for (const char *I = BufferStart; I != BufferEnd; ++I)
355     if (*I == '\n') {
356       Lines.emplace_back(Start, I - Start - (BufferStart < I && I[-1] == '\r'));
357       Start = I + 1;
358     }
359   if (Start < BufferEnd)
360     Lines.emplace_back(Start, BufferEnd - Start);
361   SourceCache[LineInfo.FileName] = std::move(Buffer);
362   return true;
363 }
364 
365 void SourcePrinter::printSourceLine(formatted_raw_ostream &OS,
366                                     object::SectionedAddress Address,
367                                     StringRef ObjectFilename,
368                                     LiveVariablePrinter &LVP,
369                                     StringRef Delimiter) {
370   if (!Symbolizer)
371     return;
372 
373   DILineInfo LineInfo = DILineInfo();
374   Expected<DILineInfo> ExpectedLineInfo =
375       Symbolizer->symbolizeCode(*Obj, Address);
376   std::string ErrorMessage;
377   if (ExpectedLineInfo) {
378     LineInfo = *ExpectedLineInfo;
379   } else if (!WarnedInvalidDebugInfo) {
380     WarnedInvalidDebugInfo = true;
381     // TODO Untested.
382     reportWarning("failed to parse debug information: " +
383                       toString(ExpectedLineInfo.takeError()),
384                   ObjectFilename);
385   }
386 
387   if (!objdump::Prefix.empty() &&
388       sys::path::is_absolute_gnu(LineInfo.FileName)) {
389     // FileName has at least one character since is_absolute_gnu is false for
390     // an empty string.
391     assert(!LineInfo.FileName.empty());
392     if (PrefixStrip > 0) {
393       uint32_t Level = 0;
394       auto StrippedNameStart = LineInfo.FileName.begin();
395 
396       // Path.h iterator skips extra separators. Therefore it cannot be used
397       // here to keep compatibility with GNU Objdump.
398       for (auto Pos = StrippedNameStart + 1, End = LineInfo.FileName.end();
399            Pos != End && Level < PrefixStrip; ++Pos) {
400         if (sys::path::is_separator(*Pos)) {
401           StrippedNameStart = Pos;
402           ++Level;
403         }
404       }
405 
406       LineInfo.FileName =
407           std::string(StrippedNameStart, LineInfo.FileName.end());
408     }
409 
410     SmallString<128> FilePath;
411     sys::path::append(FilePath, Prefix, LineInfo.FileName);
412 
413     LineInfo.FileName = std::string(FilePath);
414   }
415 
416   if (PrintLines)
417     printLines(OS, LineInfo, Delimiter, LVP);
418   if (PrintSource)
419     printSources(OS, LineInfo, ObjectFilename, Delimiter, LVP);
420   OldLineInfo = LineInfo;
421 }
422 
423 void SourcePrinter::printLines(formatted_raw_ostream &OS,
424                                const DILineInfo &LineInfo, StringRef Delimiter,
425                                LiveVariablePrinter &LVP) {
426   bool PrintFunctionName = LineInfo.FunctionName != DILineInfo::BadString &&
427                            LineInfo.FunctionName != OldLineInfo.FunctionName;
428   if (PrintFunctionName) {
429     OS << Delimiter << LineInfo.FunctionName;
430     // If demangling is successful, FunctionName will end with "()". Print it
431     // only if demangling did not run or was unsuccessful.
432     if (!StringRef(LineInfo.FunctionName).endswith("()"))
433       OS << "()";
434     OS << ":\n";
435   }
436   if (LineInfo.FileName != DILineInfo::BadString && LineInfo.Line != 0 &&
437       (OldLineInfo.Line != LineInfo.Line ||
438        OldLineInfo.FileName != LineInfo.FileName || PrintFunctionName)) {
439     OS << Delimiter << LineInfo.FileName << ":" << LineInfo.Line;
440     LVP.printBetweenInsts(OS, true);
441   }
442 }
443 
444 void SourcePrinter::printSources(formatted_raw_ostream &OS,
445                                  const DILineInfo &LineInfo,
446                                  StringRef ObjectFilename, StringRef Delimiter,
447                                  LiveVariablePrinter &LVP) {
448   if (LineInfo.FileName == DILineInfo::BadString || LineInfo.Line == 0 ||
449       (OldLineInfo.Line == LineInfo.Line &&
450        OldLineInfo.FileName == LineInfo.FileName))
451     return;
452 
453   if (SourceCache.find(LineInfo.FileName) == SourceCache.end())
454     if (!cacheSource(LineInfo))
455       return;
456   auto LineBuffer = LineCache.find(LineInfo.FileName);
457   if (LineBuffer != LineCache.end()) {
458     if (LineInfo.Line > LineBuffer->second.size()) {
459       reportWarning(
460           formatv(
461               "debug info line number {0} exceeds the number of lines in {1}",
462               LineInfo.Line, LineInfo.FileName),
463           ObjectFilename);
464       return;
465     }
466     // Vector begins at 0, line numbers are non-zero
467     OS << Delimiter << LineBuffer->second[LineInfo.Line - 1];
468     LVP.printBetweenInsts(OS, true);
469   }
470 }
471 
472 SourcePrinter::SourcePrinter(const object::ObjectFile *Obj,
473                              StringRef DefaultArch)
474     : Obj(Obj) {
475   symbolize::LLVMSymbolizer::Options SymbolizerOpts;
476   SymbolizerOpts.PrintFunctions =
477       DILineInfoSpecifier::FunctionNameKind::LinkageName;
478   SymbolizerOpts.Demangle = Demangle;
479   SymbolizerOpts.DefaultArch = std::string(DefaultArch);
480   Symbolizer.reset(new symbolize::LLVMSymbolizer(SymbolizerOpts));
481 }
482 
483 } // namespace objdump
484 } // namespace llvm
485