FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

RISC-V版xv6のコンソールデバッグ(cprintfの謎解析)

xv6をRISC-Vに移植する作業を進めているが、cprintfが上手く表示できずにずっと止まっている。

前回、怪しいと思ったのはここだ。

msyksphinz.hatenablog.com

80100600 <cprintf>:
80100600:   fa010113            addi    sp,sp,-96
80100604:   02112e23            sw  ra,60(sp)
80100608:   02812c23            sw  s0,56(sp)
8010060c:   04010413            addi    s0,sp,64
80100610:   fca42623            sw  a0,-52(s0)
80100614:   00b42223            sw  a1,4(s0)
80100618:   00c42423            sw  a2,8(s0)
8010061c:   00d42623            sw  a3,12(s0)
80100620:   00e42823            sw  a4,16(s0)
80100624:   00f42a23            sw  a5,20(s0)
80100628:   01042c23            sw  a6,24(s0)
8010062c:   01142e23            sw  a7,28(s0)

引数レジスタa0からa7を格納するのに、なぜかa1以降の位置がずれている。 これはひょっとしたらバグなんじゃないか?と思いcprintfの部分だけ取り出して、改造してどうなるか見てみた。

console.cのコンパイル結果を引き出す

-Sオプションで引き出した。その結果、console.Sが出来たので、これを見てみる。

riscv64-unknown-elf-gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -fvar-tracking -fvar-tracking-assignments -O0 -g -Wall -MD -gdwarf-2 -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -S   -c -o console_asm.S console.c
cat console_asm.S
        .globl  cprintf
        .type   cprintf, @function
cprintf:
.LFB20:
.LM25:
        .cfi_startproc
.LVL26:
        add     sp,sp,-96
.LCFI8:
        .cfi_def_cfa_offset 96
        sw      ra,60(sp)
        sw      s0,56(sp)
        .cfi_offset 1, -36
        .cfi_offset 8, -40
        add     s0,sp,64
.LCFI9:
        .cfi_def_cfa 8, 32
        sw      a0,-52(s0)
        sw      a1,4(s0)
        sw      a2,8(s0)
        sw      a3,12(s0)
        sw      a4,16(s0)
        sw      a5,20(s0)
        sw      a6,24(s0)
        sw      a7,28(s0)
.LM26:
        lui     a5,%hi(cons)
        add     a5,a5,%lo(cons)
        lw      a5,52(a5)
...

やはり引数を格納する位置がずれているのが怪しい。改造してみよう。

    sw  a0,-52(s0)
    sw  a1,-48(s0)
    sw  a2,-44(s0)
    sw  a3,-40(s0)
    sw  a4,-36(s0)
    sw  a5,-32(s0)
    sw  a6,-24(s0)
    sw  a7,-28(s0)

これでMakefileにconsole_asm.Sを追加し、さらにconsole_asm.Sからconsなどの変数を参照できるようにstatic記述をとり外す。

diff --git a/console.c b/console.c
index 6d9d5ae..72d4447 100644
--- a/console.c
+++ b/console.c
@@ -14,15 +14,24 @@
 #include "proc.h"
 #include "./riscv.h"

-static void consputc(int);
+void consputc(int);

-static int panicked = 0;
+int panicked = 0;

-static struct {
+struct {
   struct spinlock lock;
   int locking;
 } cons;

+// static void consputc(int);
+//
+// static int panicked = 0;
+//
+// static struct {
+//   struct spinlock lock;
+//   int locking;
+// } cons;
+
diff --git a/Makefile b/Makefile
index c5ec64b..74838e9 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,7 @@
 OBJS = \
        bio.o\
        console.o\
+       console_asm.o\
        exec.o\
        file.o\
        fs.o\

これでコンパイルし、実行してみたのだが、途中で止まってしまった。トレースファイルを見ると、xchgで固まっている。

  <FunctionCall 13559270: mpinit(0x801050ec)>
    <FunctionCall 13559295: cprintf(0x80100e14)>
      <FunctionCall 13559316: acquire(0x801067f0)>
        <FunctionCall 13559322: pushcli(0x80106a00)>
          <FunctionCall 13559327: readeflags(0x80106714)>
          <Return: readeflags>
          <FunctionCall 13559338: cli(0x80106734)>
          <Return: cli>
        <Return: pushcli>
        <FunctionCall 13559360: holding(0x801069b4)>
        <Return: holding>
        <FunctionCall 13559384: xchg(0x80106774)>
        <Return: xchg>
        <FunctionCall 13559405: xchg(0x80106774)>
...

なんだかスタックを壊してしまった気がする。オチが無くなってしまったが、引き続きデバッグ。。。