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 " |
この例では、ソースファイル lldiv.c がコンパイルされ、-m32 オプションを使用して 32 ビットプラットフォームで実行されると、行 7 の文の変換が、__div64 という名前の実行時サポート関数への外部参照となります。この関数は、標準 C ライブラリの 32 ビットバージョンでのみ使用できます。
同じソースファイルが -m64 オプションを使用して 64 ビットプラットフォームでコンパイルされると、コンパイラはターゲットマシンの 64 ビット算術命令セットを使用するため、標準 C ライブラリの 64 ビットバージョンで実行時サポート関数が不要になります。
一般的な事例では、フリースタンディング環境を対象にして C コンパイラを使用することはできませんが、特定のフリースタンディング環境 (つまり Solaris カーネルとデバイスドライバ) ではコードをコンパイルするためにコンパイラを使用できます (警告が生成されます)。
デバイスドライバなど、Solaris カーネルで実行されるコードは、外部関数呼び出しがカーネル内で使用可能な関数のみ参照するように記述する必要があります。これを可能にするため、次のガイドラインが推奨されます。
ユーザーモードでのみ実行されるライブラリのヘッダーファイルは含めないでください。
同じ関数がカーネルに存在していることがわかっているのでない限り、標準 C ライブラリまたはほかのユーザーモードライブラリ内の関数を呼び出さないでください。
浮動小数点型または C99 複合型を使用しないでください。
ランタイムサポートライブラリに関連付けられたコンパイラオプションを使用しないでください (-xprofile、-xopenmp など)
特定のコンパイラオプションに関連付けられた再配置可能なオブジェクトファイルは、cc(1) マニュアルページの FILES 節で説明されています。C コンパイラオプションに関連付けられた実行時サポートライブラリは、関連するオプションを説明している箇所に記載されています。
前述のように、ソースコードの変換の結果、コンパイラにより実行時サポート関数への呼び出しが生成されることがあります。Solaris カーネルの特定の事例では、カーネルが浮動小数点型や複合型、数学ライブラリ関数、または実行時サポートライブラリに関連付けられたコンパイラオプションを使用しないため、呼び出される実行時サポート関数のセットが一般的な事例より小さくなります。
次の表に、C コンパイラによるソースコードの変換の結果、Solaris カーネルで実行するためにコンパイルされたコードで呼び出される可能性のある実行時サポート関数を示します。この表に、ソースコードの変換で呼び出しが生成されるプラットフォーム、呼び出される関数の名前、関数呼び出しを引き起こすソース構造体またはコンパイラ機能を示します。C コンパイラをサポートする Solaris のすべてのバージョンで 64 ビットカーネルが実行されるため、64 ビットプラットフォームだけがリストに示されています。
32 ビット命令セット用にコンパイルすると、命令セットに固有の制限があるため、追加のマシン固有のサポート関数が呼び出されることがあります。
関数 |
64 ビットプラットフォーム |
参照元 |
---|---|---|
__align_cpy_n |
SPARC |
大きい構造体を返します。n は 1、2、4、8、または 16 です。 |
_memcpy |
x86 |
大きい構造体を返します。 |
_memcpy |
x86 および SPARC |
ベクトル化。 |
_memmove |
x86 および SPARC |
ベクトル化。 |
_memset |
x86 および SPARC |
ベクトル化。 |
一部のバージョンのカーネルは、_memmove()、_memcpy()、または _memset() を提供しませんが、ユーザーモードルーチン memmove()、memcpy()、および memset() のカーネルモードアナログは提供する点に注意してください。
追加情報については、『Writing Device Drivers』および『SPARC Compliance Definition, version 2.4』を参照してください。