/* cbfstool, CLI utility for CBFS file manipulation */
/* SPDX-License-Identifier: GPL-2.0-only */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#include <unistd.h>
#include <getopt.h>
#include "common.h"
#include "cbfs.h"
#include "cbfs_image.h"
#include "cbfs_sections.h"
#include "elfparsing.h"
#include "partitioned_file.h"
#include "lz4/lib/xxhash.h"
#include <commonlib/bsd/cbfs_private.h>
#include <commonlib/bsd/compression.h>
#include <commonlib/bsd/metadata_hash.h>
#include <commonlib/fsp.h>
#include <commonlib/endian.h>
#include <commonlib/helpers.h>
#include <commonlib/region.h>
#include <vboot_host.h>

struct command {
	const char *name;
	const char *optstring;
	int (*function) (void);
	// Whether to populate param.image_region before invoking function
	bool accesses_region;
	// This set to true means two things:
	// - in case of a command operating on a region, the region's contents
	//   will be written back to image_file at the end
	// - write access to the file is required
	bool modifies_region;
};

static struct param {
	partitioned_file_t *image_file;
	struct buffer *image_region;
	const char *name;
	const char *filename;
	const char *fmap;
	const char *region_name;
	const char *source_region;
	const char *bootblock;
	const char *ignore_section;
	const char *ucode_region;
	uint64_t u64val;
	uint32_t type;
	uint32_t baseaddress;
	/*
	 * Input can be negative. It will be transformed to offset from start of region (if
	 * negative) and stored in baseaddress.
	 */
	long long int baseaddress_input;
	uint32_t baseaddress_assigned;
	uint32_t loadaddress;
	uint32_t headeroffset;
	/*
	 * Input can be negative. It will be transformed to offset from start of region (if
	 * negative) and stored in baseaddress.
	 */
	long long int headeroffset_input;
	uint32_t headeroffset_assigned;
	uint32_t entrypoint;
	uint32_t size;
	uint32_t alignment;
	uint32_t pagesize;
	uint32_t cbfsoffset;
	/*
	 * Input can be negative. It will be transformed to corresponding region offset (if
	 * negative) and stored in baseaddress.
	 */
	long long int cbfsoffset_input;
	uint32_t cbfsoffset_assigned;
	uint32_t arch;
	uint32_t padding;
	uint32_t topswap_size;
	bool u64val_assigned;
	bool fill_partial_upward;
	bool fill_partial_downward;
	bool show_immutable;
	bool stage_xip;
	bool force_pow2_pagesize;
	bool autogen_attr;
	bool machine_parseable;
	bool unprocessed;
	bool ibb;
	enum cbfs_compression compression;
	int precompression;
	enum vb2_hash_algorithm hash;
	/* For linux payloads */
	char *initrd;
	char *cmdline;
	int force;
	/*
	 * Base and size of extended window for decoding SPI flash greater than 16MiB in host
	 * address space on x86 platforms. The assumptions here are:
	 * 1. Top 16MiB is still decoded in the fixed decode window just below 4G boundary.
	 * 2. Rest of the SPI flash below the top 16MiB is mapped at the top of extended
	 * window. Even though the platform might support a larger extended window, the SPI
	 * flash part used by the mainboard might not be large enough to be mapped in the entire
	 * window. In such cases, the mapping is assumed to be in the top part of the extended
	 * window with the bottom part remaining unused.
	 */
	uint32_t ext_win_base;
	uint32_t ext_win_size;
} param = {
	/* All variables not listed are initialized as zero. */
	.arch = CBFS_ARCHITECTURE_UNKNOWN,
	.compression = CBFS_COMPRESS_NONE,
	.hash = VB2_HASH_INVALID,
	.headeroffset = HEADER_OFFSET_UNKNOWN,
	.region_name = SECTION_NAME_PRIMARY_CBFS,
	.u64val = -1,
};

/*
 * This "metadata_hash cache" caches the value and location of the CBFS metadata
 * hash embedded in the bootblock when CBFS verification is enabled. The first
 * call to get_mh_cache() searches for the cache by scanning the whole bootblock
 * for its 8-byte signature, later calls will just return the previously found
 * information again. If the cbfs_hash.algo member in the result is
 * VB2_HASH_INVALID, that means no metadata hash was found and this image does
 * not use CBFS verification.
 */
struct mh_cache {
	const char *region;
	size_t offset;
	struct vb2_hash cbfs_hash;
	platform_fixup_func fixup;
	bool initialized;
};

static struct mh_cache *get_mh_cache(void)
{
	static struct mh_cache mhc;

	if (mhc.initialized)
		return &mhc;

	mhc.initialized = true;

	const struct fmap *fmap = partitioned_file_get_fmap(param.image_file);
	if (!fmap)
		goto no_metadata_hash;

	/* Find the metadata_hash container. If there is a "BOOTBLOCK" FMAP section, it's
	   there. If not, it's a normal file in the primary CBFS section. */
	size_t offset, size;
	struct buffer buffer;
	if (fmap_find_area(fmap, SECTION_NAME_BOOTBLOCK)) {
		if (!partitioned_file_read_region(&buffer, param.image_file,
						  SECTION_NAME_BOOTBLOCK))
			goto no_metadata_hash;
		mhc.region = SECTION_NAME_BOOTBLOCK;
		offset = 0;
		size = buffer.size;
	} else {
		struct cbfs_image cbfs;
		struct cbfs_file *mh_container;
		if (!partitioned_file_read_region(&buffer, param.image_file,
						  SECTION_NAME_PRIMARY_CBFS))
			goto no_metadata_hash;
		mhc.region = SECTION_NAME_PRIMARY_CBFS;
		if (cbfs_image_from_buffer(&cbfs, &buffer, param.headeroffset))
			goto no_metadata_hash;
		mh_container = cbfs_get_entry(&cbfs, "bootblock");
		if (!mh_container || be32toh(mh_container->type) != CBFS_TYPE_BOOTBLOCK) {
			/* Check for apu/amdfw file */
			mh_container = cbfs_get_entry(&cbfs, "apu/amdfw");
			if (!mh_container || be32toh(mh_container->type) != CBFS_TYPE_AMDFW)
				goto no_metadata_hash;
		}

		offset = (void *)mh_container + be32toh(mh_container->offset) -
			 buffer_get(&cbfs.buffer);
		size = be32toh(mh_container->len);
	}

	/* Find and validate the metadata hash anchor inside the containing file and
	   record its exact byte offset from the start of the FMAP region. */
	struct metadata_hash_anchor *anchor = memmem(buffer_get(&buffer) + offset,
			size, METADATA_HASH_ANCHOR_MAGIC, sizeof(anchor->magic));
	if (anchor) {
		if (!vb2_digest_size(anchor->cbfs_hash.algo)) {
			ERROR("Unknown CBFS metadata hash type: %d\n",
			      anchor->cbfs_hash.algo);
			goto no_metadata_hash;
		}
		mhc.cbfs_hash = anchor->cbfs_hash;
		mhc.offset = (void *)anchor - buffer_get(&buffer);
		mhc.fixup = platform_fixups_probe(&buffer, mhc.offset,
						  mhc.region);
		return &mhc;
	}

no_metadata_hash:
	mhc.cbfs_hash.algo = VB2_HASH_INVALID;
	return &mhc;
}

static void update_and_info(const char *name, void *dst, void *src, size_t size)
{
	if (!memcmp(dst, src, size))
		return;
	char *src_str = bintohex(src, size);
	char *dst_str = bintohex(dst, size);
	INFO("Updating %s from %s to %s\n", name, dst_str, src_str);
	memcpy(dst, src, size);
	free(src_str);
	free(dst_str);
}

static int update_anchor(struct mh_cache *mhc, uint8_t *fmap_hash)
{
	struct buffer buffer;
	if (!partitioned_file_read_region(&buffer, param.image_file,
					  mhc->region))
		return -1;
	struct metadata_hash_anchor *anchor = buffer_get(&buffer) + mhc->offset;
	/* The metadata hash anchor should always still be where we left it. */
	assert(!memcmp(anchor->magic, METADATA_HASH_ANCHOR_MAGIC,
		      sizeof(anchor->magic)) &&
	       anchor->cbfs_hash.algo == mhc->cbfs_hash.algo);
	update_and_info("CBFS metadata hash", anchor->cbfs_hash.raw,
		mhc->cbfs_hash.raw, vb2_digest_size(anchor->cbfs_hash.algo));
	if (fmap_hash) {
		update_and_info("FMAP hash",
				metadata_hash_anchor_fmap_hash(anchor), fmap_hash,
				vb2_digest_size(anchor->cbfs_hash.algo));
	}
	if (mhc->fixup && mhc->fixup(&buffer, mhc->offset) != 0)
		return -1;
	if (!partitioned_file_write_region(param.image_file, &buffer))
		return -1;
	return 0;

}

/* This should be called after every time CBFS metadata might have changed. It
   will recalculate and update the metadata hash in the bootblock if needed. */
static int maybe_update_metadata_hash(struct cbfs_image *cbfs)
{
	if (strcmp(param.region_name, SECTION_NAME_PRIMARY_CBFS))
		return 0;  /* Metadata hash only embedded in primary CBFS. */

	struct mh_cache *mhc = get_mh_cache();
	if (mhc->cbfs_hash.algo == VB2_HASH_INVALID)
		return 0;

	enum cb_err err = cbfs_walk(cbfs, NULL, NULL, &mhc->cbfs_hash,
				    CBFS_WALK_WRITEBACK_HASH);
	if (err != CB_CBFS_NOT_FOUND) {
		ERROR("Unexpected cbfs_walk() error %d\n", err);
		return -1;
	}

	return update_anchor(mhc, NULL);
}

/* This should be called after every time the FMAP or the bootblock itself might
   have changed, and will write the new FMAP hash into the metadata hash anchor
   in the bootblock if required (usually when the bootblock is first added). */
