/*
 * cbfstool, CLI utility for CBFS file manipulation
 *
 * Copyright (C) 2009 coresystems GmbH
 *                 written by Patrick Georgi <patrick.georgi@coresystems.de>
 * Copyright (C) 2012 Google, Inc.
 * Copyright (C) 2016 Siemens AG
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#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 "fit.h"
#include "partitioned_file.h"
#include <commonlib/fsp.h>
#include <commonlib/endian.h>
#include <commonlib/helpers.h>

#define SECTION_WITH_FIT_TABLE	"BOOTBLOCK"

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;
	uint32_t baseaddress_assigned;
	uint32_t loadaddress;
	uint32_t headeroffset;
	uint32_t headeroffset_assigned;
	uint32_t entrypoint;
	uint32_t size;
	uint32_t alignment;
	uint32_t pagesize;
	uint32_t cbfsoffset;
	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 autogen_attr;
	bool machine_parseable;
	bool unprocessed;
	int fit_empty_entries;
	enum comp_algo compression;
	int precompression;
	enum vb2_hash_algorithm hash;
	/* For linux payloads */
	char *initrd;
	char *cmdline;
	int force;
} param = {
	/* All variables not listed are initialized as zero. */
	.arch = CBFS_ARCHITECTURE_UNKNOWN,
	.compression = CBFS_COMPRESS_NONE,
	.hash = VB2_HASH_INVALID,
	.headeroffset = ~0,
	.region_name = SECTION_NAME_PRIMARY_CBFS,
	.u64val = -1,
};

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));
}

/*
 * Converts between offsets from the start of the specified image region and
 * "top-aligned" offsets from the top of the entire boot media. See comment
 * below for convert_to_from_top_aligned() about forming addresses.
 */
static unsigned convert_to_from_absolute_top_aligned(
		const struct buffer *region, unsigned offset)
{
	assert(region);

	size_t image_size = partitioned_file_total_size(param.image_file);

	return image_size - region->offset - offset;
}

/*
 * Converts between offsets from the start of the specified image region and
 * "top-aligned" offsets from the top of the image region. Works in either
 * direction: pass in one type of offset and receive the other type.
 * N.B. A top-aligned offset is always a positive number, and should not be
 * confused with a top-aliged *address*, which is its arithmetic inverse. */
static unsigned convert_to_from_top_aligned(const struct buffer *region,
								unsigned offset)
{
	assert(region);

	/* Cover the situation where a negative base address is given by the
	 * user. Callers of this function negate it, so it'll be a positive
	 * number smaller than the region.
	 */
	if ((offset > 0) && (offset < region->size)) {
		return region->size - offset;
	}

	return convert_to_from_absolute_top_aligned(region, offset);
}

static int do_cbfs_locate(int32_t *cbfs_addr, size_t metadata_size,
			size_t data_size)
{
	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;

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

	if (!data_size) {
		struct buffer buffer;
		if (buffer_from_file(&buffer, param.filename) != 0) {
			ERROR("Cannot load %s.\n", param.filename);
			return 1;
		}
		data_size = buffer.size;
		buffer_delete(&buffer);
	}

	DEBUG("File size is %zd (0x%zx)\n", data_size, data_size);

	/* 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);
	}

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

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

	if (address == -1) {
		ERROR("'%s' can't fit in CBFS for page-size %#x, align %#x.\n",
		      param.name, 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;
	}

	if (IS_TOP_ALIGNED_ADDRESS(offset))
		offset = convert_to_from_top_aligned(param.image_region,
								-offset);

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

	ret = 0;

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 != ntohl(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 = htonl(CBFS_HEADER_MAGIC);
	h->version = htonl(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 = htonl(4);
	h->align = htonl(CBFS_ENTRY_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 = htonl(size + offset);
	h->offset = htonl(offset);
	h->architecture = htonl(CBFS_ARCHITECTURE_UNKNOWN);

	header = cbfs_create_file_header(CBFS_COMPONENT_CBFSHEADER,
		buffer_size(&buffer), name);
	if (cbfs_add_entry(&image, &buffer, 0, header) != 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))
			return 1;
	}

	ret = 0;

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 */
	*offset = convert_to_from_top_aligned(param.image_region,
							buffer_size(buffer));

	return 0;
}

