diff --git a/include/nuttx/compiler.h b/include/nuttx/compiler.h index 63588bb6e24..99c1efd3b1b 100644 --- a/include/nuttx/compiler.h +++ b/include/nuttx/compiler.h @@ -135,6 +135,13 @@ extern __inline__ no_builtin(#fn) \ __attribute__((__always_inline__, \ __gnu_inline__, __artificial__)) +# elif defined(__OPTIMIZE__) && __OPTIMIZE__ > 0 && defined(__has_builtin) +# define builtin_original(fn) __typeof__(fn) __orig_##fn __asm__(#fn) +# define builtin_function(fn) builtin_original(fn); \ + extern __inline__ no_builtin(#fn) \ + __attribute__((__always_inline__, \ + __gnu_inline__, __artificial__)) +# define CONFIG_HAVE_BUILTIN 1 /* Use built-in functions */ # endif /* Pre-processor */ diff --git a/include/string.h b/include/string.h index dd8a92c4306..1cfc1e04e56 100644 --- a/include/string.h +++ b/include/string.h @@ -219,6 +219,232 @@ fortify_function(explicit_bzero) void explicit_bzero(FAR void *s, } #endif +#ifdef CONFIG_HAVE_BUILTIN +# if __has_builtin(__builtin_memcpy) +builtin_function(memcpy) FAR void *memcpy(FAR void *dest, + FAR const void *src, size_t n) +{ + if (__builtin_constant_p(n)) + { + return __builtin_memcpy(dest, src, n); + } + else + { + return __orig_memcpy(dest, src, n); + } +} +# endif + +# if __has_builtin(__builtin_memset) +builtin_function(memset) FAR void *memset(FAR void *s, int c, size_t n) +{ + if (__builtin_constant_p(n)) + { + return __builtin_memset(s, c, n); + } + else + { + return __orig_memset(s, c, n); + } +} +# endif + +# if __has_builtin(__builtin_memcmp) +builtin_function(memcmp) int memcmp(FAR const void *s1, + FAR const void *s2, size_t n) +{ + if (__builtin_constant_p(s1) && __builtin_constant_p(s2)) + { + return __builtin_memcmp(s1, s2, n); + } + else + { + return __orig_memcmp(s1, s2, n); + } +} +# endif + +# if __has_builtin(__builtin_memchr) +builtin_function(memchr) FAR void *memchr(FAR const void *s, + int c, size_t n) +{ + if (__builtin_constant_p(s)) + { + return __builtin_memchr(s, c, n); + } + else + { + return __orig_memchr(s, c, n); + } +} +# endif + +# if __has_builtin(__builtin_strcat) +builtin_function(strcat) FAR char *strcat(FAR char *dest, + FAR const char *src) +{ + if (__builtin_constant_p(src)) + { + return __builtin_strcat(dest, src); + } + else + { + return __orig_strcat(dest, src); + } +} +# endif + +# if __has_builtin(__builtin_strchr) +builtin_function(strchr) FAR char *strchr(FAR const char *s, int c) +{ + if (__builtin_constant_p(s)) + { + return __builtin_strchr(s, c); + } + else + { + return __orig_strchr(s, c); + } +} +# endif + +# if __has_builtin(__builtin_strcmp) +builtin_function(strcmp) int strcmp(FAR const char *s1, + FAR const char *s2) +{ + if (__builtin_constant_p(s1) && __builtin_constant_p(s2)) + { + return __builtin_strcmp(s1, s2); + } + else + { + return __orig_strcmp(s1, s2); + } +} +# endif + +# if __has_builtin(__builtin_strcpy) +builtin_function(strcpy) FAR char *strcpy(FAR char *dest, + FAR const char *src) +{ + if (__builtin_constant_p(src)) + { + return __builtin_strcpy(dest, src); + } + else + { + return __orig_strcpy(dest, src); + } +} +# endif + +# if __has_builtin(__builtin_strcspn) +builtin_function(strcspn) size_t strcspn(FAR const char *s, + FAR const char *reject) +{ + if (__builtin_constant_p(s) && __builtin_constant_p(reject)) + { + return __builtin_strcspn(s, reject); + } + else + { + return __orig_strcspn(s, reject); + } +} +# endif + +# if __has_builtin(__builtin_strlen) +builtin_function(strlen) size_t strlen(FAR const char *s) +{ + if (__builtin_constant_p(s)) + { + return __builtin_strlen(s); + } + else + { + return __orig_strlen(s); + } +} +# endif + +# if __has_builtin(__builtin_strncat) +builtin_function(strncat) FAR char *strncat(FAR char *dest, + FAR const char *src, + size_t n) +{ + if (__builtin_constant_p(dest)) + { + return __builtin_strncat(dest, src, n); + } + else + { + return __orig_strncat(dest, src, n); + } +} +# endif + +# if __has_builtin(__builtin_strncmp) +builtin_function(strncmp) int strncmp(FAR const char *s1, + FAR const char *s2, size_t n) +{ + if (__builtin_constant_p(s1) && __builtin_constant_p(s2)) + { + return __builtin_strncmp(s1, s2, n); + } + else + { + return __orig_strncmp(s1, s2, n); + } +} +# endif + +# if __has_builtin(__builtin_strncpy) +builtin_function(strncpy) FAR char *strncpy(FAR char *dest, + FAR const char *src, + size_t n) +{ + if (__builtin_constant_p(src)) + { + return __builtin_strncpy(dest, src, n); + } + else + { + return __orig_strncpy(dest, src, n); + } +} +# endif + +# if __has_builtin(__builtin_strpbrk) +builtin_function(strpbrk) FAR char *strpbrk(FAR const char *s1, + FAR const char *s2) +{ + if (__builtin_constant_p(s1)) + { + return __builtin_strpbrk(s1, s2); + } + else + { + return __orig_strpbrk(s1, s2); + } +} +# endif + +# if __has_builtin(__builtin_strrchr) +builtin_function(strrchr) FAR char *strrchr(FAR const char *s, + int c) +{ + if (__builtin_constant_p(s)) + { + return __builtin_strrchr(s, c); + } + else + { + return __orig_strrchr(s, c); + } +} +# endif +#endif + #undef EXTERN #if defined(__cplusplus) } diff --git a/libs/libc/machine/arch_libc.c b/libs/libc/machine/arch_libc.c index 0cce4c4d227..aaad3f83fdb 100644 --- a/libs/libc/machine/arch_libc.c +++ b/libs/libc/machine/arch_libc.c @@ -103,7 +103,8 @@ extern void __asan_storeN(FAR void *addr, size_t size); ****************************************************************************/ #ifdef CONFIG_LIBC_ARCH_MEMCHR - +#undef memchr +no_builtin("memchr") FAR void *memchr(FAR const void *s, int c, size_t n) { # ifdef CONFIG_MM_KASAN_INSTRUMENT @@ -117,6 +118,8 @@ FAR void *memchr(FAR const void *s, int c, size_t n) #endif #ifdef CONFIG_LIBC_ARCH_MEMCPY +#undef memcpy +no_builtin("memcpy") FAR void *memcpy(FAR void *dest, FAR const void *src, FAR size_t n) { # ifdef CONFIG_MM_KASAN_INSTRUMENT @@ -132,6 +135,8 @@ FAR void *memcpy(FAR void *dest, FAR const void *src, FAR size_t n) #endif #ifdef CONFIG_LIBC_ARCH_MEMCMP +#undef memcmp +no_builtin("memcmp") int memcmp(FAR const void *s1, FAR const void *s2, size_t n) { # ifdef CONFIG_MM_KASAN_INSTRUMENT @@ -160,6 +165,8 @@ FAR void *memmove(FAR void *dest, FAR const void *src, FAR size_t n) #endif #ifdef CONFIG_LIBC_ARCH_MEMSET +#undef memset +no_builtin("memset") FAR void *memset(FAR void *s, int c, FAR size_t n) { # ifdef CONFIG_MM_KASAN_INSTRUMENT @@ -172,6 +179,8 @@ FAR void *memset(FAR void *s, int c, FAR size_t n) #endif #ifdef CONFIG_LIBC_ARCH_STRCMP +#undef strcmp +no_builtin("strcmp") int strcmp(FAR const char *s1, FAR const char *s2) { # ifdef CONFIG_MM_KASAN_INSTRUMENT @@ -185,6 +194,8 @@ int strcmp(FAR const char *s1, FAR const char *s2) #endif #ifdef CONFIG_LIBC_ARCH_STRCPY +#undef strcpy +no_builtin("strcpy") FAR char *strcpy(FAR char *dest, FAR const char *src) { # ifdef CONFIG_MM_KASAN_INSTRUMENT @@ -200,6 +211,8 @@ FAR char *strcpy(FAR char *dest, FAR const char *src) #endif #ifdef CONFIG_LIBC_ARCH_STRLEN +#undef strlen +no_builtin("strlen") size_t strlen(FAR const char *s) { size_t ret = ARCH_LIBCFUN(strlen)(s); @@ -213,6 +226,8 @@ size_t strlen(FAR const char *s) #endif #ifdef CONFIG_LIBC_ARCH_STRNCPY +#undef strncpy +no_builtin("strncpy") FAR char *strncpy(FAR char *dest, FAR const char *src, size_t n) { # ifdef CONFIG_MM_KASAN_INSTRUMENT @@ -228,6 +243,8 @@ FAR char *strncpy(FAR char *dest, FAR const char *src, size_t n) #endif #ifdef CONFIG_LIBC_ARCH_STRCHR +#undef strchr +no_builtin("strchr") FAR char *strchr(FAR const char *s, int c) { # ifdef CONFIG_MM_KASAN_INSTRUMENT @@ -253,6 +270,8 @@ FAR char *strchrnul(FAR const char *s, int c) #endif #ifdef CONFIG_LIBC_ARCH_STRNCMP +#undef strncmp +no_builtin("strncmp") int strncmp(FAR const char *s1, FAR const char *s2, size_t n) { # ifdef CONFIG_MM_KASAN_INSTRUMENT @@ -285,6 +304,8 @@ size_t strnlen(FAR const char *s, size_t maxlen) #endif #ifdef CONFIG_LIBC_ARCH_STRRCHR +#undef strrchr +no_builtin("strrchr") FAR char *strrchr(FAR const char *s, int c) { # ifdef CONFIG_MM_KASAN_INSTRUMENT diff --git a/libs/libc/string/lib_bsdmemchr.c b/libs/libc/string/lib_bsdmemchr.c index de33da42d15..fd4f7ad88fa 100644 --- a/libs/libc/string/lib_bsdmemchr.c +++ b/libs/libc/string/lib_bsdmemchr.c @@ -74,6 +74,7 @@ #if !defined(CONFIG_LIBC_ARCH_MEMCHR) && defined(LIBC_BUILD_MEMCHR) #undef memchr +no_builtin("memchr") FAR void *memchr(FAR const void *s, int c, size_t n) { FAR const unsigned char *p = (FAR const unsigned char *)s; diff --git a/libs/libc/string/lib_bsdstpcpy.c b/libs/libc/string/lib_bsdstpcpy.c index 5c6f36767f0..0949c67e84d 100644 --- a/libs/libc/string/lib_bsdstpcpy.c +++ b/libs/libc/string/lib_bsdstpcpy.c @@ -62,6 +62,7 @@ #ifndef CONFIG_LIBC_ARCH_STPCPY #undef stpcpy +no_builtin("stpcpy") nosanitize_address FAR char *stpcpy(FAR char *dest, FAR const char *src) { diff --git a/libs/libc/string/lib_bsdstpncpy.c b/libs/libc/string/lib_bsdstpncpy.c index 79fb41b21b0..bc1708170b1 100644 --- a/libs/libc/string/lib_bsdstpncpy.c +++ b/libs/libc/string/lib_bsdstpncpy.c @@ -78,6 +78,7 @@ #ifndef CONFIG_LIBC_ARCH_STPNCPY #undef stpncpy +no_builtin("stpncpy") FAR char *stpncpy(FAR char *dest, FAR const char *src, size_t n) { FAR char *ret = NULL; diff --git a/libs/libc/string/lib_bsdstrcat.c b/libs/libc/string/lib_bsdstrcat.c index f04d9e4ca0a..86e65001016 100644 --- a/libs/libc/string/lib_bsdstrcat.c +++ b/libs/libc/string/lib_bsdstrcat.c @@ -49,6 +49,7 @@ #if !defined(CONFIG_LIBC_ARCH_STRCAT) && defined(LIBC_BUILD_STRCAT) #undef strcat +no_builtin("strcat") nosanitize_address FAR char *strcat(FAR char *dest, FAR const char *src) { diff --git a/libs/libc/string/lib_bsdstrchr.c b/libs/libc/string/lib_bsdstrchr.c index a910e881e2e..4446c173285 100644 --- a/libs/libc/string/lib_bsdstrchr.c +++ b/libs/libc/string/lib_bsdstrchr.c @@ -68,6 +68,7 @@ #if !defined(CONFIG_LIBC_ARCH_STRCHR) && defined(LIBC_BUILD_STRCHR) #undef strchr +no_builtin("strchr") nosanitize_address FAR char *strchr(FAR const char *s, int c) { diff --git a/libs/libc/string/lib_bsdstrcmp.c b/libs/libc/string/lib_bsdstrcmp.c index 9366d0d0a9f..b8ba758a3cb 100644 --- a/libs/libc/string/lib_bsdstrcmp.c +++ b/libs/libc/string/lib_bsdstrcmp.c @@ -51,6 +51,7 @@ #if !defined(CONFIG_LIBC_ARCH_STRCMP) && defined(LIBC_BUILD_STRCMP) #undef strcmp +no_builtin("strcmp") nosanitize_address int strcmp(FAR const char *cs, FAR const char *ct) { diff --git a/libs/libc/string/lib_bsdstrcpy.c b/libs/libc/string/lib_bsdstrcpy.c index 95e221de6c5..bf352ade5af 100644 --- a/libs/libc/string/lib_bsdstrcpy.c +++ b/libs/libc/string/lib_bsdstrcpy.c @@ -64,6 +64,7 @@ #if !defined(CONFIG_LIBC_ARCH_STRCPY) && defined(LIBC_BUILD_STRCPY) #undef strcpy nosanitize_address +no_builtin("strcpy") FAR char *strcpy(FAR char *dest, FAR const char *src) { FAR char *dst0 = dest; diff --git a/libs/libc/string/lib_bsdstrlen.c b/libs/libc/string/lib_bsdstrlen.c index efd117ae0ed..992f40f01b9 100644 --- a/libs/libc/string/lib_bsdstrlen.c +++ b/libs/libc/string/lib_bsdstrlen.c @@ -49,6 +49,7 @@ #if !defined(CONFIG_LIBC_ARCH_STRLEN) && defined(LIBC_BUILD_STRLEN) #undef strlen +no_builtin("strlen") nosanitize_address size_t strlen(FAR const char *s) { diff --git a/libs/libc/string/lib_bsdstrncmp.c b/libs/libc/string/lib_bsdstrncmp.c index 4f7d12823e2..a1f7441eebb 100644 --- a/libs/libc/string/lib_bsdstrncmp.c +++ b/libs/libc/string/lib_bsdstrncmp.c @@ -53,6 +53,7 @@ #if !defined(CONFIG_LIBC_ARCH_STRNCMP) && defined(LIBC_BUILD_STRNCMP) #undef strncmp +no_builtin("strncmp") nosanitize_address int strncmp(FAR const char *cs, FAR const char *ct, size_t nb) { diff --git a/libs/libc/string/lib_bsdstrncpy.c b/libs/libc/string/lib_bsdstrncpy.c index 0012804fbaa..a35c7dd40f5 100644 --- a/libs/libc/string/lib_bsdstrncpy.c +++ b/libs/libc/string/lib_bsdstrncpy.c @@ -77,6 +77,7 @@ #if !defined(CONFIG_LIBC_ARCH_STRNCPY) && defined(LIBC_BUILD_STRNCPY) #undef strncpy nosanitize_address +no_builtin("strncpy") FAR char *strncpy(FAR char *dest, FAR const char *src, size_t n) { FAR char *dst0 = dest; diff --git a/libs/libc/string/lib_bsdstrrchr.c b/libs/libc/string/lib_bsdstrrchr.c index 22dbcb6b698..50ab3d58779 100644 --- a/libs/libc/string/lib_bsdstrrchr.c +++ b/libs/libc/string/lib_bsdstrrchr.c @@ -36,6 +36,7 @@ #if !defined(CONFIG_LIBC_ARCH_STRRCHR) && defined(LIBC_BUILD_STRRCHR) #undef strrchr +no_builtin("strrchr") FAR char *strrchr(FAR const char *s, int c) { FAR const char *last = NULL; diff --git a/libs/libc/string/lib_memchr.c b/libs/libc/string/lib_memchr.c index dcacfde4b69..08555b79a5d 100644 --- a/libs/libc/string/lib_memchr.c +++ b/libs/libc/string/lib_memchr.c @@ -50,6 +50,7 @@ #if !defined(CONFIG_LIBC_ARCH_MEMCHR) && defined(LIBC_BUILD_MEMCHR) #undef memchr +no_builtin("memchr") FAR void *memchr(FAR const void *s, int c, size_t n) { FAR const unsigned char *p = (FAR const unsigned char *)s; diff --git a/libs/libc/string/lib_strcat.c b/libs/libc/string/lib_strcat.c index a7692eae14a..882c9ccae42 100644 --- a/libs/libc/string/lib_strcat.c +++ b/libs/libc/string/lib_strcat.c @@ -36,6 +36,7 @@ #if !defined(CONFIG_LIBC_ARCH_STRCAT) && defined(LIBC_BUILD_STRCAT) #undef strcat +no_builtin("strcat") FAR char *strcat(FAR char *dest, FAR const char *src) { FAR char *ret = dest; diff --git a/libs/libc/string/lib_strchr.c b/libs/libc/string/lib_strchr.c index c60ba071def..9002dbae8f5 100644 --- a/libs/libc/string/lib_strchr.c +++ b/libs/libc/string/lib_strchr.c @@ -50,6 +50,7 @@ #if !defined(CONFIG_LIBC_ARCH_STRCHR) && defined(LIBC_BUILD_STRCHR) #undef strchr +no_builtin("strchr") FAR char *strchr(FAR const char *s, int c) { for (; ; s++) diff --git a/libs/libc/string/lib_strcpy.c b/libs/libc/string/lib_strcpy.c index d4244fe33b7..011ed3efbb7 100644 --- a/libs/libc/string/lib_strcpy.c +++ b/libs/libc/string/lib_strcpy.c @@ -48,6 +48,7 @@ #if !defined(CONFIG_LIBC_ARCH_STRCPY) && defined(LIBC_BUILD_STRCPY) #undef strcpy +no_builtin("strcpy") FAR char *strcpy(FAR char *dest, FAR const char *src) { FAR char *tmp = dest; diff --git a/libs/libc/string/lib_strcspn.c b/libs/libc/string/lib_strcspn.c index 163d3ab9b08..82bd46ef06d 100644 --- a/libs/libc/string/lib_strcspn.c +++ b/libs/libc/string/lib_strcspn.c @@ -42,6 +42,7 @@ ****************************************************************************/ #undef strcspn +no_builtin("strcspn") size_t strcspn(const char *s, const char *reject) { size_t i; diff --git a/libs/libc/string/lib_strlen.c b/libs/libc/string/lib_strlen.c index 919940b15a5..b77d2300ddb 100644 --- a/libs/libc/string/lib_strlen.c +++ b/libs/libc/string/lib_strlen.c @@ -36,6 +36,7 @@ #if !defined(CONFIG_LIBC_ARCH_STRLEN) && defined(LIBC_BUILD_STRLEN) #undef strlen +no_builtin("strlen") size_t strlen(FAR const char *s) { FAR const char *sc; diff --git a/libs/libc/string/lib_strncmp.c b/libs/libc/string/lib_strncmp.c index 02ffef9b467..00ab1e753fe 100644 --- a/libs/libc/string/lib_strncmp.c +++ b/libs/libc/string/lib_strncmp.c @@ -36,6 +36,7 @@ #if !defined(CONFIG_LIBC_ARCH_STRNCMP) && defined(LIBC_BUILD_STRNCMP) #undef strncmp +no_builtin("strncmp") int strncmp(FAR const char *cs, FAR const char *ct, size_t nb) { register int result = 0; diff --git a/libs/libc/string/lib_strrchr.c b/libs/libc/string/lib_strrchr.c index db683445652..873e9b66ac8 100644 --- a/libs/libc/string/lib_strrchr.c +++ b/libs/libc/string/lib_strrchr.c @@ -40,6 +40,7 @@ #if !defined(CONFIG_LIBC_ARCH_STRRCHR) && defined(LIBC_BUILD_STRRCHR) #undef strrchr +no_builtin("strrchr") FAR char *strrchr(FAR const char *s, int c) { FAR const char *r = NULL; diff --git a/libs/libc/string/lib_strstr.c b/libs/libc/string/lib_strstr.c index bcd5d265a4d..67cbbd2ad6d 100644 --- a/libs/libc/string/lib_strstr.c +++ b/libs/libc/string/lib_strstr.c @@ -53,6 +53,7 @@ */ #undef strstr +no_builtin("strstr") FAR char *strstr(FAR const char *haystack, FAR const char *needle) { #ifdef CONFIG_ALLOW_MIT_COMPONENTS