static int maybe_update_fmap_hash(void)
{
	if (strcmp(param.region_name, SECTION_NAME_BOOTBLOCK) &&
	    strcmp(param.region_name, SECTION_NAME_FMAP) &&
	    param.type != CBFS_TYPE_BOOTBLOCK &&
	    param.type != CBFS_TYPE_AMDFW)
		return 0;	/* FMAP and bootblock didn't change. */

	struct mh_cache *mhc = get_mh_cache();
	if (mhc->cbfs_hash.algo == VB2_HASH_INVALID)
		return 0;

	struct vb2_hash fmap_hash;
	const struct fmap *fmap = partitioned_file_get_fmap(param.image_file);
	if (!fmap || vb2_hash_calculate(false, fmap, fmap_size(fmap),
					mhc->cbfs_hash.algo, &fmap_hash))
		return -1;
	return update_anchor(mhc, fmap_hash.raw);
}

static bool verification_exclude(enum cbfs_type type)
{
	switch (type) {
	case CBFS_TYPE_BOOTBLOCK:
	case CBFS_TYPE_CBFSHEADER:
	case CBFS_TYPE_INTEL_FIT:
	case CBFS_TYPE_AMDFW:
		return true;
	default:
		return false;
	}
}

static bool region_is_flashmap(const char *region)
{
	return partitioned_file_region_check_magic(param.image_file, region,
					FMAP_SIGNATURE, strlen(FMAP_SIGNATURE));
}

/* @return Same as cbfs_is_valid_cbfs(), but for a named region. */
static bool region_is_modern_cbfs(const char *region)
{
	return partitioned_file_region_check_magic(param.image_file, region,
				CBFS_FILE_MAGIC, strlen(CBFS_FILE_MAGIC));
}

/* This describes a window from the SPI flash address space into the host address space. */
struct mmap_window {
	struct region flash_space;
	struct region host_space;
};

/* Should be enough for now */
#define MMAP_MAX_WINDOWS 3

/* Table of all the decode windows supported by the platform. */
static int mmap_window_table_size;
static struct mmap_window mmap_window_table[MMAP_MAX_WINDOWS];

static void add_mmap_window(size_t flash_offset, size_t host_offset,
			    size_t window_size)
{
	if (mmap_window_table_size >= MMAP_MAX_WINDOWS) {
		ERROR("Too many memory map windows\n");
		return;
	}

	mmap_window_table[mmap_window_table_size].flash_space.offset = flash_offset;
	mmap_window_table[mmap_window_table_size].host_space.offset = host_offset;
	mmap_window_table[mmap_window_table_size].flash_space.size = window_size;
	mmap_window_table[mmap_window_table_size].host_space.size = window_size;
	mmap_window_table_size++;
}


static int decode_mmap_arg(char *arg)
{
	if (arg == NULL)
		return 1;

	union {
		unsigned long int array[3];
		struct {
			unsigned long int flash_base;
			unsigned long int mmap_base;
			unsigned long int mmap_size;
		};
	} mmap_args;
	char *suffix = NULL;
	char *substring = strtok(arg, ":");
	for (size_t i = 0; i < ARRAY_SIZE(mmap_args.array); i++) {
		if (!substring) {
			ERROR("Invalid mmap arguments '%s'.\n",
			      arg);
			return 1;
		}
		mmap_args.array[i] = strtol(substring, &suffix, 0);
		if (suffix && *suffix) {
			ERROR("Invalid mmap arguments '%s'.\n",
			      arg);
			return 1;
		}
		substring = strtok(NULL, ":");
	}

	if (substring != NULL) {
		ERROR("Invalid argument, too many substrings '%s'.\n",
		      arg);

		return 1;
	}

	add_mmap_window(mmap_args.flash_base, mmap_args.mmap_base, mmap_args.mmap_size);
	return 0;
}

#define DEFAULT_DECODE_WINDOW_TOP	(4ULL * GiB)
#define DEFAULT_DECODE_WINDOW_MAX_SIZE	(16 * MiB)

static bool create_mmap_windows(void)
{
	static bool done;

	if (done)
		return done;

	// No memory map provided, use a default one
	if (mmap_window_table_size == 0) {
		const size_t image_size = partitioned_file_total_size(param.image_file);
		printf("Image SIZE %zu\n", image_size);
		const size_t std_window_size = MIN(DEFAULT_DECODE_WINDOW_MAX_SIZE, image_size);
		const size_t std_window_flash_offset = image_size - std_window_size;

		/*
		 * Default decode window lives just below 4G boundary in host space and maps up to a
		 * maximum of 16MiB. If the window is smaller than 16MiB, the SPI flash window is mapped
		 * at the top of the host window just below 4G.
		 */
		add_mmap_window(std_window_flash_offset, DEFAULT_DECODE_WINDOW_TOP - std_window_size, std_window_size);
	} else {
		/*
		 * Check provided memory map
		 */
		for (int i = 0; i < mmap_window_table_size; i++) {
			for (int j = i + 1; j < mmap_window_table_size; j++) {
				if (region_overlap(&mmap_window_table[i].flash_space,
						   &mmap_window_table[j].flash_space)) {
					ERROR("Flash space windows (base=0x%zx, limit=0x%zx) and (base=0x%zx, limit=0x%zx) overlap!\n",
					      region_offset(&mmap_window_table[i].flash_space),
					      region_end(&mmap_window_table[i].flash_space),
					      region_offset(&mmap_window_table[j].flash_space),
					      region_end(&mmap_window_table[j].flash_space));
					return false;
				}

				if (region_overlap(&mmap_window_table[i].host_space,
						   &mmap_window_table[j].host_space)) {
					ERROR("Host space windows (base=0x%zx, limit=0x%zx) and (base=0x%zx, limit=0x%zx) overlap!\n",
					      region_offset(&mmap_window_table[i].flash_space),
					      region_end(&mmap_window_table[i].flash_space),
					      region_offset(&mmap_window_table[j].flash_space),
					      region_end(&mmap_window_table[j].flash_space));
					return false;
				}
			}
		}
	}

	done = true;
	return done;
}

static unsigned int convert_address(const struct region *to, const struct region *from,
				    unsigned int addr)
{
	/*
	 * Calculate the offset in the "from" region and use that offset to calculate
	 * corresponding address in the "to" region.
	 */
	size_t offset = addr - region_offset(from);
	return region_offset(to) + offset;
}

enum mmap_addr_type {
	HOST_SPACE_ADDR,
	FLASH_SPACE_ADDR,
};

static int find_mmap_window(enum mmap_addr_type addr_type, unsigned int addr)
{
	size_t i;

	for (i = 0; i < ARRAY_SIZE(mmap_window_table); i++) {
		const struct region *reg;

		if (addr_type == HOST_SPACE_ADDR)
			reg = &mmap_window_table[i].host_space;
		else
			reg = &mmap_window_table[i].flash_space;

		if (region_offset(reg) <= addr &&
		   ((uint64_t)region_offset(reg) + (uint64_t)region_sz(reg) - 1) >= addr)
			return i;
	}

	return -1;
}

static unsigned int convert_host_to_flash(const struct buffer *region, unsigned int addr)
{
	int idx;
	const struct region *to, *from;

	idx = find_mmap_window(HOST_SPACE_ADDR, addr);
	if (idx == -1) {
		ERROR("Host address(%x) not in any mmap window!\n", addr);
		return 0;
	}

	to = &mmap_window_table[idx].flash_space;
	from = &mmap_window_table[idx].host_space;

	/* region->offset is subtracted because caller expects offset in the given region. */
	return convert_address(to, from, addr) - region->offset;
}

static unsigned int convert_flash_to_host(const struct buffer *region, unsigned int addr)
{
	int idx;
	const struct region *to, *from;

	/*
	 * region->offset is added because caller provides offset in the given region. This is
	 * converted to an absolute address in the SPI flash space. This is done before the
	 * conversion as opposed to after in convert_host_to_flash() above because the address
	 * is actually an offset within the region. So, it needs to be converted into an
	 * absolute address in the SPI flash space before converting into an address in host
	 * space.
	 */
	addr += region->offset;
	idx = find_mmap_window(FLASH_SPACE_ADDR, addr);

	if (idx == -1) {
		ERROR("SPI flash address(%x) not in any mmap window!\n", addr);
		return 0;
	}

	to = &mmap_window_table[idx].host_space;
	from = &mmap_window_table[idx].flash_space;

	return convert_address(to, from, addr);
}

static unsigned int convert_addr_space(const struct buffer *region, unsigned int addr)
{
	assert(region);

	assert(create_mmap_windows());

	if (IS_HOST_SPACE_ADDRESS(addr))
		return convert_host_to_flash(region, addr);
	else
		return convert_flash_to_host(region, addr);
}

/*
 * This function takes offset value which represents the offset from one end of the region and
 * converts it to offset from the other end of the region. offset is expected to be positive.
 */
static int convert_region_offset(unsigned int offset, uint32_t *region_offset)
{
	size_t size;

	if (param.size) {
		size = param.size;
	} else {
		assert(param.image_region);
		size = param.image_region->size;
	}

	if (size < offset) {
		ERROR("Cannot convert region offset (size=0x%zx, offset=0x%x)\n", size, offset);
		return 1;
	}

	*region_offset = size - offset;
	return 0;
}

static int do_cbfs_locate(uint32_t *cbfs_addr, size_t data_size)
{
	uint32_t metadata_size = 0;

	if (!param.name) {
		ERROR("You need to specify -n/--name.\n");
		return 1;
	}

	struct cbfs_image image;
	if (cbfs_image_from_buffer(&image, param.image_region,
							param.headeroffset))
		return 1;

	if (cbfs_get_entry(&image, param.name))
		WARN("'%s' already in CBFS.\n", param.name);

	if (!data_size) {
		ERROR("File '%s' is empty?\n", param.name);
		return 1;
	}

	/* Compute required page size */
	if (param.force_pow2_pagesize) {
		param.pagesize = 1;
		while (param.pagesize < data_size)
			param.pagesize <<= 1;
		DEBUG("Page size is %d (0x%x)\n", param.pagesize, param.pagesize);
	}

	/* Include cbfs_file size along with space for with name. */
	metadata_size += cbfs_calculate_file_header_size(param.name);
	/* Adjust metadata_size if additional attributes were added */
	if (param.autogen_attr) {
		if (param.alignment)
			metadata_size += sizeof(struct cbfs_file_attr_align);
		if (param.baseaddress_assigned || param.stage_xip)
			metadata_size += sizeof(struct cbfs_file_attr_position);
	}
	if (param.precompression || param.compression != CBFS_COMPRESS_NONE)
		metadata_size += sizeof(struct cbfs_file_attr_compression);
	if (param.type == CBFS_TYPE_STAGE)
		metadata_size += sizeof(struct cbfs_file_attr_stageheader);

	/* Take care of the hash attribute if it is used */
	if (param.hash != VB2_HASH_INVALID)
		metadata_size += cbfs_file_attr_hash_size(param.hash);

	int32_t address = cbfs_locate_entry(&image, data_size, param.pagesize,
						param.alignment, metadata_size);

	if (address < 0) {
		ERROR("'%s'(%u + %zu) can't fit in CBFS for page-size %#x, align %#x.\n",
		      param.name, metadata_size, data_size, param.pagesize, param.alignment);
		return 1;
	}

	*cbfs_addr = address;
	return 0;
}

