Linux、GNU GCC、ld、バージョンスクリプト、ELFバイナリ形式 - どのように機能しますか?

Linux、GNU GCC、ld、バージョンスクリプト、ELFバイナリ形式 - どのように機能しますか?

私はLinuxのライブラリのバージョン管理とその両方をどのように機能させるかについて詳しく学びたいと思います。コンテキストは次のとおりです。

libsome1.so- などの同じインターフェイスセットを公開する2つのバージョンの動的ライブラリがありますlibsome2.so

- に接続されたアプリケーションlibsome1.so

- アプリケーションはlibdl.so他のモジュール(たとえば)を動的にロードするために使用されますlibmagic.so

- 今はlibmagic.so抜けましたlibsome2.so。明らかに、実行時に隠されたリンカスクリプトのインターフェイスlibmagic.soへのすべての呼び出しは。これは、マクロ値と比較して返された値を確認することで確認できます。libsome2.solibsome1.solibVersion()LIB_VERSION

- だから、次のように定義されエクスポートされたlibmagic.so3以外のすべてのシンボルを隠すリンカスクリプトを使用してコンパイルしてリンクしようとしました。libmagic.soこれは機能します...または少なくとも値libVersion()と一致します(そして1の代わりにバージョン2を報告します)。LIB_VERSION

- ただし、特定のデータ構造がディスクにシリアル化されると、いくつかの破損が検出されました。アプリケーションディレクトリから指すlibsome1.soソフトリンクを削除して作成すると、すべてlibsome2.soが期待どおりに機能し、同じ破損は発生しません。

私はこれがランタイムリンカーのシンボル解釈に矛盾があるために起こり得るとは思わないかもしれません。私はlibsome2.soすべてのシンボルがソートされるように接続するなど、いくつかの試みをしました。 (コマンドはまだシンボルを代わりにリストしているsymbol@@VER_2ので、これについてはまだ混乱しています。)...何も動作しないようです!助ける! ! ! ! ! !nm -CD libsome2.sosymbolsymbol@@VER_2

答え1

あなたの質問に対する正確な答えではありませんが...

まず、ELFは、Linuxで実行可能ファイル(プログラム)、共有ライブラリ、オブジェクトファイル(ソフトウェアをコンパイルするときに見つかった中間ファイル)に使用される仕様です。オブジェクトファイルは.oで終わり、共有ライブラリは.soで終わり、その後にピリオドで区切られた0個以上の数字が続き、実行可能ファイルには通常拡張子がありません。

一般に、共有ライブラリの命名には3つの形式があり、そのうちの最初のものは単に.soで終わります。たとえば、readline というライブラリは libreadline.so というファイルに保存され、通常 /lib、/usr/lib、/usr/local/lib のいずれかにあります。このファイルは、-lreadlineなどのオプションを使用してソフトウェアをコンパイルするときに見つかります。 -l コンパイラに次のライブラリへのリンクを指示します。ライブラリは随時変更されるため、古くなる可能性があるため、ライブラリにはSONAMEというエントリが含まれています。 readlineのSONAMEは、libreadlineの2番目のメジャーバージョンであるlibreadline.so.2に似ています。ソフトウェアを再コンパイルする必要がないreadlineの互換性のあるマイナーバージョンがたくさんあるかもしれません。 readlineのマイナーバージョン名はlibreadline.so.2.14です。通常、libreadline.soはreadlineの最新のメジャーバージョン(この場合libreadline.so.2)へのシンボリックリンクです。 libreadline.so.2は、実際に使用されるファイルlibreadline.so.2.14へのシンボリックリンクでもあります。

ライブラリの SONAME はライブラリファイル自体に含まれています。 libreadline.so.2.14 ファイル内のどこかに libreadline.so.2 文字列があります。プログラムがreadlineを使用してコンパイルおよびリンクされたら、libreadline.soファイルを見つけて、ここに含まれているSONAMEを読み込みます。後でプログラムが実際に実行されると、libreadline.soだけでなくlibreadline.so.2もロードされます。これは、最初に接続されたときに読み取ったSONAMEであるためです。これにより、システムは互換性のない複数のバージョンのreadlineをインストールでき、各プログラムはそれに関連付けられている適切なメジャーバージョンをロードします。また、readlineを2.17にアップグレードすると、既存のライブラリと一緒にlibreadline.so.2.17をインストールすることができました。使用すると、新しいマイナーアップデートが表示されます。

関連情報