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

Tom*_*ila 9 linux linker gcc gnu ld

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

例如,我有以下结构:

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

struct FooBar foobar;
Run Code Online (Sandbox Code Playgroud)

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

这个请求的基本原理是这个相同的源可以在两个平台上使用:在本机平台上,Register32可以简单地是一个volatile uint32_t,但在Linux上Register32是一个C++对象,其大小与uint32_t定义的大小相同operator=,然后将使用该地址对象并向具有该地址(和数据)的通信框架发送请求以在远程硬件上执行实际访问.因此,链接器将确保Register32结构的字段引用正确的"地址".

Tom*_*ila 17

litb使用的建议--defsym symbol=address确实有效,但是当你有几十个这样的实例要映射时有点麻烦.但是,--just-symbols=symbolfile只是诀窍.我花了一段时间来找出它的语法symbolfile,这是

symbolname1 = address;
symbolname2 = address;
...
Run Code Online (Sandbox Code Playgroud)

这些空间似乎是必需的,否则ld报告file format not recognized; treating as linker script.


Joh*_*itb 10

尝试一下

--defsym symbol=expression
Run Code Online (Sandbox Code Playgroud)

就像这样:

gcc -Wl,--defsym,foobar=0x76543210 file.c
Run Code Online (Sandbox Code Playgroud)

并在您的代码中使foobar成为一个外部声明:

extern struct FooBar foobar;
Run Code Online (Sandbox Code Playgroud)

这很有希望.然而,做这样的事情是个坏主意(除非你真的知道你做了什么).你为什么需要它?