xref: /minix3/minix/llvm/passes/include/magic/support/MagicMmapCtlFunction.h (revision bdb565187c0f1a04513dd488df843317b27f86c8)
13e457fe3SDavid van Moolenbroek #ifndef MAGIC_MMAP_CTL_FUNCTION_H
23e457fe3SDavid van Moolenbroek #define MAGIC_MMAP_CTL_FUNCTION_H
33e457fe3SDavid van Moolenbroek 
43e457fe3SDavid van Moolenbroek #include <pass.h>
53e457fe3SDavid van Moolenbroek #include <magic/support/TypeInfo.h>
63e457fe3SDavid van Moolenbroek 
73e457fe3SDavid van Moolenbroek using namespace llvm;
83e457fe3SDavid van Moolenbroek 
93e457fe3SDavid van Moolenbroek namespace llvm {
103e457fe3SDavid van Moolenbroek 
113e457fe3SDavid van Moolenbroek class MagicMmapCtlFunction {
123e457fe3SDavid van Moolenbroek   public:
133e457fe3SDavid van Moolenbroek       MagicMmapCtlFunction(Function *function, PointerType *voidPointerType, std::string &ptrArgName, std::string &lenArgName);
143e457fe3SDavid van Moolenbroek 
153e457fe3SDavid van Moolenbroek       Function* getFunction() const;
163e457fe3SDavid van Moolenbroek       void fixCalls(Module &M, Function *magicGetPageSizeFunc) const;
173e457fe3SDavid van Moolenbroek 
183e457fe3SDavid van Moolenbroek       void print(raw_ostream &OS) const;
193e457fe3SDavid van Moolenbroek       void printDescription(raw_ostream &OS) const;
203e457fe3SDavid van Moolenbroek       const std::string getDescription() const;
213e457fe3SDavid van Moolenbroek 
223e457fe3SDavid van Moolenbroek   private:
233e457fe3SDavid van Moolenbroek       Function *function;
243e457fe3SDavid van Moolenbroek       int ptrArg;
253e457fe3SDavid van Moolenbroek       int lenArg;
263e457fe3SDavid van Moolenbroek };
273e457fe3SDavid van Moolenbroek 
283e457fe3SDavid van Moolenbroek inline raw_ostream &operator<<(raw_ostream &OS, const MagicMmapCtlFunction &aMagicMmapCtlFunction) {
293e457fe3SDavid van Moolenbroek     aMagicMmapCtlFunction.print(OS);
303e457fe3SDavid van Moolenbroek     return OS;
313e457fe3SDavid van Moolenbroek }
323e457fe3SDavid van Moolenbroek 
print(raw_ostream & OS)333e457fe3SDavid van Moolenbroek inline void MagicMmapCtlFunction::print(raw_ostream &OS) const {
343e457fe3SDavid van Moolenbroek      OS << getDescription();
353e457fe3SDavid van Moolenbroek }
363e457fe3SDavid van Moolenbroek 
printDescription(raw_ostream & OS)373e457fe3SDavid van Moolenbroek inline void MagicMmapCtlFunction::printDescription(raw_ostream &OS) const {
383e457fe3SDavid van Moolenbroek     OS << "[ function = "; OS << function->getName() << "(" << TypeUtil::getDescription(function->getFunctionType()) << ")"
393e457fe3SDavid van Moolenbroek        << ", ptr arg = "; OS << ptrArg
403e457fe3SDavid van Moolenbroek        << ", len arg = "; OS << lenArg
413e457fe3SDavid van Moolenbroek        << "]";
423e457fe3SDavid van Moolenbroek }
433e457fe3SDavid van Moolenbroek 
getDescription()443e457fe3SDavid van Moolenbroek inline const std::string MagicMmapCtlFunction::getDescription() const {
453e457fe3SDavid van Moolenbroek     std::string string;
463e457fe3SDavid van Moolenbroek     raw_string_ostream ostream(string);
473e457fe3SDavid van Moolenbroek     printDescription(ostream);
483e457fe3SDavid van Moolenbroek     ostream.flush();
493e457fe3SDavid van Moolenbroek     return string;
503e457fe3SDavid van Moolenbroek }
513e457fe3SDavid van Moolenbroek 
MagicMmapCtlFunction(Function * function,PointerType * voidPointerType,std::string & ptrArgName,std::string & lenArgName)523e457fe3SDavid van Moolenbroek inline MagicMmapCtlFunction::MagicMmapCtlFunction(Function *function, PointerType *voidPointerType, std::string &ptrArgName, std::string &lenArgName) {
533e457fe3SDavid van Moolenbroek     this->function = function;
543e457fe3SDavid van Moolenbroek     this->ptrArg = -1;
553e457fe3SDavid van Moolenbroek     this->lenArg = -1;
563e457fe3SDavid van Moolenbroek     bool lookupPtrArg = ptrArgName.compare("");
573e457fe3SDavid van Moolenbroek     bool lookupLenArg = lenArgName.compare("");
583e457fe3SDavid van Moolenbroek     assert((lookupPtrArg || lookupLenArg) && "No valid argument name specified!");
593e457fe3SDavid van Moolenbroek     unsigned i=0;
603e457fe3SDavid van Moolenbroek     for (Function::arg_iterator it = function->arg_begin(), E = function->arg_end();
613e457fe3SDavid van Moolenbroek         it != E; ++it) {
623e457fe3SDavid van Moolenbroek         std::string argName = it->getName();
633e457fe3SDavid van Moolenbroek         if(lookupPtrArg && !argName.compare(ptrArgName)) {
643e457fe3SDavid van Moolenbroek             this->ptrArg = i;
653e457fe3SDavid van Moolenbroek         }
663e457fe3SDavid van Moolenbroek         else if(lookupLenArg && !argName.compare(lenArgName)) {
673e457fe3SDavid van Moolenbroek             this->lenArg = i;
683e457fe3SDavid van Moolenbroek         }
693e457fe3SDavid van Moolenbroek         i++;
703e457fe3SDavid van Moolenbroek     }
713e457fe3SDavid van Moolenbroek     if(this->ptrArg >= 0) {
723e457fe3SDavid van Moolenbroek         assert(function->getFunctionType()->getContainedType(this->ptrArg+1) == voidPointerType && "Invalid ptr argument specified!");
733e457fe3SDavid van Moolenbroek     }
743e457fe3SDavid van Moolenbroek     else {
753e457fe3SDavid van Moolenbroek         assert(!lookupPtrArg && "Invalid ptr argument name specified!");
763e457fe3SDavid van Moolenbroek     }
773e457fe3SDavid van Moolenbroek     if(this->lenArg >= 0) {
783e457fe3SDavid van Moolenbroek         assert(isa<IntegerType>(function->getFunctionType()->getContainedType(this->lenArg+1)) && "Invalid len argument specified!");
793e457fe3SDavid van Moolenbroek     }
803e457fe3SDavid van Moolenbroek     else {
813e457fe3SDavid van Moolenbroek         assert(!lookupLenArg && "Invalid len argument name specified!");
823e457fe3SDavid van Moolenbroek     }
833e457fe3SDavid van Moolenbroek }
843e457fe3SDavid van Moolenbroek 
getFunction()853e457fe3SDavid van Moolenbroek inline Function* MagicMmapCtlFunction::getFunction() const {
863e457fe3SDavid van Moolenbroek     return function;
873e457fe3SDavid van Moolenbroek }
883e457fe3SDavid van Moolenbroek 
893e457fe3SDavid van Moolenbroek /* This assumes in-band metadata of 1 page before every mmapped region. */
fixCalls(Module & M,Function * magicGetPageSizeFunc)903e457fe3SDavid van Moolenbroek inline void MagicMmapCtlFunction::fixCalls(Module &M, Function *magicGetPageSizeFunc) const {
91*bdb56518SDavid van Moolenbroek     std::vector<User*> Users(function->user_begin(), function->user_end());
923e457fe3SDavid van Moolenbroek     while (!Users.empty()) {
933e457fe3SDavid van Moolenbroek         User *U = Users.back();
943e457fe3SDavid van Moolenbroek         Users.pop_back();
953e457fe3SDavid van Moolenbroek 
963e457fe3SDavid van Moolenbroek         if (Instruction *I = dyn_cast<Instruction>(U)) {
973e457fe3SDavid van Moolenbroek             Function *parent = I->getParent()->getParent();
983e457fe3SDavid van Moolenbroek             if(parent->getName().startswith("magic") || parent->getName().startswith("_magic")) {
993e457fe3SDavid van Moolenbroek                 continue;
1003e457fe3SDavid van Moolenbroek             }
1013e457fe3SDavid van Moolenbroek             CallSite CS = MagicUtil::getCallSiteFromInstruction(I);
1023e457fe3SDavid van Moolenbroek 
1033e457fe3SDavid van Moolenbroek             std::vector<Value*> args;
1043e457fe3SDavid van Moolenbroek             CallInst* magicGetPageSizeCall = MagicUtil::createCallInstruction(magicGetPageSizeFunc, args, "", I);
1053e457fe3SDavid van Moolenbroek             magicGetPageSizeCall->setCallingConv(CallingConv::C);
1063e457fe3SDavid van Moolenbroek             magicGetPageSizeCall->setTailCall(false);
1073e457fe3SDavid van Moolenbroek             TYPECONST IntegerType *type = dyn_cast<IntegerType>(magicGetPageSizeCall->getType());
1083e457fe3SDavid van Moolenbroek             assert(type);
1093e457fe3SDavid van Moolenbroek 
1103e457fe3SDavid van Moolenbroek             if(this->ptrArg >= 0) {
1113e457fe3SDavid van Moolenbroek                 Value *ptrValue = CS.getArgument(this->ptrArg);
1123e457fe3SDavid van Moolenbroek                 BinaryOperator* negativePageSize = BinaryOperator::Create(Instruction::Sub, ConstantInt::get(M.getContext(), APInt(type->getBitWidth(), 0)), magicGetPageSizeCall, "", I);
1133e457fe3SDavid van Moolenbroek                 GetElementPtrInst* ptrValueWithOffset = GetElementPtrInst::Create(ptrValue, negativePageSize, "", I);
1143e457fe3SDavid van Moolenbroek 
1153e457fe3SDavid van Moolenbroek                 CS.setArgument(this->ptrArg, ptrValueWithOffset);
1163e457fe3SDavid van Moolenbroek             }
1173e457fe3SDavid van Moolenbroek             if(this->lenArg >= 0) {
1183e457fe3SDavid van Moolenbroek                 Value *lenValue = CS.getArgument(this->lenArg);
1193e457fe3SDavid van Moolenbroek                 BinaryOperator* lenValuePlusPageSize = BinaryOperator::Create(Instruction::Add, lenValue, magicGetPageSizeCall, "", I);
1203e457fe3SDavid van Moolenbroek 
1213e457fe3SDavid van Moolenbroek                 CS.setArgument(this->lenArg, lenValuePlusPageSize);
1223e457fe3SDavid van Moolenbroek             }
1233e457fe3SDavid van Moolenbroek         }
1243e457fe3SDavid van Moolenbroek     }
1253e457fe3SDavid van Moolenbroek }
1263e457fe3SDavid van Moolenbroek 
1273e457fe3SDavid van Moolenbroek }
1283e457fe3SDavid van Moolenbroek 
1293e457fe3SDavid van Moolenbroek #endif
1303e457fe3SDavid van Moolenbroek 
131