typedef int (*convert_buffer_t)(struct buffer *buffer, uint32_t *offset,
	struct cbfs_file *header);

static int cbfs_add_integer_component(const char *name,
			      uint64_t u64val,
			      uint32_t offset,
			      uint32_t headeroffset) {
	struct cbfs_image image;
	struct cbfs_file *header = NULL;
	struct buffer buffer;
	int i, ret = 1;

	if (!name) {
		ERROR("You need to specify -n/--name.\n");
		return 1;
	}

	if (buffer_create(&buffer, 8, name) != 0)
		return 1;

	for (i = 0; i < 8; i++)
		buffer.data[i] = (u64val >> i*8) & 0xff;

	if (cbfs_image_from_buffer(&image, param.image_region, headeroffset)) {
		ERROR("Selected image region is not a CBFS.\n");
		goto done;
	}

	if (cbfs_get_entry(&image, name)) {
		ERROR("'%s' already in ROM image.\n", name);
		goto done;
	}

	header = cbfs_create_file_header(CBFS_TYPE_RAW,
		buffer.size, name);

	enum vb2_hash_algorithm algo = get_mh_cache()->cbfs_hash.algo;
	if (algo != VB2_HASH_INVALID)
		if (cbfs_add_file_hash(header, &buffer, algo)) {
			ERROR("couldn't add hash for '%s'\n", name);
			goto done;
		}

	if (cbfs_add_entry(&image, &buffer, offset, header, 0) != 0) {
		ERROR("Failed to add %llu into ROM image as '%s'.\n",
					(long long unsigned)u64val, name);
		goto done;
	}

	ret = maybe_update_metadata_hash(&image);

done:
	free(header);
	buffer_delete(&buffer);
	return ret;
}

static int is_valid_topswap(void)
{
	switch (param.topswap_size) {
	case (64 * KiB):
	case (128 * KiB):
	case (256 * KiB):
	case (512 * KiB):
	case (1 * MiB):
		break;
	default:
		ERROR("Invalid topswap_size %d, topswap can be 64K|128K|256K|512K|1M\n",
							param.topswap_size);
		return 0;
	}
	return 1;
}

static void fill_header_offset(void *location, uint32_t offset)
{
	// TODO: When we have a BE target, we'll need to store this as BE
	write_le32(location, offset);
}

static int update_master_header_loc_topswap(struct cbfs_image *image,
				void *h_loc, uint32_t header_offset)
{
	struct cbfs_file *entry;
	void *ts_h_loc = h_loc;

	entry = cbfs_get_entry(image, "bootblock");
	if (entry == NULL) {
		ERROR("Bootblock not in ROM image?!?\n");
		return 1;
	}

	/*
	 * Check if the existing topswap boundary matches with
	 * the one provided.
	 */
	if (param.topswap_size != be32toh(entry->len)/2) {
		ERROR("Top swap boundary does not match\n");
		return 1;
	}

	ts_h_loc -= param.topswap_size;
	fill_header_offset(ts_h_loc, header_offset);

	return 0;
}

static int cbfs_add_master_header(void)
{
	const char * const name = "cbfs master header";
	struct cbfs_image image;
	struct cbfs_file *header = NULL;
	struct buffer buffer;
	int ret = 1;
	size_t offset;
	size_t size;
	void *h_loc;

	if (cbfs_image_from_buffer(&image, param.image_region,
		param.headeroffset)) {
		ERROR("Selected image region is not a CBFS.\n");
		return 1;
	}

	if (cbfs_get_entry(&image, name)) {
		ERROR("'%s' already in ROM image.\n", name);
		return 1;
	}

	if (buffer_create(&buffer, sizeof(struct cbfs_header), name) != 0)
		return 1;

	struct cbfs_header *h = (struct cbfs_header *)buffer.data;
	h->magic = htobe32(CBFS_HEADER_MAGIC);
	h->version = htobe32(CBFS_HEADER_VERSION);
	/* The 4 bytes are left out for two reasons:
	 * 1. the cbfs master header pointer resides there
	 * 2. some cbfs implementations assume that an image that resides
	 *    below 4GB has a bootblock and get confused when the end of the
	 *    image is at 4GB == 0.
	 */
	h->bootblocksize = htobe32(4);
	h->align = htobe32(CBFS_ALIGNMENT);
	/* The offset and romsize fields within the master header are absolute
	 * values within the boot media. As such, romsize needs to relfect
	 * the end 'offset' for a CBFS. To achieve that the current buffer
	 * representing the CBFS region's size is added to the offset of
	 * the region within a larger image.
	 */
	offset = buffer_get(param.image_region) -
		buffer_get_original_backing(param.image_region);
	size = buffer_size(param.image_region);
	h->romsize = htobe32(size + offset);
	h->offset = htobe32(offset);
	h->architecture = htobe32(CBFS_ARCHITECTURE_UNKNOWN);

	/* Never add a hash attribute to the master header. */
	header = cbfs_create_file_header(CBFS_TYPE_CBFSHEADER,
		buffer_size(&buffer), name);
	if (cbfs_add_entry(&image, &buffer, 0, header, 0) != 0) {
		ERROR("Failed to add cbfs master header into ROM image.\n");
		goto done;
	}

	struct cbfs_file *entry;
	if ((entry = cbfs_get_entry(&image, name)) == NULL) {
		ERROR("'%s' not in ROM image?!?\n", name);
		goto done;
	}

	uint32_t header_offset = CBFS_SUBHEADER(entry) -
		buffer_get(&image.buffer);
	header_offset = -(buffer_size(&image.buffer) - header_offset);

	h_loc = (void *)(buffer_get(&image.buffer) +
				buffer_size(&image.buffer) - 4);
	fill_header_offset(h_loc, header_offset);
	/*
	 * If top swap present, update the header
	 * location in secondary bootblock
	 */
	if (param.topswap_size) {
		if (update_master_header_loc_topswap(&image, h_loc,
						     header_offset))
			goto done;
	}

	ret = maybe_update_metadata_hash(&image);

done:
	free(header);
	buffer_delete(&buffer);
	return ret;
}

static int add_topswap_bootblock(struct buffer *buffer, uint32_t *offset)
{
	size_t bb_buf_size = buffer_size(buffer);

	if (bb_buf_size > param.topswap_size) {
		ERROR("Bootblock bigger than the topswap boundary\n");
		ERROR("size = %zd, ts = %d\n", bb_buf_size,
							param.topswap_size);
		return 1;
	}

	/*
	 * Allocate topswap_size*2 bytes for bootblock to
	 * accommodate the second bootblock.
	 */
	struct buffer new_bootblock, bb1, bb2;
	if (buffer_create(&new_bootblock, 2 * param.topswap_size,
							buffer->name))
		return 1;

	buffer_splice(&bb1, &new_bootblock, param.topswap_size - bb_buf_size,
							bb_buf_size);
	buffer_splice(&bb2, &new_bootblock,
				buffer_size(&new_bootblock) - bb_buf_size,
							bb_buf_size);

	/* Copy to first bootblock */
	memcpy(buffer_get(&bb1), buffer_get(buffer), bb_buf_size);
	/* Copy to second bootblock */
	memcpy(buffer_get(&bb2), buffer_get(buffer), bb_buf_size);

	buffer_delete(buffer);
	buffer_clone(buffer, &new_bootblock);

	 /* Update the location (offset) of bootblock in the region */
	return convert_region_offset(buffer_size(buffer), offset);
}

