6

我正在寻找一种简单的方法来重新排序 ELF 文件部分。我有一系列自定义部分,我希望所有部分都按特定顺序对齐。

我发现如何做到这一点的唯一方法是使用链接器脚本。但是,文档表明指定自定义链接器脚本会覆盖默认值。默认链接描述文件中有很多内容,我不想在我的自定义脚本中复制这些内容只是为了让三个部分始终按特定顺序放在一起。像这样对链接器行为进行硬编码似乎不是很灵活。

我为什么要这样做?我有一段数据需要知道(开始和结束)的运行时内存位置。所以我创建了两个额外的部分并将哨兵变量放入其中。然后我想使用这些变量的内存位置来了解内存中未知部分的范围。

.markerA 
    int markerA;
.targetSection
    ... Lots of variables ...
.markerB
    int markerB;

在上面的例子中,我知道 .targetSection 中的数据在 markerA 和 markerB 的地址之间。

还有另一种方法可以做到这一点吗?是否有库可以让我读取当前执行的 ELF 图像并确定部分位置和大小?

4

4 回答 4

4

您可以通过分析 ELF-File 格式来获取已加载段的地址。详细信息可以在例如

  • 工具接口标准 (TIS) 可移植格式规范,版本 1.2 (http://refspecs.freestandards.org/elf/elf.pdf)

为了简短的印象,哪些信息是可用的,值得看看 readelf

readelf -S <filename> 

返回 中包含的所有部分的列表。

  1. 映射到内存中的部分被键入 PROGBITS。
  2. 您要查找的地址显示在 Addr 列中。
  3. 要获取内存位置,您必须添加可执行文件/共享对象的加载地址

有几种方法可以确定可执行/共享对象的加载地址:

  1. 您可以解析 /proc/[pid]/maps (第一列包含加载地址)。[pid] 是进程 ID
  2. 如果您知道文件中包含一个函数,则可以申请dlsym接收指向该函数的指针。该指针是用于dladdr返回Dl_info包含请求的加载地址的结构的输入参数

要获取一些 ELF 信息,请使用库

  • 自由

可能是一个有用的同伴(我在研究上述 TIS 后发现了它,所以我只看了一眼,我不知道更深的细节)

我希望这个可能的解决方案的草图会有所帮助。

于 2011-05-20T19:58:39.290 回答
1

您可以考虑使用 GCC 的初始化程序来引用变量,否则这些变量将进入单独的部分,并将它们的所有指针保存在一个数组中。我推荐使用初始化器,因为它独立于文件工作。

于 2011-05-21T18:34:10.697 回答
0

您可以查看ELFIO 库。它包含 WriteObj 和 Writer 示例。通过使用该库,您将能够以编程方式创建/修改 ELF 二进制文件。

于 2011-06-10T00:25:51.210 回答
0

恐怕覆盖默认链接脚本是简单的解决方案。

由于您担心它可能不灵活(即使我认为链接脚本确实经常更改),您可以编写一个脚本以基于主机系统的默认 ld 脚本(“ld --verbose”)生成链接脚本并插入您的特殊的部分。

于 2014-07-27T07:16:20.867 回答