自己修正コード - alternative_2()
概要
置換元の命令を任意の2つの命令のいずれかで置き換えるためにデータを初期化し、初期化完了後はいずれかの命令を実行する
詳細
alternative_2(小文字でマクロを指定した場合)はアセンブリ命令を実行するALTERNATIVE_2マクロのwrapperとなる
ALTERNATIVE_2マクロ内では実行可能なアセンブリ命令の文字列を生成する
このマクロ内では以下の引数を受け取る
- 置換元の命令の文字列 : oldinstr
- 動的に挿入する命令の文字列 : newinstr1
- 動的に挿入する命令の機能番号を示す : feature1
- 動的に挿入する命令の文字列 : newinstr2
- 動的に挿入する命令の機能番号を示す : feature2
OLDINSTR_2()を実行し命令に必要なアドレスを確保する
そして、ALTINSTR_ENTRY()マクロ内でpushsectionにより、altinstructionsセクションに初期化したalt_instr構造体のデータを追加する
その後、ALTINSTR_REPLACEMENT()マクロ内でpushsectionにより、altinstr_replacementセクションに動的に挿入する命令を追加する
このマクロ内では命令の置換は行われず初期化だけが行われ、実際の命令の置換はapply_alternatives()で行われることになる*1
また、altinstructions、altinstr_replacementディレクティブについてはarch/x86/kernel/vmlinux.lds.Sのリンカスクリプト内で定義されており、altinstructions内のデータにアクセスするためには__alt_instructionsシンボルでアクセスできる
尚、初期化はコンパイル時に行われるためコンパイル時に初期化されたoldinstrを実行時に動的に初期化する
*1:この関数内ではCPUで有効になっている命令の場合に置換されるので、どちらも有効な命令の場合は2番目の命令が優先される