JavaScript is required to for searching.
ナビゲーションリンクをスキップ
印刷ビューの終了
リンカーとライブラリ     Oracle Solaris 10 8/11 Information Library (日本語)
search filter icon
search icon

ドキュメントの情報

はじめに

1.  Oracle Solaris リンカーの紹介

2.  リンカー

リンカーの起動

直接起動

コンパイラドライバを使用する

32 ビットリンカーと 64 ビットリンカー

クロスリンク編集

リンカーオプションの指定

入力ファイルの処理

アーカイブ処理

共有オブジェクトの処理

追加ライブラリとのリンク

ライブラリの命名規約

共有オブジェクトとアーカイブとの混合体へのリンク

コマンド行上のアーカイブの位置

リンカーが検索するディレクトリ

コマンド行オプションの使用

環境変数の使用

実行時リンカーが検索するディレクトリ

初期設定および終了セクション

シンボルの処理

シンボル解決

単純な解決

複雑な解決

重大な解決

未定義シンボル

実行可能ファイルの作成

共有オブジェクト出力ファイルの生成

ウィークシンボル

出力ファイル内の一時的シンボル順序

追加シンボルの定義

-u オプションを使用した追加シンボルの定義

シンボル参照の定義

絶対シンボルの定義

一時的シンボルの定義

シンボル定義の増強

シンボル範囲の縮小

シンボル削除

外部結合

文字列テーブルの圧縮

出力ファイルの生成

機能要件の特定

プラットフォーム機能の特定

マシン機能の指定

ハードウェア機能の特定

ソフトウェア機能の特定

ソフトウェア機能フレームポインタの処理

シンボル機能関数ファミリの作成

シンボル機能データ項目のファミリの作成

オブジェクト機能のシンボル機能への変換

機能ファミリの実行

再配置処理

ディスプレイスメント再配置

スタブオブジェクト

デバッグ支援

3.  実行時リンカー

4.  共有オブジェクト

5.  アプリケーションバイナリインタフェースとバージョン管理

6.  サポートインタフェース

7.  オブジェクトファイル形式

8.  スレッド固有領域 (TLS)

9.  mapfile

A.  リンカーのクイックリファレンス

B.  バージョン管理の手引き

C.  動的ストリングトークンによる依存関係の確立

D.  直接結合

E.  System V Release 4 (バージョン 1) Mapfile

F.  リンカーとライブラリのアップデートおよび新機能

索引

スタブオブジェクト

スタブオブジェクトとは、完全に mapfile から作成される、コードとデータを含まずに実際のオブジェクトと同じリンクインタフェースを提供する共有オブジェクトです。スタブオブジェクトは実行時には使用できません。しかし、スタブオブジェクトに対してアプリケーションを作成できます。スタブオブジェクトによって、実行時に使用される実際のオブジェクト名が提供されます。

スタブオブジェクトを作成する場合、リンカーはコマンド行で指定されたオブジェクトまたはライブラリファイルを無視します。これらのファイルはスタブの作成には必要ありません。コンパイル工程は省略できるため、またリンカーが行う作業は比較的少ないため、スタブオブジェクトは非常に速く作成できます。

スタブオブジェクトは、構築時のさまざまな問題点の解決に利用できます。

スタブの共有オブジェクトは、上記の問題点を回避する別のコード作成方法を提供します。ビルドによって作成されるすべての共有オブジェクトに対して、スタブオブジェクトをすぐに作成できます。その後、実際の共有オブジェクトと実行可能ファイルはすべて、リンク時に実際のオブジェクトの代わりを務めるスタブオブジェクトを使用して、平行してどのような順序でも作成できます。実行可能ファイルと実際の共有オブジェクトは保持され、スタブの共有オブジェクトは破棄されます。

スタブオブジェクトは 1 つまたは複数の mapfile から作成され、次の要件を集合的に満たす必要があります。

