LLVM API Documentation
00001 //===- BuildLibCalls.cpp - Utility builder for libcalls -------------------===// 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 // This file implements some functions that will create standard C libcalls. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/Transforms/Utils/BuildLibCalls.h" 00015 #include "llvm/ADT/SmallString.h" 00016 #include "llvm/IR/Constants.h" 00017 #include "llvm/IR/DataLayout.h" 00018 #include "llvm/IR/Function.h" 00019 #include "llvm/IR/IRBuilder.h" 00020 #include "llvm/IR/Intrinsics.h" 00021 #include "llvm/IR/LLVMContext.h" 00022 #include "llvm/IR/Module.h" 00023 #include "llvm/IR/Type.h" 00024 #include "llvm/Target/TargetLibraryInfo.h" 00025 00026 using namespace llvm; 00027 00028 /// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*. 00029 Value *llvm::CastToCStr(Value *V, IRBuilder<> &B) { 00030 return B.CreateBitCast(V, B.getInt8PtrTy(), "cstr"); 00031 } 00032 00033 /// EmitStrLen - Emit a call to the strlen function to the builder, for the 00034 /// specified pointer. This always returns an integer value of size intptr_t. 00035 Value *llvm::EmitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout *TD, 00036 const TargetLibraryInfo *TLI) { 00037 if (!TLI->has(LibFunc::strlen)) 00038 return 0; 00039 00040 Module *M = B.GetInsertBlock()->getParent()->getParent(); 00041 AttributeSet AS[2]; 00042 AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture); 00043 Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind }; 00044 AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 00045 ArrayRef<Attribute::AttrKind>(AVs, 2)); 00046 00047 LLVMContext &Context = B.GetInsertBlock()->getContext(); 00048 Constant *StrLen = M->getOrInsertFunction("strlen", 00049 AttributeSet::get(M->getContext(), 00050 AS), 00051 TD->getIntPtrType(Context), 00052 B.getInt8PtrTy(), 00053 NULL); 00054 CallInst *CI = B.CreateCall(StrLen, CastToCStr(Ptr, B), "strlen"); 00055 if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts())) 00056 CI->setCallingConv(F->getCallingConv()); 00057 00058 return CI; 00059 } 00060 00061 /// EmitStrNLen - Emit a call to the strnlen function to the builder, for the 00062 /// specified pointer. Ptr is required to be some pointer type, MaxLen must 00063 /// be of size_t type, and the return value has 'intptr_t' type. 00064 Value *llvm::EmitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B, 00065 const DataLayout *TD, const TargetLibraryInfo *TLI) { 00066 if (!TLI->has(LibFunc::strnlen)) 00067 return 0; 00068 00069 Module *M = B.GetInsertBlock()->getParent()->getParent(); 00070 AttributeSet AS[2]; 00071 AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture); 00072 Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind }; 00073 AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 00074 ArrayRef<Attribute::AttrKind>(AVs, 2)); 00075 00076 LLVMContext &Context = B.GetInsertBlock()->getContext(); 00077 Constant *StrNLen = M->getOrInsertFunction("strnlen", 00078 AttributeSet::get(M->getContext(), 00079 AS), 00080 TD->getIntPtrType(Context), 00081 B.getInt8PtrTy(), 00082 TD->getIntPtrType(Context), 00083 NULL); 00084 CallInst *CI = B.CreateCall2(StrNLen, CastToCStr(Ptr, B), MaxLen, "strnlen"); 00085 if (const Function *F = dyn_cast<Function>(StrNLen->stripPointerCasts())) 00086 CI->setCallingConv(F->getCallingConv()); 00087 00088 return CI; 00089 } 00090 00091 /// EmitStrChr - Emit a call to the strchr function to the builder, for the 00092 /// specified pointer and character. Ptr is required to be some pointer type, 00093 /// and the return value has 'i8*' type. 00094 Value *llvm::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B, 00095 const DataLayout *TD, const TargetLibraryInfo *TLI) { 00096 if (!TLI->has(LibFunc::strchr)) 00097 return 0; 00098 00099 Module *M = B.GetInsertBlock()->getParent()->getParent(); 00100 Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind }; 00101 AttributeSet AS = 00102 AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 00103 ArrayRef<Attribute::AttrKind>(AVs, 2)); 00104 00105 Type *I8Ptr = B.getInt8PtrTy(); 00106 Type *I32Ty = B.getInt32Ty(); 00107 Constant *StrChr = M->getOrInsertFunction("strchr", 00108 AttributeSet::get(M->getContext(), 00109 AS), 00110 I8Ptr, I8Ptr, I32Ty, NULL); 00111 CallInst *CI = B.CreateCall2(StrChr, CastToCStr(Ptr, B), 00112 ConstantInt::get(I32Ty, C), "strchr"); 00113 if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts())) 00114 CI->setCallingConv(F->getCallingConv()); 00115 return CI; 00116 } 00117 00118 /// EmitStrNCmp - Emit a call to the strncmp function to the builder. 00119 Value *llvm::EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, 00120 IRBuilder<> &B, const DataLayout *TD, 00121 const TargetLibraryInfo *TLI) { 00122 if (!TLI->has(LibFunc::strncmp)) 00123 return 0; 00124 00125 Module *M = B.GetInsertBlock()->getParent()->getParent(); 00126 AttributeSet AS[3]; 00127 AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture); 00128 AS[1] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture); 00129 Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind }; 00130 AS[2] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 00131 ArrayRef<Attribute::AttrKind>(AVs, 2)); 00132 00133 LLVMContext &Context = B.GetInsertBlock()->getContext(); 00134 Value *StrNCmp = M->getOrInsertFunction("strncmp", 00135 AttributeSet::get(M->getContext(), 00136 AS), 00137 B.getInt32Ty(), 00138 B.getInt8PtrTy(), 00139 B.getInt8PtrTy(), 00140 TD->getIntPtrType(Context), NULL); 00141 CallInst *CI = B.CreateCall3(StrNCmp, CastToCStr(Ptr1, B), 00142 CastToCStr(Ptr2, B), Len, "strncmp"); 00143 00144 if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts())) 00145 CI->setCallingConv(F->getCallingConv()); 00146 00147 return CI; 00148 } 00149 00150 /// EmitStrCpy - Emit a call to the strcpy function to the builder, for the 00151 /// specified pointer arguments. 00152 Value *llvm::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B, 00153 const DataLayout *TD, const TargetLibraryInfo *TLI, 00154 StringRef Name) { 00155 if (!TLI->has(LibFunc::strcpy)) 00156 return 0; 00157 00158 Module *M = B.GetInsertBlock()->getParent()->getParent(); 00159 AttributeSet AS[2]; 00160 AS[0] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture); 00161 AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 00162 Attribute::NoUnwind); 00163 Type *I8Ptr = B.getInt8PtrTy(); 00164 Value *StrCpy = M->getOrInsertFunction(Name, 00165 AttributeSet::get(M->getContext(), AS), 00166 I8Ptr, I8Ptr, I8Ptr, NULL); 00167 CallInst *CI = B.CreateCall2(StrCpy, CastToCStr(Dst, B), CastToCStr(Src, B), 00168 Name); 00169 if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts())) 00170 CI->setCallingConv(F->getCallingConv()); 00171 return CI; 00172 } 00173 00174 /// EmitStrNCpy - Emit a call to the strncpy function to the builder, for the 00175 /// specified pointer arguments. 00176 Value *llvm::EmitStrNCpy(Value *Dst, Value *Src, Value *Len, 00177 IRBuilder<> &B, const DataLayout *TD, 00178 const TargetLibraryInfo *TLI, StringRef Name) { 00179 if (!TLI->has(LibFunc::strncpy)) 00180 return 0; 00181 00182 Module *M = B.GetInsertBlock()->getParent()->getParent(); 00183 AttributeSet AS[2]; 00184 AS[0] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture); 00185 AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 00186 Attribute::NoUnwind); 00187 Type *I8Ptr = B.getInt8PtrTy(); 00188 Value *StrNCpy = M->getOrInsertFunction(Name, 00189 AttributeSet::get(M->getContext(), 00190 AS), 00191 I8Ptr, I8Ptr, I8Ptr, 00192 Len->getType(), NULL); 00193 CallInst *CI = B.CreateCall3(StrNCpy, CastToCStr(Dst, B), CastToCStr(Src, B), 00194 Len, "strncpy"); 00195 if (const Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts())) 00196 CI->setCallingConv(F->getCallingConv()); 00197 return CI; 00198 } 00199 00200 /// EmitMemCpyChk - Emit a call to the __memcpy_chk function to the builder. 00201 /// This expects that the Len and ObjSize have type 'intptr_t' and Dst/Src 00202 /// are pointers. 00203 Value *llvm::EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize, 00204 IRBuilder<> &B, const DataLayout *TD, 00205 const TargetLibraryInfo *TLI) { 00206 if (!TLI->has(LibFunc::memcpy_chk)) 00207 return 0; 00208 00209 Module *M = B.GetInsertBlock()->getParent()->getParent(); 00210 AttributeSet AS; 00211 AS = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 00212 Attribute::NoUnwind); 00213 LLVMContext &Context = B.GetInsertBlock()->getContext(); 00214 Value *MemCpy = M->getOrInsertFunction("__memcpy_chk", 00215 AttributeSet::get(M->getContext(), AS), 00216 B.getInt8PtrTy(), 00217 B.getInt8PtrTy(), 00218 B.getInt8PtrTy(), 00219 TD->getIntPtrType(Context), 00220 TD->getIntPtrType(Context), NULL); 00221 Dst = CastToCStr(Dst, B); 00222 Src = CastToCStr(Src, B); 00223 CallInst *CI = B.CreateCall4(MemCpy, Dst, Src, Len, ObjSize); 00224 if (const Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts())) 00225 CI->setCallingConv(F->getCallingConv()); 00226 return CI; 00227 } 00228 00229 /// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is 00230 /// a pointer, Val is an i32 value, and Len is an 'intptr_t' value. 00231 Value *llvm::EmitMemChr(Value *Ptr, Value *Val, 00232 Value *Len, IRBuilder<> &B, const DataLayout *TD, 00233 const TargetLibraryInfo *TLI) { 00234 if (!TLI->has(LibFunc::memchr)) 00235 return 0; 00236 00237 Module *M = B.GetInsertBlock()->getParent()->getParent(); 00238 AttributeSet AS; 00239 Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind }; 00240 AS = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 00241 ArrayRef<Attribute::AttrKind>(AVs, 2)); 00242 LLVMContext &Context = B.GetInsertBlock()->getContext(); 00243 Value *MemChr = M->getOrInsertFunction("memchr", 00244 AttributeSet::get(M->getContext(), AS), 00245 B.getInt8PtrTy(), 00246 B.getInt8PtrTy(), 00247 B.getInt32Ty(), 00248 TD->getIntPtrType(Context), 00249 NULL); 00250 CallInst *CI = B.CreateCall3(MemChr, CastToCStr(Ptr, B), Val, Len, "memchr"); 00251 00252 if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts())) 00253 CI->setCallingConv(F->getCallingConv()); 00254 00255 return CI; 00256 } 00257 00258 /// EmitMemCmp - Emit a call to the memcmp function. 00259 Value *llvm::EmitMemCmp(Value *Ptr1, Value *Ptr2, 00260 Value *Len, IRBuilder<> &B, const DataLayout *TD, 00261 const TargetLibraryInfo *TLI) { 00262 if (!TLI->has(LibFunc::memcmp)) 00263 return 0; 00264 00265 Module *M = B.GetInsertBlock()->getParent()->getParent(); 00266 AttributeSet AS[3]; 00267 AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture); 00268 AS[1] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture); 00269 Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind }; 00270 AS[2] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 00271 ArrayRef<Attribute::AttrKind>(AVs, 2)); 00272 00273 LLVMContext &Context = B.GetInsertBlock()->getContext(); 00274 Value *MemCmp = M->getOrInsertFunction("memcmp", 00275 AttributeSet::get(M->getContext(), AS), 00276 B.getInt32Ty(), 00277 B.getInt8PtrTy(), 00278 B.getInt8PtrTy(), 00279 TD->getIntPtrType(Context), NULL); 00280 CallInst *CI = B.CreateCall3(MemCmp, CastToCStr(Ptr1, B), CastToCStr(Ptr2, B), 00281 Len, "memcmp"); 00282 00283 if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts())) 00284 CI->setCallingConv(F->getCallingConv()); 00285 00286 return CI; 00287 } 00288 00289 /// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' (e.g. 00290 /// 'floor'). This function is known to take a single of type matching 'Op' and 00291 /// returns one value with the same type. If 'Op' is a long double, 'l' is 00292 /// added as the suffix of name, if 'Op' is a float, we add a 'f' suffix. 00293 Value *llvm::EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B, 00294 const AttributeSet &Attrs) { 00295 SmallString<20> NameBuffer; 00296 if (!Op->getType()->isDoubleTy()) { 00297 // If we need to add a suffix, copy into NameBuffer. 00298 NameBuffer += Name; 00299 if (Op->getType()->isFloatTy()) 00300 NameBuffer += 'f'; // floorf 00301 else 00302 NameBuffer += 'l'; // floorl 00303 Name = NameBuffer; 00304 } 00305 00306 Module *M = B.GetInsertBlock()->getParent()->getParent(); 00307 Value *Callee = M->getOrInsertFunction(Name, Op->getType(), 00308 Op->getType(), NULL); 00309 CallInst *CI = B.CreateCall(Callee, Op, Name); 00310 CI->setAttributes(Attrs); 00311 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts())) 00312 CI->setCallingConv(F->getCallingConv()); 00313 00314 return CI; 00315 } 00316 00317 /// EmitPutChar - Emit a call to the putchar function. This assumes that Char 00318 /// is an integer. 00319 Value *llvm::EmitPutChar(Value *Char, IRBuilder<> &B, const DataLayout *TD, 00320 const TargetLibraryInfo *TLI) { 00321 if (!TLI->has(LibFunc::putchar)) 00322 return 0; 00323 00324 Module *M = B.GetInsertBlock()->getParent()->getParent(); 00325 Value *PutChar = M->getOrInsertFunction("putchar", B.getInt32Ty(), 00326 B.getInt32Ty(), NULL); 00327 CallInst *CI = B.CreateCall(PutChar, 00328 B.CreateIntCast(Char, 00329 B.getInt32Ty(), 00330 /*isSigned*/true, 00331 "chari"), 00332 "putchar"); 00333 00334 if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts())) 00335 CI->setCallingConv(F->getCallingConv()); 00336 return CI; 00337 } 00338 00339 /// EmitPutS - Emit a call to the puts function. This assumes that Str is 00340 /// some pointer. 00341 Value *llvm::EmitPutS(Value *Str, IRBuilder<> &B, const DataLayout *TD, 00342 const TargetLibraryInfo *TLI) { 00343 if (!TLI->has(LibFunc::puts)) 00344 return 0; 00345 00346 Module *M = B.GetInsertBlock()->getParent()->getParent(); 00347 AttributeSet AS[2]; 00348 AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture); 00349 AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 00350 Attribute::NoUnwind); 00351 00352 Value *PutS = M->getOrInsertFunction("puts", 00353 AttributeSet::get(M->getContext(), AS), 00354 B.getInt32Ty(), 00355 B.getInt8PtrTy(), 00356 NULL); 00357 CallInst *CI = B.CreateCall(PutS, CastToCStr(Str, B), "puts"); 00358 if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts())) 00359 CI->setCallingConv(F->getCallingConv()); 00360 return CI; 00361 } 00362 00363 /// EmitFPutC - Emit a call to the fputc function. This assumes that Char is 00364 /// an integer and File is a pointer to FILE. 00365 Value *llvm::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B, 00366 const DataLayout *TD, const TargetLibraryInfo *TLI) { 00367 if (!TLI->has(LibFunc::fputc)) 00368 return 0; 00369 00370 Module *M = B.GetInsertBlock()->getParent()->getParent(); 00371 AttributeSet AS[2]; 00372 AS[0] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture); 00373 AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 00374 Attribute::NoUnwind); 00375 Constant *F; 00376 if (File->getType()->isPointerTy()) 00377 F = M->getOrInsertFunction("fputc", 00378 AttributeSet::get(M->getContext(), AS), 00379 B.getInt32Ty(), 00380 B.getInt32Ty(), File->getType(), 00381 NULL); 00382 else 00383 F = M->getOrInsertFunction("fputc", 00384 B.getInt32Ty(), 00385 B.getInt32Ty(), 00386 File->getType(), NULL); 00387 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true, 00388 "chari"); 00389 CallInst *CI = B.CreateCall2(F, Char, File, "fputc"); 00390 00391 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) 00392 CI->setCallingConv(Fn->getCallingConv()); 00393 return CI; 00394 } 00395 00396 /// EmitFPutS - Emit a call to the puts function. Str is required to be a 00397 /// pointer and File is a pointer to FILE. 00398 Value *llvm::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B, 00399 const DataLayout *TD, const TargetLibraryInfo *TLI) { 00400 if (!TLI->has(LibFunc::fputs)) 00401 return 0; 00402 00403 Module *M = B.GetInsertBlock()->getParent()->getParent(); 00404 AttributeSet AS[3]; 00405 AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture); 00406 AS[1] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture); 00407 AS[2] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 00408 Attribute::NoUnwind); 00409 StringRef FPutsName = TLI->getName(LibFunc::fputs); 00410 Constant *F; 00411 if (File->getType()->isPointerTy()) 00412 F = M->getOrInsertFunction(FPutsName, 00413 AttributeSet::get(M->getContext(), AS), 00414 B.getInt32Ty(), 00415 B.getInt8PtrTy(), 00416 File->getType(), NULL); 00417 else 00418 F = M->getOrInsertFunction(FPutsName, B.getInt32Ty(), 00419 B.getInt8PtrTy(), 00420 File->getType(), NULL); 00421 CallInst *CI = B.CreateCall2(F, CastToCStr(Str, B), File, "fputs"); 00422 00423 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) 00424 CI->setCallingConv(Fn->getCallingConv()); 00425 return CI; 00426 } 00427 00428 /// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is 00429 /// a pointer, Size is an 'intptr_t', and File is a pointer to FILE. 00430 Value *llvm::EmitFWrite(Value *Ptr, Value *Size, Value *File, 00431 IRBuilder<> &B, const DataLayout *TD, 00432 const TargetLibraryInfo *TLI) { 00433 if (!TLI->has(LibFunc::fwrite)) 00434 return 0; 00435 00436 Module *M = B.GetInsertBlock()->getParent()->getParent(); 00437 AttributeSet AS[3]; 00438 AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture); 00439 AS[1] = AttributeSet::get(M->getContext(), 4, Attribute::NoCapture); 00440 AS[2] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, 00441 Attribute::NoUnwind); 00442 LLVMContext &Context = B.GetInsertBlock()->getContext(); 00443 StringRef FWriteName = TLI->getName(LibFunc::fwrite); 00444 Constant *F; 00445 if (File->getType()->isPointerTy()) 00446 F = M->getOrInsertFunction(FWriteName, 00447 AttributeSet::get(M->getContext(), AS), 00448 TD->getIntPtrType(Context), 00449 B.getInt8PtrTy(), 00450 TD->getIntPtrType(Context), 00451 TD->getIntPtrType(Context), 00452 File->getType(), NULL); 00453 else 00454 F = M->getOrInsertFunction(FWriteName, TD->getIntPtrType(Context), 00455 B.getInt8PtrTy(), 00456 TD->getIntPtrType(Context), 00457 TD->getIntPtrType(Context), 00458 File->getType(), NULL); 00459 CallInst *CI = B.CreateCall4(F, CastToCStr(Ptr, B), Size, 00460 ConstantInt::get(TD->getIntPtrType(Context), 1), File); 00461 00462 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) 00463 CI->setCallingConv(Fn->getCallingConv()); 00464 return CI; 00465 } 00466 00467 SimplifyFortifiedLibCalls::~SimplifyFortifiedLibCalls() { } 00468 00469 bool SimplifyFortifiedLibCalls::fold(CallInst *CI, const DataLayout *TD, 00470 const TargetLibraryInfo *TLI) { 00471 // We really need DataLayout for later. 00472 if (!TD) return false; 00473 00474 this->CI = CI; 00475 Function *Callee = CI->getCalledFunction(); 00476 StringRef Name = Callee->getName(); 00477 FunctionType *FT = Callee->getFunctionType(); 00478 LLVMContext &Context = CI->getParent()->getContext(); 00479 IRBuilder<> B(CI); 00480 00481 if (Name == "__memcpy_chk") { 00482 // Check if this has the right signature. 00483 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 00484 !FT->getParamType(0)->isPointerTy() || 00485 !FT->getParamType(1)->isPointerTy() || 00486 FT->getParamType(2) != TD->getIntPtrType(Context) || 00487 FT->getParamType(3) != TD->getIntPtrType(Context)) 00488 return false; 00489 00490 if (isFoldable(3, 2, false)) { 00491 B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1), 00492 CI->getArgOperand(2), 1); 00493 replaceCall(CI->getArgOperand(0)); 00494 return true; 00495 } 00496 return false; 00497 } 00498 00499 // Should be similar to memcpy. 00500 if (Name == "__mempcpy_chk") { 00501 return false; 00502 } 00503 00504 if (Name == "__memmove_chk") { 00505 // Check if this has the right signature. 00506 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 00507 !FT->getParamType(0)->isPointerTy() || 00508 !FT->getParamType(1)->isPointerTy() || 00509 FT->getParamType(2) != TD->getIntPtrType(Context) || 00510 FT->getParamType(3) != TD->getIntPtrType(Context)) 00511 return false; 00512 00513 if (isFoldable(3, 2, false)) { 00514 B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1), 00515 CI->getArgOperand(2), 1); 00516 replaceCall(CI->getArgOperand(0)); 00517 return true; 00518 } 00519 return false; 00520 } 00521 00522 if (Name == "__memset_chk") { 00523 // Check if this has the right signature. 00524 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 00525 !FT->getParamType(0)->isPointerTy() || 00526 !FT->getParamType(1)->isIntegerTy() || 00527 FT->getParamType(2) != TD->getIntPtrType(Context) || 00528 FT->getParamType(3) != TD->getIntPtrType(Context)) 00529 return false; 00530 00531 if (isFoldable(3, 2, false)) { 00532 Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), 00533 false); 00534 B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1); 00535 replaceCall(CI->getArgOperand(0)); 00536 return true; 00537 } 00538 return false; 00539 } 00540 00541 if (Name == "__strcpy_chk" || Name == "__stpcpy_chk") { 00542 // Check if this has the right signature. 00543 if (FT->getNumParams() != 3 || 00544 FT->getReturnType() != FT->getParamType(0) || 00545 FT->getParamType(0) != FT->getParamType(1) || 00546 FT->getParamType(0) != Type::getInt8PtrTy(Context) || 00547 FT->getParamType(2) != TD->getIntPtrType(Context)) 00548 return 0; 00549 00550 00551 // If a) we don't have any length information, or b) we know this will 00552 // fit then just lower to a plain st[rp]cpy. Otherwise we'll keep our 00553 // st[rp]cpy_chk call which may fail at runtime if the size is too long. 00554 // TODO: It might be nice to get a maximum length out of the possible 00555 // string lengths for varying. 00556 if (isFoldable(2, 1, true)) { 00557 Value *Ret = EmitStrCpy(CI->getArgOperand(0), CI->getArgOperand(1), B, TD, 00558 TLI, Name.substr(2, 6)); 00559 if (!Ret) 00560 return false; 00561 replaceCall(Ret); 00562 return true; 00563 } 00564 return false; 00565 } 00566 00567 if (Name == "__strncpy_chk" || Name == "__stpncpy_chk") { 00568 // Check if this has the right signature. 00569 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 00570 FT->getParamType(0) != FT->getParamType(1) || 00571 FT->getParamType(0) != Type::getInt8PtrTy(Context) || 00572 !FT->getParamType(2)->isIntegerTy() || 00573 FT->getParamType(3) != TD->getIntPtrType(Context)) 00574 return false; 00575 00576 if (isFoldable(3, 2, false)) { 00577 Value *Ret = EmitStrNCpy(CI->getArgOperand(0), CI->getArgOperand(1), 00578 CI->getArgOperand(2), B, TD, TLI, 00579 Name.substr(2, 7)); 00580 if (!Ret) 00581 return false; 00582 replaceCall(Ret); 00583 return true; 00584 } 00585 return false; 00586 } 00587 00588 if (Name == "__strcat_chk") { 00589 return false; 00590 } 00591 00592 if (Name == "__strncat_chk") { 00593 return false; 00594 } 00595 00596 return false; 00597 }