Position independent code, shared libraries and code veneers - get them to work together

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, #-4] ; 8d4 <__library_call_veneer+0x4> 8d4: 03000320 .word 0x03000320 ; This address isn't correctly relocated! 

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); /* works */ library_call(); /* crashes */ 

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?

+6
source share
1 answer

I have found a workaround for this problem. This is not a good or clean method, but it does the job in my case.

I used the --wrap option in my linker, which redirects characters to __wrap_symbol . With this, I set up an awk script that automatically generates ASM files that download the correctly moved address to the computer. Any library calls will be redirected to this code. Basically what I did was make my own code veneer. Since the generated code veneer was not referenced, it was simply optimized.

In addition, I had to put my veneers in the .data section, since nothing in the .text section was moved correctly. Since the platform I'm working on doesn't really distinguish between code and data, this hacky workaround works.

Here is a link to the project I'm working on, where you can find the specifics.

+2
source

Source: https://habr.com/ru/post/912284/


All Articles