手动排查so文件是否已经适配16KB对齐

谷歌商店已经在2025年11月1号开始限制所有上传的app必须适配16KB对齐,否则将无法发布。

因此需要排查app中引入的so文件是否适配了16KB对齐。

如果已经有so文件,想快速排查是否已经适配16KB对齐,可以尝试如下方法:

  1. Android ndk中已经包含检测so文件的工具:aarch64-linux-android-readelf,该文件在ndk的很多目录中都有,我们可以选择任意路径下的文件,以macOS系统为例:

/Users/[username]/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/bin/

其中的[username]替换为用户名,21.4.7075529替换为本机安装的ndk版本。

  1. 打开命令行工具,cd到上述目录,然后执行命令:

./aarch64-linux-android-readelf -l /Users/[username]/sw/libtest.so

-l后面的参数表示so文件的路径,替换为实际路径。

已经适配16KB对齐的结果示例:

复制代码
Elf file type is DYN (Shared object file)
Entry point 0x2726c0
There are 9 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000000040 0x0000000000000040
                 0x00000000000001f8 0x00000000000001f8  R      8
  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000813040 0x0000000000813040  R E    4000
  LOAD           0x0000000000813040 0x0000000000817040 0x0000000000817040
                 0x000000000004bba8 0x000000000004bba8  RW     4000
  LOAD           0x000000000085ec00 0x0000000000866c00 0x0000000000866c00
                 0x0000000000002ed8 0x000000000011e990  RW     4000
  DYNAMIC        0x000000000085ad80 0x000000000085ed80 0x000000000085ed80
                 0x00000000000001e0 0x00000000000001e0  RW     8
  GNU_RELRO      0x0000000000813040 0x0000000000817040 0x0000000000817040
                 0x000000000004bba8 0x000000000004bfc0  R      1
  GNU_EH_FRAME   0x0000000000155584 0x0000000000155584 0x0000000000155584
                 0x0000000000038eac 0x0000000000038eac  R      4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0
  NOTE           0x0000000000000238 0x0000000000000238 0x0000000000000238
                 0x00000000000000b0 0x00000000000000b0  R      4

 Section to Segment mapping:
  Segment Sections...
   00     
   01     .note.android.ident .note.gnu.build-id .dynsym .gnu.version .gnu.version_r .gnu.hash .hash .dynstr .rela.dyn .rela.plt .rodata .gcc_except_table .eh_frame_hdr .eh_frame .text .plt 
   02     .fini_array .data.rel.ro .init_array .dynamic .got .got.plt 
   03     .data .bss 
   04     .dynamic 
   05     .fini_array .data.rel.ro .init_array .dynamic .got .got.plt 
   06     .eh_frame_hdr 
   07     
   08     .note.android.ident .note.gnu.build-id 

上述结果3个LOAD段的Align参数都是4000,这是16进制形式,转为10进制就是16384,即16KB对齐。

未适配16KB对齐的结果示例:

复制代码
Elf file type is DYN (Shared object file)
Entry point 0x259540
There are 9 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000000040 0x0000000000000040
                 0x00000000000001f8 0x00000000000001f8  R      8
  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000751e40 0x0000000000751e40  R E    1000
  LOAD           0x0000000000751e40 0x0000000000752e40 0x0000000000752e40
                 0x0000000000049890 0x0000000000049890  RW     1000
  LOAD           0x000000000079b6e0 0x000000000079d6e0 0x000000000079d6e0
                 0x0000000000002de8 0x000000000010bed0  RW     1000
  DYNAMIC        0x0000000000797ec0 0x0000000000798ec0 0x0000000000798ec0
                 0x00000000000001e0 0x00000000000001e0  RW     8
  GNU_RELRO      0x0000000000751e40 0x0000000000752e40 0x0000000000752e40
                 0x0000000000049890 0x000000000004a1c0  R      1
  GNU_EH_FRAME   0x0000000000147bf4 0x0000000000147bf4 0x0000000000147bf4
                 0x0000000000036b14 0x0000000000036b14  R      4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0
  NOTE           0x0000000000000238 0x0000000000000238 0x0000000000000238
                 0x00000000000000b0 0x00000000000000b0  R      4

 Section to Segment mapping:
  Segment Sections...
   00     
   01     .note.android.ident .note.gnu.build-id .dynsym .gnu.version .gnu.version_r .gnu.hash .hash .dynstr .rela.dyn .rela.plt .rodata .gcc_except_table .eh_frame_hdr .eh_frame .text .plt 
   02     .fini_array .data.rel.ro .init_array .dynamic .got .got.plt 
   03     .data .bss 
   04     .dynamic 
   05     .fini_array .data.rel.ro .init_array .dynamic .got .got.plt 
   06     .eh_frame_hdr 
   07     
   08     .note.android.ident .note.gnu.build-id 

