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>