本文介绍了的Andr​​oid NDK产生不合理的大的二进制文件,如何优化。所以大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经注意到了Android的NDK( R6B 在我的情况)产生导致.so文件不合理的大。例如,在我的情况我有〜150-200行的C ++ code(6本地方法和3 C ++简单的类),这原生code产生的 60KB(!)的.so启用异常和RTTI或12KB。所以用禁用的异常和RTTI。只是为了检查我编的 HELLO-JNI 示例包含在NDK的包,并从这个例子中得到10KB。所以单行本地方法。

在我看来,这是莫名其妙的移动平台不合理开销(我的桌面上的可比性按大小code产生〜10〜15倍以下的.so)。

  1. 有没有窍门,我应该知道,以减少二进制文件的大小?
  2. 为什么有这样的开销C-仅code?
  3. 为什么会有更大的开销C ++ code启用异常和RTTI?

更新#1:readelf输出从NDK HELLO-JNI例如

  ELF头:
  魔术:7F 45 4C 46 01 01 01 00 00 00 00 00 00 00 00 00
  类别:ELF32
  数据:2的补,小尾数
  版本:1(电流)
  OS / ABI:UNIX  - 系统V
  ABI版本:0
  类型:DYN(共享对象文件)
  机:ARM
  版本:为0x1
  入口地址:0xc18
  启动程序标题中:52(字节到文件)
  开始的节标题:9344(字节到文件)
  标志:0x5000002,有切入点,版本5 EABI
  这个头的尺寸:52(字节)
  程序头的尺寸:32(字节)
  程序头数:5
  节头尺寸:40(字节)
  节头数:19
  节头字符串表指数:18

