I'm experimenting with symbol visibility in shared libraries using gcc and clang (both seem to exhibit the same behavior as far as this problem is concerned). The motivation for this question is to ensure that a particular symbol is never exposed in the shared library. Imagine a function with a sensitive name that must remain secret and that function is used internally within the shared library. Things are doing what I expect on Linux, but on macOS I can't seem to ensure a symbol is indeed kept completely hidden.
I've distilled the problem down to the following minimal demonstrator. The real scenarios would use flags like -fvisibility
etc. rather than explicitly putting attributes on every symbol, but I've done it this way just to minimise the example (i.e. don't focus on the style, just the behavior).
f.c
__attribute__ ((visibility("default"))) int func(int v)
{
return v + 14;
}
__attribute__ ((visibility("hidden"))) double some_other_func()
{
return 1.23456;
}
Compile this with the following command line (shown for macOS, use libf.so
for Linux):
gcc -shared -fPIC -o libf.dylib f.c
I would expect the some_other_func()
function to be hidden, but using nm
I can confirm that it still appears in the text section as a global/external symbol (uppercase T
rather than lowercase t
, the latter being a local symbol that could be stripped out):
# macOS
> nm -DC lib.dylib
0000000000000f80 T func
0000000000000fa0 T some_other_func
U dyld_stub_binder
But on Linux, we get what we expect with some_other_func()
not showing up:
# 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
In both cases, if you write an application that tries to call some_other_func()
, the linker doesn't let you (it still gives you an undefined symbol on both macOS and Linux), so the problem isn't with preventing the linker from using the symbol. My problem is trying to hide the symbol completely, but it's showing up in the text section and revealing the name.
I'm using compilers from 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