Linux, GNU GCC, ld, script di versione e formato binario ELF - Come funziona?


13

Sto cercando di saperne di più sul controllo delle versioni delle librerie in Linux e su come far funzionare tutto. Ecco il contesto:

- Ho due versioni di una libreria dinamica che espongono lo stesso set di interfacce, diciamo libsome1.soe libsome2.so.

- Un'applicazione è collegata libsome1.so.

- Questa applicazione usa libdl.soper caricare dinamicamente un altro modulo, diciamo libmagic.so.

- Ora libmagic.soè collegato contro libsome2.so. Ovviamente, senza utilizzare gli script del linker per nascondere i simboli libmagic.so, in fase di esecuzione tutte le chiamate alle interfacce libsome2.sovengono risolte libsome1.so. Ciò può essere confermato controllando il valore restituito dal libVersion()valore della macro LIB_VERSION.

- Quindi provo a compilare e collegare libmagic.socon uno script di linker che nasconde tutti i simboli tranne 3 che sono definiti in libmagic.soe sono esportati da esso. Funziona ... O almeno libVersion()e i LIB_VERSIONvalori corrispondono (e riporta la versione 2 non 1).

- Tuttavia, quando alcune strutture di dati sono serializzate su disco, ho notato un po 'di corruzione. Nella directory dell'applicazione se elimino libsome1.soe creo un collegamento soft al suo posto a cui puntare libsome2.so, tutto funziona come previsto e la stessa corruzione non si verifica.

Non posso fare a meno di pensare che ciò potrebbe essere causato da un conflitto nella risoluzione dei simboli del linker di runtime. Ho provato molte cose, come cercare di collegare in libsome2.somodo che tutti i simboli siano allineati symbol@@VER_2(di cui sono ancora confuso perché il comando nm -CD libsome2.soelenca ancora i simboli come symbole non symbol@@VER_2) ... Niente sembra funzionare !!! Aiuto!!!!!!


Il tuo ultimo approccio è quello con cui avrei iniziato. E sono d'accordo sul fatto che la corruzione è probabilmente un po 'di confusione simbolica. Purtroppo non ho una risposta per te.
RobotHumans,

questo potrebbe fare di meglio su SO, anche se non lo capisco abbastanza per dirlo con certezza. segnalalo se desideri che lo spostiamo.
xenoterracide,

1
Prova i flag di apertura RTLD_LOCALe RTLD_DEEPBINDapri nell'app. Non ho tempo di provarlo ora, ma dovrebbe funzionare in base alla manpage.
stribika,

Risposte:


13

Questo non risponde esattamente alla tua domanda, ma ...

Innanzitutto, ELF è la specifica utilizzata da Linux per file eseguibili (programmi), librerie condivise e anche file oggetto che sono i file intermedi trovati durante la compilazione del software. I file oggetto finiscono in .o, le librerie condivise terminano con .so seguito da zero o più cifre separate da punti e i file eseguibili non hanno alcuna estensione normalmente.

Esistono in genere tre moduli per nominare una libreria condivisa, il primo modulo termina semplicemente in .so. Ad esempio, una libreria chiamata readline è memorizzata in un file chiamato libreadline.so e si trova normalmente in uno di / lib, / usr / lib o / usr / local / lib. Tale file si trova durante la compilazione del software con un'opzione come -lreadline. -l dice al compilatore di collegarsi alla seguente libreria. Poiché le biblioteche cambiano di volta in volta, potrebbe diventare obsoleto, quindi le biblioteche incorporano qualcosa chiamato SONAME. Il SONAME per readline potrebbe apparire come libreadline.so.2 per la seconda versione della versione principale di libreadline. Potrebbero esserci anche molte versioni secondarie di readline compatibili e che non richiedono la ricompilazione del software. Una versione minore di readline potrebbe essere denominata libreadline.so.2.14. Normalmente libreadline. così è solo un collegamento simbolico alla versione principale più recente di readline, libreadline.so.2 in questo caso. libreadline.so.2 è anche un collegamento simbolico a libreadline.so.2.14 che è in realtà il file utilizzato.

Il SONAME di una libreria è incorporato nel file della libreria stessa. Da qualche parte all'interno del file libreadline.so.2.14 è presente la stringa libreadline.so.2. Quando un programma viene compilato e collegato con readline, cercherà il file libreadline.so e leggerà il SONAME incorporato in esso. Successivamente, quando il programma viene effettivamente eseguito, caricherà libreadline.so.2, non solo libreadline.so, poiché quello era il SONAME che veniva letto al primo collegamento. Ciò consente a un sistema di avere più versioni incompatibili di readline installate e ogni programma caricherà la versione principale appropriata a cui era collegato. Inoltre, quando aggiorno readline, diciamo, a 2.17, posso semplicemente installare libreadline.so.2.17 insieme alla libreria esistente, e una volta spostato il collegamento simbolico libreadline.so.2 da libreadline.so.2.13 a libreadline.so.2.17,

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.