Librerie e linking in programmazione

Librerie e linking in programmazione

Quando si parla di linking in programmazione si fa riferimento al procedimento che riguarda l’integrazione dei diversi moduli relativi a un programma (librerie o sottoprogrammi) allo scopo di formare una singola unità eseguibile. Nello specifico, un linker o link editor (che dir si voglia), non è altro che un programma che si occupa di eseguire il collegamento – il link, appunto – tra le librerie del linguaggio di cui c’è bisogno per eseguire il programma e il programma oggetto, vale a dire la traduzione in linguaggio macchina del codice sorgente. Il programma viene denominato, negli OS/360 e negli altri mainframe IBM, “linkage editor”, mentre per le varianti di Unix al posto del termine linker a volte viene utilizzata l’espressione “loader”.

Per quel che concerne i codici oggetto, essi possono essere definiti come parti di programma che, oltre a contenere informazioni per il linker, includono anche il codice macchina. L’informazione è formata da definizione di simboli, che possono essere di due generi: simboli non definiti e non importati o simboli definiti. Questi ultimi sono simboli che rappresentano variabili o funzioni contenute nel modulo, e nel codice oggetto relativo, messe a disposizione in modo tale che possano essere sfruttate da altri moduli. I simboli non definiti e non importati, invece, rappresentano funzioni o variabili referenziate e non definite internamente, ma in moduli differenti.

Compito del linker è quello di risolvere i link ai simboli non definiti in modo da scoprire da quale modulo sono definiti, sostituendo ogni segnaposto con l’indirizzo del simbolo reale. Una libreria è, dunque, un insieme di moduli software che sono a disposizione e possono essere adoperati da altri programmi: tali moduli sono raccolti, in forma di codici oggetto, in un file contenitore unico e possono essere usati dai linker.

Alcuni di essi non comprendono nel programma di output tutta la libreria, ma unicamente le parti di cui c’è bisogno in quanto referenziate da altre librerie o da altro codice oggetto. Ci possono essere librerie di vario genere e di scopi differenti: le più diffuse sono quelle per il calcolo matematico o per l’interazione con l’hardware. In linea di massima, le librerie specifiche devono essere indicate dal programmatore in maniera esplicita, mentre le librerie comuni vengono usate in automatico.

Altra responsabilità del linker è quella di distribuire il codice oggetto (il software), nello spazio di indirizzi del programma. Il compilatore non sa in quale indirizzo di memoria si trova il codice di uno specifico modulo e di conseguenza ipotizza un indirizzo fisso che, quando i moduli saranno combinati in un unico codice eseguibile, verrà modificato. Si parla di rilocazione per indicare lo spostamento da un indirizzo a un altro di un segmento di codice: una procedura che può richiedere anche di ricalcolare gli indirizzi che vengono impiegati nelle istruzioni di salto assoluto. Infatti, se si sposta da un indirizzo a un altro un codice, è necessario modificare, dopo averli ricalcolati, la totalità degli indirizzi che puntano al codice stesso.

Nel momento in cui il programma, appena prima di essere eseguito, viene caricato in memoria, potrebbe essere richiesta dal programma eseguibile un’ulteriore rilocazione: un’operazione di cui, tuttavia, non c’è bisogno nei computer che possiedono un sistema di memoria virtuale, visto che qui tutti i programmi dispongono di uno spazio di indirizzamento privato. Per questo motivo, non c’è il rischio che tra programmi differenti sorgano dei conflitti problematici.