LLVM API Documentation

JumpInstrTables.cpp
Go to the documentation of this file.
00001 //===-- JumpInstrTables.cpp: Jump-Instruction Tables ----------------------===//
00002 //
00003 // This file is distributed under the University of Illinois Open Source
00004 // License. See LICENSE.TXT for details.
00005 //
00006 //===----------------------------------------------------------------------===//
00007 ///
00008 /// \file
00009 /// \brief An implementation of jump-instruction tables.
00010 ///
00011 //===----------------------------------------------------------------------===//
00012 
00013 #define DEBUG_TYPE "jt"
00014 
00015 #include "llvm/CodeGen/JumpInstrTables.h"
00016 
00017 #include "llvm/ADT/Statistic.h"
00018 #include "llvm/Analysis/JumpInstrTableInfo.h"
00019 #include "llvm/CodeGen/Passes.h"
00020 #include "llvm/IR/Attributes.h"
00021 #include "llvm/IR/CallSite.h"
00022 #include "llvm/IR/Constants.h"
00023 #include "llvm/IR/DerivedTypes.h"
00024 #include "llvm/IR/Function.h"
00025 #include "llvm/IR/LLVMContext.h"
00026 #include "llvm/IR/Module.h"
00027 #include "llvm/IR/Operator.h"
00028 #include "llvm/IR/Type.h"
00029 #include "llvm/IR/Verifier.h"
00030 #include "llvm/Support/CommandLine.h"
00031 #include "llvm/Support/Debug.h"
00032 #include "llvm/Support/raw_ostream.h"
00033 
00034 #include <vector>
00035 
00036 using namespace llvm;
00037 
00038 char JumpInstrTables::ID = 0;
00039 
00040 INITIALIZE_PASS_BEGIN(JumpInstrTables, "jump-instr-tables",
00041                       "Jump-Instruction Tables", true, true)
00042 INITIALIZE_PASS_DEPENDENCY(JumpInstrTableInfo);
00043 INITIALIZE_PASS_END(JumpInstrTables, "jump-instr-tables",
00044                     "Jump-Instruction Tables", true, true)
00045 
00046 STATISTIC(NumJumpTables, "Number of indirect call tables generated");
00047 STATISTIC(NumFuncsInJumpTables, "Number of functions in the jump tables");
00048 
00049 ModulePass *llvm::createJumpInstrTablesPass() {
00050   // The default implementation uses a single table for all functions.
00051   return new JumpInstrTables(JumpTable::Single);
00052 }
00053 
00054 ModulePass *llvm::createJumpInstrTablesPass(JumpTable::JumpTableType JTT) {
00055   return new JumpInstrTables(JTT);
00056 }
00057 
00058 namespace {
00059 static const char jump_func_prefix[] = "__llvm_jump_instr_table_";
00060 static const char jump_section_prefix[] = ".jump.instr.table.text.";
00061 
00062 // Checks to see if a given CallSite is making an indirect call, including
00063 // cases where the indirect call is made through a bitcast.
00064 bool isIndirectCall(CallSite &CS) {
00065   if (CS.getCalledFunction())
00066     return false;
00067 
00068   // Check the value to see if it is merely a bitcast of a function. In
00069   // this case, it will translate to a direct function call in the resulting
00070   // assembly, so we won't treat it as an indirect call here.
00071   const Value *V = CS.getCalledValue();
00072   if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
00073     return !(CE->isCast() && isa<Function>(CE->getOperand(0)));
00074   }
00075 
00076   // Otherwise, since we know it's a call, it must be an indirect call
00077   return true;
00078 }
00079 
00080 // Replaces Functions and GlobalAliases with a different Value.
00081 bool replaceGlobalValueIndirectUse(GlobalValue *GV, Value *V, Use *U) {
00082   User *Us = U->getUser();
00083   if (!Us)
00084     return false;
00085   if (Instruction *I = dyn_cast<Instruction>(Us)) {
00086     CallSite CS(I);
00087 
00088     // Don't do the replacement if this use is a direct call to this function.
00089     // If the use is not the called value, then replace it.
00090     if (CS && (isIndirectCall(CS) || CS.isCallee(U))) {
00091       return false;
00092     }
00093 
00094     U->set(V);
00095   } else if (Constant *C = dyn_cast<Constant>(Us)) {
00096     // Don't replace calls to bitcasts of function symbols, since they get
00097     // translated to direct calls.
00098     if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Us)) {
00099       if (CE->getOpcode() == Instruction::BitCast) {
00100         // This bitcast must have exactly one user.
00101         if (CE->user_begin() != CE->user_end()) {
00102           User *ParentUs = *CE->user_begin();
00103           if (CallInst *CI = dyn_cast<CallInst>(ParentUs)) {
00104             CallSite CS(CI);
00105             Use &CEU = *CE->use_begin();
00106             if (CS.isCallee(&CEU)) {
00107               return false;
00108             }
00109           }
00110         }
00111       }
00112     }
00113 
00114     // GlobalAlias doesn't support replaceUsesOfWithOnConstant. And the verifier
00115     // requires alias to point to a defined function. So, GlobalAlias is handled
00116     // as a separate case in runOnModule.
00117     if (!isa<GlobalAlias>(C))
00118       C->replaceUsesOfWithOnConstant(GV, V, U);
00119   } else {
00120     assert(false && "The Use of a Function symbol is neither an instruction nor"
00121                     " a constant");
00122   }
00123 
00124   return true;
00125 }
00126 
00127 // Replaces all replaceable address-taken uses of GV with a pointer to a
00128 // jump-instruction table entry.
00129 void replaceValueWithFunction(GlobalValue *GV, Function *F) {
00130   // Go through all uses of this function and replace the uses of GV with the
00131   // jump-table version of the function. Get the uses as a vector before
00132   // replacing them, since replacing them changes the use list and invalidates
00133   // the iterator otherwise.
00134   for (Value::use_iterator I = GV->use_begin(), E = GV->use_end(); I != E;) {
00135     Use &U = *I++;
00136 
00137     // Replacement of constants replaces all instances in the constant. So, some
00138     // uses might have already been handled by the time we reach them here.
00139     if (U.get() == GV)
00140       replaceGlobalValueIndirectUse(GV, F, &U);
00141   }
00142 
00143   return;
00144 }
00145 } // end anonymous namespace
00146 
00147 JumpInstrTables::JumpInstrTables()
00148     : ModulePass(ID), Metadata(), JITI(nullptr), TableCount(0),
00149       JTType(JumpTable::Single) {
00150   initializeJumpInstrTablesPass(*PassRegistry::getPassRegistry());
00151 }
00152 
00153 JumpInstrTables::JumpInstrTables(JumpTable::JumpTableType JTT)
00154     : ModulePass(ID), Metadata(), JITI(nullptr), TableCount(0), JTType(JTT) {
00155   initializeJumpInstrTablesPass(*PassRegistry::getPassRegistry());
00156 }
00157 
00158 JumpInstrTables::~JumpInstrTables() {}
00159 
00160 void JumpInstrTables::getAnalysisUsage(AnalysisUsage &AU) const {
00161   AU.addRequired<JumpInstrTableInfo>();
00162 }
00163 
00164 Function *JumpInstrTables::insertEntry(Module &M, Function *Target) {
00165   FunctionType *OrigFunTy = Target->getFunctionType();
00166   FunctionType *FunTy = transformType(OrigFunTy);
00167 
00168   JumpMap::iterator it = Metadata.find(FunTy);
00169   if (Metadata.end() == it) {
00170     struct TableMeta Meta;
00171     Meta.TableNum = TableCount;
00172     Meta.Count = 0;
00173     Metadata[FunTy] = Meta;
00174     it = Metadata.find(FunTy);
00175     ++NumJumpTables;
00176     ++TableCount;
00177   }
00178 
00179   it->second.Count++;
00180 
00181   std::string NewName(jump_func_prefix);
00182   NewName += (Twine(it->second.TableNum) + "_" + Twine(it->second.Count)).str();
00183   Function *JumpFun =
00184       Function::Create(OrigFunTy, GlobalValue::ExternalLinkage, NewName, &M);
00185   // The section for this table
00186   JumpFun->setSection((jump_section_prefix + Twine(it->second.TableNum)).str());
00187   JITI->insertEntry(FunTy, Target, JumpFun);
00188 
00189   ++NumFuncsInJumpTables;
00190   return JumpFun;
00191 }
00192 
00193 bool JumpInstrTables::hasTable(FunctionType *FunTy) {
00194   FunctionType *TransTy = transformType(FunTy);
00195   return Metadata.end() != Metadata.find(TransTy);
00196 }
00197 
00198 FunctionType *JumpInstrTables::transformType(FunctionType *FunTy) {
00199   // Returning nullptr forces all types into the same table, since all types map
00200   // to the same type
00201   Type *VoidPtrTy = Type::getInt8PtrTy(FunTy->getContext());
00202 
00203   // Ignore the return type.
00204   Type *RetTy = VoidPtrTy;
00205   bool IsVarArg = FunTy->isVarArg();
00206   std::vector<Type *> ParamTys(FunTy->getNumParams());
00207   FunctionType::param_iterator PI, PE;
00208   int i = 0;
00209 
00210   std::vector<Type *> EmptyParams;
00211   Type *Int32Ty = Type::getInt32Ty(FunTy->getContext());
00212   FunctionType *VoidFnTy = FunctionType::get(
00213       Type::getVoidTy(FunTy->getContext()), EmptyParams, false);
00214   switch (JTType) {
00215   case JumpTable::Single:
00216 
00217     return FunctionType::get(RetTy, EmptyParams, false);
00218   case JumpTable::Arity:
00219     // Transform all types to void* so that all functions with the same arity
00220     // end up in the same table.
00221     for (PI = FunTy->param_begin(), PE = FunTy->param_end(); PI != PE;
00222          PI++, i++) {
00223       ParamTys[i] = VoidPtrTy;
00224     }
00225 
00226     return FunctionType::get(RetTy, ParamTys, IsVarArg);
00227   case JumpTable::Simplified:
00228     // Project all parameters types to one of 3 types: composite, integer, and
00229     // function, matching the three subclasses of Type.
00230     for (PI = FunTy->param_begin(), PE = FunTy->param_end(); PI != PE;
00231          ++PI, ++i) {
00232       assert((isa<IntegerType>(*PI) || isa<FunctionType>(*PI) ||
00233               isa<CompositeType>(*PI)) &&
00234              "This type is not an Integer or a Composite or a Function");
00235       if (isa<CompositeType>(*PI)) {
00236         ParamTys[i] = VoidPtrTy;
00237       } else if (isa<FunctionType>(*PI)) {
00238         ParamTys[i] = VoidFnTy;
00239       } else if (isa<IntegerType>(*PI)) {
00240         ParamTys[i] = Int32Ty;
00241       }
00242     }
00243 
00244     return FunctionType::get(RetTy, ParamTys, IsVarArg);
00245   case JumpTable::Full:
00246     // Don't transform this type at all.
00247     return FunTy;
00248   }
00249 
00250   return nullptr;
00251 }
00252 
00253 bool JumpInstrTables::runOnModule(Module &M) {
00254   JITI = &getAnalysis<JumpInstrTableInfo>();
00255 
00256   // Get the set of jumptable-annotated functions.
00257   DenseMap<Function *, Function *> Functions;
00258   for (Function &F : M) {
00259     if (F.hasFnAttribute(Attribute::JumpTable)) {
00260       assert(F.hasUnnamedAddr() &&
00261              "Attribute 'jumptable' requires 'unnamed_addr'");
00262       Functions[&F] = nullptr;
00263     }
00264   }
00265 
00266   // Create the jump-table functions.
00267   for (auto &KV : Functions) {
00268     Function *F = KV.first;
00269     KV.second = insertEntry(M, F);
00270   }
00271 
00272   // GlobalAlias is a special case, because the target of an alias statement
00273   // must be a defined function. So, instead of replacing a given function in
00274   // the alias, we replace all uses of aliases that target jumptable functions.
00275   // Note that there's no need to create these functions, since only aliases
00276   // that target known jumptable functions are replaced, and there's no way to
00277   // put the jumptable annotation on a global alias.
00278   DenseMap<GlobalAlias *, Function *> Aliases;
00279   for (GlobalAlias &GA : M.aliases()) {
00280     Constant *Aliasee = GA.getAliasee();
00281     if (Function *F = dyn_cast<Function>(Aliasee)) {
00282       auto it = Functions.find(F);
00283       if (it != Functions.end()) {
00284         Aliases[&GA] = it->second;
00285       }
00286     }
00287   }
00288 
00289   // Replace each address taken function with its jump-instruction table entry.
00290   for (auto &KV : Functions)
00291     replaceValueWithFunction(KV.first, KV.second);
00292 
00293   for (auto &KV : Aliases)
00294     replaceValueWithFunction(KV.first, KV.second);
00295 
00296   return !Functions.empty();
00297 }