【问题标题】:Any idea how Linux determines which string should be printed in a kernel module?知道 Linux 如何确定应该在内核模块中打印哪个字符串吗?
【发布时间】:2020-06-18 20:39:03
【问题描述】:

给定最基本的内核模块

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/printk.h>

static int __init my_mod_init(void) {
    printk("Hello World!");
    printk("Goodbye World!");
    return 0;
}
static void __exit my_mod_exit(void) { }

module_init(my_mod_init);
module_exit(my_mod_exit);

MODULE_LICENSE("GPL");

GCC 生成以下 armv7 程序集(objdump)

dummy.ko:     file format elf32-littlearm

Disassembly of section .init.text:

00000000 <init_module>:
   0:   e92d4010    push    {r4, lr}
   4:   e3000000    movw    r0, #0
   8:   e3400000    movt    r0, #0
   c:   ebfffffe    bl  0 <printk>
  10:   e3000000    movw    r0, #0
  14:   e3400000    movt    r0, #0
  18:   ebfffffe    bl  0 <printk>
  1c:   e3a00000    mov r0, #0
  20:   e8bd8010    pop {r4, pc}

Disassembly of section .exit.text:

00000000 <cleanup_module>:
   0:   e12fff1e    bx  lr

rodata 部分如下所示:

Contents of section .rodata.str1.4:
 0000 48656c6c 6f20576f 726c6421 00000000  Hello World!....
 0010 476f6f64 62796520 576f726c 642100    Goodbye World!. 

我至少预计第 0x10 行和第 0x14 行的r0 类似于mov r0, #16ldr r0, [pc, #12]。第二个printk 函数如何通知打印“再见世界!”

【问题讨论】:

    标签: c assembly linux-kernel arm disassembly


    【解决方案1】:

    .ko 显然类似于 .o - 可重定位的目标文件,而不是 ELF 可执行文件或共享目标。

    所以机器码中只有占位符,实际地址仅在加载时根据重定位信息填写。

    使用objdump -dr 反汇编以显示带有符号名称的重定位。 (或objdump -drWC,就像你拆解.o时一样。

    【讨论】:

    • objdump -dr 正是我所需要的!我完全忘记了 .so 和 .ko 包含可重定位的内容;我也没有意识到-d 选项没有考虑重定位。
    • @TekuConcept:仅作记录,对于.so 你想要的动态重定位-R
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-31
    • 1970-01-01
    • 1970-01-01
    • 2020-07-27
    相关资源
    最近更新 更多