La liaison avec d'anciennes symbole de la version .si le fichier
À l'aide de gcc et de ld sur linux x86_64-je besoin de le lier avec une version plus récente d'une bibliothèque glibc (2.14), mais l'exécutable doit s'exécuter sur un système avec une version plus ancienne (2.5). Puisque le seul incompatible symbole est memcpy (besoin memcpy@GLIBC_2.2.5 mais la bibliothèque fournissant memcpy@GLIBC_2.14), je voudrais dire à l'éditeur de liens qui au lieu de prendre la version par défaut de memcpy, il devrait prendre une ancienne version je précise.
J'ai trouvé un très arkward façon de le faire: il suffit de spécifier une copie de l'ancien .si le fichier à la ligne de commande liens. Cela fonctionne bien, mais je n'aime pas l'idée d'avoir plusieurs .les fichiers (je ne pouvais faire le travail en spécifiant toutes les anciennes bibliothèques de je lien qui ont également des références à memcpy) a vérifié dans le svn et de mon système de construction.
Donc je suis à la recherche d'un moyen de dire à l'éditeur de liens de prendre l'ancien versionnées symbole.
Des solutions de rechange qui ne fonctionnent pas (bien) pour moi sont:
- À l'aide de l'asm .symver (comme on le voit sur Archive Web de Trevor Livres Blog) car cela m'obligerait à assurez-vous que le symver est avant tout le code qui est à l'aide de memcpy, ce qui serait très dur (complexe de la base de code dans la 3ème partie du code)
- Le maintien d'un environnement de compilation avec les anciennes bibliothèques; tout simplement parce que je veux développer sur mon ordinateur de bureau et il serait un pain pita à la synchronisation des trucs autour de notre réseau.
Lorsque vous pensez à toutes les tâches d'un éditeur de liens, il ne semble pas être une chose difficile à imlpement, après tout il a un peu de code pour comprendre la version par défaut d'un symbole aussi.
Toutes les autres idées qui sont sur le même niveau de complexité comme un simple éditeur de liens de ligne de commande (comme la création d'un simple éditeur de liens (linker script, etc.) sont aussi les bienvenus, tant qu'ils ne sont pas bizarre hacks en éditant le binaire résultant...
edit:
Pour conserver ce pour les futurs lecteurs, en plus de la ci-dessous des idées, j'ai trouvé l'option --wrap
à l'éditeur de liens, ce qui peut être utile parfois trop.
- Vous savez, memcpy( ) n'a pas changé en trente ans. Vous pourriez mentionner pourquoi vous avez besoin de cela. (Je m'excuse pour demander pourquoi, et je déteste quand les gens le faire. Mais vous devez avoir un réel impératif de la raison qui pourrait être crucial de savoir, étant donné que memcpy() a été stable pendant si longtemps.) Merci!
- Tout simplement parce que quand j'ai créer mon programme de lutte contre la glibc 2.14 il ne fonctionne pas sur un système avec un ancien de la glibc, puisque ceux-ci ne fournissent pas de la version du symbole memcpy@GLIBC_2.14
- Ma réponse liens un rapport de bug expliquant memcpy problème, en termes de ce qui a réellement changé - glibc fait un changement qui casse le code qui s'appuient sur la (techniquement pas défini dans le chevauchement des cas) sans-papiers", toujours effectuer une itération à partir de la gauche vers la droite" le comportement de unix traditionnel memcpy implémentations. Plus pertinent pour la question ici, cependant, est le fait que l'ancienne version est évidemment la seule prévue dans les précédentes versions de la glibc qui il doit soutenir.
- Voir aussi: stackoverflow.com/a/39537664/1546337
- Ce lit plausible: gcc.gnu.org/ml/gcc-help/2008-11/msg00303.html
- comment alors? Les versions de symboles existe à cet effet. Donc, si je décide que l'ancienne version avec son vieux sémantique me convient, pourquoi ne pas être en mesure de relier à l'encontre de qui? De tous les nombreux symboles dans la glibc, seulement
realpath
etmemcpy
jamais, se sont tenus à la correction. Et il n'y a pas de réel problème à lire dans le journal de modification, de comparaison de code source et de trouver que l'ancienne version n'est ce que l'on attend de lui ...
Vous devez vous connecter pour publier un commentaire.
Juste un lien de memcpy de manière statique - pull memcpy.o de la libc.un
ar x /path/to/libc.a memcpy.o
(quelle que soit la version - memcpy est assez bien une fonction autonome) et l'inclure dans votre dernier lien. Notez que la liaison statique peut compliquer les questions de licences si votre projet est distribué au public et de ne pas ouvrir-source.Alternativement, vous pouvez simplement mettre en œuvre memcpy vous-même, bien que la main-à l'écoute de l'assemblée de la version de la glibc est susceptible d'être plus efficace
Noter que memcpy@GLIBC_2.2.5 est mappé à memmove (les anciennes versions de memcpy systématiquement copié dans un prévisible de direction, ce qui conduit parfois mal utilisés lors de la memmove doit avoir été utilisé), et c'est la seule raison pour la version bump - vous pouvez simplement remplacer memcpy avec memmove dans votre code pour ce cas précis.
Ou vous pouvez aller à la liaison statique, ou vous pouvez vous assurer que tous les systèmes de votre réseau ont la même ou meilleure version de votre machine de compilation.
J'ai trouvé la suite de solution de travail. D'abord créer un fichier memcpy.c:
Aucune autre CFLAGS nécessaires à la constitution de ce fichier. Puis lier votre programme avec -Wl,--wrap=memcpy.
memcpy
ne change pas. Dans le cas général, nous avons besoin non seulement les anciens symboles, mais également les anciens fichiers d'en-tête. Comme les cas dans lesquels la structure des membres de changement, de sorte que l'ancienne version de la fonction s'attend à une ancienne structure.J'ai eu un problème similaire. Un tiers de la bibliothèque, nous utilisons les besoins de la vieille
memcpy@GLIBC_2.2.5
. Ma solution est une approche élargie @anight posté.J'ai aussi de la courbure de la
memcpy
de commande, mais j'ai dû utiliser une approche légèrement différente, car la solution @anight posté ne fonctionne pas pour moi.memcpy_wrap.c:
memcpy_wrap.carte:
Construire l'emballage:
Maintenant, enfin, lors de la liaison du programme ajouter
-Wl,--version-script memcpy_wrap.map
memcpy_wrap.o
de sorte que vous vous retrouvez avec quelque chose comme:
J'ai eu un problème similaire. Essayez d'installer certains composants oracle sur RHEL 7.1, j'ai obtenu ceci:
Il semble que (mon) RHEL la glibc ne définit memcpy@GLIBC_2.2.5:
Alors, j'ai réussi à contourner ce problème, en créant d'abord un memcpy.c fichier sans emballage, comme suit:
et un memcpy.fichier de la carte que les exportations notre memcpy comme memcpy@GLIBC_2.14:
J'ai ensuite compilé mon propre memcpy.c dans un partagées lib comme ceci:
déplacé libmemcpy-2.14.donc dans /certains/oracle/lib (souligné par -L des arguments dans mes liens), et lié de nouveau par
(qui a compilé sans erreurs), et vérifié par:
Cela a fonctionné pour moi. J'espère qu'il le fait pour vous, trop.
Je suis clairement un peu en retard à répondre à cela, mais j'ai récemment mis à jour (plus de raisons de ne plus jamais de mise à niveau) mon système d'exploitation Linux pour XUbuntu 14.04 qui est venu avec la nouvelle de la libc. J'ai compiler une bibliothèque partagée sur ma machine qui est utilisée par les clients qui, pour une des raisons légitimes, n'ont pas amélioré leur environnement des 10.04. La librairie partagée, j'ai compilé n'est plus chargé dans leur environnement parce que gcc mettre une dépendance sur memcpy glibc v. 2.14 (ou plus). Laissons de côté la folie de cette. La solution de contournement à travers l'ensemble de mon projet était de trois ordres:
glibc_version_nightmare.h:
script perl fragment:
Je pense que vous pouvez vous en sortir avec un simple C est un fichier contenant le symver déclaration et peut-être un mannequin d'appel de fonction memcpy. Ensuite vous avez juste à vous assurer que le fichier de l'objet est le premier fichier de l'éditeur de liens.
Je vous suggère de lier memcpy() de manière statique; ou trouver la source de memcpy( ) et le compiler en tant que votre propre bibliothèque.
Cette solution de contournement ne semblent pas compatibles avec flto option de compilation.
Ma solution est d'appeler memmove. memove fait exactement le même travail que memcpy.
La seule différence, c'est quand src et dest zone de chevauchement, memmove est sûr et memcpy est imprévisible. Donc nous pouvons toujours faire appel à memmove au lieu memcpy
Il peut être causé par de vieux ld (gnu lien) version.
Pour la suite du problème simple:
Lorsque j'utilise ld articles 2.19.1, memset est déplacé vers: memset@@GLIBC_2.0 et causer des crash.
Après mise à jour à 2,25, c'est: memset@plt, et de crash résolu.
Minimale exécutables autonomes exemple
GitHub en amont.
principal.c
un.c
un.h
un.carte
Makefile
Testé sur Ubuntu 16.04.