static int cbfs_add_component(const char *filename,
			      const char *name,
			      uint32_t headeroffset,
			      convert_buffer_t convert)
{
	/*
	 * The steps used to determine the final placement offset in CBFS, in order:
	 *
	 * 1. If --base-address was passed, that value is used. If it was passed in the host
	 *    address space, convert it to flash address space. (After that, |*offset| is always
	 *    in the flash address space.)
	 *
	 * 2. The convert() function may write a location back to |offset|, usually by calling
	 *    do_cbfs_locate(). In this case, it needs to ensure that the location found can fit
	 *    the CBFS file in its final form (after any compression and conversion).
	 *
	 * 3. If --align was passed and the offset is still undecided at this point,
	 *    do_cbfs_locate() is called to find an appropriately aligned location.
	 *
	 * 4. If |offset| is still 0 at the end, cbfs_add_entry() will find the first available
	 *    location that fits.
	 */
	uint32_t offset = param.baseaddress_assigned ? param.baseaddress : 0;
	size_t len_align = 0;

	if (param.alignment && param.baseaddress_assigned) {
		ERROR("Cannot specify both alignment and base address\n");
		return 1;
	}

	if (param.stage_xip && param.compression != CBFS_COMPRESS_NONE) {
		ERROR("Cannot specify compression for XIP.\n");
		return 1;
	}

	if (!filename) {
		ERROR("You need to specify -f/--filename.\n");
		return 1;
	}

	if (!name) {
		ERROR("You need to specify -n/--name.\n");
		return 1;
	}

	if (param.type == 0) {
		ERROR("You need to specify a valid -t/--type.\n");
		return 1;
	}

	struct cbfs_image image;
	if (cbfs_image_from_buffer(&image, param.image_region, headeroffset))
		return 1;

	if (cbfs_get_entry(&image, name)) {
		ERROR("'%s' already in ROM image.\n", name);
		return 1;
	}

	struct buffer buffer;
	if (buffer_from_file(&buffer, filename) != 0) {
		ERROR("Could not load file '%s'.\n", filename);
		return 1;
	}

	struct cbfs_file *header =
		cbfs_create_file_header(param.type, buffer.size, name);

	/* Bootblock and CBFS header should never have file hashes. When adding
	   the bootblock it is important that we *don't* look up the metadata
	   hash yet (before it is added) or we'll cache an outdated result. */
	if (!verification_exclude(param.type)) {
		enum vb2_hash_algorithm mh_algo = get_mh_cache()->cbfs_hash.algo;
		if (mh_algo != VB2_HASH_INVALID && param.hash != mh_algo) {
			if (param.hash == VB2_HASH_INVALID) {
				param.hash = mh_algo;
			} else {
				ERROR("Cannot specify hash %s that's different from metadata hash algorithm %s\n",
				      vb2_get_hash_algorithm_name(param.hash),
				      vb2_get_hash_algorithm_name(mh_algo));
				goto error;
			}
		}
	}

	/*
	 * Check if Intel CPU topswap is specified this will require a
	 * second bootblock to be added.
	 */
	if (param.type == CBFS_TYPE_BOOTBLOCK && param.topswap_size)
		if (add_topswap_bootblock(&buffer, &offset))
			goto error;

	/* With --base-address we allow host space addresses -- if so, convert it here. */
	if (IS_HOST_SPACE_ADDRESS(offset))
		offset = convert_addr_space(param.image_region, offset);

	if (convert && convert(&buffer, &offset, header) != 0) {
		ERROR("Failed to parse file '%s'.\n", filename);
		goto error;
	}

	/* This needs to run after convert() to take compression into account. */
	if (!offset && param.alignment)
		if (do_cbfs_locate(&offset, buffer_size(&buffer)))
			goto error;

	/* This needs to run after convert() to hash the actual final file data. */
	if (param.hash != VB2_HASH_INVALID &&
	    cbfs_add_file_hash(header, &buffer, param.hash) == -1) {
		ERROR("couldn't add hash for '%s'\n", name);
		goto error;
	}

	if (param.autogen_attr) {
		/* Add position attribute if assigned */
		if (param.baseaddress_assigned || param.stage_xip) {
			struct cbfs_file_attr_position *attrs =
				(struct cbfs_file_attr_position *)
				cbfs_add_file_attr(header,
					CBFS_FILE_ATTR_TAG_POSITION,
					sizeof(struct cbfs_file_attr_position));
			if (attrs == NULL)
				goto error;
			attrs->position = htobe32(offset);
		}
		/* Add alignment attribute if used */
		if (param.alignment) {
			struct cbfs_file_attr_align *attrs =
				(struct cbfs_file_attr_align *)
				cbfs_add_file_attr(header,
					CBFS_FILE_ATTR_TAG_ALIGNMENT,
					sizeof(struct cbfs_file_attr_align));
			if (attrs == NULL)
				goto error;
			attrs->alignment = htobe32(param.alignment);
		}
	}

	if (param.ibb) {
		/* Mark as Initial Boot Block */
		struct cbfs_file_attribute *attrs = cbfs_add_file_attr(header,
				CBFS_FILE_ATTR_TAG_IBB,
				sizeof(struct cbfs_file_attribute));
		if (attrs == NULL)
			goto error;
		/* For Intel TXT minimum align is 16 */
		len_align = 16;
	}

	if (param.padding) {
		const uint32_t hs = sizeof(struct cbfs_file_attribute);
		uint32_t size = ALIGN_UP(MAX(hs, param.padding),
					 CBFS_ATTRIBUTE_ALIGN);
		INFO("Padding %d bytes\n", size);
		struct cbfs_file_attribute *attr =
			(struct cbfs_file_attribute *)cbfs_add_file_attr(
					header, CBFS_FILE_ATTR_TAG_PADDING,
					size);
		if (attr == NULL)
			goto error;
	}

	if (cbfs_add_entry(&image, &buffer, offset, header, len_align) != 0) {
		ERROR("Failed to add '%s' into ROM image.\n", filename);
		goto error;
	}

	free(header);
	buffer_delete(&buffer);

	return maybe_update_metadata_hash(&image) || maybe_update_fmap_hash();

error:
	free(header);
	buffer_delete(&buffer);
	return 1;
}

static int cbfstool_convert_raw(struct buffer *buffer,
	unused uint32_t *offset, struct cbfs_file *header)
{
	char *compressed;
	int decompressed_size, compressed_size;
	comp_func_ptr compress;

	decompressed_size = buffer->size;
	if (param.precompression) {
		param.compression = read_le32(buffer->data);
		decompressed_size = read_le32(buffer->data + sizeof(uint32_t));
		compressed_size = buffer->size - 8;
		compressed = malloc(compressed_size);
		if (!compressed)
			return -1;
		memcpy(compressed, buffer->data + 8, compressed_size);
	} else {
		if (param.compression == CBFS_COMPRESS_NONE)
			goto out;

		compress = compression_function(param.compression);
		if (!compress)
			return -1;
		compressed = calloc(buffer->size, 1);
		if (!compressed)
			return -1;

		if (compress(buffer->data, buffer->size,
			     compressed, &compressed_size)) {
			WARN("Compression failed - disabled\n");
			free(compressed);
			goto out;
		}
	}

	struct cbfs_file_attr_compression *attrs =
		(struct cbfs_file_attr_compression *)
		cbfs_add_file_attr(header,
			CBFS_FILE_ATTR_TAG_COMPRESSION,
			sizeof(struct cbfs_file_attr_compression));
	if (attrs == NULL) {
		free(compressed);
		return -1;
	}
	attrs->compression = htobe32(param.compression);
	attrs->decompressed_size = htobe32(decompressed_size);

	free(buffer->data);
	buffer->data = compressed;
	buffer->size = compressed_size;

out:
	header->len = htobe32(buffer->size);
	return 0;
}

static int cbfstool_convert_fsp(struct buffer *buffer,
				uint32_t *offset, struct cbfs_file *header)
{
	uint32_t address;
	struct buffer fsp;

	/*
	 * There are 4 different cases here:
	 *
	 * 1. --xip and --base-address: we need to place the binary at the given base address
	 *    in the CBFS image and relocate it to that address. *offset was already filled in,
	 *    but we need to convert it to the host address space for relocation.
	 *
	 * 2. --xip but no --base-address: we implicitly force a 4K minimum alignment so that
	 *    relocation can occur. Call do_cbfs_locate() here to find an appropriate *offset.
	 *    This also needs to be converted to the host address space for relocation.
	 *
	 * 3. No --xip but a --base-address: special case where --base-address does not have its
	 *    normal meaning, instead we use it as the relocation target address. We explicitly
	 *    reset *offset to 0 so that the file will be placed wherever it fits in CBFS.
	 *
	 * 4. No --xip and no --base-address: this means that the FSP was pre-linked and should
	 *    not be relocated. Just chain directly to convert_raw() for compression.
	 */

	if (param.stage_xip) {
		if (!param.baseaddress_assigned) {
			param.alignment = 4*1024;
			if (do_cbfs_locate(offset, buffer_size(buffer)))
				return -1;
		}
		assert(!IS_HOST_SPACE_ADDRESS(*offset));
		address = convert_addr_space(param.image_region, *offset);
	} else {
		if (param.baseaddress_assigned == 0) {
			INFO("Honoring pre-linked FSP module, no relocation.\n");
			return cbfstool_convert_raw(buffer, offset, header);
		} else {
			address = param.baseaddress;
			*offset = 0;
		}
	}

	/* Create a copy of the buffer to attempt relocation. */
	if (buffer_create(&fsp, buffer_size(buffer), "fsp"))
		return -1;

	memcpy(buffer_get(&fsp), buffer_get(buffer), buffer_size(buffer));

	/* Replace the buffer contents w/ the relocated ones on success. */
	if (fsp_component_relocate(address, buffer_get(&fsp), buffer_size(&fsp))
	    > 0) {
		buffer_delete(buffer);
		buffer_clone(buffer, &fsp);
	} else {
		buffer_delete(&fsp);
		WARN("Invalid FSP variant.\n");
	}

	/* Let the raw path handle all the cbfs metadata logic. */
	return cbfstool_convert_raw(buffer, offset, header);
}

static int cbfstool_convert_mkstage(struct buffer *buffer, uint32_t *offset,
	struct cbfs_file *header)
{
	struct buffer output;
	size_t data_size;
	int ret;

	if (elf_program_file_size(buffer, &data_size) < 0) {
		ERROR("Could not obtain ELF size\n");
		return 1;
	}

	/*
	 * We need a final location for XIP parsing, so we need to call do_cbfs_locate() early
	 * here. That is okay because XIP stages may not be compressed, so their size cannot
	 * change anymore at a later point.
	 */
	if (param.stage_xip &&
	    do_cbfs_locate(offset, data_size))  {
		ERROR("Could not find location for stage.\n");
		return 1;
	}

	struct cbfs_file_attr_stageheader *stageheader = (void *)
		cbfs_add_file_attr(header, CBFS_FILE_ATTR_TAG_STAGEHEADER,
				   sizeof(struct cbfs_file_attr_stageheader));
	if (!stageheader)
		return -1;

	if (param.stage_xip) {
		uint32_t host_space_address = convert_addr_space(param.image_region, *offset);
		assert(IS_HOST_SPACE_ADDRESS(host_space_address));
		ret = parse_elf_to_xip_stage(buffer, &output, host_space_address,
					     param.ignore_section, stageheader);
	} else {
		ret = parse_elf_to_stage(buffer, &output, param.ignore_section,
					 stageheader);
	}
	if (ret != 0)
		return -1;

	/* Store a hash of original uncompressed stage to compare later. */
	size_t decmp_size = buffer_size(&output);
	uint32_t decmp_hash = XXH32(buffer_get(&output), decmp_size, 0);

