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

在Linux上将符号链接到固定地址,linux,gcc,linker,gnu,ld,Linux,Gcc,Linker,Gnu,Ld,如何使用GNULD将(某些)符号链接到特定的固定地址,以便二进制文件仍然可以在Linux(x86)中正常执行?不会有任何访问这些符号的权限,但它们的地址很重要 例如,我有以下结构: struct FooBar { Register32 field_1; Register32 field_2; //... }; struct FooBar foobar; 我想将foobar链接到地址0x76543210,但通常会链接标准库和应用程序的其余部分。然后,应用程序将使用foo

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

例如,我有以下结构:

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

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


此请求的理由是,在两个平台上可以使用同一个源:在本地平台上, RealStist32 < /Cord>可以简单地是<代码>易失性UTIN32×T ,但是在Linux <代码> RealSts32 < /Cuff>是一个C++对象,其大小与<代码> uINT32×t 相同,它定义了例如“代码>运算符=< /COD>”,然后,它将使用对象的地址并使用该地址(和数据)向通信框架发送请求,以在远程硬件上执行实际访问。因此,链接器将确保结构的

注册表32
字段引用正确的“地址”。

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

尝试一下

--defsym symbol=expression
关于这一点:

gcc -Wl,--defsym,foobar=0x76543210 file.c
并使代码中的foobar成为外部声明:

extern struct FooBar foobar;

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

litb建议使用
--defsym symbol=address
确实有效,但如果要映射几十个这样的实例,就有点麻烦了。然而,
--just symbols=symbolfile
就是这样做的。我花了一些时间才找到
symbolfile
的语法,它是

symbolname1 = address;
symbolname2 = address;
...

空格似乎是必需的,否则无法识别
ld
reports
文件格式;将其视为链接器脚本

为什么要这样做?在内存保护的操作系统上,没有理由这样做。在硬件位于已知特定地址的嵌入式系统中,通常需要这样做。然而,0x76543210不太可能是这样的地址。;-)ld也不是用于这些事情的最友好的链接器。有一种语法可以从链接器脚本中定义符号,这很有帮助。OP的意图似乎不仅仅是访问位于特定地址的硬件。对于GCC,类似于“struct FooBar FooBar=(struct FooBar)0x76543210”的内容应该是一种简化硬件访问的简单方法。ld文档的可能副本不是很有用,至少只需要几个小时的研究。我尝试调整编译器的默认链接器脚本,但当我注意到它甚至无法与(未编辑的)提取的默认脚本链接时,我放弃了(当然,它在没有链接器脚本的情况下链接正常)。