Oracle® Solaris 11.2 リンカーとライブラリガイド

印刷ビューの終了

更新: 2014 年 7 月
 
 

監査インタフェースの関数

次のルーチンが rtld-監査インタフェースによって提供されます。これらのルーチンは予想される使用順序に従って記載されています。


注 - アーキテクチャーあるいはオブジェクトクラス固有のインタフェースの参照では、説明を簡潔にするため、省略して一般名を使用します。たとえば、la_symbind32() および la_symbind64()la_symbind() で表します。
la_version()

このルーチンは、実行時リンカーと監査ライブラリの間の初期ハンドシェークを提供します。監査ライブラリが読み込まれるためには、このインタフェースが提供されている必要があります。

uint_t la_version(uint_t version);

実行時リンカーは、実行時リンカーがサポート可能な最上位バージョンの「rtld-監査」インタフェースによって、このインタフェースを呼び出します。監査ライブラリは、このバージョンが使用するのに十分かどうかを確認して、監査ライブラリが使用する予定のバージョンを返すことができます。このバージョンは、通常、/usr/include/link.h に定義されている LAV_CURRENT です。

監査ライブラリがゼロ、あるいは、実行時リンカーがサポートする「rtld-監査」インタフェースよりも大きなバージョンを返す場合、監査ライブラリは破棄されます。

残りの監査ルーチンには 1 つ以上の cookie が渡されます。監査インタフェースの対話を参照してください。

la_version() の呼び出しに続いて、la_objopen() ルーチンが 2 回呼び出されます。最初の呼び出しでは動的実行可能ファイルのリンクマップ情報が渡され、2 回目の呼び出しでは実行時リンカーのリンクマップ情報が渡されます。

la_objopen()

このルーチンは、新しいオブジェクトが実行時リンカーによって読み込まれるときに呼び出されます。

uint_t la_objopen(Link_map *lmp, Lmid_t lmid, uintptr_t *cookie);

lmp は、新しいオブジェクトを記述するリンクマップ構造を提供します。lmid は、オブジェクトが追加されているリンクマップリストを特定します。cookie は、識別子へのポインタを提供します。この識別子は、オブジェクト lmp に初期設定されます。オブジェクトをほかの rtld-監査インタフェースルーチンで識別しやすくするために、監査ライブラリでこの識別子を再割り当てすることができます。

la_objopen() ルーチンは、このオブジェクトで関心があるシンボル結合を示す値を返します。この結果の値は、/usr/include/link.h に定義された次の値のマスクです。

  • LA_FLG_BINDTO – このオブジェクトに対する監査シンボル結合。

  • LA_FLG_BINDFROM – このオブジェクトからの監査シンボル結合。

これらの値により、監査者は la_symbind() でモニターするオブジェクトを選択できます。ゼロの戻り値は、結合情報がこのオブジェクトで問題にならないことを示します。

たとえば、監査者は、libfoo.so から libbar.so への結合をモニターできます。libfoo.so()la_objopen は、 LA_FLG_BINDFROM を返します。libbar.sola_objopen() は、LA_FLG_BINDTO を返します。

監査者は、libfoo.solibbar.so 間のすべての結合をモニターできます。両方のオブジェクトの la_objopen() は、LA_FLG_BINDFROM LA_FLG_BINDTO を返します。

監査者は、libbar.so へのすべての結合もモニターできます。libbar.sola_objopen() は、LA_FLG_BINDTO を返します。すべての la_objopen() 呼び出しは、LA_FLG_BINDFROM を返します。

監査バージョン LAV_VERSION5 を指定すると、動的実行可能ファイルを表す la_objopen() 呼び出しがローカル監査プログラムで行われます。この場合、監査プログラムはシンボル結合フラグを返さないでください。モニタープログラムの読み込みが遅すぎるために、動的実行可能ファイルに関連するシンボル結合をモニターできない場合があるためです。監査プログラムによって返されるフラグはすべて無視されます。la_objopen() 呼び出しは、ローカル監査プログラムに、後続の la_preinit() または la_activity() 呼び出しに必要な初期 cookie を提供します。

la_activity()

このルーチンは、リンクマップアクティビティーが行われていることを監査プログラムに知らせます。

void la_activity(uintptr_t *cookie, uint_t flags);

cookie は、リンクマップの先頭のオブジェクトを指します。flags は、/usr/include/link.h に定義されているものと同じタイプのアクティビティーを指します。

  • LA_ACT_ADD – リンクマップリストにオブジェクトが追加される。

  • LA_ACT_DELETE – リンクマップリストからオブジェクトが削除される。

  • LA_ACT_CONSISTENT – オブジェクトのアクティビティーが完了した。