static int cbfs_add_component(const char *filename,
			      const char *name,
			      uint32_t type,
			      uint32_t offset,
			      uint32_t headeroffset,
			      convert_buffer_t convert)
{
	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 (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;
	}

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

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

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

	if (param.hash != VB2_HASH_INVALID)
		if (cbfs_add_file_hash(header, &buffer, param.hash) == -1) {
			ERROR("couldn't add hash for '%s'\n", name);
			free(header);
			buffer_delete(&buffer);
			return 1;
		}

	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)
				return -1;
			/* If we add a stage or a payload, we need to take  */
			/* care about the additional metadata that is added */
			/* to the cbfs file and therefore set the position  */
			/* the real beginning of the data. */
			if (type == CBFS_COMPONENT_STAGE)
				attrs->position = htonl(offset +
					sizeof(struct cbfs_stage));
			else if (type == CBFS_COMPONENT_SELF)
				attrs->position = htonl(offset +
					sizeof(struct cbfs_payload));
			else
				attrs->position = htonl(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)
				return -1;
			attrs->alignment = htonl(param.alignment);
		}
	}

	if (param.padding) {
		const uint32_t hs = sizeof(struct cbfs_file_attribute);
		uint32_t size = MAX(hs, param.padding);
		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)
			return -1;
	}

	if (IS_TOP_ALIGNED_ADDRESS(offset))
		offset = convert_to_from_top_aligned(param.image_region,
								-offset);
	if (cbfs_add_entry(&image, &buffer, offset, header) != 0) {
		ERROR("Failed to add '%s' into ROM image.\n", filename);
		free(header);
		buffer_delete(&buffer);
		return 1;
	}

	free(header);
	buffer_delete(&buffer);
	return 0;
}

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 {
		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);
			return 0;
		}
	}

	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 = htonl(param.compression);
	attrs->decompressed_size = htonl(decompressed_size);

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

	header->len = htonl(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;
	int do_relocation = 1;

	address = *offset;

	/*
	 * If the FSP component is xip, then ensure that the address is a memory
	 * mapped one.
	 * If the FSP component is not xip, then use param.baseaddress that is
	 * passed in by the caller.
	 */
	if (param.stage_xip) {
		if (!IS_TOP_ALIGNED_ADDRESS(address))
			address = -convert_to_from_absolute_top_aligned(
					param.image_region, address);
	} else {
		if (param.baseaddress_assigned == 0) {
			INFO("Honoring pre-linked FSP module.\n");
			do_relocation = 0;
		} else {
			address = param.baseaddress;
		}

		/*
		 * *offset should either be 0 or the value returned by
		 * do_cbfs_locate. do_cbfs_locate should not ever return a value
		 * that is TOP_ALIGNED_ADDRESS. Thus, if *offset contains a top
		 * aligned address, set it to 0.
		 *
		 * The only requirement in this case is that the binary should
		 * be relocated to the base address that is requested. There is
		 * no requirement on where the file ends up in the cbfs.
		 */
		if (IS_TOP_ALIGNED_ADDRESS(*offset))
			*offset = 0;
	}

	/*
	 * Nothing left to do if relocation is not being attempted. Just add
	 * the file.
	 */
	if (!do_relocation)
		return cbfstool_convert_raw(buffer, offset, header);

	/* 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;
	int ret;

	if (param.stage_xip) {
		int32_t address;
		size_t data_size;

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

		if (do_cbfs_locate(&address, sizeof(struct cbfs_stage),
			data_size))  {
			ERROR("Could not find location for XIP stage.\n");
			return 1;
		}

		/*
		 * Ensure the address is a memory mapped one. This assumes
		 * x86 semantics about the boot media being directly mapped
		 * below 4GiB in the CPU address space.
		 **/
		address = -convert_to_from_absolute_top_aligned(
				param.image_region, address);
		*offset = address;

		ret = parse_elf_to_xip_stage(buffer, &output, offset,
						param.ignore_section);
	} else
		ret = parse_elf_to_stage(buffer, &output, param.compression,
					 offset, param.ignore_section);

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

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 = htonl(CBFS_COMPONENT_FIT);
	}

	/* 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 = htonl(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 = htonl(output.size);
	return 0;
}

static int cbfs_add(void)
{
	int32_t address;
	convert_buffer_t convert;
	uint32_t local_baseaddress = param.baseaddress;

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

	convert = cbfstool_convert_raw;

	/* Set the alignment to 4KiB minimum for FSP blobs when no base address
	 * is provided so that relocation can occur. */
	if (param.type == CBFS_COMPONENT_FSP) {
		if (!param.baseaddress_assigned)
			param.alignment = 4*1024;
		convert = cbfstool_convert_fsp;
	} else if (param.stage_xip) {
		ERROR("cbfs add supports xip only for FSP component type\n");
		return 1;
	}

	if (param.alignment) {
		/* CBFS compression file attribute is unconditionally added. */
		size_t metadata_sz = sizeof(struct cbfs_file_attr_compression);
		if (do_cbfs_locate(&address, metadata_sz, 0))
			return 1;
		local_baseaddress = address;
	}

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

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

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

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

