📄 execelf.c
字号:
/******************************************************
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 + -