From 3a5157e3ba4f2581302ce74649f3bfd9d19b2791 Mon Sep 17 00:00:00 2001 From: Max Prokhorov Date: Wed, 31 Jul 2024 02:24:41 +0300 Subject: [PATCH] Mock - update func signatures for latest glibc (#9117) 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 | 138 ++++++++++++-------------- tools/sdk/include/ets_sys.h | 1 - 8 files changed, 139 insertions(+), 129 deletions(-) diff --git a/cores/esp8266/core_esp8266_noniso.cpp b/cores/esp8266/core_esp8266_noniso.cpp index f15fdc086..fb5d8f573 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 693dfda85..4fed9b615 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 f86f78bef..0c8c488ed 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); +#ifdef __cplusplus +#define __STDLIB_NONISO_NOEXCEPT noexcept +#else +#define __STDLIB_NONISO_NOEXCEPT +#endif -long atol(const char* s); +char* ltoa (long val, char *s, int radix) __STDLIB_NONISO_NOEXCEPT; -double atof(const char* s); +char* lltoa (long long val, char* str, int slen, unsigned int radix) __STDLIB_NONISO_NOEXCEPT; -char* itoa (int val, char *s, int radix); +char* ultoa (unsigned long val, char *s, int radix) __STDLIB_NONISO_NOEXCEPT; -char* ltoa (long val, char *s, int radix); +char* ulltoa (unsigned long long val, char* str, int slen, unsigned int radix) __STDLIB_NONISO_NOEXCEPT; -char* lltoa (long long val, char* str, int slen, unsigned int radix); +char* dtostrf (double val, signed char width, unsigned char prec, char *s) __STDLIB_NONISO_NOEXCEPT; -char* utoa (unsigned int val, char *s, int radix); +const char* strrstr (const char*__restrict p_pcString, + const char*__restrict p_pcPattern) __STDLIB_NONISO_NOEXCEPT; -char* ultoa (unsigned long val, char *s, int radix); - -char* ulltoa (unsigned long long val, char* str, int slen, unsigned int radix); - -char* dtostrf (double val, signed char width, unsigned char prec, char *s); - -void reverse(char* begin, char* end); - -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 f81904789..7308b10e6 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) +ifneq ($(.SHELLSTATUS), 0) +FLAGS += -DSTRLCPY_MISSING +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) +ifneq ($(.SHELLSTATUS), 0) +FLAGS += -DSTRLCAT_MISSING +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 b3308282f..344ce6b10 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); +#ifdef STRLCAT_MISSING size_t strlcat(char* dst, const char* src, size_t size); +#endif +#ifdef STRLCPY_MISSING 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 5c4e14b30..20fd3d1d5 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 0b0725b04..b01f6652a 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. -*/ +#include +#include +#include -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 */ +extern "C" { - size_t srclen; /* Length of source string */ - size_t dstlen; /* Length of destination string */ +#ifdef STRLCAT_MISSING + // '_cups_strlcat()' - Safely concatenate two strings. - /* - Figure out how much room is left... - */ - - dstlen = strlen(dst); - size -= dstlen + 1; - - if (!size) + 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 */ { - return (dstlen); /* No room, return immediately... */ + size_t srclen; /* Length of source string */ + size_t dstlen; /* Length of destination string */ + + // Figure out how much room is left... + + dstlen = strlen(dst); + size -= dstlen + 1; + + if (!size) + { + return (dstlen); /* No room, return immediately... */ + } + + // Figure out how much room is needed... + + srclen = strlen(src); + + // Copy the appropriate amount... + + if (srclen > size) + { + srclen = size; + } + + memcpy(dst + dstlen, src, srclen); + dst[dstlen + srclen] = '\0'; + + return (dstlen + srclen); } +#endif /* STRLCAT_MISSING */ - /* - Figure out how much room is needed... - */ +#ifdef STRLCPY_MISSING + // '_cups_strlcpy()' - Safely copy two strings. - srclen = strlen(src); - - /* - Copy the appropriate amount... - */ - - if (srclen > size) + 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 */ { - srclen = size; + size_t srclen; /* Length of source string */ + + // Figure out how much room is needed... + + size--; + + srclen = strlen(src); + + // Copy the appropriate amount... + + if (srclen > size) + { + srclen = size; + } + + memcpy(dst, src, srclen); + dst[srclen] = '\0'; + + return (srclen); } +#endif /* STRLCPY_MISSING */ - memcpy(dst + dstlen, src, srclen); - dst[dstlen + srclen] = '\0'; - - 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 */ - - /* - Figure out how much room is needed... - */ - - size--; - - srclen = strlen(src); - - /* - Copy the appropriate amount... - */ - - if (srclen > size) - { - srclen = size; - } - - memcpy(dst, src, srclen); - dst[srclen] = '\0'; - - return (srclen); -} -#endif /* !HAVE_STRLCPY */ +} // extern "C" diff --git a/tools/sdk/include/ets_sys.h b/tools/sdk/include/ets_sys.h index 7908f127c..a199469e0 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);