9,6 → 9,9 |
|
int __stdcall strncmp(const char *s1, const char *s2, size_t n); |
|
extern int __stdcall mnt_exec(void *raw, size_t raw_size, char *path, |
char *cmdline, u32_t flags) asm ("mnt_exec"); |
|
static dll_t core_dll; |
|
static char* strupr(char *str ) |
27,6 → 30,37 |
return( str ); |
} |
|
void * memcpy(void * _dest, const void *_src, size_t _n) |
{ |
int d0, d1, d2; |
__asm__ __volatile__( |
"rep ; movsl\n\t" |
"testb $2,%b4\n\t" |
"je 1f\n\t" |
"movsw\n" |
"1:\ttestb $1,%b4\n\t" |
"je 2f\n\t" |
"movsb\n" |
"2:" |
: "=&c" (d0), "=&D" (d1), "=&S" (d2) |
:"0" (_n/4), "q" (_n),"1" ((long)_dest),"2" ((long)_src) |
: "memory"); |
return (_dest); |
} |
|
size_t strlen(const char *str) |
{ |
int d0; |
register int __res; |
__asm__ __volatile__( |
"repne\n\t" |
"scasb\n\t" |
"notl %0\n\t" |
"decl %0" |
:"=c" (__res), "=&D" (d0) :"1" (str),"a" (0), "0" (0xffffffff)); |
return __res; |
} |
|
void init_core_dll() |
{ |
PIMAGE_DOS_HEADER dos; |
124,3 → 158,221 |
} |
} |
|
typedef struct |
{ |
int a_type; |
union |
{ |
long a_val; |
void *a_ptr; |
void (*a_fcn)( ) ; |
}a_un; |
}auxv_t; |
|
#define AUX_COUNT 0 |
|
typedef struct |
{ |
int argc; /* always 2 */ |
char *path; /* argv[0] program path */ |
char *cmdline; /* argv[1] command line. May be null */ |
u32_t sep1; /* separator. must be zero */ |
char *env; /* single environment string */ |
u32_t sep2; /* separator. must be zero */ |
auxv_t aux[1]; /* aux. AT_NULL for now */ |
}exec_stack_t; |
|
|
addr_t new_app_space(void); |
|
int __stdcall pe_app_param(char *path, void *raw, addr_t ex_pg_dir, |
addr_t ex_stack_page) asm ("pe_app_param"); |
|
int sys_exec(char *path, char *cmdline, u32_t flags) |
{ |
addr_t ex_pg_dir; |
addr_t ex_stack_tab; |
addr_t ex_stack_page; |
addr_t ex_pl0_stack; |
|
exec_stack_t *ex_stack; |
int stack_size; |
char *ex_path; |
char *ex_cmdline = NULL; |
|
size_t raw_size; |
u32_t *raw; |
|
int pathsize = 0; |
int cmdsize = 0; |
int envsize = 0; |
|
u32_t tmp; |
|
DBG("\nexec %s cmd %s flags %x\n", path, cmdline, flags); |
|
if( ! path) |
{ |
DBG("invalid path\n"); |
return; |
}; |
|
raw = load_file(path, &raw_size); |
|
if( ! raw ) |
return -5; /* FIXME */ |
|
if( (raw[0] == 0x554E454D) && |
( ( raw[1] == 0x31305445) || |
( raw[1] == 0x30305445) ) ) |
|
{ |
DBG("leagacy Kolibri application\n"); |
int tmp = mnt_exec(raw, raw_size, path, cmdline, flags); |
return tmp; |
} |
|
if( ! validate_pe(raw, raw_size) ) |
{ |
DBG("invalid executable file %s\n", path); |
mem_free(raw); |
return -31; |
} |
|
pathsize = strlen(path)+1; |
|
if( cmdline ) |
cmdsize = strlen(cmdline)+1; |
|
stack_size = sizeof(exec_stack_t) + pathsize + |
cmdsize + envsize + AUX_COUNT*sizeof(auxv_t); |
|
stack_size = (stack_size + 15) & ~15; /* keep stack aligned */ |
|
DBG("stacksize %d\n", stack_size); |
|
if( stack_size > 4096 ) |
{ |
DBG("command line too long\n"); |
return -30; |
} |
|
ex_pg_dir = new_app_space(); |
|
if( !ex_pg_dir ) |
{ |
mem_free(raw); |
return -30; /* FIXME */ |
}; |
|
ex_stack_tab = ex_pg_dir + 4096; |
ex_pl0_stack = ex_pg_dir + 4096 * 2; |
|
ex_stack_page = core_alloc(0); /* 2^0 = 1 page */ |
|
if( ! ex_stack_page ) |
{ |
core_free(ex_stack_tab); |
mem_free(raw); |
return -30; /* FIXME */ |
}; |
|
__asm__ __volatile__ ( |
"xorl %%eax, %%eax \n\t" |
"rep stosl" |
:"=c"(tmp),"=D"(tmp) |
:"c"(1024),"D"(ex_stack_page + OS_BASE) |
:"eax","cc"); |
|
((u32_t*)(ex_stack_tab+OS_BASE))[1023] = ex_stack_page | 7; |
|
ex_stack = (exec_stack_t*)(ex_stack_page + OS_BASE |
+ PAGE_SIZE - stack_size); |
ex_stack->argc = 2; |
|
ex_path = MakePtr(char*, ex_stack, sizeof(exec_stack_t)+AUX_COUNT*sizeof(auxv_t)); |
|
memcpy(ex_path, path, pathsize); |
ex_stack->path = (char*)(((addr_t)ex_path & 0xFFF) + 0x7FCFF000); /* top of stack */ |
|
if( cmdline ) |
{ |
ex_cmdline = ex_path + pathsize; |
memcpy(ex_cmdline, cmdline, cmdsize); |
ex_stack->cmdline = ex_stack->path + pathsize; |
}; |
|
/* |
ex_stack.env = null |
ex_stack.aux[0] = AT_NULL |
*/ |
|
DBG("create stack at %x\n\tpath %x\n\tcmdline %x\n", |
ex_stack, ex_stack->path, ex_stack->cmdline); |
|
pe_app_param(path, raw, ex_pg_dir, ex_stack_page); |
return 0; |
}; |
|
#define master_tab (page_tabs+ (page_tabs>>10)) |
|
void sys_app_entry(addr_t raw, addr_t ex_stack) |
{ |
PIMAGE_DOS_HEADER dos; |
PIMAGE_NT_HEADERS32 nt; |
|
size_t img_size; |
count_t img_pages; |
count_t img_tabs; |
count_t i; |
u32_t tmp; |
|
__asm__ __volatile__ ("sti"); |
|
DBG("pe_app_entry: raw %x esp %x\n", raw, ex_stack); |
|
dos = (PIMAGE_DOS_HEADER)raw; |
nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew); |
|
img_size = nt->OptionalHeader.SizeOfImage; |
|
img_pages = img_size >> 12; |
img_tabs = ((img_size + 0x3FFFFF) & ~0x3FFFFF) >> 22; |
|
DBG("app pages %d app tabs %d\n", img_pages, img_tabs); |
|
for(i = 0; i < img_tabs; i++) |
{ |
addr_t tab = core_alloc(0); |
((u32_t*)master_tab)[i] = tab|7; /* FIXME */ |
} |
|
((u32_t*)master_tab)[0x7FC/4] = (ex_stack & 0xFFFFF000)|7; /* FIXME */ |
|
__asm__ __volatile__ ( |
"xorl %%eax, %%eax \n\t" |
"rep stosl" |
:"=c"(tmp),"=D"(tmp) |
:"c"(img_tabs<<10),"D"(page_tabs) |
:"eax","cc"); |
|
for(i = 0; i < img_pages; i++) |
{ |
addr_t page = core_alloc(0); |
((u32_t*)page_tabs)[i] = page | 7; /* FIXME */ |
} |
|
create_image(0, raw); |
|
__asm__ __volatile__ ( |
"xchgw %bx, %bx"); |
|
addr_t entry = nt->OptionalHeader.AddressOfEntryPoint + |
nt->OptionalHeader.ImageBase; |
|
// __asm__ __volatile__ ( |
// "call %0":: "r" (entry)); |
|
while(1); |
|
}; |