Gil*_*Gil 8 linux linker shared
目标:使用可执行文件中的函数(不导出符号)的共享库.
手段: gcc -Wl,--defsym,function=0x432238
该手册页指出:
"--defsym symbol=expression" Create a global symbol in the output
file, containing the absolute address given by expression.
Run Code Online (Sandbox Code Playgroud)
令我沮丧的dlopen()
是0x7ffff676f000
,将共享库的基地址(这是64位代码)添加到导出的"绝对符号地址":
executable shared library
---------- linker --------------
symbol: 0x432238 =====> 0x7ffff6ba1238
Run Code Online (Sandbox Code Playgroud)
objdump 0x432238
在库中显示正确的符号地址(),但一旦加载dlopen()
,符号就有地址0x7ffff6ba1238
.
如果,一旦加载,我手动将库符号修补到正确的地址,然后一切正常(否则,库SEGFAULTs).
更新:
我对以下答复的技术相关性提出质疑,并且更多的是"更新":
使用--defsym在PIC库/可执行文件中定义重定位符号是没有意义的(除了在没有任何可用功能的情况下污染二进制文件之外,它不起任何作用).
因此,PIC共享库或PIC可执行文件中--defsym的唯一相关用法应该是定义(非重定位)"绝对地址".
顺便说一句,如果您懒得阅读手册页,这是--defsym的官方目的:
"在输出文件中创建一个全局符号,其中包含absolute address
给定的表达式."
充其量,这是一个Linux链接器的影响,这将是微不足道的修复.对于那些不能等待拒绝人员实现(并修复)他们的错误的人来说,解决方案是在缺陷链接器加载二进制映像之后修补重定位表.
然后,-defsym在PIC库/可执行文件中变得很有用,在我看来这是一个值得欢迎的进展.
你似乎从根本上误解了什么--defsym
.
--defsym=symbol=expression
Create a global symbol in the *output* file, ...
Run Code Online (Sandbox Code Playgroud)
也就是说,您正在构建的库中创建新符号.因此,符号(自然地)与库重新定位.
我猜你想要这样的东西:
// code in library
int fn()
{
// exe_fn not exported from the executable, but we know where it is.
int (*exe_fn)(void) = (int (*)(void)) 0x432238;
return (*exe_fn)();
}
Run Code Online (Sandbox Code Playgroud)
如果您不想硬编码0x432238
到库中,而是在构建时在命令行上传递值,只需使用a -DEXE_FN=0x432238
来实现它.
更新:
目标:使用可执行文件中的函数的共享库
您选择的方法无法实现这一目标.你必须使用其他方法.
为什么修改"绝对地址"?
事实并非如此.当你问链接器定义function
的绝对地址0x432238
,它正是这一点.你可以看到它objdump
,nm
并readelf -s
输出.
但由于符号是在共享库中定义的,因此对该符号的所有引用都将重新定位,即通过共享库加载地址(由动态加载程序完成)进行调整.对于动态加载器来说,没有任何意义.
怎么避免呢?
你不能.使用其他方法来实现您的目标.
归档时间: |
|
查看次数: |
3366 次 |
最近记录: |