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

📄 load.c

📁 T-kernel 的extension源代码
💻 C
字号:
/* *---------------------------------------------------------------------- *    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. * *---------------------------------------------------------------------- *//* *	@(#)load.c (solib)  * *	Shared object(SO)support library *	Loading relation */#include <string.h>#include "so.h"LOCAL ER addscope( DLScope *scope, DLInfo *dlp );LOCAL ER searchSobj( SOBJ_HDR *soHdr, UB *name );LOCAL ER findSobj( SOBJ_HDR *soHdr, UB *name );LOCAL ER checkelfheader( DLInfo *dlp );#define TSD_ASP_VAL_8	8#define TSD_SSB_VAL_2	2/* * Addition of entry to symbol scope list */LOCAL ER addscope( DLScope *scope, DLInfo *dlp ){const	W	BLKSZ = TSD_ASP_VAL_8;	UW	n;	DLInfo	**p;	ER	err;	n = (UW)scope->nent;	if ( (n % (UW)BLKSZ) == 0 ) {		/* add entry */		p = realloc(scope->ent, (n + (UW)BLKSZ) * sizeof(DLInfo*));		if ( p == NULL ) {			err = E_NOMEM;			goto err_ret;		}		scope->ent = p;	}	scope->ent[n++] = dlp;	scope->nent = (W)n;	return E_OK;err_ret:	DEBUG_PRINT(("addscope err = %d\n", err));	return err;}/* * Search of the shared object *	Search the shared object of "name" and return it to "Ink". *	"name" is premised on ASCII only. */LOCAL ER searchSobj( SOBJ_HDR *soHdr, UB *name ){	W		c;	ER		err;	struct stat	sb;	for ( c = 0; c < TSD_SSB_VAL_2; ++c ) {		switch ( c ) {		  case 0:			/* Search from the invoking program file  */			strcpy(soHdr->src.path, __so_myfile.src.path);			strcat(soHdr->src.path, (char*)name);			break;		  case 1:			/* Search from the standard library file */			strcpy(soHdr->src.path, __so_stdlib.src.path);			strcat(soHdr->src.path, (char*)name);			break;		  default:			strcpy(soHdr->src.path, "./");			strcat(soHdr->src.path, (char*)name);			break;		}		err = tkse_stat(soHdr->src.path, &sb);		if ( err >= 0 ) {			break;		}	}	if ( err < E_OK ) {		goto err_ret;	}	return E_OK;err_ret:	SYSLOG((LOG_ERR, "solib: %s is not found", name));	DEBUG_PRINT(("searchSobj err = %d\n", err));	return err;}/* * Search of the shared object(Including cache reference) *	search the shared object of "name" and return it to"Ink". *	Cache the object that is once searched, and search fastly  *	at second time or later. */LOCAL ER findSobj( SOBJ_HDR *soHdr, UB *name ){	QUEUE		*q;	SobjInfo	*sop;	ER		err;	for ( q = __so_sobjInfo.next; q != &__so_sobjInfo; q = q->next ) {		sop = (SobjInfo *)q;		if (strcmp((char*)sop->name, (char*)name) == 0) {			/* cache found */			*soHdr = sop->soHdr;			return E_OK;		}	}	/* not cached */	err = searchSobj(soHdr, name);	if ( err < E_OK ) {		goto err_ret;	}	/* add cache */	sop = malloc((size_t)(sizeof(SobjInfo) + strlen((char*)name) + 1U));	if ( sop != NULL ) {		sop->name = (UB *)sop + sizeof(SobjInfo);		strcpy((char*)sop->name, (char*)name);		sop->soHdr = *soHdr;		QueInsert(&sop->q, &__so_sobjInfo);	}	return err;err_ret:	DEBUG_PRINT(("findSobj err = %d\n", err));	return err;}/* ------------------------------------------------------------------------ *//* * Confirmation and information acquisition of ELF header */LOCAL ER checkelfheader( DLInfo *dlp ){	Elf32_Ehdr	*ehdr;	Elf32_Phdr	*phdr;	W		i;	/* ELF header confirmation */	ehdr = dlp->ldinf.loadaddr;	if (( ehdr->e_ident[EI_MAG0] != ELFMAG0 )	  ||( ehdr->e_ident[EI_MAG1] != ELFMAG1 )	  ||( ehdr->e_ident[EI_MAG2] != ELFMAG2 )	  ||( ehdr->e_ident[EI_MAG3] != ELFMAG3 )	  ||( (ehdr->e_type != ET_DYN )&&( ehdr->e_type != ET_EXEC))	  ||( ehdr->e_phoff == 0U )||( ehdr->e_phnum == 0 )) {		goto err_ret;	}	/* Difference between the address at the time of linking and the one practically loaded */	dlp->ldofs = (B*)dlp->ldinf.entry - (B*)ehdr->e_entry;	/* Readout of the program header */	phdr = (Elf32_Phdr*)((B*)ehdr + ehdr->e_phoff);	for ( i = 0; i < ehdr->e_phnum; ++i ) {		switch ( phdr[i].p_type ) {		  case PT_DYNAMIC:			dlp->dyn = LDADR(dlp, phdr[i].p_vaddr);			break;		  default:			/* nothing to do */			break;		}	}	if ( dlp->dyn == NULL ) {		goto err_ret;	}	return E_OK;err_ret:	DEBUG_PRINT(("checkelfheader err = %d\n", E_REC));	return E_REC;}/* * Load the shared object */EXPORT ER __so_loading( DLInfo **dlpp, SOBJ_HDR *soHdr, DLInfo *loader ){	DLInfo	*dlp;	ER	err;	T_LMOD	pk_mod;	/* Search if the same one is already loaded or not */	dlp = __searchDLInfo(soHdr);	if ( dlp != NULL ) {		*dlpp = dlp;		return E_OK;	}	/* New load */	dlp = __newDLInfo(soHdr, loader);	if ( dlp == NULL ) {		err = E_NOMEM;		goto err_ret1;	}	/* Load of the shared object */	pk_mod.modatr = TMA_SEIO;	pk_mod.modhdr = dlp->soHdr.src.path;		dlp->ldid = err = tkse_lod_mod(&pk_mod, &dlp->ldinf);	if ( err < E_OK ) {		goto err_ret2;	}	/* ELF header confirmation */	err = checkelfheader(dlp);	if ( err < E_OK ) {		goto err_ret3;	}	/* Readout of dynamic session */	err = __so_getdynamicinfo(dlp);	if ( err < E_OK ) {		goto err_ret3;	}	*dlpp = dlp;	return E_OK;err_ret3:	(void)tkse_unl_mod(dlp->ldid);err_ret2:	__freeDLInfo(dlp);err_ret1:	DEBUG_PRINT(("__so_loading err = %d\n", err));	return err;}/* * Load the dependency-shared object */EXPORT ER __so_depsloading( DLInfo *loader, UW global ){	DLInfo		*dep, *p;	Elf32_Dyn	*dyn;	UB		*name;	SOBJ_HDR	soHdr;	W		i;	ER		err;	/* Set the main in symbol search list */	err = addscope(&loader->search, loader);	if ( err < E_OK ) {		goto err_ret;	}	loader->nowloading = TRUE;	for ( i = 0; i < loader->search.nent; i++ ) {		p = loader->search.ent[i];		/* Search the dependency object from dynamic session */		for ( dyn = p->dyn; dyn->d_tag != DT_NULL; dyn++ ) {			if ( dyn->d_tag != DT_NEEDED ) {				continue;			}			/* Dependency object name */			name = p->strtab + dyn->d_un.d_val;			/* Search the dependency object */			soHdr.src.path = malloc(PATH_LENGTH_MAX);			if (soHdr.src.path == NULL) {				goto err_ret;			}			err = findSobj(&soHdr, name);			if ( err < E_OK ) {				goto err_ret;			}			/* Loading */			err = __so_loading(&dep, &soHdr, loader);			if ( err < E_OK ) {				goto err_ret;			}			/* Skip the duplicate loading */			if ( !dep->nowloading ) {				/* Add to symbol search list */				err = addscope(&loader->search, dep);				if ( err < E_OK ) {					goto err_ret;				}				dep->nowloading = TRUE;				dep->count++;				SYSLOG((LOG_DEBUG,					"solib: %-16s loaded at 0x%08x",					name, dep->ldinf.loadaddr));			}		}	}	for ( i = 0; i < loader->search.nent; i++ ) {		p = loader->search.ent[i];		/* Clear the flag during the loading */		p->nowloading = FALSE;		if ( global && !p->global ) {			if ( loader != &__dlInfo ) {				/* Register to global scope */				err = addscope(&__dlInfo.search, p);				if ( err < E_OK ) {					goto err_ret;				}			}			p->global = TRUE;		}	}	return E_OK;err_ret:	for ( i = 0; i < loader->search.nent; i++ ) {		loader->search.ent[i]->nowloading = FALSE;	}	DEBUG_PRINT(("__so_depsloading err = %d\n", err));	return err;}/* ------------------------------------------------------------------------ *//* * Execution of the shared object initialization routine */EXPORT void __so_callinit( DLInfo *loader ){	DLInfo	*dlp, **list;	W	i;	DM("__so_callinit\n");	list = loader->search.ent;	for ( i = loader->search.nent - 1; i >= 0; --i ) {		dlp = list[i];		if ( !dlp->initcalled ) {			if ( dlp->init != NULL ) {				(*dlp->init)();			}			dlp->initcalled = TRUE;		}	}}/* * Execution of the shared object stop sequence  */EXPORT void __so_callfini( DLInfo *loader ){	DLInfo	*dlp, **list;	W	i;	DM("__so_callfini\n");	list = loader->search.ent;	for ( i = 0; i < loader->search.nent; ++i ) {		dlp = list[i];		if (( dlp->count == 1) && dlp->initcalled ) {			if ( dlp->fini != NULL ) {				(*dlp->fini)();			}			dlp->initcalled = FALSE;		}	}}

⌨️ 快捷键说明

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