From b04efccece789d9b8d8a455a86f20917436d7bd2 Mon Sep 17 00:00:00 2001
From: dp-arm <dimitris.papastamos@arm.com>
Date: Tue, 30 Aug 2016 14:18:58 +0100
Subject: [PATCH] fiptool: Link `toc_entry` and `image` structures via UUID

The `toc_entry` and `image` data structures had a cyclic
relationship.  This patch removes the explicit dependencies and introduces
functions to link them via the UUID.

This change highlights the intent of the code better and makes it more
flexible for future enhancements.

Change-Id: I0c3dd7bfda2a631a3827c8ba4831849c500affe9
Signed-off-by: dp-arm <dimitris.papastamos@arm.com>
---
 tools/fiptool/fiptool.c     |  90 ++++++++---------
 tools/fiptool/fiptool.h     |   1 -
 tools/fiptool/tbbr_config.c | 188 ++++++++++++++++++++++++++++--------
 tools/fiptool/tbbr_config.h |   1 -
 4 files changed, 193 insertions(+), 87 deletions(-)

diff --git a/tools/fiptool/fiptool.c b/tools/fiptool/fiptool.c
index b3f02f6ce..18d1222b8 100644
--- a/tools/fiptool/fiptool.c
+++ b/tools/fiptool/fiptool.c
@@ -187,7 +187,7 @@ static void free_images(void)
 	}
 }
 
-static toc_entry_t *get_entry_lookup_from_uuid(const uuid_t *uuid)
+static toc_entry_t *lookup_entry_from_uuid(uuid_t *uuid)
 {
 	toc_entry_t *toc_entry = toc_entries;
 
@@ -197,6 +197,19 @@ static toc_entry_t *get_entry_lookup_from_uuid(const uuid_t *uuid)
 	return NULL;
 }
 
+static image_t *lookup_image_from_uuid(uuid_t *uuid)
+{
+	image_t *image;
+	int i;
+
+	for (i = 0; i < nr_images; i++) {
+		image = images[i];
+		if (memcmp(&image->uuid, uuid, sizeof(uuid_t)) == 0)
+			return image;
+	}
+	return NULL;
+}
+
 static int parse_fip(char *filename, fip_toc_header_t *toc_header_out)
 {
 	struct stat st;
@@ -268,16 +281,6 @@ static int parse_fip(char *filename, fip_toc_header_t *toc_header_out)
 		    toc_entry->size);
 		image->size = toc_entry->size;
 
-		image->toc_entry = get_entry_lookup_from_uuid(&toc_entry->uuid);
-		if (image->toc_entry == NULL) {
-			add_image(image);
-			toc_entry++;
-			continue;
-		}
-
-		assert(image->toc_entry->image == NULL);
-		/* Link backpointer from lookup entry. */
-		image->toc_entry->image = image;
 		add_image(image);
 
 		toc_entry++;
@@ -290,12 +293,14 @@ static int parse_fip(char *filename, fip_toc_header_t *toc_header_out)
 	return 0;
 }
 
