LINK(5) FreeBSD ファイルフォーマットマニュアル LINK(5)
名称
link − ダイナミックローダとリンクエディタインタフェース |
書式
#include <sys/types.h> |
解説
インクルードファイル <link.h> では、ダイナミックにリンクされたプログラム やライブラリに含まれる数種の構造体が宣言されています。その構造体は、リン クエディタとローダ機構のいくつかの構成要素間のインタフェースを定義しま す。バイナリ中でのこれらの構造体のレイアウトは多くの点で a.out 形式に類似 しており、シンボル定義 (付随する文字列テーブルを含む) や外部エンティティ への参照を解決するのに必要なリロケーションレコードといった、よく似た機能 を提供します。それに加え、ダイナミックロードとリンク処理に固有のいくつか のデータ構造も記録しています。このようなデータ構造としては、リンクエ ディット処理を完結するのに必要な他のオブジェクトへの参照や、異なるプロセ ス間でコードページの共有を進めるための 位置独立コード (Position Independent 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 構造体は、それが属するイメージのデータセグメントの最初に 置かれます。 |
データ構造
ダイナミックリンクと実行時リロケーションをサポートするデータ構造は、それ らの処理の適用対象イメージのテキスト及びデータセグメントの両方の中にあり ます。テキストセグメントにはシンボル記述や名前といった読み取り専用データ が含まれ、他方データセグメントにはリロケーション処理で更新する必要のある テーブル類が含まれます。 シンボル _DYNAMIC は _dynamic 構造体を参照します: |
_dynamic { |
||||
int |
d_version; |
|||
struct |
so_debug *d_debug; |
|||
union { |
||||
struct section_dispatch_table *d_sdt; |
||||
} 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 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 sdt_got sdt_plt sdt_rel sdt_hash sdt_nzlist sdt_filler2 sdt_buckets sdt_strings sdt_str_sz 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_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_path som_next som_sod som_sodbase som_write som_dynamic som_spd サイズ付きシンボル記述。これは単に nlist 構造体にフィールド (nz_size) を 1 つ追加したものです。共有オブジェクトのデータセグメントにあるアイテムの サイズ情報を伝達するのに用いられます。この構造体の配列は共有オブジェクト のテキストセグメントに存在し、そのアドレスは section_dispatch_table の sdt_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_table の sdt_hash フィールドは rrs_hash 構造体を指し示し ます: struct rrs_hash { |
int |
||||||
rh_symbolnum; |
/* シンボル番号 */ |
|||||
int |
||||||
rh_next; |
/* 次のハッシュエントリ */ |
}; |
rh_symbolnum
共有オブジェクトのシンボルテーブル ( ld_symbols で与えられ ます) での当該シンボルのインデックス。 rh_next 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; |
}; |
rt_sp
シンボル記述。 rt_next rt_link rt_srcaddr 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 dd_bpt_shadow 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; |
||||
int |
||||
crt_ldfd; |
||||
struct _dynamic |
*crt_dp; |
|||
char |
||||
**crt_ep; |
||||
caddr_t |
||||
crt_bp; |
||||
char |
||||
*crt_prog; |
||||
char |
||||
*crt_ldso; |
||||
struct ld_entry |
*crt_ldentry; |
}; |
#define CRT_VERSION_SUN |
1 |
|||||
#define CRT_VERSION_BSD_2 |
2 |
|||||
#define CRT_VERSION_BSD_3 |
3 |
|||||
#define |
CRT_VERSION_BSD_4 |
4 |
crt_ba
crt0 によって ld.so がロードされた仮想アドレス。 crt_dzfd crt_ldfd crt_dp crt_ep crt_bp crt_prog crt_ldso 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 /* |
int |
||||
hi_namex; |
||||
int |
||||
hi_pathx; |
||||
int |
||||
hi_dewey[MAXDEWEY]; |
||||
int |
||||
hi_ndewey; |
#define hi_major hi_dewey[0] |
int |
||||
hi_next; |
}; |
hi_namex
ライブラリを指定する文字列のインデックス。 hi_pathx hi_dewey hi_ndewey hi_next 警告 |
現在のところ、共有ライブラリ生成をサポートしているのは (GNU) C コンパイラ のみです。他のプログラミング言語では利用できません。 FreeBSD 10.0 October 23, 1993 FreeBSD 10.0 |