且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何从 Android NDK .so 文件中删除符号?

更新时间:2023-02-02 21:09:24

由于 .so 是一个动态加载的共享库,它需要有一些外部可用的符号.要查看这些,请使用 nm -D libMeow.so.Strip 不会删除这些,否则会使库无法使用.

Since the .so is a shared library that will be loaded dynamically, it needs to have some amount of symbols available externally. To view these, use nm -D libMeow.so. Strip won't remove these, or it would make the library unusable.

由于某些函数需要从外部加载,所以不能只删除所有动态符号,因为这样就没有人能够与 .so 进行交互了.如果你的 .so 是一个 JNI 库,你需要让 JNI 入口点函数在外部可见,而如果它是另一个 .so 链接的共享库,你至少需要让你的库的公共界面可见.

Since the some functions need to be loaded externally, you can't just remove all dynamic symbols, because then nobody would be able to interface with the .so. If your .so is a JNI library, you need to have the JNI entry point functions visible externally, while if it is a shared library that another .so links against, you need to have at least the public interface of your library visible.

要隐藏内部符号,您可以阅读 https://gcc.gnu.org/wiki/完整故事的可见性.大致而言,您的选择是:

To make the internal symbols hidden, you can read https://gcc.gnu.org/wiki/Visibility for the full story. Roughly, your options are:

  • 在您不希望在库外可见的每个符号上使用 __attribute__ ((visibility ("hidden"))).(这可能是相当多的,要追踪每一个都需要大量的工作.)
  • 使用 -fvisibility=hidden 构建,它在每个外部符号上隐式设置它,并在符号上添加 __attribute__ ((visibility ("default")))您实际需要导出的内容(可能要少得多)
  • 使用版本脚本"来限制要导出到选择列表的函数.链接时,传递 -Wl,-version-script -Wl,mylib.ver.
  • Use __attribute__ ((visibility ("hidden"))) on every symbol you don't want to be visible outside of the library. (This probably is quite a few and it's a lot of work to track down every single one.)
  • Build with -fvisibility=hidden, which implicitly sets this on every single external symbol, and add __attribute__ ((visibility ("default"))) on the ones that you actually need to have exported (probably much fewer)
  • Use a "version script" to limit what functions to export to a select list. When linking, pass -Wl,-version-script -Wl,mylib.ver.

对于版本脚本案例,mylib.ver 应如下所示:

For the version script case, mylib.ver should look like this:

{ global:
PublicFunction1;
PublicFunction2;
local: *; };