📄 load.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 + -