gcc位置无关代码参数-fPIC/-fPIE/-pie的关系

  1. -fPIC
    是一个编译选择,生成位置无关的.o文件,这些.o文件可以用来链接生成动态库(.so),也可以用来生成可执行文件(包括位置无关或者位置固定的)。

  2. -fPIE
    与-fPIC类似,差别就是生成的.o文件不能用来链接生成动态度(.so),只能用来生成可执行文件(也包括位置无关或者位置固定的),。

  3. -pie
    是一个链接选项,它要求链接器使用的所有.o文件编译是必须使用-fPIC或者-fPIE。

补充一点,如果命令行中同时使用了-fPIC和-fPIE会怎么选?回答是gcc只会选后出现的一个,把前一个覆盖掉了,且不会给出任务提示信息。即-fPIC和-fPIE不可同时有效,出现在命令行后面的那个会替换前面的那个。

所以:

  1. 生成动态库的.o文件必须使用-fPIC编译选项。
  2. 生成可执行文件的.o文件则,
    2.1 如果链接没有-pie选项,则使用的.o文件在生成时可以使用-fPIC或者-fPIE,或者什么都没有。
    2.2 如果链接包含-pie选项,则使用的.o文件在生成时必须使用-fPIC或者-fPIE选项。
  3. 那么是不是-fPIE的价值不太大呢,因为完全可以使用-fPIC替代就行了;我觉得应该是是的,如果只考虑功能,任何使用-fPIE的地方都可以使用-fPIC代替,无非就是用-fPIE代替-fPIC在某些场景下能够减少一次GOT/PLT的位移计算,提升一些性能。

我们看一个-fPIC,和-fPIE,以及标准的(即无-fPIC,也无-fPIE)的差异例子:

       int global_var = 0x10;
       int global_func(void) { return 0x11; }

static int static_var = 0x20;
static int static_func(void) { return 0x21; }

extern int extern_var;
extern int extern_func(void);

int main(void) {
    int x = 0;
    x = global_func();
    global_var = 0x12;

    x = static_func();
    static_var = 0x22;

    x = extern_func();
    extern_var = 0x32;

    return 0;
}

使用gcc -c编译后看它们main函数生成的指令码差异:

image.png
  1. 在global变量和函数(global_var/global_func)的引用上,PIE代码和STD代码是一样的,都是直接使用地址,而PIC代码则计算GOT/PLT表位移。
  2. 在extern变量和函数(extern_var/extern_func)的引用上,PIE代码和PIC代码是一样的,都是计算 GOT/PLT表位移,而STD代码则是直接使用。
  3. 对static变量和函数(static_var/static_func)的引用上,所有PIE,PIC,和STD的使用都是一样的。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 记录一下PIC的要点,备以后用到的时候再查看 为什么想到PIC 想到PIC(其实是再次想到)实际是一个很偶然的机会...
    倪昕阅读 4,057评论 0 0
  • 一、温故而知新 1. 内存不够怎么办 内存简单分配策略的问题地址空间不隔离内存使用效率低程序运行的地址不确定 关于...
    SeanCST阅读 12,422评论 0 27
  • 最近看了一些PWN 的题目,在此总结一波,这篇文章有些资料来自各网友的总结。像我这样记忆力比较差的人,还是要多记录...
    simle天晴阅读 9,248评论 0 0
  • -E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面. 例子用法:gcc -E hello...
    wiseAaron阅读 7,943评论 0 1
  • 总结 NX:-z execstack / -z noexecstack (关闭 / 开启) Canary:-fno...
    HAPPYers阅读 13,954评论 0 3

友情链接更多精彩内容