link(5) FreeBSD 一般コマンドマニュアル

link

前のページ 上に戻る 次のページ

link


     #include <nlist.h>
     #include <link.h>


解説

     インクルードファイル <link.h> では、ダイナミックにリンクされたプログラム
     やライブラリに含まれる数種の構造体が宣言されています。その構造体は、リン
     クエディタとローダ機構のいくつかの構成要素間のインタフェースを定義しま
     す。バイナリ中でのこれらの構造体のレイアウトは多くの点で a.out 形式に類似
     しており、シンボル定義 (付随する文字列テーブルを含む) や外部エンティティ
     への参照を解決するのに必要なリロケーションレコードといった、よく似た機能
     を提供します。それに加え、ダイナミックロードとリンク処理に固有のいくつか
     のデータ構造も記録しています。このようなデータ構造としては、リンクエ
     ディット処理を完結するのに必要な他のオブジェクトへの参照や、異なるプロセ
     ス間でコードページの共有を進めるための 位置独立コード (Position Indepen-
     dent Code 略して PIC) を機能させるための間接テーブルがあります。ここで述
     べるデータ構造全体を ランタイムリロケーションセクション (RRS) と呼び、ダ
     イナミックにリンクされるプログラムや共有オブジェクトの標準テキスト及びデ
     ータセグメントに埋め込まれます。これは、既存の a.out(5) 形式には RRS のた
     めの場所が他にないからです。

     あるプログラムを実行可能とする処理が、システムリソースの使用を最適化しつ
     つ正しく完了するよう、複数のユーティリティが協調して働きます。コンパイラ
     は PIC コードを出力し、それから ld(1) によって共有ライブラリが作られま
     す。コンパイラはまた、初期化される各データアイテムのサイズ情報をアセンブ
     ラディレクティブ .size を用いて記録します。 PIC コードは、ある間接テーブ
     ルを通じてデータ変数にアクセスする点で従来のコードと異なっています。この
     表はグローバルオフセットテーブルと呼ばれ、慣習によって、予約名
     _GLOBAL_OFFSET_TABLE_ によってアクセス可能です。ここで用いられるメカニズ
     ムの詳細は機種依存ですが、通常はそのマシンのレジスタ 1 本がこの用途に予約
     されます。このような仕組みの背景にある合理性は、実際のロードアドレスとは
     独立したコードを生成することです。実行時には、アドレス空間において様々な
     共有オブジェクトがロードされるアドレスに応じて、グローバルオフセットテー
     ブルに含まれる値のみ変更すればよいのです。

     同様に、大域的に定義された関数の呼び出しは、コアイメージのデータセグメン
     ト中に置かれているプロシージャリンケージテーブル (PLT) を通じて間接的に行
     われます。これもまた、実行時にテキストセグメントを修正せずに済ませるため
     のものです。

     リンクエディタがグローバルオフセットテーブルとプロシージャリンケージテー
     ブルを配置するのは、複数の PIC オブジェクトファイルを結合してプロセスのア
     ドレス空間にマップするのに適した 1 つのイメージにする時です。リンクエディ
     タはまた、実行時のリンクエディタが必要とする全てのシンボルを集め、それら
     をイメージのテキストとデータのビット列と共にストアします。もう 1 つの予約
     シンボル _DYNAMIC は、実行時のリンク構造が存在することを示すのに用いられ
     ます。 _DYNAMIC が 0 にリロケートされる場合は、実行時リンクエディタを起動
     する必要はありません。もし _DYNAMIC が非 0 なら、_DYNAMIC は、必要なリロ
     ケーション情報とシンボル情報の位置を引き出すことができるデータ構造を指し
     ています。これは特に、スタートアップモジュール crt0 で利用されます。慣習
     として、_DYNAMIC 構造体は、それが属するイメージのデータセグメントの最初に
     置かれます。

                   } d_un;
                   struct  ld_entry *d_entry;
           };

     d_version  このフィールドは異なったバージョンのダイナミックリンク実装用に
                提供されています。 ld(1) 及び ld.so(1) が理解する現在のバー
                ジョン番号は、 SunOS 4.x リリースで用いられている
                LD_VERSION_SUN (3) と、 FreeBSD 1.1 以来使用されている
                LD_VERSION_BSD (8) です。

     d_un       d_version に応じたデータ構造を参照します。

     so_debug   このフィールドは、共有オブジェクトのシンボルテーブルをアクセス
                するためのフックをデバッガに提供します。この共有オブジェクト
                は、実行時リンクエディタの処理の結果ロードされたものです。

     section_dispatch_table 構造体がメインとなる ``ディスパッチャ'' テーブルで
     あり、イメージ内で様々なシンボル情報やリロケーション情報が置かれるセグメ
     ントへのオフセットを保持します。

           struct section_dispatch_table {
                   struct  so_map *sdt_loaded;
                   long    sdt_sods;
                   long    sdt_filler1;
                   long    sdt_got;
                   long    sdt_plt;
                   long    sdt_rel;
                   long    sdt_hash;
                   long    sdt_nzlist;
                   long    sdt_filler2;
                   long    sdt_buckets;
                   long    sdt_strings;
                   long    sdt_str_sz;
                   long    sdt_text_sz;
                   long    sdt_plt_sz;
           };

     sdt_loaded   ロードされた最初のリンクマップ (後述) へのポインタ。このフィ
                  ールドは ld.so によって設定されます。

     sdt_sods     このオブジェクトが必要とする共有オブジェクトデスクリプタの (
                  リンク) リストの先頭。

     sdt_filler1  使用しないで下さい (SunOS ではライブラリの検索ルールを指定す
                  るのに使用されていました)。

     sdt_got      このイメージ中でのグローバルオフセットテーブルの位置。

     sdt_plt      このイメージ中でのプロシージャリンケージテーブルの位置。

     sdt_rel      実行時のリロケーションを指定する relocation_info 構造体 (
                  a.out(5) 参照) の配列の位置。

     sdt_text_sz  このオブジェクトのテキストセグメントのサイズ。

     sdt_plt_sz   プロシージャリンケージテーブルのサイズ。

     sod 構造体は、それを含むオブジェクトのリンクエディット処理を完了するのに
     必要な共有オブジェクトを記述します。そのようなオブジェクトのリスト (
     sod_next で連結されます) は section_dispatch_table 構造体の sdt_sods に
     よって指し示されます。

           struct sod {
                   long    sod_name;
                   u_int   sod_library : 1,
                           sod_reserved : 31;
                   short   sod_major;
                   short   sod_minor;
                   long    sod_next;
           };

     sod_name     このリンクオブジェクトを記述する文字列の、テキストセグメント
                  におけるオフセット。

     sod_library  もし設定されていれば、 sod_nameld.so が検索することにな
                  るライブラリを指定します。そのパス名は、あるディレクトリ群 (
                  ldconfig(8) 参照) で lib<sod_name>.so.n.m. にマッチする共有
                  オブジェクトを検索することで得られます。もし設定されていなけ
                  れば、 sod_name は希望する共有オブジェクトに対するフルパス名
                  を指し示す必要があります。

     sod_major    ロードすべき共有オブジェクトのメジャーバージョン番号を指定し
                  ます。

     sod_minor    ロードすべき共有オブジェクトの希望するマイナーバージョン番号
                  を指定します。

     プロセスのアドレス空間にロードされる共有オブジェクト全てを追跡するため
     に、実行時リンクエディタは リンクマップと呼ばれる構造体のリストを管理して
     います。これらの構造体は実行時にのみ用いられ、実行可能ファイルや共有ライ
     ブラリのテキストあるいはデータセグメントにはありません。

           struct so_map {
                   caddr_t som_addr;
                   char    *som_path;
                   struct  so_map *som_next;
                   struct  sod *som_sod;
                   caddr_t som_sodbase;
                   u_int   som_write : 1;
                   struct  _dynamic *som_dynamic;
                   caddr_t som_spd;
           };

     som_addr     このリンクマップに対応する共有オブジェクトがロードされるアド
                  レス。

     som_spd      実行時リンクエディタが管理するプライベートデータと連結するた
                  めのフック。

     サイズ付きシンボル記述。これは単に nlist 構造体にフィールド (nz_size) を
     1 つ追加したものです。共有オブジェクトのデータセグメントにあるアイテムの
     サイズ情報を伝達するのに用いられます。この構造体の配列は共有オブジェクト
     のテキストセグメントに存在し、そのアドレスは section_dispatch_tablesdt_nzlist フィールドで指定されます。

           struct nzlist {
                   struct nlist    nlist;
                   u_long          nz_size;
           #define nz_un           nlist.n_un
           #define nz_strx         nlist.n_un.n_strx
           #define nz_name         nlist.n_un.n_name
           #define nz_type         nlist.n_type
           #define nz_value        nlist.n_value
           #define nz_desc         nlist.n_desc
           #define nz_other        nlist.n_other
           };

     nlist    ( nlist(3) 参照)。

     nz_size  このシンボルで表現されるデータのサイズ。

     実行時のリンクエディットで行われるシンボル検索を高速化するため、共有オブ
     ジェクトのテキストセグメントにハッシュテーブルが含まれています。
     section_dispatch_tablesdt_hash フィールドは rrs_hash 構造体を指し示し
     ます:

           struct rrs_hash {
                   int     rh_symbolnum;           /* シンボル番号 */
                   int     rh_next;                /* 次のハッシュエントリ */
           };

     rh_symbolnum  共有オブジェクトのシンボルテーブル ( ld_symbols で与えられ
                   ます) での当該シンボルのインデックス。

     rh_next       衝突が起きたとき、このフィールドはこのハッシュテーブルのバ
                   ケットにおける次のエントリのオフセットを保持します。最終バ
                   ケット要素の場合は 0 となります。
     rt_symbol 構造体は、実行時にアロケートされるコモン(commons)と共有オブジェ
     クトからコピーされるデータアイテムを追跡するのに用いられます。これらのア
     イテムはリンクリストで管理され、デバッガでの利用のために so_debug 構造体
     (後述) 中の dd_cc フィールドによって公開されます。

           struct rt_symbol {
                   struct nzlist           *rt_sp;
                   struct rt_symbol        *rt_next;
                   struct rt_symbol        *rt_link;
                   caddr_t                 rt_srcaddr;
                   struct so_map           *rt_smp;

     so_debug 構造体は、実行時リンクエディットの結果、当該プロセスのアドレス空
     間にロードされたあらゆる共有オブジェクトの情報を得るために、デバッガに
     よって利用されます。実行時リンクエディタはプロセスの初期化処理の一部とし
     て実行されるため、共有オブジェクトからシンボルにアクセスしようとするデ
     バッガは、 crt0 からリンクエディタが呼ばれた後でのみそれが可能となりま
     す。ダイナミックリンクされているバイナリは so_debug 構造体を持っていま
     す。この構造体の場所は _dynamic 中の d_debug フィールドで指示されます。

           struct  so_debug {
                   int     dd_version;
                   int     dd_in_debugger;
                   int     dd_sym_loaded;
                   char    *dd_bpt_addr;
                   int     dd_bpt_shadow;
                   struct rt_symbol *dd_cc;
           };

     dd_version      このインタフェースのバージョン番号。

     dd_in_debugger  当該プログラムがデバッガの制御下にあることを実行時リンカ
                     に知らせるためにデバッガによってセットされます。

     dd_sym_loaded   共有オブジェクトをロードすることで実行時リンカがシンボル
                     を追加した場合、実行時リンカによってセットされます。

     dd_bpt_addr     デバッガに制御を移すために実行時リンカによってセットされ
                     るブレークポイントアドレス。このアドレスは、_main 呼び出
                     しの前に、スタートアップモジュール crt0.o によってある適
                     切な場所に決定されます。

     dd_bpt_shadow   アドレス dd_bpt_addr にあった元の機械命令を保持します。デ
                     バッガは、プログラム実行を再開する前にこの機械命令を元に
                     戻すことになっています。

     dd_cc           デバッガが必要とする可能性のある、実行時にアロケートした
                     シンボルのリンクリストへのポインタ。

     ld_entry 構造体は ld.so 中のサービスルーチン一式を定義します。

           struct ld_entry {
                   void    *(*dlopen)(char *, int);
                   int     (*dlclose)(void *);
                   void    *(*dlsym)(void *, char *);
                   char    *(*dlerror)(void);
           };

     crt_ldso 構造体は、crt0 中のスタートアップコードと ld.so との間のインタ
     フェースを定義します。

           struct crt_ldso {
                   int             crt_ba;
                   int             crt_dzfd;

     crt_dzfd  SunOS では、このフィールドは ``/dev/zero'' へのオープンされた
               ファイル記述子を保持し、 0 クリアされたデマンドページを得ます。
               FreeBSD ではこのフィールドは -1 を保持します。

     crt_ldfd  ld.so をロードするために crt0 が用いる、オープンされたファイル
               記述子を保持します。

     crt_dp    main の _dynamic 構造体へのポインタ。

     crt_ep    環境文字列へのポインタ。

     crt_bp    メインプログラムがデバッガで実行される場合、実行時リンカがブレ
               ークポイントを置くアドレス。 so_debug を参照してください。

     crt_prog  crt0 で決定されるメインプログラムの名前 (CRT_VERSION_BSD3 の
               み)。

     crt_ldso  crt0 でマップされる実行時リンカのパス (CRT_VERSION_BSD4 のみ)。

     hints_header 構造体及び hints_bucket 構造体は、通常
     ``/var/run/ld.so.hints'' に置かれるライブラリヒントのレイアウトを定義しま
     す。ライブラリヒントは、ファイルシステム中で共有オブジェクトイメージの在
     処をすばやく見つけるために ld.so によって利用されます。ヒントファイルの構
     成は ``a.out'' とそれほど異なりません。つまりヒントファイルは、固定長ハッ
     シュバケットのオフセットとサイズを決定するためのヘッダと、共通の文字列プ
     ールを持っています。

           struct hints_header {
                   long            hh_magic;
           #define HH_MAGIC        011421044151
                   long            hh_version;
           #define LD_HINTS_VERSION_1      1
                   long            hh_hashtab;
                   long            hh_nbucket;
                   long            hh_strtab;
                   long            hh_strtab_sz;
                   long            hh_ehints;
           };

     hh_magic      ヒントファイルのマジックナンバ。

     hh_version    インタフェースのバージョン番号。

     hh_hashtab    ハッシュテーブルのオフセット。

     hh_strtab     文字列テーブルのオフセット。

     hh_strtab_sz  文字列テーブルのサイズ。

     hh_ehints     ヒントファイルで利用可能な最大オフセット。


     hi_pathx   ライブラリのフルパス名を表す文字列のインデックス。

     hi_dewey   共通ライブラリのバージョン番号。

     hi_ndewey  hi_dewey 中の有効エントリ数。

     hi_next    ハッシュ衝突の際の次のバケット。


警告

     現在のところ、共有ライブラリ生成をサポートしているのは (GNU) C コンパイラ
     のみです。他のプログラミング言語では利用できません。

FreeBSD 4.4                    October 23, 1993                    FreeBSD 4.4

ABELNET VPSサービス