我指的是linux/arch/arm/kernel/module.c。它似乎是ARM ELF重定位的任意子集。 manual列出了大约130种重定位类型。其中大多数都是“静态的”(为什么模块加载器处理静态重定位而不是动态重定位?)是因为GCC只输出这些类型吗?或者还有其他原因吗?
答案 0 :(得分:0)
ARM手册适用于所有ELF 文件;这包括链接之前的'C'编译器输出。 130重定位类型适用于各种情况;模块加载器只处理它们的子集。对于共享库和内核模块,最终输出不知道它的最终地址,但它知道所有函数/数据相对于彼此的位置。需要处理绝对重定位。
它不会尝试将'.o'文件链接在一起以生成'.ko'。这是由ld
完成的,它将处理更多的重定位类型,但可能仍然不是全部。 规范旨在全局完成。在目标CPU上可能存在某种类型的重定位(例如一些非常旧的ARM1 26位)。
答案 1 :(得分:0)
我从ARM Linux新闻组得到以下答案: http://lists.infradead.org/pipermail/linux-arm-kernel/2015-May/345809.html
在用于编译内核的配置下,只有一个 这些重新安置的一小部分将由GCC发布。对于 例如,因为我们正在构建没有-fpic,许多GOT和PLT 相关的将永远不会发生。并且,因为模块不共享 库,但只是部分链接的目标文件,运行时链接 发生的事情实际上类似于静态链接而不是类似的东西 动态链接。 (不支持懒惰的解决方案 ELF标准定义的跳跃目标或符号抢占。) 此外,虽然从那时起通常在用户空间中避免文本重定位 他们打败了代码页面的共享,这不是问题所在 内核。
原因是因为GCC编译内核模块只会输出那些重定位。我希望GCC ARM维护者知道这个......