UbixOS  2.0
exec.c
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2002-2018 The UbixOS Project.
3  * All rights reserved.
4  *
5  * This was developed by Christopher W. Olsen for the UbixOS Project.
6  *
7  * Redistribution and use in source and binary forms, with or without modification, are permitted
8  * provided that the following conditions are met:
9  *
10  * 1) Redistributions of source code must retain the above copyright notice, this list of
11  * conditions, the following disclaimer and the list of authors.
12  * 2) Redistributions in binary form must reproduce the above copyright notice, this list of
13  * conditions, the following disclaimer and the list of authors in the documentation and/or
14  * other materials provided with the distribution.
15  * 3) Neither the name of the UbixOS Project nor the names of its contributors may be used to
16  * endorse or promote products derived from this software without specific prior written
17  * permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <ubixos/exec.h>
30 #include <sys/elf.h>
31 #include <ubixos/ld.h>
32 #include <ubixos/kpanic.h>
33 #include <ubixos/endtask.h>
34 #include <vmm/vmm.h>
35 #include <lib/kmalloc.h>
36 #include <lib/kprintf.h>
37 #include <lib/string.h>
38 #include <assert.h>
39 
40 #define STACK_ADDR 0xC800000
41 
42 #define AT_NULL 0 /* Terminates the vector. */
43 #define AT_IGNORE 1 /* Ignored entry. */
44 #define AT_EXECFD 2 /* File descriptor of program to load. */
45 #define AT_PHDR 3 /* Program header of program already loaded. */
46 #define AT_PHENT 4 /* Size of each program header entry. */
47 #define AT_PHNUM 5 /* Number of program header entries. */
48 #define AT_PAGESZ 6 /* Page size in bytes. */
49 #define AT_BASE 7 /* Interpreter's base address. */
50 #define AT_FLAGS 8 /* Flags (unused for i386). */
51 #define AT_ENTRY 9 /* Where interpreter should transfer control. */
52 
53 //#define AUXARGS_ENTRY(pos, id, val) {memcpy((void *)pos++,(void *)id,sizeof(long)); memcpy((void *)pos++,(void *)val,sizeof(long));}
54 #define AUXARGS_ENTRY(pos, id, val) {*pos = id;pos++; *pos = val;pos++;}
55 
56 /*****************************************************************************************
57 
58  Function: execThread(void (*)(void),int,char *);
59  Description: This function will create a thread from code in the current memory space
60 
61  Notes:
62 
63  05/19/04 - This does not work the way I want it to it still makes a copy of kernel space
64  so do not use out side of kernel space
65 
66  *****************************************************************************************/
67 uInt32 execThread(void (*tproc)(void), uInt32 stack, char *arg) {
68  kTask_t * newProcess = 0x0;
69  /* Find A New Thread */
70  newProcess = schedNewTask();
71  assert(newProcess);
72  if (stack < 0x100000)
73  kpanic("exec: stack not in valid area: [0x%X]\n", stack);
74 
75  /* Set All The Correct Thread Attributes */
76  newProcess->tss.back_link = 0x0;
77  newProcess->tss.esp0 = 0x0;
78  newProcess->tss.ss0 = 0x0;
79  newProcess->tss.esp1 = 0x0;
80  newProcess->tss.ss1 = 0x0;
81  newProcess->tss.esp2 = 0x0;
82  newProcess->tss.ss2 = 0x0;
83  newProcess->tss.cr3 = (unsigned int) kernelPageDirectory;
84  newProcess->tss.eip = (unsigned int) tproc;
85  newProcess->tss.eflags = 0x206;
86  newProcess->tss.esp = stack;
87  newProcess->tss.ebp = stack;
88  newProcess->tss.esi = 0x0;
89  newProcess->tss.edi = 0x0;
90 
91  /* Set these up to be ring 3 tasks */
92  /*
93  newProcess->tss.es = 0x30+3;
94  newProcess->tss.cs = 0x28+3;
95  newProcess->tss.ss = 0x30+3;
96  newProcess->tss.ds = 0x30+3;
97  newProcess->tss.fs = 0x30+3;
98  newProcess->tss.gs = 0x30+3;
99  */
100 
101  newProcess->tss.es = 0x10;
102  newProcess->tss.cs = 0x08;
103  newProcess->tss.ss = 0x10;
104  newProcess->tss.ds = 0x10;
105  newProcess->tss.fs = 0x10;
106  newProcess->tss.gs = 0x10;
107 
108  newProcess->tss.ldt = 0x18;
109  newProcess->tss.trace_bitmap = 0x0000;
110  newProcess->tss.io_map = 0x8000;
111  newProcess->oInfo.vmStart = 0x6400000;
112 
113  //newProcess->imageFd = 0x0;
114 
115  /* Set up default stack for thread here filled with arg list 3 times */
116  asm volatile(
117  "pusha \n"
118  "movl %%esp,%%ecx \n"
119  "movl %1,%%eax \n"
120  "movl %%eax,%%esp \n"
121  "pushl %%ebx \n"
122  "pushl %%ebx \n"
123  "pushl %%ebx \n"
124  "movl %%esp,%%eax \n"
125  "movl %%eax,%1 \n"
126  "movl %%ecx,%%esp \n"
127  "popa \n"
128  :
129  : "b" (arg),"m" (newProcess->tss.esp)
130  );
131 
132  /* Put new thread into the READY state */
133  sched_setStatus(newProcess->id, READY);
134 
135  /* Return with the new process ID */
136  return ((uInt32) newProcess);
137 }
138 
139 /*****************************************************************************************
140 
141  Function: void execFile(char *file);
142  Description: This Function Executes A Kile Into A New VM Space With Out
143  Having To Fork
144  Notes:
145 
146  07/30/02 - I Have Made Some Heavy Changes To This As Well As Fixed A Few
147  Memory Leaks The Memory Allocated To Load The Binary Into Is
148  Now Unmapped So It Can Be Used Again And Not Held Onto Until
149  The Program Exits
150 
151  07/30/02 - Now I Have To Make A Better Memory Allocator So We Can Set Up
152  The Freshly Allocated Pages With The Correct Permissions
153 
154  *****************************************************************************************/
155 void execFile(char *file, int argc, char **argv, int console) {
156 
157  int i = 0x0;
158  int x = 0x0;
159  uint32_t *tmp = 0x0;
160 
161  fileDescriptor *tmpFd = 0x0;
162  elfHeader *binaryHeader = 0x0;
163  elfProgramHeader *programHeader = 0x0;
164 
165  /* Get A New Task For This Proccess */
167  assert(_current);
168  _current->gid = 0x0;
169  _current->uid = 0x0;
170  _current->term = tty_find(console);
171  if (_current->term == 0x0)
172  kprintf("Error: invalid console\n");
173 
174  /* Set tty ownership */
176 
177  /* Now We Must Create A Virtual Space For This Proccess To Run In */
178  _current->tss.cr3 = (uInt32) vmmCreateVirtualSpace(_current->id);
179 
180  /* To Better Load This Application We Will Switch Over To Its VM Space */
181  asm volatile(
182  "movl %0,%%eax \n"
183  "movl %%eax,%%cr3 \n"
184  : : "d" ((uInt32 *)(_current->tss.cr3))
185  );
186 
187  /* Lets Find The File */
188  tmpFd = fopen(file, "r");
189 
190  /* If We Dont Find the File Return */
191  if (tmpFd == 0x0) {
192  kprintf("Exec Format Error: Binary File Not Executable.\n");
193  fclose(tmpFd);
194  return;
195  }
196  if (tmpFd->perms == 0x0) {
197  kprintf("Exec Format Error: Binary File Not Executable.\n");
198  fclose(tmpFd);
199  return;
200  }
201 
202  /* Load ELF Header */
203  binaryHeader = (elfHeader *) kmalloc(sizeof(elfHeader));
204 
205  //kprintf(">a:%i:0x%X:0x%X<",sizeof(elfHeader),binaryHeader,tmpFd);
206  fread(binaryHeader, sizeof(elfHeader), 1, tmpFd);
207 
208  /* Check If App Is A Real Application */
209  if ((binaryHeader->eIdent[1] != 'E') && (binaryHeader->eIdent[2] != 'L') && (binaryHeader->eIdent[3] != 'F')) {
210  kprintf("Exec Format Error: Binary File Not Executable.\n");
211  kfree(binaryHeader);
212  fclose(tmpFd);
213  return;
214  }
215  else if (binaryHeader->eType != 2) {
216  kprintf("Exec Format Error: Binary File Not Executable.\n");
217  kfree(binaryHeader);
218  fclose(tmpFd);
219  return;
220  }
221  else if (binaryHeader->eEntry == 0x300000) {
222  kprintf("Exec Format Error: Binary File Not Executable.\n");
223  kfree(binaryHeader);
224  fclose(tmpFd);
225  return;
226  }
227 
228  /* Load The Program Header(s) */
229  programHeader = (elfProgramHeader *) kmalloc(sizeof(elfProgramHeader) * binaryHeader->ePhnum);
230  fseek(tmpFd, binaryHeader->ePhoff, 0);
231 
232  //kprintf(">c:%i:0x%X:0x%X<",sizeof(elfProgramHeader)*binaryHeader->ePhnum,programHeader,tmpFd);
233  fread(programHeader, (sizeof(elfProgramHeader) * binaryHeader->ePhnum), 1, tmpFd);
234  //kprintf(">d<");
235 
236  /* Loop Through The Header And Load Sections Which Need To Be Loaded */
237  for (i = 0; i < binaryHeader->ePhnum; i++) {
238  if (programHeader[i].phType == 1) {
239  /*
240  Allocate Memory Im Going To Have To Make This Load Memory With Correct
241  Settings so it helps us in the future
242  */
243  for (x = 0x0; x < (programHeader[i].phMemsz); x += 0x1000) {
244  /* Make readonly and read/write !!! */
245  if (vmm_remapPage(vmm_findFreePage(_current->id), ((programHeader[i].phVaddr & 0xFFFFF000) + x), PAGE_DEFAULT) == 0x0)
246  K_PANIC("Remap Page Failed");
247 
248  memset((void *) ((programHeader[i].phVaddr & 0xFFFFF000) + x), 0x0, 0x1000);
249  }
250  _current->oInfo.vmStart = 0x80000000;
251  _current->td.vm_daddr = (char *) (programHeader[i].phVaddr & 0xFFFFF000);
252  /* Now Load Section To Memory */
253  fseek(tmpFd, programHeader[i].phOffset, 0);
254  fread((void *) programHeader[i].phVaddr, programHeader[i].phFilesz, 1, tmpFd);
255  if ((programHeader[i].phFlags & 0x2) != 0x2) {
256  kprintf("pH: [0x%X]\n", programHeader[i].phMemsz);
257  for (x = 0x0; x < (programHeader[i].phMemsz); x += 0x1000) {
258  if ((vmm_setPageAttributes((programHeader[i].phVaddr & 0xFFFFF000) + x, PAGE_PRESENT | PAGE_USER)) != 0x0)
259  kpanic("Error: vmm_setPageAttributes failed, File: %s, Line: %i\n", __FILE__, __LINE__);
260  }
261  }
262  }
263  }
264 
265  /* Set Virtual Memory Start */
266  _current->oInfo.vmStart = 0x80000000;
267  _current->td.vm_daddr = (char *) (programHeader[i].phVaddr & 0xFFFFF000);
268 
269  /* Set Up Stack Space */
270  for (x = 1; x < 100; x++) {
272  }
273 
274  /* Kernel Stack 0x2000 bytes long */
277 
278  /* Set All The Proper Information For The Task */
279  _current->tss.back_link = 0x0;
280  _current->tss.esp0 = 0x5BC000;
281  _current->tss.ss0 = 0x10;
282  _current->tss.esp1 = 0x0;
283  _current->tss.ss1 = 0x0;
284  _current->tss.esp2 = 0x0;
285  _current->tss.ss2 = 0x0;
286  _current->tss.eip = (long) binaryHeader->eEntry;
287  _current->tss.eflags = 0x206;
288  _current->tss.esp = STACK_ADDR - 12;
290  _current->tss.esi = 0x0;
291  _current->tss.edi = 0x0;
292 
293  /* Set these up to be ring 3 tasks */
294  _current->tss.es = 0x30 + 3;
295  _current->tss.cs = 0x28 + 3;
296  _current->tss.ss = 0x30 + 3;
297  _current->tss.ds = 0x30 + 3;
298  _current->tss.fs = 0x30 + 3;
299  _current->tss.gs = 0x30 + 3;
300 
301  _current->tss.ldt = 0x18;
302  _current->tss.trace_bitmap = 0x0000;
303  _current->tss.io_map = 0x8000;
304 
306 
307  kfree(binaryHeader);
308  kfree(programHeader);
309  fclose(tmpFd);
310 
311  tmp = (uInt32 *) _current->tss.esp0 - 5;
312  tmp[0] = binaryHeader->eEntry;
313  tmp[3] = STACK_ADDR - 12;
314 
315  tmp = (uInt32 *) STACK_ADDR - 2;
316 
317  if (_current->id > 4)
318  kprintf("argv[0]: [%s]\n", argv[0]);
319  kprintf("argv: [0x%X]\n", argv);
320  tmp[0] = (uint32_t) argv;
321  tmp[1] = (uint32_t) argv;
322 
323  /* Switch Back To The Kernels VM Space */
324  asm volatile(
325  "movl %0,%%eax \n"
326  "movl %%eax,%%cr3 \n"
327  : : "d" ((uInt32 *)(kernelPageDirectory))
328  );
329 
330  /* Finally Return */
331  return;
332 }
333 
334 /*****************************************************************************************
335 
336  Function: void sysExec();
337  Description: This Is The System Call To Execute A New Task
338 
339  Notes:
340  04-22-03 - It Now Loads Sections Not The Full File
341 
342  *****************************************************************************************/
343 void sysExec(char *file, char *ap) {
344  int i = 0x0;
345  int x = 0x0;
346  int argc = 0x0;
347  unsigned int *tmp = 0x0;
348  uInt32 ldAddr = 0x0;
349  uInt32 seg_size = 0x0;
350  uInt32 seg_addr = 0x0;
351  char *interp = 0x0;
352  char **argv = 0x0;
353  char **argvNew = 0x0;
354  char *args = 0x0;
355 
356  fileDescriptor *tmpFd = 0x0;
357  elfHeader *binaryHeader = 0x0;
358  elfProgramHeader *programHeader = 0x0;
359  elfSectionHeader *sectionHeader = 0x0;
360  elfDynamic *elfDynamicS = 0x0;
361  struct i386_frame *iFrame = 0x0;
362 
363  tmpFd = fopen(file, "r");
364  _current->files[0] = tmpFd;
365  /* If We Dont Find the File Return */
366  if (tmpFd == 0x0) {
367  return;
368  }
369  if (tmpFd->perms == 0) {
370  kprintf("Exec Format Error: Binary File Not Executable.\n");
371  fclose(tmpFd);
372  return;
373  }
374 
375  /* Load ELF Header */
376 
377  if ((binaryHeader = (elfHeader *) kmalloc(sizeof(elfHeader))) == 0x0)
378  endTask(_current->id);
379  fread(binaryHeader, sizeof(elfHeader), 1, tmpFd);
380  /* Set sectionHeader To Point To Loaded Binary To We Can Gather Info */
381 
382  /* Check If App Is A Real Application */
383  if ((binaryHeader->eIdent[1] != 'E') && (binaryHeader->eIdent[2] != 'L') && (binaryHeader->eIdent[3] != 'F')) {
384  kprintf("Exec Format Error: Binary File Not Executable.\n");
385  kfree(binaryHeader);
386  fclose(tmpFd);
387 
388  return;
389  }
390  else if (binaryHeader->eType != 2) {
391  kprintf("Exec Format Error: Binary File Not Executable.\n");
392  kfree(binaryHeader);
393  fclose(tmpFd);
394  return;
395  }
396  else if (binaryHeader->eEntry == 0x300000) {
397  kprintf("Exec Format Error: Binary File Not Executable.\n");
398  kfree(binaryHeader);
399  fclose(tmpFd);
400  return;
401  }
402 
403  /* Load The Program Header(s) */
404  if ((programHeader = (elfProgramHeader *) kmalloc(sizeof(elfProgramHeader) * binaryHeader->ePhnum)) == 0x0)
405  endTask(_current->id);
406 
407  assert(programHeader);
408  fseek(tmpFd, binaryHeader->ePhoff, 0);
409  fread(programHeader, (sizeof(elfProgramHeader) * binaryHeader->ePhnum), 1, tmpFd);
410 
411  if ((sectionHeader = (elfSectionHeader *) kmalloc(sizeof(elfSectionHeader) * binaryHeader->eShnum)) == 0x0)
412  endTask(_current->id);
413 
414  assert(sectionHeader);
415  fseek(tmpFd, binaryHeader->eShoff, 0);
416  fread(sectionHeader, sizeof(elfSectionHeader) * binaryHeader->eShnum, 1, tmpFd);
417 
418  /* Loop Through The Header And Load Sections Which Need To Be Loaded */
419  for (i = 0; i < binaryHeader->ePhnum; i++) {
420  switch (programHeader[i].phType) {
421  case PT_LOAD:
422  seg_addr = trunc_page(programHeader[i].phVaddr);
423  seg_size = round_page(programHeader[i].phMemsz + programHeader[i].phVaddr - seg_addr);
424 
425  /*
426  Allocate Memory Im Going To Have To Make This Load Memory With Correct
427  Settings so it helps us in the future
428  */
429  for (x = 0x0; x < (programHeader[i].phMemsz); x += 0x1000) {
430  /* Make readonly and read/write !!! */
431  if (vmm_remapPage(vmm_findFreePage(_current->id), ((programHeader[i].phVaddr & 0xFFFFF000) + x), PAGE_DEFAULT) == 0x0)
432  K_PANIC("Error: Remap Page Failed");
433  memset((void *) ((programHeader[i].phVaddr & 0xFFFFF000) + x), 0x0, 0x1000);
434  }
435 
436  /* Now Load Section To Memory */
437  fseek(tmpFd, programHeader[i].phOffset, 0);
438  fread((void *) programHeader[i].phVaddr, programHeader[i].phFilesz, 1, tmpFd);
439  if ((programHeader[i].phFlags & 0x2) != 0x2) {
440  for (x = 0x0; x < (programHeader[i].phMemsz); x += 0x1000) {
441  if ((vmm_setPageAttributes((programHeader[i].phVaddr & 0xFFFFF000) + x, PAGE_PRESENT | PAGE_USER)) != 0x0)
442  kpanic("Error: vmm_setPageAttributes failed, File: %s,Line: %i\n", __FILE__, __LINE__);
443  }
444  }
445  kprintf("setting daddr\n");
446  if (binaryHeader->eEntry >= programHeader[i].phVaddr && binaryHeader->eEntry < (programHeader[i].phVaddr + programHeader[i].phMemsz)) {
447  /* We're suposed to do something here? */
448  }
449  else {
450  _current->td.vm_dsize = seg_size >> PAGE_SHIFT;
451  _current->td.vm_daddr = (char *) seg_addr;
452  }
453 
454  _current->oInfo.vmStart = ((programHeader[i].phVaddr & 0xFFFFF000) + 0xA900000);
455  break;
456  case PT_DYNAMIC:
457  //newLoc = (char *)programHeader[i].phVaddr;
458  elfDynamicS = (elfDynamic *) programHeader[i].phVaddr;
459  fseek(tmpFd, programHeader[i].phOffset, 0);
460  fread((void *) programHeader[i].phVaddr, programHeader[i].phFilesz, 1, tmpFd);
461  break;
462  case PT_INTERP:
463  interp = (char *) kmalloc(programHeader[i].phFilesz);
464  fseek(tmpFd, programHeader[i].phOffset, 0);
465  fread((void *) interp, programHeader[i].phFilesz, 1, tmpFd);
466  kprintf("Interp: [%s]\n", interp);
467  ldAddr = ldEnable();
468  break;
469  default:
470  break;
471  }
472  }
473 
474  /* What is this doing? 11/23/06 */
475  if (elfDynamicS != 0x0) {
476  for (i = 0; i < 12; i++) {
477  if (elfDynamicS[i].dynVal == 0x3) {
478  tmp = (void *) elfDynamicS[i].dynPtr;
479  if (tmp == 0x0)
480  kpanic("tmp: NULL\n");
481  tmp[2] = (uInt32) ldAddr;
482  tmp[1] = (uInt32) tmpFd;
483  break;
484  }
485  /*
486  else {
487  kprintf("dyn_val: %i",elfDynamicS[i].dynVal);
488  }
489  */
490  }
491  }
492 
493  _current->td.vm_dsize = seg_size >> PAGE_SHIFT;
494  _current->td.vm_daddr = (char *) seg_addr;
495 
496  argv = &ap;
497 
498  if (argv[1] != 0x0) {
499  argc = (int) argv[0];
500  args = (char *) vmmGetFreeVirtualPage(_current->id, 1, VM_TASK);
501  memset(args, 0x0, 0x1000);
502  x = 0x0;
503  argvNew = (char **) kmalloc(sizeof(char *) * argc);
504  for (i = 0x0; i < argc; i++) {
505  strcpy(args + x, argv[i + 1]);
506  argvNew[i] = args + x;
507  x += strlen(argv[i + 1]) + 1;
508  //args[x] = '\0';
509  //x++;
510  }
511  argv = argvNew;
512  }
513 
516 
518  iFrame = (struct i386_frame *) _current->tss.esp0 - sizeof(struct i386_frame);
519  iFrame->ebp = STACK_ADDR;
520  iFrame->eip = binaryHeader->eEntry;
521  iFrame->user_esp = STACK_ADDR - 12;
522 
523  //if (_current->id > 3) {
524 
525  iFrame->user_esp = ((uint32_t) STACK_ADDR) - (sizeof(uint32_t) * (argc + 3));
526  tmp = (void *) iFrame->user_esp;
527 
529  tmp[0] = argc;
530  for (i = 0; i < argc; i++) {
531  tmp[i + 1] = (u_int) argv[i];
532  }
533  tmp[argc + 1] = 0x0;
534  tmp[argc + 2] = 0x1;
535  //}
536  //else {
537  //tmp = (uint32_t *)STACK_ADDR - 2;
538  //tmp[0] = 0x1;
539  //tmp[1] = 0x0;
540  //tmp[1] = (uint32_t)argv;
541  //}
542  kfree(argvNew);
543  /* Now That We Relocated The Binary We Can Unmap And Free Header Info */
544  kfree(binaryHeader);
545  kfree(programHeader);
546 
547  return;
548 }
549 
554 void sys_exec(char *file, char *ap) {
555  int error = 0x0;
556  int i = 0x0;
557  int x = 0x0;
558  int argc = 0x0;
559  uint32_t *tmp = 0x0;
560  uint32_t seg_size = 0x0;
561  uint32_t seg_addr = 0x0;
562  uint32_t addr = 0x0;
563  uint32_t eip = 0x0;
564  uint32_t proghdr = 0x0;
565  char *args = 0x0;
566  char *interp = 0x0;
567  char **argv = 0x0;
568  char **argvNew = 0x0;
569  elfHeader *binaryHeader = 0x0;
570  elfProgramHeader *programHeader = 0x0;
571  struct i386_frame *iFrame = 0x0;
572  //Elf_Auxargs *auxargs = 0x0;
573 
574  _current->files[0] = fopen(file, "r");
575  if (_current->files[0] == 0x0)
576  return; //We Need To Set errno
577 
578  /* Load the ELF header */
579  if ((binaryHeader = (elfHeader *) kmalloc(sizeof(elfHeader))) == 0x0)
580  K_PANIC("malloc failed!");
581  fread(binaryHeader, sizeof(elfHeader), 1, _current->files[0]);
582 
583  /* Check If App Is A Real Application */
584  if (((binaryHeader->eIdent[1] != 'E') && (binaryHeader->eIdent[2] != 'L') && (binaryHeader->eIdent[3] != 'F')) || (binaryHeader->eType != ET_EXEC)) {
585  kfree(binaryHeader);
586  fclose(_current->files[0]);
587  return; //We Need To Set errno
588  }
589 
590  /* Load The Program Header(s) */
591  if ((programHeader = (elfProgramHeader *) kmalloc(sizeof(elfProgramHeader) * binaryHeader->ePhnum)) == 0x0)
592  K_PANIC("malloc failed!");
593  fseek(_current->files[0], binaryHeader->ePhoff, 0);
594  fread(programHeader, (sizeof(elfProgramHeader) * binaryHeader->ePhnum), 1, _current->files[0]);
595 
596  /* Loop Through The Header And Load Sections Which Need To Be Loaded */
597  for (i = 0x0; i < binaryHeader->ePhnum; i++) {
598  switch (programHeader[i].phType) {
599  case PT_LOAD:
600  seg_addr = trunc_page(programHeader[i].phVaddr);
601  seg_size = round_page(programHeader[i].phMemsz + programHeader[i].phVaddr - seg_addr);
602 
603  /*
604  Allocate Memory Im Going To Have To Make This Load Memory With Correct
605  Settings so it helps us in the future
606  */
607  for (x = 0x0; x < (programHeader[i].phMemsz); x += 0x1000) {
608  /* Make readonly and read/write !!! */
609  if (vmm_remapPage(vmm_findFreePage(_current->id), ((programHeader[i].phVaddr & 0xFFFFF000) + x), PAGE_DEFAULT) == 0x0)
610  K_PANIC("Error: Remap Page Failed");
611  memset((void *) ((programHeader[i].phVaddr & 0xFFFFF000) + x), 0x0, 0x1000);
612  }
613 
614  /* Now Load Section To Memory */
615  fseek(_current->files[0], programHeader[i].phOffset, 0);
616  fread((void *) programHeader[i].phVaddr, programHeader[i].phFilesz, 1, _current->files[0]);
617  if ((programHeader[i].phFlags & 0x2) != 0x2) {
618  for (x = 0x0; x < (programHeader[i].phMemsz); x += 0x1000) {
619  if ((vmm_setPageAttributes((programHeader[i].phVaddr & 0xFFFFF000) + x, PAGE_PRESENT | PAGE_USER)) != 0x0)
620  K_PANIC("vmm_setPageAttributes failed");
621  }
622  }
623  if (binaryHeader->eEntry >= programHeader[i].phVaddr && binaryHeader->eEntry < (programHeader[i].phVaddr + programHeader[i].phMemsz)) {
624  /* We're suposed to do something here? */
625  }
626  else {
627  _current->td.vm_dsize = seg_size >> PAGE_SHIFT;
628  _current->td.vm_daddr = (char *) seg_addr;
629  }
630 
631  _current->oInfo.vmStart = ((programHeader[i].phVaddr & 0xFFFFF000) + 0xA900000);
632  break;
633  case PT_INTERP:
634  interp = (char *) kmalloc(programHeader[i].phFilesz);
635  if (interp == 0x0)
636  K_PANIC("malloc failed")
637  ;
638 
639  fseek(_current->files[0], programHeader[i].phOffset, 0);
640  fread((void *) interp, programHeader[i].phFilesz, 1, _current->files[0]);
641  kprintf("Interp: [%s]\n", interp);
642  //ldAddr = ldEnable();
643  break;
644  case PT_PHDR:
645  proghdr = programHeader[i].phVaddr;
646  break;
647  default:
648  break;
649  }
650  }
651 
652  addr = LD_START;
653 
654  if (interp != 0x0) {
655  //kprintf("TEST");
656  elf_loadfile(_current, interp, &addr, &eip);
657  }
658  //kprintf("[0x%X][0x%X]\n",eip,addr);
659 
660  _current->td.vm_dsize = seg_size >> PAGE_SHIFT;
661  _current->td.vm_daddr = (char *) seg_addr;
662 
664  argv = ap;
665 
666  if (argv[1] != 0x0) {
667  argc = argv[0];
668  args = (char *) vmmGetFreeVirtualPage(_current->id, 1, VM_TASK);
669  memset(args, 0x0, 0x1000);
670  x = 0x0;
671  argvNew = (char **) kmalloc(sizeof(char *) * argc);
672  for (i = 0x0; i < argc; i++) {
673  strcpy(args + x, argv[i + 1]);
674  argvNew[i] = args + x;
675  x += strlen(argv[i + 1]) + 1;
676  }
677  argv = argvNew;
678  }
679 
682 
684  iFrame = _current->tss.esp0 - sizeof(struct i386_frame);
685  iFrame->ebp = STACK_ADDR;
686  iFrame->eip = eip;
687 
688  //if (_current->id > 3) {
689 
690  iFrame->user_esp = ((uint32_t) STACK_ADDR) - (sizeof(uint32_t) * (argc + 4)); // + (sizeof(Elf_Auxargs) * 2)));
691  kprintf("\n\n\nuser_esp: [0x%X]\n", iFrame->user_esp);
692  tmp = iFrame->user_esp;
693 
695  tmp[0] = argc;
696  for (i = 0; i < argc; i++) {
697  tmp[i + 1] = argv[i];
698  }
700  args = (char *) vmmGetFreeVirtualPage(_current->id, 1, VM_TASK);
701  memset(args, 0x0, 0x1000);
702  strcpy(args, "LIBRARY_PATH=/lib");
703  tmp[argc + 2] = args;
704  kprintf("env: [0x%X][0x%X]\n", (uInt32) tmp + argc + 2, tmp[argc + 2]);
705  tmp[argc + 3] = 0x0;
706  kprintf("env: [0x%X][0x%X]\n", (uInt32) tmp + argc + 2, tmp[argc + 2]);
707  //auxargs = iFrame->user_esp + argc + 3;
708  tmp = iFrame->user_esp;
709  tmp += argc + 4;
710 
711  /*
712  auxargs->execfd = -1;
713  auxargs->phdr = proghdr;
714  auxargs->phent = binaryHeader->ePhentsize;
715  auxargs->phnum = binaryHeader->ePhnum;
716  auxargs->pagesz = PAGE_SIZE;
717  auxargs->base = addr;
718  auxargs->flags = 0x0;
719  auxargs->entry = binaryHeader->eEntry;
720  auxargs->trace = 0x0;
721 
722  AUXARGS_ENTRY(tmp, AT_PHDR, auxargs->phdr);
723  AUXARGS_ENTRY(tmp, AT_PHENT, auxargs->phent);
724  AUXARGS_ENTRY(tmp, AT_PHNUM, auxargs->phnum);
725  AUXARGS_ENTRY(tmp, AT_PAGESZ, auxargs->pagesz);
726  AUXARGS_ENTRY(tmp, AT_FLAGS, auxargs->flags);
727  AUXARGS_ENTRY(tmp, AT_ENTRY, auxargs->entry);
728  AUXARGS_ENTRY(tmp, AT_BASE, auxargs->base);
729  AUXARGS_ENTRY(tmp, AT_NULL, 0);
730 
731  kprintf("AT_BASE: [0x%X]\n",auxargs->base);
732  */
733 
734  //iFrame->ebx = 0x0;
735  //iFrame->ebx = 0x0;
736  //iFrame->eip = binaryHeader->eEntry;
737  //kprintf("\n\nDOH: [0x%X]\n\n",iFrame->eip);
738 //while (1);
739  //while (1);
740  /*
741  error = elf_loadfile(_current,file,0x0,0x0);
742  if (error)
743  K_PANIC("elf_loadfile failed");
744  */
745  return;
746 }
747 
748 /***
749  END
750  ***/
sys_exec
void sys_exec(char *file, char *ap)
New exec...
Definition: exec.c:551
taskStruct
Definition: sched.h:62
i386_frame::user_esp
uint32_t user_esp
Definition: tss.h:105
vmm_cleanVirtualSpace
int vmm_cleanVirtualSpace(uint32_t)
Definition: paging.c:587
strcpy
char * strcpy(char *, const char *)
uInt32
unsigned long int uInt32
Definition: objgfx30.h:49
fopen
fileDescriptor_t * fopen(const char *file, const char *flags)
Definition: file.c:395
tssStruct::eip
long eip
Definition: tss.h:47
PT_PHDR
#define PT_PHDR
Definition: elf_common.h:497
K_PANIC
#define K_PANIC(msg)
Definition: kpanic.h:32
tssStruct::ss1
short ss1
Definition: tss.h:41
fileDescriptor
Definition: file.h:62
tssStruct::ldt
short ldt
Definition: tss.h:66
PT_DYNAMIC
#define PT_DYNAMIC
Definition: elf_common.h:493
fread
size_t fread(void *ptr, size_t size, size_t nmemb, fileDescriptor_t *fd)
Definition: file.c:297
file
Definition: descrip.h:67
kfree
void kfree(void *baseAddr)
Definition: kmalloc.c:342
tssStruct::ds
short ds
Definition: tss.h:60
assert
#define assert(e)
Definition: assert.h:64
assert.h
trunc_page
#define trunc_page(x)
Definition: paging.h:71
tssStruct::eflags
long eflags
Definition: tss.h:48
vmm.h
tssStruct::esp0
long esp0
Definition: tss.h:37
tssStruct::back_link
short back_link
Definition: tss.h:35
round_page
#define round_page(x)
Definition: paging.h:72
endtask.h
strlen
int strlen(const char *str)
Definition: strlen.c:55
taskStruct::tss
struct tssStruct tss
Definition: sched.h:67
exec.h
i386_frame::eip
uint32_t eip
Definition: tss.h:102
ET_EXEC
#define ET_EXEC
Definition: elf_common.h:191
tssStruct::ss0
short ss0
Definition: tss.h:38
STACK_ADDR
#define STACK_ADDR
Definition: exec.c:40
PT_LOAD
#define PT_LOAD
Definition: elf_common.h:492
kpanic
void kpanic(const char *fmt,...)
print panic message and halt system
Definition: kpanic.c:41
tssStruct::ss2
short ss2
Definition: tss.h:44
taskStruct::td
struct thread td
Definition: sched.h:78
osInfo::vmStart
uInt32 vmStart
Definition: sched.h:54
i386_frame
Definition: tss.h:84
tssStruct::esp
long esp
Definition: tss.h:50
VM_TASK
#define VM_TASK
Definition: paging.h:52
tty_find
tty_term * tty_find(uInt16)
Definition: tty.c:167
LD_START
#define LD_START
Definition: kmod.h:34
kpanic.h
taskStruct::id
pidType id
Definition: sched.h:63
vmm_findFreePage
uint32_t vmm_findFreePage(pidType pid)
Definition: vmm_memory.c:221
vmm_setPageAttributes
int vmm_setPageAttributes(uint32_t, uint16_t)
Definition: setpageattributes.c:39
fclose
int fclose(fileDescriptor_t *fd)
Definition: file.c:533
kprintf.h
taskStruct::term
tty_term * term
Definition: sched.h:77
kernelPageDirectory
uint32_t * kernelPageDirectory
Definition: paging.c:41
ldEnable
uInt32 ldEnable()
PAGE_STACK
#define PAGE_STACK
Definition: paging.h:65
tssStruct::ss
short ss
Definition: tss.h:58
PAGE_DEFAULT
#define PAGE_DEFAULT
Definition: paging.h:68
taskStruct::files
fileDescriptor_t * files[MAX_OFILES]
Definition: sched.h:71
tssStruct::esp1
long esp1
Definition: tss.h:40
vmm_remapPage
int vmm_remapPage(uint32_t, uint32_t, uint16_t, pidType, int haveLock)
Definition: paging.c:199
uint32_t
__uint32_t uint32_t
Definition: types.h:46
ld.h
i386_frame::ebp
uint32_t ebp
Definition: tss.h:92
execThread
uInt32 execThread(void(*tproc)(void), uInt32 stack, char *arg)
Definition: exec.c:66
tssStruct::es
short es
Definition: tss.h:54
endTask
void endTask(pidType)
Definition: endtask.c:44
thread::vm_dsize
u_long vm_dsize
Definition: thread.h:44
_current
kTask_t * _current
Definition: sched.c:50
sched_setStatus
int sched_setStatus(pidType pid, tState state)
Definition: sched.c:265
fileDescriptor::perms
uint32_t perms
Definition: file.h:76
tssStruct::cs
short cs
Definition: tss.h:56
schedNewTask
kTask_t * schedNewTask()
Definition: sched.c:135
tssStruct::fs
short fs
Definition: tss.h:62
thread::vm_daddr
u_long vm_daddr
Definition: thread.h:43
tssStruct::edi
long edi
Definition: tss.h:53
taskStruct::uid
uint32_t uid
Definition: sched.h:73
tssStruct::io_map
short io_map
Definition: tss.h:69
tssStruct::ebp
long ebp
Definition: tss.h:51
kmalloc
void * kmalloc(uInt32 len)
Definition: kmalloc.c:241
execFile
void execFile(char *file, int argc, char **argv, int console)
Definition: exec.c:153
memset
void * memset(void *dst, int c, size_t length)
tssStruct::esi
long esi
Definition: tss.h:52
READY
Definition: sched.h:47
PAGE_SHIFT
#define PAGE_SHIFT
Definition: paging.h:36
PAGE_SIZE
#define PAGE_SIZE
Definition: paging.h:37
PAGE_USER
#define PAGE_USER
Definition: paging.h:57
KERNEL_PAGE_DEFAULT
#define KERNEL_PAGE_DEFAULT
Definition: paging.h:69
tssStruct::trace_bitmap
short trace_bitmap
Definition: tss.h:68
sysExec
void sysExec(char *file, char *ap)
Definition: exec.c:340
kprintf
int kprintf(const char *,...)
Definition: kprintf.c:259
u_int
unsigned int u_int
Definition: types.h:72
tty_termNode::owner
pidType owner
Definition: tty.h:42
tssStruct::cr3
long cr3
Definition: tss.h:46
tssStruct::esp2
long esp2
Definition: tss.h:43
elf.h
tssStruct::gs
short gs
Definition: tss.h:64
PT_INTERP
#define PT_INTERP
Definition: elf_common.h:494
PAGE_PRESENT
#define PAGE_PRESENT
Definition: paging.h:55
kmalloc.h
taskStruct::oInfo
struct osInfo oInfo
Definition: sched.h:69
taskStruct::gid
uint32_t gid
Definition: sched.h:73
fseek
int fseek(fileDescriptor_t *tmpFd, long offset, int whence)
Definition: file.c:332