newlib: split cmdline params

git-svn-id: svn://kolibrios.org@5190 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2014-11-27 01:02:55 +00:00
parent 32530313f2
commit d6244d0651
6 changed files with 168 additions and 48 deletions

View File

@ -43,9 +43,6 @@
#include "egl_dri2.h" #include "egl_dri2.h"
void* load_library(const char *name);
void *get_proc_address(void *module, char *proc_name);
int (*blit_bitmap_from_handle)(bitmap_t *bitmap, uint32_t handle); int (*blit_bitmap_from_handle)(bitmap_t *bitmap, uint32_t handle);
void (*blit_set_bo_handle)(bitmap_t *bitmap, int handle); void (*blit_set_bo_handle)(bitmap_t *bitmap, int handle);
int (*blit_blit_tex)(bitmap_t *bitmap, int scale, int vsync, int dst_x, int dst_y, int (*blit_blit_tex)(bitmap_t *bitmap, int scale, int vsync, int dst_x, int dst_y,

View File

@ -868,7 +868,7 @@
/* #undef _GLIBCXX_USE_SYSCTL_HW_NCPU */ /* #undef _GLIBCXX_USE_SYSCTL_HW_NCPU */
/* Define if code specialized for wchar_t should be used. */ /* Define if code specialized for wchar_t should be used. */
#define _GLIBCXX_USE_WCHAR_T 1 //#define _GLIBCXX_USE_WCHAR_T 1
/* Define to 1 if a verbose library is built, or 0 otherwise. */ /* Define to 1 if a verbose library is built, or 0 otherwise. */
#define _GLIBCXX_VERBOSE 1 #define _GLIBCXX_VERBOSE 1

View File

@ -1332,7 +1332,7 @@ namespace std
/* #undef _GLIBCXX_USE_SYSCTL_HW_NCPU */ /* #undef _GLIBCXX_USE_SYSCTL_HW_NCPU */
/* Define if code specialized for wchar_t should be used. */ /* Define if code specialized for wchar_t should be used. */
#define _GLIBCXX_USE_WCHAR_T 1 //#define _GLIBCXX_USE_WCHAR_T 1
/* Define to 1 if a verbose library is built, or 0 otherwise. */ /* Define to 1 if a verbose library is built, or 0 otherwise. */
#define _GLIBCXX_VERBOSE 1 #define _GLIBCXX_VERBOSE 1

View File

@ -25,19 +25,20 @@ struct app_hdr
int (*main)(int argc, char **argv, char **envp); int (*main)(int argc, char **argv, char **envp);
}; };
int _argc; void _pei386_runtime_relocator (void);
char **_argv; void init_loader(void *libc_image);
void init_reent();
int link_app();
void* get_entry_point(void *raw); void* get_entry_point(void *raw);
int (*entry)(int, char **, char **); 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)) void __attribute__((noreturn))
__thread_startup (int (*entry)(void*), void *param, __thread_startup (int (*entry)(void*), void *param,
@ -45,7 +46,7 @@ __thread_startup (int (*entry)(void*), void *param,
{ {
int retval; int retval;
asm volatile ( "xchgw %bx, %bx"); // asm volatile ( "xchgw %bx, %bx");
__asm__ __volatile__( // save stack limits __asm__ __volatile__( // save stack limits
"movl %0, %%fs:8 \n\t" // use TLS "movl %0, %%fs:8 \n\t" // use TLS
@ -64,29 +65,129 @@ char * __libc_getenv(const char *name)
return NULL; return NULL;
} }
void _pei386_runtime_relocator (void); static int split_cmdline(char *cmdline, char **argv)
int link_app(); {
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]; enum quote_state state;
int __appcwdlen; unsigned int argc;
char* __appenv; char *p = cmdline;
int __appenv_size; 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)) void __attribute__((noreturn))
libc_crt_startup (void *libc_base) libc_crt_startup (void *libc_base)
{ {
struct app_hdr *header = NULL; struct app_hdr *header = NULL;
int len;
char *p;
void *my_app;
int retval = 0; int retval = 0;
char **argv;
int argc;
_pei386_runtime_relocator(); _pei386_runtime_relocator();
memset(_tls_map, 0xFF, 32*4); memset(_tls_map, 0xFF, 32*4);
@ -106,18 +207,23 @@ libc_crt_startup (void *libc_base)
memcpy(__appcwd, header->path, __appcwdlen); memcpy(__appcwd, header->path, __appcwdlen);
set_cwd(__appcwd); set_cwd(__appcwd);
arg[0] = header->path;
if( header->cmdline[0] != 0) if( header->cmdline[0] != 0)
{ {
_argc = 2; argc = split_cmdline(header->cmdline, NULL) + 1;
arg[1] = header->cmdline; 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: done:
exit (retval); exit (retval);
} }

View File

@ -470,6 +470,14 @@ static inline void Blit(void *bitmap, int dst_x, int dst_y,
::"a"(73),"b"(0),"c"(&bc.dstx)); ::"a"(73),"b"(0),"c"(&bc.dstx));
}; };
void* load_library(const char *name);
void* get_proc_address(void *handle, const char *proc_name);
void enumerate_libraries(int (*callback)(void *handle, const char* name,
uint32_t base, uint32_t size, void *user_data),
void *user_data);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -53,8 +53,8 @@ struct tag_module
uint32_t refcount; uint32_t refcount;
void *start; char *start;
uint32_t end; char *end;
void *entry; void *entry;
@ -70,7 +70,6 @@ typedef struct
int path_len; int path_len;
}dll_path_t; }dll_path_t;
module_t* load_library(const char *name);
LIST_HEAD(path_list); LIST_HEAD(path_list);
@ -231,7 +230,7 @@ void init_loader(void *libc_image)
nt->OptionalHeader.DataDirectory[0].VirtualAddress); nt->OptionalHeader.DataDirectory[0].VirtualAddress);
libc_dll.start = libc_image; libc_dll.start = libc_image;
libc_dll.end = MakePtr(uint32_t,libc_image, nt->OptionalHeader.SizeOfImage); libc_dll.end = MakePtr(char*,libc_image, nt->OptionalHeader.SizeOfImage);
libc_dll.img_hdr = nt; libc_dll.img_hdr = nt;
libc_dll.img_sec = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32)); libc_dll.img_sec = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32));
@ -342,8 +341,6 @@ void* create_image(void *raw)
return img_base; return img_base;
}; };
//static jmp_buf loader_env;
//static loader_recursion;
int link_image(void *img_base, PIMAGE_IMPORT_DESCRIPTOR imp) int link_image(void *img_base, PIMAGE_IMPORT_DESCRIPTOR imp)
{ {
@ -457,7 +454,6 @@ int link_image(void *img_base, PIMAGE_IMPORT_DESCRIPTOR imp)
}; };
}; };
minn = 0; minn = 0;
maxn = exp->NumberOfNames - 1; maxn = exp->NumberOfNames - 1;
while (minn <= maxn) while (minn <= maxn)
@ -581,9 +577,10 @@ void* get_entry_point(void *raw)
}; };
void *get_proc_address(module_t *module, char *proc_name) void *get_proc_address(void *handle, const char *proc_name)
{ {
module_t *module = handle;
PIMAGE_DOS_HEADER expdos; PIMAGE_DOS_HEADER expdos;
PIMAGE_NT_HEADERS32 expnt; PIMAGE_NT_HEADERS32 expnt;
PIMAGE_EXPORT_DIRECTORY exp; PIMAGE_EXPORT_DIRECTORY exp;
@ -682,7 +679,7 @@ static void *load_lib_internal(const char *path)
return img_base; return img_base;
} }
module_t* load_library(const char *name) void* load_library(const char *name)
{ {
PIMAGE_DOS_HEADER dos; PIMAGE_DOS_HEADER dos;
PIMAGE_NT_HEADERS32 nt; PIMAGE_NT_HEADERS32 nt;
@ -738,10 +735,10 @@ module_t* load_library(const char *name)
if( unlikely(img_base == NULL) ) if( unlikely(img_base == NULL) )
{ {
printf("unable to load %s\n", name); printf("unable to load %s\n", name);
return NULL; return 0;
}; };
module = (module_t*)malloc(sizeof(module_t)); module = malloc(sizeof(module_t));
if(unlikely(module == NULL)) if(unlikely(module == NULL))
{ {
@ -762,7 +759,7 @@ module_t* load_library(const char *name)
exp = MakePtr(PIMAGE_EXPORT_DIRECTORY, img_base, exp = MakePtr(PIMAGE_EXPORT_DIRECTORY, img_base,
nt->OptionalHeader.DataDirectory[0].VirtualAddress); nt->OptionalHeader.DataDirectory[0].VirtualAddress);
module->end = MakePtr(uint32_t,img_base, nt->OptionalHeader.SizeOfImage); module->end = MakePtr(char*,img_base, nt->OptionalHeader.SizeOfImage);
module->img_hdr = nt; module->img_hdr = nt;
module->img_sec = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32)); module->img_sec = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32));
@ -802,7 +799,19 @@ err2:
err1: err1:
user_free(img_base); user_free(img_base);
return NULL; return NULL;
}; };
void enumerate_libraries(int (*callback)(void *handle, const char* name,
uint32_t base, uint32_t size, void *user_data),
void *user_data)
{
module_t *mod = &libc_dll;
do
{
if(0 == callback(mod, mod->img_name, (uint32_t)mod->start,
mod->end - mod->start, user_data))
break;
mod = (module_t*)mod->list.next;
}while(mod != &libc_dll);
}