	/* Chain to base conversion routine to handle compression. */
	ret = cbfstool_convert_raw(&output, offset, header);
	if (ret != 0)
		goto fail;

	/* Special care must be taken for LZ4-compressed stages that the BSS is
	   large enough to provide scratch space for in-place decompression. */
	if (!param.precompression && param.compression == CBFS_COMPRESS_LZ4) {
		size_t memlen = be32toh(stageheader->memlen);
		size_t compressed_size = buffer_size(&output);
		uint8_t *compare_buffer = malloc(memlen);
		uint8_t *start = compare_buffer + memlen - compressed_size;
		if (!compare_buffer) {
			ERROR("Out of memory\n");
			goto fail;
		}
		memcpy(start, buffer_get(&output), compressed_size);
		ret = ulz4fn(start, compressed_size, compare_buffer, memlen);
		if  (ret == 0) {
			ERROR("Not enough scratch space to decompress LZ4 in-place -- increase BSS size or disable compression!\n");
			free(compare_buffer);
			goto fail;
		} else if (ret != (int)decmp_size ||
			   decmp_hash != XXH32(compare_buffer, decmp_size, 0)) {
			ERROR("LZ4 compression BUG! Report to mailing list.\n");
			free(compare_buffer);
			goto fail;
		}
		free(compare_buffer);
	}

	buffer_delete(buffer);
	buffer_clone(buffer, &output);
	return 0;

fail:
	buffer_delete(&output);
	return -1;
}

static int cbfstool_convert_mkpayload(struct buffer *buffer,
	unused uint32_t *offset, struct cbfs_file *header)
{
	struct buffer output;
	int ret;
	/* Per default, try and see if payload is an ELF binary */
	ret = parse_elf_to_payload(buffer, &output, param.compression);

	/* If it's not an ELF, see if it's a FIT */
	if (ret != 0) {
		ret = parse_fit_to_payload(buffer, &output, param.compression);
		if (ret == 0)
			header->type = htobe32(CBFS_TYPE_FIT_PAYLOAD);
	}

	/* If it's not an FIT, see if it's a UEFI FV */
	if (ret != 0)
		ret = parse_fv_to_payload(buffer, &output, param.compression);

	/* If it's neither ELF nor UEFI Fv, try bzImage */
	if (ret != 0)
		ret = parse_bzImage_to_payload(buffer, &output,
				param.initrd, param.cmdline, param.compression);

	/* Not a supported payload type */
	if (ret != 0) {
		ERROR("Not a supported payload type (ELF / FV).\n");
		buffer_delete(buffer);
		return -1;
	}

	buffer_delete(buffer);
	// Direct assign, no dupe.
	memcpy(buffer, &output, sizeof(*buffer));
	header->len = htobe32(output.size);
	return 0;
}

static int cbfstool_convert_mkflatpayload(struct buffer *buffer,
	unused uint32_t *offset, struct cbfs_file *header)
{
	struct buffer output;
	if (parse_flat_binary_to_payload(buffer, &output,
					 param.loadaddress,
					 param.entrypoint,
					 param.compression) != 0) {
		return -1;
	}
	buffer_delete(buffer);
	// Direct assign, no dupe.
	memcpy(buffer, &output, sizeof(*buffer));
	header->len = htobe32(output.size);
	return 0;
}

static int cbfs_add(void)
{
	convert_buffer_t convert = cbfstool_convert_raw;

	if (param.type == CBFS_TYPE_FSP) {
		convert = cbfstool_convert_fsp;
	} else if (param.type == CBFS_TYPE_STAGE) {
		ERROR("stages can only be added with cbfstool add-stage\n");
		return 1;
	} else if (param.stage_xip) {
		ERROR("cbfstool add supports xip only for FSP component type\n");
		return 1;
	}

	return cbfs_add_component(param.filename,
				  param.name,
				  param.headeroffset,
				  convert);
}

static int cbfs_add_stage(void)
{
	if (param.stage_xip && param.baseaddress_assigned) {
		ERROR("Cannot specify base address for XIP.\n");
		return 1;
	}
	param.type = CBFS_TYPE_STAGE;

	return cbfs_add_component(param.filename,
				  param.name,
				  param.headeroffset,
				  cbfstool_convert_mkstage);
}

static int cbfs_add_payload(void)
{
	param.type = CBFS_TYPE_SELF;
	return cbfs_add_component(param.filename,
				  param.name,
				  param.headeroffset,
				  cbfstool_convert_mkpayload);
}

static int cbfs_add_flat_binary(void)
{
	if (param.loadaddress == 0) {
		ERROR("You need to specify a valid "
			"-l/--load-address.\n");
		return 1;
	}
	if (param.entrypoint == 0) {
		ERROR("You need to specify a valid "
			"-e/--entry-point.\n");
		return 1;
	}
	param.type = CBFS_TYPE_SELF;
	return cbfs_add_component(param.filename,
				  param.name,
				  param.headeroffset,
				  cbfstool_convert_mkflatpayload);
}

static int cbfs_add_integer(void)
{
	if (!param.u64val_assigned) {
		ERROR("You need to specify a value to write.\n");
		return 1;
	}
	return cbfs_add_integer_component(param.name,
				  param.u64val,
				  param.baseaddress,
				  param.headeroffset);
}

static int cbfs_remove(void)
{
	if (!param.name) {
		ERROR("You need to specify -n/--name.\n");
		return 1;
	}

	struct cbfs_image image;
	if (cbfs_image_from_buffer(&image, param.image_region,
							param.headeroffset))
		return 1;

	if (cbfs_remove_entry(&image, param.name) != 0) {
		ERROR("Removing file '%s' failed.\n",
		      param.name);
		return 1;
	}

	return maybe_update_metadata_hash(&image);
}

static int cbfs_create(void)
{
	struct cbfs_image image;
	memset(&image, 0, sizeof(image));
	buffer_clone(&image.buffer, param.image_region);

	if (param.fmap) {
		if (param.arch != CBFS_ARCHITECTURE_UNKNOWN || param.size ||
						param.baseaddress_assigned ||
						param.headeroffset_assigned ||
						param.cbfsoffset_assigned ||
							param.bootblock) {
			ERROR("Since -M was provided, -m, -s, -b, -o, -H, and -B should be omitted\n");
			return 1;
		}

		return cbfs_image_create(&image, image.buffer.size);
	}

	if (param.arch == CBFS_ARCHITECTURE_UNKNOWN) {
		ERROR("You need to specify -m/--machine arch.\n");
		return 1;
	}

	struct buffer bootblock;
	if (!param.bootblock) {
		DEBUG("-B not given, creating image without bootblock.\n");
		if (buffer_create(&bootblock, 0, "(dummy)") != 0)
			return 1;
	} else if (buffer_from_file(&bootblock, param.bootblock)) {
		return 1;
	}

	if (!param.alignment)
		param.alignment = CBFS_ALIGNMENT;

	// Set default offsets. x86, as usual, needs to be a special snowflake.
	if (!param.baseaddress_assigned) {
		if (param.arch == CBFS_ARCHITECTURE_X86) {
			// Make sure there's at least enough room for rel_offset
			param.baseaddress = param.size -
					MAX(bootblock.size, sizeof(int32_t));
			DEBUG("x86 -> bootblock lies at end of ROM (%#x).\n",
			      param.baseaddress);
		} else {
			param.baseaddress = 0;
			DEBUG("bootblock starts at address 0x0.\n");
		}
	}
	if (!param.headeroffset_assigned) {
		if (param.arch == CBFS_ARCHITECTURE_X86) {
			param.headeroffset = param.baseaddress -
					     sizeof(struct cbfs_header);
			DEBUG("x86 -> CBFS header before bootblock (%#x).\n",
				param.headeroffset);
		} else {
			param.headeroffset = align_up(param.baseaddress +
				bootblock.size, sizeof(uint32_t));
			DEBUG("CBFS header placed behind bootblock (%#x).\n",
				param.headeroffset);
		}
	}
	if (!param.cbfsoffset_assigned) {
		if (param.arch == CBFS_ARCHITECTURE_X86) {
			param.cbfsoffset = 0;
			DEBUG("x86 -> CBFS entries start at address 0x0.\n");
		} else {
			param.cbfsoffset = align_up(param.headeroffset +
						    sizeof(struct cbfs_header),
						    CBFS_ALIGNMENT);
			DEBUG("CBFS entries start beind master header (%#x).\n",
			      param.cbfsoffset);
		}
	}

	int ret = cbfs_legacy_image_create(&image,
					   param.arch,
					   CBFS_ALIGNMENT,
					   &bootblock,
					   param.baseaddress,
					   param.headeroffset,
					   param.cbfsoffset);
	buffer_delete(&bootblock);
	return ret;
}

static int cbfs_layout(void)
{
	const struct fmap *fmap = partitioned_file_get_fmap(param.image_file);
	if (!fmap) {
		LOG("This is a legacy image composed entirely of a single CBFS.\n");
		return 1;
	}

	printf("This image contains the following sections that can be %s with this tool:\n",
			param.show_immutable ? "accessed" : "manipulated");
	puts("");
	for (unsigned i = 0; i < fmap->nareas; ++i) {
		const struct fmap_area *current = fmap->areas + i;

		bool readonly = partitioned_file_fmap_count(param.image_file,
			partitioned_file_fmap_select_children_of, current) ||
				region_is_flashmap((const char *)current->name);
		if (!param.show_immutable && readonly)
			continue;

		printf("'%s'", current->name);

		// Detect consecutive sections that describe the same region and
		// show them as aliases. This cannot find equivalent entries
		// that aren't adjacent; however, fmaptool doesn't generate
		// FMAPs with such sections, so this convenience feature works
		// for all but the strangest manually created FMAP binaries.
		// TODO: This could be done by parsing the FMAP into some kind
		// of tree that had duplicate lists in addition to child lists,
		// which would allow covering that weird, unlikely case as well.
		unsigned lookahead;
		for (lookahead = 1; i + lookahead < fmap->nareas;
								++lookahead) {
			const struct fmap_area *consecutive =
					fmap->areas + i + lookahead;
			if (consecutive->offset != current->offset ||
					consecutive->size != current->size)
				break;
			printf(", '%s'", consecutive->name);
		}
		if (lookahead > 1)
			fputs(" are aliases for the same region", stdout);

		const char *qualifier = "";
		if (readonly)
			qualifier = "read-only, ";
		else if (region_is_modern_cbfs((const char *)current->name))
			qualifier = "CBFS, ";
		else if (current->flags & FMAP_AREA_PRESERVE)
			qualifier = "preserve, ";
		printf(" (%ssize %u, offset %u)\n", qualifier, current->size,
				current->offset);

		i += lookahead - 1;
	}
	puts("");

	if (param.show_immutable) {
		puts("It is at least possible to perform the read action on every section listed above.");
	} else {
		puts("It is possible to perform either the write action or the CBFS add/remove actions on every section listed above.");
		puts("To see the image's read-only sections as well, rerun with the -w option.");
	}

	return 0;
}

