- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在为嵌入式平台开发,但我很难弄清楚如何动态链接共享库。我使用的是 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!
如果我获取函数的地址并将其放入函数指针(因此,绕过“代码贴面”)并调用它,共享库将完美运行。
例如:
#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 */
有没有办法告诉 GCC 不生成代码单板并直接分支到位于 GOT 中的地址,或者以某种方式使代码单板分支显示在要执行的重定位列表中的地址?
最佳答案
我找到了解决此问题的方法。这不是最好或最干净的方法,但在我的情况下它可以完成工作。
我利用链接器中的 --wrap
选项将符号重定向到 __wrap_symbol
。有了这个,我设置了一个自动生成 ASM 文件的 awk 脚本,这些文件将正确重定位的地址加载到 pc 中。任何库调用都将重定向到此代码。基本上我所做的就是制作我自己的代码贴面。由于未引用生成的代码单板,它只是被优化掉了。
此外,我不得不将我的胶合板放在 .data 部分,因为 .text 部分中的任何内容都没有正确重新定位。由于我正在使用的平台并没有太多区分代码和数据,所以这个 hacky 变通方法有效。
Here's a link转到我正在处理的项目,您可以在其中查找具体信息。
关于c - 位置独立代码、共享库和代码贴面——让它们协同工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9986994/
我想插入 备注 关于要在我的 latex 文档的特定位置进行的修复 也许有一个 列表的“待办事项/修复我” 你怎么处理这个? 似乎一种方法是使用 fixme 包,但我无法使其工作。 有人在用吗? 最佳
错误:无法创建表。我已经创建了一个数据库,并且已经提供了所有特权。但仍然无法登录协作模块。我受够了,但我不想放弃。我已经尝试了所有可能的方法,但都行不通。 Stackoverflow 是我所知道的最好
我是一名优秀的程序员,十分优秀!