How to create a sprintf call in IR

Hi,

I created a global char array, char buffer[1024]. I want to call a function to append the string information to the buffer repeatedly. For example, I need to implement the following code, where length, a, b, c, are global variables.

int length = 0;
length += sprintf(buffer+length, "str%d", a);
length += sprintf(buffer+length, "str%c", b);
length += sprintf(buffer+length, "str%d", c);

I did it in the following way.

  1. Create the global array:
    IntegerType CHARTYPE = IntegerType::get(llvm::getGlobalContext(), 8);
    ArrayType* ty = ArrayType::get(CHARTYPE, 1024);

GlobalVariable* buffer = new GlobalVariable(mod, ty, false, GlobalValue::ExternalLinkage, 0, “buffer”);

  1. Create sprintf
    std::vector<Type*> agrs(2, Type::getInt8PtrTy(ctxt));
    FunctionType* sprintfFT = FunctionType::get(Type::getInt32Ty(ctxt), args, true);
    Constant* sprintf = mod->getOrInsertFunction(“sprintf”, sprintfFT);

Now, I got stuck to create teh function call for sprintf.

I didn’t it like the following:
Value* str = builder.CreateGlobalStringPtr(“str”, “”);
Value* data = builder.CreateLoad(a); //load a, b, or c
Value* buf = builder.CreateLoad(buffer);
builder.CreateCall3((value*)sprintf, buf, str, data);

I want to test the sprintf function before adding the offset, but it didn’t work. The error information is “llvm.sys:PrintStackTrace(_IO_FILE)”. Any help will be appreciated.

Best,
Zhi

You know the C code you want to replicate. So ask llvm to generate the C++ api calls that would produce that output.

eg;
https://gist.github.com/alloy/d86b007b1b14607a112f

Thanks for the pointer. It’s working now.

Best,
Zhi