Oracle® Solaris Studio 12.4: C ユーザーガイド

印刷ビューの終了

更新: 2014 年 12 月
 
 

2.17 フリースタンディング環境でのコンパイル

Oracle Solaris Studio C コンパイラは、標準 C ライブラリにリンクされたプログラムのコンパイルや、標準 C ライブラリおよびほかの実行時サポートライブラリが含まれる実行環境での実行をサポートします。C 標準では、そのような環境はホスト環境と呼ばれます。標準ライブラリ関数を提供しない環境は、フリースタンディング環境と呼ばれます。

コンパイルされたコードから呼び出される可能性のある特定の実行時サポート関数は通常、標準 C ライブラリでのみ使用可能なため、C コンパイラはフリースタンディング環境での一般的なコンパイルをサポートしません。問題は、コンパイラによるソースコードの変換によって、関数呼び出しを含まないソースコード構造体で実行時サポート関数への呼び出しが導入される場合があり、これらの関数は通常フリースタンディング環境で使用できないことです。次の例を考えてみましょう。

% cat -n lldiv.c
	 1	void
	 2	lldiv(
	 3	    long long *x,
	 4	    long long *y,
	 5	    long long *z)
	 6	{
	 7	    *z = *x / *y ;
	 8	}
% cc -c -m32 lldiv.c
% nm lldiv.o | grep " U "
 0x00000000 U __div64
% cc -c -m64 lldiv.c
% nm lldiv.o | grep " U "

この例では、-m32 オプションを使用して 32 ビットプラットフォームで実行するようにソースファイル lldiv.c がコンパイルされると、行 7 の文の変換が __div64 という名前の実行時サポート関数への外部参照となります。これは、標準 C ライブラリの 32 ビットバージョンでのみ使用できます。

同じソースファイルが -m64 オプションを使用して 64 ビットプラットフォームで実行するようにコンパイルされると、コンパイラはターゲットマシンの 64 ビット算術命令セットを使用するため、標準 C ライブラリの 64 ビットバージョンでの実行時サポート関数が不要になります。

フリースタンディング環境をターゲットとする C コンパイラの使用は一般的な事例ではサポートされませんが、特定のフリースタンディング環境 (つまり Oracle Solaris カーネルとデバイスドライバ) 用にコードをコンパイルするためにコンパイラを使用することはできます (警告が生成されます)。

デバイスドライバなど、Oracle Solaris カーネルで実行されるコードは、外部関数呼び出しがカーネル内で使用可能な関数のみ参照するように記述する必要があります。これを可能にするため、次のガイドラインが推奨されます。

  • ユーザーモードでのみ実行されるライブラリのヘッダーファイルは含めないでください。

  • 同じ関数がカーネルに存在していることがわかっているのでない限り、標準 C ライブラリまたはほかのユーザーモードライブラリ内の関数を呼び出さないでください。

  • 浮動小数点型または複合型を使用しないでください。

  • ランタイムサポートライブラリに関連付けられたコンパイラオプションを使用しないでください (-xprofile-xopenmp-xautopar など)。

    特定のコンパイラオプションに関連付けられた再配置可能なオブジェクトファイルは、cc(1) マニュアルページの FILES セクションで説明されています。C コンパイラオプションに関連付けられた実行時サポートライブラリは、関連するオプションを説明している箇所に記載されています。

前述のように、ソースコードの変換の結果、コンパイラにより実行時サポート関数への呼び出しが生成されることがあります。Oracle Solaris カーネルの特定の事例では、カーネルが浮動小数点型や複合型、数学ライブラリ関数、または実行時サポートライブラリに関連付けられたコンパイラオプションを使用しないため、呼び出される可能性のある実行時サポート関数のセットが一般的な事例より小さくなります。

次の表に、C コンパイラによるソースコード変換の結果、Oracle Solaris カーネルで実行するためにコンパイルされたコードで呼び出される可能性のある実行時サポート関数を示します。この表に、ソースコードの変換で呼び出しが生成されるプラットフォーム、呼び出される関数の名前、関数呼び出しを引き起こすソース構造体またはコンパイラ機能を示します。C コンパイラをサポートする Solaris のすべてのバージョンで 64 ビットカーネルが実行されるため、64 ビットプラットフォームだけがリストに示されています。

32 ビット命令セット用にコンパイルすると、命令セットに固有の制限があるため、追加のマシン固有のサポート関数が呼び出されることがあります。

表 2-4  実行時サポート関数
関数
64 ビットプラットフォーム
参照元
__align_cpy_n
SPARC
大きい structs を返します。n は 1、2、4、8、または 16 です。
_memcpy
x86
大きい structs を返します
_memcpy
x86 および SPARC
ベクトル化。
_memmove
x86 および SPARC
ベクトル化。
_memset
x86 および SPARC
ベクトル化。

一部のバージョンのカーネルは、_memmove()_memcpy()、または _memset() を提供しませんが、ユーザーモードルーチン memmove()memcpy()、および memset() のカーネルモードアナログを提供する点に注意してください。

x86 プラットフォーム向けの Solaris カーネルコードをコンパイルする際にはオプション –xvector=%none を使用する必要がある点に注意することが重要です。C コンパイラは、x86 プラットフォーム上ではデフォルトで、XMM レジスタを使用するコードを生成することにより、C の浮動小数点算術型を使用しないアプリケーションなど、一般的なユーザーアプリケーションのパフォーマンスを改善します。XMM レジスタの使用は、カーネルコードでは不適切です。

追加情報については、『Writing Device Drivers Guide』および『SPARC Compliance Definition, version 2.4』を参照してください。