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

📄 execelf.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************
Copyright(c) 版权所有,1998-2003微逻辑。保留所有权利。
******************************************************/

/*****************************************************
文件说明:dynlink loader模块
版本号:1.0.0
开发时期:2003-04-40
作者:ZB
修改记录:
	1. 2003-08-26...ZB: 去处PAGE_NOCACHE标志,此标志降低了系统性能。

******************************************************/

#include <ewindows.h>
#include <edevice.h>
#include <eassert.h>

#include <elf.h>
#include <exe_elf.h>
#include <romheader.h>
#include <module.h>
#include "dlstruct.h"
#include <diskio.h>
#include <epalloc.h>

ElfW(Addr) __dllookup_value (const char *name, struct __dlmodule *module);

#include <dlarch.h>
#include "dldyn.h"
#include <coresrv.h>

#define INVALID_SET_FILE_POINTER		((unsigned int)(-1))

#define DL_MEM_BLOCK					0x1000
#define ELF_ALIGN(addr)					((addr)&(~(DL_MEM_BLOCK-1)))
#define ELF_UPALIGN(addr)				(((addr)+DL_MEM_BLOCK-1)&(~(DL_MEM_BLOCK-1)))
#define ALIGN(addr,align)				(((addr)+(align)-1)&(~(align-1)))

#define INVALID_ADDR			0
//#define	DL_DYN_ENTRY			0xffffffff
#define DEFALT_STACK			0x0

#define	E_PHENTSIZE				0x20

#ifndef MODULE_INFO_START

/* module info size, now is 4k bytes */
#define MODULE_INFO_SIZE			0x1000
/* the module info in the module local virtual address */
#define MODULE_INFO_START			(0x10000)
/* module and his dependence dll info */
#define MODULE_LINK_INFO			(MODULE_INFO_START+0x400)
/* the current exe module phdr start address*/
#define MODULE_EXE_PHDR_START		(MODULE_INFO_START+0x800)
/* iff current exe module need interpret, the interpret phdr start address */
#define MODULE_DLL_PHDR_START		(MODULE_INFO_START+0xc00)

#endif //MODULE_INFO_START

#define SIZE_T					unsigned int
////////////////////////////////////////////////////////////////////////
#define elf_assert(assert_value)	ASSERT(assert_value)

#define elf_matches_host(value) value

#undef	__inline
#define	__inline

//#define		ROM_MODULE		1
//#define		ROM_FILE		2
//#define		RAM_FILE		3


//#define RETAILMSG(TONE_EXEC, 		EdbgOutputDebugString

void SHOW_ELF_HEADER(Elf32_Ehdr *ehdr);
void SHOW_ELF_PHDR(Elf32_Phdr	*phdr, UINT	phnum);

////////////////////////////////////////////////////////////////////////




////////////////////////////////////////////////////////////////////////

/*#ifndef VirtualProtect

BOOL WINAPI VirtualProtect (LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect)
{
	return FALSE;
}

#endif*/


/* check the elf header, return 0 failure
*/
static __inline unsigned int elf_check (const Elf32_Ehdr *ehdr)
{

	const unsigned char ELF_HEADER_MARK[EI_PAD] = {ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3};
	
	if (memcmp (ehdr->e_ident, ELF_HEADER_MARK, 4) != 0)
		return 0;

	if (ehdr->e_version != EV_CURRENT)
		return 0;

	if (ehdr->e_phentsize != sizeof (Elf32_Phdr))
		return 0;

	if (ehdr->e_type != ET_DYN && ehdr->e_type != ET_EXEC)
		return 0;

	if (! elf_matches_host (ehdr)) /* check arch */
		return 0;

	return 1;
}

