1 //===- Debugify.cpp - Attach synthetic debug info to everything -----------===//
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 /// \file This pass attaches synthetic debug info to everything. It can be used
10 /// to create targeted tests for debug info preservation.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/ADT/BitVector.h"
15 #include "llvm/ADT/StringExtras.h"
16 #include "llvm/IR/DIBuilder.h"
17 #include "llvm/IR/DebugInfo.h"
18 #include "llvm/IR/InstIterator.h"
19 #include "llvm/IR/Instructions.h"
20 #include "llvm/IR/IntrinsicInst.h"
21 #include "llvm/IR/Module.h"
22 #include "llvm/Pass.h"
23 #include "llvm/Transforms/Utils/Debugify.h"
24 
25 using namespace llvm;
26 
27 namespace {
28 
29 cl::opt<bool> Quiet("debugify-quiet",
30                     cl::desc("Suppress verbose debugify output"));
31 
32 raw_ostream &dbg() { return Quiet ? nulls() : errs(); }
33 
34 uint64_t getAllocSizeInBits(Module &M, Type *Ty) {
35   return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0;
36 }
37 
38 bool isFunctionSkipped(Function &F) {
39   return F.isDeclaration() || !F.hasExactDefinition();
40 }
41 
42 /// Find the basic block's terminating instruction.
43 ///
44 /// Special care is needed to handle musttail and deopt calls, as these behave
45 /// like (but are in fact not) terminators.
46 Instruction *findTerminatingInstruction(BasicBlock &BB) {
47   if (auto *I = BB.getTerminatingMustTailCall())
48     return I;
49   if (auto *I = BB.getTerminatingDeoptimizeCall())
50     return I;
51   return BB.getTerminator();
52 }
53 
54 bool applyDebugifyMetadata(Module &M,
55                            iterator_range<Module::iterator> Functions,
56                            StringRef Banner) {
57   // Skip modules with debug info.
58   if (M.getNamedMetadata("llvm.dbg.cu")) {
59     dbg() << Banner << "Skipping module with debug info\n";
60     return false;
61   }
62 
63   DIBuilder DIB(M);
64   LLVMContext &Ctx = M.getContext();
65 
66   // Get a DIType which corresponds to Ty.
67   DenseMap<uint64_t, DIType *> TypeCache;
68   auto getCachedDIType = [&](Type *Ty) -> DIType * {
69     uint64_t Size = getAllocSizeInBits(M, Ty);
70     DIType *&DTy = TypeCache[Size];
71     if (!DTy) {
72       std::string Name = "ty" + utostr(Size);
73       DTy = DIB.createBasicType(Name, Size, dwarf::DW_ATE_unsigned);
74     }
75     return DTy;
76   };
77 
78   unsigned NextLine = 1;
79   unsigned NextVar = 1;
80   auto File = DIB.createFile(M.getName(), "/");
81   auto CU = DIB.createCompileUnit(dwarf::DW_LANG_C, File, "debugify",
82                                   /*isOptimized=*/true, "", 0);
83 
84   // Visit each instruction.
85   for (Function &F : Functions) {
86     if (isFunctionSkipped(F))
87       continue;
88 
89     auto SPType = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None));
90     DISubprogram::DISPFlags SPFlags =
91         DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized;
92     if (F.hasPrivateLinkage() || F.hasInternalLinkage())
93       SPFlags |= DISubprogram::SPFlagLocalToUnit;
94     auto SP = DIB.createFunction(CU, F.getName(), F.getName(), File, NextLine,
95                                  SPType, NextLine, DINode::FlagZero, SPFlags);
96     F.setSubprogram(SP);
97     for (BasicBlock &BB : F) {
98       // Attach debug locations.
99       for (Instruction &I : BB)
100         I.setDebugLoc(DILocation::get(Ctx, NextLine++, 1, SP));
101 
102       // Inserting debug values into EH pads can break IR invariants.
103       if (BB.isEHPad())
104         continue;
105 
106       // Find the terminating instruction, after which no debug values are
107       // attached.
108       Instruction *LastInst = findTerminatingInstruction(BB);
109       assert(LastInst && "Expected basic block with a terminator");
110 
111       // Maintain an insertion point which can't be invalidated when updates
112       // are made.
113       BasicBlock::iterator InsertPt = BB.getFirstInsertionPt();
114       assert(InsertPt != BB.end() && "Expected to find an insertion point");
115       Instruction *InsertBefore = &*InsertPt;
116 
117       // Attach debug values.
118       for (Instruction *I = &*BB.begin(); I != LastInst; I = I->getNextNode()) {
119         // Skip void-valued instructions.
120         if (I->getType()->isVoidTy())
121           continue;
122 
123         // Phis and EH pads must be grouped at the beginning of the block.
124         // Only advance the insertion point when we finish visiting these.
125         if (!isa<PHINode>(I) && !I->isEHPad())
126           InsertBefore = I->getNextNode();
127 
128         std::string Name = utostr(NextVar++);
129         const DILocation *Loc = I->getDebugLoc().get();
130         auto LocalVar = DIB.createAutoVariable(SP, Name, File, Loc->getLine(),
131                                                getCachedDIType(I->getType()),
132                                                /*AlwaysPreserve=*/true);
133         DIB.insertDbgValueIntrinsic(I, LocalVar, DIB.createExpression(), Loc,
134                                     InsertBefore);
135       }
136     }
137     DIB.finalizeSubprogram(SP);
138   }
139   DIB.finalize();
140 
141   // Track the number of distinct lines and variables.
142   NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.debugify");
143   auto *IntTy = Type::getInt32Ty(Ctx);
144   auto addDebugifyOperand = [&](unsigned N) {
145     NMD->addOperand(MDNode::get(
146         Ctx, ValueAsMetadata::getConstant(ConstantInt::get(IntTy, N))));
147   };
148   addDebugifyOperand(NextLine - 1); // Original number of lines.
149   addDebugifyOperand(NextVar - 1);  // Original number of variables.
150   assert(NMD->getNumOperands() == 2 &&
151          "llvm.debugify should have exactly 2 operands!");
152 
153   // Claim that this synthetic debug info is valid.
154   StringRef DIVersionKey = "Debug Info Version";
155   if (!M.getModuleFlag(DIVersionKey))
156     M.addModuleFlag(Module::Warning, DIVersionKey, DEBUG_METADATA_VERSION);
157 
158   return true;
159 }
160 
161 /// Return true if a mis-sized diagnostic is issued for \p DVI.
162 bool diagnoseMisSizedDbgValue(Module &M, DbgValueInst *DVI) {
163   // The size of a dbg.value's value operand should match the size of the
164   // variable it corresponds to.
165   //
166   // TODO: This, along with a check for non-null value operands, should be
167   // promoted to verifier failures.
168   Value *V = DVI->getValue();
169   if (!V)
170     return false;
171 
172   // For now, don't try to interpret anything more complicated than an empty
173   // DIExpression. Eventually we should try to handle OP_deref and fragments.
174   if (DVI->getExpression()->getNumElements())
175     return false;
176 
177   Type *Ty = V->getType();
178   uint64_t ValueOperandSize = getAllocSizeInBits(M, Ty);
179   Optional<uint64_t> DbgVarSize = DVI->getFragmentSizeInBits();
180   if (!ValueOperandSize || !DbgVarSize)
181     return false;
182 
183   bool HasBadSize = false;
184   if (Ty->isIntegerTy()) {
185     auto Signedness = DVI->getVariable()->getSignedness();
186     if (Signedness && *Signedness == DIBasicType::Signedness::Signed)
187       HasBadSize = ValueOperandSize < *DbgVarSize;
188   } else {
189     HasBadSize = ValueOperandSize != *DbgVarSize;
190   }
191 
192   if (HasBadSize) {
193     dbg() << "ERROR: dbg.value operand has size " << ValueOperandSize
194           << ", but its variable has size " << *DbgVarSize << ": ";
195     DVI->print(dbg());
196     dbg() << "\n";
197   }
198   return HasBadSize;
199 }
200 
201 bool checkDebugifyMetadata(Module &M,
202                            iterator_range<Module::iterator> Functions,
203                            StringRef NameOfWrappedPass, StringRef Banner,
204                            bool Strip, DebugifyStatsMap *StatsMap) {
205   // Skip modules without debugify metadata.
206   NamedMDNode *NMD = M.getNamedMetadata("llvm.debugify");
207   if (!NMD) {
208     dbg() << Banner << "Skipping module without debugify metadata\n";
209     return false;
210   }
211 
212   auto getDebugifyOperand = [&](unsigned Idx) -> unsigned {
213     return mdconst::extract<ConstantInt>(NMD->getOperand(Idx)->getOperand(0))
214         ->getZExtValue();
215   };
216   assert(NMD->getNumOperands() == 2 &&
217          "llvm.debugify should have exactly 2 operands!");
218   unsigned OriginalNumLines = getDebugifyOperand(0);
219   unsigned OriginalNumVars = getDebugifyOperand(1);
220   bool HasErrors = false;
221 
222   // Track debug info loss statistics if able.
223   DebugifyStatistics *Stats = nullptr;
224   if (StatsMap && !NameOfWrappedPass.empty())
225     Stats = &StatsMap->operator[](NameOfWrappedPass);
226 
227   BitVector MissingLines{OriginalNumLines, true};
228   BitVector MissingVars{OriginalNumVars, true};
229   for (Function &F : Functions) {
230     if (isFunctionSkipped(F))
231       continue;
232 
233     // Find missing lines.
234     for (Instruction &I : instructions(F)) {
235       if (isa<DbgValueInst>(&I))
236         continue;
237 
238       auto DL = I.getDebugLoc();
239       if (DL && DL.getLine() != 0) {
240         MissingLines.reset(DL.getLine() - 1);
241         continue;
242       }
243 
244       if (!DL) {
245         dbg() << "ERROR: Instruction with empty DebugLoc in function ";
246         dbg() << F.getName() << " --";
247         I.print(dbg());
248         dbg() << "\n";
249         HasErrors = true;
250       }
251     }
252 
253     // Find missing variables and mis-sized debug values.
254     for (Instruction &I : instructions(F)) {
255       auto *DVI = dyn_cast<DbgValueInst>(&I);
256       if (!DVI)
257         continue;
258 
259       unsigned Var = ~0U;
260       (void)to_integer(DVI->getVariable()->getName(), Var, 10);
261       assert(Var <= OriginalNumVars && "Unexpected name for DILocalVariable");
262       bool HasBadSize = diagnoseMisSizedDbgValue(M, DVI);
263       if (!HasBadSize)
264         MissingVars.reset(Var - 1);
265       HasErrors |= HasBadSize;
266     }
267   }
268 
269   // Print the results.
270   for (unsigned Idx : MissingLines.set_bits())
271     dbg() << "WARNING: Missing line " << Idx + 1 << "\n";
272 
273   for (unsigned Idx : MissingVars.set_bits())
274     dbg() << "WARNING: Missing variable " << Idx + 1 << "\n";
275 
276   // Update DI loss statistics.
277   if (Stats) {
278     Stats->NumDbgLocsExpected += OriginalNumLines;
279     Stats->NumDbgLocsMissing += MissingLines.count();
280     Stats->NumDbgValuesExpected += OriginalNumVars;
281     Stats->NumDbgValuesMissing += MissingVars.count();
282   }
283 
284   dbg() << Banner;
285   if (!NameOfWrappedPass.empty())
286     dbg() << " [" << NameOfWrappedPass << "]";
287   dbg() << ": " << (HasErrors ? "FAIL" : "PASS") << '\n';
288 
289   // Strip the Debugify Metadata if required.
290   if (Strip) {
291     StripDebugInfo(M);
292     M.eraseNamedMetadata(NMD);
293     return true;
294   }
295 
296   return false;
297 }
298 
299 /// ModulePass for attaching synthetic debug info to everything, used with the
300 /// legacy module pass manager.
301 struct DebugifyModulePass : public ModulePass {
302   bool runOnModule(Module &M) override {
303     return applyDebugifyMetadata(M, M.functions(), "ModuleDebugify: ");
304   }
305 
306   DebugifyModulePass() : ModulePass(ID) {}
307 
308   void getAnalysisUsage(AnalysisUsage &AU) const override {
309     AU.setPreservesAll();
310   }
311 
312   static char ID; // Pass identification.
313 };
314 
315 /// FunctionPass for attaching synthetic debug info to instructions within a
316 /// single function, used with the legacy module pass manager.
317 struct DebugifyFunctionPass : public FunctionPass {
318   bool runOnFunction(Function &F) override {
319     Module &M = *F.getParent();
320     auto FuncIt = F.getIterator();
321     return applyDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)),
322                                  "FunctionDebugify: ");
323   }
324 
325   DebugifyFunctionPass() : FunctionPass(ID) {}
326 
327   void getAnalysisUsage(AnalysisUsage &AU) const override {
328     AU.setPreservesAll();
329   }
330 
331   static char ID; // Pass identification.
332 };
333 
334 /// ModulePass for checking debug info inserted by -debugify, used with the
335 /// legacy module pass manager.
336 struct CheckDebugifyModulePass : public ModulePass {
337   bool runOnModule(Module &M) override {
338     return checkDebugifyMetadata(M, M.functions(), NameOfWrappedPass,
339                                  "CheckModuleDebugify", Strip, StatsMap);
340   }
341 
342   CheckDebugifyModulePass(bool Strip = false, StringRef NameOfWrappedPass = "",
343                           DebugifyStatsMap *StatsMap = nullptr)
344       : ModulePass(ID), Strip(Strip), NameOfWrappedPass(NameOfWrappedPass),
345         StatsMap(StatsMap) {}
346 
347   void getAnalysisUsage(AnalysisUsage &AU) const override {
348     AU.setPreservesAll();
349   }
350 
351   static char ID; // Pass identification.
352 
353 private:
354   bool Strip;
355   StringRef NameOfWrappedPass;
356   DebugifyStatsMap *StatsMap;
357 };
358 
359 /// FunctionPass for checking debug info inserted by -debugify-function, used
360 /// with the legacy module pass manager.
361 struct CheckDebugifyFunctionPass : public FunctionPass {
362   bool runOnFunction(Function &F) override {
363     Module &M = *F.getParent();
364     auto FuncIt = F.getIterator();
365     return checkDebugifyMetadata(M, make_range(FuncIt, std::next(FuncIt)),
366                                  NameOfWrappedPass, "CheckFunctionDebugify",
367                                  Strip, StatsMap);
368   }
369 
370   CheckDebugifyFunctionPass(bool Strip = false,
371                             StringRef NameOfWrappedPass = "",
372                             DebugifyStatsMap *StatsMap = nullptr)
373       : FunctionPass(ID), Strip(Strip), NameOfWrappedPass(NameOfWrappedPass),
374         StatsMap(StatsMap) {}
375 
376   void getAnalysisUsage(AnalysisUsage &AU) const override {
377     AU.setPreservesAll();
378   }
379 
380   static char ID; // Pass identification.
381 
382 private:
383   bool Strip;
384   StringRef NameOfWrappedPass;
385   DebugifyStatsMap *StatsMap;
386 };
387 
388 } // end anonymous namespace
389 
390 ModulePass *createDebugifyModulePass() { return new DebugifyModulePass(); }
391 
392 FunctionPass *createDebugifyFunctionPass() {
393   return new DebugifyFunctionPass();
394 }
395 
396 PreservedAnalyses NewPMDebugifyPass::run(Module &M, ModuleAnalysisManager &) {
397   applyDebugifyMetadata(M, M.functions(), "ModuleDebugify: ");
398   return PreservedAnalyses::all();
399 }
400 
401 ModulePass *createCheckDebugifyModulePass(bool Strip,
402                                           StringRef NameOfWrappedPass,
403                                           DebugifyStatsMap *StatsMap) {
404   return new CheckDebugifyModulePass(Strip, NameOfWrappedPass, StatsMap);
405 }
406 
407 FunctionPass *createCheckDebugifyFunctionPass(bool Strip,
408                                               StringRef NameOfWrappedPass,
409                                               DebugifyStatsMap *StatsMap) {
410   return new CheckDebugifyFunctionPass(Strip, NameOfWrappedPass, StatsMap);
411 }
412 
413 PreservedAnalyses NewPMCheckDebugifyPass::run(Module &M,
414                                               ModuleAnalysisManager &) {
415   checkDebugifyMetadata(M, M.functions(), "", "CheckModuleDebugify", false,
416                         nullptr);
417   return PreservedAnalyses::all();
418 }
419 
420 char DebugifyModulePass::ID = 0;
421 static RegisterPass<DebugifyModulePass> DM("debugify",
422                                            "Attach debug info to everything");
423 
424 char CheckDebugifyModulePass::ID = 0;
425 static RegisterPass<CheckDebugifyModulePass>
426     CDM("check-debugify", "Check debug info from -debugify");
427 
428 char DebugifyFunctionPass::ID = 0;
429 static RegisterPass<DebugifyFunctionPass> DF("debugify-function",
430                                              "Attach debug info to a function");
431 
432 char CheckDebugifyFunctionPass::ID = 0;
433 static RegisterPass<CheckDebugifyFunctionPass>
434     CDF("check-debugify-function", "Check debug info from -debugify-function");
435