将符号链接到Linux上的固定地址

时间:2009-01-30 11:47:58

标签: linux gcc linker gnu ld

如何使用GNU ld将(一些)符号链接到特定的固定地址,以便二进制文件仍可在Linux(x86)中正常执行?不会访问这些符号,但它们的地址很重要。

例如,我有以下结构:

struct FooBar {
    Register32 field_1;
    Register32 field_2;
    //...
};

struct FooBar foobar;

我想将foobar链接到地址0x76543210,但是通常会链接标准库和应用程序的其余部分。然后应用程序将使用foobar的地址,但不会引用它后面的(可能不存在的)内存。

此请求的基本原理是,可以在两个平台上使用此相同的源:在本机平台上,Register32可以只是volatile uint32_t,但在Linux Register32上是与定义例如的uint32_t大小相同的C ++对象operator=,然后将使用对象的地址并向具有该地址(和数据)的通信框架发送请求,以在远程硬件上执行实际访问。因此,链接器将确保结构的Register32字段引用正确的“地址”。

3 个答案:

答案 0 :(得分:15)

litb建议使用--defsym symbol=address确实有效,但是当您有几十个这样的实例要映射时,这有点麻烦。但是,--just-symbols=symbolfile只是诀窍。我花了一段时间才找到symbolfile的语法,即

symbolname1 = address;
symbolname2 = address;
...

似乎需要空格,否则ld报告file format not recognized; treating as linker script

答案 1 :(得分:8)

尝试

--defsym symbol=expression

与此相同:

gcc -Wl,--defsym,foobar=0x76543210 file.c

在你的代码中使foobar成为一个外部声明:

extern struct FooBar foobar;

这看起来很有希望。但是,做这样的事情是个坏主意(除非你真的知道你做了什么)。你为什么需要它?

答案 2 :(得分:1)

我会给你热门提示...... GNU LD可以做到这一点(假设系统库不需要你想要的地址)。您只需构建自己的链接描述文件,而不是使用编译器的自动生成链接器脚本。阅读ld的手册页。此外,当您涉及GLIBC时,为复杂的软件构建链接描述文件也不是一件容易的事。