/* read file from the offset, return readed bytes
*/
//__inline
 unsigned int read_file (HANDLE hFile, char *buff, unsigned int size,
										unsigned int offset)
{
	//unsigned int	read;
	DWORD			read;

	elf_assert(buff != NULL);

	if (SetFilePointer (hFile, offset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
		return 0;

	if (! ReadFile (hFile, buff, size, &read, NULL))
	{
		RETAILMSG(TONE_ERROR,("--read file:%x FAILURE!\n", hFile));
		return 0;
	}

	return read;
}
/* test file exist
 * return 0 iff file not exist!
 */
static __inline unsigned int elf_file_exist (const char *name)
{
	DWORD dwAttr = GetFileAttributes (name);
	RETAILMSG(TONE_EXEC, ("--file %s attributes: %x \n", name, dwAttr));
	if (dwAttr == (DWORD)-1)
		return 0;
	if (dwAttr&FILE_ATTRIBUTE_DIRECTORY)
		return 0;
	return 1;
}

/* find binary file
 * 1. current directory
 * 2  kingmos directory
 * 3. system directory
*/
//static __inline unsigned int elf_find_binary(const char *name, char *lpszBin)
#define DEBUG_elf_find_binary 0
__inline unsigned int elf_find_binary(const char *name, char *lpszBin)
{
	unsigned int len = strlen(name);
	//const char *p = name + len;
	const char *p = name;
	//const char *file;
 
	DEBUGMSG(TONE_EXEC|DEBUG_elf_find_binary, ("elf_find_binary: entry(%s).\r\n",name ));
	
	elf_assert(name != NULL);
	
	if (elf_file_exist (name) != 0)
	{
		//memcpy (lpszBin, name, len+1);
    	DEBUGMSG(TONE_EXEC|DEBUG_elf_find_binary, ("elf_find_binary: find it(%s).\r\n",name ));		
		strcpy(lpszBin, name);	
		return 1;
	}

	

//	file = strrchr (name, '\\');
//	if (file == NULL)
//		file = name; /* name without directory info */
//	else{ 		
		//file ++; /* skip '\\' */

//		return 0;	//if with directory info... 
//	}

	while(*p){
		if(*p == '\\'){
			return 0;
		}
		else
			p ++;
	}

//	while ((p >= name)&&(*p != '\\'))
//		p --;
//	p ++;

/*	GetCurrentDirectory (lpszBin,  MAX_PATH);

	if (lpszBin[strlen(lpszBin)-1] != '\\')
		strcat (lpszBin, "\\");
	strcat(lpszBin, p);
	if (elf_file_exist (lpszBin) != 0)
		return 1;
*/
	DEBUGMSG(TONE_EXEC|DEBUG_elf_find_binary, ("elf_find_binary: searching file in kingmos, now!.\n"));

	//strcpy (lpszBin, "\\kingmos\\");
	strcpy (lpszBin, KINGMOS_PATH);
	//strcat (lpszBin, file);
	strcat (lpszBin, name);
	//RETAILMSG(TONE_TEST, ("f:%s\n", lpszBin));
	if (elf_file_exist (lpszBin) != 0)
	{
        DEBUGMSG(TONE_EXEC|DEBUG_elf_find_binary, ("elf_find_binary: finded file in kingmos.\n"));		
		return 1;
	}

	RETAILMSG(TONE_EXEC|DEBUG_elf_find_binary, ("elf_find_binary: searching file in system, now!.\n"));
		
	//strcpy (lpszBin, "\\system\\");
	strcpy (lpszBin, WORK_PATH);
	//strcat (lpszBin, file);
	strcat (lpszBin, name);
	if (elf_file_exist (lpszBin) != 0)
	{
    	RETAILMSG(TONE_EXEC|DEBUG_elf_find_binary, ("elf_find_binary: finded file in system, now!.\n"));		
		return 1;
	}
    DEBUGMSG(TONE_EXEC|DEBUG_elf_find_binary, ("elf_find_binary: leave(%s).\r\n",name ));
	return 0;
}

char	*GetSegName(HANDLE hFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr, UINT index)
{
	Elf32_Shdr *lshdr;
	UINT		i,lPosShtab = 0;
	//char		temp[100];
	char		*temp;
	DWORD		dwRead;
	char		*pstr;
	char		*pSeg;

	//RETAILMSG(TONE_EXEC, ("GetSegName: < \n"));

	for(i = 0; i < ehdr->e_shnum ; i++){
		lshdr = shdr + i;			
		if((lshdr->sh_type == SHT_STRTAB) && 
			(lshdr->sh_flags == 0)){
			lPosShtab = lshdr->sh_offset;
			break;
		}
	}
	if(lPosShtab != 0)
	{
		SetFilePointer(hFile, lPosShtab, NULL, FILE_BEGIN);

		//RETAILMSG(TONE_EXEC, ("GetSegName:  lshdr->sh_size: %x \n", lshdr->sh_size));

		temp = (char *)_kalloc(lshdr->sh_size);

		if(temp == NULL){
			RETAILMSG(TONE_ERROR, ("GetSegName: > error26 \n"));
			return NULL;
		}

		if(!ReadFile(hFile, temp, lshdr->sh_size, &dwRead, NULL)){
			RETAILMSG(TONE_ERROR, ("GetSegName: > error22 \n"));
			_kfree(temp);
			return NULL;
		}

		//for(i = 0; i < ehdr->e_shnum; i++){
			lshdr = shdr + index;			
			//index = lshdr->sh_name;
			pstr = &temp[lshdr->sh_name];
			//fprintf( stream,"section name: %s\r\n", pstr );			
			{
				int	i = strlen(pstr);

				//RETAILMSG(TONE_EXEC, ("pstr name: %s\n", pstr));
				//RETAILMSG(TONE_EXEC, ("pstr len: %x\n", i));
			}

			pSeg = (char *)_kalloc(strlen(pstr)+1);
			if(pSeg == NULL){
				RETAILMSG(TONE_ERROR, ("segment name: _kalloc fail!\n"));
				//RETAILMSG(TONE_EXEC, ("GetSegName: > error33 \n"));
				_kfree(temp);
				return NULL;
			}
			strcpy(pSeg, pstr);
			//pSeg[strlen(pstr)] = '\0';

			//RETAILMSG(TONE_EXEC, ("segment name: %s\n", pSeg));

			//RETAILMSG(TONE_EXEC, ("GetSegName: > %x \n", pSeg));
			_kfree(temp);
			return pSeg;
		//}
	}
	RETAILMSG(TONE_ERROR, ("GetSegName: > error11 \n"));

	//_kfree(temp);
	return	NULL;
}

//struct module_seg *GetSegInfo(HANDLE hFile, Elf32_Ehdr	*ehdr)
struct module_seg *GetSegInfo(HANDLE hFile)
{
	 struct module_seg	*seg_info = NULL;
	 struct module_seg	*seg_temp = NULL;
	 int	i;
	 Elf32_Shdr * shdr;
	 // 2004-10-21
	 //Elf32_Ehdr	*ehdr;	 	 
	 Elf32_Ehdr		elf_ehdr;
	 //

	 //RETAILMSG(TONE_MOD, ("GetDllSegInfo: <\n"));

	 // 2004-10-21
	 //ehdr = (Elf32_Ehdr *)_kalloc (sizeof(Elf32_Ehdr));
	 //if (ehdr == NULL){
		 //return	NULL;
	 //}	
	 // 
	
	RETAILMSG(TONE_MOD, ("GetDllSegInfo: <\n"));

	if (read_file (hFile, (char*)&elf_ehdr, sizeof(Elf32_Ehdr), 0) != sizeof(Elf32_Ehdr))
	{
		// 2004-10-21
		//_kfree(ehdr);
		//
		RETAILMSG(TONE_MOD, ("GetDllSegInfo: >xx\n"));
		return FALSE;
	}	 

	// 2004-10-21
	 //ASSERT(ehdr->e_shnum != 0);
	 ASSERT(elf_ehdr.e_shnum != 0);
	 //
	 
	 // 2004-10-21
	 //shdr = (Elf32_Shdr *)_kalloc (ehdr->e_shentsize * ehdr->e_shnum);
	 shdr = (Elf32_Shdr *)_kalloc (elf_ehdr.e_shentsize * elf_ehdr.e_shnum);
	 //
	 if (shdr == NULL){
 		// 2004-10-21
//		 _kfree(ehdr);
		 //
		 return	NULL;
	 }

	 // 2004-10-21
	 //if (read_file (hFile, (char*)shdr, ehdr->e_shentsize*ehdr->e_shnum, ehdr->e_shoff) 
		 //!= (unsigned int)(ehdr->e_shentsize*ehdr->e_shnum))
	 if (read_file (hFile, (char*)shdr, elf_ehdr.e_shentsize*elf_ehdr.e_shnum, elf_ehdr.e_shoff) 
		 != (unsigned int)(elf_ehdr.e_shentsize * elf_ehdr.e_shnum))
	 //
	 {
		 // 2004-10-21
		 //_kfree(ehdr);
		 //
		 _kfree(shdr);
		 return	NULL;
	 }
	 
	 RETAILMSG(TONE_EXEC,("elf_ehdr.e_shnum: %x\n", elf_ehdr.e_shnum));

//	 RETAILMSG(TONE_EXEC, ("GetSegInfo : ==>11!\n");
//	 return NULL;

	 // 2004-10-21
	 //for(i = 0; i < ehdr->e_shnum; i++)
	 for(i = 0; i < elf_ehdr.e_shnum; i++)
	 //
	 {
		 Elf32_Shdr	*lp = shdr + i;
		 //struct module_seg *seg_info;	
		 
		 if(lp->sh_type == SHT_NULL)
			 continue;
		 //2004-10-21
		 //seg_info = (struct module_seg *)_kalloc (sizeof(struct module_seg ));
		 seg_info = (struct module_seg *)KHeap_Alloc(sizeof(struct module_seg ));
		 //
		 if (seg_info == NULL){
			 RETAILMSG(TONE_ERROR,("GetSegInfo _kalloc	fail!\n"));
			 
			 _kfree(shdr);
			 //2004-10-21
			 //_kfree(ehdr);
			 //
			 return	NULL;
		 }
		 seg_info->sh_addr	= lp->sh_addr;
		 seg_info->sh_offset = lp->sh_offset;
		 seg_info->sh_size	= lp->sh_size;

		 //2004-10-21
		 //seg_info->sh_name = GetSegName(hFile, ehdr, shdr, i);
		 seg_info->sh_name = GetSegName(hFile, &elf_ehdr, shdr, i);

⌨️ 快捷键说明

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