定位独立代码,共享库和代码表单 - 使它们一起工作

tan*_*grs 6 c arm shared-libraries

我正在开发一个嵌入式平台,我正在努力研究如何动态链接共享库.我正在使用bFLT文件格式,我无法控制可执行文件和共享库的加载位置.

我的加载程序正确地将共享库和可执行文件加载到内存中,并在运行时修改可执行文件的GOT以链接到共享库.

我可以成功获取函数的地址,我知道在该位置反汇编代码是正确的.但是,如果我尝试调用该函数,整个事情就会崩溃.

事实证明,GCC在调用共享库函数时添加了"代码表单",并在调用函数时绕道而且实际上并未转移到函数的地址.代码表单分支的地址未正确重定位,因为它未显示在可执行二进制文件的重定位列表中.

单板的反汇编看起来像这样:

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!
Run Code Online (Sandbox Code Playgroud)

如果我获取函数的地址并将其放入函数指针(因此,绕过'代码表单')并调用它,共享库就可以正常工作.

例如:

#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 */
Run Code Online (Sandbox Code Playgroud)

有没有办法要么告诉GCC不生成代码胶合代码并直接分支到位于GOT中的地址,或者以某种方式使代码胶合板分支的地址显示在重定位列表中以执行?

tan*_*grs 2

我找到了解决这个问题的方法。这不是最好或最干净的方法,但它在我的情况下完成了工作。

我利用--wrap链接器中的选项将符号重定向到__wrap_symbol. 这样,我设置了一个 awk 脚本,该脚本自动生成 ASM 文件,将正确重定位的地址加载到 PC 中。任何库调用都将被重定向到此代码。基本上我所做的就是制作自己的代码贴面。由于生成的代码胶面没有被引用,因此它只是被优化掉了。

此外,我必须将我的胶合板放置在 .data 部分中,因为 .text 部分中的任何内容都没有正确重新定位。由于我正在开发的平台并没有太多区分代码和数据,因此这种 hacky 解决方法是有效的。

这是我正在开发的项目的链接,您可以在其中查找具体信息。