GCC,PIE,PIC,档案和共享对象 - 什么有用?

时间:2014-10-09 10:39:10

标签: gcc

我对GCC,ThreadSanitizer以及档案,共享库以及PIE和PIC的使用有疑问。

我整个上午都尽力阅读,但我无法在线找到有用,清晰的信息。

我理解PIC的作用。我想我明白PIE就是你喜欢PIC的优化版本,它只适用于可执行文件。

现在问题......

  1. 我可以使用PIC而不是PIE编译可执行文件吗?

  2. 如果我用PIC编译共享库(.so),那么我是否必须将PIC与任何使用该库的可执行文件一起使用,而不是PIE?

  3. 如果我编译档案(.a),我可以使用PIE吗? (我读过-static和-pie不应该一起使用,这意味着没有。)

  4. 我正在使用ThreadSanitizer。这需要PIC(也许PIE也可以 - 但正如你所看到的,我并不清楚这一点)。我有一个库,可以编译为存档(.a)或共享库(.so)。该库需要使用ThreadSanitizer。但是,使用它的二进制文件也需要使用ThreadSanitizer(因为它有一些需要检查的代码)。

    构建为共享库的库实际上在使用ThreadSanitizer时无法链接 - 我认为该链接无法链接到libtsan(但我怀疑这不是一个真正的库,而是内置的一堆编译器instrinc GCC)。这几乎可以肯定是我在某处弄错了。

    我真正想要做的是使用存档(.a),因为二进制文件是一个测试程序,并且应该能够在没有安装库的情况下进行编译(因此用户可以方便地检查/测试库 - makefile for the测试二进制文件具有存档二进制文件的硬编码路径。

    如果我可以将PIE与档案(.a)一起使用,那么我就可以对库和测试二进制文件进行PIE。如果PIE不能与档案一起使用,那么我认为我需要将PIC与库和测试二进制文件一起使用。我根本不想使用共享库,因为ThreadSanitizer大量使用TLS(线程本地存储),而与PIC共享的库具有绝对可怕的TLS性能。

1 个答案:

答案 0 :(得分:6)

pic和pie的终极功能相同,但gcc -fpic用于创建共享库,而-fpie用于exes。

  1. 不,你不能将pic用于可执行文件

  2. 共享库并不关心馅饼(PIE只是使exec位置独立)或普通高管正在使用它。它是链接共享库的动态链接器(ld.so)作业。

  3. 在使用静态库时,不能让exec位置独立。当你将exec与静态库链接起来时,它会创建一个对exec的依赖,并且必须在compile-time解析这些符号。所以简而言之,你就可以了。

  4. 我在办公后回答休息