linuxのメモ

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

alternative

自己修正コード - alternative()

概要 置換元の命令を任意の命令で置き換えるためにデータを初期化し、初期化完了後はいずれかの命令を実行する 詳細 alternative(小文字でマクロを指定した場合)はアセンブリ命令を実行するALTERNATIVEマクロのwrapperとなる ALTERNATIVEマクロ内では実行可…

自己修正コード - arch_static_branch_jump

概要 分岐可能なコードを生成し、条件を判断するコードを1を返すコードへのJMP命令で初期化する 詳細 asm_volatile_goto()で分岐可能なアセンブラ命令を生成する 0xe9で示されるJMP命令で初期化し、l_yesラベルへ分岐するため初期状態では常に1を返すことに…

自己修正コード - arch_static_branch()

概要 分岐可能なコードを生成し、条件を判断するコードをNOP命令で初期化する 詳細 asm_volatile_goto()で分岐可能なアセンブラ命令を生成する __stringify()にSTATIC_KEY_INIT_NOPを渡すことで5byteのNOP命令の文字列を生成するため、初期状態では常に0を返…

自己修正コード - alternative_2()

概要 置換元の命令を任意の2つの命令のいずれかで置き換えるためにデータを初期化し、初期化完了後はいずれかの命令を実行する 詳細 alternative_2(小文字でマクロを指定した場合)はアセンブリ命令を実行するALTERNATIVE_2マクロのwrapperとなる ALTERNATIVE…

自己修正コード - __OLDINSTR()

概要 命令に必要なサイズ分のアドレスを確保する 詳細 以下の引数を受け取る 置換元となる命令を示す文字列 : oldinstr 置換する命令の番号を示す : num alt_rlen()にnumを引数として実行し、命令が配置されるアドレスのサイズ取得し、この値と置換元の命令…

自己修正コード - OLDINSTR()

概要 命令に必要なサイズ分のアドレスを確保する 詳細 __OLDINSTR()で命令に必要なサイズ分のアドレスを確保し、 alt_end_markerで命令終了のシンボルを付加する

自己修正コード - ALTINSTR_ENTRY()

概要 alt_inster構造体のデータを初期化する 詳細 alt_inster構造体では以下のメンバを持つ instr_offset : 32bit整数 repl_offset : 32bit整数 cpuid : 16bit符号無し整数 instrlen : 8bit符号無し整数 replacementlen : 8bit符号無し整数 padlen : 8bit符…

自己修正コード - OLDINSTR_2()

概要 命令に必要なサイズ分のアドレスを確保する 詳細 以下の引数を受け取る 置換元となる命令を示す文字列 : oldinstr 置換する命令1の番号を示す : num1 置換する命令2の番号を示す : num2 alt_rlen()にnum1とnum2を引数として実行し、命令1と命令2の命令…

自己修正コード - alt_slen

概要 置換元の命令に必要なアドレスのサイズを取得する 詳細 662ラベルから661ラベルのアドレスを減算することで命令に必要なアドレスのサイズを取得する このマクロでは命令の開始ラベルが661、終了ラベルが662となっている必要があり、更にラベルに"b"のsu…

自己修正コード - ALTINSTR_REPLACEMENT()

概要 任意の命令をメモリに配置する 詳細 b_replacement()で命令を配置する開始アドレスを示すラベルを取得し、定義する その後、任意の命令を挿入し命令の直後にe_replacement()で命令で終了アドレスを示すラベルを定義する

自己修正コード - alt_rlen()

概要 動的に挿入する命令に必要なアドレスのサイズを取得する 詳細 b_replacement()から挿入する命令の開始アドレスを指すラベル名を、e_replacement()から挿入する命令の終了アドレスを指すラベル名をそれぞれ取得し、終了アドレスから開始アドレスを減算す…

自己修正コード - e_replacement()

概要 動的に挿入する命令の終了アドレスを指すラベル名を生成する 詳細 命令の終了アドレスを指すラベル名を文字列"665"に引数の数値を文字列として連結して生成する 尚、開始アドレスを示すラベルを生成するためにb_replacement()を使用する

自己修正コード - b_replacement()

概要 動的に挿入する命令の開始アドレスを指すラベル名を生成する 詳細 命令の開始アドレスを指すラベル名を文字列"664"に引数の数値を文字列として連結して生成する 尚、終了アドレスを示すラベルを生成するためにe_replacement()を使用する

自己修正コード - alt_max_short()

概要 2つの値の最大値を返す 詳細 ((a) ^ (((a) ^ (b)) & -(-((a) < (b))))) 上記のコードで分岐を使わずに算術演算だけで最大値を取得できる*1 分岐はコストのかかる処理なので、分岐が無いことで高速に動作する このマクロはarch/x86/include/asm/alternat…