由于您对事物的理解不是很好,因此您需要一段时间才能对linux-arm-kernel列表中的任何人做出响应。请阅读kprobes.txt并详细研究ARM体系结构。
如果kprobe处理了未定义的指令异常(bcos kprobe只创建),那么为什么__und_svc()
被调用。 __und_svc()
处理程序对于kprobes有什么作用?
在ARM,模式0b11011
是未定义指令模式。一个未定义指令发生当流量,是undef指令的
- lr_und = PC + 4
- SPSR_und = CPSR的发生指令,其中模式。
- 将模式更改为禁用中断的ARM。
- PC =矢量基地+ 4
步骤4位于__vectors_start
的主要矢量表和这只是分支到 vector_und
。该代码是一个名为vector_stub
的宏,它可以调用__und_svc
或__und_usr
。堆栈是每个进程保留的4/8k页面。它是包含任务结构和内核堆栈的内核页面。
kprobe作品放置在代码的地址,你想探测未定义指令。也就是说,它涉及未定义的指令处理程序。这应该是非常明显的。它调用两个例程,call_fpe
或do_undefinstr()
。您对第二种情况感兴趣,它获取操作码并调用call_undef_hook()
。用register_undef_hook()添加一个钩子;你可以看到arch_init_kprobes()
。主回调kprobe_handler
被称为struct pt_regs *regs
,这恰好是在__und_svc
中保留的额外内存。请注意,例如kretprobe_trampoline()
,它正在使用当前正在执行的堆栈玩弄技巧。
如果64字节的内存是强制性的,那么如何在不编译内核的情况下进行分配。即如何动态地做到这一点。?
不,它不是。您可以使用不同的机制,但您可能需要修改代码kprobes。很可能你将不得不限制功能。也可以完全重写堆栈帧并在事实之后保留额外的64字节。它是而不是如kmalloc()
中的分配。它只是从管理员堆栈指针中添加/减去一个数字。我猜测代码会重新写入来自未定义处理程序的返回地址,以便在地址的上下文(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()
是实际安装该功能。
虽然我喜欢SO的精确问题,但恐怕这个问题太具体了。你是否尝试过与内核相关的邮件列表? –
是的。我在systemtap邮件列表以及linux-arm邮件列表上发布了这个问题。运气不好在linux-arm中尚未公布。 – Jeyaram