1 #include <magic/support/MagicUtil.h>
2
3 using namespace llvm;
4
5 namespace llvm {
6
7 //===----------------------------------------------------------------------===//
8 // Public static methods
9 //===----------------------------------------------------------------------===//
10
11 static std::map<const std::string, GlobalVariable*> stringRefCache;
12
getLabelHash(std::string label)13 unsigned getLabelHash(std::string label) {
14 unsigned hash = 0;
15 for(unsigned i=0;i<label.length();i++){
16 hash ^= (label[i]);
17 hash = (hash << 9) | (hash >> ((sizeof(unsigned)*8)-9));
18 }
19 return hash;
20 }
21
getModuleHash(DIDescriptor DID,const std::string & baseDir,StringRef extraField="")22 unsigned getModuleHash(DIDescriptor DID, const std::string &baseDir, StringRef extraField="") {
23 std::string relPath;
24 PassUtil::getDbgLocationInfo(DID, baseDir, NULL, NULL, &relPath);
25 return getLabelHash(relPath + "/" + extraField.data());
26 }
27
getGVSourceName(Module & M,GlobalVariable * GV,DIGlobalVariable ** DIGVP,const std::string & baseDir)28 StringRef MagicUtil::getGVSourceName(Module &M, GlobalVariable *GV, DIGlobalVariable **DIGVP, const std::string &baseDir) {
29 static DIGlobalVariable Var;
30 MDNode *DIGV = PassUtil::findDbgGlobalDeclare(GV);
31 if(DIGV) {
32 Var = DIGlobalVariable(DIGV);
33 if(DIGVP) *DIGVP = &Var;
34 if(GV->getLinkage() == GlobalValue::InternalLinkage){
35 /* static variable */
36 StringRef funcName, countStr;
37 DIScope scope = Var.getContext();
38 if(scope.isLexicalBlock()){
39 /* find the subprogram that contains this basic block recursively */
40 while(!scope.isSubprogram()){
41 scope = DILexicalBlock(scope).getContext();
42 }
43 }
44 if(scope.isSubprogram()){
45 /* static function variable */
46
47 funcName = DISubprogram(scope).getName();
48
49 int count=0;
50 Module::GlobalListType &globalList = M.getGlobalList();
51 for (Module::global_iterator it = globalList.begin(); it != globalList.end(); ++it) {
52 GlobalVariable *OtherGV = &(*it);
53 MDNode *OtherDIGV = PassUtil::findDbgGlobalDeclare(OtherGV);
54 if(OtherDIGV) {
55 DIGlobalVariable OtherVar(OtherDIGV);
56
57 DIScope otherScope = OtherVar.getContext();
58 if(otherScope.isLexicalBlock()){
59 /* find the subprogram that contains this basic block recursively */
60 while(!otherScope.isSubprogram()){
61 otherScope = DILexicalBlock(otherScope).getContext();
62 }
63 }
64 if(otherScope.isSubprogram()){
65 if(!strcmp(Var.getName().data(), OtherVar.getName().data())){
66 if(DIGV == OtherDIGV){
67 break;
68 }
69 count++;
70 }
71 }
72 }
73 }
74
75 std::stringstream stm;
76 if(count > 0){
77 stm << "." << count;
78 }
79 countStr = StringRef(*new std::string(stm.str()));
80
81 }else{
82 /* static global variable */
83 funcName = "";
84 countStr = "";
85 }
86
87 std::stringstream stm;
88 stm << Var.getName().data() << "." << getModuleHash(Var, baseDir, funcName) << countStr.data();
89 return StringRef(*new std::string(stm.str()));
90
91 }else{
92 /* global variable */
93 return Var.getName();
94 }
95 }else{
96 /* llvm .str variables and assembly */
97 if(DIGVP) *DIGVP = NULL;
98 return GV->getName();
99 }
100 }
101
getLVSourceName(Module & M,AllocaInst * V,DIVariable ** DIVP)102 StringRef MagicUtil::getLVSourceName(Module &M, AllocaInst *V, DIVariable **DIVP) {
103 static DIVariable Var;
104 const DbgDeclareInst *DDI = FindAllocaDbgDeclare(V);
105 if(DDI && DDI != (const DbgDeclareInst *) -1){
106 Var = DIVariable(cast<MDNode>(DDI->getVariable()));
107 if(DIVP) *DIVP = &Var;
108
109 int count = 0;
110
111 Function *F = V->getParent()->getParent();
112 for (inst_iterator it = inst_begin(F), et = inst_end(F); it != et; ++it) {
113 Instruction *inst = &(*it);
114 if (DbgDeclareInst *OtherDDI = dyn_cast<DbgDeclareInst>(inst)){
115 DIVariable otherVar(cast<MDNode>(OtherDDI->getVariable()));
116 if(!strcmp(Var.getName().data(), otherVar.getName().data())){
117 if(OtherDDI == DDI){
118 break;
119 }
120 count++;
121 }
122 }
123 }
124
125 std::stringstream stm;
126 stm << Var.getName().data();
127 if(count > 0){
128 stm << "." << count;
129 }
130 return StringRef(*new std::string(stm.str()));
131 }else{
132 if(DIVP) *DIVP = NULL;
133 return V->getName();
134 }
135 }
136
getFunctionSourceName(Module & M,Function * F,DISubprogram ** DISP,const std::string & baseDir)137 StringRef MagicUtil::getFunctionSourceName(Module &M, Function *F, DISubprogram **DISP, const std::string &baseDir) {
138 static DISubprogram Func;
139 MDNode *DIF = PassUtil::findDbgSubprogramDeclare(F);
140 if(DIF) {
141 Func = DISubprogram(DIF);
142 if(DISP) *DISP = &Func;
143 if(F->getLinkage() == GlobalValue::InternalLinkage){
144 std::stringstream stm;
145 stm << Func.getName().data() << "." << getModuleHash(Func, baseDir);
146 return StringRef(*new std::string(stm.str()));
147 }else{
148 return Func.getName();
149 }
150 }else{
151 /* assembly */
152 if(DISP) *DISP = NULL;
153 return F->getName();
154 }
155 }
156
putStringRefCache(Module & M,const std::string & str,GlobalVariable * GV)157 void MagicUtil::putStringRefCache(Module &M, const std::string &str, GlobalVariable *GV) {
158 std::map<const std::string, GlobalVariable*>::iterator it;
159 it = stringRefCache.find(str);
160 if(it == stringRefCache.end()) {
161 stringRefCache.insert(std::pair<const std::string, GlobalVariable*>(str, GV));
162 }
163 }
164
getGetElementPtrConstant(Constant * constant,std::vector<Value * > & indexes)165 Constant* MagicUtil::getGetElementPtrConstant(Constant *constant, std::vector<Value*> &indexes) {
166 return PassUtil::getGetElementPtrConstant(constant, indexes);
167 }
168
createGetElementPtrInstruction(Value * ptr,std::vector<Value * > & indexes,const Twine & NameStr,Instruction * InsertBefore)169 GetElementPtrInst* MagicUtil::createGetElementPtrInstruction(Value *ptr, std::vector<Value*> &indexes, const Twine &NameStr, Instruction *InsertBefore) {
170 return PassUtil::createGetElementPtrInstruction(ptr, indexes, NameStr, InsertBefore);
171 }
172
createGetElementPtrInstruction(Value * ptr,std::vector<Value * > & indexes,const Twine & NameStr,BasicBlock * InsertAtEnd)173 GetElementPtrInst* MagicUtil::createGetElementPtrInstruction(Value *ptr, std::vector<Value*> &indexes, const Twine &NameStr, BasicBlock *InsertAtEnd) {
174 return PassUtil::createGetElementPtrInstruction(ptr, indexes, NameStr, InsertAtEnd);
175 }
176
createCallInstruction(Value * F,std::vector<Value * > & args,const Twine & NameStr,Instruction * InsertBefore)177 CallInst* MagicUtil::createCallInstruction(Value *F, std::vector<Value*> &args, const Twine &NameStr, Instruction *InsertBefore) {
178 return PassUtil::createCallInstruction(F, args, NameStr, InsertBefore);
179 }
180
createCallInstruction(Value * F,std::vector<Value * > & args,const Twine & NameStr,BasicBlock * InsertAtEnd)181 CallInst* MagicUtil::createCallInstruction(Value *F, std::vector<Value*> &args, const Twine &NameStr, BasicBlock *InsertAtEnd) {
182 return PassUtil::createCallInstruction(F, args, NameStr, InsertAtEnd);
183 }
184
getIntrinsicFunction(Module & M,Intrinsic::ID id,TYPECONST Type ** types,unsigned size)185 Function* MagicUtil::getIntrinsicFunction(Module &M, Intrinsic::ID id, TYPECONST Type** types, unsigned size) {
186 return PassUtil::getIntrinsicFunction(M, id, types, size);
187 }
188
getStringRef(Module & M,const std::string & str)189 GlobalVariable *MagicUtil::getStringRef(Module &M, const std::string &str) {
190 std::map<const std::string, GlobalVariable*>::iterator it;
191 GlobalVariable *stringRef = NULL;
192 bool debug = false;
193
194 it = stringRefCache.find(str);
195 if(it != stringRefCache.end()) {
196 if(debug) magicUtilLog("*** getStringRef: cache hit for " << str);
197 stringRef = it->second;
198 }
199 if(stringRef == NULL) {
200 stringRef = PassUtil::getStringGlobalVariable(M, str, MAGIC_HIDDEN_STR_PREFIX, MAGIC_STATIC_VARS_SECTION_RO);
201 stringRefCache.insert(std::pair<const std::string, GlobalVariable*>(str, stringRef));
202 }
203
204 return stringRef;
205 }
206
207
getIntArrayRef(Module & M,unsigned arrSize,std::vector<int> * arr,bool isConstant)208 GlobalVariable *MagicUtil::getIntArrayRef(Module &M, unsigned arrSize, std::vector<int> *arr, bool isConstant) {
209 static std::map<std::vector<int>, GlobalVariable*> arrayRefCache;
210 std::map<std::vector<int>, GlobalVariable*>::iterator it;
211 static std::vector<int> defInitilizer;
212
213 //construct an appropriate initializer if we do not have one
214 if(!arr) {
215 arr = &defInitilizer;
216 arr->clear();
217 for(unsigned i=0;i<arrSize;i++) arr->push_back(0);
218 }
219 assert(arrSize == arr->size());
220
221 //cache lookup
222 if(isConstant) {
223 it = arrayRefCache.find(*arr);
224 if(it != arrayRefCache.end()) {
225 return it->second;
226 }
227 }
228
229 //create a constant internal array reference
230 std::vector<Constant*> arrayElems;
231 for(unsigned i=0;i<arr->size();i++) {
232 arrayElems.push_back(ConstantInt::get(M.getContext(), APInt(32, (*arr)[i], 10)));
233 }
234 ArrayType* arrayTy = ArrayType::get(IntegerType::get(M.getContext(), 32), arr->size());
235 Constant *arrayValue = ConstantArray::get(arrayTy, arrayElems);
236
237 //create the global variable and record it in the module
238 GlobalVariable *arrayRef = new GlobalVariable(arrayValue->getType(), isConstant,
239 GlobalValue::InternalLinkage, arrayValue,
240 MAGIC_HIDDEN_ARRAY_PREFIX);
241 MagicUtil::setGlobalVariableSection(arrayRef, isConstant ? MAGIC_STATIC_VARS_SECTION_RO : MAGIC_STATIC_VARS_SECTION_DATA);
242 M.getGlobalList().push_back(arrayRef);
243
244 //populate cache
245 if(isConstant) {
246 arrayRefCache.insert(std::pair<std::vector<int>, GlobalVariable*>(*arr, arrayRef));
247 }
248
249 return arrayRef;
250 }
251
getStringArrayRef(Module & M,unsigned arrSize,std::vector<std::string> * arr,bool isConstant)252 GlobalVariable *MagicUtil::getStringArrayRef(Module &M, unsigned arrSize, std::vector<std::string> *arr, bool isConstant) {
253 static std::map<std::vector<std::string>, GlobalVariable*> arrayRefCache;
254 std::map<std::vector<std::string>, GlobalVariable*>::iterator it;
255 static std::vector<std::string> defInitilizer;
256 //construct an appropriate initializer if we do not have one
257 if(!arr) {
258 arr = &defInitilizer;
259 arr->clear();
260 for(unsigned i=0;i<arrSize;i++) arr->push_back("");
261 }
262 assert(arrSize == arr->size());
263
264 //cache lookup
265 if(isConstant) {
266 it = arrayRefCache.find(*arr);
267 if(it != arrayRefCache.end()) {
268 return it->second;
269 }
270 }
271
272 //create a constant internal array reference
273 std::vector<Constant*> arrayElems;
274 std::vector<Value*> arrayIndexes;
275 arrayIndexes.push_back(ConstantInt::get(M.getContext(), APInt(32, 0, 10)));
276 arrayIndexes.push_back(ConstantInt::get(M.getContext(), APInt(32, 0, 10)));
277 for(unsigned i=0;i<arr->size();i++) {
278 arrayElems.push_back(getGetElementPtrConstant(getStringRef(M, (*arr)[i]), arrayIndexes));
279 }
280 ArrayType* arrayTy = ArrayType::get(PointerType::get(IntegerType::get(M.getContext(), 8), 0), arr->size());
281 Constant *arrayValue = ConstantArray::get(arrayTy, arrayElems);
282
283 //create the global variable and record it in the module
284 GlobalVariable *arrayRef = new GlobalVariable(arrayValue->getType(), isConstant,
285 GlobalValue::InternalLinkage, arrayValue,
286 MAGIC_HIDDEN_ARRAY_PREFIX);
287 MagicUtil::setGlobalVariableSection(arrayRef, isConstant ? MAGIC_STATIC_VARS_SECTION_RO : MAGIC_STATIC_VARS_SECTION_DATA);
288 M.getGlobalList().push_back(arrayRef);
289
290 //populate cache
291 if(isConstant) {
292 arrayRefCache.insert(std::pair<std::vector<std::string>, GlobalVariable*>(*arr, arrayRef));
293 }
294
295 return arrayRef;
296 }
297
getGenericArrayRef(Module & M,std::vector<Constant * > & arrayElems,bool isConstant)298 GlobalVariable *MagicUtil::getGenericArrayRef(Module &M, std::vector<Constant*> &arrayElems, bool isConstant) {
299 static std::map<std::vector<Constant*>, GlobalVariable*> arrayRefCache;
300 std::map<std::vector<Constant*>, GlobalVariable*>::iterator it;
301 assert(arrayElems.size() > 0);
302
303 //cache lookup
304 if(isConstant) {
305 it = arrayRefCache.find(arrayElems);
306 if(it != arrayRefCache.end()) {
307 return it->second;
308 }
309 }
310
311 //create a constant internal array reference
312 ArrayType* arrayTy = ArrayType::get(arrayElems[0]->getType(), arrayElems.size());
313 Constant *arrayValue = ConstantArray::get(arrayTy, arrayElems);
314
315 //create the global variable and record it in the module
316 GlobalVariable *arrayRef = new GlobalVariable(arrayValue->getType(), isConstant,
317 GlobalValue::InternalLinkage, arrayValue,
318 MAGIC_HIDDEN_ARRAY_PREFIX);
319 MagicUtil::setGlobalVariableSection(arrayRef, isConstant ? MAGIC_STATIC_VARS_SECTION_RO : MAGIC_STATIC_VARS_SECTION_DATA);
320 M.getGlobalList().push_back(arrayRef);
321
322 //populate cache
323 if(isConstant) {
324 arrayRefCache.insert(std::pair<std::vector<Constant*>, GlobalVariable*>(arrayElems, arrayRef));
325 }
326
327 return arrayRef;
328 }
329
getMagicTypePtrArrayRef(Module & M,Instruction * InsertBefore,std::vector<Value * > & globalTypeIndexes,GlobalVariable * magicTypeArray)330 GlobalVariable *MagicUtil::getMagicTypePtrArrayRef(Module &M, Instruction *InsertBefore, std::vector<Value*> &globalTypeIndexes, GlobalVariable *magicTypeArray) {
331 int numTypeIndexes = globalTypeIndexes.size();
332 TYPECONST StructType* magicTypeStructTy = (TYPECONST StructType*) ((TYPECONST ArrayType*)magicTypeArray->getType()->getElementType())->getElementType();
333 ArrayType* typeIndexesArrTy = ArrayType::get(PointerType::get(magicTypeStructTy, 0), numTypeIndexes+1);
334 std::vector<Constant*> arrayElems;
335 for(int i=0;i<numTypeIndexes;i++) {
336 std::vector<Value*> magicTypeArrayIndexes;
337 magicTypeArrayIndexes.clear();
338 magicTypeArrayIndexes.push_back(ConstantInt::get(M.getContext(), APInt(64, 0, 10)));
339 magicTypeArrayIndexes.push_back(globalTypeIndexes[i]);
340 Constant* typePtr = getGetElementPtrConstant(magicTypeArray, magicTypeArrayIndexes);
341 arrayElems.push_back(typePtr);
342 }
343 arrayElems.push_back(ConstantPointerNull::get(PointerType::get(magicTypeStructTy, 0))); //NULL-terminated array
344
345 //create the global variable and record it in the module
346 Constant *arrayValue = ConstantArray::get(typeIndexesArrTy, arrayElems);
347 GlobalVariable *arrayRef = new GlobalVariable(arrayValue->getType(), true,
348 GlobalValue::InternalLinkage, arrayValue,
349 MAGIC_HIDDEN_ARRAY_PREFIX);
350 MagicUtil::setGlobalVariableSection(arrayRef, MAGIC_STATIC_VARS_SECTION_RO);
351 M.getGlobalList().push_back(arrayRef);
352
353 return arrayRef;
354 }
355
getExportedIntGlobalVar(Module & M,std::string name,int value,bool isConstant)356 GlobalVariable* MagicUtil::getExportedIntGlobalVar(Module &M, std::string name, int value, bool isConstant) {
357 Constant *intValue = ConstantInt::get(M.getContext(), APInt(32, value, 10));
358
359 //create the global variable and record it in the module
360 GlobalVariable *GV = new GlobalVariable(intValue->getType(), isConstant,
361 GlobalValue::LinkOnceAnyLinkage, intValue, name);
362 MagicUtil::setGlobalVariableSection(GV, isConstant ? MAGIC_STATIC_VARS_SECTION_RO : MAGIC_STATIC_VARS_SECTION_DATA);
363 M.getGlobalList().push_back(GV);
364
365 return GV;
366 }
367
getShadowRef(Module & M,GlobalVariable * GV)368 GlobalVariable* MagicUtil::getShadowRef(Module &M, GlobalVariable *GV) {
369 //create the shadow global variable and record it in the module
370 TYPECONST Type* type = GV->getType()->getElementType();
371 GlobalVariable *SGV = new GlobalVariable(type, GV->isConstant(),
372 GlobalValue::InternalLinkage, 0,
373 MAGIC_SHADOW_VAR_PREFIX + GV->getName());
374 SGV->setInitializer(Constant::getNullValue(type));
375 MagicUtil::setGlobalVariableSection(SGV, GV->isConstant() ? MAGIC_SHADOW_VARS_SECTION_RO : MAGIC_SHADOW_VARS_SECTION_DATA);
376 M.getGlobalList().push_back(SGV);
377
378 if(!GV->hasInitializer()) {
379 magicUtilLog("Shadowing for extern variable: " << GV->getName());
380 }
381 if(GV->isConstant()) {
382 magicUtilLog("Shadowing for constant variable: " << GV->getName());
383 }
384
385 return SGV;
386 }
387
getMagicStructFieldPtr(Module & M,Instruction * InsertBefore,GlobalVariable * var,Value * arrayIndex,const std::string & structFieldName,std::string * structFieldNames)388 Value* MagicUtil::getMagicStructFieldPtr(Module &M, Instruction *InsertBefore, GlobalVariable* var, Value* arrayIndex, const std::string &structFieldName, std::string *structFieldNames) {
389 //lookup field index
390 int structFieldIndex;
391 Value *varPtr;
392 for(structFieldIndex=0; structFieldName.compare(structFieldNames[structFieldIndex]) != 0; structFieldIndex++) {}
393
394 if(arrayIndex) {
395 //get array ptr
396 std::vector<Value*> arrayIndexes;
397 arrayIndexes.push_back(ConstantInt::get(M.getContext(), APInt(64, 0, 10)));
398 arrayIndexes.push_back(arrayIndex);
399 varPtr = createGetElementPtrInstruction(var, arrayIndexes, "", InsertBefore);
400 }
401 else {
402 varPtr = var;
403 }
404
405 //get struct field ptr
406 std::vector<Value*> structFieldIndexes;
407 structFieldIndexes.push_back(ConstantInt::get(M.getContext(), APInt(32, 0, 10)));
408 structFieldIndexes.push_back(ConstantInt::get(M.getContext(), APInt(32, structFieldIndex, 10)));
409 Instruction* structFieldPtr = createGetElementPtrInstruction(varPtr, structFieldIndexes, "", InsertBefore);
410
411 return structFieldPtr;
412 }
413
getMagicSStructFieldPtr(Module & M,Instruction * InsertBefore,GlobalVariable * magicArray,Value * magicArrayIndex,const std::string & structFieldName)414 Value* MagicUtil::getMagicSStructFieldPtr(Module &M, Instruction *InsertBefore, GlobalVariable* magicArray, Value* magicArrayIndex, const std::string &structFieldName) {
415 static std::string structFieldNames[] = { MAGIC_SSTRUCT_FIELDS };
416 return getMagicStructFieldPtr(M, InsertBefore, magicArray, magicArrayIndex, structFieldName, structFieldNames);
417 }
418
getMagicTStructFieldPtr(Module & M,Instruction * InsertBefore,GlobalVariable * magicTypeArray,Value * magicTypeArrayIndex,const std::string & structFieldName)419 Value* MagicUtil::getMagicTStructFieldPtr(Module &M, Instruction *InsertBefore, GlobalVariable* magicTypeArray, Value* magicTypeArrayIndex, const std::string &structFieldName) {
420 static std::string structFieldNames[] = { MAGIC_TSTRUCT_FIELDS };
421 return getMagicStructFieldPtr(M, InsertBefore, magicTypeArray, magicTypeArrayIndex, structFieldName, structFieldNames);
422 }
423
getMagicFStructFieldPtr(Module & M,Instruction * InsertBefore,GlobalVariable * magicFunctionArray,Value * magicFunctionArrayIndex,const std::string & structFieldName)424 Value* MagicUtil::getMagicFStructFieldPtr(Module &M, Instruction *InsertBefore, GlobalVariable* magicFunctionArray, Value* magicFunctionArrayIndex, const std::string &structFieldName) {
425 static std::string structFieldNames[] = { MAGIC_FSTRUCT_FIELDS };
426 return getMagicStructFieldPtr(M, InsertBefore, magicFunctionArray, magicFunctionArrayIndex, structFieldName, structFieldNames);
427 }
428
getMagicRStructFieldPtr(Module & M,Instruction * InsertBefore,GlobalVariable * magicVar,const std::string & structFieldName)429 Value* MagicUtil::getMagicRStructFieldPtr(Module &M, Instruction *InsertBefore, GlobalVariable* magicVar, const std::string &structFieldName) {
430 static std::string structFieldNames[] = { MAGIC_RSTRUCT_FIELDS };
431 return getMagicStructFieldPtr(M, InsertBefore, magicVar, NULL, structFieldName, structFieldNames);
432 }
433
getMagicDStructFieldPtr(Module & M,Instruction * InsertBefore,GlobalVariable * magicDsindexArray,Value * magicDsindexArrayIndex,const std::string & structFieldName)434 Value* MagicUtil::getMagicDStructFieldPtr(Module &M, Instruction *InsertBefore, GlobalVariable* magicDsindexArray, Value* magicDsindexArrayIndex, const std::string &structFieldName) {
435 static std::string structFieldNames[] = { MAGIC_DSTRUCT_FIELDS };
436 return getMagicStructFieldPtr(M, InsertBefore, magicDsindexArray, magicDsindexArrayIndex, structFieldName, structFieldNames);
437 }
438
getArrayPtr(Module & M,GlobalVariable * array)439 Constant* MagicUtil::getArrayPtr(Module &M, GlobalVariable* array) {
440 //indexes for array
441 static std::vector<Value*> arrayIndexes;
442 if(arrayIndexes.empty()) {
443 arrayIndexes.push_back(ConstantInt::get(M.getContext(), APInt(64, 0, 10))); //pointer to A[]
444 arrayIndexes.push_back(ConstantInt::get(M.getContext(), APInt(64, 0, 10))); //pointer to A[0]
445 }
446
447 //get array ptr
448 Constant* arrayPtr = getGetElementPtrConstant(array, arrayIndexes);
449
450 return arrayPtr;
451 }
452
insertMemcpyInst(Module & M,Instruction * InsertBefore,Value * Dst,Value * Src,Value * Len,unsigned Align)453 void MagicUtil::insertMemcpyInst(Module &M, Instruction *InsertBefore, Value *Dst, Value *Src, Value *Len, unsigned Align) {
454 bool useMemCpyIntrinsics = false;
455 Function *MemCpy = M.getFunction("memcpy");
456 if(!MemCpy) {
457 TYPECONST Type *ArgTys[1] = { IntegerType::getInt32Ty(M.getContext()) };
458 MemCpy = getIntrinsicFunction(M, Intrinsic::memcpy, ArgTys, 1);
459 useMemCpyIntrinsics = true;
460 }
461 else {
462 MemCpy = (Function*) M.getOrInsertFunction(MAGIC_MEMCPY_FUNC_NAME, MemCpy->getFunctionType());
463 }
464
465 // Insert the memcpy instruction
466 std::vector<Value*> MemCpyArgs;
467 MemCpyArgs.push_back(Dst);
468 MemCpyArgs.push_back(Src);
469 MemCpyArgs.push_back(Len);
470 if(useMemCpyIntrinsics) {
471 MemCpyArgs.push_back(ConstantInt::get(M.getContext(), APInt(32, Align, 10)));
472 }
473 createCallInstruction(MemCpy, MemCpyArgs, "", InsertBefore);
474 }
475
insertCopyInst(Module & M,Instruction * InsertBefore,GlobalVariable * GV,GlobalVariable * SGV,int GVSize,bool forceMemcpy)476 void MagicUtil::insertCopyInst(Module &M, Instruction *InsertBefore, GlobalVariable *GV, GlobalVariable *SGV, int GVSize, bool forceMemcpy) {
477 //get type and type size
478 TYPECONST Type *GVType = GV->getType()->getElementType();
479 bool isPrimitiveOrPointerType = !GVType->isAggregateType();
480
481 //no need for memcpy for primitive types or pointer types
482 if(isPrimitiveOrPointerType && !forceMemcpy) {
483 LoadInst* primitiveValue = new LoadInst(GV, "", false, InsertBefore);
484 new StoreInst(primitiveValue, SGV, false, InsertBefore);
485 return;
486 }
487
488 //cast pointers to match memcpy prototype
489 PointerType* voidPointerType = PointerType::get(IntegerType::get(M.getContext(), 8), 0);
490 Constant* varAddress = ConstantExpr::getCast(Instruction::BitCast, GV, voidPointerType);
491 Constant* varShadowAddress = ConstantExpr::getCast(Instruction::BitCast, SGV, voidPointerType);
492
493 //insert the memcpy instruction
494 MagicUtil::insertMemcpyInst(M, InsertBefore, varShadowAddress, varAddress, ConstantInt::get(M.getContext(), APInt(32, GVSize, 10)), 0);
495 }
496
getCalledFunctionFromCS(const CallSite & CS)497 Function* MagicUtil::getCalledFunctionFromCS(const CallSite &CS) {
498 assert(CS.getInstruction());
499 Function *function = CS.getCalledFunction();
500 if(function) {
501 return function;
502 }
503
504 //handle the weird case of bitcasted function call
505 //IMPORTANT! function may still be null, if it's an indirect call
506 ConstantExpr *CE = dyn_cast<ConstantExpr>(CS.getCalledValue());
507 if (CE) {
508 assert(CE->getOpcode() == Instruction::BitCast && "Bitcast expected, something else found!");
509 function = dyn_cast<Function>(CE->getOperand(0));
510 assert(function);
511 } else {
512 errs() << "Warning! Indirect call encountered!\n";
513 }
514
515 return function;
516 }
517
replaceCallInst(Instruction * originalInst,CallInst * newInst,int argOffset,bool removeUnusedFunction)518 void MagicUtil::replaceCallInst(Instruction *originalInst, CallInst *newInst, int argOffset, bool removeUnusedFunction) {
519 SmallVector< std::pair< unsigned, MDNode * >, 8> MDs;
520 originalInst->getAllMetadata(MDs);
521 for(unsigned i=0;i<MDs.size();i++) {
522 newInst->setMetadata(MDs[i].first, MDs[i].second);
523 }
524 CallSite CS = MagicUtil::getCallSiteFromInstruction(originalInst);
525 assert(CS);
526 CallingConv::ID CC = CS.getCallingConv();
527 Function *originalFunction = getCalledFunctionFromCS(CS);
528 newInst->setCallingConv(CC);
529 ATTRIBUTE_SET_TY NewAttrs = PassUtil::remapCallSiteAttributes(CS, argOffset);
530 newInst->setAttributes(NewAttrs);
531
532 originalInst->replaceAllUsesWith(newInst);
533
534 // If the old instruction was an invoke, add an unconditional branch
535 // before the invoke, which will become the new terminator.
536 if (InvokeInst *II = dyn_cast<InvokeInst>(originalInst))
537 BranchInst::Create(II->getNormalDest(), originalInst);
538
539 // Delete the old call site
540 originalInst->eraseFromParent();
541
542 // When asked, remove the original function when nobody uses it any more.
543 if(removeUnusedFunction && originalFunction->use_empty()) {
544 originalFunction->eraseFromParent();
545 }
546 }
547
getGlobalVariablesShadowFunctions(Module & M,std::vector<GlobalVariable * > globalVariables,std::vector<GlobalVariable * > shadowGlobalVariables,std::vector<int> globalVariableSizes,GlobalVariable * magicArray,int magicArraySize,bool forceShadow,bool setDirtyFlag)548 std::vector<Function*> MagicUtil::getGlobalVariablesShadowFunctions(Module &M, std::vector<GlobalVariable*> globalVariables, std::vector<GlobalVariable*> shadowGlobalVariables, std::vector<int> globalVariableSizes, GlobalVariable* magicArray, int magicArraySize, bool forceShadow, bool setDirtyFlag) {
549 std::vector<Function*> globalVariableShadowFunctions;
550 for(int i=0;i<magicArraySize;i++) {
551 Function* func = getGlobalVariableShadowFunction(M, globalVariables[i], shadowGlobalVariables[i], globalVariableSizes[i], magicArray, i, forceShadow, setDirtyFlag);
552 globalVariableShadowFunctions.push_back(func);
553 }
554
555 return globalVariableShadowFunctions;
556 }
557
getGlobalVariableShadowFunction(Module & M,GlobalVariable * GV,GlobalVariable * SGV,int GVSize,GlobalVariable * magicArray,int magicArrayIndex,bool forceShadow,bool setDirtyFlag)558 Function* MagicUtil::getGlobalVariableShadowFunction(Module &M, GlobalVariable* GV, GlobalVariable* SGV, int GVSize, GlobalVariable* magicArray, int magicArrayIndex, bool forceShadow, bool setDirtyFlag) {
559 static Constant* magicStateDirty = ConstantInt::get(M.getContext(), APInt(32, MAGIC_STATE_DIRTY, 10));
560 static Function* shadowFunc = NULL;
561 ConstantInt* magicArrayIndexConst = ConstantInt::get(M.getContext(), APInt(32, magicArrayIndex, 10));
562
563 //determine name
564 std::string name(MAGIC_SHADOW_FUNC_PREFIX);
565 name.append("_");
566 if(forceShadow) {
567 name.append("force_");
568 }
569 if(setDirtyFlag) {
570 name.append("setdf_");
571 }
572 name.append(GV->getName());
573
574 //create function
575 std::vector<TYPECONST Type*>shadowFuncArgs;
576 FunctionType* shadowFuncType = FunctionType::get(Type::getVoidTy(M.getContext()), shadowFuncArgs, false);
577 shadowFunc = Function::Create(shadowFuncType, GlobalValue::InternalLinkage, name, &M);
578 shadowFunc->setCallingConv(CallingConv::C);
579
580 //create blocks
581 BasicBlock* label_entry = BasicBlock::Create(M.getContext(), "entry",shadowFunc,0);
582 BasicBlock* label_shadow = BasicBlock::Create(M.getContext(), "shadow",shadowFunc,0);
583 BasicBlock* label_return = BasicBlock::Create(M.getContext(), "return",shadowFunc,0);
584 BranchInst::Create(label_shadow, label_entry);
585 BranchInst::Create(label_return, label_shadow);
586 Instruction* entryTerm = label_entry->getTerminator();
587 Instruction* shadowTerm = label_shadow->getTerminator();
588
589 if(!forceShadow || setDirtyFlag) {
590 //get flags
591 Value* structFlagsField = MagicUtil::getMagicSStructFieldPtr(M, entryTerm, magicArray, magicArrayIndexConst, MAGIC_SSTRUCT_FIELD_FLAGS);
592 LoadInst* varFlags = new LoadInst(structFlagsField, "", false, entryTerm);
593
594 //when not forcing, don't shadow if dirty is already set
595 if(!forceShadow) {
596 BinaryOperator* andedVarFlags = BinaryOperator::Create(Instruction::And, varFlags, magicStateDirty, "", entryTerm);
597 ICmpInst* flagsCmp = new ICmpInst(entryTerm, ICmpInst::ICMP_EQ, andedVarFlags, ConstantInt::get(M.getContext(), APInt(32, 0, 10)), "");
598 BranchInst::Create(label_shadow, label_return, flagsCmp, entryTerm);
599 entryTerm->eraseFromParent();
600 }
601
602 //set the dirty flag for the variable
603 if(setDirtyFlag) {
604 BinaryOperator* oredVarFlags = BinaryOperator::Create(Instruction::Or, varFlags, magicStateDirty, "", shadowTerm);
605 new StoreInst(oredVarFlags, structFlagsField, false, shadowTerm);
606 }
607 }
608
609 //perform a memory copy from the original variable to the shadow variable
610 MagicUtil::insertCopyInst(M, shadowTerm, GV, SGV, GVSize, /* forceMemcpy */ false);
611
612 ReturnInst::Create(M.getContext(), label_return);
613
614 return shadowFunc;
615 }
616
insertGlobalVariableCleanDirtyFlag(Module & M,GlobalVariable * GV,GlobalVariable * magicArray,int magicArrayIndex,Instruction * InsertBefore)617 void MagicUtil::insertGlobalVariableCleanDirtyFlag(Module &M, GlobalVariable* GV, GlobalVariable* magicArray, int magicArrayIndex, Instruction *InsertBefore) {
618 Value* structFlagsField = MagicUtil::getMagicSStructFieldPtr(M, InsertBefore, magicArray, ConstantInt::get(M.getContext(), APInt(32, magicArrayIndex, 10)), MAGIC_SSTRUCT_FIELD_FLAGS);
619 new StoreInst(ConstantInt::get(M.getContext(), APInt(32, 0, 10)), structFlagsField, false, InsertBefore);
620 }
621
insertShadowTag(Module & M,GlobalVariable * GV,Instruction * InsertBefore)622 void MagicUtil::insertShadowTag(Module &M, GlobalVariable *GV, Instruction *InsertBefore) {
623 static Function* shadowFunc = NULL;
624 PointerType* voidPointerType = PointerType::get(IntegerType::get(M.getContext(), 8), 0);
625
626 //create function
627 if(!shadowFunc) {
628 std::vector<TYPECONST Type*>shadowFuncArgs;
629 shadowFuncArgs.push_back(voidPointerType);
630 FunctionType* shadowFuncType = FunctionType::get(Type::getVoidTy(M.getContext()), shadowFuncArgs, false);
631 shadowFunc = Function::Create(shadowFuncType, GlobalValue::ExternalLinkage, MAGIC_LAZY_CHECKPOINT_SHADOW_TAG, &M);
632 shadowFunc->setCallingConv(CallingConv::C);
633 }
634
635 //shadow global variable
636 std::vector<Value*> args;
637 args.push_back(new BitCastInst(GV, voidPointerType, "", InsertBefore));
638 CallInst *callInst = createCallInstruction(shadowFunc, args, "", InsertBefore);
639 callInst->setCallingConv(CallingConv::C);
640 }
641
isShadowTag(Instruction * inst)642 bool MagicUtil::isShadowTag(Instruction *inst) {
643 if(dyn_cast<CallInst>(inst)) {
644 CallInst *callInst = dyn_cast<CallInst>(inst);
645 Function *function = callInst->getCalledFunction();
646 if(function == NULL) {
647 return false;
648 }
649 std::string funcName = function->getName();
650 if(!funcName.compare(MAGIC_LAZY_CHECKPOINT_SHADOW_TAG)) {
651 return true;
652 }
653 }
654 return false;
655 }
656
getGlobalVariableFromShadowTag(Instruction * inst,std::vector<Instruction * > & instructionsToRemove)657 GlobalVariable* MagicUtil::getGlobalVariableFromShadowTag(Instruction *inst, std::vector<Instruction*> &instructionsToRemove) {
658 CallSite CS = MagicUtil::getCallSiteFromInstruction(inst);
659 assert(CS.arg_size() == 1);
660 instructionsToRemove.push_back(inst);
661 CallSite::arg_iterator AI = CS.arg_begin();
662 Value *ActualArg = *AI;
663
664 while(true) {
665 BitCastInst *castInst = dyn_cast<BitCastInst>(ActualArg);
666 ConstantExpr *castExpr = dyn_cast<ConstantExpr>(ActualArg);
667 if(castInst) {
668 assert(castInst->getNumOperands() == 1);
669 ActualArg = castInst->getOperand(0);
670 instructionsToRemove.push_back(castInst);
671 }
672 else if(castExpr) {
673 //assert(castExpr->getNumOperands() == 1);
674 ActualArg = castExpr->getOperand(0);
675 }
676 else {
677 break;
678 }
679 }
680
681 GlobalVariable *GV = dyn_cast<GlobalVariable>(ActualArg);
682 if(GV == NULL) {
683 magicUtilLog("Weird ActualArg: " << *ActualArg);
684 }
685 assert(GV != NULL);
686
687 return GV;
688 }
689
cleanupShadowTag(Module & M,std::vector<Instruction * > & instructionsToRemove)690 void MagicUtil::cleanupShadowTag(Module &M, std::vector<Instruction*> &instructionsToRemove) {
691 int i=0;
692
693 for(i =0;i<(int)instructionsToRemove.size();i++) {
694 Instruction *inst = instructionsToRemove[i];
695 inst->eraseFromParent();
696 }
697 Function* func = M.getFunction(MAGIC_LAZY_CHECKPOINT_SHADOW_TAG);
698 if(func && func->getNumUses() == 0) {
699 func->eraseFromParent();
700 }
701 }
702
hasAddressTaken(const GlobalValue * GV,bool includeMembers)703 bool MagicUtil::hasAddressTaken(const GlobalValue *GV, bool includeMembers) {
704 //Most of the code taken from LLVM's SCCP.cpp
705
706 // Delete any dead constantexpr klingons.
707 GV->removeDeadConstantUsers();
708
709 std::vector<const User*> sourceUsers;
710 sourceUsers.push_back(GV);
711 if(includeMembers && isa<GlobalVariable>(GV)) {
712 for (const Use &UI : GV->uses()) {
713 const User *U = UI.getUser();
714 const ConstantExpr *constantExpr = dyn_cast<ConstantExpr>(U);
715 if(isa<GetElementPtrInst>(U)) {
716 sourceUsers.push_back(U);
717 }
718 else if(constantExpr && constantExpr->getOpcode() == Instruction::GetElementPtr) {
719 sourceUsers.push_back(U);
720 }
721 }
722 }
723
724 for(unsigned i=0;i<sourceUsers.size();i++) {
725 for (const Use &UI : sourceUsers[i]->uses()) {
726 const User *U = UI.getUser();
727 if (const StoreInst *SI = dyn_cast<StoreInst>(U)) {
728 if (SI->getOperand(0) == sourceUsers[i] || SI->isVolatile())
729 return true; // Storing addr of sourceUsers[i].
730 } else if (isa<InvokeInst>(U) || isa<CallInst>(U)) {
731 // Make sure we are calling the function, not passing the address.
732 ImmutableCallSite CS(cast<Instruction>(U));
733 if (!CS.isCallee(&UI))
734 return true;
735 } else if (const LoadInst *LI = dyn_cast<LoadInst>(U)) {
736 if (LI->isVolatile())
737 return true;
738 } else if (isa<BlockAddress>(U)) {
739 // blockaddress doesn't take the address of the function, it takes addr
740 // of label.
741 } else {
742 return true;
743 }
744 }
745 }
746 return false;
747 }
748
lookupValueSet(const GlobalVariable * GV,std::vector<int> & valueSet)749 bool MagicUtil::lookupValueSet(const GlobalVariable *GV, std::vector<int> &valueSet) {
750 //Similar to hasAddressTaken above, but we look for values
751
752 if(!isa<IntegerType>(GV->getType()->getElementType())) {
753 //integers is all we are interested in
754 return false;
755 }
756 if(!GV->hasInitializer()) {
757 //external variable
758 return false;
759 }
760
761 // Delete any dead constantexpr klingons.
762 GV->removeDeadConstantUsers();
763
764 std::set<int> set;
765 for (Value::const_user_iterator UI = GV->user_begin(), E = GV->user_end();
766 UI != E; ++UI) {
767 const User *U = *UI;
768 if (const StoreInst *SI = dyn_cast<StoreInst>(U)) {
769 if (SI->getOperand(1) == GV) {
770 Value *value = SI->getOperand(0);
771 if(ConstantInt *intValue = dyn_cast<ConstantInt>(value)) {
772 set.insert(intValue->getSExtValue());
773 }
774 else {
775 return false;
776 }
777 }
778 }
779 }
780 const Constant *constant = GV->getInitializer();
781 if(const ConstantInt *intConstant = dyn_cast<const ConstantInt>(constant)) {
782 set.insert(intConstant->getSExtValue());
783 }
784 else {
785 return false;
786 }
787
788 assert(set.size() > 0);
789 valueSet.push_back(set.size()); //push length as the first value
790 for(std::set<int>::iterator it=set.begin() ; it != set.end(); it++) {
791 valueSet.push_back(*it);
792 }
793
794 return true;
795 }
796
getStringOwner(GlobalVariable * GV)797 Value* MagicUtil::getStringOwner(GlobalVariable *GV)
798 {
799 //Similar to hasAddressTaken above, but we look for string owners
800 assert(GV && GV->isConstant());
801
802 // Skip emtpy strings.
803 if(GV->hasInitializer() && GV->getInitializer()->isNullValue()) {
804 return NULL;
805 }
806
807 // Delete any dead constantexpr klingons.
808 GV->removeDeadConstantUsers();
809
810 std::vector<User*> sourceUsers;
811 sourceUsers.push_back(GV);
812 for (Value::user_iterator UI = GV->user_begin(), E = GV->user_end();
813 UI != E; ++UI) {
814 User *U = *UI;
815 ConstantExpr *constantExpr = dyn_cast<ConstantExpr>(U);
816 if(isa<GetElementPtrInst>(U)) {
817 sourceUsers.push_back(U);
818 }
819 else if(constantExpr && constantExpr->getOpcode() == Instruction::GetElementPtr) {
820 sourceUsers.push_back(U);
821 }
822 }
823
824 Value *stringOwner = NULL;
825 for(unsigned i=0;i<sourceUsers.size();i++) {
826 for (Value::user_iterator UI = sourceUsers[i]->user_begin(), E = sourceUsers[i]->user_end();
827 UI != E; ++UI) {
828 User *U = *UI;
829 Value *V = U;
830 if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
831 V = SI->getPointerOperand();
832 }
833 if(isa<GlobalVariable>(V) || isa<AllocaInst>(V)) {
834 if(stringOwner != NULL && stringOwner != V) {
835 //no owner in the ambiguous cases
836 return NULL;
837 }
838 stringOwner = V;
839 }
840 }
841 }
842
843 return stringOwner;
844 }
845
getFirstNonAllocaInst(Function * F,bool skipAllocaPoint)846 Instruction* MagicUtil::getFirstNonAllocaInst(Function *F, bool skipAllocaPoint)
847 {
848 Instruction *I = NULL;
849 if (skipAllocaPoint) {
850 PassUtil::getAllocaInfo(F, NULL, &I);
851 }
852 else {
853 PassUtil::getAllocaInfo(F, &I, NULL);
854 }
855 assert(I);
856 return I;
857 }
858
setGlobalVariableSection(GlobalVariable * GV,const std::string & section)859 void MagicUtil::setGlobalVariableSection(GlobalVariable *GV, const std::string §ion)
860 {
861 if(GV->isThreadLocal()) {
862 return;
863 }
864
865 GV->setSection(section);
866 }
867
getCallAnnotation(Module & M,const CallSite & CS,int * annotation)868 bool MagicUtil::getCallAnnotation(Module &M, const CallSite &CS, int *annotation)
869 {
870 static GlobalVariable *magicAnnotationVar = NULL;
871 bool instFound = false;
872 bool annotationFound = false;
873 if(!magicAnnotationVar) {
874 magicAnnotationVar = M.getNamedGlobal(MAGIC_CALL_ANNOTATION_VAR_NAME);
875 assert(magicAnnotationVar);
876 }
877 Instruction *I = CS.getInstruction();
878 if(!I) {
879 return false;
880 }
881 BasicBlock *parent = I->getParent();
882 for (BasicBlock::iterator i = parent->begin(), e = parent->end(); i != e; ++i) {
883 Instruction *inst = i;
884 if(inst != I && !instFound) {
885 continue;
886 }
887 instFound = true;
888 if(inst == I) {
889 continue;
890 }
891 if(StoreInst *SI = dyn_cast<StoreInst>(inst)) {
892 if(SI->getOperand(1) == magicAnnotationVar) {
893 ConstantInt *CI = dyn_cast<ConstantInt>(SI->getOperand(0));
894 assert(CI && "Bad call annotation!");
895 annotationFound = true;
896 *annotation = CI->getSExtValue();
897 break;
898 }
899 }
900 else if(isa<CallInst>(inst) || isa<InvokeInst>(inst)) {
901 break;
902 }
903 }
904 return annotationFound;
905 }
906
getVarAnnotation(Module & M,const GlobalVariable * GV,int * annotation)907 bool MagicUtil::getVarAnnotation(Module &M, const GlobalVariable *GV, int *annotation)
908 {
909 std::string GVName = GV->getName();
910 GlobalVariable *annotationGV = M.getNamedGlobal(MAGIC_VAR_ANNOTATION_PREFIX_NAME + GVName);
911 if(!annotationGV || !annotationGV->hasInitializer()) {
912 return false;
913 }
914 ConstantInt* annotationValue = dyn_cast<ConstantInt>(annotationGV->getInitializer());
915 if(!annotationValue) {
916 return false;
917 }
918 *annotation = (int) annotationValue->getSExtValue();
919 return true;
920 }
921
getCallSiteFromInstruction(Instruction * I)922 CallSite MagicUtil::getCallSiteFromInstruction(Instruction *I)
923 {
924 return PassUtil::getCallSiteFromInstruction(I);
925 }
926
getAllocaInstFromArgument(Argument * argument)927 AllocaInst* MagicUtil::getAllocaInstFromArgument(Argument *argument)
928 {
929 Function *parent = argument->getParent();
930 std::string targetString = argument->getName().str() + "_addr";
931 std::string targetString2 = argument->getName().str() + ".addr";
932 StringRef targetName(targetString);
933 StringRef targetName2(targetString2);
934 for (inst_iterator it = inst_begin(parent), et = inst_end(parent); it != et; ++it) {
935 AllocaInst *AI = dyn_cast<AllocaInst>(&(*it));
936 if(!AI) {
937 break;
938 }
939 if(AI->getName().startswith(targetName) || AI->getName().startswith(targetName2)) {
940 return AI;
941 }
942 }
943
944 return NULL;
945 }
946
947 // searches for the specified function in module symbol table assuming that its name has been mangled
948 // returns NULL if the function has not been found
getMangledFunction(Module & M,StringRef functionName)949 Function* MagicUtil::getMangledFunction(Module &M, StringRef functionName)
950 {
951 Function *F = NULL;
952 char* outbuf;
953 const char* functionNameString = functionName.data();
954 int status;
955 for (Module::iterator it = M.begin(); it != M.end(); ++it) {
956 StringRef mangledName = (*it).getName();
957 outbuf = abi::__cxa_demangle(mangledName.data(), NULL, NULL, &status);
958 if (status == -2) {
959 continue; // mangledName is not a valid name under the C++ ABI mangling rules
960 }
961 assert(status == 0 && outbuf && "Error when trying to demangle a function name.");
962 // testing whether this is the function we are looking for
963 // the unmangled name is similar to a function prototype eg my_func(int, void*, int)
964 char* pos = strstr(outbuf, functionNameString);
965 if (!pos) {
966 free(outbuf);
967 continue;
968 }
969 // function names can only contain alpha-numeric characters and '_'
970 // if the unmangled name refers to the target function, then that substring should not
971 // be surrounded by characters allowed in a function name
972 // (to exclude cases such as myfunc vs _myfunc vs myfunc2)
973 if (pos > outbuf) {
974 if (isalnum(*(pos - 1)) || (*(pos - 1) == '_')) {
975 free(outbuf);
976 continue;
977 }
978 }
979 if (strlen(pos) > strlen(functionNameString)) {
980 if (isalnum(*(pos + strlen(functionNameString))) || (*(pos + strlen(functionNameString)) == '_')) {
981 free(outbuf);
982 continue;
983 }
984 }
985 F = it;
986 free(outbuf);
987 break;
988 }
989
990 return F;
991 }
992
getFunction(Module & M,StringRef functionName)993 Function* MagicUtil::getFunction(Module &M, StringRef functionName)
994 {
995 Function* F = M.getFunction(functionName);
996 if (!F) {
997 F = MagicUtil::getMangledFunction(M, functionName);
998 }
999 return F;
1000 }
1001
1002 // can Type1 be represented as Type2 (with no precision loss)
isCompatibleType(const Type * Type1,const Type * Type2)1003 bool MagicUtil::isCompatibleType(const Type* Type1, const Type* Type2)
1004 {
1005 if (Type1 == Type2) {
1006 return true;
1007 }
1008 if (Type1->isIntegerTy() && Type2->isIntegerTy()) {
1009 if (((const IntegerType*)Type1)->getBitWidth() <= ((const IntegerType*)Type2)->getBitWidth()) {
1010 return true;
1011 }
1012 }
1013
1014 return false;
1015 }
1016
1017 // inserts an inlined call to the pre-hook function before any other instruction is executed
1018 // it can forward (some of) the original function's parameters and additional trailing arguments
inlinePreHookForwardingCall(Function * function,Function * preHookFunction,std::vector<unsigned> argsMapping,std::vector<Value * > trailingArgs)1019 void MagicUtil::inlinePreHookForwardingCall(Function* function, Function* preHookFunction, std::vector<unsigned> argsMapping, std::vector<Value*> trailingArgs)
1020 {
1021 std::vector<Value*> callArgs;
1022 assert(preHookFunction->arg_size() == argsMapping.size() + trailingArgs.size() &&
1023 "The number of parameter values specified for the pre-hook function does not match the signature of the function.");
1024 for (std::vector<unsigned>::iterator it = argsMapping.begin(); it != argsMapping.end(); it++) {
1025 callArgs.push_back(MagicUtil::getFunctionParam(function, *it - 1));
1026 }
1027 for (std::vector<Value*>::iterator it = trailingArgs.begin(); it != trailingArgs.end(); it++) {
1028 callArgs.push_back(*it);
1029 }
1030 // insert the call after the alloca instructions so that they remain for sure in the entry block
1031 Instruction *FirstInst = MagicUtil::getFirstNonAllocaInst(function);
1032 for (unsigned i = 0; i < callArgs.size(); ++i) {
1033 TYPECONST Type* ArgType = callArgs[i]->getType();
1034 TYPECONST Type* ParamType = preHookFunction->getFunctionType()->getParamType(i);
1035
1036 if (!MagicUtil::isCompatibleType(ArgType, ParamType)) {
1037 assert(CastInst::isCastable(ArgType, ParamType) && "The value of the argument cannot be "
1038 "casted to the parameter type required by the function to be called.");
1039 Instruction::CastOps CastOpCode = CastInst::getCastOpcode(callArgs[i], false, ParamType, false);
1040 callArgs[i] = CastInst::Create(CastOpCode, callArgs[i], ParamType, "", FirstInst);
1041 }
1042 }
1043
1044 CallInst* WrapperFuncCall = MagicUtil::createCallInstruction(preHookFunction, callArgs, "", FirstInst);
1045 InlineFunctionInfo IFI;
1046 InlineFunction(WrapperFuncCall, IFI);
1047 }
1048
1049 // inserts an inlined call to the post-hook function before all return instructions
1050 // forwarded arguments from the first function come first, followed by the trailing ones
1051 // use offsets > 0 for function parameter mappings, and 0 for the return value of the function
inlinePostHookForwardingCall(Function * function,Function * postHookFunction,std::vector<unsigned> mapping,std::vector<Value * > trailingArgs)1052 void MagicUtil::inlinePostHookForwardingCall(Function* function, Function* postHookFunction, std::vector<unsigned> mapping, std::vector<Value*> trailingArgs)
1053 {
1054 std::vector<CallInst*> wrapperCalls;
1055 assert(postHookFunction->arg_size() == mapping.size() + trailingArgs.size()
1056 && "The number of parameter values specified for the post-hook function does not match the signature of the function.");
1057
1058 for (Function::iterator BI = function->getBasicBlockList().begin(); BI != function->getBasicBlockList().end(); ++BI) {
1059 ReturnInst *RetInst = dyn_cast<ReturnInst>(BI->getTerminator());
1060 if (RetInst) {
1061 std::vector<Value*> callArgs;
1062 for (std::vector<unsigned>::iterator it = mapping.begin(); it != mapping.end(); it++) {
1063 if (*it > 0) {
1064 callArgs.push_back(MagicUtil::getFunctionParam(function, *it - 1));
1065 } else {
1066 callArgs.push_back(RetInst->getReturnValue());
1067 }
1068 }
1069 for (std::vector<Value*>::iterator it = trailingArgs.begin(); it != trailingArgs.end(); it++) {
1070 callArgs.push_back(*it);
1071 }
1072 for (unsigned i = 0; i < callArgs.size(); i++) {
1073 TYPECONST Type* ArgType = callArgs[i]->getType();
1074 TYPECONST Type* ParamType = postHookFunction->getFunctionType()->getParamType(i);
1075
1076 if (!MagicUtil::isCompatibleType(ArgType, ParamType)) {
1077 assert(CastInst::isCastable(ArgType, ParamType) && "The value of the argument cannot be "
1078 "casted to the parameter type required by the function to be called.");
1079 Instruction::CastOps CastOpCode = CastInst::getCastOpcode(callArgs[i], false, ParamType, false);
1080 callArgs[i] = CastInst::Create(CastOpCode, callArgs[i], ParamType, "", RetInst);
1081 }
1082 }
1083 CallInst* WrapperFuncCall = MagicUtil::createCallInstruction(postHookFunction, callArgs, "", RetInst);
1084 wrapperCalls.push_back(WrapperFuncCall);
1085 }
1086 }
1087 for (std::vector<CallInst*>::iterator it = wrapperCalls.begin(); it != wrapperCalls.end(); ++it) {
1088 InlineFunctionInfo IFI;
1089 InlineFunction(*it, IFI);
1090 }
1091 }
1092
getPointerIndirectionLevel(const Type * type)1093 int MagicUtil::getPointerIndirectionLevel(const Type* type)
1094 {
1095 int level = 0;
1096 if (const PointerType* ptr_type = dyn_cast<PointerType>(type)) {
1097 while (ptr_type) {
1098 level++;
1099 ptr_type = dyn_cast<PointerType>(ptr_type->getElementType());
1100 }
1101 }
1102
1103 return level;
1104 }
1105
getFunctionParam(Function * function,unsigned index)1106 Value* MagicUtil::getFunctionParam(Function* function, unsigned index)
1107 {
1108 if (index >= function->arg_size()) {
1109 return NULL;
1110 }
1111 Function::arg_iterator AI = function->arg_begin();
1112 while (index --> 0) {
1113 AI++;
1114 }
1115 return AI;
1116 }
1117
isLocalConstant(Module & M,GlobalVariable * GV)1118 bool MagicUtil::isLocalConstant(Module &M, GlobalVariable *GV)
1119 {
1120 if (!GV->isConstant()) {
1121 return false;
1122 }
1123 if (GV->getName().endswith(".v")) {
1124 return true;
1125 }
1126 std::pair<StringRef, StringRef> stringPair = GV->getName().split('.');
1127 StringRef functionName = stringPair.first;
1128 if (!functionName.compare("") || M.getFunction(functionName) == NULL) {
1129 return false;
1130 }
1131
1132 return true;
1133 }
1134
1135 }
1136