exec.c

Go to the documentation of this file.
00001 /*****************************************************************************************
00002  Copyright (c) 2002-2004 The UbixOS Project
00003  All rights reserved.
00004 
00005  Redistribution and use in source and binary forms, with or without modification, are
00006  permitted provided that the following conditions are met:
00007 
00008  Redistributions of source code must retain the above copyright notice, this list of
00009  conditions, the following disclaimer and the list of authors.  Redistributions in binary
00010  form must reproduce the above copyright notice, this list of conditions, the following
00011  disclaimer and the list of authors in the documentation and/or other materials provided
00012  with the distribution. Neither the name of the UbixOS Project nor the names of its
00013  contributors may be used to endorse or promote products derived from this software
00014  without specific prior written permission.
00015 
00016  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
00017  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00018  MERCHANTABILITY AND F
00019 ITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
00020  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00021  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00022  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00023  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
00024  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00025  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 
00027  $Id: exec_8c-source.html 88 2016-01-12 00:11:29Z reddawg $
00028 
00029 *****************************************************************************************/
00030 
00031 #include <ubixos/exec.h>
00032 #include <ubixos/elf.h>
00033 #include <ubixos/ld.h>
00034 #include <ubixos/kpanic.h>
00035 #include <ubixos/endtask.h>
00036 #include <vmm/vmm.h>
00037 #include <lib/kmalloc.h>
00038 #include <lib/kprintf.h>
00039 #include <lib/string.h>
00040 #include <assert.h>
00041 
00042 #define STACK_ADDR 0xC800000
00043 
00044 /*****************************************************************************************
00045 
00046  Function:   execThread(void (*)(void),int,char *);
00047  Description: This function will create a thread from code in the current memory space
00048 
00049  Notes:
00050  
00051  05/19/04 - This does not work the way I want it to it still makes a copy of kernel space
00052             so do not use out side of kernel space
00053 
00054 *****************************************************************************************/
00055 uInt32 execThread(void (* tproc)(void),uInt32 stack,char *arg) {
00056   kTask_t * newProcess = 0x0;
00057   /* Find A New Thread */
00058   newProcess = schedNewTask();
00059   assert(newProcess); 
00060   if (stack < 0x100000)
00061     kpanic("exec: stack not in valid area: [0x%X]\n",stack);
00062 
00063   /* Set All The Correct Thread Attributes */
00064   newProcess->tss.back_link    = 0x0;
00065   newProcess->tss.esp0         = 0x0;
00066   newProcess->tss.ss0          = 0x0;
00067   newProcess->tss.esp1         = 0x0;
00068   newProcess->tss.ss1          = 0x0;
00069   newProcess->tss.esp2         = 0x0;
00070   newProcess->tss.ss2          = 0x0;
00071   newProcess->tss.cr3          = (unsigned int)kernelPageDirectory;
00072   newProcess->tss.eip          = (unsigned int)tproc;
00073   newProcess->tss.eflags       = 0x206;
00074   newProcess->tss.esp          = stack;
00075   newProcess->tss.ebp          = stack;
00076   newProcess->tss.esi          = 0x0;
00077   newProcess->tss.edi          = 0x0;
00078 
00079   /* Set these up to be ring 3 tasks */
00080   /*
00081   newProcess->tss.es           = 0x30+3;
00082   newProcess->tss.cs           = 0x28+3;
00083   newProcess->tss.ss           = 0x30+3;
00084   newProcess->tss.ds           = 0x30+3;
00085   newProcess->tss.fs           = 0x30+3;
00086   newProcess->tss.gs           = 0x30+3;
00087   */
00088 
00089   newProcess->tss.es           = 0x10;
00090   newProcess->tss.cs           = 0x08;
00091   newProcess->tss.ss           = 0x10;
00092   newProcess->tss.ds           = 0x10;
00093   newProcess->tss.fs           = 0x10;
00094   newProcess->tss.gs           = 0x10;
00095 
00096   newProcess->tss.ldt          = 0x18;
00097   newProcess->tss.trace_bitmap = 0x0000;
00098   newProcess->tss.io_map       = 0x8000;
00099   newProcess->oInfo.vmStart    = 0x6400000;
00100   
00101   newProcess->imageFd          = 0x0;
00102 
00103   /* Set up default stack for thread here filled with arg list 3 times */
00104   asm volatile(
00105     "pusha               \n"
00106     "movl   %%esp,%%ecx  \n"
00107     "movl   %1,%%eax     \n"
00108     "movl   %%eax,%%esp  \n"
00109     "pushl  %%ebx        \n"
00110     "pushl  %%ebx        \n"
00111     "pushl  %%ebx        \n"
00112     "movl   %%esp,%%eax  \n"
00113     "movl   %%eax,%1     \n"
00114     "movl   %%ecx,%%esp  \n"
00115     "popa                \n"
00116     :
00117     : "b" (arg),"m" (newProcess->tss.esp)
00118     );
00119 
00120   /* Put new thread into the READY state */
00121   sched_setStatus(newProcess->id,READY);
00122 
00123   /* Return with the new process ID */
00124   return((uInt32)newProcess);
00125   }
00126 
00127 /*****************************************************************************************
00128 
00129  Function: void execFile(char *file);
00130  Description: This Function Executes A Kile Into A New VM Space With Out
00131               Having To Fork
00132  Notes:
00133 
00134  07/30/02 - I Have Made Some Heavy Changes To This As Well As Fixed A Few
00135             Memory Leaks The Memory Allocated To Load The Binary Into Is
00136             Now Unmapped So It Can Be Used Again And Not Held Onto Until
00137             The Program Exits
00138 
00139  07/30/02 - Now I Have To Make A Better Memory Allocator So We Can Set Up
00140             The Freshly Allocated Pages With The Correct Permissions
00141 
00142 *****************************************************************************************/
00143 void execFile(char *file,int argc,char **argv,int console) {
00144 
00145   int        i         = 0x0;
00146   int        x         = 0x0;
00147   uint32_t *tmp       = 0x0;
00148 
00149   fileDescriptor   *tmpFd         = 0x0;
00150   elfHeader        *binaryHeader  = 0x0;
00151   elfProgramHeader *programHeader = 0x0;
00152 
00153   /* Get A New Task For This Proccess */
00154   _current = schedNewTask();
00155   assert(_current);
00156   _current->gid  = 0x0;
00157   _current->uid  = 0x0;
00158   _current->term = tty_find(console);
00159   if (_current->term == 0x0)
00160     kprintf("Error: invalid console\n");
00161 
00162   /* Set tty ownership */
00163   _current->term->owner = _current->id;
00164 
00165   /* Now We Must Create A Virtual Space For This Proccess To Run In */
00166   _current->tss.cr3 = (uInt32)vmmCreateVirtualSpace(_current->id);
00167 
00168   /* To Better Load This Application We Will Switch Over To Its VM Space */
00169   asm volatile(
00170     "movl %0,%%eax          \n"
00171     "movl %%eax,%%cr3       \n"
00172     : : "d" ((uInt32 *)(_current->tss.cr3))
00173     );
00174 
00175   /* Lets Find The File */
00176   tmpFd = fopen(file,"r");
00177 
00178   /* If We Dont Find the File Return */
00179   if (tmpFd == 0x0) {
00180     kprintf("Exec Format Error: Binary File Not Executable.\n");
00181     fclose(tmpFd);
00182     return;
00183     }
00184   if (tmpFd->perms == 0x0) {
00185     kprintf("Exec Format Error: Binary File Not Executable.\n");
00186     fclose(tmpFd);
00187     return;
00188     }
00189 
00190   /* Load ELF Header */
00191   binaryHeader = (elfHeader *)kmalloc(sizeof(elfHeader));
00192 
00193 
00194   //kprintf(">a:%i:0x%X:0x%X<",sizeof(elfHeader),binaryHeader,tmpFd);
00195   fread(binaryHeader,sizeof(elfHeader),1,tmpFd);
00196 
00197 
00198   /* Check If App Is A Real Application */
00199   if ((binaryHeader->eIdent[1] != 'E') && (binaryHeader->eIdent[2] != 'L') && (binaryHeader->eIdent[3] != 'F')) {
00200     kprintf("Exec Format Error: Binary File Not Executable.\n");
00201     kfree(binaryHeader);
00202     fclose(tmpFd);
00203     return;
00204     }
00205   else if (binaryHeader->eType != 2) {
00206     kprintf("Exec Format Error: Binary File Not Executable.\n");
00207     kfree(binaryHeader);
00208     fclose(tmpFd);
00209     return;
00210     }
00211   else if (binaryHeader->eEntry == 0x300000) {
00212     kprintf("Exec Format Error: Binary File Not Executable.\n");
00213     kfree(binaryHeader);
00214     fclose(tmpFd);
00215     return;
00216     }
00217 
00218   /* Load The Program Header(s) */
00219   programHeader = (elfProgramHeader *)kmalloc(sizeof(elfProgramHeader)*binaryHeader->ePhnum);
00220   fseek(tmpFd,binaryHeader->ePhoff,0);
00221 
00222   //kprintf(">c:%i:0x%X:0x%X<",sizeof(elfProgramHeader)*binaryHeader->ePhnum,programHeader,tmpFd);
00223   fread(programHeader,(sizeof(elfProgramHeader)*binaryHeader->ePhnum),1,tmpFd);
00224   //kprintf(">d<");
00225 
00226   /* Loop Through The Header And Load Sections Which Need To Be Loaded */
00227   for (i=0;i<binaryHeader->ePhnum;i++) {
00228     if (programHeader[i].phType == 1) {
00229       /*
00230       Allocate Memory Im Going To Have To Make This Load Memory With Correct
00231       Settings so it helps us in the future
00232       */
00233       for (x = 0x0;x < (programHeader[i].phMemsz);x += 0x1000) {
00234         /* Make readonly and read/write !!! */
00235         if (vmm_remapPage(vmmFindFreePage(_current->id),((programHeader[i].phVaddr & 0xFFFFF000) + x),PAGE_DEFAULT) == 0x0)
00236           K_PANIC("Remap Page Failed");
00237 
00238         memset((void *)((programHeader[i].phVaddr & 0xFFFFF000) + x),0x0,0x1000);
00239         }
00240       _current->oInfo.vmStart = 0x80000000;
00241       _current->td.vm_daddr = (char *)(programHeader[i].phVaddr & 0xFFFFF000);
00242       /* Now Load Section To Memory */
00243       fseek(tmpFd,programHeader[i].phOffset,0);
00244       fread((void *)programHeader[i].phVaddr,programHeader[i].phFilesz,1,tmpFd);
00245       if ((programHeader[i].phFlags & 0x2) != 0x2) {
00246         kprintf("pH: [0x%X]\n",programHeader[i].phMemsz);
00247         for (x = 0x0;x < (programHeader[i].phMemsz);x += 0x1000) {
00248           if ((vmm_setPageAttributes((programHeader[i].phVaddr & 0xFFFFF000) + x,PAGE_PRESENT | PAGE_USER)) != 0x0)
00249             kpanic("Error: vmm_setPageAttributes failed, File: %s, Line: %i\n",__FILE__,__LINE__);
00250           }
00251         }
00252       }
00253     }
00254 
00255   /* Set Virtual Memory Start */
00256   _current->oInfo.vmStart = 0x80000000;
00257   _current->td.vm_daddr = (char *)(programHeader[i].phVaddr & 0xFFFFF000);
00258 
00259   /* Set Up Stack Space */
00260   for (x = 1;x < 100;x++) {
00261     vmm_remapPage(vmmFindFreePage(_current->id),STACK_ADDR - (x * 0x1000),PAGE_DEFAULT | PAGE_STACK);
00262     }
00263 
00264   /* Kernel Stack 0x2000 bytes long */
00265   vmm_remapPage(vmmFindFreePage(_current->id),0x5BC000,KERNEL_PAGE_DEFAULT | PAGE_STACK);
00266   vmm_remapPage(vmmFindFreePage(_current->id),0x5BB000,KERNEL_PAGE_DEFAULT | PAGE_STACK);
00267 
00268   /* Set All The Proper Information For The Task */
00269   _current->tss.back_link    = 0x0;
00270   _current->tss.esp0         = 0x5BC000;
00271   _current->tss.ss0          = 0x10;
00272   _current->tss.esp1         = 0x0;
00273   _current->tss.ss1          = 0x0;
00274   _current->tss.esp2         = 0x0;
00275   _current->tss.ss2          = 0x0;
00276   _current->tss.eip          = (long)binaryHeader->eEntry;
00277   _current->tss.eflags       = 0x206;
00278   _current->tss.esp          = STACK_ADDR - 12;
00279   _current->tss.ebp          = STACK_ADDR;
00280   _current->tss.esi          = 0x0;
00281   _current->tss.edi          = 0x0;
00282 
00283   /* Set these up to be ring 3 tasks */
00284   _current->tss.es           = 0x30+3;
00285   _current->tss.cs           = 0x28+3;
00286   _current->tss.ss           = 0x30+3;
00287   _current->tss.ds           = 0x30+3;
00288   _current->tss.fs           = 0x30+3;
00289   _current->tss.gs           = 0x30+3;
00290 
00291   _current->tss.ldt          = 0x18;
00292   _current->tss.trace_bitmap = 0x0000;
00293   _current->tss.io_map       = 0x8000;
00294 
00295   sched_setStatus(_current->id,READY);
00296 
00297   kfree(binaryHeader);
00298   kfree(programHeader);
00299   fclose(tmpFd);
00300 
00301   tmp = (uInt32 *)_current->tss.esp0 - 5;
00302   tmp[0] = binaryHeader->eEntry;
00303   tmp[3] = STACK_ADDR - 12;
00304 
00305   tmp = (uInt32 *)STACK_ADDR - 2;
00306 
00307   if (_current->id > 4)
00308   kprintf("argv[0]: [%s]\n",argv[0]);
00309   kprintf("argv: [0x%X]\n",argv);
00310   tmp[0] = (uint32_t)argv;
00311   tmp[1] = (uint32_t)argv;
00312 
00313 
00314   /* Switch Back To The Kernels VM Space */
00315   asm volatile(
00316     "movl %0,%%eax          \n"
00317     "movl %%eax,%%cr3       \n"
00318     : : "d" ((uInt32 *)(kernelPageDirectory))
00319     );
00320 
00321   /* Finally Return */
00322   return;
00323   }
00324 
00325 /*****************************************************************************************
00326 
00327  Function: void sysExec();
00328  Description: This Is The System Call To Execute A New Task
00329 
00330  Notes:
00331  04-22-03 - It Now Loads Sections Not The Full File
00332 
00333 *****************************************************************************************/
00334 void sysExec(char *file,char *ap) {
00335   int      i        = 0x0;
00336   int      x        = 0x0;
00337   int      argc     = 0x0;
00338   uInt32  *tmp      = 0x0;
00339   uInt32   ldAddr   = 0x0;
00340   uInt32   seg_size = 0x0;
00341   uInt32   seg_addr = 0x0;
00342   char    *interp   = 0x0;
00343   char   **argv     = 0x0;
00344   char   **argvNew  = 0x0;
00345   char    *args     = 0x0;
00346 
00347   fileDescriptor    *tmpFd         = 0x0;
00348   elfHeader         *binaryHeader  = 0x0;
00349   elfProgramHeader  *programHeader = 0x0;
00350   elfSectionHeader  *sectionHeader = 0x0;
00351   elfDynamic        *elfDynamicS   = 0x0;
00352   struct i386_frame *iFrame        = 0x0;
00353 
00354 
00355   if (_current->id > 4) {
00356     sys_exec(file,ap);
00357     return;
00358     }
00359 
00360   tmpFd = fopen(file,"r");
00361   _current->imageFd = tmpFd;
00362   /* If We Dont Find the File Return */
00363   if (tmpFd == 0x0) {
00364     return;
00365     }
00366   if (tmpFd->perms == 0) {
00367     kprintf("Exec Format Error: Binary File Not Executable.\n");
00368     fclose(tmpFd);
00369     return;
00370     }
00371 
00372   /* Load ELF Header */
00373 
00374   if ((binaryHeader = (elfHeader *)kmalloc(sizeof(elfHeader))) == 0x0) 
00375     endTask(_current->id);
00376     fread(binaryHeader,sizeof(elfHeader),1,tmpFd);
00377     /* Set sectionHeader To Point To Loaded Binary To We Can Gather Info */
00378 
00379   /* Check If App Is A Real Application */
00380   if ((binaryHeader->eIdent[1] != 'E') && (binaryHeader->eIdent[2] != 'L') && (binaryHeader->eIdent[3] != 'F')) {
00381     kprintf("Exec Format Error: Binary File Not Executable.\n");
00382     kfree(binaryHeader);
00383     fclose(tmpFd);
00384 
00385     return;
00386     }
00387   else if (binaryHeader->eType != 2) {
00388     kprintf("Exec Format Error: Binary File Not Executable.\n");
00389     kfree(binaryHeader);
00390     fclose(tmpFd);
00391     return;
00392     }
00393   else if (binaryHeader->eEntry == 0x300000) {
00394     kprintf("Exec Format Error: Binary File Not Executable.\n");
00395     kfree(binaryHeader);
00396     fclose(tmpFd);
00397     return;
00398     }
00399 
00400   /* Load The Program Header(s) */
00401   if ((programHeader = (elfProgramHeader *)kmalloc(sizeof(elfProgramHeader)*binaryHeader->ePhnum)) == 0x0)
00402     endTask(_current->id);
00403 
00404   assert(programHeader);
00405   fseek(tmpFd,binaryHeader->ePhoff,0);
00406   fread(programHeader,(sizeof(elfProgramHeader)*binaryHeader->ePhnum),1,tmpFd);
00407 
00408   if ((sectionHeader = (elfSectionHeader *)kmalloc(sizeof(elfSectionHeader)*binaryHeader->eShnum)) == 0x0)
00409     endTask(_current->id);
00410 
00411   assert(sectionHeader);
00412   fseek(tmpFd,binaryHeader->eShoff,0);
00413   fread(sectionHeader,sizeof(elfSectionHeader)*binaryHeader->eShnum,1,tmpFd);
00414 
00415   /* Loop Through The Header And Load Sections Which Need To Be Loaded */
00416   for (i=0;i<binaryHeader->ePhnum;i++) {
00417     switch (programHeader[i].phType) {
00418       case PT_LOAD:
00419         seg_addr = trunc_page(programHeader[i].phVaddr);
00420         seg_size = round_page(programHeader[i].phMemsz + programHeader[i].phVaddr - seg_addr);
00421 
00422         /*
00423         Allocate Memory Im Going To Have To Make This Load Memory With Correct
00424         Settings so it helps us in the future
00425         */
00426         for (x = 0x0;x < (programHeader[i].phMemsz);x += 0x1000) {
00427           /* Make readonly and read/write !!! */
00428           if (vmm_remapPage(vmmFindFreePage(_current->id),((programHeader[i].phVaddr & 0xFFFFF000) + x),PAGE_DEFAULT) == 0x0)
00429             K_PANIC("Error: Remap Page Failed");
00430           memset((void *)((programHeader[i].phVaddr & 0xFFFFF000) + x),0x0,0x1000);
00431           }
00432 
00433         /* Now Load Section To Memory */
00434         fseek(tmpFd,programHeader[i].phOffset,0);
00435         fread((void *)programHeader[i].phVaddr,programHeader[i].phFilesz,1,tmpFd);
00436         if ((programHeader[i].phFlags & 0x2) != 0x2) {
00437           for (x = 0x0;x < (programHeader[i].phMemsz);x += 0x1000) {
00438             if ((vmm_setPageAttributes((programHeader[i].phVaddr & 0xFFFFF000) + x,PAGE_PRESENT | PAGE_USER)) != 0x0)
00439               kpanic("Error: vmm_setPageAttributes failed, File: %s,Line: %i\n",__FILE__,__LINE__);
00440             }
00441           }
00442         kprintf("setting daddr\n");
00443         if (binaryHeader->eEntry >= programHeader[i].phVaddr && binaryHeader->eEntry < (programHeader[i].phVaddr + programHeader[i].phMemsz)) {
00444           /* We're suposed to do something here? */
00445           }
00446         else {
00447           _current->td.vm_dsize = seg_size >> PAGE_SHIFT;
00448           _current->td.vm_daddr = (char *)seg_addr;
00449           }
00450 
00451         _current->oInfo.vmStart = ((programHeader[i].phVaddr & 0xFFFFF000) + 0xA900000);
00452         break;
00453       case PT_DYNAMIC:
00454         //newLoc = (char *)programHeader[i].phVaddr;
00455         elfDynamicS = (elfDynamic *)programHeader[i].phVaddr;
00456         fseek(tmpFd,programHeader[i].phOffset,0);
00457         fread((void *)programHeader[i].phVaddr,programHeader[i].phFilesz,1,tmpFd);
00458         break;
00459       case PT_INTERP:
00460         interp = (char *)kmalloc(programHeader[i].phFilesz);
00461         fseek(tmpFd,programHeader[i].phOffset,0);
00462         fread((void *)interp,programHeader[i].phFilesz,1,tmpFd);
00463         kprintf("Interp: [%s]\n",interp);
00464         ldAddr = ldEnable();
00465         break;
00466       default:
00467         break;
00468       }
00469     }
00470 
00471   /* What is this doing? 11/23/06 */
00472   if (elfDynamicS != 0x0) {
00473     for (i=0;i<12;i++) {
00474       if (elfDynamicS[i].dynVal == 0x3) {
00475         tmp = (uInt32 *)elfDynamicS[i].dynPtr;
00476         if (tmp == 0x0)
00477           kpanic("tmp: NULL\n");
00478         tmp[2] = (uInt32)ldAddr;
00479         tmp[1] = (uInt32)tmpFd;
00480         break;
00481         }
00482 /*
00483       else {
00484         kprintf("dyn_val: %i",elfDynamicS[i].dynVal);
00485         }
00486 */
00487       }
00488     }
00489 
00490   _current->td.vm_dsize = seg_size >> PAGE_SHIFT;
00491   _current->td.vm_daddr = (char *)seg_addr;
00492 
00493   argv = ap;
00494 
00495   if (argv[1] != 0x0) {
00496     argc = argv[0];
00497     args = (char *)vmmGetFreeVirtualPage(_current->id,1,VM_TASK);
00498 memset(args,0x0,0x1000);
00499     x = 0x0;
00500     argvNew = (char **)kmalloc(sizeof(char *) * argc);
00501     for (i = 0x0;i < argc;i++) {
00502       strcpy(args + x,argv[i + 1]);
00503       argvNew[i] = args + x;
00504       x += strlen(argv[i + 1]) + 1;
00505       //args[x] = '\0';
00506       //x++;
00507       }
00508     argv = argvNew;
00509     }
00510 
00512   vmm_cleanVirtualSpace(_current->td.vm_daddr + (_current->td.vm_dsize << PAGE_SIZE));
00513 
00514 
00516   iFrame = _current->tss.esp0 - sizeof(struct i386_frame);
00517   iFrame->ebp = STACK_ADDR;
00518   iFrame->eip = binaryHeader->eEntry;
00519   iFrame->user_esp = STACK_ADDR - 12;
00520 
00521   //if (_current->id > 3) {
00522 
00523     iFrame->user_esp = ((uint32_t)STACK_ADDR) - (sizeof(uint32_t) * (argc + 3));
00524     tmp = iFrame->user_esp;
00525 
00527     tmp[0] = argc;
00528     for (i = 0;i < argc;i++) {
00529       tmp[i + 1] = argv[i];
00530       }
00531     tmp[argc + 1] = 0x0;
00532     tmp[argc + 2] = 0x1;
00533     //}
00534   //else {
00535     //tmp = (uint32_t *)STACK_ADDR - 2;
00536     //tmp[0] = 0x1;
00537     //tmp[1] = 0x0;
00538     //tmp[1] = (uint32_t)argv;
00539     //}
00540   kfree(argvNew);
00541  /* Now That We Relocated The Binary We Can Unmap And Free Header Info */
00542   kfree(binaryHeader);
00543   kfree(programHeader);
00544 
00545   return;
00546   }
00547 
00552 void sys_exec(char *file,char *ap) {
00553   int                 error         = 0x0;
00554   int                 i             = 0x0;
00555   int                 x             = 0x0;
00556   int                 argc          = 0x0;
00557   uint32_t           seg_size      = 0x0;
00558   uint32_t           seg_addr      = 0x0;
00559   uint32_t           addr          = 0x0;
00560   uint32_t           eip           = 0x0;
00561   uint32_t           proghdr       = 0x0;
00562   char               *args          = 0x0;
00563   char               *interp        = 0x0;
00564   char              **argv          = 0x0;
00565   char              **argvNew       = 0x0;
00566   elfHeader          *binaryHeader  = 0x0;
00567   elfProgramHeader   *programHeader = 0x0;
00568   struct i386_frame  *iFrame        = 0x0;
00569   Elf_Auxargs        *auxargs       = 0x0;
00570 
00571   _current->imageFd = fopen(file,"r");
00572   if (_current->imageFd == 0x0)
00573     return(-1);
00574 
00575   /* Load the ELF header */
00576   if ((binaryHeader = (elfHeader *)kmalloc(sizeof(elfHeader))) == 0x0) 
00577     K_PANIC("malloc failed!");
00578   fread(binaryHeader,sizeof(elfHeader),1,_current->imageFd);
00579 
00580   /* Check If App Is A Real Application */
00581   if (((binaryHeader->eIdent[1] != 'E') && (binaryHeader->eIdent[2] != 'L') && (binaryHeader->eIdent[3] != 'F')) || (binaryHeader->eType != ET_EXEC)) {
00582     kfree(binaryHeader);
00583     fclose(_current->imageFd);
00584     return(-1);
00585     }
00586 
00587   /* Load The Program Header(s) */
00588   if ((programHeader = (elfProgramHeader *)kmalloc(sizeof(elfProgramHeader)*binaryHeader->ePhnum)) == 0x0)
00589     K_PANIC("malloc failed!");
00590   fseek(_current->imageFd,binaryHeader->ePhoff,0);
00591   fread(programHeader,(sizeof(elfProgramHeader)*binaryHeader->ePhnum),1,_current->imageFd);
00592 
00593   /* Loop Through The Header And Load Sections Which Need To Be Loaded */
00594   for (i = 0x0;i < binaryHeader->ePhnum;i++) {
00595     switch (programHeader[i].phType) {
00596       case PT_LOAD:
00597         seg_addr = trunc_page(programHeader[i].phVaddr);
00598         seg_size = round_page(programHeader[i].phMemsz + programHeader[i].phVaddr - seg_addr);
00599 
00600         /*
00601         Allocate Memory Im Going To Have To Make This Load Memory With Correct
00602         Settings so it helps us in the future
00603         */
00604         for (x = 0x0;x < (programHeader[i].phMemsz);x += 0x1000) {
00605           /* Make readonly and read/write !!! */
00606           if (vmm_remapPage(vmmFindFreePage(_current->id),((programHeader[i].phVaddr & 0xFFFFF000) + x),PAGE_DEFAULT) == 0x0)
00607             K_PANIC("Error: Remap Page Failed");
00608           memset((void *)((programHeader[i].phVaddr & 0xFFFFF000) + x),0x0,0x1000);
00609           }
00610 
00611         /* Now Load Section To Memory */
00612         fseek(_current->imageFd,programHeader[i].phOffset,0);
00613         fread((void *)programHeader[i].phVaddr,programHeader[i].phFilesz,1,_current->imageFd);
00614         if ((programHeader[i].phFlags & 0x2) != 0x2) {
00615           for (x = 0x0;x < (programHeader[i].phMemsz);x += 0x1000) {
00616             if ((vmm_setPageAttributes((programHeader[i].phVaddr & 0xFFFFF000) + x,PAGE_PRESENT | PAGE_USER)) != 0x0)
00617               K_PANIC("vmm_setPageAttributes failed");
00618             }
00619           }
00620         if (binaryHeader->eEntry >= programHeader[i].phVaddr && binaryHeader->eEntry < (programHeader[i].phVaddr + programHeader[i].phMemsz)) {
00621           /* We're suposed to do something here? */
00622           }
00623         else {
00624           _current->td.vm_dsize = seg_size >> PAGE_SHIFT;
00625           _current->td.vm_daddr = (char *)seg_addr;
00626           }
00627 
00628         _current->oInfo.vmStart = ((programHeader[i].phVaddr & 0xFFFFF000) + 0xA900000);
00629         break;
00630       case PT_INTERP:
00631         interp = (char *)kmalloc(programHeader[i].phFilesz);
00632         if (interp == 0x0)
00633           K_PANIC("malloc failed");
00634 
00635         fseek(_current->imageFd,programHeader[i].phOffset,0);
00636         fread((void *)interp,programHeader[i].phFilesz,1,_current->imageFd);
00637         kprintf("Interp: [%s]\n",interp);
00638         //ldAddr = ldEnable();
00639         break;
00640       case PT_PHDR:
00641         proghdr = programHeader[i].phVaddr; 
00642         break;
00643       default:
00644         break;
00645       }
00646     }
00647 
00648   addr = LD_START;
00649 
00650 
00651   if (interp != 0x0) {
00652     kprintf("TEST");
00653     elf_loadfile(_current,interp,&addr,&eip);
00654     }
00655   kprintf("[0x%X][0x%X]\n",eip,addr);
00656 
00657   _current->td.vm_dsize = seg_size >> PAGE_SHIFT;
00658   _current->td.vm_daddr = (char *)seg_addr;
00659 
00660   argv = ap;
00661 
00662   if (argv[1] != 0x0) {
00663     argc = argv[0];
00664     args = (char *)vmmGetFreeVirtualPage(_current->id,1,VM_TASK);
00665     memset(args,0x0,0x1000);
00666     x = 0x0;
00667     argvNew = (char **)kmalloc(sizeof(char *) * argc);
00668     for (i = 0x0;i < argc;i++) {
00669       strcpy(args + x,argv[i + 1]);
00670       argvNew[i] = args + x;
00671       x += strlen(argv[i + 1]) + 1;
00672       }
00673     argv = argvNew;
00674     }
00675 
00677   vmm_cleanVirtualSpace(_current->td.vm_daddr + (_current->td.vm_dsize << PAGE_SIZE));
00678 
00679 
00681   iFrame = _current->tss.esp0 - sizeof(struct i386_frame);
00682   iFrame->ebp = STACK_ADDR;
00683   iFrame->eip = eip;
00684 
00685   //if (_current->id > 3) {
00686 
00687   iFrame->user_esp = ((uint32_t)STACK_ADDR) - (sizeof(uint32_t) * (argc + 3 + sizeof(Elf_Auxargs)));
00688   args = iFrame->user_esp;
00689 
00691   args[0] = argc;
00692   for (i = 0;i < argc;i++) {
00693     args[i + 1] = argv[i];
00694     }
00696   args[argc + 2] = 0x0;
00697   auxargs = iFrame->user_esp + argc +  2;
00698   auxargs->execfd = -1;
00699   auxargs->phdr   = proghdr;
00700   auxargs->phent  = binaryHeader->ePhentsize;
00701   auxargs->phnum  = binaryHeader->ePhnum;
00702   auxargs->pagesz = PAGE_SIZE;
00703   auxargs->base   = addr;
00704   auxargs->flags  = 0x0;
00705   auxargs->entry  = binaryHeader->eEntry;
00706   auxargs->trace  = 0x0;
00707 kprintf("\n\nDOH\n\n");
00708 
00709  //while (1);
00710 /*
00711   error = elf_loadfile(_current,file,0x0,0x0);
00712   if (error)
00713     K_PANIC("elf_loadfile failed");
00714 */
00715   return;
00716   }
00717 
00718 /***
00719  END
00720  ***/

Generated on Fri Dec 15 11:18:55 2006 for UbixOS V2 by  doxygen 1.4.7