自己修養——目標文書.o何があるの?


自己修養--コンパイルとリンクはプログラマーの自己修正-リンクに由来する.マウント庫一本、また一章読みました~
書くのは容易ではありません.転載には出典を明記する必要があります.http://blog.csdn.net/jscese/article/details/50161675本文は【jscese】のブログから!
ファイルの種類
executable windows: PE(Portable executable) linux: EIF(Executable Linkable Format)
Relocatable file : linux:.o ; windows:.obj
Executable file : linux:/bin/xxx ; windows:.exe
Share Object file : linux:.so ; windows:.dll
コンパイルプロセスでは、最終的に1つ以上のrelocatable fileがlinkによってexecutable file、すなわちlinuxのEIFにパッケージされます.
一般的に指すターゲットファイルは、linuxで言えばコンパイルが完了する.o
.o file construction
まずsimplesectionでcを例にとると、ソースコードは以下の通りである.
int printf(const char *format,...);

int global_init_var =84;

int global_uninit_var;

void func1(int i)
{
    printf("%d
"
,i); } int main(void) { static int static_var=85; static int static_var2; int a=1; int b; func1(static_var+ static_var2 + a + b); return a; }

なぜこのように書くのか、まず悩まないでください.o
gcc -c simplesection.c

同じディレクトリの下でsimplesectionを得る.o
simplesectionを表示します.oの構成は2つのツールreadef objdumpに使用できます
.oにデータセグメント-sectionが格納されており、objdumpを使用してセグメントテーブルを次のように表示できます.
jscese@:~/jscese_code/object_file_construct$ objdump -h simplesection.o

simplesection.o:     file format elf64-x86-64

Sections:
Idx Name          Size      VMA               LMA               File offset  Algn
  0 .text         00000050  0000000000000000  0000000000000000  00000040  2**2
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  1 .data         00000008  0000000000000000  0000000000000000  00000090  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000004  0000000000000000  0000000000000000  00000098  2**2
                  ALLOC
  3 .rodata       00000004  0000000000000000  0000000000000000  00000098  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .comment      0000002b  0000000000000000  0000000000000000  0000009c  2**0
                  CONTENTS, READONLY
  5 .note.GNU-stack 00000000  0000000000000000  0000000000000000  000000c7  2**0
                  CONTENTS, READONLY
  6 .eh_frame     00000058  0000000000000000  0000000000000000  000000c8  2**3
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA

readelfを使用してコマンドを表示する:readelf-S simplesection.oフォーマットが少し違うだけですが、具体的なセグメント情報の意味はkernelincludeuapilinuxelfを参照してください.hで定義したElf 64_Shdr構造体
ここで見ることができるのは6つのsectionがそれぞれのsizeと対応する後ろのfile offsetの大きさによって、順番にファイルに並べて、分かりやすいです
コンテンツの分散ルールは次のとおりです.
コンパイルされたマシン命令-コードセグメント——.code or .textは、グローバル/ローカル静的変数-データセグメントを初期化する.dataはグローバル/ローカル静的変数を初期化する--bss読み取り専用のデータ内容——.rodata
特に注意するのはCONTS代表が内容があるかどうかです.bssは特殊なsectionです.事前に説明してください.
初期実行時のオープンデフォルトはいずれも0であり、bssは初期化されていないグローバルおよびローカル静的に占めるサイズを記録する役割を果たし、ファイルに実際に存在しないsectionであるため、ファイル空間を占めず、section tableセグメントテーブルに「bssセグメントにグローバル初期化されていない変数を残していないものもあり、commonグローバル変数記号を残してコンパイラを参照」と記録する.
ここに小さな点があります.上の表の情報にあります.text sectionのサイズは0 x 50で80 byteであり、sizeコマンドを使用してsimplesectionを表示する.o時:
jscese@:~/jscese_code/object_file_construct$ size simplesection.o
   text    data     bss     dec     hex filename
    172       8       4     184      b8 simplesection.o

