📄 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 (libdl) * * DLL support library * Loading relation */#include "libdl.h"Inline W KnlLogMsk( void );LOCAL void delscope( DLScope *scope, DLInfo *dlp );LOCAL ER unloadSobj( DLInfo *loader );LOCAL ER loadSobj( DLInfo **dlpp, SOBJ_HDR *soHdr, W flag );#define TSD_KLM_DEF_M1 (-1)#define TSD_KLM_VAL_M1 (-1)LOCAL W __KnlLogMsk = TSD_KLM_DEF_M1;/* * Kernel logmask acquisition */Inline W KnlLogMsk( void ){ if ( __KnlLogMsk < 0 ) { __KnlLogMsk = KnlDebugFunc(KD_LogMask, TSD_KLM_VAL_M1, 0, 0); } return __KnlLogMsk;}/* ------------------------------------------------------------------------ *//* * Acquire the shared object from the handle */EXPORT DLInfo* __getdlinfo( W handle ){ QUEUE *q; q = &__dlInfo.q; do { if ( DLInfoID(q) == (UW)handle ) { return (DLInfo*)q; } } while ( (q = q->next) != &__dlInfo.q ); return NULL;}/* * Deletion of entry from symbol scope list * No narrowing of "ent" scope is done */LOCAL void delscope( DLScope *scope, DLInfo *dlp ){ W i; for ( i = 0; i < scope->nent; ++i ) { if ( scope->ent[i] != dlp ) { continue; } /* Move the entry up front */ while ( ++i < scope->nent ) { scope->ent[i - 1] = scope->ent[i]; } scope->nent--; }}/* * Unload of the shared object */LOCAL ER unloadSobj( DLInfo *loader ){ DLInfo *dlp; W i; ER err, error = E_OK; /* Execution of stop sequence routine */ __so_callfini(loader); for ( i = 0; i < loader->search.nent; ++i ) { dlp = loader->search.ent[i]; if ( --dlp->count > 0 ) { continue; } if ( dlp->global != 0U ) { /* Delete from the global scope */ delscope(&__dlInfo.search, dlp); } /* Unload */ err = tkse_unl_mod(dlp->ldid); if ( err < E_OK ) { error = err; } /* Delete the management information (Put off the loader) */ if ( dlp != loader ) { __freeDLInfo(dlp); } } /* Delete the loader management information */ if ( loader->count == 0 ) { __freeDLInfo(loader); } if ( error < E_OK ) { DEBUG_PRINT(("unloadSobj err = %d\n", error)); } return error;}/* * Loading of the shared object */LOCAL ER loadSobj( DLInfo **dlpp, SOBJ_HDR *soHdr, W flag ){ DLInfo *loader; ER err; /* Load the shared object */ err = __so_loading(dlpp, soHdr, NULL); if ( err < E_OK ) { goto err_ret1; } loader = *dlpp; loader->count++; /* Load the dependency-shared object */ err = __so_depsloading(loader, (UW)flag & (UW)DL_GLOBAL); if ( err < E_OK ) { goto err_ret2; } /* Link of relocation/symbol */ err = __so_relocate(loader, (UW)(((UW)flag & (UW)DL_BINDING_MASK) == (UW)DL_LAZY)); if ( err < E_OK ) { goto err_ret2; } /* Execution of initialization routine */ __so_callinit(loader); return E_OK;err_ret2: unloadSobj(loader);err_ret1: DEBUG_PRINT(("loadSobj err = %d\n", err)); return err;}/* ------------------------------------------------------------------------ *//* * Load of the shared object * Execute a loading of the shared object specified at "Ink" to the invoking process local space. * Return the access handle (>0) for shared object to the return value. * When lnk = NULL, Return the access handle for main program instead of loading. * * flag = ( DL_LAZY || DL_NOW ) | [DL_GLOBAL] * * DL_LAZY Resolve the unspecified symbol sequentially at runtime. * The operation is not assured in case the the unspecified symbol * is not resolved. * (Usually,process falls in case of execption) * DL_NOW Resolve all the unspecified symbols at the time of loading. * When unspecified symbol is not resolved, tkse_dlopen() returns the error, * and loading is not done. * DL_GLOBAL set up so that the external symbol of loaded object is referable * from the other shared object * * When loading of what is as same as the already loaded shared object is done, * another loading is not made and same handle is returned. */EXPORT WER tkse_dlopen( T_DLOPEN *info ){ DLInfo *dlp; W mode; ER err; SOBJ_HDR soHdr; W flag; /* Parameter check */ flag = info->mode; mode = flag & DL_BINDING_MASK; if ( !((mode == DL_LAZY )||( mode == DL_NOW)) ) { err = E_PAR; goto err_ret1; } err = LockDL(); if ( err < E_OK ) { goto err_ret1; } if ( info->path == NULL ) { /* Main program */ dlp = &__dlInfo; } else { soHdr.type = (W)info->atr; soHdr.src.path = (B *)info->path; /* Load */ err = loadSobj(&dlp, &soHdr, flag); if ( err < E_OK ) { goto err_ret2; } dlp->dllcount++; /* DLL load count */ } UnlockDL(); return (WER)DLInfoID(dlp);err_ret2: UnlockDL();err_ret1: DEBUG_PRINT(("tkse_dlopen err = %d\n", err)); return err;}/* * Unload of the shared object * Unload the shared object specified at the handle. * Unload is done only after tkse_dlopen() is done with the same number of times * when tkse_dlopen() is done more than once. */EXPORT ER tkse_dlclose( W handle ){ DLInfo *dlp; ER err, error = E_OK; err = LockDL(); if ( err < E_OK ) { error = err; goto err_ret1; } /* Search the shared object */ dlp = __getdlinfo(handle); if (( dlp == NULL )||( dlp->dllcount <= 0 )) { error = E_ID; goto err_ret2; } if ( --dlp->dllcount == 0 ) { /* Unload */ err = unloadSobj(dlp); if ( err < E_OK ) { error = err; } }err_ret2: UnlockDL();err_ret1: if ( error < E_OK ) { DEBUG_PRINT(("tkse_dlclose err = %d\n", error)); } return error;}/* * Load of the shared object (POSIX I/F) */EXPORT void *dlopen(const char *filename, int flag){ DLInfo *dlp; W mode; ER err; SOBJ_HDR soHdr; W *handle; /* Parameter check */ mode = flag & DL_BINDING_MASK; if ( !((mode == DL_LAZY )||( mode == DL_NOW)) ) { err = E_PAR; goto err_ret1; } err = LockDL(); if ( err < E_OK ) { goto err_ret1; } if ( filename == NULL ) { /* Main program */ dlp = &__dlInfo; } else { soHdr.type = TMA_SEIO; soHdr.src.path = (B *)filename; /* Load */ err = loadSobj(&dlp, &soHdr, flag); if ( err < E_OK ) { goto err_ret2; } dlp->dllcount++; /* DLL load count */ } dlp->dllhandle = (VP)DLInfoID(dlp); UnlockDL(); return &(dlp->dllhandle);err_ret2: UnlockDL();err_ret1: DEBUG_PRINT(("tkse_dlopen err = %d\n", err)); return (void *)NULL;}/* * Unload of the shared object (POSIX I/F) */EXPORT int dlclose( void *handle ){ DLInfo *dlp; ER err, error = E_OK; W no; no = *((W *)handle); err = LockDL(); if ( err < E_OK ) { error = err; goto err_ret1; } /* Search the shared object */ dlp = __getdlinfo(no); if (( dlp == NULL )||( dlp->dllcount <= 0 )) { error = E_ID; goto err_ret2; } if ( --dlp->dllcount == 0 ) { dlp->dllhandle = NULL; /* Unload */ err = unloadSobj(dlp); if ( err < E_OK ) { error = err; } }err_ret2: UnlockDL();err_ret1: if ( error >= E_OK ) { error = E_OK; } else { DEBUG_PRINT(("tkse_dlclose err = %d\n", error)); } return error;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -