Skip to content

KilianKegel/toro-C-Library

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Toro C Library (formerly known as Torito C Library)

C

The toro C Library is a monolithic Standard C Library for UEFI x86-64 target platform for Microsoft Visual Studio 2022.

toro C Library is the successor of "torito C Library". "torito C Library" is discontinued with version 20210820/R166. The main difference is, that toro C Library is build using the Visual Studio 2022 build environment, while "torito C Library" uses an UEFI EDK2 2016 build environment.

Additions of a C Library function set won't be done for "torito C Library" but for its grownup version toro C Library only.

toro C Library is an implementation targeting the ANSI/ISO C Standard Library compatibility to create applications for different operating systems using design –and debug– infrastructure provided by Microsoft Visual Studio 2022 VS2022.

Use cases

  1. create menu driven applications for the UEFI shell execution environment
  2. easily port existing Standard C programs to the UEFI shell execution environment, e.g. the ACPI reference implementation
  3. easily reimplement MSDOS programs for the UEFI shell execution environment
  4. quickly implement simple CLI tools for the UEFI shell execution environment

Implementation Status

non-C-Standard, Toro C Library specific extensions SHELL  DXE   PEI 
char* _strefierror(EFI_STATUS errcode) UEFI counterpart of strerror()
Diagnostics < assert.h > SHELL  DXE   PEI 
void _wassert (const wchar_t *,const wchar_t *,unsigned)C90, MSFT implementation for assert macro
Character handling < ctype.h > SHELL  DXE   PEI 
int isalnum(int) C90, is implemented
int isalpha(int) C90, is implemented
int iscntrl(int) C90, is implemented
int isdigit(int) C90, is implemented
int isgraph(int) C90, is implemented
int islower(int) C90, is implemented
int isprint(int) C90, is implemented
int ispunct(int) C90, is implemented
int isspace(int) C90, is implemented
int isupper(int) C90, is implemented
int isxdigit(int) C90, is implemented
int tolower(int) C90, is implemented
int toupper(int) C90, is implemented
Errors < errno.h > SHELL  DXE   PEI 
int *_errno(void)C90, MSFT implementation for errno macro
Format conversion of integer types < inttypes.h > SHELL  DXE   PEI 
intmax_t strtoimax(const char* strSource,char** endptr,int base) C99, is implemented
uintmax_t strtoumax(const char* strSource, char** endptr, int base) C99, is implemented
intmax_t wcstoimax(const wchar_t* strSource,wchar_t** endptr,int base) C99, is implemented
uintmax_t wcstoumax(const wchar_t* strSource, wchar_t** endptr, int base) C99, is implemented
Localization < locale.h > SHELL  DXE   PEI 
struct lconv *localeconv(void) C90, is implemented (C-locale)
char *setlocale(int category, const char *locale) C90, is implemented (C-locale)
Nonlocal jumps < setjmp.h > SHELL  DXE   PEI 
void longjmp(jmp_buf env, int val) C90, is implemented
int setjmp(jmp_buf env) C90, _setjmp is implemented
Signal handling < signal.h > SHELL  DXE   PEI 
int raise(int sig) C90, is implemented
void (*signal(int sig, void (*func)(int)))(int) C90, is implemented
Input/output < stdio.h > SHELL  DXE   PEI 
void clearerr(FILE *stream) C90, is implemented
int fclose(FILE *stream) C90, is implemented
int feof(FILE *stream) C90, is implemented
int ferror(FILE *stream) C90, is implemented
int fflush(FILE *stream) C90, is implemented
int fgetc(FILE *stream) C90, is implemented
int fgetpos(FILE * stream,fpos_t * pos) C90, is implemented
char *fgets(char * s, int n,FILE * stream) C90, is implemented
FILE *fopen(const char * filename,const char * mode) C90, is implemented
int fprintf(FILE * stream,const char * format, ...) C90, is implemented
int fputc(int c, FILE *stream) C90, is implemented
int fputs(const char * s,FILE * stream) C90, is implemented
size_t fread(void * ptr,size_t size, size_t nmemb,FILE * stream) C90, is implemented
FILE *freopen(const char * filename,const char * mode,FILE * stream) C90, is implemented
int fscanf(FILE * stream,const char * format, ...) C90, is implemented
int fseek(FILE *stream, long int offset, int whence) C90, is implemented
int fsetpos(FILE *stream, const fpos_t *pos) C90, is implemented
long int ftell(FILE *stream) C90, is implemented
size_t fwrite(const void * ptr,size_t size, size_t nmemb,FILE * stream) C90, is implemented
int getc(FILE *stream) C90, is implemented
int getchar(void) C90, is implemented
char *gets(char *s) C90, is implemented
void perror(const char *s) C90, is implemented
int printf(const char * format, ...) C90, is implemented
int putc(int c, FILE *stream) C90, is implemented
int putchar(int c) C90, is implemented
int puts(const char *s) C90, is implemented
int remove(const char *filename) C90, is implemented
int rename(const char *old, const char *new) C90, is implemented
void rewind(FILE *stream) C90, is implemented
int scanf(const char * format, ...) C90, is implemented
void setbuf(FILE * stream,char * buf) C90, is implemented
int setvbuf(FILE * stream,char * buf,int mode, size_t size) C90, is implemented
int snprintf(char * s, size_t n,const char * format, ...) C99, is implemented
int sprintf(char * s,const char * format, ...) C90, is implemented
int sscanf(const char * s,const char * format, ...) C90, is implemented
FILE *tmpfile(void) C90, is implemented
char *tmpnam(char *s) C90, is implemented
int ungetc(int c, FILE *stream) C90, is implemented
int vfprintf(FILE * stream,const char * format, va_list arg) C90, is implemented
int vfscanf(FILE * stream,const char * format, va_list arg) C99, is implemented
int vprintf(const char * format, va_list arg) C90, is implemented
int vscanf(const char * format, va_list arg) C99, is implemented
int vsnprintf(char * s, size_t n,const char * format, va_list arg) C99, is implemented
int _vsnwprintf(wchar_t* pszDest, size_t dwCount, const wchar_t* pszFormat, va_list ap) MSFT specific, is implemented
int vsprintf(char * s,const char * format, va_list arg) C90, is implemented
int vsscanf(const char * s,const char * format, va_list arg) C99, is implemented
String handling < string.h > SHELL  DXE   PEI 
char *_strdup(const char *strSource) MSFT specific, is implemented
int _stricmp(const char *string1, const char *string2) MSFT specific, is implemented
int _strnicmp(const char* pszDst, const char* pszSrc, size_t count) MSFT specific, is implemented
void *memchr(const void *s, int c, size_t n) C90, is implemented
int memcmp(const void *s1, const void *s2, size_t n) C90, is implemented
void *memcpy(void * s1,const void * s2, size_t n) C90, is implemented
void *memmove(void *s1, const void *s2, size_t n) C90, is implemented
void *memset(void *s, int c, size_t n) C90, is implemented
char *strcat(char * s1,const char * s2) C90, is implemented
char *strchr(const char *s, int c) C90, is implemented
int strcmp(const char *s1, const char *s2) C90, is implemented
int strcoll(const char *s1, const char *s2) C90, is implemented
char *strcpy(char * s1,const char * s2) C90, is implemented
size_t strcspn(const char *s1, const char *s2) C90, is implemented
char *strerror(int errnum) C90, is implemented
size_t strlen(const char *s) C90, is implemented
char *strncat(char * s1,const char * s2, size_t n) C90, is implemented
int strncmp(const char *s1, const char *s2, size_t n) C90, is implemented
char *strncpy(char * s1,const char * s2, size_t n) C90, is implemented
char *strpbrk(const char *s1, const char *s2) C90, is implemented
char *strchr(const char *s, int c) C90, is implemented
size_t strspn(const char *s1, const char *s2) C90, is implemented
char *strstr(const char *s1, const char *s2) C90, is implemented
char *strtok(char * s1,const char * s2) C90, is implemented
size_t strxfrm(char * s1,const char * s2, size_t n) C90, is implemented
Date and time < time.h > SHELL  DXE   PEI 
char *asctime(const struct tm *timeptr) C90, is implemented
clock_t clock(void) C90, is implemented
char *ctime(const time_t *timer) C90, is implemented
double difftime(time_t time1, time_t time0) C90, is implemented
struct tm *gmtime(const time_t *timer) C90, is implemented
struct tm *localtime(const time_t *timer) C90, is implemented
time_t mktime(struct tm *timeptr) C90, is implemented
size_t strftime(char * s,size_t maxsize,const char * format,const struct tm * timeptr) C90, is implemented
time_t time(time_t *timer) C90, is implemented
Extended multibyte/wide character utilities < wchar.h > SHELL  DXE   PEI 
wint_t btowc(int c) C95, is implemented
double wcstod(const wchar_t * nptr,wchar_t ** endptr) C95, is not yet implemented
wint_t fgetwc(FILE *stream) C95, is implemented
wchar_t *fgetws(wchar_t * s, int n,FILE * stream) C95, is implemented
wint_t fputwc(wchar_t c, FILE *stream) C95, is implemented
int fputws(const wchar_t * s,FILE * stream) C95, is implemented
int fwide(FILE *stream, int mode) C95, is implemented
int fwprintf(FILE * stream,const wchar_t * format, ...) C95, is implemented
int fwscanf(FILE * stream,const wchar_t * format, ...) C95, is implemented
wint_t getwc(FILE *stream) C95, is implemented
wint_t getwchar(void) C95, is implemented
size_t mbrlen(const char * s, size_t n,mbstate_t * ps) C95, is implemented
size_t mbrtowc(wchar_t * pwc,const char * s, size_t n,mbstate_t * ps) C95, is implemented
int mbsinit(const mbstate_t *ps) C95, is implemented
size_t mbsrtowcs(wchar_t * dst,const char ** src, size_t len,mbstate_t * ps) C95, is implemented
wint_t putwc(wchar_t c, FILE *stream) C95, is implemented
wint_t putwchar(wchar_t c) C95, is implemented
int swprintf(wchar_t * s, size_t n,const wchar_t * format, ...) C95, is implemented
int swscanf(const wchar_t * s,const wchar_t * format, ...) C95, is implemented
wint_t ungetwc(wint_t c, FILE *stream) C95, is implemented
int vfwprintf(FILE * stream,const wchar_t * format, va_list arg) C95, is implemented
int vfwscanf(FILE *stream, const wchar_t *format, va_list argptr) C99, is implemented
int vswprintf(wchar_t * s, size_t n,const wchar_t * format, va_list arg) C95, is implemented
int vswscanf(const wchar_t *buffer, const wchar_t *format, va_list arglist) C99, is implemented
int vwprintf(const wchar_t * format,va_list arg) C95, is implemented
size_t wcrtomb(char * s, wchar_t wc,mbstate_t * ps) C95, is implemented
wchar_t *wcscat(wchar_t * s1,const wchar_t * s2) C95, is implemented
wchar_t *wcschr(const wchar_t *s, wchar_t c) C95, is implemented
int wcscmp(const wchar_t *s1, const wchar_t *s2) C95, is implemented
int wcscoll(const wchar_t *s1, const wchar_t *s2) C95, is implemented
size_t wcscspn(const wchar_t *s1, const wchar_t *s2) C95, is implemented
size_t wcsftime(wchar_t * s, size_t maxsize,const wchar_t * format,const struct tm * timeptr) C95, is implemented
size_t wcslen(const wchar_t *s) C95, is implemented
wchar_t *wcsncat(wchar_t * s1,const wchar_t * s2, size_t n) C95, is implemented
int wcsncmp(const wchar_t *s1, const wchar_t *s2,size_t n) C95, is implemented
wchar_t *wcsncpy(wchar_t * s1,const wchar_t * s2, size_t n) C95, is implemented
int _wcsnicmp(const wchar_t *s1, const wchar_t *s2,size_t n) C95, is implemented
wchar_t *wcspbrk(const wchar_t *s1, const wchar_t *s2) C95, is implemented
wchar_t *wcscpy(wchar_t * s1,const wchar_t * s2) C95, is implemented
wchar_t *wcsrchr(const wchar_t *s, wchar_t c) C95, is implemented
size_t wcsrtombs(char * dst,const wchar_t ** src, size_t len,mbstate_t * ps) C95, is implemented
size_t wcsspn(const wchar_t *s1, const wchar_t *s2) C95, is implemented
wchar_t *wcsstr(const wchar_t *s1, const wchar_t *s2) C95, is implemented
wchar_t *wcstok(wchar_t * s1,const wchar_t * s2,wchar_t ** ptr) C95, is implemented
long int wcstol(const wchar_t * nptr,wchar_t ** endptr, int base) C95, is implemented
long long wcstoll(const wchar_t* strSource,wchar_t** endptr,int base) C99, is implemented
unsigned long int wcstoul(const wchar_t * nptr,wchar_t ** endptr, int base) C95, is implemented
unsigned long long wcstoull(const wchar_t* s, wchar_t** endptr, int base) C99, is implemented
size_t wcsxfrm(wchar_t * s1,const wchar_t * s2, size_t n) C95, is implemented
int wctob(wint_t c) C95, is implemented
wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n) C95, is implemented
int wmemcmp(const wchar_t *s1, const wchar_t *s2,size_t n) C95, is implemented
wchar_t *wmemcpy(wchar_t * s1,const wchar_t * s2, size_t n) C95, is implemented
wchar_t *wmemmove(wchar_t *s1, const wchar_t *s2,size_t n) C95, is implemented
wchar_t *wmemset(wchar_t *s, wchar_t c, size_t n) C95, is implemented
int wprintf(const wchar_t * format, ...) C95, is implemented
int wscanf(const wchar_t * format, ...) C95, is implemented
General utilities < stdlib.h > SHELL  DXE   PEI 
char* _i64toa(long long _Value, char* _Buffer, int _Radix) MSFT specific, is implemented
wchar_t* _i64tow(long long _Value, wchar_t* _Buffer, int _Radix) MSFT specific, is implemented
char* _itoa(int _Value, char* _Buffer, int _Radix) MSFT specific, is implemented
wchar_t* _itow(int _Value, wchar_t* _Buffer, int _Radix) MSFT specific, is implemented
char* _ltoa(long _Value, char* _Buffer, int _Radix) MSFT specific, is implemented
wchar_t* _ltow(long _Value, wchar_t* _Buffer, int _Radix) MSFT specific, is implemented
char* _ui64toa(unsigned long long _Value, char* _Buffer, int _Radix) MSFT specific, is implemented
char* _ultoa(unsigned long _Value, char* _Buffer, int _Radix) MSFT specific, is implemented
wchar_t* _ultow(unsigned long _Value, wchar_t* _Buffer, int _Radix) MSFT specific, is implemented
void abort(void) C90, is implemented
int abs(int j) C90, is implemented
int atexit(void (*func)(void)) C90, is implemented
double atof(const char *nptr) C90, is not yet implemented
int atoi(const char *nptr) C90, is implemented
long int atol(const char *nptr) C90, is implemented
void *bsearch(const void *key, const void *base,size_t nmemb, size_t size,int (*compar)(const void *, const void *)) C90, is not yet implemented
void *calloc(size_t nmemb, size_t size) C90, is implemented
div_t div(int numer, int denom) C90, is implemented
void exit(int status) C90, is implemented
void free(void *ptr) C90, is implemented
char *getenv(const char *name) C90, is implemented
long int labs(long int j) C90, is implemented
ldiv_t ldiv(long int numer, long int denom) C90, is implemented
void *malloc(size_t size) C90, is implemented
int mblen(const char *s, size_t n) C90, is implemented
size_t mbstowcs(wchar_t * pwcs,const char * s, size_t n) C90, is implemented
int mbtowc(wchar_t * pwc,const char * s, size_t n) C90, is implemented
void qsort(void *base, size_t nmemb, size_t size,int (*compar)(const void *, const void *)) C90, is implemented
int rand(void) C90, is implemented
void *realloc(void *ptr, size_t size) C90, is implemented
void srand(unsigned int seed) C90, is implemented
double strtod(const char * nptr,char ** endptr) C90, is not yet implemented
long int strtol(const char * nptr,char ** endptr, int base) C90, is implemented
unsigned long int strtoul(const char * nptr,char ** endptr, int base) C90, is implemented
int system(const char *string) C90, is implemented
size_t wcstombs(char * s,const wchar_t * pwcs, size_t n) C90, is implemented
int wctomb(char *s, wchar_t wchar) C90, is implemented
Wide character classification and mapping utilities < wctype.h > SHELL  DXE   PEI 
int iswalnum(wint_t wc) C95, is implemented
int iswalpha(wint_t wc) C95, is implemented
int iswblank(wint_t wc) C99, is implemented
int iswcntrl(wint_t wc) C95, is implemented
int iswctype(wint_t wc, wctype_t desc) C95, is implemented
int iswdigit(wint_t wc) C95, is implemented
int iswgraph(wint_t wc) C95, is implemented
int iswlower(wint_t wc) C95, is implemented
int iswprint(wint_t wc) C95, is implemented
int iswpunct(wint_t wc) C95, is implemented
int iswspace(wint_t wc) C95, is implemented
int iswupper(wint_t wc) C95, is implemented
int iswxdigit(wint_t wc) C95, is implemented
wint_t towctrans(wint_t wc, wctrans_t desc) C95, is implemented
wint_t towlower(wint_t wc) C95, is implemented
wint_t towupper(wint_t wc) C95, is implemented
wctrans_t wctrans(const char *property) C95, is implemented
wctype_t wctype(const char *property) C95, is implemented
mathematical functions< math.h > SHELL  DXE   PEI 
double acos(double x) C90, is not yet implemented
double asin(double x) C90, is not yet implemented
double atan(double x) C90, is not yet implemented
double atan2(double x, double y) C90, is not yet implemented
double ceil(double x) C90, is not yet implemented
double cos(double x) C90, is not yet implemented
double cosh(double x) C90, is not yet implemented
double exp(double x) C90, is not yet implemented
double fabs(double x) C90, is not yet implemented
double floor(double x) C90, is not yet implemented
double fmod(double x, double y) C90, is not yet implemented
double frexp(double value, int *exp) C90, is not yet implemented
double ldexp(double value, int exp) C90, is not yet implemented
double log(double value) C90, is not yet implemented
double log10(double value) C90, is not yet implemented
double modf(double value, double *iptr) C90, is not yet implemented
double pow(double x, double y) C90, is not yet implemented
double sin(double x) C90, is not yet implemented
double sinh(double x) C90, is not yet implemented
double sqrt(double x) C90, is not yet implemented
double tan(double x) C90, is not yet implemented
double tan(double x) C90, is not yet implemented
non-C-Standard and Microsoft specific functions< direct.h > SHELL  DXE   PEI 
int _mkdir(const char *dirname) MSFT specific, is implemented
non-C-Standard and Microsoft specific functions< mbctype.h > SHELL  DXE   PEI 
int _getmbcp(void) MSFT specific, is implemented
int _setmbcp(int codepage) MSFT specific, is implemented
non-C-Standard and Microsoft specific functions< io.h > SHELL  DXE   PEI 
int _close(int fd) MSFT specific, is implemented
int _eof(int fd) MSFT specific, is implemented
FILE *_fdopen(int fd, const char *mode) MSFT specific, is implemented
int _fileno(FILE *stream) MSFT specific, is implemented
intptr_t _findfirst(const char *filespec, struct _finddata_t *fileinfo) MSFT specific, is implemented
int _findnext(intptr_t handle,struct _finddata_t *fileinfo) MSFT specific, is implemented
int _findclose(intptr_t handle) MSFT specific, is implemented
int _isatty( int fd ); MSFT specific, is implemented
long _lseek(int fd, long offset, int origin) MSFT specific, is implemented
int _open(const char *filename, int oflag [,int pmode]) MSFT specific, is implemented
int _read(int const fd, void * const buffer, unsigned const buffer_size) MSFT specific, is implemented
int _write(int fd, const void *buffer, unsigned int count) MSFT specific, is implemented
non-C-Standard and Microsoft specific / POSIX functions< sys/stat.h > SHELL  DXE   PEI 
int _stat64i32(const char *path, struct _stat64i32 *buffer)MSFT specific, is implemented