表示されます.textは172です.sizeのデフォルトは「Berkeley compatibility mode」で実行されます.このモードでは、実行不可能な所有"ALLOC"属性の読み取り専用セグメントが帰する.textセグメントの下で、典型的なのは.rodataセグメント.「size-A obj」を使うとo"では、sizeは"System V compatibility mode"で動作、このときobjdump-hとsizeで表示される.textセグメントのサイズはあまり差がありません.
jscese@:~/jscese_code/object_file_construct$ size -A  simplesection.o
simplesection.o  :
section           size   addr
.text               80      0
.data                8      0
.bss                 4      0
.rodata              4      0
.comment            43      0
.note.GNU-stack      0      0
.eh_frame           88      0
Total              227

これが正しい!
分割の目的
命令領域データ領域を別々に格納する目的:1:ファイルがロードされて実行され、命令データがそれぞれ2つの仮想領域にマッピングされ、命令に対応する領域が読み取り専用に設定され、データ領域が読み取り可能に設定され、命令が吐き気で修正されることを保証する
2:cache命中率の問題、別々に保管して、CPUの指の命中率を高めます
3:プログラムのマルチコピーの実行時の命令部分は1部だけ存在することができて、読み取り専用で共有して、メモリを節約して、同時にいくつかの読み取り専用のデータ部分も共有することができて、単一のコピーを保存します
セクションの表示
表示oのコードセグメントtext sectionの内容はobjdump-sを使用して16メカニズムを表示し、-dはアセンブリコードに逆アセンブリされます.
jscese@:~/jscese_code/object_file_construct$ objdump -s simplesection.o

simplesection.o:     file format elf64-x86-64

Contents of section .text:
 0000 554889e5 4883ec10 897dfc8b 45fc89c6  UH..H....}..E...
 0010 bf000000 00b80000 0000e800 000000c9  ................
 0020 c3554889 e54883ec 10c745f8 01000000  .UH..H....E.....
 0030 8b150000 00008b05 00000000 01d00345  ...............E
 0040 f80345fc 89c7e800 0000008b 45f8c9c3  ..E.........E...
Contents of section .data:
 0000 54000000 55000000                    T...U...        
Contents of section .rodata:
 0000 25640a00                             %d..    
...

最も左はオフセットで、ここでは前のsectionのファイル内のオフセットと区別するが、ここではsection中のデータのオフセット値が上のファイル内にあるだけである.textセグメントのfile offsetが00000040である場合、ファイル内の00000041の位置のバイトは0 x 5500000 90の位置の0 xc 3の中間4列が0 x 50 80バイトであり、最後の列がASCALLである
逆アセンブリ:objdump-d simplesection.o
Disassembly of section .text:

0000000000000000 <func1>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   48 83 ec 10             sub    $0x10,%rsp
   8:   89 7d fc                mov    %edi,-0x4(%rbp)
   b:   8b 45 fc                mov    -0x4(%rbp),%eax
   e:   89 c6                   mov    %eax,%esi
  10:   bf 00 00 00 00          mov    $0x0,%edi
  15:   b8 00 00 00 00          mov    $0x0,%eax
  1a:   e8 00 00 00 00          callq  1f <func1+0x1f>
  1f:   c9                      leaveq 
  20:   c3                      retq   

0000000000000021 <main>:
  21:   55                      push   %rbp
  22:   48 89 e5                mov    %rsp,%rbp
  25:   48 83 ec 10             sub    $0x10,%rsp
  29:   c7 45 f8 01 00 00 00    movl   $0x1,-0x8(%rbp)
  30:   8b 15 00 00 00 00       mov    0x0(%rip),%edx        # 36 <main+0x15>
  36:   8b 05 00 00 00 00       mov    0x0(%rip),%eax        # 3c <main+0x1b>
  3c:   01 d0                   add    %edx,%eax
  3e:   03 45 f8                add    -0x8(%rbp),%eax
  41:   03 45 fc                add    -0x4(%rbp),%eax
  44:   89 c7                   mov    %eax,%edi
  46:   e8 00 00 00 00          callq  4b <main+0x2a>
  4b:   8b 45 f8                mov    -0x8(%rbp),%eax
  4e:   c9                      leaveq 
  4f:   c3                      retq   

