Linuxの実行可能プログラムについて

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の下にパスを見つけるために出て行きます。

 


 

おすすめ

転載: www.cnblogs.com/chorm590/p/11214009.html