1 //===- BuildLibCalls.cpp - Utility builder for libcalls -------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements some functions that will create standard C libcalls. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Transforms/Utils/BuildLibCalls.h" 15 #include "llvm/Constants.h" 16 #include "llvm/Function.h" 17 #include "llvm/IRBuilder.h" 18 #include "llvm/Intrinsics.h" 19 #include "llvm/Intrinsics.h" 20 #include "llvm/LLVMContext.h" 21 #include "llvm/LLVMContext.h" 22 #include "llvm/Module.h" 23 #include "llvm/Type.h" 24 #include "llvm/ADT/SmallString.h" 25 #include "llvm/DataLayout.h" 26 #include "llvm/Target/TargetLibraryInfo.h" 27 28 using namespace llvm; 29 30 /// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*. 31 Value *llvm::CastToCStr(Value *V, IRBuilder<> &B) { 32 return B.CreateBitCast(V, B.getInt8PtrTy(), "cstr"); 33 } 34 35 /// EmitStrLen - Emit a call to the strlen function to the builder, for the 36 /// specified pointer. This always returns an integer value of size intptr_t. 37 Value *llvm::EmitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout *TD, 38 const TargetLibraryInfo *TLI) { 39 if (!TLI->has(LibFunc::strlen)) 40 return 0; 41 42 Module *M = B.GetInsertBlock()->getParent()->getParent(); 43 AttributeWithIndex AWI[2]; 44 AWI[0] = AttributeWithIndex::get(M->getContext(), 1, Attributes::NoCapture); 45 Attributes::AttrVal AVs[2] = { Attributes::ReadOnly, Attributes::NoUnwind }; 46 AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, 47 ArrayRef<Attributes::AttrVal>(AVs, 2)); 48 49 Constant *StrLen = M->getOrInsertFunction("strlen", AttrListPtr::get(AWI), 50 TD->getIntPtrType(Ptr->getType()), 51 B.getInt8PtrTy(), 52 NULL); 53 CallInst *CI = B.CreateCall(StrLen, CastToCStr(Ptr, B), "strlen"); 54 if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts())) 55 CI->setCallingConv(F->getCallingConv()); 56 57 return CI; 58 } 59 60 /// EmitStrNLen - Emit a call to the strnlen function to the builder, for the 61 /// specified pointer. Ptr is required to be some pointer type, MaxLen must 62 /// be of size_t type, and the return value has 'intptr_t' type. 63 Value *llvm::EmitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B, 64 const DataLayout *TD, const TargetLibraryInfo *TLI) { 65 if (!TLI->has(LibFunc::strnlen)) 66 return 0; 67 68 Module *M = B.GetInsertBlock()->getParent()->getParent(); 69 AttributeWithIndex AWI[2]; 70 AWI[0] = AttributeWithIndex::get(M->getContext(), 1, Attributes::NoCapture); 71 Attributes::AttrVal AVs[2] = { Attributes::ReadOnly, Attributes::NoUnwind }; 72 AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, 73 ArrayRef<Attributes::AttrVal>(AVs, 2)); 74 75 Constant *StrNLen = M->getOrInsertFunction("strnlen", AttrListPtr::get(AWI), 76 TD->getIntPtrType(Ptr->getType()), 77 B.getInt8PtrTy(), 78 TD->getIntPtrType(Ptr->getType()), 79 NULL); 80 CallInst *CI = B.CreateCall2(StrNLen, CastToCStr(Ptr, B), MaxLen, "strnlen"); 81 if (const Function *F = dyn_cast<Function>(StrNLen->stripPointerCasts())) 82 CI->setCallingConv(F->getCallingConv()); 83 84 return CI; 85 } 86 87 /// EmitStrChr - Emit a call to the strchr function to the builder, for the 88 /// specified pointer and character. Ptr is required to be some pointer type, 89 /// and the return value has 'i8*' type. 90 Value *llvm::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B, 91 const DataLayout *TD, const TargetLibraryInfo *TLI) { 92 if (!TLI->has(LibFunc::strchr)) 93 return 0; 94 95 Module *M = B.GetInsertBlock()->getParent()->getParent(); 96 Attributes::AttrVal AVs[2] = { Attributes::ReadOnly, Attributes::NoUnwind }; 97 AttributeWithIndex AWI = 98 AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, 99 ArrayRef<Attributes::AttrVal>(AVs, 2)); 100 101 Type *I8Ptr = B.getInt8PtrTy(); 102 Type *I32Ty = B.getInt32Ty(); 103 Constant *StrChr = M->getOrInsertFunction("strchr", AttrListPtr::get(AWI), 104 I8Ptr, I8Ptr, I32Ty, NULL); 105 CallInst *CI = B.CreateCall2(StrChr, CastToCStr(Ptr, B), 106 ConstantInt::get(I32Ty, C), "strchr"); 107 if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts())) 108 CI->setCallingConv(F->getCallingConv()); 109 return CI; 110 } 111 112 /// EmitStrNCmp - Emit a call to the strncmp function to the builder. 113 Value *llvm::EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, 114 IRBuilder<> &B, const DataLayout *TD, 115 const TargetLibraryInfo *TLI) { 116 if (!TLI->has(LibFunc::strncmp)) 117 return 0; 118 119 Module *M = B.GetInsertBlock()->getParent()->getParent(); 120 AttributeWithIndex AWI[3]; 121 AWI[0] = AttributeWithIndex::get(M->getContext(), 1, Attributes::NoCapture); 122 AWI[1] = AttributeWithIndex::get(M->getContext(), 2, Attributes::NoCapture); 123 Attributes::AttrVal AVs[2] = { Attributes::ReadOnly, Attributes::NoUnwind }; 124 AWI[2] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, 125 ArrayRef<Attributes::AttrVal>(AVs, 2)); 126 127 Value *StrNCmp = M->getOrInsertFunction("strncmp", AttrListPtr::get(AWI), 128 B.getInt32Ty(), 129 B.getInt8PtrTy(), 130 B.getInt8PtrTy(), 131 TD->getIntPtrType(Ptr1->getType()), 132 NULL); 133 CallInst *CI = B.CreateCall3(StrNCmp, CastToCStr(Ptr1, B), 134 CastToCStr(Ptr2, B), Len, "strncmp"); 135 136 if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts())) 137 CI->setCallingConv(F->getCallingConv()); 138 139 return CI; 140 } 141 142 /// EmitStrCpy - Emit a call to the strcpy function to the builder, for the 143 /// specified pointer arguments. 144 Value *llvm::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B, 145 const DataLayout *TD, const TargetLibraryInfo *TLI, 146 StringRef Name) { 147 if (!TLI->has(LibFunc::strcpy)) 148 return 0; 149 150 Module *M = B.GetInsertBlock()->getParent()->getParent(); 151 AttributeWithIndex AWI[2]; 152 AWI[0] = AttributeWithIndex::get(M->getContext(), 2, Attributes::NoCapture); 153 AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, 154 Attributes::NoUnwind); 155 Type *I8Ptr = B.getInt8PtrTy(); 156 Value *StrCpy = M->getOrInsertFunction(Name, AttrListPtr::get(AWI), 157 I8Ptr, I8Ptr, I8Ptr, NULL); 158 CallInst *CI = B.CreateCall2(StrCpy, CastToCStr(Dst, B), CastToCStr(Src, B), 159 Name); 160 if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts())) 161 CI->setCallingConv(F->getCallingConv()); 162 return CI; 163 } 164 165 /// EmitStrNCpy - Emit a call to the strncpy function to the builder, for the 166 /// specified pointer arguments. 167 Value *llvm::EmitStrNCpy(Value *Dst, Value *Src, Value *Len, 168 IRBuilder<> &B, const DataLayout *TD, 169 const TargetLibraryInfo *TLI, StringRef Name) { 170 if (!TLI->has(LibFunc::strncpy)) 171 return 0; 172 173 Module *M = B.GetInsertBlock()->getParent()->getParent(); 174 AttributeWithIndex AWI[2]; 175 AWI[0] = AttributeWithIndex::get(M->getContext(), 2, Attributes::NoCapture); 176 AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, 177 Attributes::NoUnwind); 178 Type *I8Ptr = B.getInt8PtrTy(); 179 Value *StrNCpy = M->getOrInsertFunction(Name, AttrListPtr::get(AWI), 180 I8Ptr, I8Ptr, I8Ptr, 181 Len->getType(), NULL); 182 CallInst *CI = B.CreateCall3(StrNCpy, CastToCStr(Dst, B), CastToCStr(Src, B), 183 Len, "strncpy"); 184 if (const Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts())) 185 CI->setCallingConv(F->getCallingConv()); 186 return CI; 187 } 188 189 /// EmitMemCpyChk - Emit a call to the __memcpy_chk function to the builder. 190 /// This expects that the Len and ObjSize have type 'intptr_t' and Dst/Src 191 /// are pointers. 192 Value *llvm::EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize, 193 IRBuilder<> &B, const DataLayout *TD, 194 const TargetLibraryInfo *TLI) { 195 if (!TLI->has(LibFunc::memcpy_chk)) 196 return 0; 197 198 Module *M = B.GetInsertBlock()->getParent()->getParent(); 199 AttributeWithIndex AWI; 200 AWI = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, 201 Attributes::NoUnwind); 202 Value *MemCpy = M->getOrInsertFunction("__memcpy_chk", 203 AttrListPtr::get(AWI), 204 B.getInt8PtrTy(), 205 B.getInt8PtrTy(), 206 B.getInt8PtrTy(), 207 TD->getIntPtrType(Dst->getType()), 208 TD->getIntPtrType(Src->getType()), 209 NULL); 210 Dst = CastToCStr(Dst, B); 211 Src = CastToCStr(Src, B); 212 CallInst *CI = B.CreateCall4(MemCpy, Dst, Src, Len, ObjSize); 213 if (const Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts())) 214 CI->setCallingConv(F->getCallingConv()); 215 return CI; 216 } 217 218 /// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is 219 /// a pointer, Val is an i32 value, and Len is an 'intptr_t' value. 220 Value *llvm::EmitMemChr(Value *Ptr, Value *Val, 221 Value *Len, IRBuilder<> &B, const DataLayout *TD, 222 const TargetLibraryInfo *TLI) { 223 if (!TLI->has(LibFunc::memchr)) 224 return 0; 225 226 Module *M = B.GetInsertBlock()->getParent()->getParent(); 227 AttributeWithIndex AWI; 228 Attributes::AttrVal AVs[2] = { Attributes::ReadOnly, Attributes::NoUnwind }; 229 AWI = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, 230 ArrayRef<Attributes::AttrVal>(AVs, 2)); 231 Value *MemChr = M->getOrInsertFunction("memchr", AttrListPtr::get(AWI), 232 B.getInt8PtrTy(), 233 B.getInt8PtrTy(), 234 B.getInt32Ty(), 235 TD->getIntPtrType(Ptr->getType()), 236 NULL); 237 CallInst *CI = B.CreateCall3(MemChr, CastToCStr(Ptr, B), Val, Len, "memchr"); 238 239 if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts())) 240 CI->setCallingConv(F->getCallingConv()); 241 242 return CI; 243 } 244 245 /// EmitMemCmp - Emit a call to the memcmp function. 246 Value *llvm::EmitMemCmp(Value *Ptr1, Value *Ptr2, 247 Value *Len, IRBuilder<> &B, const DataLayout *TD, 248 const TargetLibraryInfo *TLI) { 249 if (!TLI->has(LibFunc::memcmp)) 250 return 0; 251 252 Module *M = B.GetInsertBlock()->getParent()->getParent(); 253 AttributeWithIndex AWI[3]; 254 AWI[0] = AttributeWithIndex::get(M->getContext(), 1, Attributes::NoCapture); 255 AWI[1] = AttributeWithIndex::get(M->getContext(), 2, Attributes::NoCapture); 256 Attributes::AttrVal AVs[2] = { Attributes::ReadOnly, Attributes::NoUnwind }; 257 AWI[2] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, 258 ArrayRef<Attributes::AttrVal>(AVs, 2)); 259 260 Value *MemCmp = M->getOrInsertFunction("memcmp", AttrListPtr::get(AWI), 261 B.getInt32Ty(), 262 B.getInt8PtrTy(), 263 B.getInt8PtrTy(), 264 TD->getIntPtrType(Ptr1->getType()), 265 NULL); 266 CallInst *CI = B.CreateCall3(MemCmp, CastToCStr(Ptr1, B), CastToCStr(Ptr2, B), 267 Len, "memcmp"); 268 269 if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts())) 270 CI->setCallingConv(F->getCallingConv()); 271 272 return CI; 273 } 274 275 /// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' (e.g. 276 /// 'floor'). This function is known to take a single of type matching 'Op' and 277 /// returns one value with the same type. If 'Op' is a long double, 'l' is 278 /// added as the suffix of name, if 'Op' is a float, we add a 'f' suffix. 279 Value *llvm::EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B, 280 const AttrListPtr &Attrs) { 281 SmallString<20> NameBuffer; 282 if (!Op->getType()->isDoubleTy()) { 283 // If we need to add a suffix, copy into NameBuffer. 284 NameBuffer += Name; 285 if (Op->getType()->isFloatTy()) 286 NameBuffer += 'f'; // floorf 287 else 288 NameBuffer += 'l'; // floorl 289 Name = NameBuffer; 290 } 291 292 Module *M = B.GetInsertBlock()->getParent()->getParent(); 293 Value *Callee = M->getOrInsertFunction(Name, Op->getType(), 294 Op->getType(), NULL); 295 CallInst *CI = B.CreateCall(Callee, Op, Name); 296 CI->setAttributes(Attrs); 297 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts())) 298 CI->setCallingConv(F->getCallingConv()); 299 300 return CI; 301 } 302 303 /// EmitPutChar - Emit a call to the putchar function. This assumes that Char 304 /// is an integer. 305 Value *llvm::EmitPutChar(Value *Char, IRBuilder<> &B, const DataLayout *TD, 306 const TargetLibraryInfo *TLI) { 307 if (!TLI->has(LibFunc::putchar)) 308 return 0; 309 310 Module *M = B.GetInsertBlock()->getParent()->getParent(); 311 Value *PutChar = M->getOrInsertFunction("putchar", B.getInt32Ty(), 312 B.getInt32Ty(), NULL); 313 CallInst *CI = B.CreateCall(PutChar, 314 B.CreateIntCast(Char, 315 B.getInt32Ty(), 316 /*isSigned*/true, 317 "chari"), 318 "putchar"); 319 320 if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts())) 321 CI->setCallingConv(F->getCallingConv()); 322 return CI; 323 } 324 325 /// EmitPutS - Emit a call to the puts function. This assumes that Str is 326 /// some pointer. 327 Value *llvm::EmitPutS(Value *Str, IRBuilder<> &B, const DataLayout *TD, 328 const TargetLibraryInfo *TLI) { 329 if (!TLI->has(LibFunc::puts)) 330 return 0; 331 332 Module *M = B.GetInsertBlock()->getParent()->getParent(); 333 AttributeWithIndex AWI[2]; 334 AWI[0] = AttributeWithIndex::get(M->getContext(), 1, Attributes::NoCapture); 335 AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, 336 Attributes::NoUnwind); 337 338 Value *PutS = M->getOrInsertFunction("puts", AttrListPtr::get(AWI), 339 B.getInt32Ty(), 340 B.getInt8PtrTy(), 341 NULL); 342 CallInst *CI = B.CreateCall(PutS, CastToCStr(Str, B), "puts"); 343 if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts())) 344 CI->setCallingConv(F->getCallingConv()); 345 return CI; 346 } 347 348 /// EmitFPutC - Emit a call to the fputc function. This assumes that Char is 349 /// an integer and File is a pointer to FILE. 350 Value *llvm::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B, 351 const DataLayout *TD, const TargetLibraryInfo *TLI) { 352 if (!TLI->has(LibFunc::fputc)) 353 return 0; 354 355 Module *M = B.GetInsertBlock()->getParent()->getParent(); 356 AttributeWithIndex AWI[2]; 357 AWI[0] = AttributeWithIndex::get(M->getContext(), 2, Attributes::NoCapture); 358 AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, 359 Attributes::NoUnwind); 360 Constant *F; 361 if (File->getType()->isPointerTy()) 362 F = M->getOrInsertFunction("fputc", AttrListPtr::get(AWI), 363 B.getInt32Ty(), 364 B.getInt32Ty(), File->getType(), 365 NULL); 366 else 367 F = M->getOrInsertFunction("fputc", 368 B.getInt32Ty(), 369 B.getInt32Ty(), 370 File->getType(), NULL); 371 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true, 372 "chari"); 373 CallInst *CI = B.CreateCall2(F, Char, File, "fputc"); 374 375 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) 376 CI->setCallingConv(Fn->getCallingConv()); 377 return CI; 378 } 379 380 /// EmitFPutS - Emit a call to the puts function. Str is required to be a 381 /// pointer and File is a pointer to FILE. 382 Value *llvm::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B, 383 const DataLayout *TD, const TargetLibraryInfo *TLI) { 384 if (!TLI->has(LibFunc::fputs)) 385 return 0; 386 387 Module *M = B.GetInsertBlock()->getParent()->getParent(); 388 AttributeWithIndex AWI[3]; 389 AWI[0] = AttributeWithIndex::get(M->getContext(), 1, Attributes::NoCapture); 390 AWI[1] = AttributeWithIndex::get(M->getContext(), 2, Attributes::NoCapture); 391 AWI[2] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, 392 Attributes::NoUnwind); 393 StringRef FPutsName = TLI->getName(LibFunc::fputs); 394 Constant *F; 395 if (File->getType()->isPointerTy()) 396 F = M->getOrInsertFunction(FPutsName, AttrListPtr::get(AWI), 397 B.getInt32Ty(), 398 B.getInt8PtrTy(), 399 File->getType(), NULL); 400 else 401 F = M->getOrInsertFunction(FPutsName, B.getInt32Ty(), 402 B.getInt8PtrTy(), 403 File->getType(), NULL); 404 CallInst *CI = B.CreateCall2(F, CastToCStr(Str, B), File, "fputs"); 405 406 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) 407 CI->setCallingConv(Fn->getCallingConv()); 408 return CI; 409 } 410 411 /// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is 412 /// a pointer, Size is an 'intptr_t', and File is a pointer to FILE. 413 Value *llvm::EmitFWrite(Value *Ptr, Value *Size, Value *File, 414 IRBuilder<> &B, const DataLayout *TD, 415 const TargetLibraryInfo *TLI) { 416 if (!TLI->has(LibFunc::fwrite)) 417 return 0; 418 419 Module *M = B.GetInsertBlock()->getParent()->getParent(); 420 AttributeWithIndex AWI[3]; 421 AWI[0] = AttributeWithIndex::get(M->getContext(), 1, Attributes::NoCapture); 422 AWI[1] = AttributeWithIndex::get(M->getContext(), 4, Attributes::NoCapture); 423 AWI[2] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, 424 Attributes::NoUnwind); 425 StringRef FWriteName = TLI->getName(LibFunc::fwrite); 426 Constant *F; 427 Type *PtrTy = Ptr->getType(); 428 if (File->getType()->isPointerTy()) 429 F = M->getOrInsertFunction(FWriteName, AttrListPtr::get(AWI), 430 TD->getIntPtrType(PtrTy), 431 B.getInt8PtrTy(), 432 TD->getIntPtrType(PtrTy), 433 TD->getIntPtrType(PtrTy), 434 File->getType(), NULL); 435 else 436 F = M->getOrInsertFunction(FWriteName, TD->getIntPtrType(PtrTy), 437 B.getInt8PtrTy(), 438 TD->getIntPtrType(PtrTy), 439 TD->getIntPtrType(PtrTy), 440 File->getType(), NULL); 441 CallInst *CI = B.CreateCall4(F, CastToCStr(Ptr, B), Size, 442 ConstantInt::get(TD->getIntPtrType(PtrTy), 1), File); 443 444 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) 445 CI->setCallingConv(Fn->getCallingConv()); 446 return CI; 447 } 448 449 SimplifyFortifiedLibCalls::~SimplifyFortifiedLibCalls() { } 450 451 bool SimplifyFortifiedLibCalls::fold(CallInst *CI, const DataLayout *TD, 452 const TargetLibraryInfo *TLI) { 453 // We really need DataLayout for later. 454 if (!TD) return false; 455 456 this->CI = CI; 457 Function *Callee = CI->getCalledFunction(); 458 StringRef Name = Callee->getName(); 459 FunctionType *FT = Callee->getFunctionType(); 460 LLVMContext &Context = CI->getParent()->getContext(); 461 IRBuilder<> B(CI); 462 463 if (Name == "__memcpy_chk") { 464 Type *PT = FT->getParamType(0); 465 // Check if this has the right signature. 466 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 467 !FT->getParamType(0)->isPointerTy() || 468 !FT->getParamType(1)->isPointerTy() || 469 FT->getParamType(2) != TD->getIntPtrType(PT) || 470 FT->getParamType(3) != TD->getIntPtrType(PT)) 471 return false; 472 473 if (isFoldable(3, 2, false)) { 474 B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1), 475 CI->getArgOperand(2), 1); 476 replaceCall(CI->getArgOperand(0)); 477 return true; 478 } 479 return false; 480 } 481 482 // Should be similar to memcpy. 483 if (Name == "__mempcpy_chk") { 484 return false; 485 } 486 487 if (Name == "__memmove_chk") { 488 // Check if this has the right signature. 489 Type *PT = FT->getParamType(0); 490 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 491 !FT->getParamType(0)->isPointerTy() || 492 !FT->getParamType(1)->isPointerTy() || 493 FT->getParamType(2) != TD->getIntPtrType(PT) || 494 FT->getParamType(3) != TD->getIntPtrType(PT)) 495 return false; 496 497 if (isFoldable(3, 2, false)) { 498 B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1), 499 CI->getArgOperand(2), 1); 500 replaceCall(CI->getArgOperand(0)); 501 return true; 502 } 503 return false; 504 } 505 506 if (Name == "__memset_chk") { 507 // Check if this has the right signature. 508 Type *PT = FT->getParamType(0); 509 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 510 !FT->getParamType(0)->isPointerTy() || 511 !FT->getParamType(1)->isIntegerTy() || 512 FT->getParamType(2) != TD->getIntPtrType(PT) || 513 FT->getParamType(3) != TD->getIntPtrType(PT)) 514 return false; 515 516 if (isFoldable(3, 2, false)) { 517 Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), 518 false); 519 B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1); 520 replaceCall(CI->getArgOperand(0)); 521 return true; 522 } 523 return false; 524 } 525 526 if (Name == "__strcpy_chk" || Name == "__stpcpy_chk") { 527 // Check if this has the right signature. 528 Type *PT = FT->getParamType(0); 529 if (FT->getNumParams() != 3 || 530 FT->getReturnType() != FT->getParamType(0) || 531 FT->getParamType(0) != FT->getParamType(1) || 532 FT->getParamType(0) != Type::getInt8PtrTy(Context) || 533 FT->getParamType(2) != TD->getIntPtrType(PT)) 534 return 0; 535 536 537 // If a) we don't have any length information, or b) we know this will 538 // fit then just lower to a plain st[rp]cpy. Otherwise we'll keep our 539 // st[rp]cpy_chk call which may fail at runtime if the size is too long. 540 // TODO: It might be nice to get a maximum length out of the possible 541 // string lengths for varying. 542 if (isFoldable(2, 1, true)) { 543 Value *Ret = EmitStrCpy(CI->getArgOperand(0), CI->getArgOperand(1), B, TD, 544 TLI, Name.substr(2, 6)); 545 if (!Ret) 546 return false; 547 replaceCall(Ret); 548 return true; 549 } 550 return false; 551 } 552 553 if (Name == "__strncpy_chk" || Name == "__stpncpy_chk") { 554 // Check if this has the right signature. 555 Type *PT = FT->getParamType(0); 556 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 557 FT->getParamType(0) != FT->getParamType(1) || 558 FT->getParamType(0) != Type::getInt8PtrTy(Context) || 559 !FT->getParamType(2)->isIntegerTy() || 560 FT->getParamType(3) != TD->getIntPtrType(PT)) 561 return false; 562 563 if (isFoldable(3, 2, false)) { 564 Value *Ret = EmitStrNCpy(CI->getArgOperand(0), CI->getArgOperand(1), 565 CI->getArgOperand(2), B, TD, TLI, 566 Name.substr(2, 7)); 567 if (!Ret) 568 return false; 569 replaceCall(Ret); 570 return true; 571 } 572 return false; 573 } 574 575 if (Name == "__strcat_chk") { 576 return false; 577 } 578 579 if (Name == "__strncat_chk") { 580 return false; 581 } 582 583 return false; 584 } 585