Arm コンパイラー新バージョン 6.12 ~ セキュリティー機能と性能が向上 ~

Arm コンパイラーの最新バージョン 6.12 がリリースされました。Arm コンパイラーは、以下の開発ツールスイート製品に同梱されています。

優れたパフォーマンス

Arm はすべてのワークロードにおいてパフォーマンスが向上するよう、常に最適化に取り組んでいます。Arm コンパイラー 6.12 は、Cortex-M33 上で最高の CoreMark スコア “CoreMarks/MHz 4.02” を達成しました。また、CMSIS-DSP および CMSIS-NN ソフトウェア ライブラリーなど特定のワークロードにおいても、大幅な改善をもたらします。

Arm コンパイラー 6.12 の新機能

本リリースでは、主な新機能として以下の 2つの機能が追加されました。その他の新機能については、こちらをご覧ください。

1. スタック保護

Arm コンパイラー 6.12 は、スタック保護 (英語)を完全にサポートします。スタック保護はメモリー アクセス エラーを悪用した攻撃を防ぐセキュリティー機能で、システム全体の回復力と完全性を向上します。

この機能は、脆弱性のある各関数、またはすべての関数のスタック フレームに保護変数を挿入することで実行されます。関数のプロローグで、保護変数がスタック フレーム上に格納されます。関数から戻る前に、エピローグで保護変数が上書きされていないか確認します。上書きされている場合は、バッファーがオーバーフローしたことを意味し、ランタイム環境に警告が表示されます。

スタック保護機能は、コンパイラー オプション -fstack-protector、-fstack-protector-all、-fstack-protector-strong (英語) を使用して有効化できます。

保護変数の初期値は、グローバル変数から取り出されます。
void *__stack_chk_guard;

変数には、適切な値を指定する必要があります。例えば、プログラムが読み込まれ、最初の保護された関数に入る前に、この変数にランダムな値を設定するのも適切です。プログラムのライフサイクルの間は、値を変更しないでおく必要があります。

スタック上の保護変数が変更されたことが検知されると、関数が呼び出されてランタイム環境に通知されます。
void __stack_chk_fail(void);

最適化はスタック保護に影響を及ぼす場合があります。

  • インライン化は、関数が保護されているかどうかに影響する場合があります。
  • 使用していない変数を削除すると、関数が保護されないようにすることができます。

2. グローバル名前付きレジスター変数

Arm コンパイラー 6.12 では、グローバル名前付きレジスター変数 (英語)を使用することができます。メモリーに格納されていなくても素早くアクセスすることができ、性能が若干向上します。この機能は aarch32 ステートでのみ利用可能です。

register _asm (英語) キーワードを使うと、直接コア レジスターを C の変数のように操作することができます。
register Type VariableName __asm(“Reg”)

  • Type = 変数のデータ型。char や 8-bit、16-bi、or 32-bit の整数型、またはそれらのデータ型のポインタ型を指定可能
  • VariableName = 変数名
  • Reg = 変数を格納するのに使用するコア レジスター。R5 ~ R11 を指定可能

以下のレジスターは、フレーム ポインターとして使用するために Arm ABI (アプリケーション・バイナリー・インタフェース) で予約されているため、グローバル名前付レジスター変数で使用することは推奨されません。

  • T32 ステートでの R7
  • A32 ステートでの R11

例えば、R5 を グローバル名前付きレジスターとして使用できるように、整数型の foo として宣言する場合は、以下のように記述します。
register int foo __asm(“R5”)

Arm 標準ライブラリは –ffixed-rN オプションを使用してビルドされていないため、上記の例では -ffixed-r5 (-ffixed-rN (英語) を参照) オプションを指定してコンパイルする必要があります。

グローバル名前付きレジスター変数を含むアプリケーション コードを Arm 標準ライブラリにリンクする場合は、下記の点に注意してください。

  • 正しくランタイムが動作するように、ライブラリのコードからグローバル名前付きレジスター変数を使用したコードが呼び出されていないことを確認します。
  • アプリケーション コード内でグローバル名前付きレジスター変数として使用されているレジスターであっても、ライブラリー コードがスタックに PUSH および POP する可能性があります。

グローバル名前付きレジスター変数を使用すると、パフォーマンスは向上するものの、コンパイラーがその他の操作用途でコア レジスターを利用できなくなるため、コードのサイズが大きくなります。そのため、必要以上に宣言しすぎると、コードサイズが大幅に増加してしまいます。特定の式の計算に利用できるレジスターが不足してしまい、プログラムをコンパイルできなくなる場合もあるため、ご注意ください。

その他の関連情報

Arm コンパイラーは、Arm Development Studio または Keil MDK に同梱されています。Arm Development Studio の評価版をダウンロードいただくことで、ご試用いただけます。30 日間試用可能な無償評価版のお申し込みはこちらから。

バージョン 6.12 の変更点や新機能の詳細に関しては、こちらのページをご参照ください。また、こちらのページ (英語)で関連ドキュメントをご覧いただけます。

Arm コンパイラー 5.x をご利用中で、バージョン 6 に移行されたい場合は、『Arm Compiler Migration and Compatibility Guide Version 6.12 (英語)』をご覧ください。


この記事は、Arm 社の Software Tools Blog に公開されている「Arm Compiler 6.12: Bringing in security and improved performance」の日本語参考訳です。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする