programing

왜 GCC 컴파일된 C 프로그램에 .eh_frame 섹션이 필요한가?

shortcode 2022. 7. 16. 15:04
반응형

왜 GCC 컴파일된 C 프로그램에 .eh_frame 섹션이 필요한가?

테스트는 32비트 x86 Linux에서 실행되며gcc4.6.3

사용시gcc을 편집하다C프로그램 및 사용readelf섹션 정보를 확인하기 위해.eh_frame섹션 및.eh_frame_hdr내부 섹션입니다.

예를 들어, 다음은 이진 프로그램의 섹션 정보입니다.Perlbench.

readelf -S perlbench

There are 28 section headers, starting at offset 0x102e48:

Section Headers:
[Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
[ 0]                   NULL            00000000 000000 000000 00      0   0  0
[ 1] .interp           PROGBITS        08048154 000154 000013 00   A  0   0  1
[ 2] .note.ABI-tag     NOTE            08048168 000168 000020 00   A  0   0  4
[ 3] .note.gnu.build-i NOTE            08048188 000188 000024 00   A  0   0  4
[ 4] .gnu.hash         GNU_HASH        080481ac 0001ac 000044 04   A  5   0  4
[ 5] .dynsym           DYNSYM          080481f0 0001f0 0007b0 10   A  6   1  4
[ 6] .dynstr           STRTAB          080489a0 0009a0 0003d6 00   A  0   0  1
[ 7] .gnu.version      VERSYM          08048d76 000d76 0000f6 02   A  5   0  2
[ 8] .gnu.version_r    VERNEED         08048e6c 000e6c 0000a0 00   A  6   2  4
[ 9] .rel.dyn          REL             08048f0c 000f0c 000028 08   A  5   0  4
[10] .rel.plt          REL             08048f34 000f34 000388 08   A  5  12  4
[11] .init             PROGBITS        080492bc 0012bc 00002e 00  AX  0   0  4
[12] .plt              PROGBITS        080492f0 0012f0 000720 04  AX  0   0 16
[13] .text             PROGBITS        08049a10 001a10 0cf86c 00  AX  0   0 16
[14] .fini             PROGBITS        0811927c 0d127c 00001a 00  AX  0   0  4
[15] .rodata           PROGBITS        081192a0 0d12a0 017960 00   A  0   0 32
[16] .eh_frame_hdr     PROGBITS        08130c00 0e8c00 003604 00   A  0   0  4
[17] .eh_frame         PROGBITS        08134204 0ec204 01377c 00   A  0   0  4
[18] .ctors            PROGBITS        08148f0c 0fff0c 000008 00  WA  0   0  4
[19] .dtors            PROGBITS        08148f14 0fff14 000008 00  WA  0   0  4
[20] .jcr              PROGBITS        08148f1c 0fff1c 000004 00  WA  0   0  4
[21] .dynamic          DYNAMIC         08148f20 0fff20 0000d0 08  WA  6   0  4
[22] .got              PROGBITS        08148ff0 0ffff0 000004 04  WA  0   0  4
[23] .got.plt          PROGBITS        08148ff4 0ffff4 0001d0 04  WA  0   0  4
[24] .data             PROGBITS        081491e0 1001e0 002b50 00  WA  0   0 32
[25] .bss              NOBITS          0814bd40 102d30 002b60 00  WA  0   0 32
[26] .comment          PROGBITS        00000000 102d30 00002a 01  MS  0   0  1
[27] .shstrtab         STRTAB          00000000 102d5a 0000ec 00      0   0  1

이 두 섹션은 예외를 처리하는 데 사용되며 스택을 분리하는 방법을 설명하는 테이블을 생성합니다.

하지만 그것은 을 위한거야C++프로그램, 사용eh_frame그리고.gcc_exception_table예외를 관리하는 섹션입니다.그러면 왜 컴파일러는eh_frame그리고.eh_frame_hdr내부 섹션ELF에서 컴파일된C프로그램?

우선, 이것의 원래 이유는 대체로 정치적인 것이었다 - DWARF 기반의 긴장을 푸는 것을 추가한 사람들..eh_frame)는 C++ 예외 이외의 모든 종류의 기능을 구현하기 위해 항상 사용할 수 있는 기능을 원했습니다.다음은 예를 제시하겠습니다.

  • backtrace()
  • __attribute__((__cleanup__(f)))
  • __builtin_return_address(n),위해서n>0
  • pthread_cleanup_push, 의 관점에서 실장되어 있습니다.__attribute__((__cleanup__(f)))
  • ...

하지만 이런 것들이 필요 없다면.eh_frame약 15~30% 증가했습니다..text사이즈는 무익.의 생성을 디세블로 할 수 있습니다..eh_frame와 함께-fno-asynchronous-unwind-tables개개의 번역 유닛에 대응하고 있기 때문에, 사이즈의 코스트를 거의 삭감할 수 있습니다.다만, 아직 일부의 번역 유닛으로부터 입수할 수 있습니다.crtbegin.o, 등. 를 사용하여 제거할 수 없습니다.strip나중에 명령어.eh_frame는 프로그램의 로드된 부분(이 부분이 포인트 전체)에 존재하는 섹션으로, 실행 시 바이너리를 끊는 방식으로 바이너리를 변경합니다.파손의 예에 대해서는, https://sourceware.org/bugzilla/show_bug.cgi?id=14037 를 참조해 주세요.

DWARF 테이블은 디버깅에도 사용되지만 이를 위해 프로그램의 로드 가능한 부분에 있을 필요는 없습니다.사용.-fno-asynchronous-unwind-tables디버깅을 중단하지 않습니다.-g컴파일러에도 전달되지만 테이블은 여전히 생성됩니다.이것들은 바이너리의 개별적인 로드 불가능, 스트라이핑 가능 섹션에 저장됩니다..debug_frame.

언급URL : https://stackoverflow.com/questions/26300819/why-gcc-compiled-c-program-needs-eh-frame-section

반응형