32bit版RISC-VのLinux syscall 62はlseekではない?

Linuxシステムコール62番は、64bit版の場合、lseekです。

off_t lseek(int fd, off_t offset, int whence);

lseekシステムコールは、第一引数にファイルディスクリプタ、第二引数にどれだけ移動させるか、第三引数に動作の種類を受け取り、最終的な位置を返り値で返します。 第二引数の解釈は、第三引数によって変わります。エラーが発生した場合は、返り値が(off_t)-1になり、errnoによってエラーの種類が通知されます。

Linuxシステムコールの場合、引数や返り値はレジスタで渡されます。そうすると、32bit版では、2GiB程度までのファイルしか扱えないということになりそうです。

調べてみると、Linuxシステムコール62番は、32bit版の場合、_llseekになっています。

int _llseek(unsigned int fd, unsigned long offset_high, unsigned long offset_low, loff_t *result, unsigned int whence);

_llseekシステムコールは、第一引数にファイルディスクリプタ、第二引数と第三引数にどれだけ移動させるか、第五引数に動作の種類を受け取り、最終的な位置を第四引数で指定されたポインタの部分に書き込みます。 第二引数と第三引数は組み合わせて64bitの値として使用されます。エラーが発生した場合は、返り値が-1になり、errnoによってエラーの種類が通知されます。成功した場合、返り値は0になります。

このようにすることで、32bitのレジスタしかもっていないアーキテクチャであっても、2GiBを超えるファイルが取り扱えるようです。

この間ビルドしたspike、qemu3.1.0を使って調べたところ、どちらもlseekの動作をしているのですが、qemu4.1.0を使ってみると_llseekになっています。 gccコンパイル結果を見ても、_llseekを期待しているバイナリになっています。

これはシステムコールの仕様が変わったのでしょうか……? 公式が作っているシミュレータであるspikeが常に正しいと思っていたのですが、古い常識となっているのでしょうか?

ちょっとはまったのでメモ書きでした。