StripSymbols.cpp revision ef9b9a793949469cdaa4ab6d0173136229dcab7b
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" 31ef9b9a793949469cdaa4ab6d0173136229dcab7bReid Spencer#include "llvm/ValueSymbolTable.h" 3278d033e086e19e016273de014f9214aa6f3f844bReid Spencer#include "llvm/TypeSymbolTable.h" 33e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattnerusing namespace llvm; 34e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 35e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattnernamespace { 36e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner class StripSymbols : public ModulePass { 37e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner bool OnlyDebugInfo; 38e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner public: 39e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner StripSymbols(bool ODI = false) : OnlyDebugInfo(ODI) {} 40e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 41e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner virtual bool runOnModule(Module &M); 42e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 43e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner virtual void getAnalysisUsage(AnalysisUsage &AU) const { 44e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner AU.setPreservesAll(); 45e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner } 46e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner }; 477f8897f22e88271cfa114998a4d6088e7c8e8e11Chris Lattner RegisterPass<StripSymbols> X("strip", "Strip all symbols from a module"); 48e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner} 49e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 50e3ad43c828280cf11e8631f1a814a51a0b168016Chris LattnerModulePass *llvm::createStripSymbolsPass(bool OnlyDebugInfo) { 51e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner return new StripSymbols(OnlyDebugInfo); 52e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner} 53e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 54dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattnerstatic void RemoveDeadConstant(Constant *C) { 55dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner assert(C->use_empty() && "Constant is not dead!"); 56dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner std::vector<Constant*> Operands; 57dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) 58dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (isa<DerivedType>(C->getOperand(i)->getType()) && 59dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner C->getOperand(i)->hasOneUse()) 60dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner Operands.push_back(C->getOperand(i)); 61dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) { 62dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (!GV->hasInternalLinkage()) return; // Don't delete non static globals. 63dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner GV->eraseFromParent(); 64dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 65dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner else if (!isa<Function>(C)) 66dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner C->destroyConstant(); 67fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman 68dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner // If the constant referenced anything, see if we can delete it as well. 69dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner while (!Operands.empty()) { 70dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner RemoveDeadConstant(Operands.back()); 71dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner Operands.pop_back(); 72dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 73dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner} 74e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 75e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattnerbool StripSymbols::runOnModule(Module &M) { 76e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner // If we're not just stripping debug info, strip all symbols from the 77e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner // functions and the names from any internal globals. 78e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner if (!OnlyDebugInfo) { 797f8897f22e88271cfa114998a4d6088e7c8e8e11Chris Lattner for (Module::global_iterator I = M.global_begin(), E = M.global_end(); 807f8897f22e88271cfa114998a4d6088e7c8e8e11Chris Lattner I != E; ++I) 81e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner if (I->hasInternalLinkage()) 82e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner I->setName(""); // Internal symbols can't participate in linkage 83e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner 84e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { 85e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner if (I->hasInternalLinkage()) 86e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner I->setName(""); // Internal symbols can't participate in linkage 8778d033e086e19e016273de014f9214aa6f3f844bReid Spencer I->getValueSymbolTable().strip(); 88e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner } 89b2f6c0075cc1aafce3c83a756242f148429ade0fChris Lattner 90b2f6c0075cc1aafce3c83a756242f148429ade0fChris Lattner // Remove all names from types. 9178d033e086e19e016273de014f9214aa6f3f844bReid Spencer M.getTypeSymbolTable().strip(); 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"); 994ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey Function *RegionStart = M.getNamedFunction("llvm.dbg.region.start"); 100dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner Function *RegionEnd = M.getNamedFunction("llvm.dbg.region.end"); 1014ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey Function *Declare = M.getNamedFunction("llvm.dbg.declare"); 1024ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey if (!FuncStart && !StopPoint && !RegionStart && !RegionEnd && !Declare) 103dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner return true; 104dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner 105dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner std::vector<GlobalVariable*> DeadGlobals; 106dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner 107dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner // Remove all of the calls to the debugger intrinsics, and remove them from 108dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner // the module. 109dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (FuncStart) { 110dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner while (!FuncStart->use_empty()) { 111dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner CallInst *CI = cast<CallInst>(FuncStart->use_back()); 112dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner Value *Arg = CI->getOperand(1); 1134ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 114dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner CI->eraseFromParent(); 115dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (Arg->use_empty()) 116dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 117dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner DeadGlobals.push_back(GV); 118dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 119dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner FuncStart->eraseFromParent(); 120dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 121dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (StopPoint) { 122dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner while (!StopPoint->use_empty()) { 123dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner CallInst *CI = cast<CallInst>(StopPoint->use_back()); 124f4321a3a438833dade457e24da6e1e6907cabcd5Jim Laskey Value *Arg = CI->getOperand(3); 1254ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 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 } 1334ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey if (RegionStart) { 1344ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey while (!RegionStart->use_empty()) { 1354ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey CallInst *CI = cast<CallInst>(RegionStart->use_back()); 1364ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey Value *Arg = CI->getOperand(1); 1374ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 1384ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey CI->eraseFromParent(); 1394ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey if (Arg->use_empty()) 1404ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 1414ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey DeadGlobals.push_back(GV); 1424ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey } 1434ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey RegionStart->eraseFromParent(); 1444ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey } 145dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (RegionEnd) { 146dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner while (!RegionEnd->use_empty()) { 147dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner CallInst *CI = cast<CallInst>(RegionEnd->use_back()); 1484ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey Value *Arg = CI->getOperand(1); 1494ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 150dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner CI->eraseFromParent(); 1514ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey if (Arg->use_empty()) 1524ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 1534ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey DeadGlobals.push_back(GV); 154dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 155dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner RegionEnd->eraseFromParent(); 156dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 1574ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey if (Declare) { 1584ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey while (!Declare->use_empty()) { 1594ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey CallInst *CI = cast<CallInst>(Declare->use_back()); 1604ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey Value *Arg = CI->getOperand(2); 1614ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey assert(CI->use_empty() && "llvm.dbg intrinsic should have void result"); 1624ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey CI->eraseFromParent(); 1634ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey if (Arg->use_empty()) 1644ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg)) 1654ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey DeadGlobals.push_back(GV); 1664ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey } 1674ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey Declare->eraseFromParent(); 1684ca9757a39a1bf3bd1264a77e52db62e02cc85fbJim Laskey } 169dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner 170dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner // Finally, delete any internal globals that were only used by the debugger 171dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner // intrinsics. 172dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner while (!DeadGlobals.empty()) { 173dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner GlobalVariable *GV = DeadGlobals.back(); 174dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner DeadGlobals.pop_back(); 175dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner if (GV->hasInternalLinkage()) 176dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner RemoveDeadConstant(GV); 177dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner } 178dd0ecf67316d68940fda2733faacf73b8bd22ec6Chris Lattner 179fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman return true; 180e3ad43c828280cf11e8631f1a814a51a0b168016Chris Lattner} 181