forked from Vhex-Kernel-Core/fxlibc
Compare commits
8 Commits
48a5b7696f
...
4d7787db01
Author | SHA1 | Date |
---|---|---|
Sylvain PILLOT | 4d7787db01 | |
Sylvain PILLOT | 492b074759 | |
Yann MAGNIN | e82160c78c | |
Yann MAGNIN | 9ff2574e28 | |
Lephenixnoir | 8d7d37cd77 | |
Lephenixnoir | d6432a9af2 | |
Lephenixnoir | 4358a16b92 | |
Lephenixnoir | 547a52737d |
|
@ -3,6 +3,7 @@
|
|||
/prefix
|
||||
*.txt
|
||||
!CMakeLists.txt
|
||||
.vxsdk/
|
||||
|
||||
# GiteaPC config files
|
||||
giteapc-config.make
|
||||
|
|
|
@ -15,7 +15,9 @@ if(FXLIBC_TARGET STREQUAL vhex-sh)
|
|||
list(APPEND TARGET_FOLDERS vhex sh-generic)
|
||||
set(FXLIBC_ARCH sh)
|
||||
add_definitions(-D__SUPPORT_VHEX_KERNEL)
|
||||
set(CMAKE_INSTALL_PREFIX "${FXSDK_COMPILER_INSTALL}" CACHE PATH "..." FORCE)
|
||||
set(CMAKE_INSTALL_PREFIX "${VXSDK_COMPILER_INSTALL}" CACHE PATH "..." FORCE)
|
||||
set(INCDIR "${VXSDK_COMPILER_INSTALL}/include")
|
||||
set(LIBDIR "${VXSDK_COMPILER_INSTALL}/lib")
|
||||
endif()
|
||||
|
||||
if(FXLIBC_TARGET STREQUAL gint)
|
||||
|
@ -70,6 +72,8 @@ set(SOURCES
|
|||
3rdparty/grisu2b_59_56/grisu2b_59_56.c
|
||||
3rdparty/tinymt32/rand.c
|
||||
3rdparty/tinymt32/tinymt32.c
|
||||
# C++ API details
|
||||
src/dso.c
|
||||
# assert
|
||||
src/assert/assert.c
|
||||
# ctype
|
||||
|
@ -112,6 +116,7 @@ set(SOURCES
|
|||
src/stdio/fgetc.c
|
||||
src/stdio/fgetpos.c
|
||||
src/stdio/fgets.c
|
||||
src/stdio/fileno.c
|
||||
src/stdio/fileutil.c
|
||||
src/stdio/fopen.c
|
||||
src/stdio/fprintf.c
|
||||
|
@ -162,6 +167,7 @@ set(SOURCES
|
|||
# stdlib
|
||||
src/stdlib/abort.c
|
||||
src/stdlib/abs.c
|
||||
src/stdlib/atexit.c
|
||||
src/stdlib/atof.c
|
||||
src/stdlib/atoi.c
|
||||
src/stdlib/atol.c
|
||||
|
@ -261,22 +267,43 @@ if(gint IN_LIST TARGET_FOLDERS)
|
|||
src/time/target/gint/time.c)
|
||||
endif()
|
||||
|
||||
# TODO: All targets
|
||||
|
||||
add_library(fxlibc ${SOURCES})
|
||||
|
||||
target_include_directories(fxlibc PRIVATE include/)
|
||||
|
||||
foreach(FOLDER IN LISTS TARGET_FOLDERS)
|
||||
target_include_directories(fxlibc PRIVATE include/target/${FOLDER}/)
|
||||
#---
|
||||
# Handle "target-specific" fxlibc output format
|
||||
#---
|
||||
|
||||
if(FXLIBC_TARGET STREQUAL vhex-sh)
|
||||
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
|
||||
add_library(fxlibcStatic STATIC ${SOURCES})
|
||||
add_library(fxlibcShared SHARED ${SOURCES})
|
||||
set(FXLIBC_TARGET_LIBS "fxlibcStatic;fxlibcShared")
|
||||
else()
|
||||
add_library(fxlibcStatic STATIC ${SOURCES})
|
||||
set(FXLIBC_TARGET_LIBS "fxlibcStatic")
|
||||
endif()
|
||||
|
||||
|
||||
foreach(FXLIBC_LIB IN LISTS FXLIBC_TARGET_LIBS)
|
||||
|
||||
target_include_directories(${FXLIBC_LIB} PRIVATE include/)
|
||||
foreach(FOLDER IN LISTS TARGET_FOLDERS)
|
||||
target_include_directories(${FXLIBC_LIB} PRIVATE include/target/${FOLDER}/)
|
||||
endforeach()
|
||||
|
||||
set_target_properties(${FXLIBC_LIB} PROPERTIES OUTPUT_NAME "c")
|
||||
|
||||
install(TARGETS ${FXLIBC_LIB} DESTINATION ${LIBDIR})
|
||||
endforeach()
|
||||
|
||||
set_target_properties(fxlibc PROPERTIES
|
||||
OUTPUT_NAME "c") # libc.a
|
||||
|
||||
# Install
|
||||
|
||||
install(TARGETS fxlibc DESTINATION ${LIBDIR})
|
||||
|
||||
#---
|
||||
# Do not forget to install headers
|
||||
#---
|
||||
|
||||
install(DIRECTORY include/ DESTINATION ${INCDIR} PATTERN "target" EXCLUDE)
|
||||
|
||||
foreach(FOLDER IN LISTS TARGET_FOLDERS)
|
||||
|
|
8
STATUS
8
STATUS
|
@ -99,6 +99,7 @@ TEST: Function/symbol/macro needs to be tested
|
|||
7.19.5.4 freopen -
|
||||
7.19.5.5 setbuf -
|
||||
7.19.5.6 setvbuf -
|
||||
(EXT) fileno -
|
||||
|
||||
7.19.6.1 fprintf -
|
||||
7.19.6.2 fscanf TODO
|
||||
|
@ -161,7 +162,7 @@ TEST: Function/symbol/macro needs to be tested
|
|||
7.20.3.3 malloc - (gint)
|
||||
7.20.3.4 realloc - (gint)
|
||||
7.20.4.1 abort - (stream flushing/closing/etc?)
|
||||
7.20.4.2 atexit TODO
|
||||
7.20.4.2 atexit TEST
|
||||
7.20.4.3 exit - (stream flushing/closing/etc?)
|
||||
7.20.4.4 _Exit - (gint)
|
||||
7.20.4.5 getenv TODO
|
||||
|
@ -172,6 +173,8 @@ TEST: Function/symbol/macro needs to be tested
|
|||
7.20.6.2 div, ldiv, lldiv -
|
||||
7.20.7 Multibyte/wide char conv TODO
|
||||
7.20.8 Multibyte/wide string conv TODO
|
||||
(EXT) __cxa_atexit TEST
|
||||
(EXT) __cxa_finalize TEST
|
||||
|
||||
7.21 <string.h>
|
||||
7.21.2.1 memcpy -
|
||||
|
@ -222,6 +225,9 @@ TEST: Function/symbol/macro needs to be tested
|
|||
|
||||
7.25 <wctype.h> TODO (not a priority)
|
||||
|
||||
(EXT) <alloca.h>
|
||||
(EXT) alloca -
|
||||
|
||||
# Supporting locales
|
||||
|
||||
What if we wanted to support more locales?
|
||||
|
|
|
@ -12,16 +12,13 @@ set(CMAKE_CXX_FLAGS_INIT "")
|
|||
|
||||
add_compile_options(-nostdlib)
|
||||
add_link_options(-nostdlib)
|
||||
link_libraries(-lgcc)
|
||||
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||
|
||||
# Determine compiler install path
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_C_COMPILER} --print-file-name=.
|
||||
OUTPUT_VARIABLE FXSDK_COMPILER_INSTALL
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
if(NOT DEFINED ENV{VXSDK_COMPILER_SYSROOT})
|
||||
message(FATAL_ERROR "You should use the vxSDK to build this project")
|
||||
endif()
|
||||
set(VXSDK_COMPILER_INSTALL $ENV{VXSDK_COMPILER_SYSROOT})
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef __ALLOCA_H__
|
||||
# define __ALLOCA_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#undef alloca
|
||||
|
||||
/* Allocate a block of memory on the stack. */
|
||||
extern void *alloca(size_t __size);
|
||||
|
||||
#define alloca(size) __builtin_alloca(size)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__ALLOCA_H__*/
|
|
@ -187,6 +187,7 @@ extern void setbuf(FILE * __restrict__ __fp, char * __restrict__ __buf);
|
|||
extern int setvbuf(FILE * __restrict__ __fp, char * __restrict__ __buf,
|
||||
int __mode, size_t __size);
|
||||
|
||||
/* Return the file descriptor associated with __fp. */
|
||||
extern int fileno(FILE *__fp);
|
||||
|
||||
/*
|
||||
|
|
|
@ -38,6 +38,7 @@ extern void free(void *__ptr);
|
|||
__attribute__((noreturn))
|
||||
extern void abort(void);
|
||||
|
||||
/* Register a function to be called at program exit. */
|
||||
extern int atexit(void (*__func)(void));
|
||||
|
||||
/* Exit; calls handlers, flushes and closes streams and temporary files. */
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
/* We don't support shared object loading, so provide a single handle */
|
||||
__attribute__((visibility("hidden")))
|
||||
void *__dso_handle = (void *)&__dso_handle;
|
||||
|
||||
/* Number of atexit() calls supported, must be at least 32 (7.20.4.2§3).*/
|
||||
#define ATEXIT_MAX 32
|
||||
|
||||
struct dtor {
|
||||
void (*f)(void *);
|
||||
void *p;
|
||||
void *d;
|
||||
};
|
||||
|
||||
static struct dtor *_dtors;
|
||||
static int _dtor_count = 0;
|
||||
|
||||
__attribute__((constructor))
|
||||
static void alloc_dtors(void)
|
||||
{
|
||||
_dtors = malloc(ATEXIT_MAX * sizeof *_dtors);
|
||||
}
|
||||
|
||||
int __cxa_atexit(void (*f)(void *), void *p, void *d)
|
||||
{
|
||||
if(!_dtors || _dtor_count >= ATEXIT_MAX)
|
||||
return 1;
|
||||
_dtors[_dtor_count++] = (struct dtor){ f, p, d };
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We walk the destructor list in reverse order. Destructors may themselves
|
||||
call __cxa_atexit(), causing new destructors to be added. When that
|
||||
happens, we must call the new ones first before resuming (7.20.4.3§3). We
|
||||
track changes in _dtor_count to detect this situation.
|
||||
|
||||
This function calls destructs in the interval [low..high) that match DSO
|
||||
handle d, plus any other destructors registered as a consequence.
|
||||
_dtor_count may increase. */
|
||||
static void call_dtors_in_interval(void *d, int low, int high)
|
||||
{
|
||||
int end = _dtor_count;
|
||||
|
||||
for(int i = high - 1; i >= low; i--) {
|
||||
if(d == NULL || _dtors[i].d == d)
|
||||
_dtors[i].f(_dtors[i].p);
|
||||
|
||||
if(_dtor_count > end) {
|
||||
call_dtors_in_interval(d, end, _dtor_count);
|
||||
end = _dtor_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void __cxa_finalize(void *d)
|
||||
{
|
||||
call_dtors_in_interval(d, 0, _dtor_count);
|
||||
|
||||
/* Re-compact the array to keep only destructors we didn't call. */
|
||||
int j = 0;
|
||||
for(int i = 0; i < _dtor_count; i++) {
|
||||
if(d == NULL || _dtors[i].d == d)
|
||||
continue;
|
||||
_dtors[j++] = _dtors[i];
|
||||
}
|
||||
_dtor_count = j;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int fileno(FILE *fp)
|
||||
{
|
||||
return fp->fd;
|
||||
}
|
|
@ -41,7 +41,7 @@ void __scanf_end(struct __scanf_input *in)
|
|||
|
||||
enum
|
||||
{
|
||||
MODskip,
|
||||
MODSKIP,
|
||||
MODCHAR,
|
||||
MODSHORT,
|
||||
MODNORMAL,
|
||||
|
@ -60,7 +60,7 @@ void __purge_space( struct __scanf_input * __restrict__ in )
|
|||
|
||||
void __scanf_store_i(int64_t value, int size, va_list *args)
|
||||
{
|
||||
if(size == MODskip) return;
|
||||
if(size == MODSKIP) return;
|
||||
|
||||
if(size == MODCHAR)
|
||||
*va_arg(*args, int8_t *) = value;
|
||||
|
@ -80,7 +80,7 @@ void __scanf_store_i(int64_t value, int size, va_list *args)
|
|||
|
||||
void __scanf_store_d(long double value, int size, va_list *args)
|
||||
{
|
||||
if (size==MODskip) return;
|
||||
if (size==MODSKIP) return;
|
||||
|
||||
if(size == MODLONG)
|
||||
*va_arg(*args, double *) = value;
|
||||
|
@ -95,7 +95,8 @@ void __scanf_store_d(long double value, int size, va_list *args)
|
|||
// XX = not done yet (but will be done)
|
||||
// OK = OK, done and tested
|
||||
// -- = not applicable
|
||||
// NO = not supported (and will not be done)
|
||||
// NO = not supported (and will not be done) only for %lc as long char are not supported by gint
|
||||
|
||||
|
||||
/*************************************************************************************************************/
|
||||
/* Specifier * Explanation * num * hh * h *none* l * ll * j * z * t * L */
|
||||
|
@ -125,26 +126,32 @@ void __scanf_store_d(long double value, int size, va_list *args)
|
|||
/* f,F * match a floating point number * OK * -- * -- * OK * OK * -- * -- * -- * -- * OK */
|
||||
/* g,G * match a floating point number * OK * -- * -- * OK * OK * -- * -- * -- * -- * OK */
|
||||
/*************************************************************************************************************/
|
||||
/* p * mathc a pointer * -- * -- * -- * OK * -- * -- * -- * -- * -- * -- */
|
||||
/* p * match a pointer * -- * -- * -- * OK * -- * -- * -- * -- * -- * -- */
|
||||
/*************************************************************************************************************/
|
||||
|
||||
// %ms and %m[set] are not implemented (with memory allocation while parsing a chain or a set of characters)
|
||||
|
||||
|
||||
/* list of allowed char given by a set %[], this is updated at every set */
|
||||
bool __asciiallowed[256] = { true };
|
||||
|
||||
|
||||
/* unallow all the char for the current set */
|
||||
void __unallow_all_set( void )
|
||||
{
|
||||
for(int u =0; u<=255; u++)
|
||||
__asciiallowed[u]=false;
|
||||
}
|
||||
|
||||
/* allow all the char for the current set */
|
||||
void __allow_all_set( void )
|
||||
{
|
||||
for(int u =0; u<=255; u++)
|
||||
__asciiallowed[u]=true;
|
||||
}
|
||||
|
||||
/* allo a range of char for the current set */
|
||||
/* note1 : c1 and c2 do not to be sorted */
|
||||
/* note2 : not sur if C standard requires to be ordered or not */
|
||||
void __define_set_range( char c1, char c2, bool value )
|
||||
{
|
||||
char beg = (c1 < c2 ? c1 : c2 );
|
||||
|
@ -154,13 +161,14 @@ void __define_set_range( char c1, char c2, bool value )
|
|||
__asciiallowed[u] = value;
|
||||
}
|
||||
|
||||
/* return true if the char is in the allowed set or false otherwise */
|
||||
bool __is_allowed( const unsigned char c )
|
||||
{
|
||||
return __asciiallowed[ c ];
|
||||
}
|
||||
|
||||
|
||||
// return 0 if Ok or -1 if syntax err in the set format
|
||||
/* return 0 if Ok or -1 if syntax err in the set format */
|
||||
int __scanset(char const * __restrict__ format, int *pos )
|
||||
{
|
||||
int __sor = 0;
|
||||
|
@ -256,8 +264,11 @@ int __scanf(
|
|||
|
||||
__allow_all_set();
|
||||
|
||||
if( format[pos] == ' ' ) {
|
||||
__purge_space(in);
|
||||
}
|
||||
// we will have to manage a given format
|
||||
if( format[pos] == '%' ) {
|
||||
else if( format[pos] == '%' ) {
|
||||
|
||||
in->readmaxlength = -1;
|
||||
// main loop
|
||||
|
@ -444,7 +455,7 @@ int __scanf(
|
|||
long long int temp;
|
||||
err = __strto_int( in, 10, NULL, &temp, false ); // base is 10 as for strtol
|
||||
if (err != 0) return validrets;
|
||||
if (skip) __scanf_store_i( temp, MODskip, args );
|
||||
if (skip) __scanf_store_i( temp, MODSKIP, args );
|
||||
else __scanf_store_i( temp, MOD, args );
|
||||
validrets++;
|
||||
break;
|
||||
|
@ -456,7 +467,7 @@ int __scanf(
|
|||
long long int temp;
|
||||
err = __strto_int( in, 0, NULL, &temp, false ); // base is 0 as for strtol
|
||||
if (err != 0) return validrets;
|
||||
if (skip) __scanf_store_i( temp, MODskip, args );
|
||||
if (skip) __scanf_store_i( temp, MODSKIP, args );
|
||||
else __scanf_store_i( temp, MOD, args );
|
||||
validrets++;
|
||||
break;
|
||||
|
@ -468,7 +479,7 @@ int __scanf(
|
|||
long long int temp;
|
||||
err = __strto_int( in, 10, NULL, &temp, false ); // base is 10 as for strtol - use_unsigned must be false (validated with glibc6.2 behaviour)
|
||||
if (err != 0) return validrets;
|
||||
if (skip) __scanf_store_i( temp, MODskip, args );
|
||||
if (skip) __scanf_store_i( temp, MODSKIP, args );
|
||||
else __scanf_store_i( temp, MOD, args );
|
||||
validrets++;
|
||||
break;
|
||||
|
@ -480,7 +491,7 @@ int __scanf(
|
|||
long long int temp;
|
||||
err = __strto_int( in, 8, NULL, &temp, true ); // base is 8 as for strtol
|
||||
if (err != 0) return validrets;
|
||||
if (skip) __scanf_store_i( temp, MODskip, args );
|
||||
if (skip) __scanf_store_i( temp, MODSKIP, args );
|
||||
else __scanf_store_i( temp, MOD, args );
|
||||
validrets++;
|
||||
break;
|
||||
|
@ -493,7 +504,7 @@ int __scanf(
|
|||
long long int temp;
|
||||
err = __strto_int( in, 16, NULL, &temp, true ); // base is 16 as for strtol
|
||||
if (err != 0) return validrets;
|
||||
if (skip) __scanf_store_i( temp, MODskip, args );
|
||||
if (skip) __scanf_store_i( temp, MODSKIP, args );
|
||||
else __scanf_store_i( temp, MOD, args );
|
||||
validrets++;
|
||||
break;
|
||||
|
@ -512,7 +523,7 @@ int __scanf(
|
|||
long double temp;
|
||||
err = __strto_fp( in, NULL, NULL, &temp );
|
||||
if (err != 0) return validrets;
|
||||
if (skip) __scanf_store_d( temp, MODskip, args );
|
||||
if (skip) __scanf_store_d( temp, MODSKIP, args );
|
||||
else __scanf_store_d( temp, MOD, args );
|
||||
validrets++;
|
||||
break;
|
||||
|
@ -648,7 +659,7 @@ int __scanf(
|
|||
__scanf_in( in );
|
||||
pos++;
|
||||
}
|
||||
return validrets; // else we return the number of valid read
|
||||
else return validrets; // else we return the number of valid read
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
extern int __cxa_atexit(void (*f)(void *), void *p, void *d);
|
||||
|
||||
int atexit(void (*f)(void))
|
||||
{
|
||||
return __cxa_atexit((void (*)(void *))f, NULL, NULL);
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
extern void __cxa_finalize(void *d);
|
||||
|
||||
void exit(int rc)
|
||||
{
|
||||
/* TODO: invoke atexit callbacks */
|
||||
__cxa_finalize(NULL);
|
||||
|
||||
/* TODO: exit: Flush all streams */
|
||||
/* TODO: exit: Close all streams */
|
||||
/* TODO: exit: Remove temporary files */
|
||||
|
|
22
vxsdk.toml
22
vxsdk.toml
|
@ -1,14 +1,26 @@
|
|||
[project]
|
||||
name = 'fxlibc'
|
||||
version = '1.4.1'
|
||||
type = 'app'
|
||||
target = [
|
||||
'superh'
|
||||
]
|
||||
|
||||
[build]
|
||||
configure = 'cmake -DFXLIBC_PIC=1 -DFXLIBC_TARGET=vhex-sh -B build-vhex -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-vhex.cmake'
|
||||
build = 'make -C build-vhex'
|
||||
install = 'make -C build-vhex install'
|
||||
[superh.build]
|
||||
configure = """ \
|
||||
cmake \
|
||||
-B build-vhex \
|
||||
-DFXLIBC_PIC=1 \
|
||||
-DFXLIBC_TARGET=vhex-sh \
|
||||
-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-vhex.cmake
|
||||
"""
|
||||
build = 'cmake --build build-vhex'
|
||||
install = 'cmake --install build-vhex'
|
||||
uninstall = """ \
|
||||
if [ -e build-vhex/install_manifest.txt ]; then \
|
||||
xargs rm -f < build-vhex/install_manifest.txt; \
|
||||
fi \
|
||||
"""
|
||||
|
||||
[superh.dependencies]
|
||||
vxOpenLibm = 'master@superh'
|
||||
sh-elf-vhex = 'master@superh'
|
||||
|
|
Loading…
Reference in New Issue