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::giterator I = M.gbegin(), E = M.gend(); 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 00089 // Strip debug info in the module if it exists. To do this, we remove 00090 // llvm.dbg.func.start, llvm.dbg.stoppoint, and llvm.dbg.region.end calls, and 00091 // any globals they point to if now dead. 00092 Function *FuncStart = M.getNamedFunction("llvm.dbg.func.start"); 00093 Function *StopPoint = M.getNamedFunction("llvm.dbg.stoppoint"); 00094 Function *RegionEnd = M.getNamedFunction("llvm.dbg.region.end"); 00095 if (!FuncStart && !StopPoint && !RegionEnd) 00096 return true; 00097 00098 std::vector<GlobalVariable*> DeadGlobals; 00099 00100 // Remove all of the calls to the debugger intrinsics, and remove them from 00101 // the module. 00102 if (FuncStart) { 00103 Value *RV = UndefValue::get(StopPoint->getFunctionType()->getReturnType()); 00104 while (!FuncStart->use_empty()) { 00105 CallInst *CI = cast<CallInst>(FuncStart->use_back()); 00106 Value *Arg = CI->getOperand(1); 00107 CI->replaceAllUsesWith(RV); 00108 CI->eraseFromParent(); 00109 if (Arg->use_empty()) 00110 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 00111 DeadGlobals.push_back(GV); 00112 } 00113 FuncStart->eraseFromParent(); 00114 } 00115 if (StopPoint) { 00116 Value *RV = UndefValue::get(StopPoint->getFunctionType()->getReturnType()); 00117 while (!StopPoint->use_empty()) { 00118 CallInst *CI = cast<CallInst>(StopPoint->use_back()); 00119 Value *Arg = CI->getOperand(4); 00120 CI->replaceAllUsesWith(RV); 00121 CI->eraseFromParent(); 00122 if (Arg->use_empty()) 00123 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 00124 DeadGlobals.push_back(GV); 00125 } 00126 StopPoint->eraseFromParent(); 00127 } 00128 if (RegionEnd) { 00129 Value *RV = UndefValue::get(RegionEnd->getFunctionType()->getReturnType()); 00130 while (!RegionEnd->use_empty()) { 00131 CallInst *CI = cast<CallInst>(RegionEnd->use_back()); 00132 CI->replaceAllUsesWith(RV); 00133 CI->eraseFromParent(); 00134 } 00135 RegionEnd->eraseFromParent(); 00136 } 00137 00138 // Finally, delete any internal globals that were only used by the debugger 00139 // intrinsics. 00140 while (!DeadGlobals.empty()) { 00141 GlobalVariable *GV = DeadGlobals.back(); 00142 DeadGlobals.pop_back(); 00143 if (GV->hasInternalLinkage()) 00144 RemoveDeadConstant(GV); 00145 } 00146 00147 return true; 00148 }