未定义的异常处理程序(__und_svc)在kprobes中的作用是什么?

时间:2013-12-13 06:00:43

标签: linux-kernel arm armv7 systemtap kprobe

我试图将kprobe转换为可加载的内核模块。

我可以运行samples/kprobes/文件夹中的可用示例 内核树。

如果我们在内核(CONFIG_KPROBES)中配置kprobes,那么svc_entry宏将在__und_svc()处理程序中以64字节进行扩展。

参考: http://lxr.free-electrons.com/source/arch/arm/kernel/entry-armv.S?a=arm#L245

我的目标是不触及内核端,将kprobe作为内核模块。

因此编译内核时不启用CONFIG_KPROBES。所以svc_entry宏将以0 in扩展 __und_svc()

我想从这些怀疑中解脱出来。

  1. 如果处理kprobe未定义的指令异常(bcos kprobe 仅创建),然后调用__und_svc()的原因。 __und_svc()处理程序对kprobes的作用是什么?

  2. 如果64字节内存是强制的,那么如何分配没有 编译内核。即如何动态地进行。??

  3. 请分享您的知识。

1 个答案:

答案 0 :(得分:5)

您可能无法获得回复,因为您对事物的理解不是很好,并且 linux-arm-kernel 列表中的任何人都需要一些时间才能做出响应。阅读kprobes.txt并详细研究ARM体系结构。

  

如果处理了kprobe未定义的指令异常(仅创建了bcos kprobe),那么为什么调用__und_svc()__und_svc()处理程序对kprobes的作用是什么?

在ARM上,模式0b11011未定义的指令模式未定义指令发生时的流程是,

  1. lr_und =未完成指令的电影+ 4
  2. SPSR_und =发生指令的模式的CPSR。
  3. 在禁用中断的情况下将模式更改为ARM。
  4. PC = vector base + 4
  5. 第四步的主要向量表位于__vectors_start,这只是分支到 vector_und。该代码是一个名为vector_stub的宏,用于调用__und_svc__und_usr。堆栈是每个进程保留的4 / 8k页面。它是包含任务结构和内核堆栈的内核页面。

    kprobe 的工作原理是将未定义的指令放在您要探测的代码地址上。即,它涉及未定义的指令处理程序。这应该是非常明显的。它调用两个例程call_fpedo_undefinstr()。您对第二种情况感兴趣,它获取操作码并调用call_undef_hook()。添加register_undef_hook()的钩子;你可以看到arch_init_kprobes()。使用struct pt_regs *regs调用主回调kprobe_handler,这恰好是__und_svc中保留的额外内存。例如,注意kretprobe_trampoline(),它正在使用当前正在执行的堆栈进行技巧。

      

    如果必须使用64字节内存,那么如何在不编译内核的情况下进行分配。即如何动态地进行。?

    不,不是。您可以使用其他机制,但可能必须修改 kprobes 代码。您很可能必须限制功能。也可以完全重写堆栈帧并在事后保留额外的64字节。与kmalloc()中的不是分配。它只是从管理程序堆栈指针中添加/减去一个数字。我猜这段代码会重写未定义处理程序的返回地址,以便在 kprobed的上下文(ISR,下半部/线程IRQ,work_queue,内核任务)中执行地址。但是,您可能还有其他问题尚未遇到。如果永远不会调用arch_init_kprobes(),那么您可以随时在__und_svc进行预订;它只占用64个字节的堆栈,这将使内核堆栈更有可能溢出。即,改变,

    __und_svc:
        @ Always reserve 64 bytes, even if kprobe is not active.
        svc_entry 64
    

    arch_init_kprobes()是实际安装该功能的原因。