From 689230b674188163fe56b3aecd7d01f79ca518e6 Mon Sep 17 00:00:00 2001 From: Rodrigo Campos Date: Sun, 18 Feb 2024 16:51:03 -0300 Subject: tools/nolibc/string: export strlen() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As with commit 8d304a374023, "tools/nolibc/string: export memset() and memmove()", gcc -Os without -ffreestanding may fail to compile with: cc -fno-asynchronous-unwind-tables -fno-ident -s -Os -nostdlib -lgcc -static -o test test.c /usr/bin/ld: /tmp/cccIasKL.o: in function `main': test.c:(.text.startup+0x1e): undefined reference to `strlen' collect2: error: ld returned 1 exit status As on the aforementioned commit, this patch adds a section to export this function so compilation works on those cases too. Signed-off-by: Rodrigo Campos Signed-off-by: Thomas Weißschuh --- tools/include/nolibc/string.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/include/nolibc/string.h') diff --git a/tools/include/nolibc/string.h b/tools/include/nolibc/string.h index a01c69dd495f..ed15c22b1b2a 100644 --- a/tools/include/nolibc/string.h +++ b/tools/include/nolibc/string.h @@ -123,7 +123,7 @@ char *strcpy(char *dst, const char *src) * thus itself, hence the asm() statement below that's meant to disable this * confusing practice. */ -static __attribute__((unused)) +__attribute__((weak,unused,section(".text.nolibc_strlen"))) size_t strlen(const char *str) { size_t len; -- cgit v1.2.3-59-g8ed1b From 34d232c39a1e05ba734dc6ad9dc01d15788cd91d Mon Sep 17 00:00:00 2001 From: Rodrigo Campos Date: Sun, 18 Feb 2024 16:51:04 -0300 Subject: tools/nolibc: Fix strlcat() return code and size usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The return code should always be strlen(src) + strnlen(dst, size). Let's make sure to copy at most size-1 bytes from src and null-terminate the dst buffer if we did copied something. While we can use strnlen() and strncpy() to implement strlcat(), this is simple enough and results in shorter code when compiled. Signed-off-by: Rodrigo Campos Signed-off-by: Thomas Weißschuh --- tools/include/nolibc/string.h | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'tools/include/nolibc/string.h') diff --git a/tools/include/nolibc/string.h b/tools/include/nolibc/string.h index ed15c22b1b2a..cc51fd6b63d0 100644 --- a/tools/include/nolibc/string.h +++ b/tools/include/nolibc/string.h @@ -187,22 +187,31 @@ char *strndup(const char *str, size_t maxlen) static __attribute__((unused)) size_t strlcat(char *dst, const char *src, size_t size) { - size_t len; - char c; + size_t len = 0; - for (len = 0; dst[len]; len++) - ; + for (; len < size; len++) { + if (dst[len] == '\0') + break; + } - for (;;) { - c = *src; - if (len < size) - dst[len] = c; - if (!c) + /* + * We want len < size-1. But as size is unsigned and can wrap + * around, we use len + 1 instead. + */ + while (len + 1 < size) { + dst[len] = *src; + if (*src == '\0') break; len++; src++; } + if (len < size) + dst[len] = '\0'; + + while (*src++) + len++; + return len; } -- cgit v1.2.3-59-g8ed1b From fbffce819e5ac151e137f881b89a9c1da0ebb76c Mon Sep 17 00:00:00 2001 From: Rodrigo Campos Date: Sun, 18 Feb 2024 16:51:05 -0300 Subject: tools/nolibc: Fix strlcpy() return code and size usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The return code should always be strlen(src), and we should copy at most size-1 bytes. While we are there, make sure to null-terminate the dst buffer if we copied something. Signed-off-by: Rodrigo Campos Signed-off-by: Thomas Weißschuh --- tools/include/nolibc/string.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'tools/include/nolibc/string.h') diff --git a/tools/include/nolibc/string.h b/tools/include/nolibc/string.h index cc51fd6b63d0..565230a4ad47 100644 --- a/tools/include/nolibc/string.h +++ b/tools/include/nolibc/string.h @@ -219,16 +219,18 @@ static __attribute__((unused)) size_t strlcpy(char *dst, const char *src, size_t size) { size_t len; - char c; - for (len = 0;;) { - c = src[len]; - if (len < size) - dst[len] = c; - if (!c) - break; - len++; + for (len = 0; len < size; len++) { + dst[len] = src[len]; + if (!dst[len]) + return len; } + if (size) + dst[size-1] = '\0'; + + while (src[len]) + len++; + return len; } -- cgit v1.2.3-59-g8ed1b From e93b912ecf6ab113c9d4ec9ced2fa30dfac24c70 Mon Sep 17 00:00:00 2001 From: Thomas Weißschuh Date: Wed, 10 Apr 2024 23:27:06 +0200 Subject: tools/nolibc/string: remove open-coded strnlen() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The same header already defines an implementation of strnlen(), so use it. Signed-off-by: Thomas Weißschuh --- tools/include/nolibc/string.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'tools/include/nolibc/string.h') diff --git a/tools/include/nolibc/string.h b/tools/include/nolibc/string.h index 565230a4ad47..f9ab28421e6d 100644 --- a/tools/include/nolibc/string.h +++ b/tools/include/nolibc/string.h @@ -187,12 +187,7 @@ char *strndup(const char *str, size_t maxlen) static __attribute__((unused)) size_t strlcat(char *dst, const char *src, size_t size) { - size_t len = 0; - - for (; len < size; len++) { - if (dst[len] == '\0') - break; - } + size_t len = strnlen(dst, size); /* * We want len < size-1. But as size is unsigned and can wrap -- cgit v1.2.3-59-g8ed1b