Source Code

Repo name

Goal

The toro C Library is designed to enable the developer to create Standard C programs for UEFI Shell, Windows NT and Linux (in future releases) running in x86-64 mode. Standard C compliant source code shall be easily portable to operating systems supported by toro C Library.

The toro C Library shall provide full library compatibility with

  • ANSI X3.159-1989 ("ANSI C")
  • ISO/IEC 9899 First edition 1990-12-15 ("C90")
  • ISO/IEC 9899 First edition 1990-12-15, Amendment 1, 1995-04-01 ("C95")

Forwards to the roots

Extensions to these standards (ISO 9899:1999 etc.), secure / bounds checking interface functions xyz_s() from ISO 9899:2011, Annex K, POSIX functions or Microsoft specific add-ons will be implemented on demand into toro C Library.

Be aware, that functions like stricmp() (case sensitive string handling), itoa() (integer to string conversion), a very famous kbhit() (check for keystroke at console0), fopen()-mode-strings like "rt", "wt" (textmode read/write, just use "r", "w" instead) and open() (POSIX) are provided in various C-Library-implementations, but not specified by ANSI X3.159-1989 or ISO/IEC 9899:1990, and therefore currently not available in the toro C Library, but will be implemented on demand.

ANSI C Specification

As long as the developer moves within these standards1 and does not use any OS-specific interface or platform dependent idiosyncrasy, the created executable shall be producible merely by linking the object modules against toro C Library and choosing the OS-dependent /ENTRY:_cdeCRT0OSNAME, e.g. _cdeCRT0UefiShell or _cdeCRT0WinNT.

