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

📄 ldelf.c

📁 T-kernel 的extension源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *---------------------------------------------------------------------- *    T-Kernel / Standard Extension * *    Copyright (C) 2006 by Ken Sakamura. All rights reserved. *    T-Kernel / Standard Extension is distributed  *      under the T-License for T-Kernel / Standard Extension. *---------------------------------------------------------------------- * *    Version:   1.00.00 *    Released by T-Engine Forum(http://www.t-engine.org) at 2006/8/11. * *---------------------------------------------------------------------- *//* *	ldelf.c (memory) * *	ELF format program loading (VR4131 Virtual storage version) * *	Supports the following loading formats: *	* On-demand loading *	* Global loading/not relocated *	* Global loading/relocated */#include "segmgr.h"#include <cnvend.h>#ifdef DEBUG#  define _ER_REC(n)		( E_REC | (n) )#else#  define _ER_REC(n)		( E_REC )#endif#define	LINK_ADDR		0x00100000	/* Link address */#define TSD_GEI_SYM_M1		(-1)#define TSD_RL1_MSK_0XFC000000	0xfc000000U#define TSD_RL1_MSK_0XF0000000	0xf0000000U#define TSD_RL1_MSK_0XFFFF0000	0xffff0000U#define TSD_RL1_MSK_0X03E00000	0x03e00000U#define TSD_RL1_MSK_0X001F0000	0x001f0000U#define TSD_RL1_MSK_0X03E0	0x03e0U#define TSD_RL1_MSK_0X001F	0x001fU#define TSD_RL1_MSK_0XFC00	0xfc00U#define TSD_RL1_SFT_11		11U#define TSD_RL1_SFT_13		13U#define TSD_RL1_SFT_21		21U#define TSD_RL1_SFT_23		23U#define TSD_GEI_VAL_2		2#define TSD_LDE_ERR_1		1#define TSD_LDE_ERR_2		2#define TSD_LDE_ERR_3		3#define TSD_LDE_ERR_4		4#define TSD_LDE_ERR_5		5#define TSD_LDE_ERR_6		6#define TSD_LDE_ERR_7		7#define TSD_LDE_ERR_8		8#define TSD_LDE_ERR_9		9#define TSD_LDE_ERR_10		10#define TSD_LDE_ERR_11		11#define TSD_LDE_ERR_12		12#define TSD_LDE_ERR_13		13#define TSD_LDE_ERR_14		14#define TSD_LDE_ERR_15		15#define TSD_LDE_ERR_16		16#define TSD_LDE_ERR_17		17#define TSD_RL1_MSK_0X03FFFFFF	0x03ffffffU#define TSD_RL1_SFT_MCR		((W)((UW)addend << 6) >> 4)#define TSD_RL1_SFT_2		2U#define TSD_RL1_SFT_16		16U#define TSD_RL1_MSK_0XFFFF	0xffffU#define TSD_RL1_MSK_0X0000FFFF	0x0000ffffU/* Format checking for each supported model */#define CHK_ELFDATA(n)		( (n) == ELFDATA2LSB )#define CHK_ELFMACH(n)		( (n) == EM_MIPS )/* * ELF loading information */typedef struct {	VB*	text_ladr;	/* text area loading address */	UW	text_fofs;	/* text area file position */	UW	text_size;	/* text area size */	VB*	data_ladr;	/* data area loading address */	UW	data_fofs;	/* data area file position */	UW	data_size;	/* data area size */	VB*	bss_ladr;	/* bss  area first address */	UW	bss_size;	/* bss  area size */	UW	stack_size;	/* Stack size */	UH	text_shndx;	/* text area section number */	UH	data_shndx;	/* data area section number */	UH	bss_shndx;	/* bss  area section number */	UW	rel_text_fofs;	/* File position of text area relocation information */	UW	rel_text_size;	/* Size of text area relocation information */	UW	rel_data_fofs;	/* File position of data area relocation information */	UW	rel_data_size;	/* Size of data area relocation information */	UW	symtbl_fofs;	/* File position of symbol table */	UW	symtbl_size;	/* Size of symbol table */	BOOL	vir_or_off;	/* Virtual address (TRUE) or offset (FALSE) */	UW	reginf_fofs;	/* File position of register information */	UW	reginf_size;	/* Size of register information */	W	gp;		/* gp register value */} ELF_LoadInfo;LOCAL ER CheckLoadAddress( ELF_LoadInfo *eli );LOCAL ER CheckSysLoadAddress( ELF_LoadInfo *eli );LOCAL ER GetELFLoadInfoShdr( ELF_LoadInfo *eli, Elf32_Ehdr *hdr, POBJ_HDR *pohdr, BzRead *bzr );LOCAL BOOL HasDynSeg( Elf32_Ehdr *hdr, POBJ_HDR *pohdr, BzRead *bzr );LOCAL BOOL HasRelSec( Elf32_Ehdr *hdr, POBJ_HDR *pohdr, BzRead *bzr );LOCAL ER GetELFLoadInfoPhdr( ELF_LoadInfo *eli, Elf32_Ehdr *hdr, POBJ_HDR *pohdr, BzRead *bzr );LOCAL ER GetELFLoadInfo( ELF_LoadInfo *eli, Elf32_Ehdr *hdr, POBJ_HDR *pohdr, BzRead *bzr, BOOL relsec );LOCAL ER reloc1( ELF_LoadInfo *eli, POBJ_HDR *pohdr, W rtbl, W rtblsz, W lofs, VB *sect, W sectsz, Elf32_Sym *symtbl, W syment, BzRead *bzr );LOCAL ER elf_get_gp( POBJ_HDR *pohdr, ELF_LoadInfo *eli, BzRead *bzr );LOCAL ER elf_relocation( LDINFO *li, ELF_LoadInfo *eli, W lofs, BzRead *bzr );#ifdef DEBUGLOCAL void prELFLoadInfo( ELF_LoadInfo *eli ){	DEBUG_PRINT(("ELF_LoadInfo\n"));	DEBUG_PRINT(("\t.text_ladr     = 0x%08x\n",	eli->text_ladr));	DEBUG_PRINT(("\t.text_fofs     = 0x%08x\n",	eli->text_fofs));	DEBUG_PRINT(("\t.text_size     = 0x%08x\n",	eli->text_size));	DEBUG_PRINT(("\t.data_ladr     = 0x%08x\n",	eli->data_ladr));	DEBUG_PRINT(("\t.data_fofs     = 0x%08x\n",	eli->data_fofs));	DEBUG_PRINT(("\t.data_size     = 0x%08x\n",	eli->data_size));	DEBUG_PRINT(("\t.bss_ladr      = 0x%08x\n",	eli->bss_ladr));	DEBUG_PRINT(("\t.bss_size      = 0x%08x\n",	eli->bss_size));	DEBUG_PRINT(("\t.stack_size    = %d\n",		eli->stack_size));	DEBUG_PRINT(("\t.text_shndx    = %d\n",		eli->text_shndx));	DEBUG_PRINT(("\t.data_shndx    = %d\n",		eli->data_shndx));	DEBUG_PRINT(("\t.bss_shndx     = %d\n",		eli->bss_shndx));	DEBUG_PRINT(("\t.rel_text_fofs = 0x%08x\n",	eli->rel_text_fofs));	DEBUG_PRINT(("\t.rel_text_size = %d\n",		eli->rel_text_size));	DEBUG_PRINT(("\t.rel_data_fofs = 0x%08x\n",	eli->rel_data_fofs));	DEBUG_PRINT(("\t.rel_data_size = %d\n",		eli->rel_data_size));	DEBUG_PRINT(("\t.symtbl_fofs   = 0x%08x\n",	eli->symtbl_fofs));	DEBUG_PRINT(("\t.symtbl_size   = %d\n",		eli->symtbl_size));}#endif/* * Check if the loading address is within a range of the process unique space. */LOCAL ER CheckLoadAddress( ELF_LoadInfo *eli ){	ER	err;	if ( !isLocalSpace(eli->text_ladr)	  || !isLocalSpace(eli->bss_ladr + eli->bss_size) ) {		err = _ER_REC(TSD_LDE_ERR_1);		goto err_ret;	}	return E_OK;err_ret:	DEBUG_PRINT(("CheckLoadAddress err = %d (%d)\n", err, (UH)err));	return err;}/* * Check if the loading address is within a range of system program loading. */LOCAL ER CheckSysLoadAddress( ELF_LoadInfo *eli ){	ER	err;	if ( !isSysLoadSpace(eli->text_ladr)	  || !isSysLoadSpace(eli->bss_ladr + eli->bss_size) ) {		err = _ER_REC(TSD_LDE_ERR_1);		goto err_ret;	}	return E_OK;err_ret:	DEBUG_PRINT(("CheckSysLoadAddress err = %d (%d)\n", err, (UH)err));	return err;}/* * Obtain loading information from ELF section header. */LOCAL ER GetELFLoadInfoShdr( ELF_LoadInfo *eli, Elf32_Ehdr *hdr, POBJ_HDR *pohdr, BzRead *bzr ){	Elf32_Shdr	*shdr_buf, *shdr, *p;	W		n;	VB		*adr;	W		symsect = TSD_GEI_SYM_M1;	ER		err;	if ( (hdr->e_shentsize < sizeof(Elf32_Shdr)) || (hdr->e_shnum == 0) ) {		err = _ER_REC(TSD_LDE_ERR_1);		goto err_ret1;	}	/* Buffer for loading section header */	n = hdr->e_shentsize * hdr->e_shnum;	shdr_buf = Vmalloc((size_t)n);	if ( shdr_buf == NULL ) {		err = E_NOMEM;		goto err_ret1;	}	/* Load section header */	err = ReadProgFile(pohdr, (W)hdr->e_shoff, (VB*)shdr_buf, n, bzr);	if ( err < E_OK ) {		goto err_ret2;	}	eli->stack_size = (UW)DefaultStackSize;	for ( n = (W)hdr->e_shnum, shdr = shdr_buf;			--n >= 0; shdr = (Elf32_Shdr*)((VB*)shdr + hdr->e_shentsize) ) {		switch ( shdr->sh_type ) {		  case SHT_PROGBITS:			if (( shdr->sh_flags & SHF_ALLOC) == 0U) {				continue; /* Ignore */			}						switch ( shdr->sh_flags ) {			  case SHF_ALLOC|SHF_EXECINSTR:	/* text area */				if ( eli->text_size != 0U ) {					err = _ER_REC(TSD_LDE_ERR_2);					goto err_ret2;				}				eli->text_ladr = shdr->sh_addr;				eli->text_fofs = shdr->sh_offset;				eli->text_size = shdr->sh_size;				eli->text_shndx = (UH)(shdr - shdr_buf);				break;			  case SHF_ALLOC|SHF_WRITE:	/* data area */				if ( eli->data_ladr != NULL ) {					err = _ER_REC(TSD_LDE_ERR_3);					goto err_ret2;				}				eli->data_ladr = shdr->sh_addr;				eli->data_fofs = shdr->sh_offset;				eli->data_size = shdr->sh_size;				eli->data_shndx = (UH)(shdr - shdr_buf);				break;			  default:				err = _ER_REC(TSD_LDE_ERR_4);				goto err_ret2;			}			break;		  case SHT_NOBITS:			switch ( shdr->sh_flags ) {			  case SHF_ALLOC|SHF_WRITE:	/* bss area */				if ( eli->bss_ladr != NULL ) {					err = _ER_REC(TSD_LDE_ERR_5);					goto err_ret2;				}				eli->bss_ladr = shdr->sh_addr;				eli->bss_size = shdr->sh_size;				eli->bss_shndx = (UH)(shdr - shdr_buf);				break;			  case SHF_ALLOC:		/* stack area */				eli->stack_size = shdr->sh_size;				break;			  case 0:				continue; /* Ignore */			  default:				err = _ER_REC(TSD_LDE_ERR_6);				goto err_ret2;			}			break;		  case SHT_REL:			if ( (shdr->sh_info >= hdr->e_shnum)			  || (shdr->sh_link >= hdr->e_shnum) ) {			  	err = _ER_REC(TSD_LDE_ERR_7);			  	goto err_ret2;			}			/* Section to be relocated */			p = &shdr_buf[shdr->sh_info];			if ( p->sh_type != SHT_PROGBITS ) {				continue;			}			switch ( p->sh_flags ) {			  case SHF_ALLOC|SHF_EXECINSTR:	/* text area */				if ( eli->rel_text_size != 0U ) {					err = _ER_REC(TSD_LDE_ERR_9);					goto err_ret2;				}				eli->rel_text_fofs = shdr->sh_offset;				eli->rel_text_size = shdr->sh_size;				break;			  case SHF_ALLOC|SHF_WRITE:	/* data area */				if ( eli->rel_data_size != 0U ) {					err = _ER_REC(TSD_LDE_ERR_10);					goto err_ret2;				}				eli->rel_data_fofs = shdr->sh_offset;				eli->rel_data_size = shdr->sh_size;				break;			  case 0:				continue; /* Ignore */			  default:				err = _ER_REC(TSD_LDE_ERR_11);				goto err_ret2;			}			if ( (symsect >= 0) && (shdr->sh_link != (UW)symsect) ) {				err = _ER_REC(TSD_LDE_ERR_12);				goto err_ret2;			}			symsect = (W)shdr->sh_link;			break;		  case SHT_MIPS_REGINFO:	  		if( eli->reginf_size != 0U ) {				err = _ER_REC(TSD_LDE_ERR_17);				goto err_ret2;			}			eli->reginf_fofs = shdr->sh_offset;			eli->reginf_size = shdr->sh_size;		  	break;		  default:			continue; /* Ignore */		}	}	/* Check validity */	if ( eli->text_size == 0U ) {		err = _ER_REC(TSD_LDE_ERR_13);		goto err_ret2;	}	adr = PageAlignU(eli->text_ladr + eli->text_size);	if ( eli->data_ladr != adr ) {		err = _ER_REC(TSD_LDE_ERR_14);		goto err_ret2;	}	adr += eli->data_size;	if ( eli->bss_ladr < adr ) {		err = _ER_REC(TSD_LDE_ERR_15);		goto err_ret2;	}	if ( symsect >= 0 ) {		/* Symbol table for relocation */		if ( shdr_buf[symsect].sh_type != SHT_SYMTAB ) {			err = _ER_REC(TSD_LDE_ERR_16);			goto err_ret2;		}		eli->symtbl_fofs = shdr_buf[symsect].sh_offset;		eli->symtbl_size = shdr_buf[symsect].sh_size;	}	Vfree(shdr_buf);	return E_OK;err_ret2:	Vfree(shdr_buf);err_ret1:	DEBUG_PRINT(("GetELFLoadInfoShdr err = %d (%d)\n", err, (UH)err));	return err;}/* * Obtain loading information from ELF program header */LOCAL BOOL HasDynSeg( Elf32_Ehdr *hdr, POBJ_HDR *pohdr, BzRead *bzr ){	Elf32_Phdr	*phdr_buf, *phdr;	W		n;	ER		err;	if ( (hdr->e_phentsize < sizeof(Elf32_Phdr)) || (hdr->e_phnum < 1) ) {		err = _ER_REC(TSD_LDE_ERR_1);		goto err_ret1;	}	n = hdr->e_phentsize * hdr->e_phnum;	phdr_buf = Vmalloc((size_t)n);	if ( phdr_buf == NULL ) {		err = E_NOMEM;		goto err_ret1;	}	/* Load program header */	err = ReadProgFile(pohdr, (W)hdr->e_phoff, (VB*)phdr_buf, n, bzr);	if ( err < E_OK ) {		goto err_ret2;	}	for ( n = (W)hdr->e_phnum, phdr = phdr_buf;			--n >= 0; phdr = (Elf32_Phdr*)((VB*)phdr + hdr->e_phentsize) ) {		if ( phdr->p_type == PT_DYNAMIC ) {			goto found;		}	}	Vfree(phdr_buf);	return FALSE;found:	Vfree(phdr_buf);	return TRUE;err_ret2:	Vfree(phdr_buf);err_ret1:	DEBUG_PRINT(("HasDynSeg err = %d (%d)\n", err, (UH)err));	return FALSE;}/* * Relocation section check */LOCAL BOOL HasRelSec( Elf32_Ehdr *hdr, POBJ_HDR *pohdr, BzRead *bzr ){	Elf32_Shdr	*shdr_buf, *shdr;	W		n;	ER		err;	if ( (hdr->e_shentsize < sizeof(Elf32_Shdr)) || (hdr->e_shnum == 0) ) {		err = _ER_REC(TSD_LDE_ERR_1);		goto err_ret1;	}	n = hdr->e_shentsize * hdr->e_shnum;	shdr_buf = Vmalloc((size_t)n);	if ( shdr_buf == NULL ) {		err = E_NOMEM;		goto err_ret1;	}	/* Load section header */	err = ReadProgFile(pohdr, (W)hdr->e_shoff, (VB*)shdr_buf, n, bzr);	if ( err < E_OK ) {		goto err_ret2;	}	for ( n = (W)hdr->e_shnum, shdr = shdr_buf;			--n >= 0; shdr = (Elf32_Shdr*)((VB*)shdr + hdr->e_shentsize) ) {		switch ( shdr->sh_type ) {		  case SHT_REL:			goto found;		  default:			continue; /* Ignore */		}	}

⌨️ 快捷键说明

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