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