在Linux上将符号链接到固定地址
如何使用GNULD将(某些)符号链接到特定的固定地址,以便二进制文件仍然可以在Linux(x86)中正常执行?不会有任何访问这些符号的权限,但它们的地址很重要 例如,我有以下结构:在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
struct FooBar {
Register32 field_1;
Register32 field_2;
//...
};
struct FooBar foobar;
我想将foobar
链接到地址0x76543210,但通常会链接标准库和应用程序的其余部分。然后,应用程序将使用foobar的地址,但不会引用它后面的内存(可能不存在)
此请求的理由是,在两个平台上可以使用同一个源:在本地平台上,
字段引用正确的“地址”。注册表32
--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文档的可能副本不是很有用,至少只需要几个小时的研究。我尝试调整编译器的默认链接器脚本,但当我注意到它甚至无法与(未编辑的)提取的默认脚本链接时,我放弃了(当然,它在没有链接器脚本的情况下链接正常)。