From 038f3f85669e89c8632d0ff9b75dfd6a7fc3f67c Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Wed, 10 Jul 2013 09:35:47 +0000 Subject: [PATCH] newlib: update git-svn-id: svn://kolibrios.org@3799 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/develop/libraries/newlib/Makefile | 7 +- .../develop/libraries/newlib/crt/crtdll.c | 2 +- .../develop/libraries/newlib/crt/dllstart.c | 11 + .../libraries/newlib/include/kos32sys.h | 33 ++- programs/develop/libraries/newlib/libcdll.lds | 29 +-- .../develop/libraries/newlib/pe/crtloader.c | 219 ++++++++++++++++++ programs/develop/libraries/newlib/pe/loader.c | 2 +- .../develop/libraries/newlib/static-amz.lds | 123 ++++++++++ programs/develop/libraries/newlib/static.lds | 4 +- .../develop/libraries/newlib/stdio/siprintf.c | 171 ++++++++++++++ .../libraries/newlib/stdio/vasniprintf.c | 71 ++++++ .../libraries/newlib/stdio/vasnprintf.c | 71 ++++++ .../libraries/newlib/stdio/vdiprintf.c | 47 ++++ .../develop/libraries/newlib/stdio/vdprintf.c | 47 ++++ 14 files changed, 817 insertions(+), 20 deletions(-) create mode 100644 programs/develop/libraries/newlib/crt/dllstart.c create mode 100644 programs/develop/libraries/newlib/pe/crtloader.c create mode 100644 programs/develop/libraries/newlib/static-amz.lds create mode 100644 programs/develop/libraries/newlib/stdio/siprintf.c create mode 100644 programs/develop/libraries/newlib/stdio/vasniprintf.c create mode 100644 programs/develop/libraries/newlib/stdio/vasnprintf.c create mode 100644 programs/develop/libraries/newlib/stdio/vdiprintf.c create mode 100644 programs/develop/libraries/newlib/stdio/vdprintf.c diff --git a/programs/develop/libraries/newlib/Makefile b/programs/develop/libraries/newlib/Makefile index 9ca0f3a20f..09464b4bd1 100644 --- a/programs/develop/libraries/newlib/Makefile +++ b/programs/develop/libraries/newlib/Makefile @@ -27,6 +27,7 @@ STATIC_SRCS:= \ crt/crt2.c \ crt/chkstk.S \ crt/exit.S \ + pe/crtloader.c \ crt/setjmp.S DLL_SRCS:= \ @@ -103,7 +104,6 @@ CORE_SRCS:= \ sys/read.c \ sys/write.c \ sys/fsize.c \ - sys/fload.c \ time/asctime.c \ time/asctime_r.c \ time/clock.c \ @@ -242,6 +242,10 @@ STDIO_SRCS= \ tmpfile.c \ tmpnam.c \ ungetc.c \ + vasniprintf.c \ + vasnprintf.c \ + vdprintf.c \ + vdiprintf.c \ vscanf.c \ vsprintf.c \ vsnprintf.c \ @@ -250,6 +254,7 @@ STDIO_SRCS= \ wsetup.c \ wbuf.c \ sccl.c \ + siprintf.c \ sniprintf.c \ snprintf.c \ sprintf.c \ diff --git a/programs/develop/libraries/newlib/crt/crtdll.c b/programs/develop/libraries/newlib/crt/crtdll.c index 3358f03a5b..fa7ea47f4b 100644 --- a/programs/develop/libraries/newlib/crt/crtdll.c +++ b/programs/develop/libraries/newlib/crt/crtdll.c @@ -82,7 +82,7 @@ crt_startup (void *libc_base, void *obj_base, uint32_t *params) init_reent(); __initPOSIXHandles(); - __appenv = load_file("/sys/system.env", &__appenv_size); + // __appenv = load_file("/sys/system.env", &__appenv_size); init_loader(libc_base); diff --git a/programs/develop/libraries/newlib/crt/dllstart.c b/programs/develop/libraries/newlib/crt/dllstart.c new file mode 100644 index 0000000000..11a657f1a2 --- /dev/null +++ b/programs/develop/libraries/newlib/crt/dllstart.c @@ -0,0 +1,11 @@ + +void _pei386_runtime_relocator (void); + +int DllStartup(void *module, int reason); + + +int DllStartup(void *module, int reason) +{ + _pei386_runtime_relocator(); + return 1; +}; diff --git a/programs/develop/libraries/newlib/include/kos32sys.h b/programs/develop/libraries/newlib/include/kos32sys.h index cf8c1f50fd..64f551539f 100644 --- a/programs/develop/libraries/newlib/include/kos32sys.h +++ b/programs/develop/libraries/newlib/include/kos32sys.h @@ -240,6 +240,14 @@ static inline void yield(void) ::"a"(68), "b"(1)); }; +static inline void delay(uint32_t time) +{ + __asm__ __volatile__( + "int $0x40" + ::"a"(5), "b"(time) + :"memory"); +}; + static inline void *user_alloc(size_t size) { @@ -273,6 +281,30 @@ int *user_unmap(void *base, size_t offset, size_t size) return val; } +typedef union +{ + struct + { + void *data; + size_t size; + }; + unsigned long long raw; +}ufile_t; + + +static inline ufile_t load_file(char *path) +{ + ufile_t uf; + + __asm__ __volatile__ ( + "int $0x40" + :"=A"(uf.raw) + :"a" (68), "b"(27),"c"(path)); + + return uf; +}; + + static inline int GetScreenSize() { int retval; @@ -339,7 +371,6 @@ void* user_realloc(void *mem, size_t size) return val; } -void *load_file(const char *path, size_t *len); void *get_resource(void *data, uint32_t id); diff --git a/programs/develop/libraries/newlib/libcdll.lds b/programs/develop/libraries/newlib/libcdll.lds index 93f120f472..49c85df052 100644 --- a/programs/develop/libraries/newlib/libcdll.lds +++ b/programs/develop/libraries/newlib/libcdll.lds @@ -11,8 +11,18 @@ SECTIONS .text __image_base__ + . : { - *(.text) *(.rdata) - . = ALIGN(16); + *(.text) + *(SORT(.text$*)) + *(.text.*) + *(.glue_7t) + *(.glue_7) + ___CTOR_LIST__ = .; __CTOR_LIST__ = . ; + LONG (-1);*(.ctors); *(.ctor); *(SORT(.ctors.*)); LONG (0); + ___DTOR_LIST__ = .; __DTOR_LIST__ = . ; + LONG (-1); *(.dtors); *(.dtor); *(SORT(.dtors.*)); LONG (0); + *(.fini) + *(.rdata) + *(SORT(.rdata$*)) ___RUNTIME_PSEUDO_RELOC_LIST__ = .; __RUNTIME_PSEUDO_RELOC_LIST__ = .; *(.rdata_runtime_pseudo_reloc) @@ -28,6 +38,8 @@ SECTIONS *(.data2) *(SORT(.data$*)) *(.jcr) + __CRT_MT = .; + LONG(0); PROVIDE ( __data_end__ = .) ; *(.data_cygwin_nocopy) } @@ -50,6 +62,7 @@ SECTIONS *(.debug$F) *(.drectve) *(.note.GNU-stack) + *(.eh_frame) *(.comment) *(.debug_abbrev) *(.debug_info) @@ -61,18 +74,6 @@ SECTIONS *(.debug_ranges) } - .idata ALIGN(__section_alignment__): - { - SORT(*)(.idata$2) - SORT(*)(.idata$3) - /* These zeroes mark the end of the import list. */ - LONG (0); LONG (0); LONG (0); LONG (0); LONG (0); - SORT(*)(.idata$4) - SORT(*)(.idata$5) - SORT(*)(.idata$6) - SORT(*)(.idata$7) - } - .reloc ALIGN(__section_alignment__) : { *(.reloc) diff --git a/programs/develop/libraries/newlib/pe/crtloader.c b/programs/develop/libraries/newlib/pe/crtloader.c new file mode 100644 index 0000000000..dccb8f4e45 --- /dev/null +++ b/programs/develop/libraries/newlib/pe/crtloader.c @@ -0,0 +1,219 @@ +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "list.h" +#include "pe.h" + +#define unlikely(x) __builtin_expect(!!(x), 0) + +//#define DBG(format,...) printf(format,##__VA_ARGS__) + +#define DBG(format,...) + +static inline void sec_copy(void *dst, void *src, size_t len) +{ + __asm__ __volatile__ ( + "shrl $2, %%ecx \n\t" + "rep movsl" + : + :"c"(len),"S"(src),"D"(dst) + :"cc"); + __asm__ __volatile__ ( + "" + :::"ecx","esi","edi"); +}; + +void* load_libc(); + +static inline int IsPowerOf2(uint32_t val) +{ + if(val == 0) + return 0; + return (val & (val - 1)) == 0; +} + +int validate_pe(void *raw, size_t raw_size, int is_exec) +{ + PIMAGE_DOS_HEADER dos; + PIMAGE_NT_HEADERS32 nt; + + dos = (PIMAGE_DOS_HEADER)raw; + + if( !raw || raw_size < sizeof(IMAGE_DOS_HEADER) ) + return 0; + + if( dos->e_magic != IMAGE_DOS_SIGNATURE || dos->e_lfanew <= 0) + return 0; + + nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew); + + if( (uint32_t)nt < (uint32_t)raw) + return 0; + + if(nt->Signature != IMAGE_NT_SIGNATURE) + return 0; + + if(nt->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) + return 0; + + if(is_exec && (nt->FileHeader.Characteristics & IMAGE_FILE_DLL)) + return 0; + + if(nt->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) + return 0; + + if( is_exec && nt->OptionalHeader.ImageBase != 0) + return 0; + + if(nt->OptionalHeader.SectionAlignment < 4096) + { + if(nt->OptionalHeader.FileAlignment != nt->OptionalHeader.SectionAlignment) + return 0; + } + else if(nt->OptionalHeader.SectionAlignment < nt->OptionalHeader.FileAlignment) + return 0; + + if(!IsPowerOf2(nt->OptionalHeader.SectionAlignment) || + !IsPowerOf2(nt->OptionalHeader.FileAlignment)) + return 0; + + if(nt->FileHeader.NumberOfSections > 96) + return 0; + + return 1; +} + +void* create_image(void *raw) +{ + PIMAGE_DOS_HEADER dos; + PIMAGE_NT_HEADERS32 nt; + PIMAGE_SECTION_HEADER img_sec; + + void *img_base; + uint32_t sec_align; + int i; + + dos = (PIMAGE_DOS_HEADER)raw; + nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew); + + img_base = user_alloc(nt->OptionalHeader.SizeOfImage); + + if(unlikely(img_base == NULL)) + return 0; + + sec_copy(img_base, raw, nt->OptionalHeader.SizeOfHeaders); + + img_sec = MakePtr(PIMAGE_SECTION_HEADER, nt, sizeof(IMAGE_NT_HEADERS32)); + + sec_align = nt->OptionalHeader.SectionAlignment; + + for(i=0; i< nt->FileHeader.NumberOfSections; i++) + { + void *src_ptr; + void *dest_ptr; + size_t sec_size; + + if ( img_sec->SizeOfRawData && img_sec->PointerToRawData ) + { + src_ptr = MakePtr(void*, raw, img_sec->PointerToRawData); + dest_ptr = MakePtr(void*, img_base, img_sec->VirtualAddress); + sec_copy(dest_ptr, src_ptr, img_sec->SizeOfRawData); + }; + + img_sec++; + }; + + if(nt->OptionalHeader.DataDirectory[5].Size) + { + PIMAGE_BASE_RELOCATION reloc; + + uint32_t delta = (uint32_t)img_base - nt->OptionalHeader.ImageBase; + + reloc = MakePtr(PIMAGE_BASE_RELOCATION, img_base, + nt->OptionalHeader.DataDirectory[5].VirtualAddress); + + while ( reloc->SizeOfBlock != 0 ) + { + uint32_t cnt; + uint16_t *entry; + uint16_t reltype; + uint32_t offs; + + cnt = (reloc->SizeOfBlock - sizeof(*reloc))/sizeof(uint16_t); + entry = MakePtr( uint16_t*, reloc, sizeof(*reloc) ); + + for ( i=0; i < cnt; i++ ) + { + uint16_t *p16; + uint32_t *p32; + + reltype = (*entry & 0xF000) >> 12; + offs = (*entry & 0x0FFF) + reloc->VirtualAddress; + switch(reltype) + { + case 1: + p16 = MakePtr(uint16_t*, img_base, offs); + *p16+= (uint16_t)(delta>>16); + break; + case 2: + p16 = MakePtr(uint16_t*, img_base, offs); + *p16+= (uint16_t)delta; + break; + case 3: + p32 = MakePtr(uint32_t*, img_base, offs); + *p32+= delta; + } + entry++; + } + reloc = MakePtr(PIMAGE_BASE_RELOCATION, reloc,reloc->SizeOfBlock); + }; + printf("unmap base %p offset %x %d page(s)\n", + img_base, + nt->OptionalHeader.DataDirectory[5].VirtualAddress, + (nt->OptionalHeader.DataDirectory[5].Size+4095)>>12); + + user_unmap(img_base,nt->OptionalHeader.DataDirectory[5].VirtualAddress, + nt->OptionalHeader.DataDirectory[5].Size); + }; + return img_base; +}; + + + +void* load_libc() +{ + void *raw_img; + size_t raw_size; + void *img_base = NULL; + ufile_t uf; + + uf = load_file("/kolibrios/lib/libc.dll"); + raw_img = uf.data; + raw_size = uf.size; + + if(raw_img == NULL) + return NULL; + + printf("libc.dll raw %p, size %d\n", raw_img, raw_size); + + if( validate_pe(raw_img, raw_size, 0) == 0) + { + printf("invalide libc.dll\n"); + user_free(raw_img); + }; + + img_base = create_image(raw_img); + + + return img_base; + +} + + diff --git a/programs/develop/libraries/newlib/pe/loader.c b/programs/develop/libraries/newlib/pe/loader.c index 23a0fa9a0d..3c7e9062ef 100644 --- a/programs/develop/libraries/newlib/pe/loader.c +++ b/programs/develop/libraries/newlib/pe/loader.c @@ -658,7 +658,7 @@ module_t* load_module(const char *name) memcpy(path+dllpath->path_len, name, len); path[len+dllpath->path_len]=0; - raw_img = load_file(path, &raw_size); +// raw_img = load_file(path, &raw_size); if(raw_img == NULL) continue; diff --git a/programs/develop/libraries/newlib/static-amz.lds b/programs/develop/libraries/newlib/static-amz.lds new file mode 100644 index 0000000000..3f5a6639ca --- /dev/null +++ b/programs/develop/libraries/newlib/static-amz.lds @@ -0,0 +1,123 @@ +/*OUTPUT_FORMAT("binary")*/ + +ENTRY(__start) +SECTIONS +{ + .text 0x000000: + { + LONG(0x554e454D); + LONG(0x32305445); + LONG(1); + LONG(__start); + LONG(___iend); + LONG(___memsize); + LONG(___stacktop); + LONG(___cmdline); + LONG(___pgmname); /* full path */ + LONG(0); /*FIXME tls data */ + + *(.init) + *(.text) + *(SORT(.text$*)) + *(.text.*) + *(.glue_7t) + *(.glue_7) + ___CTOR_LIST__ = .; __CTOR_LIST__ = . ; + LONG (-1);*(.ctors); *(.ctor); *(SORT(.ctors.*)); LONG (0); + ___DTOR_LIST__ = .; __DTOR_LIST__ = . ; + LONG (-1); *(.dtors); *(.dtor); *(SORT(.dtors.*)); LONG (0); + *(.fini) + /* ??? Why is .gcc_exc here? */ + *(.gcc_exc) + PROVIDE (etext = .); + *(.gcc_except_table) + } + + .rdata ALIGN(64) : + { + *(.rdata) + *(SORT(.rdata$*)) + ___RUNTIME_PSEUDO_RELOC_LIST__ = .; + __RUNTIME_PSEUDO_RELOC_LIST__ = .; + *(.rdata_runtime_pseudo_reloc) + ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .; + __RUNTIME_PSEUDO_RELOC_LIST_END__ = .; + } + .CRT ALIGN(64) : + { + ___crt_xc_start__ = . ; + *(SORT(.CRT$XC*)) /* C initialization */ + ___crt_xc_end__ = . ; + ___crt_xi_start__ = . ; + *(SORT(.CRT$XI*)) /* C++ initialization */ + ___crt_xi_end__ = . ; + ___crt_xl_start__ = . ; + *(SORT(.CRT$XL*)) /* TLS callbacks */ + /* ___crt_xl_end__ is defined in the TLS Directory support code */ + ___crt_xp_start__ = . ; + *(SORT(.CRT$XP*)) /* Pre-termination */ + ___crt_xp_end__ = . ; + ___crt_xt_start__ = . ; + *(SORT(.CRT$XT*)) /* Termination */ + ___crt_xt_end__ = . ; + } + + .data ALIGN(64) : + { + PROVIDE ( __data_start__ = .) ; + *(.data) + *(.data2) + *(SORT(.data$*)) + *(.jcr) + __CRT_MT = .; + LONG(0); + PROVIDE ( __data_end__ = .) ; + *(.data_cygwin_nocopy) + ___iend = . ; + } + + .idata ALIGN(64): + { + SORT(*)(.idata$2) + SORT(*)(.idata$3) + /* These zeroes mark the end of the import list. */ + LONG (0); LONG (0); LONG (0); LONG (0); LONG (0); + SORT(*)(.idata$4) + SORT(*)(.idata$5) + SORT(*)(.idata$6) + SORT(*)(.idata$7) + } + + bss ALIGN(64): + { + *(.bss) + *(COMMON) + . = ALIGN(16); + ___cmdline = .; + . = . + 256; + ___pgmname = .; + . = . + 1024 + 16; + ___stacktop = .; + ___memsize = . ; + } + + /DISCARD/ : + { + *(.debug$S) + *(.debug$T) + *(.debug$F) + *(.drectve) + *(.note.GNU-stack) + *(.eh_frame) + *(.comment) + *(.debug_abbrev) + *(.debug_info) + *(.debug_line) + *(.debug_frame) + *(.debug_loc) + *(.debug_pubnames) + *(.debug_aranges) + *(.debug_ranges) + } + +} diff --git a/programs/develop/libraries/newlib/static.lds b/programs/develop/libraries/newlib/static.lds index 92fd124ad6..388881952f 100644 --- a/programs/develop/libraries/newlib/static.lds +++ b/programs/develop/libraries/newlib/static.lds @@ -64,14 +64,14 @@ SECTIONS .data ALIGN(64) : { - __data_start__ = . ; + PROVIDE ( __data_start__ = .) ; *(.data) *(.data2) *(SORT(.data$*)) *(.jcr) __CRT_MT = .; LONG(0); - __data_end__ = . ; + PROVIDE ( __data_end__ = .) ; *(.data_cygwin_nocopy) ___iend = . ; } diff --git a/programs/develop/libraries/newlib/stdio/siprintf.c b/programs/develop/libraries/newlib/stdio/siprintf.c new file mode 100644 index 0000000000..f0a80980ce --- /dev/null +++ b/programs/develop/libraries/newlib/stdio/siprintf.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* +FUNCTION +<>, <>, <>, <>, <>, <>---format output (integer only) + +INDEX + fiprintf +INDEX + _fiprintf_r +INDEX + iprintf +INDEX + _iprintf_r +INDEX + siprintf +INDEX + _siprintf_r +INDEX + sniprintf +INDEX + _sniprintf_r +INDEX + asiprintf +INDEX + _asiprintf_r +INDEX + asniprintf +INDEX + _asniprintf_r + +ANSI_SYNOPSIS + #include + + int iprintf(const char *<[format]>, ...); + int fiprintf(FILE *<[fd]>, const char *<[format]> , ...); + int siprintf(char *<[str]>, const char *<[format]>, ...); + int sniprintf(char *<[str]>, size_t <[size]>, const char *<[format]>, + ...); + int asiprintf(char **<[strp]>, const char *<[format]>, ...); + char *asniprintf(char *<[str]>, size_t *<[size]>, + const char *<[format]>, ...); + + int _iprintf_r(struct _reent *<[ptr]>, const char *<[format]>, ...); + int _fiprintf_r(struct _reent *<[ptr]>, FILE *<[fd]>, + const char *<[format]>, ...); + int _siprintf_r(struct _reent *<[ptr]>, char *<[str]>, + const char *<[format]>, ...); + int _sniprintf_r(struct _reent *<[ptr]>, char *<[str]>, size_t <[size]>, + const char *<[format]>, ...); + int _asiprintf_r(struct _reent *<[ptr]>, char **<[strp]>, + const char *<[format]>, ...); + char *_asniprintf_r(struct _reent *<[ptr]>, char *<[str]>, + size_t *<[size]>, const char *<[format]>, ...); + +DESCRIPTION + <>, <>, <>, <>, + <>, and <> are the same as <>, + <>, <>, <>, <>, and + <>, respectively, except that they restrict usage + to non-floating-point format specifiers. + + <<_iprintf_r>>, <<_fiprintf_r>>, <<_asiprintf_r>>, + <<_siprintf_r>>, <<_sniprintf_r>>, <<_asniprintf_r>> are + simply reentrant versions of the functions above. + +RETURNS +Similar to <>, <>, <>, <>, <>, +and <>. + +PORTABILITY +<>, <>, <>, <>, <>, +and <> are newlib extensions. + +Supporting OS subroutines required: <>, <>, <>, +<>, <>, <>, <>. +*/ + +#include <_ansi.h> +#include +#include +#ifdef _HAVE_STDC +#include +#else +#include +#endif +#include +#include "local.h" + +int +#ifdef _HAVE_STDC +_DEFUN(_siprintf_r, (ptr, str, fmt), + struct _reent *ptr _AND + char *str _AND + _CONST char *fmt _DOTS) +#else +_siprintf_r(ptr, str, fmt, va_alist) + struct _reent *ptr; + char *str; + _CONST char *fmt; + va_dcl +#endif +{ + int ret; + va_list ap; + FILE f; + + f._flags = __SWR | __SSTR; + f._bf._base = f._p = (unsigned char *) str; + f._bf._size = f._w = INT_MAX; + f._file = -1; /* No file. */ +#ifdef _HAVE_STDC + va_start (ap, fmt); +#else + va_start (ap); +#endif + ret = _svfiprintf_r (ptr, &f, fmt, ap); + va_end (ap); + *f._p = 0; + return (ret); +} + +#ifndef _REENT_ONLY + +int +#ifdef _HAVE_STDC +_DEFUN(siprintf, (str, fmt), + char *str _AND + _CONST char *fmt _DOTS) +#else +siprintf(str, fmt, va_alist) + char *str; + _CONST char *fmt; + va_dcl +#endif +{ + int ret; + va_list ap; + FILE f; + + f._flags = __SWR | __SSTR; + f._bf._base = f._p = (unsigned char *) str; + f._bf._size = f._w = INT_MAX; + f._file = -1; /* No file. */ +#ifdef _HAVE_STDC + va_start (ap, fmt); +#else + va_start (ap); +#endif + ret = _svfiprintf_r (_REENT, &f, fmt, ap); + va_end (ap); + *f._p = 0; + return (ret); +} + +#endif diff --git a/programs/develop/libraries/newlib/stdio/vasniprintf.c b/programs/develop/libraries/newlib/stdio/vasniprintf.c new file mode 100644 index 0000000000..56db45ec0a --- /dev/null +++ b/programs/develop/libraries/newlib/stdio/vasniprintf.c @@ -0,0 +1,71 @@ +/* Copyright (C) 2007, 2008 Eric Blake + * Permission to use, copy, modify, and distribute this software + * is freely granted, provided that this notice is preserved. + */ +/* This code was derived from asprintf.c */ +/* doc in viprintf.c */ + +#include <_ansi.h> +#include +#include +#include +#include +#include +#include "local.h" + +char * +_DEFUN(_vasniprintf_r, (ptr, buf, lenp, fmt, ap), + struct _reent *ptr _AND + char *buf _AND + size_t *lenp _AND + const char *fmt _AND + va_list ap) +{ + int ret; + FILE f; + size_t len = *lenp; + + if (buf && len) + { + /* mark an existing buffer, but allow allocation of larger string */ + f._flags = __SWR | __SSTR | __SOPT; + } + else + { + /* mark a zero-length reallocatable buffer */ + f._flags = __SWR | __SSTR | __SMBF; + len = 0; + buf = NULL; + } + f._bf._base = f._p = (unsigned char *) buf; + /* For now, inherit the 32-bit signed limit of FILE._bf._size. + FIXME - it would be nice to rewrite sys/reent.h to support size_t + for _size. */ + if (len > INT_MAX) + { + ptr->_errno = EOVERFLOW; + return NULL; + } + f._bf._size = f._w = len; + f._file = -1; /* No file. */ + ret = _svfiprintf_r (ptr, &f, fmt, ap); + if (ret < 0) + return NULL; + *lenp = ret; + *f._p = '\0'; + return (char *) f._bf._base; +} + +#ifndef _REENT_ONLY + +char * +_DEFUN(vasniprintf, (buf, lenp, fmt, ap), + char *buf _AND + size_t *lenp _AND + const char *fmt _AND + va_list ap) +{ + return _vasniprintf_r (_REENT, buf, lenp, fmt, ap); +} + +#endif /* ! _REENT_ONLY */ diff --git a/programs/develop/libraries/newlib/stdio/vasnprintf.c b/programs/develop/libraries/newlib/stdio/vasnprintf.c new file mode 100644 index 0000000000..cab89beff9 --- /dev/null +++ b/programs/develop/libraries/newlib/stdio/vasnprintf.c @@ -0,0 +1,71 @@ +/* Copyright (C) 2007 Eric Blake + * Permission to use, copy, modify, and distribute this software + * is freely granted, provided that this notice is preserved. + */ +/* This code was derived from asprintf.c */ +/* doc in vfprintf.c */ + +#include <_ansi.h> +#include +#include +#include +#include +#include +#include "local.h" + +char * +_DEFUN(_vasnprintf_r, (ptr, buf, lenp, fmt, ap), + struct _reent *ptr _AND + char *buf _AND + size_t *lenp _AND + const char *fmt _AND + va_list ap) +{ + int ret; + FILE f; + size_t len = *lenp; + + if (buf && len) + { + /* mark an existing buffer, but allow allocation of larger string */ + f._flags = __SWR | __SSTR | __SOPT; + } + else + { + /* mark a zero-length reallocatable buffer */ + f._flags = __SWR | __SSTR | __SMBF; + len = 0; + buf = NULL; + } + f._bf._base = f._p = (unsigned char *) buf; + /* For now, inherit the 32-bit signed limit of FILE._bf._size. + FIXME - it would be nice to rewrite sys/reent.h to support size_t + for _size. */ + if (len > INT_MAX) + { + ptr->_errno = EOVERFLOW; + return NULL; + } + f._bf._size = f._w = len; + f._file = -1; /* No file. */ + ret = _svfprintf_r (ptr, &f, fmt, ap); + if (ret < 0) + return NULL; + *lenp = ret; + *f._p = '\0'; + return (char *) f._bf._base; +} + +#ifndef _REENT_ONLY + +char * +_DEFUN(vasnprintf, (buf, lenp, fmt, ap), + char *buf _AND + size_t *lenp _AND + const char *fmt _AND + va_list ap) +{ + return _vasnprintf_r (_REENT, buf, lenp, fmt, ap); +} + +#endif /* ! _REENT_ONLY */ diff --git a/programs/develop/libraries/newlib/stdio/vdiprintf.c b/programs/develop/libraries/newlib/stdio/vdiprintf.c new file mode 100644 index 0000000000..51bdb000e2 --- /dev/null +++ b/programs/develop/libraries/newlib/stdio/vdiprintf.c @@ -0,0 +1,47 @@ +/* Copyright 2005, 2007 Shaun Jackman + * Permission to use, copy, modify, and distribute this software + * is freely granted, provided that this notice is preserved. + */ +/* doc in diprintf.c */ + +#include <_ansi.h> +#include +#include +#include +#include +#include +#include "local.h" + +int +_DEFUN(_vdiprintf_r, (ptr, fd, format, ap), + struct _reent *ptr _AND + int fd _AND + const char *format _AND + va_list ap) +{ + char *p; + char buf[512]; + size_t n = sizeof buf; + + _REENT_SMALL_CHECK_INIT (ptr); + p = _vasniprintf_r (ptr, buf, &n, format, ap); + if (!p) + return -1; + n = _write_r (ptr, fd, p, n); + if (p != buf) + _free_r (ptr, p); + return n; +} + +#ifndef _REENT_ONLY + +int +_DEFUN(vdiprintf, (fd, format, ap), + int fd _AND + const char *format _AND + va_list ap) +{ + return _vdiprintf_r (_REENT, fd, format, ap); +} + +#endif /* ! _REENT_ONLY */ diff --git a/programs/develop/libraries/newlib/stdio/vdprintf.c b/programs/develop/libraries/newlib/stdio/vdprintf.c new file mode 100644 index 0000000000..bfb19c95b7 --- /dev/null +++ b/programs/develop/libraries/newlib/stdio/vdprintf.c @@ -0,0 +1,47 @@ +/* Copyright 2005, 2007 Shaun Jackman + * Permission to use, copy, modify, and distribute this software + * is freely granted, provided that this notice is preserved. + */ +/* doc in dprintf.c */ + +#include <_ansi.h> +#include +#include +#include +#include +#include +#include "local.h" + +int +_DEFUN(_vdprintf_r, (ptr, fd, format, ap), + struct _reent *ptr _AND + int fd _AND + const char *format _AND + va_list ap) +{ + char *p; + char buf[512]; + size_t n = sizeof buf; + + _REENT_SMALL_CHECK_INIT (ptr); + p = _vasnprintf_r (ptr, buf, &n, format, ap); + if (!p) + return -1; + n = _write_r (ptr, fd, p, n); + if (p != buf) + _free_r (ptr, p); + return n; +} + +#ifndef _REENT_ONLY + +int +_DEFUN(vdprintf, (fd, format, ap), + int fd _AND + const char *format _AND + va_list ap) +{ + return _vdprintf_r (_REENT, fd, format, ap); +} + +#endif /* ! _REENT_ONLY */