有一个用C ++编写的以Android为目标的动态库。最终的二进制包含许多对相同符号的绝对重定位,例如。为__cxa_pure_virtual
。 readelf --relocs
告诉下一个:
...
00332fe4 00030502 R_ARM_ABS32 00000000 __cxa_pure_virtual
00332fe8 00030502 R_ARM_ABS32 00000000 __cxa_pure_virtual
00332fec 00030502 R_ARM_ABS32 00000000 __cxa_pure_virtual
00332ff0 00030502 R_ARM_ABS32 00000000 __cxa_pure_virtual
00332ff4 00030502 R_ARM_ABS32 00000000 __cxa_pure_virtual
00332ff8 00030502 R_ARM_ABS32 00000000 __cxa_pure_virtual
00332ffc 00030502 R_ARM_ABS32 00000000 __cxa_pure_virtual
003330f4 00030502 R_ARM_ABS32 00000000 __cxa_pure_virtual
003330f8 00030502 R_ARM_ABS32 00000000 __cxa_pure_virtual
003330fc 00030502 R_ARM_ABS32 00000000 __cxa_pure_virtual
...
它们的数量非常庞大。因此,在加载期间,动态链接器会一遍又一遍地寻找相同的符号,从而浪费用户的时间。据我所知,仿生链接器无法缓存查找结果。因此,避免这些疯狂查找的唯一方法是将所有重定位合并为一个。
GCC / Clang是否可以选择控制此类场景的代码生成?也许某些选项强制生成另一个重定位类型,以后可能会被链接器与其他对象模块中的类似重定位类型合并?