题
一个会如何,这样的二进制仍然可以正常在Linux中(86)执行联(一些)符号使用GNU ld的特定固定地址?不会有任何访问的那些符号,但是它们的地址是重要的。
例如,我有以下结构:
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;
这看起来很有希望。然而,这是一个坏主意,做这样的事情(除非你的真正的知道你做了什么)。你为什么需要它?
我给你热尖... GNU LD可以做到这一点(假设系统库不需要你想要的地址)。你只需要建立自己的链接脚本,而不是使用编译器的自动生成一个。阅读ld的手册页。此外,建立一个链接描述为复杂的软件是不容易的任务,当你涉及glibc的了。