gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 00:35:13 24 4
gpt4 key购买 nike

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

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

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

我唯一找到的是-fno-toplevel-reorder这对我没有帮助。

最佳答案

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

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

在其他程序期望的地址处提供蹦床几乎是最简单的,并且具有这些指向的实际功能(无论它们可能在哪里)。这将要求您的代码使用不同的基地址,因此实际的程序代码不会与蹦床发生冲突。

为函数提供固定地址几乎可以使用三件事:

  • 您可以使用 __attribute__ ((section ("some name"))) 将每个不允许移动的功能放在其适当的部分中。 .不幸的是,.text总是作为第一部分出现,所以如果 .text 中有任何内容更改因此大小超过 512 字节边界,您的偏移量将发生变化。默认情况下(但见下文)您无法在 .text 之前开始某个部分.
  • -falign-functions=n命令行选项可让您将函数与边界对齐。通常这是大约 16 个字节。现在,您可以选择一个较大的值,例如 1024。这将浪费大量空间,但也可以确保只要函数只是适度更改,以下函数的地址将保持不变。显然,它仍然不能阻止编译器/链接器在需要时重新排序整个 block (尽管 -fno-toplevel-reorder 将至少部分阻止这种情况)。
  • 如果你愿意写自定义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/6614209/

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