riscv-testsでのハマりポイント(個人的に)

はじめに

riscv-testsの個人的ハマりポイントの備忘録です。riscv-testsを初めて触った時の自分や将来完全に仕様を忘れてるであろう自分向けの記事です。参考になれば幸いです。もっといい方法や誤りがあれば教えてください。

テスト終了の判定

riscv-testsではテストが終了すると.tohostセクションに1が書き込まれます。readelf -Sで確認しましょう。以下が.tohostセクションのアドレスを表示させたものになります。このアドレスは物理アドレスです。0x80001000番地に.tohostセクションが多いですね。

1
2
3
4
5
6
> ls tests/isa/elves/*  | grep -v -e \.dump$  -e Makefile | xargs -IFILE readelf -S FILE | grep tohost | awk '{print "0x" $5}' | sort | uniq -c
    350 0x0000000080001000
      3 0x0000000080002000
      1 0x0000000080003000
    268 0x80001000
      1 0x80002000

フラットバイナリ

riscv-testsをビルドするとelfファイルとして出力されるのですがelfローダを実装するのが面倒(怠惰)でとりあえず以下のようにelfファイルをフラットバイナリに変換し、テストを実行していました。

1
riscv64-unknown-elf-objcopy -O binary file file.bin

ですが仮想メモリシステムを実装する際にテストが通らなかったのファイルの中身をみたところLOADセクションの配置すべき物理アドレスがちゃんとずれていました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
> readelf -l   tests/isa/elves/rv64ui-v-add                                                                                                                                                   

Elf ファイルタイプは EXEC (実行可能ファイル) です
Entry point 0x80000000
There are 4 program headers, starting at offset 64

プログラムヘッダ:
  タイプ        オフセット          仮想Addr           物理Addr
            ファイルサイズ        メモリサイズ         フラグ 整列
  RISCV_ATTRIBUT 0x00000000000041c4 0x0000000000000000 0x0000000000000000
                 0x0000000000000065 0x0000000000000000  R      0x1
  LOAD           0x0000000000001000 0x0000000080000000 0x0000000080000000
                 0x0000000000000200 0x0000000000000200  R E    0x1000
  LOAD           0x0000000000002000 0x0000000080001000 0x0000000080001000
                 0x00000000000021c4 0x0000000000008010  RWE    0x1000
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0x10

 セグメントマッピングへのセクション:
  セグメントセクション...
   00     .riscv.attributes
   01     .text.init
   02     .tohost .text .rodata.str1.8 .bss .sbss
   03

LOADセクションを正しい位置に配置するだけの簡易的なELFローダを作成しテストを実行したところテストを通すことができました。やはり怠惰はいけないです。そもそもフラットバイナリに変換するシェルスクリプト書くよりELFローダ書いた方が早かったのでは

0x80000000

フラットバイナリを0x0番地に配置し、pcを0にセットして実行していく形式にしていましたがこれも仮想メモリシステムを実装する際にテストが通らなくなりました。0x80000000番地に配置する想定にしましょう。リンカスクリプトを変更すれば別のところに配置することはできるようになると思います。(未検証)

Licensed under CC BY-NC-SA 4.0
Hugo で構築されています。
テーマ StackJimmy によって設計されています。