/*Symbol table entry.*/ typedefstruct{ Elf32_Word st name;/*Symbol name (string tbl index)*/ Elf32_Addr st_value;/*Symbol value*/ Elf32_Word st_size;/*Symbol size*/ unsignedchar st info;/*Symbol type and binding */ unsignedchar st_other;/*Symbol visibility*/ Elf32_Section st shndx;/*Section index*/ }Elf32_Sym; /*How to extract and insert information held in the st info field.*/ #define ELF32_ST_BIND(val) (((unsigned char)(val))>>4) #define ELF32_ST_TYPE(val) ((va1)&0xf) #define ELF32_ST_INFO(bind,type)((bind) << 4)+((type) &0xf)
/*Relocation table entry without addend (in section of type SHT_REL).*/ typedefstruct{ Elf32_Addr r_offset;/*Address*/ Elf32_Word r_info;/*Relocation type and symbol index*/ } Elf32_Rel; /*How to extract and insert information held in the r info field.*/ #define ELF32_R_SYM(val) ((val)>>8) #define ELF32_R_TYPE(val) ((val)& Oxff) #define ELF32_R_INFO(sym,type) (((sym)<<8)((type)&0xff))
/* Sanity check that we're really looking at a PLT relocation. */ assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);//检查
/* Look up the target symbol. If the normal lookup rules are not used don't look in the global scope. */ if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0) { conststructr_found_version *version =NULL;
if (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL) { constElfW(Half) *vernum = (constvoid *) D_PTR (l, l_info[VERSYMIDX (DT_VERSYM)]); ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)] & 0x7fff; version = &l->l_versions[ndx]; if (version->hash == 0) version = NULL; }
/* We need to keep the scope around so do some locking. This is not necessary for objects which cannot be unloaded or when we are not using any threads (yet). */ int flags = DL_LOOKUP_ADD_DEPENDENCY; if (!RTLD_SINGLE_THREAD_P) { THREAD_GSCOPE_SET_FLAG (); flags |= DL_LOOKUP_GSCOPE_LOCK; }
/* Currently result contains the base load address (or link map) of the object that defines sym. Now add in the symbol offset. */ value = DL_FIXUP_MAKE_VALUE (result, SYMBOL_ADDRESS (result, sym, false));//获得函数真实地址 } else { /* We already found the symbol. The module (and therefore its load address) is also known. */ value = DL_FIXUP_MAKE_VALUE (l, SYMBOL_ADDRESS (l, sym, true)); result = l; }
/* And now perhaps the relocation addend. */ value = elf_machine_plt_value (l, reloc, value);
if (sym != NULL && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)) value = elf_ifunc_invoke (DL_FIXUP_VALUE_ADDR (value));
/* Finally, fix up the plt itself. */ if (__glibc_unlikely (GLRO(dl_bind_not))) return value;