是否可以静态链接libstdc ++并包装memcpy?

吉兽

我正在尝试在满足以下条件的Linux上构建可执行文件:

  1. 静态链接到libstdc ++和libgcc
  2. 使用最新版本的gcc(版本> = 4.8.2)和glibc(版本> 2.14)构建
  3. 向后兼容旧版本的glibc(版本<2.5)

我当前的开发环境是CentOS 7上的gcc4.8.5,glibc 2.17,由于对memcpy的依赖,内置的二进制文件在glibc <2.14的系统上不起作用。

objdump -T main | fgrep GLIBC_2.14
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.14  memcpy

glibc 2.14中对memcpy进行了重大更改,因此我想强制使用旧版本。我遇到了这个stackoverflow帖子,在.so文件中链接到较旧的符号版本,但是由于与libstdc ++相关的链接器问题,它对我不起作用。这是我在下面的解决方案中的尝试。

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, memcpy@GLIBC_2.2.5");

void *__wrap_memcpy(void *dest, const void *src, size_t n)
{
    return memcpy(dest, src, n);
}

编译器选项和错误:

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

我在这里做错了什么?我还在堆栈溢出后尝试了其他解决方案,但遇到了同样的错误。我还尝试在Ubuntu 15.0.4的glibc 5.2.1上构建此文件,并得到了相同的结果。请注意,由于许可问题,不能将memcpy(在GPL许可下)静态链接到二进制文件中。

克林贡

您需要将__wrap_memcpy包装在extern“ C” {}中,以便将此函数导出为C函数。否则,其名称将被修饰为C ++函数。此外,我强烈建议使用其他#ifdef,因为此问题仅在更高版本的编译器版本中且仅针对x64出现(条件并非完全完美,因此可能需要对其进行调整):

#if defined( __GNUC__ )  &&  defined( __LP64__ )  &&  __LP64__ >= 1  && \
(_GNUC__ >= 5  ||  (__GNUC__ == 4  &&  __GNUC_MINOR__ >= 7))  &&  \
(defined( __x86_64__ )  ||  defined( __i386__ )  ||\
defined( __i486__ )  ||  defined( __i586__ )  ||  defined( __i686__ ))

#include <string.h>

__asm__(".symver memcpy, memcpy@GLIBC_2.2.5");

extern "C"
{
void *__wrap_memcpy(void *dest, const void *src, size_t n)
{
    return memcpy(dest, src, n);
}
}

#endif

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

STUArray是否有memmove / memcpy包装器?

来自分类Dev

使用clang的静态链接libstdc ++

来自分类Dev

包装时是否可以更改物品的顺序?

来自分类Dev

g ++静态链接到libstdc ++。a错误

来自分类Dev

libstdc ++-不使用qmake静态链接

来自分类Dev

libstdc ++-不使用qmake静态链接

来自分类Dev

是否可以将macfuse链接到C ++静态库?

来自分类Dev

#+ BIND:可以包装吗?

来自分类Dev

在Svelte中禁用包装链接

来自分类Dev

链接包装块中断元素

来自分类Dev

是否可以将C枚举包装在Rust中?

来自分类Dev

是否可以为Verilog模块的Modport创建SystemVerilog包装器?

来自分类Dev

是否可以在发电机内部包装promise?

来自分类Dev

是否可以使用仅CSS的容器包装器?

来自分类Dev

包装时是否可以更改项目的顺序?

来自分类Dev

是否可以为Verilog模块的Modport创建SystemVerilog包装器?

来自分类Dev

使用包装器类隐藏错误是否可以接受?

来自分类Dev

是否可以将错误路由到类包装的Bottle方法?

来自分类Dev

是否可以使用仅CSS的容器包装器?

来自分类Dev

是否可以在 Python 的包装器中传递字典?

来自分类Dev

在静态容器中包装非静态类

来自分类Dev

用非静态类包装静态类

来自分类Dev

MinGW,如何避免链接静态完整的 libstdc++

来自分类Dev

是否可以重新路由lambda以将其包装在包装器类中?

来自分类Dev

是否允许:memcpy(dest,src,0)

来自分类Dev

循环复制是否比memcpy()效率低?

来自分类Dev

char [] + memcpy()是否违反严格的别名?

来自分类Dev

Scala是否自动包装字段?

来自分类Dev

季节包装是否支持花键?