Domanda

Quando si compilano librerie condivise in gcc, l'opzione -fPIC compila il codice come indipendente dalla posizione. C'è qualche motivo (prestazioni o altro) per cui non dovresti compilare tutta la posizione del codice indipendente?

È stato utile?

Soluzione

Aggiunge un riferimento indiretto. Con il codice indipendente dalla posizione devi caricare l'indirizzo della tua funzione e poi saltarci sopra. Normalmente l'indirizzo della funzione è già presente nel flusso di istruzioni.

Altri suggerimenti

Sì, ci sono motivi di prestazioni. Alcuni accessi sono effettivamente sotto un altro livello di riferimento indiretto per ottenere la posizione assoluta in memoria.

Esiste anche la GOT (tabella di offset globale) che memorizza gli offset delle variabili globali. Per me, questo sembra solo una tabella di correzione IAT, che è classificata come dipendente dalla posizione da Wikipedia e da alcune altre fonti.

http://en.wikipedia.org/wiki/Position_independent_code

Questo articolo spiega come funziona PIC e lo confronta con l'alternativa - trasferimento del tempo di caricamento . Penso che sia pertinente per la tua domanda.

Oltre alla risposta accettata. Una cosa che danneggia molto le prestazioni del codice PIC è la mancanza di "quotazione relativa dell'IP". su x86. Con "quotazione relativa IP" potresti chiedere dati che sono X byte dal puntatore dell'istruzione corrente. Ciò renderebbe il codice PIC molto più semplice.

Salti e chiamate, di solito sono relativi all'EIP, quindi quelli non rappresentano un problema. Tuttavia, l'accesso ai dati richiederà un piccolo trucco in più. A volte, un registro sarà temporaneamente riservato come "puntatore di base" ai dati richiesti dal codice. Ad esempio, una tecnica comune è quella di abusare del modo in cui le chiamate funzionano su x86:

call label_1
.dd 0xdeadbeef
.dd 0xfeedf00d
.dd 0x11223344
label_1:
pop ebp            ; now ebp holds the address of the first dataword
                   ; this works because the call pushes the **next**
                   ; instructions address
                   ; real code follows
mov eax, [ebp + 4] ; for example i'm accessing the '0xfeedf00d' in a PIC way

Questa e altre tecniche aggiungono un livello di riferimento indiretto agli accessi ai dati. Ad esempio, la GOT (Global offset table) utilizzata dai compilatori gcc.

x86-64 ha aggiunto un "RIP relativo" modalità che semplifica le cose molto .

Perché l'implementazione del codice indipendente di posizione completa aggiunge un vincolo al generatore di codice che può impedire l'uso di operazioni più veloci o aggiungere ulteriori passaggi per preservare tale vincolo.

Questo potrebbe essere un compromesso accettabile per ottenere il multiprocessing senza un sistema di memoria virtuale, in cui ti fidi dei processi per non invadere la memoria dell'altro e potrebbe essere necessario caricare una particolare applicazione in qualsiasi indirizzo di base.

In molti sistemi moderni i compromessi delle prestazioni sono diversi e un caricatore di trasferimento è spesso meno costoso (costa ogni volta che il codice viene caricato per la prima volta) rispetto al meglio che un ottimizzatore può fare se ha un regno libero. Inoltre, la disponibilità di spazi di indirizzi virtuali nasconde in primo luogo la maggior parte della motivazione per l'indipendenza della posizione.

Inoltre, l'hardware di memoria virtuale nei processori più moderni (utilizzato dalla maggior parte dei sistemi operativi moderni) significa che un sacco di codice (tutte le app dello spazio utente, salvo l'uso eccentrico di mmap o simili) non deve essere indipendente dalla posizione. Ogni programma ha il proprio spazio di indirizzi che a suo avviso inizia da zero.

codice indipendente dalla posizione ha un sovraccarico prestazionale sulla maggior parte dell'architettura, perché richiede un registro aggiuntivo.

Quindi, questo è a scopo prestazionale.

Oggi il sistema operativo e il compilatore di default rendono tutto il codice come codice indipendente dalla posizione. Prova a compilare senza il flag -fPIC, il codice verrà compilato correttamente ma riceverai solo un avviso. Come Windows, usa una tecnica chiamata come mapping di memoria per raggiungere questo obiettivo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top