📄 dlmain.c
字号:
module = __dlmap_module (hFile, &ehdr, &elfinfo, NULL, uFileType);
//CloseHandle (hFile);
}else{
//load ram file...
if ((! ReadFile (hFile, &ehdr, sizeof(Elf32_Ehdr), (LPDWORD)&read, NULL))
||(read != sizeof(Elf32_Ehdr)))
{
RETAILMSG(TONE_ERROR, ("read the elf header error !\n"));
CloseHandle (hFile);
return NULL;
}
if (__dlcheck_elf (&ehdr) == 0)
{
RETAILMSG(TONE_ERROR, ("check elf hdr failure !\n"));
CloseHandle (hFile);
return NULL;
}
module = __dlmap_module (hFile, &ehdr, NULL, lpHandle, uFileType);
//don't close handle , because core should use the handle of hFile in module info...
//CloseHandle (hFile);
}
if (module == NULL)
return NULL;
// __dllock_module ();
if (__dl_loaded == NULL)
{
/* this is the first file loaded for this program */
__dl_loaded = module;
}
else
{
dl = __dl_loaded;
RETAILMSG(TONE_DLL, ("__dl_loaded: %x, dl: %x\n", __dl_loaded, dl));
while (dl->l_next != NULL)
dl = dl->l_next;
dl->l_next = module;
module->l_prev = dl;
}
RETAILMSG(TONE_DLL, ("++load 010!\n"));
__dl_nloaded ++;
// __dlunlock_module ();
module->l_loader = caller;
if (ehdr.e_type == ET_EXEC)
module->l_type = lt_executable;
else
module->l_type = lt_loaded;
if (caller && caller->l_type == lt_executable)
module->l_type = lt_library; /* module load by the execute set this type */
RETAILMSG(TONE_DLL, ("++load 011!\n"));
module->l_origin = file;
find = strrchr (file, '\\');
if (find == NULL)
{
module->l_name = (char *)module->l_origin; /* just make compiler happy */
module->l_origin = NULL;
}
else
{
find[0] = 0;
module->l_name = ++find; /* module name and path use same buff */
}
RETAILMSG(TONE_DLL, ("++load 012!\n"));
__dlget_dynamic_info (module);
RETAILMSG(TONE_DLL, ("++load 013!\n"));
if (__dlopen_dependence (module, mode) < 0)
{
RETAILMSG(TONE_DLL, ("calling __dlclean_module!\n"));
//NOTE: 2003-09-04...ZB
// fix a bug of free.
//__dlclean_module (module);
__dlclean_module (module, FALSE);
//NOTE: 2003-09-04...ZB
return NULL;
}
RETAILMSG(TONE_DLL, ("++load 014!\n"));
__dlsetup_hash (module);
//
//The dll's init and fini is doing at module manager.
//
//__dlinit_module (module, 0, NULL, NULL);
// ELF_DYNAMIC_RELOCATE(module, mode);
RETAILMSG(TONE_DLL, ("++load 015!\n"));
__dlrelocate_module (module, module->l_scope, mode);
RETAILMSG(TONE_DLL, ("++load 016!\n"));
return module;
}
///////////////////////////////////////////////////////////////////////
unsigned int __dlrelocate_module(struct __dlmodule *module, struct __dlscope_elem **scope, unsigned int mode)
{
// ELF_DYNAMIC_RELOCATE (module, mode);
int edr_lazy;
struct { ElfW(Addr) start; int size; int lazy; } ranges[2];
int ranges_index;
RETAILMSG(TONE_DLL, ("__dlrelocate_module: <\n"));
if (module->l_relocated){
RETAILMSG(TONE_DLL, ("__dlrelocate_module: haved relocated! >\n"));
return 1;
}
module->l_relocated = 1;
edr_lazy = __dlarch_setup_runtime(module, mode);
RETAILMSG(TONE_DLL, ("edr_lazy: %x\r\n", edr_lazy));
ranges[0].lazy = 0;
ranges[0].size = ranges[1].size = 0;
ranges[0].start = 0;
if ((module)->l_info[DT_REL])
{
ranges[0].start = D_PTR (module, l_info[DT_REL]);
ranges[0].size = module->l_info[DT_RELSZ]->d_un.d_val;
}
if (module->l_info[DT_PLTREL] && (module->l_info[DT_PLTREL]->d_un.d_val == DT_REL))
{
ElfW(Addr) start = D_PTR (module, l_info[DT_JMPREL]);
if (edr_lazy
|| ranges[0].start + ranges[0].size != start)
{
RETAILMSG(TONE_DLL, ("ranges[1] set!\r\n"));
ranges[1].start = start;
ranges[1].size = module->l_info[DT_PLTRELSZ]->d_un.d_val;
ranges[1].lazy = edr_lazy;
}
else
/* Combine processing the sections. */
ranges[0].size += module->l_info[DT_PLTRELSZ]->d_un.d_val;
}
for (ranges_index = 0; ranges_index < 2; ++ranges_index)
{
RETAILMSG(TONE_DLL, ("ranges_index: <%x\r\n", ranges_index));
__dldynamic_rel (module, ranges[ranges_index].start,
ranges[ranges_index].size,
ranges[ranges_index].lazy);
RETAILMSG(TONE_DLL, ("ranges_index: >%x\r\n", ranges_index));
}
RETAILMSG(TONE_DLL, ("__dlrelocate_module: >\n"));
return 1;
};
struct __dlmodule* __dlload_module (PMODULE_HANDLE lpHandle, const char * name)
{
struct __dlmodule *module;
__dlassert (name != NULL);
//RETAILMSG(TONE_TEST, ("__dlload_module: 11\n"));
module = __dlopen_module (name, RTLD_NOW, NULL, lpHandle);
if (module == NULL){
RETAILMSG(TONE_ERROR, ("__dlload_module FAIL!\n"));
return NULL;
}
RETAILMSG(TONE_DLL, ("__dlload_module OK!\n"));
return module;
}
unsigned int __dlclean_module (struct __dlmodule *module, BOOL bNested)
{
/* Acquire the lock. */
// __libc_lock_lock (_dl_load_lock);
//note: 2003-09-04...zb
//fix a bug of free.
#define MAX_MODULE 100
static struct __dlmodule * CleanedModule[MAX_MODULE];
static int index;
BOOL bHaveCleaned ;
int j;
if(!bNested){ //第一次进入
index = 0;
memset(CleanedModule, 0, sizeof(CleanedModule));
}else{
if((index+1) < MAX_MODULE){
CleanedModule[index ++] = module;
}else{
RETAILMSG(1, ("elfmodule:error: modules is larger than length of array!\r\n"));
}
}
//note: 2003-09-04...zb
RETAILMSG(TONE_DLL|TONE_DEBUG, ("__dlclean_module: < %x:%s\n",module, module->l_name));
/* Decrement the reference count. */
if (module->l_opencount > 1)
{
/* One decrement the object itself, not the dependencies. */
--module->l_opencount;
// __libc_lock_unlock (_dl_load_lock);
RETAILMSG(TONE_DLL|TONE_DEBUG, ("__dlclean_module: > ref --: %d\n",module->l_opencount ));
return 0;
}
if (module->l_initfini != NULL)
{
struct __dlmodule **list = module->l_initfini;
unsigned int i;
RETAILMSG(TONE_DLL|TONE_DEBUG, ("__dlclean_module: ==>%s\n", list[0]->l_name));
/* first is himself */
for (i = 1; list[i] != NULL; ++i)
{
//note: 2003-09-04...zb
//add to fix a bug of free.
bHaveCleaned = FALSE;
for(j = 0; j < index; j++)
{
if(CleanedModule[j] == list[i]){
bHaveCleaned = TRUE;
break;
}
}
if(!bHaveCleaned){
RETAILMSG(TONE_DLL|TONE_DEBUG, ("__dlclean_module: list[%d]:%x\n", i, list[i]));
__dlclean_module (list[i], TRUE);
}else{
RETAILMSG(TONE_DLL|TONE_DEBUG, ("__dlclean_module: module:%x have cleaned\n", list[i]));
}
//note: 2003-09-04...zb
}
RETAILMSG(TONE_DLL|TONE_DEBUG, ("__dlclean_module: ==>1\n"));
__dlfree (module->l_initfini);
module->l_initfini = NULL;
}
//we do this at freelibrary!!! so remove it here!
/*if (module->l_info[DT_FINI_ARRAY] != NULL)
{
ElfW(Addr) *array =
(ElfW(Addr) *) (module->l_addr
+ module->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
unsigned int sz = (module->l_info[DT_FINI_ARRAYSZ]->d_un.d_val
/ sizeof (ElfW(Addr)));
unsigned int cnt;
RETAILMSG(TONE_DLL, ("__dlclean_module: ==>2\n"));
for (cnt = 0; cnt < sz; ++cnt){
((__dlfinit_fun) (module->l_addr + array[cnt])) ();
}
}
RETAILMSG(TONE_DLL, ("__dlclean_module: ==>3\n"));
if (module->l_info[DT_FINI] != NULL)
((__dlfinit_fun)(module->l_addr + module->l_info[DT_FINI]->d_un.d_ptr)) ();
*/
if (module->l_prev != NULL)
module->l_prev->l_next = module->l_next;
else
__dl_loaded = module->l_next;
if (module->l_next)
module->l_next->l_prev = module->l_prev;
RETAILMSG(TONE_DLL|TONE_DEBUG, ("__dlclean_module: ==>4\n"));
if (module->l_versions != NULL)
__dlfree (module->l_versions); /* */
RETAILMSG(TONE_DLL|TONE_DEBUG, ("__dlclean_module: ==>5\n"));
if (module->l_origin != NULL){
RETAILMSG(TONE_DLL|TONE_DEBUG, ("__dlclean_module: ==>51\n"));
__dlfree ((char *) module->l_origin);
}else{
RETAILMSG(TONE_DLL|TONE_DEBUG, ("__dlclean_module: ==>52\n"));
__dlfree (module->l_name);
}
RETAILMSG(TONE_DLL|TONE_DEBUG, ("__dlclean_module: ==>6\n"));
if (module->l_phdr_allocated)
__dlfree ((void *) module->l_phdr);
RETAILMSG(TONE_DLL|TONE_DEBUG, ("__dlclean_module: ==>7\n"));
__dlfree (module);
// __libc_lock_unlock (_dl_load_lock);
RETAILMSG(TONE_DLL|TONE_DEBUG, ("__dlclean_module: > ok\n"));
return 1;
}
/* Search loaded objects' symbol tables for a definition of the symbol
UNDEF_NAME. */
static ElfW(Addr) __dllookup_symbol (const char *name, struct __dlmodule *module,
const ElfW(Sym) **ref, struct __dlscope_elem *symbol_scope[],
int reloc_type, int explicit_mode)
{
const unsigned int hash = __dlhash (name);
struct __dlsym_val value = { NULL, NULL };
struct __dlscope_elem **scope;
int protect;
int noexec = __dlarch_lookup_noexec_p (reloc_type);
int noplt = __dlarch_lookup_noplt_p (reloc_type);
RETAILMSG(TONE_DLL, ("=> find symbol: %s...\n", name));
/* Search the relevant loaded objects for a definition. */
for (scope = symbol_scope; *scope; ++scope)
{
//RETAILMSG(TONE_DLL, ("=> scope: %x...\n", *scope);
if (__dllookup (name, hash, NULL, &value, *scope, 0, NULL,
noexec, noplt))
{
break;
}
}
if (value.s == NULL)
{
if (*ref == NULL || ELF32_ST_BIND((*ref)->st_info) != STB_WEAK)
{
/* We could find no value for a strong reference. */
/* XXX We cannot translate the messages. */
*ref = NULL;
}
RETAILMSG(TONE_DLL, ("=> no find symbol\n"));
return 0;
}
protect = *ref && ELF32_ST_VISIBILITY((*ref)->st_other) == STV_PROTECTED;
if (protect == 0)
{
*ref = value.s;
//RETAILMSG(TONE_DLL, ("=> find symbol\n");
return value.m->l_addr;
}
else
{
/* It is very tricky. We need to figure out what value to
return for the protected symbol */
struct __dlsym_val protected_value = { NULL, NULL };
for (scope = symbol_scope; *scope; ++scope)
{
if (__dllookup (name, hash, *ref, &protected_value, *scope, 0,
NULL, 0, 1))
break;
}
if (protected_value.s == NULL || protected_value.m == module)
{
*ref = value.s;
return value.m->l_addr;
}
return module->l_addr;
}
}
#define DEBUG_dllookup_value 0
ElfW(Addr) __dllookup_value (const char *name, struct __dlmodule *module)
{
const ElfW(Sym) *ref = NULL;
ElfW(Addr) result;
//RETAILMSG(TONE_DLL, ("__dllookup_value 11\n");
//RETAILMSG(TONE_DLL, ("__dllookup_value : %s : %x\n", name, module);
result = __dllookup_symbol (name, module, &ref, module->l_scope, 0, 1);
//RETAILMSG(TONE_DLL, ("__dllookup_value 12\n");
if( ref == NULL )
{
ERRORMSG( DEBUG_dllookup_value, ( "error in __dllookup_value: not find name=%s, module name=%s.\r\n", name, module->l_name ) );
return 0;
}
return (result + ref->st_value);
}
/* macro for arch lazy relocat resolve */
void __dlarch_runtime_resolve (Elf32_Word addr)
{
}
//ELF_MACHINE_RUNTIME_TRAMPOLINE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -