From 2a52c22f36854e7c322c92adbee98555ad75dbd8 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Sun, 27 Nov 2022 05:19:14 +0400 Subject: [PATCH] Implement libc callbacks (#112) --- libc/Makefile.am | 1 + libc/include/Makefile.am | 1 + libc/include/kernaux/libc.h | 26 +++++++++++++++++++++ libc/include/stdlib.h | 4 ++++ libc/src/kernaux.c | 17 ++++++++++++++ libc/src/stdlib.c | 46 +++++++++++++++++++++++++++++++++---- 6 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 libc/include/kernaux/libc.h create mode 100644 libc/src/kernaux.c diff --git a/libc/Makefile.am b/libc/Makefile.am index acdfa47..dcee272 100644 --- a/libc/Makefile.am +++ b/libc/Makefile.am @@ -11,6 +11,7 @@ endif libc_la_SOURCES = \ src/ctype.c \ src/errno.c \ + src/kernaux.c \ src/stdlib.c \ src/string.c diff --git a/libc/include/Makefile.am b/libc/include/Makefile.am index 3a76e8c..4a748cc 100644 --- a/libc/include/Makefile.am +++ b/libc/include/Makefile.am @@ -1,4 +1,5 @@ nobase_include_HEADERS = \ + kernaux/libc.h \ ctype.h \ errno.h \ inttypes.h \ diff --git a/libc/include/kernaux/libc.h b/libc/include/kernaux/libc.h new file mode 100644 index 0000000..46ceb92 --- /dev/null +++ b/libc/include/kernaux/libc.h @@ -0,0 +1,26 @@ +#ifndef KERNAUX_INCLUDED_LIBC +#define KERNAUX_INCLUDED_LIBC + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +struct KernAux_Libc { + void (*abort)() __attribute__((noreturn)); + void (*exit)(int status) __attribute__((noreturn)); + + void *(*calloc)(size_t nmemb, size_t size); + void (*free)(void *ptr); + void *(*malloc)(size_t size); + void *(*realloc)(void *ptr, size_t size); +}; + +extern struct KernAux_Libc kernaux_libc; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h index 56e41db..18baf84 100644 --- a/libc/include/stdlib.h +++ b/libc/include/stdlib.h @@ -12,10 +12,14 @@ extern "C" { int atoi(const char *str); +__attribute__((noreturn)) void abort(); +__attribute__((noreturn)) void exit(int status); +void *calloc(size_t nmemb, size_t size); void free(void *ptr); +void *malloc(size_t size); void *realloc(void *ptr, size_t size); #ifdef __cplusplus diff --git a/libc/src/kernaux.c b/libc/src/kernaux.c new file mode 100644 index 0000000..688c769 --- /dev/null +++ b/libc/src/kernaux.c @@ -0,0 +1,17 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +struct KernAux_Libc kernaux_libc = { + .abort = NULL, + .exit = NULL, + + .calloc = NULL, + .free = NULL, + .malloc = NULL, + .realloc = NULL, +}; diff --git a/libc/src/stdlib.c b/libc/src/stdlib.c index 1959031..5d6a9ca 100644 --- a/libc/src/stdlib.c +++ b/libc/src/stdlib.c @@ -2,22 +2,60 @@ #include "config.h" #endif +#include + #include #include #include +#include -// TODO: stub -void exit(const int status __attribute__((unused))) +void exit(const int status) { - for (;;); + // Custom implementation + kernaux_libc.exit(status); } -// TODO: stub void abort() { + // Custom implementation + if (kernaux_libc.abort) kernaux_libc.abort(); + + // Default implementation exit(EXIT_FAILURE); } +void *calloc(const size_t nmemb, const size_t size) +{ + // Custom implementation + if (kernaux_libc.calloc) return kernaux_libc.calloc(nmemb, size); + + // Default implementation + const size_t total_size = nmemb * size; + if (!total_size) return NULL; + if (total_size / nmemb != size) return NULL; + void *const ptr = malloc(total_size); + if (ptr) memset(ptr, 0, total_size); + return ptr; +} + +void free(void *const ptr) +{ + // Custom implementation + kernaux_libc.free(ptr); +} + +void *malloc(const size_t size) +{ + // Custom implementation + return kernaux_libc.malloc(size); +} + +void *realloc(void *const ptr, const size_t size) +{ + // Custom implementation + return kernaux_libc.realloc(ptr, size); +} + int atoi(const char *str) { while (isspace(*str)) ++str;