ld + --library-pathを使ってプログラムを実行することとpatchelfを使ってローダを変更することの違いは何ですか?
これを説明するために、以下は現状のまま実行されないバイナリです。それはおそらく、最新バージョンのライブラリがないからです。
$ ~/DOWNLOADS/APPS/magick
/tmp/.mount_magickXiWzgy/usr/bin/magick: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.29' not found (required by /tmp/.mount_magickXiWzgy/usr/lib/libMagickCore-7.Q16HDRI.so.10)
/tmp/.mount_magickXiWzgy/usr/bin/magick: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.25' not found (required by /tmp/.mount_magickXiWzgy/usr/lib/libMagickCore-7.Q16HDRI.so.10)
/tmp/.mount_magickXiWzgy/usr/bin/magick: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.29' not found (required by /tmp/.mount_magickXiWzgy/usr/lib/liblcms2.so.2)
...
$
私は3つの異なるローダーとライブラリパス(core18、core20、およびcore22)を使って実行しました。 ELFファイルのABIバージョンが無効であるたびに。
$ /snap/core18/current/lib64/ld-linux-x86-64.so.2 --library-path /snap/core18/current/usr/lib/x86_64-linux-gnu/ ~/DOWNLOADS/APPS/magick
/home/ychaouche/DOWNLOADS/APPS/magick: error while loading shared libraries: /home/ychaouche/DOWNLOADS/APPS/magick: ELF file ABI version invalid
$ /snap/core20/current/lib64/ld-linux-x86-64.so.2 --library-path /snap/core20/current/usr/lib/x86_64-linux-gnu/ ~/DOWNLOADS/APPS/magick
/home/ychaouche/DOWNLOADS/APPS/magick: error while loading shared libraries: /home/ychaouche/DOWNLOADS/APPS/magick: ELF file ABI version invalid
$ /snap/core22/current/lib64/ld-linux-x86-64.so.2 --library-path /snap/core22/current/usr/lib/x86_64-linux-gnu/ ~/DOWNLOADS/APPS/magick
/home/ychaouche/DOWNLOADS/APPS/magick: error while loading shared libraries: /home/ychaouche/DOWNLOADS/APPS/magick: ELF file ABI version invalid
$
その後、patchelfを使用してバイナリから直接ローダーとrpathを変更して実行しようとすると、次
の分割エラーが発生します。
$ patchelf --set-interpreter /snap/core18/current/lib64/ld-linux-x86-64.so.2 --set-rpath /snap/core18/current/usr/lib/x86_64-linux-gnu/ magick
$ ./magick
Segmentation fault
$ ldd magick
not a dynamic executable
$
readelfは読み取ることができますが、lddはそれを動的実行可能ファイルとして認識しません。
@user10489が要求したldd出力。
$ file DOWNLOADS/APPS/magick
DOWNLOADS/APPS/magick: ELF 64-bit LSB executable, x86-64, version 1, dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=9fdbc145689e0fb79cb7291203431012ae8e1911, stripped
$
私の質問は、コマンドラインでローダを指定したときにELFファイルABIのバージョンが無効で、バイナリ内でローダ(およびrpath)を変更すると分割エラーが発生するのはなぜですか?
答え1
ライブラリのバージョン管理の全体的な目的は、ライブラリのABIが変更されたときの問題を回避し、アプリケーションが期待するABIと一致するライブラリを見つけることを可能にすることです。
ライブラリのバージョンを強制することで、実行可能ファイルに期待されたものとは異なるABIを使用して関数を呼び出すように強制しました。その結果、エラーで失敗し、最悪の場合、予測不能な方法で競合が発生します。
特定のライブラリでプログラムを使用するには、そのライブラリのコンパイルされたバージョンを探すか、ソースから再コンパイルする必要があります(APIが一致する可能性があると仮定)。