Approach

The C-Standards mentioned above leave some freedom for a particular library implementation; this affects return values that provide flags beside beeing only 'nonzero' as specified or different handling of text vs. binary mode for file operations.

C-Library vendors usually describe their own specific details, but not the Standard C requirements. Using and relying on such implementation-specific details makes the source code non-portable to other C-Libraries, e.g. GLIBC.

The toro C Library is intended to be identical in all aspects to functions specified in ANSI C, C90 and C95 provided in LIBCMT.LIB that comes with VS2022. (It is assumed, that LIBCMT.LIB of VS2022 is compliant to aforementioned standards.)

Microsoft C Language Reference

Doing so, the development of toro C Library itself is unburdened from the exegesis of the specifications mentioned above and the creation of the required header files -- the header files delivered with VS2022 are utilized instead.

The developer using toro C Library benefits from this approach because the experience remains unchanged using the VS2022 environment.

Riding the UEFI shell / enabling the platform for developers

With the disappearance of MSDOS as a simple, single threaded, unprotected operating system with full hardware access to user programs on upcoming personal computer models the UEFI shell was intended to be the successor of MSDOS.

But the lack of an established, well known programming interface (as is the Standard C library) makes it cumbersome to get started on UEFI Shell programming.

Reimplementing LIBCMT.LIB for WinNT

