StripSymbols.cpp revision 26f8c27c34b44f7d87de74d1de2128c1a02855bf
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/Constants.h" 25#include "llvm/DerivedTypes.h" 26#include "llvm/Instructions.h" 27#include "llvm/Module.h" 28#include "llvm/Pass.h" 29#include "llvm/ValueSymbolTable.h" 30#include "llvm/TypeSymbolTable.h" 31#include "llvm/Support/Compiler.h" 32#include "llvm/ADT/SmallPtrSet.h" 33using namespace llvm; 34 35namespace { 36 class VISIBILITY_HIDDEN StripSymbols : public ModulePass { 37 bool OnlyDebugInfo; 38 public: 39 static char ID; // Pass identification, replacement for typeid 40 explicit StripSymbols(bool ODI = false) 41 : ModulePass(&ID), OnlyDebugInfo(ODI) {} 42 43 virtual bool runOnModule(Module &M); 44 45 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 46 AU.setPreservesAll(); 47 } 48 }; 49} 50 51char StripSymbols::ID = 0; 52static RegisterPass<StripSymbols> 53X("strip", "Strip all symbols from a module"); 54 55ModulePass *llvm::createStripSymbolsPass(bool OnlyDebugInfo) { 56 return new StripSymbols(OnlyDebugInfo); 57} 58 59static void RemoveDeadConstant(Constant *C) { 60 assert(C->use_empty() && "Constant is not dead!"); 61 std::vector<Constant*> Operands; 62 for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) 63 if (isa<DerivedType>(C->getOperand(i)->getType()) && 64 C->getOperand(i)->hasOneUse()) 65 Operands.push_back(C->getOperand(i)); 66 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) { 67 if (!GV->hasInternalLinkage()) return; // Don't delete non static globals. 68 GV->eraseFromParent(); 69 } 70 else if (!isa<Function>(C)) 71 C->destroyConstant(); 72 73 // If the constant referenced anything, see if we can delete it as well. 74 while (!Operands.empty()) { 75 RemoveDeadConstant(Operands.back()); 76 Operands.pop_back(); 77 } 78} 79 80// Strip the symbol table of its names. 81// 82static void StripSymtab(ValueSymbolTable &ST) { 83 for (ValueSymbolTable::iterator VI = ST.begin(), VE = ST.end(); VI != VE; ) { 84 Value *V = VI->getValue(); 85 ++VI; 86 if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasInternalLinkage()) { 87 // Set name to "", removing from symbol table! 88 V->setName(""); 89 } 90 } 91} 92 93// Strip the symbol table of its names. 94static void StripTypeSymtab(TypeSymbolTable &ST) { 95 for (TypeSymbolTable::iterator TI = ST.begin(), E = ST.end(); TI != E; ) 96 ST.remove(TI++); 97} 98 99 100 101bool StripSymbols::runOnModule(Module &M) { 102 // If we're not just stripping debug info, strip all symbols from the 103 // functions and the names from any internal globals. 104 if (!OnlyDebugInfo) { 105 SmallPtrSet<const GlobalValue*, 8> llvmUsedValues; 106 if (GlobalVariable *LLVMUsed = M.getGlobalVariable("llvm.used")) { 107 llvmUsedValues.insert(LLVMUsed); 108 // Collect values that are preserved as per explicit request. 109 // llvm.used is used to list these values. 110 if (ConstantArray *Inits = 111 dyn_cast<ConstantArray>(LLVMUsed->getInitializer())) { 112 for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i) { 113 if (GlobalValue *GV = dyn_cast<GlobalValue>(Inits->getOperand(i))) 114 llvmUsedValues.insert(GV); 115 else if (ConstantExpr *CE = 116 dyn_cast<ConstantExpr>(Inits->getOperand(i))) 117 if (CE->getOpcode() == Instruction::BitCast) 118 if (GlobalValue *GV = dyn_cast<GlobalValue>(CE->getOperand(0))) 119 llvmUsedValues.insert(GV); 120 } 121 } 122 } 123 124 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); 125 I != E; ++I) { 126 if (I->hasInternalLinkage() && llvmUsedValues.count(I) == 0) 127 I->setName(""); // Internal symbols can't participate in linkage 128 } 129 130 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { 131 if (I->hasInternalLinkage() && llvmUsedValues.count(I) == 0) 132 I->setName(""); // Internal symbols can't participate in linkage 133 StripSymtab(I->getValueSymbolTable()); 134 } 135 136 // Remove all names from types. 137 StripTypeSymtab(M.getTypeSymbolTable()); 138 } 139 140 // Strip debug info in the module if it exists. To do this, we remove 141 // llvm.dbg.func.start, llvm.dbg.stoppoint, and llvm.dbg.region.end calls, and 142 // any globals they point to if now dead. 143 Function *FuncStart = M.getFunction("llvm.dbg.func.start"); 144 Function *StopPoint = M.getFunction("llvm.dbg.stoppoint"); 145 Function *RegionStart = M.getFunction("llvm.dbg.region.start"); 146 Function *RegionEnd = M.getFunction("llvm.dbg.region.end"); 147 Function *Declare = M.getFunction("llvm.dbg.declare"); 148 if (!FuncStart && !StopPoint && !RegionStart && !RegionEnd && !Declare) 149 return true; 150 151 std::vector<GlobalVariable*> DeadGlobals; 152 153 // Remove all of the calls to the debugger intrinsics, and remove them from 154 // the module. 155 if (FuncStart) { 156 while (!FuncStart->use_empty()) { 157 CallInst *CI = cast<CallInst>(FuncStart->use_back()); 158 Value *Arg = CI->getOperand(1); 159 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 160 CI->eraseFromParent(); 161 if (Arg->use_empty()) 162 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 163 DeadGlobals.push_back(GV); 164 } 165 FuncStart->eraseFromParent(); 166 } 167 if (StopPoint) { 168 while (!StopPoint->use_empty()) { 169 CallInst *CI = cast<CallInst>(StopPoint->use_back()); 170 Value *Arg = CI->getOperand(3); 171 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 172 CI->eraseFromParent(); 173 if (Arg->use_empty()) 174 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 175 DeadGlobals.push_back(GV); 176 } 177 StopPoint->eraseFromParent(); 178 } 179 if (RegionStart) { 180 while (!RegionStart->use_empty()) { 181 CallInst *CI = cast<CallInst>(RegionStart->use_back()); 182 Value *Arg = CI->getOperand(1); 183 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 184 CI->eraseFromParent(); 185 if (Arg->use_empty()) 186 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 187 DeadGlobals.push_back(GV); 188 } 189 RegionStart->eraseFromParent(); 190 } 191 if (RegionEnd) { 192 while (!RegionEnd->use_empty()) { 193 CallInst *CI = cast<CallInst>(RegionEnd->use_back()); 194 Value *Arg = CI->getOperand(1); 195 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 196 CI->eraseFromParent(); 197 if (Arg->use_empty()) 198 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 199 DeadGlobals.push_back(GV); 200 } 201 RegionEnd->eraseFromParent(); 202 } 203 if (Declare) { 204 while (!Declare->use_empty()) { 205 CallInst *CI = cast<CallInst>(Declare->use_back()); 206 Value *Arg = CI->getOperand(2); 207 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 208 CI->eraseFromParent(); 209 if (Arg->use_empty()) 210 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 211 DeadGlobals.push_back(GV); 212 } 213 Declare->eraseFromParent(); 214 } 215 216 // Finally, delete any internal globals that were only used by the debugger 217 // intrinsics. 218 while (!DeadGlobals.empty()) { 219 GlobalVariable *GV = DeadGlobals.back(); 220 DeadGlobals.pop_back(); 221 if (GV->hasInternalLinkage()) 222 RemoveDeadConstant(GV); 223 } 224 225 return true; 226} 227