왜 GCC 컴파일된 C 프로그램에 .eh_frame 섹션이 필요한가?
테스트는 32비트 x86 Linux에서 실행되며gcc
4.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
'programing' 카테고리의 다른 글
Vue JS의 상위 구성 요소에서 하위 구성 요소로 업데이트된 값을 보내는 방법 (0) | 2022.07.17 |
---|---|
이것이 Vue.js 컴포넌트에서 ID를 설정하는 올바른 방법입니까? (0) | 2022.07.16 |
네이티브 Java 또는 Kotlin에서 "의존관계 AAR 메타데이터에 지정된 minCompileSdk(31)" 오류를 해결하려면 어떻게 해야 합니까? (0) | 2022.07.16 |
Java EE 웹 응용 프로그램에서 WEB-INF는 무엇에 사용됩니까? (0) | 2022.07.16 |
intr_t의 용도는 무엇입니까? (0) | 2022.07.16 |