.rodata重定位相关问题

3
我正在为一台无虚拟内存(或者更准确的说,没有操作系统)的机器编写C程序,并且在.rodata部分上遇到了一些困难,或者更准确地说是放在那里的东西。问题在于,尽管这些部分在链接过程中被定位在明确定义的地址处,但当程序执行时,它们会被重定位。
例如:假设我的程序从0x1000开始链接,在执行时,应该在0x1000处的内容将被重定位到0xff1000。
就是说,我的问题是通常放在.rodata的东西是由编译器(gcc)“硬编码”的,由于重定位和gcc硬编码它们的地址以获得绝对偏移量而不是相对偏移量,我有点失去了.rodata中的这些常量。
有没有办法让.rodata常量具有相对偏移量而不是绝对偏移量呢?通过相对偏移量,我是指相对于任何活动过程寄存器的偏移量。

可能只需要生成位置无关代码(使用GCC的-fPIC选项)。代码是否总是被重定位到0xff1000,还是会变化的? - user786653
它可能是可变的。我的意思是现在不是,但你永远不知道哪个程序会加载这段代码。我设法解决了这个问题,在手动重新定位代码到应该在的位置之后(这实际上是我应该达到的点,但这是牵强附会的,而且调试几乎不存在)。至于fPIC,我真的无法再测试了,但在一个-fPIC编译的源码和一个没有-fPIC的源码之间进行交叉引用后,似乎已经起作用了(尽管我不会抱太大希望,因为它做了一些相当奇怪的事情)。 - skyel
你正在编译到哪种目标格式?如果我没记错,.rodata 包含相对地址。这是加载器的工作,将它们添加到代码的基地址并相应地更新 .text 部分。我编写了自己的操作系统和应用程序加载器,这就是我能记得的。 - Unsigned
由于该问题尚未得到解答:请指明平台。 .rodata 包含只读数据,但其在内存中的位置是由定位器(通常是链接器的一部分)确定的,定位器接受指定可用内存区域的配置文件。也许您有一个配置文件指定了 .rodata 不同于您想要/认为/假设的位置。不过,我需要更多详细信息。 - Johan Bezem
1个回答

1

根据架构不同,.rodata可能会被任意重定位到特定的内存区域(例如ROM)。这种信息可以在机器数据手册中找到。 如果您处于这种情况下,您需要使用链接脚本告诉链接器将.rodata部分放置在正确的区域。 关于GCC链接器脚本的概述可以在此处找到:

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

此外,您可以在互联网上轻松找到许多针对特定架构的链接脚本。
希望这能帮到您!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接