10

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

例如,我将具有以下结构:

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

struct FooBar foobar;

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

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

4

3 回答 3

20

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

symbolname1 = address;
symbolname2 = address;
...

空间似乎是必需的,否则ld报告file format not recognized; treating as linker script

于 2009-01-30T14:19:08.257 回答
10

试试看

--defsym symbol=expression

与此一样:

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

并在您的代码中使 foobar 成为外部声明:

extern struct FooBar foobar;

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

于 2009-01-30T12:10:39.950 回答
1

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

于 2009-01-30T12:07:19.287 回答