From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f53.google.com (mail-wm1-f53.google.com [209.85.128.53]) by mx.groups.io with SMTP id smtpd.web10.45648.1680229851176582973 for ; Thu, 30 Mar 2023 19:30:51 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20210112 header.b=nk484P93; spf=pass (domain: gmail.com, ip: 209.85.128.53, mailfrom: pedro.falcato@gmail.com) Received: by mail-wm1-f53.google.com with SMTP id n10-20020a05600c4f8a00b003ee93d2c914so14148181wmq.2 for ; Thu, 30 Mar 2023 19:30:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680229849; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=y2PVXgrH2gDpTXp45KIArrM5wCQEc/C9JKqBu5MLyOc=; b=nk484P93IsZ4hzwrORMXwK31eJNYZf1yBb60rEuF8Toq2KUqALVLlCJ/gK/w5tcIQ+ 80nCcrW/hD3+PAwyWX/Hm1TSUNoRutUXJ5oVbbxTuiOiyOCTtLK0zIjcYUwpnMPtt6UV QyYisPHuJPiDpeQzl6hhvNomZuxUco7mxhe4q0OmfXU48xaajgPEz0UnuFRSDP1CcCdi fiCVfR9h74kmGInRCnFClRHoNPoeObntsA4sguudHZnrT1uW7Isz9yKw4+8QyAw7rU98 BRuCOdB4McaS/o43Rdc5n7bjCK+LSV+JH62Mbx2tflsaAwWlWiNG2FRXUz3kWwyrqcfb BqVQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680229849; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=y2PVXgrH2gDpTXp45KIArrM5wCQEc/C9JKqBu5MLyOc=; b=6cFQdbf6wr9U3gKle6qcOeET+k5mjhJWYZwv8YYsZJj1QX5vwHiyJFGtZKRN8AxQxH HlGKVa4otV2yMRJc/bVm94WmCzGNzchkG/z5xWC0fFyjxG/jy/cJ/vsgU3Y9Qvmm8zU3 gBKY6TWDeKl/GhTa5Y6/rPDCb3csA3el0EAiL9twYjKOPysZuoM/fzQAyBxQHfqp+Q4h wEdDlmlyfBCYlGbqteQ4JgaghXXnP5eAbhkgH/o9ZiaW+MVFiuBxkkNf/nxe3ReBhGka x54eNx1yLk+Fk4X2Lx7zBrnszPXeLZ5DW77LySVUMOO1MFbEdoxGu4aLumoCWGcQTgvB oGYg== X-Gm-Message-State: AO0yUKXNCwma3w7/nrAu0lcrRcszADWZXcJtftPkbcXkiEWz8U83CTIb C/As5xPMHF0vWgk/v8/FtBUANjBWzfQ= X-Google-Smtp-Source: AK7set9h8k88c+tpohqeR5+QfAb0JY6EdF7tIOAn5ifbKpdU5RqOsP0uJNOEOoAEEvXaEDXjB3RM/w== X-Received: by 2002:a05:600c:378d:b0:3ed:377b:19cc with SMTP id o13-20020a05600c378d00b003ed377b19ccmr18293777wmr.0.1680229848952; Thu, 30 Mar 2023 19:30:48 -0700 (PDT) Return-Path: Received: from PC-PEDRO-ARCH.lan ([2001:8a0:7280:5801:9441:3dce:686c:bfc7]) by smtp.gmail.com with ESMTPSA id n2-20020a05600c4f8200b003ef5e5f93f5sm8105646wmq.19.2023.03.30.19.30.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Mar 2023 19:30:48 -0700 (PDT) From: "Pedro Falcato" To: devel@edk2.groups.io Cc: Pedro Falcato , Michael D Kinney , Liming Gao , Zhiguang Liu , Benny Lin Subject: [RFC PATCH 1/1] MdePkg: Add a libc implementation Date: Fri, 31 Mar 2023 03:30:45 +0100 Message-Id: <20230331023045.66516-1-pedro.falcato@gmail.com> X-Mailer: git-send-email 2.40.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 Cc: Liming Gao Cc: Zhiguang Liu Cc: Benny Lin Signed-off-by: Pedro Falcato --- 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 // 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 + +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 + +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 +#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 +#include + +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 +#include + +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 +#include + +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 +#include + +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 +#include + +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 + +// 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 +#include + +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 +#include +#include + +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 +#include + +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