我经常读到必须使用-fno-pic
编译Android内核模块才能工作。这是针对ARM体系结构的,还是为什么不需要/(什么时候)x86的内核模块需要使用该标志进行编译?
答案 0 :(得分:0)
根据https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/Code-Gen-Options.html,-fno-pic
是-fpic
参数的否定形式。从同一链接:
-fpic如果目标计算机支持,则生成适用于共享库的位置无关代码(PIC)。这样的代码 通过全局偏移表(GOT)访问所有常量地址。 程序启动时,动态加载程序会解析GOT条目 (动态加载程序不是GCC的一部分;它是运行中的一部分 系统)。如果链接的可执行文件的GOT大小超过 特定于计算机的最大大小,您会从 链接器,指示-fpic不起作用;在这种情况下,重新编译 而是使用-fPIC。 (在SPARC上,这些最大值为8k;在 m68k和RS / 6000上为AArch64和32k。 x86没有这样的限制。) 与位置无关的代码需要特殊的支持,因此 仅适用于某些计算机。对于x86,GCC支持PIC 系统V,但不适用于Sun 386i。为IBM RS / 6000生成的代码 始终与位置无关。
设置此标志后,宏
__pic__
和__PIC__
定义为 1。
所以-fno-pic
的意思是“不要不要使用与位置无关的代码(PIC)”。
但是为什么?
在AArch64上将-fpic编译器标志与GCC编译器一起使用会导致 编译器在每个地址计算中减少一条指令 代码,并可以提供代码大小和性能优势。然而, 它还为全局偏移表(GOT)设置了32k的限制,并且 由于GOT,构建可能会在可执行文件链接阶段失败 溢出。
因此,最后,-fno-pic
似乎比实际需要更多的是预防措施。当然,这只是一个猜测,可能涉及更多的事情。