Linux 使用 g++ 的符号可见性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4994741/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 02:51:51  来源:igfitidea点击:

Symbol visibility using g++

linuxg++visibilitysymbolshidden

提问by JoeSlav

I compiled a C++ library under Linux/Mac with its symbols hidden. I've used _attribute_ ((visibility("hidden")))for all my classes and compiled with options (-c -O2 -fPIC -MMD -MP -MF). Under Mac, using MacDependencies (http://code.google.com/p/macdependency/), the job is done just fine as I see only my exports (I actually saw the difference before and after).

我在 Linux/Mac 下编译了一个隐藏符号的 C++ 库。我已经将_属性_ ((visibility("hidden")))用于我的所有类,并使用选项(-c -O2 -fPIC -MMD -MP -MF)进行编译。在 Mac 下,使用 MacDependencies (http://code.google.com/p/macdependency/),工作做得很好,因为我只看到了我的导出(我实际上看到了前后的差异)。

However, I noticed that using nmI still see all the names of the symbols. This happens under both Mac and Linux.

但是,我注意到使用nm我仍然可以看到所有符号的名称。这在 Mac 和 Linux 下都会发生。

Why is that? Is there any way to avoid this?

这是为什么?有什么办法可以避免这种情况吗?

Best Regards and thanks, Joe

最好的问候和感谢,乔

采纳答案by Maxim Egorushkin

Public or hidden, symbols are still there. nmshows all symbols. The difference is that hidden symbols are not available to the dynamic linker, i.e. not exported and can not be interposed.

公共或隐藏,符号仍然存在。nm显示所有符号。不同之处在于动态链接器无法使用隐藏符号,即无法导出且无法插入。

You might also like the following man gcc:

您可能还喜欢以下内容 man gcc

   -fvisibility=default|internal|hidden|protected
       ...
       A good explanation of the benefits offered by ensuring ELF symbols
       have the correct visibility is given by "How To Write Shared
       Libraries" by Ulrich Drepper (which can be found at
       <http://people.redhat.com/~drepper/>)---however a superior solution
       made possible by this option to marking things hidden when the
       default is public is to make the default hidden and mark things
       public.  This is the norm with DLL's on Windows and with
       -fvisibility=hidden and "__attribute__ ((visibility("default")))"
       instead of "__declspec(dllexport)" you get almost identical
       semantics with identical syntax.  This is a great boon to those
       working with cross-platform projects.

回答by Hasturkun

You can stripyour binary to remove any unneeded symbols.

您可以使用strip二进制文件删除任何不需要的符号。

回答by Timmmm

On OSX (not sure about others) I found the following.

在 OSX 上(不确定其他人)我发现了以下内容。

As mentioned by Maxim, using -fvisibility=hiddenor __attribute__((visibility("hidden")))still puts the symbol in the symbol table, it just gets marked as unexported. The easiest way to see this is with nm, e.g:

正如 Maxim 所提到的,使用-fvisibility=hidden__attribute__((visibility("hidden")))仍然将符号放入符号表中,它只是被标记为未导出。看到这一点的最简单方法是使用nm,例如:

$ nm libfoo.dylib 
...
0000000000001fa0 t __Z10a_functionv
0000000000002140 T __Z17a_public_functionv
...

If the letter after the address is lowercase it means it isn't exported. Here a_function()is hidden, and a_public_functionhas default visibility.

如果地址后面的字母是小写,则表示它没有导出。这里a_function()是隐藏的,并且a_public_function具有默认可见性。

To strip the non-exported symbols from the symbol table you can use strip -x, which according to the man page:

要从符号表中去除未导出的符号,您可以使用strip -x,根据手册页:

-x Remove all local symbols (saving only the global symbols).

-x 删除所有局部符号(仅保存全局符号)。

$ strip -x libfoo.dylib
$ nm libfoo.dylib 
...
0000000000002140 T __Z17a_public_functionv
...

I believe (but am not 100% sure) that using hiddendoesn't justamount to changing a flag, and 'unhiding' the symbols wouldn't be trivial.

我相信,(但我不是100%确定),使用hidden并不仅仅等同于不断变化的一个标志,而“取消隐藏”符号不会是微不足道的。