链接器为什么要修改--defsym“绝对地址"? [英] Why does the linker modify a --defsym "absolute address"

查看:829
本文介绍了链接器为什么要修改--defsym“绝对地址"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目标:共享库,可使用可执行文件中的功能(不导出符号).

Goal: a shared library to use a function from an executable (which does not export symbols).

手段: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位代码)添加到导出的绝对符号地址"中:

To my dismay, dlopen() is adding 0x7ffff676f000, the shared library's base address (this is 64-bit code) to the exported "absolute symbol address":

        executable        shared library
        ---------- linker --------------
symbol: 0x432238   =====> 0x7ffff6ba1238

objdump在库中显示正确的符号地址(0x432238),但是一旦加载了dlopen(),则符号的地址为0x7ffff6ba1238.

objdump shows the correct symbol address (0x432238) in the library, but once loaded with dlopen(), the symbol has address 0x7ffff6ba1238.

如果加载后我手动将库符号修补到正确的地址,则一切正常(否则,库SEGFAULTs).

If, once loaded, I manually patch the library symbol to the correct address then all works fine (else, the library SEGFAULTs).

  • 为什么修改绝对地址"?
  • 如何避免呢?

更新:

我质疑以下回复的技术相关性,甚至是其更新"内容:

具有--defsym在PIC库/可执行文件中定义重定位的符号是没有意义的(除了污染没有任何可用功能的二进制文件之外,它没有任何目的).

Having --defsym to define a relocated symbol in a PIC library/executable is pointless (it does not serve ANY purpose other than polluting the binary without any usable feature).

因此,-defsym在PIC共享库或PIC可执行文件中的唯一相关用途应该是定义(未重定位)绝对地址".

Therefore, the only relevant use of --defsym in a PIC shared library or PIC executable should be to define a (non-relocated) "absolute address".

顺便说一句,这是--defsym的官方目的,如果您不愿意阅读手册页:

Incidentally, that's the official purpose of --defsym if you bother to read the man page:

在输出文件中创建一个全局符号,其中包含表达式给出的absolute address."

充其量,这是一个Linux链接器缺陷,修复起来很简单.对于那些迫不及待地拒绝人们意识到(并修复)他们的错误的人,解决方案是在有缺陷的链接器加载二进制映像后修补重定位表.

At best, this is a Linux linker deffect which would be trivial to fix. And for those who can't wait for the people-in-denial to realize (and fix) their mistake, the solution is to patch the relocation table after the binary image has been loaded by the defective linker.

然后,--defsym在PIC库/可执行文件中变得很有用,在我看来这是一个可喜的进步.

Then, --defsym becomes useful in PIC libraries/executables, which seems to me is a welcome progress.

推荐答案

您似乎从根本上误解了--defsym的功能.

You appear to have fundamentally misunderstood what --defsym does.

--defsym=symbol=expression
   Create a global symbol in the *output* file, ...

也就是说,您正在创建的库中创建新符号 .这样,该符号(自然地)随库一起重新定位.

That is, you are creating the new symbol in the library that you are building. As such, the symbol is (naturally) relocated with the library.

我猜你想改成这样:

// 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)();
}

如果您不想将0x432238硬编码到库中,而是在构建时在命令行中传递值,只需使用-DEXE_FN=0x432238即可实现.

If you didn't want to hard-code 0x432238 into the library, and instead pass the value on command line at build time, just use a -DEXE_FN=0x432238 to achieve that.

更新:

目标:共享库以使用可执行文件中的功能

Goal: a shared library to use a function from an executable

您选择的方法无法实现该目标 .您将不得不使用其他方式.

That goal can not be achieved by the method you selected. You'll have to use other means.

为什么修改绝对地址"?

Why the "absolute address" is modified?

不是.当您要求链接器在绝对地址0x432238上定义function时,它确实做到了完全.您可以在objdumpnmreadelf -s输出中看到它.

It isn't. When you ask the linker to define function at absolute address 0x432238, it does exactly that. You can see it in objdump, nm and readelf -s output.

但是由于符号是在共享库中定义的,因此所有对该符号的引用都将被重定位,即通过共享库的加载地址进行调整(由动态加载程序).对于动态加载程序来说,毫无意义.

But because the symbol is defined in the shared library, all references to that symbol are relocated, i.e. adjusted by the shared library load address (that is done by the dynamic loader). It makes no sense whatsoever for the dynamic loader to do otherwise.

如何避免呢?

How to avoid it?

不能.使用其他方式实现您的目标.

You can't. Use other means to achieve your goal.

这篇关于链接器为什么要修改--defsym“绝对地址"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