diff options
Diffstat (limited to 'builtin')
-rw-r--r-- | builtin/assert.h | 10 | ||||
-rw-r--r-- | builtin/build.mk | 6 | ||||
-rw-r--r-- | builtin/ctype.h | 16 | ||||
-rw-r--r-- | builtin/endian.h | 8 | ||||
-rw-r--r-- | builtin/inttypes.h | 2 | ||||
-rw-r--r-- | builtin/limits.h | 2 | ||||
-rw-r--r-- | builtin/math.h | 2 | ||||
-rw-r--r-- | builtin/stdarg.h | 10 | ||||
-rw-r--r-- | builtin/stdbool.h | 8 | ||||
-rw-r--r-- | builtin/stddef.h | 10 | ||||
-rw-r--r-- | builtin/stdint.h | 68 | ||||
-rw-r--r-- | builtin/stdio.h | 61 | ||||
-rw-r--r-- | builtin/stdlib.c | 465 | ||||
-rw-r--r-- | builtin/stdlib.h | 11 | ||||
-rw-r--r-- | builtin/stdnoreturn.h | 5 | ||||
-rw-r--r-- | builtin/string.h | 26 | ||||
-rw-r--r-- | builtin/strings.h | 14 | ||||
-rw-r--r-- | builtin/sys/types.h | 9 | ||||
-rw-r--r-- | builtin/time.h | 2 |
19 files changed, 666 insertions, 69 deletions
diff --git a/builtin/assert.h b/builtin/assert.h index 010198fd1b..b667a0d2a2 100644 --- a/builtin/assert.h +++ b/builtin/assert.h @@ -1,4 +1,4 @@ -/* Copyright 2016 The Chromium OS Authors. All rights reserved. +/* Copyright 2016 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -11,6 +11,8 @@ /* Include CONFIG definitions for EC sources. */ #ifndef THIRD_PARTY #include "common.h" +#else +#define test_mockable_noreturn noreturn #endif #ifdef __cplusplus @@ -21,7 +23,7 @@ extern "C" { #ifdef CONFIG_DEBUG_ASSERT_REBOOTS #ifdef CONFIG_DEBUG_ASSERT_BRIEF -noreturn void panic_assert_fail(const char *fname, int linenum); +test_mockable_noreturn void panic_assert_fail(const char *fname, int linenum); #define ASSERT(cond) \ do { \ if (!(cond)) \ @@ -30,8 +32,8 @@ noreturn void panic_assert_fail(const char *fname, int linenum); #else /* !CONFIG_DEBUG_ASSERT_BRIEF */ -noreturn void panic_assert_fail(const char *msg, const char *func, - const char *fname, int linenum); +test_mockable_noreturn void panic_assert_fail(const char *msg, const char *func, + const char *fname, int linenum); #define ASSERT(cond) \ do { \ if (!(cond)) \ diff --git a/builtin/build.mk b/builtin/build.mk new file mode 100644 index 0000000000..6613bfec05 --- /dev/null +++ b/builtin/build.mk @@ -0,0 +1,6 @@ +# Copyright 2022 The ChromiumOS Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Build for EC's standard library implementation. +builtin-y=stdlib.o diff --git a/builtin/ctype.h b/builtin/ctype.h new file mode 100644 index 0000000000..8844adca67 --- /dev/null +++ b/builtin/ctype.h @@ -0,0 +1,16 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __CROS_EC_CTYPE_H__ +#define __CROS_EC_CTYPE_H__ + +int isdigit(int c); +int isspace(int c); +int isalpha(int c); +int isupper(int c); +int isprint(int c); +int tolower(int c); + +#endif /* __CROS_EC_CTYPE_H__ */ diff --git a/builtin/endian.h b/builtin/endian.h index 65c064bb78..0220836dca 100644 --- a/builtin/endian.h +++ b/builtin/endian.h @@ -1,4 +1,4 @@ -/* Copyright 2016 The Chromium OS Authors. All rights reserved. +/* Copyright 2016 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -17,7 +17,7 @@ extern "C" { * host byte order. Note that the code currently does not require functions * for converting little endian integers. */ -#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) static inline uint16_t be16toh(uint16_t in) { @@ -40,10 +40,10 @@ static inline uint64_t be64toh(uint64_t in) #define htole32(x) (uint32_t)(x) #define htole64(x) (uint64_t)(x) -#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */ +#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */ #ifdef __cplusplus } #endif -#endif /* __EC_BUILTIN_ENDIAN_H */ +#endif /* __EC_BUILTIN_ENDIAN_H */ diff --git a/builtin/inttypes.h b/builtin/inttypes.h index c442fbe499..1ef305548b 100644 --- a/builtin/inttypes.h +++ b/builtin/inttypes.h @@ -1,4 +1,4 @@ -/* Copyright 2019 The Chromium OS Authors. All rights reserved. +/* Copyright 2019 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ diff --git a/builtin/limits.h b/builtin/limits.h index e5deb70291..0e185614ae 100644 --- a/builtin/limits.h +++ b/builtin/limits.h @@ -1,4 +1,4 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. +/* Copyright 2020 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ diff --git a/builtin/math.h b/builtin/math.h index 9292ac8b34..c015d9d18d 100644 --- a/builtin/math.h +++ b/builtin/math.h @@ -1,4 +1,4 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. +/* Copyright 2021 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ diff --git a/builtin/stdarg.h b/builtin/stdarg.h index 66ab940b16..5bf0aa8aa2 100644 --- a/builtin/stdarg.h +++ b/builtin/stdarg.h @@ -1,4 +1,4 @@ -/* Copyright 2016 The Chromium OS Authors. All rights reserved. +/* Copyright 2016 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -13,10 +13,10 @@ */ #ifdef __GNUC__ -#define va_start(v, l) __builtin_va_start(v, l) -#define va_end(v) __builtin_va_end(v) -#define va_arg(v, l) __builtin_va_arg(v, l) -typedef __builtin_va_list va_list; +#define va_start(v, l) __builtin_va_start(v, l) +#define va_end(v) __builtin_va_end(v) +#define va_arg(v, l) __builtin_va_arg(v, l) +typedef __builtin_va_list va_list; #else #include_next <stdarg.h> #endif diff --git a/builtin/stdbool.h b/builtin/stdbool.h index 6e0f92dfc0..72d4927484 100644 --- a/builtin/stdbool.h +++ b/builtin/stdbool.h @@ -1,4 +1,4 @@ -/* Copyright 2016 The Chromium OS Authors. All rights reserved. +/* Copyright 2016 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -6,8 +6,8 @@ #ifndef __CROS_EC_STDBOOL_H__ #define __CROS_EC_STDBOOL_H__ -#define bool _Bool -#define true 1 -#define false 0 +#define bool _Bool +#define true 1 +#define false 0 #endif /* __CROS_EC_STDBOOL_H__ */ diff --git a/builtin/stddef.h b/builtin/stddef.h index 69fb1982c7..9e69ba55ad 100644 --- a/builtin/stddef.h +++ b/builtin/stddef.h @@ -1,4 +1,4 @@ -/* Copyright 2016 The Chromium OS Authors. All rights reserved. +/* Copyright 2016 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -11,12 +11,6 @@ #endif typedef __SIZE_TYPE__ size_t; -/* There is a GCC macro for a size_t type, but not for a ssize_t type. - * The following construct convinces GCC to make __SIZE_TYPE__ signed. - */ -#define unsigned signed -typedef __SIZE_TYPE__ ssize_t; -#undef unsigned #ifndef NULL #define NULL ((void *)0) @@ -36,7 +30,7 @@ typedef __WCHAR_TYPE__ wchar_t; * check for safety. */ #ifndef offsetof -#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER) +#define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER) #endif #endif /* __CROS_EC_STDDEF_H__ */ diff --git a/builtin/stdint.h b/builtin/stdint.h index dedc9de475..5a107e1730 100644 --- a/builtin/stdint.h +++ b/builtin/stdint.h @@ -1,4 +1,4 @@ -/* Copyright 2016 The Chromium OS Authors. All rights reserved. +/* Copyright 2016 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -6,43 +6,43 @@ #ifndef __CROS_EC_STDINT_H__ #define __CROS_EC_STDINT_H__ -typedef unsigned char uint8_t; -typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed char int8_t; -typedef unsigned short uint16_t; -typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed short int16_t; -typedef unsigned int uint32_t; -typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed int int32_t; typedef unsigned long long uint64_t; -typedef signed long long int64_t; +typedef signed long long int64_t; -typedef unsigned int uintptr_t; -typedef int intptr_t; +typedef unsigned int uintptr_t; +typedef int intptr_t; /* uint_leastX_t represents the smallest type available with at least X bits. * uint_fastX_t represents the fastest type available with at least X bits. */ -typedef uint8_t uint_least8_t; -typedef uint16_t uint_least16_t; -typedef uint32_t uint_least32_t; -typedef uint64_t uint_least64_t; - -typedef int8_t int_least8_t; -typedef int16_t int_least16_t; -typedef int32_t int_least32_t; -typedef int64_t int_least64_t; - -typedef uint8_t uint_fast8_t; -typedef uint16_t uint_fast16_t; -typedef uint32_t uint_fast32_t; -typedef uint64_t uint_fast64_t; - -typedef int8_t int_fast8_t; -typedef int16_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef int64_t int_fast64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; + +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; #ifndef UINT8_MAX #define UINT8_MAX (255U) @@ -67,12 +67,15 @@ typedef int64_t int_fast64_t; #ifndef INT32_MAX #define INT32_MAX (2147483647U) #endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483648) +#endif #ifndef UINT64_C -#define UINT64_C(c) c ## ULL +#define UINT64_C(c) c##ULL #endif #ifndef INT64_C -#define INT64_C(c) c ## LL +#define INT64_C(c) c##LL #endif #ifndef UINT64_MAX @@ -81,5 +84,8 @@ typedef int64_t int_fast64_t; #ifndef INT64_MAX #define INT64_MAX INT64_C(9223372036854775807) #endif +#ifndef INT64_MIN +#define INT64_MIN (INT64_C(-9223372036854775807) - 1) +#endif #endif /* __CROS_EC_STDINT_H__ */ diff --git a/builtin/stdio.h b/builtin/stdio.h new file mode 100644 index 0000000000..7536499feb --- /dev/null +++ b/builtin/stdio.h @@ -0,0 +1,61 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __CROS_EC_STDIO_H__ +#define __CROS_EC_STDIO_H__ + +#include <stddef.h> +#include <stdarg.h> + +#include "common.h" + +/** + * Print formatted outut to a string. + * + * Guarantees null-termination if size!=0. + * + * @param str Destination string + * @param size Size of destination in bytes + * @param format Format string + * @return EC_SUCCESS, or EC_ERROR_OVERFLOW if the output was truncated. + */ +__attribute__((__format__(__printf__, 3, 4))) +__warn_unused_result __stdlib_compat int +crec_snprintf(char *str, size_t size, const char *format, ...); + +/** + * Print formatted output to a string. + * + * Guarantees null-termination if size!=0. + * + * @param str Destination string + * @param size Size of destination in bytes + * @param format Format string + * @param args Parameters + * @return The string length written to str, or a negative value on error. + * The negative values can be -EC_ERROR_INVAL or -EC_ERROR_OVERFLOW. + */ +__warn_unused_result __stdlib_compat int +crec_vsnprintf(char *str, size_t size, const char *format, va_list args); + +/* + * Create weak aliases to the crec_* printf functions. This lets us call the + * crec_* printf functions in tests that link the C standard library. + */ + +/** + * Alias to crec_snprintf. + */ +__attribute__((__format__(__printf__, 3, 4))) +__warn_unused_result __stdlib_compat int +snprintf(char *str, size_t size, const char *format, ...); + +/** + * Alias to crec_vsnprintf. + */ +__warn_unused_result __stdlib_compat int +vsnprintf(char *str, size_t size, const char *format, va_list args); + +#endif /* __CROS_EC_STDIO_H__ */ diff --git a/builtin/stdlib.c b/builtin/stdlib.c new file mode 100644 index 0000000000..0d654f0395 --- /dev/null +++ b/builtin/stdlib.c @@ -0,0 +1,465 @@ +/* Copyright 2021 The ChromiumOS Authors + * 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 "printf.h" +#include "util.h" + +#include <stdio.h> + +/* + * The following macros are defined in stdlib.h in the C standard library, which + * conflict with the definitions in this file. + */ +#undef isspace +#undef isdigit +#undef isalpha +#undef isupper +#undef isprint +#undef tolower + +/* Context for snprintf() */ +struct snprintf_context { + char *str; + int size; +}; + +/** + * Add a character to the string context. + * + * @param context Context receiving character + * @param c Character to add + * @return 0 if character added, 1 if character dropped because no space. + */ +static int snprintf_addchar(void *context, int c) +{ + struct snprintf_context *ctx = (struct snprintf_context *)context; + + if (!ctx->size) + return 1; + + *(ctx->str++) = c; + ctx->size--; + return 0; +} + +int crec_vsnprintf(char *str, size_t size, const char *format, va_list args) +{ + struct snprintf_context ctx; + int rv; + + if (!str || !format || size <= 0) + return -EC_ERROR_INVAL; + + ctx.str = str; + ctx.size = size - 1; /* Reserve space for terminating '\0' */ + + rv = vfnprintf(snprintf_addchar, &ctx, format, args); + + /* Terminate string */ + *ctx.str = '\0'; + + return (rv == EC_SUCCESS) ? (ctx.str - str) : -rv; +} +#ifndef CONFIG_ZEPHYR +int vsnprintf(char *str, size_t size, const char *format, va_list args) + __attribute__((weak, alias("crec_vsnprintf"))); +#endif /* CONFIG_ZEPHYR */ + +int crec_snprintf(char *str, size_t size, const char *format, ...) +{ + va_list args; + int rv; + + va_start(args, format); + rv = crec_vsnprintf(str, size, format, args); + va_end(args); + + return rv; +} +#ifndef CONFIG_ZEPHYR +int snprintf(char *str, size_t size, const char *format, ...) + __attribute__((weak, alias("crec_snprintf"))); +#endif /* CONFIG_ZEPHYR */ + +/* + * TODO(b/237712836): Zephyr's libc should provide strcasecmp. For now we'll + * use the EC implementation. + */ +__stdlib_compat int strcasecmp(const char *s1, const char *s2) +{ + int diff; + + do { + diff = tolower(*s1) - tolower(*s2); + if (diff) + return diff; + } while (*(s1++) && *(s2++)); + return 0; +} + +/* + * TODO(b/237712836): Remove this conditional once strcasecmp is added to + * Zephyr's libc. + */ +#ifndef CONFIG_ZEPHYR +__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 unsigned long long int strtoull(const char *nptr, char **endptr, + int base) +{ + uint64_t result = 0; + int c = '\0'; + + while ((c = *nptr++) && isspace(c)) + ; + + if (c == '+') { + c = *nptr++; + } else if (c == '-') { + if (endptr) + *endptr = (char *)nptr - 1; + return result; + } + + base = find_base(base, &c, &nptr); + + while (c) { + if (c >= '0' && c < '0' + MIN(base, 10)) + result = result * base + (c - '0'); + else if (c >= 'A' && c < 'A' + base - 10) + result = result * base + (c - 'A' + 10); + else if (c >= 'a' && c < 'a' + base - 10) + result = result * base + (c - 'a' + 10); + else + break; + + c = *nptr++; + } + + if (endptr) + *endptr = (char *)nptr - 1; + return result; +} +BUILD_ASSERT(sizeof(unsigned long long int) == sizeof(uint64_t)); + +__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; +} + +__keep __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)) +__keep __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)) +__keep __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)) +__keep __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; +} +#endif /* !CONFIG_ZEPHYR */ diff --git a/builtin/stdlib.h b/builtin/stdlib.h new file mode 100644 index 0000000000..fcce72ee8d --- /dev/null +++ b/builtin/stdlib.h @@ -0,0 +1,11 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __CROS_EC_STDLIB_H__ +#define __CROS_EC_STDLIB_H__ + +int atoi(const char *nptr); + +#endif /* __CROS_EC_STDLIB_H__ */ diff --git a/builtin/stdnoreturn.h b/builtin/stdnoreturn.h index 659d3c540f..078a0d6698 100644 --- a/builtin/stdnoreturn.h +++ b/builtin/stdnoreturn.h @@ -1,4 +1,4 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. +/* Copyright 2020 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -9,7 +9,8 @@ /* * Only defined for C: https://en.cppreference.com/w/c/language/_Noreturn * - * C++ uses [[noreturn]]: https://en.cppreference.com/w/cpp/language/attributes/noreturn + * C++ uses [[noreturn]]: + * https://en.cppreference.com/w/cpp/language/attributes/noreturn */ #ifndef __cplusplus #ifndef noreturn diff --git a/builtin/string.h b/builtin/string.h index 8c9a71bd75..742d75a478 100644 --- a/builtin/string.h +++ b/builtin/string.h @@ -1,12 +1,10 @@ -/* Copyright 2016 The Chromium OS Authors. All rights reserved. +/* Copyright 2016 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ -/* This header is only needed for CR50 compatibility */ - -#ifndef __CROS_EC_STRINGS_H__ -#define __CROS_EC_STRINGS_H__ +#ifndef __CROS_EC_STRING_H__ +#define __CROS_EC_STRING_H__ #include <stddef.h> @@ -20,12 +18,28 @@ void *memmove(void *dest, const void *src, size_t n); void *memset(void *dest, int c, size_t len); void *memchr(const void *buffer, int c, size_t n); +size_t strlen(const char *s); size_t strnlen(const char *s, size_t maxlen); char *strncpy(char *dest, const char *src, size_t n); int strncmp(const char *s1, const char *s2, size_t n); +/** + * Calculates the length of the initial segment of s which consists + * entirely of bytes not in reject. + */ +size_t strcspn(const char *s, const char *reject); + +/** + * Find the first occurrence of the substring <s2> in the string <s1> + * + * @param s1 String where <s2> is searched. + * @param s2 Substring to be located in <s1> + * @return Pointer to the located substring or NULL if not found. + */ +char *strstr(const char *s1, const char *s2); + #ifdef __cplusplus } #endif -#endif /* __CROS_EC_STRINGS_H__ */ +#endif /* __CROS_EC_STRING_H__ */ diff --git a/builtin/strings.h b/builtin/strings.h new file mode 100644 index 0000000000..cbcc858c36 --- /dev/null +++ b/builtin/strings.h @@ -0,0 +1,14 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef __CROS_EC_STRINGS_H__ +#define __CROS_EC_STRINGS_H__ + +#include <stddef.h> + +int strcasecmp(const char *s1, const char *s2); +int strncasecmp(const char *s1, const char *s2, size_t size); + +#endif /* __CROS_EC_STRINGS_H__ */ diff --git a/builtin/sys/types.h b/builtin/sys/types.h index 3f8de955e0..01fc1a7749 100644 --- a/builtin/sys/types.h +++ b/builtin/sys/types.h @@ -1,4 +1,4 @@ -/* Copyright 2022 The ChromiumOS Authors. +/* Copyright 2022 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -9,4 +9,11 @@ /* Data type for POSIX style clock() implementation */ typedef long clock_t; +/* There is a GCC macro for a size_t type, but not for a ssize_t type. + * The following construct convinces GCC to make __SIZE_TYPE__ signed. + */ +#define unsigned signed +typedef __SIZE_TYPE__ ssize_t; +#undef unsigned + #endif /* __CROS_EC_SYS_TYPES_H__ */ diff --git a/builtin/time.h b/builtin/time.h index a069ae18c9..36b07b4721 100644 --- a/builtin/time.h +++ b/builtin/time.h @@ -1,4 +1,4 @@ -/* Copyright 2016 The Chromium OS Authors. All rights reserved. +/* Copyright 2016 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ |