代码之家  ›  专栏  ›  技术社区  ›  Tomi Junnila

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

  •  9
  • Tomi Junnila  · 技术社区  · 16 年前

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

    例如,我有以下结构:

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

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

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

    3 回复  |  直到 11 年前
        1
  •  15
  •   Tomi Junnila    16 年前

    利特建议使用 --defsym symbol=address 确实有效,但是当您有几十个这样的实例需要映射时,这有点麻烦。然而, --just-symbols=symbolfile 只会耍花招。我花了一段时间才发现 symbolfile ,这就是

    symbolname1 = address;
    symbolname2 = address;
    ...
    

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

        2
  •  8
  •   Johannes Schaub - litb    16 年前

    试一试

    --defsym symbol=expression
    

    与此相同:

    gcc -Wl,--defsym,foobar=0x76543210 file.c
    

    在代码中使foobar成为外部声明:

    extern struct FooBar foobar;
    

    这看起来很有希望。但是,做这样的事是个坏主意(除非你 真的? 知道你在做什么)。你为什么需要它?

        3
  •  1
  •   Adam Hawes    16 年前

    我会给你小费的…GNUld可以这样做(假设系统libs不需要您想要的地址)。您只需要构建自己的链接器脚本,而不是使用编译器的自动生成脚本。阅读LD的手册页。另外,为一个复杂的软件构建一个链接器脚本在涉及glibc时也不是一件容易的事情。