2019年7月30日
キーワード:動的コンパイル、静的コンパイル、readelfが
入門
Linuxの実行可能プログラムは、2つのタイプに分けることができます。
図1に示すように、コンパイルされた動的。
2は、静的にコンパイル。
だから、2つの違いは何ですか?
動的コンパイル
必要な参照は、外部ライブラリまたは外部実行可能プログラム、などの外部インターフェイスは、ライブラリに対応するリンクのみを保存する場合には、コンパイル時に動的コンパイラプログラムのソースコードを指します。その後のアプリケーション・プログラミング・インタフェース・ライブラリまたは実行時に必要なライブラリー・パスを指定したシステムを探しに行きます。
コンパイル時に、自身のソースコードのパッケージのみで、このモードでは、それらの利点は、製品のコンパクトでコンパイル、及び外部インターフェースをロードしながら無駄なメモリ空間が存在しないであろう。欠点は、環境の保全への依存度実行することです。任意の外部プログラムに必要なプログラミング・インタフェースが存在しない場合にシステムが実行しないプログラムが発生します。
静的にコンパイル
そして、比較的動的コンパイルの種類は、それは、外部の独自のソースコードコンパイラパッケージに加えて、あなたは外部ライブラリのインタフェースを参照したい場合ことを意味するだけでなく、コンパイル時に一緒にパッケージされています。私は、動的コンパイル型を使用し、私はちょうどあなたがそれの上にある場所を覚えておく必要がある、と私は静的コンパイルを使用したいされますされ、あなたはいつも私と一緒に滞在し、私の側に来ています。
そのため、プログラムの静的変換は、その体積が比較的大きくなりますが、それは実行しているデータベース環境に依存しません。また、メモリの無駄が発生することがあり欠点があります。各実行可能プログラムを保持するためのライブラリに依存しているため内部でのコピーがメモリにロードするために、これらのライブラリが一緒にパッケージされている使用する必要があります。複数の静的コンパイルされたプログラムは、同じ依存関係が含まれていますがある場合は、その状況は、ライブラリが同じメモリフットプリントの複数のコピーを持っている原因となります。
コンパイラの種類を伝える方法
私たちは、実行可能プログラムへのLinux readelfがコマンドは動的または静的コンパイラベースのコンパイルされて区別することができます。
readelfが-l XXX
静的コンパイラベースのプログラムの場合は、以下の情報のようなものを見ることができます
ELF ファイルタイプは、EXEC(実行可能ファイル) エントリポイント0x8b28 あり6つのオフセット開始プログラムヘッダ、52 :プログラムヘッダ VirtAddr PhysAddr FileSiz MemSiz FLG整列オフセット型 EXIDXを 0x077610 0x0007f610 0x0007f610 0x00768 0x00768 Rの を0x4の LOAD 0x000000を 0x00008000 0x00008000 0x77d7c 0x77d7cの REには0x8000の 負荷を 0x077d7c 0x00087d7c 0x00087d7c 0x00c58 0x020dcRW は0x8000 NOTE 0x0000f4 0x000080f4 0x000080f4 0x00020 0x00020 Rの 0x4の TLS 0x077d7c 0x00087d7c 0x00087d7c 0x00010 0x00028 Rは、 0x4の GNU_STACK 0x000000を 0x00000000に 0x00000000の 0x00000 0x00000 RW を0x4の セグメントへのマッピングセクション: セグメントセクション... 00 .ARM.exidx 01 .note.ABI-タグ.INITの.text __libc_freeres_fn __libc_thread_freeres_fn .finiに.rodata __libc_subfreeres __libc_atexit __libc_thread_subfreeres .ARM.extab .ARM.exidx .eh_frame 02 .tdata .init_array .fini_array .jcr .data.rel.ro .gotを.dataセクション.bssの__libc_freeres_ptrs 03 。注。 ABI- タグ 04 .tdata .tbss 05
何も非常に特別な場所。
それは動的にコンパイルタイプである場合は、次の情報のようなものを見ることができます
ELF ファイルタイプは、EXEC(実行可能ファイル) エントリポイント0xe5d0 あり8つのオフセット開始プログラムヘッダ、52 :プログラムヘッダ VirtAddr PhysAddr FileSiz MemSiz FLG整列オフセット型 EXIDXを 0x00bd50 0x00013d50 0x00013d50 0x00008 0x00008 Rの を0x4の PHDR 0x000034 0x00008034 0x00008034 0x00100 0x00100のRE を0x4の INTERPを 0x000134 0x00008134 0x00008134 0x00013 0x00013Rの 0x1の プログラムインタプリタを要求[: / libに/ LD -linux.so。3 ] LOAD 0x000000を 0x00008000 0x00008000 0x0bd5c 0x0bd5c RE は0x8000の LOAD 0x00c000 0x0001c000 0x0001c000 0x00670 0x006b4 RW 0x8000の DYNAMIC 0x00c01cの 0x0001c01c 0x0001c01c 0x00130 0x00130 RWの を0x4の 注 0x000148 0x00008148 0x00008148 0x00020 0x00020 R 0x4の GNU_STACK 0x000000を 0x00000000に 0x00000000の 0x00000 0x00000 RW を0x4の セグメントへのマッピングセクション: セグメントセクション... 00 .ARM.exidx 01 02 .interp 03 .interp .note.ABI- タグ.hash .dynsym .dynstr .gnu.version .gnu。 version_r .rel.dyn .rel.plt .INIT .PLTの.text .finiに.rodata .ARM.exidx .eh_frame 04 .init_array .fini_array .jcrする。dynamic .gotを.dataセクション.bssの 05 する。dynamic 06 .note.ABI- タグ 07
あなたは大胆な赤のフィールドに上記を参照することができます。動的コンパイラベースのプログラムは、readelfが-lコマンドを実行している、それはINTERPセグメントのよりになります。このフィールドはで説明されて、この手順の負荷条件。ここでは、あなたが読んで、プログラムをロードするには、プレゼンス/lib/ld-linux.so.3ライブラリを持っている必要があります。
システムはこの環境/lib/ld-linux.so.3を持っていない場合は、このプログラムの実装ではそのようなファイルやディレクトリのエラーが報告されません。
ダイナミック頼るコンパイル問い合わせ
実行可能ファイルが静的にコンパイルされている場合は、直接、うまく実行し、ああ、非常に簡単です。
それが動的にコンパイルされている場合でも、時にはプログラムはクーファ外のいくつかの強さに依存する必要があります。幸いなことに、我々はまた、ライブラリに依存readelfがコマンドでそれを見ることができます。
readelfが-d XXX
動的コンパイラベースのプログラムの場合は、以下の種類の情報と同様に表示されます。
オフセット時の動的セクション0xc01cが含まれている33個のエントリを: タグタイプの名前 / 値 は0x00000001(必要な)共有ライブラリ:[libqte.so。3 ] 0x00000001の(必要な)共有ライブラリ:[libts- 0.0の.so。0 ] 0x00000001の(必要な)共有ライブラリ:[librt.so。1 ] 0x00000001の(必要な)共有ライブラリ:[libpthread.so。0 ] 0x00000001の(必要な)共有ライブラリ:[libdl.so。2 ] 0x00000001の(必要な)共有ライブラリ:[にlibstdc ++そう。6 ] 0x00000001の(必要な)共有ライブラリ:[libm.so. 6 ] 0x00000001の(必要な)共有ライブラリ:[libgcc_s.so。1 ] 0x00000001の(必要な)共有ライブラリ:[libc.so. 6 ] 0x0000000f(RPATH)ライブラリRPATH:[/ USR / qte338-TARGET2 / LIB] 0x0000000c(INIT) 0xd684 0x0000000d(FINI) 0x1304cの 0x00000019(INIT_ARRAY) 0x1c000
すべての上記の情報は、外部のライブラリに依存必要なのであることを、このプログラムを実行しているとマークされています。私たちは、このプログラムの正常に実行するためのパスを見つけることができるシステムで、これらのライブラリを下げる必要があります。
Linuxでは、システム変数が在庫置くパスを記録しています。それはあります
LD_LIBRARY_PATH
例えば、アンドロイド、その値があってもよいです
LD_LIBRARY_PATH = /ベンダー/ libに:/システム/ libに
外部ライブラリを検索するための一般的な必要としているLinuxシステム、/ libと/ usr / libディレクトリの下に見つけることが最初のものである、見つからない場合は、LD_LIBRARY_PATHの下にパスを見つけるために出て行きます。