/* This is the second half of _dl_start (below). It can be inlined safely
under DONT_USE_BOOTSTRAP_MAP, where it is careful not to make any GOTreferences. When the tools don't permit us to avoid using a GOT entry
for _dl_rtld_global (no attribute_hidden support), we must make sure
this function is not inlined (see below). */
这是_dl_start函数的一部分,仅供_start_start函数调用,
如果DONT_USE_BOOTSTRAP_MAP宏被定义,它能内联,不允许GOT引用
如果编译器允许使用GOT入口来访问_dl_rtld_global,则此函数不许inlined
#ifdef DONT_USE_BOOTSTRAP_MAPstatic inline ElfW(Addr) __attribute__ ((always_inline)) _dl_start_final (void *arg)
#else
static ElfW(Addr) __attribute__ ((noinline))
_dl_start_final (void *arg, struct dl_start_final_info *info)
#endif
{
ElfW(Addr) start_addr;
if (HP_TIMING_AVAIL)
{
/* If it hasn't happen yet record the startup time. */
if (! HP_TIMING_INLINE)
HP_TIMING_NOW (start_time);
#if !defined DONT_USE_BOOTSTRAP_MAP && !defined HP_TIMING_NONAVAIL
else
start_time = info->start_time;
#endif
/* Initialize the timing functions. */
HP_TIMING_DIFF_INIT (); //平台相关宏,初始化dl_hp_timing_overhead
}
/* Transfer data about ourselves to the permanent link_map structure. */
#ifndef DONT_USE_BOOTSTRAP_MAP
GL(dl_rtld_map).l_addr = info->l.l_addr;
GL(dl_rtld_map).l_ld = info->l.l_ld;
memcpy (GL(dl_rtld_map).l_info, info->l.l_info,
sizeof GL(dl_rtld_map).l_info);
GL(dl_rtld_map).l_mach = info->l.l_mach;
GL(dl_rtld_map).l_relocated = 1;
#endif
_dl_setup_hash (&GL(dl_rtld_map));
下面插入_dl_setup_hash函数的注释
==============================_dl_setup_hash start===============================
/* Cache the location of MAP's hash table. */
void
internal_function
_dl_setup_hash (struct link_map *map)
{
Elf_Symndx *hash;
Elf_Symndx nchain;
插入link_map结构体的l_info字段注释,定义于include/link.h
========================link_map.l_info start=================
/* Indexed pointers to dynamic section.
[0,DT_NUM) are indexed by the processor-independent tags.
[DT_NUM,DT_NUM+DT_THISPROCNUM) are indexed by the tag minus DT_LOPROC.
[DT_NUM+DT_THISPROCNUM,DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM) are
indexed by DT_VERSIONTAGIDX(tagvalue).
[DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM,
DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM) are indexed by
DT_EXTRATAGIDX(tagvalue).
[DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM,
DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM+DT_VALNUM) are
indexed by DT_VALTAGIDX(tagvalue) and
[DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM+DT_VALNUM,
DT_NUM+DT_THISPROCNUM+DT_VERSIONTAGNUM+DT_EXTRANUM+DT_VALNUM+DT_ADDRNUM)
are indexed by DT_ADDRTAGIDX(tagvalue), see <elf.h>. */
一个区间指针数组,指针指向各个动态连接的段(section)
DT_NUM = 34(elf.h) &