我们都知道动态链接是由一个叫做动态链接器的工具来来完成,在linux中即为ld.so(ld.linux.so),
但是它本身也作为一个共享对象存在,那么它本身的重定位,GOT表解析又是谁完成的呢?
解开这个先有鸡还是先有蛋的谜团的是使glibc中的一段代码,也就是本文要分析的代码,
它使用了一种要做bootstrap的思想,中文我也想不好太好的词来翻译,只可意会不可言喻呀!
static ElfW(Addr)//Elf32_Addr或者Elf64_Addr
__attribute_used__ internal_function
_dl_start (void *arg)
{
#ifdef DONT_USE_BOOTSTRAP_MAP
# define bootstrap_map GL(dl_rtld_map)
//展开之后为#define bootstap_map rtld_local._dl_trld_map
#else
struct dl_start_final_info info;
# define bootstrap_map info.l
#endif
/* This #define produces dynamic linking inline functions for
bootstrap relocation instead of general-purpose relocation.
Since ld.so must not have any undefined symbols the result
is trivial: always the map of ld.so itself. */
#define RTLD_BOOTSTRAP
#define RESOLVE_MAP(sym, version, flags) (&bootstrap_map)
#include "dynamic-link.h"
/*里面有几个动态链接需要用的宏和函数,会用到前面这两个宏
如头文件dynamic-link.h中下面这段代码,会根据上面宏的定义与否功能不同
#ifndef RESOLVE_MAP
static
#else
auto
#endif
inline void __attribute__ ((unused, always_inline))
elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
{
ElfW(Dyn) *dyn = l->l_ld;
ElfW(Dyn) **info;
#ifndef RTLD_BOOTSTRAP
if (dyn == NULL)
return;
#endif
*/
if (HP_TIMING_INLINE && HP_TIMING_AVAIL)
#ifdef DONT_USE_BOOTSTRAP_MAP
HP_TIMING_NOW (start_time);//获取开始时间,这个宏的内容跟平台相关
#else
HP_TIMING_NOW (info.start_time);
#endif
/* Partly clean the `bootstrap_map' structure up. Don't use
`memset' since it might not be built in or inlined and we cannot
make function calls at this point. Use '__builtin_memset' if we
know it is available. We do not have to clear the memory if we
do not h