首页 > 解决方案 > 共享库隐藏符号在 macOS 上仍然可见,但在 Linux 上不可见

问题描述

我正在使用 gcc 和 clang 试验共享库中的符号可见性(就这个问题而言,两者似乎表现出相同的行为)。这个问题的动机是确保特定符号永远不会在共享库中公开。想象一个具有敏感名称的函数,该名称必须保密,并且该函数在共享库内部使用。事情在 Linux 上符合我的预期,但在 macOS 上,我似乎无法确保符号确实完全隐藏。

我已将问题提炼为以下最小的演示者。真实场景会使用诸如此类的标志,-fvisibility而不是显式地将属性放在每个符号上,但我这样做只是为了最小化示例(即不关注样式,只关注行为)。

fc

__attribute__ ((visibility("default"))) int func(int v)
{
    return v + 14;
}


__attribute__ ((visibility("hidden"))) double some_other_func()
{
    return 1.23456;
}

使用以下命令行编译它(显示为 macOS,libf.so用于 Linux):

gcc -shared -fPIC -o libf.dylib f.c

我希望该some_other_func()函数被隐藏,但使用nm我可以确认它仍然作为全局/外部符号出现在文本部分中(大写T而不是小写t,后者是可以被剥离的本地符号):

# macOS
> nm -DC lib.dylib
0000000000000f80 T func
0000000000000fa0 T some_other_func
                 U dyld_stub_binder

但是在 Linux 上,我们得到了我们所期望的some_other_func()没有出现的结果:

# Linux
> nm -DC libf.so
0000000000201020 B __bss_start
                 w __cxa_finalize
0000000000201020 D _edata
0000000000201028 B _end
0000000000000598 T _fini
000000000000057a T func
                 w __gmon_start__
0000000000000460 T _init
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable

在这两种情况下,如果您编写一个尝试调用的应用程序,some_other_func()链接器不会让您(它仍然在 macOS 和 Linux 上为您提供未定义的符号),因此问题不在于阻止链接器使用该符号. 我的问题是试图完全隐藏符号,但它出现在文本部分并显示名称。

我正在使用 Xcode 10.3 中的编译器:

> gcc --version
Configured with: --prefix=/Applications/Xcode-10.3.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode-10.3.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/c++/4.2.1
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.6.0
Thread model: posix
InstalledDir: /Applications/Xcode-10.3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

标签: clinuxmacosgccvisibility

解决方案


推荐阅读