如何通过模块构建器系统在 LLVM 中调用@printf
How To Call @printf in LLVM through the module builder system
我正在学习 LLVM。我知道 LLVM 中已经提供了许多有用的 C 函数作为固有函数。所以我试图从我的代码中调用 @printf 函数。
我在 LLVM 参考手册中找到了描述 IR 代码的相应部分,相对清楚:
declare i32 @printf(i8* noalias nocapture, ...)
call i32 (i8*, ...)* @printf(i8* %msg, i32 12, i8 42)
等但是我无法找到如何使用 IRBuilder<> class 来做到这一点。我检查了构建器 class,但我无法弄清楚任何事情。
我不想传递任何花哨的变量,基本上就像
printf( "%lu", variable_64_bit );
在 C 或类似语言中。
任何人都可以告诉我我必须做什么才能通过构建器调用 printf 函数。
提前致谢
我在别处找到了 。事实上,它有点超出了我最初的问题,但它对我有帮助,希望它也能帮助其他人。
void kprintf(Module *mod, BasicBlock *bb, const char *format, ...)
{
Function *func_printf = mod->getFunction("printf");
if (!func_printf) {
PointerType *Pty = PointerType::get(IntegerType::get(mod->getContext(), 8), 0);
FunctionType *FuncTy9 = FunctionType::get(IntegerType::get(mod->getContext(), 32), true);
func_printf = Function::Create(FuncTy9, GlobalValue::ExternalLinkage, "printf", mod);
func_printf->setCallingConv(CallingConv::C);
AttrListPtr func_printf_PAL;
func_printf->setAttributes(func_printf_PAL);
}
IRBuilder <> builder(mod->getContext());
builder.SetInsertPoint(bb);
Value *str = builder.CreateGlobalStringPtr(format);
std::vector <Value *> int32_call_params;
int32_call_params.push_back(str);
va_list ap;
va_start(ap, format);
char *str_ptr = va_arg(ap, char*);
Value *format_ptr = builder.CreateGlobalStringPtr(str_ptr);
int32_call_params.push_back(format_ptr);
std::vector<llvm::Value*> extra;
do {
llvm::Value *op = va_arg(ap, llvm::Value*);
if (op) {
int32_call_params.push_back(op);
} else {
break;
}
} while (1);
va_end(ap);
CallInst * int32_call = CallInst::Create(func_printf, int32_call_params, "call", bb);
}
#define oprintf(...) kprintf(__VA_ARGS__)
#define llvm_printf(...) oprintf(mod, bb, __VA_ARGS__, NULL)
llvm_printf("Output: 0x%08X %f %d\n", 0x12345678, 3.1415926, 12345);
希望对您有所帮助
我正在学习 LLVM。我知道 LLVM 中已经提供了许多有用的 C 函数作为固有函数。所以我试图从我的代码中调用 @printf 函数。
我在 LLVM 参考手册中找到了描述 IR 代码的相应部分,相对清楚:
declare i32 @printf(i8* noalias nocapture, ...)
call i32 (i8*, ...)* @printf(i8* %msg, i32 12, i8 42)
等但是我无法找到如何使用 IRBuilder<> class 来做到这一点。我检查了构建器 class,但我无法弄清楚任何事情。
我不想传递任何花哨的变量,基本上就像
printf( "%lu", variable_64_bit );
在 C 或类似语言中。
任何人都可以告诉我我必须做什么才能通过构建器调用 printf 函数。
提前致谢
我在别处找到了
void kprintf(Module *mod, BasicBlock *bb, const char *format, ...)
{
Function *func_printf = mod->getFunction("printf");
if (!func_printf) {
PointerType *Pty = PointerType::get(IntegerType::get(mod->getContext(), 8), 0);
FunctionType *FuncTy9 = FunctionType::get(IntegerType::get(mod->getContext(), 32), true);
func_printf = Function::Create(FuncTy9, GlobalValue::ExternalLinkage, "printf", mod);
func_printf->setCallingConv(CallingConv::C);
AttrListPtr func_printf_PAL;
func_printf->setAttributes(func_printf_PAL);
}
IRBuilder <> builder(mod->getContext());
builder.SetInsertPoint(bb);
Value *str = builder.CreateGlobalStringPtr(format);
std::vector <Value *> int32_call_params;
int32_call_params.push_back(str);
va_list ap;
va_start(ap, format);
char *str_ptr = va_arg(ap, char*);
Value *format_ptr = builder.CreateGlobalStringPtr(str_ptr);
int32_call_params.push_back(format_ptr);
std::vector<llvm::Value*> extra;
do {
llvm::Value *op = va_arg(ap, llvm::Value*);
if (op) {
int32_call_params.push_back(op);
} else {
break;
}
} while (1);
va_end(ap);
CallInst * int32_call = CallInst::Create(func_printf, int32_call_params, "call", bb);
}
#define oprintf(...) kprintf(__VA_ARGS__)
#define llvm_printf(...) oprintf(mod, bb, __VA_ARGS__, NULL)
llvm_printf("Output: 0x%08X %f %d\n", 0x12345678, 3.1415926, 12345);
希望对您有所帮助