The sole purpose of toro C Library for WinNT is to validate the C library compatibility on a Windows-x64-Platform. Usually testprograms are linked once against the original LIBCMT.LIB and then against toro C Library for WinNT to be able to compare program behavior in Windows.4 Most of all bugs and pitfalls can be found quickly, debugged easily and fixed soon, in the build and debug environment of Visual Studio.

It is considered the only effective way to reach the ANSI C compatibility and strive for a faultless implementation within a reasonable amount of time, because by far most parts of each single function test can be run through, debugged and tested natively on the (Windows) development machine. Only final tests need to be run on the UEFI Shell target. This proceeding can be reached only by the OSIF (Operating System Interface) architecture of the library.

HELLO is now WELCOME

//
// WELCOME.c
//
#include <stdio.h>

int main(int argc, char **argv){

    printf("WELCOME, to ANSI C\n");

    return 0;
}

WELCOME.c can be translated in the VS2022 64Bit command line environment by running the build.bat script below:

@echo off
echo Compiling the C source...
cl /nologo /c /GS- /D_NO_CRT_STDIO_INLINE /D_CRT_SECURE_NO_WARNINGS WELCOME.c

echo Linking the .OBJ to UEFI SHELL Executable WELCOME.EFI 
link /nologo /NODEFAULTLIB /ENTRY:_cdeCRT0UefiShell /OUT:welcome.efi /SUBSYSTEM:EFI_APPLICATION WELCOME.obj toroC64.lib