节标题:
  [NR名称类型地址关尺寸ES FLG路天道酬勤铝
  [0] NULL 00000000 000000 000000 00 0 0 0
  [1] .hash HASH 000000d4 0000d4 0001a4 04 A 2 0 4
  [2]显.dynsym DYNSYM 00000278 000278 000420 10 A 3 3 4
  [3]的.dynstr STRTAB 00000698 000698 0004aa 00 0 0 1
  [4] .rel.dyn REL 00000b44 000b44 000048 08 A 2 0 4
  [5] .rel.plt REL 00000b8c 000b8c 000030 08 A 2 6 4
  [6] .PLT PROGBITS 00000bbc 000bbc 00005c 04 AX 0 0 4
  [7]的.text PROGBITS 00000c18 000c18 001518 00 AX 0 0 4
  [8] .RODATA PROGBITS 00002130 002130 000014 01 AMS 0 0 4
  [9] .ARM.extab PROGBITS 00002144 002144 000024 00 0 0 4
  [10] .ARM.exidx ARM_EXIDX 00002168 002168 0000e0 00 AL 7 0 4
  [11] .init_array INIT_ARRAY 00003248 002248 000008 00 WA 0 0 1
  [12] .fini_array FINI_ARRAY 00003250 002250 00000c 00 WA 0 0 1
  [13]。动态动态0000325c 00225c 0000e8 08 WA 3 0 4
  [14]即.got PROGBITS 00003344 002344 000040 04 WA 0 0 4
  [15] .BSS NOBITS 00003390 002384 000010 00 WA 0 0 16
  [16]的.comment PROGBITS 00000000 002384 000036 00 0 0 1
  [17] .ARM.attributes ARM_ATTRIBUTES 00000000 0023ba 000029 00 0 0 1
  [18] .shstrtab STRTAB 00000000 0023e3 00009b 00 0 0 1
关键标志:
  W(写),A(ALLOC),X(执行),M(合并),S(串)
  I(信息),L(链接顺序),G(组),X(未知数)
  O(额外OS处理所需)O(OS专用),P(特定处理器)

有在此文件中没有节组。

程序头:
  型胶印VirtAddr PhysAddr FileSiz MemSiz FLG对齐
  EXIDX 0x002168 0x00002168 0x00002168 0x000e0 0x000e0  -  [R为0x4
  LOAD 0x000000处00000000 00000000 0x02248 0x02248 RE为0x1000
  LOAD 0x002248 0x00003248 0x00003248 0x0013c 0x00158 RW为0x1000
  动态0x00225c 0x0000325c 0x0000325c 0x000e8 0x000e8 RW为0x4
  GNU_STACK 0x000000处00000000 00000000 0x00000 0x00000 RW为0x4

 科段映射:
  段段...
   00 .ARM.exidx
   01 .hash显.dynsym的.dynstr .rel.dyn .rel.plt .PLT的.text .RODATA .ARM.extab .ARM.exidx
   02 .init_array .fini_array。动态.GOT的.bss
   03。动态
   04

动态部分的抵消0x225c包含25项:
  标签类型名称/值
 00000001(需要)共享库:[的libstdc ++等等。]
 00000001(需要)共享库:[libm.so]
 00000001(需要)共享库:[libc.so]
 00000001(需要)共享库:[libdl.so]
 0x0000000e(SONAME)库的soname:[libhello-jni.so]
 0x00000010(符号)为0x0
 0x00000019(INIT_ARRAY)0x3248
 0x0000001b(INIT_ARRAYSZ)8(字节)
 0x0000001a(FINI_ARRAY)0x3250
 0x0000001c(FINI_ARRAYSZ)12(字节)
 0x00000004(HASH)0xd4
 0x00000005(STRTAB)0x698
 0x00000006(SYMTAB)0x278
 0X0000000A(STRSZ)1194(字节)
 0x0000000b(SYMENT)16(字节)
 0x00000003(PLTGOT)0x3344
 0x00000002(PLTRELSZ)48(字节)
 0x00000014(PLTREL)REL
 0x00000017(JM preL)0xb8c
 0x00000011(REL)0xb44
 0x00000012(RELSZ)72(字节)
 0x00000013(松口)8(字节)
 0x00000016(TEXTREL)为0x0
 0x6ffffffa(RELCOUNT)7
 00000000(NULL)为0x0

搬迁节.rel.dyn偏移量0xb44包含9项:
 偏移讯息Sym.Value符号。名称
00000c24 00000017 R_ARM_RELATIVE
00003254 00000017 R_ARM_RELATIVE
00003368 00000017 R_ARM_RELATIVE
0000336c ​​00000017 R_ARM_RELATIVE
00003374 00000017 R_ARM_RELATIVE
00003378 00000017 R_ARM_RELATIVE
00003380 00000017 R_ARM_RELATIVE
00003370 00001015 00000000 R_ARM_GLOB_DAT __cxa_call_unexpected
0000337c 00003215 R_ARM_GLOB_DAT 00000000 __gnu_Unwind_Find_exid

搬迁节.rel.plt偏移量0xb8c包括6项:
 偏移讯息Sym.Value符号。名称
00003350 00000d16 R_ARM_JUMP_SLOT 00000000 __cxa_begin_cleanup
00003354 00001216 00000000 R_ARM_JUMP_SLOT memcpy的
00003358 00001416 00000000 R_ARM_JUMP_SLOT __cxa_finalize
0000335c 00001f16 R_ARM_JUMP_SLOT 00000000中止
00003360 00002a16 R_ARM_JUMP_SLOT 00000000 __cxa_type_match
00003364 00003216 00000000 R_ARM_JUMP_SLOT __gnu_Unwind_Find_exid

还有在这个文件中没有放卷部分。

符号表显.dynsym包含66项:
   编号:值大小类型绑定可见NDX名称
     0:00000000 0 NoType在本地默认UND
     1:00000c18 0部分本地默认7
     2:00003390 0部分本地默认15
     3:00001c64 36 FUNC全局默认7 ___Unwind_ForcedUnwind
     4:00001668 164 FUNC全局默认7 __gnu_Unwind_RaiseExcepti
     5:00001b20 0 FUNC全局默认7 __gnu_Unwind_Save_VFP
     6:00001c40 36 FUNC全局默认7 _Unwind_Resume_or_Rethrow
     7:00002248 0 NoType在全局默认ABS __exidx_end
     8:000011c0 8 FUNC全局默认7 __aeabi_unwind_cpp_pr0
     9:00001d4c 44 FUNC全局默认7 _Unwind_GetRegionStart
    10:00001c40 36 FUNC全局默认7 ___Unwind_Resume_or_Rethr
    11:000033a0 0 NoType在全局默认ABS _bss_end__
    12:00001c88 36 FUNC全局默认7 _Unwind_Backtrace
    13:00000000 0 NoType在弱默认UND __cxa_begin_cleanup
    14:00001b04 20 FUNC全局默认7 __restore_core_regs
    15:00001b40 0 FUNC全局默认7 __gnu_Unwind_Save_VFP_D_1
    16:00000000 0 NoType在弱默认UND __cxa_call_unexpected
    17:00000cf0 8 FUNC全局默认7 _Unwind_GetCFA
    18:00000000 0 FUNC全局默认UND的memcpy
    19:00000c8c 76 FUNC全局默认7 _Unwind_VRS_Set
    20:00000000 0 FUNC全局默认UND __cxa_finalize
    21:00003250 0 NoType在全局默认12 __FINI_ARRAY__
    22:00003384 0 NoType在全局默认ABS __bss_start__
    23:00001404 212 FUNC全局默认7 __gnu_Unwind_Backtrace
    24:00003390 4对象全局默认15 __dso_handle
    25:00001b30 0 FUNC全局默认7 __gnu_Unwind_Save_VFP_D
    26:00001798 876 FUNC全局默认7 _Unwind_VRS_Pop
    27:000011b0 8 FUNC弱默认值7 __aeabi_unwind_cpp_pr2
    28:00001c88 36 FUNC全局默认7 ___Unwind_Backtrace
    29:00002168 0 NoType在全局默认ABS __exidx_start
    30:00001bf8 36 FUNC全局默认7 ___Unwind_RaiseException
    31:00000000 0 FUNC全局默认UND中止
    32:00001c1c 36 FUNC全局默认7 ___Unwind_Resume
    33:00001b48 0 FUNC全局默认7 __gnu_Unwind_Restore_WMMX
    34:00001b18 0 FUNC全局默认7 __gnu_Unwind_Restore_VFP
    35:00001c1c 36 FUNC全局默认7 _Unwind_Resume
    36:00000cfc 32 FUNC全局默认7 _Unwind_DeleteException
    37:00000cf8 4 FUNC全局默认7 _Unwind_Complete
    38:000033a0 0 NoType在全局默认ABS __bss_end__
    39:00003248 0 NoType在全局默认11 __INIT_ARRAY__
    40:00001d78 888 FUNC全局默认7 __gnu_unwind_execute
    41:00001b28 0 FUNC全局默认7 __gnu_Unwind_Restore_VFP_
    42:00000000 0 NoType在弱默认UND __cxa_type_match
    43:0000172c 108 FUNC全局默认7 __gnu_Unwind_Resume
    44:00001b38 0 FUNC全局默认7 __gnu_Unwind_Restore_VFP_
    45:00001bf8 36 FUNC全局默认7 _Unwind_RaiseException
    46:00003384 0 NoType在全局默认ABS __bss_start
    47:000033a0 0 NoType在全局默认ABS __END__
    48:000015f4 28 FUNC全局默认7 __gnu_Unwind_ForcedUnwind
    49:0000170c 32 FUNC全局默认7 __gnu_Unwind_Resume_or_Re
    50:00000000 0 FUNC弱默认UND __gnu_Unwind_Find_exidx
    51:00001b04 20 FUNC全局默认7 restore_core_regs
    52:00001be4 0 FUNC全局默认7 __gnu_Unwind_Save_WMMXC
    53:00001d04 8 FUNC全局默认7 _Unwind_GetTextRelBase
    54:00000c29 24 FUNC全局默认7 Java_com_example_hellojni
    55:00001d14 56 FUNC全局默认7 _Unwind_GetLanguageSpecif
    56:00000c40 76 FUNC全局默认7 _Unwind_VRS_Get
    57:00001bd0 0 FUNC全局默认7 __gnu_Unwind_Restore_WMMX
    58:000020f0 64 FUNC全局默认7 __gnu_unwind_frame
    59:00001c64 36 FUNC全局默认7 _Unwind_ForcedUnwind
    60:00003384 0 NoType在全局默认ABS _edata
    61:000033a0 0 NoType在全局默认ABS _end
    62:00001b8c 0 FUNC全局默认7 __gnu_Unwind_Save_WMMXD
    63:000011b8 8 FUNC弱默认值7 __aeabi_unwind_cpp_pr1
    64:00001d0c 8 FUNC全局默认7 _Unwind_GetDataRelBase
    65:00003384 0 NoType在全局默认14 __data_start

直方图的遗愿清单长度(共37桶):
 总覆盖长度人数%
      0 5(13.5%)
      1月14日(37.8%)22.2%
      2月9日(24.3%)50.8%
      3 6(16.2%)79.4%
      4 2(5.4%)92.1%
      5 1(2.7%)100.0%

没有此文件中的版本信息。
属性组:AEABI
文件属性
  Tag_CPU_name:5TE
  Tag_CPU_arch:结构v5TE
  Tag_ARM_ISA_use:是
  Tag_THUMB_ISA_use:拇指-1
  Tag_ABI_PCS_wchar_t:4
  Tag_ABI_FP_denormal:所需
  Tag_ABI_FP_exceptions:所需
  Tag_ABI_FP_number_model:IEEE 754
  Tag_ABI_align8_needed:是
  Tag_ABI_align8_ preserved:是的,除了叶SP
  Tag_ABI_enum_size:INT
 

您可能会看到一个接 @Joel˚F,尤其是那些关于堆栈展开提供的差异(对C ++异常?)

更新#2

现在的问题是在工具链包含在NDK R6B,特别是对连接器的。由于 @Joel˚F约previous NDK版本胶水。我已经安装了NDK R5C旁边NDK R6B并比较结果。编译器由双方工具链,但连接结果是不同的后产生相同的目标文件。

解决方案

修改3 我能够重现10KB HELLO-JNI二进制NDK R6B。我发现了一个可怕的黑客这里。基本上把此行的文件之一:

 字符__aeabi_unwind_cpp_pr0 [0];
 

但你的code会有所欠缺异常处理(我认为是的 -fno-异常点 ...)

不管怎么说,这带来libhello-jni.so下降到2228字节我。仍比R5C大,但比10KB少了很多。

编辑2 是的,它好像你有很多C ++相关的开销在readelf输出。也许他们改变了R5C和R6B之间的事情?没有C ++ code在R5C的HELLO-jni.c。

我有160行C code表示NDK R5C减少到3.8KB。所以。请尝试以下,看看有什么是责任大小:

<$p$p><$c$c>/path/to/ndk/toolchains/arm-linux-androideabi-4.4.3/$p$pbuilt/<platform>/bin/arm-linux-androideabi-readelf -a libmylib.so

修改我建有NDK R5C的HELLO-JNI的例子,所得 libhello-jni.so 文件是1588字节。

生成命令:

  NDK建造V = 1
 

生成输出: http://pastebin.com/AdRDVbnF (显然让对线长或某事的限制)。

从输出 readelf -a libhello-jni.so

ELF头:
  魔术:7F 45 4C 46 01 01 01 00 00 00 00 00 00 00 00 00
  类别:ELF32
  数据:2的补,小尾数
  版本:1(电流)
  OS / ABI:UNIX  - 系统V
  ABI版本:0
  类型:DYN(共享对象文件)
  机:ARM
  版本:为0x1
  入口地址:0x2dc
  启动程序标题中:52(字节到文件)
  开始的节标题:1108(字节到文件)
  标志:0x5000002,有切入点,版本5 EABI
  这个头的尺寸:52(字节)
  程序头的尺寸:32(字节)
  程序头数:5
  节头尺寸:40(字节)
  节头数:12
  节头字符串表指数:11

节标题:
  [NR名称类型地址关尺寸ES FLG路天道酬勤铝
  [0] NULL 00000000 000000 000000 00 0 0 0
  [1] .hash HASH 000000d4 0000d4 00004c 04 A 2 0 4
  [2]显.dynsym DYNSYM 00000120 000120 0000e0 10 A 3 2 4
  [3]的.dynstr STRTAB 00000200 0002000000分贝00 0 0 1
  [4]的.text PROGBITS 000002dc 0002dc 00002c 00 AX 0 0 4
  [5] .RODATA PROGBITS 00000308 000308 000014 00 0 0 4
  [6] .ARM.exidx ARM_EXIDX 0000031c 00031c 000008 00 AL 4 0 4
  [7]。动态动态00001324 000324 000088 08 WA 3 0 4
  [8] .GOT PROGBITS 000013ac 0003ac 00000c 04 WA 0 0 4
  [9]的.comment PROGBITS 00000000 0003b8 000012 00 0 0 1
  [10] .ARM.attributes ARM_ATTRIBUTES 00000000 0003ca 000029 00 0 0 1
  [11] .shstrtab STRTAB 00000000 0003f3 000061 00 0 0 1
关键标志:
  W(写),A(ALLOC),X(执行),M(合并),S(串)
  I(信息),L(链接顺序),G(组),X(未知数)
  O(额外OS处理所需)O(OS专用),P(特定处理器)

有在此文件中没有节组。

程序头:
  型胶印VirtAddr PhysAddr FileSiz MemSiz FLG对齐
  EXIDX 0x00031c 0x0000031c 0x0000031c 0x00008 0x00008  -  [R为0x4
  LOAD 0x000000处00000000 00000000 0x00324 0x00324 RE为0x1000
  LOAD 0x000324 0x00001324 0x00001324 0x00094 0x00094 RW为0x1000
  动态0x000324 0x00001324 0x00001324 0x00088 0x00088 RW为0x4
  GNU_STACK 0x000000处00000000 00000000 0x00000 0x00000 RW为0x4

 科段映射:
  段段...
   00 .ARM.exidx
   01 .hash显.dynsym的.dynstr的.text .RODATA .ARM.exidx
   02。动态.GOT
   03。动态
   04

动力部分偏移量0x324包含12项:
  标签类型名称/值
 00000001(需要)共享库:[libc.so]
 00000001(需要)共享库:[的libstdc ++等等。]
 00000001(需要)共享库:[libm.so]
 00000001(需要)共享库:[libdl.so]
 0x0000000e(SONAME)库的soname:[libhello-jni.so]
 0x00000010(符号)为0x0
 0x00000004(HASH)0xd4
 0x00000005(STRTAB)为0x200
 0x00000006(SYMTAB)量0x120
 0X0000000A(STRSZ)219(字节)
 0x0000000b(SYMENT)16(字节)
 00000000(NULL)为0x0

还有在这个文件中没有重定位。

还有在这个文件中没有放卷部分。

符号表显.dynsym包含14项:
   编号:值大小类型绑定可见NDX名称
     0:00000000 0 NoType在本地默认UND
     1:0 000002dc部分本地默认4
     2:00000324 0 NoType在全局默认ABS __exidx_end
     3:00000000 0 FUNC全局默认UND __aeabi_unwind_cpp_pr0
     4:000013b8 0 NoType在全局默认ABS _bss_end__
     5:000013b8 0 NoType在全局默认ABS __bss_start__
     6:0000031c 0 NoType在全局默认ABS __exidx_start
     7:000013b8 0 NoType在全局默认ABS __bss_end__
     8:000013b8 0 NoType在全局默认ABS __bss_start
     9:000013b8 0 NoType在全局默认ABS __END__
    10:000002dd 44 FUNC全局默认4 Java_com_example_hellojni
    11:000013b8 0 NoType在全局默认ABS _edata
    12:000013b8 0 NoType在全局默认ABS _end
    13:000013b8 0 NoType在全局默认8 __data_start

直方图的遗愿清单长度(共3桶):
 总覆盖长度人数%
      0 0(0.0%)
      1 0(0.0%)0.0%
      2 1 33.3%16.7%
      3 0(0.0%)16.7%
      4 1(33.3%)50.0%
      5 0(0.0%)50.0%
      6 1(33.3%),100.0%

没有此文件中的版本信息。
属性组:AEABI
文件属性
  Tag_CPU_name:5TE
  Tag_CPU_arch:结构v5TE
  Tag_THUMB_ISA_use:拇指-1
  Tag_ABI_PCS_wchar_t:4
  Tag_ABI_FP_denormal:所需
  Tag_ABI_FP_exceptions:所需
  Tag_ABI_FP_number_model:IEEE 754
  Tag_ABI_align8_needed:是
  Tag_ABI_align8_ preserved:是的,除了叶SP
  Tag_ABI_enum_size:INT
  Tag_ABI_optimization_goals:积极调试

I have notice that Android NDK (r6b in my case) produce unreasonable big resulting .so files. For example, in my case I have ~150-200 lines of C++ code (6 native methods and 3 C++ simplest classes) and this native code produce 60kb (!) .so with enabled exceptions and RTTI or 12kb .so with disabled exceptions and RTTI. Just to check I have compile hello-jni example included in NDK package and get 10kb .so for single-line native method from this example.

In my opinion it is somehow unreasonable overhead for mobile platform (on my desktop the comparable by size code produce ~10-15 times less .so).

  1. Are there tricks I should know to reduce the binaries size ?
  2. Why there is such overhead for C-only code ?
  3. And why there is even bigger overhead for C++ code with enabled exceptions and RTTI ?

Update #1: readelf output for hello-jni example from NDK

ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0xc18
  Start of program headers:          52 (bytes into file)
  Start of section headers:          9344 (bytes into file)
  Flags:                             0x5000002, has entry point, Version5 EABI
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         5
  Size of section headers:           40 (bytes)
  Number of section headers:         19
  Section header string table index: 18

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .hash             HASH            000000d4 0000d4 0001a4 04   A  2   0  4
  [ 2] .dynsym           DYNSYM          00000278 000278 000420 10   A  3   3  4
  [ 3] .dynstr           STRTAB          00000698 000698 0004aa 00   A  0   0  1
  [ 4] .rel.dyn          REL             00000b44 000b44 000048 08   A  2   0  4
  [ 5] .rel.plt          REL             00000b8c 000b8c 000030 08   A  2   6  4
  [ 6] .plt              PROGBITS        00000bbc 000bbc 00005c 04  AX  0   0  4
  [ 7] .text             PROGBITS        00000c18 000c18 001518 00  AX  0   0  4
  [ 8] .rodata           PROGBITS        00002130 002130 000014 01 AMS  0   0  4
  [ 9] .ARM.extab        PROGBITS        00002144 002144 000024 00   A  0   0  4
  [10] .ARM.exidx        ARM_EXIDX       00002168 002168 0000e0 00  AL  7   0  4
  [11] .init_array       INIT_ARRAY      00003248 002248 000008 00  WA  0   0  1
  [12] .fini_array       FINI_ARRAY      00003250 002250 00000c 00  WA  0   0  1
  [13] .dynamic          DYNAMIC         0000325c 00225c 0000e8 08  WA  3   0  4
  [14] .got              PROGBITS        00003344 002344 000040 04  WA  0   0  4
  [15] .bss              NOBITS          00003390 002384 000010 00  WA  0   0 16
  [16] .comment          PROGBITS        00000000 002384 000036 00      0   0  1
  [17] .ARM.attributes   ARM_ATTRIBUTES  00000000 0023ba 000029 00      0   0  1
  [18] .shstrtab         STRTAB          00000000 0023e3 00009b 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

There are no section groups in this file.

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  EXIDX          0x002168 0x00002168 0x00002168 0x000e0 0x000e0 R   0x4
  LOAD           0x000000 0x00000000 0x00000000 0x02248 0x02248 R E 0x1000
  LOAD           0x002248 0x00003248 0x00003248 0x0013c 0x00158 RW  0x1000
  DYNAMIC        0x00225c 0x0000325c 0x0000325c 0x000e8 0x000e8 RW  0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x4

 Section to Segment mapping:
  Segment Sections...
   00     .ARM.exidx 
   01     .hash .dynsym .dynstr .rel.dyn .rel.plt .plt .text .rodata .ARM.extab .ARM.exidx 
   02     .init_array .fini_array .dynamic .got .bss 
   03     .dynamic 
   04     

Dynamic section at offset 0x225c contains 25 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libstdc++.so]
 0x00000001 (NEEDED)                     Shared library: [libm.so]
 0x00000001 (NEEDED)                     Shared library: [libc.so]
 0x00000001 (NEEDED)                     Shared library: [libdl.so]
 0x0000000e (SONAME)                     Library soname: [libhello-jni.so]
 0x00000010 (SYMBOLIC)                   0x0
 0x00000019 (INIT_ARRAY)                 0x3248
 0x0000001b (INIT_ARRAYSZ)               8 (bytes)
 0x0000001a (FINI_ARRAY)                 0x3250
 0x0000001c (FINI_ARRAYSZ)               12 (bytes)
 0x00000004 (HASH)                       0xd4
 0x00000005 (STRTAB)                     0x698
 0x00000006 (SYMTAB)                     0x278
 0x0000000a (STRSZ)                      1194 (bytes)
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000003 (PLTGOT)                     0x3344
 0x00000002 (PLTRELSZ)                   48 (bytes)
 0x00000014 (PLTREL)                     REL
 0x00000017 (JMPREL)                     0xb8c
 0x00000011 (REL)                        0xb44
 0x00000012 (RELSZ)                      72 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x00000016 (TEXTREL)                    0x0
 0x6ffffffa (RELCOUNT)                   7
 0x00000000 (NULL)                       0x0

Relocation section '.rel.dyn' at offset 0xb44 contains 9 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
00000c24  00000017 R_ARM_RELATIVE   
00003254  00000017 R_ARM_RELATIVE   
00003368  00000017 R_ARM_RELATIVE   
0000336c  00000017 R_ARM_RELATIVE   
00003374  00000017 R_ARM_RELATIVE   
00003378  00000017 R_ARM_RELATIVE   
00003380  00000017 R_ARM_RELATIVE   
00003370  00001015 R_ARM_GLOB_DAT    00000000   __cxa_call_unexpected
0000337c  00003215 R_ARM_GLOB_DAT    00000000   __gnu_Unwind_Find_exid

Relocation section '.rel.plt' at offset 0xb8c contains 6 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
00003350  00000d16 R_ARM_JUMP_SLOT   00000000   __cxa_begin_cleanup
00003354  00001216 R_ARM_JUMP_SLOT   00000000   memcpy
00003358  00001416 R_ARM_JUMP_SLOT   00000000   __cxa_finalize
0000335c  00001f16 R_ARM_JUMP_SLOT   00000000   abort
00003360  00002a16 R_ARM_JUMP_SLOT   00000000   __cxa_type_match
00003364  00003216 R_ARM_JUMP_SLOT   00000000   __gnu_Unwind_Find_exid

There are no unwind sections in this file.

Symbol table '.dynsym' contains 66 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00000c18     0 SECTION LOCAL  DEFAULT    7 
     2: 00003390     0 SECTION LOCAL  DEFAULT   15 
     3: 00001c64    36 FUNC    GLOBAL DEFAULT    7 ___Unwind_ForcedUnwind
     4: 00001668   164 FUNC    GLOBAL DEFAULT    7 __gnu_Unwind_RaiseExcepti
     5: 00001b20     0 FUNC    GLOBAL DEFAULT    7 __gnu_Unwind_Save_VFP
     6: 00001c40    36 FUNC    GLOBAL DEFAULT    7 _Unwind_Resume_or_Rethrow
     7: 00002248     0 NOTYPE  GLOBAL DEFAULT  ABS __exidx_end
     8: 000011c0     8 FUNC    GLOBAL DEFAULT    7 __aeabi_unwind_cpp_pr0
     9: 00001d4c    44 FUNC    GLOBAL DEFAULT    7 _Unwind_GetRegionStart
    10: 00001c40    36 FUNC    GLOBAL DEFAULT    7 ___Unwind_Resume_or_Rethr
    11: 000033a0     0 NOTYPE  GLOBAL DEFAULT  ABS _bss_end__
    12: 00001c88    36 FUNC    GLOBAL DEFAULT    7 _Unwind_Backtrace
    13: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __cxa_begin_cleanup
    14: 00001b04    20 FUNC    GLOBAL DEFAULT    7 __restore_core_regs
    15: 00001b40     0 FUNC    GLOBAL DEFAULT    7 __gnu_Unwind_Save_VFP_D_1
    16: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __cxa_call_unexpected
    17: 00000cf0     8 FUNC    GLOBAL DEFAULT    7 _Unwind_GetCFA
    18: 00000000     0 FUNC    GLOBAL DEFAULT  UND memcpy
    19: 00000c8c    76 FUNC    GLOBAL DEFAULT    7 _Unwind_VRS_Set
    20: 00000000     0 FUNC    GLOBAL DEFAULT  UND __cxa_finalize
    21: 00003250     0 NOTYPE  GLOBAL DEFAULT   12 __FINI_ARRAY__
    22: 00003384     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start__
    23: 00001404   212 FUNC    GLOBAL DEFAULT    7 __gnu_Unwind_Backtrace
    24: 00003390     4 OBJECT  GLOBAL DEFAULT   15 __dso_handle
    25: 00001b30     0 FUNC    GLOBAL DEFAULT    7 __gnu_Unwind_Save_VFP_D
    26: 00001798   876 FUNC    GLOBAL DEFAULT    7 _Unwind_VRS_Pop
    27: 000011b0     8 FUNC    WEAK   DEFAULT    7 __aeabi_unwind_cpp_pr2
    28: 00001c88    36 FUNC    GLOBAL DEFAULT    7 ___Unwind_Backtrace
    29: 00002168     0 NOTYPE  GLOBAL DEFAULT  ABS __exidx_start
    30: 00001bf8    36 FUNC    GLOBAL DEFAULT    7 ___Unwind_RaiseException
    31: 00000000     0 FUNC    GLOBAL DEFAULT  UND abort
    32: 00001c1c    36 FUNC    GLOBAL DEFAULT    7 ___Unwind_Resume
    33: 00001b48     0 FUNC    GLOBAL DEFAULT    7 __gnu_Unwind_Restore_WMMX
    34: 00001b18     0 FUNC    GLOBAL DEFAULT    7 __gnu_Unwind_Restore_VFP
    35: 00001c1c    36 FUNC    GLOBAL DEFAULT    7 _Unwind_Resume
    36: 00000cfc    32 FUNC    GLOBAL DEFAULT    7 _Unwind_DeleteException
    37: 00000cf8     4 FUNC    GLOBAL DEFAULT    7 _Unwind_Complete
    38: 000033a0     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_end__
    39: 00003248     0 NOTYPE  GLOBAL DEFAULT   11 __INIT_ARRAY__
    40: 00001d78   888 FUNC    GLOBAL DEFAULT    7 __gnu_unwind_execute
    41: 00001b28     0 FUNC    GLOBAL DEFAULT    7 __gnu_Unwind_Restore_VFP_
    42: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __cxa_type_match
    43: 0000172c   108 FUNC    GLOBAL DEFAULT    7 __gnu_Unwind_Resume
    44: 00001b38     0 FUNC    GLOBAL DEFAULT    7 __gnu_Unwind_Restore_VFP_
    45: 00001bf8    36 FUNC    GLOBAL DEFAULT    7 _Unwind_RaiseException
    46: 00003384     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
    47: 000033a0     0 NOTYPE  GLOBAL DEFAULT  ABS __end__
    48: 000015f4    28 FUNC    GLOBAL DEFAULT    7 __gnu_Unwind_ForcedUnwind
    49: 0000170c    32 FUNC    GLOBAL DEFAULT    7 __gnu_Unwind_Resume_or_Re
    50: 00000000     0 FUNC    WEAK   DEFAULT  UND __gnu_Unwind_Find_exidx
    51: 00001b04    20 FUNC    GLOBAL DEFAULT    7 restore_core_regs
    52: 00001be4     0 FUNC    GLOBAL DEFAULT    7 __gnu_Unwind_Save_WMMXC
    53: 00001d04     8 FUNC    GLOBAL DEFAULT    7 _Unwind_GetTextRelBase
    54: 00000c29    24 FUNC    GLOBAL DEFAULT    7 Java_com_example_hellojni
    55: 00001d14    56 FUNC    GLOBAL DEFAULT    7 _Unwind_GetLanguageSpecif
    56: 00000c40    76 FUNC    GLOBAL DEFAULT    7 _Unwind_VRS_Get
    57: 00001bd0     0 FUNC    GLOBAL DEFAULT    7 __gnu_Unwind_Restore_WMMX
    58: 000020f0    64 FUNC    GLOBAL DEFAULT    7 __gnu_unwind_frame
    59: 00001c64    36 FUNC    GLOBAL DEFAULT    7 _Unwind_ForcedUnwind
    60: 00003384     0 NOTYPE  GLOBAL DEFAULT  ABS _edata
    61: 000033a0     0 NOTYPE  GLOBAL DEFAULT  ABS _end
    62: 00001b8c     0 FUNC    GLOBAL DEFAULT    7 __gnu_Unwind_Save_WMMXD
    63: 000011b8     8 FUNC    WEAK   DEFAULT    7 __aeabi_unwind_cpp_pr1
    64: 00001d0c     8 FUNC    GLOBAL DEFAULT    7 _Unwind_GetDataRelBase
    65: 00003384     0 NOTYPE  GLOBAL DEFAULT   14 __data_start

Histogram for bucket list length (total of 37 buckets):
 Length  Number     % of total  Coverage
      0  5          ( 13.5%)
      1  14         ( 37.8%)     22.2%
      2  9          ( 24.3%)     50.8%
      3  6          ( 16.2%)     79.4%
      4  2          (  5.4%)     92.1%
      5  1          (  2.7%)    100.0%

No version information found in this file.
Attribute Section: aeabi
File Attributes
  Tag_CPU_name: "5TE"
  Tag_CPU_arch: v5TE
  Tag_ARM_ISA_use: Yes
  Tag_THUMB_ISA_use: Thumb-1
  Tag_ABI_PCS_wchar_t: 4
  Tag_ABI_FP_denormal: Needed
  Tag_ABI_FP_exceptions: Needed
  Tag_ABI_FP_number_model: IEEE 754
  Tag_ABI_align8_needed: Yes
  Tag_ABI_align8_preserved: Yes, except leaf SP
  Tag_ABI_enum_size: int

You may see the difference from one provided by @Joel F, and especially stuff about stack unwinding (for C++ exceptions ?)

Update #2

The problem is in toolchain included in NDK r6b and in particular it is about of linker. Thanks to @Joel F for glues about previous NDK release. I have installed the NDK r5c alongside of NDK r6b and compare results. Compilers produce the same object files by both toolchains but after linking results are different.

解决方案

EDIT 3I was able to reproduce the 10KB hello-jni binary with NDK r6b. I found an awful hack here. Basically put this line in one of your files:

char __aeabi_unwind_cpp_pr0[0];

But your code will be lacking exception handling (which I thought was the point of -fno-exceptions....)

Anyways, this brings libhello-jni.so down to 2228 bytes for me. Still larger than r5c, but a lot less than 10KB.

EDIT 2Yes it seems like you have a lot of C++ related overhead in your readelf output. Perhaps they changed something between r5c and r6b? There is no C++ code in r5c's hello-jni.c.

I have 160 lines of C code that NDK r5c reduces to a 3.8KB .so. Try the following to see what is responsible for the size:

/path/to/ndk/toolchains/arm-linux-androideabi-4.4.3/prebuilt/<platform>/bin/arm-linux-androideabi-readelf -a libmylib.so

EDITI built the hello-jni example with NDK r5c and the resulting libhello-jni.so file is 1588 bytes.

Build command:

ndk-build V=1

Build output: http://pastebin.com/AdRDVbnF (apparently SO has limits on line length or something).

Output from readelf -a libhello-jni.so:

ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x2dc
  Start of program headers:          52 (bytes into file)
  Start of section headers:          1108 (bytes into file)
  Flags:                             0x5000002, has entry point, Version5 EABI
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         5
  Size of section headers:           40 (bytes)
  Number of section headers:         12
  Section header string table index: 11

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .hash             HASH            000000d4 0000d4 00004c 04   A  2   0  4
  [ 2] .dynsym           DYNSYM          00000120 000120 0000e0 10   A  3   2  4
  [ 3] .dynstr           STRTAB          00000200 000200 0000db 00   A  0   0  1
  [ 4] .text             PROGBITS        000002dc 0002dc 00002c 00  AX  0   0  4
  [ 5] .rodata           PROGBITS        00000308 000308 000014 00   A  0   0  4
  [ 6] .ARM.exidx        ARM_EXIDX       0000031c 00031c 000008 00  AL  4   0  4
  [ 7] .dynamic          DYNAMIC         00001324 000324 000088 08  WA  3   0  4
  [ 8] .got              PROGBITS        000013ac 0003ac 00000c 04  WA  0   0  4
  [ 9] .comment          PROGBITS        00000000 0003b8 000012 00      0   0  1
  [10] .ARM.attributes   ARM_ATTRIBUTES  00000000 0003ca 000029 00      0   0  1
  [11] .shstrtab         STRTAB          00000000 0003f3 000061 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

There are no section groups in this file.

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  EXIDX          0x00031c 0x0000031c 0x0000031c 0x00008 0x00008 R   0x4
  LOAD           0x000000 0x00000000 0x00000000 0x00324 0x00324 R E 0x1000
  LOAD           0x000324 0x00001324 0x00001324 0x00094 0x00094 RW  0x1000
  DYNAMIC        0x000324 0x00001324 0x00001324 0x00088 0x00088 RW  0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x4

 Section to Segment mapping:
  Segment Sections...
   00     .ARM.exidx 
   01     .hash .dynsym .dynstr .text .rodata .ARM.exidx 
   02     .dynamic .got 
   03     .dynamic 
   04     

Dynamic section at offset 0x324 contains 12 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libc.so]
 0x00000001 (NEEDED)                     Shared library: [libstdc++.so]
 0x00000001 (NEEDED)                     Shared library: [libm.so]
 0x00000001 (NEEDED)                     Shared library: [libdl.so]
 0x0000000e (SONAME)                     Library soname: [libhello-jni.so]
 0x00000010 (SYMBOLIC)                   0x0
 0x00000004 (HASH)                       0xd4
 0x00000005 (STRTAB)                     0x200
 0x00000006 (SYMTAB)                     0x120
 0x0000000a (STRSZ)                      219 (bytes)
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000000 (NULL)                       0x0

There are no relocations in this file.

There are no unwind sections in this file.

Symbol table '.dynsym' contains 14 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 000002dc     0 SECTION LOCAL  DEFAULT    4 
     2: 00000324     0 NOTYPE  GLOBAL DEFAULT  ABS __exidx_end
     3: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_unwind_cpp_pr0
     4: 000013b8     0 NOTYPE  GLOBAL DEFAULT  ABS _bss_end__
     5: 000013b8     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start__
     6: 0000031c     0 NOTYPE  GLOBAL DEFAULT  ABS __exidx_start
     7: 000013b8     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_end__
     8: 000013b8     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
     9: 000013b8     0 NOTYPE  GLOBAL DEFAULT  ABS __end__
    10: 000002dd    44 FUNC    GLOBAL DEFAULT    4 Java_com_example_hellojni
    11: 000013b8     0 NOTYPE  GLOBAL DEFAULT  ABS _edata
    12: 000013b8     0 NOTYPE  GLOBAL DEFAULT  ABS _end
    13: 000013b8     0 NOTYPE  GLOBAL DEFAULT    8 __data_start

Histogram for bucket list length (total of 3 buckets):
 Length  Number     % of total  Coverage
      0  0          (  0.0%)
      1  0          (  0.0%)      0.0%
      2  1          ( 33.3%)     16.7%
      3  0          (  0.0%)     16.7%
      4  1          ( 33.3%)     50.0%
      5  0          (  0.0%)     50.0%
      6  1          ( 33.3%)    100.0%

No version information found in this file.
Attribute Section: aeabi
File Attributes
  Tag_CPU_name: "5TE"
  Tag_CPU_arch: v5TE
  Tag_THUMB_ISA_use: Thumb-1
  Tag_ABI_PCS_wchar_t: 4
  Tag_ABI_FP_denormal: Needed
  Tag_ABI_FP_exceptions: Needed
  Tag_ABI_FP_number_model: IEEE 754
  Tag_ABI_align8_needed: Yes
  Tag_ABI_align8_preserved: Yes, except leaf SP
  Tag_ABI_enum_size: int
  Tag_ABI_optimization_goals: Aggressive Debug

这篇关于的Andr​​oid NDK产生不合理的大的二进制文件,如何优化。所以大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-03 03:43