読者です 読者をやめる 読者になる 読者になる

linuxのメモ

Linux kernelの実装を解説していきます (対象ver 4.5)

アセンブラ命令 - THUNK

概要

任意のラベル名でデフォルト引数を持つ指定した関数を実行するコードを生成する

詳細

アセンブラのマクロとして定義され、以下の引数を受け取る

  • ラベルの名前を示す : name
  • 実行する関数へのポインタ : func
  • 実行する関数に呼び出し元のアドレスが必要かどうかを確認するための値 : put_ret_addr_in_eax
    • この値はデフォルトで0になるため、指定されていない場合は呼び出し元のアドレスを実行するの引数として渡さない

実行する処理の流れとしては以下のようなものになる

  1. 呼び出し元の関数の引数として渡されているデータをスタックに退避する
  2. call命令によりfuncを実行する
  3. put_ret_addr_in_eaxが0以外の場合は呼び出し元のアドレスを保持するアドレスをスタックから%eaxレジスタにコピーする
  4. 対比した引数のデータをスタックから元のレジスタを復元す
  5. _ASM_NOKPROBEnameを示すアドレスを kprobe_blacklistセクションに追加する*1

このマクロは32bitと64bitでコードは違うが、処理の内容は全く同じである

異なる点は、スタックに退避・復元するレジスタの種類と呼び出し元のアドレスを保持するアドレスを算出するときに使用する%espレジスタとの相対アドレスだけです

32bitの場合は4byte * 3、64bitの場合は8byte * 9で呼び出し元のアドレスを保持するアドレスを算出します

3、9はそれぞれ退避するレジスタの個数を示しています

*1:これはC言語で同じシンボル名を使用されることを防いでいるのだと思うが、まだわかりません。。