LLVM API Documentation

StripSymbols.cpp

Go to the documentation of this file.
00001 //===- StripSymbols.cpp - Strip symbols and debug info from a module ------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by the LLVM research group and is distributed under
00006 // the University of Illinois Open Source License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements stripping symbols out of symbol tables.
00011 //
00012 // Specifically, this allows you to strip all of the symbols out of:
00013 //   * All functions in a module
00014 //   * All non-essential symbols in a module (all function symbols + all module
00015 //     scope symbols)
00016 //   * Debug information.
00017 //
00018 // Notice that:
00019 //   * This pass makes code much less readable, so it should only be used in
00020 //     situations where the 'strip' utility would be used (such as reducing
00021 //     code size, and making it harder to reverse engineer code).
00022 //
00023 //===----------------------------------------------------------------------===//
00024 
00025 #include "llvm/Transforms/IPO.h"
00026 #include "llvm/Constants.h"
00027 #include "llvm/DerivedTypes.h"
00028 #include "llvm/Instructions.h"
00029 #include "llvm/Module.h"
00030 #include "llvm/Pass.h"
00031 #include "llvm/SymbolTable.h"
00032 using namespace llvm;
00033 
00034 namespace {
00035   class StripSymbols : public ModulePass {
00036     bool OnlyDebugInfo;
00037   public:
00038     StripSymbols(bool ODI = false) : OnlyDebugInfo(ODI) {}
00039 
00040     virtual bool runOnModule(Module &M);
00041 
00042     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
00043       AU.setPreservesAll();
00044     }
00045   };
00046   RegisterOpt<StripSymbols> X("strip", "Strip all symbols from a module");
00047 }
00048 
00049 ModulePass *llvm::createStripSymbolsPass(bool OnlyDebugInfo) {
00050   return new StripSymbols(OnlyDebugInfo);
00051 }
00052 
00053 static void RemoveDeadConstant(Constant *C) {
00054   assert(C->use_empty() && "Constant is not dead!");
00055   std::vector<Constant*> Operands;
00056   for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i)
00057     if (isa<DerivedType>(C->getOperand(i)->getType()) &&
00058         C->getOperand(i)->hasOneUse())
00059       Operands.push_back(C->getOperand(i));
00060   if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) {
00061     if (!GV->hasInternalLinkage()) return;   // Don't delete non static globals.
00062     GV->eraseFromParent();
00063   }
00064   else if (!isa<Function>(C))
00065     C->destroyConstant();
00066 
00067   // If the constant referenced anything, see if we can delete it as well.
00068   while (!Operands.empty()) {
00069     RemoveDeadConstant(Operands.back());
00070     Operands.pop_back();
00071   }
00072 }
00073 
00074 bool StripSymbols::runOnModule(Module &M) {
00075   // If we're not just stripping debug info, strip all symbols from the
00076   // functions and the names from any internal globals.
00077   if (!OnlyDebugInfo) {
00078     for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
00079       if (I->hasInternalLinkage())
00080         I->setName("");     // Internal symbols can't participate in linkage
00081 
00082     for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
00083       if (I->hasInternalLinkage())
00084         I->setName("");     // Internal symbols can't participate in linkage
00085       I->getSymbolTable().strip();
00086     }
00087     
00088     // Remove all names from types.
00089     SymbolTable &SymTab = M.getSymbolTable();
00090     while (SymTab.type_begin() != SymTab.type_end())
00091       SymTab.remove(SymTab.type_begin());
00092   }
00093 
00094   // Strip debug info in the module if it exists.  To do this, we remove
00095   // llvm.dbg.func.start, llvm.dbg.stoppoint, and llvm.dbg.region.end calls, and
00096   // any globals they point to if now dead.
00097   Function *FuncStart = M.getNamedFunction("llvm.dbg.func.start");
00098   Function *StopPoint = M.getNamedFunction("llvm.dbg.stoppoint");
00099   Function *RegionStart = M.getNamedFunction("llvm.dbg.region.start");
00100   Function *RegionEnd = M.getNamedFunction("llvm.dbg.region.end");
00101   Function *Declare = M.getNamedFunction("llvm.dbg.declare");
00102   if (!FuncStart && !StopPoint && !RegionStart && !RegionEnd && !Declare)
00103     return true;
00104 
00105   std::vector<GlobalVariable*> DeadGlobals;
00106 
00107   // Remove all of the calls to the debugger intrinsics, and remove them from
00108   // the module.
00109   if (FuncStart) {
00110     while (!FuncStart->use_empty()) {
00111       CallInst *CI = cast<CallInst>(FuncStart->use_back());
00112       Value *Arg = CI->getOperand(1);
00113       assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
00114       CI->eraseFromParent();
00115       if (Arg->use_empty())
00116         if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg))
00117           DeadGlobals.push_back(GV);
00118     }
00119     FuncStart->eraseFromParent();
00120   }
00121   if (StopPoint) {
00122     while (!StopPoint->use_empty()) {
00123       CallInst *CI = cast<CallInst>(StopPoint->use_back());
00124       Value *Arg = CI->getOperand(3);
00125       assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
00126       CI->eraseFromParent();
00127       if (Arg->use_empty())
00128         if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg))
00129           DeadGlobals.push_back(GV);
00130     }
00131     StopPoint->eraseFromParent();
00132   }
00133   if (RegionStart) {
00134     while (!RegionStart->use_empty()) {
00135       CallInst *CI = cast<CallInst>(RegionStart->use_back());
00136       Value *Arg = CI->getOperand(1);
00137       assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
00138       CI->eraseFromParent();
00139       if (Arg->use_empty())
00140         if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg))
00141           DeadGlobals.push_back(GV);
00142     }
00143     RegionStart->eraseFromParent();
00144   }
00145   if (RegionEnd) {
00146     while (!RegionEnd->use_empty()) {
00147       CallInst *CI = cast<CallInst>(RegionEnd->use_back());
00148       Value *Arg = CI->getOperand(1);
00149       assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
00150       CI->eraseFromParent();
00151       if (Arg->use_empty())
00152         if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg))
00153           DeadGlobals.push_back(GV);
00154     }
00155     RegionEnd->eraseFromParent();
00156   }
00157   if (Declare) {
00158     while (!Declare->use_empty()) {
00159       CallInst *CI = cast<CallInst>(Declare->use_back());
00160       Value *Arg = CI->getOperand(2);
00161       assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
00162       CI->eraseFromParent();
00163       if (Arg->use_empty())
00164         if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg))
00165           DeadGlobals.push_back(GV);
00166     }
00167     Declare->eraseFromParent();
00168   }
00169 
00170   // Finally, delete any internal globals that were only used by the debugger
00171   // intrinsics.
00172   while (!DeadGlobals.empty()) {
00173     GlobalVariable *GV = DeadGlobals.back();
00174     DeadGlobals.pop_back();
00175     if (GV->hasInternalLinkage())
00176       RemoveDeadConstant(GV);
00177   }
00178 
00179   return true;
00180 }