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

Jey*_*ram 4 arm linux-kernel systemtap armv7 kprobe

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

我能够samples/kprobes/从内核树中运行文件夹中的可用示例.

如果我们在kernel(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宏将在__und_svc()中以0扩展

我想从这些疑虑中解脱出来.

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

  2. 如果64字节内存是强制的,那么如何在不编译内核的情况下进行分配.即如何动态地做到这一点.

请分享您的知识.

art*_*ise 5

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

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

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

  1. lr_und = undef指令的pc + 4
  2. SPSR_und =指令发生的模式的CPSR.
  3. 将模式更改为ARM,禁用中断.
  4. PC =矢量基数+4

第四步的主矢量表位于,__vectors_start它只是分支到 vector_und.代码是一个被调用的宏vector_stub,它做出一个descision来调用__und_svc或者__und_usr.堆栈是每个进程保留的4/8k页面.它是包含任务结构和内核堆栈的内核页面.

kprobe的工作原理是将未定义的指令放在您想要探测的代码地址上.即,它涉及未定义的指令处理程序.这应该是非常明显的.它调用两个例程,call_fpedo_undefinstr().您对第二种情况感兴趣,它获取操作码和调用call_undef_hook().使用register_undef_hook()添加一个钩子; 你可以看到arch_init_kprobes().kprobe_handler使用a调用主回调struct pt_regs *regs,这恰好是保留的额外内存__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
Run Code Online (Sandbox Code Playgroud)

arch_init_kprobes() 是实际安装该功能.