- x86_64カーネルサポートでコンパイルされている場合、x86_64カーネルを使用してx86_32プログラムを実行できることはよく知られています。ただし、動的リンカーは32ビットプログラム用にプリロードされた別々のライブラリセットを定義する方法を提供していないため、これらのプログラムを実行するたびにx86_64プリロードを実行すると、次のエラーメッセージが表示されます。
ERROR: ld.so: object '… … …' from /etc/ld.so.preload cannot be preloaded (wrong ELF class: ELFCLASS64): ignored.
あらかじめロードするために同じx86_32ライブラリのリストをそこに入れると正常に動作しますが、すべての純粋なx86_64の実行も文句を言い始めます。
明らかに最善のアプローチは、別のファイルからプリロードをサポートするように動的ローダーを変更することですが、いくら言っても時間がかかるプロセスです。きれいな解決策を考えることができますか?
これで必要なファイルを自分でロードできることを考えていますがmulti-class-pre-load.so
、私が見るとELFには「マルチクラス」サポートはありません。
答え1
ld.so.preloadでは、パスに明示的な「lib」または「lib64」ではなく「$LIB」を指定しようとしています。したがって、Redhatスタイルのディストリビューションでは、32ビットプロセスの場合、/usr/alternates/$LIB/libfoo.soは/usr/alternates/lib/libfoo.soと/usr/alternates/lib64/になります。 64 ビットプロセスの場合は libfoo.so" usr/alternates/x86_64-linux-" になります。 gnu/libfoo.so" です。その後、両方のアーキテクチャのライブラリでツリーを埋める必要があります。
「rpathトークンの拡張」を参照してください。ld.so(8) のマニュアルページこれについて詳しく学んでください。
ただし、ロードを変更したいバイナリをコンパイルする場合は、ライブラリを事前ロードするよりも設定を介してパスを変更する方が良いかもしれません。DT_RUNPATHリンク行(同じ「$LIB」スタイル・パスを使用して、システムのデフォルトよりもライブラリーの場所を優先するようにバイナリを構成します。
あるいは、他の人が指摘したように、ELFファイルを編集して、コンパイルされていないバイナリにDT_RUNPATHを設定することもできます。
以下はx86_64 Centos 6.5システムに適用されます。
cd /tmp
mkdir lib lib64
wget http://carrera.databits.net/~ksb/msrc/local/lib/snoopy/snoopy.h
wget http://carrera.databits.net/~ksb/msrc/local/lib/snoopy/snoopy.c
gcc -m64 -shared -fPIC -ldl snoopy.c -o /tmp/lib64/snoopy.so
gcc -m32 -shared -fPIC -ldl snoopy.c -o /tmp/lib/snoopy.so
cat > true.c <<EOF
int main(void)
{ return 0; }
EOF
gcc -m64 true.c -o true64
gcc -m32 true.c -o true32
sudo bash -c "echo '/tmp/\$LIB/snoopy.so' > /etc/ld.so.preload"
strace -fo /tmp/strace64.out /tmp/true64
strace -fo /tmp/strace32.out /tmp/true32
sudo rm /etc/ld.so.preload"
strace出力では、strace64.outには次のものが含まれます。
open("/tmp/lib64/snoopy.so", O_RDONLY) = 3
strace32.out には以下が含まれます。
open("/tmp/lib/snoopy.so", O_RDONLY) = 3
ld.so.preloadの内容は次のとおりです。
/tmp/$LIB/snoopy.so
答え2
プリロードは意図されていません。ノーマルシステム運用通常、使用するライブラリに実際にリンクする必要があります。
複数のアーキテクチャでプログラムを実行するときにプリロードを必要とする少数の人々は、無害なエラーメッセージに気を配らないと考えられています。
あるいは、プログラムが他のアーキテクチャの他のプログラムを実行していない限り、LD_PRELOAD
不正なライブラリー部分を持つプログラムを使用する方が良いかもしれません。
ただし、実際には編集段階でELFファイルにリストされているライブラリを変更する方が良いですが、後でELFを編集するためのツールもあります。
(注:最初はあなたの質問がx64_32に関するものだと思いました。まったく異なり、いくつかの興味深いバグがあります)