最近,我一直在颠倒Nexus S手机的Android框架。
99%的源代码当然是开放的,但是很少有适当的共享库需要下载才能编译操作系统。 。
这些共享库已从符号中剥离,突然间我才明白我并不真正了解剥离的库是如何链接的。如果符号不存在,链接器如何匹配引用的库函数?

#1 楼

即使是剥离的库仍然必须保留动态链接所需的符号。这些通常放置在名为.dynsym的部分中,并且也由动态部分中的条目指向。

例如,以下是剥离的Android库上readelf的输出:

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            000000b4 0000b4 000280 04   A  2   0  4
  [ 2] .dynsym           DYNSYM          00000334 000334 0005b0 10   A  3   6  4
  [ 3] .dynstr           STRTAB          000008e4 0008e4 00042f 00   A  0   0  1
  [ 4] .rel.dyn          REL             00000d14 000d14 000008 08   A  2   2  4
  [ 5] .rel.plt          REL             00000d1c 000d1c 000100 08   A  2   6  4
  [ 6] .plt              PROGBITS        00000e24 000e24 000214 04  AX  0   0  4
  [ 7] .text             PROGBITS        00001038 001038 00210c 00  AX  0   0  8
  [ 8] .rodata           PROGBITS        00003144 003144 000a70 00   A  0   0  4
  [ 9] .ARM.extab        PROGBITS        00003bb4 003bb4 000024 00   A  0   0  4
  [10] .ARM.exidx        ARM_EXIDX       00003bd8 003bd8 000170 00  AL  7   0  4
  [11] .dynamic          DYNAMIC         00004000 004000 0000c8 08  WA  3   0  4
  [12] .got              PROGBITS        000040c8 0040c8 000094 04  WA  0   0  4
  [13] .data             PROGBITS        0000415c 00415c 000004 00  WA  0   0  4
  [14] .bss              NOBITS          00004160 004160 000940 00  WA  0   0  4
  [15] .ARM.attributes   ARM_ATTRIBUTES  00000000 004160 000010 00      0   0  1
  [16] .shstrtab         STRTAB          00000000 004170 000080 00      0   0  1


您可以看到,即使缺少.symtab部分,.dynsym仍然存在。实际上,也可以删除节表(例如,使用sstrip),并且该文件仍然有效。这是因为动态链接器仅使用程序头(也就是段表): :

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  EXIDX          0x003bd8 0x00003bd8 0x00003bd8 0x00170 0x00170 R   0x4
  LOAD           0x000000 0x00000000 0x00000000 0x03d48 0x03d48 R E 0x1000
  LOAD           0x004000 0x00004000 0x00004000 0x00160 0x00aa0 RW  0x1000
  DYNAMIC        0x004000 0x00004000 0x00004000 0x000c8 0x000c8 RW  0x4


符号解析所需的两个输入是DYNAMIC.dynamic。它们一起构成了动态符号表:

Dynamic section at offset 0x4000 contains 21 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [liblog.so]
 0x00000001 (NEEDED)                     Shared library: [libcutils.so]
 0x00000001 (NEEDED)                     Shared library: [libc.so]
 0x00000001 (NEEDED)                     Shared library: [libstdc++.so]
 0x00000001 (NEEDED)                     Shared library: [libm.so]
 0x0000000e (SONAME)                     Library soname: [libnetutils.so]
 0x00000010 (SYMBOLIC)                   0x0
 0x00000004 (HASH)                       0xb4
 0x00000005 (STRTAB)                     0x8e4
 0x00000006 (SYMTAB)                     0x334
 0x0000000a (STRSZ)                      1071 (bytes)
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000003 (PLTGOT)                     0x40c8
 0x00000002 (PLTRELSZ)                   256 (bytes)
 0x00000014 (PLTREL)                     REL
 0x00000017 (JMPREL)                     0xd1c
 0x00000011 (REL)                        0xd14
 0x00000012 (RELSZ)                      8 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x6ffffffa (RELCOUNT)                   1
 0x00000000 (NULL)                       0x0


您可以看到它包含STRTAB(未定义)符号-库所需的符号和从其他.so导入的符号。 ,以及由库为其用户导出的“常规”全局符号。导出的符号的地址在“值”列中列出的库中。

评论


感谢您的回答。可能是正确的,但似乎我需要阅读一些才能理解该主题。

–烛光
13年5月12日在6:57

如果是这样,为什么首先要包含符号?只是重复而已。

– MarcusJ
2014年10月3日14:35