echo Linking the .OBJ to Windows NT Executable WELCOME.EXE
link /nologo /NODEFAULTLIB /ENTRY:_cdeCRT0WinNT /OUT:welcome.exe /SUBSYSTEM:CONSOLE WELCOME.obj toroC64.lib KERNEL32.LIB

With just one additional link-step in the above script, without re-compiling, a Windows NT executable could be created.

If you prefer to use state-of-the-art build environment Visual Studio 2022, please follow the step-by-step-configuration HowTo-configure-VS2022-to-build-.EFI-executables

To run Visual Studio 2022 .EFI samples, check out Visual-ANSI-C-for-UEFI-Shell.

Known bugs

  • printf()-family's format specifiers e,f,g2 not yet implemented
  • scanf()-family's format specifiers [],p,e,f,g2,C,S not yet implemented
  • 20181129: file operations does not yet support drive mappings and path
  • 20180107: strtol()'s/strtoul()'s base parameter accepts only 0d, 8d, 10d, 16d. Letters aâ��z or Aâ��Z representing digits in the range [10, 36] are not (yet) supported.
  • <time.h>: UTC-only support. No Daylightsaving, no timezones.
  • <locale.h>: C-locale-only support
  • <math.h> not yet implemented2
  • 20191017: CTRL-C interception not yet implemented
  • 20191017: toro C Library based progams use ASCII console interface only, not UCS-2!
    • ASCII is written to stdoutand stderr
    • ASCII is read from stdin pay attention when dealing with >, <, | and >a, <a, |a shell operators

non-Standard C90/C95 functions that will be implemented on demand

Revision history

20240505, v0.8.4 Build 91

  • fixed EDK2 DEBUG trace macro won't crash anymore with UEFI specific (non-ANSI-C) format specifiers: %g, %t and %r
    NOTE: The improvement above doesn't change ANSI-C related behaviour of previous library versions

20240414, v0.8.2 Build 73

  • add timeout detection for disabled COM1/UART at I/O 3F8h used for debug traces.
    NOTE: Disabled I/O devices usually do not respond to I/O cycles.
    Internally this is done by ignoring the chipselect for that particular I/O address range, e.g. 3F8h .. 3FFh for COM1.
    FFh is driven to the data bus when reading registers of those disabled devices.
    On special implementations hardware designers chose a different approach to disabled devices:
    1. address decoding is kept enabled
    2. internal clock line is stopped or decoupled from internal circuitry
      The disadvantage of this aproach is, that status registers are still visible but not updated anymore.

