6

Linux関連の経験があまりないため、質問が正確でない場合はお詫び申し上げます。現在、Linux をゼロから構築しています (ほとんどの場合、linuxfromscratch.org バージョン 7.3 のガイドに従っています)。次の問題に遭遇しました。実行可能ファイルをビルドすると、ELF インタープリターと呼ばれるものへのハードコードされたパスが取得されます。

readelf -l program

のようなものを示しています

[Requesting program interpreter: /lib/ld-linux.so.2]

このライブラリ ld-linux-so.2 が glibc の一部であることを突き止めました。この動作にはあまり満足していません。バイナリが非常に移植しにくくなるためです。/lib/ld-linux.so.2 の場所を変更すると、実行可能ファイルが機能しなくなり、見つかった唯一の「修正」は patchelf を使用することです。 NixOS のユーティリティを使用して、ハードコードされたパスを別のハードコードされたパスに変更します。このため、ld ライブラリの静的バージョンにリンクしたいのですが、そのようなものは生成されません。これが私の質問です。glibc をビルドして ld-linux.so.2 の静的バージョンを生成し、後で実行可能ファイルにリンクする方法を教えてください。この ld ライブラリが何をするのか完全には理解していませんが、これは他の動的ライブラリ (または少なくとも glibc.so) をロードする部分であると思います。実行可能ファイルを動的にリンクしたいのですが、しかし、動的リンカー自体を静的に組み込みたいので、ハードコーディングされたパスに依存しません。または、LD_LIBRARY_PATH、おそらくLD_INTERPRETER_PATHに似た環境変数を使用して、インタープリターへのパスを設定できるようにしたいと考えています。目標は、ディレクトリ構造に関係なく、同じ ABI を使用して任意のプラットフォームで実行されるポータブル バイナリを生成できるようにすることです。

関連する可能性のある背景: Slackware 14 x86 を使用して i686 コンパイラ ツールチェーンを構築しているため、全体としてはすべて x86 のホストとターゲットです。glibc 2.17 と gcc 4.7.x を使用しています。

4

2 に答える 2

1

私は同じ問題に遭遇しました。私の場合、システムにインストールされているものとは異なる GLIBC でアプリケーションをバンドルしたいと考えています。ld-linux.so は GLIBC のバージョンと一致する必要があるため、単純にアプリケーションを対応する GLIBC でデプロイすることはできません。問題は、必要な GLIBC バージョンがない古いインストールでアプリケーションを実行できないことです。

ローダー インタープリターへのパスは、--dynamic-linker=/path/to/interp で変更できます。ただし、これはコンパイル時に設定する必要があるため、アプリケーションをその場所にインストールする必要があります (または、少なくとも、GLIBC に対応する ld-linux.so をその場所にデプロイする必要があります。 xcopy の展開。

したがって、必要なのは -rpath オプションが処理できるものと同等の $ORIGIN オプションです。これにより、完全に動的な展開が可能になります。

(実行時に) 動的なインタープリター パスがない場合、次の 2 つのオプションがあります。

a) patchelf を使用して、実行可能ファイルが起動される前にパスを変更します。b) 実行可能ファイルを引数として ld-linux.so を直接呼び出します。

両方のオプションは、実行可能ファイル自体のコンパイル済み $ORIGIN パスほど「統合」されていません。

于 2016-09-21T03:39:10.317 に答える