LLVM API Documentation
00001 //===- StripSymbols.cpp - Strip symbols and debug info from a module ------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements stripping symbols out of symbol tables. 00011 // 00012 // Specifically, this allows you to strip all of the symbols out of: 00013 // * All functions in a module 00014 // * All non-essential symbols in a module (all function symbols + all module 00015 // scope symbols) 00016 // * Debug information. 00017 // 00018 // Notice that: 00019 // * This pass makes code much less readable, so it should only be used in 00020 // situations where the 'strip' utility would be used (such as reducing 00021 // code size, and making it harder to reverse engineer code). 00022 // 00023 //===----------------------------------------------------------------------===// 00024 00025 #include "llvm/Transforms/IPO.h" 00026 #include "llvm/Constants.h" 00027 #include "llvm/DerivedTypes.h" 00028 #include "llvm/Instructions.h" 00029 #include "llvm/Module.h" 00030 #include "llvm/Pass.h" 00031 #include "llvm/SymbolTable.h" 00032 using namespace llvm; 00033 00034 namespace { 00035 class StripSymbols : public ModulePass { 00036 bool OnlyDebugInfo; 00037 public: 00038 StripSymbols(bool ODI = false) : OnlyDebugInfo(ODI) {} 00039 00040 virtual bool runOnModule(Module &M); 00041 00042 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 00043 AU.setPreservesAll(); 00044 } 00045 }; 00046 RegisterOpt<StripSymbols> X("strip", "Strip all symbols from a module"); 00047 } 00048 00049 ModulePass *llvm::createStripSymbolsPass(bool OnlyDebugInfo) { 00050 return new StripSymbols(OnlyDebugInfo); 00051 } 00052 00053 static void RemoveDeadConstant(Constant *C) { 00054 assert(C->use_empty() && "Constant is not dead!"); 00055 std::vector<Constant*> Operands; 00056 for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) 00057 if (isa<DerivedType>(C->getOperand(i)->getType()) && 00058 C->getOperand(i)->hasOneUse()) 00059 Operands.push_back(C->getOperand(i)); 00060 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) { 00061 if (!GV->hasInternalLinkage()) return; // Don't delete non static globals. 00062 GV->eraseFromParent(); 00063 } 00064 else if (!isa<Function>(C)) 00065 C->destroyConstant(); 00066 00067 // If the constant referenced anything, see if we can delete it as well. 00068 while (!Operands.empty()) { 00069 RemoveDeadConstant(Operands.back()); 00070 Operands.pop_back(); 00071 } 00072 } 00073 00074 bool StripSymbols::runOnModule(Module &M) { 00075 // If we're not just stripping debug info, strip all symbols from the 00076 // functions and the names from any internal globals. 00077 if (!OnlyDebugInfo) { 00078 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) 00079 if (I->hasInternalLinkage()) 00080 I->setName(""); // Internal symbols can't participate in linkage 00081 00082 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { 00083 if (I->hasInternalLinkage()) 00084 I->setName(""); // Internal symbols can't participate in linkage 00085 I->getSymbolTable().strip(); 00086 } 00087 00088 // Remove all names from types. 00089 SymbolTable &SymTab = M.getSymbolTable(); 00090 while (SymTab.type_begin() != SymTab.type_end()) 00091 SymTab.remove(SymTab.type_begin()); 00092 } 00093 00094 // Strip debug info in the module if it exists. To do this, we remove 00095 // llvm.dbg.func.start, llvm.dbg.stoppoint, and llvm.dbg.region.end calls, and 00096 // any globals they point to if now dead. 00097 Function *FuncStart = M.getNamedFunction("llvm.dbg.func.start"); 00098 Function *StopPoint = M.getNamedFunction("llvm.dbg.stoppoint"); 00099 Function *RegionStart = M.getNamedFunction("llvm.dbg.region.start"); 00100 Function *RegionEnd = M.getNamedFunction("llvm.dbg.region.end"); 00101 Function *Declare = M.getNamedFunction("llvm.dbg.declare"); 00102 if (!FuncStart && !StopPoint && !RegionStart && !RegionEnd && !Declare) 00103 return true; 00104 00105 std::vector<GlobalVariable*> DeadGlobals; 00106 00107 // Remove all of the calls to the debugger intrinsics, and remove them from 00108 // the module. 00109 if (FuncStart) { 00110 while (!FuncStart->use_empty()) { 00111 CallInst *CI = cast<CallInst>(FuncStart->use_back()); 00112 Value *Arg = CI->getOperand(1); 00113 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 00114 CI->eraseFromParent(); 00115 if (Arg->use_empty()) 00116 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 00117 DeadGlobals.push_back(GV); 00118 } 00119 FuncStart->eraseFromParent(); 00120 } 00121 if (StopPoint) { 00122 while (!StopPoint->use_empty()) { 00123 CallInst *CI = cast<CallInst>(StopPoint->use_back()); 00124 Value *Arg = CI->getOperand(3); 00125 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 00126 CI->eraseFromParent(); 00127 if (Arg->use_empty()) 00128 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 00129 DeadGlobals.push_back(GV); 00130 } 00131 StopPoint->eraseFromParent(); 00132 } 00133 if (RegionStart) { 00134 while (!RegionStart->use_empty()) { 00135 CallInst *CI = cast<CallInst>(RegionStart->use_back()); 00136 Value *Arg = CI->getOperand(1); 00137 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 00138 CI->eraseFromParent(); 00139 if (Arg->use_empty()) 00140 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 00141 DeadGlobals.push_back(GV); 00142 } 00143 RegionStart->eraseFromParent(); 00144 } 00145 if (RegionEnd) { 00146 while (!RegionEnd->use_empty()) { 00147 CallInst *CI = cast<CallInst>(RegionEnd->use_back()); 00148 Value *Arg = CI->getOperand(1); 00149 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 00150 CI->eraseFromParent(); 00151 if (Arg->use_empty()) 00152 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 00153 DeadGlobals.push_back(GV); 00154 } 00155 RegionEnd->eraseFromParent(); 00156 } 00157 if (Declare) { 00158 while (!Declare->use_empty()) { 00159 CallInst *CI = cast<CallInst>(Declare->use_back()); 00160 Value *Arg = CI->getOperand(2); 00161 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 00162 CI->eraseFromParent(); 00163 if (Arg->use_empty()) 00164 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 00165 DeadGlobals.push_back(GV); 00166 } 00167 Declare->eraseFromParent(); 00168 } 00169 00170 // Finally, delete any internal globals that were only used by the debugger 00171 // intrinsics. 00172 while (!DeadGlobals.empty()) { 00173 GlobalVariable *GV = DeadGlobals.back(); 00174 DeadGlobals.pop_back(); 00175 if (GV->hasInternalLinkage()) 00176 RemoveDeadConstant(GV); 00177 } 00178 00179 return true; 00180 }