20240309, v0.8.1 Build 54

20231118

  • add ACPI timer based synchronization for toro C Library Shell programs. NOTE: On recent Intel platforms the previously used legacy timer's (i8254) input clock frequency is clocked down to an unspecified frequency with setup default Enable 8254 Clock Gate. Additionally the I/O latency to access i8254 ports is increased with setup default Legacy IO Low Latency that lowers i8254 based timing precision.
    So i8254 gets unusable for UEFI Shell programs on new platforms.
  • improve synchronization error correction for i8254 based POST drivers (with Enable 8254 Clock Gate := disable, Legacy IO Low Latency := enable)

20231014

20230926

  • fixed: _strefieerror() to return error correct string when running in pre-memory PEI

20230916

  • improve debug trace CDETRACE() configuration switches
    • #define CDEDBG STDOUT – traces directed to stdout
    • #define CDEDBG STDERR – traces directed to stderr
    • #define CDEDBG STDDBG – traces directed to CDE debug channel, normally COM1, I/O 0x3F8 115200,8,n,1
    • CDEDBG undefined – UEFI Shell/post DRIVERS: STDDBG, Windows NT: STDOUT

20230909

  • add CDE(C Development Environment)-interface for native Tianocore UEFI SHELL UEFISHELLDRV.
    Enable Toro-C-LibraryDXE function set at CRT0() and full Toro-C-LibrarySHELL function set with availability of the EfiShellProtocol/EFI_SHELL_PROTOCOL_GUID:
    https://github.com/KilianKegel/Visual-TORO-C-LIBRARY-for-UEFI/tree/main/toroCLibrary/OSInterface/UEFISHELLDRV

    This is the foundation of an ANSI-C-API-extended "CDE UEFI SHELL"

  • prepare system() ANSI-C-API call for MSDOS drive name support (A:, B:, C: ...) coming soon for Visual-UEFI-SHELL

  • update MdePkg to version edk2-stable202308

  • improve CDEABI (C Development Environment Application Binary Interface)

    • force all Core and operating system interface osif modules to uses exclusively ANSI-C-API on CDEABI to avoid collision with EDK2 StdLibC and relatives
      primarily remaining errno(), setjmp(), longjmp(), strlen(), strcpy(), strcmp(), wcslen(), wcscpy(), wcscmp()
  • improve freopen() to set redirection flag O_CDEREDIR to speed up character transission to file

  • fix fscanf(): assignment suppression indicated by a "*": https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf#page=295

  • fix raise()

  • INTERN:

    • add: size_t _cdeInt2EfiStatus(int intstatus)
    • add: int _cdeEfiStatus2Int(size_t Status)
    • move selected file functions to CdeAppIf driver side.
      This allows future/upcoming code size reduced shell application type.
    • preliminary: LINUX-OSIF buildable, ALPHA
    • preliminary: osifCdeUefiShellAppEntryPoint(), osifCdeUefiShellAppCRT0Service() for future/upcoming shell application type that doesn't include entire CdeAppIf machine code to each .EFI application, but share CdeAppIf provided by a CDE UEFI SHELL. This allows code size reduced applications.

20230625

20230415

  • fixed: in the pre-Memory-Discovered PEI (Pre Efi Initialization) POST x86-32 Standard C function localeconv() crashed the platform.
    NOTE: All x86-64 operation modes (UEFI Shell, UEFI SMM, UEFI DXE, Windows NT) and post-Memory-Discovered PEI (Pre Efi Initialization) x86-32 was not affected by that bug.

20230409

NOTE: This release 20230409 doesn't change UEFI Shell programs behavior
The improvements provided here only affects PEI drivers, based on toro C Library/CdePkg listed below:

  • add Memory Discovered handling for PEIM (Pre-EFI Initialization Module)

    • restart memory management when switching from CAR (Cash As RAM) to permanent memory
    • reassign CDE_SERVICES pointer when switching from CAR (Cash As RAM) to permanent memory
  • support of multi-invocation of CdePkg-based PEIM

    • NOTE: Each CdePkg-based PEIM needs a small, read-/writeable, dedicated static duration to provide Standard C Library compliance (e.g. to hold atexit()-registered function pointers, the internal strtok()pointer, the rand() next, the jump buffer, the I/O buffer for stdin, stdout and stderr ...).

      Internally this is provided in the HOB storage area and holds a CDE_APP_IF protocol registered with the driver specific gEfiCallerIdGuid. HOB storage is available early in POST in PEI (Pre-EFI Initialization).

      Once a PEIM is started multiple times, only the first instance static duration will be reinitialized with current EFI_PEI_FILE_HANDLE, EFI_PEI_SERVICES and the current CDE_SERVICES pointer.

      This proceeding prevents LocatePpi() to return an invalid pointer to the first instance, while a second instance is currently active.

  • improve CDEABI (C Development Environment Application Binary Interface), used as collision avoidance with EDK2 StdLibC and relatives
    NOTE: In real-world UEFI implementations various components provide "reduced"(mildly put) Standard C Interface just fitting the requirements of that particular package (CryptoPkg, RedfishPkg).

    To avoid symbol double definitions at link time or link order failures with EDK2 StdLibC, CDEABI:

    • provides Standard C Functions in their __declspec(dllimport) incarnation only
    • except for Microsoft compiler intrinsics __cdecl memset() and __cdecl memcmp() that are paired with the its __declsspec(dllimport) counterpart in the same COMDAT (same .OBJ module)

