¿Cómo se puede vincular dinámicamente el enlazador / cargador dinámico como se informa en `file`?

12

Considere las dependencias de objetos compartidos de /bin/bash, que incluye /lib64/ld-linux-x86-64.so.2(enlazador / cargador dinámico):

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)

La inspección /lib64/ld-linux-x86-64.so.2muestra que es un enlace simbólico para /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

Además, los fileinformes /lib/x86_64-linux-gnu/ld-2.28.sopara sí mismo se vincularán dinámicamente:

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

Me gustaría saber:

  1. ¿Cómo se puede /lib64/ld-linux-x86-64.so.2vincular dinámicamente el enlazador / cargador ( ) en sí? ¿Se vincula en tiempo de ejecución?
  2. /lib/x86_64-linux-gnu/ld-2.28.soestá documentado para manejar a.out binarios ( man ld.so), pero ¿ /bin/bashes un ELF ejecutable?

El programa ld.so maneja a.out binarios, un formato usado hace mucho tiempo; ld-linux.so * (/lib/ld-linux.so.1 para libc5, /lib/ld-linux.so.2 para glibc2) maneja ELF, que todo el mundo ha estado utilizando durante años.

Shuzheng
fuente
Al núcleo no le importan esas sutiles sutilezas taxonómicas (y a usted tampoco debería ;-)). El núcleo solo hace la diferencia entre los ELF que necesitan un intérprete y los que no. Y AFAIK, no puede usar un intérprete que sí necesita uno.
mosvy
@StephenKitt mine no tiene ( /lib/x86_64-linux-gnu/ld-2.28.so, debian 10 buster)
mosvy
@mosvy sí, lo siento, me confundí con fileel comentario erróneo de cómo define los binarios estáticos y la realidad de ld-2.28.so... El diferenciador es PT_DYNAMIC.
Stephen Kitt el

Respuestas:

17
  1. Sí, se vincula cuando se inicializa. Técnicamente, el enlazador dinámico no necesita resolución de objetos y reubicación por sí mismo, ya que está completamente resuelto tal como está, pero sí define símbolos y debe cuidarlos cuando resuelve el binario que está "interpretando", y esos símbolos se actualizan para señalar sus implementaciones en las bibliotecas cargadas. En particular, esto afecta malloc: el enlazador tiene una versión mínima incorporada, con el símbolo correspondiente, pero que se reemplaza por la versión de la biblioteca C una vez que se carga y se reubica (o incluso por una versión interpuesta si hay una), con algo de cuidado tomado para asegurar que esto no suceda en un punto donde pueda romper el enlazador.

    Los detalles sangrientos están rtld.cen la dl_mainfunción.

    Sin embargo, ld.sotenga en cuenta que no tiene dependencias externas. Puedes ver los símbolos involucrados con nm -D; ninguno de ellos es indefinido.

  2. La página de manual solo se refiere a las entradas directamente debajo /lib, es decir /lib/ld.so (el enlazador dinámico libc 5, que admite a.out) y /lib*/ld-linux*.so*(el enlazador dinámico libc 6, que admite ELF). La página de manual es muy específica, y ld.sono lo es ld-2.28.so.

    El enlazador dinámico que se encuentra en la gran mayoría de los sistemas actuales no incluye a.outsoporte.

filee lddinforman diferentes cosas para el enlazador dinámico porque tienen diferentes definiciones de lo que constituye un binario enlazado estáticamente. Para ldd, un binario está estáticamente vinculado si no tiene DT_NEEDEDsímbolos, es decir , no tiene símbolos indefinidos. Para file, un binario ELF está vinculado estáticamente si no tiene una PT_DYNAMICsección (esto cambiará en el lanzamiento del filesiguiente 5.37; ahora usa la presencia de una PT_INTERPsección como el indicador de un binario vinculado dinámicamente, que coincide con el comentario en el código).

El enlazador dinámico de la biblioteca GNU C no tiene ningún DT_NEEDEDsímbolo, pero tiene una PT_DYNAMICsección (ya que técnicamente es una biblioteca compartida). Como resultado, ldd(que es el vinculador dinámico) indica que está vinculado estáticamente, pero fileindica que está vinculado dinámicamente. No tiene una PT_INTERPsección, por lo que la próxima versión de filetambién indicará que está vinculada estáticamente.

$ 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

(con 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

(con la versión actualmente en desarrollo de file).

Stephen Kitt
fuente
¿Por qué se usa la palabra "interpretar" en el contexto de la vinculación dinámica? Esa palabra se usa generalmente en el contexto de lenguajes de programación.
Shuzheng el
¿Qué quiere decir con "enlazador dinámico de la biblioteca GNU C"? ¿Te refieres a /lib*/ld-linux*.so*un tercer enlazador dinámico?
Shuzheng
¿Dónde puede ver los lddinformes del enlazador dinámico como enlazados estáticamente? ¿Porque su lista de dependencias de objetos compartidos está vacía?
Shuzheng el
Los programas vinculados dinámicamente necesitan que se les haga un trabajo antes de poder ejecutarse; ese trabajo lo realiza el enlazador dinámico, que termina jugando un papel similar al de un intérprete: interpreta las tablas de reubicación, etc. para producir algo que la computadora pueda ejecutar.
Stephen Kitt el
Cuando digo "enlazador dinámico de la biblioteca GNU C", me refiero a la implementación incluida en la biblioteca GNU C, que generalmente se envía como /lib*/ld-linux*.so*. Especifiqué el origen del enlazador dinámico porque hay otras implementaciones disponibles para Linux.
Stephen Kitt el
0
  1. Sospecho que el fileprograma está equivocado acerca de que el enlazador / cargador dinámico se vincula dinámicamente. El lddprograma no está de acuerdo. Al menos no en mi sistema (Debian Stretch):

    ldd /lib/x86_64-linux-gnu/ld-2.24.so
        statically linked
    
  2. man ld.sotambién se lee: "ld-linux.so * maneja ELF" . En su sistema (y el mío también por cierto) ambos son enlaces simbólicos al mismo binario que deduzco que es capaz de manejar tanto ELF como el formato a.out (antiguo obsoleto).

Hkoof
fuente
¿Qué información agrega a la respuesta aceptada?
milagro173
2
@ miracle173 esta respuesta es anterior a la respuesta aceptada ;-).
Stephen Kitt
tienes razón. Me perdí esto. Pensé que la pregunta y la respuesta aceptada son muy antiguas y esta respuesta se publicó en las últimas horas. No puedo deshacer mi voto negativo hasta que alguien modifique la publicación.
milagro173