25,20 → 25,21 |
int (*main)(int argc, char **argv, char **envp); |
}; |
|
int _argc; |
char **_argv; |
void _pei386_runtime_relocator (void); |
void init_loader(void *libc_image); |
void init_reent(); |
|
|
int link_app(); |
void* get_entry_point(void *raw); |
int (*entry)(int, char **, char **); |
|
void init_loader(void *libc_image); |
char __appcwd[1024]; |
int __appcwdlen; |
char* __appenv; |
int __appenv_size; |
|
extern char _tls_map[128]; |
|
void init_reent(); |
|
jmp_buf loader_env; |
|
void __attribute__((noreturn)) |
__thread_startup (int (*entry)(void*), void *param, |
void *stacklow, void *stackhigh) |
45,7 → 46,7 |
{ |
int retval; |
|
asm volatile ( "xchgw %bx, %bx"); |
// asm volatile ( "xchgw %bx, %bx"); |
|
__asm__ __volatile__( // save stack limits |
"movl %0, %%fs:8 \n\t" // use TLS |
64,29 → 65,129 |
return NULL; |
} |
|
void _pei386_runtime_relocator (void); |
int link_app(); |
static int split_cmdline(char *cmdline, char **argv) |
{ |
enum quote_state |
{ |
QUOTE_NONE, /* no " active in current parm */ |
QUOTE_DELIMITER, /* " was first char and must be last */ |
QUOTE_STARTED /* " was seen, look for a match */ |
}; |
|
char __appcwd[1024]; |
int __appcwdlen; |
char* __appenv; |
int __appenv_size; |
enum quote_state state; |
unsigned int argc; |
char *p = cmdline; |
char *new_arg, *start; |
|
static char *arg[2]; |
argc = 0; |
|
extern char _tls_map[128]; |
for(;;) |
{ |
/* skip over spaces and tabs */ |
if ( *p ) |
{ |
while (*p == ' ' || *p == '\t') |
++p; |
} |
|
if (*p == '\0') |
break; |
|
state = QUOTE_NONE; |
if( *p == '\"' ) |
{ |
p++; |
state = QUOTE_DELIMITER; |
} |
new_arg = start = p; |
for (;;) |
{ |
if( *p == '\"' ) |
{ |
p++; |
if( state == QUOTE_NONE ) |
{ |
state = QUOTE_STARTED; |
} |
else |
{ |
state = QUOTE_NONE; |
} |
continue; |
} |
|
if( *p == ' ' || *p == '\t' ) |
{ |
if( state == QUOTE_NONE ) |
{ |
break; |
} |
} |
|
if( *p == '\0' ) |
break; |
|
if( *p == '\\' ) |
{ |
if( p[1] == '\"' ) |
{ |
++p; |
if( p[-2] == '\\' ) |
{ |
continue; |
} |
} |
} |
if( argv ) |
{ |
*(new_arg++) = *p; |
} |
++p; |
}; |
|
if( argv ) |
{ |
argv[ argc ] = start; |
++argc; |
|
/* |
The *new = '\0' is req'd in case there was a \" to " |
translation. It must be after the *p check against |
'\0' because new and p could point to the same char |
in which case the scan would be terminated too soon. |
*/ |
|
if( *p == '\0' ) |
{ |
*new_arg = '\0'; |
break; |
} |
*new_arg = '\0'; |
++p; |
} |
else |
{ |
++argc; |
if( *p == '\0' ) |
{ |
break; |
} |
++p; |
} |
} |
|
return argc; |
}; |
|
void __attribute__((noreturn)) |
libc_crt_startup (void *libc_base) |
{ |
struct app_hdr *header = NULL; |
int retval = 0; |
|
int len; |
char *p; |
char **argv; |
int argc; |
|
void *my_app; |
int retval = 0; |
|
_pei386_runtime_relocator(); |
|
memset(_tls_map, 0xFF, 32*4); |
106,18 → 207,23 |
memcpy(__appcwd, header->path, __appcwdlen); |
set_cwd(__appcwd); |
|
arg[0] = header->path; |
|
if( header->cmdline[0] != 0) |
{ |
_argc = 2; |
arg[1] = header->cmdline; |
argc = split_cmdline(header->cmdline, NULL) + 1; |
argv = alloca((argc+1)*sizeof(char*)); |
argv[0] = header->path; |
|
split_cmdline(header->cmdline, argv + 1); |
} |
else _argc = 1; |
else |
{ |
argc = 1; |
argv = alloca((argc+1)*sizeof(char*)); |
argv[0] = header->path; |
} |
argv[argc] = NULL; |
|
_argv = arg; |
|
retval = header->main(_argc, _argv, NULL); |
retval = header->main(argc, argv, NULL); |
done: |
exit (retval); |
} |