static enum cb_err verify_walker(__always_unused cbfs_dev_t dev, size_t offset,
				 const union cbfs_mdata *mdata, size_t already_read, void *arg)
{
	uint32_t type = be32toh(mdata->h.type);
	uint32_t data_offset = be32toh(mdata->h.offset);
	if (verification_exclude(type))
		return CB_CBFS_NOT_FOUND;
	assert(already_read == data_offset);
	const struct vb2_hash *hash = cbfs_file_hash(mdata);
	if (!hash)
		return CB_ERR;
	void *file_data = arg + offset + data_offset;
	if (vb2_hash_verify(false, file_data, be32toh(mdata->h.len), hash) != VB2_SUCCESS)
		return CB_CBFS_HASH_MISMATCH;
	return CB_CBFS_NOT_FOUND;
}

static int cbfs_print(void)
{
	struct cbfs_image image;
	if (cbfs_image_from_buffer(&image, param.image_region,
							param.headeroffset))
		return 1;
	if (param.machine_parseable) {
		if (verbose)
			printf("[FMAP REGION]\t%s\n", param.region_name);
		cbfs_print_parseable_directory(&image);
	} else {
		printf("FMAP REGION: %s\n", param.region_name);
		cbfs_print_directory(&image);
	}

	if (verbose) {
		const char *verification_state = "fully valid";
		struct mh_cache *mhc = get_mh_cache();
		if (mhc->cbfs_hash.algo == VB2_HASH_INVALID)
			return 0;

		struct vb2_hash real_hash = { .algo = mhc->cbfs_hash.algo };
		enum cb_err err = cbfs_walk(&image, verify_walker, buffer_get(&image.buffer),
					    &real_hash, CBFS_WALK_WRITEBACK_HASH);
		if (err == CB_CBFS_HASH_MISMATCH)
			verification_state = "invalid file hashes";
		else if (err != CB_CBFS_NOT_FOUND)
			verification_state = "missing file hashes";
		char *hash_str = bintohex(real_hash.raw,
				vb2_digest_size(real_hash.algo));
		printf("[METADATA HASH]\t%s:%s",
		       vb2_get_hash_algorithm_name(real_hash.algo), hash_str);
		if (!strcmp(param.region_name, SECTION_NAME_PRIMARY_CBFS)) {
			if (!memcmp(mhc->cbfs_hash.raw, real_hash.raw,
				    vb2_digest_size(real_hash.algo))) {
				printf(":valid");
			} else {
				printf(":invalid");
				verification_state = "invalid metadata hash";
			}
		}
		printf("\n");
		printf("[CBFS VERIFICATION (%s)]\t%s\n", param.region_name, verification_state);
		free(hash_str);
	}

	return 0;
}

static int cbfs_extract(void)
{
	if (!param.filename) {
		ERROR("You need to specify -f/--filename.\n");
		return 1;
	}

	if (!param.name) {
		ERROR("You need to specify -n/--name.\n");
		return 1;
	}

	struct cbfs_image image;
	if (cbfs_image_from_buffer(&image, param.image_region,
							param.headeroffset))
		return 1;

	return cbfs_export_entry(&image, param.name, param.filename,
				param.arch, !param.unprocessed);
}

static int cbfs_write(void)
{
	if (!param.filename) {
		ERROR("You need to specify a valid input -f/--file.\n");
		return 1;
	}
	if (!partitioned_file_is_partitioned(param.image_file)) {
		ERROR("This operation isn't valid on legacy images having CBFS master headers\n");
		return 1;
	}

	if (!param.force && region_is_modern_cbfs(param.region_name)) {
		ERROR("Target image region '%s' is a CBFS and must be manipulated using add and remove\n",
							param.region_name);
		return 1;
	}

	struct buffer new_content;
	if (buffer_from_file(&new_content, param.filename))
		return 1;

	if (buffer_check_magic(&new_content, FMAP_SIGNATURE,
						strlen(FMAP_SIGNATURE))) {
		ERROR("File '%s' appears to be an FMAP and cannot be added to an existing image\n",
								param.filename);
		buffer_delete(&new_content);
		return 1;
	}
	if (!param.force && buffer_check_magic(&new_content, CBFS_FILE_MAGIC,
						strlen(CBFS_FILE_MAGIC))) {
		ERROR("File '%s' appears to be a CBFS and cannot be inserted into a raw region\n",
								param.filename);
		buffer_delete(&new_content);
		return 1;
	}

	unsigned offset = 0;
	if (param.fill_partial_upward && param.fill_partial_downward) {
		ERROR("You may only specify one of -u and -d.\n");
		buffer_delete(&new_content);
		return 1;
	} else if (!param.fill_partial_upward && !param.fill_partial_downward) {
		if (new_content.size != param.image_region->size) {
			ERROR("File to add is %zu bytes and would not fill %zu-byte target region (did you mean to pass either -u or -d?)\n",
				new_content.size, param.image_region->size);
			buffer_delete(&new_content);
			return 1;
		}
	} else {
		if (new_content.size > param.image_region->size) {
			ERROR("File to add is %zu bytes and would overflow %zu-byte target region\n",
				new_content.size, param.image_region->size);
			buffer_delete(&new_content);
			return 1;
		}
		if (param.u64val == (uint64_t)-1) {
			WARN("Written area will abut %s of target region: any unused space will keep its current contents\n",
					param.fill_partial_upward ? "bottom" : "top");
		} else if (param.u64val > 0xff) {
			ERROR("given fill value (%x) is larger than a byte\n", (unsigned)(param.u64val & 0xff));
			buffer_delete(&new_content);
			return 1;
		} else {
			memset(buffer_get(param.image_region),
				param.u64val & 0xff,
				buffer_size(param.image_region));
		}
		if (param.fill_partial_downward)
			offset = param.image_region->size - new_content.size;
	}

	memcpy(param.image_region->data + offset, new_content.data,
							new_content.size);
	buffer_delete(&new_content);

	return maybe_update_fmap_hash();
}

static int cbfs_read(void)
{
	if (!param.filename) {
		ERROR("You need to specify a valid output -f/--file.\n");
		return 1;
	}
	if (!partitioned_file_is_partitioned(param.image_file)) {
		ERROR("This operation isn't valid on legacy images having CBFS master headers\n");
		return 1;
	}

	return buffer_write_file(param.image_region, param.filename);
}

static int cbfs_copy(void)
{
	struct cbfs_image src_image;
	struct buffer src_buf;

	if (!param.source_region) {
		ERROR("You need to specify -R/--source-region.\n");
		return 1;
	}

	/* Obtain the source region and convert it to a cbfs_image. */
	if (!partitioned_file_read_region(&src_buf, param.image_file,
						param.source_region)) {
		ERROR("Region not found in image: %s\n", param.source_region);
		return 1;
	}

	if (cbfs_image_from_buffer(&src_image, &src_buf, param.headeroffset))
		return 1;

	return cbfs_copy_instance(&src_image, param.image_region);
}

static int cbfs_compact(void)
{
	struct cbfs_image image;
	if (cbfs_image_from_buffer(&image, param.image_region,
							param.headeroffset))
		return 1;
	WARN("Compacting a CBFS doesn't honor alignment or fixed addresses!\n");
	return cbfs_compact_instance(&image);
}

static int cbfs_expand(void)
{
	struct buffer src_buf;

	/* Obtain the source region. */
	if (!partitioned_file_read_region(&src_buf, param.image_file,
						param.region_name)) {
		ERROR("Region not found in image: %s\n", param.source_region);
		return 1;
	}

	return cbfs_expand_to_region(param.image_region);
}

static int cbfs_truncate(void)
{
	struct buffer src_buf;

	/* Obtain the source region. */
	if (!partitioned_file_read_region(&src_buf, param.image_file,
						param.region_name)) {
		ERROR("Region not found in image: %s\n", param.source_region);
		return 1;
	}

	uint32_t size;
	int result = cbfs_truncate_space(param.image_region, &size);
	if (!result)
		printf("0x%x\n", size);
	return result;
}

static const struct command commands[] = {
	{"add", "H:r:f:n:t:c:b:a:p:yvA:j:gh?", cbfs_add, true, true},
	{"add-flat-binary", "H:r:f:n:l:e:c:b:p:vA:gh?", cbfs_add_flat_binary,
				true, true},
	{"add-payload", "H:r:f:n:c:b:a:C:I:p:vA:gh?", cbfs_add_payload,
				true, true},
	{"add-stage", "a:H:r:f:n:t:c:b:P:QS:p:yvA:gh?", cbfs_add_stage,
				true, true},
	{"add-int", "H:r:i:n:b:vgh?", cbfs_add_integer, true, true},
	{"add-master-header", "H:r:vh?j:", cbfs_add_master_header, true, true},
	{"compact", "r:h?", cbfs_compact, true, true},
	{"copy", "r:R:h?", cbfs_copy, true, true},
	{"create", "M:r:s:B:b:H:o:m:vh?", cbfs_create, true, true},
	{"extract", "H:r:m:n:f:Uvh?", cbfs_extract, true, false},
	{"layout", "wvh?", cbfs_layout, false, false},
	{"print", "H:r:vkh?", cbfs_print, true, false},
	{"read", "r:f:vh?", cbfs_read, true, false},
	{"remove", "H:r:n:vh?", cbfs_remove, true, true},
	{"write", "r:f:i:Fudvh?", cbfs_write, true, true},
	{"expand", "r:h?", cbfs_expand, true, true},
	{"truncate", "r:h?", cbfs_truncate, true, true},
};

