以下の内容はhttps://retrage01.hateblo.jp/entry/2025/12/11/182205より取得しました。


ARM64向けの高速なシステムコールフックであるsvc-hookをNetBSD対応させた話

本記事はNetBSD Advent Calendar 2025 11日目の記事として書かれた。

前置き

去年、趣味で svc-hook というバイナリ書き換えを利用した高速な(ptraceの1000倍以上)ARM64向けシステムコールフックを開発した。当初はLinuxのみのサポートであったが、他のUnix系OSにも対応したら面白いだろうということで、FreeBSDNetBSDに対応した。今回はNetBSDに限って、どのような対応が必要だったのかを解説する。svc-hook公開時のブログ記事では、初期の設計について解説している。

なお、svc-hookはACM/IFIP Middleware 2025の論文として採択された

ARM64 Linuxの場合

NetBSDに入る前に、ARM64 LinuxにおけるSystem Call ABIとそれを踏まえたsvc-hookの作りを説明する。 Linuxでは、x8レジスタシステムコール番号を、x0からx7に引数を入れた上で svc 命令を実行することでシステムコールが発行される。x86syscall/sysenterと異なり、 svc命令自身も16-bitの即値 #immを取るが、Linuxではこの即値は必ず0が与えられており、使われていない。

この「x8にシステムコール番号を入れる」という規約はFreeBSDでも同様である。

svc-hookでは、svcb命令に置き換えてトランポリンを経由したあとにユーザが設定したhook functionを呼び出すようにしている。このとき、x8へのアクセスは発生しないので、hook functionの中からx8を読み出すことで容易にシステムコール番号を知ることができる。

ARM64 NetBSDの場合

一方、NetBSDでは事情が異なる。NetBSDでは、Linux/FreeBSDでは使用されていない svc 命令の即値 #immシステムコール番号を設定して呼び出す。通常、EL0からシステムコールが発行されると、EL1/EL2のexception vectorに飛んだときに ESR_ELx.ISSに即値の値が入るので、x8に入っている場合とあまり変わらない手順でシステムコール番号を知ることができる。

一方、svc-hookのようにユーザ空間に飛ばす場合は事情が異なる。b命令で svcを即値もろとも書き換えるので、そのままでは即値の情報が失われてしまう。そこで、

  1. 即値は命令をデコードすれば簡単にわかる
  2. svc-hookでは各 svcごとにトランポリンを持っている

という二つの特徴から、トランポリン作成時に各 svc の即値をトランポリンに埋め込んであげることでhook functionからシステムコール番号がわかるようにした。

また、Linux/FreeBSDではsvc-hookから svc命令を実行する場合には、ただ一つの svc #0を用意してそこにジャンプするだけでよかったが、NetBSDの場合は即値は0~216 - 1 の値を取りうる。このため、svc-hookでは、初期化時に svc #n; ret; (合計8bytes) のシステムコールテーブルを用意して対応している。対応する即値を持ったシステムコールを発行したい場合には、nr_syscall * 8 のオフセットに関数呼び出しをするだけでよい。

雑多に思うこと

そもそもなぜNetBSDLinux/FreeBSDと異なるシステムコール番号の渡し方を採用したのか、というのは気になるところである。おそらくARM社がARM64のソフトウェア対応を始めたときには真っ先にLinux (Android)などのモバイル環境をターゲットにしたはずであり、であれば先行しているLinuxなどに挙動を合わせることも可能であったはずである。しかし、そうはなっていない。私はArmv8よりも前のARMに詳しくないので想像だが、かつての組み込みではレジスタ数が少なく、可能な限りシステムコール発行時に使用するレジスタ数を減らすというのがセオリーだった名残ではないかと推測している。この辺り、NetBSDにポートされた2014年当時を知る方がいらっしゃったら教えていただきたい。

終わりに

この記事ではsvc-hookのNetBSD固有の対応が必要だった部分について解説した。「ARM64でのシステムコール番号の渡し方」という非常にニッチな話題ながら、BSD系ですら違いがあるのは非常に面白く、年末の酒の肴にピッタリの小ネタであるといえる。




以上の内容はhttps://retrage01.hateblo.jp/entry/2025/12/11/182205より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14