2016-05-10 1 views
2

Scénario:-rdynamic pour les symboles de sélection seulement?

Un exécutable charge l'objet partagé lors de l'exécution via dlopen.

L'objet partagé fait référence à un symbole (une fonction) qui est réellement compilé dans l'exécutable principal.

Cela fonctionne très bien si j'ajoute -rdynamic à gcc lors de la liaison de l'exécutable. -rdynamic exporte tous les symboles non-statiques de l'exécutable

Mon objet partagé n'a besoin que d'un petit nombre. Question: Existe-t-il un moyen d'obtenir l'effet de -rdynamic, mais restreint les quelques symboles de sélection dont je sais que mon objet partagé a besoin?

Edit:

Au moins deux personnes ont mal compris la question, alors j'essaie de préciser:

Cette question porte sur l'exportation d'un symbole de l'exécutable principal.

Cette question est pas sur l'exportation d'un symbole à partir d'une bibliothèque dynamique.

Voici un exemple minimal:

func.h, le fichier d'en-tête commune

#include <stdio.h> 
void func(void); 

main.c, le principal code exécutable:

#include <dlfcn.h> 
#include "func.h" 

// this function is later called by plugin 
void func(void) { 
    printf("func\n"); 
} 

int main() { 
    void * plugin_lib = dlopen("./plugin.so", RTLD_NOW); 
    printf("dlopen -> %p, error: %s\n", plugin_lib, dlerror()); 

    // find and call function "plugin" in plugin.so 
    void (*p)(void); // declares p as pointer to function 
    p = dlsym(plugin_lib, "plugin"); 
    p(); 

    return 0; 
} 

plugin.c, le code pour le plugin chargé à l'exécution:

#include "func.h" 

void plugin() 
{ 
    printf("plugin\n"); 
    func(); 
} 

Si je compile avec

$ gcc -o main main.c -ldl 
$ gcc -shared -fPIC -o plugin.so plugin.c 

Alors plugin.so ne peut pas être chargé, car il fait référence à la fonc symbole, qui ne peut être résolu:

$ ./main 
dlopen -> (nil), error: ./plugin.so: undefined symbol: func 
Segmentation fault (core dumped) 

Je peux convaincre l'exécutable principal d'exporter toute sa symboles globaux en compilant avec -rdynamic:

$ gcc -rdynamic -o main main.c -ldl 
$ ./main 
dlopen -> 0x75e030, error: (null) 
plugin 
func 

Mais cela remplit inutilement la table des symboles dynamiques avec tous les symboles.

(Ce tableau symbole dynamique peut être inspecté avec nm -D main.)

La question est, comment puis-je ajouter que « Fonction » à la table de symbole dynamique de l'exécutable principal, et pas tout.

+0

Copie possible de [Explicitement exporter des fonctions de bibliothèque partagée sous Linux] (http://stackoverflow.com/questions/2164827/explicitly-exporting-shared-library-functions-in-linux) – greydet

+0

Copie possible de [comment appeler fonction dans exécutable de ma bibliothèque?] (http://stackoverflow.com/questions/6292473/how-to-call-function-in-executable-from-my-library) – ninjalj

+0

@ninjalj Nice find! Cette question en elle-même n'est pas ma question. Mais il a une réponse http://stackoverflow.com/posts/6298434/revisions qui répond également à ma question. –

Répondre

0

Vous pouvez le faire avec l'attribut de visibilité de GCC. Déclarer la fonction à exporter avec le drapeau __attribute__ ((visibility ("default"))). Ensuite, compilez toute votre bibliothèque en passant l'argument -fvisibility=hidden à GCC.

Pour une explication complète à ce sujet, se reporter à GCC documentation page.

+0

Merci, mais Non. Ma question concerne l'exportation de symboles à partir de l'exécutable principal, et non à partir d'une bibliothèque. –

1

Malheureusement, il est plus difficile de réaliser cela pour les exécutables. Vous devez générer une liste de symboles que vous souhaitez exporter, puis ajouter -Wl,--dynamic-list=symfile.txt à LDFLAGS.

Here's example comment cela se fait dans Clang (et here est le script qu'ils utilisent pour générer le fichier de symboles).

+0

Oui, -Wl, - dynamic-list = est le moyen de le faire. Voir https://stackoverflow.com/posts/6298434/revisions pour une réponse donnant un exemple de fichier de symboles. –