android - 为什么 LTO 在 armv8a NDK 构建中引入新的 DT 标志 TLSDESC_PLT 和 TLSDESC_GOT

标签 android android-ndk linker arm elf

我正在使用 NDK 构建适用于 Android 的 armv8a SDK,我想在启用 LTO 的情况下进行构建。我将 -flto 添加到 C++ 工具链的编译和链接标志中,一切顺利,直到我尝试在模拟器中运行,此时发出如下错误:

警告:链接器:/data/lib/libservice.so:未使用的 DT 条目:类型 0x6ffffef6 arg 0x8e30

警告:链接器:/data/lib/libservice.so:未使用的 DT 条目:类型 0x6ffffef7 arg 0x2fb50

一些研究使我找到了 this answer这使我能够挖掘出 0x6ffffef60x6ffffef6 的符号名称,它们恰好分别是 TLSDESC_PLTTLSDESC_GOT ,显然与动态链接器和 PLT/GOT 以及 TLS 有关。很好。

将非 LTO 构建与 LTO 构建进行比较,这些标志肯定只出现在 LTO 构建中:

$ readelf -a/lto/lib/libservice.so | grep TLS L(链接顺序),O(需要额外的 OS 处理),G(组),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 本地默认值 17 _ZN5xxxxx12_GLOBAL__N_113 788:0000000000000000 1 TLS 本地默认值 17 __tls_guard $

$ readelf -a/nolto/lib/libservice.so | grep TLS L(链接顺序),O(需要额外的 OS 处理),G(组),T(TLS), $

那么,一些问题:

  • 为什么 android armv8a 运行时会拒绝这些 DT 标志?
  • 为什么启用 LTO 似乎会改变 TLS 实现或需求?为什么会发出这些标签(连同其他符号)?
  • 我该如何防止或避免此问题?我可以申请其他 TLS 模型吗?
  • 我至少发现了一个类似的问题,其中 Android 环境拒绝标志 DT_ORIGIN,这通常是 $ORIGIN 处理所必需的,但仍然尊重 $ORIGIN 即使没有设置 DT_ORIGIN。拒绝 TLDESC_ 标志是否可能是一种类似的过度检查,而代码实际上没有问题,这表明存在 NDK 错误?

任何见解表示赞赏。请注意,这似乎适用于其他 Android 目标,特别是 Android x86_64 构建与 -flto 一起工作得很好,并且生成的二进制文件在 readelf -a 输出。

最佳答案

我升级到 NDK r18 beta2,我不再有这个问题。看起来潜在的错误与不通过 gold 链接器插件传播模拟 TLS 的使用有关(请参阅 https://github.com/android-ndk/ndk/issues/498 ),该插件已在 r18 中修复。

关于android - 为什么 LTO 在 armv8a NDK 构建中引入新的 DT 标志 TLSDESC_PLT 和 TLSDESC_GOT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50495647/

相关文章:

android - ART中AOT和JIT编译器的区别

android - 如何从apk提取统一游戏的声音?

android - 如何构建 Android 内核以使用 DS-5 精简?

android - 编译项目时出现 undefined reference 错误(ANDROID NDK)

android - 从 Android 应用程序运行 shell 脚本

C++ 64 位 - 无法读取符号 : Archive has no index; run ranlib to add one

android - 在钛中点击通知后如何打开特定窗口

Android NDK 最佳实践

c++ - 如何在 C++ 中通过链接器进行模拟测试

c - GNU 链接器中的部分链接是什么?