Android dynamic linker

/system/bin/linker是Android的dynamic linker。尽管它是个很小的程序,但它的实现里依然有不少值得学习的地方。

由于dynamic linker要在libc.so被载入之前工作,因此没有malloc可用。它使用了两个算法,为不同目的分配(并管理)内容。

一类内存是为了载入动态链接库的代码段和数据段,这块内存使用buddy memory allocation算法管理。虽然是个简洁的算法,但如果是第一次接触,想通过阅读代码的方式理解它的工作原理,还是有些难度的。幸好维基百科上的条目解释得非常清楚,在此基础上,一些实现上的小技巧也就好理解了。

另一类是使用array + freelist的方式管理soinfo数据。因为数据类型相同,可以使用静态分配的数组;由于soinfo数据可能动态添加和删除,使用array + freelist方式,可以在O(1)内找到空余的项目。

还有一个很神奇的地方,即如果要使用dlopen/dlclose之类的函数,需要链接libdl.so这个动态库,然而在运行时调用的,确是dynamic linker里面的实现。

简单地说,提供libdl.so是为了让linker知道,dlopen/dlclose这几个函数是存在的,在静态链接时不要报undefined reference之类的错误。在实际调用的时候,dynamic linker把这几个symbol的值解析为自己的实现,以达到代码复用,避免重复的目的。在具体实现里,libdl.so对应的soinfo,并不是像其它动态链接库一样,是通过分析对应的文件得来的,而是dynamic linker硬造出来的,使得dlopen/dlclose等symbol解析为dynamic linker内的实现。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据