我正在使用NDK构建适用于Android的armv8a SDK,并且想在启用LTO的情况下进行构建。我在C++工具链的编译和链接标志中添加了-flto,并且一切顺利,直到尝试在模拟器中运行,这时发出了如下错误:
WARNING: linker: /data/lib/libservice.so: unused DT entry: type 0x6ffffef6 arg 0x8e30

WARNING: linker: /data/lib/libservice.so: unused DT entry: type 0x6ffffef7 arg 0x2fb50
一些研究使我想到this answer,这使我能够找出0x6ffffef60x6ffffef6的符号名称,它们恰好分别是TLSDESC_PLTTLSDESC_GOT,因此显然与动态链接程序,PLT/GOT以及TLS有关。美好的。

将非LTO构建与LTO构建进行比较,这些标志肯定只出现在LTO构建中:
$ readelf -a /lto/lib/libservice.so | grep TLS L (link order), O (extra OS processing required), G (group), T (TLS), TLS 0x000000000001ed70 0x000000000002ed70 0x000000000002ed70 0x000000006ffffef6 (TLSDESC_PLT) 0x8e30 0x000000006ffffef7 (TLSDESC_GOT) 0x2fb5000000002ffd8 000000000407 R_AARCH64_TLSDESC 000000002ffe8 000000000407 R_AARCH64_TLSDESC 8 579: 0000000000000008 8 TLS LOCAL DEFAULT 17 _ZN5xxxxx12_GLOBAL__N_113 788: 0000000000000000 1 TLS LOCAL DEFAULT 17 __tls_guard$$ readelf -a /nolto/lib/libservice.so | grep TLS L (link order), O (extra OS processing required), G (group), T (TLS),$
因此,一些问题:

  • 为什么Android armv8a运行时拒绝这些DT标志?
  • 为什么启用LTO似乎会改变TLS的实现或需求?为什么会发出这些标签(以及其他符号)?
  • 如何防止这种情况发生,否则可以避免此问题?我可以要求其他一些TLS模型吗?
  • 我发现了至少另一个这样的问题,其中Android环境拒绝DT_ORIGIN处理通常需要的标志$ORIGIN,但即使未设置$ORIGIN,也仍然尊重DT_ORIGIN。拒绝TLDESC_标志是否可能是类似的过度热情检查,并且该代码实际上是正确的,这将指示NDK错误?

  • 任何见解表示赞赏。请注意,这似乎适用于其他Android目标,特别是Android x86_64构建可以与-flto一起使用,并且生成的二进制文件在TLSDESC输出中不包含任何readelf -a

    最佳答案

    我已升级到NDK r18 beta2,并且不再有此问题。似乎该潜在错误与不通过r18中修复的gold链接器插件(请参阅https://github.com/android-ndk/ndk/issues/498)向下传播仿真TLS的使用有关。

    09-26 14:13