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/Constants.h" 00025 #include "llvm/DerivedTypes.h" 00026 #include "llvm/Instructions.h" 00027 #include "llvm/Module.h" 00028 #include "llvm/Pass.h" 00029 #include "llvm/ValueSymbolTable.h" 00030 #include "llvm/TypeSymbolTable.h" 00031 #include "llvm/Support/Compiler.h" 00032 #include "llvm/ADT/SmallPtrSet.h" 00033 using namespace llvm; 00034 00035 namespace { 00036 class VISIBILITY_HIDDEN StripSymbols : public ModulePass { 00037 bool OnlyDebugInfo; 00038 public: 00039 static char ID; // Pass identification, replacement for typeid 00040 explicit StripSymbols(bool ODI = false) 00041 : ModulePass(&ID), OnlyDebugInfo(ODI) {} 00042 00043 virtual bool runOnModule(Module &M); 00044 00045 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 00046 AU.setPreservesAll(); 00047 } 00048 }; 00049 00050 class VISIBILITY_HIDDEN StripNonDebugSymbols : public ModulePass { 00051 public: 00052 static char ID; // Pass identification, replacement for typeid 00053 explicit StripNonDebugSymbols() 00054 : ModulePass(&ID) {} 00055 00056 virtual bool runOnModule(Module &M); 00057 00058 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 00059 AU.setPreservesAll(); 00060 } 00061 }; 00062 } 00063 00064 char StripSymbols::ID = 0; 00065 static RegisterPass<StripSymbols> 00066 X("strip", "Strip all symbols from a module"); 00067 00068 ModulePass *llvm::createStripSymbolsPass(bool OnlyDebugInfo) { 00069 return new StripSymbols(OnlyDebugInfo); 00070 } 00071 00072 char StripNonDebugSymbols::ID = 0; 00073 static RegisterPass<StripNonDebugSymbols> 00074 Y("strip-nondebug", "Strip all symbols, except dbg symbols, from a module"); 00075 00076 ModulePass *llvm::createStripNonDebugSymbolsPass() { 00077 return new StripNonDebugSymbols(); 00078 } 00079 00080 /// OnlyUsedBy - Return true if V is only used by Usr. 00081 static bool OnlyUsedBy(Value *V, Value *Usr) { 00082 for(Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) { 00083 User *U = *I; 00084 if (U != Usr) 00085 return false; 00086 } 00087 return true; 00088 } 00089 00090 static void RemoveDeadConstant(Constant *C) { 00091 assert(C->use_empty() && "Constant is not dead!"); 00092 SmallPtrSet<Constant *, 4> Operands; 00093 for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) 00094 if (isa<DerivedType>(C->getOperand(i)->getType()) && 00095 OnlyUsedBy(C->getOperand(i), C)) 00096 Operands.insert(C->getOperand(i)); 00097 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) { 00098 if (!GV->hasInternalLinkage()) return; // Don't delete non static globals. 00099 GV->eraseFromParent(); 00100 } 00101 else if (!isa<Function>(C)) 00102 if (isa<CompositeType>(C->getType())) 00103 C->destroyConstant(); 00104 00105 // If the constant referenced anything, see if we can delete it as well. 00106 for (SmallPtrSet<Constant *, 4>::iterator OI = Operands.begin(), 00107 OE = Operands.end(); OI != OE; ++OI) 00108 RemoveDeadConstant(*OI); 00109 } 00110 00111 // Strip the symbol table of its names. 00112 // 00113 static void StripSymtab(ValueSymbolTable &ST, bool PreserveDbgInfo) { 00114 for (ValueSymbolTable::iterator VI = ST.begin(), VE = ST.end(); VI != VE; ) { 00115 Value *V = VI->getValue(); 00116 ++VI; 00117 if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasInternalLinkage()) { 00118 if (!PreserveDbgInfo || strncmp(V->getNameStart(), "llvm.dbg", 8)) 00119 // Set name to "", removing from symbol table! 00120 V->setName(""); 00121 } 00122 } 00123 } 00124 00125 // Strip the symbol table of its names. 00126 static void StripTypeSymtab(TypeSymbolTable &ST, bool PreserveDbgInfo) { 00127 for (TypeSymbolTable::iterator TI = ST.begin(), E = ST.end(); TI != E; ) { 00128 if (PreserveDbgInfo && strncmp(TI->first.c_str(), "llvm.dbg", 8) == 0) 00129 ++TI; 00130 else 00131 ST.remove(TI++); 00132 } 00133 } 00134 00135 /// Find values that are marked as llvm.used. 00136 void findUsedValues(Module &M, 00137 SmallPtrSet<const GlobalValue*, 8>& llvmUsedValues) { 00138 if (GlobalVariable *LLVMUsed = M.getGlobalVariable("llvm.used")) { 00139 llvmUsedValues.insert(LLVMUsed); 00140 // Collect values that are preserved as per explicit request. 00141 // llvm.used is used to list these values. 00142 if (ConstantArray *Inits = 00143 dyn_cast<ConstantArray>(LLVMUsed->getInitializer())) { 00144 for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i) { 00145 if (GlobalValue *GV = dyn_cast<GlobalValue>(Inits->getOperand(i))) 00146 llvmUsedValues.insert(GV); 00147 else if (ConstantExpr *CE = 00148 dyn_cast<ConstantExpr>(Inits->getOperand(i))) 00149 if (CE->getOpcode() == Instruction::BitCast) 00150 if (GlobalValue *GV = dyn_cast<GlobalValue>(CE->getOperand(0))) 00151 llvmUsedValues.insert(GV); 00152 } 00153 } 00154 } 00155 } 00156 00157 /// StripSymbolNames - Strip symbol names. 00158 bool StripSymbolNames(Module &M, bool PreserveDbgInfo) { 00159 00160 SmallPtrSet<const GlobalValue*, 8> llvmUsedValues; 00161 findUsedValues(M, llvmUsedValues); 00162 00163 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); 00164 I != E; ++I) { 00165 if (I->hasInternalLinkage() && llvmUsedValues.count(I) == 0) 00166 if (!PreserveDbgInfo || strncmp(I->getNameStart(), "llvm.dbg", 8)) 00167 I->setName(""); // Internal symbols can't participate in linkage 00168 } 00169 00170 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { 00171 if (I->hasInternalLinkage() && llvmUsedValues.count(I) == 0) 00172 if (!PreserveDbgInfo || strncmp(I->getNameStart(), "llvm.dbg", 8)) 00173 I->setName(""); // Internal symbols can't participate in linkage 00174 StripSymtab(I->getValueSymbolTable(), PreserveDbgInfo); 00175 } 00176 00177 // Remove all names from types. 00178 StripTypeSymtab(M.getTypeSymbolTable(), PreserveDbgInfo); 00179 00180 return true; 00181 } 00182 00183 // StripDebugInfo - Strip debug info in the module if it exists. 00184 // To do this, we remove llvm.dbg.func.start, llvm.dbg.stoppoint, and 00185 // llvm.dbg.region.end calls, and any globals they point to if now dead. 00186 bool StripDebugInfo(Module &M) { 00187 00188 Function *FuncStart = M.getFunction("llvm.dbg.func.start"); 00189 Function *StopPoint = M.getFunction("llvm.dbg.stoppoint"); 00190 Function *RegionStart = M.getFunction("llvm.dbg.region.start"); 00191 Function *RegionEnd = M.getFunction("llvm.dbg.region.end"); 00192 Function *Declare = M.getFunction("llvm.dbg.declare"); 00193 00194 std::vector<Constant*> DeadConstants; 00195 00196 // Remove all of the calls to the debugger intrinsics, and remove them from 00197 // the module. 00198 if (FuncStart) { 00199 while (!FuncStart->use_empty()) { 00200 CallInst *CI = cast<CallInst>(FuncStart->use_back()); 00201 Value *Arg = CI->getOperand(1); 00202 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 00203 CI->eraseFromParent(); 00204 if (Arg->use_empty()) 00205 if (Constant *C = dyn_cast<Constant>(Arg)) 00206 DeadConstants.push_back(C); 00207 } 00208 FuncStart->eraseFromParent(); 00209 } 00210 if (StopPoint) { 00211 while (!StopPoint->use_empty()) { 00212 CallInst *CI = cast<CallInst>(StopPoint->use_back()); 00213 Value *Arg = CI->getOperand(3); 00214 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 00215 CI->eraseFromParent(); 00216 if (Arg->use_empty()) 00217 if (Constant *C = dyn_cast<Constant>(Arg)) 00218 DeadConstants.push_back(C); 00219 } 00220 StopPoint->eraseFromParent(); 00221 } 00222 if (RegionStart) { 00223 while (!RegionStart->use_empty()) { 00224 CallInst *CI = cast<CallInst>(RegionStart->use_back()); 00225 Value *Arg = CI->getOperand(1); 00226 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 00227 CI->eraseFromParent(); 00228 if (Arg->use_empty()) 00229 if (Constant *C = dyn_cast<Constant>(Arg)) 00230 DeadConstants.push_back(C); 00231 } 00232 RegionStart->eraseFromParent(); 00233 } 00234 if (RegionEnd) { 00235 while (!RegionEnd->use_empty()) { 00236 CallInst *CI = cast<CallInst>(RegionEnd->use_back()); 00237 Value *Arg = CI->getOperand(1); 00238 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 00239 CI->eraseFromParent(); 00240 if (Arg->use_empty()) 00241 if (Constant *C = dyn_cast<Constant>(Arg)) 00242 DeadConstants.push_back(C); 00243 } 00244 RegionEnd->eraseFromParent(); 00245 } 00246 if (Declare) { 00247 while (!Declare->use_empty()) { 00248 CallInst *CI = cast<CallInst>(Declare->use_back()); 00249 Value *Arg1 = CI->getOperand(1); 00250 Value *Arg2 = CI->getOperand(2); 00251 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 00252 CI->eraseFromParent(); 00253 if (Arg1->use_empty()) { 00254 if (Constant *C = dyn_cast<Constant>(Arg1)) 00255 DeadConstants.push_back(C); 00256 if (Instruction *I = dyn_cast<Instruction>(Arg1)) 00257 I->eraseFromParent(); 00258 } 00259 if (Arg2->use_empty()) 00260 if (Constant *C = dyn_cast<Constant>(Arg2)) 00261 DeadConstants.push_back(C); 00262 } 00263 Declare->eraseFromParent(); 00264 } 00265 00266 SmallPtrSet<const GlobalValue*, 8> llvmUsedValues; 00267 findUsedValues(M, llvmUsedValues); 00268 00269 // llvm.dbg.compile_units and llvm.dbg.subprograms are marked as linkonce 00270 // but since we are removing all debug information, make them internal now. 00271 if (Constant *C = M.getNamedGlobal("llvm.dbg.compile_units")) 00272 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) 00273 GV->setLinkage(GlobalValue::InternalLinkage); 00274 00275 if (Constant *C = M.getNamedGlobal("llvm.dbg.subprograms")) 00276 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) 00277 GV->setLinkage(GlobalValue::InternalLinkage); 00278 00279 if (Constant *C = M.getNamedGlobal("llvm.dbg.global_variables")) 00280 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) 00281 GV->setLinkage(GlobalValue::InternalLinkage); 00282 00283 // Delete all dbg variables. 00284 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); 00285 I != E; ++I) { 00286 GlobalVariable *GV = dyn_cast<GlobalVariable>(I); 00287 if (!GV) continue; 00288 if (GV->use_empty() && llvmUsedValues.count(I) == 0 00289 && (!GV->hasSection() 00290 || strcmp(GV->getSection().c_str(), "llvm.metadata") == 0)) 00291 DeadConstants.push_back(GV); 00292 } 00293 00294 if (DeadConstants.empty()) 00295 return false; 00296 00297 // Delete any internal globals that were only used by the debugger intrinsics. 00298 while (!DeadConstants.empty()) { 00299 Constant *C = DeadConstants.back(); 00300 DeadConstants.pop_back(); 00301 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) { 00302 if (GV->hasInternalLinkage()) 00303 RemoveDeadConstant(GV); 00304 } 00305 else 00306 RemoveDeadConstant(C); 00307 } 00308 00309 // Remove all llvm.dbg types. 00310 TypeSymbolTable &ST = M.getTypeSymbolTable(); 00311 for (TypeSymbolTable::iterator TI = ST.begin(), TE = ST.end(); TI != TE; ) { 00312 if (!strncmp(TI->first.c_str(), "llvm.dbg.", 9)) 00313 ST.remove(TI++); 00314 else 00315 ++TI; 00316 } 00317 00318 return true; 00319 } 00320 00321 bool StripSymbols::runOnModule(Module &M) { 00322 bool Changed = false; 00323 Changed |= StripDebugInfo(M); 00324 if (!OnlyDebugInfo) 00325 Changed |= StripSymbolNames(M, false); 00326 return Changed; 00327 } 00328 00329 bool StripNonDebugSymbols::runOnModule(Module &M) { 00330 return StripSymbolNames(M, true); 00331 } 00332
This web site is hosted by the Computer Science Department at the University of Illinois at Urbana-Champaign.