動的実行可能ファイルおよび実行時リンカーの la_objopen() 呼び出しに続いて、LA_ACT_ADD アクティビティーがプロセス起動時に呼び出されて、新しい依存関係が追加されることが示されます。このアクティビティーは、遅延読み込みと dlopen(3C) イベントの場合にも呼び出されます。LA_ACT_DELETE アクティビティーは、dlclose(3C) でオブジェクトが削除されたときにも呼び出されます。

LA_ACT_ADD および LA_ACT_DELETE アクティビティーは、後に続くことが予想されるイベントのヒントです。実際のイベントが異なる場合が多数あります。たとえば、新しいオブジェクトが追加された場合にそれらのオブジェクトを完全に再配置できないときは、新しいオブジェクトのいくつかが削除されることがあります。.fini 実行可能ファイルによって新しいオブジェクトが遅延読み込みになった場合、オブジェクトの削除によって新しいオブジェクトが追加されることもあります。オブジェクトの追加または削除の後に、アプリケーションのリンクマップリストが一貫していることを示すために LA_ACT_CONSISTENT アクティビティーが発生します。このアクティビティーは信頼できます。監査プログラムは、無条件に LA_ACT_ADD および LA_ACT_DELETE のヒントを信じるのではなく、実際の結果を注意深く検証する必要があります。

監査バージョン LAV_VERSION1 から LAV_VERSION4 の場合、la_activity() は大域監査でのみ呼び出されていました。監査バージョンが LAV_VERSION5 の場合、ローカル監査によってアクティビティーのイベントを取得できます。アクティビティーのイベントは、アプリケーションのリンクマップを表す cookie を提供します。このアクティビティーを準備し、監査プログラムがこの cookie の内容を制御できるようにするため、最初にローカル監査の la_objopen() が呼び出されます。la_objopen() 呼び出しによって、アプリケーションのリンクマップを表す初期 cookie が提供されます。監査インタフェースの対話を参照してください。

la_objsearch()

このルーチンは、オブジェクトの検索を実行することを監査プログラムに知らせます。

char *la_objsearch(const char *name, uintptr_t *cookie, uint_t flags);

name は、検索中のファイルあるいはパス名を指します。cookie は、検索を開始しているオブジェクトを指します。flags は、/usr/include/link.h に定義されている name の出所および作成を示します。

  • LA_SER_ORIG – 初期検索名。通常は、DT_NEEDED エントリとして記録されたファイル名、あるいは dlopen(3C) に与えられた引数を指します。

  • LA_SER_LIBPATH – パス名が LD_LIBRARY_PATH コンポーネントから作成されている。

  • LA_SER_RUNPATH – パス名が「実行パス」コンポーネントから作成されている。

  • LA_SER_DEFAULT – パス名がデフォルトの検索パスコンポーネントから作成されている。

  • LA_SER_CONFIG – パスコンポーネントの出所が構成ファイルである。crle(1) のマニュアルページを参照してください。

  • LA_SER_SECURE – パスコンポーネントがセキュアなオブジェクトに固有である。

戻り値は、実行時リンカーが処理を継続する必要がある検索パス名を示します。値 0 は、このパスが無視されることを示しています。検索パスをモニターする監査ライブラリは、name を返します。

la_objfilter()

このルーチンは、フィルタが新しいフィルティーを読み込むと呼び出されます。フィルタとしての共有オブジェクトを参照してください。

int la_objfilter(uintptr_t *fltrcook, const char *fltestr,
    uintptr_t *fltecook, uint_t flags);

fltrcook は、フィルタを特定します。fltestr は、フィルティー文字列を指します。fltecook は、フィルティーを特定します。flags は、現在使用されていません。la_objfilter() は、フィルタとフィルティーの la_objopen() が呼び出されたあとに呼び出されます。

戻り値 0 は、このフィルティーが無視されることを示しています。フィルタの使用をモニターする監査ライブラリは、0 以外の値を返します。

la_preinit()

このルーチンは、アプリケーションのすべての即時依存関係がロードされたあとで一度呼び出されます。

void la_preinit(uintptr_t *cookie);

cookie は、プロセスを開始したプライマリオブジェクト、通常は動的実行可能プログラムを表します。

