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 is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // The StripSymbols transformation implements code stripping. Specifically, it
00011 // can delete:
00012 // 
00013 //   * names for virtual registers
00014 //   * symbols for internal globals and functions
00015 //   * debug information
00016 //
00017 // Note that this transformation makes code much less readable, so it should
00018 // only be used in situations where the 'strip' utility would be used, such as
00019 // reducing code size or making it harder to reverse engineer code.
00020 //
00021 //===----------------------------------------------------------------------===//
00022 
00023 #include "llvm/Transforms/IPO.h"
00024 #include "llvm/Constants.h"
00025 #include "llvm/DerivedTypes.h"
00026 #include "llvm/Instructions.h"
00027 #include "llvm/Module.h"
00028 #include "llvm/Pass.h"
00029 #include "llvm/ValueSymbolTable.h"
00030 #include "llvm/TypeSymbolTable.h"
00031 #include "llvm/Support/Compiler.h"
00032 #include "llvm/ADT/SmallPtrSet.h"
00033 using namespace llvm;
00034 
00035 namespace {
00036   class VISIBILITY_HIDDEN StripSymbols : public ModulePass {
00037     bool OnlyDebugInfo;
00038   public:
00039     static char ID; // Pass identification, replacement for typeid
00040     explicit StripSymbols(bool ODI = false) 
00041       : ModulePass(&ID), OnlyDebugInfo(ODI) {}
00042 
00043     virtual bool runOnModule(Module &M);
00044 
00045     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
00046       AU.setPreservesAll();
00047     }
00048   };
00049 
00050   class VISIBILITY_HIDDEN StripNonDebugSymbols : public ModulePass {
00051   public:
00052     static char ID; // Pass identification, replacement for typeid
00053     explicit StripNonDebugSymbols()
00054       : ModulePass(&ID) {}
00055 
00056     virtual bool runOnModule(Module &M);
00057 
00058     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
00059       AU.setPreservesAll();
00060     }
00061   };
00062 }
00063 
00064 char StripSymbols::ID = 0;
00065 static RegisterPass<StripSymbols>
00066 X("strip", "Strip all symbols from a module");
00067 
00068 ModulePass *llvm::createStripSymbolsPass(bool OnlyDebugInfo) {
00069   return new StripSymbols(OnlyDebugInfo);
00070 }
00071 
00072 char StripNonDebugSymbols::ID = 0;
00073 static RegisterPass<StripNonDebugSymbols>
00074 Y("strip-nondebug", "Strip all symbols, except dbg symbols, from a module");
00075 
00076 ModulePass *llvm::createStripNonDebugSymbolsPass() {
00077   return new StripNonDebugSymbols();
00078 }
00079 
00080 /// OnlyUsedBy - Return true if V is only used by Usr.
00081 static bool OnlyUsedBy(Value *V, Value *Usr) {
00082   for(Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) {
00083     User *U = *I;
00084     if (U != Usr)
00085       return false;
00086   }
00087   return true;
00088 }
00089 
00090 static void RemoveDeadConstant(Constant *C) {
00091   assert(C->use_empty() && "Constant is not dead!");
00092   SmallPtrSet<Constant *, 4> Operands;
00093   for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i)
00094     if (isa<DerivedType>(C->getOperand(i)->getType()) &&
00095         OnlyUsedBy(C->getOperand(i), C)) 
00096       Operands.insert(C->getOperand(i));
00097   if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) {
00098     if (!GV->hasInternalLinkage()) return;   // Don't delete non static globals.
00099     GV->eraseFromParent();
00100   }
00101   else if (!isa<Function>(C))
00102     if (isa<CompositeType>(C->getType()))
00103       C->destroyConstant();
00104 
00105   // If the constant referenced anything, see if we can delete it as well.
00106   for (SmallPtrSet<Constant *, 4>::iterator OI = Operands.begin(),
00107          OE = Operands.end(); OI != OE; ++OI)
00108     RemoveDeadConstant(*OI);
00109 }
00110 
00111 // Strip the symbol table of its names.
00112 //
00113 static void StripSymtab(ValueSymbolTable &ST, bool PreserveDbgInfo) {
00114   for (ValueSymbolTable::iterator VI = ST.begin(), VE = ST.end(); VI != VE; ) {
00115     Value *V = VI->getValue();
00116     ++VI;
00117     if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasInternalLinkage()) {
00118       if (!PreserveDbgInfo || strncmp(V->getNameStart(), "llvm.dbg", 8))
00119         // Set name to "", removing from symbol table!
00120         V->setName("");
00121     }
00122   }
00123 }
00124 
00125 // Strip the symbol table of its names.
00126 static void StripTypeSymtab(TypeSymbolTable &ST, bool PreserveDbgInfo) {
00127   for (TypeSymbolTable::iterator TI = ST.begin(), E = ST.end(); TI != E; ) {
00128     if (PreserveDbgInfo && strncmp(TI->first.c_str(), "llvm.dbg", 8) == 0)
00129       ++TI;
00130     else
00131       ST.remove(TI++);
00132   }
00133 }
00134 
00135 /// Find values that are marked as llvm.used.
00136 void findUsedValues(Module &M,
00137                     SmallPtrSet<const GlobalValue*, 8>& llvmUsedValues) {
00138   if (GlobalVariable *LLVMUsed = M.getGlobalVariable("llvm.used")) {
00139     llvmUsedValues.insert(LLVMUsed);
00140     // Collect values that are preserved as per explicit request.
00141     // llvm.used is used to list these values.
00142     if (ConstantArray *Inits = 
00143         dyn_cast<ConstantArray>(LLVMUsed->getInitializer())) {
00144       for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i) {
00145         if (GlobalValue *GV = dyn_cast<GlobalValue>(Inits->getOperand(i)))
00146           llvmUsedValues.insert(GV);
00147         else if (ConstantExpr *CE =
00148                  dyn_cast<ConstantExpr>(Inits->getOperand(i)))
00149           if (CE->getOpcode() == Instruction::BitCast)
00150             if (GlobalValue *GV = dyn_cast<GlobalValue>(CE->getOperand(0)))
00151               llvmUsedValues.insert(GV);
00152       }
00153     }
00154   }
00155 }
00156 
00157 /// StripSymbolNames - Strip symbol names.
00158 bool StripSymbolNames(Module &M, bool PreserveDbgInfo) {
00159 
00160   SmallPtrSet<const GlobalValue*, 8> llvmUsedValues;
00161   findUsedValues(M, llvmUsedValues);
00162 
00163   for (Module::global_iterator I = M.global_begin(), E = M.global_end();
00164        I != E; ++I) {
00165     if (I->hasInternalLinkage() && llvmUsedValues.count(I) == 0)
00166       if (!PreserveDbgInfo || strncmp(I->getNameStart(), "llvm.dbg", 8))
00167         I->setName("");     // Internal symbols can't participate in linkage
00168   }
00169   
00170   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
00171     if (I->hasInternalLinkage() && llvmUsedValues.count(I) == 0)
00172       if (!PreserveDbgInfo || strncmp(I->getNameStart(), "llvm.dbg", 8))
00173         I->setName("");     // Internal symbols can't participate in linkage
00174     StripSymtab(I->getValueSymbolTable(), PreserveDbgInfo);
00175   }
00176   
00177   // Remove all names from types.
00178   StripTypeSymtab(M.getTypeSymbolTable(), PreserveDbgInfo);
00179 
00180   return true;
00181 }
00182 
00183 // StripDebugInfo - Strip debug info in the module if it exists.  
00184 // To do this, we remove llvm.dbg.func.start, llvm.dbg.stoppoint, and 
00185 // llvm.dbg.region.end calls, and any globals they point to if now dead.
00186 bool StripDebugInfo(Module &M) {
00187 
00188   Function *FuncStart = M.getFunction("llvm.dbg.func.start");
00189   Function *StopPoint = M.getFunction("llvm.dbg.stoppoint");
00190   Function *RegionStart = M.getFunction("llvm.dbg.region.start");
00191   Function *RegionEnd = M.getFunction("llvm.dbg.region.end");
00192   Function *Declare = M.getFunction("llvm.dbg.declare");
00193 
00194   std::vector<Constant*> DeadConstants;
00195 
00196   // Remove all of the calls to the debugger intrinsics, and remove them from
00197   // the module.
00198   if (FuncStart) {
00199     while (!FuncStart->use_empty()) {
00200       CallInst *CI = cast<CallInst>(FuncStart->use_back());
00201       Value *Arg = CI->getOperand(1);
00202       assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
00203       CI->eraseFromParent();
00204       if (Arg->use_empty())
00205         if (Constant *C = dyn_cast<Constant>(Arg)) 
00206           DeadConstants.push_back(C);
00207     }
00208     FuncStart->eraseFromParent();
00209   }
00210   if (StopPoint) {
00211     while (!StopPoint->use_empty()) {
00212       CallInst *CI = cast<CallInst>(StopPoint->use_back());
00213       Value *Arg = CI->getOperand(3);
00214       assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
00215       CI->eraseFromParent();
00216       if (Arg->use_empty())
00217         if (Constant *C = dyn_cast<Constant>(Arg)) 
00218           DeadConstants.push_back(C);
00219     }
00220     StopPoint->eraseFromParent();
00221   }
00222   if (RegionStart) {
00223     while (!RegionStart->use_empty()) {
00224       CallInst *CI = cast<CallInst>(RegionStart->use_back());
00225       Value *Arg = CI->getOperand(1);
00226       assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
00227       CI->eraseFromParent();
00228       if (Arg->use_empty())
00229         if (Constant *C = dyn_cast<Constant>(Arg)) 
00230           DeadConstants.push_back(C);
00231     }
00232     RegionStart->eraseFromParent();
00233   }
00234   if (RegionEnd) {
00235     while (!RegionEnd->use_empty()) {
00236       CallInst *CI = cast<CallInst>(RegionEnd->use_back());
00237       Value *Arg = CI->getOperand(1);
00238       assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
00239       CI->eraseFromParent();
00240       if (Arg->use_empty())
00241         if (Constant *C = dyn_cast<Constant>(Arg)) 
00242           DeadConstants.push_back(C);
00243     }
00244     RegionEnd->eraseFromParent();
00245   }
00246   if (Declare) {
00247     while (!Declare->use_empty()) {
00248       CallInst *CI = cast<CallInst>(Declare->use_back());
00249       Value *Arg1 = CI->getOperand(1);
00250       Value *Arg2 = CI->getOperand(2);
00251       assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
00252       CI->eraseFromParent();
00253       if (Arg1->use_empty()) {
00254         if (Constant *C = dyn_cast<Constant>(Arg1)) 
00255           DeadConstants.push_back(C);
00256         if (Instruction *I = dyn_cast<Instruction>(Arg1))
00257           I->eraseFromParent();
00258       }
00259       if (Arg2->use_empty())
00260         if (Constant *C = dyn_cast<Constant>(Arg2)) 
00261           DeadConstants.push_back(C);
00262     }
00263     Declare->eraseFromParent();
00264   }
00265 
00266   SmallPtrSet<const GlobalValue*, 8> llvmUsedValues;
00267   findUsedValues(M, llvmUsedValues);
00268 
00269   // llvm.dbg.compile_units and llvm.dbg.subprograms are marked as linkonce
00270   // but since we are removing all debug information, make them internal now.
00271   if (Constant *C = M.getNamedGlobal("llvm.dbg.compile_units"))
00272     if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C))
00273       GV->setLinkage(GlobalValue::InternalLinkage);
00274 
00275   if (Constant *C = M.getNamedGlobal("llvm.dbg.subprograms"))
00276     if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C))
00277       GV->setLinkage(GlobalValue::InternalLinkage);
00278  
00279   if (Constant *C = M.getNamedGlobal("llvm.dbg.global_variables"))
00280     if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C))
00281       GV->setLinkage(GlobalValue::InternalLinkage);
00282 
00283   // Delete all dbg variables.
00284   for (Module::global_iterator I = M.global_begin(), E = M.global_end(); 
00285        I != E; ++I) {
00286     GlobalVariable *GV = dyn_cast<GlobalVariable>(I);
00287     if (!GV) continue;
00288     if (GV->use_empty() && llvmUsedValues.count(I) == 0
00289         && (!GV->hasSection() 
00290             || strcmp(GV->getSection().c_str(), "llvm.metadata") == 0))
00291       DeadConstants.push_back(GV);
00292   }
00293 
00294   if (DeadConstants.empty())
00295     return false;
00296 
00297   // Delete any internal globals that were only used by the debugger intrinsics.
00298   while (!DeadConstants.empty()) {
00299     Constant *C = DeadConstants.back();
00300     DeadConstants.pop_back();
00301     if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) {
00302       if (GV->hasInternalLinkage())
00303         RemoveDeadConstant(GV);
00304     }
00305     else
00306       RemoveDeadConstant(C);
00307   }
00308 
00309   // Remove all llvm.dbg types.
00310   TypeSymbolTable &ST = M.getTypeSymbolTable();
00311   for (TypeSymbolTable::iterator TI = ST.begin(), TE = ST.end(); TI != TE; ) {
00312     if (!strncmp(TI->first.c_str(), "llvm.dbg.", 9))
00313       ST.remove(TI++);
00314     else 
00315       ++TI;
00316   }
00317   
00318   return true;
00319 }
00320 
00321 bool StripSymbols::runOnModule(Module &M) {
00322   bool Changed = false;
00323   Changed |= StripDebugInfo(M);
00324   if (!OnlyDebugInfo)
00325     Changed |= StripSymbolNames(M, false);
00326   return Changed;
00327 }
00328 
00329 bool StripNonDebugSymbols::runOnModule(Module &M) {
00330   return StripSymbolNames(M, true);
00331 }
00332 



This web site is hosted by the Computer Science Department at the University of Illinois at Urbana-Champaign.