UbixOS V2 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 */
166 _current = schedNewTask();
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 */
175 _current->term->owner = _current->id;
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++) {
271 vmm_remapPage(vmm_findFreePage(_current->id), STACK_ADDR - (x * 0x1000), PAGE_DEFAULT | PAGE_STACK);
272 }
273
274 /* Kernel Stack 0x2000 bytes long */
275 vmm_remapPage(vmm_findFreePage(_current->id), 0x5BC000, KERNEL_PAGE_DEFAULT | PAGE_STACK);
276 vmm_remapPage(vmm_findFreePage(_current->id), 0x5BB000, KERNEL_PAGE_DEFAULT | PAGE_STACK);
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;
289 _current->tss.ebp = STACK_ADDR;
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
305 sched_setStatus(_current->id, READY);
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
515 vmm_cleanVirtualSpace(_current->td.vm_daddr + (_current->td.vm_dsize << PAGE_SIZE));
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
681 vmm_cleanVirtualSpace(_current->td.vm_daddr + (_current->td.vm_dsize << PAGE_SIZE));
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:388
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:291
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:526
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:326