StripSymbols.cpp revision b2f6c0075cc1aafce3c83a756242f148429ade0f
1e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner//===- StripSymbols.cpp - Strip symbols and debug info from a module ------===// 2fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman// 3e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner// The LLVM Compiler Infrastructure 4e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner// 5e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner// This file was developed by the LLVM research group and is distributed under 6e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner// the University of Illinois Open Source License. See LICENSE.TXT for details. 7fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman// 8e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner//===----------------------------------------------------------------------===// 9e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner// 10e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner// This file implements stripping symbols out of symbol tables. 11e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner// 12e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner// Specifically, this allows you to strip all of the symbols out of: 13e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner// * All functions in a module 14e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner// * All non-essential symbols in a module (all function symbols + all module 15e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner// scope symbols) 16e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner// * Debug information. 17e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner// 18e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner// Notice that: 19e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner// * This pass makes code much less readable, so it should only be used in 20fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman// situations where the 'strip' utility would be used (such as reducing 21e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner// code size, and making it harder to reverse engineer code). 22e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner// 23e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner//===----------------------------------------------------------------------===// 24e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 25e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner#include "llvm/Transforms/IPO.h" 26dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner#include "llvm/Constants.h" 27dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner#include "llvm/DerivedTypes.h" 28dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner#include "llvm/Instructions.h" 29e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner#include "llvm/Module.h" 30e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner#include "llvm/Pass.h" 31dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner#include "llvm/SymbolTable.h" 32e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattnerusing namespace llvm; 33e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 34e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattnernamespace { 35e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner class StripSymbols : public ModulePass { 36e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner bool OnlyDebugInfo; 37e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner public: 38e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner StripSymbols(bool ODI = false) : OnlyDebugInfo(ODI) {} 39e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 40e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner virtual bool runOnModule(Module &M); 41e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 42e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner virtual void getAnalysisUsage(AnalysisUsage &AU) const { 43e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner AU.setPreservesAll(); 44e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner } 45e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner }; 46e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner RegisterOpt<StripSymbols> X("strip", "Strip all symbols from a module"); 47e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner} 48e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 49e3ad43c828280cf11e8631f1a814a51a0b168016Chris LattnerModulePass *llvm::createStripSymbolsPass(bool OnlyDebugInfo) { 50e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner return new StripSymbols(OnlyDebugInfo); 51e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner} 52e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 53dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattnerstatic void RemoveDeadConstant(Constant *C) { 54dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner assert(C->use_empty() && "Constant is not dead!"); 55dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner std::vector<Constant*> Operands; 56dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) 57dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (isa<DerivedType>(C->getOperand(i)->getType()) && 58dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner C->getOperand(i)->hasOneUse()) 59dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner Operands.push_back(C->getOperand(i)); 60dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) { 61dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (!GV->hasInternalLinkage()) return; // Don't delete non static globals. 62dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner GV->eraseFromParent(); 63dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 64dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner else if (!isa<Function>(C)) 65dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner C->destroyConstant(); 66fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman 67dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner // If the constant referenced anything, see if we can delete it as well. 68dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner while (!Operands.empty()) { 69dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner RemoveDeadConstant(Operands.back()); 70dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner Operands.pop_back(); 71dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 72dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner} 73e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 74e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattnerbool StripSymbols::runOnModule(Module &M) { 75e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner // If we're not just stripping debug info, strip all symbols from the 76e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner // functions and the names from any internal globals. 77e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner if (!OnlyDebugInfo) { 78e4d5c441e04bdc00ccf1804744af670655123b07Chris Lattner for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) 79e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner if (I->hasInternalLinkage()) 80e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner I->setName(""); // Internal symbols can't participate in linkage 81e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 82e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { 83e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner if (I->hasInternalLinkage()) 84e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner I->setName(""); // Internal symbols can't participate in linkage 85e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner I->getSymbolTable().strip(); 86e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner } 87b2f6c0075cc1aafce3c83a756242f148429ade0fChris Lattner 88b2f6c0075cc1aafce3c83a756242f148429ade0fChris Lattner // Remove all names from types. 89b2f6c0075cc1aafce3c83a756242f148429ade0fChris Lattner SymbolTable &SymTab = M.getSymbolTable(); 90b2f6c0075cc1aafce3c83a756242f148429ade0fChris Lattner while (SymTab.type_begin() != SymTab.type_end()) 91b2f6c0075cc1aafce3c83a756242f148429ade0fChris Lattner SymTab.remove(SymTab.type_begin()); 92e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner } 93e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 94dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner // Strip debug info in the module if it exists. To do this, we remove 95dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner // llvm.dbg.func.start, llvm.dbg.stoppoint, and llvm.dbg.region.end calls, and 96dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner // any globals they point to if now dead. 97dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner Function *FuncStart = M.getNamedFunction("llvm.dbg.func.start"); 98dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner Function *StopPoint = M.getNamedFunction("llvm.dbg.stoppoint"); 99dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner Function *RegionEnd = M.getNamedFunction("llvm.dbg.region.end"); 100dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (!FuncStart && !StopPoint && !RegionEnd) 101dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner return true; 102dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner 103dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner std::vector<GlobalVariable*> DeadGlobals; 104dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner 105dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner // Remove all of the calls to the debugger intrinsics, and remove them from 106dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner // the module. 107dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (FuncStart) { 108e2b59d2760a4f72c84c262af67642ba09e91bfd1Chris Lattner Value *RV = UndefValue::get(FuncStart->getFunctionType()->getReturnType()); 109dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner while (!FuncStart->use_empty()) { 110dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner CallInst *CI = cast<CallInst>(FuncStart->use_back()); 111dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner Value *Arg = CI->getOperand(1); 112dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner CI->replaceAllUsesWith(RV); 113dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner CI->eraseFromParent(); 114dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (Arg->use_empty()) 115dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 116dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner DeadGlobals.push_back(GV); 117dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 118dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner FuncStart->eraseFromParent(); 119dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 120dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (StopPoint) { 121dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner Value *RV = UndefValue::get(StopPoint->getFunctionType()->getReturnType()); 122dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner while (!StopPoint->use_empty()) { 123dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner CallInst *CI = cast<CallInst>(StopPoint->use_back()); 124f4321a3a438833dade457e24da6e1e6907cabcd5Jim Laskey Value *Arg = CI->getOperand(3); 125dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner CI->replaceAllUsesWith(RV); 126dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner CI->eraseFromParent(); 127dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (Arg->use_empty()) 128dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 129dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner DeadGlobals.push_back(GV); 130dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 131dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner StopPoint->eraseFromParent(); 132dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 133dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (RegionEnd) { 134dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner Value *RV = UndefValue::get(RegionEnd->getFunctionType()->getReturnType()); 135dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner while (!RegionEnd->use_empty()) { 136dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner CallInst *CI = cast<CallInst>(RegionEnd->use_back()); 137dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner CI->replaceAllUsesWith(RV); 138dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner CI->eraseFromParent(); 139dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 140dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner RegionEnd->eraseFromParent(); 141dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 142dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner 143dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner // Finally, delete any internal globals that were only used by the debugger 144dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner // intrinsics. 145dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner while (!DeadGlobals.empty()) { 146dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner GlobalVariable *GV = DeadGlobals.back(); 147dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner DeadGlobals.pop_back(); 148dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (GV->hasInternalLinkage()) 149dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner RemoveDeadConstant(GV); 150dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 151dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner 152fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman return true; 153e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner} 154