Che cos'è un binario rilocabile?

1

Che cos'è un binario rilocabile?

Ho provato a fare qualche ricerca su Google, ma sono ancora confuso.

Inoltre: qual è la differenza tra un binario eseguibile e rilocabile?

    
posta Hemang Bhogayata 31.03.2016 - 08:29
fonte

2 risposte

2

Sebbene questa sia stata accettata come risposta corrretta, la risposta di Basile descrive meglio l'uso corrente del termine. ovvero i dati utilizzati come input per un processo di collegamento e caricamento.

Tuttavia, ho sentito il termine usato per descrivere binario trasferibile come un eseguibile che può essere caricato in qualsiasi indirizzo di memoria, e non ha bisogno di alcun indirizzamento "fix-up" dopo il caricamento. (L'indirizzo di ingresso sarà ovviamente diverso a seconda di dove è stato caricato). Questo è più correttamente noto come codice indipendente dalla posizione.

La necessità di un codice indipendente dalla posizione era principalmente guidata da sistemi operativi in tempo reale, in cui i programmi venivano in genere eseguiti direttamente da EPROM o ROM e le correzioni non erano possibili.

All'inizio degli anni '90 ho lavorato con un tale sistema. Ho pensato che fosse OS-9 (non la versione Apple) come descritto in questo articolo di Wikipedea . Ma dopo averlo letto, potrei sbagliarmi. Ma lo chiamerò OS-9 comunque.

Affinché un sistema del genere funzioni, è necessario eseguire la mesh di più parti componenti:

  • Il set di istruzioni della CPU deve supportare strongmente l'indirizzamento relativo del contatore di programma. Le CPU Intel non hanno funzionato bene per programmi diversi, ma banali. I processori Motorola 68000 erano migliori, ma anche loro avevano bisogno di aiuto per emulare un'istruzione "long branch to subroutine".

  • I compilatori devono sapere per generare codice che utilizza sempre la ramificazione relativa. Devono anche sapere come emulare le istruzioni che la CPU non supporta in modo nativo.

  • Il sistema operativo deve supportare la ricerca di programmi in memoria e aggiungerli alle sue strutture di directory. OS-9 ha fatto questo passando attraverso lo spazio di memoria al momento dell'avvio (in incrementi di 4k?), Cercando un numero magico che identificasse un blocco di intestazione del programma. Se trovato, calcola un CRC dell'intestazione. Se questo corrisponde al CRC memorizzato nell'intestazione, allora calcola il CRC dell'intero programma. Se corrisponde a un altro valore nell'intestazione, il programma verrà aggiunto alla directory. Il vantaggio era che potevamo portare le nostre EPROM di diagnostica su un sito client, collegarle a qualsiasi slot vuoto sulla scheda CPU e riavviare - voilà che la diagnostica fosse disponibile.

Ma il codice indipendente della posizione è andato fuori moda per molte ragioni:

  • L'ascesa dell'architettura PC IBM, da cui il processore Intel, e quindi il set di istruzioni 8086.
  • RAM è diventato economico e di grandi dimensioni. Non c'era più bisogno di eseguire codice direttamente dalla memoria di sola lettura.
  • Gli hard disk sono diventati economici e onnipresenti. Poiché è necessario caricare un programma da un disco rigido nella memoria per l'esecuzione, l'esecuzione di alcuni codici banali per eseguire correzioni non è stato un grosso problema.
  • L'ascesa dei sistemi operativi portatili come Linux ha portato ad un accoppiamento più libero tra compilatore e codice macchina. Il codice indipendente dalla posizione era semplicemente una complessità che poteva essere eliminata.
  • Le librerie condivise sono un vero problema. L'indirizzo in cui è caricata la libreria non può essere conosciuto in anticipo, quindi è difficile collegare il codice indipendente dalla posizione al codice condiviso.

Quindi un'altra buona idea di calcolo sfuma nella cronologia e i binari rilocabili che richiedono correzioni sono ora comuni. In alcune lingue (ad esempio, Assembler e C) ci sono file che contengono il binario rilocabile. Altre lingue potrebbero nascondere questo passaggio, ad es. Java fa tutto all'interno della JVM e non vengono prodotti file intermedi.

    
risposta data 31.03.2016 - 10:13
fonte
4

La rilocazione è relativa a collegamento e caricamento. Leggi il libro di Levine Linker & Caricatori per i dettagli. Molto tempo fa (al inizio di Unix , anni '70) il kernel caricava e avviava un eseguibile semplicemente copiando blocchi - segmenti di memoria - dal disco alla RAM, ma oggi, con memoria virtuale & paging abilitando librerie condivise , le cose sono molto più complesse.

(Sto prendendo per lo più una prospettiva Linux sotto, ma suppongo che tu possa adattare la mia risposta al tuo sistema operativo.)

Di solito file oggetto (o librerie), talvolta chiamati binari rilocabili, contengono non solo alcune sezioni binarie (contenenti codice macchina e / o dati) ma anche alcune sezioni di relocation contenenti una sequenza di direttive di rilocazione per modificare il segmento che contiene la sezione al link o al tempo di caricamento. Anche alcuni eseguibili (in particolare quelli collegamento dinamico ) può contenere direttive di rilocazione ... Una direttiva di riposizionamento potrebbe essere: in memoria all'indirizzo A caricato dall'offset B nel file, sostituire i tre seguenti byte con i 24 bit più bassi di differenza tra A e il valore di il linker simbolo (ad es. l'indirizzo della funzione chiamata) printf

Leggi ulteriori informazioni su ELF e leggi ABI specifica pertinente al tuo sistema (es. questo per Linux / x86_64 ABI), per i dettagli sulle direttive di trasferimento particolari possibili sul tuo computer. Le direttive di ricollocazione effettive dipendono dal set di istruzioni & del processore. modalità di indirizzamento e flessibilità del linker o del kernel del sistema operativo.

Leggi anche il codice indipendente dalla posizione , auto-relocation , linker dinamico , ASLR . Vedi anche ld-linux (8) & elf (5) . Usa e gioca con readelf (1) , objdump(1) , ldd (1) per esplorare e comprendere alcuni particolari binari ELF (ad esempio /bin/ls ), ed eseguirlo con strace (1) per capire le chiamate di sistema (elencate in syscalls (2) ...) coinvolto durante l'esecuzione. Vedi anche execve (2) & leggi Programmazione Linux avanzata per ottenere un'immagine più ampia.

In alcuni sistemi, le direttive di ricollocazione (in realtà alcuni bytecode per il linker) possono essere abbastanza complesse da renderle < a href="https://en.wikipedia.org/wiki/Turing_completeness"> Turing completo (iirc, alcune versioni di HPUX per alcuni processori RISC HPPA hanno avuto ricollocazioni molto complesse, con condizionali, aritmetica, loop).

E potresti considerare che l' ottimizzazione del tempo di collegamento potrebbe essere vista come una delocalizzazione molto complessa; ma la maggior parte delle persone la vede come una strana ottimizzazione del compilatore che si verifica al momento del collegamento (in effetti, il confine tra compilation & linking & amp ; la corsa non è chiara, vedi anche compilazione just-in-time ).

    
risposta data 31.03.2016 - 09:16
fonte

Leggi altre domande sui tag