동적으로 로드/링크된 라이브러리의 메모리 레이아웃

동적으로 로드/링크된 라이브러리의 메모리 레이아웃

Linux 시스템에서 공유 라이브러리를 로드할 때 공유 라이브러리의 메모리 레이아웃은 어떻게 됩니까?

예를 들어 원래 메모리 레이아웃은 다음과 같습니다.

+-----------+
|heap(ori)  |
+-----------+
|stack(ori) |
+-----------+
|.data(ori) |
+-----------+
|.text(ori) |
+-----------+

dlopen 을 할 때 foo.so메모리 레이아웃은 A인가요, 아니면 B인가요?

A
+-----------+
|heap(ori)  |
+-----------+
|stack(ori) |
+-----------+
|.data(ori) |
+-----------+
|.text(ori) |
+-----------+
|heap(foo)  |
+-----------+
|stack(foo) |
+-----------+
|.data(foo) |
+-----------+
|.text(foo) |
+-----------+

또는

B
+-----------+
|heap(ori)  |
+-----------+
|heap(foo)  |
+-----------+
|stack(foo) |
+-----------+
|stack(ori) |
+-----------+
|.data(foo) |
+-----------+
|.data(ori) |
+-----------+
|.text(foo) |
+-----------+
|.text(ori) |
+-----------+

아니면 A와 B 외에 다른 것이 있는 걸까요...?

답변1

대답은 "기타"입니다. 메모리 레이아웃을 이해하는 데 사용할 수 있습니다 cat /proc/self/maps. 내 64비트 Arch 노트북에서:

00400000-0040c000 r-xp 00000000 08:02 1186758                            /usr/bin/cat
0060b000-0060c000 r--p 0000b000 08:02 1186758                            /usr/bin/cat
0060c000-0060d000 rw-p 0000c000 08:02 1186758                            /usr/bin/cat
02598000-025b9000 rw-p 00000000 00:00 0                                  [heap]
7fe4b805c000-7fe4b81f5000 r-xp 00000000 08:02 1182914                    /usr/lib/libc-2.21.so
7fe4b81f5000-7fe4b83f5000 ---p 00199000 08:02 1182914                    /usr/lib/libc-2.21.so
7fe4b83f5000-7fe4b83f9000 r--p 00199000 08:02 1182914                    /usr/lib/libc-2.21.so
7fe4b83f9000-7fe4b83fb000 rw-p 0019d000 08:02 1182914                    /usr/lib/libc-2.21.so
7fe4b83fb000-7fe4b83ff000 rw-p 00000000 00:00 0
7fe4b83ff000-7fe4b8421000 r-xp 00000000 08:02 1183072                    /usr/lib/ld-2.21.so
7fe4b85f9000-7fe4b85fc000 rw-p 00000000 00:00 0
7fe4b85fe000-7fe4b8620000 rw-p 00000000 00:00 0
7fe4b8620000-7fe4b8621000 r--p 00021000 08:02 1183072                    /usr/lib/ld-2.21.so
7fe4b8621000-7fe4b8622000 rw-p 00022000 08:02 1183072                    /usr/lib/ld-2.21.so
7fe4b8622000-7fe4b8623000 rw-p 00000000 00:00 0
7ffe430c4000-7ffe430e5000 rw-p 00000000 00:00 0                          [stack]
7ffe431ed000-7ffe431ef000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

실행 파일이 낮은 메모리, 즉 .text 세그먼트, 읽기 전용 데이터 및 .bss에 로드되는 것을 볼 수 있습니다. 이것이 "힙"입니다. 더 높은 메모리에는 C 라이브러리와 "ELF 파일 인터프리터", "ld-so"가 로드됩니다. 그 다음에는 스택이 있습니다. 지정된 주소 공간에 대해 얼마나 많은 공유 라이브러리가 로드되더라도 스택과 힙은 하나만 있습니다. catC 라이브러리만 로드된 것 같습니다.

그렇게 하면 cat /proc/$$/maps호출한 쉘의 메모리 맵을 얻을 수 있습니다 cat. 모든 셸에는 동적으로 로드되는 많은 라이브러리가 있으며, 많은 수의 라이브러리가 로드 zsh됩니다 bash. "[힙]"과 "[스택]"이 하나만 있는 것을 볼 수 있습니다.

호출되면 dlopen()공유 객체 파일은 보다 높은 주소의 주소 공간에 매핑됩니다 /usr/lib/libc-2.21.so. mmap()반환된 모든 주소가 표시되는 "구현에 따른" 메모리 맵 세그먼트가 있습니다 . 바라보다인메모리 프로그램 분석좋은 그래픽을 위해.

출처가 /usr/lib/ld-2.21.so조금 까다롭기는 하지만 2등 시민은 아닙니다 dlopen().dlopen()

"vdso"와 "vsyscall"은 약간 신비롭지만이 Stackoverflow 질문좋은 설명이 있고 Wikipedia에도 설명이 있습니다.

관련 정보