Sto sviluppando per una piattaforma incorporata e sto avendo difficoltà a capire come collegare dinamicamente le librerie condivise. Sto usando il formato di file bFLT e non ho il controllo su dove è caricato il file eseguibile e la libreria condivisa.Codice di posizione indipendente, librerie condivise e faccette di codice - per farle funzionare insieme
Il mio caricatore carica correttamente la libreria condivisa e l'eseguibile in memoria e modifica il GOT dell'eseguibile in fase di esecuzione per collegarsi alla libreria condivisa.
Posso prendere con successo l'indirizzo della funzione e so che è corretto dal disassemblare il codice in quella posizione. Tuttavia, se provo a chiamare la funzione, l'intera cosa si blocca.
Si scopre che GCC aggiunge un "pacchetto di codice" quando chiama le funzioni di libreria condivisa e prende una deviazione quando viene chiamata la funzione e non si dirige effettivamente verso l'indirizzo della funzione. L'indirizzo a cui il codice si ramifica è non riposizionato correttamente perché non viene visualizzato nell'elenco di rilocazioni nel file eseguibile.
Lo smontaggio del rivestimento si presenta così:
000008d0 <__library_call_veneer>:
8d0: e51ff004 ldr pc, [pc, #-4] ; 8d4 <__library_call_veneer+0x4>
8d4: 03000320 .word 0x03000320 ; This address isn't correctly relocated!
Se prendo l'indirizzo della funzione e metterlo in un puntatore a funzione (quindi, bypassando il 'codice di rivestimento') e lo chiamano, il la biblioteca condivisa funziona perfettamente.
Così, per esempio:
#define DIRECT_LIB_CALL(x, args...) do { \
typeof(x) * volatile tmp = x; \
tmp(#args); \
} while (0)
DIRECT_LIB_CALL(library_call); /* works */
library_call(); /* crashes */
C'è un modo per entrambi, dire a GCC di non produrre una patina di codice e il ramo direttamente all'indirizzo situato nel GOT o in qualche modo rendere l'indirizzo che i rami impiallacciatura codice apparire nella lista delle delocalizzazioni da eseguire?
State dichiarando i prototipi della libreria usando extern C? –
Sto compilando sotto C così extern "C" sarebbe ridondante, non è vero? – tangrs
Le impiallacciature sono più o meno necessarie sui sistemi ARM, rendendo l'impiallacciatura la cosa giusta da fare. Tuttavia, non aggiornare l'indirizzo non è ... Guardando il tuo formato di file, http://docs.blackfin.uclinux.org/doku.php?id=toolchain:executable_file_formats e http://docs.blackfin.uclinux.org /doku.php?id=toolchain:creating_libraries si presentano. Sembra che tu possa avere un ID di libreria condivisa in conflitto o potresti voler modificare i tuoi flag di collegamento (come spiegato qui). Spiacente non posso aiutare molto di più –