diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst index 65f39b0..de7b5db 100644 --- a/docs/porting-guide.rst +++ b/docs/porting-guide.rst @@ -2982,32 +2982,13 @@ more functionality is required, the needed library functions will need to be added to the local implementation. -Versions of `FreeBSD`_ headers can be found in ``include/lib/stdlib``. Some of -these headers have been cut down in order to simplify the implementation. In -order to minimize changes to the header files, the `FreeBSD`_ layout has been -maintained. The generic C library definitions can be found in -``include/lib/stdlib`` with more system and machine specific declarations in -``include/lib/stdlib/sys`` and ``include/lib/stdlib/machine``. +Some C headers have been obtained from `FreeBSD`_ and `SCC`_, while others have +been written specifically for TF-A. Fome implementation files have been obtained +from `FreeBSD`_, others have been written specifically for TF-A as well. The +files can be found in ``include/lib/libc`` and ``lib/libc``. -The local C library implementations can be found in ``lib/stdlib``. In order to -extend the C library these files may need to be modified. It is recommended to -use a release version of `FreeBSD`_ as a starting point. - -The C library header files in the `FreeBSD`_ source tree are located in the -``include`` and ``sys/sys`` directories. `FreeBSD`_ machine specific definitions -can be found in the ``sys/`` directories. These files define things -like 'the size of a pointer' and 'the range of an integer'. Since an AArch64 -port for `FreeBSD`_ does not yet exist, the machine specific definitions are -based on existing machine types with similar properties (for example SPARC64). - -Where possible, C library function implementations were taken from `FreeBSD`_ -as found in the ``lib/libc`` directory. - -A copy of the `FreeBSD`_ sources can be downloaded with ``git``. - -:: - - git clone git://github.com/freebsd/freebsd.git -b origin/release/9.2.0 +SCC can be found in `http://www.simple-cc.org/`_. A copy of the `FreeBSD`_ +sources can be obtained from `http://github.com/freebsd/freebsd`_. Storage abstraction layer ------------------------- @@ -3082,3 +3063,4 @@ .. _Arm Generic Interrupt Controller version 2.0 (GICv2): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0048b/index.html .. _3.0 (GICv3): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0069b/index.html .. _FreeBSD: http://www.freebsd.org +.. _SCC: http://www.simple-cc.org/ diff --git a/include/lib/libc/limits.h b/include/lib/libc/limits.h new file mode 100644 index 0000000..df1a963 --- /dev/null +++ b/include/lib/libc/limits.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2012-2017 Roberto E. Vargas Caballero + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _LIMITS_H +#define _LIMITS_H + +#include + +#define CHAR_BIT 8 +#define MB_LEN_MAX 1 + +#endif diff --git a/include/lib/libc/stdarg.h b/include/lib/libc/stdarg.h new file mode 100644 index 0000000..3c20788 --- /dev/null +++ b/include/lib/libc/stdarg.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2012-2017 Roberto E. Vargas Caballero + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _STDARG_H +#define _STDARG_H + +#define va_list __builtin_va_list +#define va_start(ap, last) __builtin_va_start(ap, last) +#define va_end(ap) __builtin_va_end(ap) +#define va_copy(to, from) __builtin_va_copy(to, from) +#define va_arg(to, type) __builtin_va_arg(to, type) + +#endif diff --git a/include/lib/libc/stddef.h b/include/lib/libc/stddef.h new file mode 100644 index 0000000..1150650 --- /dev/null +++ b/include/lib/libc/stddef.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2012-2017 Roberto E. Vargas Caballero + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _STDDEF_H +#define _STDDEF_H + +#include + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#define offsetof(st, m) ((size_t)&(((st *)0)->m)) + +#endif diff --git a/include/lib/libc/stdint.h b/include/lib/libc/stdint.h new file mode 100644 index 0000000..cd24d1f --- /dev/null +++ b/include/lib/libc/stdint.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2012-2017 Roberto E. Vargas Caballero + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _STDINT_H_ +#define _STDINT_H_ + +#include + +#endif diff --git a/include/lib/libc/stdio.h b/include/lib/libc/stdio.h new file mode 100644 index 0000000..a876f6c --- /dev/null +++ b/include/lib/libc/stdio.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2012-2017 Roberto E. Vargas Caballero + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _STDIO_H +#define _STDIO_H + +#include + +#ifndef FOPEN_MAX +#define FOPEN_MAX 12 +#endif + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#define EOF -1 +#define SEEK_CUR 0 +#define SEEK_END 1 +#define SEEK_SET 2 + + +#define _IOWRITE (1 << 0) +#define _IOREAD (1 << 1) +#define _IORW (1 << 2) +#define _IOEOF (1 << 3) +#define _IOERR (1 << 4) +#define _IOSTRG (1 << 5) +#define _IOTXT (1 << 6) +#define _IOFBF (1 << 7) +#define _IOLBF (1 << 8) +#define _IONBF (1 << 9) +#define _IOALLOC (1 <<10) + +typedef struct { + int fd; /* file descriptor */ + unsigned char *buf; /* pointer to i/o buffer */ + unsigned char *rp; /* read pointer */ + unsigned char *wp; /* write pointer */ + unsigned char *lp; /* write pointer used when line-buffering */ + size_t len; /* actual length of buffer */ + unsigned short flags; + unsigned char unbuf[1]; /* tiny buffer for unbuffered io */ +} FILE; + +extern FILE __iob[FOPEN_MAX]; + +#define stdin (&__iob[0]) +#define stdout (&__iob[1]) +#define stderr (&__iob[2]) + +extern int remove(const char *filename); +extern int rename(const char *old, const char *new); +extern FILE *tmpfile(void); +extern char *tmpnam(char *s); +extern int fclose(FILE *fp); +extern int fflush(FILE *fp); +extern FILE *fopen(const char * restrict fname, const char * restrict mode); +extern FILE *freopen(const char * restrict fname, const char * restrict mode, + FILE * restrict fp); +extern void setbuf(FILE * restrict fp, char * restrict buf); +extern int setvbuf(FILE * restrict fp, + char * restrict buf, int mode, size_t size); +extern int fprintf(FILE * restrict fp, const char * restrict fmt, ...); +extern int fscanf(FILE * restrict fp, const char * restrict fmt, ...); +extern int printf(const char * restrict fmt, ...); +extern int scanf(const char * restrict fmt, ...); +extern int snprintf(char * restrict s, + size_t n, const char * restrict fmt, ...); +extern int sprintf(char * restrict s, const char * restrict fmt, ...); +extern int sscanf(const char * restrict s, const char * restrict fmt, ...); + +#ifdef _STDARG_H +extern int vfprintf(FILE * restrict fp, + const char * restrict fmt, va_list arg); +extern int vfscanf(FILE * restrict fp, + const char * restrict fmt, va_list arg); +extern int vprintf(const char * restrict fmt, va_list arg); +extern int vscanf(const char * restrict fmt, va_list arg); +extern int vsnprintf(char * restrict s, size_t n, const char * restrict fmt, + va_list arg); +extern int vsprintf(char * restrict s, + const char * restrict fmt, va_list arg); +extern int vsscanf(const char * restrict s, + const char * restrict fmt, va_list arg); +#endif + +extern int fgetc(FILE *fp); +extern char *fgets(char * restrict s, int n, FILE * restrict fp); +extern int fputc(int c, FILE *fp); +extern int fputs(const char * restrict s, FILE * restrict fp); +extern int getc(FILE *fp); +extern int getchar(void); +extern char *gets(char *s); +extern int putc(int c, FILE *fp); +extern int putchar(int c); +extern int puts(const char *s); +extern int ungetc(int c, FILE *fp); +extern size_t fread(void * restrict ptr, size_t size, size_t nmemb, + FILE * restrict fp); +extern size_t fwrite(const void * restrict ptr, size_t size, size_t nmemb, + FILE * restrict fp); +extern int fgetpos(FILE * restrict fp, fpos_t * restrict pos); +extern int fseek(FILE *fp, long int offset, int whence); +extern int fsetpos(FILE *fp, const fpos_t *pos); +extern long int ftell(FILE *fp); +extern void rewind(FILE *fp); +extern void clearerr(FILE *fp); +extern int feof(FILE *fp); +extern int ferror(FILE *fp); +extern void perror(const char *s); + +extern int __getc(FILE *fp); +extern int __putc(int, FILE *fp); + +#ifdef __USE_MACROS +#ifdef __UNIX_FILES +#define getc(fp) ((fp)->rp >= (fp)->wp ? __getc(fp) : *(fp)->rp++) +#define putc(c, fp) ((fp)->wp >= (fp)->rp ? __putc(c,fp) : (*(fp)->wp++ = c)) +#endif + +#define ferror(fp) ((fp)->flags & _IOERR) +#define feof(fp) ((fp)->flags & _IOEOF) +#define clearerr(fp) (void) ((fp)->flags &= ~(_IOERR|_IOEOF)) +#define getchar() getc(stdin) +#define putchar(c) putc((c), stdout) +#define setbuf(fp, b) (void) setvbuf(fp, b, b ? _IOFBF:_IONBF, BUFSIZ) +#endif + +#endif diff --git a/include/lib/libc/stdlib.h b/include/lib/libc/stdlib.h new file mode 100644 index 0000000..6aec2b3 --- /dev/null +++ b/include/lib/libc/stdlib.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2012-2017 Roberto E. Vargas Caballero + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _STDLIB_H +#define _STDLIB_H + +#include + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#define _ATEXIT_MAX 32 + +#define MB_CUR_MAX 1 +#define RAND_MAX 32767 + +typedef struct { + int quot, rem; +} div_t; + +typedef struct { + long quot, rem; +} ldiv_t; + +typedef struct { + long long quot, rem; +} lldiv_t; + +extern double atof(const char *nptr); +extern int atoi(const char *nptr); +extern long int atol(const char *nptr); +extern long long int atoll(const char *nptr); +extern double strtod(const char * restrict nptr, char ** restrict endptr); +extern float strtof(const char * restrict nptr, char ** restrict endptr); +extern long double strtold(const char * restrict nptr, char ** restrict endptr); +extern long int strtol(const char * restrict nptr, char ** restrict endptr, int base); +extern long long int strtoll(const char * restrict nptr, char ** restrict endptr, + int base); +extern unsigned long int strtoul(const char * restrict nptr, char ** restrict endptr, + int base); +extern unsigned long long int strtoull(const char * restrict nptr, + char ** restrict endptr, int base); +extern int rand(void); +extern void srand(unsigned int seed); +extern void *calloc(size_t nmemb, size_t size); +extern void free(void *ptr); +extern void *malloc(size_t size); +extern void *realloc(void *ptr, size_t size); +extern void abort(void); +extern int atexit(void (*func)(void)); +extern void exit(int status); +extern void _Exit(int status); +extern char *getenv(const char *name); +extern int system(const char *string); +extern void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, + int (*compar)(const void *, const void *)); +extern void qsort(void *base, size_t nmemb, size_t size, + int (*compar)(const void *, const void *)); +extern int abs(int j); +extern long int labs(long int j); +extern long long int llabs(long long int j); +extern div_t div(int numer, int denom); +extern ldiv_t ldiv(long int numer, long int denom); +extern lldiv_t lldiv(long long int numer, long long int denom); +extern int mblen(const char *s, size_t n); +extern int mbtowc(wchar_t * restrict pwc, const char * restrict s, size_t n); +extern int wctomb(char *s, wchar_t wchar); +extern size_t mbstowcs(wchar_t * restrict pwcs, const char * restrict s, size_t n); +extern size_t wcstombs(char * restrict s, const wchar_t * restrict pwcs, size_t n); + +#ifdef __USE_MACROS +extern int __abs; +extern long __labs; +extern long long __llabs; + +#define abs(x) (__abs = (x), (__abs) < 0 ? -__abs : __abs) +#define labs(x) (__labs = (x), (__labs) < 0 ? -__labs : __labs) +#define llabs(x) (__llabs = (x), (__llabs) < 0 ? -__llabs : __llabs) +#endif + +#endif diff --git a/include/lib/libc/string.h b/include/lib/libc/string.h new file mode 100644 index 0000000..72ba769 --- /dev/null +++ b/include/lib/libc/string.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2012-2017 Roberto E. Vargas Caballero + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _STRING_H +#define _STRING_H + +#include + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +extern void *memcpy(void * restrict s1, const void * restrict s2, size_t n); +extern void *memmove(void *s1, const void *s2, size_t n); +extern char *strcpy(char * restrict s1, const char * restrict s2); +extern char *strncpy(char * restrict s1, const char * restrict s2, size_t n); +extern char *strcat(char * restrict s1, const char * restrict s2); +extern char *strncat(char * restrict s1, const char * restrict s2, size_t n); +extern int memcmp(const void *s1, const void *s2, size_t n); +extern int strcmp(const char *s1, const char *s2); +extern int strcoll(const char *s1, const char *s2); +extern int strncmp(const char *s1, const char *s2, size_t n); +extern size_t strxfrm(char * restrict s1, const char * restrict s2, size_t n); +extern void *memchr(const void *s, int c, size_t n); +extern char *strchr(const char *s, int c); +extern size_t strcspn(const char *s1, const char *s2); +extern char *strpbrk(const char *s1, const char *s2); +extern char *strrchr(const char *s, int c); +extern size_t strspn(const char *s1, const char *s2); +extern char *strstr(const char *s1, const char *s2); +extern char *strtok(char * restrict s1, const char * restrict s2); +extern void *memset(void *s, int c, size_t n); +extern char *strerror(int errnum); +extern size_t strlen(const char *s); + +#endif diff --git a/include/lib/libc/time.h b/include/lib/libc/time.h new file mode 100644 index 0000000..846ec21 --- /dev/null +++ b/include/lib/libc/time.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2012-2017 Roberto E. Vargas Caballero + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _TIME_H +#define _TIME_H + +#include + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#define CLOCKS_PER_SEC 1000000 + +typedef long int clock_t; + +struct tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; +}; + +extern clock_t clock(void); +extern double difftime(time_t time1, time_t time0); +extern time_t mktime(struct tm *timeptr); +extern time_t time(time_t *timer); +extern char *asctime(const struct tm *timeptr); +extern char *ctime(const time_t *timer); +extern struct tm *gmtime(const time_t *timer); +extern struct tm *localtime(const time_t *timer); +extern size_t strftime(char * restrict s, size_t maxsize, + const char * restrict format, + const struct tm * restrict timeptr); + +#endif diff --git a/readme.rst b/readme.rst index 4897f36..26e1fde 100644 --- a/readme.rst +++ b/readme.rst @@ -30,8 +30,9 @@ This project contains code from other projects as listed below. The original license text is included in those source files. -- The stdlib source code is derived from FreeBSD code, which uses various - BSD licenses, including BSD-3-Clause and BSD-2-Clause. +- The libc source code is derived from `FreeBSD`_ and `SCC`_. FreeBSD uses + various BSD licenses, including BSD-3-Clause and BSD-2-Clause. The SCC code + is used under the BSD-3-Clause license with the author's permission. - The libfdt source code is disjunctively dual licensed (GPL-2.0+ OR BSD-2-Clause). It is used by this project under the terms of @@ -275,3 +276,5 @@ .. _Change Log: ./docs/change-log.rst .. _User Guide: ./docs/user-guide.rst .. _Porting Guide: ./docs/porting-guide.rst +.. _FreeBSD: http://www.freebsd.org +.. _SCC: http://www.simple-cc.org/