リンカーとライブラリ

複雑な解析

複雑な解析は、同じ名前を持つ 2 つのシンボルが、異なる属性とともに検出された場合に発生します。この場合、リンカーは最も適切なシンボルを選択し、そのシンボル、対立する属性、およびそのシンボル定義を取り出したファイルの ID を示す警告メッセージを生成します。次に例を示します。


$ cat foo.c
int array[1];

$ cat bar.c
int array[2] = { 1, 2 };

$ cc -dn -r -o temp.o foo.c bar.c
ld: warning: symbol `array' has differing sizes:
        (file foo.o value=0x4; file bar.o value=0x8);
        bar.o definition taken

ここで、データ項目の配列の定義が指定された 2 つのファイルでは、サイズの必要条件が異なっています。シンボル配列の必要条件が異なる場合には、同様の診断プログラムが作成されます。この 2 つのケースの場合、リンカーの -t オプションを使用すると、診断プログラムを抑制できます。

この他の属性形式の違いに、シンボルの「タイプ」があります。次に例を示します。


$ cat foo.c
bar()
{
        return (0);
}
$ cc -o libfoo.so -G -K pic foo.c
$ cat main.c
int     bar = 1;

main()
{
        return (bar);
}
$ cc -o main main.c -L. -lfoo
ld: warning: symbol `bar' has differing types:
        (file main.o type=OBJT; file ./libfoo.so type=FUNC);
        main.o definition taken

ここで、シンボル bar() は、データ項目と関数の両方として定義されています。


注 -

このコンテキスト内の型とは、ELF で表されたシンボルタイプのことです。このシンボルタイプは、まったく手を加えられていない場合を除いて、プログラミング言語が使用するデータ型には関連していません。


このような場合には、再配置可能オブジェクトと共有オブジェクト間で解析が発生したときには、再配置可能オブジェクトの定義がとられます。または、2 つの共有オブジェクト間で解析が発生した場合には、最初の共有オブジェクトの定義がとられます。このような解析が異なる結合間 (「ウィーク」または「大域」) で発生すると、警告メッセージも同時に作成されます。

リンカーの -t オプションを使用しても、シンボルタイプ間の不一致は抑制できません。