StripSymbols.cpp revision 199481
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/LLVMContext.h" 28#include "llvm/Module.h" 29#include "llvm/Pass.h" 30#include "llvm/Analysis/DebugInfo.h" 31#include "llvm/ValueSymbolTable.h" 32#include "llvm/TypeSymbolTable.h" 33#include "llvm/Transforms/Utils/Local.h" 34#include "llvm/ADT/SmallPtrSet.h" 35using namespace llvm; 36 37namespace { 38 class StripSymbols : public ModulePass { 39 bool OnlyDebugInfo; 40 public: 41 static char ID; // Pass identification, replacement for typeid 42 explicit StripSymbols(bool ODI = false) 43 : ModulePass(&ID), OnlyDebugInfo(ODI) {} 44 45 virtual bool runOnModule(Module &M); 46 47 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 48 AU.setPreservesAll(); 49 } 50 }; 51 52 class StripNonDebugSymbols : public ModulePass { 53 public: 54 static char ID; // Pass identification, replacement for typeid 55 explicit StripNonDebugSymbols() 56 : ModulePass(&ID) {} 57 58 virtual bool runOnModule(Module &M); 59 60 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 61 AU.setPreservesAll(); 62 } 63 }; 64 65 class StripDebugDeclare : public ModulePass { 66 public: 67 static char ID; // Pass identification, replacement for typeid 68 explicit StripDebugDeclare() 69 : ModulePass(&ID) {} 70 71 virtual bool runOnModule(Module &M); 72 73 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 74 AU.setPreservesAll(); 75 } 76 }; 77} 78 79char StripSymbols::ID = 0; 80static RegisterPass<StripSymbols> 81X("strip", "Strip all symbols from a module"); 82 83ModulePass *llvm::createStripSymbolsPass(bool OnlyDebugInfo) { 84 return new StripSymbols(OnlyDebugInfo); 85} 86 87char StripNonDebugSymbols::ID = 0; 88static RegisterPass<StripNonDebugSymbols> 89Y("strip-nondebug", "Strip all symbols, except dbg symbols, from a module"); 90 91ModulePass *llvm::createStripNonDebugSymbolsPass() { 92 return new StripNonDebugSymbols(); 93} 94 95char StripDebugDeclare::ID = 0; 96static RegisterPass<StripDebugDeclare> 97Z("strip-debug-declare", "Strip all llvm.dbg.declare intrinsics"); 98 99ModulePass *llvm::createStripDebugDeclarePass() { 100 return new StripDebugDeclare(); 101} 102 103/// OnlyUsedBy - Return true if V is only used by Usr. 104static bool OnlyUsedBy(Value *V, Value *Usr) { 105 for(Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) { 106 User *U = *I; 107 if (U != Usr) 108 return false; 109 } 110 return true; 111} 112 113static void RemoveDeadConstant(Constant *C) { 114 assert(C->use_empty() && "Constant is not dead!"); 115 SmallPtrSet<Constant*, 4> Operands; 116 for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) 117 if (isa<DerivedType>(C->getOperand(i)->getType()) && 118 OnlyUsedBy(C->getOperand(i), C)) 119 Operands.insert(cast<Constant>(C->getOperand(i))); 120 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) { 121 if (!GV->hasLocalLinkage()) return; // Don't delete non static globals. 122 GV->eraseFromParent(); 123 } 124 else if (!isa<Function>(C)) 125 if (isa<CompositeType>(C->getType())) 126 C->destroyConstant(); 127 128 // If the constant referenced anything, see if we can delete it as well. 129 for (SmallPtrSet<Constant*, 4>::iterator OI = Operands.begin(), 130 OE = Operands.end(); OI != OE; ++OI) 131 RemoveDeadConstant(*OI); 132} 133 134// Strip the symbol table of its names. 135// 136static void StripSymtab(ValueSymbolTable &ST, bool PreserveDbgInfo) { 137 for (ValueSymbolTable::iterator VI = ST.begin(), VE = ST.end(); VI != VE; ) { 138 Value *V = VI->getValue(); 139 ++VI; 140 if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasLocalLinkage()) { 141 if (!PreserveDbgInfo || !V->getName().startswith("llvm.dbg")) 142 // Set name to "", removing from symbol table! 143 V->setName(""); 144 } 145 } 146} 147 148// Strip the symbol table of its names. 149static void StripTypeSymtab(TypeSymbolTable &ST, bool PreserveDbgInfo) { 150 for (TypeSymbolTable::iterator TI = ST.begin(), E = ST.end(); TI != E; ) { 151 if (PreserveDbgInfo && strncmp(TI->first.c_str(), "llvm.dbg", 8) == 0) 152 ++TI; 153 else 154 ST.remove(TI++); 155 } 156} 157 158/// Find values that are marked as llvm.used. 159static void findUsedValues(GlobalVariable *LLVMUsed, 160 SmallPtrSet<const GlobalValue*, 8> &UsedValues) { 161 if (LLVMUsed == 0) return; 162 UsedValues.insert(LLVMUsed); 163 164 ConstantArray *Inits = dyn_cast<ConstantArray>(LLVMUsed->getInitializer()); 165 if (Inits == 0) return; 166 167 for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i) 168 if (GlobalValue *GV = 169 dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts())) 170 UsedValues.insert(GV); 171} 172 173/// StripSymbolNames - Strip symbol names. 174static bool StripSymbolNames(Module &M, bool PreserveDbgInfo) { 175 176 SmallPtrSet<const GlobalValue*, 8> llvmUsedValues; 177 findUsedValues(M.getGlobalVariable("llvm.used"), llvmUsedValues); 178 findUsedValues(M.getGlobalVariable("llvm.compiler.used"), llvmUsedValues); 179 180 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); 181 I != E; ++I) { 182 if (I->hasLocalLinkage() && llvmUsedValues.count(I) == 0) 183 if (!PreserveDbgInfo || !I->getName().startswith("llvm.dbg")) 184 I->setName(""); // Internal symbols can't participate in linkage 185 } 186 187 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { 188 if (I->hasLocalLinkage() && llvmUsedValues.count(I) == 0) 189 if (!PreserveDbgInfo || !I->getName().startswith("llvm.dbg")) 190 I->setName(""); // Internal symbols can't participate in linkage 191 StripSymtab(I->getValueSymbolTable(), PreserveDbgInfo); 192 } 193 194 // Remove all names from types. 195 StripTypeSymtab(M.getTypeSymbolTable(), PreserveDbgInfo); 196 197 return true; 198} 199 200// StripDebugInfo - Strip debug info in the module if it exists. 201// To do this, we remove llvm.dbg.func.start, llvm.dbg.stoppoint, and 202// llvm.dbg.region.end calls, and any globals they point to if now dead. 203static bool StripDebugInfo(Module &M) { 204 205 bool Changed = false; 206 207 // Remove all of the calls to the debugger intrinsics, and remove them from 208 // the module. 209 if (Function *Declare = M.getFunction("llvm.dbg.declare")) { 210 while (!Declare->use_empty()) { 211 CallInst *CI = cast<CallInst>(Declare->use_back()); 212 CI->eraseFromParent(); 213 } 214 Declare->eraseFromParent(); 215 Changed = true; 216 } 217 218 NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.gv"); 219 if (NMD) { 220 Changed = true; 221 NMD->eraseFromParent(); 222 } 223 MetadataContext &TheMetadata = M.getContext().getMetadata(); 224 unsigned MDDbgKind = TheMetadata.getMDKind("dbg"); 225 if (!MDDbgKind) 226 return Changed; 227 228 for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) 229 for (Function::iterator FI = MI->begin(), FE = MI->end(); FI != FE; 230 ++FI) 231 for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; 232 ++BI) 233 TheMetadata.removeMD(MDDbgKind, BI); 234 235 return true; 236} 237 238bool StripSymbols::runOnModule(Module &M) { 239 bool Changed = false; 240 Changed |= StripDebugInfo(M); 241 if (!OnlyDebugInfo) 242 Changed |= StripSymbolNames(M, false); 243 return Changed; 244} 245 246bool StripNonDebugSymbols::runOnModule(Module &M) { 247 return StripSymbolNames(M, true); 248} 249 250bool StripDebugDeclare::runOnModule(Module &M) { 251 252 Function *Declare = M.getFunction("llvm.dbg.declare"); 253 std::vector<Constant*> DeadConstants; 254 255 if (Declare) { 256 while (!Declare->use_empty()) { 257 CallInst *CI = cast<CallInst>(Declare->use_back()); 258 Value *Arg1 = CI->getOperand(1); 259 Value *Arg2 = CI->getOperand(2); 260 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 261 CI->eraseFromParent(); 262 if (Arg1->use_empty()) { 263 if (Constant *C = dyn_cast<Constant>(Arg1)) 264 DeadConstants.push_back(C); 265 else 266 RecursivelyDeleteTriviallyDeadInstructions(Arg1); 267 } 268 if (Arg2->use_empty()) 269 if (Constant *C = dyn_cast<Constant>(Arg2)) 270 DeadConstants.push_back(C); 271 } 272 Declare->eraseFromParent(); 273 } 274 275 while (!DeadConstants.empty()) { 276 Constant *C = DeadConstants.back(); 277 DeadConstants.pop_back(); 278 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) { 279 if (GV->hasLocalLinkage()) 280 RemoveDeadConstant(GV); 281 } else 282 RemoveDeadConstant(C); 283 } 284 285 return true; 286} 287