동적 링커 / 로더 자체는 어떻게`file`에 의해보고 된대로 동적으로 링크 될 수 있습니까?

(동적 링커 / 로더) /bin/bash를 포함하는 의 공유 객체 종속성을 고려하십시오 /lib64/ld-linux-x86-64.so.2.

ldd /bin/bash
    linux-vdso.so.1 (0x00007fffd0887000)
    libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007f57a04e3000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f57a04de000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f57a031d000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f57a0652000)

검사 /lib64/ld-linux-x86-64.so.2는 다음과의 심볼릭 링크임을 보여줍니다 /lib/x86_64-linux-gnu/ld-2.28.so.

ls -la /lib64/ld-linux-x86-64.so.2
lrwxrwxrwx 1 root root 32 May  1 19:24 /lib64/ld-linux-x86-64.so.2 -> /lib/x86_64-linux-gnu/ld-2.28.so

또한 file보고서 /lib/x86_64-linux-gnu/ld-2.28.so자체는 동적으로 연결됩니다.

file -L /lib64/ld-linux-x86-64.so.2
/lib64/ld-linux-x86-64.so.2: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=f25dfd7b95be4ba386fd71080accae8c0732b711, stripped

알고 싶습니다 :

  1. 동적 링커 / 로더 ( /lib64/ld-linux-x86-64.so.2) 자체를 어떻게 동적으로 링크 할 수 있습니까? 런타임에 자체적으로 연결됩니까?
  2. /lib/x86_64-linux-gnu/ld-2.28.so.out 바이너리 ( man ld.so) 를 처리하도록 문서화 되었지만 /bin/bashELF 실행 파일입니까?

프로그램 ld.so는 오래 전에 사용 된 형식 인 a.out 바이너리를 처리합니다. ld-linux.so * (libc5의 경우 /lib/ld-linux.so.1, glibc2의 경우 /lib/ld-linux.so.2)는 모든 사람들이 수년간 사용해 온 ELF를 처리합니다.



답변

  1. 예, 초기화 될 때 연결됩니다. 기술적으로 동적 링커는 객체 해상도와 위치 변경이 필요하지 않습니다. 그대로 해석되므로 심볼을 정의하고 바이너리를 해석 할 때 심볼을 처리해야하며, 해석되어 해당 심볼이 업데이트됩니다. 로드 된 라이브러리에서의 구현을 가리 킵니다. 특히, 이는 영향을 미칩니다 malloc. 링커에는 해당하는 기호가있는 최소 버전이 내장되어 있지만 C 라이브러리의 버전이로드 및 재배치되면 (또는 경우에 따라 삽입 된 버전이 있으면) C 라이브러리 버전으로 대체됩니다. 링커가 파손될 수있는 지점에서 발생하지 않도록하기 위해 수행되었습니다.

    피투성이의 세부 사항에 rtld.c에, dl_main기능.

    그러나 ld.so외부 종속성이 없습니다. 당신은 관련된 기호를 볼 수 있습니다 nm -D; 그들 중 어느 것도 정의되지 않았습니다.

  2. 맨 페이지는 /lib, /lib/ld.so (을 지원하는 libc 5 동적 링커 a.out) 및 /lib*/ld-linux*.so*(ELF를 지원하는 libc 6 동적 링커 ) 바로 아래의 항목 만 참조합니다 . 맨 페이지는 매우 구체적 ld.so이며 그렇지 않습니다 ld-2.28.so.

    현재 대다수의 시스템에서 발견되는 동적 링커에는 a.out지원이 포함되어 있지 않습니다 .

file그리고 ldd그들은 정적으로 링크 된 바이너리를 구성하는 것에 대한 다른 정의를 가지고 있기 때문에 동적 링커를 위해 다른 일을보고한다. 의 경우 ldd, 바이너리가 DT_NEEDED심볼 이없는 경우 , 정의되지 않은 심볼 이없는 경우 바이너리는 정적으로 링크 됩니다. 의 경우 fileELF 바이너리는 PT_DYNAMIC섹션 이없는 경우 정적으로 링크됩니다 (이는 file5.37 이후 릴리스에서 변경됨) . 섹션 의 존재를PT_INTERP 동적으로 링크 된 바이너리의 지표로 사용합니다. 코드).

GNU C 라이브러리 동적 링커에는 DT_NEEDED기호가 없지만 PT_DYNAMIC섹션이 있습니다 (기술적으로 공유 라이브러리이므로). 결과적으로 ldd(동적 링커)는 정적으로 연결되어 있지만 file동적으로 연결되어 있음을 나타냅니다. 그것은없는 PT_INTERP의 다음 릴리스 있도록 섹션 file것 또한이 정적으로 링크 된 것을 나타냅니다.

$ ldd /lib64/ld-linux-x86-64.so.2
        statically linked

$ file $(readlink /lib64/ld-linux-x86-64.so.2)
/lib/x86_64-linux-gnu/ld-2.28.so: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=f25dfd7b95be4ba386fd71080accae8c0732b711, stripped

( file5.35)

$ file $(readlink /lib64/ld-linux-x86-64.so.2)
/lib/x86_64-linux-gnu/ld-2.28.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=f25dfd7b95be4ba386fd71080accae8c0732b711, stripped

(현재 개발중인 버전의 file).


답변

  1. file동적 링커 / 로더가 동적으로 자체 연결되어 있다는 점 에서 프로그램이 잘못 되었다고 생각합니다 . ldd프로그램은 동의하지 않습니다. 적어도 내 시스템에는 없습니다 (Debian Stretch) :

    ldd /lib/x86_64-linux-gnu/ld-2.24.so
        statically linked
    
  2. man ld.so“ld-linux.so *는 ELF를 처리합니다”라고 읽습니다 . 귀하의 시스템에서 (그리고 내 방식으로도) 둘 다 ELF와 (오래된 구식) a.out 형식을 모두 처리 할 수 ​​있다고 생각하는 동일한 이진에 대한 심볼릭 링크입니다.