如何使用GNU ld将(某些)符号链接到特定的固定地址,以便二进制文件仍可在Linux(x86)中正常执行?不会访问这些符号,但它们的地址很重要.
例如,我有以下结构:
struct FooBar { Register32 field_1; Register32 field_2; //... }; struct FooBar foobar;
我想链接foobar
到地址0x76543210,但通常链接标准库和应用程序的其余部分.然后,应用程序将使用foobar的地址,但不会引用它后面的(可能不存在的)内存.
这个请求的基本原理是这个相同的源可以在两个平台上使用:在本机平台上,Register32
可以简单地是一个volatile uint32_t
,但在Linux上Register32
是一个C++对象,其大小与uint32_t
定义的大小相同operator=
,然后将使用该地址对象并向具有该地址(和数据)的通信框架发送请求以在远程硬件上执行实际访问.因此,链接器将确保Register32
结构的字段引用正确的"地址".
litb使用的建议--defsym symbol=address
确实有效,但是当你有几十个这样的实例要映射时有点麻烦.但是,--just-symbols=symbolfile
只是诀窍.我花了一段时间来找出它的语法symbolfile
,这是
symbolname1 = address; symbolname2 = address; ...
这些空间似乎是必需的,否则ld
报告file format not recognized; treating as linker script
.
尝试一下
--defsym symbol=expression
就像这样:
gcc -Wl,--defsym,foobar=0x76543210 file.c
并在您的代码中使foobar成为一个外部声明:
extern struct FooBar foobar;
这很有希望.然而,做这样的事情是个坏主意(除非你真的知道你做了什么).你为什么需要它?