Function call veneers
Colin (478) 2433 posts |
When writing a module in C the module entry points have a veneer wrapped around them to convert the Assembler based call standard of the calling routine (which presumably wants the called function to preserve all registers and return errors with V set) to the APCS call standard used by C programs. But why do you need a veneer when the caller’s call standard is the same as the callee’s call standard? Is it something to do with r12 (the modules private word)? For example USB controller drivers exist in their own modules. They register their interface functions with the USBDriver. As both the controller driver module and the USBDriver module are written in C, I would expect that you could pass a normal C function pointer from the controller driver module to the USBDriver module and call it from the USBDriver module. But what happens is every controller driver module wraps each interface function in a call veneer and I’m trying to understand why. |
Jeffrey Lee (213) 6048 posts |
It’s a requirement of the shared C library. There are a couple of relocation offsets which are expected to be stored at the base of the SVC stack. These relocation offsets are used to translate the pointers/offsets which are embedded in the module code/data into real pointers for accessing the code/data for that module instance. This means each module needs its own set of relocation offsets, and if the offsets are wrong then bad things will happen. As far as I know r12 isn’t actually used in C modules (i.e. C code treats it as an ordinary scratch register), except for entry point veneers which use it to look up the relocation offsets. |