Hi Pedro, Thank you for starting this.
I recall some challenges with the Openssl libc wrapper, so let's work on that one last. If we can get a libc wrapper that is compatible with Brotli, regular expression, jannson, and fdtlib that would be a huge step forward. Can you test your code against these 3 use cases that are already in edk2? * MdeModulePkg\Library\BrotliCustomDecompressLib * MdeModulePkg\Universal\RegularExpressionDxe * RedfishPkg\PrivateInclude\Crt Mike > -----Original Message----- > From: Pedro Falcato <pedro.falc...@gmail.com> > Sent: Thursday, March 30, 2023 7:31 PM > To: devel@edk2.groups.io > Cc: Pedro Falcato <pedro.falc...@gmail.com>; Kinney, Michael D > <michael.d.kin...@intel.com>; Gao, Liming > <gaolim...@byosoft.com.cn>; Liu, Zhiguang <zhiguang....@intel.com>; Lin, > Benny <benny....@intel.com> > Subject: [RFC PATCH 1/1] MdePkg: Add a libc implementation > > Add LibcLib, a libc implementation meant to centralize all libc bits in > edk2. > > Work in progress, does not support Windows targets (CLANGPDB and MSVC) > just yet. > > Cc: Michael D Kinney <michael.d.kin...@intel.com> > Cc: Liming Gao <gaolim...@byosoft.com.cn> > Cc: Zhiguang Liu <zhiguang....@intel.com> > Cc: Benny Lin <benny....@intel.com> > Signed-off-by: Pedro Falcato <pedro.falc...@gmail.com> > --- > Wrote this to fulfill the new needs for BaseFdtLib and libfdt. > It's very much a work in progress. Please test (I have no way to test this, > and I have not attempted to replace OpenSSL stuff just yet). It's not > perfect, > but I attempted to be as correct as possible. Please, comment. > > Some details: > 1) I attempted to be as standards-correct as possible, used __name and _Name > to avoid namespace polution. > I (unfortunately) had to include Base.h for NULL, because defining my own > would possibly spell disaster > if someone included a C standard header and Base.h. > 2) ProcessorBind.h implicitly polutes the global namespace. I don't think > this is fixable. > 3) In some places, I wrote my own functions when I could redirect to > BaseMemoryLib stuff. > The amount of possible points of failure made me nervous (max string size > PCD, etc). To be discussed. > 4) This should fulfill BaseFdtLib's needs. I went a bit more in-depth where > I could (without wasting too much time). > Of course, this means it's still missing a *HUGE* chunk of libc. I don't > think I'm aiming to write a full libc here > (haha). > Just the common bits that may be useful for edk2. > 5) As discussed before (in the context of compiler intrinsics), GCC and > clang require memcpy, memset, and some others for > valid > codegen. This should possibly be done implicitly by BaseTools. > 6) Again, please, comment or contribute. If anyone wants to send PRs or > checkout directly, feel free: > https://github.com/heatd/edk2/tree/wip-libc > > MdePkg/Include/limits.h | 69 ++++++++++++++ > MdePkg/Include/stdbool.h | 17 ++++ > MdePkg/Include/stddef.h | 26 +++++ > MdePkg/Include/stdint.h | 116 +++++++++++++++++++++++ > MdePkg/Include/stdlib.h | 21 ++++ > MdePkg/Include/string.h | 86 +++++++++++++++++ > MdePkg/Include/types.h | 27 ++++++ > MdePkg/Library/LibcLib/LibcLib.inf | 38 ++++++++ > MdePkg/Library/LibcLib/Stdlib/strtoul.c | 121 ++++++++++++++++++++++++ > MdePkg/Library/LibcLib/String/memchr.c | 19 ++++ > MdePkg/Library/LibcLib/String/memcmp.c | 19 ++++ > MdePkg/Library/LibcLib/String/memcpy.c | 29 ++++++ > MdePkg/Library/LibcLib/String/memset.c | 21 ++++ > MdePkg/Library/LibcLib/String/strchr.c | 56 +++++++++++ > MdePkg/Library/LibcLib/String/strcmp.c | 27 ++++++ > MdePkg/Library/LibcLib/String/strcpy.c | 59 ++++++++++++ > MdePkg/Library/LibcLib/String/strlen.c | 16 ++++ > MdePkg/MdeLibs.dsc.inc | 1 + > MdePkg/MdePkg.dec | 4 + > MdePkg/MdePkg.dsc | 1 + > 20 files changed, 773 insertions(+) > create mode 100644 MdePkg/Include/limits.h > create mode 100644 MdePkg/Include/stdbool.h > create mode 100644 MdePkg/Include/stddef.h > create mode 100644 MdePkg/Include/stdint.h > create mode 100644 MdePkg/Include/stdlib.h > create mode 100644 MdePkg/Include/string.h > create mode 100644 MdePkg/Include/types.h > create mode 100644 MdePkg/Library/LibcLib/LibcLib.inf > create mode 100644 MdePkg/Library/LibcLib/Stdlib/strtoul.c > create mode 100644 MdePkg/Library/LibcLib/String/memchr.c > create mode 100644 MdePkg/Library/LibcLib/String/memcmp.c > create mode 100644 MdePkg/Library/LibcLib/String/memcpy.c > create mode 100644 MdePkg/Library/LibcLib/String/memset.c > create mode 100644 MdePkg/Library/LibcLib/String/strchr.c > create mode 100644 MdePkg/Library/LibcLib/String/strcmp.c > create mode 100644 MdePkg/Library/LibcLib/String/strcpy.c > create mode 100644 MdePkg/Library/LibcLib/String/strlen.c > > diff --git a/MdePkg/Include/limits.h b/MdePkg/Include/limits.h > new file mode 100644 > index 000000000000..f87b870e6cbc > --- /dev/null > +++ b/MdePkg/Include/limits.h > @@ -0,0 +1,69 @@ > +/** @file > + ISO C limits.h > + > + Copyright (c) 2023 Pedro Falcato All rights reserved. > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _LIMITS_H > +#define _LIMITS_H > + > +#if defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64) > +// Hint for LONG_* stuff > +#define __LIMITS_64BIT > +#endif > + > +#ifndef __GNUC__ > +// TODO: MSVC support is missing (some types are not exactly the same) > +// Should this whole logic be in ProcessorBind.h or something? > + #error "MSVC support TODO" > +#endif > + > +#define CHAR_BIT 8 > + > +/* Char limits - for char, signed char, unsigned char */ > +#define SCHAR_MIN -128 > +#define SCHAR_MAX 127 > +#define UCHAR_MAX 255 > + > +// Note: We must check if chars are signed or unsigned here. 0xff = -128 for > signed chars > +#if '\xff' < 0 > +#define __CHAR_IS_SIGNED > +#endif > + > +#ifdef __CHAR_IS_SIGNED > +#define CHAR_MIN SCHAR_MIN > +#define CHAR_MAX SCHAR_MAX > +#else > +#define CHAR_MIN 0 > +#define CHAR_MAX UCHAR_MAX > +#endif > + > +/* Short limits - for short, unsigned short */ > +#define SHRT_MIN (-1 - 0x7fff) > +#define SHRT_MAX 0x7fff > +#define USHRT_MAX 0xffff > + > +/* Int limits - for int, unsigned int */ > +#define INT_MIN (-1 - 0x7fffffff) > +#define INT_MAX 0x7fffffff > +#define UINT_MAX 0xffffffffU > + > +/* Long limits - for long, unsigned long and long long variants */ > + > +#ifdef __LIMITS_64BIT > +#define LONG_MAX 0x7fffffffffffffffL > +#define LONG_MIN (-1 - 0x7fffffffffffffffL) > +#define ULONG_MAX 0xffffffffffffffffUL > +#else > +#define LONG_MAX 0x7fffffffL > +#define LONG_MIN (-1 - 0x7fffffffL) > +#define ULONG_MAX 0xffffffffUL > +#endif > + > +/* long long must always be 64-bit for EFI UINT64 */ > +#define LLONG_MIN (-1 - 0x7fffffffffffffffLL) > +#define LLONG_MAX 0x7fffffffffffffffLL > +#define ULLONG_MAX 0xffffffffffffffffULL > + > +#endif > diff --git a/MdePkg/Include/stdbool.h b/MdePkg/Include/stdbool.h > new file mode 100644 > index 000000000000..c365fbcc4f0f > --- /dev/null > +++ b/MdePkg/Include/stdbool.h > @@ -0,0 +1,17 @@ > +/** @file > + ISO C stdbool.h > + > + Copyright (c) 2023 Pedro Falcato All rights reserved. > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _STDBOOL_H > +#define _STDBOOL_H > + > +#define bool _Bool > +#define true 1 > +#define false 0 > + > +#define __bool_true_false_are_defined 1 > + > +#endif > diff --git a/MdePkg/Include/stddef.h b/MdePkg/Include/stddef.h > new file mode 100644 > index 000000000000..86c17102f4b2 > --- /dev/null > +++ b/MdePkg/Include/stddef.h > @@ -0,0 +1,26 @@ > +/** @file > + ISO C stddef.h > + > + Copyright (c) 2023 Pedro Falcato All rights reserved. > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _STDDEF_H > +#define _STDDEF_H > + > +#include <Base.h> // For NULL > +// TODO: Namespace polution > + > +typedef INTN ptrdiff_t; > +typedef UINTN size_t; > +typedef CHAR16 wchar_t; > + > +// offsetof taken from Base.h > + > +#if (defined (__GNUC__) && __GNUC__ >= 4) || defined (__clang__) > +#define offsetof(TYPE, Field) ((UINTN) __builtin_offsetof(TYPE, Field)) > +#else > +#define offsetof(TYPE, Field) ((UINTN) &(((TYPE *)0)->Field)) > +#endif > + > +#endif > diff --git a/MdePkg/Include/stdint.h b/MdePkg/Include/stdint.h > new file mode 100644 > index 000000000000..ed554ff1773d > --- /dev/null > +++ b/MdePkg/Include/stdint.h > @@ -0,0 +1,116 @@ > +/** @file > + ISO C stdint.h > + > + Copyright (c) 2023 Pedro Falcato All rights reserved. > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _STDINT_H > +#define _STDINT_H > + > +// INT(N), UINT(N) taken from ProcessorBind.h > +typedef INT8 int8_t; > +typedef INT16 int16_t; > +typedef INT32 int32_t; > +typedef INT64 int64_t; > + > +typedef UINT8 uint8_t; > +typedef UINT16 uint16_t; > +typedef UINT32 uint32_t; > +typedef UINT64 uint64_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_least8_t; > +typedef uint16_t uint_least16_t; > +typedef uint32_t uint_least32_t; > +typedef uint64_t uint_least64_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_fast8_t; > +typedef uint16_t uint_fast16_t; > +typedef uint32_t uint_fast32_t; > +typedef uint64_t uint_fast64_t; > + > +typedef INTN intptr_t; > +typedef UINTN uintptr_t; > + > +typedef INT64 intmax_t; > +typedef UINT64 uintmax_t; > + > +/* Limits for the types declared above */ > +#define INT8_MIN -128 > +#define INT8_MAX 127 > +#define UINT8_MAX 255 > +#define INT16_MIN (-1 - 0x7fff) > +#define INT16_MAX 0x7fff > +#define UINT16_MAX 0xffff > +#define INT32_MIN (-1 - 0x7fffffff) > +#define INT32_MAX 0x7fffffff > +#define UINT32_MAX 0xffffffffU > +#define INT64_MIN (-1 - 0x7fffffffffffffffLL) > +#define INT64_MAX 0x7fffffffffffffffLL > +#define UINT64_MAX 0xffffffffffffffffULL > + > +#define INT_LEAST8_MIN INT8_MIN > +#define INT_LEAST8_MAX INT8_MAX > +#define UINT_LEAST8_MAX UINT8_MAX > +#define INT_LEAST16_MIN INT16_MIN > +#define INT_LEAST16_MAX INT16_MAX > +#define UINT_LEAST16_MAX UINT16_MAX > +#define INT_LEAST32_MIN INT32_MIN > +#define INT_LEAST32_MAX INT32_MAX > +#define UINT_LEAST32_MAX UINT32_MAX > +#define INT_LEAST64_MIN INT64_MIN > +#define INT_LEAST64_MAX INT64_MAX > +#define UINT_LEAST64_MAX UINT64_MAX > + > +#define INT_FAST8_MIN INT8_MIN > +#define INT_FAST8_MAX INT8_MAX > +#define UINT_FAST8_MAX UINT8_MAX > +#define INT_FAST16_MIN INT16_MIN > +#define INT_FAST16_MAX INT16_MAX > +#define UINT_FAST16_MAX UINT16_MAX > +#define INT_FAST32_MIN INT32_MIN > +#define INT_FAST32_MAX INT32_MAX > +#define UINT_FAST32_MAX UINT32_MAX > +#define INT_FAST64_MIN INT64_MIN > +#define INT_FAST64_MAX INT64_MAX > +#define UINT_FAST64_MAX UINT64_MAX > + > +#define INTPTR_MIN (1 - MAX_INTN) > +#define INTPTR_MAX MAX_INTN > +#define UINTPTR_MAX MAX_UINTN > + > +#define INTMAX_MIN INT64_MIN > +#define INTMAX_MAX INT64_MAX > +#define UINTMAX_MAX UINT64_MAX > + > +#define PTRDIFF_MIN INTPTR_MIN > +#define PTRDIFF_MAX INTPTR_MAX > +#define SIZE_MAX MAX_UINTN > + > +// TODO: SIG_ATOMIC, WCHAR, WINT > + > +/* Macros to declare (u)int(N)_t constants */ > + > +#define INT8_C(c) c > +#define INT16_C(c) c > +#define INT32_C(c) c > +#define INT64_C(c) c ## LL > +#define UINT8_C(c) c > +#define UINT16_C(c) c > +#define UINT32_C(c) c ## U > +#define UINT64_C(c) c ## ULL > + > +#define INTMAX_C(c) c ## LL > +#define UINTMAX_C(c) c ## ULL > + > +#endif > diff --git a/MdePkg/Include/stdlib.h b/MdePkg/Include/stdlib.h > new file mode 100644 > index 000000000000..954da4bbea8e > --- /dev/null > +++ b/MdePkg/Include/stdlib.h > @@ -0,0 +1,21 @@ > +/** @file > + ISO C stdlib.h > + > + Copyright (c) 2023 Pedro Falcato All rights reserved. > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _STDLIB_H > +#define _STDLIB_H > + > +#define __NEED_NULL > +#include <types.h> > + > +unsigned long > +strtoul ( > + const char *Nptr, > + char **EndPtr, > + int Base > + ); > + > +#endif > diff --git a/MdePkg/Include/string.h b/MdePkg/Include/string.h > new file mode 100644 > index 000000000000..31d95db91cfe > --- /dev/null > +++ b/MdePkg/Include/string.h > @@ -0,0 +1,86 @@ > +/** @file > + ISO C string.h > + > + Copyright (c) 2023 Pedro Falcato All rights reserved. > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _STRING_H > +#define _STRING_H > + > +#define __NEED_size_t > +#define __NEED_NULL > +#include <types.h> > + > +void * > +memcpy ( > + void *restrict Dst, > + const void *restrict Src, > + size_t Count > + ); > + > +void * > +memmove ( > + void *Dst, > + const void *Src, > + size_t Count > + ); > + > +void * > +memset ( > + void *Buf, > + int Val, > + size_t Count > + ); > + > +void * > +memchr ( > + const void *Buf, > + int Char, > + size_t Count > + ); > + > +int > +memcmp ( > + const void *S1, > + const void *S2, > + size_t Count > + ); > + > +size_t > +strlen ( > + const char *Str > + ); > + > +char * > +strcpy ( > + char *restrict Dest, > + const char *restrict Source > + ); > + > +char * > +strncpy ( > + char *restrict Dest, > + const char *restrict Source, > + size_t Count > + ); > + > +char * > +strcat ( > + char *restrict Dest, > + const char *restrict Source > + ); > + > +char * > +strchr ( > + const char *Str, > + int Char > + ); > + > +char * > +strrchr ( > + const char *Str, > + int Char > + ); > + > +#endif > diff --git a/MdePkg/Include/types.h b/MdePkg/Include/types.h > new file mode 100644 > index 000000000000..97e90d7b31e3 > --- /dev/null > +++ b/MdePkg/Include/types.h > @@ -0,0 +1,27 @@ > +/** @file > + ISO C auxiliary types file > + > + Copyright (c) 2023 Pedro Falcato All rights reserved. > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _TYPES_H > +#define _TYPES_H > + > +/* C has a variety of types we must define in a lot of header files, without > + including the "canonical" header file due to namespace pollution reasons. > + So define them here and use __NEED_ macros to ask for certain definitions. > + */ > + > +#if defined (__NEED_size_t) && !defined (__defined_size_t) > +typedef UINTN size_t; > +#define __defined_size_t > +#endif > + > +#if defined (__NEED_NULL) && !defined (__defined_NULL) > + #include <Base.h> > +#define __defined_NULL > +// TODO: Namespace pollution > +#endif > + > +#endif > diff --git a/MdePkg/Library/LibcLib/LibcLib.inf > b/MdePkg/Library/LibcLib/LibcLib.inf > new file mode 100644 > index 000000000000..d15def794973 > --- /dev/null > +++ b/MdePkg/Library/LibcLib/LibcLib.inf > @@ -0,0 +1,38 @@ > +## @file > +# ISO C libc implementation for EDK2 modules > +# > +# Copyright (c) 2023 Pedro Falcato All rights reserved. > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +## > + > +[Defines] > + INF_VERSION = 0x0001001B > + BASE_NAME = LibcLib > + FILE_GUID = 469201d7-0884-497a-ba93-ec5ee911b0e8 > + MODULE_TYPE = BASE > + VERSION_STRING = 1.0 > + LIBRARY_CLASS = LibcLib|BASE > + > +# > +# The following information is for reference only and not required by the > build tools. > +# > +# VALID_ARCHITECTURES = IA32 X64 AARCH64 > +# > + > +[Sources] > + String/strcpy.c > + String/strcmp.c > + String/strlen.c > + String/strchr.c > + String/memcpy.c > + String/memset.c > + String/memchr.c > + String/memcmp.c > + Stdlib/strtoul.c > + > +[Packages] > + MdePkg/MdePkg.dec > + > +[LibraryClasses] > + BaseLib > + BaseMemoryLib > diff --git a/MdePkg/Library/LibcLib/Stdlib/strtoul.c > b/MdePkg/Library/LibcLib/Stdlib/strtoul.c > new file mode 100644 > index 000000000000..952d3b899c5e > --- /dev/null > +++ b/MdePkg/Library/LibcLib/Stdlib/strtoul.c > @@ -0,0 +1,121 @@ > +/** @file > + memcpy-like functions > + > + Copyright (c) 2023 Pedro Falcato All rights reserved. > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include <stdlib.h> > +#include <limits.h> > + > +STATIC > +int > +__isspace ( > + int ch > + ) > +{ > + // basic ASCII ctype.h:isspace(). Not efficient > + return ch == '\r' || ch == '\n' || ch == ' ' || ch == '\t' || ch == '\v' > || ch == '\f'; > +} > + > +unsigned long > +strtoul ( > + const char *Nptr, > + char **EndPtr, > + int Base > + ) > +{ > + BOOLEAN Negate; > + BOOLEAN Overflow; > + unsigned long Val; > + > + Negate = FALSE; > + Overflow = FALSE; > + Val = 0; > + > + // Reject bad numeric bases > + if ((Base < 0) || (Base == 1) || (Base > 36)) { > + return 0; > + } > + > + // Skip whitespace > + while (__isspace (*Nptr)) { > + Nptr++; > + } > + > + // Check for + or - prefixes > + if (*Nptr == '-') { > + Negate = TRUE; > + Nptr++; > + } else if (*Nptr == '+') { > + Nptr++; > + } > + > + // Consume the start, autodetecting base if needed > + if ((Nptr[0] == '0') && ((Nptr[1] == 'x') || (Nptr[1] == 'X')) && ((Base > == 0) || (Base == 16))) { > + // Hex > + Nptr += 2; > + Base = 16; > + } else if ((Nptr[0] == '0') && ((Nptr[1] == 'b') || (Nptr[1] == 'B')) && > ((Base == 0) || (Base == 2))) { > + // Binary (standard pending C23) > + Nptr += 2; > + Base = 2; > + } else if ((Nptr[0] == '0') && ((Base == 0) || (Base == 8))) { > + // Octal > + Nptr++; > + Base = 8; > + } else { > + if (Base == 0) { > + // Assume decimal > + Base = 10; > + } > + } > + > + while (TRUE) { > + int Digit; > + char C; > + unsigned long NewVal; > + > + C = *Nptr; > + Digit = -1; > + > + if ((C >= '0') && (C <= '9')) { > + Digit = C - '0'; > + } else if ((C >= 'a') && (C <= 'z')) { > + Digit = C - 'a' + 10; > + } else if ((C >= 'A') && (C <= 'Z')) { > + Digit = C - 'A' + 10; > + } > + > + if ((Digit == -1) || (Digit >= Base)) { > + // Note that this case also handles the \0 > + if (EndPtr) { > + *EndPtr = (char *)Nptr; > + } > + > + break; > + } > + > + NewVal = Val * Base + Digit; > + > + if (NewVal < Val) { > + // Overflow > + Overflow = TRUE; > + } > + > + Val = NewVal; > + > + Nptr++; > + } > + > + if (Negate) { > + Val = -Val; > + } > + > + if (Overflow) { > + Val = ULONG_MAX; > + } > + > + // TODO: We're lacking errno here. > + return Val; > +} > diff --git a/MdePkg/Library/LibcLib/String/memchr.c > b/MdePkg/Library/LibcLib/String/memchr.c > new file mode 100644 > index 000000000000..cea8b71349f0 > --- /dev/null > +++ b/MdePkg/Library/LibcLib/String/memchr.c > @@ -0,0 +1,19 @@ > +/** @file > + memchr-like functions > + > + Copyright (c) 2023 Pedro Falcato All rights reserved. > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include <string.h> > +#include <Library/BaseMemoryLib.h> > + > +void * > +memchr ( > + const void *Buf, > + int Char, > + size_t Count > + ) > +{ > + return ScanMem8 (Buf, Count, Char); > +} > diff --git a/MdePkg/Library/LibcLib/String/memcmp.c > b/MdePkg/Library/LibcLib/String/memcmp.c > new file mode 100644 > index 000000000000..d02aa5d980f7 > --- /dev/null > +++ b/MdePkg/Library/LibcLib/String/memcmp.c > @@ -0,0 +1,19 @@ > +/** @file > + memcmp-like functions > + > + Copyright (c) 2023 Pedro Falcato All rights reserved. > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include <string.h> > +#include <Library/BaseMemoryLib.h> > + > +int > +memcmp ( > + const void *S1, > + const void *S2, > + size_t Count > + ) > +{ > + return (int)CompareMem (S1, S2, Count); > +} > diff --git a/MdePkg/Library/LibcLib/String/memcpy.c > b/MdePkg/Library/LibcLib/String/memcpy.c > new file mode 100644 > index 000000000000..d6e85f7eb37f > --- /dev/null > +++ b/MdePkg/Library/LibcLib/String/memcpy.c > @@ -0,0 +1,29 @@ > +/** @file > + memcpy-like functions > + > + Copyright (c) 2023 Pedro Falcato All rights reserved. > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include <string.h> > +#include <Library/BaseMemoryLib.h> > + > +void * > +memcpy ( > + void *restrict Dst, > + const void *restrict Src, > + size_t Count > + ) > +{ > + return CopyMem (Dst, Src, Count); > +} > + > +void * > +memmove ( > + void *Dst, > + const void *Src, > + size_t Count > + ) > +{ > + return CopyMem (Dst, Src, Count); > +} > diff --git a/MdePkg/Library/LibcLib/String/memset.c > b/MdePkg/Library/LibcLib/String/memset.c > new file mode 100644 > index 000000000000..e66d6ade5582 > --- /dev/null > +++ b/MdePkg/Library/LibcLib/String/memset.c > @@ -0,0 +1,21 @@ > +/** @file > + memcpy-like functions > + > + Copyright (c) 2023 Pedro Falcato All rights reserved. > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include <string.h> > +#include <Library/BaseMemoryLib.h> > + > +void * > +memset ( > + void *Buf, > + int Val, > + size_t Count > + ) > +{ > + // The standard defines memset as converting Val into an unsigned char > before storing, > + // so this cast is entirely safe. > + return SetMem (Buf, Count, (UINT8)Val); > +} > diff --git a/MdePkg/Library/LibcLib/String/strchr.c > b/MdePkg/Library/LibcLib/String/strchr.c > new file mode 100644 > index 000000000000..5e0ce7c43c98 > --- /dev/null > +++ b/MdePkg/Library/LibcLib/String/strchr.c > @@ -0,0 +1,56 @@ > +/** @file > + strchr-like implementations > + > + Copyright (c) 2023 Pedro Falcato All rights reserved. > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > +#include <Base.h> > + > +// Very quick notes: > +// We only go through the string once for both functions > +// They are minimal implementations (not speed optimized) of ISO C semantics > +// strchr and strrchr also include the null terminator as part of the string > +// so the code gets a bit clunky to handle that case specifically. > + > +char * > +strchr ( > + const char *Str, > + int Char > + ) > +{ > + char *S; > + > + S = (char *)Str; > + > + for ( ; ; S++) { > + if (*S == Char) { > + return S; > + } > + > + if (*S == '\0') { > + return NULL; > + } > + } > +} > + > +char * > +strrchr ( > + const char *Str, > + int Char > + ) > +{ > + char *S, *last; > + > + S = (char *)Str; > + last = NULL; > + > + for ( ; ; S++) { > + if (*S == Char) { > + last = S; > + } > + > + if (*S == '\0') { > + return last; > + } > + } > +} > diff --git a/MdePkg/Library/LibcLib/String/strcmp.c > b/MdePkg/Library/LibcLib/String/strcmp.c > new file mode 100644 > index 000000000000..9561fad389d3 > --- /dev/null > +++ b/MdePkg/Library/LibcLib/String/strcmp.c > @@ -0,0 +1,27 @@ > +/** @file > + strcmp-like implementations > + > + Copyright (c) 2023 Pedro Falcato All rights reserved. > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > +#include <string.h> > +#include <Library/BaseLib.h> > + > +int > +strcmp ( > + const char *Str1, > + const char *Str2 > + ) > +{ > + return (int)AsciiStrCmp (Str1, Str2); > +} > + > +int > +strncmp ( > + const char *Str1, > + const char *Str2, > + size_t Count > + ) > +{ > + return (int)AsciiStrnCmp (Str1, Str2, Count); > +} > diff --git a/MdePkg/Library/LibcLib/String/strcpy.c > b/MdePkg/Library/LibcLib/String/strcpy.c > new file mode 100644 > index 000000000000..767c18d6a464 > --- /dev/null > +++ b/MdePkg/Library/LibcLib/String/strcpy.c > @@ -0,0 +1,59 @@ > +/** @file > + strcpy-like implementations > + > + Copyright (c) 2023 Pedro Falcato All rights reserved. > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > +#include <string.h> > +#include <Library/BaseLib.h> > +#include <Library/BaseMemoryLib.h> > + > +char * > +strcpy ( > + char *restrict Dest, > + const char *restrict Source > + ) > +{ > + char *Ret; > + > + Ret = Dest; > + > + for ( ; *Source != '\0'; Source++, Dest++) { > + *Dest = *Source; > + } > + > + *Dest = '\0'; > + > + return Ret; > +} > + > +char * > +strncpy ( > + char *restrict Dest, > + const char *restrict Source, > + size_t Count > + ) > +{ > + char *Ret; > + > + Ret = Dest; > + > + while (Count--) { > + if (*Source != '\0') { > + *Dest++ = *Source++; > + } else { > + *Dest++ = '\0'; > + } > + } > + > + return Ret; > +} > + > +char * > +strcat ( > + char *restrict Dest, > + const char *restrict Source > + ) > +{ > + return strcpy (Dest + strlen (Dest), Source); > +} > diff --git a/MdePkg/Library/LibcLib/String/strlen.c > b/MdePkg/Library/LibcLib/String/strlen.c > new file mode 100644 > index 000000000000..a95fb7a18f7b > --- /dev/null > +++ b/MdePkg/Library/LibcLib/String/strlen.c > @@ -0,0 +1,16 @@ > +/** @file > + strlen implementation > + > + Copyright (c) 2023 Pedro Falcato All rights reserved. > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > +#include <string.h> > +#include <Library/BaseLib.h> > + > +size_t > +strlen ( > + const char *Str > + ) > +{ > + return AsciiStrLen (Str); > +} > diff --git a/MdePkg/MdeLibs.dsc.inc b/MdePkg/MdeLibs.dsc.inc > index 4580481cb580..f17d79286ec4 100644 > --- a/MdePkg/MdeLibs.dsc.inc > +++ b/MdePkg/MdeLibs.dsc.inc > @@ -16,3 +16,4 @@ > > RegisterFilterLib|MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf > CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf > > SmmCpuRendezvousLib|MdePkg/Library/SmmCpuRendezvousLibNull/SmmCpuRendezvousLibNull.inf > + LibcLib|MdePkg/Library/LibcLib/LibcLib.inf > diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec > index e49b2d5b5f28..8c37d89f5418 100644 > --- a/MdePkg/MdePkg.dec > +++ b/MdePkg/MdePkg.dec > @@ -284,6 +284,10 @@ > # > ArmTrngLib|Include/Library/ArmTrngLib.h > > + ## @libraryclass Provides various bits of a C standard library. > + # > + LibcLib|MdePkg/Library/LibcLib/LibcLib.inf > + > [LibraryClasses.IA32, LibraryClasses.X64, LibraryClasses.AARCH64] > ## @libraryclass Provides services to generate random number. > # > diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc > index 32a852dc466e..09828ae12647 100644 > --- a/MdePkg/MdePkg.dsc > +++ b/MdePkg/MdePkg.dsc > @@ -135,6 +135,7 @@ > MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf > MdePkg/Library/CcProbeLibNull/CcProbeLibNull.inf > MdePkg/Library/SmmCpuRendezvousLibNull/SmmCpuRendezvousLibNull.inf > + MdePkg/Library/LibcLib/LibcLib.inf > > [Components.IA32, Components.X64, Components.ARM, Components.AARCH64] > # > -- > 2.40.0 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#102588): https://edk2.groups.io/g/devel/message/102588 Mute This Topic: https://groups.io/mt/97965830/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/leave/9847357/21656/1706620634/xyzzy [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-