FPGA開発日記

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

RISC-VのGDBのビルドとISSの対応

RISC-V向けにxv6の移植に挑戦したくて、そのためにはRISC-VのGDBの対応を考えないとデバッグがつらい。 いろいろ調査していると、RISC-V向けのGDBの移植が進んでいるようだ。早速使ってみよう。

1. RISC-V向けGDBのビルド

以下のリポジトリを落としてきて、ビルドしてみた。

github.com

RISC-V GDB port | RISC-V BLOG

A RISC-V port of GDB is now available at https://github.com/mythdraenor/riscv-gdb.git courtesy of Todd Snyder at Bluespec, Inc., enabling source-level debugging of C/C++ codes compiled for RISC-V.

とりあえずビルドしてみよう。ビルドの手順はgithubにそのまま書いてあるが、これでは僕の使っているUbuntu 14.10では上手くいかなかった。 どうやら既存のgdbのバグのようだ。以下のようにリポジトリの中身を変更する。

diff --git a/bfd/doc/bfd.texinfo b/bfd/doc/bfd.texinfo
index ce1c5af..47a0667 100644
--- a/bfd/doc/bfd.texinfo
+++ b/bfd/doc/bfd.texinfo
@@ -323,7 +323,7 @@ All of BFD lives in one directory.
 @printindex cp

 @tex
-% I think something like @colophon should be in texinfo.  In the
+% I think something like @@colophon should be in texinfo.  In the
 % meantime:
 \long\def\colophon{\hbox to0pt{}\vfill
 \centerline{The body of this manual is set in}
@@ -334,7 +334,7 @@ All of BFD lives in one directory.
 \centerline{{\sl\fontname\tensl\/}}
 \centerline{are used for emphasis.}\vfill}
 \page\colophon
-% Blame: doc@cygnus.com, 28mar91.
+% Blame: doc@@cygnus.com, 28mar91.
 @end tex

 @bye
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 65d4899..eb48c79 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -35592,7 +35592,7 @@ which @value{GDBN} currently ignores.
 @printindex cp

 @tex
-% I think something like @colophon should be in texinfo.  In the
+% I think something like @@colophon should be in texinfo.  In the
 % meantime:
 \long\def\colophon{\hbox to0pt{}\vfill
 \centerline{The body of this manual is set in}
@@ -35604,7 +35604,7 @@ which @value{GDBN} currently ignores.
 \centerline{{\sl\fontname\tensl\/}}
 \centerline{are used for emphasis.}\vfill}
 \page\colophon
-% Blame: doc@cygnus.com, 1991.
+% Blame: doc@@cygnus.com, 1991.
 @end tex

これで、riscv-gdbをビルドできるようになる。

mkdir build
cd build
../configure --program-prefix=riscv- --target=riscv
make
sudo make install

2. RISC-V GDBISSを対応させる

僕のRISC-VのISSは、既にMIPS向けのモードにて、GDBに対応している。基本的にはGDB階層で区切っているので、対応できるはずだ。

github.com

一点参照しなければならない点として、MIPSではPCレジスタに参照するときにインデックスが0x25だったが、RISC-Vでは0x20(汎用レジスタのすぐ傍)になっていた。この部分を変更すれば、RISC-VのGDBからブレークポイントを張れるようになった。

+    if (reg_addr == 0x20) {
+      res = m_env->GetPC ();
+      std::cout << "PC = " << std::hex << res << '\n';

テストのために、riscv-testsのパタンを使用した。qsort.riscvをビルドし、mainにブレークポイントを張ってみる。下記のように、ちゃんとGDBと通信できた!

   ┌──qsort/qsort_main.c─────────────────────────────────────
   │133             ir = j-1;                                                                     │
   │134           }                                                                               │
   │135           else                                                                            │
   │136           {                                                                               │
   │137             stackp[0] = j-1;                                                              │
   │138             stackp[-1] = l;                                                               │
   │139             l = i;                                                                        │
   │140           }                                                                               │
   │141         }                                                                                 │
   │142       }                                                                                   │
   │143     }                                                                                     │
   │144                                                                                           │
   │145     //--------------------------------------------------------------------------          │
   │146     // Main                                                                               │
   │147                                                                                           │
   │148     int main( int argc, char* argv[] )                                                    │
   │149     {                                                                                     │
   │150       // Output the input array                                                           │
   │151       printArray( "input", DATA_SIZE, input_data );                                       │
   │152       printArray( "verify", DATA_SIZE, verify_data );                                     │
   │153                                                                                           │
   │154     #if PREALLOCATE                                                                       │
   │155       // If needed we preallocate everything in the caches                                │
B+>│156       sort(DATA_SIZE, verify_data);                                                       │
   │157       if (verify(DATA_SIZE, input_data, input_data))                                      │
   │158         return 1;                                                                         │
   │159     #endif                                                                                │
   │160                                                                                           │
   │161       // Do the sort                                                                      │
   │162       setStats(1);                                                                        │
   │163       sort( DATA_SIZE, input_data );                                                      │
   │164       setStats(0);                                                                        │
   │165                                                                                           │
   │166       // Print out the results                                                            │
   │167       printArray( "test", DATA_SIZE, input_data );                                        │
   │168                                                                                           │
   │169       // Check the results                                                                │
   │170       return verify( DATA_SIZE, input_data, verify_data );                                │
   │171     }                                                                                     │
   │172                                                                                           │
   │173                                                                                           │
   │174                                                                                           │
   │175                                                                                           │
   │176                                                                                           │
   │177                                                                                           │
   │178                                                                                           │
   │179                                                                                           │
   │180                                                                                           │
   │181                                                                                           │
   │182                                                                                           │
   └────────────────────────────────────────────────
remote Thread <main> In: main                                                                      

(gdb) b main
Breakpoint 1 at 0x13b4: file qsort/qsort_main.c, line 156.
(gdb) c
The program is not being run.
(gdb) b main
Note: breakpoint 1 also set at pc 0x13b4.
Breakpoint 2 at 0x13b4: file qsort/qsort_main.c, line 156.
(gdb) target remote :10000
Remote debugging using :10000
0x0000000000000200 in _start ()
(gdb) b main
Note: breakpoints 1 and 2 also set at pc 0x13b4.
Breakpoint 3 at 0x13b4: file qsort/qsort_main.c, line 156.
(gdb) c
Continuing.

Breakpoint 1, main () at qsort/qsort_main.c:156
(gdb)