layout: Introduce flashrom_layout_new()

It initializes an empty layout. Currently the maximum number of entries
has to be specified, which will vanish once we use dynamic allocation
per entry.

We replace the two special cases `single_layout` and `ich_layout` with
dynamically allocated layouts. As a result, we have to take care to
release the `default_layout` in a flashctx once we are done with it.

Change-Id: I2ae7246493ff592e631cce924777925c7825e398
Signed-off-by: Nico Huber <nico.h@gmx.de>
Original-Reviewed-on: https://review.coreboot.org/c/flashrom/+/33543
Original-Reviewed-by: Edward O'Callaghan <quasisec@chromium.org>
Original-Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-on: https://review.coreboot.org/c/flashrom-stable/+/72214
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/ich_descriptors.c b/ich_descriptors.c
index 585a8b0..61cf6fc 100644
--- a/ich_descriptors.c
+++ b/ich_descriptors.c
@@ -1338,7 +1338,9 @@
  *	   1 if the descriptor couldn't be parsed,
  *	   2 when out of memory.
  */
-int layout_from_ich_descriptors(struct ich_layout *const layout, const void *const dump, const size_t len)
+int layout_from_ich_descriptors(
+		struct flashrom_layout **const layout,
+		const void *const dump, const size_t len)
 {
 	static const char *const regions[] = {
 		"fd", "bios", "me", "gbe", "pd", "reg5", "bios2", "reg7", "ec", "reg9", "ie",
@@ -1350,10 +1352,8 @@
 	if (read_ich_descriptors_from_dump(dump, len, &cs, &desc))
 		return 1;
 
-	memset(layout, 0x00, sizeof(*layout));
-	layout->base.entries = layout->entries;
-	layout->base.capacity = ARRAY_SIZE(layout->entries);
-	layout->base.num_entries = 0;
+	if (flashrom_layout_new(layout, ARRAY_SIZE(regions)))
+		return 2;
 
 	ssize_t i;
 	const ssize_t nr = MIN(ich_number_of_regions(cs, &desc.content), (ssize_t)ARRAY_SIZE(regions));
@@ -1362,8 +1362,11 @@
 		const chipoff_t limit = ICH_FREG_LIMIT(desc.region.FLREGs[i]);
 		if (limit <= base)
 			continue;
-		if (flashrom_layout_add_region(&layout->base, base, limit, regions[i]))
+		if (flashrom_layout_add_region(*layout, base, limit, regions[i])) {
+			flashrom_layout_release(*layout);
+			*layout = NULL;
 			return 2;
+		}
 	}
 	return 0;
 }