⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dlmain.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 4 页
字号:
		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 + -