11 #if ULONG_MAX == 0xffffffff
12 typedef Elf32_Ehdr Ehdr
;
13 typedef Elf32_Phdr Phdr
;
14 typedef Elf32_Sym Sym
;
15 typedef Elf32_Verdef Verdef
;
16 typedef Elf32_Verdaux Verdaux
;
18 typedef Elf64_Ehdr Ehdr
;
19 typedef Elf64_Phdr Phdr
;
20 typedef Elf64_Sym Sym
;
21 typedef Elf64_Verdef Verdef
;
22 typedef Elf64_Verdaux Verdaux
;
25 static int checkver(Verdef
*def
, int vsym
, const char *vername
, char *strings
)
29 if (!(def
->vd_flags
& VER_FLG_BASE
)
30 && (def
->vd_ndx
& 0x7fff) == vsym
)
32 if (def
->vd_next
== 0)
34 def
= (Verdef
*)((char *)def
+ def
->vd_next
);
36 Verdaux
*aux
= (Verdaux
*)((char *)def
+ def
->vd_aux
);
37 return !strcmp(vername
, strings
+ aux
->vda_name
);
40 #define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON)
41 #define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE)
43 void *__vdsosym(const char *vername
, const char *name
)
46 for (i
=0; libc
.auxv
[i
] != AT_SYSINFO_EHDR
; i
+=2)
47 if (!libc
.auxv
[i
]) return 0;
48 if (!libc
.auxv
[i
+1]) return 0;
49 Ehdr
*eh
= (void *)libc
.auxv
[i
+1];
50 Phdr
*ph
= (void *)((char *)eh
+ eh
->e_phoff
);
51 size_t *dynv
=0, base
=-1;
52 for (i
=0; i
<eh
->e_phnum
; i
++, ph
=(void *)((char *)ph
+eh
->e_phentsize
)) {
53 if (ph
->p_type
== PT_LOAD
)
54 base
= (size_t)eh
+ ph
->p_offset
- ph
->p_vaddr
;
55 else if (ph
->p_type
== PT_DYNAMIC
)
56 dynv
= (void *)((char *)eh
+ ph
->p_offset
);
58 if (!dynv
|| base
==(size_t)-1) return 0;
62 Elf_Symndx
*hashtab
= 0;
66 for (i
=0; dynv
[i
]; i
+=2) {
67 void *p
= (void *)(base
+ dynv
[i
+1]);
69 case DT_STRTAB
: strings
= p
; break;
70 case DT_SYMTAB
: syms
= p
; break;
71 case DT_HASH
: hashtab
= p
; break;
72 case DT_VERSYM
: versym
= p
; break;
73 case DT_VERDEF
: verdef
= p
; break;
77 if (!strings
|| !syms
|| !hashtab
) return 0;
78 if (!verdef
) versym
= 0;
80 for (i
=0; i
<hashtab
[1]; i
++) {
81 if (!(1<<(syms
[i
].st_info
&0xf) & OK_TYPES
)) continue;
82 if (!(1<<(syms
[i
].st_info
>>4) & OK_BINDS
)) continue;
83 if (!syms
[i
].st_shndx
) continue;
84 if (strcmp(name
, strings
+syms
[i
].st_name
)) continue;
85 if (versym
&& !checkver(verdef
, versym
[i
], vername
, strings
))
87 return (void *)(base
+ syms
[i
].st_value
);