StripSymbols.cpp revision f4321a3a438833dade457e24da6e1e6907cabcd5
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 } 87e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner } 88e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 89dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner // Strip debug info in the module if it exists. To do this, we remove 90dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner // llvm.dbg.func.start, llvm.dbg.stoppoint, and llvm.dbg.region.end calls, and 91dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner // any globals they point to if now dead. 92dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner Function *FuncStart = M.getNamedFunction("llvm.dbg.func.start"); 93dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner Function *StopPoint = M.getNamedFunction("llvm.dbg.stoppoint"); 94dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner Function *RegionEnd = M.getNamedFunction("llvm.dbg.region.end"); 95dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (!FuncStart && !StopPoint && !RegionEnd) 96dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner return true; 97dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner 98dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner std::vector<GlobalVariable*> DeadGlobals; 99dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner 100dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner // Remove all of the calls to the debugger intrinsics, and remove them from 101dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner // the module. 102dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (FuncStart) { 103e2b59d2760a4f72c84c262af67642ba09e91bfd1Chris Lattner Value *RV = UndefValue::get(FuncStart->getFunctionType()->getReturnType()); 104dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner while (!FuncStart->use_empty()) { 105dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner CallInst *CI = cast<CallInst>(FuncStart->use_back()); 106dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner Value *Arg = CI->getOperand(1); 107dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner CI->replaceAllUsesWith(RV); 108dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner CI->eraseFromParent(); 109dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (Arg->use_empty()) 110dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 111dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner DeadGlobals.push_back(GV); 112dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 113dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner FuncStart->eraseFromParent(); 114dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 115dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (StopPoint) { 116dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner Value *RV = UndefValue::get(StopPoint->getFunctionType()->getReturnType()); 117dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner while (!StopPoint->use_empty()) { 118dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner CallInst *CI = cast<CallInst>(StopPoint->use_back()); 119f4321a3a438833dade457e24da6e1e6907cabcd5Jim Laskey Value *Arg = CI->getOperand(3); 120dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner CI->replaceAllUsesWith(RV); 121dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner CI->eraseFromParent(); 122dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (Arg->use_empty()) 123dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 124dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner DeadGlobals.push_back(GV); 125dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 126dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner StopPoint->eraseFromParent(); 127dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 128dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (RegionEnd) { 129dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner Value *RV = UndefValue::get(RegionEnd->getFunctionType()->getReturnType()); 130dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner while (!RegionEnd->use_empty()) { 131dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner CallInst *CI = cast<CallInst>(RegionEnd->use_back()); 132dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner CI->replaceAllUsesWith(RV); 133dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner CI->eraseFromParent(); 134dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 135dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner RegionEnd->eraseFromParent(); 136dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 137dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner 138dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner // Finally, delete any internal globals that were only used by the debugger 139dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner // intrinsics. 140dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner while (!DeadGlobals.empty()) { 141dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner GlobalVariable *GV = DeadGlobals.back(); 142dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner DeadGlobals.pop_back(); 143dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (GV->hasInternalLinkage()) 144dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner RemoveDeadConstant(GV); 145dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 146dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner 147fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman return true; 148e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner} 149