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
, argv
및 envp
[환경 변수를위한 공간]을 스택에 "푸시"합니다.
그런 다음 시작 주소가 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. 당신의 이해를 도울 수 있습니다.
'ld.so'는 커널의 일부는 아니지만 커널에 의해로드됩니다. –
실제로 리눅스에서는 GNU libc의 일부입니다. http://www.cs.virginia.edu/~dww4s/articles/ld_linux.html – nephtes