summaryrefslogtreecommitdiff
path: root/common/util_stdlib.c
diff options
context:
space:
mode:
authorMichał Barnaś <mb@semihalf.com>2021-08-09 17:54:36 +0200
committerCommit Bot <commit-bot@chromium.org>2021-08-25 17:26:29 +0000
commit6fc57405b6f9d38edf62824cd2d2fdae1f6e5bbf (patch)
tree945ef3d2a774799a2f71a4a0018eced9cd71a265 /common/util_stdlib.c
parentd610bce3c3b08e0432f8008c1b4020b173f32e27 (diff)
downloadchrome-ec-6fc57405b6f9d38edf62824cd2d2fdae1f6e5bbf.tar.gz
common: move standard library functions from util.c to another file
This commit moves some of the standard library functions from util.c file to util_stdlib.c file. It will allow to use util.c for both CrOS EC and Zephyr builds and will make shim util file unnecessary. BRANCH=main BUG=b:177096231 TEST=Build both, CrOS EC and Zephyr firmwares Compilation should finish without any problems After flashing, both versions work as they should Change-Id: If6f930a04d28bec35faa16759f43b36176bf3de7 Signed-off-by: Michał Barnaś <mb@semihalf.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3081827 Commit-Queue: Keith Short <keithshort@chromium.org> Reviewed-by: Keith Short <keithshort@chromium.org>
Diffstat (limited to 'common/util_stdlib.c')
-rw-r--r--common/util_stdlib.c332
1 files changed, 332 insertions, 0 deletions
diff --git a/common/util_stdlib.c b/common/util_stdlib.c
new file mode 100644
index 0000000000..8302730ad7
--- /dev/null
+++ b/common/util_stdlib.c
@@ -0,0 +1,332 @@
+/* Copyright 2021 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Standard library utility functions for Chrome EC */
+
+#include "common.h"
+#include "console.h"
+#include "util.h"
+
+__stdlib_compat size_t strlen(const char *s)
+{
+ int len = 0;
+
+ while (*s++)
+ len++;
+
+ return len;
+}
+
+__stdlib_compat size_t strnlen(const char *s, size_t maxlen)
+{
+ size_t len = 0;
+
+ while (len < maxlen && *s) {
+ s++;
+ len++;
+ }
+ return len;
+}
+
+__stdlib_compat size_t strcspn(const char *s, const char *reject)
+{
+ size_t i;
+ size_t reject_len = strlen(reject);
+
+ for (i = 0; s[i] != 0; i++)
+ for (size_t j = 0; j < reject_len; j++)
+ if (s[i] == reject[j])
+ return i;
+ return i;
+}
+
+__stdlib_compat int isspace(int c)
+{
+ return c == ' ' || c == '\t' || c == '\r' || c == '\n';
+}
+
+__stdlib_compat int isdigit(int c)
+{
+ return c >= '0' && c <= '9';
+}
+
+__stdlib_compat int isalpha(int c)
+{
+ return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
+}
+
+__stdlib_compat int isupper(int c)
+{
+ return c >= 'A' && c <= 'Z';
+}
+
+__stdlib_compat int isprint(int c)
+{
+ return c >= ' ' && c <= '~';
+}
+
+__stdlib_compat int tolower(int c)
+{
+ return c >= 'A' && c <= 'Z' ? c + 'a' - 'A' : c;
+}
+
+__stdlib_compat int strncasecmp(const char *s1, const char *s2, size_t size)
+{
+ int diff;
+
+ if (!size)
+ return 0;
+
+ do {
+ diff = tolower(*s1) - tolower(*s2);
+ if (diff)
+ return diff;
+ } while (*(s1++) && *(s2++) && --size);
+ return 0;
+}
+
+__stdlib_compat char *strstr(const char *s1, const char *s2)
+{
+ const char *p, *q, *r;
+ size_t len1 = strlen(s1);
+ size_t len2 = strlen(s2);
+
+ if (len1 == 0 || len2 == 0 || len1 < len2)
+ return NULL;
+
+ r = s1 + len1 - len2 + 1;
+ for (; s1 < r; s1++) {
+ if (*s1 == *s2) {
+ p = s1 + 1;
+ q = s2 + 1;
+ for (; q < s2 + len2;) {
+ if (*p++ != *q++)
+ break;
+ }
+ if (*q == '\0')
+ return (char *)s1;
+ }
+ }
+ return NULL;
+}
+
+__stdlib_compat int atoi(const char *nptr)
+{
+ int result = 0;
+ int neg = 0;
+ char c = '\0';
+
+ while ((c = *nptr++) && isspace(c))
+ ;
+
+ if (c == '-') {
+ neg = 1;
+ c = *nptr++;
+ }
+
+ while (isdigit(c)) {
+ result = result * 10 + (c - '0');
+ c = *nptr++;
+ }
+
+ return neg ? -result : result;
+}
+
+__attribute__((used))
+__stdlib_compat int memcmp(const void *s1, const void *s2, size_t len)
+{
+ const char *sa = s1;
+ const char *sb = s2;
+ int diff = 0;
+
+ while (len-- > 0) {
+ diff = *(sa++) - *(sb++);
+ if (diff)
+ return diff;
+ }
+
+ return 0;
+}
+
+#if !(__has_feature(address_sanitizer) || __has_feature(memory_sanitizer))
+__attribute__((used))
+__stdlib_compat void *memcpy(void *dest, const void *src, size_t len)
+{
+ char *d = (char *)dest;
+ const char *s = (const char *)src;
+ uint32_t *dw;
+ const uint32_t *sw;
+ char *head;
+ char * const tail = (char *)dest + len;
+ /* Set 'body' to the last word boundary */
+ uint32_t * const body = (uint32_t *)((uintptr_t)tail & ~3);
+
+ if (((uintptr_t)dest & 3) != ((uintptr_t)src & 3)) {
+ /* Misaligned. no body, no tail. */
+ head = tail;
+ } else {
+ /* Aligned */
+ if ((uintptr_t)tail < (((uintptr_t)d + 3) & ~3))
+ /* len is shorter than the first word boundary */
+ head = tail;
+ else
+ /* Set 'head' to the first word boundary */
+ head = (char *)(((uintptr_t)d + 3) & ~3);
+ }
+
+ /* Copy head */
+ while (d < head)
+ *(d++) = *(s++);
+
+ /* Copy body */
+ dw = (uint32_t *)d;
+ sw = (uint32_t *)s;
+ while (dw < body)
+ *(dw++) = *(sw++);
+
+ /* Copy tail */
+ d = (char *)dw;
+ s = (const char *)sw;
+ while (d < tail)
+ *(d++) = *(s++);
+
+ return dest;
+}
+#endif /* address_sanitizer || memory_sanitizer */
+
+#if !(__has_feature(address_sanitizer) || __has_feature(memory_sanitizer))
+__attribute__((used))
+__stdlib_compat __visible void *memset(void *dest, int c, size_t len)
+{
+ char *d = (char *)dest;
+ uint32_t cccc;
+ uint32_t *dw;
+ char *head;
+ char * const tail = (char *)dest + len;
+ /* Set 'body' to the last word boundary */
+ uint32_t * const body = (uint32_t *)((uintptr_t)tail & ~3);
+
+ c &= 0xff; /* Clear upper bits before ORing below */
+ cccc = c | (c << 8) | (c << 16) | (c << 24);
+
+ if ((uintptr_t)tail < (((uintptr_t)d + 3) & ~3))
+ /* len is shorter than the first word boundary */
+ head = tail;
+ else
+ /* Set 'head' to the first word boundary */
+ head = (char *)(((uintptr_t)d + 3) & ~3);
+
+ /* Copy head */
+ while (d < head)
+ *(d++) = c;
+
+ /* Copy body */
+ dw = (uint32_t *)d;
+ while (dw < body)
+ *(dw++) = cccc;
+
+ /* Copy tail */
+ d = (char *)dw;
+ while (d < tail)
+ *(d++) = c;
+
+ return dest;
+}
+#endif /* address_sanitizer || memory_sanitizer */
+
+#if !(__has_feature(address_sanitizer) || __has_feature(memory_sanitizer))
+__attribute__((used))
+__stdlib_compat void *memmove(void *dest, const void *src, size_t len)
+{
+ if ((uintptr_t)dest <= (uintptr_t)src ||
+ (uintptr_t)dest >= (uintptr_t)src + len) {
+ /* Start of destination doesn't overlap source, so just use
+ * memcpy().
+ */
+ return memcpy(dest, src, len);
+ } else {
+ /* Need to copy from tail because there is overlap. */
+ char *d = (char *)dest + len;
+ const char *s = (const char *)src + len;
+ uint32_t *dw;
+ const uint32_t *sw;
+ char *head;
+ char * const tail = (char *)dest;
+ /* Set 'body' to the last word boundary */
+ uint32_t * const body = (uint32_t *)(((uintptr_t)tail+3) & ~3);
+
+ if (((uintptr_t)dest & 3) != ((uintptr_t)src & 3)) {
+ /* Misaligned. no body, no tail. */
+ head = tail;
+ } else {
+ /* Aligned */
+ if ((uintptr_t)tail > ((uintptr_t)d & ~3))
+ /* Shorter than the first word boundary */
+ head = tail;
+ else
+ /* Set 'head' to the first word boundary */
+ head = (char *)((uintptr_t)d & ~3);
+ }
+
+ /* Copy head */
+ while (d > head)
+ *(--d) = *(--s);
+
+ /* Copy body */
+ dw = (uint32_t *)d;
+ sw = (uint32_t *)s;
+ while (dw > body)
+ *(--dw) = *(--sw);
+
+ /* Copy tail */
+ d = (char *)dw;
+ s = (const char *)sw;
+ while (d > tail)
+ *(--d) = *(--s);
+
+ return dest;
+ }
+}
+#endif /* address_sanitizer || memory_sanitizer */
+
+__stdlib_compat void *memchr(const void *buffer, int c, size_t n)
+{
+ char *current = (char *)buffer;
+ char *end = current + n;
+
+ while (current != end) {
+ if (*current == c)
+ return current;
+ current++;
+ }
+ return NULL;
+}
+
+__stdlib_compat char *strncpy(char *dest, const char *src, size_t n)
+{
+ char *d = dest;
+
+ while (n && *src) {
+ *d++ = *src++;
+ n--;
+ }
+ if (n)
+ *d = '\0';
+ return dest;
+}
+
+__stdlib_compat int strncmp(const char *s1, const char *s2, size_t n)
+{
+ while (n--) {
+ if (*s1 != *s2)
+ return *s1 - *s2;
+ if (!*s1)
+ break;
+ s1++;
+ s2++;
+
+ }
+ return 0;
+}