StripSymbols.cpp revision 261991
1//===- StripSymbols.cpp - Strip symbols and debug info from a module ------===// 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// 10// The StripSymbols transformation implements code stripping. Specifically, it 11// can delete: 12// 13// * names for virtual registers 14// * symbols for internal globals and functions 15// * debug information 16// 17// Note that this transformation makes code much less readable, so it should 18// only be used in situations where the 'strip' utility would be used, such as 19// reducing code size or making it harder to reverse engineer code. 20// 21//===----------------------------------------------------------------------===// 22 23#include "llvm/Transforms/IPO.h" 24#include "llvm/ADT/DenseMap.h" 25#include "llvm/ADT/SmallPtrSet.h" 26#include "llvm/DebugInfo.h" 27#include "llvm/IR/Constants.h" 28#include "llvm/IR/DerivedTypes.h" 29#include "llvm/IR/Instructions.h" 30#include "llvm/IR/Module.h" 31#include "llvm/IR/TypeFinder.h" 32#include "llvm/IR/ValueSymbolTable.h" 33#include "llvm/Pass.h" 34#include "llvm/Transforms/Utils/Local.h" 35using namespace llvm; 36 37namespace { 38 class StripSymbols : public ModulePass { 39 bool OnlyDebugInfo; 40 public: 41 static char ID; // Pass identification, replacement for typeid 42 explicit StripSymbols(bool ODI = false) 43 : ModulePass(ID), OnlyDebugInfo(ODI) { 44 initializeStripSymbolsPass(*PassRegistry::getPassRegistry()); 45 } 46 47 virtual bool runOnModule(Module &M); 48 49 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 50 AU.setPreservesAll(); 51 } 52 }; 53 54 class StripNonDebugSymbols : public ModulePass { 55 public: 56 static char ID; // Pass identification, replacement for typeid 57 explicit StripNonDebugSymbols() 58 : ModulePass(ID) { 59 initializeStripNonDebugSymbolsPass(*PassRegistry::getPassRegistry()); 60 } 61 62 virtual bool runOnModule(Module &M); 63 64 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 65 AU.setPreservesAll(); 66 } 67 }; 68 69 class StripDebugDeclare : public ModulePass { 70 public: 71 static char ID; // Pass identification, replacement for typeid 72 explicit StripDebugDeclare() 73 : ModulePass(ID) { 74 initializeStripDebugDeclarePass(*PassRegistry::getPassRegistry()); 75 } 76 77 virtual bool runOnModule(Module &M); 78 79 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 80 AU.setPreservesAll(); 81 } 82 }; 83 84 class StripDeadDebugInfo : public ModulePass { 85 public: 86 static char ID; // Pass identification, replacement for typeid 87 explicit StripDeadDebugInfo() 88 : ModulePass(ID) { 89 initializeStripDeadDebugInfoPass(*PassRegistry::getPassRegistry()); 90 } 91 92 virtual bool runOnModule(Module &M); 93 94 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 95 AU.setPreservesAll(); 96 } 97 }; 98} 99 100char StripSymbols::ID = 0; 101INITIALIZE_PASS(StripSymbols, "strip", 102 "Strip all symbols from a module", false, false) 103 104ModulePass *llvm::createStripSymbolsPass(bool OnlyDebugInfo) { 105 return new StripSymbols(OnlyDebugInfo); 106} 107 108char StripNonDebugSymbols::ID = 0; 109INITIALIZE_PASS(StripNonDebugSymbols, "strip-nondebug", 110 "Strip all symbols, except dbg symbols, from a module", 111 false, false) 112 113ModulePass *llvm::createStripNonDebugSymbolsPass() { 114 return new StripNonDebugSymbols(); 115} 116 117char StripDebugDeclare::ID = 0; 118INITIALIZE_PASS(StripDebugDeclare, "strip-debug-declare", 119 "Strip all llvm.dbg.declare intrinsics", false, false) 120 121ModulePass *llvm::createStripDebugDeclarePass() { 122 return new StripDebugDeclare(); 123} 124 125char StripDeadDebugInfo::ID = 0; 126INITIALIZE_PASS(StripDeadDebugInfo, "strip-dead-debug-info", 127 "Strip debug info for unused symbols", false, false) 128 129ModulePass *llvm::createStripDeadDebugInfoPass() { 130 return new StripDeadDebugInfo(); 131} 132 133/// OnlyUsedBy - Return true if V is only used by Usr. 134static bool OnlyUsedBy(Value *V, Value *Usr) { 135 for(Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) { 136 User *U = *I; 137 if (U != Usr) 138 return false; 139 } 140 return true; 141} 142 143static void RemoveDeadConstant(Constant *C) { 144 assert(C->use_empty() && "Constant is not dead!"); 145 SmallPtrSet<Constant*, 4> Operands; 146 for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) 147 if (OnlyUsedBy(C->getOperand(i), C)) 148 Operands.insert(cast<Constant>(C->getOperand(i))); 149 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) { 150 if (!GV->hasLocalLinkage()) return; // Don't delete non static globals. 151 GV->eraseFromParent(); 152 } 153 else if (!isa<Function>(C)) 154 if (isa<CompositeType>(C->getType())) 155 C->destroyConstant(); 156 157 // If the constant referenced anything, see if we can delete it as well. 158 for (SmallPtrSet<Constant*, 4>::iterator OI = Operands.begin(), 159 OE = Operands.end(); OI != OE; ++OI) 160 RemoveDeadConstant(*OI); 161} 162 163// Strip the symbol table of its names. 164// 165static void StripSymtab(ValueSymbolTable &ST, bool PreserveDbgInfo) { 166 for (ValueSymbolTable::iterator VI = ST.begin(), VE = ST.end(); VI != VE; ) { 167 Value *V = VI->getValue(); 168 ++VI; 169 if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasLocalLinkage()) { 170 if (!PreserveDbgInfo || !V->getName().startswith("llvm.dbg")) 171 // Set name to "", removing from symbol table! 172 V->setName(""); 173 } 174 } 175} 176 177// Strip any named types of their names. 178static void StripTypeNames(Module &M, bool PreserveDbgInfo) { 179 TypeFinder StructTypes; 180 StructTypes.run(M, false); 181 182 for (unsigned i = 0, e = StructTypes.size(); i != e; ++i) { 183 StructType *STy = StructTypes[i]; 184 if (STy->isLiteral() || STy->getName().empty()) continue; 185 186 if (PreserveDbgInfo && STy->getName().startswith("llvm.dbg")) 187 continue; 188 189 STy->setName(""); 190 } 191} 192 193/// Find values that are marked as llvm.used. 194static void findUsedValues(GlobalVariable *LLVMUsed, 195 SmallPtrSet<const GlobalValue*, 8> &UsedValues) { 196 if (LLVMUsed == 0) return; 197 UsedValues.insert(LLVMUsed); 198 199 ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer()); 200 201 for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i) 202 if (GlobalValue *GV = 203 dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts())) 204 UsedValues.insert(GV); 205} 206 207/// StripSymbolNames - Strip symbol names. 208static bool StripSymbolNames(Module &M, bool PreserveDbgInfo) { 209 210 SmallPtrSet<const GlobalValue*, 8> llvmUsedValues; 211 findUsedValues(M.getGlobalVariable("llvm.used"), llvmUsedValues); 212 findUsedValues(M.getGlobalVariable("llvm.compiler.used"), llvmUsedValues); 213 214 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); 215 I != E; ++I) { 216 if (I->hasLocalLinkage() && llvmUsedValues.count(I) == 0) 217 if (!PreserveDbgInfo || !I->getName().startswith("llvm.dbg")) 218 I->setName(""); // Internal symbols can't participate in linkage 219 } 220 221 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { 222 if (I->hasLocalLinkage() && llvmUsedValues.count(I) == 0) 223 if (!PreserveDbgInfo || !I->getName().startswith("llvm.dbg")) 224 I->setName(""); // Internal symbols can't participate in linkage 225 StripSymtab(I->getValueSymbolTable(), PreserveDbgInfo); 226 } 227 228 // Remove all names from types. 229 StripTypeNames(M, PreserveDbgInfo); 230 231 return true; 232} 233 234bool StripSymbols::runOnModule(Module &M) { 235 bool Changed = false; 236 Changed |= StripDebugInfo(M); 237 if (!OnlyDebugInfo) 238 Changed |= StripSymbolNames(M, false); 239 return Changed; 240} 241 242bool StripNonDebugSymbols::runOnModule(Module &M) { 243 return StripSymbolNames(M, true); 244} 245 246bool StripDebugDeclare::runOnModule(Module &M) { 247 248 Function *Declare = M.getFunction("llvm.dbg.declare"); 249 std::vector<Constant*> DeadConstants; 250 251 if (Declare) { 252 while (!Declare->use_empty()) { 253 CallInst *CI = cast<CallInst>(Declare->use_back()); 254 Value *Arg1 = CI->getArgOperand(0); 255 Value *Arg2 = CI->getArgOperand(1); 256 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 257 CI->eraseFromParent(); 258 if (Arg1->use_empty()) { 259 if (Constant *C = dyn_cast<Constant>(Arg1)) 260 DeadConstants.push_back(C); 261 else 262 RecursivelyDeleteTriviallyDeadInstructions(Arg1); 263 } 264 if (Arg2->use_empty()) 265 if (Constant *C = dyn_cast<Constant>(Arg2)) 266 DeadConstants.push_back(C); 267 } 268 Declare->eraseFromParent(); 269 } 270 271 while (!DeadConstants.empty()) { 272 Constant *C = DeadConstants.back(); 273 DeadConstants.pop_back(); 274 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) { 275 if (GV->hasLocalLinkage()) 276 RemoveDeadConstant(GV); 277 } else 278 RemoveDeadConstant(C); 279 } 280 281 return true; 282} 283 284/// Remove any debug info for global variables/functions in the given module for 285/// which said global variable/function no longer exists (i.e. is null). 286/// 287/// Debugging information is encoded in llvm IR using metadata. This is designed 288/// such a way that debug info for symbols preserved even if symbols are 289/// optimized away by the optimizer. This special pass removes debug info for 290/// such symbols. 291bool StripDeadDebugInfo::runOnModule(Module &M) { 292 bool Changed = false; 293 294 LLVMContext &C = M.getContext(); 295 296 // Find all debug info in F. This is actually overkill in terms of what we 297 // want to do, but we want to try and be as resilient as possible in the face 298 // of potential debug info changes by using the formal interfaces given to us 299 // as much as possible. 300 DebugInfoFinder F; 301 F.processModule(M); 302 303 // For each compile unit, find the live set of global variables/functions and 304 // replace the current list of potentially dead global variables/functions 305 // with the live list. 306 SmallVector<Value *, 64> LiveGlobalVariables; 307 SmallVector<Value *, 64> LiveSubprograms; 308 DenseSet<const MDNode *> VisitedSet; 309 310 for (DebugInfoFinder::iterator CI = F.compile_unit_begin(), 311 CE = F.compile_unit_end(); CI != CE; ++CI) { 312 // Create our compile unit. 313 DICompileUnit DIC(*CI); 314 assert(DIC.Verify() && "DIC must verify as a DICompileUnit."); 315 316 // Create our live subprogram list. 317 DIArray SPs = DIC.getSubprograms(); 318 bool SubprogramChange = false; 319 for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { 320 DISubprogram DISP(SPs.getElement(i)); 321 assert(DISP.Verify() && "DISP must verify as a DISubprogram."); 322 323 // Make sure we visit each subprogram only once. 324 if (!VisitedSet.insert(DISP).second) 325 continue; 326 327 // If the function referenced by DISP is not null, the function is live. 328 if (DISP.getFunction()) 329 LiveSubprograms.push_back(DISP); 330 else 331 SubprogramChange = true; 332 } 333 334 // Create our live global variable list. 335 DIArray GVs = DIC.getGlobalVariables(); 336 bool GlobalVariableChange = false; 337 for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i) { 338 DIGlobalVariable DIG(GVs.getElement(i)); 339 assert(DIG.Verify() && "DIG must verify as DIGlobalVariable."); 340 341 // Make sure we only visit each global variable only once. 342 if (!VisitedSet.insert(DIG).second) 343 continue; 344 345 // If the global variable referenced by DIG is not null, the global 346 // variable is live. 347 if (DIG.getGlobal()) 348 LiveGlobalVariables.push_back(DIG); 349 else 350 GlobalVariableChange = true; 351 } 352 353 // If we found dead subprograms or global variables, replace the current 354 // subprogram list/global variable list with our new live subprogram/global 355 // variable list. 356 if (SubprogramChange) { 357 // Make sure that 9 is still the index of the subprograms. This is to make 358 // sure that an assert is hit if the location of the subprogram array 359 // changes. This is just to make sure that this is updated if such an 360 // event occurs. 361 assert(DIC->getNumOperands() >= 10 && 362 SPs == DIC->getOperand(9) && 363 "DICompileUnits is expected to store Subprograms in operand " 364 "9."); 365 DIC->replaceOperandWith(9, MDNode::get(C, LiveSubprograms)); 366 Changed = true; 367 } 368 369 if (GlobalVariableChange) { 370 // Make sure that 10 is still the index of global variables. This is to 371 // make sure that an assert is hit if the location of the subprogram array 372 // changes. This is just to make sure that this index is updated if such 373 // an event occurs. 374 assert(DIC->getNumOperands() >= 11 && 375 GVs == DIC->getOperand(10) && 376 "DICompileUnits is expected to store Global Variables in operand " 377 "10."); 378 DIC->replaceOperandWith(10, MDNode::get(C, LiveGlobalVariables)); 379 Changed = true; 380 } 381 382 // Reset lists for the next iteration. 383 LiveSubprograms.clear(); 384 LiveGlobalVariables.clear(); 385 } 386 387 return Changed; 388} 389