Hi everybody. I've just started learning about LLVM and didn't get too far studying the core. I couldn't find the solution to my problem (if it has one) in the mailing list or the source code. The problem is: how can I redefine a function that's been called already by some other function? Suppose I have 3 files, all compiled to bytecode through llvm-gcc (I think it could be clang instead). File1.c: void do_print() { print(); } File2.c: void print() { printf("File2.c\n"); } File3.c: void print() { printf("File3.c\n"); } Then, I have the main file compiled to executable like this: int main() { // initialize and get context (not shown) Module *file1(LoadFile("file1.bc",Context)); Module *file2(LoadFile("file2.bc",Context)); Module *file3(LoadFile("file3.bc",Context)); Linker::LinkModules(file1, file2, NULL); EngineBuilder builder(file1); ExecutionEngine *EE = builder.create(); EE->runStaticConstructorsDestructors(false); func = EE->FindFunctionNamed("do_print"); EE->runFunction(func, std::vector<GenericValue>()); //swap the definition of the function "print" from the one in File2.c to File3.c swap (file1, file2, file3); EE->runFunction(func, std::vector<GenericValue>()); EE->runStaticConstructorsDestructors(true); return 0; } I can get everything before the swap working (if I comment the rest, the output is OK). I've tried to build the "swap" function many times but I can't get it to work. The expected output is: File2.c File3.c If someone know how to do this or knows it's impossible, I would be very thankful. I don't even know if this is the best way to do it. Miranda -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20100129/1973c42d/attachment.html>
Hi Conrado,> I couldn't find the solution to my problem (if it has one) in the > mailing list or the source code. The problem is: how can I redefine a > function that's been called already by some other function?why do you want to do this?> Suppose I have 3 files, all compiled to bytecode through llvm-gcc (I > think it could be clang instead). > > File1.c: > void do_print() { print(); } > > File2.c: > void print() { printf("File2.c\n"); } > > File3.c: > void print() { printf("File3.c\n"); }The solution in C is to give the version in File2 a weak linkage type, for example using gcc's "weak" attribute. You then link all three files together, and the weak print in File2 will be magically replaced with the non-weak print in File3.> //swap the definition of the function "print" from the one in File2.c > to File3.c > swap (file1, file2, file3);If all the functions are in the same module, then you can use FunctionA->replaceAllUsesWith(FunctionB) if they have the same type. Ciao, Duncan.
Hi Duncan,> I couldn't find the solution to my problem (if it has one) in the mailing >> list or the source code. The problem is: how can I redefine a function >> that's been called already by some other function? >> > > why do you want to do this? >To implement something that is common in Lisp. Suppose I have a program that is running and can't be stopped or the cost being stoped is prohibitive. If I find a better way to run an algorithm, I'd like to update the running program non-stopping. Suppose I have 3 files, all compiled to bytecode through llvm-gcc (I think> it could be clang instead). > > File1.c: > void do_print() { print(); } > > File2.c: > void print() { printf("File2.c\n"); } > > File3.c: > void print() { printf("File3.c\n"); } >The solution in C is to give the version in File2 a weak linkage type,> for example using gcc's "weak" attribute. You then link all three files > together, and the weak print in File2 will be magically replaced with the > non-weak print in File3.Never heard of it before. After a quick reading, it sounds OK. Keeping the rest of the file, changed the attribute and this section: func = EE->FindFunctionNamed ("do_print"); EE->runFunction(func, std::vector<GenericValue> ()); Linker::LinkModules(main_file, print2, &ErrorMessage); EE->runFunction(func, std::vector<GenericValue> ()); And now I get this error before the second runFunction: While deleting: void ()* %print An asserting value handle still pointed to this value! UNREACHABLE executed at /home/miranda/llvm-2.6/lib/VMCore/Value.cpp:492! I suppose that's because "do_print" was already called. By the way, it seems like weak attribute is only supported for ELF and a.out. Maybe not the better solution. //swap the definition of the function "print" from the one in File2.c to> File3.c > swap (file1, file2, file3); >If all the functions are in the same module, then you can use> FunctionA->replaceAllUsesWith(FunctionB) if they have the same > type. >Sorry I didn't see that function before. But, when I tried that (pastebin code: http://pastebin.com/m2485ae4f), it still doesn't print as supposed. It calls only the first function printing File2.c File2.c Maybe that works when the functions haven't been called before. Am I using the wrong way or had to do something before? Thanks, Miranda -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20100130/c29ad19c/attachment.html>