enum {
	/* begin after ASCII characters */
	LONGOPT_START = 256,
	LONGOPT_IBB = LONGOPT_START,
	LONGOPT_MMAP,
	LONGOPT_END,
};

static struct option long_options[] = {
	{"alignment",     required_argument, 0, 'a' },
	{"base-address",  required_argument, 0, 'b' },
	{"bootblock",     required_argument, 0, 'B' },
	{"cmdline",       required_argument, 0, 'C' },
	{"compression",   required_argument, 0, 'c' },
	{"topswap-size",  required_argument, 0, 'j' },
	{"empty-fits",    required_argument, 0, 'x' },
	{"entry-point",   required_argument, 0, 'e' },
	{"file",          required_argument, 0, 'f' },
	{"fill-downward", no_argument,       0, 'd' },
	{"fill-upward",   no_argument,       0, 'u' },
	{"flashmap",      required_argument, 0, 'M' },
	{"fmap-regions",  required_argument, 0, 'r' },
	{"force",         no_argument,       0, 'F' },
	{"source-region", required_argument, 0, 'R' },
	{"hash-algorithm",required_argument, 0, 'A' },
	{"header-offset", required_argument, 0, 'H' },
	{"help",          no_argument,       0, 'h' },
	{"ignore-sec",    required_argument, 0, 'S' },
	{"initrd",        required_argument, 0, 'I' },
	{"int",           required_argument, 0, 'i' },
	{"load-address",  required_argument, 0, 'l' },
	{"machine",       required_argument, 0, 'm' },
	{"name",          required_argument, 0, 'n' },
	{"offset",        required_argument, 0, 'o' },
	{"padding",       required_argument, 0, 'p' },
	{"pow2page",      no_argument,       0, 'Q' },
	{"ucode-region",  required_argument, 0, 'q' },
	{"size",          required_argument, 0, 's' },
	{"type",          required_argument, 0, 't' },
	{"verbose",       no_argument,       0, 'v' },
	{"with-readonly", no_argument,       0, 'w' },
	{"xip",           no_argument,       0, 'y' },
	{"gen-attribute", no_argument,       0, 'g' },
	{"mach-parseable",no_argument,       0, 'k' },
	{"unprocessed",   no_argument,       0, 'U' },
	{"ibb",           no_argument,       0, LONGOPT_IBB },
	{"mmap",          required_argument, 0, LONGOPT_MMAP },
	{NULL,            0,                 0,  0  }
};

static int get_region_offset(long long int offset, uint32_t *region_offset)
{
	/* If offset is not negative, no transformation required. */
	if (offset >= 0) {
		*region_offset = offset;
		return 0;
	}

	/* Calculate offset from start of region. */
	return convert_region_offset(-offset, region_offset);
}

static int calculate_region_offsets(void)
{
	int ret = 0;

	if (param.baseaddress_assigned)
		ret |= get_region_offset(param.baseaddress_input, &param.baseaddress);
	if (param.headeroffset_assigned)
		ret |= get_region_offset(param.headeroffset_input, &param.headeroffset);
	if (param.cbfsoffset_assigned)
		ret |= get_region_offset(param.cbfsoffset_input, &param.cbfsoffset);

	return ret;
}

static int dispatch_command(struct command command)
{
	if (command.accesses_region) {
		assert(param.image_file);

		if (partitioned_file_is_partitioned(param.image_file)) {
			INFO("Performing operation on '%s' region...\n",
					param.region_name);
		}
		if (!partitioned_file_read_region(param.image_region,
					param.image_file, param.region_name)) {
			ERROR("The image will be left unmodified.\n");
			return 1;
		}

		if (command.modifies_region) {
			// We (intentionally) don't support overwriting the FMAP
			// section. If you find yourself wanting to do this,
			// consider creating a new image rather than performing
			// whatever hacky transformation you were planning.
			if (region_is_flashmap(param.region_name)) {
				ERROR("Image region '%s' is read-only because it contains the FMAP.\n",
							param.region_name);
				ERROR("The image will be left unmodified.\n");
				return 1;
			}
			// We don't allow writing raw data to regions that
			// contain nested regions, since doing so would
			// overwrite all such subregions.
			if (partitioned_file_region_contains_nested(
					param.image_file, param.region_name)) {
				ERROR("Image region '%s' is read-only because it contains nested regions.\n",
							param.region_name);
				ERROR("The image will be left unmodified.\n");
				return 1;
			}
		}

		/*
		 * Once image region is read, input offsets can be adjusted accordingly if the
		 * inputs are provided as negative integers i.e. offsets from end of region.
		 */
		if (calculate_region_offsets())
			return 1;
	}

	if (command.function()) {
		if (partitioned_file_is_partitioned(param.image_file)) {
			ERROR("Failed while operating on '%s' region!\n",
							param.region_name);
			ERROR("The image will be left unmodified.\n");
		}
		return 1;
	}

	return 0;
}

static void usage(char *name)
{
	printf
	    ("cbfstool: Management utility for CBFS formatted ROM images\n\n"
	     "USAGE:\n" " %s [-h]\n"
	     " %s FILE COMMAND [-v] [PARAMETERS]...\n\n" "OPTIONs:\n"
	     "  -H header_offset Do not search for header; use this offset*\n"
	     "  -T               Output top-aligned memory address\n"
	     "  -u               Accept short data; fill upward/from bottom\n"
	     "  -d               Accept short data; fill downward/from top\n"
	     "  -F               Force action\n"
	     "  -g               Generate position and alignment arguments\n"
	     "  -U               Unprocessed; don't decompress or make ELF\n"
	     "  -v               Provide verbose output (-v=INFO -vv=DEBUG output)\n"
	     "  -h               Display this help message\n\n"
	     "  --ext-win-base   Base of extended decode window in host address\n"
	     "                   space(x86 only)\n"
	     "  --ext-win-size   Size of extended decode window in host address\n"
	     "                   space(x86 only)\n"
	     "COMMANDs:\n"
	     " add [-r image,regions] -f FILE -n NAME -t TYPE [-A hash] \\\n"
	     "        [-c compression] [-b base-address | -a alignment] \\\n"
	     "        [-p padding size] [-y|--xip if TYPE is FSP]       \\\n"
	     "        [-j topswap-size] (Intel CPUs only) [--ibb]       \\\n"
	     "        [--ext-win-base win-base --ext-win-size win-size]     "
			"Add a component\n"
	     "                                                         "
	     "    -j valid size: 0x10000 0x20000 0x40000 0x80000 0x100000 \n"
	     " add-payload [-r image,regions] -f FILE -n NAME [-A hash] \\\n"
	     "        [-c compression] [-b base-address] \\\n"
	     "        (linux specific: [-C cmdline] [-I initrd])           "
			"Add a payload to the ROM\n"
	     " add-stage [-r image,regions] -f FILE -n NAME [-A hash] \\\n"
	     "        [-c compression] [-b base] [-S section-to-ignore] \\\n"
	     "        [-a alignment] [-Q|--pow2page] \\\n"
	     "        [-y|--xip] [--ibb]                                \\\n"
	     "        [--ext-win-base win-base --ext-win-size win-size]     "
			"Add a stage to the ROM\n"
	     " add-flat-binary [-r image,regions] -f FILE -n NAME \\\n"
	     "        [-A hash] -l load-address -e entry-point \\\n"
	     "        [-c compression] [-b base]                           "
			"Add a 32bit flat mode binary\n"
	     " add-int [-r image,regions] -i INTEGER -n NAME [-b base]     "
			"Add a raw 64-bit integer value\n"
	     " add-master-header [-r image,regions] \\                   \n"
	     "        [-j topswap-size] (Intel CPUs only)                  "
			"Add a legacy CBFS master header\n"
	     " remove [-r image,regions] -n NAME                           "
			"Remove a component\n"
	     " compact -r image,regions                                    "
			"Defragment CBFS image.\n"
	     " copy -r image,regions -R source-region                      "
			"Create a copy (duplicate) cbfs instance in fmap\n"
	     " create -m ARCH -s size [-b bootblock offset] \\\n"
	     "        [-o CBFS offset] [-H header offset] [-B bootblock]   "
			"Create a legacy ROM file with CBFS master header*\n"
	     " create -M flashmap [-r list,of,regions,containing,cbfses]   "
			"Create a new-style partitioned firmware image\n"
	     " layout [-w]                                                 "
			"List mutable (or, with -w, readable) image regions\n"
	     " print [-r image,regions] [-k]                               "
			"Show the contents of the ROM\n"
	     " extract [-r image,regions] [-m ARCH] -n NAME -f FILE [-U]   "
			"Extracts a file from ROM\n"
	     " write [-F] -r image,regions -f file [-u | -d] [-i int]      "
			"Write file into same-size [or larger] raw region\n"
	     " read [-r fmap-region] -f file                               "
			"Extract raw region contents into binary file\n"
	     " truncate [-r fmap-region]                                   "
			"Truncate CBFS and print new size on stdout\n"
	     " expand [-r fmap-region]                                     "
			"Expand CBFS to span entire region\n"
	     "OFFSETs:\n"
	     "  Numbers accompanying -b, -H, and -o switches* may be provided\n"
	     "  in two possible formats: if their value is greater than\n"
	     "  0x80000000, they are interpreted as a top-aligned x86 memory\n"
	     "  address; otherwise, they are treated as an offset into flash.\n"
	     "ARCHes:\n", name, name
	    );
	print_supported_architectures();

	printf("TYPEs:\n");
	print_supported_filetypes();
	printf(
	     "\n* Note that these actions and switches are only valid when\n"
	     "  working with legacy images whose structure is described\n"
	     "  primarily by a CBFS master header. New-style images, in\n"
	     "  contrast, exclusively make use of an FMAP to describe their\n"
	     "  layout: this must minimally contain an '%s' section\n"
	     "  specifying the location of this FMAP itself and a '%s'\n"
	     "  section describing the primary CBFS. It should also be noted\n"
	     "  that, when working with such images, the -F and -r switches\n"
	     "  default to '%s' for convenience, and the -b switch becomes\n"
	     "  relative to the selected CBFS region's lowest address.\n"
	     "  The one exception to this rule is the top-aligned address,\n"
	     "  which is always relative to the end of the entire image\n"
	     "  rather than relative to the local region; this is true for\n"
	     "  for both input (sufficiently large) and output (-T) data.\n",
	     SECTION_NAME_FMAP, SECTION_NAME_PRIMARY_CBFS,
	     SECTION_NAME_PRIMARY_CBFS
	     );
}

