R_X86_64_32S和R_X86_64_64重定位是什么意思?
|
当我尝试在64位FreeBSD中编译C应用程序时出现以下错误:
创建共享库时,不能使用重定位R_X86_64_32S;用-fPIC重新编译
什么是“ 0”重定位,什么是“ 1”重定位?
我一直在搜索该错误,并且可能是由该原因引起的-如果有人能说出R_X86_64_32S的真正含义,那就太好了。
没有找到相关结果
已邀请:
5 个回复
室邢
和
是重定位类型的名称,用于为amd64架构编译的代码。您可以在amd64 ABI中查找所有这些文件。 根据它,ѭ1被分解为: R_X86_64-所有名称都带有前缀 64-直接64位重定位 和
到: R_X86_64-前缀 32S-将值截断为32位并进行符号扩展 在两种情况下,这基本上表示\“此重定位所指向的符号的值加上任何加数\”。然后对于链接器“ 0”,验证生成的值是否符号扩展为原始的64位值。 现在,在可执行文件中,为代码和数据段指定了指定的虚拟基址。可执行代码不共享,每个可执行文件都有其自己的新地址空间。这意味着编译器确切知道数据段将在哪里,并可以直接引用它。另一方面,库只能知道其数据段与基地址之间有指定的偏移量。该基地址的值只能在运行时知道。因此,所有库必须使用无论位置如何都可以执行的代码(称为位置无关代码(简称PIC))生成。 现在,当要解决您的问题时,错误消息说明了一切。
凰葱崎济邯
,
和
均由System V AMD ABI定义,其中包含ELF文件格式的AMD64细节。 它们都是重定位条目的“ 10”字段的所有可能值,在System V ABI 4.1(1997)中指定,该字段指定ELF格式的体系结构中立部分。该标准仅指定字段,而不指定与拱有关的值。 在4.4.1 \“重定位类型\”下,我们看到摘要表:
我们将在后面解释该表。 并注意:
和
重定位将计算值截断为32位。链接器必须验证R_X86_64_32(R_X86_64_32S)重定位的生成值零扩展(符号扩展)为原始64位值。 R_X86_64_64和R_X86_64_32的示例 让我们先来看看
和
:
然后:
包含:
在Ubuntu 14.04和Binutils 2.24上进行了测试。 现在暂时忽略反汇编(因为这是数据,所以没有意义),而只看标签,字节和重定位。 第一次搬迁:
意思是:
:作用于字节0(标签
)
:AMD64系统V ABI的所有重定位类型使用的前缀
:标签
的64位地址被截断为32位地址,因为我们仅指定了
(4个字节)
:我们在
部分
:这是加数,是重定位条目的字段 重定位的地址计算如下:
哪里:
:加号,here31ѭ
:重定位前符号的值,here33ѭ 因此,在重定位之后,新的地址将在“ 26”节中为0xC == 12个字节。 这正是我们的期望,因为
紧随
(4字节)和
(8字节)之后。
与之类似,但是更简单,因为这里不需要截断
的地址。这是通过through40ѭ而不是
列中的
表示的。 R_X86_64_32S和R_X86_64_32
与
的区别在于链接器将抱怨“截断位置适合””:
:抱怨如果重定位后的截断值不为零,则扩展旧值,即截断的字节必须为零: 例如:
至
会产生投诉,因为
不为零。
:抱怨如果重定位后的截断值没有符号,则扩展旧值。 例如:
到
很好,因为
的最后一位和截短的位都为1。 另请参阅:这个GCC错误“ ...重定位被截断以适合...”是什么意思?
可通过以下方式生成:
然后:
给出:
现在我们可以观察到带有链接描述文件的\“ relocation \”被截断以适合
:
现在:
很好,因为:
被截断为into61ѭ,这是一个符号扩展。 但是,如果我们将链接描述文件更改为:
现在它会产生错误,因为ѭ20不再使它成为符号扩展。 使用ѭ49进行内存访问而用ѭ23进行即时访问的理由:什么时候汇编程序最好使用R_X86_64_32S之类的符号扩展重定位而不是使用R_X86_64_32之类的零扩展名? R_X86_64_32S和PIE(与位置无关的可执行文件 R_X86_64_32S不能用于位置无关的可执行文件,例如用
完成,否则链接失败:
升 我在以下位置提供了一个解释它的最小示例:gcc和ld中与位置无关的可执行文件的-fPIE选项是什么?
董碘奴星
标志:
你需要打电话
在ELF平台(Linux)下,共享对象使用位置无关的代码进行编译-可以在内存中任何位置运行的代码,如果未指定此标志,则生成的代码与位置有关,因此无法使用此共享宾语。
布埃郝卞簿
砷竣阿