diff options
Diffstat (limited to 'include/test.h')
| -rw-r--r-- | include/test.h | 525 |
1 files changed, 475 insertions, 50 deletions
diff --git a/include/test.h b/include/test.h index 012ffc51..5261dbd9 100644 --- a/include/test.h +++ b/include/test.h @@ -8,7 +8,14 @@ #ifndef TEST_H_ #define TEST_H_ +#define _GNU_SOURCE + #include <stdarg.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> #if defined(__aarch64__) #include <aarch64/efibind.h> @@ -36,17 +43,368 @@ #include <stdlib.h> -#define ZeroMem(buf, sz) memset(buf, 0, sz) -#define SetMem(buf, sz, value) memset(buf, value, sz) -#define CopyMem(dest, src, len) memcpy(dest, src, len) -#define CompareMem(dest, src, len) memcmp(dest, src, len) +#include <assert.h> + +#include <efiui.h> +#include <efilib.h> + +#include <efivar/efivar.h> #include <assert.h> -#define AllocateZeroPool(x) calloc(1, (x)) -#define AllocatePool(x) malloc(x) -#define FreePool(x) free(x) -#define ReallocatePool(old, oldsz, newsz) realloc(old, newsz) +#include "list.h" + +INTN StrCmp(IN CONST CHAR16 *s1, + IN CONST CHAR16 *s2); +INTN StrnCmp(IN CONST CHAR16 *s1, + IN CONST CHAR16 *s2, + IN UINTN len); +VOID StrCpy(IN CHAR16 *Dest, + IN CONST CHAR16 *Src); +VOID StrnCpy(IN CHAR16 *Dest, + IN CONST CHAR16 *Src, + IN UINTN Len); +CHAR16 *StrDuplicate(IN CONST CHAR16 *Src); +UINTN StrLen(IN CONST CHAR16 *s1); +UINTN StrSize(IN CONST CHAR16 *s1); +VOID StrCat(IN CHAR16 *Dest, IN CONST CHAR16 *Src); +CHAR16 *DevicePathToStr(EFI_DEVICE_PATH *DevPath); + +extern EFI_SYSTEM_TABLE *ST; +extern EFI_BOOT_SERVICES *BS; +extern EFI_RUNTIME_SERVICES *RT; + +#define GUID_FMT "%08x-%04hx-%04hx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx" +#define GUID_ARGS(guid) \ + ((EFI_GUID)guid).Data1, ((EFI_GUID)guid).Data2, ((EFI_GUID)guid).Data3, \ + ((EFI_GUID)guid).Data4[1], ((EFI_GUID)guid).Data4[0], \ + ((EFI_GUID)guid).Data4[2], ((EFI_GUID)guid).Data4[3], \ + ((EFI_GUID)guid).Data4[4], ((EFI_GUID)guid).Data4[5], \ + ((EFI_GUID)guid).Data4[6], ((EFI_GUID)guid).Data4[7] + +static inline INT64 +guidcmp_helper(const EFI_GUID * const guid0, const EFI_GUID * const guid1) +{ +#if (defined(SHIM_DEBUG) && SHIM_DEBUG != 0) + printf("%s:%d:%s(): Comparing "GUID_FMT" to "GUID_FMT"\n", + __FILE__, __LINE__-1, __func__, + GUID_ARGS(*guid0), GUID_ARGS(*guid1)); +#endif + + if (guid0->Data1 != guid1->Data1) { +#if (defined(SHIM_DEBUG) && SHIM_DEBUG != 0) + printf("%s:%d:%s(): returning 0x%"PRIx64"-0x%"PRIx64"->0x%"PRIx64"\n", + __FILE__, __LINE__-1, __func__, + (INT64)guid0->Data1, (INT64)guid1->Data1, + (INT64)guid0->Data1 - (INT64)guid1->Data1); +#endif + return (INT64)guid0->Data1 - (INT64)guid1->Data1; + } + + if (guid0->Data2 != guid1->Data2) { +#if (defined(SHIM_DEBUG) && SHIM_DEBUG != 0) + printf("%s:%d:%s(): returning 0x%"PRIx64"-0x%"PRIx64"->0x%"PRIx64"\n", + __FILE__, __LINE__-1, __func__, + (INT64)guid0->Data2, (INT64)guid1->Data2, + (INT64)guid0->Data2 - (INT64)guid1->Data2); +#endif + return (INT64)guid0->Data2 - (INT64)guid1->Data2; + } + + if (guid0->Data3 != guid1->Data3) { +#if (defined(SHIM_DEBUG) && SHIM_DEBUG != 0) + printf("%s:%d:%s(): returning 0x%"PRIx64"-0x%"PRIx64"->0x%"PRIx64"\n", + __FILE__, __LINE__-1, __func__, + (INT64)guid0->Data3, (INT64)guid1->Data3, + (INT64)guid0->Data3 - (INT64)guid1->Data3); +#endif + return (INT64)guid0->Data3 - (INT64)guid1->Data3; + } + + /* + * This is out of order because that's also true in the string + * representation of it. + */ + if (guid0->Data4[1] != guid1->Data4[1]) { +#if (defined(SHIM_DEBUG) && SHIM_DEBUG != 0) + printf("%s:%d:%s(): returning 0x%"PRIx64"-0x%"PRIx64"->0x%"PRIx64"\n", + __FILE__, __LINE__-1, __func__, + (INT64)guid0->Data4[1], (INT64)guid1->Data4[1], + (INT64)guid0->Data4[1] - (INT64)guid1->Data4[1]); +#endif + return (INT64)guid0->Data4[1] - (INT64)guid1->Data4[1]; + } + + if (guid0->Data4[0] != guid1->Data4[0]) { +#if (defined(SHIM_DEBUG) && SHIM_DEBUG != 0) + printf("%s:%d:%s(): returning 0x%"PRIx64"-0x%"PRIx64"->0x%"PRIx64"\n", + __FILE__, __LINE__-1, __func__, + (INT64)guid0->Data4[0], (INT64)guid1->Data4[0], + (INT64)guid0->Data4[0] - (INT64)guid1->Data4[0]); +#endif + return (INT64)guid0->Data4[0] - (INT64)guid1->Data4[0]; + } + + for (UINTN i = 2; i < 8; i++) { + if (guid0->Data4[i] != guid1->Data4[i]) { +#if (defined(SHIM_DEBUG) && SHIM_DEBUG != 0) + printf("%s:%d:%s(): returning 0x%"PRIx64"-0x%"PRIx64"->0x%"PRIx64"\n", + __FILE__, __LINE__-1, __func__, + (INT64)guid0->Data4[i], (INT64)guid1->Data4[i], + (INT64)guid0->Data4[i] - (INT64)guid1->Data4[i]); +#endif + return (INT64)guid0->Data4[i] - (INT64)guid1->Data4[i]; + } + } + +#if (defined(SHIM_DEBUG) && SHIM_DEBUG != 0) + printf("%s:%d:%s(): returning 0x0\n", + __FILE__, __LINE__-1, __func__); +#endif + return 0; +} + +static inline int +guidcmp(const EFI_GUID * const guid0, const EFI_GUID * const guid1) +{ + INT64 cmp; + int ret; + EFI_GUID empty; + const EFI_GUID * const guida = guid0 ? guid0 : ∅ + const EFI_GUID * const guidb = guid1 ? guid1 : ∅ + + SetMem(&empty, sizeof(EFI_GUID), 0); + + cmp = guidcmp_helper(guida, guidb); + ret = cmp < 0 ? -1 : (cmp > 0 ? 1 : 0); +#if (defined(SHIM_DEBUG) && SHIM_DEBUG != 0) + printf("%s:%d:%s():CompareGuid("GUID_FMT","GUID_FMT")->%lld (%d)\n", + __FILE__, __LINE__-1, __func__, + GUID_ARGS(*guida), GUID_ARGS(*guidb), cmp, ret); +#endif + return ret; +} + +#define CompareGuid(a, b) guidcmp(a, b) + +static inline char * +efi_strerror(EFI_STATUS status) +{ + static char buf0[1024]; + static char buf1[1024]; + char *out; + static int n; + + out = n++ % 2 ? buf0 : buf1; + if (n > 1) + n -= 2; + SetMem(out, 1024, 0); + + switch (status) { + case EFI_SUCCESS: + strcpy(out, "EFI_SUCCESS"); + break; + case EFI_LOAD_ERROR: + strcpy(out, "EFI_LOAD_ERROR"); + break; + case EFI_INVALID_PARAMETER: + strcpy(out, "EFI_INVALID_PARAMETER"); + break; + case EFI_UNSUPPORTED: + strcpy(out, "EFI_UNSUPPORTED"); + break; + case EFI_BAD_BUFFER_SIZE: + strcpy(out, "EFI_BAD_BUFFER_SIZE"); + break; + case EFI_BUFFER_TOO_SMALL: + strcpy(out, "EFI_BUFFER_TOO_SMALL"); + break; + case EFI_NOT_READY: + strcpy(out, "EFI_NOT_READY"); + break; + case EFI_DEVICE_ERROR: + strcpy(out, "EFI_DEVICE_ERROR"); + break; + case EFI_WRITE_PROTECTED: + strcpy(out, "EFI_WRITE_PROTECTED"); + break; + case EFI_OUT_OF_RESOURCES: + strcpy(out, "EFI_OUT_OF_RESOURCES"); + break; + case EFI_VOLUME_CORRUPTED: + strcpy(out, "EFI_VOLUME_CORRUPTED"); + break; + case EFI_VOLUME_FULL: + strcpy(out, "EFI_VOLUME_FULL"); + break; + case EFI_NO_MEDIA: + strcpy(out, "EFI_NO_MEDIA"); + break; + case EFI_MEDIA_CHANGED: + strcpy(out, "EFI_MEDIA_CHANGED"); + break; + case EFI_NOT_FOUND: + strcpy(out, "EFI_NOT_FOUND"); + break; + case EFI_ACCESS_DENIED: + strcpy(out, "EFI_ACCESS_DENIED"); + break; + case EFI_NO_RESPONSE: + strcpy(out, "EFI_NO_RESPONSE"); + break; + case EFI_NO_MAPPING: + strcpy(out, "EFI_NO_MAPPING"); + break; + case EFI_TIMEOUT: + strcpy(out, "EFI_TIMEOUT"); + break; + case EFI_NOT_STARTED: + strcpy(out, "EFI_NOT_STARTED"); + break; + case EFI_ALREADY_STARTED: + strcpy(out, "EFI_ALREADY_STARTED"); + break; + case EFI_ABORTED: + strcpy(out, "EFI_ABORTED"); + break; + case EFI_ICMP_ERROR: + strcpy(out, "EFI_ICMP_ERROR"); + break; + case EFI_TFTP_ERROR: + strcpy(out, "EFI_TFTP_ERROR"); + break; + case EFI_PROTOCOL_ERROR: + strcpy(out, "EFI_PROTOCOL_ERROR"); + break; + case EFI_INCOMPATIBLE_VERSION: + strcpy(out, "EFI_INCOMPATIBLE_VERSION"); + break; + case EFI_SECURITY_VIOLATION: + strcpy(out, "EFI_SECURITY_VIOLATION"); + break; + case EFI_CRC_ERROR: + strcpy(out, "EFI_CRC_ERROR"); + break; + case EFI_END_OF_MEDIA: + strcpy(out, "EFI_END_OF_MEDIA"); + break; + case EFI_END_OF_FILE: + strcpy(out, "EFI_END_OF_FILE"); + break; + case EFI_INVALID_LANGUAGE: + strcpy(out, "EFI_INVALID_LANGUAGE"); + break; + case EFI_COMPROMISED_DATA: + strcpy(out, "EFI_COMPROMISED_DATA"); + break; + default: + sprintf(out, "0x%lx", status); + break; + } + return out; +} + +static inline char * +Str2str(CHAR16 *in) +{ + static char buf0[1024]; + static char buf1[1024]; + char *out; + static int n; + + out = n++ % 2 ? buf0 : buf1; + if (n > 1) + n -= 2; + SetMem(out, 1024, 0); + for (UINTN i = 0; i < 1023 && in[i]; i++) + out[i] = in[i]; + return out; +} + +static inline char * +format_var_attrs(UINT32 attr) +{ + static char buf0[1024]; + static char buf1[1024]; + static int n; + int pos = 0; + bool found = false; + char *buf, *bufp; + + buf = n++ % 2 ? buf0 : buf1; + if (n > 1) + n -= 2; + SetMem(buf, sizeof(buf0), 0); + bufp = &buf[0]; + for (UINT32 i = 0; i < 8; i++) { + switch((1ul << i) & attr) { + case EFI_VARIABLE_NON_VOLATILE: + if (found) + bufp = stpcpy(bufp, "|"); + bufp = stpcpy(bufp, "NV"); + attr &= ~EFI_VARIABLE_NON_VOLATILE; + found = true; + break; + case EFI_VARIABLE_BOOTSERVICE_ACCESS: + if (found) + bufp = stpcpy(bufp, "|"); + bufp = stpcpy(bufp, "BS"); + attr &= ~EFI_VARIABLE_BOOTSERVICE_ACCESS; + found = true; + break; + case EFI_VARIABLE_RUNTIME_ACCESS: + if (found) + bufp = stpcpy(bufp, "|"); + bufp = stpcpy(bufp, "RT"); + attr &= ~EFI_VARIABLE_RUNTIME_ACCESS; + found = true; + break; + case EFI_VARIABLE_HARDWARE_ERROR_RECORD: + if (found) + bufp = stpcpy(bufp, "|"); + bufp = stpcpy(bufp, "HER"); + attr &= ~EFI_VARIABLE_HARDWARE_ERROR_RECORD; + found = true; + break; + case EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS: + if (found) + bufp = stpcpy(bufp, "|"); + bufp = stpcpy(bufp, "AUTH"); + attr &= ~EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS; + found = true; + break; + case EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS: + if (found) + bufp = stpcpy(bufp, "|"); + bufp = stpcpy(bufp, "TIMEAUTH"); + attr &= ~EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS; + found = true; + break; + case EFI_VARIABLE_APPEND_WRITE: + if (found) + bufp = stpcpy(bufp, "|"); + bufp = stpcpy(bufp, "APPEND"); + attr &= ~EFI_VARIABLE_APPEND_WRITE; + found = true; + break; + case EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS: + if (found) + bufp = stpcpy(bufp, "|"); + bufp = stpcpy(bufp, "ENHANCED_AUTH"); + attr &= ~EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS; + found = true; + break; + default: + break; + } + } + if (attr) { + if (found) + bufp = stpcpy(bufp, "|"); + snprintf(bufp, bufp - buf - 1, "0x%x", attr); + } + return &buf[0]; +} extern int debug; #ifdef dprint @@ -54,6 +412,14 @@ extern int debug; #define dprint(fmt, ...) {( if (debug) printf("%s:%d:" fmt, __func__, __LINE__, ##__VA_ARGS__); }) #endif +void EFIAPI mock_efi_void(); +EFI_STATUS EFIAPI mock_efi_success(); +EFI_STATUS EFIAPI mock_efi_unsupported(); +EFI_STATUS EFIAPI mock_efi_not_found(); +void init_efi_system_table(void); +void reset_efi_system_table(void); +void print_traceback(int skip); + #define eassert(cond, fmt, ...) \ ({ \ if (!(cond)) { \ @@ -63,24 +429,24 @@ extern int debug; assert(cond); \ }) -#define assert_true_as_expr(a, status, fmt, ...) \ - ({ \ - int rc_ = 0; \ - if (!(a)) { \ - printf("%s:%d:got %lld, expected nonzero " fmt, \ - __func__, __LINE__, (long long)(a), \ - ##__VA_ARGS__); \ - printf("%s:%d:Assertion `%s' failed.\n", __func__, \ - __LINE__, __stringify(!(a))); \ - rc_ = status; \ - } \ - rc_; \ +#define assert_true_as_expr(a, status, fmt, ...) \ + ({ \ + __typeof__(status) rc_ = 0; \ + if (!(a)) { \ + printf("%s:%d:got %lld, expected nonzero " fmt, \ + __func__, __LINE__, (long long)(uintptr_t)(a), \ + ##__VA_ARGS__); \ + printf("%s:%d:Assertion `%s' failed.\n", __func__, \ + __LINE__, __stringify(!(a))); \ + rc_ = status; \ + } \ + rc_; \ }) #define assert_nonzero_as_expr(a, ...) assert_true_as_expr(a, ##__VA_ARGS__) #define assert_false_as_expr(a, status, fmt, ...) \ ({ \ - int rc_ = 0; \ + __typeof__(status) rc_ = (__typeof__(status))0; \ if (a) { \ printf("%s:%d:got %lld, expected zero " fmt, __func__, \ __LINE__, (long long)(a), ##__VA_ARGS__); \ @@ -94,7 +460,7 @@ extern int debug; #define assert_positive_as_expr(a, status, fmt, ...) \ ({ \ - int rc_ = 0; \ + __typeof__(status) rc_ = (__typeof__(status))0; \ if ((a) <= 0) { \ printf("%s:%d:got %lld, expected > 0 " fmt, __func__, \ __LINE__, (long long)(a), ##__VA_ARGS__); \ @@ -107,7 +473,7 @@ extern int debug; #define assert_negative_as_expr(a, status, fmt, ...) \ ({ \ - int rc_ = 0; \ + __typeof__(status) rc_ = (__typeof__(status))0; \ if ((a) >= 0) { \ printf("%s:%d:got %lld, expected < 0 " fmt, __func__, \ __LINE__, (long long)(a), ##__VA_ARGS__); \ @@ -120,7 +486,7 @@ extern int debug; #define assert_equal_as_expr(a, b, status, fmt, ...) \ ({ \ - int rc_ = 0; \ + __typeof__(status) rc_ = (__typeof__(status))0; \ if (!((a) == (b))) { \ printf("%s:%d:" fmt, __func__, __LINE__, (a), (b), \ ##__VA_ARGS__); \ @@ -131,9 +497,22 @@ extern int debug; rc_; \ }) +#define assert_not_equal_as_expr(a, b, status, fmt, ...) \ + ({ \ + __typeof__(status) rc_ = (__typeof__(status))0; \ + if (!((a) != (b))) { \ + printf("%s:%d:" fmt, __func__, __LINE__, (a), (b), \ + ##__VA_ARGS__); \ + printf("%s:%d:Assertion `%s' failed.\n", __func__, \ + __LINE__, __stringify(a != b)); \ + rc_ = status; \ + } \ + rc_; \ + }) + #define assert_as_expr(cond, status, fmt, ...) \ ({ \ - int rc_ = 0; \ + __typeof__(status) rc_ = (__typeof__(status))0; \ if (!(cond)) { \ printf("%s:%d:" fmt, __func__, __LINE__, \ ##__VA_ARGS__); \ @@ -144,51 +523,62 @@ extern int debug; rc_; \ }) -#define assert_true_return(a, status, fmt, ...) \ - ({ \ - int rc_ = assert_true_as_expr(a, status, fmt, ##__VA_ARGS__); \ - if (rc_ != 0) \ - return rc_; \ +#define assert_true_return(a, status, fmt, ...) \ + ({ \ + __typeof__(status) rc_ = \ + assert_true_as_expr(a, status, fmt, ##__VA_ARGS__); \ + if (rc_ != 0) \ + return rc_; \ }) #define assert_nonzero_return(a, ...) assert_true_return(a, ##__VA_ARGS__) -#define assert_false_return(a, status, fmt, ...) \ - ({ \ - int rc_ = assert_false_as_expr(a, status, fmt, ##__VA_ARGS__); \ - if (rc_ != 0) \ - return rc_; \ +#define assert_false_return(a, status, fmt, ...) \ + ({ \ + __typeof__(status) rc_ = \ + assert_false_as_expr(a, status, fmt, ##__VA_ARGS__); \ + if (rc_ != 0) \ + return rc_; \ }) #define assert_zero_return(a, ...) assert_false_return(a, ##__VA_ARGS__) #define assert_positive_return(a, status, fmt, ...) \ ({ \ - int rc_ = assert_positive_as_expr(a, status, fmt, \ - ##__VA_ARGS__); \ + __typeof__(status) rc_ = assert_positive_as_expr( \ + a, status, fmt, ##__VA_ARGS__); \ if (rc_ != 0) \ return rc_; \ }) #define assert_negative_return(a, status, fmt, ...) \ ({ \ - int rc_ = assert_negative_as_expr(a, status, fmt, \ - ##__VA_ARGS__); \ + __typeof__(status) rc_ = assert_negative_as_expr( \ + a, status, fmt, ##__VA_ARGS__); \ if (rc_ != 0) \ return rc_; \ }) -#define assert_equal_return(a, b, status, fmt, ...) \ - ({ \ - int rc_ = assert_equal_as_expr(a, b, status, fmt, \ - ##__VA_ARGS__); \ - if (rc_ != 0) \ - return rc_; \ +#define assert_equal_return(a, b, status, fmt, ...) \ + ({ \ + __typeof__(status) rc_ = assert_equal_as_expr( \ + a, b, status, fmt, ##__VA_ARGS__); \ + if (rc_ != 0) \ + return rc_; \ }) -#define assert_return(cond, status, fmt, ...) \ - ({ \ - int rc_ = assert_as_expr(cond, status, fmt, ##__VA_ARGS__); \ - if (rc_ != 0) \ - return rc_; \ +#define assert_not_equal_return(a, b, status, fmt, ...) \ + ({ \ + __typeof__(status) rc_ = assert_not_equal_as_expr( \ + a, b, status, fmt, ##__VA_ARGS__); \ + if (rc_ != 0) \ + return rc_; \ + }) + +#define assert_return(cond, status, fmt, ...) \ + ({ \ + __typeof__(status) rc_ = \ + assert_as_expr(cond, status, fmt, ##__VA_ARGS__); \ + if (rc_ != 0) \ + return rc_; \ }) #define assert_goto(cond, label, fmt, ...) \ @@ -213,6 +603,41 @@ extern int debug; } \ }) +#define assert_not_equal_goto(a, b, label, fmt, ...) \ + ({ \ + if (!((a) != (b))) { \ + printf("%s:%d:" fmt, __func__, __LINE__, (a), (b), \ + ##__VA_ARGS__); \ + printf("%s:%d:Assertion `%s' failed.\n", __func__, \ + __LINE__, __stringify(a != b)); \ + goto label; \ + } \ + }) + +#define assert_true_goto(a, label, fmt, ...) \ + ({ \ + if (!(a)) { \ + printf("%s:%d:" fmt, __func__, __LINE__, (a), \ + ##__VA_ARGS__); \ + printf("%s:%d:Assertion `%s' failed.\n", __func__, \ + __LINE__, __stringify(!(a))); \ + goto label; \ + } \ + }) +#define assert_nonzero_goto(a, ...) assert_true_goto(a, ##__VA_ARGS__) + +#define assert_false_goto(a, label, fmt, ...) \ + ({ \ + if (a) { \ + printf("%s:%d:" fmt, __func__, __LINE__, (a), \ + ##__VA_ARGS__); \ + printf("%s:%d:Assertion `%s' failed.\n", __func__, \ + __LINE__, __stringify(a)); \ + goto label; \ + } \ + }) +#define assert_zero_goto(a, ...) assert_false_goto(a, ##__VA_ARGS__) + #define assert_negative_goto(a, label, fmt, ...) \ ({ \ int rc_ = assert_negative_as_expr(a, -1, fmt, ##__VA_ARGS__); \ |
