나는 main.c
리눅스에서 썼다 :
int main()
{
while (1){}
}
컴파일하고 시작할 때 할 수 pmap
있습니다.
# pmap 28578
28578: ./a.out
0000000000400000 4K r-x-- /root/a.out
0000000000600000 4K r---- /root/a.out
0000000000601000 4K rw--- /root/a.out
00007f87c16c2000 1524K r-x-- /lib/libc-2.11.1.so
00007f87c183f000 2044K ----- /lib/libc-2.11.1.so
00007f87c1a3e000 16K r---- /lib/libc-2.11.1.so
00007f87c1a42000 4K rw--- /lib/libc-2.11.1.so
00007f87c1a43000 20K rw--- [ anon ]
00007f87c1a48000 128K r-x-- /lib/ld-2.11.1.so
00007f87c1c55000 12K rw--- [ anon ]
00007f87c1c65000 8K rw--- [ anon ]
00007f87c1c67000 4K r---- /lib/ld-2.11.1.so
00007f87c1c68000 4K rw--- /lib/ld-2.11.1.so
00007f87c1c69000 4K rw--- [ anon ]
00007fff19b82000 84K rw--- [ stack ]
00007fff19bfe000 8K r-x-- [ anon ]
ffffffffff600000 4K r-x-- [ anon ]
total 3876K
총계 (3876)를 K로 나눈 값 VIRT
은의 출력 에서 열과 같습니다 top
. 이제 텍스트 세그먼트는 어디에 있습니까? 400000, 600000, 601000 에서요? 어디에 있는지 설명을 어디서 읽을 수 있습니까? man pmap
도와주지 않았다.
답변
텍스트 세그먼트는 0x400000에서의 매핑입니다. 읽기 및 실행 가능하도록 ‘rx’로 표시되어 있습니다. 0x600000에서의 매핑은 읽기 전용이므로 실행 파일의 “.rodata”섹션이 거의 확실합니다. GCC는 C 문자열 리터럴을 읽기 전용 섹션에 넣습니다. 0x601000의 매핑은 ‘rw-‘이므로 유명한 힙일 것입니다. 실행 파일을 malloc()
1024 바이트로 설정하고 주소를 인쇄하여 확인할 수 있습니다.
프로세스의 PID를 찾고 다음을 수행하여 조금 더 많은 정보를 얻을 수 있습니다.- cat /proc/$PID/maps
내 Arch 랩톱에서 추가 정보를 제공합니다. 그것은 3.12 커널을 실행하고 있기 때문에 /proc/$PID/numa_maps
작은 통찰력을 줄 수있는 catting도 있습니다.
실행 파일에서 실행할 기타 사항 : nm
및 objdump -x
. 전자는 메모리 맵에서 다양한 것들이 어디에 있는지에 대한 아이디어를 줄 수 있으므로 0x4000000 섹션과 다른 섹션의 내용을 볼 수 있습니다. objdump -x
많은 다른 것들 중에서 ELF 파일 헤더를 보여 주므로 모든 섹션을 볼 수 있으며 섹션 이름과 런타임에 매핑되었는지 여부를 모두 볼 수 있습니다.
“어디에 있는지”에 대한 서면 설명을 찾는 한 “ELF FILE 메모리 레이아웃”에 대해 Google과 같은 작업을 수행해야합니다. ELF 파일 형식은 일반적으로 사용되는 것보다 더 이국적인 메모리 레이아웃을 지원할 수 있습니다. GCC와 Gnuld 및 glibc는 모두 실행 파일이 어떻게 배치되고 런타임에 메모리에 매핑되는지에 대한 간단한 가정을합니다. 이를 문서화하기위한 많은 웹 페이지가 존재하지만 이전 버전의 Linux, 이전 버전의 GCC 또는 glibc에만 적용되거나 x86 실행 파일에만 적용됩니다. 없는 경우 readelf
명령을 받으십시오 . C 프로그램을 작성할 수 있다면, 자신의 버전을 만들 objdump -x
거나 readelf
실행 파일의 작동 방식과 그 내용을 숙지하십시오.