从预编译的Linux内核模块中删除对_gnu_mcount_nc的引用

从预编译的Linux内核模块中删除对_gnu_mcount_nc的引用,linux,assembly,profiling,arm,Linux,Assembly,Profiling,Arm,我有一个用于某些外围设备的二进制Linux内核模块。 它工作得很好,但它使用了我从中删除的分析支持 出于性能方面的原因,内核被删除了。我无法重新编译模块 因为它的第三方专有软件和我没有访问权限 到源代码。我只拥有所需的对象文件(*.o) 将驱动程序链接到我的Linux内核版本 是否可以处理.ko文件并删除到的跳转 \u gnu\u mcount\u nc功能?我在考虑更改操作码 从bl到mov r8,r8,但由于 事实上,每个到外部函数的分支都有ebfffffeopcode。 这让我想到了我想避

我有一个用于某些外围设备的二进制Linux内核模块。 它工作得很好,但它使用了我从中删除的分析支持 出于性能方面的原因,内核被删除了。我无法重新编译模块 因为它的第三方专有软件和我没有访问权限 到源代码。我只拥有所需的对象文件(*.o) 将驱动程序链接到我的Linux内核版本

是否可以处理.ko文件并删除到的跳转
\u gnu\u mcount\u nc
功能?我在考虑更改操作码 从
bl
mov r8,r8
,但由于 事实上,每个到外部函数的分支都有
ebfffffe
opcode。 这让我想到了我想避免的搬迁话题。我在找 对于一些琐碎的解决方案

Disassembly of section .text:

00000000 <some_func1>:
       0:       e92d4000        push    {lr}
       4:       ebfffffe        bl      18e0 <__gnu_mcount_nc>
       8:       e3a00001        mov     r0, #1
       c:       e12fff1e        bx      lr

00000010 <some_func2>:
      10:       e92d4000        push    {lr}
      14:       ebfffffe        bl      18e0 <__gnu_mcount_nc>
      18:       e3a00001        mov     r0, #1
      1c:       e12fff1e        bx      lr

00000020 <some_func3>:
      20:       e92d4038        push    {r3, r4, r5, lr}
      24:       e92d4000        push    {lr}
      28:       ebfffffe        bl      18e0 <__gnu_mcount_nc>
      2c:       e1a04001        mov     r4, r1
      30:       e59f3038        ldr     r3, [pc, #56]   ; 70 <some_func3+0x50>
      34:       e5905034        ldr     r5, [r0, #52]   ; 0x34
...
节的反汇编。文本:
00000000 :
0:e92d4000推送{lr}
4:ebfffffe bl 18e0
8:e3a00001 mov r0,#1
c:E12FF1E bx lr
00000010 :
10:e92d4000推送{lr}
14:ebfffffe bl 18e0
18:e3a00001 mov r0,#1
1c:E12FF1E bx lr
00000020 :
20:e92d4038推送{r3,r4,r5,lr}
24:e92d4000推送{lr}
28:ebfffffe bl 18e0
2c:e1a04001 mov r4,r1
30:e59f3038 ldr r3,[pc,#56];70
34:e5905034 ldr r5[r0,#52];0x34
...
目标板基于armv7-a架构和Cortex-A9内核

编辑:

问题1:
\uu mcount\u loc
包含指向
的相对指针。内核如何在修复地址的过程中知道指针相对于哪个部分

问题2:似乎“被黑客攻击”的内核模块不起作用。发出insmod.ko触发器错误消息:

insmod:无法插入'some_driver.ko':模块或中的未知符号 无效参数

我是否必须从某个部分删除符号u_gnu_mcount_nc?即使现在还没用


正在寻找一些想法,谢谢。

您应该使用FTRACE支持重新编译内核,并启用
CONFIG\u DYNAMIC\u FTRACE


您不必担心它会影响性能-除非实际启用了跟踪,否则内核加载程序对
\uu gnu\u mcount\u nc
的所有调用。这就是
\uuuu mcount\u loc
部分(在final.ko中)的作用-它有一个包含
bl\uuuu gnu\u mcount\u nc
在二进制文件中调用的所有位置的列表。

而不是试图修改代码,您需要查看重定位表,因为它包含模块使用的实际内核符号。抱歉,我没有得到它。我知道模块中使用了哪些符号,我想保留它们,除了一个:如果您在命令行上执行
objdump-r
,您将看到所有重新定位的列表。基本上,当加载模块时,内核将扫描重新定位列表,并用跳转到实际函数替换所有这些
ebfffffe
指令。这个想法是,您可以自己查看重新定位,找到任何引用
\uu gnu\u mcount\u nc
的内容,并删除这些重新定位条目(您还需要将它引用的指令修改为
nop
或等效指令),但我也想到了内核本身的大小——在没有FTRACE支持的情况下,它大约要小170kB。我有非常有限的闪存,我想保持FTRACE禁用。因此,我坚持使用概念,将所有
BL
更改为
“mov r8,r8”
。我从
\uu mcount\u loc
中取出所有指向
\uu gnu mcount\u nc
的相关指针,并交换指令。这是成功的——至少从我拆解内核模块后看到的情况来看是如此。