哪里可以在linux内核中找到指令地址(PC值)?

时间:2013-05-17 20:46:18

标签: linux kernel instructions

所有

当我分配新的物理页面时,我正在尝试打印当前的PC值。 在linux内核源码中,mm / memory.c负责分配页面, 但它没有关于PC值的信息...... 有谁知道我在哪里可以找到这个PC值并在memory.c文件中使用它?

1 个答案:

答案 0 :(得分:1)

将我的评论写回答。

您正在寻找的不是当前PC (一直在变化),而是指令的PC触发页面错误。要了解存储的位置以及如何检索它,让我们深入挖掘一下。

当x86中发生异常(陷阱或中断)时,CPU将执行以下操作:

  • 使用向量(陷阱号/中断号 - 这是HW隐式和/或可通过编程中断控制器进行配置 - 是的,你可以进行网络中断触发页面故障,技术上......)作为中断描述符表(IDT)的索引
  • 验证存储在那里的数据结构(所谓的门描述符
  • 如果无效......提出#GP错误(一般保护[错误]);因为它本身就是一个例外......如果它的门也是无效的...... #DF(双重故障)......冲洗重复......如果无效 - 三重故障(重置CPU很难) )。
  • 如果有效,则门将指定目标上下文(通过代码段),并在其中指定处理程序地址。用非专业的话来说,这就是说“进入下面的权限级别并调用这个处理程序”(通过使目标%cs成为内核,并使处理程序成为一个低级别的中断入口函数)。
  • 如果执行此操作涉及权限切换,则CPU将更改为目标权限级别,并切换堆栈指针。
  • CPU将中断返回信息写入该堆栈(注意此处的下一个#DF机会...如果由于内核堆栈指针损坏或堆栈溢出而失败,则会发生进入未映射的内存)。书面信息包含:
    1. 故障时的代码段(原始“上下文”)
    2. 堆栈指针在故障时激活(即用户堆栈),堆栈被切换
    3. flags注册
    4. 故障地址/ PC(不是所有类型的陷阱,但绝对是页面错误)
  • 只有之后发生了这一切,才会调用实际的中断向量处理函数。从这里开始,软件 - 内核代码接管:
    1. 在汇编代码中,将剩余的通用寄存器和其他必需的“上下文”信息保存到异常帧中,然后构造适合于调用C代码的堆栈。 / LI>
    2. struct ptregs*作为参数调用C函数 - 这是异常帧,由陷阱条目保存的寄存器状态(部分由HW / CPU本身,部分由条目存根代码保存)。这是实际用于处理陷阱/异常/中断的内容。

从陷阱/中断返回时,x86 iret指令用于展开CPU推送到内核堆栈的四个/五个字,以便恢复/返回。

这样,内核中的每个异常条目都被赋予相同的数据结构struct ptregs * - 如上所述,对于大多数陷阱/中断,除了其他信息之外,还包含程序计数器/指令指针,其中说明了故障发生了。 struct pt_regs.ip是您需要查看的字段。

尤其对于页面错误,请参阅do_page_fault()并查看其使用位置/方式。