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