링커란 무엇이며 동적 링킹의 로더는 무엇입니까?

링커란 무엇이며 동적 링킹의 로더는 무엇입니까?

컴퓨터 시스템: 프로그래머의 관점(3ed)p733 라고

7.9 실행 가능한 타겟 파일 로딩

실행 가능한 개체 파일인 prog를 실행하려면 Linux 셸의 명령줄에 해당 이름을 입력하면 됩니다.

리눅스> ./prog

prog내장된 셸 명령과 일치하지 않기 때문에 셸 prog에서는 실행 가능한 개체 파일이라고 가정합니다. 이 파일은 다음과 같은 메모리 상주 운영 체제 코드를 호출하여 생성됩니다.짐을 싣는 사람. 모든 Linux 프로그램은 이 함수를 호출하여 로더를 호출할 수 있으며 execve, 이에 대해서는 섹션 8.4.6에서 자세히 다룰 것입니다.

p736에서: 동적 연결 중

7.10 공유 라이브러리와의 동적 연결

라이브러리를 생성한 후 이를 그림 7.7의 예제 프로그램에 연결합니다.

linux> gcc -o prog2l main2.c ./libvector.so

prog2l이는 런타임에 링크 될 수 있는 형태로 실행 가능한 개체 파일을 생성합니다 . libvector.so기본 아이디어는 실행 파일이 생성될 때 일부 링크를 정적으로 수행한 다음 프로그램이 로드될 때 링크 프로세스를 동적으로 완료하는 것입니다. 깨닫는 것이 중요하다libVector.so의 코드나 데이터 중 어떤 부분도 실제로 실행 파일에 복사되지 않습니다.prog2l이 지점에서. 대신에,링커는 일부 재배치 및 기호 테이블 정보를 복사합니다.libvector.so이렇게 하면 로드 시 코드 및 데이터에 대한 참조를 확인할 수 있습니다.

로더가 실행 파일을 로드하고 실행할 때 prog2l섹션 7.9에 설명된 기술을 사용하여 부분적으로 링크된 실행 파일을 로드합니다. prog2l다음으로, 그 자체가 공유 객체인 동적 링커의 경로 이름을 포함하는 섹션 prog2l이 포함되어 있음을 확인합니다 .interp(예: ld-linux.soLinux 시스템에서). 로더는 평소처럼 애플리케이션에 제어를 전달하는 대신 동적 링커를 로드하고 실행합니다. 동적 링커그런 다음 완료작업 연결다음 재배치를 수행하여:

  • 텍스트와 데이터를 libc.so메모리 세그먼트로 재배치
  • 텍스트와 데이터를 libvector.so다른 메모리 세그먼트로 재배치
  • prog2l및에 의해 정의된 기호 에 대한 참조를 재배치합니다 .libc.solibvector.so

위의 동적링크 상황은 "정적 로딩, 동적링크" 상황이다.스티븐 키트의 답변:

정적 로딩, 동적 연결:링커/usr/bin/ld를 다시 사용하지만 공유 라이브러리(.so)를 사용합니다.짐을 싣는 사람64비트 x86 기반 Debian 9의 /lib64/ld-linux-x86-64.so.2(현재 /lib/x86_64-linux-gnu/ld-2.24.so에 매핑됨)와 같은 바이너리용 인터프리터입니다. 주요 실행 파일도 로드하는 커널에 의해;

차이점은 CSAPP에서는 로더가 (뒤에 있는 커널 코드) execve()반면 링커는 ld-linux.so(컴파일 타임에 링크가 발생하지 않지만 ld실제 링크는 로드 타임에 발생함 ld-linux.so)이라고 말하는 것 같습니다.

링커란 무엇이며 동적 링킹의 로더는 무엇입니까?

감사해요.

답변1

강조할 핵심 사항은 다음과 같습니다.

동적 링커그런 다음 완료작업 연결

중요한 단어를 놓쳤어요"마치다”. 링커는 ld연결 작업을 시작하여 빌드 시 가능한 한 많은 작업을 수행하고 이를 완료하는 데 필요한 데이터 구조를 준비합니다.

그런 다음 로더는 프로그램과 필수 라이브러리를 로드하는 연결 작업(기호 일치 및 필요한 재배치 수행)을 완료할 수 있습니다.

CSAPP 용어에서 동적 로더는 커널의 ELF 로더이고 동적 링커는 ld-linux.so.

GNU C 라이브러리 자체 문서 ld.so는 다음과 같습니다.동적 링커/로더. ld.so(또는 ld-linux.so) 자체는 링크뿐만 아니라 로딩도 많이 수행하므로 두 용어를 모두 적용하는 것이 정확할 것입니다. 커널은 실행 파일 자체와 해당 인터프리터(동적 링커/로더)를 로드하고 인터프리터는 필요한 다른 모든 것을 로드합니다. 도서관.

바라보다프로그램 실행 방법: ELF 바이너리이 모든 것이 Linux 시스템에서 어떻게 작동하는지 자세히 알아보세요.

답변2

동적 링커는 call 입니다 ld.so. 아래에서 구성을 찾을 수 있습니다 /etc/ld.so*. 대부분의 구성은 .so를 검색하는 경로와 관련이 있습니다.

ld실행 파일의 연결을 완료하기 전에 모든 기능이 공유 라이브러리에 있는지 확인해야 합니다(음...기술적으로는 수행할 필요는 없지만 수행합니다. 즉, From에서 시작하는 경우) 컴퓨터마다 .so가 다를 수 있고 새로운 기능이 있을 수 있지만 이전 기능이 손실되고 바이너리가 실행되지 않습니다.

링커()는 공유 라이브러리가 필요한 바이너리를 생성할 때 ld섹션에 특정 개수의 기호와 해당 주소를 예약합니다. .text이는 동적 링커( ld.so)가 런타임 시 연결을 완료하는 데 사용하는 것입니다. 해당 .so 파일에서 기호를 검색하고 코드에서 필요할 때마다 해당 주소를 저장합니다(함수의 경우 일반적으로 jump명령 목록이므로 각 함수를 한 번만 연결할 수 있습니다).

물론 바이너리를 제거하면특수 기호삭제되지 마십시오.

로드될 라이브러리 목록을 보려면 ldd실행 파일에 대해 실행할 수 있습니다. 특히 기호(전체 경로)를 확인하기 위해 어떤 .so가 선택되었는지 보여줍니다. 환경 변수를 사용하여 검색 경로를 변경할 수 있습니다 LD_LIBRARY_PATH. 이를 통해 다른 또는 제거된 .so 파일에 대해 테스트할 수 있습니다(cmake, automake도 --rpath해당 파일을 사용합니다. 동일하며 경로는 바이너리에 직접 저장됩니다).

정확히 어느 부분이 파일을 로드하고 실행하는지 잘 모르겠습니다. execve()이 모든 논리는 직접 구현되지 않을 수도 있습니다 . 그러나 실행 파일을 실행하는 방법을 아는 가장 낮은 수준의 함수에 확실히 가깝습니다.

실제로 동적 연결은매우 간단하다표준 링커와 비교한 프로세스:

  1. 로드.so
  2. .so에서 기호 검색
  3. 기호 주소 저장

완벽한. 그렇기 때문에 너무 빠릅니다.

노트:use 를 사용하면 더욱 역동성을 얻을 수 있지만 dlopen()그 부분을 말하는 것 같지는 않습니다.

관련 정보