20230304

  • fixed strtok(), wcstok()

20230212

  • introduce CDEABI, an additional application binary interface ABI to ease coexistance of CdePkg based BIOS drivers with incomplete tianocore EDK2 C Library fragments

    NOTE: CDEABI uses the Microsoft DLL interface __declspec(dllimport) for EDK2-built drivers . Technically this uses indirect function calls on machine code level.

  • promote CDETRACE(), remove former, alternate trace method (CDEMOFINE()) completely

20230104

  • fixed strftime() parameter: %I, %m, %x

20230103

  • add Microsoft/POSIX C Library functions:
    • _isatty()
  • imitate funny/buggy Microsoft behaviour for fopen() with fmode parameter w+ or a:
    function terminates successfully with errno set to 22, Invalid argument
  • imitate funny/buggy Microsoft behaviour for _fileno() with invalid filepointer:
    MSFT: _fileno(-1) just crashes by an invalid memory access
    This behaviour is imitated by an exit(3) invocation
  • fixed application crash at termination when a redirected I/O stream STDERR is reopened with reopen()
  • improve existing invalidate parameter handling; enable file name string, function name string, line number string and expression string at RELEASE runtime
    NOTE: Microsoft enables this feature only when using DEBUG version of LIBCMT.LIB.

20221022

  • add O_TEMPORARY support to Microsoft/POSIX _open()
  • fixed "fall time bug" (autumn). Broken time calculation on two digit month number (Oct, Nov, Dec).

20220731

  • add Standard C90 Library functions:
    • wcstoul()
    • wcstol()
  • add Standard C99 Library functions:
    • strtoull()
    • strtoll()
    • strtoimax()
    • strtoumax()
    • wcstoull()
    • wcstoll()
    • wcstoimax()
    • wcstoumax()
  • add Microsoft/POSIX C Library functions:
    • _ultow()
    • _ultoa()
    • _ui64tow()
    • _ui64toa()
    • _ltow()
    • _ltoa()
    • _itow()
    • _itoa()
    • _i64tow()
    • _i64toa()
  • implement full __chkstk() for Windows 32Bit: https://docs.microsoft.com/en-us/windows/win32/devnotes/-win32-chkstk
  • fixed stdout/stderr redirection > and >> didn't work anymore (since 20220501)
  • fixed "a"/O_APPEND append file open attribute didn't work anymore (since 20220501)
  • fixed ftell()/fgetpos() reports wrong offset after writing to "a"/O_APPEND opened files

20220529

  • fixed: free() and C++ operator delete() crash to free NULL pointer

20220522

  • add C++ minimum support
    • void* operator new(size_t size)
    • void* operator new[](size_t size)
    • void operator delete[](void* ptr)
    • void operator delete(void* ptr, unsigned __int64 size)

20220501

  • add Microsoft/POSIX C Library functions:
    • _open()
    • _close()
    • _read()
    • _write()
    • _fdopen()
    • _fileno()
    • _wfopen()
    • _fseeki64()
    • _ftelli64()
  • fixed errno values for file position functions with negative offsets (fsetpos(), fseek())
  • fixed UEFI BUG: gap of non-initialized disk space
    File positioning bug, if data written behind EOF, data range between old EOF and new data contains medium data / garbage, instead of 0
  • simplify CDETRACE() implemantation, improve portability of that CdePkg specific debug macro
  • add _strefierror(): rename Toro-C-Library UEFI-specific function strefierror() to ANSI C naming convention compatible _strefierror()
  • implement full __chkstk() for Windows 64Bit: https://docs.microsoft.com/en-us/windows/win32/devnotes/-win32-chkstk
  • partially implementation of the %G fprintf() – format specifier for Visual-LIBXLSXWRITER-for-UEFI-Shell
  • fixed fread() end-of-file indicator not set correctly when EOF is reached within a buffer instead of reading of 0 bytes from the mass storage device
  • changed exit code of the abort() function from 3 to 0xC0000409
  • fixed: reassigned (by running freopen()) filepointers to stdout/stderr are not flushed at exit
  • CdePkg– SMM Driver: Erroneous message shown at startup: FATAL ERROR : CdeServices SMM not available

20220109

  • add Standard C Library functions:
    • strcoll()
    • strxfrm()
    • fgetwc()
    • fputwc()
    • fputws()
    • fwide()
    • fwprintf()
    • fwscanf()
    • getwc()
    • getwchar()
    • putwc()
    • putwchar()
    • swscanf()
    • ungetwc()
    • vfwscanf()
    • vswscanf()
    • wcscoll()
    • wcsxfrm()
    • btowc()
  • fix "BINARY MODE" for wide printf()/scanf() family functions
  • imitate funny Microsoft behaviour when replacing and pushing back -ungetc()- a character by CTRL-Z to a stream (in that case the stream is not terminated)
  • fix fscanf() family return value for "event of an early matching failure" http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=299

20211218

  • introduce CDETRACE() debug/trace macro that is parameter checked at build time
  • improve wmain() support; now selected at build time by choosing the CRT0 entry point name
    • _cdeCRT0UefiShellW()
    • _cdeCRT0WinNTW() NOTE: The *env pointer is not passed to wmain()

20211128

  • fixed: UEFI Shell overwrites the last line of text of a previously terminated application with its prompt
  • add: fgetws()

20211107

  • add wmain() support
    ATTENTION: The presence of main() is not detected at build time anymore, but at runtime.

