Questions like this should probably go to gcc-help@xxxxxxxxxxx, but...
Tom Quarendon wrote:
I'm porting some code that does a kind of JIT to translate a user script
into a dynamically created function for execution, but am having trouble
porting this to GCC and the way it implementes exceptions.
Lets say I've got
int doPUT() {
throw IOException;
}
int doGET() {
throw IOException
}
and I want to magic up a function by writing (intel x86) instructions
into memory that does the same as if I'd done
int magic() {
doPUT();
doGET();
return 0;
}
You don't say how you get them into memory. Are you building a shared library and then loading it with dlopen()?
I then want to call my magic function as in
int main() {
// magic up my function in memory containing calls to doGET and doPUT.
try {
// call my magic'd function
}
catch (IOException) {
// Report the exception
}
}
If I do this I get std::terminate called from __cxa_throw. Researching
this it seems that I somehow need to register some exception handling
tables to correspond to the "magic" function to enable the exception
handler to allow the exception to propagate through.
I'd welcome any pointers to where I might be able to get some
information on this. I've looked at the C++ ABI documentation which
helps a bit, and I've found some information on the format that the
tables need to be in (and indeed I've looked at the assembler generated
by the gcc compiler if I code up "magic" and compile it directly), but I
don't yet see quite how to put it all together.
If you pass -funwind-tables to gcc it will generate the necessary unwinding information. If you put the code in a shared library and dlopen() it it should just work.
If you are loading the code some other way, then you may have to call some of the __register_frame* family of functions (in libgcc) passing pointers to the appropriate .eh_frame sections of the generated code.
I imagine that GCJ has do to this ind of thing?
g++ as well.
David Daney