2012-02-11 27 views
2

请有人帮忙。 我创建一个共享库,并与本指令运行此给出了一个错误 “GCC -shared libx.o -o libx.so”希望对内存级共享库有很好的理解

/usr/lib64/gcc/x86_64-suse-linux/4.3/ ../../../../x86_64-suse-linux/bin/ld:libx.o:在创建共享对象时,无法使用针对`.rodata'的重定位R_X86_64_32; 重新编译-fPIC libx.o:看不懂的符号:

collect2错误值:LD返回1退出状态

所以,我用-fPIC运行它,它编译,请你给我一个对内存级的-FPIC意义有很好的理解,我的意思是它是如何在使用这个共享库的两个程序之间的物理内存中共享的。

非常感谢。

+0

[GCC -fPIC选项]的可能重复(https://stackoverflow.com/questions/5311515/gcc-fpic-option) – 2017-07-27 22:03:36

回答

1

的副本对于虚拟内存系统加载器很可能会共享代码映射到在一些连续的页面正在使用该库的应用程序的内存空间。为了在多个进程之间共享这些页面,它们必须是:

  1. 只读。
  2. 能够映射到进程的地址空间中的任意位置。

后果:

  1. 大多数代码是不是只读的,因为它不能只是被映射到进程的内存空间,并运行 - 它必须首先通过的方式加载程序进行修改这是特定于每个过程。为了实现只读文本,您需要将-fpic选项传递给编译器。这会导致编译器生成较不理想的机器码,但具有只读的优点。

  2. 有效代码通常不能映射到地址空间中的任意位置。通常高效的代码要么限制在特定的地址上,要么限制在低地址范围内。 -fpic选项指示编译器使用效率较低的代码,但不受运行位置约束的限制。

现在我们能理解您的问题:

反对搬迁R_X86_64_32`.RODATA” - 这里的链接器警告您的编译器使用的被限制在运行于低范围的codgen地址。因此,它不适合在共享库中使用。