From de47eb59bb829423b1d0f47ba13099073999b3cb Mon Sep 17 00:00:00 2001 From: Nicolas Planel Date: Wed, 29 Oct 2003 16:07:11 +0000 Subject: Corporate Server 2.1.1 release --- mdk-stage1/dietlibc/libdl/dlsym.c | 93 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 4 deletions(-) (limited to 'mdk-stage1/dietlibc/libdl/dlsym.c') diff --git a/mdk-stage1/dietlibc/libdl/dlsym.c b/mdk-stage1/dietlibc/libdl/dlsym.c index 2af940837..c58bb4d11 100644 --- a/mdk-stage1/dietlibc/libdl/dlsym.c +++ b/mdk-stage1/dietlibc/libdl/dlsym.c @@ -1,7 +1,92 @@ #include "_dl_int.h" -void *dlsym(void *handle, char *symbol) -{ - printf("dlsym(%08x,%s) -> %08x\n",handle,symbol,elf_hash(symbol)%17); - return 0; +#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; } -- cgit v1.2.1