静态和动态链接对起始地址的影响


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(),对不对?

Answers:


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()依次调用invokes __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。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.