Come può il linker / loader dinamico stesso essere collegato dinamicamente come riportato da `file`?


12

Considera le dipendenze degli oggetti condivisi di /bin/bash, che include /lib64/ld-linux-x86-64.so.2(linker / caricatore dinamico):

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)

L'ispezione /lib64/ld-linux-x86-64.so.2mostra che si tratta di un collegamento simbolico a /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

Inoltre, i filerapporti /lib/x86_64-linux-gnu/ld-2.28.soa se stessi sono collegati dinamicamente:

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

Mi piacerebbe sapere

  1. Come si può /lib64/ld-linux-x86-64.so.2collegare dinamicamente il linker / loader ( ) stesso in modo dinamico? Si collega in fase di esecuzione?
  2. /lib/x86_64-linux-gnu/ld-2.28.soè documentato per gestire a.out binaries ( man ld.so), ma /bin/bashè un eseguibile ELF?

Il programma ld.so gestisce i binari a.out, un formato usato molto tempo fa; ld-linux.so * (/lib/ld-linux.so.1 per libc5, /lib/ld-linux.so.2 per glibc2) gestisce ELF, che tutti usano da anni.


Al kernel non interessano queste sottili sottigliezze tassonomiche (e nemmeno voi dovreste ;-)). Il kernel fa solo la differenza tra ELF che hanno bisogno di un interprete e quelli che non lo fanno. E AFAIK, non puoi usare un interprete che a sua volta ne ha bisogno.
mosvy,

La mia @StephenKitt non ha ( /lib/x86_64-linux-gnu/ld-2.28.so, debian 10 buster)
mosvy,

@mosvy sì, scusa, mi sono confuso tra fileil commento errato su come definisce i binari statici e la realtà di ld-2.28.so... Il differenziatore è PT_DYNAMIC.
Stephen Kitt,

Risposte:


17
  1. Sì, si collega quando si inizializza. Tecnicamente il linker dinamico non ha bisogno della risoluzione e del riposizionamento degli oggetti per sé, poiché è completamente risolto così com'è, ma definisce i simboli e deve occuparsene quando risolve il binario che sta "interpretando", e quei simboli vengono aggiornati per puntare alle loro implementazioni nelle librerie caricate. In particolare, ciò influisce malloc: il linker ha una versione minima integrata, con il simbolo corrispondente, ma viene sostituito dalla versione della libreria C una volta caricata e trasferita (o anche da una versione interposta se ce n'è una), con una certa cura preso per garantire che ciò non accada in un punto in cui potrebbe interrompere il linker.

    I dettagli gory sono dentro rtld.c, nella dl_mainfunzione.

    Si noti tuttavia che ld.sonon ha dipendenze esterne. Puoi vedere i simboli coinvolti nm -D; nessuno di questi è indefinito.

  2. La manpage si riferisce solo alle voci direttamente sotto /lib, ovvero /lib/ld.so (il linker dinamico libc 5, che supporta a.out) e /lib*/ld-linux*.so*(il linker dinamico libc 6, che supporta ELF). La manpage è molto specifica e ld.sonon lo è ld-2.28.so.

    Il linker dinamico trovato nella stragrande maggioranza dei sistemi attuali non include il a.outsupporto.

filee lddriportano cose diverse per il linker dinamico perché hanno definizioni diverse di ciò che costituisce un binario staticamente collegato. Infatti ldd, un binario è staticamente collegato se non ha DT_NEEDEDsimboli, cioè senza simboli indefiniti. Infatti file, un binario ELF è staticamente collegato se non ha una PT_DYNAMICsezione (questo cambierà nel rilascio del fileseguente 5.37; ora utilizza la presenza di una PT_INTERPsezione come indicatore di un binario collegato dinamicamente, che corrisponde al commento in il codice).

Il linker dinamico della libreria GNU C non ha alcun DT_NEEDEDsimbolo, ma ha una PT_DYNAMICsezione (dal momento che è tecnicamente una libreria condivisa). Di conseguenza, ldd(che è il linker dinamico) indica che è staticamente collegato, ma fileindica che è collegato dinamicamente. Non ha una PT_INTERPsezione, quindi la prossima versione di fileindicherà anche che è staticamente collegata.

$ 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 versione attualmente in sviluppo di file).


Perché la parola "interpretazione" viene utilizzata nel contesto del collegamento dinamico? Quella parola è di solito usata nel contesto di linguaggi di programmazione.
Shuzheng,

Cosa intendi con "linker dinamico della libreria GNU C"? Ti riferisci a /lib*/ld-linux*.so*un terzo linker dinamico?
Shuzheng,

Dove puoi vedere lddsegnala il linker dinamico come staticamente collegato? Perché il suo elenco di dipendenze di oggetti condivisi è vuoto?
Shuzheng,

I programmi collegati dinamicamente necessitano di un po 'di lavoro fatto prima di poter essere eseguiti; quel lavoro viene svolto dal linker dinamico, che finisce per svolgere un ruolo simile a quello di un interprete: interpreta le tabelle di trasferimento ecc. per produrre qualcosa che il computer può eseguire.
Stephen Kitt,

Quando dico "linker dinamico della libreria GNU C", mi riferisco all'implementazione inclusa nella libreria GNU C, generalmente fornita come /lib*/ld-linux*.so*. Ho specificato l'origine del linker dinamico perché ci sono altre implementazioni disponibili per Linux.
Stephen Kitt,

0
  1. Ho il sospetto che il fileprogramma abbia torto sul fatto che il linker / loader sia dinamicamente collegato a se stesso. Il lddprogramma non è d'accordo. Almeno non sul mio sistema (Debian Stretch):

    ldd /lib/x86_64-linux-gnu/ld-2.24.so
        statically linked
    
  2. man ld.solegge anche: "ld-linux.so * gestisce ELF" . Sul tuo sistema (e anche il mio) entrambi sono collegamenti simbolici allo stesso binario che deduco sia in grado di gestire sia il formato ELF che il (vecchio obsoleto) a.out.


quali informazioni aggiungi alla risposta accettata?
miracolo173

2
@ miracle173 questa risposta è più vecchia della risposta accettata ;-).
Stephen Kitt,

hai ragione. Mi è mancato questo. Pensavo che la domanda e la risposta accettata fossero molto vecchie e questa risposta è stata pubblicata nelle ultime ore. Non posso annullare il mio downvote finché qualcuno non modifica il post.
miracolo173
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.