static bool valid_opt(size_t i, int c)
{
	/* Check if it is one of the optstrings supported by the command. */
	if (strchr(commands[i].optstring, c))
		return true;

	/*
	 * Check if it is one of the non-ASCII characters. Currently, the
	 * non-ASCII characters are only checked against the valid list
	 * irrespective of the command.
	 */
	if (c >= LONGOPT_START && c < LONGOPT_END)
		return true;

	return false;
}

int main(int argc, char **argv)
{
	size_t i;
	int c;

	if (argc < 3) {
		usage(argv[0]);
		return 1;
	}

	char *image_name = argv[1];
	char *cmd = argv[2];
	optind += 2;

	for (i = 0; i < ARRAY_SIZE(commands); i++) {
		if (strcmp(cmd, commands[i].name) != 0)
			continue;

		while (1) {
			char *suffix = NULL;
			int option_index = 0;

			c = getopt_long(argc, argv, commands[i].optstring,
						long_options, &option_index);
			if (c == -1) {
				if (optind < argc) {
					ERROR("%s: excessive argument -- '%s'"
						"\n", argv[0], argv[optind]);
					return 1;
				}
				break;
			}

			/* Filter out illegal long options */
			if (!valid_opt(i, c)) {
				ERROR("%s: invalid option -- '%d'\n",
				      argv[0], c);
				c = '?';
			}

			switch(c) {
			case 'n':
				param.name = optarg;
				break;
			case 't':
				if (intfiletype(optarg) != ((uint64_t) - 1))
					param.type = intfiletype(optarg);
				else
					param.type = strtoul(optarg, NULL, 0);
				if (param.type == 0)
					WARN("Unknown type '%s' ignored\n",
							optarg);
				break;
			case 'c': {
				if (strcmp(optarg, "precompression") == 0) {
					param.precompression = 1;
					break;
				}
				int algo = cbfs_parse_comp_algo(optarg);
				if (algo >= 0)
					param.compression = algo;
				else
					WARN("Unknown compression '%s' ignored.\n",
									optarg);
				break;
			}
			case 'A': {
				if (!vb2_lookup_hash_alg(optarg, &param.hash)) {
					ERROR("Unknown hash algorithm '%s'.\n",
						optarg);
					return 1;
				}
				break;
			}
			case 'M':
				param.fmap = optarg;
				break;
			case 'r':
				param.region_name = optarg;
				break;
			case 'R':
				param.source_region = optarg;
				break;
			case 'b':
				param.baseaddress_input = strtoll(optarg, &suffix, 0);
				if (!*optarg || (suffix && *suffix)) {
					ERROR("Invalid base address '%s'.\n",
						optarg);
					return 1;
				}
				// baseaddress may be zero on non-x86, so we
				// need an explicit "baseaddress_assigned".
				param.baseaddress_assigned = 1;
				break;
			case 'l':
				param.loadaddress = strtoul(optarg, &suffix, 0);
				if (!*optarg || (suffix && *suffix)) {
					ERROR("Invalid load address '%s'.\n",
						optarg);
					return 1;
				}
				break;
			case 'e':
				param.entrypoint = strtoul(optarg, &suffix, 0);
				if (!*optarg || (suffix && *suffix)) {
					ERROR("Invalid entry point '%s'.\n",
						optarg);
					return 1;
				}
				break;
			case 's':
				param.size = strtoul(optarg, &suffix, 0);
				if (!*optarg) {
					ERROR("Empty size specified.\n");
					return 1;
				}
				switch (tolower((int)suffix[0])) {
				case 'k':
					param.size *= 1024;
					break;
				case 'm':
					param.size *= 1024 * 1024;
					break;
				case '\0':
					break;
				default:
					ERROR("Invalid suffix for size '%s'.\n",
						optarg);
					return 1;
				}
				break;
			case 'B':
				param.bootblock = optarg;
				break;
			case 'H':
				param.headeroffset_input = strtoll(optarg, &suffix, 0);
				if (!*optarg || (suffix && *suffix)) {
					ERROR("Invalid header offset '%s'.\n",
						optarg);
					return 1;
				}
				param.headeroffset_assigned = 1;
				break;
			case 'a':
				param.alignment = strtoul(optarg, &suffix, 0);
				if (!*optarg || (suffix && *suffix)) {
					ERROR("Invalid alignment '%s'.\n",
						optarg);
					return 1;
				}
				break;
			case 'p':
				param.padding = strtoul(optarg, &suffix, 0);
				if (!*optarg || (suffix && *suffix)) {
					ERROR("Invalid pad size '%s'.\n",
						optarg);
					return 1;
				}
				break;
			case 'Q':
				param.force_pow2_pagesize = 1;
				break;
			case 'o':
				param.cbfsoffset_input = strtoll(optarg, &suffix, 0);
				if (!*optarg || (suffix && *suffix)) {
					ERROR("Invalid cbfs offset '%s'.\n",
						optarg);
					return 1;
				}
				param.cbfsoffset_assigned = 1;
				break;
			case 'f':
				param.filename = optarg;
				break;
			case 'F':
				param.force = 1;
				break;
			case 'i':
				param.u64val = strtoull(optarg, &suffix, 0);
				param.u64val_assigned = 1;
				if (!*optarg || (suffix && *suffix)) {
					ERROR("Invalid int parameter '%s'.\n",
						optarg);
					return 1;
				}
				break;
			case 'u':
				param.fill_partial_upward = true;
				break;
			case 'd':
				param.fill_partial_downward = true;
				break;
			case 'w':
				param.show_immutable = true;
				break;
			case 'j':
				param.topswap_size = strtol(optarg, NULL, 0);
				if (!is_valid_topswap())
					return 1;
				break;
			case 'q':
				param.ucode_region = optarg;
				break;
			case 'v':
				verbose++;
				break;
			case 'm':
				param.arch = string_to_arch(optarg);
				break;
			case 'I':
				param.initrd = optarg;
				break;
			case 'C':
				param.cmdline = optarg;
				break;
			case 'S':
				param.ignore_section = optarg;
				break;
			case 'y':
				param.stage_xip = true;
				break;
			case 'g':
				param.autogen_attr = true;
				break;
			case 'k':
				param.machine_parseable = true;
				break;
			case 'U':
				param.unprocessed = true;
				break;
			case LONGOPT_IBB:
				param.ibb = true;
				break;
			case LONGOPT_MMAP:
				if (decode_mmap_arg(optarg))
					return 1;
				break;
			case 'h':
			case '?':
				usage(argv[0]);
				return 1;
			default:
				break;
			}
		}

		if (commands[i].function == cbfs_create) {
			if (param.fmap) {
				struct buffer flashmap;
				if (buffer_from_file(&flashmap, param.fmap))
					return 1;
				param.image_file = partitioned_file_create(
							image_name, &flashmap);
				buffer_delete(&flashmap);
			} else if (param.size) {
				param.image_file = partitioned_file_create_flat(
							image_name, param.size);
			} else {
				ERROR("You need to specify a valid -M/--flashmap or -s/--size.\n");
				return 1;
			}
		} else {
			bool write_access = commands[i].modifies_region;

			param.image_file =
				partitioned_file_reopen(image_name,
							write_access);
		}
		if (!param.image_file)
			return 1;

		unsigned num_regions = 1;
		for (const char *list = strchr(param.region_name, ','); list;
						list = strchr(list + 1, ','))
			++num_regions;

		// If the action needs to read an image region, as indicated by
		// having accesses_region set in its command struct, that
		// region's buffer struct will be stored here and the client
		// will receive a pointer to it via param.image_region. It
		// need not write the buffer back to the image file itself,
		// since this behavior can be requested via its modifies_region
		// field. Additionally, it should never free the region buffer,
		// as that is performed automatically once it completes.
		struct buffer image_regions[num_regions];
		memset(image_regions, 0, sizeof(image_regions));

		bool seen_primary_cbfs = false;
		char region_name_scratch[strlen(param.region_name) + 1];
		strcpy(region_name_scratch, param.region_name);
		param.region_name = strtok(region_name_scratch, ",");
		for (unsigned region = 0; region < num_regions; ++region) {
			if (!param.region_name) {
				ERROR("Encountered illegal degenerate region name in -r list\n");
				ERROR("The image will be left unmodified.\n");
				partitioned_file_close(param.image_file);
				return 1;
			}

			if (strcmp(param.region_name, SECTION_NAME_PRIMARY_CBFS)
									== 0)
				seen_primary_cbfs = true;

			param.image_region = image_regions + region;
			if (dispatch_command(commands[i])) {
				partitioned_file_close(param.image_file);
				return 1;
			}

			param.region_name = strtok(NULL, ",");
		}

		if (commands[i].function == cbfs_create && !seen_primary_cbfs) {
			ERROR("The creation -r list must include the mandatory '%s' section.\n",
						SECTION_NAME_PRIMARY_CBFS);
			ERROR("The image will be left unmodified.\n");
			partitioned_file_close(param.image_file);
			return 1;
		}

		if (commands[i].modifies_region) {
			assert(param.image_file);
			for (unsigned region = 0; region < num_regions;
								++region) {

				if (!partitioned_file_write_region(
							param.image_file,
						image_regions + region)) {
					partitioned_file_close(
							param.image_file);
					return 1;
				}
			}
		}

		partitioned_file_close(param.image_file);
		return 0;
	}

	ERROR("Unknown command '%s'.\n", cmd);
	usage(argv[0]);
	return 1;
}
