From 934a2e9aea08e8799fcc85d3581e8a91ab97e374 Mon Sep 17 00:00:00 2001 From: Maxim Prokhorov Date: Sun, 31 Mar 2024 21:52:44 +0300 Subject: [PATCH 1/2] Mock - optionally hide locally implemented funcs glibc 2.38 includes strlcpy and strlcat, attempt to detect them before use --- cores/esp8266/core_esp8266_noniso.cpp | 15 +--- cores/esp8266/stdlib_noniso.cpp | 16 +++- cores/esp8266/stdlib_noniso.h | 35 ++++---- tests/host/Makefile | 26 ++++++ tests/host/common/mock.h | 15 ++-- tests/host/common/noniso.c | 22 +---- tests/host/common/strl.cpp | 116 ++++++++++++-------------- tools/sdk/include/ets_sys.h | 1 - 8 files changed, 128 insertions(+), 118 deletions(-) diff --git a/cores/esp8266/core_esp8266_noniso.cpp b/cores/esp8266/core_esp8266_noniso.cpp index f15fdc0860..fb5d8f573a 100644 --- a/cores/esp8266/core_esp8266_noniso.cpp +++ b/cores/esp8266/core_esp8266_noniso.cpp @@ -28,19 +28,12 @@ #include #include #include + #include "stdlib_noniso.h" extern "C" { -char* ltoa(long value, char* result, int base) { - return itoa((int)value, result, base); -} - -char* ultoa(unsigned long value, char* result, int base) { - return utoa((unsigned int)value, result, base); -} - -char * dtostrf(double number, signed char width, unsigned char prec, char *s) { +char* dtostrf(double number, signed char width, unsigned char prec, char *s) noexcept { bool negative = false; if (isnan(number)) { @@ -125,7 +118,7 @@ char * dtostrf(double number, signed char width, unsigned char prec, char *s) { */ const char* strrstr(const char*__restrict p_pcString, - const char*__restrict p_pcPattern) + const char*__restrict p_pcPattern) noexcept { const char* pcResult = 0; @@ -149,4 +142,4 @@ const char* strrstr(const char*__restrict p_pcString, return pcResult; } -}; +} // extern "C" diff --git a/cores/esp8266/stdlib_noniso.cpp b/cores/esp8266/stdlib_noniso.cpp index 693dfda850..4fed9b615d 100644 --- a/cores/esp8266/stdlib_noniso.cpp +++ b/cores/esp8266/stdlib_noniso.cpp @@ -21,11 +21,13 @@ #include "stdlib_noniso.h" +extern "C" { + // ulltoa() is slower than std::to_char() (1.6 times) // but is smaller by ~800B/flash and ~250B/rodata // ulltoa fills str backwards and can return a pointer different from str -char* ulltoa(unsigned long long val, char* str, int slen, unsigned int radix) +char* ulltoa(unsigned long long val, char* str, int slen, unsigned int radix) noexcept { str += --slen; *str = 0; @@ -39,7 +41,7 @@ char* ulltoa(unsigned long long val, char* str, int slen, unsigned int radix) } // lltoa fills str backwards and can return a pointer different from str -char* lltoa (long long val, char* str, int slen, unsigned int radix) +char* lltoa(long long val, char* str, int slen, unsigned int radix) noexcept { bool neg; if (val < 0) @@ -60,3 +62,13 @@ char* lltoa (long long val, char* str, int slen, unsigned int radix) } return ret; } + +char* ltoa(long value, char* result, int base) noexcept { + return itoa((int)value, result, base); +} + +char* ultoa(unsigned long value, char* result, int base) noexcept { + return utoa((unsigned int)value, result, base); +} + +} // extern "C" diff --git a/cores/esp8266/stdlib_noniso.h b/cores/esp8266/stdlib_noniso.h index f86f78befc..0c8c488ed1 100644 --- a/cores/esp8266/stdlib_noniso.h +++ b/cores/esp8266/stdlib_noniso.h @@ -22,38 +22,35 @@ #ifndef STDLIB_NONISO_H #define STDLIB_NONISO_H +#include + #ifdef __cplusplus -extern "C"{ +extern "C" { #endif -int atoi(const char *s); - -long atol(const char* s); - -double atof(const char* s); - -char* itoa (int val, char *s, int radix); - -char* ltoa (long val, char *s, int radix); +#ifdef __cplusplus +#define __STDLIB_NONISO_NOEXCEPT noexcept +#else +#define __STDLIB_NONISO_NOEXCEPT +#endif -char* lltoa (long long val, char* str, int slen, unsigned int radix); +char* ltoa (long val, char *s, int radix) __STDLIB_NONISO_NOEXCEPT; -char* utoa (unsigned int val, char *s, int radix); +char* lltoa (long long val, char* str, int slen, unsigned int radix) __STDLIB_NONISO_NOEXCEPT; -char* ultoa (unsigned long val, char *s, int radix); +char* ultoa (unsigned long val, char *s, int radix) __STDLIB_NONISO_NOEXCEPT; -char* ulltoa (unsigned long long val, char* str, int slen, unsigned int radix); +char* ulltoa (unsigned long long val, char* str, int slen, unsigned int radix) __STDLIB_NONISO_NOEXCEPT; -char* dtostrf (double val, signed char width, unsigned char prec, char *s); +char* dtostrf (double val, signed char width, unsigned char prec, char *s) __STDLIB_NONISO_NOEXCEPT; -void reverse(char* begin, char* end); +const char* strrstr (const char*__restrict p_pcString, + const char*__restrict p_pcPattern) __STDLIB_NONISO_NOEXCEPT; -const char* strrstr(const char*__restrict p_pcString, - const char*__restrict p_pcPattern); +#undef __STDLIB_NONISO_NOEXCEPT #ifdef __cplusplus } // extern "C" #endif - #endif diff --git a/tests/host/Makefile b/tests/host/Makefile index f819047891..aac9f14bce 100644 --- a/tests/host/Makefile +++ b/tests/host/Makefile @@ -30,6 +30,7 @@ GENHTML ?= genhtml CXXFLAGS += -std=gnu++17 CFLAGS += -std=gnu17 +# 32-bit mode is prefered, but not required ifeq ($(FORCE32),1) SIZEOFLONG = $(shell echo 'int main(){return sizeof(long);}'|$(CXX) -m32 -x c++ - -o sizeoflong 2>/dev/null && ./sizeoflong; echo $$?; rm -f sizeoflong;) ifneq ($(SIZEOFLONG),4) @@ -50,6 +51,7 @@ endif OUTPUT_BINARY := $(BINDIR)/host_tests LCOV_DIRECTORY := $(BINDIR)/../lcov +# Hide full build commands by default ifeq ($(V), 0) VERBC = @echo "C $@"; VERBCXX = @echo "C++ $@"; @@ -66,6 +68,30 @@ endif $(shell mkdir -p $(BINDIR)) +# Core files sometimes override libc functions, check when necessary to hide them +# TODO proper configure script / other build system? +ifeq (,$(wildcard $(BINDIR)/.have_strlcpy)) +$(shell echo -e '#include \nint main(){char a[4]{}; char b[4]{}; strlcpy(&a[0], &b[0], sizeof(a)); return 0;}' | \ + $(CXX) -x c++ - -o $(BINDIR)/.have_strlcpy 2>/dev/null || ( echo -e '#!/bin/sh\nexit 1' > $(BINDIR)/.have_strlcpy ; chmod +x $(BINDIR)/.have_strlcpy; )) +endif + +$(shell $(BINDIR)/.have_strlcpy) +ifeq ($(.SHELLSTATUS), 0) +FLAGS += -DHAVE_STRLCPY +endif + +ifeq (,$(wildcard $(BINDIR)/.have_strlcat)) +$(shell echo -e '#include \nint main(){char a[4]{}; strlcat(&a[0], "test", sizeof(a)); return 0;}' | \ + $(CXX) -x c++ - -o $(BINDIR)/.have_strlcat 2>/dev/null || ( echo -e '#!/bin/sh\nexit 1' > $(BINDIR)/.have_strlcat ; chmod +x $(BINDIR)/.have_strlcat; )) +endif + +$(shell $(BINDIR)/.have_strlcat) +ifeq ($(.SHELLSTATUS), 0) +FLAGS += -DHAVE_STRLCAT +endif + +# Actual build recipes + CORE_CPP_FILES := \ $(addprefix $(abspath $(CORE_PATH))/,\ debug.cpp \ diff --git a/tests/host/common/mock.h b/tests/host/common/mock.h index b3308282f0..ece973edfc 100644 --- a/tests/host/common/mock.h +++ b/tests/host/common/mock.h @@ -56,18 +56,23 @@ #define D8 8 #include +#include +#include + +#include #ifdef __cplusplus extern "C" { #endif - // TODO: #include ? - char* itoa(int val, char* s, int radix); - char* ltoa(long val, char* s, int radix); - + char* utoa(unsigned value, char* result, int base); + char* itoa(int value, char* result, int base); +#ifndef HAVE_STRLCAT size_t strlcat(char* dst, const char* src, size_t size); +#endif +#ifndef HAVE_STRLCPY size_t strlcpy(char* dst, const char* src, size_t size); - +#endif #ifdef __cplusplus } #endif diff --git a/tests/host/common/noniso.c b/tests/host/common/noniso.c index 5c4e14b306..20fd3d1d5a 100644 --- a/tests/host/common/noniso.c +++ b/tests/host/common/noniso.c @@ -18,9 +18,10 @@ #include #include #include -#include "stdlib_noniso.h" -void reverse(char* begin, char* end) +#include + +static void reverse(char* begin, char* end) { char* is = begin; char* ie = end - 1; @@ -84,20 +85,3 @@ char* itoa(int value, char* result, int base) utoa(uvalue, result, base); return out; } - -int atoi(const char* s) -{ - return (int)atol(s); -} - -long atol(const char* s) -{ - char* tmp; - return strtol(s, &tmp, 10); -} - -double atof(const char* s) -{ - char* tmp; - return strtod(s, &tmp); -} diff --git a/tests/host/common/strl.cpp b/tests/host/common/strl.cpp index 0b0725b046..78a6e0efa6 100644 --- a/tests/host/common/strl.cpp +++ b/tests/host/common/strl.cpp @@ -1,84 +1,78 @@ // https://gist.github.com/Fonger/98cc95ac39fbe1a7e4d9 -#ifndef HAVE_STRLCAT -/* - '_cups_strlcat()' - Safely concatenate two strings. -*/ - -size_t /* O - Length of string */ -strlcat(char* dst, /* O - Destination string */ - const char* src, /* I - Source string */ - size_t size) /* I - Size of destination string buffer */ +#include +#include +#include + +extern "C" { - size_t srclen; /* Length of source string */ - size_t dstlen; /* Length of destination string */ +#ifndef HAVE_STRLCAT + // '_cups_strlcat()' - Safely concatenate two strings. - /* - Figure out how much room is left... - */ + size_t /* O - Length of string */ + strlcat(char* dst, /* O - Destination string */ + const char* src, /* I - Source string */ + size_t size) /* I - Size of destination string buffer */ + { + size_t srclen; /* Length of source string */ + size_t dstlen; /* Length of destination string */ - dstlen = strlen(dst); - size -= dstlen + 1; + // Figure out how much room is left... - if (!size) - { - return (dstlen); /* No room, return immediately... */ - } + dstlen = strlen(dst); + size -= dstlen + 1; - /* - Figure out how much room is needed... - */ + if (!size) + { + return (dstlen); /* No room, return immediately... */ + } - srclen = strlen(src); + // Figure out how much room is needed... - /* - Copy the appropriate amount... - */ + srclen = strlen(src); - if (srclen > size) - { - srclen = size; - } + // Copy the appropriate amount... + + if (srclen > size) + { + srclen = size; + } - memcpy(dst + dstlen, src, srclen); - dst[dstlen + srclen] = '\0'; + memcpy(dst + dstlen, src, srclen); + dst[dstlen + srclen] = '\0'; - return (dstlen + srclen); -} + return (dstlen + srclen); + } #endif /* !HAVE_STRLCAT */ #ifndef HAVE_STRLCPY -/* - '_cups_strlcpy()' - Safely copy two strings. -*/ - -size_t /* O - Length of string */ -strlcpy(char* dst, /* O - Destination string */ - const char* src, /* I - Source string */ - size_t size) /* I - Size of destination string buffer */ -{ - size_t srclen; /* Length of source string */ + // '_cups_strlcpy()' - Safely copy two strings. - /* - Figure out how much room is needed... - */ + size_t /* O - Length of string */ + strlcpy(char* dst, /* O - Destination string */ + const char* src, /* I - Source string */ + size_t size) /* I - Size of destination string buffer */ + { + size_t srclen; /* Length of source string */ - size--; + // Figure out how much room is needed... - srclen = strlen(src); + size--; - /* - Copy the appropriate amount... - */ + srclen = strlen(src); - if (srclen > size) - { - srclen = size; - } + // Copy the appropriate amount... + + if (srclen > size) + { + srclen = size; + } - memcpy(dst, src, srclen); - dst[srclen] = '\0'; + memcpy(dst, src, srclen); + dst[srclen] = '\0'; - return (srclen); -} + return (srclen); + } #endif /* !HAVE_STRLCPY */ + +} // extern "C" diff --git a/tools/sdk/include/ets_sys.h b/tools/sdk/include/ets_sys.h index 7908f127c3..a199469e0d 100644 --- a/tools/sdk/include/ets_sys.h +++ b/tools/sdk/include/ets_sys.h @@ -208,7 +208,6 @@ void *ets_memset(void *s, int c, size_t n); void ets_timer_arm_new(ETSTimer *a, int b, int c, int isMstimer); void ets_timer_setfn(ETSTimer *t, ETSTimerFunc *fn, void *parg); void ets_timer_disarm(ETSTimer *a); -int atoi(const char *nptr); int ets_strncmp(const char *s1, const char *s2, int len); int ets_strcmp(const char *s1, const char *s2); int ets_strlen(const char *s); From ccbcf17918a11cd8c6e6366e64b36c7a5d5dc5fc Mon Sep 17 00:00:00 2001 From: Maxim Prokhorov Date: Wed, 31 Jul 2024 02:10:06 +0300 Subject: [PATCH 2/2] inverse dep, default to no strl funcs override --- tests/host/Makefile | 8 ++++---- tests/host/common/mock.h | 4 ++-- tests/host/common/strl.cpp | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/host/Makefile b/tests/host/Makefile index aac9f14bce..7308b10e60 100644 --- a/tests/host/Makefile +++ b/tests/host/Makefile @@ -76,8 +76,8 @@ $(shell echo -e '#include \nint main(){char a[4]{}; char b[4]{}; strlcp endif $(shell $(BINDIR)/.have_strlcpy) -ifeq ($(.SHELLSTATUS), 0) -FLAGS += -DHAVE_STRLCPY +ifneq ($(.SHELLSTATUS), 0) +FLAGS += -DSTRLCPY_MISSING endif ifeq (,$(wildcard $(BINDIR)/.have_strlcat)) @@ -86,8 +86,8 @@ $(shell echo -e '#include \nint main(){char a[4]{}; strlcat(&a[0], "tes endif $(shell $(BINDIR)/.have_strlcat) -ifeq ($(.SHELLSTATUS), 0) -FLAGS += -DHAVE_STRLCAT +ifneq ($(.SHELLSTATUS), 0) +FLAGS += -DSTRLCAT_MISSING endif # Actual build recipes diff --git a/tests/host/common/mock.h b/tests/host/common/mock.h index ece973edfc..344ce6b10c 100644 --- a/tests/host/common/mock.h +++ b/tests/host/common/mock.h @@ -67,10 +67,10 @@ extern "C" #endif char* utoa(unsigned value, char* result, int base); char* itoa(int value, char* result, int base); -#ifndef HAVE_STRLCAT +#ifdef STRLCAT_MISSING size_t strlcat(char* dst, const char* src, size_t size); #endif -#ifndef HAVE_STRLCPY +#ifdef STRLCPY_MISSING size_t strlcpy(char* dst, const char* src, size_t size); #endif #ifdef __cplusplus diff --git a/tests/host/common/strl.cpp b/tests/host/common/strl.cpp index 78a6e0efa6..b01f6652a8 100644 --- a/tests/host/common/strl.cpp +++ b/tests/host/common/strl.cpp @@ -6,7 +6,7 @@ extern "C" { -#ifndef HAVE_STRLCAT +#ifdef STRLCAT_MISSING // '_cups_strlcat()' - Safely concatenate two strings. size_t /* O - Length of string */ @@ -43,9 +43,9 @@ extern "C" return (dstlen + srclen); } -#endif /* !HAVE_STRLCAT */ +#endif /* STRLCAT_MISSING */ -#ifndef HAVE_STRLCPY +#ifdef STRLCPY_MISSING // '_cups_strlcpy()' - Safely copy two strings. size_t /* O - Length of string */ @@ -73,6 +73,6 @@ extern "C" return (srclen); } -#endif /* !HAVE_STRLCPY */ +#endif /* STRLCPY_MISSING */ } // extern "C"