From c1722924cee57e1eb27cad656baf079bf809b8f6 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 22 Feb 2021 12:03:53 -0500 Subject: compiler.h: fix a typo and add some more function attribute macros This fixes the ifndef guard on NONNULL and __CONCAT3 and adds definitions for: - __CONCAT() for a##b with the intermediate tokenization step - ALLOCFUNC for __malloc__ - DEPRECATED for __deprecated__ - PURE for __pure__ - RETURNS_NONNULL for __nonnull__ Signed-off-by: Peter Jones --- include/compiler.h | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) (limited to 'include/compiler.h') diff --git a/include/compiler.h b/include/compiler.h index 4e44840d..3cabd09c 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -3,6 +3,24 @@ #ifndef COMPILER_H_ #define COMPILER_H_ +/* + * These are special ones that get our unit tests in trouble with the + * compiler optimizer dropping out tests... + */ +#ifdef NONNULL +# undef NONNULL +#endif +#ifdef RETURNS_NONNULL +# undef RETURNS_NONNULL +#endif +#ifdef SHIM_UNIT_TEST +# define NONNULL(first, args...) +# define RETURNS_NONNULL +#else +# define NONNULL(first, args...) __attribute__((__nonnull__(first, ## args))) +# define RETURNS_NONNULL __attribute__((__returns_nonnull__)) +#endif + #ifndef UNUSED #define UNUSED __attribute__((__unused__)) #endif @@ -12,6 +30,9 @@ #ifndef PUBLIC #define PUBLIC __attribute__((__visibility__ ("default"))) #endif +#ifndef DEPRECATED +#define DEPRECATED __attribute__((__deprecated__)) +#endif #ifndef DESTRUCTOR #define DESTRUCTOR __attribute__((destructor)) #endif @@ -21,12 +42,15 @@ #ifndef ALIAS #define ALIAS(x) __attribute__((weak, alias (#x))) #endif -#ifndef NONNULL +#ifndef ALLOCFUNC +#define ALLOCFUNC(dealloc, dealloc_arg) __attribute__((__malloc__(dealloc, dealloc_arg))) #endif -#define NONNULL(first, args...) __attribute__((__nonnull__(first, ## args))) #ifndef PRINTF #define PRINTF(first, args...) __attribute__((__format__(printf, first, ## args))) #endif +#ifndef PURE +#define PURE __attribute__((__pure__)) +#endif #ifndef FLATTEN #define FLATTEN __attribute__((__flatten__)) #endif @@ -56,6 +80,9 @@ #endif #ifndef __CONCAT +#define __CONCAT(a, b) a ## b +#endif +#ifndef __CONCAT3 #define __CONCAT3(a, b, c) a ## b ## c #endif #ifndef CAT -- cgit v1.2.3 From 766aac4d5cfbe76026be5ce718b0883ee211f323 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 9 Mar 2021 11:54:58 -0500 Subject: Consolidate most of our standard lib functions to lib Signed-off-by: Peter Jones --- Cryptlib/Include/OpenSslSupport.h | 23 +--- Cryptlib/Makefile | 3 +- Cryptlib/SysCall/BaseStrings.c | 34 +----- Cryptlib/SysCall/CrtWrapper.c | 82 ------------- Cryptlib/SysCall/memset.c | 40 ------- Makefile | 4 +- csv.c | 4 +- gnu-efi | 2 +- httpboot.c | 14 +-- include/compiler.h | 5 + include/endian.h | 19 +++ include/hexdump.h | 2 - include/str.h | 118 +----------------- include/system/alloca.h | 6 + include/system/builtins_begin_.h | 94 +++++++++++++++ include/system/builtins_end_.h | 28 +++++ include/system/ctype.h | 73 +++++++++++- include/system/stdlib.h | 12 ++ include/system/string.h | 51 +++++++- include/system/strings.h | 9 ++ lib/string.c | 245 ++++++++++++++++++++++++++++++++++++++ mok.c | 2 +- netboot.c | 8 +- sbat.c | 4 +- shim.h | 2 + 25 files changed, 566 insertions(+), 318 deletions(-) delete mode 100644 Cryptlib/SysCall/memset.c create mode 100644 include/endian.h create mode 100644 include/system/builtins_begin_.h create mode 100644 include/system/builtins_end_.h create mode 100644 lib/string.c (limited to 'include/compiler.h') diff --git a/Cryptlib/Include/OpenSslSupport.h b/Cryptlib/Include/OpenSslSupport.h index 7af9650f..6bb7ba64 100644 --- a/Cryptlib/Include/OpenSslSupport.h +++ b/Cryptlib/Include/OpenSslSupport.h @@ -288,34 +288,21 @@ extern int errno; void *malloc (size_t); void *realloc (void *, size_t); void free (void *); -int isdigit (int); -int isspace (int); -int tolower (int); -int isupper (int); -int isxdigit (int); -int isalnum (int); void *memcpy (void *, const void *, size_t); void *memset (void *, int, size_t); void *memchr (const void *, int, size_t); int memcmp (const void *, const void *, size_t); void *memmove (void *, const void *, size_t); -int strcmp (const char *, const char *); -int strncmp (const char *, const char *, size_t); char *strcpy (char *, const char *); char *strncpy (char *, const char *, size_t); -size_t strlen (const char *); char *strcat (char *, const char *); char *strchr (const char *, int); int strcasecmp (const char *, const char *); int strncasecmp (const char *, const char *, size_t); char *strncpy (char *, const char *, size_t); -int strncmp (const char *, const char *, size_t); -char *strrchr (const char *, int); unsigned long strtoul (const char *, char **, int); long strtol (const char *, char **, int); char *strerror (int); -size_t strspn (const char *, const char *); -size_t strcspn (const char *, const char *); int printf (const char *, ...); int sscanf (const char *, const char *, ...); int open (const char *, int, ...); @@ -351,7 +338,6 @@ gid_t getegid (void); void qsort (void *, size_t, size_t, int (*)(const void *, const void *)); char *getenv (const char *); void exit (int); -void abort (void); __sighandler_t *signal (int, __sighandler_t *); // @@ -361,7 +347,7 @@ extern FILE *stderr; extern FILE *stdin; extern FILE *stdout; -#define AsciiStrLen(x) strlena(x) +#define AsciiStrLen(x) strlen(x) #define AsciiStrnCmp(s1, s2, len) strncmpa((CHAR8 *)s1, (CHAR8 *)s2, len) // @@ -372,17 +358,10 @@ extern FILE *stdout; #define memchr(buf,ch,count) ScanMem8((CHAR8 *)buf,(UINTN)(count),ch) #define memcmp(buf1,buf2,count) (int)(CompareMem(buf1,buf2,(UINTN)(count))) #define memmove(dest,source,count) CopyMem(dest,source,(UINTN)(count)) -#define strlen(str) (size_t)(AsciiStrLen((CHAR8 *)str)) -#define strcpy(strDest,strSource) AsciiStrCpy((CHAR8 *)strDest,(const CHAR8 *)strSource) -#define strncpy(strDest,strSource,count) AsciiStrnCpy((CHAR8 *)strDest,(const CHAR8 *)strSource,(UINTN)count) -#define strcat(strDest,strSource) AsciiStrCat((CHAR8 *)strDest,(const CHAR8 *)strSource) -#define strchr(str,ch) (char *)(ScanMem8((CHAR8 *)str,AsciiStrSize((CHAR8 *)str),ch)) -#define strncmp(string1,string2,count) (int)(AsciiStrnCmp((const CHAR8 *)string1, (const CHAR8 *)string2,(UINTN)(count))) #define localtime(timer) NULL #define assert(expression) #define atoi(nptr) AsciiStrDecimalToUintn((const CHAR8 *)nptr) #define gettimeofday(tvp,tz) do { (tvp)->tv_sec = time(NULL); (tvp)->tv_usec = 0; } while (0) #define gmtime_r(timer,result) (result = NULL) -#define abort() #endif diff --git a/Cryptlib/Makefile b/Cryptlib/Makefile index 65a3918c..27614618 100644 --- a/Cryptlib/Makefile +++ b/Cryptlib/Makefile @@ -63,8 +63,7 @@ OBJS = Hash/CryptMd4Null.o \ SysCall/CrtWrapper.o \ SysCall/TimerWrapper.o \ SysCall/BaseMemAllocation.o \ - SysCall/BaseStrings.o \ - SysCall/memset.o + SysCall/BaseStrings.o all: $(TARGET) diff --git a/Cryptlib/SysCall/BaseStrings.c b/Cryptlib/SysCall/BaseStrings.c index c4b3e18e..29a16100 100644 --- a/Cryptlib/SysCall/BaseStrings.c +++ b/Cryptlib/SysCall/BaseStrings.c @@ -3,7 +3,7 @@ CHAR8 * AsciiStrCat(CHAR8 *Destination, const CHAR8 *Source) { - UINTN dest_len = strlena((CHAR8 *)Destination); + UINTN dest_len = strlen((CHAR8 *)Destination); UINTN i; for (i = 0; Source[i] != '\0'; i++) @@ -61,37 +61,7 @@ WriteUnaligned32(UINT32 *Buffer, UINT32 Value) UINTN AsciiStrSize(const CHAR8 *string) { - return strlena(string) + 1; -} - -int -strcmp (const char *str1, const char *str2) -{ - return strcmpa((CHAR8 *)str1,(CHAR8 *)str2); -} - -inline static char -toupper (char c) -{ - return ((c >= 'a' && c <= 'z') ? c - ('a' - 'A') : c); -} - -/* Based on AsciiStriCmp() in edk2 MdePkg/Library/BaseLib/String.c */ -int -strcasecmp (const char *str1, const char *str2) -{ - char c1, c2; - - c1 = toupper (*str1); - c2 = toupper (*str2); - while ((*str1 != '\0') && (c1 == c2)) { - str1++; - str2++; - c1 = toupper (*str1); - c2 = toupper (*str2); - } - - return c1 - c2; + return strlen(string) + 1; } /* Based on AsciiStrDecimalToUintnS() in edk2 diff --git a/Cryptlib/SysCall/CrtWrapper.c b/Cryptlib/SysCall/CrtWrapper.c index 698e1eef..4bdaede9 100644 --- a/Cryptlib/SysCall/CrtWrapper.c +++ b/Cryptlib/SysCall/CrtWrapper.c @@ -121,21 +121,6 @@ QuickSortWorker ( // -- String Manipulation Routines -- // -/* Scan a string for the last occurrence of a character */ -char *strrchr (const char *str, int c) -{ - char * save; - - for (save = NULL; ; ++str) { - if (*str == c) { - save = (char *)str; - } - if (*str == 0) { - return (save); - } - } -} - /* Read formatted data from a string */ int sscanf (const char *buffer, const char *format, ...) { @@ -146,59 +131,6 @@ int sscanf (const char *buffer, const char *format, ...) return 0; } -// -// -- Character Classification Routines -- -// - -/* Determines if a particular character is a decimal-digit character */ -int isdigit (int c) -{ - // - // ::= [0-9] - // - return (('0' <= (c)) && ((c) <= '9')); -} - -/* Determine if an integer represents character that is a hex digit */ -int isxdigit (int c) -{ - // - // ::= [0-9] | [a-f] | [A-F] - // - return ((('0' <= (c)) && ((c) <= '9')) || - (('a' <= (c)) && ((c) <= 'f')) || - (('A' <= (c)) && ((c) <= 'F'))); -} - -/* Determines if a particular character represents a space character */ -int isspace (int c) -{ - // - // ::= [ ] - // - return ((c) == ' '); -} - -/* Determine if a particular character is an alphanumeric character */ -int isalnum (int c) -{ - // - // ::= [0-9] | [a-z] | [A-Z] - // - return ((('0' <= (c)) && ((c) <= '9')) || - (('a' <= (c)) && ((c) <= 'z')) || - (('A' <= (c)) && ((c) <= 'Z'))); -} - -/* Determines if a particular character is in upper case */ -int isupper (int c) -{ - // - // := [A-Z] - // - return (('A' <= (c)) && ((c) <= 'Z')); -} - // // -- Data Conversion Routines -- // @@ -223,15 +155,6 @@ unsigned long strtoul (const char *nptr, char **endptr, int base) return 0; } -/* Convert character to lowercase */ -int tolower (int c) -{ - if (('A' <= (c)) && ((c) <= 'Z')) { - return (c - ('A' - 'a')); - } - return (c); -} - // // -- Searching and Sorting Routines -- // @@ -424,11 +347,6 @@ int stat (const char *c, struct stat *s) return -1; } -int strncasecmp (const char *c, const char *s, size_t l) -{ - return 0; -} - void syslog (int a, const char *c, ...) { diff --git a/Cryptlib/SysCall/memset.c b/Cryptlib/SysCall/memset.c deleted file mode 100644 index 76deed68..00000000 --- a/Cryptlib/SysCall/memset.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2016 SUSE LINUX GmbH - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -typedef UINTN size_t; - -void * -memset (void *dest, int ch, size_t count) -{ - SetMem(dest, count, (UINT8)(ch)); - return dest; -} diff --git a/Makefile b/Makefile index 6a62e00a..7c0fbb11 100644 --- a/Makefile +++ b/Makefile @@ -116,12 +116,12 @@ LIBS = Cryptlib/libcryptlib.a \ gnu-efi/$(ARCH_GNUEFI)/gnuefi/libgnuefi.a $(SHIMSONAME): $(OBJS) $(LIBS) - $(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS) + $(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS) lib/lib.a fallback.o: $(FALLBACK_SRCS) $(FBSONAME): $(FALLBACK_OBJS) $(LIBS) - $(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS) + $(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS) lib/lib.a MokManager.o: $(MOK_SOURCES) diff --git a/csv.c b/csv.c index 3c821414..d141f035 100644 --- a/csv.c +++ b/csv.c @@ -21,8 +21,8 @@ parse_csv_line(char * line, size_t max, size_t *n_columns, const char *columns[] valid = strntoken(next, max, delims, &token, &state); } if (valid) { - next += strlena(token) + 1; - max -= strlena(token) + 1; + next += strlen(token) + 1; + max -= strlen(token) + 1; columns[n] = token; new_n = n + 1; } else { diff --git a/gnu-efi b/gnu-efi index 9aa86c75..d7e183a3 160000 --- a/gnu-efi +++ b/gnu-efi @@ -1 +1 @@ -Subproject commit 9aa86c7526a4adc363afe6847bc3a4c8efe6df84 +Subproject commit d7e183a351d1a81efb2402e5148a4a69fc170365 diff --git a/httpboot.c b/httpboot.c index fe08f3f7..93d88931 100644 --- a/httpboot.c +++ b/httpboot.c @@ -130,7 +130,7 @@ find_httpboot (EFI_HANDLE device) /* Save the current URI */ UriNode = (URI_DEVICE_PATH *)Node; - uri_size = strlena(UriNode->Uri); + uri_size = strlen(UriNode->Uri); uri = AllocatePool(uri_size + 1); if (!uri) { perror(L"Failed to allocate uri\n"); @@ -156,10 +156,10 @@ generate_next_uri (CONST CHAR8 *current_uri, CONST CHAR8 *next_loader, UINTN path_len = 0; UINTN count = 0; - if (strncmpa(current_uri, (CHAR8 *)"http://", 7) == 0) { + if (strncmp(current_uri, (CHAR8 *)"http://", 7) == 0) { ptr = current_uri + 7; count += 7; - } else if (strncmpa(current_uri, (CHAR8 *)"https://", 8) == 0) { + } else if (strncmp(current_uri, (CHAR8 *)"https://", 8) == 0) { ptr = current_uri + 8; count += 8; } else { @@ -167,7 +167,7 @@ generate_next_uri (CONST CHAR8 *current_uri, CONST CHAR8 *next_loader, } /* Extract the path */ - next_len = strlena(next_loader); + next_len = strlen(next_loader); while (*ptr != '\0') { count++; if (*ptr == '/') @@ -192,9 +192,9 @@ extract_hostname (CONST CHAR8 *url, CHAR8 **hostname) CONST CHAR8 *ptr, *start; UINTN host_len = 0; - if (strncmpa(url, (CHAR8 *)"http://", 7) == 0) + if (strncmp(url, (CHAR8 *)"http://", 7) == 0) start = url + 7; - else if (strncmpa(url, (CHAR8 *)"https://", 8) == 0) + else if (strncmp(url, (CHAR8 *)"https://", 8) == 0) start = url + 8; else return EFI_INVALID_PARAMETER; @@ -571,7 +571,7 @@ receive_http_response(EFI_HTTP_PROTOCOL *http, VOID **buffer, UINT64 *buf_size) /* Check the length of the file */ for (i = 0; i < rx_message.HeaderCount; i++) { - if (!strcmpa(rx_message.Headers[i].FieldName, (CHAR8 *)"Content-Length")) { + if (!strcmp(rx_message.Headers[i].FieldName, (CHAR8 *)"Content-Length")) { *buf_size = ascii_to_int(rx_message.Headers[i].FieldValue); } } diff --git a/include/compiler.h b/include/compiler.h index 3cabd09c..40358a11 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -179,5 +179,10 @@ #define MIN(a, b) ({(a) < (b) ? (a) : (b);}) #define MAX(a, b) ({(a) <= (b) ? (b) : (a);}) +/** + * Builtins that don't go in string.h + */ +#define unreachable() __builtin_unreachable() + #endif /* !COMPILER_H_ */ // vim:fenc=utf-8:tw=75:et diff --git a/include/endian.h b/include/endian.h new file mode 100644 index 00000000..267fbf00 --- /dev/null +++ b/include/endian.h @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: BSD-2-Clause-Patent +/* + * endian.h - bswap decls that can't go in compiler.h + * Copyright Peter Jones + */ + +#ifndef ENDIAN_H_ +#define ENDIAN_H_ + +#include + +#include "system/builtins_begin_.h" +mkbi1_(uint16_t, bswap16, uint16_t, x) +mkbi1_(uint32_t, bswap32, uint32_t, x) +mkbi1_(uint64_t, bswap64, uint64_t, x) +#include "system/builtins_end_.h" + +#endif /* !ENDIAN_H_ */ +// vim:fenc=utf-8:tw=75:noet diff --git a/include/hexdump.h b/include/hexdump.h index 36d77ec4..a6aa2bfa 100644 --- a/include/hexdump.h +++ b/include/hexdump.h @@ -48,8 +48,6 @@ prepare_hex(const void *data, size_t size, char *buf, unsigned int position) return ret; } -#define isprint(c) ((c) >= 0x20 && (c) <= 0x7e) - static inline void UNUSED prepare_text(const void *data, size_t size, char *buf, unsigned int position) { diff --git a/include/str.h b/include/str.h index c4d12113..189aceff 100644 --- a/include/str.h +++ b/include/str.h @@ -9,122 +9,8 @@ #pragma GCC diagnostic ignored "-Wnonnull-compare" #endif -static inline UNUSED NONNULL(1) unsigned long -strnlena(const CHAR8 *s, unsigned long n) -{ - unsigned long i; - for (i = 0; i < n; i++) - if (s[i] == '\0') - break; - return i; -} - -static inline UNUSED RETURNS_NONNULL NONNULL(1, 2) CHAR8 * -strncpya(CHAR8 *dest, const CHAR8 *src, unsigned long n) -{ - unsigned long i; - - for (i = 0; i < n && src[i] != '\0'; i++) - dest[i] = src[i]; - for (; i < n; i++) - dest[i] = '\0'; - - return dest; -} - -static inline UNUSED RETURNS_NONNULL NONNULL(1, 2) CHAR8 * -strcata(CHAR8 *dest, const CHAR8 *src) -{ - unsigned long dest_len = strlena(dest); - unsigned long i; - - for (i = 0; src[i] != '\0'; i++) - dest[dest_len + i] = src[i]; - dest[dest_len + i] = '\0'; - - return dest; -} - -static inline UNUSED NONNULL(1) CHAR8 * -strdup(const CHAR8 * const src) -{ - UINTN len; - CHAR8 *news = NULL; - - len = strlena(src); - news = AllocateZeroPool(len + 1); - if (news) - strncpya(news, src, len); - return news; -} - -static inline UNUSED NONNULL(1) CHAR8 * -strndupa(const CHAR8 * const src, const UINTN srcmax) -{ - UINTN len; - CHAR8 *news = NULL; - - len = strnlena(src, srcmax); - news = AllocateZeroPool(len + 1); - if (news) - strncpya(news, src, len); - return news; -} - -static inline UNUSED RETURNS_NONNULL NONNULL(1, 2) char * -stpcpy(char *dest, const char * const src) -{ - size_t i = 0; - for (i = 0; src[i]; i++) - dest[i] = src[i]; - dest[i] = '\000'; - return &dest[i]; -} - -static inline UNUSED CHAR8 * -translate_slashes(CHAR8 *out, const char *str) -{ - int i; - int j; - if (str == NULL || out == NULL) - return NULL; - - for (i = 0, j = 0; str[i] != '\0'; i++, j++) { - if (str[i] == '\\') { - out[j] = '/'; - if (str[i+1] == '\\') - i++; - } else - out[j] = str[i]; - } - out[j] = '\0'; - return out; -} - -static inline UNUSED RETURNS_NONNULL NONNULL(1) CHAR8 * -strchrnula(const CHAR8 *s, int c) -{ - unsigned int i; - - for (i = 0; s[i] != '\000' && s[i] != c; i++) - ; - - return (CHAR8 *)&s[i]; -} - -static inline UNUSED NONNULL(1) CHAR8 * -strchra(const CHAR8 *s, int c) -{ - const CHAR8 *s1; - - s1 = strchrnula(s, c); - if (!s1 || s1[0] == '\000') - return NULL; - - return (CHAR8 *)s1; -} - -static inline UNUSED RETURNS_NONNULL NONNULL(1) char * +static inline UNUSED RETURNS_NONNULL NONNULL(1) +char * strnchrnul(const char *s, size_t max, int c) { unsigned int i; diff --git a/include/system/alloca.h b/include/system/alloca.h index dc11b60d..a9d1aab1 100644 --- a/include/system/alloca.h +++ b/include/system/alloca.h @@ -5,6 +5,12 @@ #ifndef _ALLOCA_H #define _ALLOCA_H +#include +mkbi1_(void *, alloca, size_t, size) +#define alloca_with_align(size, alignment) __builtin_alloca_with_align(size, alignment) +#define alloca_with_align_and_max(size, alignment, max) __builtin_alloca_with_align_and_max(size, alignment, max) +#include + #endif /* !_ALLOCA_H */ #endif // vim:fenc=utf-8:tw=75:noet diff --git a/include/system/builtins_begin_.h b/include/system/builtins_begin_.h new file mode 100644 index 00000000..92ea5e3a --- /dev/null +++ b/include/system/builtins_begin_.h @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: BSD-2-Clause-Patent +/** + * macros to build builtin wrappers + */ +#ifndef mkbi_cat_ +#define mkbi_cat_(a, b) a##b +#endif +#ifdef SHIM_STRING_C_ + +#ifndef mkbi1_ +#define mkbi1_(rtype, x, typea, a) __typeof__(mkbi_cat_(__builtin_, x)) x; +#endif +#ifndef mkbi2_ +#define mkbi2_(rtype, x, typea, a, typeb, b) __typeof__(mkbi_cat_(__builtin_, x)) x; +#endif + +#ifndef mkbi3_ +#define mkbi3_(rtype, x, typea, a, typeb, b, typec, c) __typeof__(mkbi_cat_(__builtin_, x)) x; +#endif + +#ifndef mkdepbi1_ +#define mkdepbi1_(rtype, x, typea, a) __typeof__(mkbi_cat_(__builtin_, x)) x; +#endif + +#ifndef mkdepbi2_ +#define mkdepbi2_(rtype, x, typea, a, typeb, b) __typeof__(mkbi_cat_(__builtin_, x)) x; +#endif + +#else /* ! SHIM_STRING_C_ */ + +#ifndef mkbi1_ +#define mkbi1_(rtype, x, typea, a) \ + static inline __attribute__((__unused__)) \ + rtype \ + x(typea a) \ + { \ + return mkbi_cat_(__builtin_, x)(a); \ + } +#endif + +#ifndef mkbi2_ +#define mkbi2_(rtype, x, typea, a, typeb, b) \ + static inline __attribute__((__unused__)) \ + rtype \ + x(typea a, typeb b) \ + { \ + return mkbi_cat_(__builtin_, x)(a, b); \ + } +#endif + +#ifndef mkbi3_ +#define mkbi3_(rtype, x, typea, a, typeb, b, typec, c) \ + static inline __attribute__((__unused__)) \ + rtype \ + x(typea a, typeb b, typec c) \ + { \ + return mkbi_cat_(__builtin_, x)(a, b,c); \ + } +#endif + +#ifdef SHIM_DEPRECATE_STRLEN +#ifndef mkdepbi_dep_ +#define mkdepbi_dep_ __attribute__((__deprecated__)) +#endif +#else /* !SHIM_DEPRECATE_STRLEN */ +#ifndef mkdepbi_dep_ +#define mkdepbi_dep_ +#endif +#endif /* SHIM_DEPRECATE_STRLEN */ + +#ifndef mkdepbi1_ +#define mkdepbi1_(rtype, x, typea, a) \ + static inline __attribute__((__unused__)) \ + mkdepbi_dep_ \ + rtype \ + x(typea a) \ + { \ + return mkbi_cat_(__builtin_, x)(a); \ + } +#endif + +#ifndef mkdepbi2_ +#define mkdepbi2_(rtype, x, typea, a, typeb, b) \ + static inline __attribute__((__unused__)) \ + mkdepbi_dep_ \ + rtype \ + x(typea a, typeb b) \ + { \ + return mkbi_cat_(__builtin_, x)(a, b); \ + } +#endif +#endif /* SHIM_STRING_C_ */ + +// vim:fenc=utf-8:tw=75:noet diff --git a/include/system/builtins_end_.h b/include/system/builtins_end_.h new file mode 100644 index 00000000..0a6ad60a --- /dev/null +++ b/include/system/builtins_end_.h @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: BSD-2-Clause-Patent + +#ifdef mkbi1_ +#undef mkbi1_ +#endif +#ifdef mkbi2_ +#undef mkbi2_ +#endif +#ifdef mkbi3_ +#undef mkbi3_ +#endif +#ifdef mkdepbi1_ +#undef mkdepbi1_ +#endif +#ifdef mkdepbi2_ +#undef mkdepbi2_ +#endif +#ifdef mkdepbi_dep_ +#undef mkdepbi_dep_ +#endif +#ifdef mkbi_cat_ +#undef mkbi_cat_ +#endif + +#ifdef _BUILTINS_BEGIN__H +#undef _BUILTINS_BEGIN__H +#endif +// vim:fenc=utf-8:tw=75:noet diff --git a/include/system/ctype.h b/include/system/ctype.h index c771bb69..65e7348f 100644 --- a/include/system/ctype.h +++ b/include/system/ctype.h @@ -3,11 +3,82 @@ * ctype.h - standard ctype functions */ #ifdef SHIM_UNIT_TEST -#include_next +#include_next #else #ifndef _CTYPE_H #define _CTYPE_H +#define isprint(c) ((c) >= 0x20 && (c) <= 0x7e) + +/* Determines if a particular character is a decimal-digit character */ +static inline __attribute__((__unused__)) int +isdigit(int c) +{ + // + // ::= [0-9] + // + return (('0' <= (c)) && ((c) <= '9')); +} + +/* Determine if an integer represents character that is a hex digit */ +static inline __attribute__((__unused__)) int +isxdigit(int c) +{ + // + // ::= [0-9] | [a-f] | [A-F] + // + return ((('0' <= (c)) && ((c) <= '9')) || + (('a' <= (c)) && ((c) <= 'f')) || + (('A' <= (c)) && ((c) <= 'F'))); +} + +/* Determines if a particular character represents a space character */ +static inline __attribute__((__unused__)) int +isspace(int c) +{ + // + // ::= [ ] + // + return ((c) == ' '); +} + +/* Determine if a particular character is an alphanumeric character */ +static inline __attribute__((__unused__)) int +isalnum(int c) +{ + // + // ::= [0-9] | [a-z] | [A-Z] + // + return ((('0' <= (c)) && ((c) <= '9')) || + (('a' <= (c)) && ((c) <= 'z')) || + (('A' <= (c)) && ((c) <= 'Z'))); +} + +/* Determines if a particular character is in upper case */ +static inline __attribute__((__unused__)) int +isupper(int c) +{ + // + // := [A-Z] + // + return (('A' <= (c)) && ((c) <= 'Z')); +} + +/* Convert character to lowercase */ +static inline __attribute__((__unused__)) int +tolower(int c) +{ + if (('A' <= (c)) && ((c) <= 'Z')) { + return (c - ('A' - 'a')); + } + return (c); +} + +static inline __attribute__((__unused__)) int +toupper(int c) +{ + return ((c >= 'a' && c <= 'z') ? c - ('a' - 'A') : c); +} #endif /* !_CTYPE_H */ #endif /* !SHIM_UNIT_TEST */ diff --git a/include/system/stdlib.h b/include/system/stdlib.h index f2660f63..da7d3af9 100644 --- a/include/system/stdlib.h +++ b/include/system/stdlib.h @@ -11,6 +11,18 @@ */ #include +static inline void abort(void) { } + +#include +mkbi1_(int, abs, int, j) +mkbi1_(long int, labs, long int, j) +mkbi1_(long long int, llabs, long long int, j) + +#ifdef _INTTYPES_H +mkbi1_(intmax_t, imaxabs, intmax_t, j) +#endif /* _INTTYPES_H */ +#include + #endif /* !_STDLIB_H */ #endif // vim:fenc=utf-8:tw=75:noet diff --git a/include/system/string.h b/include/system/string.h index 21e46c1d..822e28fa 100644 --- a/include/system/string.h +++ b/include/system/string.h @@ -7,8 +7,55 @@ #include -__typeof__(__builtin_memset) memset; -__typeof__(__builtin_memcpy) memcpy; +#include + +mkbi1_(long int, ffsl, long int, x) +mkbi1_(long int, clzl, long int, x) +mkbi1_(long int, ctzl, long int, x) +mkbi1_(long int, clrsbl, long int, x) +mkbi1_(long int, popcountl, long int, x) +mkbi1_(long int, parityl, long int, x) +mkbi1_(long long int, ffsll, long long int, x) +mkbi1_(long long int, clzll, long long int, x) +mkbi1_(long long int, ctzll, long long int, x) +mkbi1_(long long int, clrsbll, long long int, x) +mkbi1_(long long int, popcountll, long long int, x) +mkbi1_(long long int, parityll, long long int, x) + +mkbi3_(int, bcmp, const void *, s1, const void *, s2, size_t, n) +mkbi3_(void, bcopy, const void *, src, void *, dest, size_t, n) +mkbi2_(void, bzero, void *, s, size_t, n) +mkdepbi2_(char *, index, const char *, s, int, c) +mkbi3_(void *, memchr, const void *, s, int, c, size_t, n) +mkbi3_(int, memcmp, const void *, s1, const void *, s2, size_t, n) +mkbi3_(void *, memcpy, void *, dest, const void *, src, size_t, n) +mkbi3_(void *, memmove, void *, dest, const void *, src, size_t, n) +mkbi3_(void *, mempcpy, void *, dest, const void *, src, size_t, n) +mkdepbi2_(char *, rindex, const char *, s, int, c) +mkdepbi2_(char *, stpcpy, char *, dest, const char *, src) +mkbi3_(char *, stpncpy, char *, dest, const char *, src, size_t, n) +mkdepbi2_(int, strcasecmp, const char *, s1, const char *, s2) +mkdepbi2_(char *, strcat, char *, dest, const char *, src) +mkdepbi2_(char *, strchr, const char *, s, int, c) +mkdepbi2_(int, strcmp, const char *, s1, const char *, s2) +mkdepbi2_(char *, strcpy, char *, dest, const char *, src) +mkdepbi2_(size_t, strcspn, const char *, s, const char *, reject) +mkdepbi1_(char *, strdup, const char *, s) +mkbi2_(char *, strndup, const char *, s, size_t, n) +mkdepbi1_(size_t, strlen, const char *, s) +mkbi3_(int, strncasecmp, const char *, s1, const char *, s2, size_t, n) +mkbi3_(char *, strncat, char *, dest, const char *, src, size_t, n) +mkbi3_(int, strncmp, const char *, s1, const char *, s2, size_t, n) +mkbi3_(char *, strncpy, char *, dest, const char *, src, size_t, n) +mkbi2_(int, strnlen, const char *, s1, size_t, n) +mkdepbi2_(char *, strpbrk, const char *, s, const char *, accept) +mkdepbi2_(char *, strrchr, const char *, s, int, c) +mkdepbi2_(size_t, strspn, const char *, s, const char *, accept) +mkdepbi2_(char *, strstr, const char *, haystack, const char *, needle) + +mkbi3_(void *, memset, void *, s, int, c, size_t, n); + +#include #endif /* _STRING_H */ #endif diff --git a/include/system/strings.h b/include/system/strings.h index c82bd917..99bc05f2 100644 --- a/include/system/strings.h +++ b/include/system/strings.h @@ -5,6 +5,15 @@ #ifndef _STRINGS_H #define _STRINGS_H +#include +mkbi1_(int, ffs, int, x) +mkbi1_(int, clz, int, x) +mkbi1_(int, ctz, int, x) +mkbi1_(int, clrsb, int, x) +mkbi1_(int, popcount, int, x) +mkbi1_(int, parity, int, x) +#include + #endif /* !_STRINGS_H */ #endif // vim:fenc=utf-8:tw=75:noet diff --git a/lib/string.c b/lib/string.c new file mode 100644 index 00000000..1f58f3ec --- /dev/null +++ b/lib/string.c @@ -0,0 +1,245 @@ +// SPDX-License-Identifier: BSD-2-Clause-Patent +/* + * string.c - implementations we need for string finctions + */ +#define SHIM_STRING_C_ +#include "shim.h" + +size_t +strlen(const char *s1) +{ + size_t len; + + for (len = 0; *s1; s1 += 1, len += 1) + ; + return len; +} + +int +strcmp(const char *s1p, const char *s2p) +{ + const uint8_t *s1 = (const uint8_t *)s1p; + const uint8_t *s2 = (const uint8_t *)s2p; + + while (*s1) { + if (*s1 != *s2) { + break; + } + + s1 += 1; + s2 += 1; + } + + return *s1 - *s2; +} + +int +strncmp(const char *s1p, const char *s2p, size_t len) +{ + const uint8_t *s1 = (const uint8_t *)s1p; + const uint8_t *s2 = (const uint8_t *)s2p; + + while (*s1 && len) { + if (*s1 != *s2) { + break; + } + + s1 += 1; + s2 += 1; + len -= 1; + } + + return len ? *s1 - *s2 : 0; +} + +/* Based on AsciiStriCmp() in edk2 MdePkg/Library/BaseLib/String.c */ +int +strncasecmp(const char *s1p, const char *s2p, size_t n) +{ + const uint8_t *s1 = (const uint8_t *)s1p; + const uint8_t *s2 = (const uint8_t *)s2p; + + while (*s1 && n) { + if (toupper(*s1) != toupper(*s2)) { + break; + } + + s1 += 1; + s2 += 1; + n -= 1; + } + + return n ? *s1 - *s2 : 0; +} + +/* Based on AsciiStriCmp() in edk2 MdePkg/Library/BaseLib/String.c */ +int +strcasecmp(const char *str1, const char *str2) +{ + char c1, c2; + + c1 = toupper(*str1); + c2 = toupper(*str2); + while ((*str1 != '\0') && (c1 == c2)) { + str1++; + str2++; + c1 = toupper(*str1); + c2 = toupper(*str2); + } + + return c1 - c2; +} + +/* Scan a string for the last occurrence of a character */ +char * +strrchr(const char *str, int c) +{ + char *save; + + for (save = NULL;; ++str) { + if (*str == c) { + save = (char *)str; + } + if (*str == 0) { + return (save); + } + } +} + +NONNULL(1) +size_t +strnlen(const char *s, size_t n) +{ + size_t i; + for (i = 0; i < n; i++) + if (s[i] == '\0') + break; + return i; +} + +RETURNS_NONNULL NONNULL(1, 2) +char * +strcpy(char *dest, const char *src) +{ + size_t i; + + for (i = 0; src[i] != '\0'; i++) + dest[i] = src[i]; + + dest[i] = '\0'; + return dest; +} + +RETURNS_NONNULL NONNULL(1, 2) +char * +strncpy(char *dest, const char *src, size_t n) +{ + size_t i; + + for (i = 0; i < n && src[i] != '\0'; i++) + dest[i] = src[i]; + for (; i < n; i++) + dest[i] = '\0'; + + return dest; +} + +RETURNS_NONNULL NONNULL(1, 2) +char * +strcat(char *dest, const char *src) +{ + size_t dest_len = strlen(dest); + size_t i; + + for (i = 0; src[i] != '\0'; i++) + dest[dest_len + i] = src[i]; + dest[dest_len + i] = '\0'; + + return dest; +} + +NONNULL(1) +char * +strdup(const char *const src) +{ + size_t len; + char *news = NULL; + + len = strlen(src); + news = AllocateZeroPool(len + 1); + if (news) + strncpy(news, src, len); + return news; +} + +NONNULL(1) +char * +strndup(const char *const src, const size_t srcmax) +{ + size_t len; + char *news = NULL; + + len = strnlen(src, srcmax); + news = AllocateZeroPool(len + 1); + if (news) + strncpy(news, src, len); + return news; +} + +RETURNS_NONNULL NONNULL(1, 2) +char * +stpcpy(char *dest, const char *const src) +{ + size_t i = 0; + for (i = 0; src[i]; i++) + dest[i] = src[i]; + dest[i] = '\000'; + return &dest[i]; +} + +RETURNS_NONNULL NONNULL(1) +char * +strchrnul(const char *s, int c) +{ + unsigned int i; + + for (i = 0; s[i] != '\000' && s[i] != c; i++) + ; + + return (char *)&s[i]; +} + +NONNULL(1) +char * +strchr(const char *s, int c) +{ + const char *s1; + + s1 = strchrnul(s, c); + if (!s1 || s1[0] == '\000') + return NULL; + + return (char *)s1; +} + +char * +translate_slashes(char *out, const char *str) +{ + int i; + int j; + if (str == NULL || out == NULL) + return NULL; + + for (i = 0, j = 0; str[i] != '\0'; i++, j++) { + if (str[i] == '\\') { + out[j] = '/'; + if (str[i + 1] == '\\') + i++; + } else + out[j] = str[i]; + } + out[j] = '\0'; + return out; +} + +// vim:fenc=utf-8:tw=75:noet diff --git a/mok.c b/mok.c index 6bd506be..be477c48 100644 --- a/mok.c +++ b/mok.c @@ -1013,7 +1013,7 @@ EFI_STATUS import_mok_state(EFI_HANDLE image_handle) struct mok_state_variable *v = &mok_state_variables[i]; ZeroMem(&config_template, sizeof(config_template)); - strncpya(config_template.name, (CHAR8 *)v->rtname8, 255); + strncpy(config_template.name, (CHAR8 *)v->rtname8, 255); config_template.name[255] = '\0'; config_template.data_size = v->data_size; diff --git a/netboot.c b/netboot.c index 450e9def..3f5c5198 100644 --- a/netboot.c +++ b/netboot.c @@ -172,7 +172,7 @@ static BOOLEAN extract_tftp_info(CHAR8 *url) // to check against str2ip6() errors memset(ip6inv, 0, sizeof(ip6inv)); - if (strncmp((UINT8 *)url, (UINT8 *)"tftp://", 7)) { + if (strncmp((const char *)url, (const char *)"tftp://", 7)) { console_print(L"URLS MUST START WITH tftp://\n"); return FALSE; } @@ -258,7 +258,7 @@ static EFI_STATUS parseDhcp4() pkt_v4 = &pxe->Mode->PxeReply.Dhcpv4; } - INTN dir_len = strnlena((CHAR8 *)pkt_v4->BootpBootFile, 127); + INTN dir_len = strnlen((CHAR8 *)pkt_v4->BootpBootFile, 127); INTN i; UINT8 *dir = pkt_v4->BootpBootFile; @@ -274,13 +274,13 @@ static EFI_STATUS parseDhcp4() return EFI_OUT_OF_RESOURCES; if (dir_len > 0) { - strncpya(full_path, (CHAR8 *)dir, dir_len); + strncpy(full_path, (CHAR8 *)dir, dir_len); if (full_path[dir_len-1] == '/' && template[0] == '/') full_path[dir_len-1] = '\0'; } if (dir_len == 0 && dir[0] != '/' && template[0] == '/') template_ofs++; - strcata(full_path, template + template_ofs); + strcat(full_path, template + template_ofs); memcpy(&tftp_addr.v4, pkt_v4->BootpSiAddr, 4); return EFI_SUCCESS; diff --git a/sbat.c b/sbat.c index d8750962..fec22a73 100644 --- a/sbat.c +++ b/sbat.c @@ -48,7 +48,7 @@ parse_sbat_section(char *section_base, size_t section_size, efi_status = EFI_INVALID_PARAMETER; goto err; } - allocsz += strlena(row->columns[i]) + 1; + allocsz += strlen(row->columns[i]) + 1; } n++; } @@ -226,7 +226,7 @@ parse_sbat_var_data(list_t *entry_list, UINT8 *data, UINTN datasize) efi_status = EFI_INVALID_PARAMETER; goto err; } - allocsz += strlena(row->columns[i]) + 1; + allocsz += strlen(row->columns[i]) + 1; } n++; } diff --git a/shim.h b/shim.h index 61dafa82..3d2ac2d4 100644 --- a/shim.h +++ b/shim.h @@ -259,4 +259,6 @@ verify_buffer (char *data, int datasize, #define LogError(fmt, ...) #endif +char *translate_slashes(char *out, const char *str); + #endif /* SHIM_H_ */ -- cgit v1.2.3 From 4033d1fd0f25196f9a35e944679676277cd51960 Mon Sep 17 00:00:00 2001 From: Alex Burmashev Date: Wed, 10 Mar 2021 08:49:54 -0500 Subject: Fix compilation for older gcc Signed-off-by: Alex Burmashev --- Make.defaults | 2 +- include/compiler.h | 4 ++++ include/str.h | 2 ++ include/system/string.h | 6 +++++- shim.c | 2 +- 5 files changed, 13 insertions(+), 3 deletions(-) (limited to 'include/compiler.h') diff --git a/Make.defaults b/Make.defaults index 20aa8cd4..95c24914 100644 --- a/Make.defaults +++ b/Make.defaults @@ -107,7 +107,7 @@ override DEFAULT_FEATUREFLAGS = \ -std=gnu11 \ -ggdb \ -ffreestanding \ - -fmacro-prefix-map='$(TOPDIR)/=$(DEBUGSRC)' \ + $(shell $(CC) -fmacro-prefix-map=./=./ -E -x c /dev/null >/dev/null 2>&1 && echo -fmacro-prefix-map='$(TOPDIR)/=$(DEBUGSRC)') \ -fno-stack-protector \ -fno-strict-aliasing \ -fpic \ diff --git a/include/compiler.h b/include/compiler.h index 40358a11..18576724 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -18,7 +18,11 @@ # define RETURNS_NONNULL #else # define NONNULL(first, args...) __attribute__((__nonnull__(first, ## args))) +#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))) # define RETURNS_NONNULL __attribute__((__returns_nonnull__)) +#else +# define RETURNS_NONNULL +#endif #endif #ifndef UNUSED diff --git a/include/str.h b/include/str.h index 189aceff..d433e6ec 100644 --- a/include/str.h +++ b/include/str.h @@ -3,11 +3,13 @@ #ifndef SHIM_STR_H #define SHIM_STR_H +#if __GNUC__ > 6 #ifdef SHIM_UNIT_TEST #pragma GCC diagnostic error "-Wnonnull-compare" #else #pragma GCC diagnostic ignored "-Wnonnull-compare" #endif +#endif static inline UNUSED RETURNS_NONNULL NONNULL(1) char * diff --git a/include/system/string.h b/include/system/string.h index 66e7d93e..2b366df7 100644 --- a/include/system/string.h +++ b/include/system/string.h @@ -64,7 +64,11 @@ mkbi3_(int, strncasecmp, const char *, s1, const char *, s2, size_t, n) mkbi3_(char *, strncat, char *, dest, const char *, src, size_t, n) mkbi3_(int, strncmp, const char *, s1, const char *, s2, size_t, n) mkbi3_(char *, strncpy, char *, dest, const char *, src, size_t, n) -mkbi2_(int, strnlen, const char *, s1, size_t, n) +#if defined(__GNUC__) && __GNUC__ >= 9 +mkbi2_(size_t, strnlen, const char *, s1, size_t, n) +#else +size_t strnlen(const char * s1, size_t n); +#endif mkdepbi2_(char *, strpbrk, const char *, s, const char *, accept) mkdepbi2_(char *, strrchr, const char *, s, int, c) mkdepbi2_(size_t, strspn, const char *, s, const char *, accept) diff --git a/shim.c b/shim.c index 6f627b1f..fd4c0322 100644 --- a/shim.c +++ b/shim.c @@ -1095,7 +1095,7 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath) void *sourcebuffer = NULL; UINT64 sourcesize = 0; void *data = NULL; - int datasize; + int datasize = 0; /* * We need to refer to the loaded image protocol on the running -- cgit v1.2.3 From aa61fdf490d16aaa23de0cbe5e9f16d3bc72e582 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Thu, 19 May 2022 15:55:40 -0400 Subject: Give the Coverity scanner some more GCC blinders... Coverity complains: CID 373676 (#3 of 3): Unrecoverable parse warning (PARSE_ERROR) 1. arguments_provided_for_attribute: attribute "__malloc__" does not take arguments This is, of course, just plain wrong. Even so, I'm tired of looking at it, so this patch wraps the #define we use for that attribute in a check to see if it's being built by Coverity. Signed-off-by: Peter Jones --- include/compiler.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/compiler.h') diff --git a/include/compiler.h b/include/compiler.h index 18576724..b4bf1031 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -47,8 +47,12 @@ #define ALIAS(x) __attribute__((weak, alias (#x))) #endif #ifndef ALLOCFUNC +#if defined(__COVERITY__) +#define ALLOCFUNC(a, b) +#else #define ALLOCFUNC(dealloc, dealloc_arg) __attribute__((__malloc__(dealloc, dealloc_arg))) #endif +#endif #ifndef PRINTF #define PRINTF(first, args...) __attribute__((__format__(printf, first, ## args))) #endif -- cgit v1.2.3 From 5c537b3d0cf8c393dad2e61d49aade68f3af1401 Mon Sep 17 00:00:00 2001 From: dann frazier Date: Tue, 6 Sep 2022 09:28:22 -0600 Subject: shim: Flush the memory region from i-cache before execution We've seen crashes in early GRUB code on an ARM Cortex-A72-based platform that point at seemingly harmless instructions. Flushing the i-cache of those instructions prior to executing has been shown to avoid the problem, which has parallels with this story: https://www.mail-archive.com/osv-dev@googlegroups.com/msg06203.html Add a cache flushing utility function and provide an implementation using a GCC intrinsic. This will need to be extended to support other compilers. Note that this intrinsic is a no-op for x86 platforms. This fixes issue #498. Signed-off-by: dann frazier --- include/compiler.h | 6 ++++++ pe.c | 3 +++ 2 files changed, 9 insertions(+) (limited to 'include/compiler.h') diff --git a/include/compiler.h b/include/compiler.h index b4bf1031..b0d595f3 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -192,5 +192,11 @@ */ #define unreachable() __builtin_unreachable() +#if defined(__GNUC__) +#define cache_invalidate(begin, end) __builtin___clear_cache(begin, end) +#else /* __GNUC__ */ +#error shim has no cache_invalidate() implementation for this compiler +#endif /* __GNUC__ */ + #endif /* !COMPILER_H_ */ // vim:fenc=utf-8:tw=75:et diff --git a/pe.c b/pe.c index ba3e2bbc..f94530a2 100644 --- a/pe.c +++ b/pe.c @@ -1196,6 +1196,9 @@ handle_image (void *data, unsigned int datasize, CopyMem(buffer, data, context.SizeOfHeaders); + /* Flush the instruction cache for the region holding the image */ + cache_invalidate(buffer, buffer + context.ImageSize); + *entry_point = ImageAddress(buffer, context.ImageSize, context.EntryPoint); if (!*entry_point) { perror(L"Entry point is invalid\n"); -- cgit v1.2.3 From f27182695d88350b48c8b9a6dce54bb513d7aa4e Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Thu, 27 Jul 2023 15:13:08 -0400 Subject: Add primitives for overflow-checked arithmetic operations. We need to do arithmetic on untrusted values sometimes, so this patch adds the following primitives as macros that wrap the compiler builtins. bool checked_add(TYPE addend0, TYPE addend1, TYPE *sum) bool checked_sub(TYPE minuend, TYPE subtrahend, TYPE *difference) bool checked_mul(TYPE factor0, TYPE factor1, TYPE *product) And also the following primitive which returns True if divisor is 0 and False otherwise: bool checked_div(TYPE dividend, TYPE divisor, TYPE *quotient) Signed-off-by: Peter Jones --- include/compiler.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'include/compiler.h') diff --git a/include/compiler.h b/include/compiler.h index b0d595f3..545a72e5 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -198,5 +198,21 @@ #error shim has no cache_invalidate() implementation for this compiler #endif /* __GNUC__ */ +#define checked_add(addend0, addend1, sum) \ + __builtin_add_overflow(addend0, addend1, sum) +#define checked_sub(minuend, subtrahend, difference) \ + __builtin_sub_overflow(minuend, subtrahend, difference) +#define checked_mul(factor0, factor1, product) \ + __builtin_mul_overflow(factor0, factor1, product) +#define checked_div(dividend, divisor, quotient) \ + ({ \ + bool _ret = True; \ + if ((divisor) != 0) { \ + _ret = False; \ + (quotient) = (dividend) / (divisor); \ + } \ + _ret; \ + }) + #endif /* !COMPILER_H_ */ // vim:fenc=utf-8:tw=75:et -- cgit v1.2.3 From 13abd9f51b285db7eb46bf375cae623bf1153404 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Wed, 6 Dec 2023 17:07:01 -0500 Subject: pe-relocate: Avoid __builtin_add_overflow() on GCC < 5 GCC 4 doesn't have __builtin_add_overflow() and friends, so this results in a compiler error. On platforms using that version, do the arithmetic without it. Signed-off-by: Peter Jones --- include/compiler.h | 34 ++++++++++++++++++++++++++++++++++ pe-relocate.c | 2 +- 2 files changed, 35 insertions(+), 1 deletion(-) (limited to 'include/compiler.h') diff --git a/include/compiler.h b/include/compiler.h index 545a72e5..8e8a658d 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -198,12 +198,46 @@ #error shim has no cache_invalidate() implementation for this compiler #endif /* __GNUC__ */ +#if defined(__GNUC__) && defined(__GNUC_MINOR__) +#define GNUC_PREREQ(maj, min) \ + ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) +#else +#define GNUC_PREREQ(maj, min) 0 +#endif + +#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__) +#define CLANG_PREREQ(maj, min) \ + ((__clang_major__ > (maj)) || \ + (__clang_major__ == (maj) && __clang_minor__ >= (min))) +#else +#define CLANG_PREREQ(maj, min) 0 +#endif + +#if GNUC_PREREQ(5, 1) || CLANG_PREREQ(3, 8) #define checked_add(addend0, addend1, sum) \ __builtin_add_overflow(addend0, addend1, sum) #define checked_sub(minuend, subtrahend, difference) \ __builtin_sub_overflow(minuend, subtrahend, difference) #define checked_mul(factor0, factor1, product) \ __builtin_mul_overflow(factor0, factor1, product) +#else +#define checked_add(a0, a1, s) \ + ({ \ + (*s) = ((a0) + (a1)); \ + 0; \ + }) +#define checked_sub(s0, s1, d) \ + ({ \ + (*d) = ((s0) - (s1)); \ + 0; \ + }) +#define checked_mul(f0, f1, p) \ + ({ \ + (*p) = ((f0) * (f1)); \ + 0; \ + }) +#endif + #define checked_div(dividend, divisor, quotient) \ ({ \ bool _ret = True; \ diff --git a/pe-relocate.c b/pe-relocate.c index d399cdf1..bde71729 100644 --- a/pe-relocate.c +++ b/pe-relocate.c @@ -20,7 +20,7 @@ ImageAddress (void *image, uint64_t size, uint64_t address) /* Insure our math won't overflow */ img_addr = (uintptr_t)image; - if (__builtin_add_overflow(img_addr, address, &img_addr)) + if (checked_add(img_addr, address, &img_addr)) return NULL; /* return the absolute pointer */ -- cgit v1.2.3 From 5f541823991d26f80f66f6e8e188c7cb246fe316 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 17 Dec 2024 11:00:07 -0500 Subject: includes: work around CLANG_PREREQ() double-definition Right now when doing test builds with clang, we wind up getting an error from two different definitions of CLANG_PREREQ() in the headers. It might be that we can just rip one of these out, but for now I'm just making one of them conditional. Signed-off-by: Peter Jones --- include/compiler.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/compiler.h') diff --git a/include/compiler.h b/include/compiler.h index 8e8a658d..982bc235 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -205,6 +205,7 @@ #define GNUC_PREREQ(maj, min) 0 #endif +#if !defined(CLANG_PREREQ) #if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__) #define CLANG_PREREQ(maj, min) \ ((__clang_major__ > (maj)) || \ @@ -212,6 +213,7 @@ #else #define CLANG_PREREQ(maj, min) 0 #endif +#endif /* CLANG_PREREQ */ #if GNUC_PREREQ(5, 1) || CLANG_PREREQ(3, 8) #define checked_add(addend0, addend1, sum) \ -- cgit v1.2.3 From 765f2944fb392be2e8f76f3503ae7ceab301fea4 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Thu, 27 Jun 2024 15:16:18 -0400 Subject: compiler.h: minor ALIGN_... fixes This fixes some minor errors with the testing of how ALIGN() and similar are defined, and makes an explicit "ALIGN_UP()" macro to complement the existing ALIGN_DOWN() macro. Signed-off-by: Peter Jones --- include/compiler.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'include/compiler.h') diff --git a/include/compiler.h b/include/compiler.h index 982bc235..6a19217c 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -175,14 +175,19 @@ #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg) #endif -#ifndef ALIGN +#ifndef __ALIGN #define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) #define __ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a) - 1) +#endif +#ifndef ALIGN #define ALIGN(x, a) __ALIGN((x), (a)) #endif #ifndef ALIGN_DOWN #define ALIGN_DOWN(x, a) __ALIGN((x) - ((a) - 1), (a)) #endif +#ifndef ALIGN_UP +#define ALIGN_UP(addr, align) (((addr) + (typeof (addr)) (align) - 1) & ~((typeof (addr)) (align) - 1)) +#endif #define MIN(a, b) ({(a) < (b) ? (a) : (b);}) #define MAX(a, b) ({(a) <= (b) ? (b) : (a);}) -- cgit v1.2.3