la_preinit() が呼び出されたあとも、プロセスでは、初期スレッドローカルストレージの作成などスレッドの初期化が必要です。プログラムの起動を参照してください。さらに、ロードされたすべてのオブジェクトを実行する前に、その初期設定セクションで収集およびソートを行う必要があります。初期設定および終了ルーチンを参照してください。この関数は、初期プロセスにオブジェクトを追加するときに便利な制御ポイントをもたらします。これらのオブジェクトは、初期スレッドローカルストレージと、プロセスの初期設定に使用できます。

監査バージョン LAV_VERSION1 から LAV_VERSION4 の場合、la_preinit() は大域監査でのみ呼び出されていました。監査バージョンが LAV_VERSION5 の場合、ローカル監査によって preinit イベントを取得できます。preinit イベントは、アプリケーションのリンクマップを表す cookie を提供します。この preinit を準備し、監査プログラムがこの cookie の内容を制御できるようにするため、最初にローカル監査の la_objopen() が呼び出されます。la_objopen() 呼び出しによって、アプリケーションのリンクマップを表す初期 cookie が提供されます。監査インタフェースの対話を参照してください。

la_callinit()

このルーチンは、スレッドの初期化が完了し、初期スレッドローカルストレージが確立されたあとで呼び出されます。さらに、すべての初期化ルーチンは収集およびソートされ、実行できるようになっています。

void la_callinit(uintptr_t *cookie);

cookie と、大域監査およびローカル監査からの呼び出しについては、la_preinit() の場合と同じです。

このインタフェースは、監査バージョン LAV_VERSION6 で追加されたインタフェースであり、アプリケーションコードの実行への遷移にマークを付けます。

la_callentry()

このルーチンは、すべての初期化ルーチンが実行されたあとで呼び出されます。

void la_callentry(uintptr_t *cookie);

cookie と、大域監査およびローカル監査からの呼び出しについては、la_preinit() の場合と同じです。

このインタフェースは、監査バージョン LAV_VERSION6 で追加されたインタフェースであり、アプリケーションエントリポイントへの遷移にマークを付けます。

la_symbind()

このルーチンは、la_objopen() によって結合通知のタグが付けられた 2 つのオブジェクト間で結合が発生したときに呼び出されます。

uintptr_t la_symbind32(Elf32_Sym *sym, uint_t ndx,
    uintptr_t *refcook, uintptr_t *defcook, uint_t *flags);

uintptr_t la_symbind64(Elf64_Sym *sym, uint_t ndx,
    uintptr_t *refcook, uintptr_t *defcook, uint_t *flags,
    const char *sym_name);

sym は構築されたシンボル構造であり、sym->st_value は結合されたシンボル定義のアドレスを示します。/usr/include/sys/elf.h を参照してください。la_symbind32() は、sym->st_name を調整して実際のシンボル名を指すようにしています。la_symbind64() は sym->st_name を結合オブジェクトの文字列テーブルのインデックスのままにしています。

ndx は、結合オブジェクト動的シンボルテーブル内のシンボルインデックスを示します。refcook は、このシンボルへの参照を行うオブジェクトを特定します。この識別子は、LA_FLG_BINDFROM を返した la_objopen() ルーチンに渡されたものと同じです。defcook は、このシンボルを定義するオブジェクトを特定します。この識別子は、LA_FLG_BINDTO を返した la_objopen() に渡されるものと同じです。

flags は、結合に関する情報を伝達できるデータ項目を指します。このデータ項目を使用すると、プロシージャーのリンクテーブルエントリの連続監査も変更できます。この値は、/usr/include/link.h に定義されたシンボル結合フラグのマスクです。

次のフラグが la_symbind() に提供される場合もあります。

  • LA_SYMB_DLSYMdlsym(3C) を呼び出した結果、シンボル結合が発生した。

  • LA_SYMB_ALTVALUE (LAV_VERSION2)la_symbind() への以前の呼び出しによって、シンボル値に対して代替値が返された。

la_pltenter() または la_pltexit() ルーチンが存在する場合、これらのルーチンは、プロシージャーリンクテーブルエントリの la_symbind() の後に呼び出されます。これらのルーチンは、シンボルが参照されるたびに呼び出されます。詳細は、監査インタフェースの制限を参照してください。

次のフラグは、デフォルトの動作を変更するために la_symbind() から提供されます。これらのフラグは、flags 引数が指す値とのビット単位の OR 演算として適用されます。

  • LA_SYMB_NOPLTENTER – このシンボルに対して la_pltenter() ルーチンを呼び出さない

  • LA_SYMB_NOPLTEXIT – このシンボルに対して la_pltexit() ルーチンを呼び出さない

