Stdin 在Spike/PK上调用RISC-V组件中的FGET

Stdin 在Spike/PK上调用RISC-V组件中的FGET,stdin,fgets,riscv,forth,newlib,Stdin,Fgets,Riscv,Forth,Newlib,更新:写下这篇文章可以让我发现哪里出了问题,但并不是为什么。我显然是以错误的方式调用fgets,因为在五次调用之后,我到达了地址0x221000,这是mmapped内存所在的位置-我在更高的地址写入-但我不知道为什么会发生这种情况。有人能解释一下吗 这有点复杂,我不知道为什么会出现这种行为:我不知道我是否把基本知识搞错了,或者这是Spike/PK的一个特性 注意:这里的libc由newlib提供,代码编译为riscv64 unknown elf Short-version我有用RISC-V汇编编

更新:写下这篇文章可以让我发现哪里出了问题,但并不是为什么。我显然是以错误的方式调用fgets,因为在五次调用之后,我到达了地址0x221000,这是mmapped内存所在的位置-我在更高的地址写入-但我不知道为什么会发生这种情况。有人能解释一下吗

这有点复杂,我不知道为什么会出现这种行为:我不知道我是否把基本知识搞错了,或者这是Spike/PK的一个特性

注意:这里的libc由newlib提供,代码编译为riscv64 unknown elf

Short-version我有用RISC-V汇编编写的输入代码,以前运行得很顺利,但自从我引入了对mmap的系统调用后,它在第五次执行时崩溃了。问题是因为我得到了错误的调用序列,还是因为Spike emulator和PK代理内核可能存在问题

详细解释

我正在写一种类似Forth的解释语言。它目前的目标是Spike emulator上的PK代理内核,但有望很快在“真实”硬件上运行。代码在

实现了一个无止境的循环来获取输入,依次调用一个例程来获取标准输入的filepointer,然后调用一个例程来获取输入

要获取标准输入文件指针(存储在堆栈上),请执行以下操作:

(stdinopen在.data部分作为.asciz“r”)

然后,要获取输入,请将其从堆栈中弹出

lw a2, 0(sp)
addi sp, sp, 8
la a0, INPUT_BUFFER
li a1, BUFFERLEN #0x200
call fgets
输入缓冲区在.bss节中定义为.common输入缓冲区,BUFFERLEN,8

这一切都很好,直到我添加了新的代码,在一些内存中映射为R/W/X——如果你知道Forth,你就会知道我需要具有这组不同寻常的权限的内存,因为我必须允许用户定义新的关键字

现在,获取输入的尝试在第四次调用时失败。(不过,如果我定义了mmap,问题就会消失。)

下面是一个失败的例子:





欢迎来到RISCYFORTH-版权所有Adrian McMenamin 2020-2021


RISCYFORTH是一种紧密基于FORTH的线程解释语言。 目前,我们正在执行模式下运行,您键入的任何内容都将 在输入每一行时执行。 RISCYFORTH根据GNU通用公共许可证第2版获得许可。 看



346 5622*dup 嗯

重复 嗯

重复 嗯

。 1945212好的

z 0000000000000000 ra 0000000000010442 sp 000000 3FFFFFF8 gp 000000000001fe30 tp 0000000000000000 T0000000000009FA60 t1 000000000000000a t2 0000000000000003 S00000000000000000 s1 0000000000000000 A0000000000001E530 a1 000000000009fa60 a2 0000000000000 200 a3 0000000000000000 a4 0000000000 221000 a5 000000000000000 1 A6000000000001EC88 a7 00000000000000 D6 s2 0000000000000 1FF S3000000000009FA60 s4 000000000001e530 s5 000000000009fa60 s6 0000000000000000 s7 0000000000011b64 s8 00000000000 10400 s9 0000000000 11FC58 sA 000000000009f950 sB 0000000000000000 t3 00000000000000 64 T4000000 3FFFFB08 t5 00000000000000 54 t6 00000000000000 54 pc 0000000000011ca4 va/inst 0000000000008 sr 800000200006020 用户加载segfault@0x0000000000000008

下面是代码失败的地方:

