50 # error Not yet ported to non-x86_64 architectures
53 static struct vdso_info
63 const char *symstrings;
73 static unsigned long elf_hash(
const unsigned char *
name)
75 unsigned long h = 0,
g;
78 h = (h << 4) + *name++;
79 if (g = h & 0xf0000000)
89 bool found_vaddr =
false;
91 vdso_info.valid =
false;
93 vdso_info.load_addr = base;
103 for (i = 0; i < hdr->
e_phnum; i++)
105 if (pt[i].p_type ==
PT_LOAD && !found_vaddr) {
107 vdso_info.load_offset = base
111 dyn = (
Elf64_Dyn*)(base + pt[i].p_offset);
115 if (!found_vaddr || !dyn)
122 vdso_info.symstrings = 0;
123 vdso_info.symtab = 0;
124 vdso_info.versym = 0;
125 vdso_info.verdef = 0;
127 switch (dyn[i].d_tag) {
129 vdso_info.symstrings = (
const char *)
131 + vdso_info.load_offset);
136 + vdso_info.load_offset);
141 + vdso_info.load_offset);
144 vdso_info.versym = (Elf64_Versym *)
146 + vdso_info.load_offset);
149 vdso_info.verdef = (Elf64_Verdef *)
151 + vdso_info.load_offset);
155 if (!vdso_info.symstrings || !vdso_info.symtab || !hash)
158 if (!vdso_info.verdef)
159 vdso_info.versym = 0;
162 vdso_info.nbucket = hash[0];
163 vdso_info.nchain = hash[1];
164 vdso_info.bucket = &hash[2];
165 vdso_info.chain = &hash[vdso_info.nbucket + 2];
168 vdso_info.valid =
true;
171 static bool vdso_match_version(Elf64_Versym
ver,
191 Elf64_Verdef *def = vdso_info.verdef;
193 if ((def->vd_flags & VER_FLG_BASE) == 0
194 && (def->vd_ndx & 0x7fff) == ver)
197 if (def->vd_next == 0)
200 def = (Elf64_Verdef *)((
char *)def + def->vd_next);
204 Elf64_Verdaux *
aux = (Elf64_Verdaux*)((
char *)def + def->vd_aux);
205 return def->vd_hash == hash
206 && !
strcmp(name, vdso_info.symstrings + aux->vda_name);
211 unsigned long ver_hash;
212 if (!vdso_info.valid)
215 ver_hash = elf_hash(version);
216 Elf64_Word chain = vdso_info.bucket[elf_hash(name) % vdso_info.nbucket];
218 for (; chain != STN_UNDEF; chain = vdso_info.chain[
chain]) {
234 && !vdso_match_version(vdso_info.versym[chain],
238 return (
void *)(vdso_info.load_offset + sym->
st_value);
246 Elf64_auxv_t *elf_auxv = auxv;
247 for (
int i = 0; elf_auxv[
i].a_type !=
AT_NULL;
i++)
255 vdso_info.valid =
false;