開始アドレスに対する静的リンクと動的リンクの影響


8

簡単なCプログラムがあります。走る:

$ gcc Q1.c -Wall -save-temps -o Q1

次に、生成された実行可能ファイルを検査します。

$  objdump -f Q1
Q1:     file format elf32-i386
architecture: i386, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x080483b0

次に、静的リンクを使用してコンパイルします。

$ gcc Q1.c -Wall -save-temps -static -o Q1

そしてファイルをもう一度調べます:

$ objdump -f Q1
Q1:     file format elf32-i386
architecture: i386, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x08048e08

静的リンクと動的リンクはプログラムの開始アドレスにどのような影響がありますか?開始アドレスはのアドレスmain()ですよね?

回答:


10

開始アドレスはのアドレスmain()ですよね?

それほどではない:プログラムの開始は実際にはそうではありませんmain()。デフォルトでは、GCCは_startシンボルに対応する開始アドレスを持つ実行可能ファイルを生成します。あなたはそれを行うことでそれを見ることができますobjdump --disassemble Q1。これは私の中でのみ行う私の単純なプログラムの出力return 0;ですmain()

0000000000400e30 <_start>:
  400e30:       31 ed                   xor    %ebp,%ebp
  400e32:       49 89 d1                mov    %rdx,%r9
  400e35:       5e                      pop    %rsi
  400e36:       48 89 e2                mov    %rsp,%rdx
  400e39:       48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
  400e3d:       50                      push   %rax
  400e3e:       54                      push   %rsp
  400e3f:       49 c7 c0 a0 15 40 00    mov    $0x4015a0,%r8
  400e46:       48 c7 c1 10 15 40 00    mov    $0x401510,%rcx
  400e4d:       48 c7 c7 40 0f 40 00    mov    $0x400f40,%rdi
  400e54:       e8 f7 00 00 00          callq  400f50 <__libc_start_main>
  400e59:       f4                      hlt    
  400e5a:       66 90                   xchg   %ax,%ax
  400e5c:       0f 1f 40 00             nopl   0x0(%rax)

address 400e54で確認できるように_start()、次にが呼び出され__libc_start_main、必要なもの(pthreads、atexitなど)が初期化され、最後main()に適切な引数(argc、argv、env)で呼び出されます。

わかりましたが、開始アドレスの変更とはどう関係しているのでしょうか。

gcc静的にリンクするように要求する場合、それは、上記で説明したすべての初期化を、実行可能ファイルにある関数を使用して実行する必要があることを意味します。実際、両方の実行可能ファイルのサイズを見ると、静的バージョンの方がはるかに大きいことがわかります。私のテストでは、静的バージョンは800Kですが、共有バージョンはわずか6Kです。

追加の関数がたまたまの前_start()に配置されているため、開始アドレスが変更されています。静的実行可能ファイルのレイアウトは次のstart()とおりです。

000000000049e960 r translit_from_tbl
0000000000400a76 t _i18n_number_rewrite
0000000000400bc0 t fini
0000000000400bd0 t init_cacheinfo
0000000000400e30 T _start
0000000000400e60 t deregister_tm_clones
0000000000400e90 t register_tm_clones
0000000000400ed0 t __do_global_dtors_aux

そして、これが共有実行可能ファイルのレイアウトです。

00000000004003c0 T _start
00000000004003f0 t deregister_tm_clones
00000000004004b0 T main
00000000004004c0 T __libc_csu_init
00000000006008a0 B _end
0000000000400370 T _init

その結果、わずかに異なる開始アドレスが取得されます。静的な場合は0x400e30、共有の場合は0x4003c0です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.