目标:一个使用可执行文件中的函数(不导出符号)的共享库。
Means: gcc -Wl,--defsym,function=0x432238
手册页指出:
"--defsym symbol=expression" Create a global symbol in the output
file, containing the absolute address given by expression.
令我沮丧的是,dlopen()
正在添加0x7ffff676f000
,共享库的基地址(这是 64 位代码)到导出的“绝对符号地址”:
executable shared library
---------- linker --------------
symbol: 0x432238 =====> 0x7ffff6ba1238
objdump 显示正确的符号地址(0x432238
)在库中,但一旦加载dlopen()
,符号有地址0x7ffff6ba1238
.
如果加载后,我手动将库符号修补到正确的地址,则一切正常(否则,库 SEGFAULT)。
Update:
我对下面回复的技术相关性提出质疑,甚至更质疑其“更新”:
使用 --defsym 在 PIC 库/可执行文件中定义重定位符号是没有意义的(除了污染二进制文件而没有任何可用功能之外,它没有任何用途)。
因此,在 PIC 共享库或 PIC 可执行文件中 --defsym 的唯一相关用途应该是定义 (未搬迁)“绝对地址”。
顺便说一句,如果您费心阅读手册页,这就是 --defsym 的官方目的:
“在输出文件中创建一个全局符号,包含absolute address
由表达式给出。”
充其量,这是一个 Linux 链接器缺陷,修复起来很简单。对于那些迫不及待地等待否认者意识到(并修复)他们的错误的人来说,解决方案是在有缺陷的链接器加载二进制映像后修补重定位表。
然后,--defsym 在 PIC 库/可执行文件中变得有用,在我看来这是一个可喜的进步。