From 2a2d8df30df639facb32703cb0f64ec5bcaa1099 Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Tue, 10 Sep 2013 19:07:11 +0000 Subject: [PATCH] newlib: update git-svn-id: svn://kolibrios.org@3900 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/develop/libraries/newlib/Makefile | 27 +- .../develop/libraries/newlib/crt/dllstart.c | 5 +- .../libraries/newlib/crt/pseudo-reloc.c | 8 +- .../libraries/newlib/include/kos32sys.h | 6 +- programs/develop/libraries/newlib/pe/loader.c | 272 ++++++++++-------- .../develop/libraries/newlib/string/stpcpy.c | 91 ++++++ .../develop/libraries/newlib/string/stpncpy.c | 114 ++++++++ 7 files changed, 381 insertions(+), 142 deletions(-) create mode 100644 programs/develop/libraries/newlib/string/stpcpy.c create mode 100644 programs/develop/libraries/newlib/string/stpncpy.c diff --git a/programs/develop/libraries/newlib/Makefile b/programs/develop/libraries/newlib/Makefile index 9b5cb29dc3..f6119e68e3 100644 --- a/programs/develop/libraries/newlib/Makefile +++ b/programs/develop/libraries/newlib/Makefile @@ -2,7 +2,7 @@ CC = gcc CFLAGS = -c -O2 -fomit-frame-pointer -DBUILD_DLL -LDFLAGS = -nostdlib -shared -s -T libcdll.lds --out-implib libcimp.a --image-base 0 +LDFLAGS = -nostdlib -shared -s -T libcdll.lds --output-def libc.orig.def --out-implib libc.dll.a --image-base 0 LIBC_TOPDIR = . LIBC_INCLUDES = $(LIBC_TOPDIR)/include @@ -40,6 +40,7 @@ LIBCRT_SRCS:= \ crt/start.S \ crt/chkstk.S \ crt/crt3.c \ + crt/pseudo-reloc.c \ pe/crtloader.c CORE_SRCS:= \ @@ -126,8 +127,7 @@ CORE_SRCS:= \ time/strftime.c \ time/time.c \ time/tzlock.c \ - time/tzvars.c \ - unpack/unpacker.asm + time/tzvars.c STDLIB_SRCS= \ @@ -172,13 +172,15 @@ STDLIB_SRCS= \ wctomb_r.c -STRING_SRCS= memcpy.c \ - memcmp.c \ - memmove.c \ - memset.c \ - memchr.c \ - strcat.c \ - strchr.c \ +STRING_SRCS= memcpy.c \ + memcmp.c \ + memmove.c \ + memset.c \ + memchr.c \ + stpcpy.c \ + stpncpy.c \ + strcat.c \ + strchr.c \ strcmp.c \ strcoll.c \ strcasecmp.c \ @@ -368,7 +370,10 @@ shared: $(NAME).dll libcrt.a libdll.a $(NAME).dll: $(LIB_OBJS) $(SRC_DEP) Makefile - ld $(LDFLAGS) -Map libcmap -L. -o $@ $(LIB_OBJS) -lgcc + ld $(LDFLAGS) --exclude-symbols __chkstk,__chkstk_ms,_alloca -Map libcmap -L. -o $@ $(LIB_OBJS) -lgcc --version-script libc.ver + sed -e "s/ @[^ ]*//" libc.orig.def > libc.def + sed -f cmd1.sed libc.def > mem + sed -f cmd2.sed mem >libc.inc libcrt.a: $(LIBCRT_OBJS) Makefile diff --git a/programs/develop/libraries/newlib/crt/dllstart.c b/programs/develop/libraries/newlib/crt/dllstart.c index 11a657f1a2..619a6868ba 100644 --- a/programs/develop/libraries/newlib/crt/dllstart.c +++ b/programs/develop/libraries/newlib/crt/dllstart.c @@ -1,8 +1,5 @@ -void _pei386_runtime_relocator (void); - -int DllStartup(void *module, int reason); - +extern void _pei386_runtime_relocator (void); int DllStartup(void *module, int reason) { diff --git a/programs/develop/libraries/newlib/crt/pseudo-reloc.c b/programs/develop/libraries/newlib/crt/pseudo-reloc.c index 67685f12c1..2a6a4a8cd7 100644 --- a/programs/develop/libraries/newlib/crt/pseudo-reloc.c +++ b/programs/develop/libraries/newlib/crt/pseudo-reloc.c @@ -130,8 +130,8 @@ do_pseudo_reloc (void * start, void * end, void * base) /* Check if this is a known version. */ if (v2_hdr->version != RP_VERSION_V2) { - printf(" Unknown pseudo relocation protocol version %d.\n", - (int) v2_hdr->version); +// printf(" Unknown pseudo relocation protocol version %d.\n", +// (int) v2_hdr->version); return; } @@ -176,8 +176,8 @@ do_pseudo_reloc (void * start, void * end, void * base) break; default: reldata=0; - printf(" Unknown pseudo relocation bit size %d.\n", - (int) (r->flags & 0xff)); +// printf(" Unknown pseudo relocation bit size %d.\n", +// (int) (r->flags & 0xff)); break; } diff --git a/programs/develop/libraries/newlib/include/kos32sys.h b/programs/develop/libraries/newlib/include/kos32sys.h index 64f551539f..61a5c4d555 100644 --- a/programs/develop/libraries/newlib/include/kos32sys.h +++ b/programs/develop/libraries/newlib/include/kos32sys.h @@ -292,7 +292,7 @@ typedef union }ufile_t; -static inline ufile_t load_file(char *path) +static inline ufile_t load_file(const char *path) { ufile_t uf; @@ -303,7 +303,7 @@ static inline ufile_t load_file(char *path) return uf; }; - + static inline int GetScreenSize() { @@ -394,7 +394,7 @@ void Blit(void *bitmap, int dst_x, int dst_y, int src_x, int src_y, int w, int h, int src_w, int src_h, int stride); - + #endif diff --git a/programs/develop/libraries/newlib/pe/loader.c b/programs/develop/libraries/newlib/pe/loader.c index 9053981438..009143ad54 100644 --- a/programs/develop/libraries/newlib/pe/loader.c +++ b/programs/develop/libraries/newlib/pe/loader.c @@ -70,7 +70,7 @@ typedef struct int path_len; }dll_path_t; -module_t* load_module(const char *name); +module_t* load_library(const char *name); LIST_HEAD(path_list); @@ -145,13 +145,12 @@ void init_loader(void *libc_image) PIMAGE_NT_HEADERS32 nt; PIMAGE_EXPORT_DIRECTORY exp; - struct app_hdr *header; - dll_path_t *path; + struct app_hdr *header = NULL; + dll_path_t *path; + int len; + char *p; #if 0 - dll_path_t *path; - int len; - char *p; if(__appenv_size) { @@ -197,8 +196,7 @@ void init_loader(void *libc_image) }; }; }; - - header = (struct app_hdr*)NULL; +#endif len = strrchr(header->path, '/') - header->path+1; p = (char*)malloc(len+1); @@ -212,7 +210,6 @@ void init_loader(void *libc_image) DBG("add libraries path %s\n", path->path); list_add_tail(&path->list, &path_list); -#endif path = (dll_path_t*)malloc(sizeof(dll_path_t)); INIT_LIST_HEAD(&path->list); @@ -243,20 +240,6 @@ void init_loader(void *libc_image) }; -const module_t* find_module(const char *name) -{ - module_t* mod = &libc_dll; - - do - { - if( !strncmp(name, mod->img_name, 16)) - return mod; - mod = (module_t*)mod->list.next; - }while(mod != &libc_dll); - - return load_module(name); -}; - static inline void sec_copy(void *dst, void *src, size_t len) { __asm__ __volatile__ ( @@ -397,7 +380,7 @@ int link_image(void *img_base, PIMAGE_IMPORT_DESCRIPTOR imp) DBG("import from %s\n",libname); - api = find_module(libname); + api = load_library(libname); if(unlikely(api == NULL)) { printf("library %s not found\n", libname); @@ -625,110 +608,159 @@ void *get_proc_address(module_t *module, char *proc_name) return function; }; - -module_t* load_module(const char *name) +static void *load_lib_internal(const char *path) { - dll_path_t *dllpath; + PIMAGE_DOS_HEADER dos; + PIMAGE_NT_HEADERS32 nt; + PIMAGE_EXPORT_DIRECTORY exp; - char *path; - int len; + ufile_t uf; + void *raw_img; + size_t raw_size; + void *img_base = NULL; - len = strlen(name); + uf = load_file(path); + raw_img = uf.data; + raw_size = uf.size; - list_for_each_entry(dllpath, &path_list, list) + if(raw_img == NULL) + return NULL; + + if( validate_pe(raw_img, raw_size, 0) == 0) { - PIMAGE_DOS_HEADER dos; - PIMAGE_NT_HEADERS32 nt; - PIMAGE_EXPORT_DIRECTORY exp; - - module_t *module; - ufile_t uf; - void *raw_img; - size_t raw_size; - void *img_base; - - path = alloca(len+dllpath->path_len+1); - memcpy(path, dllpath->path, dllpath->path_len); - - memcpy(path+dllpath->path_len, name, len); - path[len+dllpath->path_len]=0; - -// printf("%s %s\n", path); - - uf = load_file(path); - raw_img = uf.data; - raw_size = uf.size; - - if(raw_img == NULL) - continue; - - - if( validate_pe(raw_img, raw_size, 0) == 0) - { - printf("invalide module %s\n", path); - user_free(raw_img); - continue; - }; - - img_base = create_image(raw_img); + printf("invalide module %s\n", path); user_free(raw_img); - - if( unlikely(img_base == NULL) ) - { - printf("cannot create image %s\n",path); - continue; - }; - - module = (module_t*)malloc(sizeof(module_t)); - - if(unlikely(module == NULL)) - { - printf("%s epic fail: no enough memory\n",__FUNCTION__); - user_free(img_base); - return NULL; - } - - INIT_LIST_HEAD(&module->list); - - module->img_name = strdup(name); - module->img_path = strdup(path); - module->start = img_base; - module->entry = get_entry_point(img_base); - module->refcount = 1; - - dos = (PIMAGE_DOS_HEADER)img_base; - nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew); - exp = MakePtr(PIMAGE_EXPORT_DIRECTORY, img_base, - nt->OptionalHeader.DataDirectory[0].VirtualAddress); - - module->end = MakePtr(uint32_t,img_base, nt->OptionalHeader.SizeOfImage); - - module->img_hdr = nt; - module->img_sec = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32)); - module->img_exp = MakePtr(PIMAGE_EXPORT_DIRECTORY, img_base, - nt->OptionalHeader.DataDirectory[0].VirtualAddress); - - list_add_tail(&module->list, &libc_dll.list); - - if(nt->OptionalHeader.DataDirectory[1].Size) - { - PIMAGE_IMPORT_DESCRIPTOR imp; - int (*dll_startup)(module_t *mod, uint32_t reason); - - imp = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, img_base, - nt->OptionalHeader.DataDirectory[1].VirtualAddress); - - if(link_image(img_base, imp) == 0) - return NULL; - - dll_startup = get_proc_address(module, "DllStartup"); - if( dll_startup ) - if( 0 == dll_startup(module, 1)) - return NULL; - }; - return module; + return NULL; }; + + img_base = create_image(raw_img); + user_free(raw_img); + + if( unlikely(img_base == NULL) ) + printf("cannot create image %s\n",path); + + return img_base; +} + +module_t* load_library(const char *name) +{ + PIMAGE_DOS_HEADER dos; + PIMAGE_NT_HEADERS32 nt; + PIMAGE_EXPORT_DIRECTORY exp; + + module_t *module, *mod = &libc_dll; + dll_path_t *dllpath; + char *path; + int len; + char *libname, *tmp; + void *img_base; + + +/* check for already loaded libraries */ + + tmp = strrchr(name, '/'); + libname = path = tmp != NULL ? tmp+1 : (char*)name; + +// printf("path %s\n", path); + + do + { + if( !strncmp(path, mod->img_name, 16)) + return mod; + mod = (module_t*)mod->list.next; + }while(mod != &libc_dll); + + if(name[0] == '/') + { + path = (char*)name; + img_base = load_lib_internal(path); + } + else + { + len = strlen(libname); + list_for_each_entry(dllpath, &path_list, list) + { + path = alloca(len+dllpath->path_len+1); + memcpy(path, dllpath->path, dllpath->path_len); + + memcpy(path+dllpath->path_len, libname, len); + path[len+dllpath->path_len]=0; + + printf("%s\n", path); + + img_base = load_lib_internal(path); + + if( unlikely(img_base == NULL) ) + continue; + }; + } + + if( unlikely(img_base == NULL) ) + { + printf("unable to load %s\n", name); + return NULL; + }; + + module = (module_t*)malloc(sizeof(module_t)); + + if(unlikely(module == NULL)) + { + printf("%s epic fail: no enough memory\n",__FUNCTION__); + goto err1; + } + + INIT_LIST_HEAD(&module->list); + + module->img_name = strdup(libname); + module->img_path = strdup(path); + module->start = img_base; + module->entry = get_entry_point(img_base); + module->refcount = 1; + + dos = (PIMAGE_DOS_HEADER)img_base; + nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew); + exp = MakePtr(PIMAGE_EXPORT_DIRECTORY, img_base, + nt->OptionalHeader.DataDirectory[0].VirtualAddress); + + module->end = MakePtr(uint32_t,img_base, nt->OptionalHeader.SizeOfImage); + + module->img_hdr = nt; + module->img_sec = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32)); + module->img_exp = MakePtr(PIMAGE_EXPORT_DIRECTORY, img_base, + nt->OptionalHeader.DataDirectory[0].VirtualAddress); + + list_add_tail(&module->list, &libc_dll.list); + + if(nt->OptionalHeader.DataDirectory[1].Size) + { + PIMAGE_IMPORT_DESCRIPTOR imp; + int (*dll_startup)(module_t *mod, uint32_t reason); + + imp = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, img_base, + nt->OptionalHeader.DataDirectory[1].VirtualAddress); + + if(link_image(img_base, imp) == 0) + goto err2; + + dll_startup = get_proc_address(module, "DllStartup"); + if( dll_startup ) + { + if( 0 == dll_startup(module, 1)) + goto err2; + } + }; + + return module; + +err2: + list_del(&module->list); + free(module->img_name); + free(module->img_path); + free(module); +err1: + user_free(img_base); return NULL; + }; diff --git a/programs/develop/libraries/newlib/string/stpcpy.c b/programs/develop/libraries/newlib/string/stpcpy.c new file mode 100644 index 0000000000..62fe79997d --- /dev/null +++ b/programs/develop/libraries/newlib/string/stpcpy.c @@ -0,0 +1,91 @@ +/* +FUNCTION + <>---copy string returning a pointer to its end + +INDEX + stpcpy + +ANSI_SYNOPSIS + #include + char *stpcpy(char *<[dst]>, const char *<[src]>); + +TRAD_SYNOPSIS + #include + char *stpcpy(<[dst]>, <[src]>) + char *<[dst]>; + char *<[src]>; + +DESCRIPTION + <> copies the string pointed to by <[src]> + (including the terminating null character) to the array + pointed to by <[dst]>. + +RETURNS + This function returns a pointer to the end of the destination string, + thus pointing to the trailing '\0'. + +PORTABILITY +<> is a GNU extension, candidate for inclusion into POSIX/SUSv4. + +<> requires no supporting OS subroutines. + +QUICKREF + stpcpy gnu +*/ + +#include +#include + +/*SUPPRESS 560*/ +/*SUPPRESS 530*/ + +/* Nonzero if either X or Y is not aligned on a "long" boundary. */ +#define UNALIGNED(X, Y) \ + (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1))) + +#if LONG_MAX == 2147483647L +#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080) +#else +#if LONG_MAX == 9223372036854775807L +/* Nonzero if X (a long int) contains a NULL byte. */ +#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080) +#else +#error long int is not a 32bit or 64bit type. +#endif +#endif + +#ifndef DETECTNULL +#error long int is not a 32bit or 64bit byte +#endif + +char* +_DEFUN (stpcpy, (dst, src), + char *dst _AND + _CONST char *src) +{ +#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) + long *aligned_dst; + _CONST long *aligned_src; + + /* If SRC or DEST is unaligned, then copy bytes. */ + if (!UNALIGNED (src, dst)) + { + aligned_dst = (long*)dst; + aligned_src = (long*)src; + + /* SRC and DEST are both "long int" aligned, try to do "long int" + sized copies. */ + while (!DETECTNULL(*aligned_src)) + { + *aligned_dst++ = *aligned_src++; + } + + dst = (char*)aligned_dst; + src = (char*)aligned_src; + } +#endif /* not PREFER_SIZE_OVER_SPEED */ + + while ((*dst++ = *src++)) + ; + return --dst; +} diff --git a/programs/develop/libraries/newlib/string/stpncpy.c b/programs/develop/libraries/newlib/string/stpncpy.c new file mode 100644 index 0000000000..fca10d3985 --- /dev/null +++ b/programs/develop/libraries/newlib/string/stpncpy.c @@ -0,0 +1,114 @@ +/* +FUNCTION + <>---counted copy string returning a pointer to its end + +INDEX + stpncpy + +ANSI_SYNOPSIS + #include + char *stpncpy(char *<[dst]>, const char *<[src]>, size_t <[length]>); + +TRAD_SYNOPSIS + #include + char *stpncpy(<[dst]>, <[src]>, <[length]>) + char *<[dst]>; + char *<[src]>; + size_t <[length]>; + +DESCRIPTION + <> copies not more than <[length]> characters from the + the string pointed to by <[src]> (including the terminating + null character) to the array pointed to by <[dst]>. If the + string pointed to by <[src]> is shorter than <[length]> + characters, null characters are appended to the destination + array until a total of <[length]> characters have been + written. + +RETURNS + This function returns a pointer to the end of the destination string, + thus pointing to the trailing '\0', or, if the destination string is + not null-terminated, pointing to dst + n. + +PORTABILITY +<> is a GNU extension, candidate for inclusion into POSIX/SUSv4. + +<> requires no supporting OS subroutines. + +QUICKREF + stpncpy gnu +*/ + +#include +#include + +/*SUPPRESS 560*/ +/*SUPPRESS 530*/ + +/* Nonzero if either X or Y is not aligned on a "long" boundary. */ +#define UNALIGNED(X, Y) \ + (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1))) + +#if LONG_MAX == 2147483647L +#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080) +#else +#if LONG_MAX == 9223372036854775807L +/* Nonzero if X (a long int) contains a NULL byte. */ +#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080) +#else +#error long int is not a 32bit or 64bit type. +#endif +#endif + +#ifndef DETECTNULL +#error long int is not a 32bit or 64bit byte +#endif + +#define TOO_SMALL(LEN) ((LEN) < sizeof (long)) + +char * +_DEFUN (stpncpy, (dst, src), + char *dst _AND + _CONST char *src _AND + size_t count) +{ + char *ret = NULL; + +#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) + long *aligned_dst; + _CONST long *aligned_src; + + /* If SRC and DEST is aligned and count large enough, then copy words. */ + if (!UNALIGNED (src, dst) && !TOO_SMALL (count)) + { + aligned_dst = (long*)dst; + aligned_src = (long*)src; + + /* SRC and DEST are both "long int" aligned, try to do "long int" + sized copies. */ + while (count >= sizeof (long int) && !DETECTNULL(*aligned_src)) + { + count -= sizeof (long int); + *aligned_dst++ = *aligned_src++; + } + + dst = (char*)aligned_dst; + src = (char*)aligned_src; + } +#endif /* not PREFER_SIZE_OVER_SPEED */ + + while (count > 0) + { + --count; + if ((*dst++ = *src++) == '\0') + { + ret = dst - 1; + break; + } + } + + while (count-- > 0) + *dst++ = '\0'; + + return ret ? ret : dst; +}