シンボル・プリエンプション

共有可能なオブジェクトの関数やデータと独自に定義したものを一緒に使用することができます。例えば、標準 C ランタイム・ライブラリーの共有可能なオブジェクト libc.so と、独自のヒープ管理ルーチン malloc() および free() の定義を一緒に使用することができます。この場合、libc.so 内の malloc() および free() を呼び出しで、libc.so にある定義ではなく独自のルーチンの定義を呼び出す必要があります。独自の定義は、共有可能なオブジェクト内の定義を無効に (プリエンプト) します。

この機能は、シンボル・プリエンプションと呼ばれます。ランタイムローダーがコンポーネントをロードするとき、コンポーネント内の default 可視属性のシンボルはすべて、すでにロードされているコンポーネント内の同じ名前のシンボルによりプリエンプトされます。メイン・プログラム・イメージは常に最初にロードされるので、メインプログラムで定義されているシンボルはプリエンプトされません。

default 可視属性のシンボルは実行時までメモリーアドレスにバインドされないため、シンボル・プリエンプションが発生する可能性により、多くのコンパイラーの最適化は禁止されます。例えば、default 可視属性のルーチンへの呼び出しは、コンパイル単位が共有可能なオブジェクトにリンクされた場合にプリエンプトされるため、インライン展開することができません。また、プリエンプト可能なデータシンボルは、名前が異なるコンポーネント中のシンボルにバインドされている可能性があるため、GP 相対アドレス指定を使用してアクセスすることはできません。GP 相対アドレスはコンパイル時にはわかりません。

シンボル・プリエンプションは、コンパイラーの最適化に著しく反するため、ほとんど使用されていない機能です。そのため、コンパイラーはすべてのグローバルシンボル定義をデフォルトでプリエンプト可能ではない (つまり、protected 可視属性) として扱います。ほかのコンパイル単位で定義されているシンボルへのグローバル参照は、デフォルトでプリエンプト可能である (つまり、default 可視属性) と仮定されます。すべてのグローバル定義や参照をプリエンプト可能にする場合は、このデフォルトを無視する -fpic オプションを指定してください。