📄 dlmain.c
字号:
strcpy (dir, caller->l_origin);
strcat (dir, "\\");
strcat (dir,file);
if (__dlfileexist (dir))
return strdup (dir);
}
*/
/* GetCurrentDirectory (MAX_PATH, dir);
strcat (dir, "\\");
strcat (dir, file);
if (__dlfileexist (dir))
return strdup (dir);
*/
/* search shared directory */
/* GetSharedDirectory (dir, MAX_PATH);
strcat (dir, "\\");
strcat (dir, file);
if (__dlfileexist (dir))
return strdup (dir);
*/
RETAILMSG(TONE_DLL, ("--find kingmos.... \n"));
// search in kingmos...
//strcpy(dir, "\\kingmos\\");
strcpy (dir, KINGMOS_PATH);
// strcat(dir, file);
strcat(dir, name);
if (__dlfileexist (dir))
return strdup (dir);
RETAILMSG(TONE_DLL, ("--find system....\n"));
/* search system directory */
// GetSystemDirectory (dir, MAX_PATH);
// strcat (dir, "\\");
strcpy (dir, WORK_PATH);
// strcat (dir, file);
strcat(dir, name);
if (__dlfileexist (dir))
return strdup (dir);
return NULL;
}
unsigned int __dlcheck_elf (const Elf32_Ehdr *ehdr)
{
const unsigned char ELF_HEADER_MARK[EI_PAD] = {ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3};
__dlassert (ehdr != NULL);
if (memcmp (ehdr->e_ident, ELF_HEADER_MARK, 4) != 0)
return 0; /* not elf file */
if (ehdr->e_version != EV_CURRENT)
return 0; /* version is not current */
if (ehdr->e_phentsize != sizeof (Elf32_Phdr))
return 0; /* phdr size is not we want */
if (! __dlarch_matches_host (ehdr))
return 0; /* determine the binary code compatible */
if (ehdr->e_type != ET_DYN && ehdr->e_type != ET_EXEC)
return 0; /* just execute and dynamic binary can be load */
return 1;
}
/* open the module dependence modules, whitch is in DT_NEEDED
set the module's scope and searchlist and finit info
*/
int __dlopen_dependence (struct __dlmodule* module, unsigned int mode)
{
Elf32_Dyn *dyn;
unsigned int nneeded = 1; /* set one for self contained module safe */
const char *strtab = (const void *) D_PTR (module, l_info[DT_STRTAB]);
__dlassert (module != NULL);
RETAILMSG(TONE_DLL, ("__dlopen_dependence: < !\n"));
/* RETAILMSG(TONE_DLL, ("*******************************************************\n");
RETAILMSG(TONE_DLL, ("--get GetFileAttributes : %x \n", GetFileAttributes);
RETAILMSG(TONE_DLL, ("--get file attr : %x \n", GetFileAttributes ("libmydll.so"));
RETAILMSG(TONE_DLL, ("--get file attr : %x \n", GetFileAttributes ("\\system\\hello.exe"));
RETAILMSG(TONE_DLL, ("*******************************************************\n");
*/
if (module->l_ld == NULL)
return 0; /* if module have not dynamic info, it must be execute binary, ignore it */
for (dyn = module->l_ld; dyn->d_tag != DT_NULL; dyn ++)
{
if (dyn->d_tag == DT_NEEDED)
nneeded ++;
}
//RETAILMSG(TONE_TEST , ("__dlopen_dependence: nneeded:%x !\n", nneeded));
module->l_initfini = (struct __dlmodule **)__dlmalloc ((2*nneeded+1) * sizeof(struct __dlmodule*));
if (module->l_initfini == NULL)
{
RETAILMSG(TONE_ERROR, ("can't alloc memory !\n"));
return -1;
}
memset (module->l_initfini, 0, (2*nneeded+1) * sizeof(struct __dlmodule*));
module->l_searchlist.r_list = module->l_initfini + nneeded + 1;
module->l_searchlist.r_nlist = nneeded;
module->l_searchlist.r_list[0] = module;
module->l_scope[0] = &module->l_searchlist; /* the first scope is the searchlist */
if (nneeded != 1)
{
nneeded = 1; /* the first is the module self */
for (dyn = module->l_ld; dyn->d_tag != DT_NULL; dyn ++)
{
if (dyn->d_tag == DT_NEEDED)
{
extern PMODULE_HANDLE FindLoadedHandle(PMODULE_NODE pMod, UINT flag);
extern PMODULE_NODE FindOrCreateModule(LPCTSTR lpszFileName, UINT *uResult, UINT flag);
extern CRITICAL_SECTION csModuleList; //module list 临界段
UINT uResult;
const char *need = (const char *)(strtab + dyn->d_un.d_val);
PMODULE_NODE pMod = NULL ;
PMODULE_HANDLE ptemp;
RETAILMSG(TONE_DLL, ("--depend library : %s <\n", need));
EnterCriticalSection( &csModuleList );
//pMod = FindOrCreateModule(need, NULL, MODULE_EXEC);
pMod = FindOrCreateModule(need, NULL, CREATE_LIBRARY);
LeaveCriticalSection( &csModuleList );
//if(uResult == NEW_MODULE){
//if(pMod->lpBase == NULL){
ptemp = FindLoadedHandle(pMod, FIND_NON_XIP_REF);
if(ptemp == NULL){
RETAILMSG(TONE_TEST, ("->%s: load new %s\n", module->l_name, need));
module->l_searchlist.r_list[nneeded] = __dlopen_module (need, mode, module, NULL);
RETAILMSG(TONE_DLL, ("__dlopen_dependence: > 1100 !\n"));
}else{
RETAILMSG(TONE_TEST, ("->%s: ref %s\n", module->l_name, need));
//module->l_searchlist.r_list[nneeded] = __dlopen_module (need, mode, module, pMod->lpBase);
module->l_searchlist.r_list[nneeded] = __dlopen_module (need, mode, module, ptemp);
RETAILMSG(TONE_DLL, ("__dlopen_dependence: > 1200 !\n"));
}
if (module->l_searchlist.r_list[nneeded] == NULL)
{
RETAILMSG(TONE_ERROR, ("can't open dependence module !\n"));
return -1;
}
nneeded ++;
}
}
}
RETAILMSG(TONE_DLL, ("__dlopen_dependence: 1101 !\n"));
//RETAILMSG(TONE_TEST , ("__dlopen_dependence: r_nlist:%x:%s !\n", module->l_searchlist.r_nlist,module->l_name));
memcpy (module->l_initfini, module->l_searchlist.r_list,
sizeof(struct __dlmodule*)*module->l_searchlist.r_nlist);
RETAILMSG(TONE_DLL, ("__dlopen_dependence: > !\n"));
return --nneeded;
}
extern unsigned int read_file (HANDLE hFile, char *buff, unsigned int size,unsigned int offset);
/* map a binary file to memory */
static struct __dlmodule * __dlmap_module (HANDLE hFile, ElfW(Ehdr) *ehdr, ELF_INFO *pElfinfo, PMODULE_HANDLE lpHandle,
UINT flag)
{
struct __dlmodule *module;
Elf32_Phdr *phdr = NULL;
unsigned int size;
int inload = 0;
Elf32_Phdr *lp = NULL;
unsigned int i;
BOOL bMapModule = FALSE;
int indexPtLoad = 0;
DWORD flAllocationType;
DWORD flflag;
//struct module_info *info;
PLOAD_MODULE info;
Elf32_Addr addr_start, addr_end = 0, addr_segstart;
BOOL bRomModule = FALSE;
RETAILMSG(TONE_DLL, ("__dlmap_module: <\n"));
if(flag == XIP_MODULE)
bRomModule = TRUE;
else if(lpHandle != NULL){
bMapModule = TRUE;
info = lpHandle->info;
RETAILMSG(TONE_DLL, ("module_info: -------------\n"));
RETAILMSG(TONE_DLL, ("info->addr: %x\n", info->addr));
RETAILMSG(TONE_DLL, ("info->start: %x\n", info->start));
RETAILMSG(TONE_DLL, ("info->end: %x\n", info->end));
RETAILMSG(TONE_DLL, ("info->entry: %x\n", info->entry));
//RETAILMSG(TONE_DLL, ("info->addr: %x\n", info->addr));
RETAILMSG(TONE_DLL, ("module_info: -------------\n"));
}else{
bMapModule = FALSE;
}
if(flag == XIP_MODULE){
phdr = (Elf32_Phdr *)(pElfinfo->ulFileBase + pElfinfo->ulPhdroff);
if (phdr == NULL)
return NULL;
}else{
size = ehdr->e_phentsize * ehdr->e_phnum;
phdr = (Elf32_Phdr *)__dlmalloc (size);
if (phdr == NULL)
return NULL;
/* first load phdr info */
if (read_file (hFile, (char*)phdr, size, ehdr->e_phoff) != size)
{
__dlfree (phdr);
return NULL;
}
}
for (lp = phdr, i = 0; i < ehdr->e_phnum; i ++, lp ++)
{
if(lp->p_vaddr == 0) //if the p_vaddr is 0, i think that is invalid phdr record...
continue;
switch (lp->p_type)
{
case PT_LOAD:
if((++indexPtLoad) >= PT_LOAD_RES) //.res section isn't loaded in memory....
break;
if (((lp->p_vaddr - lp->p_offset)&(lp->p_align - 1)) != 0) //???
{
RETAILMSG(TONE_DLL, ("loadable segment is not align!\n"));
__dlfree (phdr); /* not align */
return NULL;
}
RETAILMSG(TONE_DLL, ("__dlmap_module: lp->p_align:%x\n", lp->p_align));
//ZB changed...
//addr_segstart = ALIGN (lp->p_vaddr, lp->p_align);
addr_segstart = lp->p_vaddr;
addr_end = addr_end > (addr_segstart + lp->p_memsz) ? addr_end : (addr_segstart + lp->p_memsz);
RETAILMSG(TONE_DLL, ("__dlmap_module: addr_segstart:%x, p_memsz:%x\n",addr_segstart, lp->p_memsz ));
RETAILMSG(TONE_DLL, ("__dlmap_module: addr_end:%x\n",addr_end));
if (inload == 0)
{ /* this is the first loadable phdr */
addr_start = addr_segstart;
/* addr_fstart = lp->p_offset; */
inload = 1;
}
break;
}
}
// RETAILMSG(TONE_DLL, ("__dlmap_module: 11\n"));
/* alloc module info memory */
module = (struct __dlmodule *) __dlmalloc (sizeof (struct __dlmodule));
if (module == NULL)
{
RETAILMSG(TONE_ERROR, ("alloc memory for module info failure !\n"));
__dlfree (phdr);
return NULL;
}
memset (module, 0, sizeof(struct __dlmodule));
module->l_phnum = ehdr->e_phnum;
// if(flag == ROM_MODULE)
// module->filetype = ROM_MODULE;
// else
// module->filetype = NORMAL_MODULE;
//Zb add...
module->hFile = hFile;
#ifdef WIN32_TEST
/* on win32 platform, virtual meory must align 64k size,
this just for test on win32 platform */
addr_start = ALIGN(addr_start,ALIGN_SIZE);
#endif /* WIN32_TEST */
size = addr_end - addr_start;
if(bMapModule||bRomModule){
RETAILMSG(TONE_DLL, ("__dlmap_module: ->11\n"));
flAllocationType = MEM_RESERVE;
//NOTE: 2003-08-26...ZB
//PAGE_NOCACHE 会降低系统性能
//flflag = PAGE_NOCACHE|PAGE_EXECUTE_READWRITE;
flflag = PAGE_EXECUTE_READWRITE;
//NOTE: 2003-08-26...ZB
}else{
flAllocationType = MEM_COMMIT|MEM_RESERVE;
flflag = PAGE_EXECUTE_READWRITE;
}
RETAILMSG(TONE_DLL, ("__dlmap_module: 22\n"));
if (ehdr->e_type == ET_EXEC)
{ /* execute program must load at fix address */
module->l_map_start = (ElfW(Addr))VirtualAlloc ((LPVOID)addr_start, size,
flAllocationType, flflag);
}
else
{
RETAILMSG(TONE_DLL, ("__dlmap_module: ->12\n"));
module->l_map_start = (ElfW(Addr))VirtualAlloc (NULL, size,
flAllocationType, flflag);
}
if ((module->l_map_start == 0)
||((module->l_map_start != addr_start)&&(ehdr->e_type == ET_EXEC)))
{
RETAILMSG(TONE_ERROR, ("virtual alloc failure !\n"));
__dlfree (module);
__dlfree (phdr);
return NULL;
}
module->l_map_end = module->l_map_start + size;
module->l_addr = module->l_map_start - addr_start; /* in execute program this must be zero */
module->l_entry = ehdr->e_entry + module->l_addr;
RETAILMSG(TONE_DLL, ("module->l_map_start:%x \n", module->l_map_start));
RETAILMSG(TONE_DLL, ("module->l_map_end:%x \n", module->l_map_end));
RETAILMSG(TONE_DLL, ("module->l_addr:%x \n", module->l_addr));
RETAILMSG(TONE_DLL, ("module->l_entry:%x \n", module->l_entry));
RETAILMSG(TONE_DLL, ("__dlmap_module: 33\n"));
indexPtLoad = 0;
for (lp = phdr, i = 0; i < ehdr->e_phnum; i ++, lp ++)
{
if(lp->p_vaddr == 0) //if the p_vaddr is 0, i think that is invalid phdr record...
continue;
switch (lp->p_type)
{
case PT_PHDR:
module->l_phdr = (ElfW(Phdr) *)(lp->p_vaddr + module->l_addr);
break;
case PT_DYNAMIC:
module->l_ld = (ElfW(Dyn) *)(lp->p_vaddr + module->l_addr);
module->l_ldnum = lp->p_memsz / sizeof (ElfW(Dyn));
break;
case PT_LOAD:
{
unsigned int nprotect;
DWORD oprotect;
indexPtLoad++;
if(indexPtLoad >= PT_LOAD_RES) //.res section isn't loaded in memory....
break;
if (lp->p_flags & PF_R)
nprotect = PAGE_READONLY;
if (lp->p_flags & PF_W)
nprotect = PAGE_READWRITE; //PAGE_WRITECOPY
if (lp->p_flags & PF_X)
nprotect = PAGE_EXECUTE_READWRITE; //PAGE_EXECUTE_WRITECOPY
//NOTE: 2003-08-26...ZB
//PAGE_NOCACHE 会降低系统性能
//nprotect |= PAGE_NOCACHE;
//NOTE: 2003-08-26...ZB
if(bMapModule||bRomModule){
RETAILMSG(TONE_DLL, ("module->l_map_start: %x, load addr:%x\n", module->l_map_start, lp->p_vaddr+module->l_addr));
if(indexPtLoad == PT_LOAD_CODE){
LPVOID pDest ;
if(bMapModule){
RETAILMSG(TONE_DLL, ("LoadDll: -> 1\r\n"));
pDest = MapPtrToProcess((LPVOID)info->start, lpHandle->hProc);
}else{
RETAILMSG(TONE_DLL, ("LoadDll: -> 2\r\n"));
pDest = (LPVOID)(pElfinfo->ulFileBase + lp->p_offset);
}
//RETAILMSG(TONE_DLL, ("info->start: %x\n", info->start));
RETAILMSG(TONE_DLL, ("LoadDll: -> 3\r\n"));
if(!VirtualCopy((LPVOID)(lp->p_vaddr+module->l_addr), pDest, lp->p_memsz, nprotect)){
RETAILMSG(TONE_ERROR, ("virtualcopy fail@\n"));
goto cleanup;
}
}else if(indexPtLoad == PT_LOAD_DATA){
RETAILMSG(TONE_DLL, ("LoadDll: -> 4\r\n"));
VirtualAlloc ((LPVOID)(lp->p_vaddr+module->l_addr), lp->p_memsz,
MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(bMapModule){
/* read program loadable segment */
if (read_file (hFile, (char*)(lp->p_vaddr+module->l_addr),
lp->p_filesz, lp->p_offset) != lp->p_filesz)
goto cleanup;
}else{
RETAILMSG(TONE_DLL, ("LoadDll: -> 5\r\n"));
memcpy((void *)(lp->p_vaddr+module->l_addr), (void *)(pElfinfo->ulFileBase + lp->p_offset),
lp->p_filesz);
}
}
}else{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -