🍢
RISC-Vのコードをqemuで実行しgdbで観察する
RISC-VのCPUの実機を持っていなくても、qemuを使えば実行することができるし、gdbでステップ実行することもできます。
RISC-V用のクロスgdbの準備
こちらの記事を見てください。
サンプルのCのソースコード
この記事のものを使用しました。
pi.c
#include <stdio.h>
double AandW(int n)
{
double pi = 0.0;
if (n < 32) {
for (; n >= 0; --n) {
double n4 = n * 4.0;
double tmp =
(2 / (n4 + 1) + 2 / (n4 + 2) +
1 / (n4 + 3)) / (1LL << 2 * n);
pi += n & 1 ? -tmp : tmp;
}
}
return pi;
}
int main()
{
printf("PI=%.15f\n", AandW(31));
}
コンパイル
$ zig cc -o pi_riscv64 -target riscv64-linux-musl pi.c
$ file pi_riscv64
pi_riscv64: ELF 64-bit LSB executable, UCB RISC-V, RVC, double-float ABI, version 1 (SYSV), statically linked, with debug_info, not stripped
zig cc
でビルドするとデバッグ情報がついてきます。(gcc
の-g
がデフォルトで有効になっている)
qemuで実行しgdbで観察する
qemu-riscv64
またはqemu-riscv64-static
で実行。gdb用のポートは1234
にした。
$ qemu-riscv64-static -g 1234 ./pi_riscv64
別の端末からgdbを起動。
$ riscv64-linux-musl-gdb ./pi_riscv64
GNU gdb (GDB) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=aarch64-unknown-linux-gnu --target=riscv64-linux-musl".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./pi_riscv64...
リモートデバッグのセットアップ。
(gdb) target remote :1234
Remote debugging using :1234
0x0000000000011d7c in _start ()
(gdb) b main
Breakpoint 1 at 0x11f70: file pi.c, line 22.
(gdb) c
Continuing.
Breakpoint 1, main () at pi.c:22
22 printf("PI=%.15f\n", AandW(31));
毎回逆アセンブル表示をするように指定。
(gdb) display/i $pc
1: x/i $pc
=> 0x11f70 <main+10>: auipc ra,0x0
RISC-Vの命令単位でステップ実行する。
(gdb) si
0x0000000000011dc6 4 {
1: x/i $pc
=> 0x11dc6 <AandW+2>: sd ra,104(sp)
(gdb) si
0x0000000000011dc8 4 {
1: x/i $pc
=> 0x11dc8 <AandW+4>: sd s0,96(sp)
(gdb) si
0x0000000000011dca 4 {
1: x/i $pc
=> 0x11dca <AandW+6>: addi s0,sp,112
(gdb) si
0x0000000000011dcc 4 {
1: x/i $pc
=> 0x11dcc <AandW+8>: sw a0,-20(s0)
(gdb) si
0x0000000000011dd0 4 {
1: x/i $pc
=> 0x11dd0 <AandW+12>: li a0,0
(gdb) si
5 double pi = 0.0;
1: x/i $pc
=> 0x11dd2 <AandW+14>: sd a0,-32(s0)
(gdb) si
6 if (n < 32) {
1: x/i $pc
=> 0x11dd6 <AandW+18>: lw a1,-20(s0)
(gdb) si
0x0000000000011dda 6 if (n < 32) {
1: x/i $pc
=> 0x11dda <AandW+22>: li a0,31
(gdb)
レジスタのダンプ。
(gdb) info all-reg
zero 0x0 0
ra 0x11f78 0x11f78 <main+18>
sp 0x4000800440 0x4000800440
gp 0x18010 0x18010
tp 0x18c70 0x18c70 <builtin_tls+200>
t0 0x0 0
t1 0x7 7
t2 0x6474e551 1685382481
fp 0x40008004b0 0x40008004b0
s1 0x1 1
a0 0x0 0
a1 0x1f 31
a2 0x4000800508 274886296840
a3 0x0 0
a4 0xfffffffffffe7390 -101488
a5 0x12174 74100
a6 0x18cf8 101624
a7 0x60 96
s2 0x11f66 73574
s3 0x4000800508 274886296840
s4 0x0 0
s5 0x0 0
s6 0x0 0
s7 0x0 0
s8 0x0 0
s9 0x0 0
s10 0x0 0
s11 0x0 0
t3 0x18a40 100928
t4 0x6 6
t5 0x1 1
t6 0x0 0
pc 0x11dda 0x11dda <AandW+22>
ft0 {float = 0, double = 0} (raw 0x0000000000000000)
ft1 {float = 0, double = 0} (raw 0x0000000000000000)
ft2 {float = 0, double = 0} (raw 0x0000000000000000)
ft3 {float = 0, double = 0} (raw 0x0000000000000000)
ft4 {float = 0, double = 0} (raw 0x0000000000000000)
ft5 {float = 0, double = 0} (raw 0x0000000000000000)
ft6 {float = 0, double = 0} (raw 0x0000000000000000)
ft7 {float = 0, double = 0} (raw 0x0000000000000000)
fs0 {float = 0, double = 0} (raw 0x0000000000000000)
fs1 {float = 0, double = 0} (raw 0x0000000000000000)
--Type <RET> for more, q to quit, c to continue without paging--c
fa0 {float = 0, double = 0} (raw 0x0000000000000000)
fa1 {float = 0, double = 0} (raw 0x0000000000000000)
fa2 {float = 0, double = 0} (raw 0x0000000000000000)
fa3 {float = 0, double = 0} (raw 0x0000000000000000)
fa4 {float = 0, double = 0} (raw 0x0000000000000000)
fa5 {float = 0, double = 0} (raw 0x0000000000000000)
fa6 {float = 0, double = 0} (raw 0x0000000000000000)
fa7 {float = 0, double = 0} (raw 0x0000000000000000)
fs2 {float = 0, double = 0} (raw 0x0000000000000000)
fs3 {float = 0, double = 0} (raw 0x0000000000000000)
fs4 {float = 0, double = 0} (raw 0x0000000000000000)
fs5 {float = 0, double = 0} (raw 0x0000000000000000)
fs6 {float = 0, double = 0} (raw 0x0000000000000000)
fs7 {float = 0, double = 0} (raw 0x0000000000000000)
fs8 {float = 0, double = 0} (raw 0x0000000000000000)
fs9 {float = 0, double = 0} (raw 0x0000000000000000)
fs10 {float = 0, double = 0} (raw 0x0000000000000000)
fs11 {float = 0, double = 0} (raw 0x0000000000000000)
ft8 {float = 0, double = 0} (raw 0x0000000000000000)
ft9 {float = 0, double = 0} (raw 0x0000000000000000)
ft10 {float = 0, double = 0} (raw 0x0000000000000000)
ft11 {float = 0, double = 0} (raw 0x0000000000000000)
fflags 0x0 RD:0 NV:0 DZ:0 OF:0 UF:0 NX:0
frm 0x0 FRM:0 [RNE (round to nearest; ties to even)]
fcsr 0x0 RD:0 NV:0 DZ:0 OF:0 UF:0 NX:0 FRM:0 [RNE (round to nearest; ties to even)]
cycle 0x5378ecd49022f 1468461352550959
time 0x5378ecd4cf226 1468461352808998
instret 0x5378ecd4ed135 1468461352931637
priv 0x0 prv:0 [User/Application]
(gdb)
gdbのドキュメント
関連
Discussion