C语言 R_X86_64_32S 和 R_X86_64_64 重定位是什么意思?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6093547/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 08:44:00  来源:igfitidea点击:

What do R_X86_64_32S and R_X86_64_64 relocation mean?

ccompiler-constructionlinkerelfrelocation

提问by Raj

Got the following error when I tried to compile a C application in 64-bit FreeBSD:

当我尝试在 64 位 FreeBSD 中编译 C 应用程序时出现以下错误:

relocation R_X86_64_32S can not be used when making a shared object; recompile with -fPIC

relocation R_X86_64_32S 在制作共享对象时不能使用;用 -fPIC 重新编译

What is R_X86_64_32Srelocation and what is R_X86_64_64?

什么是R_X86_64_32S搬迁,什么是R_X86_64_64

I've googled about the error, and it's possible causes - It'd be great if anyone could tell what R_X86_64_32S really means.

我在谷歌上搜索了这个错误,这可能是原因 - 如果有人能说出 R_X86_64_32S 的真正含义,那就太好了。

采纳答案by Michael Foukarakis

The R_X86_64_32Sand R_X86_64_64are names of relocation types, for code compiled for the amd64 architecture. You can look all of them up in the amd64 ABI. According to it, R_X86_64_64is broken down to:

R_X86_64_32SR_X86_64_64是重定位类型的名称,编为AMD64架构的代码。您可以在amd64 ABI 中查找所有这些。根据它,R_X86_64_64分解为:

  • R_X86_64 - all names are prefixed with this
  • 64 - Direct 64 bit relocation
  • R_X86_64 - 所有名称都以 this 为前缀
  • 64 - 直接 64 位重定位

and R_X86_64_32Sto:

R_X86_64_32S

  • R_X86_64 - prefix
  • 32S - truncate value to 32 bits and sign-extend
  • R_X86_64 - 前缀
  • 32S - 将值截断为 32 位并进行符号扩展

which basically means "the value of the symbol pointed to by this relocation, plus any addend", in both cases. For R_X86_64_32Sthe linker then verifies that the generated value sign-extends to the original 64-bit value.

在这两种情况下,这基本上意味着“此重定位指向的符号的值,加上任何加数”。对于R_X86_64_32S链接器,然后验证生成的值是否符号扩展为原始 64 位值。

Now, in an executable file, the code and data segments are given a specified virtual base address. The executable code is not shared, and each executable gets its own fresh address space. This means that the compiler knows exactly where the data section will be, and can reference it directly. Libraries, on the other hand, can only know that their data section will be at a specified offset from the base address; the value of that base address can only be known at runtime. Hence, all libraries must be produced with code that can execute no matter where it is put into memory, known as position independent code (or PIC for short).

现在,在一个可执行文件中,代码和数据段被赋予了一个指定的虚拟基地址。可执行代码不共享,每个可执行文件都有自己的新地址空间。这意味着编译器确切地知道数据段的位置,并且可以直接引用它。另一方面,库只能知道它们的数据部分将位于距基地址的指定偏移处;该基地址的值只能在运行时知道。因此,所有库都必须使用无论放入内存何处都可以执行的代码生成,称为位置无关代码(或简称 PIC)。

Now when it comes to resolving your problem, the error message speaks for itself.

现在,在解决您的问题时,错误消息不言自明。

回答by Artyom

That means that compiled a shared object without using -fPICflag as you should:

这意味着在不使用-fPIC标志的情况下编译共享对象,您应该这样做:

 gcc -shared foo.c -o libfoo.so # Wrong

You need to call

你需要打电话

 gcc -shared -fPIC foo.c -o libfoo.so # Right

Under ELF platform (Linux) shared objects are compiled with position independent code - code that can run from any location in memory, if this flag is not given, the code that is generated is position dependent, so it is not possible to use this shared object.

在 ELF 平台 (Linux) 下,共享对象使用位置无关代码编译 - 可以从内存中的任何位置运行的代码,如果未给出此标志,则生成的代码是位置相关的,因此无法使用此共享目的。

回答by jonawebb

I ran into this problem and found this answer didn't help me. I was trying to link a static library together with a shared library. I also investigated putting the -fPIC switch earlier on the command line (as advised in answers elsewhere). The only thing that fixed the problem, for me, was changing the static library to shared. I suspect the error message about -fPIC can happen due to a number of causes but fundamentally what you want to look at is how your libraries are being built, and be suspicious of libraries that are being built in different ways.

我遇到了这个问题,发现这个答案对我没有帮助。我试图将静态库与共享库链接在一起。我还研究了将 -fPIC 开关更早地放在命令行上(如其他地方的答案中所建议的那样)。对我来说,解决问题的唯一方法是将静态库更改为共享。我怀疑有关 -fPIC 的错误消息可能由于多种原因而发生,但从根本上说,您想要查看的是您的库是如何构建的,并对以不同方式构建的库持怀疑态度。

回答by XavierStuvw

In my case the issue arose because the program to compile expected to find shared libraries in a remote directory, while only the corresponding static libraries were there in a mistake.

在我的情况下,问题出现是因为要编译的程序希望在远程目录中找到共享库,而只有相应的静态库出错了。

Actually, this relocation error was a file-not-found error in disguise.

实际上,这个重定位错误是变相的文件未找到错误。

I have detailed how I coped with it in this other thread https://stackoverflow.com/a/42388145/5459638

我在另一个线程中详细说明了我是如何处理它的https://stackoverflow.com/a/42388145/5459638