gpt4 book ai didi

gcc - 如何使用 gcc 工具链强制二进制文件中的函数顺序?

转载 作者:行者123 更新时间:2023-12-05 06:47:15 30 4
gpt4 key购买 nike

我正在用几个源文件和库构建一个静态二进制文件,我想控制函数放入生成的二进制文件的顺序。

背景是,我有外部代码链接到这个二进制文件中的偏移量。现在,如果我更改源代码,所有偏移量都会发生变化,因为 gcc 可能决定以不同的方式对函数进行排序,因此我想将引用的函数以固定顺序放在开头,以便它们的偏移量保持不变...

我查看了 ld 的文档,但找不到任何关于函数顺序的信息。

我发现的唯一东西是 -fno-toplevel-reorder,它对我没有真正帮助。

最佳答案

确实没有干净可靠的方法可以将函数强制到特定地址(入口函数除外),甚至强制具有特定顺序的函数(如果您可以强制执行顺序仍然不意味着地址在源更改时保持不变!)。

我看到的最大问题是,即使可以将一个函数修复到一些地址,也完全不可能将所有函数都修复到已经存在的地址外部程序期望(假设您不能修改此程序)。如果这真的奏效,那将是巧合和纯粹的运气。

在其他程序期望的地址处提供蹦床,并让真正的函数(无论它们在哪里)指向这些地址,这可能是最简单的方法。这将要求您的代码使用不同的基地址,因此实际的程序代码不会与蹦床冲突。

几乎可以通过三种方式为函数提供固定地址:

  1. 您可以使用 __attribute__ ((section ("some name"))) 将不允许移动的每个函数放在其适当的部分中.不幸的是,.text总是作为第一部分出现,所以如果有的话 .text发生变化,因此大小超过 512 字节边界,您的偏移量将发生变化。默认情况下(但请参阅下文)您无法在 .text 之前开始一个部分。 .
  2. -falign-functions=n命令行选项允许您将函数对齐到边界。通常这是大约 16 个字节。现在,您可以选择一个较大的值,例如 1024。这将浪费大量空间,但它也将确保只要函数只是适度更改,后续函数的地址将保持不变。显然,它仍然不会阻止编译器/链接器在需要时重新排序整个 block (尽管 -fno-toplevel-reorder 至少会部分阻止这种情况)。
  3. 如果你愿意写一个自定义linker script ,您可以为每个部分分配一个起始地址。这些是虚拟内存地址,而不是可执行文件中的位置,但我假设硬链接(hard link)也适用于 VMA(基于默认镜像库)。所以这可以有点工作,尽管有很多麻烦而且不是很好的方式。
    在编写您自己的链接器脚本时,您还可以考虑将不能移动的函数放入它们自己的部分将这些部分移动到可执行文件的开头(在.text 之前),这样更改在 .text不会移动您的功能。

更新:“gcc”标签表明您可能以 *NIX 为目标,所以这可能对您没有帮助,但是...如果您可以选择使用 COFF,美元符号部分可能会起作用(该信息可能对其他人,在任何情况下)。

我今天偶然发现了这个(强调我的):

The "$" character (dollar sign) has a special interpretation in section names in object files. When determining the image section that will contain the contents of an object section, the linker discards the "$" and all characters that follow it. Thus, an object section named .text$X actually contributes to the .text section in the image. However, the characters following the "$" determine the ordering of the contributions to the image section. All contributions with the same object-section name are allocated contiguously in the image, and the blocks of contributions are sorted in lexical order by object-section name. Therefore, everything in object files with section name .text$X ends up together, after the .text$W contributions and before the .text$Y contributions.

如果文档没有说谎(如果我没看错的话),这意味着您应该能够将您想要位于前面的所有功能打包到一个部分中 .text$A , 以及所有其他内容到 .text$B ,它应该做到这一点。

关于gcc - 如何使用 gcc 工具链强制二进制文件中的函数顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67176300/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com