Réécriture de la bibliothèque partagée du fnud symbole de la version de l'objet compilé
Question
Je suis en train de compiler et lier un programme (appelons-la " myprog) qui est liée à l'encontre d'une bibliothèque partagée (dans ce cas libcryto & libssl, mais , pour que la bibliothèque n'est pas pertinent).Je suis bâtiment sur Centos 5.5 mais veux le même binaire à exécuter sur d'autres RHEL-comme les distributions (par ex.CloudLinux).Les deux versions de la même bibliothèque, avec le même SO_NAME
(c'est à dire DT_NEEDED
les versions correspondent).
Ma question est la suivante.Quand je compile sur Centos je vois:
centos$ objdump -T myprog | fgrep SSL_new
0000000000000000 DF *UND* 0000000000000000 libssl.so.10 SSL_new
ce qui fonctionne bien parce que:
centos$ objdump -T /usr/lib64/libssl.so.10 | fgrep SSL_new
00000000000447d0 g DF .text 0000000000000390 libssl.so.10 SSL_new
Cependant, sur CloudLinux:
cloudlinux$ objdump -T /usr/lib64/libssl.so.10 | fgrep SSL_new
00000033a623a120 g DF .text 0000000000000390 Base SSL_new
Remarque: la version du protocole SSL symbole a changé à partir de libssl.so.10
pour Base
.
Cela signifie que lorsque je lance le binaire je reçois:
cloudlinux$ ./myprog
./myprog: /usr/lib64/libcrypto.so.10: no version information available (required by ./myprog)
./myprog: /usr/lib64/libssl.so.10: no version information available (required by ./myprog)
Je comprends que c'est juste un avertissement, mais je veux m'en débarrasser.
Est ce que je veux pour mon binaire à exécuter sur les deux cloudlinux et centos sans avertissements.L'ABI des bibliothèques openssl sont, autant que je peux dire, identique, au moins dans les morceaux que j'utilise.Maintenant, je ne peux pas changer les bibliothèques partagées comme myprog
est destiné à être exécuté sur n'importe quel cloudlinux ou centos bibliothèques.Je accepter une solution qui, au moment de l'installation fixe les symboles (en quelque sorte), par exempleavec objcopy
.
Une approche pourrait être quelque chose comme introduire un faible le symbole de SSL_new@libssl.so.10
qui est un alias pour SSL_new@Base
.Évidemment, ce serait pour chaque symbole dans la bibliothèque ssl (donc wrappers ne sont pas appropriés).Mais je ne peux pas obtenir -Wl,--defsym=x=y
pour prendre les valeurs de x
et y
avec @
les symboles.
Une autre approche qui pourrait fonctionner est tout simplement de supprimer le symbole de la version de la binaire (c'est à diresupprimer la libssl.so.10
la version de chacun des ssl symboles, et s'appuient sur la gestion des versions dans le DT_NEEDED
nom).Cela semble être une simple demande, mais je ne vois pas comment faire.Est-il une objcopy
incantation?
Pire des cas, en s'appuyant sur une Centos (séparée) de la version qui fonctionne sur CloudLinux ce serait bien.J'ai essayé en faisant ceci:
#define OSLB(SYMNAME) __asm__(".symver " #SYMNAME "," #SYMNAME "@Base");
OSLB (SSL_new);
Cependant, qui échoue sur le lien qui se plaignent que SSL_new@Base
est un symbole non défini (ce qui est, sur Centos, comme Centos .so
qui n'ont pas de symbole).
Est-il un moyen de contourner cela?
La solution
Une autre approche qui pourrait fonctionner est tout simplement de supprimer le symbole de la version de la binaire (c'est à diresupprimer la libssl.donc.10 version de chacun des ssl symboles, et s'appuient sur la gestion des versions dans le DT_NEEDED nom).Cela semble être une simple demande, mais je ne vois pas comment faire.Est-il un objcopy incantation?
La suppression des informations de version post-link est impossible -- ces chaînes sont entrées dans les tables de hachage, et la reconstruction de ces tables de hachage est trop compliqué une chose à faire avec objcopy
.
Ce que vous voulez faire est de créer un stub libssl.so.10
avec DT_SONAME
mis à libssl.so.10
, qui définit tous les symboles dont vous avez besoin, mais sans toute les infos de version.Par exemple, ce serait faire si vous avez seulement besoin de l' SSL_new
symbole:
echo "void SSL_new() { }" > t.c &&
gcc -fPIC -shared -o libssl.so -Wl,--soname='libssl.so.10' t.c
Lien de votre programme à l'encontre de ce talon de la bibliothèque, et on aura pas exiger de toute versionnées symboles.
Le moteur d'exécution de l'éditeur de liens va ensuite satisfaire à cette non défini non versionnés SSL_new
avec SSL_new@libssl.so.10
sur CentOS, et avec SSL_new@Base
sur CloudLinux.
Autres conseils
J'ai été en mesure de se débarrasser de ces mises en garde de cette façon (avec Debian et Arch plutôt que CentOS/Cloud Linux, mais il devrait fonctionner pour vous aussi):
Supprimer tout libssl-devel paquet pour éviter la confusion
Compiler libssl à partir de la source
./config --prefix=/usr/local --openssldir=/usr/local/openssl shared
Construire votre logiciel contre.
Pour moi, ces références de version, puis a disparu et il a couru sans mise en garde:
Version References:
required from libcrypto.so.1.0.0:
0x066a2b20 0x00 10 OPENSSL_1.0.0
required from libssl.so.1.0.0:
0x066a2b20 0x00 05 OPENSSL_1.0.0