LLVM API Documentation
00001 //===- StripSymbols.cpp - Strip symbols and debug info from a module ------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // The StripSymbols transformation implements code stripping. Specifically, it 00011 // can delete: 00012 // 00013 // * names for virtual registers 00014 // * symbols for internal globals and functions 00015 // * debug information 00016 // 00017 // Note that this transformation makes code much less readable, so it should 00018 // only be used in situations where the 'strip' utility would be used, such as 00019 // reducing code size or making it harder to reverse engineer code. 00020 // 00021 //===----------------------------------------------------------------------===// 00022 00023 #include "llvm/Transforms/IPO.h" 00024 #include "llvm/ADT/DenseMap.h" 00025 #include "llvm/ADT/SmallPtrSet.h" 00026 #include "llvm/IR/Constants.h" 00027 #include "llvm/IR/DebugInfo.h" 00028 #include "llvm/IR/DerivedTypes.h" 00029 #include "llvm/IR/Instructions.h" 00030 #include "llvm/IR/Module.h" 00031 #include "llvm/IR/TypeFinder.h" 00032 #include "llvm/IR/ValueSymbolTable.h" 00033 #include "llvm/Pass.h" 00034 #include "llvm/Transforms/Utils/Local.h" 00035 using namespace llvm; 00036 00037 namespace { 00038 class StripSymbols : public ModulePass { 00039 bool OnlyDebugInfo; 00040 public: 00041 static char ID; // Pass identification, replacement for typeid 00042 explicit StripSymbols(bool ODI = false) 00043 : ModulePass(ID), OnlyDebugInfo(ODI) { 00044 initializeStripSymbolsPass(*PassRegistry::getPassRegistry()); 00045 } 00046 00047 bool runOnModule(Module &M) override; 00048 00049 void getAnalysisUsage(AnalysisUsage &AU) const override { 00050 AU.setPreservesAll(); 00051 } 00052 }; 00053 00054 class StripNonDebugSymbols : public ModulePass { 00055 public: 00056 static char ID; // Pass identification, replacement for typeid 00057 explicit StripNonDebugSymbols() 00058 : ModulePass(ID) { 00059 initializeStripNonDebugSymbolsPass(*PassRegistry::getPassRegistry()); 00060 } 00061 00062 bool runOnModule(Module &M) override; 00063 00064 void getAnalysisUsage(AnalysisUsage &AU) const override { 00065 AU.setPreservesAll(); 00066 } 00067 }; 00068 00069 class StripDebugDeclare : public ModulePass { 00070 public: 00071 static char ID; // Pass identification, replacement for typeid 00072 explicit StripDebugDeclare() 00073 : ModulePass(ID) { 00074 initializeStripDebugDeclarePass(*PassRegistry::getPassRegistry()); 00075 } 00076 00077 bool runOnModule(Module &M) override; 00078 00079 void getAnalysisUsage(AnalysisUsage &AU) const override { 00080 AU.setPreservesAll(); 00081 } 00082 }; 00083 00084 class StripDeadDebugInfo : public ModulePass { 00085 public: 00086 static char ID; // Pass identification, replacement for typeid 00087 explicit StripDeadDebugInfo() 00088 : ModulePass(ID) { 00089 initializeStripDeadDebugInfoPass(*PassRegistry::getPassRegistry()); 00090 } 00091 00092 bool runOnModule(Module &M) override; 00093 00094 void getAnalysisUsage(AnalysisUsage &AU) const override { 00095 AU.setPreservesAll(); 00096 } 00097 }; 00098 } 00099 00100 char StripSymbols::ID = 0; 00101 INITIALIZE_PASS(StripSymbols, "strip", 00102 "Strip all symbols from a module", false, false) 00103 00104 ModulePass *llvm::createStripSymbolsPass(bool OnlyDebugInfo) { 00105 return new StripSymbols(OnlyDebugInfo); 00106 } 00107 00108 char StripNonDebugSymbols::ID = 0; 00109 INITIALIZE_PASS(StripNonDebugSymbols, "strip-nondebug", 00110 "Strip all symbols, except dbg symbols, from a module", 00111 false, false) 00112 00113 ModulePass *llvm::createStripNonDebugSymbolsPass() { 00114 return new StripNonDebugSymbols(); 00115 } 00116 00117 char StripDebugDeclare::ID = 0; 00118 INITIALIZE_PASS(StripDebugDeclare, "strip-debug-declare", 00119 "Strip all llvm.dbg.declare intrinsics", false, false) 00120 00121 ModulePass *llvm::createStripDebugDeclarePass() { 00122 return new StripDebugDeclare(); 00123 } 00124 00125 char StripDeadDebugInfo::ID = 0; 00126 INITIALIZE_PASS(StripDeadDebugInfo, "strip-dead-debug-info", 00127 "Strip debug info for unused symbols", false, false) 00128 00129 ModulePass *llvm::createStripDeadDebugInfoPass() { 00130 return new StripDeadDebugInfo(); 00131 } 00132 00133 /// OnlyUsedBy - Return true if V is only used by Usr. 00134 static bool OnlyUsedBy(Value *V, Value *Usr) { 00135 for (User *U : V->users()) 00136 if (U != Usr) 00137 return false; 00138 00139 return true; 00140 } 00141 00142 static void RemoveDeadConstant(Constant *C) { 00143 assert(C->use_empty() && "Constant is not dead!"); 00144 SmallPtrSet<Constant*, 4> Operands; 00145 for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) 00146 if (OnlyUsedBy(C->getOperand(i), C)) 00147 Operands.insert(cast<Constant>(C->getOperand(i))); 00148 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) { 00149 if (!GV->hasLocalLinkage()) return; // Don't delete non-static globals. 00150 GV->eraseFromParent(); 00151 } 00152 else if (!isa<Function>(C)) 00153 if (isa<CompositeType>(C->getType())) 00154 C->destroyConstant(); 00155 00156 // If the constant referenced anything, see if we can delete it as well. 00157 for (Constant *O : Operands) 00158 RemoveDeadConstant(O); 00159 } 00160 00161 // Strip the symbol table of its names. 00162 // 00163 static void StripSymtab(ValueSymbolTable &ST, bool PreserveDbgInfo) { 00164 for (ValueSymbolTable::iterator VI = ST.begin(), VE = ST.end(); VI != VE; ) { 00165 Value *V = VI->getValue(); 00166 ++VI; 00167 if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasLocalLinkage()) { 00168 if (!PreserveDbgInfo || !V->getName().startswith("llvm.dbg")) 00169 // Set name to "", removing from symbol table! 00170 V->setName(""); 00171 } 00172 } 00173 } 00174 00175 // Strip any named types of their names. 00176 static void StripTypeNames(Module &M, bool PreserveDbgInfo) { 00177 TypeFinder StructTypes; 00178 StructTypes.run(M, false); 00179 00180 for (unsigned i = 0, e = StructTypes.size(); i != e; ++i) { 00181 StructType *STy = StructTypes[i]; 00182 if (STy->isLiteral() || STy->getName().empty()) continue; 00183 00184 if (PreserveDbgInfo && STy->getName().startswith("llvm.dbg")) 00185 continue; 00186 00187 STy->setName(""); 00188 } 00189 } 00190 00191 /// Find values that are marked as llvm.used. 00192 static void findUsedValues(GlobalVariable *LLVMUsed, 00193 SmallPtrSetImpl<const GlobalValue*> &UsedValues) { 00194 if (!LLVMUsed) return; 00195 UsedValues.insert(LLVMUsed); 00196 00197 ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer()); 00198 00199 for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i) 00200 if (GlobalValue *GV = 00201 dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts())) 00202 UsedValues.insert(GV); 00203 } 00204 00205 /// StripSymbolNames - Strip symbol names. 00206 static bool StripSymbolNames(Module &M, bool PreserveDbgInfo) { 00207 00208 SmallPtrSet<const GlobalValue*, 8> llvmUsedValues; 00209 findUsedValues(M.getGlobalVariable("llvm.used"), llvmUsedValues); 00210 findUsedValues(M.getGlobalVariable("llvm.compiler.used"), llvmUsedValues); 00211 00212 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); 00213 I != E; ++I) { 00214 if (I->hasLocalLinkage() && llvmUsedValues.count(I) == 0) 00215 if (!PreserveDbgInfo || !I->getName().startswith("llvm.dbg")) 00216 I->setName(""); // Internal symbols can't participate in linkage 00217 } 00218 00219 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { 00220 if (I->hasLocalLinkage() && llvmUsedValues.count(I) == 0) 00221 if (!PreserveDbgInfo || !I->getName().startswith("llvm.dbg")) 00222 I->setName(""); // Internal symbols can't participate in linkage 00223 StripSymtab(I->getValueSymbolTable(), PreserveDbgInfo); 00224 } 00225 00226 // Remove all names from types. 00227 StripTypeNames(M, PreserveDbgInfo); 00228 00229 return true; 00230 } 00231 00232 bool StripSymbols::runOnModule(Module &M) { 00233 bool Changed = false; 00234 Changed |= StripDebugInfo(M); 00235 if (!OnlyDebugInfo) 00236 Changed |= StripSymbolNames(M, false); 00237 return Changed; 00238 } 00239 00240 bool StripNonDebugSymbols::runOnModule(Module &M) { 00241 return StripSymbolNames(M, true); 00242 } 00243 00244 bool StripDebugDeclare::runOnModule(Module &M) { 00245 00246 Function *Declare = M.getFunction("llvm.dbg.declare"); 00247 std::vector<Constant*> DeadConstants; 00248 00249 if (Declare) { 00250 while (!Declare->use_empty()) { 00251 CallInst *CI = cast<CallInst>(Declare->user_back()); 00252 Value *Arg1 = CI->getArgOperand(0); 00253 Value *Arg2 = CI->getArgOperand(1); 00254 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 00255 CI->eraseFromParent(); 00256 if (Arg1->use_empty()) { 00257 if (Constant *C = dyn_cast<Constant>(Arg1)) 00258 DeadConstants.push_back(C); 00259 else 00260 RecursivelyDeleteTriviallyDeadInstructions(Arg1); 00261 } 00262 if (Arg2->use_empty()) 00263 if (Constant *C = dyn_cast<Constant>(Arg2)) 00264 DeadConstants.push_back(C); 00265 } 00266 Declare->eraseFromParent(); 00267 } 00268 00269 while (!DeadConstants.empty()) { 00270 Constant *C = DeadConstants.back(); 00271 DeadConstants.pop_back(); 00272 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) { 00273 if (GV->hasLocalLinkage()) 00274 RemoveDeadConstant(GV); 00275 } else 00276 RemoveDeadConstant(C); 00277 } 00278 00279 return true; 00280 } 00281 00282 /// Remove any debug info for global variables/functions in the given module for 00283 /// which said global variable/function no longer exists (i.e. is null). 00284 /// 00285 /// Debugging information is encoded in llvm IR using metadata. This is designed 00286 /// such a way that debug info for symbols preserved even if symbols are 00287 /// optimized away by the optimizer. This special pass removes debug info for 00288 /// such symbols. 00289 bool StripDeadDebugInfo::runOnModule(Module &M) { 00290 bool Changed = false; 00291 00292 LLVMContext &C = M.getContext(); 00293 00294 // Find all debug info in F. This is actually overkill in terms of what we 00295 // want to do, but we want to try and be as resilient as possible in the face 00296 // of potential debug info changes by using the formal interfaces given to us 00297 // as much as possible. 00298 DebugInfoFinder F; 00299 F.processModule(M); 00300 00301 // For each compile unit, find the live set of global variables/functions and 00302 // replace the current list of potentially dead global variables/functions 00303 // with the live list. 00304 SmallVector<Value *, 64> LiveGlobalVariables; 00305 SmallVector<Value *, 64> LiveSubprograms; 00306 DenseSet<const MDNode *> VisitedSet; 00307 00308 for (DICompileUnit DIC : F.compile_units()) { 00309 assert(DIC.Verify() && "DIC must verify as a DICompileUnit."); 00310 00311 // Create our live subprogram list. 00312 DIArray SPs = DIC.getSubprograms(); 00313 bool SubprogramChange = false; 00314 for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { 00315 DISubprogram DISP(SPs.getElement(i)); 00316 assert(DISP.Verify() && "DISP must verify as a DISubprogram."); 00317 00318 // Make sure we visit each subprogram only once. 00319 if (!VisitedSet.insert(DISP).second) 00320 continue; 00321 00322 // If the function referenced by DISP is not null, the function is live. 00323 if (DISP.getFunction()) 00324 LiveSubprograms.push_back(DISP); 00325 else 00326 SubprogramChange = true; 00327 } 00328 00329 // Create our live global variable list. 00330 DIArray GVs = DIC.getGlobalVariables(); 00331 bool GlobalVariableChange = false; 00332 for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i) { 00333 DIGlobalVariable DIG(GVs.getElement(i)); 00334 assert(DIG.Verify() && "DIG must verify as DIGlobalVariable."); 00335 00336 // Make sure we only visit each global variable only once. 00337 if (!VisitedSet.insert(DIG).second) 00338 continue; 00339 00340 // If the global variable referenced by DIG is not null, the global 00341 // variable is live. 00342 if (DIG.getGlobal()) 00343 LiveGlobalVariables.push_back(DIG); 00344 else 00345 GlobalVariableChange = true; 00346 } 00347 00348 // If we found dead subprograms or global variables, replace the current 00349 // subprogram list/global variable list with our new live subprogram/global 00350 // variable list. 00351 if (SubprogramChange) { 00352 // Make sure that 9 is still the index of the subprograms. This is to make 00353 // sure that an assert is hit if the location of the subprogram array 00354 // changes. This is just to make sure that this is updated if such an 00355 // event occurs. 00356 assert(DIC->getNumOperands() >= 10 && 00357 SPs == DIC->getOperand(9) && 00358 "DICompileUnits is expected to store Subprograms in operand " 00359 "9."); 00360 DIC->replaceOperandWith(9, MDNode::get(C, LiveSubprograms)); 00361 Changed = true; 00362 } 00363 00364 if (GlobalVariableChange) { 00365 // Make sure that 10 is still the index of global variables. This is to 00366 // make sure that an assert is hit if the location of the subprogram array 00367 // changes. This is just to make sure that this index is updated if such 00368 // an event occurs. 00369 assert(DIC->getNumOperands() >= 11 && 00370 GVs == DIC->getOperand(10) && 00371 "DICompileUnits is expected to store Global Variables in operand " 00372 "10."); 00373 DIC->replaceOperandWith(10, MDNode::get(C, LiveGlobalVariables)); 00374 Changed = true; 00375 } 00376 00377 // Reset lists for the next iteration. 00378 LiveSubprograms.clear(); 00379 LiveGlobalVariables.clear(); 00380 } 00381 00382 return Changed; 00383 }