1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
#include "_dl_int.h"
#include "elf_hash.h"
#ifdef __DIET_LD_SO__
static
#endif
void *_dlsym(void*handle,char*symbol) {
unsigned long*sym=0;
if (handle) {
struct _dl_handle*dh=(struct _dl_handle*)handle;
unsigned long hash =elf_hash(symbol);
unsigned long bhash=hash%HASH_BUCKET_LEN(dh->hash_tab);
unsigned long*chain=HASH_CHAIN(dh->hash_tab);
unsigned long ind;
char *name=dh->dyn_str_tab;
#ifdef DEBUG
// pf(__FUNCTION__); pf(": bucket("); ph(bhash); pf(",\""); pf(symbol); pf("\")\n");
#endif
ind=HASH_BUCKET(dh->hash_tab)[bhash];
#ifdef DEBUG
// pf(__FUNCTION__); pf(": chain ("); ph(ind); pf(",\""); pf(symbol); pf("\")\n");
#endif
while(ind) {
int ptr=dh->dyn_sym_tab[ind].st_name;
#ifdef DEBUG
// pf(__FUNCTION__); pf(": symbol(\""); pf(name+ptr); pf("\",\"); pf(symbol); pf("\")\n");
#endif
if (strcmp(name+ptr,symbol)==0) {
if (ELF_ST_TYPE(dh->dyn_sym_tab[ind].st_shndx)!=0) {
sym=(long*)(dh->mem_base+dh->dyn_sym_tab[ind].st_value);
break; /* ok found ... */
}
}
ind=chain[ind];
}
#ifdef DEBUG
pf(__FUNCTION__); pf(": symbol \""); pf(symbol); pf("\" @ "); ph((long)sym); pf("\n");
#endif
}
return sym;
}
#ifdef __DIET_LD_SO__
static
#endif
void*_dl_sym_search_str(struct _dl_handle*dh,char*name) {
void *sym=0;
struct _dl_handle*tmp;
#ifdef DEBUG
pf(__FUNCTION__); pf(": search for: "); pf(name); pf("\n");
#endif
for (tmp=_dl_root_handle;tmp && (!sym);tmp=tmp->next) {
// if (!(tmp->flags&RTLD_GLOBAL)) continue;
#ifdef DEBUG
pf(__FUNCTION__); pf(": searching in "); pf(tmp->name); pf("\n");
#endif
sym=_dlsym((void*)tmp,name);
#ifdef DEBUG
if (sym) { pf(__FUNCTION__); pf(": found: "); pf(name); pf(" @ "); ph((long)sym); pf("\n"); }
#endif
}
return sym;
}
#ifdef __DIET_LD_SO__
static
#endif
void*_dl_sym(struct _dl_handle*dh,int symbol) {
char *name=dh->dyn_str_tab+dh->dyn_sym_tab[symbol].st_name;
void*sym=_dl_sym_search_str(dh,name);
#ifdef DEBUG
pf(__FUNCTION__); pf(": "); ph(symbol); pf(" -> "); ph((long)sym); pf("\n");
#endif
return sym;
}
void*dlsym(void*handle,char*symbol) {
void*h;
if (handle==RTLD_DEFAULT || !handle /* RTLD_DEFAULT is NULL on glibc */ )
h=_dl_sym_search_str(0,symbol);
else h=_dlsym(handle,symbol);
if (h==0) {
_dl_error_location="dlsym";
_dl_error_data=symbol;
_dl_error=5;
}
return h;
}
|