I’ve been working on converting my existing 32-bit ppc code to ppc64. A lot of the ABI is the same (and my funky StackFrame
class hides a lot of the differences) but one weird thing is that on ppc64 function pointers do not point to the actual code but to some descriptor thing. OpenJDK has loads of places that do the following, and they’re all wrong:
void (*function)() = generate_some_code(); ... (*function)();
I think the descriptors are supposed to be in some table that the linker creates, but I sneaked around it by making an assembler macro, function_entry_point()
, that creates a function descriptor that points to the address immediately following it, the idea being that you place it at the start of anything you’re going to jump into from C. I’m not entirely happy with it: I’m not sure what the implications of mixing descriptors and code like this, and it makes the stubs non-relocatable, and omitting the function_entry_point()
will cause a mysterious segfault as the processor dereferences the first two instructions of your stub and jumps to wherever they point. But needs must…
your work is impressive, all slackintosh users are eagerly waiting to see your job included in the distribution :)
thanks for all the code you’re doing.
Ah, I wondered what your interest was.
Thank Red Hat, they’re paying! :)
Ah, I wondered what your interest was.
ahah, the powa of internat ;-)
Thank Red Hat, they’re paying! :)
interesting :)
Too bad the ia64 code wasn’t open sourced. It does what I suspect is a similar thing. On ia64 as I recall (this is a suppressed memory) the function pointer returns a pointer to a block of storage that contains the actual function address and also a pointer to the value that goes in gp (?). The jvm ran with all the data in the same area so we created dummy function descriptors so that c++ code could call our stubs and gp never would change. This wouldn’t work if other libraries besides libjvm.so called our generated stubs but that doesn’t occur. The assembler had an “instruction” to produce one of the descriptors which we used at the start of a stub (or anywhere we’d call in from C++). For calls from our generated assembly code I think that the instruction magically pulled out the target from the descriptor and called that.
That sounds pretty much identical. On ppc64 the function pointer points to a block of storage that contains two 64-bit values: the function address, and a value to load into
r2
prior to jumping to it. So I made this macro:All the stub generators have something like
address start = __ pc()
so I just changed them toaddress start = __ enter()
and that was that.