web-dev-qa-db-ja.com

endbr64命令は実際には何をしますか?

私はGCCによって生成されたアセンブリ言語コードを理解しようとしましたが、_start()を含む多くの関数の開始時にこの命令に頻繁に遭遇しましたが、その目的を説明するガイドが見つかりませんでした

31-0000000000001040 <_start>:
32:    1040:    f3 0f 1e fa             endbr64 
33-    1044:    31 ed                   xor    ebp,ebp
9
Mah35h

これは「End Branch 64ビット」を意味します-より正確には、64ビットでTerminate Indirect Branch

インテルにはこの命令に関するドキュメントがあります

操作は次のとおりです。

IF EndbranchEnabled(CPL) & EFER.LMA = 1 & CS.L = 1
  IF CPL = 3
  THEN
    IA32_U_CET.TRACKER = IDLE
    IA32_U_CET.SUPPRESS = 0
  ELSE
    IA32_S_CET.TRACKER = IDLE
    IA32_S_CET.SUPPRESS = 0
  FI
FI;

それ以外の場合、命令はNOPと見なされます。

CET機能は、間接ブランチが実際に有効な場所に移動することを確認するために使用されます。これにより、安全性がさらに向上します。これはIntelからの段落です:

ENDBRANCH(詳細はセクション73を参照)は、プログラム内の間接呼び出しとジャンプの有効なジャンプターゲットアドレスをマークするために使用される新しい命令です。この命令オペコードは、レガシーマシンでNOPになるように選択されているため、ENDBRANCH新しい命令でコンパイルされたプログラムは、CETを適用しなくても古いマシンで機能し続けます。 CETをサポートするプロセッサでは、ENDBRANCHは引き続きNOPであり、主にプロセッサパイプラインによってマーカー命令として使用され、制御フロー違反を検出します。 CPUは、間接jmpと呼び出し命令を追跡するステートマシンを実装します。これらの命令のいずれかが表示されると、ステートマシンはIDLE状態からWAIT_FOR_ENDBRANCH状態に移行します。 WAIT_FOR_ENDBRANCH状態では、プログラムストリームの次の命令はENDBRANCHでなければなりません。 ENDBRANCHが表示されない場合、プロセッサは制御保護例外(#CP)を発生させます。それ以外の場合、ステートマシンはIDLE状態に戻ります。

10
Alexis Wilke