【问题标题】:Why compile Android kernel module with -fno-pic?为什么要使用 -fno-pic 编译 Android 内核模块?
【发布时间】:2015-02-03 03:54:42
【问题描述】:

我经常读到 Android 内核模块必须使用 -fno-pic 编译才能工作。这是否特定于 ARM 架构,或者为什么不需要/(何时)x86 的内核模块需要使用该标志进行编译?

【问题讨论】:

标签: android linux-kernel kernel kernel-module


【解决方案1】:

根据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,在 SPARC 上为 28k m68k 和 RS/6000 上的 AArch64 和 32k。 x86 没有这样的限制。) 与位置无关的代码需要特殊支持,因此 仅适用于某些机器。 对于 x86,GCC 支持 PIC for System V,但不适用于 Sun 386i。为 IBM RS/6000 生成的代码 始终与位置无关。

设置此标志时,宏 __pic____PIC__ 被定义为 1.

所以-fno-pic 的意思是“不要使用与位置无关的代码 (PIC)。”

但是为什么呢?

好吧,通过查看https://developer.arm.com/products/software-development-tools/hpc/documentation/note-about-building-position-independent-code-pic-on-aarch64,我们发现:

在 AArch64 上对 GCC 编译器使用 -fpic 编译器标志会导致 编译器在每个地址计算中生成少一条指令 代码,并且可以提供代码大小和性能优势。然而, 它还为全局偏移表 (GOT) 设置了 32k 的限制,并且 构建可能在可执行链接阶段失败,因为 GOT 溢出。

所以,最后,-fno-pic 似乎更像是一种预防措施,而不是真正的需要。当然,这只是一种猜测,可能涉及更多的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-28
    • 1970-01-01
    • 2013-07-04
    • 2015-11-30
    • 1970-01-01
    • 2011-05-03
    • 1970-01-01
    相关资源
    最近更新 更多