戻り値は、この呼び出しに続いて制御を渡す必要があるアドレスを示します。シンボル結合をモニターするだけの監査ライブラリは、sym->st_value の値を返すため、制御は結合シンボル定義に渡されます。監査ライブラリは、異なる値を返すことによって、シンボル結合を意図的にリダイレクトできます。

sym_name は、la_symbind64() のみに適用可能であり、処理されるシンボルの名前を含みます。この名前は、32 ビットインタフェースの sym->st_name フィールドから得られます。

la_pltenter()

これらのルーチンはシステムに固有です。これらのルーチンは、結合通知のタグが付いた 2 つのオブジェクト間でプロシージャーのリンクテーブルエントリが呼び出されるときに呼び出されます。

uintptr_t la_sparcv8_pltenter(Elf32_Sym *sym, uint_t ndx,
    uintptr_t *refcook, uintptr_t *defcook,
    La_sparcv8_regs *regs, uint_t *flags);

uintptr_t la_sparcv9_pltenter(Elf64_Sym *sym, uint_t ndx,
    uintptr_t *refcook, uintptr_t *defcook,
    La_sparcv9_regs *regs, uint_t *flags,
    const char *sym_name);

uintptr_t la_i86_pltenter(Elf32_Sym *sym, uint_t ndx,
    uintptr_t *refcook, uintptr_t *defcook,
    La_i86_regs *regs, uint_t *flags);

uintptr_t la_amd64_pltenter(Elf64_Sym *sym, uint_t ndx,
    uintptr_t *refcook, uintptr_t *defcook,
    La_amd64_regs *regs, uint_t *flags, const char *sym_name);

sym、ndx、refcook、defcook、および sym_name は、la_symbind() に渡されたものと同じ情報を提供します。

la_sparcv8_pltenter()la_sparcv9_pltenter() では、regs は out レジスタを指します。la_i86_pltenter() では、regs は stack および frame レジスタを指します。la_amd64_pltenter() では、 regs は stack および frame レジスタ、および整数引数の受け渡しに使用されるレジスタを指します。regs は /usr/include/link.h に定義されています。

flags は、結合に関する情報を伝達できるデータ項目を指します。このデータ項目を使用すると、プロシージャーリンクテーブルのエントリの連続監査を変更できます。このデータ項目は、la_symbind() から flags によって指されるものと同じです。

次のフラグは、現在の監査動作を変更するために la_pltenter() から提供できます。これらのフラグは、flags 引数が指す値とのビット単位の OR 演算として適用されます。

  • LA_SYMB_NOPLTENTERla_pltenter() は、このシンボルでは再び呼び出されることはない。

  • LA_SYMB_NOPLTEXITla_pltexit() は、このシンボルでは呼び出されない。

戻り値は、この呼び出しに続いて制御を渡す必要があるアドレスを示します。シンボル結合をモニターするだけの監査ライブラリは、sym->st_value の値を返すため、制御は結合シンボル定義に渡されます。監査ライブラリは、異なる値を返すことによって、シンボル結合を意図的にリダイレクトできます。

la_pltexit()

このルーチンは、結合通知のタグが付いた 2 つのオブジェクト間でプロシージャーのリンクテーブルエントリが返されるときに呼び出されます。このルーチンは、制御が呼び出し側に到達する前に呼び出されます。

uintptr_t la_pltexit(Elf32_Sym *sym, uint_t ndx, uintptr_t *refcook,
    uintptr_t *defcook, uintptr_t retval);

uintptr_t la_pltexit64(Elf64_Sym *sym, uint_t ndx, uintptr_t *refcook,
    uintptr_t *defcook, uintptr_t retval, const char *sym_name);

sym、ndx、refcook、defcook、および sym_name は、la_symbind() に渡されたものと同じ情報を提供します。retval は結合関数からの戻りコードです。シンボル結合をモニターする監査ライブラリは、retval を返します。監査ライブラリは、意図的に異なる値を返すことができます。


注 - la_pltexit() は実験段階のインタフェースです。詳細は、監査インタフェースの制限を参照してください。
la_objclose()

このルーチンは、オブジェクトに対する終了コードが実行されてから、オブジェクトが読み込みを解除されるまでに呼び出されます。

uint_t la_objclose(uintptr_t *cookie);

cookie はオブジェクトを特定するもので、以前の la_objopen() から取得されています。戻り値は、ここではすべて無視されます。