【问题标题】:.rodata relocation related question.rodata 搬迁相关问题
【发布时间】:2011-10-28 18:44:02
【问题描述】:

我正在尝试为没有虚拟内存(或者更准确地说是操作系统)的机器编写一个 C 程序,但我在 .rodata 部分遇到了一些困难,或者更准确地说是那里的东西.问题出现了,虽然在链接过程中这些节被定位在明确定义的地址,但当程序开始执行时,它正在被重新定位。

例如:假设我的程序开始链接到从 0x1000 开始,当它被执行时,应该在 0x1000 的内容被重新定位在 0xff1000。

话虽如此,我的问题是,通常进入 .rodata 的内容是由编译器(gcc)“硬编码”的,并且由于重定位和 gcc 对它们的地址进行硬编码,我有点失去了内存中的 .rodata 常量以便他们获得绝对偏移量而不是相对偏移量。

有没有一种方法可以让 .rodata 常量具有相对偏移量而不是绝对偏移量。相对,我的意思是相对于任何活动的进程寄存器?

【问题讨论】:

  • 这可能就像生成与位置无关的代码一样简单(-fPIC 使用 GCC)。代码是始终重定位到0xff1000 还是可变的?
  • 它可能是可变的。我的意思是现在不是,但你永远不知道是什么程序加载了这段代码。在手动将代码重新定位到它应该在的位置之后,我设法解决了这个问题(这实际上是我应该到达的地方,但它是牵强的,调试几乎不存在)。至于 fPIC,我真的无法再测试它了,但是在 -fPIC 编译源和没有 -fPIC 的源之间进行交叉引用之后,它似乎已经工作了(虽然我不会屏住呼吸,因为它确实一些很奇怪的东西)
  • 你要编译成什么目标格式? .rodata 确实,IIRC,包含相对地址。加载程序的工作是将它们添加到代码的基地址并相应地更新 .text 部分。我编写了自己的操作系统和应用程序加载器,这就是我能记住的。
  • 由于此问题尚未得到解答:请说明平台。 .rodata 包含只读数据,但它在内存中的位置由定位器(通常是链接器的一部分)确定,它采用一个配置文件来指定可用的内存区域。也许你有一个配置文件为.rodata 指定了一个不同于你想要/认为/假设的位置。不过,我需要更多细节。

标签: c low-level-code


【解决方案1】:

根据架构,.rodata 可能会被任意重定位到特定的内存区域(例如 ROM)。此类信息可在您的机器数据表中找到。 如果是这种情况,您必须使用链接描述文件告诉链接将您的 .rodata 部分放在正确的区域中。 可以在此处找到有关 GCC 链接器脚本如何工作的一个很好的概述:

http://www.scoberlin.de/content/media/http/informatik/gcc_docs/ld_3.html

此外,您可以在互联网上轻松找到许多特定于架构的链接脚本。

希望有所帮助!

【讨论】:

    猜你喜欢
    • 2015-05-07
    • 1970-01-01
    • 2013-03-18
    • 2013-04-29
    • 2012-04-23
    • 1970-01-01
    • 1970-01-01
    • 2020-12-26
    • 1970-01-01
    相关资源
    最近更新 更多