gonzui


Format: Advanced Search

t2ex/t2ex_source/t2ex/load/src/progload.cbare sourcepermlink (0.04 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    T2EX Software Package
    4:  *
    5:  *    Copyright 2012 by Ken Sakamura.
    6:  *    This software is distributed under the latest version of T-License 2.x.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by T-Engine Forum(http://www.t-engine.org/) at 2012/12/12.
   10:  *    Modified by T-Engine Forum at 2013/03/08.
   11:  *    Modified by TRON Forum(http://www.tron.org/) at 2015/06/04.
   12:  *
   13:  *----------------------------------------------------------------------
   14:  */
   15: /*
   16:  * This software package is available for use, modification, 
   17:  * and redistribution in accordance with the terms of the attached 
   18:  * T-License 2.x.
   19:  * If you want to redistribute the source code, you need to attach 
   20:  * the T-License 2.x document.
   21:  * There's no obligation to publish the content, and no obligation 
   22:  * to disclose it to the TRON Forum if you have modified the 
   23:  * software package.
   24:  * You can also distribute the modified source code. In this case, 
   25:  * please register the modification to T-Kernel traceability service.
   26:  * People can know the history of modifications by the service, 
   27:  * and can be sure that the version you have inherited some 
   28:  * modification of a particular version or not.
   29:  *
   30:  *    http://trace.tron.org/tk/?lang=en
   31:  *    http://trace.tron.org/tk/?lang=ja
   32:  *
   33:  * As per the provisions of the T-License 2.x, TRON Forum ensures that 
   34:  * the portion of the software that is copyrighted by Ken Sakamura or 
   35:  * the TRON Forum does not infringe the copyrights of a third party.
   36:  * However, it does not make any warranty other than this.
   37:  * DISCLAIMER: TRON Forum and Ken Sakamura shall not be held
   38:  * responsible for any consequences or damages caused directly or
   39:  * indirectly by the use of this software package.
   40:  *
   41:  * The source codes in bsd_source.tar.gz in this software package are 
   42:  * derived from NetBSD or OpenBSD and not covered under T-License 2.x.
   43:  * They need to be changed or redistributed according to the 
   44:  * representation of each source header.
   45:  */
   46: 
   47: /*
   48:  *      progload.c
   49:  *
   50:  *       T2EX: program load functions
   51:  *       program load operations
   52:  */
   53: 
   54: #include <basic.h>
   55: #include <errno.h>
   56: #include <sys/debug.h>
   57: #include <tk/tkernel.h>
   58: #include <t2ex/load.h>
   59: #include "service.h"
   60: #include "pminfo.h"
   61: #include "source.h"
   62: #include "elf.h"
   63: 
   64: IMPORT ER elf_load( ProgInfo *pg, LoadSource *ldr, UINT attr, Elf32_Ehdr *hdr );
   65: IMPORT ER pmCallStartup( INT ac, UB *av[], FP entry );
   66: 
   67: /*
   68:  * Open program load source
   69:  */
   70: LOCAL ER pmOpenSource( LoadSource* source, const struct pm* prog )
   71: {
   72:         switch (prog->pmtype) {
   73: #if USE_FILELOADER
   74:         case PM_FILE:
   75:                 return openFileSource(source, prog);
   76: #endif
   77: #if USE_MEMLOADER
   78:         case PM_PTR:
   79:                 return openMemSource(source, prog);
   80: #endif
   81:         default:
   82:                 return EX_INVAL;
   83:         }
   84: }
   85: 
   86: 
   87: /*
   88:  * Object file header
   89:  */
   90: typedef struct {
   91:         Elf32_Ehdr     elf;
   92: } ObjectHeader;
   93: 
   94: 
   95: /*
   96:  * Load program module
   97:  */
   98: LOCAL ID pmLoadProg( const struct pm* prog, UINT attr, FP* entry )
   99: {
  100:         LoadSource     source;
  101:         ProgInfo       *pginfo;
  102:         ObjectHeader   hdr;
  103:         ER             er;
  104: 
  105:         /* Allocate control block*/
  106:         pginfo = pmAllocInfo();
  107:         if ( pginfo == NULL ) { er = E_LIMIT; goto err_ret0; }
  108:         pginfo->attr = attr;
  109: 
  110:         /* Open program load source */
  111:         er = pmOpenSource(&source, prog);
  112:         if ( er < E_OK ) goto err_ret1;
  113: 
  114:         /* Read object header */
  115:         er = source.read(&source, 0, &hdr, sizeof(ObjectHeader));
  116:         if ( er < E_OK ) goto err_ret2;
  117:         if ( er < sizeof(ObjectHeader) ) { er = EX_NOEXEC; goto err_ret2; }
  118: 
  119:         /* Load object */
  120:         if ( hdr.elf.e_ident[EI_MAG0] == ELFMAG0
  121:              && hdr.elf.e_ident[EI_MAG1] == ELFMAG1
  122:              && hdr.elf.e_ident[EI_MAG2] == ELFMAG2
  123:              && hdr.elf.e_ident[EI_MAG3] == ELFMAG3 ) {
  124:                 /* ELF format */
  125:                 er = elf_load(pginfo, &source, attr, &(hdr.elf));
  126:         }
  127:         else {
  128:                 /* Unsupported format */
  129:                 er = EX_NOEXEC;
  130:                 goto err_ret2;
  131:         }
  132:         if ( er < E_OK ) goto err_ret2;
  133: 
  134:         source.close(&source);
  135: 
  136:         /* Return entry point and program ID */
  137:         *entry = pginfo->entry;
  138:         er = pginfo->pmid;
  139: 
  140:         return er;
  141: 
  142: err_ret2:
  143:         source.close(&source);
  144: err_ret1:
  145:         pmFreeInfo(pginfo);
  146: err_ret0:
  147:         TM_DEBUG_PRINT(("_pm_load ercd = %d\n", er));
  148:         return er;
  149: }
  150: 
  151: 
  152: /*
  153:  * Unload program
  154:  */
  155: Inline ER pmUnloadProg( ProgInfo* pginfo )
  156: {
  157:         ER     er;
  158: 
  159:         er = tk_rel_smb(pginfo->loadadr);
  160:         pmFreeInfo(pginfo);
  161: 
  162:         return er;
  163: }
  164: 
  165: 
  166: /*
  167:  * Load program module
  168:  */
  169: EXPORT ID _pm_load( const struct pm* prog, UINT attr, pm_entry_t** entry )
  170: {
  171:         ER     er;
  172:         ID     pmid;
  173:         FP     realEntry;
  174:         ProgInfo*      pginfo;
  175: 
  176:         /* Check parameters */
  177:         er = ChkSpaceR(prog, sizeof(*prog));
  178:         if ( er < E_OK ) goto err_ret0;
  179: 
  180:         if ( entry ) {
  181:                 er = ChkSpaceR(entry, sizeof(*entry));
  182:                 if ( er < E_OK ) goto err_ret0;
  183:         }
  184: 
  185:         LockPM();
  186: 
  187:         /* Load program module */
  188:         er = pmLoadProg(prog, attr, &realEntry);
  189:         if ( er < E_OK ) goto err_ret1;
  190:         pmid = er;
  191:         pginfo = pmGetInfo(pmid);
  192: 
  193:         /* Execute startup */
  194:         er = pmCallStartup(0, (UB**)&(pginfo->modentry), realEntry);
  195:         if ( er < E_OK ) goto err_ret2;
  196:         if ( !pginfo->modentry ) { er = EX_INVAL; goto err_ret2; }
  197: 
  198:         /* Return module entry point */
  199:         if ( entry ) {
  200:                 *entry = (pm_entry_t*)pginfo->modentry;
  201:         }
  202: 
  203:         UnlockPM();
  204: 
  205:         return pmid;
  206: 
  207: err_ret2:
  208:         pmUnloadProg(pginfo);
  209: err_ret1:
  210:         UnlockPM();
  211: err_ret0:
  212:         TM_DEBUG_PRINT(("_pm_load ercd = %d\n", er));
  213:         return er;
  214: }
  215: 
  216: 
  217: /*
  218:  * Load system program module
  219:  */
  220: EXPORT ID _pm_loadspg( const struct pm* prog, INT ac, UB* av[] )
  221: {
  222:         ER     er;
  223:         ID     pmid;
  224:         int    i;
  225:         FP     entry = NULL;
  226:         
  227:         /* Check parameters */
  228:         er = ChkSpaceR(prog, sizeof(*prog));
  229:         if ( er < E_OK ) goto err_ret0;
  230: 
  231:         if ( ac < 0 ) goto err_ret0;
  232: 
  233:         er = ChkSpaceR(av, ac * sizeof(UB*));
  234:         if ( er < E_OK ) goto err_ret0;
  235: 
  236:         for ( i = 0; i < ac; i++ ) {
  237:                 er = ChkSpaceR(av[i], 0);
  238:                 if ( er < E_OK ) goto err_ret0;
  239:         }
  240: 
  241:         LockPM();
  242: 
  243:         /* Load program module */
  244:         er = pmLoadProg(prog, TA_RNG0, &entry);
  245:         if ( er < E_OK ) goto err_ret1;
  246:         pmid = er;
  247: 
  248:         /* Execute startup */
  249:         er = pmCallStartup(ac, av, entry);
  250:         if ( er < E_OK ) goto err_ret2;
  251: 
  252:         UnlockPM();
  253: 
  254:         return pmid;
  255: 
  256: err_ret2:
  257:         pmUnloadProg(pmGetInfo(pmid));
  258: err_ret1:
  259:         UnlockPM();
  260: err_ret0:
  261:         TM_DEBUG_PRINT(("_pm_loadspg ercd = %d\n", er));
  262:         return er;
  263: }
  264: 
  265: 
  266: /*
  267:  * Unload program module
  268:  */
  269: EXPORT ER _pm_unload( ID progid )
  270: {
  271:         ProgInfo*      pginfo;
  272:         ER             er;
  273: 
  274:         LockPM();
  275: 
  276:         /* Get control block */
  277:         pginfo = pmGetInfo(progid);
  278:         if ( !pginfo || !pginfo->used ) {
  279:                 er = E_ID;
  280:                 goto err_ret;
  281:         }
  282: 
  283:         /* If system program, call cleanup */
  284:         er = pmCallStartup(-1, NULL, pginfo->entry);
  285: 
  286:         /* Unload program module */
  287:         pmUnloadProg(pginfo);
  288: 
  289:         UnlockPM();
  290: 
  291:         return er;
  292: 
  293: err_ret:
  294:         UnlockPM();
  295:         TM_DEBUG_PRINT(("_pm_unload ercd = %d\n", er));        
  296:         return er;
  297: }
  298: 
  299: 
  300: /*
  301:  * Get program module information
  302:  */
  303: EXPORT ER _pm_status( ID progid, struct pm_stat* status )
  304: {
  305:         ER             er;
  306:         ProgInfo*      pginfo;
  307: 
  308:         /* Check parameters */
  309:         er = ChkSpaceR(status, sizeof(*status));
  310:         if ( er < E_OK ) goto err_ret0;
  311: 
  312:         LockPM();
  313: 
  314:         /* Get program module information */
  315:         pginfo = pmGetInfo(progid);
  316:         if ( !pginfo || !pginfo->used ) {
  317:                 er = E_ID;
  318:                 goto err_ret1;
  319:         }
  320: 
  321:         /* Set information to status */
  322:         status->sysprg = ( pginfo->modentry )? FALSE: TRUE;
  323:         status->attr = pginfo->attr;
  324:         status->entry = ( pginfo->modentry )? pginfo->modentry: pginfo->entry;
  325:         status->start = pginfo->loadadr;
  326:         status->end = (void*)((B*)pginfo->loadadr + pginfo->loadsz);
  327: 
  328:         UnlockPM();
  329: 
  330:         return E_OK;
  331: 
  332: err_ret1:
  333:         UnlockPM();
  334: err_ret0:
  335:         TM_DEBUG_PRINT(("_pm_status ercd = %d\n", er));
  336:         return er;
  337: }