diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/build.mk | 2 | ||||
-rw-r--r-- | common/util.c | 338 | ||||
-rw-r--r-- | common/util_stdlib.c | 332 |
3 files changed, 334 insertions, 338 deletions
diff --git a/common/build.mk b/common/build.mk index 2ba81f6006..48a247d58a 100644 --- a/common/build.mk +++ b/common/build.mk @@ -9,7 +9,7 @@ # Note that this variable includes the trailing "/" _common_dir:=$(dir $(lastword $(MAKEFILE_LIST))) -common-y=util.o +common-y=util.o util_stdlib.o common-y+=version.o printf.o queue.o queue_policies.o irq_locking.o common-$(CONFIG_ACCELGYRO_BMI160)+=math_util.o diff --git a/common/util.c b/common/util.c index deaa62f37f..dac5cf5e09 100644 --- a/common/util.c +++ b/common/util.c @@ -9,73 +9,6 @@ #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 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 size_t strnlen(const char *s, size_t maxlen) -{ - size_t len = 0; - - while (len < maxlen && *s) { - s++; - len++; - } - return len; -} - - -__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 strcasecmp(const char *s1, const char *s2) { int diff; @@ -88,71 +21,8 @@ __stdlib_compat int strcasecmp(const char *s1, const char *s2) return 0; } - -__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) +static int find_base(int base, int *c, 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; -} - -static int find_base(int base, int *c, const char **nptr) { if ((base == 0 || base == 16) && *c == '0' && (**nptr == 'x' || **nptr == 'X')) { *c = (*nptr)[1]; @@ -164,7 +34,6 @@ static int find_base(int base, int *c, const char **nptr) { return base; } - /* Like strtol(), but for integers */ __stdlib_compat int strtoi(const char *nptr, char **endptr, int base) { @@ -260,21 +129,6 @@ __stdlib_compat int parse_bool(const char *s, int *dest) return 0; } -__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; -} /* Constant-time memory comparison */ int safe_memcmp(const void *s1, const void *s2, size_t size) @@ -296,163 +150,6 @@ int safe_memcmp(const void *s1, const void *s2, size_t size) return result != 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; -} - - void reverse(void *dest, size_t len) { int i; @@ -467,7 +164,6 @@ void reverse(void *dest, size_t len) } } - __stdlib_compat char *strzcpy(char *dest, const char *src, int len) { char *d = dest; @@ -481,36 +177,6 @@ __stdlib_compat char *strzcpy(char *dest, const char *src, int len) return dest; } - -__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; -} - - int uint64divmod(uint64_t *n, int d) { uint64_t q = 0, mask; @@ -614,7 +280,6 @@ int cond_is(cond_t *c, int val) return !(*c & COND_CURR_MASK); } - void cond_set(cond_t *c, int val) { if (val && cond_is(c, 0)) @@ -627,7 +292,6 @@ void cond_set(cond_t *c, int val) *c &= ~COND_CURR_MASK; } - int cond_went(cond_t *c, int val) { int ret; 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; +} |