2009-05-31 9 views
6

All'inizio sembra una domanda stupida, ma sopporta me.Quale parte (in particolare) di un eseguibile nativo lo rende non portatile?

È risaputo che i file binari per un'architettura CPU non vengono eseguiti su altri. Quindi, ad esempio, è impossibile eseguire (senza un livello di compatibilità di qualche tipo), un binario x86 su un chip sparc64. I set di istruzioni sono diversi, quindi chiaramente non funzionerà.

Ma quando il binario è per la stessa CPU, ma per un diverso sistema operativo, quale parte del codice impedisce l'esecuzione possibile. Ad esempio, eseguendo un file binario di Solaris x86 su una macchina Linux x86. Presumo che esista un qualche tipo di stub specifico della piattaforma che si riferisce al linker di runtime o all'utilità di pianificazione dei processi?

Sarei interessato a sapere. Grazie.

risposta

12

Ci sono una serie di ragioni. I principali, ordinati in "distanza dal metallo" sono:

  1. I sistemi operativi possono avere diversi formati binari per i file eseguibili. In questo caso non sarai in grado di caricare il file binario in primo luogo.
  2. Il programma può utilizzare un altro metodo per indicare che desiderano effettuare una chiamata di sistema (ad esempio INT21 vs INT80).
  3. Il programma può fare affidamento su chiamate di sistema che non sono presenti nell'altro SO (ad esempio dlopen())
  4. Il programma può fare affidamento sulla libreria standard non presente sull'altro sistema operativo.
  5. Il programma può fare affidamento su altre librerie che non sono disponibili sull'altro sistema operativo.

Naturalmente ci sono molti altri modi in cui un programma in esecuzione in un ambiente inaspettato può fallire in modo spettacolare.

+1

I motivi 1, 2 e 3 sono molto facili da risolvere. Linux supporta già un gran numero di formati eseguibili. Nuove interruzioni potrebbero essere create con un modulo kernel caricabile. E le chiamate di sistema di solito corrispondono abbastanza bene tra diversi SO. – Zifre

+0

Avrei dovuto dire che stiamo assumendo ELF :) Grazie per la risposta. –

1

Sono librerie specifiche di sistema che non sono sempre portatili. Ad esempio, non puoi usare l'API della finestra win32 su vanilla linux (e sì, mi rendo conto che ci sono degli arround per questo come il vino, non è il miglior esempio).

3

Sono principalmente le API. Ad esempio, le API Win32 non sono realmente disponibili su Linux. È possibile aggirare questo problema, vedere Wine. Il formato eseguibile potrebbe anche essere diverso (ELF/PE), ma potrebbe essere risolto abbastanza facilmente (Wine lo fa, consente agli eseguibili PE di essere eseguiti su Linux).

Inoltre, il tuo esempio di mixaggio di eseguibili Solaris e Linux sarebbe abbastanza facile da implementare, dal momento che i SO sono così simili (ELF per il formato eseguibile, API POSIX, sistema X window, ecc.). FreeBSD può già eseguire eseguibili di Linux. Il motivo per cui questo non è così comune è semplicemente che non c'è molta richiesta. Esistono molti più programmi Windows rispetto ai programmi * NIX, quindi Wine è stato creato. Ci sono molti più programmi Linux rispetto ai programmi FreeBSD, quindi FreeBSD ha implementato il livello di compatibilità di Linux. Solaris potrebbe eventualmente implementare qualcosa di simile. Tuttavia, non aspettatevi il contrario (eseguibili Solaris/BSD su Linux), poiché non vi è alcuna richiesta.

1

Librerie di sistema e API. Il codice semplice effettivo dovrebbe funzionare. Questo è il motivo per cui i layer come Wine non eseguono alcuna emulazione della CPU, ma implementano nuovamente l'API di Windows.

0

Come già sottolineato, l'incompatibilità ha meno a che fare con i formati eseguibili stessi delle librerie a cui fa riferimento un eseguibile.

credo Linux è in realtà compatibile con una serie di diversi formati eseguibili anche se potrei sbagliarmi qui

5

ci sono quattro problemi:

  1. diversi sistemi operativi pacchetto loro eseguibili binari in modo diverso (ad esempio Linux ELF vs formato di Windows);
  2. Set di istruzioni differenti su diverse architetture della CPU;
  3. Diversi sistemi operativi hanno chiamate di sistema diverse (ad esempio CreateProcess() in Win32 vs fork() in Linux/Unix);
  4. Differenze quali percorsi, caratteri legali, separatori di directory e così via.

Si presume che le librerie non di sistema siano presenti su entrambi, altrimenti questa è un'altra differenza.

1

In aggiunta a ciò che altri hanno detto, il formato effettivo dell'eseguibile può essere diverso. Quindi, quando il sistema operativo viene a caricarlo, non trova i valori che si aspetta per il codice, i segmenti di dati ecc. Nei punti giusti del file.

+1

Ancora, potrebbe essere risolto abbastanza facilmente. Linux supporta già molti formati eseguibili. Anche il vino lo fa. Le librerie sono un fattore * molto * più grande del formato eseguibile. – Zifre

2

Oltre al formato binario e ad altre funzionalità di "packaging" (che potrebbero non essere esattamente banali) Ci sono anche le conseguenze che si trovano in quasi tutti i frammenti di codice. Roba come

  1. PIC potrebbe far sì che ogni accesso globale si basi su ipotesi specifiche del sistema sul ricaricamento del puntatore GOT e ipotesi su offset aggiuntivi.
  2. Molti sistemi hanno una determinata ABI, passando piccoli le strutture in registri, saltando registri per scopi di allineamento, riservando registri per scopi speciali Alcuni hanno vari (come ARM EABI e OABI) questioni
  3. locale di thread relativi, variabili che sono un'istanza per thread sono strettamente accoppiati alle strutture specificate dal sistema operativo. Registro scelta, offset, ecc.
  4. Alcune finestre OS (in particolare) supportano un determinato formato di gestione delle eccezioni per consentire la gestione delle eccezioni cross-language e anche cross-machine (tramite DCOM).
  5. I sistemi di programmi incrociati di livello superiore (come COM, ma anche l'interoperabilità Objective C su Mac o la compatibilità con una determinata versione di KDE-gcc) potrebbero anche avere determinati requisiti sul layout VMT.
  6. Alcuni linker e formati supportano gli offset negativi a una sezione, altri no.

Si noti che questo è solo un braindump di cose che potrebbero essere interessanti da esaminare. Probabilmente non è completo, e non tutti potrebbero applicarsi. Alcuni dei punti sopra potrebbero sovrapporsi (ad esempio prenotare un registro per TLS o PIC è anche un cambiamento ABI)

Problemi correlati