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

📄 procmap.c

📁 T-kernel 的extension源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *---------------------------------------------------------------------- *    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. * *---------------------------------------------------------------------- *//* *	procmap.c (memory) * *	Segment management (Virtual storage version) *	Process map */#include "segmgr.h"#include "prcinfo.h"#include <extension/sys/tkse_ssid.h>/* * Model-based support for object formats *//* ELF is basically supported by all models. */#define ELF_SUPPORT	1#define TSD_WLM_POS_0	0#define TSD_WLM_POS_1	1#define TSD_WLM_POS_2	2#define TSD_LSP_POS_2	2#define TSD_LPF_ERR_M1	(-1)#define TSD_MPR_ERR_M1	(-1)#define TSD_CSP_VAL_M1	(-1)#define TSD_SPS_VAL_2	2/* * Default user stack size */EXPORT W DefaultStackSize;	/* Byte *//* * Object format */typedef enum { UNKNOWN, AOUT, COFF, ELF } OBJ_TYP;typedef struct {	OBJ_TYP	typ;		/* Object format */	unsigned int sysproc:1;	/* If system process is specified: 1 */	OBJ_HDR	hdr;		/* Object header */} OBJ_INF;typedef struct {	W fd;			/* File descriptor */	W fdtype;		/* File type */	ID mid[N_LDMID];	/* File map ID */	VP loadadr;		/* Load address */	UH dpage;		/* Number of disk map pages */	UH mpage;		/* Number of memory map pages */	FP entry;		/* Program entry */	TC name[L_FNM];		/* Name */} SysProgInfo;LOCAL WER OpenProgFile( POBJ_HDR *pohdr, TC *name, OBJ_INF *obj, BzRead *bzr );LOCAL ER demand_load( LDINFO *li, UW lsid, UW mode, OBJ_INF *obj, W nent, FP *entry, BzRead *bzr );LOCAL ER direct_load( LDINFO *li, UW lsid, UB mode, OBJ_INF *obj, FP *entry, BzRead *bzr );LOCAL ER loadprogfile( POBJ_HDR *pohdr, UW lsid, UW mode, LDINFO *inf, TC *name, FP *entry );LOCAL ER unloadprogfile( LDINFO *inf, UW lsid );LOCAL DYNLD* newDynld( PRCMINFO *pmi );LOCAL void freeDynld( DYNLD *dynld );LOCAL DYNLD* searchDynld( W loadid, PRCMINFO *pmi );LOCAL SysProgInfo* searchProgID( void );LOCAL ER SysProgStartup( TC *name, TC *arg, FP entry );/* * Open executable file *	Note that name has a length of L_FNM. */LOCAL WER OpenProgFile( POBJ_HDR *pohdr, TC *name, OBJ_INF *obj, BzRead *bzr ){	W	rsz, expsz;	UB*	buf;	TC	namebuf[L_FNM + 1];	ER	err;	memset(bzr, 0, (size_t)sizeof(BzRead));	obj->sysproc = 0;	/* Open executable file */	err = ExecFileOpen(pohdr);	if ( err < E_OK ) {		goto err_ret1;	}	/* Obtain file name (process name) */	err = ExecFileGetName(pohdr, namebuf);	if ( err < E_OK ) {		goto err_ret2;	}	if ( name != NULL ) {		tc_strncpy(name, namebuf, L_FNM);	}	/* Read header information */	err = ExecFileRead(pohdr, (VB*)&obj->hdr, sizeof(OBJ_HDR), 0, &rsz, NULL);	if ( err < E_OK ) {		goto err_ret2;	}	if ( rsz < (W)sizeof(OBJ_HDR) ) {		err = E_REC;		goto err_ret2;	}	/* Decompress the file if it is compressed. */	if ( ((err == BzRT1 )||( err == BzRT2))  /* Special compression format record */	  && ((obj->hdr.bz.magic1 == BzMAGIC1 )	   || (obj->hdr.bz.magic1 == BzMAGIC1S))	  && (obj->hdr.bz.magic2 == BzMAGIC2 )	  && (obj->hdr.bz.magic3 == BzMAGIC3 )	  && ((W)obj->hdr.bz.expsz > rsz )) {		expsz = (W)obj->hdr.bz.expsz;		if ( obj->hdr.bz.magic1 == BzMAGIC1S ) {			obj->sysproc = 1;		}		/* Buffer for decompression */		buf = Vmalloc((size_t)(expsz + rsz));		if ( buf == NULL ) {			err = E_SYSMEM;			goto err_ret2;		}		/* Load record data */		err = ExecFileRead(pohdr, (VB*)buf + expsz, rsz, 0, (W*)NULL, (VP)&bzr->recSubType);		if ( err < E_OK ) {			goto err_ret3;		}		/* Decompress */		err = buffer_uncompress(buf, buf + expsz + sizeof(Bz_HDR),					expsz, rsz - (W)sizeof(Bz_HDR));		if ( err < E_OK ) {			goto err_ret3;		}		/* Replace object header information with decompressed data. */		memcpy(&obj->hdr, buf, (size_t)sizeof(OBJ_HDR));		bzr->recBuf = buf;		bzr->recLen = expsz;	}	/* Check object format */	obj->typ = UNKNOWN;#if AOUT_SUPPORT	if (( obj->hdr.aout.a_magic == OMAGIC )	  ||( obj->hdr.aout.a_magic == ZMAGIC )) {		obj->typ = AOUT;	}#endif#if ELF_SUPPORT	if (( obj->hdr.elf.e_ident[EI_MAG0] == ELFMAG0 )	  &&( obj->hdr.elf.e_ident[EI_MAG1] == ELFMAG1 )	  &&( obj->hdr.elf.e_ident[EI_MAG2] == ELFMAG2 )	  &&( obj->hdr.elf.e_ident[EI_MAG3] == ELFMAG3 )) {		obj->typ = ELF;	}#endif	return pohdr->desc;err_ret3:	Vfree(buf);err_ret2:	ExecFileClose(pohdr);err_ret1:	DEBUG_PRINT(("OpenProgFile err = %d\n", err));	return err;}/* * Load executable file */EXPORT ER ReadProgFile( POBJ_HDR *pohdr, W ofs, VB *adr, W sz, BzRead *bzr ){	W	rsz;	ER	err;	if ( bzr->recBuf == NULL ) {		/* Uncompressed format */		err = ExecFileRead(pohdr, adr, sz, ofs, &rsz, NULL);		if ( err < E_OK ) {			goto err_ret;		}		if ( rsz < sz ) {			err = E_REC;			goto err_ret;		}	} else {		/* Compression format */		if ( sz > bzr->recLen ) {			err = E_REC;			goto err_ret;		}		memcpy(adr, bzr->recBuf + ofs, (size_t)sz);	}	return E_OK;err_ret:	DEBUG_PRINT(("ReadProgFile err = %d\n", err));	return err;}/* * On-demand loading *	lsid == 0	Not acceptable *	lsid != 0	Load into local space */LOCAL ER demand_load( LDINFO *li, UW lsid, UW mode, OBJ_INF *obj, W nent, FP *entry, BzRead *bzr ){	PhyBlk	*pb;	ID	did;	W	ofs, rsz, n;	ER	err;	/* Obtain disk block structure */	pb = Imalloc(sizeof(PhyBlk) * (UW)(nent + 1));	if ( pb == NULL ) {		err = E_SYSMEM;		goto err_ret1;	}	did = ExecFileRecInfo(&li->pohdr, &ofs, &rsz, pb, nent, &n);	if ( did < E_OK ) {		err = did;		goto err_ret2;	}	pb[n].len = 0;	if ( ofs != 0 ) {		err = E_REC;		goto err_ret2;	}	switch ( obj->typ ) {#if AOUT_SUPPORT	  case AOUT:		err = DemandLoad_aout(li, lsid, mode, &obj->hdr.aout,						did, pb, entry, bzr);		break;#endif#if COFF_SUPPORT	  case COFF:		err = DemandLoad_coff(li, lsid, mode, &obj->hdr.coff,						did, pb, entry, bzr);		break;#endif#if ELF_SUPPORT	  case ELF:		err = DemandLoad_elf(li, lsid, mode, &obj->hdr.elf,						did, pb, entry, bzr);		break;#endif	  default:	/* Object format error (unsupported format) */		err = E_REC;		break;	}	if ( err < E_OK ) {		goto err_ret2;	}	Ifree(pb);	return E_OK;err_ret2:	Ifree(pb);err_ret1:	DEBUG_PRINT(("demand_load err = %d\n", err));	return err;}/* * Global loading *	lsid == 0	Load into system space *	lsid != 0	Load into local space */LOCAL ER direct_load( LDINFO *li, UW lsid, UB mode, OBJ_INF *obj, FP *entry, BzRead *bzr ){	ER	err;	switch ( obj->typ ) {#if AOUT_SUPPORT	  case AOUT:		err = DirectLoad_aout(li, lsid, mode, &obj->hdr.aout,						entry, bzr);		break;#endif#if COFF_SUPPORT	  case COFF:		err = DirectLoad_coff(li, lsid, mode, &obj->hdr.coff,						entry, bzr);		break;#endif#if ELF_SUPPORT	  case ELF:		err = DirectLoad_elf(li, lsid, mode, &obj->hdr.elf,						entry, bzr);		break;#endif	  default:	/* Object format error (unsupported format) */		err = E_REC;		break;	}	if ( err < E_OK ) {		goto err_ret;	}	return E_OK;err_ret:	DEBUG_PRINT(("direct_load err = %d\n", err));	return err;}/* * Process mapping */EXPORT ER MapProc( PINFO *pinfo, POBJ_HDR *pohdr, FP *entry ){IMPORT	W		ForceLoadFlag;		/* debug.c forced load flag */	LDINFO		*li = &pinfo->ldinfo;	/* ldinfo has been cleared to 0. */	UW		lsid = GetLSID_pinfo(pinfo);	UW		mode;	OBJ_INF		obj;	BzRead		bzr;	ID		did;	W		nent;	ID		oldrid;	T_TSKSPC	curspc;	ER		err;	/* Check access right */	err = ExecFileCheck(pohdr);	if ( err < E_OK ) {		goto err_ret1;	}	/* To record that the initial process (INIT) opened an executable file,	   temporarily change resource IDs in its current task. */	oldrid = tk_set_rid(TSK_SELF, INIT_PINFO->resid);	if ( oldrid < E_OK ) {		err = ERtoERR(oldrid);		goto err_ret1;	}	/* Open executable file */	err = OpenProgFile(pohdr, pinfo->name, &obj, &bzr);	if ( err < E_OK ) {		goto err_ret2;	}	li->pohdr = *pohdr;	pohdr = &li->pohdr;	if ((pohdr->type & (TPA_LINK | TMA_LINK)) != 0) {		li->lnk = *(pohdr->src.lnk);	} else {		memset(&li->lnk, 0, sizeof(LINK));	}	/* If the object has a specified system process, reflect it in pinfo. */	mode = ( (pinfo->sysproc |= obj.sysproc) != 0 )? (UW)LDMD_SYS: (UW)LDMD_USR;	/* Obtain disk ID */	did = ExecFileRecInfo(&li->pohdr, NULL, NULL, NULL, 0, &nent);	if ( did < E_OK ) {		err = did;		goto err_ret3;	}	/* Change to logical space of process (pinfo) to be loaded */	err = ChangeLogicalSpace(&curspc, GetTSKSPC_pinfo(pinfo));	if ( err < E_OK ) {		err = ERtoERR(err);		goto err_ret3;	}	err = TSD_MPR_ERR_M1;	if ( (did > 0) && !isRemovableDisk(did) &&( bzr.recBuf == NULL )	  &&( ForceLoadFlag == 0 )) {		/* On-demand loading */		err = demand_load(li, lsid, mode, &obj, nent, entry, &bzr);		/* (err < E_OK) If files cannot be loaded on demand, load them all at once. */	}	if ( err < E_OK ) {		/* Global loading */		err = direct_load(li, lsid, (UB)mode, &obj, entry, &bzr);		if ( err < E_OK ) {			goto err_ret4;		}	}	/* Turn back to original logical space. */	ChangeLogicalSpace(NULL, curspc);	/* Release memory for decompression */	if ( bzr.recBuf != NULL ) {		Vfree(bzr.recBuf);	}	/* If files are not loaded on demand, close executable files. */	if ( li->dpage == 0U ) {		ExecFileClose(pohdr);	}	/* Return resource ID */	tk_set_rid(TSK_SELF, oldrid);#ifdef MaxStackSize	if ( li->stacksz > MaxStackSize ) {		err = E_REC;		goto err_ret5;	}#endif	/* Initialize local memory space */	err = InitLocalMemory(pinfo);	if ( err < E_OK ) {		err = ERtoERR(err);		goto err_ret5;	}	return E_OK;err_ret5:	UnmapProc(pinfo);	goto err_ret1;err_ret4:	ChangeLogicalSpace(NULL, curspc);err_ret3:	if ( bzr.recBuf != NULL ) {		Vfree(bzr.recBuf);	}	ExecFileClose(pohdr);err_ret2:	tk_set_rid(TSK_SELF, oldrid);err_ret1:	DEBUG_PRINT(("MapProc err = %d\n", err));	return err;}/* * Process unmapping */EXPORT ER UnmapProc( PINFO *pinfo ){	LDINFO	*li = &pinfo->ldinfo;	UW	lsid = GetLSID_pinfo(pinfo);	ID	oldrid;	W	i;	ER	err, error;	err = error = E_OK;	for ( i = 0; i < N_LDMID; ++i ) {		if ( li->mid[i] == 0 ) {			continue;		}		/* Reset disk map */		err = UnmapDisk(li->mid[i], MD_RDONLY);		if ( err < E_OK ) {			error = err;		}	}	if ( li->dpage > 0U ) {		/* Since the initial process (INIT) opens an executable file,		   temporarily change resource IDs in its current task. */		oldrid = tk_set_rid(TSK_SELF, INIT_PINFO->resid);		if ( err < E_OK ) {			error = ERtoERR(err);		} else {			/* Close executable file */			err = ExecFileClose(&li->pohdr);			if ( err < E_OK ) {				error = err;			}			/* Return resource ID */			tk_set_rid(TSK_SELF, oldrid);		}	}	/* Reset memory map */	err = UnmakeSpace((VB*)li->topadr + (li->dpage * (UW)PAGESIZE),						(W)li->mpage, (W)lsid);	if ( err < E_OK ) {		error = ERtoERR(err);	}#ifdef DEBUG	if ( error < E_OK ) {		DEBUG_PRINT(("UnmapProc err = %d\n", error));	}#endif	return error;}/* * Stack mapping */EXPORT ER MapStack( PINFO *pinfo, W stksz, VP *laddr ){#define	INIT_STACKSZ	128	/* Although the size depends on the CPU,				   allocate an appropriate size. */	UW		lsid = GetLSID_pinfo(pinfo);	UW		npage = PageCount((UW)stksz) + 1U;	VB		*p;	T_TSKSPC	curspc;	ER		err;	if ( stksz < INIT_STACKSZ ) {		err = E_PAR;		goto err_ret1;	}	/* Allocate a stack area on user space */	p = AllocMemorySpace((W)npage, lsid);	if ( p == NULL ) {		err = E_NOMEM;		goto err_ret1;	}	/* Set memory space */	err = MakeSpace(p + PAGESIZE, (W)npage - 1, (W)lsid, (UW)PTE_UMEM_NC);	if ( err < E_OK ) {		err = ERtoERR(err);		goto err_ret2;	}	/* To set task startup parameters, make access to the user stack at task	 * startup (tk_sta_tsk). Since occurrence of page fault leads to system down,	 * perform page-in beforehand. In a strict sense, even if page-in is performed	 * at this point, page-out may occur (leading to system down) until	 * tk_sta_tsk() processing is performed. However, such a possibility is	 * considered low and therefore specific measures are not taken here.	 */	err = ChangeLogicalSpace(&curspc, GetTSKSPC_lsid(lsid));	if ( err < E_OK ) {		err = ERtoERR(err);		goto err_ret3;	}	memset(p + PAGESIZE + stksz - INIT_STACKSZ, 0, (size_t)INIT_STACKSZ);	ChangeLogicalSpace(NULL, curspc);	*laddr = p + PAGESIZE;	return E_OK;err_ret3:	UnmakeSpace(p + PAGESIZE, (W)npage - 1, (W)lsid);err_ret2:	FreeMemorySpace(p, lsid);err_ret1:	DEBUG_PRINT(("MapStack err = %d\n", err));	return err;}/* * Stack unmapping */EXPORT ER UnmapStack( PINFO *pinfo, VP laddr ){	UW	lsid = GetLSID_pinfo(pinfo);	VB	*p = laddr;	UW	npage;	ER	err;	/* Release stack area from user space. */	npage = (UW)FreeMemorySpace(p - PAGESIZE, lsid);	if ( npage <= 0U ) {		err = E_SYS;		goto err_ret;	}	/* Remove memory space. */	err = UnmakeSpace(p, (W)npage - 1, (W)lsid);	if ( err < E_OK ) {		err = ERtoERR(err);		goto err_ret;	}	return E_OK;err_ret:	DEBUG_PRINT(("UnmapStack err = %d\n", err));	return err;}/* ======================================================================== *//* * Program loading *	Used in dynamic loading and system program loading * *	lsid = 0 Load into system space (system program loading) *	lsid > 0 Load into local space (dynamic loading) */LOCAL ER loadprogfile( POBJ_HDR *pohdr, UW lsid, UW mode, LDINFO *inf, TC *name, FP *entry ){IMPORT	W	ForceLoadFlag;		/* debug.c forced load flag */	OBJ_INF	obj;	BzRead	bzr;	ID	did;	W	nent;	ER	err;	memset(inf, 0, (size_t)sizeof(LDINFO));	/* Open executable file */	err = OpenProgFile(pohdr, name, &obj, &bzr);	if ( err < E_OK ) {		goto err_ret1;	}	inf->pohdr = *pohdr;	/* Obtain disk ID */	did = ExecFileRecInfo(&inf->pohdr, NULL, NULL, NULL, 0, &nent);	if ( did < E_OK ) {		err = did;		goto err_ret2;	}	err = TSD_LPF_ERR_M1;	if ( (did > 0) && ((lsid > 0U) || isMemoryDisk(did)) &&	     (!isRemovableDisk(did)) && (bzr.recBuf == NULL) &&	     (ForceLoadFlag == 0) ) {		/* On-demand loading */		err = demand_load(inf, lsid, mode, &obj, nent, entry, &bzr);		/* (err < E_OK) If files cannot be loaded on demand, load them all at once. */	}	if ( err < E_OK ) {		/* Global loading */		err = direct_load(inf, lsid, (UB)mode, &obj, entry, &bzr);		if ( err < E_OK ) {			goto err_ret2;		}	}	/* Release memory for decompression */	if ( bzr.recBuf != NULL ) {		Vfree(bzr.recBuf);	}	/* If files are not loaded on demand, close executable files. */	if ( inf->dpage == 0U ) {		ExecFileClose(&inf->pohdr);		memset(&inf->pohdr, 0, sizeof(POBJ_HDR));	}	return E_OK;err_ret2:	if ( bzr.recBuf != NULL ) {		Vfree(bzr.recBuf);	}

⌨️ 快捷键说明

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