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

📄 execelf.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 3 页
字号:
		 //
	 
		 seg_info->lpNext = seg_temp;
		 seg_temp = seg_info;

	 }

	 _kfree(shdr);
	 //2004-10-21
	 //_kfree(ehdr);
	 //

	 //RETAILMSG(TONE_EXEC, ("GetSegInfo : > result: %x, ok!\n", seg_temp);
	 return seg_temp;
}

#define		__KFREE_INTERPRET();	//\
elf_assert(0); \
_kfree (interpret);	


static __inline unsigned int elf_load_binary (struct exe_module *module, const char * name, PMODULE_HANDLE lpHandle, 
											  UINT	flag)
{
	HANDLE			hFile;	/* file handle of the binary file */
	Elf32_Ehdr		ehdr;   /* for read elf head */
	Elf32_Phdr		*phdr = NULL;
//	char			lpszBin[MAX_PATH];
	//char			*lpszBin;
	char szBin[MAX_PATH];

	char			*interpret = NULL;
	int				have_inter = 0;

	Elf32_Addr		entry_addr;
	Elf32_Addr		start = 0, end = 0;
	int				start_set = 0;

	Elf32_Addr		load_addr;
	Elf32_Addr		addr_offset;

	unsigned int	i;
	unsigned int	retval = INVALID_ADDR;

	Elf32_Phdr			*module_phdr = NULL;
	int					module_phdr_allocated = 0;
	Elf32_Dyn			*module_dyn = NULL;
	unsigned int		module_ndyn = 0;

	struct module_info	*info;

	DWORD			dwFileAttr;
	EXE_ROM			*pExeInfo;
	UINT			uFileType;
	DWORD			dwReturn;
	ELF_INFO		elfinfo;
	UINT			indexLoad = 0;
	BOOL			bMapModule = FALSE;
	BOOL			bRomModule = FALSE;
	//struct module_info	*lpInfo;
	PLOAD_MODULE	lpInfo;
	DWORD			flAllocationType;
	DWORD			flflag;

	unsigned long	romfileBase;
	unsigned long	romfileType;
	unsigned long	romfileEntry;
	unsigned long	romphnum = 0;

	elf_assert (name != NULL);

	if(lpHandle != NULL){
		//RETAILMSG(TONE_TEST, ("elf_load_binary: load new module!\n"));
		RETAILMSG(TONE_TEST, ("->(%s\n",name));
		lpInfo = lpHandle->info;
		bMapModule = TRUE;
	}
	else{
		//RETAILMSG(TONE_TEST, ("elf_load_binary: ref a module!\n"));
		RETAILMSG(TONE_TEST, ("->)%s\n",name));
		bMapModule = FALSE;
	}

	//2004-10-21
	//if(!(lpszBin = (char*)_kalloc(MAX_PATH))){
	//	RETAILMSG(TONE_ERROR,("_kalloc fail!\n"));
	//	return 0;
	//}
	//
		

	RETAILMSG(TONE_EXEC, ("--xxload file:%s \n", name));
	//2004-10-21
	//if (elf_find_binary(name, lpszBin) == 0)
	if (elf_find_binary(name, szBin) == 0)	
	//
	{
		//RETAILMSG(TONE_ERROR,("--file:%s not exist!\n", lpszBin));
		RETAILMSG(TONE_ERROR,("--file:%s not exist!\n", name));
		//2004-10-21
		//_kfree(lpszBin);
		//
		return 0;
	}
	//2004-10-21
	//hFile = CreateFile (lpszBin, GENERIC_READ, FILE_SHARE_READ, NULL,
		//OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	hFile = CreateFile (szBin, GENERIC_READ, FILE_SHARE_READ, NULL,
		OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	//
	if (hFile == INVALID_HANDLE_VALUE)
	{
		RETAILMSG(TONE_ERROR,("--open file:%s failure!\n", szBin));

		//2004-10-21
		//_kfree(lpszBin);
		//
		return INVALID_ADDR;
	}

	module->hFile	= hFile;	

	if(flag == MODULE_LOAD){	//以后通过hFile获取文件属性和段信息!!!
		//2004-10-21
		//_kfree(lpszBin);
		//
		return 0x01;
	}

	RETAILMSG(TONE_EXEC,("--open file:%x OK!\n", hFile));
	//2004-10-21
	//dwFileAttr = GetFileAttributes(lpszBin);
	dwFileAttr = GetFileAttributes(szBin);
	//
	if (dwFileAttr == (DWORD)-1){
		//2004-10-21
		//_kfree(lpszBin);
		//
		return 0;
	}

	//2004-10-21
	//_kfree(lpszBin);
	//

	RETAILMSG(TONE_EXEC,("-- file attr:%x !\n", dwFileAttr));

	if(dwFileAttr & FILE_ATTRIBUTE_ROMMODULE )
	{
		uFileType = XIP_MODULE;
	}else{
		uFileType = NON_XIP_MODULE;
	}
	
	if(uFileType == XIP_MODULE){	

		bRomModule = TRUE;

		RETAILMSG(TONE_EXEC,("deviceiocontrol: %x!\r\n", &elfinfo));
		if(!DeviceIoControl(hFile, IOCTL_ROM_GET_ELF_INFO, NULL, 0, &elfinfo, 0, &dwReturn, NULL))
			return 0;

		RETAILMSG(TONE_EXEC,("deviceiocontrol ok!\r\n"));

		romfileBase  = elfinfo.ulFileBase;
		romfileType  = elfinfo.ulFileType;
		romfileEntry = elfinfo.ulEntry;
		romphnum =  elfinfo.ulPhdrnum;
		phdr  = (Elf32_Phdr *)(elfinfo.ulPhdroff + romfileBase);

		RETAILMSG(TONE_EXEC,("base:%x, type:%x, entry:%x, phnum:%x, phdr:%x!\r\n", romfileBase, romfileType, romfileEntry,
			romphnum, phdr));

		/*if(!DeviceIoControl(hFile, IOCTL_ROM_GET_EXE_INFO, NULL, 0, pExeInfo, 0, &dwReturn, NULL))
			return 0;
		RETAILMSG(TONE_EXEC, (TEXT("EXE: exe info: exe_imageflags:%x,exe_entryrav:%x,exe_vbase:%x,exe_stackmax:%x, \
				exe_vsize:%x,exe_phdroff:%x,exe_phdrnum:%x\r\n"), pExeInfo->exe_imageflags, pExeInfo->exe_entryrav,
				pExeInfo->exe_vbase, pExeInfo->exe_stackmax, pExeInfo->exe_vsize, pExeInfo->exe_phdroff, 
				pExeInfo->exe_phdrnum));
				*/
	}else{
		if (read_file (hFile, (char*)&ehdr, sizeof(Elf32_Ehdr), 0) != sizeof(Elf32_Ehdr))
		{
			//RETAILMSG(TONE_ERROR, ("-read %s ehdr failure!\n", lpszBin));
			CloseHandle (hFile);
			return INVALID_ADDR;
		}
		//RETAILMSG(TONE_EXEC, ("--read file:%s elf head OK!\n", lpszBin));
		
		SHOW_ELF_HEADER(&ehdr);

		if (! elf_check (&ehdr))
		{
			RETAILMSG(TONE_ERROR, ("--the binary can't run in this arch!\n"));
			CloseHandle (hFile);
			return INVALID_ADDR;
		}
		//RETAILMSG(TONE_EXEC, ("--check file:%s elf head OK!\n", lpszBin));
		

			
			phdr = (Elf32_Phdr *)_kalloc (ehdr.e_phentsize * ehdr.e_phnum);
			if (phdr == NULL)
			{
				CloseHandle (hFile);
				return INVALID_ADDR;
			}
			RETAILMSG(TONE_EXEC, ("--alloc phdr:%x  OK!\n", phdr));
			
			/* read phdr infomation */
			if (read_file (hFile, (char*)phdr, ehdr.e_phentsize*ehdr.e_phnum, ehdr.e_phoff) 
				!= (unsigned int)(ehdr.e_phentsize*ehdr.e_phnum))
			{
				RETAILMSG(TONE_ERROR, ("--read %s phdr failure!\n"));
				goto error_out;
			}
			//RETAILMSG(TONE_EXEC, ("--read file:%s elf phdr OK!\n", lpszBin));
			
			SHOW_ELF_PHDR(phdr, ehdr.e_phnum);

			romphnum		= ehdr.e_phnum;
			romfileType		= ehdr.e_type;
			romfileEntry	= ehdr.e_entry;
	}


	RETAILMSG(TONE_EXEC, ("load_binary_module: ==>111\n"));

	for (i = 0; i < romphnum; i ++)
	{
		Elf32_Phdr	*lp = phdr + i;

		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:
			{
				Elf32_Addr	segment_end = lp->p_vaddr + lp->p_memsz;
				
				if((++indexLoad) >= PT_LOAD_RES)
					break;

				if (start_set == 0)
				{
					start_set = 1;
					start = lp->p_vaddr;
				}
				end = end < segment_end ? segment_end : end;
			}
			break;
		case PT_INTERP:
			/* we just use the interpret of the execute binary file
			*/
			if(bRomModule){
				if ((! have_inter)&&(romfileType == ET_EXEC)) 
				{					
					//interpret = (char*)(romfileBase + lp->p_vaddr);
					interpret = (char*)(romfileBase + lp->p_offset);
					have_inter = 1;
					RETAILMSG(TONE_EXEC,("interpret: %s\n", interpret));
				}
			}else{
				if ((! have_inter)&&(romfileType == ET_EXEC)) 
				{
					interpret = (char *)_kalloc(lp->p_memsz + 1);
					
					//RETAILMSG(TONE_EXEC, ("--lp->p_memsz:%x \n", lp->p_memsz);
					
					if (interpret == NULL){
						RETAILMSG(TONE_ERROR, ("--PT_INTERP: fail! \n"));
						goto error_out;
					}
					//__KFREE_INTERPRET();
					//RETAILMSG(TONE_EXEC, ("--PT_INTERP:%x \n", interpret));
					
					//__KFREE_INTERPRET();
					
					memset (interpret, 0, lp->p_memsz + 1);
					
					if (read_file(hFile, interpret, lp->p_filesz, lp->p_offset) != lp->p_filesz)
						goto error_out;
					have_inter = 1;
					//__KFREE_INTERPRET();
				}
			}
			break;
		}
	}

	RETAILMSG(TONE_EXEC,("start: %x, end: %x !\r\n", start, end));

	/* if file have no PT_LOAD phdr, we just lose it */
	if (! start_set)
		goto error_out;

	/* align the end address of the module */
	end = ELF_UPALIGN(end);

	if((bMapModule)||(bRomModule)){//Ref loaded module or load rom module!

		RETAILMSG(TONE_EXEC, ("__dlmap_module: ->11\n"));
		flAllocationType = MEM_RESERVE;
		//NOTE: 2003-08-26
		//PAGE_NOCACHE 会降低系统性能
		//flflag = PAGE_NOCACHE|PAGE_EXECUTE_READWRITE; 
		flflag = PAGE_EXECUTE_READWRITE; 
		//NOTE: 2003-08-26
	}else{
		flAllocationType = MEM_COMMIT|MEM_RESERVE;
		flflag = PAGE_EXECUTE_READWRITE; 
	}

	if (romfileType == ET_EXEC)
	{
		/* execute binary need fix address */
		load_addr = (Elf32_Addr)VirtualAlloc ((LPVOID)ELF_ALIGN(start), end-ELF_ALIGN(start),
			flAllocationType, flflag);
		addr_offset = 0;
	}
	else
	{
		load_addr = (Elf32_Addr)VirtualAlloc (NULL, end-start,
			flAllocationType, flflag);
		addr_offset = load_addr - start;
	}
	__KFREE_INTERPRET();

	if (load_addr == INVALID_ADDR)
		goto error_out;

	RETAILMSG(TONE_EXEC, ("--virtual alloc address:%x \n", load_addr));
	RETAILMSG(TONE_EXEC, ("--virtual alloc size:%x \n", end-ELF_ALIGN(start)));
	RETAILMSG(TONE_EXEC, ("--virtual alloc OK \n"));


	indexLoad = 0;

	for (i = 0; i < romphnum; i ++)
	{
		Elf32_Phdr	*lp = phdr + i;
	
		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:
		{
			unsigned int nprotect = 0;
			//unsigned int oprotect;
			DWORD			oprotect;
			char *seg_addr = (char *)(lp->p_vaddr + addr_offset);
			
			if((++indexLoad) >= PT_LOAD_RES)
				break;

			RETAILMSG(TONE_EXEC, ("--load segment :at:%x size:%x off:%x \n", seg_addr, lp->p_filesz, lp->p_offset));

			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

			if(bMapModule||bRomModule){
				//__dlprintf("module->l_map_start: %x, load addr:%x\n", module->l_map_start, lp->p_vaddr+module->l_addr);

				if(indexLoad == PT_LOAD_CODE){
					LPVOID	pDest;

					if(bMapModule){
						pDest = MapPtrToProcess((LPVOID)lpInfo->start, lpHandle->hProc);
					}else{
						pDest = (LPVOID)(romfileBase + lp->p_offset);
					}
					//RETAILMSG(TONE_EXEC,("Map CODE segment to previous loaded module...\n"));
					//RETAILMSG(TONE_EXEC,("lpInfo->start: %x\n", lpInfo->start));

					//NOTE: 2003-08-26
					//PAGE_NOCACHE 会降低系统性能
					//if(!VirtualCopy((LPVOID)(seg_addr), pDest, lp->p_memsz, nprotect|PAGE_NOCACHE)){
					if(!VirtualCopy((LPVOID)(seg_addr), pDest, lp->p_memsz, nprotect)){
					//NOTE: 2003-08-26
						
						RETAILMSG(TONE_ERROR,("virtualcopy fail@\n"));
						goto error_out;
					}
				}else if(indexLoad == PT_LOAD_DATA){				

					RETAILMSG(TONE_EXEC,("Load DATA segment to memory...\n"));

					VirtualAlloc ((LPVOID)(seg_addr), lp->p_memsz, MEM_COMMIT, nprotect);

					if(bMapModule){
						/* read program loadable segment */
						if (read_file (hFile, (char*)(seg_addr),lp->p_filesz, lp->p_offset) != lp->p_filesz)
							goto error_out;					
					}else{
						memcpy(seg_addr, (LPVOID)(romfileBase + lp->p_offset), lp->p_filesz);
					}
				}				
			}else{				
				RETAILMSG(TONE_EXEC, ("__dlmap_module: 44\n"));

				if (read_file (hFile, seg_addr, lp->p_filesz, lp->p_offset) != lp->p_filesz)
					goto error_out;				

				//VirtualProtect ((LPVOID)seg_addr, lp->p_memsz, nprotect, &oprotect);
			}
			VirtualProtect ((LPVOID)seg_addr, lp->p_memsz, nprotect, &oprotect);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -