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