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