LLVM API Documentation
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 }