StripSymbols.cpp revision f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cc
1//===- StripSymbols.cpp - Strip symbols and debug info from a module ------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by the LLVM research group and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements stripping symbols out of symbol tables. 11// 12// Specifically, this allows you to strip all of the symbols out of: 13// * All functions in a module 14// * All non-essential symbols in a module (all function symbols + all module 15// scope symbols) 16// * Debug information. 17// 18// Notice that: 19// * This pass makes code much less readable, so it should only be used in 20// situations where the 'strip' utility would be used (such as reducing 21// code size, and making it harder to reverse engineer code). 22// 23//===----------------------------------------------------------------------===// 24 25#include "llvm/Transforms/IPO.h" 26#include "llvm/Constants.h" 27#include "llvm/DerivedTypes.h" 28#include "llvm/Instructions.h" 29#include "llvm/Module.h" 30#include "llvm/Pass.h" 31#include "llvm/ValueSymbolTable.h" 32#include "llvm/TypeSymbolTable.h" 33#include "llvm/Support/Compiler.h" 34using namespace llvm; 35 36namespace { 37 class VISIBILITY_HIDDEN StripSymbols : public ModulePass { 38 bool OnlyDebugInfo; 39 public: 40 static char ID; // Pass identification, replacement for typeid 41 StripSymbols(bool ODI = false) 42 : ModulePass((intptr_t)&ID), OnlyDebugInfo(ODI) {} 43 44 virtual bool runOnModule(Module &M); 45 46 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 47 AU.setPreservesAll(); 48 } 49 }; 50 51 char StripSymbols::ID = 0; 52 RegisterPass<StripSymbols> X("strip", "Strip all symbols from a module"); 53} 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 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); 106 I != E; ++I) 107 if (I->hasInternalLinkage()) 108 I->setName(""); // Internal symbols can't participate in linkage 109 110 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { 111 if (I->hasInternalLinkage()) 112 I->setName(""); // Internal symbols can't participate in linkage 113 StripSymtab(I->getValueSymbolTable()); 114 } 115 116 // Remove all names from types. 117 StripTypeSymtab(M.getTypeSymbolTable()); 118 } 119 120 // Strip debug info in the module if it exists. To do this, we remove 121 // llvm.dbg.func.start, llvm.dbg.stoppoint, and llvm.dbg.region.end calls, and 122 // any globals they point to if now dead. 123 Function *FuncStart = M.getFunction("llvm.dbg.func.start"); 124 Function *StopPoint = M.getFunction("llvm.dbg.stoppoint"); 125 Function *RegionStart = M.getFunction("llvm.dbg.region.start"); 126 Function *RegionEnd = M.getFunction("llvm.dbg.region.end"); 127 Function *Declare = M.getFunction("llvm.dbg.declare"); 128 if (!FuncStart && !StopPoint && !RegionStart && !RegionEnd && !Declare) 129 return true; 130 131 std::vector<GlobalVariable*> DeadGlobals; 132 133 // Remove all of the calls to the debugger intrinsics, and remove them from 134 // the module. 135 if (FuncStart) { 136 while (!FuncStart->use_empty()) { 137 CallInst *CI = cast<CallInst>(FuncStart->use_back()); 138 Value *Arg = CI->getOperand(1); 139 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 140 CI->eraseFromParent(); 141 if (Arg->use_empty()) 142 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 143 DeadGlobals.push_back(GV); 144 } 145 FuncStart->eraseFromParent(); 146 } 147 if (StopPoint) { 148 while (!StopPoint->use_empty()) { 149 CallInst *CI = cast<CallInst>(StopPoint->use_back()); 150 Value *Arg = CI->getOperand(3); 151 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 152 CI->eraseFromParent(); 153 if (Arg->use_empty()) 154 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 155 DeadGlobals.push_back(GV); 156 } 157 StopPoint->eraseFromParent(); 158 } 159 if (RegionStart) { 160 while (!RegionStart->use_empty()) { 161 CallInst *CI = cast<CallInst>(RegionStart->use_back()); 162 Value *Arg = CI->getOperand(1); 163 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 164 CI->eraseFromParent(); 165 if (Arg->use_empty()) 166 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 167 DeadGlobals.push_back(GV); 168 } 169 RegionStart->eraseFromParent(); 170 } 171 if (RegionEnd) { 172 while (!RegionEnd->use_empty()) { 173 CallInst *CI = cast<CallInst>(RegionEnd->use_back()); 174 Value *Arg = CI->getOperand(1); 175 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 176 CI->eraseFromParent(); 177 if (Arg->use_empty()) 178 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 179 DeadGlobals.push_back(GV); 180 } 181 RegionEnd->eraseFromParent(); 182 } 183 if (Declare) { 184 while (!Declare->use_empty()) { 185 CallInst *CI = cast<CallInst>(Declare->use_back()); 186 Value *Arg = CI->getOperand(2); 187 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 188 CI->eraseFromParent(); 189 if (Arg->use_empty()) 190 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 191 DeadGlobals.push_back(GV); 192 } 193 Declare->eraseFromParent(); 194 } 195 196 // Finally, delete any internal globals that were only used by the debugger 197 // intrinsics. 198 while (!DeadGlobals.empty()) { 199 GlobalVariable *GV = DeadGlobals.back(); 200 DeadGlobals.pop_back(); 201 if (GV->hasInternalLinkage()) 202 RemoveDeadConstant(GV); 203 } 204 205 return true; 206} 207