我正在使用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
一些研究使我得出了这个答案,这使我能够挖掘出0x6ffffef6
和0x6ffffef6
的符号名称,它们恰好分别是TLSDESC_PLT
和TLSDESC_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) 0x2fb50
00000002ffd8 000000000407 R_AARCH64_TLSDESC 0
00000002ffe8 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 环境拒绝
$ORIGIN
处理通常需要的标志DT_ORIGIN
,但即使没有设置DT_ORIGIN
,仍然尊重$ORIGIN
。拒绝TLDESC_
标志是否可能是一种类似的过度检查,并且代码实际上很好,这表明存在 NDK 错误?
任何见解都值得赞赏。请注意,这似乎适用于其他Android目标,特别是Android x86_64构建在-flto
上运行良好,并且生成的二进制文件在readelf -a
输出中没有任何TLSDESC
。
我升级到NDK r18 beta2,不再有这个问题。似乎潜在的错误与不通过黄金链接器插件向下传播模拟TLS的使用有关(参见 https://github.com/android-ndk/ndk/issues/498(,该插件已在r18中修复。