-static image_t *read_image_from_file(toc_entry_t *toc_entry, char *filename)
+static image_t *read_image_from_file(uuid_t *uuid, char *filename)
 {
 	struct stat st;
 	image_t *image;
 	FILE *fp;
 
+	assert(uuid != NULL);
+
 	fp = fopen(filename, "r");
 	if (fp == NULL)
 		log_err("fopen %s", filename);
@@ -307,7 +312,7 @@ static image_t *read_image_from_file(toc_entry_t *toc_entry, char *filename)
 	if (image == NULL)
 		log_err("malloc");
 
-	memcpy(&image->uuid, &toc_entry->uuid, sizeof(uuid_t));
+	memcpy(&image->uuid, uuid, sizeof(uuid_t));
 
 	image->buffer = malloc(st.st_size);
 	if (image->buffer == NULL)
@@ -315,7 +320,6 @@ static image_t *read_image_from_file(toc_entry_t *toc_entry, char *filename)
 	if (fread(image->buffer, 1, st.st_size, fp) != st.st_size)
 		log_errx("Failed to read %s", filename);
 	image->size = st.st_size;
-	image->toc_entry = toc_entry;
 
 	fclose(fp);
 	return image;
@@ -391,18 +395,21 @@ static int info_cmd(int argc, char *argv[])
 	    (sizeof(fip_toc_entry_t) * (nr_images + 1));
 
 	for (i = 0; i < nr_images; i++) {
+		toc_entry_t *toc_entry;
+
 		image = images[i];
-		if (image->toc_entry != NULL)
-			printf("%s: ", image->toc_entry->name);
+		toc_entry = lookup_entry_from_uuid(&image->uuid);
+		if (toc_entry != NULL)
+			printf("%s: ", toc_entry->name);
 		else
 			printf("Unknown entry: ");
 		image_size = image->size;
 		printf("offset=0x%llX, size=0x%llX",
 		    (unsigned long long)image_offset,
 		    (unsigned long long)image_size);
-		if (image->toc_entry != NULL)
+		if (toc_entry != NULL)
 			printf(", cmdline=\"--%s\"",
-			    image->toc_entry->cmdline_name);
+			    toc_entry->cmdline_name);
 		if (verbose) {
 			unsigned char md[SHA256_DIGEST_LENGTH];
 
@@ -505,7 +512,7 @@ static int pack_images(char *filename, uint64_t toc_flags)
 static void update_fip(void)
 {
 	toc_entry_t *toc_entry;
-	image_t *image;
+	image_t *new_image, *old_image;
 
 	/* Add or replace images in the FIP file. */
 	for (toc_entry = toc_entries;
@@ -514,21 +521,21 @@ static void update_fip(void)
 		if (toc_entry->action != DO_PACK)
 			continue;
 
-		image = read_image_from_file(toc_entry, toc_entry->action_arg);
-		if (toc_entry->image != NULL) {
+		new_image = read_image_from_file(&toc_entry->uuid,
+		    toc_entry->action_arg);
+		old_image = lookup_image_from_uuid(&toc_entry->uuid);
+		if (old_image != NULL) {
 			if (verbose)
 				log_dbgx("Replacing image %s.bin with %s",
 				    toc_entry->cmdline_name,
 				    toc_entry->action_arg);
-			replace_image(toc_entry->image, image);
+			replace_image(old_image, new_image);
 		} else {
 			if (verbose)
 				log_dbgx("Adding image %s",
 				    toc_entry->action_arg);
-			add_image(image);
+			add_image(new_image);
 		}
-		/* Link backpointer from lookup entry. */
-		toc_entry->image = image;
 
 		free(toc_entry->action_arg);
 		toc_entry->action_arg = NULL;
@@ -758,23 +765,13 @@ static int unpack_cmd(int argc, char *argv[])
 		if (chdir(outdir) == -1)
 			log_err("chdir %s", outdir);
 
-	/* Mark all images to be unpacked. */
-	if (unpack_all) {
-		for (toc_entry = toc_entries;
-		     toc_entry->cmdline_name != NULL;
-		     toc_entry++) {
-			if (toc_entry->image != NULL) {
-				toc_entry->action = DO_UNPACK;
-				toc_entry->action_arg = NULL;
-			}
-		}
-	}
-
 	/* Unpack all specified images. */
 	for (toc_entry = toc_entries;
 	     toc_entry->cmdline_name != NULL;
 	     toc_entry++) {
-		if (toc_entry->action != DO_UNPACK)
+		image_t *image;
+
+		if (!unpack_all && toc_entry->action != DO_UNPACK)
 			continue;
 
 		/* Build filename. */
@@ -785,9 +782,11 @@ static int unpack_cmd(int argc, char *argv[])
 			snprintf(file, sizeof(file), "%s",
 			    toc_entry->action_arg);
 
-		if (toc_entry->image == NULL) {
-			log_warnx("Requested image %s is not in %s",
-			    file, argv[0]);
+		image = lookup_image_from_uuid(&toc_entry->uuid);
+		if (image == NULL) {
+			if (!unpack_all)
+				log_warnx("Requested image %s is not in %s",
+				    file, argv[0]);
 			free(toc_entry->action_arg);
 			toc_entry->action_arg = NULL;
 			continue;
@@ -796,7 +795,7 @@ static int unpack_cmd(int argc, char *argv[])
 		if (access(file, F_OK) != 0 || fflag) {
 			if (verbose)
 				log_dbgx("Unpacking %s", file);
-			write_image_to_file(toc_entry->image, file);
+			write_image_to_file(image, file);
 		} else {
 			log_warnx("File %s already exists, use --force to overwrite it",
 			    file);
@@ -885,13 +884,16 @@ static int remove_cmd(int argc, char *argv[])
 	for (toc_entry = toc_entries;
 	     toc_entry->cmdline_name != NULL;
 	     toc_entry++) {
+		image_t *image;
+
 		if (toc_entry->action != DO_REMOVE)
 			continue;
-		if (toc_entry->image != NULL) {
+		image = lookup_image_from_uuid(&toc_entry->uuid);
+		if (image != NULL) {
 			if (verbose)
 				log_dbgx("Removing %s.bin",
 				    toc_entry->cmdline_name);
-			remove_image(toc_entry->image);
+			remove_image(image);
 		} else {
 			log_warnx("Requested image %s.bin is not in %s",
 			    toc_entry->cmdline_name, argv[0]);
diff --git a/tools/fiptool/fiptool.h b/tools/fiptool/fiptool.h
index 0fe64c0c2..770510767 100644
--- a/tools/fiptool/fiptool.h
+++ b/tools/fiptool/fiptool.h
@@ -57,7 +57,6 @@ typedef struct image {
 	uuid_t            uuid;
 	size_t            size;
 	void             *buffer;
-	struct toc_entry *toc_entry;
 } image_t;
 
 typedef struct cmd {
diff --git a/tools/fiptool/tbbr_config.c b/tools/fiptool/tbbr_config.c
index e8fbbbaab..b92e8daf3 100644
--- a/tools/fiptool/tbbr_config.c
+++ b/tools/fiptool/tbbr_config.c
@@ -35,49 +35,155 @@
 
 /* The images used depends on the platform. */
 toc_entry_t toc_entries[] = {
-	{ "SCP Firmware Updater Configuration FWU SCP_BL2U", UUID_TRUSTED_UPDATE_FIRMWARE_SCP_BL2U,
-	  "scp-fwu-cfg", NULL, 0, NULL },
-	{ "AP Firmware Updater Configuration BL2U", UUID_TRUSTED_UPDATE_FIRMWARE_BL2U,
-	  "ap-fwu-cfg", NULL, 0, NULL },
-	{ "Firmware Updater NS_BL2U", UUID_TRUSTED_UPDATE_FIRMWARE_NS_BL2U,
-	  "fwu", NULL, 0, NULL },
-	{ "Non-Trusted Firmware Updater certificate", UUID_TRUSTED_FWU_CERT,
-	  "fwu-cert", NULL, 0, NULL },
-	{ "Trusted Boot Firmware BL2", UUID_TRUSTED_BOOT_FIRMWARE_BL2,
-	  "tb-fw", NULL, 0, NULL },
-	{ "SCP Firmware SCP_BL2", UUID_SCP_FIRMWARE_SCP_BL2,
-	  "scp-fw", NULL, 0, NULL },
-	{ "EL3 Runtime Firmware BL31", UUID_EL3_RUNTIME_FIRMWARE_BL31,
-	  "soc-fw", NULL, 0, NULL },
-	{ "Secure Payload BL32 (Trusted OS)", UUID_SECURE_PAYLOAD_BL32,
-	  "tos-fw", NULL, 0, NULL },
-	{ "Non-Trusted Firmware BL33", UUID_NON_TRUSTED_FIRMWARE_BL33,
-	  "nt-fw", NULL, 0, NULL },
+	{
+		.name = "SCP Firmware Updater Configuration FWU SCP_BL2U",
+		.uuid = UUID_TRUSTED_UPDATE_FIRMWARE_SCP_BL2U,
+		.cmdline_name = "scp-fwu-cfg",
+		.action = 0,
+		.action_arg = NULL
+	},
+	{
+		.name = "AP Firmware Updater Configuration BL2U",
+		.uuid = UUID_TRUSTED_UPDATE_FIRMWARE_BL2U,
+		.cmdline_name = "ap-fwu-cfg",
+		.action = 0,
+		.action_arg = NULL
+	},
+	{
+		.name = "Firmware Updater NS_BL2U",
+		.uuid = UUID_TRUSTED_UPDATE_FIRMWARE_NS_BL2U,
+		.cmdline_name = "fwu",
+		.action = 0,
+		.action_arg = NULL
+	},
+	{
+		.name = "Non-Trusted Firmware Updater certificate",
+		.uuid = UUID_TRUSTED_FWU_CERT,
+		.cmdline_name = "fwu-cert",
+		.action = 0,
+		.action_arg = NULL
+	},
+	{
+		.name = "Trusted Boot Firmware BL2",
+		.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
+		.cmdline_name = "tb-fw",
+		.action = 0,
+		.action_arg = NULL
+	},
+	{
+		.name = "SCP Firmware SCP_BL2",
+		.uuid = UUID_SCP_FIRMWARE_SCP_BL2,
+		.cmdline_name = "scp-fw",
+		.action = 0,
+		.action_arg = NULL
+	},
+	{
+		.name = "EL3 Runtime Firmware BL31",
+		.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
+		.cmdline_name = "soc-fw",
+		.action = 0,
+		.action_arg = NULL
+	},
+	{
+		.name = "Secure Payload BL32 (Trusted OS)",
+		.uuid = UUID_SECURE_PAYLOAD_BL32,
+		.cmdline_name = "tos-fw",
+		.action = 0,
+		.action_arg = NULL
+	},
+	{
+		.name = "Non-Trusted Firmware BL33",
+		.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
+		.cmdline_name = "nt-fw",
+		.action = 0,
+		.action_arg = NULL
+	},
 	/* Key Certificates */
-	{ "Root Of Trust key certificate", UUID_ROT_KEY_CERT,
-	  "rot-cert", NULL, 0, NULL },
-	{ "Trusted key certificate", UUID_TRUSTED_KEY_CERT,
-	  "trusted-key-cert", NULL, 0, NULL },
-	{ "SCP Firmware key certificate", UUID_SCP_FW_KEY_CERT,
-	  "scp-fw-key-cert", NULL, 0, NULL },
-	{ "SoC Firmware key certificate", UUID_SOC_FW_KEY_CERT,
-	  "soc-fw-key-cert", NULL, 0, NULL },
-	{ "Trusted OS Firmware key certificate", UUID_TRUSTED_OS_FW_KEY_CERT,
-	  "tos-fw-key-cert", NULL, 0, NULL },
-	{ "Non-Trusted Firmware key certificate", UUID_NON_TRUSTED_FW_KEY_CERT,
-	  "nt-fw-key-cert", NULL, 0, NULL },
+	{
+		.name = "Root Of Trust key certificate",
+		.uuid = UUID_ROT_KEY_CERT,
+		.cmdline_name = "rot-cert",
+		.action = 0,
+		.action_arg = NULL
+	},
+	{
+		.name = "Trusted key certificate",
+		.uuid = UUID_TRUSTED_KEY_CERT,
+		.cmdline_name = "trusted-key-cert",
+		.action = 0,
+		.action_arg = NULL
+	},
+	{
+		.name = "SCP Firmware key certificate",
+		.uuid = UUID_SCP_FW_KEY_CERT,
+		.cmdline_name = "scp-fw-key-cert",
+		.action = 0,
+		.action_arg = NULL
+	},
+	{
+		.name = "SoC Firmware key certificate",
+		.uuid = UUID_SOC_FW_KEY_CERT,
+		.cmdline_name = "soc-fw-key-cert",
+		.action = 0,
+		.action_arg = NULL
+	},
+	{
+		.name = "Trusted OS Firmware key certificate",
+		.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
+		.cmdline_name = "tos-fw-key-cert",
+		.action = 0,
+		.action_arg = NULL
+	},
+	{
+		.name = "Non-Trusted Firmware key certificate",
+		.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
+		.cmdline_name = "nt-fw-key-cert",
+		.action = 0,
+		.action_arg = NULL
+	},
 	/* Content certificates */
-	{ "Trusted Boot Firmware BL2 certificate", UUID_TRUSTED_BOOT_FW_CERT,
-	  "tb-fw-cert", NULL, 0, NULL },
-	{ "SCP Firmware content certificate", UUID_SCP_FW_CONTENT_CERT,
-	  "scp-fw-cert", NULL, 0, NULL },
-	{ "SoC Firmware content certificate", UUID_SOC_FW_CONTENT_CERT,
-	  "soc-fw-cert", NULL, 0, NULL },
-	{ "Trusted OS Firmware content certificate", UUID_TRUSTED_OS_FW_CONTENT_CERT,
-	  "tos-fw-cert", NULL, 0, NULL },
-	{ "Non-Trusted Firmware content certificate", UUID_NON_TRUSTED_FW_CONTENT_CERT,
-	  "nt-fw-cert", NULL, 0, NULL },
-	{ NULL, { 0 }, NULL, NULL, 0, NULL }
+	{
+		.name = "Trusted Boot Firmware BL2 certificate",
+		.uuid = UUID_TRUSTED_BOOT_FW_CERT,
+		.cmdline_name = "tb-fw-cert",
+		.action = 0,
+		.action_arg = NULL
+	},
+	{
+		.name = "SCP Firmware content certificate",
+		.uuid = UUID_SCP_FW_CONTENT_CERT,
+		.cmdline_name = "scp-fw-cert",
+		.action = 0,
+		.action_arg = NULL
+	},
+	{
+		.name = "SoC Firmware content certificate",
+		.uuid = UUID_SOC_FW_CONTENT_CERT,
+		.cmdline_name = "soc-fw-cert",
+		.action = 0,
+		.action_arg = NULL
+	},
+	{
+		.name = "Trusted OS Firmware content certificate",
+		.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
+		.cmdline_name = "tos-fw-cert",
+		.action = 0,
+		.action_arg = NULL
+	},
+	{
+		.name = "Non-Trusted Firmware content certificate",
+		.uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
+		.cmdline_name = "nt-fw-cert",
+		.action = 0,
+		.action_arg = NULL
+	},
+	{
+		.name = NULL,
+		.uuid = { 0 },
+		.cmdline_name = NULL,
+		.action = 0,
+		.action_arg = NULL
+	}
 };
 
 size_t toc_entries_len = sizeof(toc_entries) / sizeof(toc_entries[0]);
diff --git a/tools/fiptool/tbbr_config.h b/tools/fiptool/tbbr_config.h
index d771a9bbf..c45933598 100644
--- a/tools/fiptool/tbbr_config.h
+++ b/tools/fiptool/tbbr_config.h
@@ -42,7 +42,6 @@ typedef struct toc_entry {
 	const char   *name;
 	uuid_t        uuid;
 	const char   *cmdline_name;
-	struct image *image;
 	int           action;
 	char         *action_arg;
 } toc_entry_t;
-- 
GitLab