【发布时间】:2010-10-04 11:04:04
【问题描述】:
如何使用 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 字段引用正确的“地址”。
【问题讨论】:
-
为什么你可能想要这样做?
-
在受内存保护的操作系统上,没有理由这样做。
-
在硬件位于已知特定地址的嵌入式系统中经常需要这种东西。但是,0x76543210 不太可能是这样的地址。 ;-) ld 也不是用于此类事情的最友好的链接器。从链接描述文件中定义符号的语法很有帮助。
-
OP 的意图似乎不仅仅是访问位于特定地址的硬件。使用 GCC,类似“struct FooBar foobar = (struct FooBar)0x76543210”之类的内容应该是促进硬件访问的直接方式。