typedefstruct { Elf64_Word st_name; /* Symbol name (string tbl index) */ unsignedchar st_info; /* Symbol type and binding */ unsignedchar st_other; /* Symbol visibility */ Elf64_Section st_shndx; /* Section index */ Elf64_Addr st_value; /* Symbol value */ Elf64_Xword st_size; /* Symbol size */ } Elf64_Sym;
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));
#ifdef SHARED /* Auditing checkpoint: we have a new binding. Provide the auditing libraries the possibility to change the value and tell us whether further auditing is wanted. The l_reloc_result is only allocated if there is an audit module which provides a la_symbind. */ if (l->l_reloc_result != NULL) { /* This is the address in the array where we store the result of previous relocations. */ structreloc_result *reloc_result = &l->l_reloc_result[reloc_index(pltgot, reloc_arg, sizeof(PLTREL))]; unsignedint init = atomic_load_acquire(&reloc_result->init); if (init == 0) { _dl_audit_symbind(l, reloc_result, sym, &value, result);
/* Store the result for later runs. */ if (__glibc_likely(!GLRO(dl_bind_not))) { reloc_result->addr = value; /* Guarantee all previous writes complete before init is updated. See CONCURRENCY NOTES below. */ atomic_store_release(&reloc_result->init, 1); } } else value = reloc_result->addr; } #endif
/* Finally, fix up the plt itself. */ if (__glibc_unlikely(GLRO(dl_bind_not))) return value;