您可能不会收到回复,因为您对事物的理解不是很好,并且linux-arm-kernel列表中的任何人都需要一些时间才能回复。阅读kprobes.txt并详细研究 ARM 架构。
如果 kprobe 处理了未定义的指令异常(只创建了 bcos kprobe),那么为什么__und_svc()会被调用。__und_svc()处理程序对于 kprobes的作用是什么?
在 ARM 上,mode0b11011是未定义指令模式。发生未定义指令时的流程是,
- lr_und = undef 指令的 pc + 4
- SPSR_und = 发生指令的模式的 CPSR。
- 在禁用中断的情况下将模式更改为 ARM。
- PC = 向量基数 + 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()。它只是从主管堆栈指针中添加/减去一个数字。我猜想代码会重写未定义处理程序的返回地址,以在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()是实际安装该功能的内容。