首页 > 解决方案 > 如何防止 GLIBC 符号从 .so 中导出?

问题描述

我将 GLIBC 静态链接到我的 .so 中:

g++ -shared -o morpher.so -static-libstdc++ -static-libgcc -Wl,-L。-Wl,--whole-archive -l:hello.o -l:libmorpher.a -Wl,--no-whole-archive

我这样做是为了使我的二进制文件 (.so) 在不同的 Linux 发行版和版本中可移植。

然而,这有一个不良的副作用:所有 GLIBC 符号,包括例如 malloc() 和 free(),都是从我的共享库中导出的:

$ nm morpher.so | grep free
00000000000ef520 t _ZN12_GLOBAL__N_14pool4freeEPv.constprop.0
000000000008b08c t _ZN12_GLOBAL__N_14pool4freeEPv.constprop.0.cold
00000000000ef710 T _ZN9__gnu_cxx9__freeresEv
00000000000ef860 T __cxa_free_dependent_exception
00000000000ef7b0 T __cxa_free_exception
                 U __freelocale@@GLIBC_2.2.5
                 U free@@GLIBC_2.2.5

添加-fvisibility=hidden没有效果:它只在编译时对源文件有效。

有没有办法防止 GLIBC 和 libstdc++ 符号被导出?

标签: gcc

解决方案


nm(不带-D选项)显示静态符号表 ( .symtab),而不是动态符号表 ( .dynsym)。只有动态符号表与动态链接相关。

在您的情况下,似乎这些符号实际上并未在共享对象中定义。相反,__freelocaleandfree是未定义的 ( U) 或导入的。如果您在要支持的最旧发行版上构建共享对象,则此类导入不会影响跨发行版兼容性,因为 glibc 具有跨发行版的兼容 ABI,并且更高版本支持来自旧版本的符号。

-static-libgcc是关于 libgcc(不是 glibc)的。很多 libgcc 总是静态链接的。默认共享部分主要是关于展开器,建议动态链接,以便使用系统展开器。


推荐阅读