📄 procmap.c
字号:
ExecFileClose(&inf->pohdr);err_ret1: DEBUG_PRINT(("loadprogfile err = %d\n", err)); return err;}/* * Program unloading * Used in dynamic loading and system program loading */LOCAL ER unloadprogfile( LDINFO *inf, UW lsid ){ W i; ER err, error = E_OK; for ( i = 0; i < N_LDMID; ++i ) { if ( inf->mid[i] == 0 ) { continue; } /* Reset disk map */ err = UnmapDisk(inf->mid[i], MD_RDONLY); if ( err < E_OK ) { error = err; } } /* Reset memory map */ err = UnmakeSpace((VB*)inf->topadr + (inf->dpage * (UW)PAGESIZE), (W)inf->mpage, (W)lsid); if ( err < E_OK ) { error = ERtoERR(err); } if ( inf->pohdr.desc > 0 ) { /* Close executable file */ err = ExecFileClose(&inf->pohdr); if ( err < E_OK ) { error = err; } } /* If program is loaded into local space (lsid > 0) * or system memory space, release memory space * reserved at loading. */ if (( lsid > 0U ) ||( ((UW)inf->topadr >= SYSSPACE_TOP ) &&( (UW)inf->topadr < SYSSPACE_END) )) { /* Release memory space */ err = FreeMemorySpace(inf->topadr, lsid); if ( err < E_OK ) { error = ERtoERR(err); } }#ifdef DEBUG if ( error < E_OK ) { DEBUG_PRINT(("unloadprogfile err = %d\n", error)); }#endif return error;}/* ------------------------------------------------------------------------ *//* * Dynamic loading *//* * Obtain dynamic loading management information */LOCAL DYNLD* newDynld( PRCMINFO *pmi ){ DYNLD *dynld; dynld = Vmalloc(sizeof(DYNLD)); if ( dynld == NULL ) { return NULL; } /* Register in management queue */ QueInsert((QUEUE*)dynld, &pmi->dynldq); return dynld;}/* * Release dynamic loading management information */LOCAL void freeDynld( DYNLD *dynld ){ /* Delete from management queue */ QueRemove((QUEUE*)dynld); Vfree(dynld);}/* * Search for dynamic loading management information */LOCAL DYNLD* searchDynld( W loadid, PRCMINFO *pmi ){ QUEUE *q; for ( q = pmi->dynldq.next; q != &pmi->dynldq; q = q->next ) { if ( DynLoadID(q) == (UW)loadid ) { return (DYNLD*)q; } } return NULL;}/* * Load shared object */EXPORT WER LoadModule( POBJ_HDR *pohdr, P_DYNLDINF *info, PINFO *pinfo ){ UW lsid = GetLSID_pinfo(pinfo); PRCMINFO *pmi = (PRCMINFO*)GetMinfo(TSK_SELF, PM_SVC); DYNLD *dynld; LDINFO ldinfo; FP entry; UW mode; ER err; Lock(&ProcMgrLock); /* Obtain management information */ dynld = newDynld(pmi); if ( dynld == NULL ) { err = E_SYSMEM; goto err_ret1; } /* Loading */ mode = ( pinfo->sysproc != 0 )? (UW)(LDMD_SYS|LDMD_DYN): (UW)(LDMD_USR|LDMD_DYN); err = loadprogfile(pohdr, lsid, mode, &ldinfo, dynld->name, &entry); if ( err < E_OK ) { goto err_ret2; } /* Save loading information */ dynld->fd = ldinfo.pohdr.desc; dynld->fdtype = ldinfo.pohdr.type; dynld->mid[TSD_WLM_POS_0] = ldinfo.mid[TSD_WLM_POS_0]; dynld->mid[TSD_WLM_POS_1] = ldinfo.mid[TSD_WLM_POS_1]; dynld->topadr = ldinfo.topadr; dynld->dpage = ldinfo.dpage; dynld->mpage = ldinfo.mpage; /* Loading information to be returned to application */ info->loadaddr = dynld->topadr; info->loadsize = (ldinfo.dpage + ldinfo.mpage) * (UW)PAGESIZE; info->entry = entry; info->info[TSD_WLM_POS_0] = 0; info->info[TSD_WLM_POS_1] = 0; info->info[TSD_WLM_POS_2] = 0; Unlock(&ProcMgrLock); return (WER)DynLoadID(dynld);err_ret2: freeDynld(dynld);err_ret1: Unlock(&ProcMgrLock); DEBUG_PRINT(("LoadModule err = %d\n", err)); return err;}/* * Unload shared object */EXPORT ER UnloadModule( W loadid, PINFO *pinfo ){ UW lsid = GetLSID_pinfo(pinfo); PRCMINFO *pmi = (PRCMINFO*)GetMinfo(TSK_SELF, PM_SVC); DYNLD *dynld; LDINFO ldinfo; ER err, error = E_OK; Lock(&ProcMgrLock); /* Search for management information */ dynld = searchDynld(loadid, pmi); if ( dynld == NULL ) { error = E_PAR; goto err_ret; } ldinfo.pohdr.desc = dynld->fd; ldinfo.pohdr.type = dynld->fdtype; ldinfo.mid[0] = dynld->mid[0]; ldinfo.mid[1] = dynld->mid[1]; ldinfo.topadr = dynld->topadr; ldinfo.dpage = dynld->dpage; ldinfo.mpage = dynld->mpage; /* Unloading */ err = unloadprogfile(&ldinfo, lsid); if ( err < E_OK ) { error = err; } /* Release management information */ freeDynld(dynld);err_ret: Unlock(&ProcMgrLock);#ifdef DEBUG if ( error < E_OK ) { DEBUG_PRINT(("UnloadModule err = %d\n", error)); }#endif return error;}/* * Process termination processing: unload all shared objects. */EXPORT void UnloadAllModule( PRCMINFO *pmi, W pid ){ DYNLD *dynld; LDINFO ldinfo; PINFO *pinfo; UW lsid; if ( isQueEmpty(&pmi->dynldq) != 0 ) { return; } if ( PidToPinfo(pid, &pinfo) < E_OK ) { return; } lsid = GetLSID_pinfo(pinfo); UnlockPinfo(); while ( (dynld = (DYNLD*)QueRemoveNext(&pmi->dynldq)) != NULL ) { /* Already closed through file management. */ ldinfo.pohdr.desc = 0; ldinfo.pohdr.type = 0; ldinfo.mid[0] = dynld->mid[0]; ldinfo.mid[1] = dynld->mid[1]; ldinfo.topadr = dynld->topadr; ldinfo.dpage = dynld->dpage; ldinfo.mpage = dynld->mpage; /* Unloading */ unloadprogfile(&ldinfo, lsid); Vfree(dynld); }}/* ------------------------------------------------------------------------ *//* * Load system program */LOCAL SysProgInfo *SysProgInfoTbl;LOCAL W MaxSysProgID;#define toSysProgID(inf) ( (inf) - (SysProgInfoTbl) + 1 )#define toSysProgInfo(progid) ( &SysProgInfoTbl[(progid) - 1] )/* * Search for free program ID */LOCAL SysProgInfo* searchProgID( void ){ SysProgInfo *inf; W i; for ( i = 0; i < MaxSysProgID; ++i ) { inf = SysProgInfoTbl + i; if ( inf->loadadr == NULL ) { return inf; } } return NULL;}/* * Check if there are system programs loaded by disk map. * Return value 0 : Not mapped to did disk. * 1 : Mapped to did disk. * * (*) Call system programs in LockSEG state. */EXPORT W ChkSysProgMap( ID did ){ SysProgInfo *inf; ID mid, d; W i, j; for ( i = 0; i < MaxSysProgID; ++i ) { inf = SysProgInfoTbl + i; if ( inf->loadadr == NULL ) { continue; } for ( j = 0; j < N_LDMID; ++j ) { mid = inf->mid[j]; if ( mid == 0 ) { continue; } d = GetMapDid(mid); if ( d == did ) { return 1; } } } return 0;}/* * Start system program */LOCAL ER SysProgStartup( TC *name, TC *arg, FP entry ){ W ac; UB **av; UB *buf, *p; W n, m; ER err; /* Convert argument from TC to EUC. */ n = tcstoeucs(NULL, name); if ( n < 0 ) { err = E_PAR; goto err_ret1; } m = tcstoeucs(NULL, arg); if ( m < 0 ) { err = E_PAR; goto err_ret1; } buf = Vmalloc((size_t)(n + m + TSD_SPS_VAL_2)); if ( buf == NULL ) { err = E_NOMEM; goto err_ret1; } tcstoeucs(buf, name); buf[n] = ' '; tcstoeucs(buf + n + 1, arg); /* Delimit argument with space. */ p = buf; while ( (*p != '\0') && (*p <= ' ') ) { p++; /* Skip preceding space. */ } for ( ac = 0; *p != '\0'; ac++ ) { while ( (*p != '\0') && (*p > ' ') ) { p++; } while ( (*p != '\0') && (*p <= ' ') ) { p++; } } av = Vmalloc((size_t)((ac + 1) * (W)sizeof(UB*))); if ( av == NULL ) { err = E_NOMEM; goto err_ret2; } p = buf; for ( n = 0; n < ac; n++ ) { while ( (*p != '\0') && (*p <= ' ') ) { p++; } av[n] = p; while ( (*p != '\0') && (*p > ' ') ) { p++; } *p++ = '\0'; } av[n] = NULL; /* Call system program */ err = CallSysProgInit(ac, av, entry); if ( err < E_OK ) { goto err_ret3; } Vfree(av); Vfree(buf); return err;err_ret3: Vfree(av);err_ret2: Vfree(buf);err_ret1: DEBUG_PRINT(("SysProgStartup err = %d\n", err)); return err;}/* * Load system program * Load lnk program and start it as in sysproc(ac, av). * Return the following information as loadadr: * loadadr[0] = Loaded start address * loadadr[1] = Loaded end address * Return program ID as a return value. */EXPORT WER LoadSysProg( POBJ_HDR *pohdr, TC *arg, VP loadadr[TSD_LSP_POS_2] ){ SysProgInfo *inf; LDINFO ldinfo; FP entry; W sz; ER err; Lock(&ProcMgrLock); /* Obtain program ID */ inf = searchProgID(); if ( inf == NULL ) { err = E_LIMIT; goto err_ret1; } /* Loading */ err = loadprogfile(pohdr, 0, LDMD_SYS, &ldinfo, inf->name, &entry); if ( err < E_OK ) { goto err_ret1; } /* Save loading information */ inf->fd = ldinfo.pohdr.desc; inf->fdtype = ldinfo.pohdr.type; inf->mid[0] = ldinfo.mid[0]; inf->mid[1] = ldinfo.mid[1]; inf->loadadr = ldinfo.topadr; inf->dpage = (UH)ldinfo.dpage; inf->mpage = (UH)ldinfo.mpage; inf->entry = NULL; Unlock(&ProcMgrLock); sz = (inf->dpage + inf->mpage) * PAGESIZE; /* Load size */ /* Resident */ err = LockSpace(inf->loadadr, sz); if ( err < E_OK ) { err = ERtoERR(err); goto err_ret2; } /* Run system program */ err = SysProgStartup(inf->name, arg, entry); if ( err < E_OK ) { goto err_ret2; } inf->entry = entry; loadadr[0] = inf->loadadr; loadadr[1] = (VB*)inf->loadadr + sz; return toSysProgID(inf);err_ret2: /* Unloading */ UnloadSysProg(toSysProgID(inf)); goto err_ret0;err_ret1: Unlock(&ProcMgrLock);err_ret0: DEBUG_PRINT(("LoadSysProg err = %d\n", err)); return err;}/* * Unload system program * Run progid program as in sysprog(-1, NULL), * and then unload it. */EXPORT ER UnloadSysProg( W progid ){ SysProgInfo *inf; LDINFO ldinfo; ER err, error = E_OK; /* ID check */ if (( progid < 1 )||( progid > MaxSysProgID )) { error = E_ID; goto err_ret; } inf = toSysProgInfo(progid); if ( inf->loadadr == NULL ) { error = E_ID; goto err_ret; } if ( inf->entry != NULL ) { /* Terminate system program */ err = CallSysProgInit(TSD_CSP_VAL_M1, NULL, inf->entry); if ( err < E_OK ) { error = err; goto err_ret; } } ldinfo.pohdr.desc = inf->fd; ldinfo.pohdr.type = inf->fdtype; ldinfo.mid[0] = inf->mid[0]; ldinfo.mid[1] = inf->mid[1]; ldinfo.topadr = inf->loadadr; ldinfo.dpage = inf->dpage; ldinfo.mpage = inf->mpage; /* Unloading */ err = unloadprogfile(&ldinfo, 0); if ( err < E_OK ) { error = err; } Lock(&ProcMgrLock); inf->loadadr = NULL; Unlock(&ProcMgrLock);err_ret:#ifdef DEBUG if ( error < E_OK ) { DEBUG_PRINT(("UnloadSysProg err = %d\n", error)); }#endif return error;}/* * Terminate all system programs * Called at system termination only. */EXPORT ER FinishAllSysProgs( void ){ SysProgInfo *inf; W i; ER err, error = E_OK; /* Call termination processing in inverse order of registration. */ for ( i = MaxSysProgID - 1; i >= 0; --i ) { inf = SysProgInfoTbl + i; if (( inf->loadadr == NULL )||( inf->entry == NULL )) { continue; } /* Call termination processing, but do not release memory for safety reasons. */ err = CallSysProgInit(TSD_CSP_VAL_M1, NULL, inf->entry); if ( err < E_OK ) { error = err; } else { inf->entry = NULL; } }#ifdef DEBUG if ( error < E_OK ) { DEBUG_PRINT(("FinishAllSysProgs err = %d\n", error)); }#endif return error;}/* ------------------------------------------------------------------------- *//* * Initialize process map/system program loading */EXPORT ER InitProcMap( void ){ ER err; /* Default user stack size */ err = GetSysConf_log((UB*)"UsrStkSz", &DefaultStackSize, 1); if ( err < E_OK ) { goto err_ret; } /* Maximum number of registered system programs */ err = GetSysConf_log((UB*)"MaxSysPrg", &MaxSysProgID, 1); if ( err < E_OK ) { goto err_ret; } /* Generate system program management table */ SysProgInfoTbl = Icalloc((UW)MaxSysProgID, sizeof(SysProgInfo)); if ( SysProgInfoTbl == NULL ) { err = E_NOMEM; goto err_ret; } return E_OK;err_ret: DEBUG_PRINT(("InitProcMap err = %d\n", err)); return err;}/* ======================================================================== *//* * Debug support function */#if DEBUGFUNC_SUPPORT#define M(v, c) ( (v)? (c): '-' )/* * Indicate system program information */EXPORT void DumpSysProg( void ){ W i; printf("SYSTEM PROGRAM:\n"); DumpMore(0); for ( i = 0; i < MaxSysProgID; ++i ) { if ( SysProgInfoTbl[i].loadadr == NULL ) { continue; } printf(" [%2d] %c 0x%08x - %2d %.20S\n", i + 1, M(SysProgInfoTbl[i].dpage > 0, 'R'), SysProgInfoTbl[i].loadadr, SysProgInfoTbl[i].dpage + SysProgInfoTbl[i].mpage, SysProgInfoTbl[i].name ); if ( DumpMore(1) ) { break; } }}/* * Indicate dynamic loading information */EXPORT void DumpDynLoad( W pid ){ PRCMINFO *pmi; QUEUE *q; DYNLD *dynld; if ( PidToMinfo(pid, PM_SVC, (VP*)&pmi) < E_OK ) { return; } printf("DYNAMIC LOAD: PID=%d\n", pid); DumpMore(0); for ( q = pmi->dynldq.next; q != &pmi->dynldq; q = q->next ) { dynld = (DYNLD*)q; printf(" 0x%08x - %3d+%-2d %.20S\n", dynld->topadr, dynld->dpage, dynld->mpage, dynld->name ); if ( DumpMore(1) ) { break; } }}#endif /* DEBUGFUNC_SUPPORT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -