# 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   u_int32_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] = (u_int32_t)argv;
    00311   tmp[1] = (u_int32_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 = ((u_int32_t)STACK_ADDR) - (sizeof(u_int32_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 = (u_int32_t *)STACK_ADDR - 2;
    00536     //tmp[0] = 0x1;
    00537     //tmp[1] = 0x0;
    00538     //tmp[1] = (u_int32_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   u_int32_t           seg_size      = 0x0;
    00558   u_int32_t           seg_addr      = 0x0;
    00559   u_int32_t           addr          = 0x0;
    00560   u_int32_t           eip           = 0x0;
    00561   u_int32_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 = ((u_int32_t)STACK_ADDR) - (sizeof(u_int32_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  ***/