简体   繁体   English

什么可能导致 RISC-V 上的 SIGILL(非法指令除外)

[英]What might cause a SIGILL (other than an illegal instruction) on RISC-V

I am trying to load some Forth into my Forth compiler running on a RISC-V SBC (I do not believe this is a Forth-related question though):我正在尝试将一些 Forth 加载到我在 RISC-V SBC 上运行的 Forth 编译器中(不过我不相信这是一个与 Forth 相关的问题):

 >load /root/repos/riscyforth/test2.4th
 : cuboid * * [ The cuboid has a volume of ] . ;
 
 OK
 cuboid
  
 
 Program received signal SIGILL, Illegal instruction.
 0x0000003ff7dbd038 in ?? ()

What the above shows is that I load the file with the Forth and the first line, echoed back to the terminal, is the definition of the word cuboid.上面显示的是我用 Forth 加载文件,第一行,回显到终端,是 cuboid 这个词的定义。 The subsequent OK shows that the Forth compiler has successfully compiled the word.随后的 OK 说明 Forth 编译器已经成功编译了这个词。

Then the second line is an invocation of this word, cuboid and then the message that the program (being run under GDB in this case) has cashed with a SIGILL.然后第二行是这个词的调用,长方体,然后是程序(在这种情况下在 GDB 下运行)已经用 SIGILL 兑现的消息。

However, this is what a disassembly shows:但是,这是反汇编显示的内容:

(gdb) disassemble 0x3ff7dbd038, 0x3ff7dbd078
Dump of assembler code from 0x3ff7dbd038 to 0x3ff7dbd078:
=> 0x0000003ff7dbd038:  addi    s9,s9,-8
   0x0000003ff7dbd03c:  sd  s7,0(s9)
   0x0000003ff7dbd040:  li  s8,63
   0x0000003ff7dbd044:  slli    s8,s8,0x20
   0x0000003ff7dbd048:  lui t0,0xf7dbd
   0x0000003ff7dbd04c:  ori t0,t0,0
   0x0000003ff7dbd050:  slli    t0,t0,0x20
   0x0000003ff7dbd054:  srli    t0,t0,0x20
   0x0000003ff7dbd058:  or  s8,s8,t0
   0x0000003ff7dbd05c:  addi    s8,s8,112
   0x0000003ff7dbd060:  mv  s7,s8
   0x0000003ff7dbd062:  nop
   0x0000003ff7dbd064:  lui t0,0x10
   0x0000003ff7dbd068:  addi    t0,t0,1976 # 0x107b8 <COLON_NEXT>
   0x0000003ff7dbd06c:  jr  t0
   0x0000003ff7dbd070:  addi    a2,sp,868
   0x0000003ff7dbd072:  nop
   0x0000003ff7dbd074:  unimp
   0x0000003ff7dbd076:  unimp

This is exactly as I would expect and as can be seen there is a perfectly good instruction at 0x0000003ff7dbd038.这正是我所期望的,并且可以看出在 0x0000003ff7dbd038 处有一条非常好的指令。

This memory is mmaped into the system as executible and this mechanism works well for words I define on the command line (as opposed to read in from the file).该内存作为可执行文件映射到系统中,这种机制适用于我在命令行上定义的单词(而不是从文件中读入)。 Moreover if I just define the word in the file I load and then run it from the command line it's also fine (I am aware these might suggest an issue with the loading, but I cannot see it or why it would generate this signal.此外,如果我只是在我加载的文件中定义这个词,然后从命令行运行它也可以(我知道这些可能表明加载有问题,但我看不到它或它为什么会生成这个信号。

To add to the puzzle, if I step through the code using GDB then I don't get this SIGILL problem and the code beginning at 0x0000003ff7dbd038 executes as I would expect.更重要的是,如果我使用 GDB 单步执行代码,那么我不会遇到这个 SIGILL 问题,并且以 0x0000003ff7dbd038 开头的代码会按照我的预期执行。

This is RV64 on RVBoards Nezha - immediately before this the standard Forth interpreter commands are executed:这是 RVBoards Nezha 上的 RV64 - 在此之前执行标准的 Forth 解释器命令:

  NEXT:
            ld s8, 0(s7)                        #word address register takes content of next secondary
            addi s7, s7, ADDRWIDTH              #next secondary along

   RUN:
            ld t0, 0(s8)                        #extract first instruction address of primative

Unlike on x86, RISC-V does not permit to write machine code and execute it without synchronisation, even within the same thread.与 x86 不同,RISC-V 不允许编写机器代码并在没有同步的情况下执行它,即使在同一线程中也是如此。 Before executing newly written machine code, issue a fence.i instruction to synchronise the instruction cache with the current state of memory.在执行新编写的机器代码之前,发出一条fence.i指令,将指令缓存与内存的当前状态同步。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM