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]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to