git: 9d218a7be088 - main - efitable: Don't assume EFI GUID are uuid_t

From: Warner Losh <imp_at_FreeBSD.org>
Date: Thu, 01 May 2025 18:06:38 UTC
The branch main has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=9d218a7be088c6b5ef250a945d532f3ae59c6a1a

commit 9d218a7be088c6b5ef250a945d532f3ae59c6a1a
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2025-05-01 17:53:19 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2025-05-01 17:53:19 +0000

    efitable: Don't assume EFI GUID are uuid_t
    
    To share code better with EDK2, we need to align our interfaces with its
    definition of EFI_GUID. This structure is the same size as our uuid_t,
    but has different elements. The EFI standard uses a string notaiton that
    are compatible with the uuid_* routines, however. So we use those
    routies to parse, but need to b careful to cast as appropriate. Becuas
    the ABI is the same, this is safe, though perhaps suboptimal. These
    changes make efitable API neutral.
    
    Sponsored by:           Netflix
    Reviewed by:            tsoome
    Differential Revision:  https://reviews.freebsd.org/D50036
---
 usr.sbin/efitable/efitable.c | 27 +++++++++++++++++++--------
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/usr.sbin/efitable/efitable.c b/usr.sbin/efitable/efitable.c
index 81d8bb999c58..f283d467b01d 100644
--- a/usr.sbin/efitable/efitable.c
+++ b/usr.sbin/efitable/efitable.c
@@ -46,17 +46,19 @@ static void efi_table_print_esrt(const void *data);
 static void efi_table_print_prop(const void *data);
 static void usage(void) __dead2;
 
+typedef uuid_t efi_guid_t;	/*  Typedef for future efi_guid_t */
+
 struct efi_table_op {
 	char name[TABLE_MAX_LEN];
 	void (*parse) (const void *);
-	struct uuid uuid;
+	efi_guid_t guid;
 };
 
 static const struct efi_table_op efi_table_ops[] = {
 	{ .name = "esrt", .parse = efi_table_print_esrt,
-	    .uuid = EFI_TABLE_ESRT },
+	    .guid = EFI_TABLE_ESRT },
 	{ .name = "prop", .parse = efi_table_print_prop,
-	    .uuid = EFI_PROPERTIES_TABLE }
+	    .guid = EFI_PROPERTIES_TABLE }
 };
 
 int
@@ -81,14 +83,23 @@ main(int argc, char **argv)
 	if (argc < 0)
 		exit(EXIT_FAILURE);
 
-	while ((ch = getopt_long(argc, argv, "u:t:", longopts, NULL)) != -1) {
+	while ((ch = getopt_long(argc, argv, "g:t:u:", longopts, NULL)) != -1) {
 		switch (ch) {
+		case 'g':
 		case 'u':
 		{
 			char *uuid_str = optarg;
 			struct uuid uuid;
 			uint32_t status;
 
+			/*
+			 * Note: we use the uuid parsing routine to parse the
+			 * guid strings. However, EFI defines a slightly
+			 * different structure to access them. We unify on
+			 * using a structure that's compatible with EDK2
+			 * EFI_GUID structure.
+			 */
+
 			uuid_set = 1;
 
 			uuid_from_string(uuid_str, &uuid, &status);
@@ -96,7 +107,7 @@ main(int argc, char **argv)
 				xo_errx(EX_DATAERR, "invalid UUID");
 
 			for (size_t n = 0; n < nitems(efi_table_ops); n++) {
-				if (!memcmp(&uuid, &efi_table_ops[n].uuid,
+				if (!memcmp(&uuid, &efi_table_ops[n].guid,
 				    sizeof(uuid))) {
 					efi_idx = n;
 					got_table = true;
@@ -140,7 +151,7 @@ main(int argc, char **argv)
 	if (efi_fd < 0)
 		xo_err(EX_OSFILE, "/dev/efi");
 
-	table.uuid = efi_table_ops[efi_idx].uuid;
+	memcpy(&table.uuid, &efi_table_ops[efi_idx].guid, sizeof(struct uuid));
 	if (ioctl(efi_fd, EFIIOC_GET_TABLE, &table) == -1)
 		xo_err(EX_OSERR, "EFIIOC_GET_TABLE (len == 0)");
 
@@ -181,7 +192,7 @@ efi_table_print_esrt(const void *data)
 		uint32_t status;
 		char *uuid;
 
-		uuid_to_string(&e->fw_class, &uuid, &status);
+		uuid_to_string((const uuid_t *)&e->fw_class, &uuid, &status);
 		if (status != uuid_s_ok) {
 			xo_errx(EX_DATAERR, "uuid_to_string error");
 		}
@@ -232,6 +243,6 @@ efi_table_print_prop(const void *data)
 
 static void usage(void)
 {
-	xo_error("usage: efitable [-d uuid | -t name] [--libxo]\n");
+	xo_error("usage: efitable [-g guid | -t name] [--libxo]\n");
 	exit(EX_USAGE);
 }