Je dois relier le programme C sur un objet partagé sans en-tête de section
-
22-09-2019 - |
Question
J'ai écrit une interface avec le générateur de code qui me permet de produire des objets partagés. Bien que je ne veux pas o mettre en œuvre un soutien pour la table d'en-tête de section, car c'est là la complexité majoritaire du format de fichier ELF reste.
GNU ld utilise les en-têtes de section pour relier contre des objets partagés. Cela signifie que lorsque je tente de mettre le lien gcc contre mon objet partagé sans en-tête de section, il échouera car le ld ne trouve pas les symboles, même si elles existent dans la bibliothèque.
Est-ce qu'il existe un truc que je pourrais utiliser pour tromper le compilateur de faire le lien réussir même si elle ne trouverait pas certains symboles?
Voici quelques précisions sur le problème:
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
La solution 2
La meilleure approche est d'ajouter ici les tableaux de section requis par gcc. Si vous avez un mécanisme de liaison dynamique de travail dans votre générateur, il exige que tous les mêmes informations que ce que vous insérez dans les tableaux de la section.
Pour la paresse j'ai écrit un fichier de montage partagé et bande-commande utilisée sur elle pour obtenir un point de référence. 'readelf --sections' montre deux sections, mais vous ne les ont pas besoin du tout. J'ai travaillé à travers cela et mis en œuvre des sections afin jusqu'à ce qu'il a commencé à travailler correctement. Voici ce que je devais ajouter:
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)
Il ne fait pas mal si vous mettez dans plusieurs sections que celles-ci, mais cela est suffisant pour faire fonctionner la liaison dynamique.
Autres conseils
gcc (qui est, ld derrière gcc) présente une option de ligne de commande d'ignorer externes non résolus. Ça va supprimer le message d'erreur que vous obtenez de gcc. Je ne suis pas sûr que cela va vous rendre heureux.