Blame SOURCES/0060-Improve-debug-output-some.patch

d84fc6
From fc4368fed53837e00d303600d8b628cb0392b629 Mon Sep 17 00:00:00 2001
d84fc6
From: Peter Jones <pjones@redhat.com>
d84fc6
Date: Thu, 23 Jul 2020 20:29:52 -0400
d84fc6
Subject: [PATCH 60/62] Improve debug output some
d84fc6
d84fc6
Signed-off-by: Peter Jones <pjones@redhat.com>
d84fc6
Upstream: pr#213
d84fc6
---
d84fc6
 errlog.c          |  26 ++++++-
d84fc6
 shim.c            |  36 ++++++++--
d84fc6
 include/console.h |   3 +
d84fc6
 include/hexdump.h | 172 ++++++++++++++++++++++++++++------------------
d84fc6
 shim.h            |   5 +-
d84fc6
 5 files changed, 164 insertions(+), 78 deletions(-)
d84fc6
d84fc6
diff --git a/errlog.c b/errlog.c
d84fc6
index 6669c800233..08f7a82a6b2 100644
d84fc6
--- a/errlog.c
d84fc6
+++ b/errlog.c
d84fc6
@@ -3,12 +3,28 @@
d84fc6
  * Copyright 2017 Peter Jones <pjones@redhat.com>
d84fc6
  */
d84fc6
 #include "shim.h"
d84fc6
+#include "hexdump.h"
d84fc6
 
d84fc6
 static CHAR16 **errs = NULL;
d84fc6
 static UINTN nerrs = 0;
d84fc6
 
d84fc6
 EFI_STATUS
