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