Comment linux résout-il les symboles non résolus pour les bibliothèques utilisées comme extensions?

Il y a un mystère que j’essaie de comprendre:

J’ai créé une application qui peut être étendue avec des bibliothèques dynamics contenant du code mais qui doivent cependant accéder à certaines fonctions définies dans l’application elle-même. Pour être clair:

J’ai l’application appelons-le APP, puis j’ai l’extension EXT. APP est étendu avec certaines fonctionnalités implémentées dans EXT, mais EXT doit appeler certaines fonctions définies dans APP afin de “s’y accrocher” (par exemple, enregistrer de nouveaux éléments dans la mise en page APP, etc.). Dans MS Windows, je ne pourrais pas comstackr EXT à cause de symboles non résolus – cela a du sens – comment pourrais-je appeler des fonctions qui se trouvent dans APP sans avoir rien pour les associer, alors j’ai créé une bibliothèque APP vient d’être construit en tant que DLL avec toutes ces fonctions auxquelles j’ai besoin d’accéder avec exporté en utilisant __declspec (dllexport) (appelons-le simplement LIB), ainsi cela fonctionne comme ceci:

APP charge EXT et EXT appelle les fonctions APP via LIB. C’est une mauvaise solution à un moment donné, mais je ne pouvais pas trouver mieux. Et ce qui est le plus important – cela fonctionne parfaitement.

Maintenant, ce qui me rend fou, c’est que tout cela fonctionne sur Linux sans avoir à créer LIB? Ce truc de Windows est méchant mais il est parfaitement logique, mais sur Linux, je peux construire EXT même sans avoir à créer APP ou LIB, il ignore simplement ces symboles non résolus et les relie de toute façon. Toute la bibliothèque les contient, je peux le vérifier en appelant:

ld: warning: cannot find entry symbol _start; not setting start address libhuggle_md.so: undefined reference to `Huggle::Query::NetworkManager' libhuggle_md.so: undefined reference to `Huggle::Syslog::HuggleLogs' libhuggle_md.so: undefined reference to `Huggle::Core::HuggleCore' libhuggle_md.so: undefined reference to `Huggle::QueryPool::HugglePool' libhuggle_md.so: undefined reference to `Huggle::Localizations::HuggleLocalizations' libhuggle_md.so: undefined reference to `Huggle::Configuration::HuggleConfiguration' libhuggle_md.so: undefined reference to `Huggle::GC::gc' libhuggle_md.so: undefined reference to `Huggle::WikiUser::WikiUser(QSsortingng)' libhuggle_md.so: undefined reference to `Huggle::WikiUtil::MessageUser(Huggle::WikiUser*, QSsortingng, QSsortingng, QSsortingng, bool, Huggle::Query*, bool, bool, bool, QSsortingng, bool, bool)' 

Donc, vous pouvez voir que EXT fait référence à certaines fonctions de l’APP, mais il n’a jamais été lié à une bibliothèque qui les implémenterait. Ils ne sont pas résolus.

Lorsque je charge EXT dans APP, il se passe quelque chose de magique à l’intérieur du kernel et tout fonctionne comme par magie. Pourquoi l’application sur Linux n’a pas besoin de LIB alors que Windows en a besoin? Pourquoi est-il possible de lier quelque chose sur Linux avec des symboles externes non résolus? Comment savoir à quels symboles je me réfère? Les trouve-t-il dans APP et les résout-il?

Pour toute personne intéressée, voici une source complète: https://github.com/huggle/huggle3-qt-lx si vous clonez ceci sur linux et lancez extensions (même s’il n’y a rien à faire avec) alors il crée l’application, et si vous exécutez make install et que vous essayez de l’exécuter, vous verrez qu’il se charge très bien et qu’il utilise un peu de magie pour réparer les symboles non résolus runtime Comment cela marche-t-il? Et pourquoi cela ne fonctionne pas sous Windows?

Je pense qu’il est lié au format ELF utilisé pour les exécutables et les bibliothèques sous Linux (et de nombreux autres * NIX) et l’éditeur de liens dynamic .

Lorsque le programme lié dynamicment est démarré (le processus est créé), l’éditeur de liens dynamic prépare l’espace d’adressage de ce processus. Les bibliothèques Linux sont compilées à l’aide de PIC (code indépendant de la position), elles peuvent donc être placées n’importe où dans l’espace d’adressage du processus. Les liens entre les fonctions des différents modules à l’exécution sont résolus via les tables PLT (Procedure Lookup) et GOT (Global Offset). PLT (lecture seule, section exécutable) contient des instructions de saut indirectes aux adresses dans la table GOT (lecture-écriture, section non exécutable). Le premier appel à fonctionner via PLT conduit à passer à une fonction de l’éditeur de liens d’exécution, qui met à jour l’entrée GOT (et passe à l’adresse réelle). Les appels suivants à la même fonction lui sont directement transmis.

Si je comprends bien, le compilateur dispose de suffisamment d’informations (prototypes de fonctions et autres données des fichiers d’en-tête) pour créer correctement la bibliothèque. Mais pour créer un exécutable, vous devrez fournir toutes les bibliothèques requirejses (pourtant, à l’exécution, vous pouvez modifier les bibliothèques utilisées à condition qu’elles fournissent toutes les fonctions utilisées).

Je suppose que les liens dynamics fonctionnent comme ceci: un autre système d’exploitation UNIX, utilisant le format ELF.

Je ne suis pas très familier avec le format exécutable de Windows, donc je ne peux pas commenter pourquoi le tour similaire ne fonctionne pas là.