StripSymbols.cpp revision 7f8897f22e88271cfa114998a4d6088e7c8e8e11
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/SymbolTable.h" 32using namespace llvm; 33 34namespace { 35 class StripSymbols : public ModulePass { 36 bool OnlyDebugInfo; 37 public: 38 StripSymbols(bool ODI = false) : OnlyDebugInfo(ODI) {} 39 40 virtual bool runOnModule(Module &M); 41 42 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 43 AU.setPreservesAll(); 44 } 45 }; 46 RegisterPass<StripSymbols> X("strip", "Strip all symbols from a module"); 47} 48 49ModulePass *llvm::createStripSymbolsPass(bool OnlyDebugInfo) { 50 return new StripSymbols(OnlyDebugInfo); 51} 52 53static void RemoveDeadConstant(Constant *C) { 54 assert(C->use_empty() && "Constant is not dead!"); 55 std::vector<Constant*> Operands; 56 for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) 57 if (isa<DerivedType>(C->getOperand(i)->getType()) && 58 C->getOperand(i)->hasOneUse()) 59 Operands.push_back(C->getOperand(i)); 60 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) { 61 if (!GV->hasInternalLinkage()) return; // Don't delete non static globals. 62 GV->eraseFromParent(); 63 } 64 else if (!isa<Function>(C)) 65 C->destroyConstant(); 66 67 // If the constant referenced anything, see if we can delete it as well. 68 while (!Operands.empty()) { 69 RemoveDeadConstant(Operands.back()); 70 Operands.pop_back(); 71 } 72} 73 74bool StripSymbols::runOnModule(Module &M) { 75 // If we're not just stripping debug info, strip all symbols from the 76 // functions and the names from any internal globals. 77 if (!OnlyDebugInfo) { 78 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); 79 I != E; ++I) 80 if (I->hasInternalLinkage()) 81 I->setName(""); // Internal symbols can't participate in linkage 82 83 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { 84 if (I->hasInternalLinkage()) 85 I->setName(""); // Internal symbols can't participate in linkage 86 I->getSymbolTable().strip(); 87 } 88 89 // Remove all names from types. 90 SymbolTable &SymTab = M.getSymbolTable(); 91 while (SymTab.type_begin() != SymTab.type_end()) 92 SymTab.remove(SymTab.type_begin()); 93 } 94 95 // Strip debug info in the module if it exists. To do this, we remove 96 // llvm.dbg.func.start, llvm.dbg.stoppoint, and llvm.dbg.region.end calls, and 97 // any globals they point to if now dead. 98 Function *FuncStart = M.getNamedFunction("llvm.dbg.func.start"); 99 Function *StopPoint = M.getNamedFunction("llvm.dbg.stoppoint"); 100 Function *RegionStart = M.getNamedFunction("llvm.dbg.region.start"); 101 Function *RegionEnd = M.getNamedFunction("llvm.dbg.region.end"); 102 Function *Declare = M.getNamedFunction("llvm.dbg.declare"); 103 if (!FuncStart && !StopPoint && !RegionStart && !RegionEnd && !Declare) 104 return true; 105 106 std::vector<GlobalVariable*> DeadGlobals; 107 108 // Remove all of the calls to the debugger intrinsics, and remove them from 109 // the module. 110 if (FuncStart) { 111 while (!FuncStart->use_empty()) { 112 CallInst *CI = cast<CallInst>(FuncStart->use_back()); 113 Value *Arg = CI->getOperand(1); 114 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 115 CI->eraseFromParent(); 116 if (Arg->use_empty()) 117 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 118 DeadGlobals.push_back(GV); 119 } 120 FuncStart->eraseFromParent(); 121 } 122 if (StopPoint) { 123 while (!StopPoint->use_empty()) { 124 CallInst *CI = cast<CallInst>(StopPoint->use_back()); 125 Value *Arg = CI->getOperand(3); 126 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 127 CI->eraseFromParent(); 128 if (Arg->use_empty()) 129 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 130 DeadGlobals.push_back(GV); 131 } 132 StopPoint->eraseFromParent(); 133 } 134 if (RegionStart) { 135 while (!RegionStart->use_empty()) { 136 CallInst *CI = cast<CallInst>(RegionStart->use_back()); 137 Value *Arg = CI->getOperand(1); 138 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 139 CI->eraseFromParent(); 140 if (Arg->use_empty()) 141 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 142 DeadGlobals.push_back(GV); 143 } 144 RegionStart->eraseFromParent(); 145 } 146 if (RegionEnd) { 147 while (!RegionEnd->use_empty()) { 148 CallInst *CI = cast<CallInst>(RegionEnd->use_back()); 149 Value *Arg = CI->getOperand(1); 150 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 151 CI->eraseFromParent(); 152 if (Arg->use_empty()) 153 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 154 DeadGlobals.push_back(GV); 155 } 156 RegionEnd->eraseFromParent(); 157 } 158 if (Declare) { 159 while (!Declare->use_empty()) { 160 CallInst *CI = cast<CallInst>(Declare->use_back()); 161 Value *Arg = CI->getOperand(2); 162 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 163 CI->eraseFromParent(); 164 if (Arg->use_empty()) 165 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 166 DeadGlobals.push_back(GV); 167 } 168 Declare->eraseFromParent(); 169 } 170 171 // Finally, delete any internal globals that were only used by the debugger 172 // intrinsics. 173 while (!DeadGlobals.empty()) { 174 GlobalVariable *GV = DeadGlobals.back(); 175 DeadGlobals.pop_back(); 176 if (GV->hasInternalLinkage()) 177 RemoveDeadConstant(GV); 178 } 179 180 return true; 181} 182