From 6fc57405b6f9d38edf62824cd2d2fdae1f6e5bbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Barna=C5=9B?= Date: Mon, 9 Aug 2021 17:54:36 +0200 Subject: common: move standard library functions from util.c to another file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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ś Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3081827 Commit-Queue: Keith Short Reviewed-by: Keith Short --- common/util_stdlib.c | 332 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 332 insertions(+) create mode 100644 common/util_stdlib.c (limited to 'common/util_stdlib.c') 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; +} -- cgit v1.2.1