시작 주소에 대한 정적 및 동적 연결의 영향

시작 주소에 대한 정적 및 동적 연결의 영향

간단한 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()바로 주소죠?

답변1

시작주소는 의 주소겠죠 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입니다.

관련 정보