From b3e9214e96eb2a5a5eb94127037eecfee81d3509 Mon Sep 17 00:00:00 2001 From: Antonio Nino Diaz Date: Thu, 27 Sep 2018 09:18:57 +0100 Subject: [PATCH 1/4] libc: Import strlcpy from FreeBSD From commit aafd1cf4235d78ce85b76d7da63e9589039344b3: - lib/libc/strlcpy.c Change-Id: Iaa7028fcc26706bdd6ee3f1e4bd55dd5873a30c6 Signed-off-by: Antonio Nino Diaz --- lib/libc/strlcpy.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 lib/libc/strlcpy.c diff --git a/lib/libc/strlcpy.c b/lib/libc/strlcpy.c new file mode 100644 index 000000000..019d2316a --- /dev/null +++ b/lib/libc/strlcpy.c @@ -0,0 +1,53 @@ +/* $OpenBSD: strlcpy.c,v 1.12 2015/01/15 03:54:12 millert Exp $ */ + +/* + * Copyright (c) 1998, 2015 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +/* + * Copy string src to buffer dst of size dsize. At most dsize-1 + * chars will be copied. Always NUL terminates (unless dsize == 0). + * Returns strlen(src); if retval >= dsize, truncation occurred. + */ +size_t +strlcpy(char * __restrict dst, const char * __restrict src, size_t dsize) +{ + const char *osrc = src; + size_t nleft = dsize; + + /* Copy as many bytes as will fit. */ + if (nleft != 0) { + while (--nleft != 0) { + if ((*dst++ = *src++) == '\0') + break; + } + } + + /* Not enough room in dst, add NUL and traverse rest of src. */ + if (nleft == 0) { + if (dsize != 0) + *dst = '\0'; /* NUL-terminate dst */ + while (*src++) + ; + } + + return(src - osrc - 1); /* count does not include NUL */ +} From b4cf974a3256275fe2c03d8eaaf07a5e5b337cfc Mon Sep 17 00:00:00 2001 From: Antonio Nino Diaz Date: Thu, 27 Sep 2018 09:22:19 +0100 Subject: [PATCH 2/4] libc: Adapt strlcpy to this codebase Change-Id: I2f5f64aaf90caae936510e1179392a8835f493e0 Signed-off-by: Antonio Nino Diaz --- include/lib/libc/string.h | 1 + lib/libc/libc.mk | 1 + lib/libc/strlcpy.c | 9 ++++----- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/lib/libc/string.h b/include/lib/libc/string.h index 3c8e3b65e..ee6eeacef 100644 --- a/include/lib/libc/string.h +++ b/include/lib/libc/string.h @@ -28,5 +28,6 @@ void *memset(void *dst, int val, size_t count); size_t strlen(const char *s); size_t strnlen(const char *s, size_t maxlen); char *strrchr(const char *p, int ch); +size_t strlcpy(char * dst, const char * src, size_t dsize); #endif /* STRING_H */ diff --git a/lib/libc/libc.mk b/lib/libc/libc.mk index daa2ec102..1276f5c82 100644 --- a/lib/libc/libc.mk +++ b/lib/libc/libc.mk @@ -19,6 +19,7 @@ LIBC_SRCS := $(addprefix lib/libc/, \ snprintf.c \ strchr.c \ strcmp.c \ + strlcpy.c \ strlen.c \ strncmp.c \ strnlen.c \ diff --git a/lib/libc/strlcpy.c b/lib/libc/strlcpy.c index 019d2316a..c4f39bb9b 100644 --- a/lib/libc/strlcpy.c +++ b/lib/libc/strlcpy.c @@ -1,6 +1,8 @@ /* $OpenBSD: strlcpy.c,v 1.12 2015/01/15 03:54:12 millert Exp $ */ /* + * SPDX-License-Identifier: ISC + * * Copyright (c) 1998, 2015 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any @@ -16,10 +18,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -__FBSDID("$FreeBSD$"); - -#include +#include #include /* @@ -28,7 +27,7 @@ __FBSDID("$FreeBSD$"); * Returns strlen(src); if retval >= dsize, truncation occurred. */ size_t -strlcpy(char * __restrict dst, const char * __restrict src, size_t dsize) +strlcpy(char * dst, const char * src, size_t dsize) { const char *osrc = src; size_t nleft = dsize; From 2747362062d4286e47cb13dbdfddfebc6d355dca Mon Sep 17 00:00:00 2001 From: Antonio Nino Diaz Date: Tue, 26 Jun 2018 10:34:07 +0100 Subject: [PATCH 3/4] Introduce new fdt helper to read string properties Introduced fdtw_read_string() to read string properties. Change-Id: I854eef0390632cf2eaddd2dce60cdb98c117de43 Signed-off-by: Antonio Nino Diaz --- common/fdt_wrappers.c | 33 +++++++++++++++++++++++++++++++++ include/common/fdt_wrappers.h | 3 +++ 2 files changed, 36 insertions(+) diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c index 1a726a8aa..1715a6f0e 100644 --- a/common/fdt_wrappers.c +++ b/common/fdt_wrappers.c @@ -10,6 +10,7 @@ #include #include #include +#include /* * Read cells from a given property of the given node. At most 2 cells of the @@ -61,6 +62,38 @@ int fdtw_read_cells(const void *dtb, int node, const char *prop, return 0; } +/* + * Read string from a given property of the given node. Up to 'size - 1' + * characters are read, and a NUL terminator is added. Returns 0 on success, + * and -1 upon error. + */ +int fdtw_read_string(const void *dtb, int node, const char *prop, + char *str, size_t size) +{ + const char *ptr; + size_t len; + + assert(dtb != NULL); + assert(node >= 0); + assert(prop != NULL); + assert(str != NULL); + assert(size > 0U); + + ptr = fdt_getprop_namelen(dtb, node, prop, (int)strlen(prop), NULL); + if (ptr == NULL) { + WARN("Couldn't find property %s in dtb\n", prop); + return -1; + } + + len = strlcpy(str, ptr, size); + if (len >= size) { + WARN("String of property %s in dtb has been truncated\n", prop); + return -1; + } + + return 0; +} + /* * Write cells in place to a given property of the given node. At most 2 cells * of the property are written. Returns 0 on success, and -1 upon error. diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h index 3eae944e5..a0fe6b753 100644 --- a/include/common/fdt_wrappers.h +++ b/include/common/fdt_wrappers.h @@ -14,6 +14,9 @@ int fdtw_read_cells(const void *dtb, int node, const char *prop, unsigned int cells, void *value); +int fdtw_read_string(const void *dtb, int node, const char *prop, + char *str, size_t size); int fdtw_write_inplace_cells(void *dtb, int node, const char *prop, unsigned int cells, void *value); + #endif /* __FDT_WRAPPERS__ */ From 73f1ac6c8ee4a688ed8e1fddc040b882171d3453 Mon Sep 17 00:00:00 2001 From: Antonio Nino Diaz Date: Tue, 26 Jun 2018 10:34:10 +0100 Subject: [PATCH 4/4] Introduce fdtw_read_array() helper fdtw_read_cells() can only read one or two cells, sometimes it may be needed to read more cells from one property. Change-Id: Ie70dc76d1540cd6a04787cde7cccb4d1bafc7282 Signed-off-by: Antonio Nino Diaz --- common/fdt_wrappers.c | 40 ++++++++++++++++++++++++++++++++++- include/common/fdt_wrappers.h | 2 ++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c index 1715a6f0e..31dafb2eb 100644 --- a/common/fdt_wrappers.c +++ b/common/fdt_wrappers.c @@ -40,7 +40,6 @@ int fdtw_read_cells(const void *dtb, int node, const char *prop, return -1; } - /* Verify that property length accords with cell length */ if (NCELLS((unsigned int)value_len) != cells) { WARN("Property length mismatch\n"); @@ -62,6 +61,45 @@ int fdtw_read_cells(const void *dtb, int node, const char *prop, return 0; } +/* + * Read cells from a given property of the given node. Any number of 32-bit + * cells of the property can be read. The fdt pointer is updated. Returns 0 on + * success, and -1 on error. + */ +int fdtw_read_array(const void *dtb, int node, const char *prop, + unsigned int cells, void *value) +{ + const uint32_t *value_ptr; + int value_len; + + assert(dtb != NULL); + assert(prop != NULL); + assert(value != NULL); + assert(node >= 0); + + /* Access property and obtain its length (in bytes) */ + value_ptr = fdt_getprop_namelen(dtb, node, prop, (int)strlen(prop), + &value_len); + if (value_ptr == NULL) { + WARN("Couldn't find property %s in dtb\n", prop); + return -1; + } + + /* Verify that property length accords with cell length */ + if (NCELLS((unsigned int)value_len) != cells) { + WARN("Property length mismatch\n"); + return -1; + } + + uint32_t *dst = value; + + for (unsigned int i = 0U; i < cells; i++) { + dst[i] = fdt32_to_cpu(value_ptr[i]); + } + + return 0; +} + /* * Read string from a given property of the given node. Up to 'size - 1' * characters are read, and a NUL terminator is added. Returns 0 on success, diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h index a0fe6b753..c8d753f9a 100644 --- a/include/common/fdt_wrappers.h +++ b/include/common/fdt_wrappers.h @@ -14,6 +14,8 @@ int fdtw_read_cells(const void *dtb, int node, const char *prop, unsigned int cells, void *value); +int fdtw_read_array(const void *dtb, int node, const char *prop, + unsigned int cells, void *value); int fdtw_read_string(const void *dtb, int node, const char *prop, char *str, size_t size); int fdtw_write_inplace_cells(void *dtb, int node, const char *prop,