/*-
* Copyright (c) 2002-2018 The UbixOS Project.
* All rights reserved.
*
* This was developed by Christopher W. Olsen for the UbixOS Project.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* 1) Redistributions of source code must retain the above copyright notice, this list of
* conditions, the following disclaimer and the list of authors.
* 2) Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions, the following disclaimer and the list of authors in the documentation and/or
* other materials provided with the distribution.
* 3) Neither the name of the UbixOS Project nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <ubixos/exec.h>
#include <sys/elf.h>
#include <ubixos/ld.h>
#include <ubixos/kpanic.h>
#include <ubixos/endtask.h>
#include <vmm/vmm.h>
#include <lib/kmalloc.h>
#include <lib/kprintf.h>
#include <lib/string.h>
#include <assert.h>
#define STACK_ADDR 0xC800000
#define AT_NULL 0 /* Terminates the vector. */
#define AT_IGNORE 1 /* Ignored entry. */
#define AT_EXECFD 2 /* File descriptor of program to load. */
#define AT_PHDR 3 /* Program header of program already loaded. */
#define AT_PHENT 4 /* Size of each program header entry. */
#define AT_PHNUM 5 /* Number of program header entries. */
#define AT_PAGESZ 6 /* Page size in bytes. */
#define AT_BASE 7 /* Interpreter's base address. */
#define AT_FLAGS 8 /* Flags (unused for i386). */
#define AT_ENTRY 9 /* Where interpreter should transfer control. */
//#define AUXARGS_ENTRY(pos, id, val) {memcpy((void *)pos++,(void *)id,sizeof(long)); memcpy((void *)pos++,(void *)val,sizeof(long));}
#define AUXARGS_ENTRY(pos, id, val) {*pos = id;pos++; *pos = val;pos++;}
/*****************************************************************************************
Function: execThread(void (*)(void),int,char *);
Description: This function will create a thread from code in the current memory space
Notes:
05/19/04 - This does not work the way I want it to it still makes a copy of kernel space
so do not use out side of kernel space
*****************************************************************************************/
uInt32 execThread(void (*tproc)(void), uInt32 stack, char *arg) {
kTask_t * newProcess = 0x0;
/* Find A New Thread */
newProcess = schedNewTask();
assert(newProcess);
if (stack < 0x100000)
kpanic("exec: stack not in valid area: [0x%X]\n", stack);
/* Set All The Correct Thread Attributes */
newProcess->tss.back_link = 0x0;
newProcess->tss.esp0 = 0x0;
newProcess->tss.ss0 = 0x0;
newProcess->tss.esp1 = 0x0;
newProcess->tss.ss1 = 0x0;
newProcess->tss.esp2 = 0x0;
newProcess->tss.ss2 = 0x0;
newProcess->tss.cr3 = (unsigned int) kernelPageDirectory;
newProcess->tss.eip = (unsigned int) tproc;
newProcess->tss.eflags = 0x206;
newProcess->tss.esp = stack;
newProcess->tss.ebp = stack;
newProcess->tss.esi = 0x0;
newProcess->tss.edi = 0x0;
/* Set these up to be ring 3 tasks */
/*
newProcess->tss.es = 0x30+3;
newProcess->tss.cs = 0x28+3;
newProcess->tss.ss = 0x30+3;
newProcess->tss.ds = 0x30+3;
newProcess->tss.fs = 0x30+3;
newProcess->tss.gs = 0x30+3;
*/
newProcess->tss.es = 0x10;
newProcess->tss.cs = 0x08;
newProcess->tss.ss = 0x10;
newProcess->tss.ds = 0x10;
newProcess->tss.fs = 0x10;
newProcess->tss.gs = 0x10;
newProcess->tss.ldt = 0x18;
newProcess->tss.trace_bitmap = 0x0000;
newProcess->tss.io_map = 0x8000;
newProcess->oInfo.vmStart = 0x6400000;
//newProcess->imageFd = 0x0;
/* Set up default stack for thread here filled with arg list 3 times */
asm volatile(
"pusha \n"
"movl %%esp,%%ecx \n"
"movl %1,%%eax \n"
"movl %%eax,%%esp \n"
"pushl %%ebx \n"
"pushl %%ebx \n"
"pushl %%ebx \n"
"movl %%esp,%%eax \n"
"movl %%eax,%1 \n"
"movl %%ecx,%%esp \n"
"popa \n"
:
: "b" (arg),"m" (newProcess->tss.esp)
);
/* Put new thread into the READY state */
sched_setStatus(newProcess->id, READY);
/* Return with the new process ID */
return ((uInt32) newProcess);
}
/*****************************************************************************************
Function: void execFile(char *file);
Description: This Function Executes A Kile Into A New VM Space With Out
Having To Fork
Notes:
07/30/02 - I Have Made Some Heavy Changes To This As Well As Fixed A Few
Memory Leaks The Memory Allocated To Load The Binary Into Is
Now Unmapped So It Can Be Used Again And Not Held Onto Until
The Program Exits
07/30/02 - Now I Have To Make A Better Memory Allocator So We Can Set Up
The Freshly Allocated Pages With The Correct Permissions
*****************************************************************************************/
void execFile(char *file, int argc, char **argv, int console) {
int i = 0x0;
int x = 0x0;
uint32_t *tmp = 0x0;
fileDescriptor *tmpFd = 0x0;
elfHeader *binaryHeader = 0x0;
elfProgramHeader *programHeader = 0x0;
/* Get A New Task For This Proccess */
_current = schedNewTask();
assert(_current);
_current->gid = 0x0;
_current->uid = 0x0;
_current->term = tty_find(console);
if (_current->term == 0x0)
kprintf("Error: invalid console\n");
/* Set tty ownership */
_current->term->owner = _current->id;
/* Now We Must Create A Virtual Space For This Proccess To Run In */
_current->tss.cr3 = (uInt32) vmmCreateVirtualSpace(_current->id);
/* To Better Load This Application We Will Switch Over To Its VM Space */
asm volatile(
"movl %0,%%eax \n"
"movl %%eax,%%cr3 \n"
: : "d" ((uInt32 *)(_current->tss.cr3))
);
/* Lets Find The File */
tmpFd = fopen(file, "r");
/* If We Dont Find the File Return */
if (tmpFd == 0x0) {
kprintf("Exec Format Error: Binary File Not Executable.\n");
fclose(tmpFd);
return;
}
if (tmpFd->perms == 0x0) {
kprintf("Exec Format Error: Binary File Not Executable.\n");
fclose(tmpFd);
return;
}
/* Load ELF Header */
binaryHeader = (elfHeader *) kmalloc(sizeof(elfHeader));
//kprintf(">a:%i:0x%X:0x%X<",sizeof(elfHeader),binaryHeader,tmpFd);
fread(binaryHeader, sizeof(elfHeader), 1, tmpFd);
/* Check If App Is A Real Application */
if ((binaryHeader->eIdent[1] != 'E') && (binaryHeader->eIdent[2] != 'L') && (binaryHeader->eIdent[3] != 'F')) {
kprintf("Exec Format Error: Binary File Not Executable.\n");
kfree(binaryHeader);
fclose(tmpFd);
return;
}
else if (binaryHeader->eType != 2) {
kprintf("Exec Format Error: Binary File Not Executable.\n");
kfree(binaryHeader);
fclose(tmpFd);
return;
}
else if (binaryHeader->eEntry == 0x300000) {
kprintf("Exec Format Error: Binary File Not Executable.\n");
kfree(binaryHeader);
fclose(tmpFd);
return;
}
/* Load The Program Header(s) */
programHeader = (elfProgramHeader *) kmalloc(sizeof(elfProgramHeader) * binaryHeader->ePhnum);
fseek(tmpFd, binaryHeader->ePhoff, 0);
//kprintf(">c:%i:0x%X:0x%X<",sizeof(elfProgramHeader)*binaryHeader->ePhnum,programHeader,tmpFd);
fread(programHeader, (sizeof(elfProgramHeader) * binaryHeader->ePhnum), 1, tmpFd);
//kprintf(">d<");
/* Loop Through The Header And Load Sections Which Need To Be Loaded */
for (i = 0; i < binaryHeader->ePhnum; i++) {
if (programHeader[i].phType == 1) {
/*
Allocate Memory Im Going To Have To Make This Load Memory With Correct
Settings so it helps us in the future
*/
for (x = 0x0; x < (programHeader[i].phMemsz); x += 0x1000) {
/* Make readonly and read/write !!! */
if (vmm_remapPage(vmm_findFreePage(_current->id), ((programHeader[i].phVaddr & 0xFFFFF000) + x), PAGE_DEFAULT) == 0x0)
K_PANIC("Remap Page Failed");
memset((void *) ((programHeader[i].phVaddr & 0xFFFFF000) + x), 0x0, 0x1000);
}
_current->oInfo.vmStart = 0x80000000;
_current->td.vm_daddr = (char *) (programHeader[i].phVaddr & 0xFFFFF000);
/* Now Load Section To Memory */
fseek(tmpFd, programHeader[i].phOffset, 0);
fread((void *) programHeader[i].phVaddr, programHeader[i].phFilesz, 1, tmpFd);
if ((programHeader[i].phFlags & 0x2) != 0x2) {
kprintf("pH: [0x%X]\n", programHeader[i].phMemsz);
for (x = 0x0; x < (programHeader[i].phMemsz); x += 0x1000) {
if ((vmm_setPageAttributes((programHeader[i].phVaddr & 0xFFFFF000) + x, PAGE_PRESENT | PAGE_USER)) != 0x0)
kpanic("Error: vmm_setPageAttributes failed, File: %s, Line: %i\n", __FILE__, __LINE__);
}
}
}
}
/* Set Virtual Memory Start */
_current->oInfo.vmStart = 0x80000000;
_current->td.vm_daddr = (char *) (programHeader[i].phVaddr & 0xFFFFF000);
/* Set Up Stack Space */
for (x = 1; x < 100; x++) {
vmm_remapPage(vmm_findFreePage(_current->id), STACK_ADDR - (x * 0x1000), PAGE_DEFAULT | PAGE_STACK);
}
/* Kernel Stack 0x2000 bytes long */
vmm_remapPage(vmm_findFreePage(_current->id), 0x5BC000, KERNEL_PAGE_DEFAULT | PAGE_STACK);
vmm_remapPage(vmm_findFreePage(_current->id), 0x5BB000, KERNEL_PAGE_DEFAULT | PAGE_STACK);
/* Set All The Proper Information For The Task */
_current->tss.back_link = 0x0;
_current->tss.esp0 = 0x5BC000;
_current->tss.ss0 = 0x10;
_current->tss.esp1 = 0x0;
_current->tss.ss1 = 0x0;
_current->tss.esp2 = 0x0;
_current->tss.ss2 = 0x0;
_current->tss.eip = (long) binaryHeader->eEntry;
_current->tss.eflags = 0x206;
_current->tss.esp = STACK_ADDR - 12;
_current->tss.ebp = STACK_ADDR;
_current->tss.esi = 0x0;
_current->tss.edi = 0x0;
/* Set these up to be ring 3 tasks */
_current->tss.es = 0x30 + 3;
_current->tss.cs = 0x28 + 3;
_current->tss.ss = 0x30 + 3;
_current->tss.ds = 0x30 + 3;
_current->tss.fs = 0x30 + 3;
_current->tss.gs = 0x30 + 3;
_current->tss.ldt = 0x18;
_current->tss.trace_bitmap = 0x0000;
_current->tss.io_map = 0x8000;
sched_setStatus(_current->id, READY);
kfree(binaryHeader);
kfree(programHeader);
fclose(tmpFd);
tmp = (uInt32 *) _current->tss.esp0 - 5;
tmp[0] = binaryHeader->eEntry;
tmp[3] = STACK_ADDR - 12;
tmp = (uInt32 *) STACK_ADDR - 2;
if (_current->id > 4)
kprintf("argv[0]: [%s]\n", argv[0]);
kprintf("argv: [0x%X]\n", argv);
tmp[0] = (uint32_t) argv;
tmp[1] = (uint32_t) argv;
/* Switch Back To The Kernels VM Space */
asm volatile(
"movl %0,%%eax \n"
"movl %%eax,%%cr3 \n"
: : "d" ((uInt32 *)(kernelPageDirectory))
);
/* Finally Return */
return;
}
/*****************************************************************************************
Function: void sysExec();
Description: This Is The System Call To Execute A New Task
Notes:
04-22-03 - It Now Loads Sections Not The Full File
*****************************************************************************************/
void sysExec(char *file, char *ap) {
int i = 0x0;
int x = 0x0;
int argc = 0x0;
unsigned int *tmp = 0x0;
uInt32 ldAddr = 0x0;
uInt32 seg_size = 0x0;
uInt32 seg_addr = 0x0;
char *interp = 0x0;
char **argv = 0x0;
char **argvNew = 0x0;
char *args = 0x0;
fileDescriptor *tmpFd = 0x0;
elfHeader *binaryHeader = 0x0;
elfProgramHeader *programHeader = 0x0;
elfSectionHeader *sectionHeader = 0x0;
elfDynamic *elfDynamicS = 0x0;
struct i386_frame *iFrame = 0x0;
tmpFd = fopen(file, "r");
_current->files[0] = tmpFd;
/* If We Dont Find the File Return */
if (tmpFd == 0x0) {
return;
}
if (tmpFd->perms == 0) {
kprintf("Exec Format Error: Binary File Not Executable.\n");
fclose(tmpFd);
return;
}
/* Load ELF Header */
if ((binaryHeader = (elfHeader *) kmalloc(sizeof(elfHeader))) == 0x0)
endTask(_current->id);
fread(binaryHeader, sizeof(elfHeader), 1, tmpFd);
/* Set sectionHeader To Point To Loaded Binary To We Can Gather Info */
/* Check If App Is A Real Application */
if ((binaryHeader->eIdent[1] != 'E') && (binaryHeader->eIdent[2] != 'L') && (binaryHeader->eIdent[3] != 'F')) {
kprintf("Exec Format Error: Binary File Not Executable.\n");
kfree(binaryHeader);
fclose(tmpFd);
return;
}
else if (binaryHeader->eType != 2) {
kprintf("Exec Format Error: Binary File Not Executable.\n");
kfree(binaryHeader);
fclose(tmpFd);
return;
}
else if (binaryHeader->eEntry == 0x300000) {
kprintf("Exec Format Error: Binary File Not Executable.\n");
kfree(binaryHeader);
fclose(tmpFd);
return;
}
/* Load The Program Header(s) */
if ((programHeader = (elfProgramHeader *) kmalloc(sizeof(elfProgramHeader) * binaryHeader->ePhnum)) == 0x0)
endTask(_current->id);
assert(programHeader);
fseek(tmpFd, binaryHeader->ePhoff, 0);
fread(programHeader, (sizeof(elfProgramHeader) * binaryHeader->ePhnum), 1, tmpFd);
if ((sectionHeader = (elfSectionHeader *) kmalloc(sizeof(elfSectionHeader) * binaryHeader->eShnum)) == 0x0)
endTask(_current->id);
assert(sectionHeader);
fseek(tmpFd, binaryHeader->eShoff, 0);
fread(sectionHeader, sizeof(elfSectionHeader) * binaryHeader->eShnum, 1, tmpFd);
/* Loop Through The Header And Load Sections Which Need To Be Loaded */
for (i = 0; i < binaryHeader->ePhnum; i++) {
switch (programHeader[i].phType) {
case PT_LOAD:
seg_addr = trunc_page(programHeader[i].phVaddr);
seg_size = round_page(programHeader[i].phMemsz + programHeader[i].phVaddr - seg_addr);
/*
Allocate Memory Im Going To Have To Make This Load Memory With Correct
Settings so it helps us in the future
*/
for (x = 0x0; x < (programHeader[i].phMemsz); x += 0x1000) {
/* Make readonly and read/write !!! */
if (vmm_remapPage(vmm_findFreePage(_current->id), ((programHeader[i].phVaddr & 0xFFFFF000) + x), PAGE_DEFAULT) == 0x0)
K_PANIC("Error: Remap Page Failed");
memset((void *) ((programHeader[i].phVaddr & 0xFFFFF000) + x), 0x0, 0x1000);
}
/* Now Load Section To Memory */
fseek(tmpFd, programHeader[i].phOffset, 0);
fread((void *) programHeader[i].phVaddr, programHeader[i].phFilesz, 1, tmpFd);
if ((programHeader[i].phFlags & 0x2) != 0x2) {
for (x = 0x0; x < (programHeader[i].phMemsz); x += 0x1000) {
if ((vmm_setPageAttributes((programHeader[i].phVaddr & 0xFFFFF000) + x, PAGE_PRESENT | PAGE_USER)) != 0x0)
kpanic("Error: vmm_setPageAttributes failed, File: %s,Line: %i\n", __FILE__, __LINE__);
}
}
kprintf("setting daddr\n");
if (binaryHeader->eEntry >= programHeader[i].phVaddr && binaryHeader->eEntry < (programHeader[i].phVaddr + programHeader[i].phMemsz)) {
/* We're suposed to do something here? */
}
else {
_current->td.vm_dsize = seg_size >> PAGE_SHIFT;
_current->td.vm_daddr = (char *) seg_addr;
}
_current->oInfo.vmStart = ((programHeader[i].phVaddr & 0xFFFFF000) + 0xA900000);
break;
case PT_DYNAMIC:
//newLoc = (char *)programHeader[i].phVaddr;
elfDynamicS = (elfDynamic *) programHeader[i].phVaddr;
fseek(tmpFd, programHeader[i].phOffset, 0);
fread((void *) programHeader[i].phVaddr, programHeader[i].phFilesz, 1, tmpFd);
break;
case PT_INTERP:
interp = (char *) kmalloc(programHeader[i].phFilesz);
fseek(tmpFd, programHeader[i].phOffset, 0);
fread((void *) interp, programHeader[i].phFilesz, 1, tmpFd);
kprintf("Interp: [%s]\n", interp);
ldAddr = ldEnable();
break;
default:
break;
}
}
/* What is this doing? 11/23/06 */
if (elfDynamicS != 0x0) {
for (i = 0; i < 12; i++) {
if (elfDynamicS[i].dynVal == 0x3) {
tmp = (void *) elfDynamicS[i].dynPtr;
if (tmp == 0x0)
kpanic("tmp: NULL\n");
tmp[2] = (uInt32) ldAddr;
tmp[1] = (uInt32) tmpFd;
break;
}
/*
else {
kprintf("dyn_val: %i",elfDynamicS[i].dynVal);
}
*/
}
}
_current->td.vm_dsize = seg_size >> PAGE_SHIFT;
_current->td.vm_daddr = (char *) seg_addr;
argv = ≈
if (argv[1] != 0x0) {
argc = (int) argv[0];
args = (char *) vmmGetFreeVirtualPage(_current->id, 1, VM_TASK);
memset(args, 0x0, 0x1000);
x = 0x0;
argvNew = (char **) kmalloc(sizeof(char *) * argc);
for (i = 0x0; i < argc; i++) {
strcpy(args + x, argv[i + 1]);
argvNew[i] = args + x;
x += strlen(argv[i + 1]) + 1;
//args[x] = '\0';
//x++;
}
argv = argvNew;
}
//! Clean the virtual of COW pages left over from the fork
vmm_cleanVirtualSpace(_current->td.vm_daddr + (_current->td.vm_dsize << PAGE_SIZE));
//! Adjust iframe
iFrame = (struct i386_frame *) _current->tss.esp0 - sizeof(struct i386_frame);
iFrame->ebp = STACK_ADDR;
iFrame->eip = binaryHeader->eEntry;
iFrame->user_esp = STACK_ADDR - 12;
//if (_current->id > 3) {
iFrame->user_esp = ((uint32_t) STACK_ADDR) - (sizeof(uint32_t) * (argc + 3));
tmp = (void *) iFrame->user_esp;
//! build argc and argv[]
tmp[0] = argc;
for (i = 0; i < argc; i++) {
tmp[i + 1] = (u_int) argv[i];
}
tmp[argc + 1] = 0x0;
tmp[argc + 2] = 0x1;
//}
//else {
//tmp = (uint32_t *)STACK_ADDR - 2;
//tmp[0] = 0x1;
//tmp[1] = 0x0;
//tmp[1] = (uint32_t)argv;
//}
kfree(argvNew);
/* Now That We Relocated The Binary We Can Unmap And Free Header Info */
kfree(binaryHeader);
kfree(programHeader);
return;
}
/*!
* \brief New exec...
*
*/
void sys_exec(char *file, char *ap) {
int error = 0x0;
int i = 0x0;
int x = 0x0;
int argc = 0x0;
uint32_t *tmp = 0x0;
uint32_t seg_size = 0x0;
uint32_t seg_addr = 0x0;
uint32_t addr = 0x0;
uint32_t eip = 0x0;
uint32_t proghdr = 0x0;
char *args = 0x0;
char *interp = 0x0;
char **argv = 0x0;
char **argvNew = 0x0;
elfHeader *binaryHeader = 0x0;
elfProgramHeader *programHeader = 0x0;
struct i386_frame *iFrame = 0x0;
//Elf_Auxargs *auxargs = 0x0;
_current->files[0] = fopen(file, "r");
if (_current->files[0] == 0x0)
return; //We Need To Set errno
/* Load the ELF header */
if ((binaryHeader = (elfHeader *) kmalloc(sizeof(elfHeader))) == 0x0)
K_PANIC("malloc failed!");
fread(binaryHeader, sizeof(elfHeader), 1, _current->files[0]);
/* Check If App Is A Real Application */
if (((binaryHeader->eIdent[1] != 'E') && (binaryHeader->eIdent[2] != 'L') && (binaryHeader->eIdent[3] != 'F')) || (binaryHeader->eType != ET_EXEC)) {
kfree(binaryHeader);
fclose(_current->files[0]);
return; //We Need To Set errno
}
/* Load The Program Header(s) */
if ((programHeader = (elfProgramHeader *) kmalloc(sizeof(elfProgramHeader) * binaryHeader->ePhnum)) == 0x0)
K_PANIC("malloc failed!");
fseek(_current->files[0], binaryHeader->ePhoff, 0);
fread(programHeader, (sizeof(elfProgramHeader) * binaryHeader->ePhnum), 1, _current->files[0]);
/* Loop Through The Header And Load Sections Which Need To Be Loaded */
for (i = 0x0; i < binaryHeader->ePhnum; i++) {
switch (programHeader[i].phType) {
case PT_LOAD:
seg_addr = trunc_page(programHeader[i].phVaddr);
seg_size = round_page(programHeader[i].phMemsz + programHeader[i].phVaddr - seg_addr);
/*
Allocate Memory Im Going To Have To Make This Load Memory With Correct
Settings so it helps us in the future
*/
for (x = 0x0; x < (programHeader[i].phMemsz); x += 0x1000) {
/* Make readonly and read/write !!! */
if (vmm_remapPage(vmm_findFreePage(_current->id), ((programHeader[i].phVaddr & 0xFFFFF000) + x), PAGE_DEFAULT) == 0x0)
K_PANIC("Error: Remap Page Failed");
memset((void *) ((programHeader[i].phVaddr & 0xFFFFF000) + x), 0x0, 0x1000);
}
/* Now Load Section To Memory */
fseek(_current->files[0], programHeader[i].phOffset, 0);
fread((void *) programHeader[i].phVaddr, programHeader[i].phFilesz, 1, _current->files[0]);
if ((programHeader[i].phFlags & 0x2) != 0x2) {
for (x = 0x0; x < (programHeader[i].phMemsz); x += 0x1000) {
if ((vmm_setPageAttributes((programHeader[i].phVaddr & 0xFFFFF000) + x, PAGE_PRESENT | PAGE_USER)) != 0x0)
K_PANIC("vmm_setPageAttributes failed");
}
}
if (binaryHeader->eEntry >= programHeader[i].phVaddr && binaryHeader->eEntry < (programHeader[i].phVaddr + programHeader[i].phMemsz)) {
/* We're suposed to do something here? */
}
else {
_current->td.vm_dsize = seg_size >> PAGE_SHIFT;
_current->td.vm_daddr = (char *) seg_addr;
}
_current->oInfo.vmStart = ((programHeader[i].phVaddr & 0xFFFFF000) + 0xA900000);
break;
case PT_INTERP:
interp = (char *) kmalloc(programHeader[i].phFilesz);
if (interp == 0x0)
K_PANIC("malloc failed")
;
fseek(_current->files[0], programHeader[i].phOffset, 0);
fread((void *) interp, programHeader[i].phFilesz, 1, _current->files[0]);
kprintf("Interp: [%s]\n", interp);
//ldAddr = ldEnable();
break;
case PT_PHDR:
proghdr = programHeader[i].phVaddr;
break;
default:
break;
}
}
addr = LD_START;
if (interp != 0x0) {
//kprintf("TEST");
elf_loadfile(_current, interp, &addr, &eip);
}
//kprintf("[0x%X][0x%X]\n",eip,addr);
_current->td.vm_dsize = seg_size >> PAGE_SHIFT;
_current->td.vm_daddr = (char *) seg_addr;
//! copy in arg strings
argv = ap;
if (argv[1] != 0x0) {
argc = argv[0];
args = (char *) vmmGetFreeVirtualPage(_current->id, 1, VM_TASK);
memset(args, 0x0, 0x1000);
x = 0x0;
argvNew = (char **) kmalloc(sizeof(char *) * argc);
for (i = 0x0; i < argc; i++) {
strcpy(args + x, argv[i + 1]);
argvNew[i] = args + x;
x += strlen(argv[i + 1]) + 1;
}
argv = argvNew;
}
//! Clean the virtual of COW pages left over from the fork
vmm_cleanVirtualSpace(_current->td.vm_daddr + (_current->td.vm_dsize << PAGE_SIZE));
//! Adjust iframe
iFrame = _current->tss.esp0 - sizeof(struct i386_frame);
iFrame->ebp = STACK_ADDR;
iFrame->eip = eip;
//if (_current->id > 3) {
iFrame->user_esp = ((uint32_t) STACK_ADDR) - (sizeof(uint32_t) * (argc + 4)); // + (sizeof(Elf_Auxargs) * 2)));
kprintf("\n\n\nuser_esp: [0x%X]\n", iFrame->user_esp);
tmp = iFrame->user_esp;
//! build argc and argv[]
tmp[0] = argc;
for (i = 0; i < argc; i++) {
tmp[i + 1] = argv[i];
}
//! Build ENV
args = (char *) vmmGetFreeVirtualPage(_current->id, 1, VM_TASK);
memset(args, 0x0, 0x1000);
strcpy(args, "LIBRARY_PATH=/lib");
tmp[argc + 2] = args;
kprintf("env: [0x%X][0x%X]\n", (uInt32) tmp + argc + 2, tmp[argc + 2]);
tmp[argc + 3] = 0x0;
kprintf("env: [0x%X][0x%X]\n", (uInt32) tmp + argc + 2, tmp[argc + 2]);
//auxargs = iFrame->user_esp + argc + 3;
tmp = iFrame->user_esp;
tmp += argc + 4;
/*
auxargs->execfd = -1;
auxargs->phdr = proghdr;
auxargs->phent = binaryHeader->ePhentsize;
auxargs->phnum = binaryHeader->ePhnum;
auxargs->pagesz = PAGE_SIZE;
auxargs->base = addr;
auxargs->flags = 0x0;
auxargs->entry = binaryHeader->eEntry;
auxargs->trace = 0x0;
AUXARGS_ENTRY(tmp, AT_PHDR, auxargs->phdr);
AUXARGS_ENTRY(tmp, AT_PHENT, auxargs->phent);
AUXARGS_ENTRY(tmp, AT_PHNUM, auxargs->phnum);
AUXARGS_ENTRY(tmp, AT_PAGESZ, auxargs->pagesz);
AUXARGS_ENTRY(tmp, AT_FLAGS, auxargs->flags);
AUXARGS_ENTRY(tmp, AT_ENTRY, auxargs->entry);
AUXARGS_ENTRY(tmp, AT_BASE, auxargs->base);
AUXARGS_ENTRY(tmp, AT_NULL, 0);
kprintf("AT_BASE: [0x%X]\n",auxargs->base);
*/
//iFrame->ebx = 0x0;
//iFrame->ebx = 0x0;
//iFrame->eip = binaryHeader->eEntry;
//kprintf("\n\nDOH: [0x%X]\n\n",iFrame->eip);
//while (1);
//while (1);
/*
error = elf_loadfile(_current,file,0x0,0x0);
if (error)
K_PANIC("elf_loadfile failed");
*/
return;
}
/***
END
***/