Quelles sont les différences d’en-tête ELF entre un fichier object ELF et un object partagé?

Tout d’abord, je pose cette question d’un sharepoint vue technique, et non d’une perspective de l’utilisateur du code de la bibliothèque. Un exemple de différence réside dans le fait que les objects partagés contiennent des en-têtes de programme et des fichiers objects ordinaires. Quelles sont les autres différences?

En ce qui concerne l’object de ma question, j’essaie de déterminer quel contenu devrait être supprimé d’un fichier object partagé pour que l’éditeur de liens le traite comme un fichier object ordinaire et tente de le relier et de le lier de manière statique à l’exécutable généré. fichier, plutôt que de l’identifier en tant que bibliothèque partagée et de générer une référence DT_NEEDED . Ceci à son tour est la première étape vers la “conversion” primitive d’une bibliothèque partagée vers quelque chose qui peut être lié de manière statique (des travaux supplémentaires pour rendre les réinstallations satisfaisables peuvent cependant être requirejs).

L’une des principales différences que vous constaterez est que, lors de la phase finale du lien, un certain nombre de composants de la bibliothèque C sont liés statiquement dans la bibliothèque, formant entre autres les symboles INIT et FINI. Ceux-ci sont spécifiés avec les entrées DT_INIT et DT_FINI dans l’en-tête du programme; vous devrez les transformer en entrées de constructeur / destructeur statiques. Les entrées DT_NEEDED seront perdues lors d’une transformation en un .o; vous devrez les rappend manuellement.

Le PLT généré lors de la dernière étape du lien doit être soit fusionné avec le fichier de sortie final, soit reconverti en déplacements ordinaires; c’est non sortingvial, car le PLT est juste du code. Le GOT est également un problème; il est situé à un décalage relatif fixe par rapport au segment .text et contient des pointeurs vers les membres de données. Cependant, il contient également un pointeur vers la structure _DYNAMIC, dont il ne peut y en avoir qu’un par bibliothèque ou exécutable. Et vous ne pouvez pas modifier les décalages dans le GOT, car ils sont référencés directement à partir du code.

Il est donc assez difficile de convertir à nouveau un .so à nouveau. les informations ont été perdues lors de la conversion en PLT / GOT. Une meilleure approche pourrait être de modifier l’éditeur de liens dynamic dans la bibliothèque C pour prendre en charge la liaison d’une bibliothèque partagée déjà mappée en mémoire en tant qu’image statique. C’est-à-dire que vous convertissez le .so en un .o simplement en le convertissant en une section en lecture seule alignée sur la page; transmettez-le ensuite à l’éditeur de liens dynamic pour le reconfigurer avec les permissions appropriées et effectuez une initialisation de bibliothèque partagée normale. Ajoutez ensuite un constructeur statique à appeler dans la bibliothèque C pour initialiser la bibliothèque partagée. Enfin, ajoutez les symboles exportés appropriés pour correspondre aux symboles dynamics dans le segment .text de la bibliothèque partagée.

Un problème avec cette approche est que les constructeurs statiques peuvent s’exécuter avant le constructeur statique qui initialise votre faux solib. Dans ce cas, ils ne doivent pas tenter d’appeler des fonctions depuis le solib, sinon vous risquez de tomber en panne, car le solib n’est pas encore initialisé. Cela pourrait être évité en faisant pointer les symboles exportés dans une fonction de trampoline qui assure que le solib est initialisé en premier (mais pas si facile avec des symboles de données!)

Vous pourriez également trouver que cette question précédente pourrait vous être utile.