Exception handling 当前执行模式/异常级别等是什么?

Exception handling 当前执行模式/异常级别等是什么?,exception-handling,arm,arm64,Exception Handling,Arm,Arm64,我不熟悉ARMv8体系结构。我脑子里有以下几个基本问题: 如何知道当前的执行模式是AArch32还是AArch64?我应该阅读CPSR或SPSR来确定这一点吗 当前的异常级别是什么,EL0/1/2/3 一旦出现异常,我可以读取任何寄存器来确定我是否在Serror/Synchronous/IRQ/FIQ异常处理程序中 蒂亚 32位和64位的汇编指令及其二进制编码完全不同。因此,在编译过程中,您/编译器已经需要知道当前处于何种模式的信息。在运行时检查它们没有意义。对于C,C++编译可以通过编译时(α

我不熟悉ARMv8体系结构。我脑子里有以下几个基本问题:


  • 如何知道当前的执行模式是AArch32还是AArch64?我应该阅读CPSR或SPSR来确定这一点吗

  • 当前的异常级别是什么,EL0/1/2/3

  • 一旦出现异常,我可以读取任何寄存器来确定我是否在Serror/Synchronous/IRQ/FIQ异常处理程序中

  • 蒂亚

  • 32位和64位的汇编指令及其二进制编码完全不同。因此,在编译过程中,您/编译器已经需要知道当前处于何种模式的信息。在运行时检查它们没有意义。对于C,C++编译可以通过编译时(<代码>αIFIFF < /代码>)通过编译器提供的宏,如代码< > ARMCLANN/CONT>提供的代码:<代码>
  • 取决于执行模式:
    • aarch32:
      MRS,CPSR
      将当前状态读入寄存器编号n。然后提取包含当前模式的位3:0
    • aarch64:
      MRS,CurrentEL
      将当前EL读入寄存器编号n
  • 简单回答:你不能。详细回答:假设通过代码的结构和任何用户定义变量的状态,您已经知道自己在做什么。i、 e.无论您是通过常规代码还是通过异常代码获得代码职位
  • aarch64 C代码:

    register uint64_t x0 __asm__ ("x0");
    __asm__ ("mrs x0, CurrentEL;" : : : "%x0");
    printf("EL = %" PRIu64 "\n", x0 >> 2);
    
    arm C代码:

    register uint32_t r0 __asm__ ("r0");
    __asm__ ("mrs r0, CPSR" : : : "%r0");
    printf("EL = %" PRIu32 "\n", r0 & 0x1F);
    
    CurrentEL
    但是不能从EL0中读取,如ARMv8手册C5.2.1“CurrentEL,当前异常级别”部分“可访问性”所示。尝试在Linux用户环境中运行它会引发SIGILL。你可以捕捉到那个信号,但我想

    然而,CPSR可从EL0读取


    在QEMU和gem5上测试。

    “我如何知道当前的执行模式是AArch32还是AArch64?”-我认为如果试图检查模式的代码编译为64位,则模式为64位;如果编译为32位,则模式为32位。对于第二点,当我处于EL1、EL2或EL3模式时,我可以通过读取CPSR寄存器找到当前模式。但是,如果我在EL0模式下读取cpsr会导致异常。@chetan:“如果我在EL0模式下读取cpsr会导致异常。”好吧,这当然是全部要点!EL0是无特权的“应用”模式;应用程序不能/一定不能访问这样的信息。因此,我的理解是,编写一个内核模块来读取寄存器值。如果不是EL2,它应该在EL1中运行。嗨,如果我使用gdb,我可以像“info reg currentel”一样读取寄存器吗?这不管用。我能看一下这个的登记表吗?我尝试了CPSR(它是最低的4位),但它不完全是EL值。@ChanKim我不确定这一点,我要寻找的是GDB XML,它决定了什么是公开的或不公开的,例如在QEMU上,请参见下面的aarch64条目: