13e457fe3SDavid van Moolenbroek #include <magic/support/MagicUtil.h>
23e457fe3SDavid van Moolenbroek
33e457fe3SDavid van Moolenbroek using namespace llvm;
43e457fe3SDavid van Moolenbroek
53e457fe3SDavid van Moolenbroek namespace llvm {
63e457fe3SDavid van Moolenbroek
73e457fe3SDavid van Moolenbroek //===----------------------------------------------------------------------===//
83e457fe3SDavid van Moolenbroek // Public static methods
93e457fe3SDavid van Moolenbroek //===----------------------------------------------------------------------===//
103e457fe3SDavid van Moolenbroek
113e457fe3SDavid van Moolenbroek static std::map<const std::string, GlobalVariable*> stringRefCache;
123e457fe3SDavid van Moolenbroek
getLabelHash(std::string label)133e457fe3SDavid van Moolenbroek unsigned getLabelHash(std::string label) {
143e457fe3SDavid van Moolenbroek unsigned hash = 0;
153e457fe3SDavid van Moolenbroek for(unsigned i=0;i<label.length();i++){
163e457fe3SDavid van Moolenbroek hash ^= (label[i]);
173e457fe3SDavid van Moolenbroek hash = (hash << 9) | (hash >> ((sizeof(unsigned)*8)-9));
183e457fe3SDavid van Moolenbroek }
193e457fe3SDavid van Moolenbroek return hash;
203e457fe3SDavid van Moolenbroek }
213e457fe3SDavid van Moolenbroek
getModuleHash(DIDescriptor DID,const std::string & baseDir,StringRef extraField="")223e457fe3SDavid van Moolenbroek unsigned getModuleHash(DIDescriptor DID, const std::string &baseDir, StringRef extraField="") {
233e457fe3SDavid van Moolenbroek std::string relPath;
243e457fe3SDavid van Moolenbroek PassUtil::getDbgLocationInfo(DID, baseDir, NULL, NULL, &relPath);
253e457fe3SDavid van Moolenbroek return getLabelHash(relPath + "/" + extraField.data());
263e457fe3SDavid van Moolenbroek }
273e457fe3SDavid van Moolenbroek
getGVSourceName(Module & M,GlobalVariable * GV,DIGlobalVariable ** DIGVP,const std::string & baseDir)283e457fe3SDavid van Moolenbroek StringRef MagicUtil::getGVSourceName(Module &M, GlobalVariable *GV, DIGlobalVariable **DIGVP, const std::string &baseDir) {
293e457fe3SDavid van Moolenbroek static DIGlobalVariable Var;
30*bdb56518SDavid van Moolenbroek MDNode *DIGV = PassUtil::findDbgGlobalDeclare(GV);
313e457fe3SDavid van Moolenbroek if(DIGV) {
32*bdb56518SDavid van Moolenbroek Var = DIGlobalVariable(DIGV);
333e457fe3SDavid van Moolenbroek if(DIGVP) *DIGVP = &Var;
343e457fe3SDavid van Moolenbroek if(GV->getLinkage() == GlobalValue::InternalLinkage){
353e457fe3SDavid van Moolenbroek /* static variable */
363e457fe3SDavid van Moolenbroek StringRef funcName, countStr;
373e457fe3SDavid van Moolenbroek DIScope scope = Var.getContext();
383e457fe3SDavid van Moolenbroek if(scope.isLexicalBlock()){
393e457fe3SDavid van Moolenbroek /* find the subprogram that contains this basic block recursively */
403e457fe3SDavid van Moolenbroek while(!scope.isSubprogram()){
413e457fe3SDavid van Moolenbroek scope = DILexicalBlock(scope).getContext();
423e457fe3SDavid van Moolenbroek }
433e457fe3SDavid van Moolenbroek }
443e457fe3SDavid van Moolenbroek if(scope.isSubprogram()){
453e457fe3SDavid van Moolenbroek /* static function variable */
463e457fe3SDavid van Moolenbroek
473e457fe3SDavid van Moolenbroek funcName = DISubprogram(scope).getName();
483e457fe3SDavid van Moolenbroek
493e457fe3SDavid van Moolenbroek int count=0;
503e457fe3SDavid van Moolenbroek Module::GlobalListType &globalList = M.getGlobalList();
513e457fe3SDavid van Moolenbroek for (Module::global_iterator it = globalList.begin(); it != globalList.end(); ++it) {
523e457fe3SDavid van Moolenbroek GlobalVariable *OtherGV = &(*it);
53*bdb56518SDavid van Moolenbroek MDNode *OtherDIGV = PassUtil::findDbgGlobalDeclare(OtherGV);
543e457fe3SDavid van Moolenbroek if(OtherDIGV) {
55*bdb56518SDavid van Moolenbroek DIGlobalVariable OtherVar(OtherDIGV);
563e457fe3SDavid van Moolenbroek
573e457fe3SDavid van Moolenbroek DIScope otherScope = OtherVar.getContext();
583e457fe3SDavid van Moolenbroek if(otherScope.isLexicalBlock()){
593e457fe3SDavid van Moolenbroek /* find the subprogram that contains this basic block recursively */
603e457fe3SDavid van Moolenbroek while(!otherScope.isSubprogram()){
613e457fe3SDavid van Moolenbroek otherScope = DILexicalBlock(otherScope).getContext();
623e457fe3SDavid van Moolenbroek }
633e457fe3SDavid van Moolenbroek }
643e457fe3SDavid van Moolenbroek if(otherScope.isSubprogram()){
653e457fe3SDavid van Moolenbroek if(!strcmp(Var.getName().data(), OtherVar.getName().data())){
663e457fe3SDavid van Moolenbroek if(DIGV == OtherDIGV){
673e457fe3SDavid van Moolenbroek break;
683e457fe3SDavid van Moolenbroek }
693e457fe3SDavid van Moolenbroek count++;
703e457fe3SDavid van Moolenbroek }
713e457fe3SDavid van Moolenbroek }
723e457fe3SDavid van Moolenbroek }
733e457fe3SDavid van Moolenbroek }
743e457fe3SDavid van Moolenbroek
753e457fe3SDavid van Moolenbroek std::stringstream stm;
763e457fe3SDavid van Moolenbroek if(count > 0){
773e457fe3SDavid van Moolenbroek stm << "." << count;
783e457fe3SDavid van Moolenbroek }
793e457fe3SDavid van Moolenbroek countStr = StringRef(*new std::string(stm.str()));
803e457fe3SDavid van Moolenbroek
813e457fe3SDavid van Moolenbroek }else{
823e457fe3SDavid van Moolenbroek /* static global variable */
833e457fe3SDavid van Moolenbroek funcName = "";
843e457fe3SDavid van Moolenbroek countStr = "";
853e457fe3SDavid van Moolenbroek }
863e457fe3SDavid van Moolenbroek
873e457fe3SDavid van Moolenbroek std::stringstream stm;
883e457fe3SDavid van Moolenbroek stm << Var.getName().data() << "." << getModuleHash(Var, baseDir, funcName) << countStr.data();
893e457fe3SDavid van Moolenbroek return StringRef(*new std::string(stm.str()));
903e457fe3SDavid van Moolenbroek
913e457fe3SDavid van Moolenbroek }else{
923e457fe3SDavid van Moolenbroek /* global variable */
933e457fe3SDavid van Moolenbroek return Var.getName();
943e457fe3SDavid van Moolenbroek }
953e457fe3SDavid van Moolenbroek }else{
963e457fe3SDavid van Moolenbroek /* llvm .str variables and assembly */
973e457fe3SDavid van Moolenbroek if(DIGVP) *DIGVP = NULL;
983e457fe3SDavid van Moolenbroek return GV->getName();
993e457fe3SDavid van Moolenbroek }
1003e457fe3SDavid van Moolenbroek }
1013e457fe3SDavid van Moolenbroek
getLVSourceName(Module & M,AllocaInst * V,DIVariable ** DIVP)1023e457fe3SDavid van Moolenbroek StringRef MagicUtil::getLVSourceName(Module &M, AllocaInst *V, DIVariable **DIVP) {
1033e457fe3SDavid van Moolenbroek static DIVariable Var;
104*bdb56518SDavid van Moolenbroek const DbgDeclareInst *DDI = FindAllocaDbgDeclare(V);
1053e457fe3SDavid van Moolenbroek if(DDI && DDI != (const DbgDeclareInst *) -1){
1063e457fe3SDavid van Moolenbroek Var = DIVariable(cast<MDNode>(DDI->getVariable()));
1073e457fe3SDavid van Moolenbroek if(DIVP) *DIVP = &Var;
1083e457fe3SDavid van Moolenbroek
1093e457fe3SDavid van Moolenbroek int count = 0;
1103e457fe3SDavid van Moolenbroek
1113e457fe3SDavid van Moolenbroek Function *F = V->getParent()->getParent();
1123e457fe3SDavid van Moolenbroek for (inst_iterator it = inst_begin(F), et = inst_end(F); it != et; ++it) {
1133e457fe3SDavid van Moolenbroek Instruction *inst = &(*it);
1143e457fe3SDavid van Moolenbroek if (DbgDeclareInst *OtherDDI = dyn_cast<DbgDeclareInst>(inst)){
1153e457fe3SDavid van Moolenbroek DIVariable otherVar(cast<MDNode>(OtherDDI->getVariable()));
1163e457fe3SDavid van Moolenbroek if(!strcmp(Var.getName().data(), otherVar.getName().data())){
1173e457fe3SDavid van Moolenbroek if(OtherDDI == DDI){
1183e457fe3SDavid van Moolenbroek break;
1193e457fe3SDavid van Moolenbroek }
1203e457fe3SDavid van Moolenbroek count++;
1213e457fe3SDavid van Moolenbroek }
1223e457fe3SDavid van Moolenbroek }
1233e457fe3SDavid van Moolenbroek }
1243e457fe3SDavid van Moolenbroek
1253e457fe3SDavid van Moolenbroek std::stringstream stm;
1263e457fe3SDavid van Moolenbroek stm << Var.getName().data();
1273e457fe3SDavid van Moolenbroek if(count > 0){
1283e457fe3SDavid van Moolenbroek stm << "." << count;
1293e457fe3SDavid van Moolenbroek }
1303e457fe3SDavid van Moolenbroek return StringRef(*new std::string(stm.str()));
1313e457fe3SDavid van Moolenbroek }else{
1323e457fe3SDavid van Moolenbroek if(DIVP) *DIVP = NULL;
1333e457fe3SDavid van Moolenbroek return V->getName();
1343e457fe3SDavid van Moolenbroek }
1353e457fe3SDavid van Moolenbroek }
1363e457fe3SDavid van Moolenbroek
getFunctionSourceName(Module & M,Function * F,DISubprogram ** DISP,const std::string & baseDir)1373e457fe3SDavid van Moolenbroek StringRef MagicUtil::getFunctionSourceName(Module &M, Function *F, DISubprogram **DISP, const std::string &baseDir) {
1383e457fe3SDavid van Moolenbroek static DISubprogram Func;
139*bdb56518SDavid van Moolenbroek MDNode *DIF = PassUtil::findDbgSubprogramDeclare(F);
1403e457fe3SDavid van Moolenbroek if(DIF) {
141*bdb56518SDavid van Moolenbroek Func = DISubprogram(DIF);
1423e457fe3SDavid van Moolenbroek if(DISP) *DISP = &Func;
1433e457fe3SDavid van Moolenbroek if(F->getLinkage() == GlobalValue::InternalLinkage){
1443e457fe3SDavid van Moolenbroek std::stringstream stm;
1453e457fe3SDavid van Moolenbroek stm << Func.getName().data() << "." << getModuleHash(Func, baseDir);
1463e457fe3SDavid van Moolenbroek return StringRef(*new std::string(stm.str()));
1473e457fe3SDavid van Moolenbroek }else{
1483e457fe3SDavid van Moolenbroek return Func.getName();
1493e457fe3SDavid van Moolenbroek }
1503e457fe3SDavid van Moolenbroek }else{
1513e457fe3SDavid van Moolenbroek /* assembly */
1523e457fe3SDavid van Moolenbroek if(DISP) *DISP = NULL;
1533e457fe3SDavid van Moolenbroek return F->getName();
1543e457fe3SDavid van Moolenbroek }
1553e457fe3SDavid van Moolenbroek }
1563e457fe3SDavid van Moolenbroek
putStringRefCache(Module & M,const std::string & str,GlobalVariable * GV)1573e457fe3SDavid van Moolenbroek void MagicUtil::putStringRefCache(Module &M, const std::string &str, GlobalVariable *GV) {
1583e457fe3SDavid van Moolenbroek std::map<const std::string, GlobalVariable*>::iterator it;
1593e457fe3SDavid van Moolenbroek it = stringRefCache.find(str);
1603e457fe3SDavid van Moolenbroek if(it == stringRefCache.end()) {
1613e457fe3SDavid van Moolenbroek stringRefCache.insert(std::pair<const std::string, GlobalVariable*>(str, GV));
1623e457fe3SDavid van Moolenbroek }
1633e457fe3SDavid van Moolenbroek }
1643e457fe3SDavid van Moolenbroek
getGetElementPtrConstant(Constant * constant,std::vector<Value * > & indexes)1653e457fe3SDavid van Moolenbroek Constant* MagicUtil::getGetElementPtrConstant(Constant *constant, std::vector<Value*> &indexes) {
1663e457fe3SDavid van Moolenbroek return PassUtil::getGetElementPtrConstant(constant, indexes);
1673e457fe3SDavid van Moolenbroek }
1683e457fe3SDavid van Moolenbroek
createGetElementPtrInstruction(Value * ptr,std::vector<Value * > & indexes,const Twine & NameStr,Instruction * InsertBefore)1693e457fe3SDavid van Moolenbroek GetElementPtrInst* MagicUtil::createGetElementPtrInstruction(Value *ptr, std::vector<Value*> &indexes, const Twine &NameStr, Instruction *InsertBefore) {
1703e457fe3SDavid van Moolenbroek return PassUtil::createGetElementPtrInstruction(ptr, indexes, NameStr, InsertBefore);
1713e457fe3SDavid van Moolenbroek }
1723e457fe3SDavid van Moolenbroek
createGetElementPtrInstruction(Value * ptr,std::vector<Value * > & indexes,const Twine & NameStr,BasicBlock * InsertAtEnd)1733e457fe3SDavid van Moolenbroek GetElementPtrInst* MagicUtil::createGetElementPtrInstruction(Value *ptr, std::vector<Value*> &indexes, const Twine &NameStr, BasicBlock *InsertAtEnd) {
1743e457fe3SDavid van Moolenbroek return PassUtil::createGetElementPtrInstruction(ptr, indexes, NameStr, InsertAtEnd);
1753e457fe3SDavid van Moolenbroek }
1763e457fe3SDavid van Moolenbroek
createCallInstruction(Value * F,std::vector<Value * > & args,const Twine & NameStr,Instruction * InsertBefore)1773e457fe3SDavid van Moolenbroek CallInst* MagicUtil::createCallInstruction(Value *F, std::vector<Value*> &args, const Twine &NameStr, Instruction *InsertBefore) {
1783e457fe3SDavid van Moolenbroek return PassUtil::createCallInstruction(F, args, NameStr, InsertBefore);
1793e457fe3SDavid van Moolenbroek }
1803e457fe3SDavid van Moolenbroek
createCallInstruction(Value * F,std::vector<Value * > & args,const Twine & NameStr,BasicBlock * InsertAtEnd)1813e457fe3SDavid van Moolenbroek CallInst* MagicUtil::createCallInstruction(Value *F, std::vector<Value*> &args, const Twine &NameStr, BasicBlock *InsertAtEnd) {
1823e457fe3SDavid van Moolenbroek return PassUtil::createCallInstruction(F, args, NameStr, InsertAtEnd);
1833e457fe3SDavid van Moolenbroek }
1843e457fe3SDavid van Moolenbroek
getIntrinsicFunction(Module & M,Intrinsic::ID id,TYPECONST Type ** types,unsigned size)1853e457fe3SDavid van Moolenbroek Function* MagicUtil::getIntrinsicFunction(Module &M, Intrinsic::ID id, TYPECONST Type** types, unsigned size) {
1863e457fe3SDavid van Moolenbroek return PassUtil::getIntrinsicFunction(M, id, types, size);
1873e457fe3SDavid van Moolenbroek }
1883e457fe3SDavid van Moolenbroek
getStringRef(Module & M,const std::string & str)1893e457fe3SDavid van Moolenbroek GlobalVariable *MagicUtil::getStringRef(Module &M, const std::string &str) {
1903e457fe3SDavid van Moolenbroek std::map<const std::string, GlobalVariable*>::iterator it;
1913e457fe3SDavid van Moolenbroek GlobalVariable *stringRef = NULL;
1923e457fe3SDavid van Moolenbroek bool debug = false;
1933e457fe3SDavid van Moolenbroek
1943e457fe3SDavid van Moolenbroek it = stringRefCache.find(str);
1953e457fe3SDavid van Moolenbroek if(it != stringRefCache.end()) {
1963e457fe3SDavid van Moolenbroek if(debug) magicUtilLog("*** getStringRef: cache hit for " << str);
1973e457fe3SDavid van Moolenbroek stringRef = it->second;
1983e457fe3SDavid van Moolenbroek }
1993e457fe3SDavid van Moolenbroek if(stringRef == NULL) {
2003e457fe3SDavid van Moolenbroek stringRef = PassUtil::getStringGlobalVariable(M, str, MAGIC_HIDDEN_STR_PREFIX, MAGIC_STATIC_VARS_SECTION_RO);
2013e457fe3SDavid van Moolenbroek stringRefCache.insert(std::pair<const std::string, GlobalVariable*>(str, stringRef));
2023e457fe3SDavid van Moolenbroek }
2033e457fe3SDavid van Moolenbroek
2043e457fe3SDavid van Moolenbroek return stringRef;
2053e457fe3SDavid van Moolenbroek }
2063e457fe3SDavid van Moolenbroek
2073e457fe3SDavid van Moolenbroek
getIntArrayRef(Module & M,unsigned arrSize,std::vector<int> * arr,bool isConstant)2083e457fe3SDavid van Moolenbroek GlobalVariable *MagicUtil::getIntArrayRef(Module &M, unsigned arrSize, std::vector<int> *arr, bool isConstant) {
2093e457fe3SDavid van Moolenbroek static std::map<std::vector<int>, GlobalVariable*> arrayRefCache;
2103e457fe3SDavid van Moolenbroek std::map<std::vector<int>, GlobalVariable*>::iterator it;
2113e457fe3SDavid van Moolenbroek static std::vector<int> defInitilizer;
2123e457fe3SDavid van Moolenbroek
2133e457fe3SDavid van Moolenbroek //construct an appropriate initializer if we do not have one
2143e457fe3SDavid van Moolenbroek if(!arr) {
2153e457fe3SDavid van Moolenbroek arr = &defInitilizer;
2163e457fe3SDavid van Moolenbroek arr->clear();
2173e457fe3SDavid van Moolenbroek for(unsigned i=0;i<arrSize;i++) arr->push_back(0);
2183e457fe3SDavid van Moolenbroek }
2193e457fe3SDavid van Moolenbroek assert(arrSize == arr->size());
2203e457fe3SDavid van Moolenbroek
2213e457fe3SDavid van Moolenbroek //cache lookup
2223e457fe3SDavid van Moolenbroek if(isConstant) {
2233e457fe3SDavid van Moolenbroek it = arrayRefCache.find(*arr);
2243e457fe3SDavid van Moolenbroek if(it != arrayRefCache.end()) {
2253e457fe3SDavid van Moolenbroek return it->second;
2263e457fe3SDavid van Moolenbroek }
2273e457fe3SDavid van Moolenbroek }
2283e457fe3SDavid van Moolenbroek
2293e457fe3SDavid van Moolenbroek //create a constant internal array reference
2303e457fe3SDavid van Moolenbroek std::vector<Constant*> arrayElems;
2313e457fe3SDavid van Moolenbroek for(unsigned i=0;i<arr->size();i++) {
2323e457fe3SDavid van Moolenbroek arrayElems.push_back(ConstantInt::get(M.getContext(), APInt(32, (*arr)[i], 10)));
2333e457fe3SDavid van Moolenbroek }
2343e457fe3SDavid van Moolenbroek ArrayType* arrayTy = ArrayType::get(IntegerType::get(M.getContext(), 32), arr->size());
2353e457fe3SDavid van Moolenbroek Constant *arrayValue = ConstantArray::get(arrayTy, arrayElems);
2363e457fe3SDavid van Moolenbroek
2373e457fe3SDavid van Moolenbroek //create the global variable and record it in the module
2383e457fe3SDavid van Moolenbroek GlobalVariable *arrayRef = new GlobalVariable(arrayValue->getType(), isConstant,
2393e457fe3SDavid van Moolenbroek GlobalValue::InternalLinkage, arrayValue,
2403e457fe3SDavid van Moolenbroek MAGIC_HIDDEN_ARRAY_PREFIX);
2413e457fe3SDavid van Moolenbroek MagicUtil::setGlobalVariableSection(arrayRef, isConstant ? MAGIC_STATIC_VARS_SECTION_RO : MAGIC_STATIC_VARS_SECTION_DATA);
2423e457fe3SDavid van Moolenbroek M.getGlobalList().push_back(arrayRef);
2433e457fe3SDavid van Moolenbroek
2443e457fe3SDavid van Moolenbroek //populate cache
2453e457fe3SDavid van Moolenbroek if(isConstant) {
2463e457fe3SDavid van Moolenbroek arrayRefCache.insert(std::pair<std::vector<int>, GlobalVariable*>(*arr, arrayRef));
2473e457fe3SDavid van Moolenbroek }
2483e457fe3SDavid van Moolenbroek
2493e457fe3SDavid van Moolenbroek return arrayRef;
2503e457fe3SDavid van Moolenbroek }
2513e457fe3SDavid van Moolenbroek
getStringArrayRef(Module & M,unsigned arrSize,std::vector<std::string> * arr,bool isConstant)2523e457fe3SDavid van Moolenbroek GlobalVariable *MagicUtil::getStringArrayRef(Module &M, unsigned arrSize, std::vector<std::string> *arr, bool isConstant) {
2533e457fe3SDavid van Moolenbroek static std::map<std::vector<std::string>, GlobalVariable*> arrayRefCache;
2543e457fe3SDavid van Moolenbroek std::map<std::vector<std::string>, GlobalVariable*>::iterator it;
2553e457fe3SDavid van Moolenbroek static std::vector<std::string> defInitilizer;
2563e457fe3SDavid van Moolenbroek //construct an appropriate initializer if we do not have one
2573e457fe3SDavid van Moolenbroek if(!arr) {
2583e457fe3SDavid van Moolenbroek arr = &defInitilizer;
2593e457fe3SDavid van Moolenbroek arr->clear();
2603e457fe3SDavid van Moolenbroek for(unsigned i=0;i<arrSize;i++) arr->push_back("");
2613e457fe3SDavid van Moolenbroek }
2623e457fe3SDavid van Moolenbroek assert(arrSize == arr->size());
2633e457fe3SDavid van Moolenbroek
2643e457fe3SDavid van Moolenbroek //cache lookup
2653e457fe3SDavid van Moolenbroek if(isConstant) {
2663e457fe3SDavid van Moolenbroek it = arrayRefCache.find(*arr);
2673e457fe3SDavid van Moolenbroek if(it != arrayRefCache.end()) {
2683e457fe3SDavid van Moolenbroek return it->second;
2693e457fe3SDavid van Moolenbroek }
2703e457fe3SDavid van Moolenbroek }
2713e457fe3SDavid van Moolenbroek
2723e457fe3SDavid van Moolenbroek //create a constant internal array reference
2733e457fe3SDavid van Moolenbroek std::vector<Constant*> arrayElems;
2743e457fe3SDavid van Moolenbroek std::vector<Value*> arrayIndexes;
2753e457fe3SDavid van Moolenbroek arrayIndexes.push_back(ConstantInt::get(M.getContext(), APInt(32, 0, 10)));
2763e457fe3SDavid van Moolenbroek arrayIndexes.push_back(ConstantInt::get(M.getContext(), APInt(32, 0, 10)));
2773e457fe3SDavid van Moolenbroek for(unsigned i=0;i<arr->size();i++) {
2783e457fe3SDavid van Moolenbroek arrayElems.push_back(getGetElementPtrConstant(getStringRef(M, (*arr)[i]), arrayIndexes));
2793e457fe3SDavid van Moolenbroek }
2803e457fe3SDavid van Moolenbroek ArrayType* arrayTy = ArrayType::get(PointerType::get(IntegerType::get(M.getContext(), 8), 0), arr->size());
2813e457fe3SDavid van Moolenbroek Constant *arrayValue = ConstantArray::get(arrayTy, arrayElems);
2823e457fe3SDavid van Moolenbroek
2833e457fe3SDavid van Moolenbroek //create the global variable and record it in the module
2843e457fe3SDavid van Moolenbroek GlobalVariable *arrayRef = new GlobalVariable(arrayValue->getType(), isConstant,
2853e457fe3SDavid van Moolenbroek GlobalValue::InternalLinkage, arrayValue,
2863e457fe3SDavid van Moolenbroek MAGIC_HIDDEN_ARRAY_PREFIX);
2873e457fe3SDavid van Moolenbroek MagicUtil::setGlobalVariableSection(arrayRef, isConstant ? MAGIC_STATIC_VARS_SECTION_RO : MAGIC_STATIC_VARS_SECTION_DATA);
2883e457fe3SDavid van Moolenbroek M.getGlobalList().push_back(arrayRef);
2893e457fe3SDavid van Moolenbroek
2903e457fe3SDavid van Moolenbroek //populate cache
2913e457fe3SDavid van Moolenbroek if(isConstant) {
2923e457fe3SDavid van Moolenbroek arrayRefCache.insert(std::pair<std::vector<std::string>, GlobalVariable*>(*arr, arrayRef));
2933e457fe3SDavid van Moolenbroek }
2943e457fe3SDavid van Moolenbroek
2953e457fe3SDavid van Moolenbroek return arrayRef;
2963e457fe3SDavid van Moolenbroek }
2973e457fe3SDavid van Moolenbroek
getGenericArrayRef(Module & M,std::vector<Constant * > & arrayElems,bool isConstant)2983e457fe3SDavid van Moolenbroek GlobalVariable *MagicUtil::getGenericArrayRef(Module &M, std::vector<Constant*> &arrayElems, bool isConstant) {
2993e457fe3SDavid van Moolenbroek static std::map<std::vector<Constant*>, GlobalVariable*> arrayRefCache;
3003e457fe3SDavid van Moolenbroek std::map<std::vector<Constant*>, GlobalVariable*>::iterator it;
3013e457fe3SDavid van Moolenbroek assert(arrayElems.size() > 0);
3023e457fe3SDavid van Moolenbroek
3033e457fe3SDavid van Moolenbroek //cache lookup
3043e457fe3SDavid van Moolenbroek if(isConstant) {
3053e457fe3SDavid van Moolenbroek it = arrayRefCache.find(arrayElems);
3063e457fe3SDavid van Moolenbroek if(it != arrayRefCache.end()) {
3073e457fe3SDavid van Moolenbroek return it->second;
3083e457fe3SDavid van Moolenbroek }
3093e457fe3SDavid van Moolenbroek }
3103e457fe3SDavid van Moolenbroek
3113e457fe3SDavid van Moolenbroek //create a constant internal array reference
3123e457fe3SDavid van Moolenbroek ArrayType* arrayTy = ArrayType::get(arrayElems[0]->getType(), arrayElems.size());
3133e457fe3SDavid van Moolenbroek Constant *arrayValue = ConstantArray::get(arrayTy, arrayElems);
3143e457fe3SDavid van Moolenbroek
3153e457fe3SDavid van Moolenbroek //create the global variable and record it in the module
3163e457fe3SDavid van Moolenbroek GlobalVariable *arrayRef = new GlobalVariable(arrayValue->getType(), isConstant,
3173e457fe3SDavid van Moolenbroek GlobalValue::InternalLinkage, arrayValue,
3183e457fe3SDavid van Moolenbroek MAGIC_HIDDEN_ARRAY_PREFIX);
3193e457fe3SDavid van Moolenbroek MagicUtil::setGlobalVariableSection(arrayRef, isConstant ? MAGIC_STATIC_VARS_SECTION_RO : MAGIC_STATIC_VARS_SECTION_DATA);
3203e457fe3SDavid van Moolenbroek M.getGlobalList().push_back(arrayRef);
3213e457fe3SDavid van Moolenbroek
3223e457fe3SDavid van Moolenbroek //populate cache
3233e457fe3SDavid van Moolenbroek if(isConstant) {
3243e457fe3SDavid van Moolenbroek arrayRefCache.insert(std::pair<std::vector<Constant*>, GlobalVariable*>(arrayElems, arrayRef));
3253e457fe3SDavid van Moolenbroek }
3263e457fe3SDavid van Moolenbroek
3273e457fe3SDavid van Moolenbroek return arrayRef;
3283e457fe3SDavid van Moolenbroek }
3293e457fe3SDavid van Moolenbroek
getMagicTypePtrArrayRef(Module & M,Instruction * InsertBefore,std::vector<Value * > & globalTypeIndexes,GlobalVariable * magicTypeArray)3303e457fe3SDavid van Moolenbroek GlobalVariable *MagicUtil::getMagicTypePtrArrayRef(Module &M, Instruction *InsertBefore, std::vector<Value*> &globalTypeIndexes, GlobalVariable *magicTypeArray) {
3313e457fe3SDavid van Moolenbroek int numTypeIndexes = globalTypeIndexes.size();
3323e457fe3SDavid van Moolenbroek TYPECONST StructType* magicTypeStructTy = (TYPECONST StructType*) ((TYPECONST ArrayType*)magicTypeArray->getType()->getElementType())->getElementType();
3333e457fe3SDavid van Moolenbroek ArrayType* typeIndexesArrTy = ArrayType::get(PointerType::get(magicTypeStructTy, 0), numTypeIndexes+1);
3343e457fe3SDavid van Moolenbroek std::vector<Constant*> arrayElems;
3353e457fe3SDavid van Moolenbroek for(int i=0;i<numTypeIndexes;i++) {
3363e457fe3SDavid van Moolenbroek std::vector<Value*> magicTypeArrayIndexes;
3373e457fe3SDavid van Moolenbroek magicTypeArrayIndexes.clear();
3383e457fe3SDavid van Moolenbroek magicTypeArrayIndexes.push_back(ConstantInt::get(M.getContext(), APInt(64, 0, 10)));
3393e457fe3SDavid van Moolenbroek magicTypeArrayIndexes.push_back(globalTypeIndexes[i]);
3403e457fe3SDavid van Moolenbroek Constant* typePtr = getGetElementPtrConstant(magicTypeArray, magicTypeArrayIndexes);
3413e457fe3SDavid van Moolenbroek arrayElems.push_back(typePtr);
3423e457fe3SDavid van Moolenbroek }
3433e457fe3SDavid van Moolenbroek arrayElems.push_back(ConstantPointerNull::get(PointerType::get(magicTypeStructTy, 0))); //NULL-terminated array
3443e457fe3SDavid van Moolenbroek
3453e457fe3SDavid van Moolenbroek //create the global variable and record it in the module
3463e457fe3SDavid van Moolenbroek Constant *arrayValue = ConstantArray::get(typeIndexesArrTy, arrayElems);
3473e457fe3SDavid van Moolenbroek GlobalVariable *arrayRef = new GlobalVariable(arrayValue->getType(), true,
3483e457fe3SDavid van Moolenbroek GlobalValue::InternalLinkage, arrayValue,
3493e457fe3SDavid van Moolenbroek MAGIC_HIDDEN_ARRAY_PREFIX);
3503e457fe3SDavid van Moolenbroek MagicUtil::setGlobalVariableSection(arrayRef, MAGIC_STATIC_VARS_SECTION_RO);
3513e457fe3SDavid van Moolenbroek M.getGlobalList().push_back(arrayRef);
3523e457fe3SDavid van Moolenbroek
3533e457fe3SDavid van Moolenbroek return arrayRef;
3543e457fe3SDavid van Moolenbroek }
3553e457fe3SDavid van Moolenbroek
getExportedIntGlobalVar(Module & M,std::string name,int value,bool isConstant)3563e457fe3SDavid van Moolenbroek GlobalVariable* MagicUtil::getExportedIntGlobalVar(Module &M, std::string name, int value, bool isConstant) {
3573e457fe3SDavid van Moolenbroek Constant *intValue = ConstantInt::get(M.getContext(), APInt(32, value, 10));
3583e457fe3SDavid van Moolenbroek
3593e457fe3SDavid van Moolenbroek //create the global variable and record it in the module
3603e457fe3SDavid van Moolenbroek GlobalVariable *GV = new GlobalVariable(intValue->getType(), isConstant,
3613e457fe3SDavid van Moolenbroek GlobalValue::LinkOnceAnyLinkage, intValue, name);
3623e457fe3SDavid van Moolenbroek MagicUtil::setGlobalVariableSection(GV, isConstant ? MAGIC_STATIC_VARS_SECTION_RO : MAGIC_STATIC_VARS_SECTION_DATA);
3633e457fe3SDavid van Moolenbroek M.getGlobalList().push_back(GV);
3643e457fe3SDavid van Moolenbroek
3653e457fe3SDavid van Moolenbroek return GV;
3663e457fe3SDavid van Moolenbroek }
3673e457fe3SDavid van Moolenbroek
getShadowRef(Module & M,GlobalVariable * GV)3683e457fe3SDavid van Moolenbroek GlobalVariable* MagicUtil::getShadowRef(Module &M, GlobalVariable *GV) {
3693e457fe3SDavid van Moolenbroek //create the shadow global variable and record it in the module
3703e457fe3SDavid van Moolenbroek TYPECONST Type* type = GV->getType()->getElementType();
3713e457fe3SDavid van Moolenbroek GlobalVariable *SGV = new GlobalVariable(type, GV->isConstant(),
3723e457fe3SDavid van Moolenbroek GlobalValue::InternalLinkage, 0,
3733e457fe3SDavid van Moolenbroek MAGIC_SHADOW_VAR_PREFIX + GV->getName());
3743e457fe3SDavid van Moolenbroek SGV->setInitializer(Constant::getNullValue(type));
3753e457fe3SDavid van Moolenbroek MagicUtil::setGlobalVariableSection(SGV, GV->isConstant() ? MAGIC_SHADOW_VARS_SECTION_RO : MAGIC_SHADOW_VARS_SECTION_DATA);
3763e457fe3SDavid van Moolenbroek M.getGlobalList().push_back(SGV);
3773e457fe3SDavid van Moolenbroek
3783e457fe3SDavid van Moolenbroek if(!GV->hasInitializer()) {
3793e457fe3SDavid van Moolenbroek magicUtilLog("Shadowing for extern variable: " << GV->getName());
3803e457fe3SDavid van Moolenbroek }
3813e457fe3SDavid van Moolenbroek if(GV->isConstant()) {
3823e457fe3SDavid van Moolenbroek magicUtilLog("Shadowing for constant variable: " << GV->getName());
3833e457fe3SDavid van Moolenbroek }
3843e457fe3SDavid van Moolenbroek
3853e457fe3SDavid van Moolenbroek return SGV;
3863e457fe3SDavid van Moolenbroek }
3873e457fe3SDavid van Moolenbroek
getMagicStructFieldPtr(Module & M,Instruction * InsertBefore,GlobalVariable * var,Value * arrayIndex,const std::string & structFieldName,std::string * structFieldNames)3883e457fe3SDavid van Moolenbroek Value* MagicUtil::getMagicStructFieldPtr(Module &M, Instruction *InsertBefore, GlobalVariable* var, Value* arrayIndex, const std::string &structFieldName, std::string *structFieldNames) {
3893e457fe3SDavid van Moolenbroek //lookup field index
3903e457fe3SDavid van Moolenbroek int structFieldIndex;
3913e457fe3SDavid van Moolenbroek Value *varPtr;
3923e457fe3SDavid van Moolenbroek for(structFieldIndex=0; structFieldName.compare(structFieldNames[structFieldIndex]) != 0; structFieldIndex++) {}
3933e457fe3SDavid van Moolenbroek
3943e457fe3SDavid van Moolenbroek if(arrayIndex) {
3953e457fe3SDavid van Moolenbroek //get array ptr
3963e457fe3SDavid van Moolenbroek std::vector<Value*> arrayIndexes;
3973e457fe3SDavid van Moolenbroek arrayIndexes.push_back(ConstantInt::get(M.getContext(), APInt(64, 0, 10)));
3983e457fe3SDavid van Moolenbroek arrayIndexes.push_back(arrayIndex);
3993e457fe3SDavid van Moolenbroek varPtr = createGetElementPtrInstruction(var, arrayIndexes, "", InsertBefore);
4003e457fe3SDavid van Moolenbroek }
4013e457fe3SDavid van Moolenbroek else {
4023e457fe3SDavid van Moolenbroek varPtr = var;
4033e457fe3SDavid van Moolenbroek }
4043e457fe3SDavid van Moolenbroek
4053e457fe3SDavid van Moolenbroek //get struct field ptr
4063e457fe3SDavid van Moolenbroek std::vector<Value*> structFieldIndexes;
4073e457fe3SDavid van Moolenbroek structFieldIndexes.push_back(ConstantInt::get(M.getContext(), APInt(32, 0, 10)));
4083e457fe3SDavid van Moolenbroek structFieldIndexes.push_back(ConstantInt::get(M.getContext(), APInt(32, structFieldIndex, 10)));
4093e457fe3SDavid van Moolenbroek Instruction* structFieldPtr = createGetElementPtrInstruction(varPtr, structFieldIndexes, "", InsertBefore);
4103e457fe3SDavid van Moolenbroek
4113e457fe3SDavid van Moolenbroek return structFieldPtr;
4123e457fe3SDavid van Moolenbroek }
4133e457fe3SDavid van Moolenbroek
getMagicSStructFieldPtr(Module & M,Instruction * InsertBefore,GlobalVariable * magicArray,Value * magicArrayIndex,const std::string & structFieldName)4143e457fe3SDavid van Moolenbroek Value* MagicUtil::getMagicSStructFieldPtr(Module &M, Instruction *InsertBefore, GlobalVariable* magicArray, Value* magicArrayIndex, const std::string &structFieldName) {
4153e457fe3SDavid van Moolenbroek static std::string structFieldNames[] = { MAGIC_SSTRUCT_FIELDS };
4163e457fe3SDavid van Moolenbroek return getMagicStructFieldPtr(M, InsertBefore, magicArray, magicArrayIndex, structFieldName, structFieldNames);
4173e457fe3SDavid van Moolenbroek }
4183e457fe3SDavid van Moolenbroek
getMagicTStructFieldPtr(Module & M,Instruction * InsertBefore,GlobalVariable * magicTypeArray,Value * magicTypeArrayIndex,const std::string & structFieldName)4193e457fe3SDavid van Moolenbroek Value* MagicUtil::getMagicTStructFieldPtr(Module &M, Instruction *InsertBefore, GlobalVariable* magicTypeArray, Value* magicTypeArrayIndex, const std::string &structFieldName) {
4203e457fe3SDavid van Moolenbroek static std::string structFieldNames[] = { MAGIC_TSTRUCT_FIELDS };
4213e457fe3SDavid van Moolenbroek return getMagicStructFieldPtr(M, InsertBefore, magicTypeArray, magicTypeArrayIndex, structFieldName, structFieldNames);
4223e457fe3SDavid van Moolenbroek }
4233e457fe3SDavid van Moolenbroek
getMagicFStructFieldPtr(Module & M,Instruction * InsertBefore,GlobalVariable * magicFunctionArray,Value * magicFunctionArrayIndex,const std::string & structFieldName)4243e457fe3SDavid van Moolenbroek Value* MagicUtil::getMagicFStructFieldPtr(Module &M, Instruction *InsertBefore, GlobalVariable* magicFunctionArray, Value* magicFunctionArrayIndex, const std::string &structFieldName) {
4253e457fe3SDavid van Moolenbroek static std::string structFieldNames[] = { MAGIC_FSTRUCT_FIELDS };
4263e457fe3SDavid van Moolenbroek return getMagicStructFieldPtr(M, InsertBefore, magicFunctionArray, magicFunctionArrayIndex, structFieldName, structFieldNames);
4273e457fe3SDavid van Moolenbroek }
4283e457fe3SDavid van Moolenbroek
getMagicRStructFieldPtr(Module & M,Instruction * InsertBefore,GlobalVariable * magicVar,const std::string & structFieldName)4293e457fe3SDavid van Moolenbroek Value* MagicUtil::getMagicRStructFieldPtr(Module &M, Instruction *InsertBefore, GlobalVariable* magicVar, const std::string &structFieldName) {
4303e457fe3SDavid van Moolenbroek static std::string structFieldNames[] = { MAGIC_RSTRUCT_FIELDS };
4313e457fe3SDavid van Moolenbroek return getMagicStructFieldPtr(M, InsertBefore, magicVar, NULL, structFieldName, structFieldNames);
4323e457fe3SDavid van Moolenbroek }
4333e457fe3SDavid van Moolenbroek
getMagicDStructFieldPtr(Module & M,Instruction * InsertBefore,GlobalVariable * magicDsindexArray,Value * magicDsindexArrayIndex,const std::string & structFieldName)4343e457fe3SDavid van Moolenbroek Value* MagicUtil::getMagicDStructFieldPtr(Module &M, Instruction *InsertBefore, GlobalVariable* magicDsindexArray, Value* magicDsindexArrayIndex, const std::string &structFieldName) {
4353e457fe3SDavid van Moolenbroek static std::string structFieldNames[] = { MAGIC_DSTRUCT_FIELDS };
4363e457fe3SDavid van Moolenbroek return getMagicStructFieldPtr(M, InsertBefore, magicDsindexArray, magicDsindexArrayIndex, structFieldName, structFieldNames);
4373e457fe3SDavid van Moolenbroek }
4383e457fe3SDavid van Moolenbroek
getArrayPtr(Module & M,GlobalVariable * array)4393e457fe3SDavid van Moolenbroek Constant* MagicUtil::getArrayPtr(Module &M, GlobalVariable* array) {
4403e457fe3SDavid van Moolenbroek //indexes for array
4413e457fe3SDavid van Moolenbroek static std::vector<Value*> arrayIndexes;
4423e457fe3SDavid van Moolenbroek if(arrayIndexes.empty()) {
4433e457fe3SDavid van Moolenbroek arrayIndexes.push_back(ConstantInt::get(M.getContext(), APInt(64, 0, 10))); //pointer to A[]
4443e457fe3SDavid van Moolenbroek arrayIndexes.push_back(ConstantInt::get(M.getContext(), APInt(64, 0, 10))); //pointer to A[0]
4453e457fe3SDavid van Moolenbroek }
4463e457fe3SDavid van Moolenbroek
4473e457fe3SDavid van Moolenbroek //get array ptr
4483e457fe3SDavid van Moolenbroek Constant* arrayPtr = getGetElementPtrConstant(array, arrayIndexes);
4493e457fe3SDavid van Moolenbroek
4503e457fe3SDavid van Moolenbroek return arrayPtr;
4513e457fe3SDavid van Moolenbroek }
4523e457fe3SDavid van Moolenbroek
insertMemcpyInst(Module & M,Instruction * InsertBefore,Value * Dst,Value * Src,Value * Len,unsigned Align)4533e457fe3SDavid van Moolenbroek void MagicUtil::insertMemcpyInst(Module &M, Instruction *InsertBefore, Value *Dst, Value *Src, Value *Len, unsigned Align) {
4543e457fe3SDavid van Moolenbroek bool useMemCpyIntrinsics = false;
4553e457fe3SDavid van Moolenbroek Function *MemCpy = M.getFunction("memcpy");
4563e457fe3SDavid van Moolenbroek if(!MemCpy) {
4573e457fe3SDavid van Moolenbroek TYPECONST Type *ArgTys[1] = { IntegerType::getInt32Ty(M.getContext()) };
4583e457fe3SDavid van Moolenbroek MemCpy = getIntrinsicFunction(M, Intrinsic::memcpy, ArgTys, 1);
4593e457fe3SDavid van Moolenbroek useMemCpyIntrinsics = true;
4603e457fe3SDavid van Moolenbroek }
4613e457fe3SDavid van Moolenbroek else {
4623e457fe3SDavid van Moolenbroek MemCpy = (Function*) M.getOrInsertFunction(MAGIC_MEMCPY_FUNC_NAME, MemCpy->getFunctionType());
4633e457fe3SDavid van Moolenbroek }
4643e457fe3SDavid van Moolenbroek
4653e457fe3SDavid van Moolenbroek // Insert the memcpy instruction
4663e457fe3SDavid van Moolenbroek std::vector<Value*> MemCpyArgs;
4673e457fe3SDavid van Moolenbroek MemCpyArgs.push_back(Dst);
4683e457fe3SDavid van Moolenbroek MemCpyArgs.push_back(Src);
4693e457fe3SDavid van Moolenbroek MemCpyArgs.push_back(Len);
4703e457fe3SDavid van Moolenbroek if(useMemCpyIntrinsics) {
4713e457fe3SDavid van Moolenbroek MemCpyArgs.push_back(ConstantInt::get(M.getContext(), APInt(32, Align, 10)));
4723e457fe3SDavid van Moolenbroek }
4733e457fe3SDavid van Moolenbroek createCallInstruction(MemCpy, MemCpyArgs, "", InsertBefore);
4743e457fe3SDavid van Moolenbroek }
4753e457fe3SDavid van Moolenbroek
insertCopyInst(Module & M,Instruction * InsertBefore,GlobalVariable * GV,GlobalVariable * SGV,int GVSize,bool forceMemcpy)4763e457fe3SDavid van Moolenbroek void MagicUtil::insertCopyInst(Module &M, Instruction *InsertBefore, GlobalVariable *GV, GlobalVariable *SGV, int GVSize, bool forceMemcpy) {
4773e457fe3SDavid van Moolenbroek //get type and type size
4783e457fe3SDavid van Moolenbroek TYPECONST Type *GVType = GV->getType()->getElementType();
4793e457fe3SDavid van Moolenbroek bool isPrimitiveOrPointerType = !GVType->isAggregateType();
4803e457fe3SDavid van Moolenbroek
4813e457fe3SDavid van Moolenbroek //no need for memcpy for primitive types or pointer types
4823e457fe3SDavid van Moolenbroek if(isPrimitiveOrPointerType && !forceMemcpy) {
4833e457fe3SDavid van Moolenbroek LoadInst* primitiveValue = new LoadInst(GV, "", false, InsertBefore);
4843e457fe3SDavid van Moolenbroek new StoreInst(primitiveValue, SGV, false, InsertBefore);
4853e457fe3SDavid van Moolenbroek return;
4863e457fe3SDavid van Moolenbroek }
4873e457fe3SDavid van Moolenbroek
4883e457fe3SDavid van Moolenbroek //cast pointers to match memcpy prototype
4893e457fe3SDavid van Moolenbroek PointerType* voidPointerType = PointerType::get(IntegerType::get(M.getContext(), 8), 0);
4903e457fe3SDavid van Moolenbroek Constant* varAddress = ConstantExpr::getCast(Instruction::BitCast, GV, voidPointerType);
4913e457fe3SDavid van Moolenbroek Constant* varShadowAddress = ConstantExpr::getCast(Instruction::BitCast, SGV, voidPointerType);
4923e457fe3SDavid van Moolenbroek
4933e457fe3SDavid van Moolenbroek //insert the memcpy instruction
4943e457fe3SDavid van Moolenbroek MagicUtil::insertMemcpyInst(M, InsertBefore, varShadowAddress, varAddress, ConstantInt::get(M.getContext(), APInt(32, GVSize, 10)), 0);
4953e457fe3SDavid van Moolenbroek }
4963e457fe3SDavid van Moolenbroek
getCalledFunctionFromCS(const CallSite & CS)4973e457fe3SDavid van Moolenbroek Function* MagicUtil::getCalledFunctionFromCS(const CallSite &CS) {
4983e457fe3SDavid van Moolenbroek assert(CS.getInstruction());
4993e457fe3SDavid van Moolenbroek Function *function = CS.getCalledFunction();
5003e457fe3SDavid van Moolenbroek if(function) {
5013e457fe3SDavid van Moolenbroek return function;
5023e457fe3SDavid van Moolenbroek }
5033e457fe3SDavid van Moolenbroek
5043e457fe3SDavid van Moolenbroek //handle the weird case of bitcasted function call
5053e457fe3SDavid van Moolenbroek //IMPORTANT! function may still be null, if it's an indirect call
5063e457fe3SDavid van Moolenbroek ConstantExpr *CE = dyn_cast<ConstantExpr>(CS.getCalledValue());
5073e457fe3SDavid van Moolenbroek if (CE) {
5083e457fe3SDavid van Moolenbroek assert(CE->getOpcode() == Instruction::BitCast && "Bitcast expected, something else found!");
5093e457fe3SDavid van Moolenbroek function = dyn_cast<Function>(CE->getOperand(0));
5103e457fe3SDavid van Moolenbroek assert(function);
5113e457fe3SDavid van Moolenbroek } else {
5123e457fe3SDavid van Moolenbroek errs() << "Warning! Indirect call encountered!\n";
5133e457fe3SDavid van Moolenbroek }
5143e457fe3SDavid van Moolenbroek
5153e457fe3SDavid van Moolenbroek return function;
5163e457fe3SDavid van Moolenbroek }
5173e457fe3SDavid van Moolenbroek
replaceCallInst(Instruction * originalInst,CallInst * newInst,int argOffset,bool removeUnusedFunction)5183e457fe3SDavid van Moolenbroek void MagicUtil::replaceCallInst(Instruction *originalInst, CallInst *newInst, int argOffset, bool removeUnusedFunction) {
5193e457fe3SDavid van Moolenbroek SmallVector< std::pair< unsigned, MDNode * >, 8> MDs;
5203e457fe3SDavid van Moolenbroek originalInst->getAllMetadata(MDs);
5213e457fe3SDavid van Moolenbroek for(unsigned i=0;i<MDs.size();i++) {
5223e457fe3SDavid van Moolenbroek newInst->setMetadata(MDs[i].first, MDs[i].second);
5233e457fe3SDavid van Moolenbroek }
5243e457fe3SDavid van Moolenbroek CallSite CS = MagicUtil::getCallSiteFromInstruction(originalInst);
5253e457fe3SDavid van Moolenbroek assert(CS);
5263e457fe3SDavid van Moolenbroek CallingConv::ID CC = CS.getCallingConv();
5273e457fe3SDavid van Moolenbroek Function *originalFunction = getCalledFunctionFromCS(CS);
5283e457fe3SDavid van Moolenbroek newInst->setCallingConv(CC);
5293e457fe3SDavid van Moolenbroek ATTRIBUTE_SET_TY NewAttrs = PassUtil::remapCallSiteAttributes(CS, argOffset);
5303e457fe3SDavid van Moolenbroek newInst->setAttributes(NewAttrs);
5313e457fe3SDavid van Moolenbroek
5323e457fe3SDavid van Moolenbroek originalInst->replaceAllUsesWith(newInst);
5333e457fe3SDavid van Moolenbroek
5343e457fe3SDavid van Moolenbroek // If the old instruction was an invoke, add an unconditional branch
5353e457fe3SDavid van Moolenbroek // before the invoke, which will become the new terminator.
5363e457fe3SDavid van Moolenbroek if (InvokeInst *II = dyn_cast<InvokeInst>(originalInst))
5373e457fe3SDavid van Moolenbroek BranchInst::Create(II->getNormalDest(), originalInst);
5383e457fe3SDavid van Moolenbroek
5393e457fe3SDavid van Moolenbroek // Delete the old call site
5403e457fe3SDavid van Moolenbroek originalInst->eraseFromParent();
5413e457fe3SDavid van Moolenbroek
5423e457fe3SDavid van Moolenbroek // When asked, remove the original function when nobody uses it any more.
5433e457fe3SDavid van Moolenbroek if(removeUnusedFunction && originalFunction->use_empty()) {
5443e457fe3SDavid van Moolenbroek originalFunction->eraseFromParent();
5453e457fe3SDavid van Moolenbroek }
5463e457fe3SDavid van Moolenbroek }
5473e457fe3SDavid van Moolenbroek
getGlobalVariablesShadowFunctions(Module & M,std::vector<GlobalVariable * > globalVariables,std::vector<GlobalVariable * > shadowGlobalVariables,std::vector<int> globalVariableSizes,GlobalVariable * magicArray,int magicArraySize,bool forceShadow,bool setDirtyFlag)5483e457fe3SDavid van Moolenbroek 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) {
5493e457fe3SDavid van Moolenbroek std::vector<Function*> globalVariableShadowFunctions;
5503e457fe3SDavid van Moolenbroek for(int i=0;i<magicArraySize;i++) {
5513e457fe3SDavid van Moolenbroek Function* func = getGlobalVariableShadowFunction(M, globalVariables[i], shadowGlobalVariables[i], globalVariableSizes[i], magicArray, i, forceShadow, setDirtyFlag);
5523e457fe3SDavid van Moolenbroek globalVariableShadowFunctions.push_back(func);
5533e457fe3SDavid van Moolenbroek }
5543e457fe3SDavid van Moolenbroek
5553e457fe3SDavid van Moolenbroek return globalVariableShadowFunctions;
5563e457fe3SDavid van Moolenbroek }
5573e457fe3SDavid van Moolenbroek
getGlobalVariableShadowFunction(Module & M,GlobalVariable * GV,GlobalVariable * SGV,int GVSize,GlobalVariable * magicArray,int magicArrayIndex,bool forceShadow,bool setDirtyFlag)5583e457fe3SDavid van Moolenbroek Function* MagicUtil::getGlobalVariableShadowFunction(Module &M, GlobalVariable* GV, GlobalVariable* SGV, int GVSize, GlobalVariable* magicArray, int magicArrayIndex, bool forceShadow, bool setDirtyFlag) {
5593e457fe3SDavid van Moolenbroek static Constant* magicStateDirty = ConstantInt::get(M.getContext(), APInt(32, MAGIC_STATE_DIRTY, 10));
5603e457fe3SDavid van Moolenbroek static Function* shadowFunc = NULL;
5613e457fe3SDavid van Moolenbroek ConstantInt* magicArrayIndexConst = ConstantInt::get(M.getContext(), APInt(32, magicArrayIndex, 10));
5623e457fe3SDavid van Moolenbroek
5633e457fe3SDavid van Moolenbroek //determine name
5643e457fe3SDavid van Moolenbroek std::string name(MAGIC_SHADOW_FUNC_PREFIX);
5653e457fe3SDavid van Moolenbroek name.append("_");
5663e457fe3SDavid van Moolenbroek if(forceShadow) {
5673e457fe3SDavid van Moolenbroek name.append("force_");
5683e457fe3SDavid van Moolenbroek }
5693e457fe3SDavid van Moolenbroek if(setDirtyFlag) {
5703e457fe3SDavid van Moolenbroek name.append("setdf_");
5713e457fe3SDavid van Moolenbroek }
5723e457fe3SDavid van Moolenbroek name.append(GV->getName());
5733e457fe3SDavid van Moolenbroek
5743e457fe3SDavid van Moolenbroek //create function
5753e457fe3SDavid van Moolenbroek std::vector<TYPECONST Type*>shadowFuncArgs;
5763e457fe3SDavid van Moolenbroek FunctionType* shadowFuncType = FunctionType::get(Type::getVoidTy(M.getContext()), shadowFuncArgs, false);
5773e457fe3SDavid van Moolenbroek shadowFunc = Function::Create(shadowFuncType, GlobalValue::InternalLinkage, name, &M);
5783e457fe3SDavid van Moolenbroek shadowFunc->setCallingConv(CallingConv::C);
5793e457fe3SDavid van Moolenbroek
5803e457fe3SDavid van Moolenbroek //create blocks
5813e457fe3SDavid van Moolenbroek BasicBlock* label_entry = BasicBlock::Create(M.getContext(), "entry",shadowFunc,0);
5823e457fe3SDavid van Moolenbroek BasicBlock* label_shadow = BasicBlock::Create(M.getContext(), "shadow",shadowFunc,0);
5833e457fe3SDavid van Moolenbroek BasicBlock* label_return = BasicBlock::Create(M.getContext(), "return",shadowFunc,0);
5843e457fe3SDavid van Moolenbroek BranchInst::Create(label_shadow, label_entry);
5853e457fe3SDavid van Moolenbroek BranchInst::Create(label_return, label_shadow);
5863e457fe3SDavid van Moolenbroek Instruction* entryTerm = label_entry->getTerminator();
5873e457fe3SDavid van Moolenbroek Instruction* shadowTerm = label_shadow->getTerminator();
5883e457fe3SDavid van Moolenbroek
5893e457fe3SDavid van Moolenbroek if(!forceShadow || setDirtyFlag) {
5903e457fe3SDavid van Moolenbroek //get flags
5913e457fe3SDavid van Moolenbroek Value* structFlagsField = MagicUtil::getMagicSStructFieldPtr(M, entryTerm, magicArray, magicArrayIndexConst, MAGIC_SSTRUCT_FIELD_FLAGS);
5923e457fe3SDavid van Moolenbroek LoadInst* varFlags = new LoadInst(structFlagsField, "", false, entryTerm);
5933e457fe3SDavid van Moolenbroek
5943e457fe3SDavid van Moolenbroek //when not forcing, don't shadow if dirty is already set
5953e457fe3SDavid van Moolenbroek if(!forceShadow) {
5963e457fe3SDavid van Moolenbroek BinaryOperator* andedVarFlags = BinaryOperator::Create(Instruction::And, varFlags, magicStateDirty, "", entryTerm);
5973e457fe3SDavid van Moolenbroek ICmpInst* flagsCmp = new ICmpInst(entryTerm, ICmpInst::ICMP_EQ, andedVarFlags, ConstantInt::get(M.getContext(), APInt(32, 0, 10)), "");
5983e457fe3SDavid van Moolenbroek BranchInst::Create(label_shadow, label_return, flagsCmp, entryTerm);
5993e457fe3SDavid van Moolenbroek entryTerm->eraseFromParent();
6003e457fe3SDavid van Moolenbroek }
6013e457fe3SDavid van Moolenbroek
6023e457fe3SDavid van Moolenbroek //set the dirty flag for the variable
6033e457fe3SDavid van Moolenbroek if(setDirtyFlag) {
6043e457fe3SDavid van Moolenbroek BinaryOperator* oredVarFlags = BinaryOperator::Create(Instruction::Or, varFlags, magicStateDirty, "", shadowTerm);
6053e457fe3SDavid van Moolenbroek new StoreInst(oredVarFlags, structFlagsField, false, shadowTerm);
6063e457fe3SDavid van Moolenbroek }
6073e457fe3SDavid van Moolenbroek }
6083e457fe3SDavid van Moolenbroek
6093e457fe3SDavid van Moolenbroek //perform a memory copy from the original variable to the shadow variable
6103e457fe3SDavid van Moolenbroek MagicUtil::insertCopyInst(M, shadowTerm, GV, SGV, GVSize, /* forceMemcpy */ false);
6113e457fe3SDavid van Moolenbroek
6123e457fe3SDavid van Moolenbroek ReturnInst::Create(M.getContext(), label_return);
6133e457fe3SDavid van Moolenbroek
6143e457fe3SDavid van Moolenbroek return shadowFunc;
6153e457fe3SDavid van Moolenbroek }
6163e457fe3SDavid van Moolenbroek
insertGlobalVariableCleanDirtyFlag(Module & M,GlobalVariable * GV,GlobalVariable * magicArray,int magicArrayIndex,Instruction * InsertBefore)6173e457fe3SDavid van Moolenbroek void MagicUtil::insertGlobalVariableCleanDirtyFlag(Module &M, GlobalVariable* GV, GlobalVariable* magicArray, int magicArrayIndex, Instruction *InsertBefore) {
6183e457fe3SDavid van Moolenbroek Value* structFlagsField = MagicUtil::getMagicSStructFieldPtr(M, InsertBefore, magicArray, ConstantInt::get(M.getContext(), APInt(32, magicArrayIndex, 10)), MAGIC_SSTRUCT_FIELD_FLAGS);
6193e457fe3SDavid van Moolenbroek new StoreInst(ConstantInt::get(M.getContext(), APInt(32, 0, 10)), structFlagsField, false, InsertBefore);
6203e457fe3SDavid van Moolenbroek }
6213e457fe3SDavid van Moolenbroek
insertShadowTag(Module & M,GlobalVariable * GV,Instruction * InsertBefore)6223e457fe3SDavid van Moolenbroek void MagicUtil::insertShadowTag(Module &M, GlobalVariable *GV, Instruction *InsertBefore) {
6233e457fe3SDavid van Moolenbroek static Function* shadowFunc = NULL;
6243e457fe3SDavid van Moolenbroek PointerType* voidPointerType = PointerType::get(IntegerType::get(M.getContext(), 8), 0);
6253e457fe3SDavid van Moolenbroek
6263e457fe3SDavid van Moolenbroek //create function
6273e457fe3SDavid van Moolenbroek if(!shadowFunc) {
6283e457fe3SDavid van Moolenbroek std::vector<TYPECONST Type*>shadowFuncArgs;
6293e457fe3SDavid van Moolenbroek shadowFuncArgs.push_back(voidPointerType);
6303e457fe3SDavid van Moolenbroek FunctionType* shadowFuncType = FunctionType::get(Type::getVoidTy(M.getContext()), shadowFuncArgs, false);
6313e457fe3SDavid van Moolenbroek shadowFunc = Function::Create(shadowFuncType, GlobalValue::ExternalLinkage, MAGIC_LAZY_CHECKPOINT_SHADOW_TAG, &M);
6323e457fe3SDavid van Moolenbroek shadowFunc->setCallingConv(CallingConv::C);
6333e457fe3SDavid van Moolenbroek }
6343e457fe3SDavid van Moolenbroek
6353e457fe3SDavid van Moolenbroek //shadow global variable
6363e457fe3SDavid van Moolenbroek std::vector<Value*> args;
6373e457fe3SDavid van Moolenbroek args.push_back(new BitCastInst(GV, voidPointerType, "", InsertBefore));
6383e457fe3SDavid van Moolenbroek CallInst *callInst = createCallInstruction(shadowFunc, args, "", InsertBefore);
6393e457fe3SDavid van Moolenbroek callInst->setCallingConv(CallingConv::C);
6403e457fe3SDavid van Moolenbroek }
6413e457fe3SDavid van Moolenbroek
isShadowTag(Instruction * inst)6423e457fe3SDavid van Moolenbroek bool MagicUtil::isShadowTag(Instruction *inst) {
6433e457fe3SDavid van Moolenbroek if(dyn_cast<CallInst>(inst)) {
6443e457fe3SDavid van Moolenbroek CallInst *callInst = dyn_cast<CallInst>(inst);
6453e457fe3SDavid van Moolenbroek Function *function = callInst->getCalledFunction();
6463e457fe3SDavid van Moolenbroek if(function == NULL) {
6473e457fe3SDavid van Moolenbroek return false;
6483e457fe3SDavid van Moolenbroek }
6493e457fe3SDavid van Moolenbroek std::string funcName = function->getName();
6503e457fe3SDavid van Moolenbroek if(!funcName.compare(MAGIC_LAZY_CHECKPOINT_SHADOW_TAG)) {
6513e457fe3SDavid van Moolenbroek return true;
6523e457fe3SDavid van Moolenbroek }
6533e457fe3SDavid van Moolenbroek }
6543e457fe3SDavid van Moolenbroek return false;
6553e457fe3SDavid van Moolenbroek }
6563e457fe3SDavid van Moolenbroek
getGlobalVariableFromShadowTag(Instruction * inst,std::vector<Instruction * > & instructionsToRemove)6573e457fe3SDavid van Moolenbroek GlobalVariable* MagicUtil::getGlobalVariableFromShadowTag(Instruction *inst, std::vector<Instruction*> &instructionsToRemove) {
6583e457fe3SDavid van Moolenbroek CallSite CS = MagicUtil::getCallSiteFromInstruction(inst);
6593e457fe3SDavid van Moolenbroek assert(CS.arg_size() == 1);
6603e457fe3SDavid van Moolenbroek instructionsToRemove.push_back(inst);
6613e457fe3SDavid van Moolenbroek CallSite::arg_iterator AI = CS.arg_begin();
6623e457fe3SDavid van Moolenbroek Value *ActualArg = *AI;
6633e457fe3SDavid van Moolenbroek
6643e457fe3SDavid van Moolenbroek while(true) {
6653e457fe3SDavid van Moolenbroek BitCastInst *castInst = dyn_cast<BitCastInst>(ActualArg);
6663e457fe3SDavid van Moolenbroek ConstantExpr *castExpr = dyn_cast<ConstantExpr>(ActualArg);
6673e457fe3SDavid van Moolenbroek if(castInst) {
6683e457fe3SDavid van Moolenbroek assert(castInst->getNumOperands() == 1);
6693e457fe3SDavid van Moolenbroek ActualArg = castInst->getOperand(0);
6703e457fe3SDavid van Moolenbroek instructionsToRemove.push_back(castInst);
6713e457fe3SDavid van Moolenbroek }
6723e457fe3SDavid van Moolenbroek else if(castExpr) {
6733e457fe3SDavid van Moolenbroek //assert(castExpr->getNumOperands() == 1);
6743e457fe3SDavid van Moolenbroek ActualArg = castExpr->getOperand(0);
6753e457fe3SDavid van Moolenbroek }
6763e457fe3SDavid van Moolenbroek else {
6773e457fe3SDavid van Moolenbroek break;
6783e457fe3SDavid van Moolenbroek }
6793e457fe3SDavid van Moolenbroek }
6803e457fe3SDavid van Moolenbroek
6813e457fe3SDavid van Moolenbroek GlobalVariable *GV = dyn_cast<GlobalVariable>(ActualArg);
6823e457fe3SDavid van Moolenbroek if(GV == NULL) {
6833e457fe3SDavid van Moolenbroek magicUtilLog("Weird ActualArg: " << *ActualArg);
6843e457fe3SDavid van Moolenbroek }
6853e457fe3SDavid van Moolenbroek assert(GV != NULL);
6863e457fe3SDavid van Moolenbroek
6873e457fe3SDavid van Moolenbroek return GV;
6883e457fe3SDavid van Moolenbroek }
6893e457fe3SDavid van Moolenbroek
cleanupShadowTag(Module & M,std::vector<Instruction * > & instructionsToRemove)6903e457fe3SDavid van Moolenbroek void MagicUtil::cleanupShadowTag(Module &M, std::vector<Instruction*> &instructionsToRemove) {
6913e457fe3SDavid van Moolenbroek int i=0;
6923e457fe3SDavid van Moolenbroek
6933e457fe3SDavid van Moolenbroek for(i =0;i<(int)instructionsToRemove.size();i++) {
6943e457fe3SDavid van Moolenbroek Instruction *inst = instructionsToRemove[i];
6953e457fe3SDavid van Moolenbroek inst->eraseFromParent();
6963e457fe3SDavid van Moolenbroek }
6973e457fe3SDavid van Moolenbroek Function* func = M.getFunction(MAGIC_LAZY_CHECKPOINT_SHADOW_TAG);
6983e457fe3SDavid van Moolenbroek if(func && func->getNumUses() == 0) {
6993e457fe3SDavid van Moolenbroek func->eraseFromParent();
7003e457fe3SDavid van Moolenbroek }
7013e457fe3SDavid van Moolenbroek }
7023e457fe3SDavid van Moolenbroek
hasAddressTaken(const GlobalValue * GV,bool includeMembers)7033e457fe3SDavid van Moolenbroek bool MagicUtil::hasAddressTaken(const GlobalValue *GV, bool includeMembers) {
7043e457fe3SDavid van Moolenbroek //Most of the code taken from LLVM's SCCP.cpp
7053e457fe3SDavid van Moolenbroek
7063e457fe3SDavid van Moolenbroek // Delete any dead constantexpr klingons.
7073e457fe3SDavid van Moolenbroek GV->removeDeadConstantUsers();
7083e457fe3SDavid van Moolenbroek
7093e457fe3SDavid van Moolenbroek std::vector<const User*> sourceUsers;
7103e457fe3SDavid van Moolenbroek sourceUsers.push_back(GV);
7113e457fe3SDavid van Moolenbroek if(includeMembers && isa<GlobalVariable>(GV)) {
712*bdb56518SDavid van Moolenbroek for (const Use &UI : GV->uses()) {
713*bdb56518SDavid van Moolenbroek const User *U = UI.getUser();
7143e457fe3SDavid van Moolenbroek const ConstantExpr *constantExpr = dyn_cast<ConstantExpr>(U);
7153e457fe3SDavid van Moolenbroek if(isa<GetElementPtrInst>(U)) {
7163e457fe3SDavid van Moolenbroek sourceUsers.push_back(U);
7173e457fe3SDavid van Moolenbroek }
7183e457fe3SDavid van Moolenbroek else if(constantExpr && constantExpr->getOpcode() == Instruction::GetElementPtr) {
7193e457fe3SDavid van Moolenbroek sourceUsers.push_back(U);
7203e457fe3SDavid van Moolenbroek }
7213e457fe3SDavid van Moolenbroek }
7223e457fe3SDavid van Moolenbroek }
7233e457fe3SDavid van Moolenbroek
7243e457fe3SDavid van Moolenbroek for(unsigned i=0;i<sourceUsers.size();i++) {
725*bdb56518SDavid van Moolenbroek for (const Use &UI : sourceUsers[i]->uses()) {
726*bdb56518SDavid van Moolenbroek const User *U = UI.getUser();
7273e457fe3SDavid van Moolenbroek if (const StoreInst *SI = dyn_cast<StoreInst>(U)) {
7283e457fe3SDavid van Moolenbroek if (SI->getOperand(0) == sourceUsers[i] || SI->isVolatile())
7293e457fe3SDavid van Moolenbroek return true; // Storing addr of sourceUsers[i].
7303e457fe3SDavid van Moolenbroek } else if (isa<InvokeInst>(U) || isa<CallInst>(U)) {
7313e457fe3SDavid van Moolenbroek // Make sure we are calling the function, not passing the address.
7323e457fe3SDavid van Moolenbroek ImmutableCallSite CS(cast<Instruction>(U));
733*bdb56518SDavid van Moolenbroek if (!CS.isCallee(&UI))
7343e457fe3SDavid van Moolenbroek return true;
7353e457fe3SDavid van Moolenbroek } else if (const LoadInst *LI = dyn_cast<LoadInst>(U)) {
7363e457fe3SDavid van Moolenbroek if (LI->isVolatile())
7373e457fe3SDavid van Moolenbroek return true;
7383e457fe3SDavid van Moolenbroek } else if (isa<BlockAddress>(U)) {
7393e457fe3SDavid van Moolenbroek // blockaddress doesn't take the address of the function, it takes addr
7403e457fe3SDavid van Moolenbroek // of label.
7413e457fe3SDavid van Moolenbroek } else {
7423e457fe3SDavid van Moolenbroek return true;
7433e457fe3SDavid van Moolenbroek }
7443e457fe3SDavid van Moolenbroek }
7453e457fe3SDavid van Moolenbroek }
7463e457fe3SDavid van Moolenbroek return false;
7473e457fe3SDavid van Moolenbroek }
7483e457fe3SDavid van Moolenbroek
lookupValueSet(const GlobalVariable * GV,std::vector<int> & valueSet)7493e457fe3SDavid van Moolenbroek bool MagicUtil::lookupValueSet(const GlobalVariable *GV, std::vector<int> &valueSet) {
7503e457fe3SDavid van Moolenbroek //Similar to hasAddressTaken above, but we look for values
7513e457fe3SDavid van Moolenbroek
7523e457fe3SDavid van Moolenbroek if(!isa<IntegerType>(GV->getType()->getElementType())) {
7533e457fe3SDavid van Moolenbroek //integers is all we are interested in
7543e457fe3SDavid van Moolenbroek return false;
7553e457fe3SDavid van Moolenbroek }
7563e457fe3SDavid van Moolenbroek if(!GV->hasInitializer()) {
7573e457fe3SDavid van Moolenbroek //external variable
7583e457fe3SDavid van Moolenbroek return false;
7593e457fe3SDavid van Moolenbroek }
7603e457fe3SDavid van Moolenbroek
7613e457fe3SDavid van Moolenbroek // Delete any dead constantexpr klingons.
7623e457fe3SDavid van Moolenbroek GV->removeDeadConstantUsers();
7633e457fe3SDavid van Moolenbroek
7643e457fe3SDavid van Moolenbroek std::set<int> set;
765*bdb56518SDavid van Moolenbroek for (Value::const_user_iterator UI = GV->user_begin(), E = GV->user_end();
7663e457fe3SDavid van Moolenbroek UI != E; ++UI) {
7673e457fe3SDavid van Moolenbroek const User *U = *UI;
7683e457fe3SDavid van Moolenbroek if (const StoreInst *SI = dyn_cast<StoreInst>(U)) {
7693e457fe3SDavid van Moolenbroek if (SI->getOperand(1) == GV) {
7703e457fe3SDavid van Moolenbroek Value *value = SI->getOperand(0);
7713e457fe3SDavid van Moolenbroek if(ConstantInt *intValue = dyn_cast<ConstantInt>(value)) {
7723e457fe3SDavid van Moolenbroek set.insert(intValue->getSExtValue());
7733e457fe3SDavid van Moolenbroek }
7743e457fe3SDavid van Moolenbroek else {
7753e457fe3SDavid van Moolenbroek return false;
7763e457fe3SDavid van Moolenbroek }
7773e457fe3SDavid van Moolenbroek }
7783e457fe3SDavid van Moolenbroek }
7793e457fe3SDavid van Moolenbroek }
7803e457fe3SDavid van Moolenbroek const Constant *constant = GV->getInitializer();
7813e457fe3SDavid van Moolenbroek if(const ConstantInt *intConstant = dyn_cast<const ConstantInt>(constant)) {
7823e457fe3SDavid van Moolenbroek set.insert(intConstant->getSExtValue());
7833e457fe3SDavid van Moolenbroek }
7843e457fe3SDavid van Moolenbroek else {
7853e457fe3SDavid van Moolenbroek return false;
7863e457fe3SDavid van Moolenbroek }
7873e457fe3SDavid van Moolenbroek
7883e457fe3SDavid van Moolenbroek assert(set.size() > 0);
7893e457fe3SDavid van Moolenbroek valueSet.push_back(set.size()); //push length as the first value
7903e457fe3SDavid van Moolenbroek for(std::set<int>::iterator it=set.begin() ; it != set.end(); it++) {
7913e457fe3SDavid van Moolenbroek valueSet.push_back(*it);
7923e457fe3SDavid van Moolenbroek }
7933e457fe3SDavid van Moolenbroek
7943e457fe3SDavid van Moolenbroek return true;
7953e457fe3SDavid van Moolenbroek }
7963e457fe3SDavid van Moolenbroek
getStringOwner(GlobalVariable * GV)7973e457fe3SDavid van Moolenbroek Value* MagicUtil::getStringOwner(GlobalVariable *GV)
7983e457fe3SDavid van Moolenbroek {
7993e457fe3SDavid van Moolenbroek //Similar to hasAddressTaken above, but we look for string owners
8003e457fe3SDavid van Moolenbroek assert(GV && GV->isConstant());
8013e457fe3SDavid van Moolenbroek
8023e457fe3SDavid van Moolenbroek // Skip emtpy strings.
8033e457fe3SDavid van Moolenbroek if(GV->hasInitializer() && GV->getInitializer()->isNullValue()) {
8043e457fe3SDavid van Moolenbroek return NULL;
8053e457fe3SDavid van Moolenbroek }
8063e457fe3SDavid van Moolenbroek
8073e457fe3SDavid van Moolenbroek // Delete any dead constantexpr klingons.
8083e457fe3SDavid van Moolenbroek GV->removeDeadConstantUsers();
8093e457fe3SDavid van Moolenbroek
8103e457fe3SDavid van Moolenbroek std::vector<User*> sourceUsers;
8113e457fe3SDavid van Moolenbroek sourceUsers.push_back(GV);
812*bdb56518SDavid van Moolenbroek for (Value::user_iterator UI = GV->user_begin(), E = GV->user_end();
8133e457fe3SDavid van Moolenbroek UI != E; ++UI) {
8143e457fe3SDavid van Moolenbroek User *U = *UI;
8153e457fe3SDavid van Moolenbroek ConstantExpr *constantExpr = dyn_cast<ConstantExpr>(U);
8163e457fe3SDavid van Moolenbroek if(isa<GetElementPtrInst>(U)) {
8173e457fe3SDavid van Moolenbroek sourceUsers.push_back(U);
8183e457fe3SDavid van Moolenbroek }
8193e457fe3SDavid van Moolenbroek else if(constantExpr && constantExpr->getOpcode() == Instruction::GetElementPtr) {
8203e457fe3SDavid van Moolenbroek sourceUsers.push_back(U);
8213e457fe3SDavid van Moolenbroek }
8223e457fe3SDavid van Moolenbroek }
8233e457fe3SDavid van Moolenbroek
8243e457fe3SDavid van Moolenbroek Value *stringOwner = NULL;
8253e457fe3SDavid van Moolenbroek for(unsigned i=0;i<sourceUsers.size();i++) {
826*bdb56518SDavid van Moolenbroek for (Value::user_iterator UI = sourceUsers[i]->user_begin(), E = sourceUsers[i]->user_end();
8273e457fe3SDavid van Moolenbroek UI != E; ++UI) {
8283e457fe3SDavid van Moolenbroek User *U = *UI;
8293e457fe3SDavid van Moolenbroek Value *V = U;
8303e457fe3SDavid van Moolenbroek if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
8313e457fe3SDavid van Moolenbroek V = SI->getPointerOperand();
8323e457fe3SDavid van Moolenbroek }
8333e457fe3SDavid van Moolenbroek if(isa<GlobalVariable>(V) || isa<AllocaInst>(V)) {
8343e457fe3SDavid van Moolenbroek if(stringOwner != NULL && stringOwner != V) {
8353e457fe3SDavid van Moolenbroek //no owner in the ambiguous cases
8363e457fe3SDavid van Moolenbroek return NULL;
8373e457fe3SDavid van Moolenbroek }
8383e457fe3SDavid van Moolenbroek stringOwner = V;
8393e457fe3SDavid van Moolenbroek }
8403e457fe3SDavid van Moolenbroek }
8413e457fe3SDavid van Moolenbroek }
8423e457fe3SDavid van Moolenbroek
8433e457fe3SDavid van Moolenbroek return stringOwner;
8443e457fe3SDavid van Moolenbroek }
8453e457fe3SDavid van Moolenbroek
getFirstNonAllocaInst(Function * F,bool skipAllocaPoint)8463e457fe3SDavid van Moolenbroek Instruction* MagicUtil::getFirstNonAllocaInst(Function *F, bool skipAllocaPoint)
8473e457fe3SDavid van Moolenbroek {
8483e457fe3SDavid van Moolenbroek Instruction *I = NULL;
8493e457fe3SDavid van Moolenbroek if (skipAllocaPoint) {
8503e457fe3SDavid van Moolenbroek PassUtil::getAllocaInfo(F, NULL, &I);
8513e457fe3SDavid van Moolenbroek }
8523e457fe3SDavid van Moolenbroek else {
8533e457fe3SDavid van Moolenbroek PassUtil::getAllocaInfo(F, &I, NULL);
8543e457fe3SDavid van Moolenbroek }
8553e457fe3SDavid van Moolenbroek assert(I);
8563e457fe3SDavid van Moolenbroek return I;
8573e457fe3SDavid van Moolenbroek }
8583e457fe3SDavid van Moolenbroek
setGlobalVariableSection(GlobalVariable * GV,const std::string & section)8593e457fe3SDavid van Moolenbroek void MagicUtil::setGlobalVariableSection(GlobalVariable *GV, const std::string §ion)
8603e457fe3SDavid van Moolenbroek {
8613e457fe3SDavid van Moolenbroek if(GV->isThreadLocal()) {
8623e457fe3SDavid van Moolenbroek return;
8633e457fe3SDavid van Moolenbroek }
8643e457fe3SDavid van Moolenbroek
8653e457fe3SDavid van Moolenbroek GV->setSection(section);
8663e457fe3SDavid van Moolenbroek }
8673e457fe3SDavid van Moolenbroek
getCallAnnotation(Module & M,const CallSite & CS,int * annotation)8683e457fe3SDavid van Moolenbroek bool MagicUtil::getCallAnnotation(Module &M, const CallSite &CS, int *annotation)
8693e457fe3SDavid van Moolenbroek {
8703e457fe3SDavid van Moolenbroek static GlobalVariable *magicAnnotationVar = NULL;
8713e457fe3SDavid van Moolenbroek bool instFound = false;
8723e457fe3SDavid van Moolenbroek bool annotationFound = false;
8733e457fe3SDavid van Moolenbroek if(!magicAnnotationVar) {
8743e457fe3SDavid van Moolenbroek magicAnnotationVar = M.getNamedGlobal(MAGIC_CALL_ANNOTATION_VAR_NAME);
8753e457fe3SDavid van Moolenbroek assert(magicAnnotationVar);
8763e457fe3SDavid van Moolenbroek }
8773e457fe3SDavid van Moolenbroek Instruction *I = CS.getInstruction();
8783e457fe3SDavid van Moolenbroek if(!I) {
8793e457fe3SDavid van Moolenbroek return false;
8803e457fe3SDavid van Moolenbroek }
8813e457fe3SDavid van Moolenbroek BasicBlock *parent = I->getParent();
8823e457fe3SDavid van Moolenbroek for (BasicBlock::iterator i = parent->begin(), e = parent->end(); i != e; ++i) {
8833e457fe3SDavid van Moolenbroek Instruction *inst = i;
8843e457fe3SDavid van Moolenbroek if(inst != I && !instFound) {
8853e457fe3SDavid van Moolenbroek continue;
8863e457fe3SDavid van Moolenbroek }
8873e457fe3SDavid van Moolenbroek instFound = true;
8883e457fe3SDavid van Moolenbroek if(inst == I) {
8893e457fe3SDavid van Moolenbroek continue;
8903e457fe3SDavid van Moolenbroek }
8913e457fe3SDavid van Moolenbroek if(StoreInst *SI = dyn_cast<StoreInst>(inst)) {
8923e457fe3SDavid van Moolenbroek if(SI->getOperand(1) == magicAnnotationVar) {
8933e457fe3SDavid van Moolenbroek ConstantInt *CI = dyn_cast<ConstantInt>(SI->getOperand(0));
8943e457fe3SDavid van Moolenbroek assert(CI && "Bad call annotation!");
8953e457fe3SDavid van Moolenbroek annotationFound = true;
8963e457fe3SDavid van Moolenbroek *annotation = CI->getSExtValue();
8973e457fe3SDavid van Moolenbroek break;
8983e457fe3SDavid van Moolenbroek }
8993e457fe3SDavid van Moolenbroek }
9003e457fe3SDavid van Moolenbroek else if(isa<CallInst>(inst) || isa<InvokeInst>(inst)) {
9013e457fe3SDavid van Moolenbroek break;
9023e457fe3SDavid van Moolenbroek }
9033e457fe3SDavid van Moolenbroek }
9043e457fe3SDavid van Moolenbroek return annotationFound;
9053e457fe3SDavid van Moolenbroek }
9063e457fe3SDavid van Moolenbroek
getVarAnnotation(Module & M,const GlobalVariable * GV,int * annotation)9073e457fe3SDavid van Moolenbroek bool MagicUtil::getVarAnnotation(Module &M, const GlobalVariable *GV, int *annotation)
9083e457fe3SDavid van Moolenbroek {
9093e457fe3SDavid van Moolenbroek std::string GVName = GV->getName();
9103e457fe3SDavid van Moolenbroek GlobalVariable *annotationGV = M.getNamedGlobal(MAGIC_VAR_ANNOTATION_PREFIX_NAME + GVName);
9113e457fe3SDavid van Moolenbroek if(!annotationGV || !annotationGV->hasInitializer()) {
9123e457fe3SDavid van Moolenbroek return false;
9133e457fe3SDavid van Moolenbroek }
9143e457fe3SDavid van Moolenbroek ConstantInt* annotationValue = dyn_cast<ConstantInt>(annotationGV->getInitializer());
9153e457fe3SDavid van Moolenbroek if(!annotationValue) {
9163e457fe3SDavid van Moolenbroek return false;
9173e457fe3SDavid van Moolenbroek }
9183e457fe3SDavid van Moolenbroek *annotation = (int) annotationValue->getSExtValue();
9193e457fe3SDavid van Moolenbroek return true;
9203e457fe3SDavid van Moolenbroek }
9213e457fe3SDavid van Moolenbroek
getCallSiteFromInstruction(Instruction * I)9223e457fe3SDavid van Moolenbroek CallSite MagicUtil::getCallSiteFromInstruction(Instruction *I)
9233e457fe3SDavid van Moolenbroek {
9243e457fe3SDavid van Moolenbroek return PassUtil::getCallSiteFromInstruction(I);
9253e457fe3SDavid van Moolenbroek }
9263e457fe3SDavid van Moolenbroek
getAllocaInstFromArgument(Argument * argument)9273e457fe3SDavid van Moolenbroek AllocaInst* MagicUtil::getAllocaInstFromArgument(Argument *argument)
9283e457fe3SDavid van Moolenbroek {
9293e457fe3SDavid van Moolenbroek Function *parent = argument->getParent();
9303e457fe3SDavid van Moolenbroek std::string targetString = argument->getName().str() + "_addr";
9313e457fe3SDavid van Moolenbroek std::string targetString2 = argument->getName().str() + ".addr";
9323e457fe3SDavid van Moolenbroek StringRef targetName(targetString);
9333e457fe3SDavid van Moolenbroek StringRef targetName2(targetString2);
9343e457fe3SDavid van Moolenbroek for (inst_iterator it = inst_begin(parent), et = inst_end(parent); it != et; ++it) {
9353e457fe3SDavid van Moolenbroek AllocaInst *AI = dyn_cast<AllocaInst>(&(*it));
9363e457fe3SDavid van Moolenbroek if(!AI) {
9373e457fe3SDavid van Moolenbroek break;
9383e457fe3SDavid van Moolenbroek }
9393e457fe3SDavid van Moolenbroek if(AI->getName().startswith(targetName) || AI->getName().startswith(targetName2)) {
9403e457fe3SDavid van Moolenbroek return AI;
9413e457fe3SDavid van Moolenbroek }
9423e457fe3SDavid van Moolenbroek }
9433e457fe3SDavid van Moolenbroek
9443e457fe3SDavid van Moolenbroek return NULL;
9453e457fe3SDavid van Moolenbroek }
9463e457fe3SDavid van Moolenbroek
9473e457fe3SDavid van Moolenbroek // searches for the specified function in module symbol table assuming that its name has been mangled
9483e457fe3SDavid van Moolenbroek // returns NULL if the function has not been found
getMangledFunction(Module & M,StringRef functionName)9493e457fe3SDavid van Moolenbroek Function* MagicUtil::getMangledFunction(Module &M, StringRef functionName)
9503e457fe3SDavid van Moolenbroek {
9513e457fe3SDavid van Moolenbroek Function *F = NULL;
9523e457fe3SDavid van Moolenbroek char* outbuf;
9533e457fe3SDavid van Moolenbroek const char* functionNameString = functionName.data();
9543e457fe3SDavid van Moolenbroek int status;
9553e457fe3SDavid van Moolenbroek for (Module::iterator it = M.begin(); it != M.end(); ++it) {
9563e457fe3SDavid van Moolenbroek StringRef mangledName = (*it).getName();
9573e457fe3SDavid van Moolenbroek outbuf = abi::__cxa_demangle(mangledName.data(), NULL, NULL, &status);
9583e457fe3SDavid van Moolenbroek if (status == -2) {
9593e457fe3SDavid van Moolenbroek continue; // mangledName is not a valid name under the C++ ABI mangling rules
9603e457fe3SDavid van Moolenbroek }
9613e457fe3SDavid van Moolenbroek assert(status == 0 && outbuf && "Error when trying to demangle a function name.");
9623e457fe3SDavid van Moolenbroek // testing whether this is the function we are looking for
9633e457fe3SDavid van Moolenbroek // the unmangled name is similar to a function prototype eg my_func(int, void*, int)
9643e457fe3SDavid van Moolenbroek char* pos = strstr(outbuf, functionNameString);
9653e457fe3SDavid van Moolenbroek if (!pos) {
9663e457fe3SDavid van Moolenbroek free(outbuf);
9673e457fe3SDavid van Moolenbroek continue;
9683e457fe3SDavid van Moolenbroek }
9693e457fe3SDavid van Moolenbroek // function names can only contain alpha-numeric characters and '_'
9703e457fe3SDavid van Moolenbroek // if the unmangled name refers to the target function, then that substring should not
9713e457fe3SDavid van Moolenbroek // be surrounded by characters allowed in a function name
9723e457fe3SDavid van Moolenbroek // (to exclude cases such as myfunc vs _myfunc vs myfunc2)
9733e457fe3SDavid van Moolenbroek if (pos > outbuf) {
9743e457fe3SDavid van Moolenbroek if (isalnum(*(pos - 1)) || (*(pos - 1) == '_')) {
9753e457fe3SDavid van Moolenbroek free(outbuf);
9763e457fe3SDavid van Moolenbroek continue;
9773e457fe3SDavid van Moolenbroek }
9783e457fe3SDavid van Moolenbroek }
9793e457fe3SDavid van Moolenbroek if (strlen(pos) > strlen(functionNameString)) {
9803e457fe3SDavid van Moolenbroek if (isalnum(*(pos + strlen(functionNameString))) || (*(pos + strlen(functionNameString)) == '_')) {
9813e457fe3SDavid van Moolenbroek free(outbuf);
9823e457fe3SDavid van Moolenbroek continue;
9833e457fe3SDavid van Moolenbroek }
9843e457fe3SDavid van Moolenbroek }
9853e457fe3SDavid van Moolenbroek F = it;
9863e457fe3SDavid van Moolenbroek free(outbuf);
9873e457fe3SDavid van Moolenbroek break;
9883e457fe3SDavid van Moolenbroek }
9893e457fe3SDavid van Moolenbroek
9903e457fe3SDavid van Moolenbroek return F;
9913e457fe3SDavid van Moolenbroek }
9923e457fe3SDavid van Moolenbroek
getFunction(Module & M,StringRef functionName)9933e457fe3SDavid van Moolenbroek Function* MagicUtil::getFunction(Module &M, StringRef functionName)
9943e457fe3SDavid van Moolenbroek {
9953e457fe3SDavid van Moolenbroek Function* F = M.getFunction(functionName);
9963e457fe3SDavid van Moolenbroek if (!F) {
9973e457fe3SDavid van Moolenbroek F = MagicUtil::getMangledFunction(M, functionName);
9983e457fe3SDavid van Moolenbroek }
9993e457fe3SDavid van Moolenbroek return F;
10003e457fe3SDavid van Moolenbroek }
10013e457fe3SDavid van Moolenbroek
10023e457fe3SDavid van Moolenbroek // can Type1 be represented as Type2 (with no precision loss)
isCompatibleType(const Type * Type1,const Type * Type2)10033e457fe3SDavid van Moolenbroek bool MagicUtil::isCompatibleType(const Type* Type1, const Type* Type2)
10043e457fe3SDavid van Moolenbroek {
10053e457fe3SDavid van Moolenbroek if (Type1 == Type2) {
10063e457fe3SDavid van Moolenbroek return true;
10073e457fe3SDavid van Moolenbroek }
10083e457fe3SDavid van Moolenbroek if (Type1->isIntegerTy() && Type2->isIntegerTy()) {
10093e457fe3SDavid van Moolenbroek if (((const IntegerType*)Type1)->getBitWidth() <= ((const IntegerType*)Type2)->getBitWidth()) {
10103e457fe3SDavid van Moolenbroek return true;
10113e457fe3SDavid van Moolenbroek }
10123e457fe3SDavid van Moolenbroek }
10133e457fe3SDavid van Moolenbroek
10143e457fe3SDavid van Moolenbroek return false;
10153e457fe3SDavid van Moolenbroek }
10163e457fe3SDavid van Moolenbroek
10173e457fe3SDavid van Moolenbroek // inserts an inlined call to the pre-hook function before any other instruction is executed
10183e457fe3SDavid van Moolenbroek // 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)10193e457fe3SDavid van Moolenbroek void MagicUtil::inlinePreHookForwardingCall(Function* function, Function* preHookFunction, std::vector<unsigned> argsMapping, std::vector<Value*> trailingArgs)
10203e457fe3SDavid van Moolenbroek {
10213e457fe3SDavid van Moolenbroek std::vector<Value*> callArgs;
10223e457fe3SDavid van Moolenbroek assert(preHookFunction->arg_size() == argsMapping.size() + trailingArgs.size() &&
10233e457fe3SDavid van Moolenbroek "The number of parameter values specified for the pre-hook function does not match the signature of the function.");
10243e457fe3SDavid van Moolenbroek for (std::vector<unsigned>::iterator it = argsMapping.begin(); it != argsMapping.end(); it++) {
10253e457fe3SDavid van Moolenbroek callArgs.push_back(MagicUtil::getFunctionParam(function, *it - 1));
10263e457fe3SDavid van Moolenbroek }
10273e457fe3SDavid van Moolenbroek for (std::vector<Value*>::iterator it = trailingArgs.begin(); it != trailingArgs.end(); it++) {
10283e457fe3SDavid van Moolenbroek callArgs.push_back(*it);
10293e457fe3SDavid van Moolenbroek }
10303e457fe3SDavid van Moolenbroek // insert the call after the alloca instructions so that they remain for sure in the entry block
10313e457fe3SDavid van Moolenbroek Instruction *FirstInst = MagicUtil::getFirstNonAllocaInst(function);
10323e457fe3SDavid van Moolenbroek for (unsigned i = 0; i < callArgs.size(); ++i) {
10333e457fe3SDavid van Moolenbroek TYPECONST Type* ArgType = callArgs[i]->getType();
10343e457fe3SDavid van Moolenbroek TYPECONST Type* ParamType = preHookFunction->getFunctionType()->getParamType(i);
10353e457fe3SDavid van Moolenbroek
10363e457fe3SDavid van Moolenbroek if (!MagicUtil::isCompatibleType(ArgType, ParamType)) {
10373e457fe3SDavid van Moolenbroek assert(CastInst::isCastable(ArgType, ParamType) && "The value of the argument cannot be "
10383e457fe3SDavid van Moolenbroek "casted to the parameter type required by the function to be called.");
10393e457fe3SDavid van Moolenbroek Instruction::CastOps CastOpCode = CastInst::getCastOpcode(callArgs[i], false, ParamType, false);
10403e457fe3SDavid van Moolenbroek callArgs[i] = CastInst::Create(CastOpCode, callArgs[i], ParamType, "", FirstInst);
10413e457fe3SDavid van Moolenbroek }
10423e457fe3SDavid van Moolenbroek }
10433e457fe3SDavid van Moolenbroek
10443e457fe3SDavid van Moolenbroek CallInst* WrapperFuncCall = MagicUtil::createCallInstruction(preHookFunction, callArgs, "", FirstInst);
10453e457fe3SDavid van Moolenbroek InlineFunctionInfo IFI;
10463e457fe3SDavid van Moolenbroek InlineFunction(WrapperFuncCall, IFI);
10473e457fe3SDavid van Moolenbroek }
10483e457fe3SDavid van Moolenbroek
10493e457fe3SDavid van Moolenbroek // inserts an inlined call to the post-hook function before all return instructions
10503e457fe3SDavid van Moolenbroek // forwarded arguments from the first function come first, followed by the trailing ones
10513e457fe3SDavid van Moolenbroek // 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)10523e457fe3SDavid van Moolenbroek void MagicUtil::inlinePostHookForwardingCall(Function* function, Function* postHookFunction, std::vector<unsigned> mapping, std::vector<Value*> trailingArgs)
10533e457fe3SDavid van Moolenbroek {
10543e457fe3SDavid van Moolenbroek std::vector<CallInst*> wrapperCalls;
10553e457fe3SDavid van Moolenbroek assert(postHookFunction->arg_size() == mapping.size() + trailingArgs.size()
10563e457fe3SDavid van Moolenbroek && "The number of parameter values specified for the post-hook function does not match the signature of the function.");
10573e457fe3SDavid van Moolenbroek
10583e457fe3SDavid van Moolenbroek for (Function::iterator BI = function->getBasicBlockList().begin(); BI != function->getBasicBlockList().end(); ++BI) {
10593e457fe3SDavid van Moolenbroek ReturnInst *RetInst = dyn_cast<ReturnInst>(BI->getTerminator());
10603e457fe3SDavid van Moolenbroek if (RetInst) {
10613e457fe3SDavid van Moolenbroek std::vector<Value*> callArgs;
10623e457fe3SDavid van Moolenbroek for (std::vector<unsigned>::iterator it = mapping.begin(); it != mapping.end(); it++) {
10633e457fe3SDavid van Moolenbroek if (*it > 0) {
10643e457fe3SDavid van Moolenbroek callArgs.push_back(MagicUtil::getFunctionParam(function, *it - 1));
10653e457fe3SDavid van Moolenbroek } else {
10663e457fe3SDavid van Moolenbroek callArgs.push_back(RetInst->getReturnValue());
10673e457fe3SDavid van Moolenbroek }
10683e457fe3SDavid van Moolenbroek }
10693e457fe3SDavid van Moolenbroek for (std::vector<Value*>::iterator it = trailingArgs.begin(); it != trailingArgs.end(); it++) {
10703e457fe3SDavid van Moolenbroek callArgs.push_back(*it);
10713e457fe3SDavid van Moolenbroek }
10723e457fe3SDavid van Moolenbroek for (unsigned i = 0; i < callArgs.size(); i++) {
10733e457fe3SDavid van Moolenbroek TYPECONST Type* ArgType = callArgs[i]->getType();
10743e457fe3SDavid van Moolenbroek TYPECONST Type* ParamType = postHookFunction->getFunctionType()->getParamType(i);
10753e457fe3SDavid van Moolenbroek
10763e457fe3SDavid van Moolenbroek if (!MagicUtil::isCompatibleType(ArgType, ParamType)) {
10773e457fe3SDavid van Moolenbroek assert(CastInst::isCastable(ArgType, ParamType) && "The value of the argument cannot be "
10783e457fe3SDavid van Moolenbroek "casted to the parameter type required by the function to be called.");
10793e457fe3SDavid van Moolenbroek Instruction::CastOps CastOpCode = CastInst::getCastOpcode(callArgs[i], false, ParamType, false);
10803e457fe3SDavid van Moolenbroek callArgs[i] = CastInst::Create(CastOpCode, callArgs[i], ParamType, "", RetInst);
10813e457fe3SDavid van Moolenbroek }
10823e457fe3SDavid van Moolenbroek }
10833e457fe3SDavid van Moolenbroek CallInst* WrapperFuncCall = MagicUtil::createCallInstruction(postHookFunction, callArgs, "", RetInst);
10843e457fe3SDavid van Moolenbroek wrapperCalls.push_back(WrapperFuncCall);
10853e457fe3SDavid van Moolenbroek }
10863e457fe3SDavid van Moolenbroek }
10873e457fe3SDavid van Moolenbroek for (std::vector<CallInst*>::iterator it = wrapperCalls.begin(); it != wrapperCalls.end(); ++it) {
10883e457fe3SDavid van Moolenbroek InlineFunctionInfo IFI;
10893e457fe3SDavid van Moolenbroek InlineFunction(*it, IFI);
10903e457fe3SDavid van Moolenbroek }
10913e457fe3SDavid van Moolenbroek }
10923e457fe3SDavid van Moolenbroek
getPointerIndirectionLevel(const Type * type)10933e457fe3SDavid van Moolenbroek int MagicUtil::getPointerIndirectionLevel(const Type* type)
10943e457fe3SDavid van Moolenbroek {
10953e457fe3SDavid van Moolenbroek int level = 0;
10963e457fe3SDavid van Moolenbroek if (const PointerType* ptr_type = dyn_cast<PointerType>(type)) {
10973e457fe3SDavid van Moolenbroek while (ptr_type) {
10983e457fe3SDavid van Moolenbroek level++;
10993e457fe3SDavid van Moolenbroek ptr_type = dyn_cast<PointerType>(ptr_type->getElementType());
11003e457fe3SDavid van Moolenbroek }
11013e457fe3SDavid van Moolenbroek }
11023e457fe3SDavid van Moolenbroek
11033e457fe3SDavid van Moolenbroek return level;
11043e457fe3SDavid van Moolenbroek }
11053e457fe3SDavid van Moolenbroek
getFunctionParam(Function * function,unsigned index)11063e457fe3SDavid van Moolenbroek Value* MagicUtil::getFunctionParam(Function* function, unsigned index)
11073e457fe3SDavid van Moolenbroek {
11083e457fe3SDavid van Moolenbroek if (index >= function->arg_size()) {
11093e457fe3SDavid van Moolenbroek return NULL;
11103e457fe3SDavid van Moolenbroek }
11113e457fe3SDavid van Moolenbroek Function::arg_iterator AI = function->arg_begin();
11123e457fe3SDavid van Moolenbroek while (index --> 0) {
11133e457fe3SDavid van Moolenbroek AI++;
11143e457fe3SDavid van Moolenbroek }
11153e457fe3SDavid van Moolenbroek return AI;
11163e457fe3SDavid van Moolenbroek }
11173e457fe3SDavid van Moolenbroek
isLocalConstant(Module & M,GlobalVariable * GV)11183e457fe3SDavid van Moolenbroek bool MagicUtil::isLocalConstant(Module &M, GlobalVariable *GV)
11193e457fe3SDavid van Moolenbroek {
11203e457fe3SDavid van Moolenbroek if (!GV->isConstant()) {
11213e457fe3SDavid van Moolenbroek return false;
11223e457fe3SDavid van Moolenbroek }
11233e457fe3SDavid van Moolenbroek if (GV->getName().endswith(".v")) {
11243e457fe3SDavid van Moolenbroek return true;
11253e457fe3SDavid van Moolenbroek }
11263e457fe3SDavid van Moolenbroek std::pair<StringRef, StringRef> stringPair = GV->getName().split('.');
11273e457fe3SDavid van Moolenbroek StringRef functionName = stringPair.first;
11283e457fe3SDavid van Moolenbroek if (!functionName.compare("") || M.getFunction(functionName) == NULL) {
11293e457fe3SDavid van Moolenbroek return false;
11303e457fe3SDavid van Moolenbroek }
11313e457fe3SDavid van Moolenbroek
11323e457fe3SDavid van Moolenbroek return true;
11333e457fe3SDavid van Moolenbroek }
11343e457fe3SDavid van Moolenbroek
11353e457fe3SDavid van Moolenbroek }
1136