d84fc6
-VLogError(const char *file, int line, const char *func, CHAR16 *fmt, va_list args)
d84fc6
+vdprint_(const CHAR16 *fmt, const char *file, int line, const char *func, va_list args)
d84fc6
+{
d84fc6
+	va_list args2;
d84fc6
+	EFI_STATUS efi_status = EFI_SUCCESS;
d84fc6
+
d84fc6
+	if (verbose) {
d84fc6
+		va_copy(args2, args);
d84fc6
+		console_print(L"%a:%d:%a() ", file, line, func);
d84fc6
+		efi_status = VPrint(fmt, args2);
d84fc6
+		va_end(args2);
d84fc6
+	}
d84fc6
+	return efi_status;
d84fc6
+}
d84fc6
+
d84fc6
+EFI_STATUS
d84fc6
+VLogError(const char *file, int line, const char *func, const CHAR16 *fmt, va_list args)
d84fc6
 {
d84fc6
 	va_list args2;
d84fc6
 	CHAR16 **newerrs;
d84fc6
@@ -35,7 +51,7 @@ VLogError(const char *file, int line, const char *func, CHAR16 *fmt, va_list arg
d84fc6
 }
d84fc6
 
d84fc6
 EFI_STATUS
d84fc6
-LogError_(const char *file, int line, const char *func, CHAR16 *fmt, ...)
d84fc6
+LogError_(const char *file, int line, const char *func, const CHAR16 *fmt, ...)
d84fc6
 {
d84fc6
 	va_list args;
d84fc6
 	EFI_STATUS efi_status;
d84fc6
@@ -47,6 +63,12 @@ LogError_(const char *file, int line, const char *func, CHAR16 *fmt, ...)
d84fc6
 	return efi_status;
d84fc6
 }
d84fc6
 
d84fc6
+VOID
d84fc6
+LogHexdump_(const char *file, int line, const char *func, const void *data, size_t sz)
d84fc6
+{
d84fc6
+	hexdumpat(file, line, func, data, sz, 0);
d84fc6
+}
d84fc6
+
d84fc6
 VOID
d84fc6
 PrintErrors(VOID)
d84fc6
 {
d84fc6
diff --git a/shim.c b/shim.c
d84fc6
index d10a1ba1cac..9248642bd57 100644
d84fc6
--- a/shim.c
d84fc6
+++ b/shim.c
d84fc6
@@ -34,6 +34,7 @@
d84fc6
  */
d84fc6
 
d84fc6
 #include "shim.h"
d84fc6
+#include "hexdump.h"
d84fc6
 #if defined(ENABLE_SHIM_CERT)
d84fc6
 #include "shim_cert.h"
d84fc6
 #endif /* defined(ENABLE_SHIM_CERT) */
d84fc6
@@ -373,12 +374,18 @@ static BOOLEAN verify_x509(UINT8 *Cert, UINTN CertSize)
d84fc6
 	 * and 64KB. For convenience, assume the number of value bytes
d84fc6
 	 * is 2, i.e. the second byte is 0x82.
d84fc6
 	 */
d84fc6
-	if (Cert[0] != 0x30 || Cert[1] != 0x82)
d84fc6
+	if (Cert[0] != 0x30 || Cert[1] != 0x82) {
d84fc6
+		dprint(L"cert[0:1] is [%02x%02x], should be [%02x%02x]\n",
d84fc6
+		       Cert[0], Cert[1], 0x30, 0x82);
d84fc6
 		return FALSE;
d84fc6
+	}
d84fc6
 
d84fc6
 	length = Cert[2]<<8 | Cert[3];
d84fc6
-	if (length != (CertSize - 4))
d84fc6
+	if (length != (CertSize - 4)) {
d84fc6
+		dprint(L"Cert length is %ld, expecting %ld\n",
d84fc6
+		       length, CertSize);
d84fc6
 		return FALSE;
d84fc6
+	}
d84fc6
 
d84fc6
 	return TRUE;
d84fc6
 }
d84fc6
@@ -426,19 +433,23 @@ static CHECK_STATUS check_db_cert_in_ram(EFI_SIGNATURE_LIST *CertList,
d84fc6
 	EFI_SIGNATURE_DATA *Cert;
d84fc6
 	UINTN CertSize;
d84fc6
 	BOOLEAN IsFound = FALSE;
d84fc6
+	int i = 0;
d84fc6
 
d84fc6
 	while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) {
d84fc6
 		if (CompareGuid (&CertList->SignatureType, &EFI_CERT_TYPE_X509_GUID) == 0) {
d84fc6
 			Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
d84fc6
 			CertSize = CertList->SignatureSize - sizeof(EFI_GUID);
d84fc6
+			dprint(L"trying to verify cert %d (%s)\n", i++, dbname);
d84fc6
 			if (verify_x509(Cert->SignatureData, CertSize)) {
d84fc6
 				if (verify_eku(Cert->SignatureData, CertSize)) {
d84fc6
+					drain_openssl_errors();
d84fc6
 					IsFound = AuthenticodeVerify (data->CertData,
d84fc6
 								      data->Hdr.dwLength - sizeof(data->Hdr),
d84fc6
 								      Cert->SignatureData,
d84fc6
 								      CertSize,
d84fc6
 								      hash, SHA256_DIGEST_SIZE);
d84fc6
 					if (IsFound) {
d84fc6
+						dprint(L"AuthenticodeVerify() succeeded: %d\n", IsFound);
d84fc6
 						tpm_measure_variable(dbname, guid, CertSize, Cert->SignatureData);
d84fc6
 						drain_openssl_errors();
d84fc6
 						return DATA_FOUND;
d84fc6
@@ -447,7 +458,9 @@ static CHECK_STATUS check_db_cert_in_ram(EFI_SIGNATURE_LIST *CertList,
d84fc6
 					}
d84fc6
 				}
d84fc6
 			} else if (verbose) {
d84fc6
-				console_notify(L"Not a DER encoding x.509 Certificate");
d84fc6
+				console_print(L"Not a DER encoded x.509 Certificate");
d84fc6
+				dprint(L"cert:\n");
d84fc6
+				dhexdumpat(Cert->SignatureData, CertSize, 0);
d84fc6
 			}
d84fc6
 		}
d84fc6
 
d84fc6
@@ -641,7 +654,7 @@ static EFI_STATUS check_whitelist (WIN_CERTIFICATE_EFI_PKCS *cert,
d84fc6
 			verification_method = VERIFIED_BY_CERT;
d84fc6
 			update_verification_method(VERIFIED_BY_CERT);
d84fc6
 			return EFI_SUCCESS;
d84fc6
-		} else {
d84fc6
+		} else if (cert) {
d84fc6
 			LogError(L"check_db_cert(db, sha256hash) != DATA_FOUND\n");
d84fc6
 		}
d84fc6
 	}
d84fc6
@@ -666,7 +679,7 @@ static EFI_STATUS check_whitelist (WIN_CERTIFICATE_EFI_PKCS *cert,
d84fc6
 		verification_method = VERIFIED_BY_CERT;
d84fc6
 		update_verification_method(VERIFIED_BY_CERT);
d84fc6
 		return EFI_SUCCESS;
d84fc6
-	} else {
d84fc6
+	} else if (cert) {
d84fc6
 		LogError(L"check_db_cert(vendor_db, sha256hash) != DATA_FOUND\n");
d84fc6
 	}
d84fc6
 #endif
d84fc6
@@ -685,7 +698,7 @@ static EFI_STATUS check_whitelist (WIN_CERTIFICATE_EFI_PKCS *cert,
d84fc6
 		verification_method = VERIFIED_BY_CERT;
d84fc6
 		update_verification_method(VERIFIED_BY_CERT);
d84fc6
 		return EFI_SUCCESS;
d84fc6
-	} else {
d84fc6
+	} else if (cert) {
d84fc6
 		LogError(L"check_db_cert(MokList, sha256hash) != DATA_FOUND\n");
d84fc6
 	}
d84fc6
 
d84fc6
@@ -993,6 +1006,11 @@ static EFI_STATUS generate_hash (char *data, unsigned int datasize_in,
d84fc6
 		goto done;
d84fc6
 	}
d84fc6
 
d84fc6
+	dprint(L"sha1 authenticode hash:\n");
d84fc6
+	dhexdumpat(sha1hash, SHA1_DIGEST_SIZE, 0);
d84fc6
+	dprint(L"sha256 authenticode hash:\n");
d84fc6
+	dhexdumpat(sha256hash, SHA256_DIGEST_SIZE, 0);
d84fc6
+
d84fc6
 done:
d84fc6
 	if (SectionHeader)
d84fc6
 		FreePool(SectionHeader);
d84fc6
@@ -1155,6 +1173,7 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
d84fc6
 	if (EFI_ERROR(ret_efi_status)) {
d84fc6
 		dprint(L"check_whitelist: %r\n", ret_efi_status);
d84fc6
 		if (ret_efi_status != EFI_NOT_FOUND) {
d84fc6
+			dprint(L"check_whitelist(): %r\n", ret_efi_status);
d84fc6
 			PrintErrors();
d84fc6
 			ClearErrors();
d84fc6
 			crypterr(ret_efi_status);
d84fc6
@@ -1803,6 +1822,7 @@ static EFI_STATUS load_image (EFI_LOADED_IMAGE *li, void **data,
d84fc6
 
d84fc6
 	device = li->DeviceHandle;
d84fc6
 
d84fc6
+	dprint(L"attempting to load %s\n", PathName);
d84fc6
 	/*
d84fc6
 	 * Open the device
d84fc6
 	 */
d84fc6
@@ -2778,6 +2798,10 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab)
d84fc6
 	 */
d84fc6
 	InitializeLib(image_handle, systab);
d84fc6
 
d84fc6
+	dprint(L"vendor_authorized:0x%08lx vendor_authorized_size:%lu\n",
d84fc6
+		      __FILE__, __LINE__, __func__, vendor_authorized, vendor_authorized_size);
d84fc6
+	dprint(L"vendor_deauthorized:0x%08lx vendor_deauthorized_size:%lu\n",
d84fc6
+		      __FILE__, __LINE__, __func__, vendor_deauthorized, vendor_deauthorized_size);
d84fc6
 	init_openssl();
d84fc6
 
d84fc6
 	/*
d84fc6
diff --git a/include/console.h b/include/console.h
d84fc6
index 810bf13a1f1..ac6fdf61d18 100644
d84fc6
--- a/include/console.h
d84fc6
+++ b/include/console.h
d84fc6
@@ -85,6 +85,9 @@ extern UINT32 verbose;
d84fc6
 		__dprint_ret;							\
d84fc6
 	})
d84fc6
 #define dprint(fmt, ...) dprint_(L"%a:%d:%a() " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__)
d84fc6
+extern EFI_STATUS
d84fc6
+vdprint_(const CHAR16 *fmt, const char *file, int line, const char *func, va_list args);
d84fc6
+#define vdprint(fmt, ...) vdprint_(fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__)
d84fc6
 
d84fc6
 extern EFI_STATUS print_crypto_errors(EFI_STATUS rc, char *file, const char *func, int line);
d84fc6
 #define crypterr(rc) print_crypto_errors((rc), __FILE__, __func__, __LINE__)
d84fc6
diff --git a/include/hexdump.h b/include/hexdump.h
d84fc6
index d337b571d8d..f3f3ac284a3 100644
d84fc6
--- a/include/hexdump.h
d84fc6
+++ b/include/hexdump.h
d84fc6
@@ -1,104 +1,140 @@
d84fc6
 #ifndef STATIC_HEXDUMP_H
d84fc6
 #define STATIC_HEXDUMP_H
d84fc6
 
d84fc6
-static int
d84fc6
-__attribute__((__unused__))
d84fc6
-isprint(char c)
d84fc6
-{
d84fc6
-	if (c < 0x20)
d84fc6
-		return 0;
d84fc6
-	if (c > 0x7e)
d84fc6
-		return 0;
d84fc6
-	return 1;
d84fc6
-}
d84fc6
+#include <stdint.h>
d84fc6
 
d84fc6
-static UINTN
d84fc6
-__attribute__((__unused__))
d84fc6
-format_hex(UINT8 *data, UINTN size, CHAR16 *buf)
d84fc6
+static inline unsigned long UNUSED
d84fc6
+prepare_hex(const void *data, size_t size, char *buf, int position)
d84fc6
 {
d84fc6
-	UINTN sz = (UINTN)data % 16;
d84fc6
-	CHAR16 hexchars[] = L"0123456789abcdef";
d84fc6
+	char hexchars[] = "0123456789abcdef";
d84fc6
 	int offset = 0;
d84fc6
-	UINTN i;
d84fc6
-	UINTN j;
d84fc6
+	unsigned long i;
d84fc6
+	unsigned long j;
d84fc6
+	unsigned long ret;
d84fc6
 
d84fc6
-	for (i = 0; i < sz; i++) {
d84fc6
-		buf[offset++] = L' ';
d84fc6
-		buf[offset++] = L' ';
d84fc6
-		buf[offset++] = L' ';
d84fc6
+	unsigned long before = (position % 16);
d84fc6
+	unsigned long after = (before+size >= 16) ? 0 : 16 - (before+size);
d84fc6
+
d84fc6
+	for (i = 0; i < before; i++) {
d84fc6
+		buf[offset++] = 'X';
d84fc6
+		buf[offset++] = 'X';
d84fc6
+		buf[offset++] = ' ';
d84fc6
 		if (i == 7)
d84fc6
-			buf[offset++] = L' ';
d84fc6
+			buf[offset++] = ' ';
d84fc6
 	}
d84fc6
-	for (j = sz; j < 16 && j < size; j++) {
d84fc6
-		UINT8 d = data[j-sz];
d84fc6
+	for (j = 0; j < 16 - after - before; j++) {
d84fc6
+		uint8_t d = ((uint8_t *)data)[j];
d84fc6
 		buf[offset++] = hexchars[(d & 0xf0) >> 4];
d84fc6
 		buf[offset++] = hexchars[(d & 0x0f)];
d84fc6
-		if (j != 15)
d84fc6
-			buf[offset++] = L' ';
d84fc6
-		if (j == 7)
d84fc6
-			buf[offset++] = L' ';
d84fc6
+		if (i+j != 15)
d84fc6
+			buf[offset++] = ' ';
d84fc6
+		if (i+j == 7)
d84fc6
+			buf[offset++] = ' ';
d84fc6
 	}
d84fc6
-	for (i = j; i < 16; i++) {
d84fc6
-		buf[offset++] = L' ';
d84fc6
-		buf[offset++] = L' ';
d84fc6
-		if (i != 15)
d84fc6
-			buf[offset++] = L' ';
d84fc6
-		if (i == 7)
d84fc6
-			buf[offset++] = L' ';
d84fc6
+	ret = 16 - after - before;
d84fc6
+	j += i;
d84fc6
+	for (i = 0; i < after; i++) {
d84fc6
+		buf[offset++] = 'X';
d84fc6
+		buf[offset++] = 'X';
d84fc6
+		if (i+j != 15)
d84fc6
+			buf[offset++] = ' ';
d84fc6
+		if (i+j == 7)
d84fc6
+			buf[offset++] = ' ';
d84fc6
 	}
d84fc6
-	buf[offset] = L'\0';
d84fc6
-	return j - sz;
d84fc6
+	buf[offset] = '\0';
d84fc6
+	return ret;
d84fc6
 }
d84fc6
 
d84fc6
-static void
d84fc6
-__attribute__((__unused__))
d84fc6
-format_text(UINT8 *data, UINTN size, CHAR16 *buf)
d84fc6
+#define isprint(c) ((c) >= 0x20 && (c) <= 0x7e)
d84fc6
+
d84fc6
+static inline void UNUSED
d84fc6
+prepare_text(const void *data, size_t size, char *buf, int position)
d84fc6
 {
d84fc6
-	UINTN sz = (UINTN)data % 16;
d84fc6
 	int offset = 0;
d84fc6
-	UINTN i;
d84fc6
-	UINTN j;
d84fc6
+	unsigned long i;
d84fc6
+	unsigned long j;
d84fc6
 
d84fc6
-	for (i = 0; i < sz; i++)
d84fc6
-		buf[offset++] = L' ';
d84fc6
-	buf[offset++] = L'|';
d84fc6
-	for (j = sz; j < 16 && j < size; j++) {
d84fc6
-		if (isprint(data[j-sz]))
d84fc6
-			buf[offset++] = data[j-sz];
d84fc6
+	unsigned long before = position % 16;
d84fc6
+	unsigned long after = (before+size > 16) ? 0 : 16 - (before+size);
d84fc6
+
d84fc6
+	if (size == 0) {
d84fc6
+		buf[0] = '\0';
d84fc6
+		return;
d84fc6
+	}
d84fc6
+	for (i = 0; i < before; i++)
d84fc6
+		buf[offset++] = 'X';
d84fc6
+	buf[offset++] = '|';
d84fc6
+	for (j = 0; j < 16 - after - before; j++) {
d84fc6
+		if (isprint(((uint8_t *)data)[j]))
d84fc6
+			buf[offset++] = ((uint8_t *)data)[j];
d84fc6
 		else
d84fc6
-			buf[offset++] = L'.';
d84fc6
+			buf[offset++] = '.';
d84fc6
 	}
d84fc6
-	buf[offset++] = L'|';
d84fc6
-	for (i = j; i < 16; i++)
d84fc6
-		buf[offset++] = L' ';
d84fc6
-	buf[offset] = L'\0';
d84fc6
+	buf[offset++] = size > 0 ? '|' : 'X';
d84fc6
+	buf[offset] = '\0';
d84fc6
 }
d84fc6
 
d84fc6
-static void
d84fc6
-__attribute__((__unused__))
d84fc6
-hexdump(UINT8 *data, UINTN size)
d84fc6
+/*
d84fc6
+ * variadic hexdump formatted
d84fc6
+ * think of it as: printf("%s%s\n", vformat(fmt, ap), hexdump(data,size));
d84fc6
+ */
d84fc6
+static inline void UNUSED
d84fc6
+vhexdumpf(const char *file, int line, const char *func, const CHAR16 * const fmt, const void *data, unsigned long size, size_t at, va_list ap)
d84fc6
 {
d84fc6
-	UINTN display_offset = (UINTN)data & 0xffffffff;
d84fc6
-	UINTN offset = 0;
d84fc6
-	//console_print(L"hexdump: data=0x%016x size=0x%x\n", data, size);
d84fc6
+	unsigned long display_offset = at;
d84fc6
+	unsigned long offset = 0;
d84fc6
 
d84fc6
 	while (offset < size) {
d84fc6
-		CHAR16 hexbuf[49];
d84fc6
-		CHAR16 txtbuf[19];
d84fc6
-		UINTN sz;
d84fc6
+		char hexbuf[49];
d84fc6
+		char txtbuf[19];
d84fc6
+		unsigned long sz;
d84fc6
 
d84fc6
-		sz = format_hex(data+offset, size-offset, hexbuf);
d84fc6
+		sz = prepare_hex(data+offset, size-offset, hexbuf,
d84fc6
+				 (unsigned long)data+offset);
d84fc6
 		if (sz == 0)
d84fc6
 			return;
d84fc6
-		msleep(200000);
d84fc6
 
d84fc6
-		format_text(data+offset, size-offset, txtbuf);
d84fc6
-		console_print(L"%08x  %s  %s\n", display_offset, hexbuf, txtbuf);
d84fc6
-		msleep(200000);
d84fc6
+		prepare_text(data+offset, size-offset, txtbuf,
d84fc6
+			     (unsigned long)data+offset);
d84fc6
+		if (fmt && fmt[0] != 0)
d84fc6
+			vdprint_(fmt, file, line, func, ap);
d84fc6
+		dprint_(L"%a:%d:%a() %08lx  %a  %a\n", file, line, func, display_offset, hexbuf, txtbuf);
d84fc6
 
d84fc6
 		display_offset += sz;
d84fc6
 		offset += sz;
d84fc6
 	}
d84fc6
 }
d84fc6
 
d84fc6
+/*
d84fc6
+ * hexdump formatted
d84fc6
+ * think of it as: printf("%s%s", format(fmt, ...), hexdump(data,size)[lineN]);
d84fc6
+ */
d84fc6
+static inline void UNUSED
d84fc6
+hexdumpf(const char *file, int line, const char *func, const CHAR16 * const fmt, const void *data, unsigned long size, size_t at, ...)
d84fc6
+{
d84fc6
+	va_list ap;
d84fc6
+
d84fc6
+	va_start(ap, at);
d84fc6
+	vhexdumpf(file, line, func, fmt, data, size, at, ap);
d84fc6
+	va_end(ap);
d84fc6
+}
d84fc6
+
d84fc6
+static inline void UNUSED
d84fc6
+hexdump(const char *file, int line, const char *func, const void *data, unsigned long size)
d84fc6
+{
d84fc6
+	hexdumpf(file, line, func, L"", data, size, (intptr_t)data);
d84fc6
+}
d84fc6
+
d84fc6
+static inline void UNUSED
d84fc6
+hexdumpat(const char *file, int line, const char *func, const void *data, unsigned long size, size_t at)
d84fc6
+{
d84fc6
+	hexdumpf(file, line, func, L"", data, size, at);
d84fc6
+}
d84fc6
+
d84fc6
+#define LogHexdump(data, sz) LogHexdump_(__FILE__, __LINE__, __func__, data, sz)
d84fc6
+#define dhexdump(data, sz) hexdump(__FILE__, __LINE__, __func__, data, sz)
d84fc6
+#define dhexdumpat(data, sz, at) hexdumpat(__FILE__, __LINE__, __func__, data, sz, at)
d84fc6
+#define dhexdumpf(fmt, data, sz, at, ...) hexdumpf(__FILE__, __LINE__, __func__, fmt, data, sz, at, ##__VA_ARGS__)
d84fc6
+
d84fc6
 #endif /* STATIC_HEXDUMP_H */
d84fc6
+// vim:fenc=utf-8:tw=75:noet
d84fc6
diff --git a/shim.h b/shim.h
d84fc6
index c1d7e7c7197..0b3ad4f2d20 100644
d84fc6
--- a/shim.h
d84fc6
+++ b/shim.h
d84fc6
@@ -182,8 +182,9 @@ typedef struct _SHIM_LOCK {
d84fc6
 
d84fc6
 extern EFI_STATUS shim_init(void);
d84fc6
 extern void shim_fini(void);
d84fc6
-extern EFI_STATUS LogError_(const char *file, int line, const char *func, CHAR16 *fmt, ...);
d84fc6
-extern EFI_STATUS VLogError(const char *file, int line, const char *func, CHAR16 *fmt, va_list args);
d84fc6
+extern EFI_STATUS LogError_(const char *file, int line, const char *func, const CHAR16 *fmt, ...);
d84fc6
+extern EFI_STATUS VLogError(const char *file, int line, const char *func, const CHAR16 *fmt, va_list args);
d84fc6
+extern VOID LogHexdump_(const char *file, int line, const char *func, const void *data, size_t sz);
d84fc6
 extern VOID PrintErrors(VOID);
d84fc6
 extern VOID ClearErrors(VOID);
d84fc6
 extern EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath);
d84fc6
-- 
d84fc6
2.26.2
d84fc6