AMD64 ターゲットと ABI

Linux AMD64 ターゲット属性、呼び出し境界、native 機能範囲について説明します。

Wave Foundation

ターゲット識別子

nativeプロファイルのターゲット識別子はx86_64-whale-linuxです。

プロパティ 値
オペレーティングシステム Linux
コマンドセット AMD64
バイト順 Little endian
Native アドレス幅 64ビット
オブジェクト形式 ELF64
C呼び出し規約 SysV AMD64 ABI
静的実行可能ファイル形式 ELF ET_EXEC

ビルドホストと出力ターゲットは異なる概念です。他のホストでWhaleを実行できるとしても、そのホストのコマンドセットやオブジェクト形式を出力できるわけではありません。実装されたコンパイルパスについては、サポート状況を参照してください。

ターゲットの選択と検証

実験的なir lowerコマンドは、x86_64-whale-linuxをデフォルトで唯一のサポートターゲットとして使用します。このコマンドを使用するには、--features socket-cliでビルドします。

whale ir lower program.json --target x86_64-whale-linux

出力ターゲットは、ビルドホストとは無関係に64ビットlittle-endianデータレイアウトを提供します。未知の識別子やaarch64-whale-linux、x86_64-whale-windowsなどの未サポートの組み合わせは、入力を読み取るか出力ファイルを置き換える前にサポートターゲットを案内するエラーで失敗します。 --no-verifyでもターゲット選択チェックをオフにできません。

空のAST({"globals":[],"functions":[]})を入力すると、次のヘッダーとモジュールが出力されます。

module {
  format_version 2
  semantics_version 1
  target "x86_64-whale-linux"
  datalayout { ptr=64, endian=little }

}

未サポートターゲットを指定すると、失敗状態で終了します。

whale ir lower program.json --target banana
Error: unsupported target "banana"; supported targets: x86_64-whale-linux

Rustではir::Target::lookup("x86_64-whale-linux")でターゲットを選択し、そのname()とdata_layout()をlower_o0に渡すことができます。 Loweringは、渡されたレイアウトが選択したターゲットと異なる場合は拒否します。直接設定したIRもverify_moduleで未サポートのターゲット名とレイアウトの不一致を確認します。

オブジェクトモデルは、ObjectTargetにformat、machine、endian、address_bitsを保存します。 ObjectFile::with_targetは明示的な識別情報を保存し、シリアル化はAMD64・little-endian・64ビットELF64の組み合わせのみを許可します。他のアーキテクチャのmachine識別子があるという事実は、そのエンコーダのサポートを意味しません。両方のELFwriterエントリポイントはすべてメタデータをチェックし、リンカ入力はシンボル解析またはリンクの前にチェックします。サポートされているオブジェクトのELFヘッダーはEM_X86_64を保持します。

ObjectFile::new(ObjectFormat::ELF64)は、従来のようにこのAMD64識別情報を使用する便利なコンストラクタです。既存のobject.formatにアクセスしていたコードは、object.target.formatを使用する必要があります。

このチェックは、ターゲットの選択とオブジェクトの識別を提供します。構造体・配列などの大きさ、フィールドoffset、strideはIRレイアウトAPIで照会できます。オブジェクトファイルの読み取り、nativeABIlowering、実行可能ファイルへのリンクはまだサポートされていません。スカラー lowering は明示的な並べ替えを指定し続け、全体の複合型レイアウト規則は メモリ参照ドキュメント で定義されています。

呼び出しと署名

IR 宣言と呼び出しベリファイアは、明示的な Whale および SysV64 規則を受け入れます。この規則は fnptr タイプの一部であり、呼び出しサイトで一致する必要があります。可変長署名と SysV64 集合署名は拒否されます。 実行可能呼び出しの構築例を参照してください。これにより、IR 契約が検証されます。マシン ABI 分類、引数レジスタ/スタックの配置、およびネイティブ呼び出しの発行はまだ実装されていません。

サポートされている呼び出しには明示的な署名と呼び出し規約が必要です。未サポート署名はエラーです。バックエンドは引数を欠落したり、他の表現に置き換えて同様の呼び出しを作成してはいけません。

署名サポートは基本整数・ポインタ、f32/f64、構造体・広い値、可変因子で区分します。 IRタイプ体系にタイプがあると、そのタイプの引数渡しや返却までABIでサポートされるという意味ではありません。バックエンドを選択するときは、必要なカテゴリのサポートを確認する必要があります。

たとえば、i32戻りを処理するバックエンドもサポートしていない構造体戻り署名は拒否する必要があります。構造体の一部がスカラーレジスタに入るため、スカラー戻り規約を適用することはできません。

内部呼び出しとC境界

nativeポインタアドレスは64ビットです。トレースポインタのshadowmetadataはコピー・保存・引数・返却を経ても一緒に渡さなければなりません。

CABIと内部メタデータ配信規約は区別されます。 C境界を超える呼び出しには明示的なアダプタが必要です。数字の住所をCABIに渡したという理由だけで、割り当てアイデンティティ、寿命、範囲、アクセス権限が保存されたと見なすべきではありません。

スタックフレーム

フレームポインタを保持し、redzoneを使用しません。 O0は、異なるローカル変数の記憶領域を再利用しません。呼び出しフレームのデバッグ情報は、nativeフレームと元のプログラムの対応を記述します。

このルールはデバッグのためのものであり、例外unwindingサポートを意味しません。 O0とデバッグを参照してください。

プロファイル制限

最初の O0 native プロファイルには次の機能は含まれません。

  • O1以上最適化、ベクトル化、LTO.
  • 共有メモリとatomic演算。
  • 例外 unwinding、async関数、coroutine.
  • GCと言語別の所有権検査。
  • ランダム外部メモリの所有権の移転。
  • 完全なインラインアセンブリ制約のサポート。
  • 動的リンク、TLS、追加のコマンドセット、追加のオブジェクト形式。

サポート範囲外の要求は、他の機能に静かに置き換えることなく拒否する必要があります。この制限は、nativeコンパイルパスのためのものであり、独立して提供されている他のツールチェーンコンポーネントを削除するわけではありません。