LLVM API Documentation

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

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::giterator I = M.gbegin(), E = M.gend(); 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 
00089   // Strip debug info in the module if it exists.  To do this, we remove
00090   // llvm.dbg.func.start, llvm.dbg.stoppoint, and llvm.dbg.region.end calls, and
00091   // any globals they point to if now dead.
00092   Function *FuncStart = M.getNamedFunction("llvm.dbg.func.start");
00093   Function *StopPoint = M.getNamedFunction("llvm.dbg.stoppoint");
00094   Function *RegionEnd = M.getNamedFunction("llvm.dbg.region.end");
00095   if (!FuncStart && !StopPoint && !RegionEnd)
00096     return true;
00097 
00098   std::vector<GlobalVariable*> DeadGlobals;
00099 
00100   // Remove all of the calls to the debugger intrinsics, and remove them from
00101   // the module.
00102   if (FuncStart) {
00103     Value *RV = UndefValue::get(StopPoint->getFunctionType()->getReturnType());
00104     while (!FuncStart->use_empty()) {
00105       CallInst *CI = cast<CallInst>(FuncStart->use_back());
00106       Value *Arg = CI->getOperand(1);
00107       CI->replaceAllUsesWith(RV);
00108       CI->eraseFromParent();
00109       if (Arg->use_empty())
00110         if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg))
00111           DeadGlobals.push_back(GV);
00112     }
00113     FuncStart->eraseFromParent();
00114   }
00115   if (StopPoint) {
00116     Value *RV = UndefValue::get(StopPoint->getFunctionType()->getReturnType());
00117     while (!StopPoint->use_empty()) {
00118       CallInst *CI = cast<CallInst>(StopPoint->use_back());
00119       Value *Arg = CI->getOperand(4);
00120       CI->replaceAllUsesWith(RV);
00121       CI->eraseFromParent();
00122       if (Arg->use_empty())
00123         if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg))
00124           DeadGlobals.push_back(GV);
00125     }
00126     StopPoint->eraseFromParent();
00127   }
00128   if (RegionEnd) {
00129     Value *RV = UndefValue::get(RegionEnd->getFunctionType()->getReturnType());
00130     while (!RegionEnd->use_empty()) {
00131       CallInst *CI = cast<CallInst>(RegionEnd->use_back());
00132       CI->replaceAllUsesWith(RV);
00133       CI->eraseFromParent();
00134     }
00135     RegionEnd->eraseFromParent();
00136   }
00137 
00138   // Finally, delete any internal globals that were only used by the debugger
00139   // intrinsics.
00140   while (!DeadGlobals.empty()) {
00141     GlobalVariable *GV = DeadGlobals.back();
00142     DeadGlobals.pop_back();
00143     if (GV->hasInternalLinkage())
00144       RemoveDeadConstant(GV);
00145   }
00146 
00147   return true; 
00148 }