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