static int cbfs_add_payload(void)
{
	return cbfs_add_component(param.filename,
				  param.name,
				  CBFS_COMPONENT_SELF,
				  param.baseaddress,
				  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;
	}
	return cbfs_add_component(param.filename,
				  param.name,
				  CBFS_COMPONENT_SELF,
				  param.baseaddress,
				  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 0;
}

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, ";
		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 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)
		return cbfs_print_parseable_directory(&image);
	else
		return cbfs_print_directory(&image);
}

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 0;
}

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_update_fit(void)
{
	if (!param.name) {
		ERROR("You need to specify -n/--name.\n");
		return 1;
	}

	if (param.fit_empty_entries <= 0) {
		ERROR("Invalid number of fit entries "
		        "(-x/--empty-fits): %d\n", param.fit_empty_entries);
		return 1;
	}

	struct buffer bootblock;
	// The bootblock is part of the CBFS on x86
	buffer_clone(&bootblock, param.image_region);

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

	uint32_t addr = 0;

	/*
	 * Get the address of provided region for first row.
	 */
	if (param.ucode_region) {
		struct buffer ucode;

		if (partitioned_file_read_region(&ucode,
				param.image_file, param.ucode_region))
			addr = -convert_to_from_top_aligned(&ucode, 0);
		else
			return 1;
	}


	if (fit_update_table(&bootblock, &image, param.name,
			param.fit_empty_entries, convert_to_from_top_aligned,
						param.topswap_size, addr))
		return 1;

	// The region to be written depends on the type of image, so we write it
	// here rather than having main() write the CBFS region back as usual.
	return !partitioned_file_write_region(param.image_file, &bootblock);
}

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);
	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:C:I:p:vA:gh?", cbfs_add_payload,
				true, true},
	{"add-stage", "a:H:r:f:n:t:c:b:P:S: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},
	{"update-fit", "H:r:n:x:vh?j:q:", cbfs_update_fit, 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},
};

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' },
	{"page-size",     required_argument, 0, 'P' },
	{"ucode-region",  required_argument, 0, 'q' },
	{"size",          required_argument, 0, 's' },
	{"top-aligned",   required_argument, 0, 'T' },
	{"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' },
	{NULL,            0,                 0,  0  }
};

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;
			}
		}
	}

	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\n"
	     "  -h               Display this help message\n\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)                   "
			"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] [-y|--xip] [-P page-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"
	     " locate [-r image,regions] -f FILE -n NAME [-P page-size] \\\n"
	     "        [-a align] [-T]                                      "
			"Find a place for a file of that size\n"
	     " layout [-w]                                                 "
			"List mutable (or, with -w, readable) image regions\n"
	     " print [-r image,regions]                                    "
			"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"
	     " update-fit [-r image,regions] -n MICROCODE_BLOB_NAME \\\n"
	     "        -x EMTPY_FIT_ENTRIES \\                         \n"
	     "        [-j topswap-size [-q ucode-region](Intel CPUs only)] "
			"Updates the FIT table with microcode entries.\n"
	     "                                                         "
	     "    ucode-region is a region in the FMAP, its address is \n"
	     "                                                         "
	     "    inserted as the first entry in the topswap FIT.  \n"
	     "\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 both the -b switch to\n"
	     "  CBFS operations and the output of the locate action become\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
	     );
}

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 (strchr(commands[i].optstring, c) == NULL) {
				/* TODO maybe print actual long option instead */
				ERROR("%s: invalid option -- '%c'\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': {
				int algo = cbfs_parse_hash_algo(optarg);
				if (algo >= 0)
					param.hash = algo;
				else {
					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 = strtoul(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 = strtoul(
						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 'P':
				param.pagesize = strtoul(optarg, &suffix, 0);
				if (!*optarg || (suffix && *suffix)) {
					ERROR("Invalid page size '%s'.\n",
						optarg);
					return 1;
				}
				break;
			case 'o':
				param.cbfsoffset = strtoul(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 'x':
				param.fit_empty_entries = strtol(
						optarg, &suffix, 0);
				if (!*optarg || (suffix && *suffix)) {
					ERROR("Invalid number of fit entries "
						"'%s'.\n", optarg);
					return 1;
				}
				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 '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;
}