0000000000011c64 <_fgets_r>:
11c64:       4785                    li      a5,1
11c66:       0ac7de63                bge     a5,a2,11d22 <_fgets_r+0xbe>
11c6a:       7139                    addi    sp,sp,-64
11c6c:       f822                    sd      s0,48(sp)
11c6e:       f04a                    sd      s2,32(sp)
11c70:       ec4e                    sd      s3,24(sp)
11c72:       e852                    sd      s4,16(sp)
11c74:       fc06                    sd      ra,56(sp)
11c76:       f426                    sd      s1,40(sp)
11c78:       e456                    sd      s5,8(sp)
11c7a:       e05a                    sd      s6,0(sp)
11c7c:       8932                    mv      s2,a2
11c7e:       8a2a                    mv      s4,a0
11c80:       89ae                    mv      s3,a1
11c82:       8436                    mv      s0,a3
11c84:       c119                    beqz    a0,11c8a <_fgets_r+0x26>
11c86:       493c                    lw      a5,80(a0)
11c88:       cbc1                    beqz    a5,11d18 <_fgets_r+0xb4>
11c8a:       397d                    addiw   s2,s2,-1
11c8c:       8ace                    mv      s5,s3
11c8e:       a819                    j       11ca4 <_fgets_r+0x40>
11c90:       601c                    ld      a5,0(s0)
11c92:       9f05                    subw    a4,a4,s1
11c94:       9aa6                    add     s5,s5,s1
11c96:       94be                    add     s1,s1,a5
11c98:       c418                    sw      a4,8(s0)
11c9a:       e004                    sd      s1,0(s0)
11c9c:       3cb000ef                jal     ra,12866 <memcpy>
11ca0:       04090f63                beqz    s2,11cfe <_fgets_r+0x9a>
11ca4:       441c                    lw      a5,8(s0)
0000000000011c64:
11c64:4785 li a5,1
11c66:0ac7de63 bge a5,a2,11d22
11c6a:7139附加sp,sp,-64
11c6c:f822 sd s0,48(sp)
11c6e:f04a sd s2,32(sp)
11c70:ec4e sd s3,24(sp)
11c72:e852 sd s4,16(sp)
11c74:fc06 sd ra,56(sp)
11c76:f426 sd s1,40(sp)
11c78:e456 sd s5,8(sp)
11c7a:e05a sd s6,0(sp)
11c7c:8932 mv s2,a2
11c7e:8a2a中压s4,a0
11c80:89ae mv s3,a1
11c82:8436 mv s0,a3
11c84:c119 beqz a0,11c8a
11c86:493c lw a5,80(a0)
11c88:cbc1 beqz a5,11d18
11c8a:397d添加s2,s2,-1
11c8c:8ace mv s5、s3
11c8e:a819 j 11ca4
11c90:601c ld a5,0(s0)
11c92:9f05子带a4、a4、s1
11c94:9aa6添加s5、s5、s1
11c96:94be添加s1、s1、a5
11c98:c418西南a4,8(s0)
11c9a:e004 sd s1,0(s0)
11c9c:3cb000ef日本航空公司,邮编12866
11ca0:04090f63 beqz s2,11cfe
11ca4:441c lw a5,8(s0)
(_fgets_r由fgets调用)

0000000000011d26:
11d26:87aa中压a5,a0
11d28:8401b503 ld a0,-1984(gp)#1f670
11d2c:86b2 mv a3,a2
11d2e:862e mv a2,a1
11d30:85be mv a1、a5
11d32:bf0d j 11c64
memcpy出现了一些问题,给我留下了一个空指针,但我不清楚是什么——但我更基本的问题是:我有正确调用fgets的基本过程吗?

我相信我以前有过也没有过任何问题,但是关于这个问题的文档很少,所以确认会很有帮助,至少会建议我更仔细地查看mmap代码


当然,如果有人能发现任何其他错误,我们都会感激地接受。

通过反复打开文件,我的代码正在消耗越来越多的内存,并最终过度编译
0000000000011c64 <_fgets_r>:
11c64:       4785                    li      a5,1
11c66:       0ac7de63                bge     a5,a2,11d22 <_fgets_r+0xbe>
11c6a:       7139                    addi    sp,sp,-64
11c6c:       f822                    sd      s0,48(sp)
11c6e:       f04a                    sd      s2,32(sp)
11c70:       ec4e                    sd      s3,24(sp)
11c72:       e852                    sd      s4,16(sp)
11c74:       fc06                    sd      ra,56(sp)
11c76:       f426                    sd      s1,40(sp)
11c78:       e456                    sd      s5,8(sp)
11c7a:       e05a                    sd      s6,0(sp)
11c7c:       8932                    mv      s2,a2
11c7e:       8a2a                    mv      s4,a0
11c80:       89ae                    mv      s3,a1
11c82:       8436                    mv      s0,a3
11c84:       c119                    beqz    a0,11c8a <_fgets_r+0x26>
11c86:       493c                    lw      a5,80(a0)
11c88:       cbc1                    beqz    a5,11d18 <_fgets_r+0xb4>
11c8a:       397d                    addiw   s2,s2,-1
11c8c:       8ace                    mv      s5,s3
11c8e:       a819                    j       11ca4 <_fgets_r+0x40>
11c90:       601c                    ld      a5,0(s0)
11c92:       9f05                    subw    a4,a4,s1
11c94:       9aa6                    add     s5,s5,s1
11c96:       94be                    add     s1,s1,a5
11c98:       c418                    sw      a4,8(s0)
11c9a:       e004                    sd      s1,0(s0)
11c9c:       3cb000ef                jal     ra,12866 <memcpy>
11ca0:       04090f63                beqz    s2,11cfe <_fgets_r+0x9a>
11ca4:       441c                    lw      a5,8(s0)
0000000000011d26 <fgets>:
11d26:       87aa                    mv      a5,a0
11d28:       8401b503                ld      a0,-1984(gp) # 1f670 <_impure_ptr>
11d2c:       86b2                    mv      a3,a2
11d2e:       862e                    mv      a2,a1
11d30:       85be                    mv      a1,a5
11d32:       bf0d                    j       11c64 <_fgets_r>
            la t0, inputfileptr
            lw a0, 0(t0)
            bne a0, zero, getstdin_getin
            la a1, stdinopen
            call fdopen                
            la t0, inputfileptr
            sw a0, 0(t0)
            getstdin_getin:
            PUSH a0                          #store value on stack