Ho bisogno di collegare il programma C su un oggetto condiviso senza intestazioni di sezione
-
22-09-2019 - |
Domanda
ho scritto un'interfaccia al generatore di codice che mi permette di produrre oggetti condivisi. Anche se io non voglio o implementare il supporto per la tabella di sezione di intestazione perché è lì che la complessità maggior parte dei formati di file ELF rimane in.
GNU ld utilizza le intestazioni di sezione per il collegamento agli oggetti condivisi. Ciò significa che quando provo a mettere collegamento gcc contro il mio oggetto condiviso senza intestazioni di sezione, fallirà perché la ld non trova i simboli, anche se esiste nella biblioteca.
Vuol esiste qualche trucco che ho potuto usare per ingannare il compilatore per rendere il collegamento tra avere successo anche se non avrebbe trovato alcuni simboli?
Ecco alcuni chiarimenti sul problema:
cheery@ruttunen:~/Documents/g386$ gcc dev/shared_test.c -L. -lshared -m32
/tmp/cc6qBViY.o: In function `main':
shared_test.c:(.text+0xa): undefined reference to `example_function'
collect2: ld returned 1 exit status
cheery@ruttunen:~/Documents/g386$ cat dev/shared_test.c
// gcc shared_test.c -L. -lshared -m32
// LD_LIBRARY_PATH=. ./a.out
#include <stdio.h>
extern int example_function();
int main(){
printf("hello %d\n", example_function());
}
cheery@ruttunen:~/Documents/g386$ readelf -D -s libshared.so
Symbol table for image:
Num Buc: Value Size Type Bind Vis Ndx Name
2 0: 00800164 0 FUNC GLOBAL DEFAULT ABS example_function
1 0: 008000ac 0 OBJECT GLOBAL DEFAULT ABS _DYNAMIC
Soluzione 2
L'approccio migliore è quello di aggiungere le tabelle sezione richiesta da gcc. Se si dispone di un meccanismo di linking dinamico lavorare nel vostro generatore, richiede le stesse informazioni come quello che ci si inserisce nelle tabelle della sezione.
Per la pigrizia ho scritto un file assembly condiviso e strip-comando utilizzato su di esso per ottenere un punto di riferimento. 'readelf --sections' mostra coppia di sezioni, ma non c'è bisogno tutti. Ho lavorato attraverso questo e implementato le sezioni in modo fino a quando non ha iniziato a lavorare in modo corretto. Ecco cosa ho dovuto aggiungere:
cheery@ruttunen:~/Documents/g386$ readelf --sections dynamic_hello.app
There are 5 section headers, starting at offset 0x1b9:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .shstrndx STRTAB 00000000 000281 000024 00 0 0 1
[ 2] .dynamic DYNAMIC 00000000 0000b0 000050 08 WA 3 0 4
[ 3] .dynstr STRTAB 00000000 000158 000020 00 A 0 0 1
[ 4] .dynsym DYNSYM 00000000 000100 000040 10 A 3 0 4
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
Non fa male se si mette in più sezioni di queste, ma questo è sufficiente per ottenere il collegamento dinamico di lavoro.
Altri suggerimenti
gcc (vale a dire, ld dietro GCC) ha un'opzione della riga di comando di ignorare esterni non risolti. Che verrà sopprimere il messaggio di errore che si ottiene da gcc. Non sono sicuro che che sta per farti felice.