gcc

您所在的位置:网站首页 编译so库加fpic与不加fpic的区别 gcc

gcc

2024-07-15 23:07| 来源: 网络整理| 查看: 265

gcc -fpic 和 -fPIC 参数问题

目的:生成位置无关的代码。

位置无关代码(Position-Independent Code),则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。

如果不加-fPIC,则加载.so文件的代码段时,代码段引用的数据对象需要重定位, 重定位会修改代码段的内容,这就造成每个使用这个.so文件代码段的进程在内核里都会生成这个.so文件代码段的copy.每个copy都不一样,取决于 这个.so文件代码段和数据段内存映射的位置. 也就是 不加fPIC编译出来的so,是要再加载时根据加载到的位置再次重定位的.(因为它里面的代码并不是位置无关代码) 如果被多个应用程序共同使用,那么它们必须每个程序维护一份.so的代码副本了.(因为.so被每个程序加载的位置都不同,显然这些重定位后的代码也不同,当然不能共享) 我们总是用fPIC来生成so,也从来不用fPIC来生成.a;fPIC与动态链接可以说基本没有关系,libc.so一样可以不用fPIC编译,只是这样的so必须要在加载到用户程序的地址空间时重定向所有表目.

下面情况可以不用fPIC编译动态库so:

1.该库可能需要经常更新 2.该库需要非常高的效率(尤其是有很多全局量的使用时) 3.该库并不很大. 4.该库基本不需要被多个应用程序共享

如果用没有加这个参数的编译后的共享库,也可以使用的话,可能是两个原因: 1:gcc默认开启-fPIC选项 2:loader使你的代码位置无关

 

gcc 官网解释:https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options

-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, 28k on AArch64 and 32k on the m68k and RS/6000. The x86 has no such limit.)

Position-independent code requires special support, and therefore works only on certain machines. For the x86, 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.

如果目标计算机支持,则生成适合在共享库中使用的位置无关代码(PIC)。 这样的代码通过全局偏移表(GOT)访问所有常量地址。 动态加载程序在程序启动时解析GOT条目(动态加载程序不是GCC的一部分;它是操作系统的一部分)。 如果链接的可执行文件的GOT大小超过了计算机特定的最大大小,则您会从链接程序中收到一条错误消息,指示-fpic无法正常工作; 在这种情况下,请改用-fPIC重新编译。 (这些最大值在SPARC上为8k,在AArch64上为28k,在m68k和RS / 6000上为32k。x86没有此限制。)

与位置无关的代码需要特殊的支持,因此仅在某些机器上有效。 对于x86,GCC支持PIC for System V,但不支持Sun 386i。 为IBM RS / 6000生成的代码始终与位置无关。

设置此标志后,宏__pic__和__PIC__被定义为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 AArch64, 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.

如果目标机器支持,则发出与位置无关的代码,该代码适用于动态链接并避免对全局偏移表的大小进行任何限制。 此选项对AArch64,m68k,PowerPC和SPARC有所不同。

与位置无关的代码需要特殊的支持,因此仅在某些机器上有效。

设置此标志后,宏__pic__和__PIC__被定义为2。

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3