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>
diff --git a/tools/fiptool/fiptool.c b/tools/fiptool/fiptool.c
index b3f02f6..18d1222 100644
--- a/tools/fiptool/fiptool.c
+++ b/tools/fiptool/fiptool.c
@@ -187,7 +187,7 @@
 	}
 }
 
-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 @@
 	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 @@
 		    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 @@
 	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 @@
 	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 @@
 	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 @@
 	    (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 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 @@
 		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 @@
 		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 @@
 			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 @@
 		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 @@
 	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 0fe64c0..7705107 100644
--- a/tools/fiptool/fiptool.h
+++ b/tools/fiptool/fiptool.h
@@ -57,7 +57,6 @@
 	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 e8fbbba..b92e8da 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 d771a9b..c459335 100644
--- a/tools/fiptool/tbbr_config.h
+++ b/tools/fiptool/tbbr_config.h
@@ -42,7 +42,6 @@
 	const char   *name;
 	uuid_t        uuid;
 	const char   *cmdline_name;
-	struct image *image;
 	int           action;
 	char         *action_arg;
 } toc_entry_t;