J'essaie de construire un exécutable sur Linux qui répond aux critères suivants:Est-il possible d'établir un lien statique entre libstdC++ et wrap memcpy?
- lié statiquement à libstdC++ et libgcc
- construit avec une version récente de gcc (version> = 4.8.2) et glibc (version> 2.14)
- arrière compatible avec les anciennes versions de la glibc (version < 2,5)
Mon environnement actuel dev est gcc4.8.5, glibc 2.17 sur CentOS 7. Le binaire construit ne fonctionne pas sur les systèmes avec glibc < 2.14 en raison d'une dépendance sur memcpy.
objdump -T main | fgrep GLIBC_2.14
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.14 memcpy
Il y avait un changement de rupture à Memcpy introduit dans la glibc 2.14 donc je veux forcer l'utilisation d'une version plus ancienne. Je suis tombé sur ce message de stackoverflow Linking against older symbol version in a .so file mais cela n'a pas fonctionné pour moi en raison des problèmes d'éditeur de liens liés à libstdC++. Voici ma tentative de solution ci-dessous.
main.cpp
#include <iostream>
#include <string.h>
int main(int argc, char** argv)
{
char source[] = "once upon a midnight dreary...", dest[4];
memcpy(dest, source, sizeof dest);
std::cout << dest << std::endl;
}
wrap_memcpy.cpp
#include <string.h>
__asm__(".symver memcpy, [email protected]_2.2.5");
void *__wrap_memcpy(void *dest, const void *src, size_t n)
{
return memcpy(dest, src, n);
}
options du compilateur et des erreurs:
g++ -static-libgcc -static-libstdc++ wrap_memcpy.cpp main.cpp -o main -Wl,--wrap=memcpy
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libstdc++.a(locale-inst.o): In function `std::ctype<char>::widen(char const*, char const*, char*) const':
(.text._ZNKSt5ctypeIcE5widenEPKcS2_Pc[_ZNKSt5ctypeIcE5widenEPKcS2_Pc]+0x5f): undefined reference to `__wrap_memcpy'
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libstdc++.a(locale-inst.o): In function `std::__timepunct<char>::__timepunct(__locale_struct*, char const*, unsigned long)':
(.text._ZNSt11__timepunctIcEC2EP15__locale_structPKcm[_ZNSt11__timepunctIcEC5EP15__locale_structPKcm]+0x96): undefined reference to `__wrap_memcpy'
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libstdc++.a(locale-inst.o): In function `std::messages<char>::messages(__locale_struct*, char const*, unsigned long)':
(.text._ZNSt8messagesIcEC2EP15__locale_structPKcm[_ZNSt8messagesIcEC5EP15__locale_structPKcm]+0x8e): undefined reference to `__wrap_memcpy'
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libstdc++.a(locale-inst.o): In function `std::messages_byname<char>::messages_byname(char const*, unsigned long)':
(.text._ZNSt15messages_bynameIcEC2EPKcm[_ZNSt15messages_bynameIcEC5EPKcm]+0xd6): undefined reference to `__wrap_memcpy'
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libstdc++.a(locale-inst.o): In function `std::__numpunct_cache<char>::_M_cache(std::locale const&)':
(.text._ZNSt16__numpunct_cacheIcE8_M_cacheERKSt6locale[_ZNSt16__numpunct_cacheIcE8_M_cacheERKSt6locale]+0x2ad): undefined reference to `__wrap_memcpy'
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libstdc++.a(locale-inst.o):(.text._ZNSt16__numpunct_cacheIcE8_M_cacheERKSt6locale[_ZNSt16__numpunct_cacheIcE8_M_cacheERKSt6locale]+0x2cd): more undefined references to `__wrap_memcpy' follow
collect2: error: ld returned 1 exit status
ce que je fais mal ici? J'ai également essayé d'autres solutions dans le poste de débordement de la pile et j'ai la même erreur. J'ai aussi essayé de construire ceci sur glibc 5.2.1 sous Ubuntu 15.0.4 et j'ai obtenu le même résultat. Notez que lier de manière statique memcpy (qui est sous la licence GPL) dans le binaire n'est pas une option en raison de problèmes de licence.
Le chemin du moins La résistance est probablement de rechercher et remplacer globalement toutes les utilisations de 'memcpy' dans votre code avec' memmove', et vous n'aurez pas besoin de l'ancien 'memcpy'. Sinon, corrigez le code qui dépend du comportement 'memcpy' non garanti, mais si c'était facile, vous l'avez déjà fait. – zwol
Merci pour la réponse. Malheureusement, nous dépendons des bibliothèques tierces qui dépendent du nouveau memcpy (par exemple, boost). #include ajoute également une dépendance à memcpy. –
yoshimonster
Peut-être que je ne comprends pas votre problème. Si votre code n'a pas besoin du comportement non garanti de l'ancien 'memcpy', alors pourquoi essayez-vous de l'utiliser? (Autrement dit, pourquoi est-ce un problème pour votre binaire de se référer au nouveau 'memcpy'?) – zwol