c - gcc 和 GNU ld 链接器 - 生成具有强制固定地址/偏移量的静态链接代码

标签 c gcc linker ld

我有一个(相对较大的)静态二进制文件,我想用另一个函数替换其中的一个函数。鉴于函数的复杂性,我想用C和gcc编译拼接函数,然后直接替换代码。显然,为了使其工作,我需要以某种方式强制执行函数和我将访问的某些全局变量位于特定的偏移量处。我如何使用 gcc 和 ld 做到这一点?

一个非常简单的例子 - 给定一个这样的程序:

int global = 42;
int get_global() { return global; }

int main() {
    return get_global();
}

编译和反汇编此函数会产生以下结果:

00000000004004ad <get_global>:
  4004ad:       55                      push   %rbp
  4004ae:       48 89 e5                mov    %rsp,%rbp
  4004b1:       8b 05 61 04 20 00       mov    0x200461(%rip),%eax        # 600918 <global>
  4004b7:       5d                      pop    %rbp
  4004b8:       c3                      retq   

注意:

  • global 变量的地址为 0x600918
  • get_global 得到 0x4004ad

基本上,问题是,我如何使用 gcc 和 ld 来生成一个函数的代码,该函数将:

  • 引用 global 变量和/或函数在提到的确切地址上
  • 从我希望它开始的地址开始(我对从地址 0x4004ad 开始特别感兴趣,因此它可能用于拼接现有的 get_global 实现)

我认为可以使用为函数原型(prototype)和/或全局变量指定的一些编译指示或特定于编译器的属性,事实上,gcc has some variables attributes that control packing and placement of functions/variables in certain sections , 但不可能指定固定地址。

我强烈怀疑这可以通过手动调用 ld 并使用一些 ld 链接器脚本魔术来完成,但是 a quick look at its documentation似乎没有为我敲响任何警钟。我错过了什么吗?

绝对相关:Fixed address variable in C

最佳答案

我以前见过这样做,使用 ASM 文件将变量固定到特定地址。这专门用于共享内存中使用的全局变量。

在任何其他源文件中,您显然需要声明全局变量 extern

因此,编写一个仅包含变量的简短 asm 文件,然后编译并将其与其余代码链接。

关于c - gcc 和 GNU ld 链接器 - 生成具有强制固定地址/偏移量的静态链接代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25276741/

相关文章:

c - 二维数组 - 每行都被下一行覆盖

c - -fstack-usage 对于叶函数是否错误?

gcc - 无法暂时禁用 GCC 中的未知编译指示警告

c++ - undefined symbol std::__throw_bad_function_call

c++ - collect2.exe 有什么作用?

c - printf() 仅在 while 循环期间打印空值

c++ - 等价于 C++ 中的 C NULL 函数指针?

gcc - 为什么 mingw 找不到 gcc 找不到的库?

C++ 链接器找不到对局部函数的引用

c - 信号中断 read()