(57)【要約】【課題】  実行効率を高めることのできる動的リンクライブラリ処理装置を提供する。【解決手段】  それぞれの動的リンクライブラリが配置される仮想アドレス上での位置を示す仮想アドレス配置プランを作成し、この仮想アドレス配置プランに従って動的リンクライブラリをリロケートする。さらに、動的リンクライブラリをロードするときに、仮想アドレス配置プランに示された位置に動的リンクライブラリをロードする。この事により、動的リンクライブラリのコードに実行効率の高い位置依存コードを使用する事ができ、かつ動コードを複数のプロセス間で共有する事ができる。【選択図】      図１
2006048431.tif 000002
【特許請求の範囲】
【請求項１】
仮想メモリ機構を用いるコンピュータシステムにおいて、
一つ以上の実行可能プログラムと一つ以上の動的リンクライブラリとを受け取り、動的リンクライブラリが重複しないように、前記一つ以上の動的リンクライブラリおよび前記一つ以上の実行可能プログラムの仮想アドレス上での配置を決定することにより、前記一つ以上の動的リンクライブラリおよび前記一つ以上の実行可能プログラムの仮想アドレス上での配置位置を示す仮想アドレス配置プランを生成する仮想アドレス配置プラン生成部と、
前記一つ以上の実行可能プログラムと前記一つ以上の動的リンクライブラリとを受け取り、それぞれの実行可能プログラムと動的リンクライブラリを、プログラムの実行以前に、前記仮想アドレス配置プランに基づいてリロケートする配置プラン対応リロケータと、
プログラムの実行時に、前記配置プラン対応リロケータがリロケートした実行可能プログラムおよび動的リンクライブラリを受け取り、ロード対象の実行可能プログラムまたは動的リンクライブラリが実行しているプログラムと異なる仮想アドレス空間に既にロードされている場合はそのコードを共有し、そうでない場合は前記仮想アドレス配置プランに従った仮想アドレス上での位置に、実行可能プログラムまたは動的リンクライブラリをロードする配置プラン対応ローダと、
を備える事を特徴とする動的リンクライブラリ処理装置。
【請求項２】
前記配置プラン対応リロケータによってリロケートされた実行可能プログラムまたは動的リンクライブラリを受け取り、それぞれの実行可能プログラムまたは動的リンクライブラリの中の、シンボル情報およびリロケート情報を削除するストリッパ、
を更に備える事を特徴とする請求項１記載の動的リンクライブラリ処理装置。
【請求項３】
前記仮想アドレス配置プランを受け取り、仮想アドレス上のメモリ領域を確保するときに、前記仮想アドレス配置プランによって示されている仮想アドレス領域以外からメモリ確保を行なうメモリマネージャ、
を更に備える事を特徴とする請求項１または請求項２記載の動的リンクライブラリ処理装置。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、実行可能プログラム及び動的リンクライブラリのリンクおよびロードを行う動的リンクライブラリ処理装置に関するものである。
【背景技術】
【０００２】
コンピュータシステムにおいて、複数のプログラムで共通する処理は多くある。複数のプログラムで共通する処理をプログラムごとに開発する事は重複であり、非効率的である。そこで、複数のプログラムで共通する処理は、ライブラリとしてまとめられて開発される。
【０００３】
ライブラリが一度開発され、このライブラリを使用する複数のプログラムの本体部分が開発されるという形で開発が進められ、共通の処理が重複開発される事がなくなる。
【０００４】
一般に、ライブラリはプログラムの本体部分から切り離されて、カプセル化されて構築される。プログラムの本体部分と、ライブラリがそれぞれ別々に構築され、最後にこれらをリンクして、実行可能プログラムが生成される。
【０００５】
リンクとは、プログラム内のある部分と別の部分を連結する処理である。リンク処理はリンカによって行なわれる。リンク処理では、例えば関数呼び出しなどで、呼び出し元と呼び出し先を連結するといった処理が行なわれる。
【０００６】
例えば、プログラムの本体部分から、ライブラリ内にある関数を呼び出すときを考える。一般に、関数呼び出しでは、呼び出し元から呼び出し先にジャンプする機械語命令が使用される。したがって、呼び出し先の関数が書かれているアドレスを呼び出し元のコードに書き込む事になる。リンカは、まずライブラリ内にある関数（呼び出し先）のアドレスを取得する。次に、このアドレスをプログラム本体部分（呼び出し元）に書き込む。これにより、呼び出し元と呼び出し先が適切にリンクされ、プログラムの本体部分からライブラリ内にある関数が呼び出せるようになる。また、このように、アドレスを解決して、コードなどを書き換える作業をリロケート（再配置）と言う。
【０００７】
ライブラリをリンクする方法は、大きく分けて２つある。ひとつは静的リンク方式であり、もうひとつは動的リンク方式である。
【０００８】
静的リンク方式は、実行可能プログラムを構築するときに、ライブラリのコードのコピーを作って、プログラムの本体部分にリンクする方式である。ライブラリの開発自体が重複するわけではないが、構築されたライブラリのコードは複数のプログラムにコピーされる事になる。静的リンク方式では、実行可能プログラムを構築するときにプログラム本体部分とライブラリがリンクされるため、実行可能プログラムは単体で実行できるものである。
【０００９】
静的リンク方式では、複数のプログラムに同じライブラリのコードがコピーされるため、コンピュータシステム内にひとつのコードのコピーがたくさん作られてしまう可能性がある。また、仮想メモリ機構を使用するコンピュータシステムの場合、同じコードがメモリ上に重複して存在してしまう場合が発生してしまう事もある。このため、近年のコンピュータシステムでは下記で説明する動的リンク方式が採用される事が多い。
【００１０】
動的リンク方式は、実行可能プログラムの本体部分にライブラリのコードを含めず、プログラム実行時にライブラリを読み込んでリンクする方式である。プログラムの本体部分である実行可能プログラムにはライブラリのコードが含まれていないため、プログラムの本体部分は最初、未解決のアドレス参照を含んでいる。したがって、実行可能プログラムは、単体では実行できない場合がある。実行可能プログラムの起動時や、ライブラリ内の情報が必要になったときに、プログラム本体とライブラリがリンクされる。
【００１１】
業界標準のフォーマットであるＥＬＦを用いた動的リンク方式として、ＧＯＴ（Ｇｌｏｂａｌ  Ｏｆｆｓｅｔ  Ｔａｂｌｅ）等のアプリケーション・バイナリ・インタフェースを用いた方法が、特許文献１で開示されている。ＧＯＴは、プログラムの本体部分やライブラリが、異なるライブラリのアドレスを参照するときに使用されるアドレスのテーブルである。
【００１２】
例えば、あるライブラリＸと、別のライブラリＹを使用するプログラムが実行されるときを考える。このとき、ライブラリＹの中に関数ｆがあり、この関数がライブラリＸから使用されるものとする。プログラムが実行されると、このプログラムが使用するライブラリがロードされ、それぞれのライブラリのＧＯＴが初期化される。ライブラリＸのＧＯＴには、ｆのためのエントリが用意されている。この、ｆのためのエントリには、関数ｆのアドレスが格納される。すなわち、ライブラリＹの中にある関数ｆのアドレスが、ライブラリＸのＧＯＴに格納される事になる。ライブラリＸから関数ｆを呼び出すとき、ＧＯＴを調べて関数ｆのアドレスを取得し、取得したアドレスにジャンプする。
【００１３】
あるライブラリが、ライブラリ外のアドレスを参照するとき、直接そのアドレスを参照するのではなく、ＧＯＴを経由して参照する事になる。ライブラリのコード自体は、ライブラリ外のアドレスがどこにあっても変わらない。したがって、ＧＯＴを使用すると、位置独立コードを生成する事ができる。位置独立コードは、プログラムのコードがアドレス空間のどの位置に配置されても良いコード、すなわち位置に依存しないコードである。位置に依存する情報は、ＧＯＴにまとめられており、ＧＯＴはライブラリのロード時などに初期化される。
【００１４】
あるライブラリのコードが位置独立のとき、このライブラリはアドレス空間のどの位置に配置されても良い。したがって、このライブラリがロードされるときに、ライブラリのコードが書き換えられる必要がない。
【００１５】
ライブラリのコードは書き換えられないため、コードの内容は不変である。このため、仮想メモリ機構を使用するマルチプロセス環境において、複数のプログラムが同じライブラリを使用するとき、このライブラリのコードを共有する事が可能となる。例えば、それぞれが独立した仮想アドレス空間で動作している異なるプログラムが複数あったとする。これらのプログラムが同じライブラリを異なる位置にロードしたとする。ライブラリのコードは位置独立であり、どの位置にロードされていてもコードは不変である。したがって、これらの異なるプログラムは、全く同じコードを参照している事になる。このため、これらのプログラムは、ライブラリのコードを共有する事ができる。
【００１６】
ライブラリのコードが共有されると、同じライブラリを複数回ロードする必要がなく、またメモリ上にライブラリのコードが重複して存在する必要がない。このため、メモリの使用効率が良い。
【特許文献１】特開平８−１７９９４７号公報
【発明の開示】
【発明が解決しようとする課題】
【００１７】
前記のＧＯＴを用いた方法では、ライブラリのコードを位置独立にする事ができる。その結果、異なる仮想アドレス空間で動作するプログラム間であっても、ライブラリのコードを共有する事ができる。
【００１８】
しかしながら、ＧＯＴを用いた方法では、ライブラリ外のアドレスを参照するときに、直接参照先のアドレスにアクセスするのではなく、ＧＯＴを経由した間接参照となってしまうという問題点があった。例えば、関数呼び出しの場合を考える。直接アドレス参照であれば、あらかじめコードに書き込まれている参照先のアドレスに直接ジャンプするだけで関数呼び出しが実現できる。他方、間接アドレス参照の場合、いったんＧＯＴから参照先のアドレスを取得してレジスタに保存し、レジスタが示すアドレスにジャンプする処理が必要になる。間接参照は、直接参照と比較して処理命令数が増加してしまい、実行効率の低下につながってしまうという問題点があった。
【００１９】
本発明は上記問題点を解決するためになされたもので、実行効率を高めることのできる動的リンクライブラリ処理装置を提供することを目的とする。
【課題を解決するための手段】
【００２０】
本発明では、前記の課題を解決するために、どの動的リンクライブラリを仮想アドレス空間の中のどの位置にロードするのかを示す仮想アドレス配置プランを作り、この仮想アドレス配置プランに基づいて動的リンクライブラリをリロケートし、動的リンクライブラリがロードされる時に仮想アドレス配置プランに示される位置にロードされるようにする。
【００２１】
仮想アドレスの配置プランにより、それぞれの動的リンクライブラリが仮想アドレス空間のどの位置に配置されるのかが決まる。それぞれの動的リンクライブラリが配置されるアドレスは重複しないように決められる。
【００２２】
さらに、この仮想アドレス配置プランに従って、それぞれの動的リンクライブラリは、プログラム実行前にリロケートされる。例えば、ある動的リンクライブラリＸが、別の動的リンクライブラリＹの中にある関数ｆを呼び出すときを考える。動的リンクライブラリＹが仮想アドレスのどの位置に配置されるのかが仮想アドレス配置プランにより決まっているため、動的リンクライブラリＹの中の関数ｆが置かれているアドレスも決まっている。動的リンクライブラリＸから、関数ｆを呼び出すコードは、直接関数ｆのアドレスにジャンプするようにリロケートされる。
【００２３】
ローダによって動的リンクライブラリまたは実行可能プログラムがメモリ上にロードされるときに、ロード対象の動的リンクライブラリまたは実行可能プログラムが異なる仮想アドレス空間上で既にロードされている場合、そのコードは共有され、そうでない場合は、仮想アドレス配置プランで決められた位置に動的リンクライブラリまたは実行可能プログラムが配置される。
【発明の効果】
【００２４】
本発明にかかる動的リンクライブラリ処理装置を用いると、仮想メモリ機構を使用するマルチプロセス環境においてライブラリのコードを複数の仮想アドレス空間で共有する事ができ、かつ、仮想アドレスの位置に依存するコードを用いる事ができる。ライブラリのコードは共有されるため、メモリ使用効率が良い。また、アドレスの位置に依存するコードであるため、アドレス参照で直接参照を使用する事ができ、実行効率が向上する。
【００２５】
例えば、ある動的リンクライブラリに、別の動的リンクライブラリのデータを直接アドレス参照するような位置依存コードがあったとしても、それぞれの動的リンクライブラリが配置されるアドレスは仮想アドレス配置プランによって決定されている。このため、参照先のアドレスはプログラム実行前に分かっており、事前にアドレス解決が行われている。それぞれの動的リンクライブラリのコードは既にリロケートされているため、実行時にコードを書き換える必要がない。このため、動的リンクライブラリのコードを異なる仮想アドレス空間で共有する事ができる。
【発明を実施するための最良の形態】
【００２６】
本発明の実施の形態について、図面を参照して説明する。
【００２７】
（実施の形態１）
図１は本発明の実施の形態１における動的リンクライブラリ処理装置の構成を示す図である。
【００２８】
二次記憶装置１０１は、プログラムやデータを保存する装置であって、動的リンクライブラリ１０２、実行可能プログラム１０３、仮想アドレス配置プラン１０４を保存している。なお、二次記憶装置はこれら以外にもユーザのデータなど他の情報を保存しておいても良い。
【００２９】
動的リンクライブラリ１０２は、プログラムが実行するときに使用するコードやデータを含むライブラリであり、ひとつまたは複数存在している。動的リンクライブラリの詳細な説明は図２を用いて後述する。
【００３０】
実行可能プログラム１０３は、それぞれのプログラムのうちのライブラリを除いた本体部分であり、ひとつまたは複数存在している。実行可能プログラムの詳細な説明は図２を用いて後述する。
【００３１】
仮想アドレス配置プラン１０４は、それぞれの動的リンクライブラリ１０２や実行可能プログラム１０３が、プログラム実行時に、仮想アドレス上のどの位置に配置されるのかを示すプランである。仮想アドレス配置プラン１０４の詳細な説明は図４を用いて後述する。
【００３２】
仮想アドレス配置プラン生成部１０５は、ひとつまたは複数の、実行可能プログラム１０３と動的リンクライブラリ１０２を受け取り、仮想アドレス配置プラン１０４を生成する。仮想アドレス配置プランを生成する処理の詳細な説明は図６を用いて後述する。
【００３３】
配置プラン対応リロケータ１０６は、ひとつまたは複数の、実行可能プログラム１０３と動的リンクライブラリ１０２を受け取り、それぞれの実行可能プログラムと動的リンクライブラリを、仮想アドレス配置プラン生成部１０５が生成した、仮想アドレス配置プラン１０４に基づいてリロケートする。仮想アドレス配置プランを用いたリロケート処理の詳細な説明は図６を用いて後述する。
【００３４】
配置プラン対応ローダ１０７は、配置プラン対応リロケータ１０６がリロケートした実行可能プログラム１０３と動的リンクライブラリ１０２を受け取り、ロード対象の実行可能プログラムまたは動的リンクライブラリと同じ実行可能プログラムまたは動的リンクライブラリが既にロードされている場合はそのコードを共有し、そうでない場合は、仮想アドレス配置プラン１０４に従った仮想アドレス上での位置にロード対象の実行可能プログラムまたは動的リンクライブラリをロードする。仮想アドレス配置プランに従ったロード処理の詳細な説明は図１０を用いて後述する。
【００３５】
図２は、ひとつの実行可能プログラムまたは動的リンクライブラリに含まれる情報を示す図である。なお、以下では、実行可能プログラムと動的リンクライブラリを総称して、プログラムバイナリと呼ぶ。
【００３６】
ヘッダ情報２０１には、そのプログラムバイナリ全体の情報が含まれている。含まれている情報は、そのプログラムバイナリが実行可能プログラムなのか動的リンクライブラリなのかを示すフラグ、ファイル形式のバージョン情報、使用するエンディアンの情報、対応アーキテクチャ、含まれているセクションとその位置、使用する動的リンクライブラリなどである。
【００３７】
テキストセクション２０２には、そのプログラムバイナリのテキストが含まれている。テキストとは、ＣＰＵが実行する機械語命令の列である。ＣＰＵは、実行時にメモリ上に配置されたテキストに従って、書かれている命令をひとつずつ読み込み、実行する。本実施の形態では、実行効率の高い位置依存コードのテキストの場合を説明する。なお、テキストは、位置独立コードであっても良い。
【００３８】
データセクション２０３には、そのプログラムバイナリが使用するデータが含まれている。例えば、そのプログラムバイナリの元となったソースコードに、大域変数があったとする。また、この大域変数には初期値が設定されていたとする。この大域変数の初期値は、データセクションに格納される。プログラムバイナリのロード時に、大域変数の初期値がデータセクションから読み出されて大域変数が初期化される。
【００３９】
ｂｓｓセクション２０４には、そのプログラムバイナリが使用する初期化不要のデータが含まれている。前記データセクション２０３では、初期値を必要とする大域変数のためのデータが含まれており、ロード時にデータセクション２０３からその初期値が読み出されて大域変数が初期化される。しかし、大域変数によっては明示的な初期化を必要としないものもある。初期化を必要としない大域変数はｂｓｓセクションに含まれ、例えばゼロ初期化されるなどの処理がローダによって行なわれる。
【００４０】
リロケート情報２０５には、そのプログラムバイナリの、テキストセクション２０２やデータセクション２０３をリロケートするときに必要な情報である未解決参照情報が含まれている。未解決参照情報は、未解決のままになっているアドレス参照の位置と、参照先のシンボルの情報の組からなる。リロケート情報２０５には、未解決のままになっているアドレス参照の数だけ、未解決参照情報が存在している。
【００４１】
シンボルテーブル２０６には、そのプログラムバイナリが持つシンボルの情報が含まれている。シンボル情報は、そのプログラムバイナリの元になるソースコードに含まれていた関数や変数が、プログラムバイナリのどの位置に配置されているのかを表わす情報である。ひとつのシンボル情報は、シンボル文字列と、そのシンボルに対応する関数またはデータが仮想アドレス上で配置される位置、の組からなる。シンボルテーブル２０６には、そのプログラムバイナリに含まれている数だけのシンボルが含まれている。なお、シンボル情報は、シンボル文字列のかわりに、シンボルを表わすハッシュキーで表現しても良く、またシンボルを含む文字列テーブルへのポインタであっても良い。また、シンボルテーブル２０６は、そのプログラムバイナリの全てのシンボル情報ではなく、処理に必要な分だけのシンボル情報のみを保持しても良い。
【００４２】
図３は、具体例を用いて、リロケート情報２０５やシンボルテーブル２０６の情報を説明した図である。３０１および３０２は、それぞれ別個の動的リンクライブラリである。３０３および３０４は、それぞれ動的リンクライブラリ３０１および３０２のテキストセクションである。３０５は、関数ｆへの未解決のアドレス参照である。３０６は、関数ｆのテキストである。３０７は、動的リンクライブラリ３０１のリロケート情報である。３０８は、リロケート情報３０７のうちのひとつの項目であり、３０５の位置とシンボルｆからなる組である。３０９は、動的リンクライブラリ３０２のシンボルテーブルである。３１０は、３０９のうちのひとつの項目であり、シンボルｆと３０６のアドレスからなる組である。
【００４３】
動的リンクライブラリ３０１には、関数ｆへの参照が含まれており、その関数ｆは動的リンクライブラリ３０２に含まれている。動的リンクライブラリ３０１の構築時には、関数ｆが仮想アドレス空間のどの位置に置かれるのかが分からないため、関数ｆへの参照を未解決のまま残される。これが未解決の参照３０５である。後に、リロケート処理を行なうときのために、この未解決の情報を記憶しておく必要があり、それが、ひとつのリロケート情報３０８である。
【００４４】
動的リンクライブラリ３０２には、関数ｆが含まれている。別のライブラリ（例えば、動的リンクライブラリ３０１）などが関数ｆを参照するときのために、ｆとその位置が記憶されている必要があり、これがシンボル情報３１０である。
【００４５】
図４は、仮想アドレス配置プラン１０４の内容を示した一例である。４０１は、仮想アドレス配置プラン１０４の内容を示したテーブルである。この例では、プログラムバイナリは合計で６個ある。実行可能プログラムがＰ＃１、Ｐ＃２、Ｐ＃３の３個であり、動的リンクライブラリがＬ＃１、Ｌ＃２、Ｌ＃３の３個である。
【００４６】
また、ここでは実行可能プログラムＰ＃１が動的リンクライブラリＬ＃１と動的リンクライブラリＬ＃２を使用し、実行可能プログラムＰ＃２が動的リンクライブラリＬ＃１と動的リンクライブラリＬ＃３を使用し、実行可能プログラムＰ＃３が動的リンクライブラリＬ＃１と動的リンクライブラリＬ＃２と動的リンクライブラリＬ＃３を使用するとする。
【００４７】
仮想アドレス配置プランでは、それぞれのプログラムバイナリの開始アドレスと終了アドレスを決める。実行可能プログラムＰ＃１の開始アドレスと終了アドレスはそれぞれａ＃１とａ＃２である。実行可能プログラムＰ＃２の開始アドレスと終了アドレスはそれぞれａ＃１とａ＃３である。実行可能プログラムＰ＃３の開始アドレスと終了アドレスはそれぞれａ＃１とａ＃４である。動的リンクライブラリＬ＃１の開始アドレスと終了アドレスはそれぞれａ＃４とａ＃５である。動的リンクライブラリＬ＃２の開始アドレスと終了アドレスはそれぞれａ＃５とａ＃６である。動的リンクライブラリＬ＃３の開始アドレスと終了アドレスはそれぞれａ＃６とａ＃７である。
【００４８】
仮想アドレス配置プランでは、複数の実行可能プログラムが同じ仮想アドレス位置に重複して配置されても良い。複数の実行可能プログラムが同じ仮想アドレス空間上にロードされる事はないため、仮想アドレス配置プラン上で複数の実行可能プログラムが同じ仮想アドレス位置に重複して配置されても問題はない。全ての実行可能プログラムが、仮想アドレス配置プラン上で同じ仮想アドレス位置に配置されると、大量の実行可能プログラムがあっても仮想アドレス空間の領域を必要以上に消費する事はない。なお、複数の実行可能プログラムの仮想アドレス領域が重複しないように配置されても良い。
【００４９】
動的リンクライブラリの仮想アドレス領域は重複しないように設定される。すなわち、ひとつの動的リンクライブラリが配置されている仮想アドレス領域には、他のプログラムバイナリが配置されないようにする。ひとつのプログラムから複数の動的リンクライブラリが使用される事はあるため、複数の動的リンクライブラリが同じ仮想アドレス空間上にロードされる事はある。複数の動的リンクライブラリが同じ仮想アドレス空間上にロードされる場合、それらが同じ仮想アドレス位置に配置されると競合が生じてしまう。
【００５０】
図５は、前記仮想アドレス配置プラン４０１に従って、それぞれの実行可能プログラムが実行されたときの、仮想アドレス上でのプログラムバイナリの配置である。
【００５１】
５０１は、実行可能プログラムＰ＃１が実行されたときの仮想アドレス空間であり、仮想アドレス上でのプログラムバイナリの配置を示している。実行可能プログラムＰ＃１は、動的リンクライブラリＬ＃１と動的リンクライブラリＬ＃２を使用する。前記仮想アドレス配置プラン４０１に従い、実行可能プログラムＰ＃１の仮想アドレス上での配置は、アドレスａ＃１からアドレスａ＃２であり、動的リンクライブラリＬ＃１の開始アドレスと終了アドレスはそれぞれａ＃４とａ＃５であり、動的リンクライブラリＬ＃２の開始アドレスと終了アドレスはそれぞれａ＃５とａ＃６である。
【００５２】
５０２は、実行可能プログラムＰ＃２が実行されたときの仮想アドレス空間であり、仮想アドレス上でのプログラムバイナリの配置を示している。実行可能プログラムＰ＃２は、動的リンクライブラリＬ＃１と動的リンクライブラリＬ＃３を使用する。前記仮想アドレス配置プラン４０１に従い、実行可能プログラムＰ＃２の仮想アドレス上での配置は、アドレスａ＃１からアドレスａ＃３であり、動的リンクライブラリＬ＃１の開始アドレスと終了アドレスはそれぞれａ＃４とａ＃５であり、動的リンクライブラリＬ＃３の開始アドレスと終了アドレスはそれぞれａ＃６とａ＃７である。
【００５３】
５０３は、実行可能プログラムＰ＃３が実行されたときの仮想アドレス空間であり、仮想アドレス上でのプログラムバイナリの配置を示している。実行可能プログラムＰ＃３は、動的リンクライブラリＬ＃１と動的リンクライブラリＬ＃２と動的リンクライブラリＬ＃３とを使用する。前記仮想アドレス配置プラン４０１に従い、実行可能プログラムＰ＃３の仮想アドレス上での配置は、アドレスａ＃１からアドレスａ＃４であり、動的リンクライブラリＬ＃１の開始アドレスと終了アドレスはそれぞれａ＃４とａ＃５であり、動的リンクライブラリＬ＃２の開始アドレスと終了アドレスはそれぞれａ＃５とａ＃６であり、動的リンクライブラリＬ＃３の開始アドレスと終了アドレスはそれぞれａ＃６とａ＃７である。
【００５４】
実行可能プログラムＰ＃１、Ｐ＃２、Ｐ＃３の仮想アドレス領域は重複している。例えば、実行可能プログラムＰ＃３にはアドレスａ＃１からアドレスａ＃４までの領域が割り当てられるが、この領域は、実行可能プログラムＰ＃１が割り当てられるアドレスａ＃１からアドレスａ＃２までの領域と重複している。これは、プログラムの実行時に、ひとつの仮想アドレス空間に複数の実行可能プログラムがロードされる事がないためである。プログラムの実行時に、複数の実行可能プログラムが実行される事がないため、実行可能プログラムの仮想アドレス領域が重複していても、仮想アドレス空間上での競合は生じない。
【００５５】
また、どの実行可能プログラムから使用される場合でも、動的リンクライブラリＬ＃１の仮想アドレス領域はアドレスａ＃４からアドレスａ＃５である。（動的リンクライブラリＬ＃２、Ｌ＃３も同様である。）
【００５６】
実行可能プログラムＰ＃２は動的リンクライブラリＬ＃２を使用しないため、仮想アドレス空間５０２のアドレスａ＃５からアドレスａ＃６は使用されていない。同様に、仮想アドレス空間５０１のうちのアドレスａ＃２からアドレスａ＃４までの領域なども使用されていない。しかし、この領域は仮想アドレス領域であって、対応する物理メモリ領域が割り当てられるわけではないので、このように仮想アドレス空間で使用していないメモリがあっても、不必要にメモリ使用量を増大させる事はない。
【００５７】
図６は、本実施の形態の仮想アドレス配置プラン生成部１０５と配置プラン対応リロケータ１０６による、プログラムバイナリのリロケート処理までのステップを示したフローチャートである。
【００５８】
Ｓ６０１で、仮想アドレス配置プラン生成部１０５が、空の仮想アドレス配置プラン１０４を生成する。空の仮想アドレス配置プラン１０４は、どの仮想アドレス領域も予約されていない事を意味する。
【００５９】
Ｓ６０２で、仮想アドレス配置プラン生成部１０５が、二次記憶装置１０１からプログラムバイナリ（動的リンクライブラリ１０２または実行可能プログラム１０３）をひとつ読み込む。
【００６０】
Ｓ６０３で、仮想アドレス配置プラン生成部１０５が、Ｓ６０１で生成した仮想アドレス配置プラン１０４に、読み込んだプログラムバイナリのための仮想アドレス情報を追加する。ステップＳ６０３の詳細な説明は、図７を用いて後述する。
【００６１】
Ｓ６０４で、仮想アドレス配置プラン生成部１０５が、二次記憶装置１０１から取得する最後のプログラムバイナリなのかを判別する。もし最後のプログラムバイナリならＳ６０５に進む。もし最後のプログラムバイナリでないなら、次のプログラムバイナリを読み込む対象にして、Ｓ６０２に戻る。
【００６２】
Ｓ６０５で、仮想アドレス配置プラン生成部１０５が、二次記憶装置１０１に、ステップＳ６０１で生成しＳ６０３で配置情報が追加された仮想アドレス配置プラン１０４を、保存する。
【００６３】
Ｓ６０６で、配置プラン対応リロケータ１０６が、二次記憶装置１０１から、プログラムバイナリをひとつ読み込む。ここでは、このプログラムバイナリをＢとする。
【００６４】
Ｓ６０７で、配置プラン対応リロケータ１０６が、二次記憶装置１０１から読み込んだプログラムバイナリ（動的リンクライブラリ１０２または実行可能プログラム１０３）をリロケートする。ステップＳ６０７の詳細な説明は、図８を用いて後述する。
【００６５】
Ｓ６０８で、配置プラン対応リロケータ１０６が、二次記憶装置１０１から取得する最後のプログラムバイナリなのかを判別する。もし最後のプログラムバイナリなら処理が終了する。もし最後のプログラムバイナリでないなら、次のプログラムバイナリを読み込む対象にして、Ｓ６０６に戻る。
【００６６】
図７は、図６のステップＳ６０３の内容を示すフローチャートである。
【００６７】
Ｓ７０１で、仮想アドレス配置プラン生成部１０５が、ステップＳ６０２で取得したプログラムバイナリの情報を取得する。取得する情報は、そのプログラムバイナリが必要とする仮想アドレス領域の大きさである。
【００６８】
Ｓ７０２で、仮想アドレス配置プラン生成部１０５が、ステップＳ６０２で取得したプログラムバイナリが実行可能プログラムなのかどうかを判別する。取得したプログラムバイナリが実行可能プログラムの場合、ステップＳ７０３に進み、取得したプログラムバイナリが動的リンクライブラリの場合、ステップＳ７０４に進む。
【００６９】
Ｓ７０３で、仮想アドレス配置プラン生成部１０５が、ステップＳ６０２で取得した実行可能プログラムを配置する領域を決める。割り当てる領域の大きさは、ステップＳ７０１で必要とする仮想アドレス領域の大きさである。割り当てる領域の開始アドレスは、あらかじめ決められている実行可能プログラム用の開始アドレスである。
【００７０】
Ｓ７０４で、仮想アドレス配置プラン生成部１０５が、ステップＳ６０２で取得した動的リンクライブラリを配置する領域を決める。動的リンクライブラリを割り当てる領域は、仮想アドレス配置プラン１０４で未使用の領域である。
【００７１】
Ｓ７０５で、仮想アドレス配置プラン生成部１０５が、ステップＳ７０３またはステップＳ７０４で決めた、プログラムバイナリを割り当てる仮想アドレス領域を、Ｓ６０１で生成した仮想アドレス配置プラン１０４に書き込む。
【００７２】
図８は、図６のステップＳ６０７の内容を示すフローチャートである。
【００７３】
Ｓ８０１で、配置プラン対応リロケータ１０６が、Ｓ６０６で取得したプログラムバイナリＢが依存する動的リンクライブラリを全て取得する。特に、ここではＳ６０６で取得したプログラムバイナリが直接依存する動的リンクライブラリだけでなく、本ステップで取得された動的リンクライブラリが依存する動的リンクライブラリも、再帰的に取得する。
【００７４】
Ｓ８０２で、配置プラン対応リロケータ１０６が、プログラムバイナリＢのリロケート情報を取得する。
【００７５】
Ｓ８０３で、配置プラン対応リロケータ１０６が、Ｓ８０２で取得したリロケート情報から、ひとつの未解決参照項目を取得する。
【００７６】
Ｓ８０４で、配置プラン対応リロケータ１０６が、Ｓ８０３で取得した未解決参照項目を解決するリロケート処理を行なう。Ｓ８０４の詳細な説明は図９を用いて後述する。
【００７７】
Ｓ８０５で、配置プラン対応リロケータ１０６が、プログラムバイナリから取得する最後の未解決参照項目なのかを判別する。もし最後の未解決参照項目であれば終了し、そうでないなら次の未解決参照項目を対象にしてステップＳ８０３に戻る。
【００７８】
図９は、図８のステップＳ８０４の内容を示すフローチャートである。
【００７９】
Ｓ９０１で、配置プラン対応リロケータ１０６が、ステップＳ８０３で取得した未解決参照項目から、未解決参照の位置と、参照先のシンボルを取得する。ここで、取得された未解決参照の位置をＰ、参照先のシンボルをＳとする。
【００８０】
Ｓ９０２で、配置プラン対応リロケータ１０６が、ステップＳ８０１で取得した、プログラムバイナリＢが依存する動的リンクライブラリのうちの、ひとつの動的リンクライブラリを取得する。ここでは、この動的リンクライブラリをＬとする。
【００８１】
Ｓ９０３で、配置プラン対応リロケータ１０６が、動的リンクライブラリＬのシンボルテーブルを取得する。ここでは、このシンボルテーブルをＴとする。
【００８２】
Ｓ９０４で、配置プラン対応リロケータ１０６が、シンボルテーブルＴに、Ｓ９０１で取得したシンボルＳが含まれているかを判別する。もし含まれていれば、Ｓ９０４に進む。もし含まれていなければ、次の動的リンクライブラリを調べる対象にして、ステップＳ９０２に戻る。
【００８３】
Ｓ９０５で、配置プラン対応リロケータ１０６が、シンボルＳに対応するアドレスをシンボルテーブルＴから取得し、ステップＳ９０１で取得された未解決参照位置Ｐに書き込む。
【００８４】
図１０は、配置プラン対応ローダ１０７の処理ステップを示したフローチャートである。
【００８５】
配置プラン対応ローダ１０７は、実行中のプログラム等から、特定の実行可能プログラムまたは動的リンクライブラリをロードする要求を受けて起動される。
【００８６】
配置プラン対応ローダ１０７は、配置プラン対応リロケータ１０６がリロケートしたプログラムバイナリ（実行可能プログラム１０３または動的リンクライブラリ１０２）を二次記憶装置１０１から読み込み、ロード対象のプログラムバイナリと同じプログラムバイナリが既にロードされている場合はそのコードを共有し、そうでない場合は、仮想アドレス配置プラン生成部１０５が生成した仮想アドレス配置プラン１０４に従った仮想アドレス上での位置に、プログラムバイナリをロードする。以下で詳細なステップを説明する。
【００８７】
配置プラン対応ローダ１０７は、プログラムバイナリを受け取って起動される。ここでは、このプログラムバイナリをＢとする。
【００８８】
ステップＳ１００１で、配置プラン対応ローダ１０７は、プログラムバイナリＢが既にロードされているかどうかを判別する。既にロードされている場合、ステップＳ１００３に進む。未だにロードされていない場合、ステップＳ１００２に進む。
【００８９】
ステップＳ１００２で、配置プラン対応ローダ１０７は、プログラムバイナリＢのテキストセクションをロードする。このとき、ロードするアドレスは仮想アドレス配置プラン１０４に従う。この後、ステップＳ１００４に進む。
【００９０】
ステップＳ１００３で、配置プラン対応ローダ１０７は、既に別のプロセス等によってロードされているプログラムバイナリＢのテキストセクションを共有する。仮想メモリ機構を備えたコンピュータシステムでは、仮想アドレス領域と特定の物理アドレス領域を対応づける事ができ、仮想アドレス領域にアクセスすると実際のアクセスが物理アドレス領域に対して行なわれる。あるメモリ領域を共有するとき、それぞれの仮想アドレス領域が同じ物理アドレス領域に対応づける。この後、ステップＳ１００４に進む。
【００９１】
ステップＳ１００４で、配置プラン対応ローダ１０７は、プログラムバイナリのデータセクションをロードする。このとき、動的リンクライブラリをロードするアドレスは、仮想アドレス配置プランに従う。
【００９２】
テキスト領域とは異なり、データ領域とｂｓｓ領域は、それぞれのプロセスが固有の情報を書き込む事ができる。したがって、一般に、データ領域やｂｓｓ領域はプロセス間で共有する事ができない。なお、データ領域であっても、書き込みが行なわれるまでは共有する事が可能であるため、書き込みが行なわれるまで、複数のプロセスの間でデータ領域を共有しても良い。
【００９３】
ステップＳ１００５で、配置プラン対応ローダ１０７は、プログラムバイナリＢのｂｓｓセクションをロードする。このとき、ｂｓｓセクションをロードするアドレスは、仮想アドレス配置プラン１０４に従う。
【００９４】
ステップＳ１００６で、配置プラン対応ローダ１０７は、プログラムバイナリＢが依存する動的リンクライブラリを全て再帰的にロードする。
【００９５】
本実施の形態にかかる動的リンクライブラリ処理装置を用いると、それぞれの動的リンクライブラリがロードされる仮想アドレスが常に一定に定まる。したがって、ある動的リンクライブラリから別の動的リンクライブラリの情報を参照する場合、参照先の情報が置かれている仮想アドレス上での位置が確定する。この事から、それぞれの動的リンクライブラリのうちの未解決の参照を事前に解決しておく事ができる。
【００９６】
例えば、図５の仮想アドレス空間５０１、５０２、５０３のいずれでも、動的リンクライブラリＬ＃１は、アドレスａ＃４からアドレスａ＃５に配置される。したがって、動的リンクライブラリＬ＃１内にある関数やデータなどが置かれているアドレスは常に一定である。したがって、ある別のプログラムバイナリから、動的リンクライブラリＬ＃１内の関数やデータへのアドレス参照があったとき、その関数やデータのアドレスは事前に決定できる。この事から、プログラムバイナリ間でのアドレス参照であっても、事前にリロケートする事ができる。
【００９７】
また、それぞれの動的リンクライブラリがロードされる仮想アドレスが常に一定である事から、ＧＯＴなどのバイナリインタフェースを経由する事なく、異なる動的リンクライブラリにアクセスするような、位置に依存するコードを使用する事ができる。位置依存コードは、ＧＯＴを使用する位置独立コードよりも実行効率が高い。
【００９８】
以上により、本実施の形態にかかる動的リンクライブラリ処理装置を用いると、仮想メモリ機構を使用するマルチプロセス環境においてライブラリのコードを複数の仮想アドレス空間で共有する事ができ、かつ、仮想アドレスの位置に依存するコードを用いる事ができる。ライブラリのコードは共有されるため、メモリ使用効率が良い。また、アドレスの位置に依存するコードであるため、アドレス参照で直接参照を使用する事ができ、実行効率が向上する。
【００９９】
従来の静的リンク方式でも、従来のＧＯＴを用いた動的リンク方式でも、プログラムを実行するために、それぞれのプログラムバイナリの配置プランを生成する。
【０１００】
従来の静的リンク方式では、あるアドレス領域にプログラムバイナリを割り当てると、その領域に他のプログラムバイナリを重複して割り当てる事ができない。また、静的リンク方式では、ライブラリのコードは実行可能プログラムにコピーされるため、異なるプログラム間で共有する事ができない。本実施の形態の動的リンクライブラリ処理装置では、実行可能プログラムを割り当てる仮想アドレス領域は重複させる事ができる。また、ライブラリは動的リンクライブラリとして異なるプログラム間で共有する事ができる。例えば、図５の仮想アドレス空間５０１と、５０２を考える。実行可能プログラムＰ＃１とＰ＃２は同じ仮想アドレス領域に重複して割り当てられている。また、動的リンクライブラリＬ＃１は実行可能プログラムＰ＃１およびＰ＃２から共有される。
【０１０１】
従来のＧＯＴ等を用いた動的リンク方式では、動的リンクライブラリが配置される仮想アドレス領域がプログラムごとに異なっていた。動的リンクライブラリが異なる仮想アドレス領域に配置されるときに、動的リンクライブラリが位置依存のコードを含むと、プログラム間で動的リンクライブラリのコードを共有できなくなってしまう。本実施の形態の動的リンクライブラリ装置を用いた方式では、全てのプログラムで共通する仮想アドレス配置プランを使用する事により、ある動的リンクライブラリがロードされる仮想アドレス領域は、どのプログラムでも共通となる。したがって、それぞれの動的リンクライブラリがロードされる位置が常に決まっているため、位置依存コードを使用しても、動的リンクライブラリのコードをプログラム間で共有する事ができる。
【０１０２】
（実施の形態２）
図１１は、本発明の実施の形態２における動的リンクライブラリ処理装置の構成を示す図である。図１１において、図１と同じ構成については同じ符号を用い、説明を省略する。
【０１０３】
ストリッパ１１０１は、配置プラン対応リロケータ１０６によってリロケートされた動的リンクライブラリ１０２または実行可能プログラム１０３から、リロケートに必要なシンボル情報およびリロケート情報を削除するストリッパである。
【０１０４】
図２のリロケート情報２０５およびシンボルテーブル２０６は、リロケートに必要な情報である。これらの情報は、リロケートが完了すると不要になる事がある。ストリッパ１１０１は、これらの不要なものを削除し、プログラムバイナリのサイズを縮小させ、効率化を図る。
【０１０５】
図１２は、ストリッパ１１０１が、プログラムバイナリのリロケート情報２０５およびシンボルテーブル２０６を削除する処理ステップを示したフローチャートである。
【０１０６】
Ｓ１２０１で、ストリッパ１１０１が、二次記憶装置１０１から、プログラムバイナリ（実行可能プログラム１０３または動的リンクライブラリ１０２）をひとつ取得する。ここでは、取得したプログラムバイナリをＢとする。
【０１０７】
Ｓ１２０２で、ストリッパ１１０１が、プログラムバイナリＢの中にあるリロケート情報２０５を取得し、これを削除する。
【０１０８】
Ｓ１２０３で、ストリッパ１１０１が、プログラムバイナリＢの中にあるシンボルテーブル２０６を取得し、これを削除する。
【０１０９】
Ｓ１２０４で、ストリッパ１１０１が、リロケート情報２０５およびシンボルテーブル２０６が削除されたプログラムバイナリを、二次記憶装置１０１に保存する。
【０１１０】
Ｓ１２０５で、ストリッパ１１０１は、プログラムバイナリＢが取得できる最後のプログラムバイナリかどうかを判別する。最後のプログラムバイナリの場合、処理は終了する。最後のプログラムバイナリでない場合、次のプログラムバイナリを処理対象にしてＳ１２０１に戻る。
【０１１１】
従来のＧＯＴを用いた動的リンクライブラリ技術の場合、動的リンクライブラリのロード時にＧＯＴを生成するために、シンボルテーブルやリロケート情報を動的リンクライブラリ内に残しておく必要があった。本実施の形態にかかる動的リンクライブラリ処理装置を用いると、実行可能プログラムや動的リンクライブラリのリロケート処理が完了し、リロケート情報などがなくてもプログラムが適切にロードできるようになる。したがって、本実施の形態にかかる動的リンクライブラリ処理装置では、不要なリロケート情報やシンボルテーブルを削除し、プログラムバイナリのサイズを縮小し、効率化を図る事ができる。
【０１１２】
（実施の形態３）
図１３は、本発明の実施の形態３における動的リンクライブラリ処理装置の構成を示す図である。図１３において、図１と同じ構成については同じ符号を用い、説明を省略する。
【０１１３】
１３０１は、仮想アドレス領域の確保と解放を行なうメモリマネージャであり、実行中のプログラムから仮想アドレス領域を確保する要求を受けて処理を開始する。
【０１１４】
確保済みメモリ領域テーブル１３０２は、メモリマネージャ１３０１が、確保した領域を記憶しておくために使用するテーブルである。確保済みメモリ領域テーブル１３０２は初期状態では空の状態である。
【０１１５】
メモリマネージャ１３０１は、実行中のプログラムから仮想アドレス領域の確保要求を受けたとき、仮想アドレス配置プラン１０４を参照し、仮想アドレス配置プラン１０４で割り当てられていない仮想アドレス領域を使用しないよう、メモリ確保を行なう。
【０１１６】
図１４は、メモリマネージャ１３０１がメモリを確保するときの処理ステップを示したフローチャートである。
【０１１７】
ステップＳ１４０１で、メモリマネージャ１３０１は、実行中のプログラムから仮想アドレスの領域を確保する要求を受けて処理を開始する。確保要求では、確保するメモリの容量が指定される。
【０１１８】
ステップＳ１４０２で、メモリマネージャ１３０１は、二次記憶装置１０１から仮想アドレス配置プラン１０４を読み込み、仮想アドレス配置プラン１０４でプログラムバイナリ用に割り当てられている仮想アドレス領域を取得する。
【０１１９】
ステップＳ１４０３で、メモリメネージャ１３０１は、確保済みメモリ領域テーブル１３０２を調べ、割り当てられている仮想アドレス領域を取得する。
【０１２０】
ステップＳ１４０４で、メモリメネージャ１３０１は、ステップＳ１４０２およびステップＳ１４０３の両方で割り当てられていない仮想アドレス領域を確保し、確保済みメモリ領域テーブル１３０２に割り当てた領域として書き込む。
【０１２１】
ステップＳ１４０５で、メモリマネージャ１３０１は、ステップＳ１４０４で確保した仮想アドレス領域をプログラムに通知して終了する。
【０１２２】
一般に、あるプログラムが実行するとき、全ての動的リンクライブラリは使用されず、一部の動的リンクライブラリのみが使用される。また、あるプログラムが使用する動的リンクライブラリであっても、プログラムの起動時にロードせず、実行中に必要に応じてその場でロードする事も可能である。したがって、あるプログラムが実行するとき、仮想アドレス配置プランに含まれている全ての仮想アドレス領域が使用されるわけではなく、実行中のプログラムが使用していない動的リンクライブラリのための仮想アドレス領域は未使用のまま残っている事になる。
【０１２３】
動的リンクライブラリは実行時にリンクする事が可能であるため、プログラムの処理が進んだ後に動的リンクライブラリが使用されるようになる可能性がある。動的リンクライブラリが使用されるようになったときに、その動的リンクライブラリのための仮想アドレス領域が他の用途で使用されていると、仮想アドレス配置プランに示されている位置に動的リンクライブラリを配置できない。そこで、本実施の形態のメモリメネージャは、メモリ確保要求を受け取ったときに、仮想アドレス配置プランに示されていない仮想アドレス領域を確保して割り当てる。この結果、仮想アドレス配置プランで割り当てられている仮想アドレス領域が、他の用途で使用される事がなく、動的リンクライブラリを適切な位置にロードする事を保証できる。
【産業上の利用可能性】
【０１２４】
本発明にかかる動的リンクライブラリ処理装置は、仮想メモリ機構を用いるコンピュータシステムにおいて、位置依存コードを用いても動的リンクライブラリのコードの共有を可能とする。動的リンクライブラリのコードが複数のプロセスで共有されるため、メモリ消費量が少なく、また実行効率の高い位置依存コードを用いる事ができるため、プログラムの実行効率も向上し、有用である。
【図面の簡単な説明】
【０１２５】
【図１】本発明の実施の形態１における動的リンクライブラリ処理装置の構成を示す図である。
【図２】ひとつの実行可能プログラムまたは動的リンクライブラリに含まれる情報を示す図である。
【図３】具体例を用いて、リロケート情報２０５やシンボルテーブル２０６の情報を説明した図である。
【図４】仮想アドレス配置プラン１０４の内容を示した一例である。
【図５】前記仮想アドレス配置プラン４０１に従って、それぞれの実行可能プログラムが実行されたときの、仮想アドレス上でのプログラムバイナリの配置の図である。
【図６】図１の仮想アドレス配置プラン生成部１０５と配置プラン対応リロケータ１０６による、プログラムバイナリのリロケート処理までのステップを示したフローチャートである。
【図７】図６のステップＳ６０３の内容を示すフローチャートである。
【図８】図６のステップＳ６０７の内容を示すフローチャートである。
【図９】図８のステップＳ８０４の内容を示すフローチャートである。
【図１０】配置プラン対応ローダ１０７の処理ステップを示したフローチャートである。
【図１１】本発明の実施の形態２における動的リンクライブラリ処理装置の構成を示す図である。
【図１２】ストリッパ１１０１が、プログラムバイナリのリロケート情報２０５およびシンボルテーブル２０６を削除する処理ステップを示したフローチャートである。
【図１３】本発明の実施の形態３における動的リンクライブラリ処理装置の構成を示す図である。
【図１４】メモリマネージャ１３０１がメモリを確保するときの処理ステップを示したフローチャートである。
【符号の説明】
【０１２６】
１０１  二次記憶装置
１０２  動的リンクライブラリ
１０３  実行可能プログラム
１０４  仮想アドレス配置プラン
１０５  仮想アドレス配置プラン生成部
１０６  配置プラン対応リロケータ
１０７  配置プラン対応ローダ
１０８  メモリ
２０１  ヘッダ情報
２０２  テキストセクション
２０３  データセクション
２０４  ｂｓｓセクション
２０５  リロケート情報
２０６  シンボルテーブル
３０１  動的リンクライブラリ
３０２  動的リンクライブラリ
３０３  テキストセクション
３０４  テキストセクション
３０５  未解決の参照
３０６  関数のテキスト
３０７  リロケート情報
３０８  リロケート情報
３０９  シンボルテーブル
３１０  シンボル情報
４０１  仮想アドレス配置プラン
５０１  仮想アドレス空間
５０２  仮想アドレス空間
５０３  仮想アドレス空間
１１０１  ストリッパ
１３０１  メモリマネージャ
１３０２  確保済みメモリ領域テーブル
【図１】
2006048431.tif 000003
【図２】
2006048431.tif 000004
【図３】
2006048431.tif 000005
【図４】
2006048431.tif 000006
【図５】
2006048431.tif 000007
【図６】
2006048431.tif 000008
【図７】
2006048431.tif 000009
【図８】
2006048431.tif 000010
【図９】
2006048431.tif 000011
【図１０】
2006048431.tif 000012
【図１１】
2006048431.tif 000013
【図１２】
2006048431.tif 000014
【図１３】
2006048431.tif 000015
【図１４】
2006048431.tif 000016