このような mapfile を使用すると、共有オブジェクトのスタブと実オブジェクトそれぞれの作成時に同じコマンド行を使用できます。-z stub オプションは、スタブオブジェクトのリンク編集に追加され、実オブジェクトのリンク編集から削除されます。

これらの考えを示すため、次のコードで名前が idx5 の共有オブジェクトを実装します。このオブジェクトは 5 つの要素を持つ整数の配列からデータをエクスポートします。各要素は初期化され、ゼロから始まる配列インデックスを格納します。このデータは、大域配列として、また結合が弱い代替の別名データシンボルとして、関数インタフェースを介して公開されます。

$ cat idx5.c
int _idx5[5] = { 0, 1, 2, 3, 4 };
#pragma weak idx5 = _idx5

int
idx5_func(int index)
{
        if ((index < 0) || (index > 4))
                return (-1);
        return (_idx5[index]);
}

mapfile では、この共有オブジェクトで提供されるインタフェースを記述する必要があります。

$ cat mapfile
$mapfile_version 2
STUB_OBJECT;
SYMBOL_SCOPE {
        _idx5   {
                        ASSERT { TYPE=data; SIZE=4[5] };
                };
        idx5    {
                        ASSERT { BINDING=weak; ALIAS=_idx5 };
                };
        idx5_func;
    local:
        *;
};

次のメインプログラムは、idx5 共有オブジェクトから利用可能なすべてのインデックス値を出力するために使用されます。

$ cat main.c
#include <stdio.h>

extern int      _idx5[5], idx5[5], idx5_func(int);

int
main(int argc, char **argv)
{
        int     i;
        for (i = 0; i < 5; i++)
                (void) printf("[%d] %d %d %d\n",
                    i, _idx5[i], idx5[i], idx5_func(i));
        return (0);
}

次のコマンドでは、この共有オブジェクトのスタブ版を、stublib という名前のサブディレクトリに作成します。elfdump コマンドは、作成されるオブジェクトがスタブであることを検証するために使用されます。スタブの作成に使用されるコマンドは、-z stub オプションを追加する点、および異なる出力ファイル名を使用する点だけが、実オブジェクトのコマンドと異なります。これは、スタブ作成が既存コードに容易に追加できることを示します。

$ cc -Kpic -G -M mapfile -h libidx5.so.1 idx5.c -o stublib/libidx5.so.1 -zstub
$ ln -s libidx5.so.1 stublib/libidx5.so
$ elfdump -d stublib/libidx5.so | grep STUB
      [11]  FLAGS_1           0x4000000           [ STUB ]

これで、実際の共有オブジェクトの代わりになるスタブオブジェクトを使用して、メインプログラムを構築できるようになりました。スタブオブジェクトは、実行時に実オブジェクトを検索する「実行パス」を設定します。しかし、実オブジェクトはまだ作成されていないため、このプログラムはまだ動作しません。システムがスタブオブジェクトを読み込もうとする試みは拒否されます。実行時リンカーは、実オブジェクトにある実際のコードとデータがスタブオブジェクトにないために、実行できないことをわかっているためです。

$ cc main.c -L stublib -R '$ORIGIN/lib' -lidx5 -lc
$ ./a.out
ld.so.1: a.out: fatal: libidx5.so.1: open failed: \
    No such file or directory
Killed
$ LD_PRELOAD=stublib/libidx5.so.1 ./a.out
ld.so.1: a.out: fatal: stublib/libidx5.so.1: stub shared object \
    cannot be used at runtime
Killed

実オブジェクトの作成には、スタブオブジェクトを作成するために使用したコマンドと同じものを使用します。-z stub オプションは省かれ、実際の出力ファイルのパスが指定されます。

$ cc -Kpic -G -M mapfile -h libidx5.so.1 idx5.c -o lib/libidx5.so.1

実オブジェクトが lib サブディレクトリに作成されたあとは、このプログラムを実行できます。

$ ./a.out
[0] 0 0 0
[1] 1 1 1
[2] 2 2 2
[3] 3 3 3
[4] 4 4 4