【问题标题】:Analog of setting trap flag in Event Flags in Thread Context for ARM64在 ARM64 的线程上下文中的事件标志中设置陷阱标志的模拟
【发布时间】:2021-11-27 17:47:15
【问题描述】:
我有一个项目要迁移到 ARM64,而在 x86 项目中我正在这样做:
CONTEXT ctx;
ctx.EFlags |= 0x100;
这基本上是在线程上下文的事件标志中设置陷阱标志,允许调试器以单步模式运行(基本上是放置断点并一次移动一条指令)。但是 EFlags 在 ARM64 架构的 CONTEXT 结构中不可用,我在 ARM64 中找不到这个的模拟。我想要一个更强大的寄存器资源,以及事件标志的 ARM64 模拟。答案资源将不胜感激。 This 是我了解事件标志的地方,here 是有关陷阱标志的地方。提前致谢。
【问题讨论】:
标签:
c++
cpu-registers
vscode-debugger
arm64
【解决方案1】:
不熟悉 Windows,无法测试,但可能如下:
ARM64_NT_CONTEXT ctx;
ctx.Cpsr |= 0x200000;
如果您自己在内核模式下实现此功能,您将写入spsr_el1 的第 21 位。引用 the manual(版本 G.b 中的第 C5-460 页):
SS, bit [21]
Software Step. Set to the value of PSTATE.SS on taking an exception to EL1,
and conditionally copied to PSTATE.SS on executing an exception return
operation in EL1
现在,spsr、cpsr 和 pstate 的命名有些混乱。在 A32/T32 中,ARM 将当前程序状态称为 cpsr,并拥有一个可以修改的同名系统寄存器。在 A64 中,他们称其为 pstate,但不给您直接修改的寄存器(他们为您提供了一堆寄存器,例如 pan 和 nzcv)。在异常进入时,该状态被复制到spsr_elX,而在异常返回时,该寄存器中的值被复制回处理器状态。
因此,spsr、cpsr 和 pstate 在已保存线程状态的上下文中都指代同一事物。
而ARM64_NT_CONTEXT 结构包含一个名为Cpsr 的寄存器,这意味着您可以这样设置spsr_el1。
注意:除非您处理的 API 是内核 API,否则 Windows 可能会从该字段中过滤掉某些位,最值得注意的是最低的几位,它们编码线程/进程运行的异常级别。他们是否过滤掉单步位我不能说,但如果他们在 x64 上不这样做,我希望他们也不要在 arm64 上这样做。