別々の実装を提供する、同じ名前の多重定義シンボルは、偶発的な割り込みを回避するために分離する必要があります。オブジェクトによってエクスポートされたインタフェースからシンボルを削除するもっとも簡単な方法は、シンボルを局所に限定することです。シンボルを局所に限定するには、シンボル「static」を定義することで、またはコンパイラが提供するシンボル属性を使用することでも、実現できます。
シンボルは、リンカーと mapfile を使用しても、局所に限定できます。次の例では、local スコープ指令を使用して大域関数 error() を局所シンボルに限定する mapfile を示します。
$ cc -o A.so.1 -G -Kpic error.c a.c b.c .... $ elfdump -sN.symtab A.so.1 | fgrep error [36] 0x2d0 0x14 FUNC GLOB D 0 .text error $ cat mapfile $mapfile_version 2 SYMBOL_SCOPE { local: error; }; $ cc -o A.so.2 -G -Kpic -M mapfile error.c a.c b.c .... $ elfdump -sN.symtab A.so.2 | fgrep error [24] 0x2c8 0x14 FUNC LOCL H 0 .text error
mapfile の明示的な定義を使用して個々のシンボルを局所に限定することはできますが、シンボルのバージョン管理を介して全体のインタフェースファミリを定義することをお勧めします。Chapter 9, インタフェースおよびバージョン管理を参照してください。
バージョン管理は、主に共有オブジェクトからエクスポートされたインタフェースを特定するために採用された、有用な技術です。同じように、動的実行可能ファイルをバージョン管理すると、エクスポートされたインタフェースを定義できます。動的実行可能ファイルに必要なことは、結合するオブジェクトの依存関係に対して利用できるようにしなければならないインタフェースをエクスポートするだけです。多くの場合、動的実行可能ファイルに追加するコードは、インタフェースをエクスポートする必要がありません。
動的実行可能ファイルからエクスポートされたインタフェースを削除するには、コンパイラドライバによって確立されたすべてのシンボル定義を考慮する必要があります。これらの定義は、コンパイラドライバが最後のリンク編集に追加する補助ファイルが元になっています。コンパイラドライバを使用するを参照してください。
次の例の mapfile では、コンパイラドライバが確立する可能性がある、共通のシンボル定義セットをエクスポートする一方で、ほかのすべての大域定義を局所に限定します。
$ cat mapfile $mapfile_version 2 SYMBOL_SCOPE { global: __Argv; __environ_lock; _environ; _lib_version; environ; local: *; };
コンパイラドライバが確立するシンボル定義を決定する必要があります。動的実行可能ファイル内で使用されるすべての定義は大域のままにします。
動的実行可能ファイルからエクスポートされたインタフェースを削除することで、オブジェクトの依存関係が変わっていくにつれて今後発生する可能性がある割り込みの問題から、この実行可能ファイルが保護されます。