2012-05-02 5 views
15

실행하기위한 ELF 파일 프로그램 (세그먼트) 헤더 readelf -a 통해 알 수있는 섹션 헤더를 가지며, 여기에서 예는 섹션 헤더 및 프로그램 (세그먼트) 헤더를 포함한다. 세그먼트 헤더는 프로그램을 메모리에로드하는 데 사용되는 여러 섹션 헤더로 구성되어 있음을 알 수 있습니다.ELF 파일의 어느 부분을 메모리에로드해야합니까?</p> <p><img src="https://i.stack.imgur.com/V7Cu6.png" alt="enter image description here"></p> <p><img src="https://i.stack.imgur.com/oi9jf.png" alt="enter image description here"></p> <p>두 이미지 위에 위치 :

.text, .rodata, .data, .bss 섹션 만 메모리에로드하면됩니까?

세그먼트에있는 다른 모든 섹션 (예 : 세 번째 세그먼트의 .ctors, .dtors .jcr)이 정렬에 사용됩니까?

+1

_aligning_? –

+0

@ Adriano, 예, 페이지 크기에 맞추면 프로그램의 다른 부분 (예 : .text (rx))에 다른 보호를 사용할 수 있습니다. –

답변

18

섹션과 세그먼트는 완전히 다른 두 가지 개념입니다. 섹션은 거기에 저장된 데이터의 의미 (즉, 사용할 내용)와 관련이 있으며 디버깅 목적을 제외하고 프로그램이나 공유 라이브러리가 링크되면 실제로는 관련이 없습니다. 섹션 헤더를 완전히 제거 할 수도 있고 (또는 임의의 쓰레기로 덮어 쓸 수도 있습니다) 프로그램이 여전히 작동합니다.

세그먼트 (즉, 프로그램 헤더로드 지시문)는 프로그램을로드 할 때 커널 및/또는 동적 링커가 실제로 보는 내용입니다. 예를 들어, 두 가지로드 지시문이 있습니다. 첫 번째는 파일의 첫 번째 4k (1 페이지)가 0x08048000 번지에 매핑되도록하고 실제로이 매핑의 첫 번째 0x4b8 바이트 만 사용되도록 지시합니다 (나머지는 정렬입니다). 두 번째는 파일의 처음 8k (2 페이지)가 주소 0x08049000에 매핑되도록합니다. 대다수는 정렬입니다. 첫 번째 0xf14 바이트는로드 지시문 (정렬)의 일부가 아니므로 낭비됩니다. 0x08049f14부터 파일에서 매핑 된 0x108 바이트가 실제로 사용되며 0x108의 MemSize에 도달하기위한 또 다른 0x10 바이트는 로더 (커널 또는 동적 링커)에 의해 0으로 채워집니다. 최대 0x0804a02c (두 번째로 매핑 된 페이지에서). 나머지 두 번째 매핑 페이지는 사용되지 않거나 낭비됩니다 (그러나 malloc은 힙의 일부로 사용할 수 있습니다).

마지막으로 섹션 헤더가 전혀 사용되지 않지만 실행중인 프로그램에서 여러 섹션의 내용을 사용할 수 있습니다. .ctors.dtors의 주소 범위는 두 번째로드 매핑의 시작 부분에 있으므로 런타임에 프로그램에서 매핑하고 액세스 할 수 있습니다 (런타임 시작/종료 코드는 C++ 또는 C# 인 경우 전역 생성자 및 소멸자를 실행하기 위해이를 사용합니다). ctor/dtor 속성을 가진 "GNU C"코드가 사용되었습니다). 또한 .data은 두 번째로 매핑 된 페이지의 주소 0x0804a00c에서 시작합니다. 이렇게하면 재배치가 적용된 후 첫 페이지가 읽기 전용으로 보호됩니다 (프로그램 헤더의 RELRO 지시문).

+0

+1을 지적합니다. GNU_RELRO – SquareRootOfTwentyThree

+0

C에 생성자가 있습니까 또는 소멸자를 C++로? –

+0

아니요,하지만 GCC는 C가 아니며 "GNU C"입니다. 예외 및 생성자와 같은 모든 종류의 비표준 작업을 수행 할 수 있습니다. –

관련 문제

 관련 문제