データとアセンブリ命令の対応関係、詳細はアセンブリ命令と対応マシンコードを調べることができる
カスタムsectionの割り当て
  static int itest1=0;
  static int itest2=1;

itest 1存bssセグメントitest 2が格納.Dataセグメントは、初期化されていない変数がデフォルトで0であるため、bssセグメントの予約位置でファイルにスペースを占めず、itest 1をbssセグメントに配置してシンボルテーブルを表示することを最適化します.
   jscese@:~/jscese_code/object_file_construct$ objdump -t simplesection.o

simplesection.o:     file format elf64-x86-64

SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000 simplesection.c
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000000 l    d  .data  0000000000000000 .data
0000000000000000 l    d  .bss   0000000000000000 .bss
0000000000000000 l    d  .rodata        0000000000000000 .rodata
0000000000000004 l     O .data  0000000000000004 static_var.1594
0000000000000000 l     O .bss   0000000000000004 static_var2.1595
0000000000000000 l    d  .note.GNU-stack        0000000000000000 .note.GNU-stack
0000000000000000 l    d  .eh_frame      0000000000000000 .eh_frame
0000000000000000 l    d  .comment       0000000000000000 .comment
0000000000000000 g     O .data  0000000000000004 global_init_var
0000000000000004       O *COM*  0000000000000004 global_uninit_var
0000000000000000 g     F .text  0000000000000021 func1
0000000000000000         *UND*  0000000000000000 printf
0000000000000021 g     F .text  000000000000002f main

global_が見えますuninit_varは存在しない.bss中,.bssにはstatic_しかありませんvar 2、これも上のsection tableにある.bssが4 byteしかない理由は、上述した特殊なコンパイラが、定義されていないグローバル変数を置かないことに注意しなければならない.bssは、COMMONの記号を予約しています.ここでは、0000000004 O COM 0000000004 global_uninit_var
いくつかのアドレスレイアウトなどの問題を考慮すると、ある変数を特定のセグメントに保存することをカスタマイズすることができ、gccはこのようなメカニズムを提供しています.
  __attribute__((section("name"))) //  

上を変更します.c,初期化されたグローバル変数を置く.bssセグメントの中へ:
 __attribute__((section(".bss"))) int global_init_var =84;

シンボルテーブルをもう一度見てみましょう.
SYMBOL TABLE:
0000000000000000 l    df *ABS*  0000000000000000 simplesection.c
0000000000000000 l    d  .text  0000000000000000 .text
0000000000000000 l    d  .data  0000000000000000 .data
0000000000000000 l    d  .bss   0000000000000000 .bss
0000000000000000 l    d  .rodata        0000000000000000 .rodata
0000000000000000 l     O .data  0000000000000004 static_var.1594
0000000000000004 l     O .bss   0000000000000004 static_var2.1595
0000000000000000 l    d  .note.GNU-stack        0000000000000000 .note.GNU-stack
0000000000000000 l    d  .eh_frame      0000000000000000 .eh_frame
0000000000000000 l    d  .comment       0000000000000000 .comment
0000000000000000 g     O .bss   0000000000000004 global_init_var
0000000000000004       O *COM*  0000000000000004 global_uninit_var
0000000000000000 g     F .text  0000000000000021 func1
0000000000000000         *UND*  0000000000000000 printf
0000000000000021 g     F .text  000000000000002f main

から見ることができます.データが到着しました.bss
上の一連の分析を話したことがあるが,全体に対して言うべきだ.oファイルは全体的な認識があって、最後に1枚の原書の中の構造図を補充します:自我修养——目标文件.o有什么_第1张图片