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"); 2. 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 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20151124/1c2ea425/attachment.html>
Jeremy Lakeman via llvm-dev
2015-Nov-25 04:39 UTC
[llvm-dev] How to create a sprintf call in IR
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 On Wed, Nov 25, 2015 at 5:34 AM, zhi chen via llvm-dev < llvm-dev at lists.llvm.org> wrote:> 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"); > > 2. 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 > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20151125/cd29e55c/attachment.html>
Thanks for the pointer. It's working now. Best, Zhi On Tue, Nov 24, 2015 at 8:39 PM, Jeremy Lakeman <Jeremy.Lakeman at gmail.com> wrote:> 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 > > > On Wed, Nov 25, 2015 at 5:34 AM, zhi chen via llvm-dev < > llvm-dev at lists.llvm.org> wrote: > >> 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"); >> >> 2. 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 >> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >> >> >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20151125/52b7c50e/attachment.html>