llvm 创建外部调用函数方法

llvm 创建外部调用函数方法

2023-02-12 15:26:19

sizaif
img

法一:

声名参数类型及函数类型

// Fun Ty
static FunctionType *_EntryStackFnTy;
static FunctionType *_TaintHandleTy;
// Fn
static Function *_EntryStackFn;
static Function *_TaintFn;

_TaintHandleTy = FunctionType::get(VoidTy, {Int32Ty, Int32Ty, Int32Ty}, true); // true可变参数 
_EntryStackFnTy = FunctionType::get(VoidTy, {Int8PtrTy,Int64Ty}, false);

第三个参数false,表示此函数不是可变参数, 若为true 则表明函数是可变参数

在llvm IR中处理并调用函数:

map<StringRef ,GlobalVariable *> fnname2gv;
IRBuilder<> *builder;

....    
void handle(Module *mod){
    builder = new IRBuilder<>(mod->getContext()); // 声明builder
    Int32Ty = IntegerType::getInt32Ty(mod->getContext());
    
    std::vector<Value*>vec_arg;
    StringRef fn_name = func->getName();
    u64 fn_name_hash = hash64_char(fn_name.str().c_str(), fn_name.size()); 
    // hash(fn_name)
    if(!fnname2gv.count(fn_name)){
        ArrayType *ty = ArrayType::get(Type::getInt8Ty(mod->getContext()), fn_name.size() + 1);
        GlobalVariable *gv = new GlobalVariable(
            *mod, ty, true, GlobalValue::InternalLinkage, nullptr,
            (funcCount > 0 ? ".funcName." + to_string(funcCount) : ".funcName"));
        ++funcCount;
        gv->setAlignment(MaybeAlign(1));
        Constant *arrayValue = ConstantDataArray::getString(mod->getContext(), fn_name, true);
        gv->setInitializer(arrayValue);
        fnname2gv[fn_name] = gvfnname;
    }
    vector<Constant *> indices;
    indices.push_back(ConstantInt::get(Int64Ty, 0));
    indices.push_back(ConstantInt::get(Int64Ty, 0));
    vec_arg.push_back(ConstantExpr::getGetElementPtr(fnname2gv[fn_name]->getValueType(),fnname2gv[fn_name],indices));
    vec_arg.push_back(ConstantInt::get(Int64Ty,fn_name_hash));
    builder->SetInsertPoint(inst);
    builder->CreateCall(_EntryStackFn,vec_arg);
}

1.对于字符串类型,无法直接将string 转换成Value*, 但GlobalStringValue类型,

所以通过构建全局变量的形式: string->StringRef->globalString->Value*

在llvm IR中传递参数应使用Value*

2.对于可变参数变量

只需要先填充counts (告知后面有几个参数,这个counts是不包含在可变参数里,需要显式声明的) ;

然后往vector里填充即可

例如:

std:vector<Value*>vec_arg;

vec_arg.push_back(ConstantInt::get(Int32Ty,2)); // counts
vec_arg.push_back(ConstantInt::get(Int32Ty,10000)); 
vec_arg.push_back(fnname2gv[fn_name]); 

外部函数:

extern "C" void entrystackFunc(char *funcName, u64 fnamehash){
    .....
}

extern "C" void _Taint_handle(int inst_type, int isOrNo, int counts, ...){
    va_list args;
    va_start(args, counts);
    for (int idx = 0; idx < counts; idx++)
    {
        auto temps_va = va_arg(args, void *); //  void * 类型接收
        u64 tmp = (u64)(temps_va); // 转换到对应的类型
    }
    va_end(args);
}

法二

声明函数

string entryFuncName("entryFunc");

Function *insertentryFuncDecl(Module *mod)
{
    Int64Ty = IntegerType::getInt64Ty(mod->getContext());
    FunctionCallee c = mod->getOrInsertFunction(entryFuncName,
					 FunctionType::getVoidTy(mod->getContext()),
                     Type::getInt8PtrTy(mod->getContext()),
                     Int64Ty);
    return static_cast<Function *>(c.getCallee());
}

在llvm IR中处理并函数调用

Function *entryFunc = insertentryFuncDecl(mod);
std::vector<Value *> Args;
....
Args.push_back(...)
....
Instruction *entryCall = CallInst::Create(
    entryFunc->getFunctionType(),
    entryFunc,
    Args);
entryCall->insertBefore(inst);

外部函数

外部函数同法一中所指

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值