2016-08-09 2 views
2

동적 링커 (일명 프로그램 인터프리터, 링크 로더)가 커널 또는 GCC 라이브러리의 일부입니까?Linux 시스템에서 동적 링커는 커널 또는 GCC 라이브러리의 일부입니까?

UPDATE (28-08-16)는 :

나는 (즉, 공유 라이브러리에 링크) 진 모든 동적 링커/lib64/ld-linux-x86-64.so.2 사용의 기본 경로는 공유에 대한 링크 것으로 나타났습니다 라이브러리 /lib/x86_64-linux-gnu/ld-2.23.so은 실제 동적 링커입니다.

그리고 libc6 (2.23-0ubuntu3) 패키지의 일부입니다. AMD64 아키텍처 용 우분투의 GNU C Library: Shared libraries.

내 실제 질문은

(이제 모든하는 일) 동적으로 연결되어있는 모든 응용 프로그램에 무슨 일이 일어날 지,이 도우미 프로그램 ( ld-2.23.so )가 존재하지 않는 경우?

그리고 대답은 "응용 프로그램이 실행되지 않으며 심지어 셸 프로그램"입니다. 나는 virutal 기계에서 그것을 시도했다.

+0

'ld.so'는 커널의 일부는 아니지만 커널에 의해로드됩니다. –

+0

실제로 리눅스에서는 GNU libc의 일부입니다. http://www.cs.virginia.edu/~dww4s/articles/ld_linux.html – nephtes

답변

5

ELF 실행 파일에서이를 "ELF 인터프리터"라고합니다. 리눅스에서 (예를 들어)이이 하지 커널의 일부 [일반적] glibc 등 함께 /lib64/ld-linux-x86-64.so.2

이다. al.

커널이 ELF 실행 파일을 실행하면 실행 파일을 사용자 공간 메모리로 매핑해야합니다. 그런 다음 INTERP [전체 경로 인 문자열을 포함하는]이라는 특수 하위 섹션을 찾습니다.

커널은 인터프리터를 사용자 공간 메모리에 매핑하고 그에 대한 제어를 전달합니다. 그런 다음 인터프리터는 필요한 연결 /로드를 수행하고 프로그램을 시작합니다.

ELF은 "확장 가능한 링커 형식"을 나타내므로 ELF 파일에서 여러 가지 하위 섹션을 허용합니다.

수많은 확장 기능에 대해 알 필요없이 커널에 부담을주기보다는 파일과 쌍을 이루는 ELF 인터프리터가 알고 있습니다.

일반적으로 주어진 시스템에서 하나의 형식 만 사용되지만 시스템마다 ELF 인터프리터가있는 여러 가지 다른 유형의 ELF 파일이있을 수 있습니다.

이렇게하면 ELF 파일이 리눅스가 아닌 BSD ELF 인터프리터를 가리 키기 때문에 BSD ELF 파일을 [다른 조정/지원과 함께] 리눅스 시스템에서 실행할 수 있습니다.


UPDATE :

모든 프로세스 (VLC 플레이어, 크롬) 자신의 주소 공간의 일부로서 공유 라이브러리 ld.so했다.

예. 나는 당신이 /proc/<pid>/maps을보고 있다고 가정합니다. 이들은 매핑입니다. (예 :mmap 사용)을 파일에 추가하십시오. 이는 "로딩"과 다소 다르며, 이는을 링크하는 [기호] 을 의미 할 수 있습니다.

그래서 주로 로더 메모리에 실행 파일 (코드 & 데이터)를로드 한 후, 그것은 &이 주소 공간

이가 바꿔을 이해하는 가장 좋은 방법은 동적 링커 (.so를) 매핑로드 당신은 단지 말 :

그래서 주로 커널 메모 위에 매핑 실행 (코드 & 데이터) 후 RY, 커널 는 프로그램 주소 공간 본질적 올

동적 링커 (.so는)를 맵핑한다. 커널은 bss 세그먼트와 스택과 같은 다른 것들도 매핑합니다. 그런 다음 argc, argvenvp [환경 변수를위한 공간]을 스택에 "푸시"합니다.

그런 다음 시작 주소가 ld.so (파일의 특정 섹션을 읽음으로써) 인 것으로 결정하면이를 다시 시작 주소로 설정하고 스레드를 시작합니다.

지금까지 커널 작업이 진행되어 왔습니다. 커널은을 연결하는 심볼 을 거의하지 않습니다.

지금, ld.so은 ... 더로드는 도서관, 도서관지도 & 해결 참조를 공유

을 수행합니다. 그런 다음 입력 기능 (_start) 원래 실행 파일 (예를 들어, vlc)이 메모리에 매핑 된 때문에

, ld.so가 필요한 공유 라이브러리의 목록을 검사 할 수 있습니다를 호출합니다. 그것은 을 메모리에 맵핑하지만 이 아님 링크 바로 기호입니다.

매핑이 쉽고 빠릅니다. mmap 전화.

실행 파일의 시작 주소 [은 ld.so의 시작 주소와 혼동되지 않아야합니다]는 ELF 실행 파일의 특수 섹션에서 가져옵니다. 이 시작 주소와 관련된 심볼은 전통적으로 _start을 불려왔다,하지만, 실제로는 시작 주소와 기호의 하지 주소를 결정하는 섹션 데이터에 무엇으로 (예를 들어 __my_start을) 어떤 이름 수 _start

심볼 정의에 심볼 참조를 연결하는 것은 시간이 많이 걸리는 프로세스입니다. 따라서 심볼이 실제로 사용될 때까지 연기됩니다.즉 프로그램이 printf에 대한 참조가있는 경우, 링커가 실제로 실제로 프로그램 호출 처음 할 때까지 printf에 연결하려고하지 않습니다이며, 이것은 때때로 "온 디맨드 링크"또는 "이라고printf

주문형 연결 ". 내 대답을 참조하십시오 : Which segments are affected by a copy-on-write? 그 자세한 설명 및 실제로 실행 파일을 사용자 공간에 매핑 할 때 실제로 어떻게되는지.

ldd /usr/bin/vlc을 사용하면 해당 라이브러리가 사용하는 공유 라이브러리 목록을 얻을 수 있습니다. readelf -a /usr/bin/vlc의 출력을 보면 동일한 공유 라이브러리가 표시됩니다. 또한 ELF 인터프리터의 전체 경로를 얻고 readelf -a <full_path_to_interpreter>을 수행하고 차이점에 유의하십시오. vlc이 원하는 파일 .so에 대해이 프로세스를 반복 할 수 있습니다.

모두를 /proc/<pid>maps 등으로 결합하십시오. al. 당신의 이해를 도울 수 있습니다.

+0

@criag를 참조하십시오. 내가 알았 듯이 모든 프로세스 (vlc 플레이어, 크롬)는 주소 공간의 일부로 공유 라이브러리 ** ld.so **를 보유하고 있습니다. 따라서 로더는 실행 파일 (코드 및 데이터)을 메모리에로드 한 후 동적 공유기 (.so) **를 주소 공간에로드 및 매핑하여 공유 라이브러리를로드하고 라이브러리에 대한 참조를 매핑 및 해결합니다. 그런 다음 항목 기능 (_start)을 호출합니다. 이 올바른지 ? –

+1

젠장, 잘 설명 크레이그. –

+0

@craig. 고마워요, 업데이트가 도움이되었습니다 :) –