【待整理】Gcc中编译和链接选项 -fpic -fPIC -fpie -fPIE -pie的含义

-fpic

Generate position-independent code (PIC) suitable for use in a shared library, if supported for the target machine. Such code accesses all constant addresses through a global offset table (GOT). The dynamic loader resolves the GOT entries when the program starts (the dynamic loader is not part of GCC; it is part of the operating system). If the GOT size for the linked executable exceeds a machine-specific maximum size, you get an error message from the linker indicating that -fpic does not work; in that case, recompile with -fPIC instead. (These maximums are 8k on the SPARC and 32k on the m68k and RS/6000. The 386 has no such limit.)

Position-independent code requires special support, and therefore works only on certain machines. For the 386, GCC supports PIC for System V but not for the Sun 386i. Code generated for the IBM RS/6000 is always position-independent.

When this flag is set, the macros __pic__ and __PIC__ are defined to 1.

-fPIC

If supported for the target machine, emit position-independent code, suitable for dynamic linking and avoiding any limit on the size of the global offset table. This option makes a difference on the m68k, PowerPC and SPARC.

Position-independent code requires special support, and therefore works only on certain machines.

When this flag is set, the macros __pic__ and __PIC__ are defined to 2.

-fpie

-fPIE

These options are similar to -fpic and -fPIC, but generated position independent code can be only linked into executables. Usually these options are used when -pie GCC option will be used during linking.

-fpie and -fPIE both define the macros __pie__ and __PIE__. The macros have the value 1 for -fpie and 2 for -fPIE.

-fno-jump-tables

Do not use jump tables for switch statements even where it would be more efficient than other code generation strategies. This option is of use in conjunction with -fpic or -fPIC for building code which forms part of a dynamic linker and cannot reference the address of a jump table. On some targets, jump tables do not require a GOT and this option is not needed.

————————————————–

Position-Independent-Executable是Binutils,glibc和gcc的一个功能,能用来创建介于共享库和通常可执行代码之间的代码–能像共享库一样可重分配地址的程序,这种程序必须连接到Scrt1.o。标准的可执行程序需要固定的地址,并且只有被装载到这个地址时,程序才能正确执行。PIE能使程序像共享库一样在主存任何位置装载,这需要将程序编译成位置无关,并链接为ELF共享对象。

引入PIE的原因是让程序能装载在随机的地址,通常情况下,内核都在固定的地址运行,如果能改用位置无关,那攻击者就很难借助系统中的可执行码实施攻击了。类似缓冲区溢出之类的攻击将无法实施。而且这种安全提升的代价很小

谈到PIE就不得不说说Pax和Grsec内核。这两个东西都是为了构建坚不可摧到安全系统而准备的。PaX是Linux内核安全增强补丁,它能在两方面保证安全性,一是ASLR(Address Space Layout Randomization,地址空间分布随机化),这是一种将所有数据装载到内存时都随机化地址的方式,当使用PIE选项编译应用时,PaX能将应用的地址做随机加法;二是能提供不可执行的内存空间,这样就能使得攻击者放入内存中的恶意代码不可执行。不过PaX官网上能支持的最新内核是2.6.27,已经是一年前的更新了。Grsec也时类似的内核补丁,更新较为频繁能支持最新的2.6.32内核。这两种方式都能将内核完全位置无关,除了Grub和Glibc中无法位置无关的汇编码。

PIE最早由RedHat的人实现,他在连接起上增加了-pie选项,这样使用-fPIE编译的对象就能通过连接器得到位置无关可执行程序。fPIE和fPIC有些不同。可以参考Gcc和Open64中的-fPIC选项.

gcc中的-fpic选项,使用于在目标机支持时,编译共享库时使用。编译出的代码将通过全局偏移表(Global Offset Table)中的常数地址访存,动态装载器将在程序开始执行时解析GOT表项(注意,动态装载器操作系统的一部分,连接器是GCC的一部分).而gcc中的-fPIC选项则是针对某些特殊机型做了特殊处理,比如适合动态链接并能避免超出GOT大小限制之类的错误。而Open64仅仅支持不会导致GOT表溢出的PIC编译。

gcc中的-fpie和-fPIE选项和fpic及fPIC很相似,但不同的是,除了生成为位置无关代码外,还能假定代码是属于本程序。通常这些选项会和GCC链接时的-pie选项一起使用。fPIE选项仅能在编译可执行码时用,不能用于编译库。所以,如果想要PIE的程序,需要你除了在gcc增加-fPIE选项外,还需要在ld时增加-pie选项才能产生这种代码。即gcc -fpie -pie来编译程序。单独使用哪一个都无法达到效果。

你可以使用file命令来查看当前的可执行文件是不是PIE的。

下面是本博编译helloword的显示。可以看出,可执行文件属性从executable变成了shared object.

$ gcc  helloworld.c

$ file a.out

a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped

$ gcc -fpie -pie helloworld.c

$ file a.out

a.out: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped

接下来,我们就能实验了,使用strace命令来查看这两个a.out执行情况了。关于strace命令,可以参考strace命令介绍

在博主电脑上,有PIE时,执行第一个brk(0)系统调用时,返回的地址一直是变化的。而无PIE时,brk(O)系统调用返回地址一直不变。内容太多,不再贴出。

