I am developing an embedded platform and it is difficult for me to work on how to dynamically link shared libraries. I use the bFLT file format and I have no control over the loading of the executable and shared library.
My bootloader correctly loads the shared library and executable into memory and modifies the executable GOT at runtime to communicate with the shared library.
I can successfully use the address of the function, and I know that it is correct if you parse the code in this place. However, if I try to call a function, all of this will work.
It turns out that GCC adds a "code veneer" when calling the functions of the shared library and takes a detour when calling the functions and does not actually go to the address of the function. The address that the code window branch hangs on does not move properly, because it does not appear in the navigation list in the binary executable.
Dismantling veneer is as follows:
000008d0 <__library_call_veneer>: 8d0: e51ff004 ldr pc, [pc,
If I take the address of the function and put it in the function pointer (therefore, bypassing the "code veneer") and calling it, the shared library works fine.
So for example:
#define DIRECT_LIB_CALL(x, args...) do { \ typeof(x) * volatile tmp = x; \ tmp(#args); \ } while (0) DIRECT_LIB_CALL(library_call); library_call();
Is there a way to either tell GCC so that it does not create a code veneer and does not go directly to the address located in the GOT, or somehow make the address that the code window branches hang in the list of movements to execute?
source share