上述结果3个LOAD段的Align参数都是1000,这是16进制形式,转为10进制就是4096,即4KB对齐。说明此so不支持16KB对齐,需要重编。

可能需要适配16KB对齐的结果示例:

复制代码
Elf file type is DYN (Shared object file)
Entry point 0x19e60
There are 7 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x000000000043d970 0x000000000043d970  R E    10000
  LOAD           0x0000000000446310 0x0000000000446310 0x0000000000446310
                 0x000000000000cce8 0x0000000000038ad0  RW     10000
  DYNAMIC        0x000000000044e7b8 0x000000000044e7b8 0x000000000044e7b8
                 0x0000000000000210 0x0000000000000210  RW     8
  NOTE           0x00000000000001c8 0x00000000000001c8 0x00000000000001c8
                 0x0000000000000024 0x0000000000000024  R      4
  GNU_EH_FRAME   0x00000000003e91c0 0x00000000003e91c0 0x00000000003e91c0
                 0x000000000000f644 0x000000000000f644  R      4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     10
  GNU_RELRO      0x0000000000446310 0x0000000000446310 0x0000000000446310
                 0x0000000000009cf0 0x0000000000009cf0  R      1

 Section to Segment mapping:
  Segment Sections...
   00     .note.gnu.build-id .hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .plt .text .rodata .eh_frame_hdr .eh_frame 
   01     .init_array .fini_array .data.rel.ro .dynamic .got .data .bss 
   02     .dynamic 
   03     .note.gnu.build-id 
   04     .eh_frame_hdr 
   05     
   06     .init_array .fini_array .data.rel.ro .dynamic .got 

上述结果3个LOAD段的Align参数都是10000,这是16进制形式,转为10进制就是65536,即64KB对齐。理论上来说,64KB对齐的so是支持16KB对齐的,但是有可能早期的ndk编译出来的so在16KB对齐的设备上会崩溃,因此此种情况需要测试一下,看看结果。如果功能正常不崩溃,则不需要适配。否则需要基于较新的ndk重新编译或改为16KB对齐。

说明:

上述方式只是可以初步排查出没有适配的so,没有适配的so一定需要重编。对于其他情况,就需要实际验证再确定是否需要重编了。

相关推荐
津津有味道1 年前
Android Studio创建新项目并引入第三方so外部aar库驱动NFC读写器读写IC卡
android·ide·android studio·引用·so·aar
机器学习之心1 年前
JCR一区级 | Matlab实现SO-Transformer-LSTM多变量回归预测(蛇群算法优化)
matlab·lstm·transformer·蛇群算法优化·so
呦呦乎2 年前
Android NDK开发 CMAKE 相关总结
android·opencv·cmake·ndk·so
云满笔记2 年前
golang 动态库 (buildmode)
golang·dll·a·so·buildmode
云水-禅心2 年前
Android NDK JNI 开发native层崩溃日志栈分析
android·jvm·jni·so
机器学习之心2 年前
回归预测 | Matlab实现SO-CNN-SVM蛇群算法优化卷积神经网络-支持向量机的多输入单输出回归预测
多输入单输出回归预测·蛇群算法优化·cnn-svm·卷积神经网络-支持向量机·so-cnn-svm·so