注:

linux系统调用brk():

linux系统内部分配内存的系统调用,malloc()其实也是调用的brk().直接修改堆的大小,返回新内存区域的结束地址。

————————————————–

说实话,还是看的不是很懂,似懂非懂的感觉。

arm linux gcc fpic,【待整理】Gcc中编译和链接选项 -fpic -fPIC -fpie -fPIE -pie的含义相关推荐

  1. linux的网络命令整理 更新中

    linux的网络命令整理 更新中 1.安装包: net-tools 主要命令: netstat , ifconfig , route , iptunnel iproute 主要命令: ss , ip ...

  2. gcc ------ 编译与链接选项及CFLAGS、LDFLAGS、LIBS

    gcc ------ 编译与链接选项及CFLAGS.LDFLAGS.LIBS GCC手册:https://gcc.gnu.org/onlinedocs/ GCC编译选项CFLAGS参数 选项 说明 - ...

  3. Linux系统中编译、链接的基石-ELF文件:扒开它的层层外衣,从字节码的粒度来探索

    初次见面 大家好,我是 ELF 文件,大名叫 Executable and Linkable Format. 经常在 Linux 系统中开发的小伙伴们,对于我肯定是再熟悉不过了,特别是那些需要了解编译 ...

  4. Linux系统中编译、链接的基石-ELF文件:扒开它的层层外衣,从字节码的粒度来探索...

    初次见面 大家好,我是 ELF 文件,大名叫 Executable and Linkable Format. 经常在 Linux 系统中开发的小伙伴们,对于我肯定是再熟悉不过了,特别是那些需要了解编译 ...

  5. arm linux输出到lcd,求助 armlinux中实现lcd显示

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 /* for (bufIdx=0; bufIdx < NUM_DISPLAY_BUFS-1; bufIdx++) { fbp[bufIdx+1] = ...

  6. Linux篇【3】:Linux环境基础开发工具使用(中)

    目录 一.Linux 编译器:gcc/g++ 的使用 1.1.知识拓展: 1.2.如何安装 C/C++ 标准静态库: 1.3.头文件与库文件: 1.4.静态库,静态链接,动态库,动态链接: 二.简单 ...

  7. gcc常用命令与gcc编译器背后的故事

    目录 1 gcc常用命令 1.1 简介 1.2 简单编译 1.2.1 预处理 1.2.2 编译为汇编代码(Compilation) 1.2.3 汇编(Assembly) 1.2.4 连接(Linkin ...

  8. GCC常用命令及GCC编译器背后的故事

    文章目录 一. GCC常用命令 1. 简介 2. 简单编译 2.1 预处理 2.2 编译为汇编代码(Compilation) 2.3 汇编(Assembly) 2.4 连接(Linking) 3. 多 ...

  9. 第三十四期-ARM Linux内核的中断(4)

    作者:罗宇哲,中国科学院软件研究所智能软件研究中心 上一期中我们介绍了ARM Linux内核中外设中断处理的部分流程,这一期我们将继续介绍ARM Linux内核的外设中断处理流程中与中断描述符相关的部 ...

最新文章

  1. CentOS6.9编译安装Nginx1.12
  2. Nagios 监控系列学习 —— 简介和安装
  3. 如何使用 ABAP 报表将 ABAP 服务器上的 SAP UI5 应用下载到本地
  4. Media Query在SAP Spartacus里的用途
  5. 设置停靠模式,切割设置星级图标
  6. React之初始化state
  7. python写一个路径选择app_django下创建多个app并设置urls方法
  8. dreawever与php做网页,教程方法;Drea、mweaver CS5更改代码颜色方法电脑技巧-琪琪词资源网...
  9. 人工智能_TensorFlow工作笔记003---在pycharm中安装TensorFlow
  10. Aix5.3安装Bash Shell环境
  11. 面试复习笔记二(javaweb)
  12. win10音量图标没有了
  13. SpringBoot生成条形码
  14. java 压制警报_适用于Java开发人员的微服务:监视和警报
  15. 生活是苦难的,我又划着我的断桨出发了
  16. 怎样从微博下载视频?
  17. 多进程动态规划破解微信小程序水排序谜题
  18. Android设置全屏代码
  19. 申报须知,2022年滁州市各区县高新技术企业奖励政策变化,明光市
  20. android+代码调用+相册+小米,Android调用系统相册选择图片,支持小米4云相册

热门文章

  1. 决策树和随机森林(下)
  2. libsvm matlab 调参数,matlab – 使用libsvm调整svm
  3. 从ICCV 2021看夜间场景自监督深度估计最新进展
  4. 博士申请 | 瑞典皇家理工学院分布式计算研究组招收NLP/ML全奖博士生
  5. 直播 | ACL 2021论文解读:低资源语言场景下的跨语言文本摘要
  6. 决赛评委阵容重磅公布!6万大奖,超分辨率图像性能挑战赛最后召集令!
  7. 烟台大学计算机学院老师,王鹏-烟台大学计算机与控制工程学院
  8. 【算法系列之线索化二叉树,前序线索化、中序线索化、后序线索化以及遍历~】
  9. Python——中国大学MOOC——神经网络与深度学习——Matblotlib绘图基础
  10. Visual C++——加速键