20211031

  • add Microsoft specific fopen() mode string modifier "t" for text mode
    • NOTE: "t" modifier is not defined by ANSI/ISO C, because binary/text mode differentiation is done by "w" modifier only.
  • fix fclose() bug in UEFI shell returns an error, when closing a read only file

20211010

  • add Microsoft C Library functions for UEFIShell 64Bit applications only

    • _mkdir()
    • _stat64i32() that is the Microsoft version of POSIX stat()

    add POSIX C Library functions

    • strnlen(), wcsnlen()

20210912

  • initial version of TORO C LIBRARY (toroC64.lib and toroC32.lib)
  • TORITO C LIBRARY is discontinued from now on
  • add Microsoft C Library functions for UEFIShell applications only
    • getc()
    • _findfirst()
    • _findnext()
    • _findclose()

20210820/R166

  • add Standard C Library functions
    • mblen()
    • mbstowcs()
    • mbtowc()
    • wcstombs()
    • wctomb()
    • wctob()
    • wmemchr()
    • vfwprintf()

20210815/R165

  • fixed time calibration issue on AMD (Ryzen7, A6)
    • on AMD systems the RTC device sporadically loses the PF (periodic interrupt) flag from RTC register 0x0C
    • instead PIT 8254 timer seems to be reliable on AMD and Intel platforms

20210808/R164

  • fixed bugs related to length modifiers for string format specifiers
    • wprintf() with %ls, %hs and Microsoft specific %S
    • printf() with %ls, %hs and Microsoft specific %S
    • the string (null) was reported wrongly in wide format on NULL pointer (e.g. wprintf()or %ls modifier)

20200416/R159

  • fixed "" at end of commandline not detected by command line parser
  • fixed improved stability of TSC based TIME.H functions, improved TSC calibration
  • force minimum ShellProtocol version to v2.2
  • fixed Torito C Library for NT redirects STDOUT to file always beginning to file begin, instead of file end That overwrites a logfile used for multiple redirected traces

20200204/R154

  • add VS2019/16.4.4 support
  • update copyright

20191216/R152

20191126/R149

  • fixed Torito C library CRT0 for Windows NT data corruption may crash the application
  • fixed functions snprintf() and vsnprintf() return value: number of characters that would have been written had n been sufficiently large

20191111/R146

  • add missing intrinsic functions _difftime64() and _gmtime64() required by Microsoft Compiler
  • fixed mktime() to crash with invalid time/date before 01/01/1970 00:00:00

20191017/R141

  • add CTRL-C support
    NOTE: CTRL-C is implemented on Signal handling <signal.h> interface and can be catched and supressed by the application. https://github.com/KilianKegel/Visual-ANSI-C-for-UEFI-Shell/blob/master/welcome9/welcome9.c
  • fixed system() library function does not workaround completely fully the EfiShellProtocol->Execute() bug to display the drive mappings, when multipartition ("BLK10") mass storage device is attached
  • implement UEFI Shell compatibility mode for STDOUT and STDERR to allow I/O redirection >a for ASCII and > for UCS-2/UTF16
  • add build switch char _gSTDOUTMode = 1; /* 0 == UEFI Shell default, 1 == ASCII only */ to force TORITO C backward compatibility ( ASCII mode only )
  • autodetect I/O redirection UTF16 vs. ASCII

20190918/R137

  • update copyright

20190621/R133

  • add VS2019 compatibility, remove library dependancy from compiler version

20190410/R126

  • fixed: scanf() related functions fails to terminate tokens, e.g. sscanf("123:456","%d:%d",&n1,&n2)
  • fixed: qsort() fails if number of elements (nmemb) is 0
  • add _wassert() required by newer assert-macro implementations

20190116/R124

  • fixed single '\r', ASCII 0x0D, carriage return, that appears w/o '\n', ASCII 0x0A, line feed in a file, opened in text mode, is handled wrongly.

    NOTE: ftell(), fgetpos(), fsetpos() in textmode is implemented differently. Unable to reimplement LIBCMT.lib bugs, when '\n' or Ctrl-Z is present in the text file
    fposbug.c

20190109/R123

  • add getenv()
  • add rename()

20181221/R122

  • add <locale.h> related: setlocale(), localeconv() - supporting C-locale only

20181216/R119

  • add missing memchr() from string.h
  • add <wctype.h> related functions: iswalnum(), iswalpha(), iswblank(), iswcntrl(), iswctype(), iswdigit(), iswgraph(), iswlower(), iswprint(), iswpunct(), iswspace(), iswupper(), iswxdigit(), towctrans(), towlower(), towupper(), wctrans(), wctype()

20181129/R116

20181112/R110

  • add %[] scanset format specifier to scanf-family
  • add %p pointer format specifier to scanf-family
  • fixed token count bug in scanf-family

20180921/R107

  • add VS2017/15.8 support (Just My Code)

20180830/R102

  • add system() library function
  • improved stability of memory management

20180717/R101

  • add qsort(), vsscanf()
  • fixed calloc()

20180508

  • added WELCOME.c sample
  • added BUILD.BAT sample

20180411/R95

20180130/R86

  • added getchar(), remove(), tmpfile(), tmpnam()

20180108/R85

  • fixed: strol() and stroul() doesn't support base 2..36 required by the Standard C Library
  • fixed: time() function N/A in Windows build
  • fixed: time base in Windows build is QPC now, not TSC.
  • fixed: gets() functions fails with lines starting with '\n'

20171105/R78

  • initial revision