1 #ifndef MAGIC_MEM_FUNCTION_H 2 #define MAGIC_MEM_FUNCTION_H 3 4 #include <pass.h> 5 #include <magic/support/TypeInfo.h> 6 7 #define NUM_MAGIC_ARGS 3 8 9 using namespace llvm; 10 11 namespace llvm { 12 13 class MagicMemFunction { 14 public: 15 MagicMemFunction(Module &M, Function *function, Function *wrapper, bool isDealloc, bool isNested, int allocFlags); 16 17 Function* getFunction() const; 18 Function* getWrapper() const; 19 bool isDeallocFunction() const; 20 bool isNestedFunction() const; 21 int getAllocFlags() const; 22 Instruction* getInstruction() const; 23 Function* getInstructionParent() const; 24 TypeInfo* getInstructionTypeInfo() const; 25 Value* getInstructionTypeValue() const; 26 bool hasInstructionType() const; 27 std::vector<MagicMemFunction> getInstructionDeps() const; 28 29 void setInstruction(Instruction* I); 30 void setInstructionTypeInfo(TypeInfo* aTypeInfo, std::string &allocName, std::string &allocParentName); 31 void setInstructionTypeValue(Value* typeValue, Value* allocNameValue, Value* allocParentNameValue); 32 void addInstructionDep(MagicMemFunction &function); 33 void replaceInstruction(std::map<TypeInfo*, Constant*> &magicArrayTypePtrMap, TypeInfo *voidPtrTypeInfo); 34 35 void print(raw_ostream &OS) const; 36 void printDescription(raw_ostream &OS) const; 37 const std::string getDescription() const; 38 39 static int getMemFunctionPointerParam(Function* function, std::set<Function*> &brkFunctions, TypeInfo *voidPtrTypeInfo); 40 static Function* getCustomWrapper(Function* function, Function* stdFunction, Function* stdWrapper, std::vector<unsigned> argMapping, 41 bool isDealloc); 42 static bool isCustomWrapper(Function *function); 43 44 private: 45 Module *module; 46 Function *function; 47 Function *wrapper; 48 bool isDealloc; 49 bool isNested; 50 int allocFlags; 51 Instruction *instruction; 52 TypeInfo* aTypeInfo; 53 std::string allocName; 54 std::string allocParentName; 55 Value* typeValue; 56 Value* allocNameValue; 57 Value* allocParentNameValue; 58 std::vector<MagicMemFunction> instructionDeps; 59 60 void buildWrapper(std::map<TypeInfo*, Constant*> &magicArrayTypePtrMap, TypeInfo *voidPtrTypeInfo); 61 62 static Function *lastAllocWrapper; 63 static std::map<std::string, Function*> allocWrapperCache; 64 static std::set<Function*> customWrapperSet; 65 }; 66 67 inline raw_ostream &operator<<(raw_ostream &OS, const MagicMemFunction &aMagicMemFunction) { 68 aMagicMemFunction.print(OS); 69 return OS; 70 } 71 72 inline void MagicMemFunction::print(raw_ostream &OS) const { 73 OS << getDescription(); 74 } 75 76 inline void MagicMemFunction::printDescription(raw_ostream &OS) const { 77 OS << "[ function = "; 78 OS << function->getName() << "(" << TypeUtil::getDescription(function->getFunctionType()) << ")"; 79 OS << ", wrapper = "; 80 if (wrapper) { 81 OS << wrapper->getName() << "(" << TypeUtil::getDescription(wrapper->getFunctionType()) << ")"; 82 } else 83 OS << "NULL"; 84 OS << ", isDeallocFunction = "; 85 OS << isDealloc; 86 OS << ", isNestedFunction = "; 87 OS << isNested; 88 OS << ", instruction = "; 89 if (instruction) 90 instruction->print(OS); 91 else 92 OS << "NULL"; 93 OS << ", typeInfo = "; 94 if (aTypeInfo) 95 OS << aTypeInfo->getDescription(); 96 else 97 OS << "NULL"; 98 OS << ", allocName = "; 99 OS << allocName; 100 OS << ", allocParentName = "; 101 OS << allocParentName; 102 OS << ", typeValue = "; 103 if (typeValue) 104 typeValue->print(OS); 105 else 106 OS << "NULL"; 107 OS << ", allocNameValue = "; 108 if (allocNameValue) 109 allocNameValue->print(OS); 110 else 111 OS << "NULL"; 112 OS << ", allocParentNameValue = "; 113 if (allocParentNameValue) 114 allocParentNameValue->print(OS); 115 else 116 OS << "NULL"; 117 OS << ", instructionDeps = {"; 118 for (unsigned i = 0; i < instructionDeps.size(); i++) { 119 if (i > 0) { 120 OS << ", "; 121 } 122 instructionDeps[i].print(OS); 123 } 124 OS << "}]"; 125 } 126 127 inline const std::string MagicMemFunction::getDescription() const { 128 std::string string; 129 raw_string_ostream ostream(string); 130 printDescription(ostream); 131 ostream.flush(); 132 return string; 133 } 134 135 inline MagicMemFunction::MagicMemFunction(Module &M, Function *function, Function *wrapper, bool isDealloc, bool isNested, int allocFlags) { 136 this->module = &M; 137 this->function = function; 138 this->wrapper = wrapper; 139 this->isDealloc = isDealloc; 140 this->isNested = isNested; 141 this->allocFlags = allocFlags; 142 this->instruction = NULL; 143 this->aTypeInfo = NULL; 144 this->allocName = ""; 145 this->allocParentName = ""; 146 this->typeValue = NULL; 147 this->allocNameValue = NULL; 148 this->allocParentNameValue = NULL; 149 assert(function); 150 if (wrapper && !isDealloc && !isNested) { 151 lastAllocWrapper = wrapper; 152 } 153 if (isDealloc) { 154 assert(!allocFlags); 155 } 156 } 157 158 inline Function* MagicMemFunction::getFunction() const { 159 return function; 160 } 161 162 inline Function* MagicMemFunction::getWrapper() const { 163 return wrapper; 164 } 165 166 inline bool MagicMemFunction::isDeallocFunction() const { 167 return isDealloc; 168 } 169 170 inline bool MagicMemFunction::isNestedFunction() const { 171 return isNested; 172 } 173 174 inline int MagicMemFunction::getAllocFlags() const { 175 return allocFlags; 176 } 177 178 inline Instruction* MagicMemFunction::getInstruction() const { 179 return instruction; 180 } 181 182 inline Function* MagicMemFunction::getInstructionParent() const { 183 if (!instruction) { 184 return NULL; 185 } 186 return instruction->getParent()->getParent(); 187 } 188 189 inline TypeInfo* MagicMemFunction::getInstructionTypeInfo() const { 190 return aTypeInfo; 191 } 192 193 inline Value* MagicMemFunction::getInstructionTypeValue() const { 194 return typeValue; 195 } 196 197 inline bool MagicMemFunction::hasInstructionType() const { 198 return aTypeInfo || typeValue; 199 } 200 201 inline std::vector<MagicMemFunction> MagicMemFunction::getInstructionDeps() const { 202 return instructionDeps; 203 } 204 205 inline void MagicMemFunction::setInstruction(Instruction* I) { 206 this->instruction = I; 207 assert(isa<CallInst>(instruction) || isa<InvokeInst>(instruction)); 208 } 209 210 inline void MagicMemFunction::setInstructionTypeInfo(TypeInfo* aTypeInfo, std::string &allocName, std::string &allocParentName) { 211 this->aTypeInfo = aTypeInfo; 212 this->allocName = allocName; 213 this->allocParentName = allocParentName; 214 } 215 216 inline void MagicMemFunction::setInstructionTypeValue(Value* typeValue, Value* allocNameValue, Value* allocParentNameValue) { 217 this->typeValue = typeValue; 218 this->allocNameValue = allocNameValue; 219 this->allocParentNameValue = allocParentNameValue; 220 } 221 222 inline void MagicMemFunction::addInstructionDep(MagicMemFunction &function) { 223 assert(wrapper == NULL && "Dependencies are resolved at wrapper building time, so wrapper has to be NULL!"); 224 instructionDeps.push_back(function); 225 allocFlags |= function.getAllocFlags(); 226 } 227 228 inline void MagicMemFunction::replaceInstruction(std::map<TypeInfo*, Constant*> &magicArrayTypePtrMap, TypeInfo *voidPtrTypeInfo) { 229 Instruction *I = getInstruction(); 230 assert(I); 231 CallSite CS = MagicUtil::getCallSiteFromInstruction(I); 232 std::vector<Value*> magicMemArgs; 233 unsigned numMagicArgs = 0; 234 //if we do not have a wrapper, build one 235 if (!wrapper) { 236 buildWrapper(magicArrayTypePtrMap, voidPtrTypeInfo); 237 } 238 //inject magic args 239 if (!isDeallocFunction() && !isNestedFunction()) { 240 std::map<TypeInfo*, Constant*>::iterator it; 241 if (!typeValue) { 242 assert(aTypeInfo); 243 if (aTypeInfo == voidPtrTypeInfo->getContainedType(0)) { 244 typeValue = ConstantPointerNull::get((TYPECONST PointerType*) (wrapper->arg_begin()->getType())); 245 } else { 246 it = magicArrayTypePtrMap.find(aTypeInfo); 247 assert(it != magicArrayTypePtrMap.end()); 248 typeValue = it->second; 249 } 250 assert(allocName.compare("")); 251 assert(allocParentName.compare("")); 252 allocNameValue = MagicUtil::getArrayPtr(*module, MagicUtil::getStringRef(*module, allocName)); 253 allocParentNameValue = MagicUtil::getArrayPtr(*module, MagicUtil::getStringRef(*module, allocParentName)); 254 } 255 magicMemArgs.push_back(typeValue); 256 magicMemArgs.push_back(allocNameValue); 257 magicMemArgs.push_back(allocParentNameValue); 258 numMagicArgs = NUM_MAGIC_ARGS; 259 } 260 //push other args 261 unsigned arg_size = MagicUtil::getCalledFunctionFromCS(CS)->getFunctionType()->getNumContainedTypes() - 1; 262 for (unsigned i = 0; i < arg_size; i++) { 263 Value *arg = CS.getArgument(i); 264 TYPECONST Type* wArgType = wrapper->getFunctionType()->getContainedType(i + numMagicArgs + 1); 265 if (arg->getType() != wArgType) { 266 if (arg->getType()->isPointerTy()) { 267 assert(wArgType->isPointerTy()); 268 arg = CastInst::CreatePointerCast(arg, wArgType, "WrapperCast", I); 269 } 270 else { 271 assert(arg->getType()->isIntegerTy()); 272 assert(wArgType->isIntegerTy()); 273 arg = CastInst::CreateIntegerCast(arg, wArgType, false, "WrapperCast", I); 274 } 275 } 276 magicMemArgs.push_back(arg); 277 } 278 //replace function with wrapper 279 CallInst* newInst = MagicUtil::createCallInstruction(wrapper, magicMemArgs, "", I); 280 newInst->takeName(I); 281 MagicUtil::replaceCallInst(I, newInst, NUM_MAGIC_ARGS); 282 } 283 284 inline int MagicMemFunction::getMemFunctionPointerParam(Function* function, std::set<Function*> &brkFunctions, TypeInfo *voidPtrTypeInfo) { 285 TYPECONST Type *type = function->getReturnType(); 286 if (type == voidPtrTypeInfo->getType()) { 287 return 0; 288 } else if (brkFunctions.find(function) != brkFunctions.end()) { 289 return 1; 290 } else { 291 unsigned i; 292 for (i = 1; i < function->getFunctionType()->getNumContainedTypes(); i++) { 293 type = function->getFunctionType()->getContainedType(i); 294 if (type->isPointerTy() && type->getContainedType(0) == voidPtrTypeInfo->getType()) { 295 return i; 296 } 297 } 298 } 299 300 return -1; 301 } 302 303 inline void MagicMemFunction::buildWrapper(std::map<TypeInfo*, Constant*> &magicArrayTypePtrMap, TypeInfo *voidPtrTypeInfo) { 304 assert(!isDeallocFunction()); 305 assert(!isNestedFunction()); 306 assert(lastAllocWrapper); 307 std::vector<TYPECONST Type*> ArgTypes; 308 VALUE_TO_VALUE_MAP_TY VMap; 309 310 std::map<std::string, Function*>::iterator allocWrapperCacheIt; 311 312 // See if the wrapper is in cache, otherwise create a new wrapper using function cloning 313 allocWrapperCacheIt = allocWrapperCache.find(function->getName()); 314 if (allocWrapperCacheIt != allocWrapperCache.end()) { 315 wrapper = allocWrapperCacheIt->second; 316 return; 317 } 318 319 // Build arg types for wrapper 320 Function::const_arg_iterator E = lastAllocWrapper->arg_begin(); 321 for (unsigned i = 0; i < NUM_MAGIC_ARGS; i++) 322 E++; 323 for (Function::const_arg_iterator I = lastAllocWrapper->arg_begin(); I != E; ++I) 324 ArgTypes.push_back(I->getType()); 325 E = function->arg_end(); 326 for (Function::const_arg_iterator I = function->arg_begin(); I != E; ++I) 327 ArgTypes.push_back(I->getType()); 328 329 // Create a new function type... 330 FunctionType *FTy = FunctionType::get(function->getFunctionType()->getReturnType(), ArgTypes, function->getFunctionType()->isVarArg()); 331 332 // Create the wrapper 333 wrapper = Function::Create(FTy, function->getLinkage(), "magic_" + function->getName(), function->getParent()); 334 335 // Loop over the arguments, copying the names of the mapped arguments over... 336 Function::arg_iterator DestI = wrapper->arg_begin(); 337 Value *magicTypeValue = DestI; 338 magicTypeValue->setName("magic_type"); 339 DestI++; 340 Value *magicNameValue = DestI; 341 magicNameValue->setName("magic_name"); 342 DestI++; 343 Value *magicParentNameValue = DestI; 344 magicParentNameValue->setName("magic_parent_name"); 345 DestI++; 346 for (Function::const_arg_iterator I = function->arg_begin(), E = function->arg_end(); I != E; ++I) { 347 DestI->setName(I->getName()); 348 VMap[I] = DestI++; 349 } 350 351 SmallVector<ReturnInst*, 8> Returns; // Ignore returns cloned... 352 CloneFunctionInto(wrapper, function, VMap, false, Returns, "", NULL); 353 354 allocWrapperCache.insert(std::pair<std::string, Function*>(function->getName(), wrapper)); 355 356 // Create a mapping between the function instruction pointers and the wrapper instruction pointers 357 std::vector<Instruction *> wrapperInstructionDeps; 358 for (unsigned i = 0; i < instructionDeps.size(); i++) { 359 Instruction *instruction = instructionDeps[i].getInstruction(); 360 Instruction *wrapperInstruction = NULL; 361 unsigned instructionOffset = 0; 362 for (inst_iterator I = inst_begin(function), E = inst_end(function); I != E; ++I, instructionOffset++) { 363 if (instruction == &(*I)) { 364 break; 365 } 366 } 367 assert(instructionOffset > 0); 368 for (inst_iterator I = inst_begin(wrapper), E = inst_end(wrapper); I != E; ++I, instructionOffset--) { 369 if (instructionOffset == 0) { 370 wrapperInstruction = &(*I); 371 break; 372 } 373 } 374 assert(wrapperInstruction); 375 wrapperInstructionDeps.push_back(wrapperInstruction); 376 } 377 378 // Forward magic type argument to any dependent instruction and replace it 379 for (unsigned i = 0; i < wrapperInstructionDeps.size(); i++) { 380 instructionDeps[i].setInstruction(wrapperInstructionDeps[i]); 381 instructionDeps[i].setInstructionTypeValue(magicTypeValue, magicNameValue, magicParentNameValue); 382 instructionDeps[i].replaceInstruction(magicArrayTypePtrMap, voidPtrTypeInfo); 383 } 384 } 385 386 inline Function* MagicMemFunction::getCustomWrapper(Function* function, Function* stdFunction, Function* stdWrapper, std::vector<unsigned> argMapping, 387 bool isDealloc) { 388 Function* wrapper; 389 std::vector<TYPECONST Type*> ArgTypes; 390 VALUE_TO_VALUE_MAP_TY VMap; 391 392 // Build arg types for wrapper 393 // add magic arguments 394 if (!isDealloc) { 395 Function::const_arg_iterator E = stdWrapper->arg_begin(); 396 for (unsigned i = 0; i < NUM_MAGIC_ARGS; i++) 397 E++; 398 for (Function::const_arg_iterator I = stdWrapper->arg_begin(); I != E; ++I) { 399 ArgTypes.push_back(I->getType()); 400 } 401 } 402 // add original function arguments 403 for (Function::const_arg_iterator I = function->arg_begin(), E = function->arg_end(); I != E; ++I) { 404 ArgTypes.push_back(I->getType()); 405 } 406 407 // Create a new function type... 408 FunctionType *FTy = FunctionType::get(stdWrapper->getFunctionType()->getReturnType(), ArgTypes, function->getFunctionType()->isVarArg()); 409 410 // Create the wrapper 411 wrapper = Function::Create(FTy, function->getLinkage(), "magic_" + function->getName(), function->getParent()); 412 413 // Loop over the arguments, copying the names of the mapped arguments over... 414 Function::arg_iterator DestI = wrapper->arg_begin(); 415 std::vector<Value*> wrapperArgs; 416 if (!isDealloc) { 417 std::string magicArgs[] = { "magic_type", "magic_name", "magic_parent_name" }; 418 for (unsigned i = 0; i < NUM_MAGIC_ARGS; i++) { 419 DestI->setName(magicArgs[i]); 420 wrapperArgs.push_back(DestI); 421 DestI++; 422 } 423 } 424 for (Function::const_arg_iterator I = function->arg_begin(), E = function->arg_end(); I != E; ++I) { 425 DestI->setName(I->getName()); 426 wrapperArgs.push_back(DestI); 427 DestI++; 428 } 429 430 // map the arguments of the standard wrapper to the arguments of the new custom wrapper 431 if ((!isDealloc) || argMapping.size()) { 432 Function::const_arg_iterator W = stdWrapper->arg_begin(); 433 if (!isDealloc) { 434 // magic arguments are in the same position 435 for (unsigned i = 0; i < NUM_MAGIC_ARGS; i++) { 436 VMap[W] = wrapperArgs[i]; 437 W++; 438 } 439 } 440 // map the selected arguments of the custom wrapper using the mapping provided as input 441 unsigned argOffset = isDealloc ? 0 : NUM_MAGIC_ARGS; 442 for (unsigned i = 0; i < argMapping.size(); i++) { 443 VMap[W] = wrapperArgs[argOffset + argMapping[i] - 1]; 444 W++; 445 } 446 } 447 448 SmallVector<ReturnInst*, 8> Returns; // Ignore returns cloned... 449 CloneFunctionInto(wrapper, stdWrapper, VMap, false, Returns, "", NULL); 450 451 // check whether some of the arguments of the custom wrapper need to be casted 452 // in order to match the basic wrapper implementation 453 Instruction *FirstInst = MagicUtil::getFirstNonAllocaInst(wrapper); 454 Function::const_arg_iterator W = stdWrapper->arg_begin(); 455 unsigned argOffset = 0; 456 if (!isDealloc) { 457 argOffset = NUM_MAGIC_ARGS; 458 // skip the magic arguments, they are always the same 459 for (unsigned i = 0; i < NUM_MAGIC_ARGS; i++) { 460 W++; 461 } 462 } 463 for (unsigned i = 0; i < argMapping.size(); i++) { 464 TYPECONST Type* StdParamType = W->getType(); 465 Value* ParamValue = wrapperArgs[argOffset + argMapping[i] - 1]; 466 TYPECONST Type* ParamType = ParamValue->getType(); 467 if (!MagicUtil::isCompatibleType(ParamType, StdParamType)) { 468 assert(CastInst::isCastable(ParamType, StdParamType) && "The type of the parameter of the custom wrapper " 469 "cannot be casted to the type of the basic wrapper to which it is corresponding."); 470 Instruction::CastOps CastOpCode = CastInst::getCastOpcode(ParamValue, false, StdParamType, false); 471 Instruction *ParamCastInst = CastInst::Create(CastOpCode, ParamValue, StdParamType, "", FirstInst); 472 473 for (Value::use_iterator it = ParamValue->use_begin(); it != ParamValue->use_end(); it++) { 474 if (Constant * C = dyn_cast<Constant>(*it)) { 475 if (!isa<GlobalValue>(C)) { 476 C->replaceUsesOfWith(ParamValue, ParamCastInst); 477 continue; 478 } 479 } 480 Instruction *I = dyn_cast<Instruction>(*it); 481 if (I && (I != ParamCastInst)) { 482 // replace all uses, except for the calls to the wrapped function 483 CallInst *CI = dyn_cast<CallInst>(I); 484 if (CI && (CI->getCalledFunction() == function)) { 485 continue; 486 } 487 I->replaceUsesOfWith(ParamValue, ParamCastInst); 488 } 489 } 490 } 491 W++; 492 } 493 494 // replace the call(s) to the standard function with calls to our function 495 for (Function::iterator BI = wrapper->getBasicBlockList().begin(), BE = wrapper->getBasicBlockList().end(); BI != BE; ++BI) { 496 unsigned pos = 0; 497 unsigned bbSize = BI->getInstList().size(); 498 while (pos < bbSize) { 499 BasicBlock::iterator it = BI->getInstList().begin(); 500 for (unsigned i = 0; i < pos; i++) { 501 it++; 502 } 503 Instruction *inst = &(*it); 504 // find the calls to the standard function 505 CallInst *callInst = dyn_cast<CallInst>(inst); 506 if (callInst && callInst->getCalledFunction() && (callInst->getCalledFunction()->getFunctionType() == stdFunction->getFunctionType()) 507 && (!callInst->getCalledFunction()->getName().compare(stdFunction->getName()))) { 508 CallSite CS = MagicUtil::getCallSiteFromInstruction(callInst); 509 unsigned numStdParams = stdFunction->getFunctionType()->getNumParams(); 510 unsigned numParams = function->getFunctionType()->getNumParams(); 511 // construct the parameter array 512 std::vector<Value*> callArgs(numParams, NULL); 513 // first add the arguments that are common to the custom and standard function 514 // add casts where necessary 515 for (unsigned i = 0; i < numStdParams; i++) { 516 Value *argValue = CS.getArgument(i); 517 TYPECONST Type* paramType = function->getFunctionType()->getParamType(i); 518 TYPECONST Type* argType = argValue->getType(); 519 if (paramType != argType) { 520 assert(CastInst::isCastable(argType, paramType) && "The value of the argument cannot be " 521 "casted to the parameter type required by the function to be called."); 522 Instruction::CastOps opcode = CastInst::getCastOpcode(argValue, false, paramType, false); 523 argValue = CastInst::Create(opcode, argValue, paramType, "", callInst); 524 } 525 callArgs[argMapping[i] - 1] = argValue; 526 } 527 // the other arguments are just forwarded from the wrapper's argument list 528 // skip the magic arguments of the wrapper from the beginning of the argument list 529 unsigned argOffset = isDealloc ? 0 : NUM_MAGIC_ARGS; 530 for (unsigned i = argOffset; i < wrapper->getFunctionType()->getNumParams(); i++) { 531 if (callArgs[i - argOffset] == NULL) { 532 Value* arg = wrapperArgs[i]; 533 callArgs[i - argOffset] = arg; 534 } 535 } 536 537 CallInst* newCallInst = MagicUtil::createCallInstruction(function, callArgs, "", callInst); 538 newCallInst->takeName(callInst); 539 MagicUtil::replaceCallInst(callInst, newCallInst, argOffset); 540 } 541 pos++; 542 } 543 } 544 545 customWrapperSet.insert(wrapper); 546 return wrapper; 547 } 548 549 inline bool MagicMemFunction::isCustomWrapper(Function *function) 550 { 551 return customWrapperSet.find(function) != customWrapperSet.end(); 552 } 553 554 } 555 556 #endif 557 558