[coreboot-gerrit] New patch to review for coreboot: 5d82abe fmaptool: Add listing of annotated CBFS sections and generate header

Sol Boucher (solb@chromium.org) gerrit at coreboot.org
Wed Apr 22 20:27:42 CEST 2015


Sol Boucher (solb at chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/9967

-gerrit

commit 5d82abe952e27162978932dd1c29ba62e4e527c4
Author: Sol Boucher <solb at chromium.org>
Date:   Wed Mar 18 10:13:48 2015 -0700

    fmaptool: Add listing of annotated CBFS sections and generate header
    
    The fmd compiler now processes "(CBFS)" annotations, distilling them
    into a comma-separated list of the names of sections containing
    CBFSes. This list is the only thing printed to standard output to
    enable easy capture and machine consumption by other tools.
    Additionally, the ability to generate a tiny header with a define for
    the primary CBFS's size is implemented and can be requested via a
    new command-line switch.
    
    BUG=chromium:470407
    TEST=Verify that fmd files without a "COREBOOT" section or with one
    that isn't annotated as "(CBFS)" are not accepted. Ensure that the
    list of CBFS sections matches the descriptor file's annotations and
    is led by the "COREBOOT" section. Invoke with the header generation
    switch and check that output file for reasonableness.
    BRANCH=None
    
    Change-Id: I496dd937f69467bfd9233c28df59c7608e89538f
    Signed-off-by: Sol Boucher <solb at chromium.org>
    Original-Commit-Id: 9227698adecf675770b2983380eb570676c2b5d2
    Original-Change-Id: I8b32f6ef19cabe2f6760106e676683c4565bbaad
    Original-Signed-off-by: Sol Boucher <solb at chromium.org>
    Original-Reviewed-on: https://chromium-review.googlesource.com/262956
    Original-Reviewed-by: Duncan Laurie <dlaurie at chromium.org>
    Original-Reviewed-by: Julius Werner <jwerner at chromium.org>
---
 util/cbfstool/Makefile        |   3 +-
 util/cbfstool/Makefile.inc    |   1 +
 util/cbfstool/cbfs_sections.c | 122 ++++++++++++++++++++++++++++
 util/cbfstool/cbfs_sections.h |  59 ++++++++++++++
 util/cbfstool/fmap_from_fmd.c |  15 ++--
 util/cbfstool/fmaptool.c      | 181 +++++++++++++++++++++++++++++++++++-------
 util/cbfstool/fmd.c           |  27 +++----
 util/cbfstool/fmd_parser.c    |  85 ++++++++++----------
 util/cbfstool/fmd_parser.h    |   4 +-
 util/cbfstool/fmd_parser.y    |  13 +--
 10 files changed, 405 insertions(+), 105 deletions(-)

diff --git a/util/cbfstool/Makefile b/util/cbfstool/Makefile
index cb0b3d8..175e564 100644
--- a/util/cbfstool/Makefile
+++ b/util/cbfstool/Makefile
@@ -22,7 +22,8 @@ CBFSTOOL_COMMON+=lzma/C/LzFind.o  lzma/C/LzmaDec.o  lzma/C/LzmaEnc.o
 CBFSTOOL_COMMON:=$(addprefix $(obj)/,$(CBFSTOOL_COMMON))
 
 FMAPTOOL_BINARY:=$(obj)/fmaptool
-FMAPTOOL_COMMON:=fmap_from_fmd.o fmd.o fmd_parser.o fmd_scanner.o
+FMAPTOOL_COMMON:=cbfs_sections.o fmap_from_fmd.o
+FMAPTOOL_COMMON+=fmd.o fmd_parser.o fmd_scanner.o
 # FMAP
 FMAPTOOL_COMMON+=flashmap/fmap.o
 FMAPTOOL_COMMON+=flashmap/kv_pair.o flashmap/valstr.o
diff --git a/util/cbfstool/Makefile.inc b/util/cbfstool/Makefile.inc
index b5eed70..b3377e6 100644
--- a/util/cbfstool/Makefile.inc
+++ b/util/cbfstool/Makefile.inc
@@ -19,6 +19,7 @@ cbfsobj += cbfs-payload-linux.o
 
 fmapobj :=
 fmapobj += fmaptool.o
+fmapobj += cbfs_sections.o
 fmapobj += fmap_from_fmd.o
 fmapobj += fmd.o
 fmapobj += fmd_parser.o
diff --git a/util/cbfstool/cbfs_sections.c b/util/cbfstool/cbfs_sections.c
new file mode 100644
index 0000000..81912d5
--- /dev/null
+++ b/util/cbfstool/cbfs_sections.c
@@ -0,0 +1,122 @@
+/*
+ * fmap_sections.c, track which sections of the image will contain CBFSes
+ *
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
+ */
+
+#include "cbfs_sections.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct descriptor_node {
+	const struct flashmap_descriptor *val;
+	struct descriptor_node *next;
+};
+
+static struct descriptor_list {
+	struct descriptor_node *head;
+	struct descriptor_node *tail;
+} cbfs_sections;
+
+static bool seen_primary_section = false;
+
+static void descriptor_list_prepend(struct descriptor_list *list,
+					struct descriptor_node *new_head)
+{
+	assert(list);
+	assert(new_head);
+
+	new_head->next = list->head;
+	list->head = new_head;
+	if (!list->tail)
+		list->tail = new_head;
+}
+
+static void descriptor_list_append(struct descriptor_list *list,
+					struct descriptor_node *new_tail)
+{
+	assert(list);
+	assert(new_tail);
+
+	if (list->tail)
+		list->tail->next = new_tail;
+	list->tail = new_tail;
+	if (!list->head)
+		list->head = new_tail;
+}
+
+/* Implementation of cbfs module's callback; invoked during fmd file parsing */
+bool fmd_process_annotation_impl(const struct flashmap_descriptor *node,
+							const char *annotation)
+{
+	if (strcmp(annotation, SECTION_ANNOTATION_CBFS) == 0 &&
+							node->list_len == 0) {
+		struct descriptor_node *list_node = malloc(sizeof(*list_node));
+		list_node->val = node;
+		list_node->next = NULL;
+
+		if (strcmp(node->name, SECTION_NAME_PRIMARY_CBFS) == 0) {
+			descriptor_list_prepend(&cbfs_sections, list_node);
+			seen_primary_section = true;
+		} else {
+			descriptor_list_append(&cbfs_sections, list_node);
+		}
+
+		return true;
+	}
+
+	return false;
+}
+
+cbfs_section_iterator_t cbfs_sections_iterator(void)
+{
+	return cbfs_sections.head;
+}
+
+bool cbfs_sections_iterator_advance(cbfs_section_iterator_t *it)
+{
+	assert(it);
+	if (!*it)
+		return false;
+
+	*it = (*it)->next;
+	return true;
+}
+
+const struct flashmap_descriptor *cbfs_sections_iterator_deref(
+						cbfs_section_iterator_t it)
+{
+	assert(it);
+	return it->val;
+}
+
+bool cbfs_sections_primary_cbfs_accounted_for(void)
+{
+	return seen_primary_section;
+}
+
+void cbfs_sections_cleanup(void)
+{
+	for (struct descriptor_node *cur = cbfs_sections.head, *next = NULL;
+							cur; cur = next) {
+		next = cur->next;
+		free(cur);
+	}
+	cbfs_sections.head = NULL;
+	cbfs_sections.tail = NULL;
+}
diff --git a/util/cbfstool/cbfs_sections.h b/util/cbfstool/cbfs_sections.h
new file mode 100644
index 0000000..5a23899
--- /dev/null
+++ b/util/cbfstool/cbfs_sections.h
@@ -0,0 +1,59 @@
+/*
+ * fmap_sections.h, track which sections of the image will contain CBFSes
+ *
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
+ */
+
+#ifndef CBFS_SECTIONS_H_
+#define CBFS_SECTIONS_H_
+
+#include "fmd.h"
+
+#include <stdbool.h>
+
+#define SECTION_NAME_FMAP		"FMAP"
+#define SECTION_NAME_PRIMARY_CBFS	"COREBOOT"
+
+#define SECTION_ANNOTATION_CBFS		"CBFS"
+
+typedef const struct descriptor_node *cbfs_section_iterator_t;
+
+/** @return Iterator pointing to first CBFS section, or NULL if none exist */
+cbfs_section_iterator_t cbfs_sections_iterator(void);
+
+/**
+ * Advance iterator to point to the next CBFS section.
+ * If it was already pointing to the last such section, it will be set to NULL.
+ *
+ * @param it (Non-NULL) pointer to (possibly NULL) iterator to be updated
+ * @return   Whether it was successfully advanced (wasn't already NULL)
+ */
+bool cbfs_sections_iterator_advance(cbfs_section_iterator_t *it);
+
+/**
+ * @param it Iterator, which must currently be non-NULL
+ * @return   Section to which it points
+ */
+const struct flashmap_descriptor *cbfs_sections_iterator_deref(
+						cbfs_section_iterator_t it);
+
+/** @return Whether a section named SECTION_NAME_PRIMARY_CBFS is in the list. */
+bool cbfs_sections_primary_cbfs_accounted_for(void);
+
+/** Reclaim the space used to store knowledge of which sections are CBFSes. */
+void cbfs_sections_cleanup(void);
+
+#endif
diff --git a/util/cbfstool/fmap_from_fmd.c b/util/cbfstool/fmap_from_fmd.c
index fa1024b..2671743 100644
--- a/util/cbfstool/fmap_from_fmd.c
+++ b/util/cbfstool/fmap_from_fmd.c
@@ -28,9 +28,8 @@ static bool fmap_append_fmd_node(struct fmap **flashmap,
 				const struct flashmap_descriptor *section,
 						unsigned absolute_watermark) {
 	if (strlen(section->name) >= FMAP_STRLEN) {
-		fprintf(stderr,
-			"ERROR: Section name ('%s') exceeds %d character FMAP format limit\n",
-					section->name, FMAP_STRLEN - 1);
+		ERROR("Section name ('%s') exceeds %d character FMAP format limit\n",
+						section->name, FMAP_STRLEN - 1);
 		return false;
 	}
 
@@ -38,9 +37,8 @@ static bool fmap_append_fmd_node(struct fmap **flashmap,
 
 	if (fmap_append_area(flashmap, absolute_watermark, section->size,
 					(uint8_t *)section->name, 0) < 0) {
-		fprintf(stderr,
-			"ERROR: Failed to insert section '%s' into FMAP\n",
-							section->name);
+		ERROR("Failed to insert section '%s' into FMAP\n",
+								section->name);
 		return false;
 	}
 
@@ -59,8 +57,7 @@ struct fmap *fmap_from_fmd(const struct flashmap_descriptor *desc)
 	assert(desc->size_known);
 
 	if (strlen(desc->name) >= FMAP_STRLEN) {
-		fprintf(stderr,
-			"ERROR: Image name ('%s') exceeds %d character FMAP header limit\n",
+		ERROR("Image name ('%s') exceeds %d character FMAP header limit\n",
 						desc->name, FMAP_STRLEN - 1);
 		return NULL;
 	}
@@ -68,7 +65,7 @@ struct fmap *fmap_from_fmd(const struct flashmap_descriptor *desc)
 	struct fmap *fmap = fmap_create(desc->offset_known ? desc->offset : 0,
 					desc->size, (uint8_t *)desc->name);
 	if (!fmap) {
-		fputs("ERROR: Failed to allocate FMAP header\n", stderr);
+		ERROR("Failed to allocate FMAP header\n");
 		return fmap;
 	}
 
diff --git a/util/cbfstool/fmaptool.c b/util/cbfstool/fmaptool.c
index 961e9dc..09b68d2 100644
--- a/util/cbfstool/fmaptool.c
+++ b/util/cbfstool/fmaptool.c
@@ -18,53 +18,149 @@
  */
 
 #include "common.h"
+#include "cbfs_sections.h"
 #include "fmap_from_fmd.h"
 
 #include <stdio.h>
 #include <string.h>
+#include <unistd.h>
 
 #define STDIN_FILENAME_SENTINEL "-"
 
+#define HEADER_FMAP_OFFSET "FMAP_OFFSET"
+
 enum fmaptool_return {
 	FMAPTOOL_EXIT_SUCCESS = 0,
 	FMAPTOOL_EXIT_BAD_ARGS,
 	FMAPTOOL_EXIT_BAD_INPUT_PATH,
 	FMAPTOOL_EXIT_BAD_OUTPUT_PATH,
 	FMAPTOOL_EXIT_FAILED_DESCRIPTOR,
+	FMAPTOOL_EXIT_MISSING_FMAP_SECTION,
+	FMAPTOOL_EXIT_MISSING_PRIMARY_CBFS,
 	FMAPTOOL_EXIT_FAILED_FMAP_CONVERSION,
 	FMAPTOOL_EXIT_UNKNOWN_FMAP_SIZE,
-	FMAPTOOL_EXIT_FAILED_WRITING_FILE,
+	FMAPTOOL_EXIT_FAILED_WRITING_OUTPUT,
+	FMAPTOOL_EXIT_FAILED_WRITING_HEADER,
 };
 
-bool fmd_process_annotation_impl(unused const struct flashmap_descriptor *node,
-						unused const char *annotation)
+static void usage(const char *invoked_as)
 {
-	// We always accept annotations, but never act on them.
+	fputs("fmaptool: Compiler for fmd (flashmap descriptor) files\n",
+									stderr);
+	fputs("\nUSAGE:\n", stderr);
+	fprintf(stderr,
+		"\t%s [-h <header output file>] <fmd input file> <binary output file>\n",
+								invoked_as);
+	fputs("\nMANDATORY ARGUMENTS:\n", stderr);
+	fprintf(stderr,
+		"<fmd input file> may be '%s' to read from standard input\n",
+						STDIN_FILENAME_SENTINEL);
+	fputs("<binary output file> must be a regular file\n", stderr);
+	fputs("\nOPTIONAL SWITCHES:\n", stderr);
+	fprintf(stderr,
+		"-h\tAlso produce a C header defining %s to the FMAP section's flash offset.\n",
+							HEADER_FMAP_OFFSET);
+	fputs("\nOUTPUT:\n", stderr);
+	fputs("A successful invocation prints a summary of work done to standard error, and a comma-separated list\n",
+									stderr);
+	fputs("of those sections that contain CBFSes, starting with the primary such section, to standard output.\n",
+									stderr);
+}
+
+static void list_cbfs_section_names(void)
+{
+	cbfs_section_iterator_t cbfs_it = cbfs_sections_iterator();
+	assert(cbfs_it);
+
+	bool subsequent = false;
+	while (cbfs_it) {
+		const char *cur_name =
+				cbfs_sections_iterator_deref(cbfs_it)->name;
+		if (cbfs_sections_iterator_advance(&cbfs_it) && subsequent)
+			putchar(',');
+		fputs(cur_name, stdout);
+		subsequent = true;
+	}
+	putchar('\n');
+}
+
+static bool write_header(const char *out_fname,
+					const struct flashmap_descriptor *root)
+{
+	assert(out_fname);
+
+	FILE *header = fopen(out_fname, "w");
+	if (!header) {
+		fprintf(stderr, "FATAL: Unable to open file '%s' for writing\n",
+				out_fname);
+		return false;
+	}
+
+	unsigned fmap_offset =
+			fmd_calc_absolute_offset(root, SECTION_NAME_FMAP);
+	assert(fmap_offset != FMD_NOTFOUND);
+
+	fputs("#ifndef FMAPTOOL_GENERATED_HEADER_H_\n", header);
+	fputs("#define FMAPTOOL_GENERATED_HEADER_H_\n\n", header);
+	fprintf(header, "#define %s %#x\n\n", HEADER_FMAP_OFFSET, fmap_offset);
+	fputs("#endif\n", header);
+
+	fclose(header);
 	return true;
 }
 
+static void full_fmd_cleanup(struct flashmap_descriptor **victim)
+{
+	assert(victim);
+
+	cbfs_sections_cleanup();
+	fmd_cleanup(*victim);
+	*victim = NULL;
+}
+
 int main(int argc, char **argv)
 {
-	if (argc != 3) {
-		fputs("Convert a human-readable flashmap descriptor (fmd) file into the binary FMAP format for use in firmware images\n",
-									stderr);
-		fprintf(stderr,
-			"USAGE: %s <fmd input file> <binary output file>\n",
-								argv[0]);
-		fprintf(stderr,
-			"To read from standard input, provide '%s' as the input filename.\n",
-					STDIN_FILENAME_SENTINEL);
+	struct {
+		// Mandatory
+		const char *fmd_filename;
+		const char *fmap_filename;
+
+		// Optional
+		const char *header_filename;
+	} args = {NULL, NULL, NULL};
+
+	bool show_usage = false;
+	int each_arg;
+	while (!show_usage && (each_arg = getopt(argc, argv, ":h:")) != -1) {
+		switch (each_arg) {
+		case 'h':
+			args.header_filename = optarg;
+			break;
+		case ':':
+			fprintf(stderr, "-%c: Expected an accompanying value\n",
+									optopt);
+			show_usage = true;
+			break;
+		default:
+			fprintf(stderr, "-%c: Unexpected command-line switch\n",
+									optopt);
+			show_usage = true;
+		}
+	}
+
+	if (show_usage || argc - optind != 2) {
+		usage(argv[0]);
 		return FMAPTOOL_EXIT_BAD_ARGS;
 	}
-	const char *fmd_filename = argv[1];
-	const char *fmap_filename = argv[2];
+	args.fmd_filename = argv[optind];
+	args.fmap_filename = argv[optind + 1];
 
 	FILE *fmd_file = stdin;
-	if (strcmp(fmd_filename, STDIN_FILENAME_SENTINEL) != 0) {
-		fmd_file = fopen(fmd_filename, "r");
+	if (strcmp(args.fmd_filename, STDIN_FILENAME_SENTINEL) != 0) {
+		fmd_file = fopen(args.fmd_filename, "r");
 		if (!fmd_file) {
 			fprintf(stderr, "FATAL: Unable to open file '%s'\n",
-								fmd_filename);
+							args.fmd_filename);
 			return FMAPTOOL_EXIT_BAD_INPUT_PATH;
 		}
 	}
@@ -74,14 +170,32 @@ int main(int argc, char **argv)
 	if (!descriptor) {
 		fputs("FATAL: Failed while processing provided descriptor\n",
 									stderr);
+		full_fmd_cleanup(&descriptor);
 		return FMAPTOOL_EXIT_FAILED_DESCRIPTOR;
 	}
 
+	if (!fmd_find_node(descriptor, SECTION_NAME_FMAP)) {
+		fprintf(stderr,
+			"FATAL: Flashmap descriptor must have an '%s' section\n",
+							SECTION_NAME_FMAP);
+		full_fmd_cleanup(&descriptor);
+		return FMAPTOOL_EXIT_MISSING_FMAP_SECTION;
+	}
+
+	if (!cbfs_sections_primary_cbfs_accounted_for()) {
+		fprintf(stderr,
+			"FATAL: Flashmap descriptor must have a '%s' section that is annotated with '(%s)'\n",
+						SECTION_NAME_PRIMARY_CBFS,
+						SECTION_ANNOTATION_CBFS);
+		full_fmd_cleanup(&descriptor);
+		return FMAPTOOL_EXIT_MISSING_PRIMARY_CBFS;
+	}
+
 	struct fmap *flashmap = fmap_from_fmd(descriptor);
 	if (!flashmap) {
 		fputs("FATAL: Failed while constructing FMAP section\n",
 									stderr);
-		fmd_cleanup(descriptor);
+		full_fmd_cleanup(&descriptor);
 		return FMAPTOOL_EXIT_FAILED_FMAP_CONVERSION;
 	}
 
@@ -90,16 +204,16 @@ int main(int argc, char **argv)
 		fputs("FATAL: Failed to determine FMAP section size\n",
 									stderr);
 		fmap_destroy(flashmap);
-		fmd_cleanup(descriptor);
+		full_fmd_cleanup(&descriptor);
 		return FMAPTOOL_EXIT_UNKNOWN_FMAP_SIZE;
 	}
 
-	FILE *fmap_file = fopen(fmap_filename, "wb");
+	FILE *fmap_file = fopen(args.fmap_filename, "wb");
 	if (!fmap_file) {
 		fprintf(stderr, "FATAL: Unable to open file '%s' for writing\n",
-								fmap_filename);
+							args.fmap_filename);
 		fmap_destroy(flashmap);
-		fmd_cleanup(descriptor);
+		full_fmd_cleanup(&descriptor);
 		return FMAPTOOL_EXIT_BAD_OUTPUT_PATH;
 	}
 
@@ -107,13 +221,24 @@ int main(int argc, char **argv)
 		fputs("FATAL: Failed to write final FMAP to file\n", stderr);
 		fclose(fmap_file);
 		fmap_destroy(flashmap);
-		fmd_cleanup(descriptor);
-		return FMAPTOOL_EXIT_FAILED_WRITING_FILE;
+		full_fmd_cleanup(&descriptor);
+		return FMAPTOOL_EXIT_FAILED_WRITING_OUTPUT;
 	}
 	fclose(fmap_file);
-	printf("SUCCESS: Wrote %d bytes to file '%s'\n", size, fmap_filename);
-
 	fmap_destroy(flashmap);
-	fmd_cleanup(descriptor);
+
+	if (args.header_filename &&
+			!write_header(args.header_filename, descriptor)) {
+		full_fmd_cleanup(&descriptor);
+		return FMAPTOOL_EXIT_FAILED_WRITING_HEADER;
+	}
+
+	fprintf(stderr, "SUCCESS: Wrote %d bytes to file '%s'%s\n", size,
+							args.fmap_filename,
+			args.header_filename ? " (and generated header)" : "");
+	fputs("The sections containing CBFSes are: ", stderr);
+	list_cbfs_section_names();
+
+	full_fmd_cleanup(&descriptor);
 	return FMAPTOOL_EXIT_SUCCESS;
 }
diff --git a/util/cbfstool/fmd.c b/util/cbfstool/fmd.c
index bfce049..a4430be 100644
--- a/util/cbfstool/fmd.c
+++ b/util/cbfstool/fmd.c
@@ -19,6 +19,7 @@
 
 #include "fmd.h"
 
+#include "common.h"
 #include "fmd_parser.h"
 #include "fmd_scanner.h"
 #include "option.h"
@@ -56,8 +57,7 @@ static bool validate_descriptor_node(const struct flashmap_descriptor *node,
 
 	ENTRY search_key = {node->name, NULL};
 	if (hsearch(search_key, FIND)) {
-		fprintf(stderr, "ERROR: Multiple sections with name '%s'\n",
-								node->name);
+		ERROR("Multiple sections with name '%s'\n", node->name);
 		return false;
 	}
 	if (!hsearch(search_key, ENTER))
@@ -65,26 +65,22 @@ static bool validate_descriptor_node(const struct flashmap_descriptor *node,
 
 	if (node->offset_known) {
 		if (start.val_known && node->offset < start.val) {
-			fprintf(stderr, "ERROR: Section '%s' starts too low\n",
-								node->name);
+			ERROR("Section '%s' starts too low\n", node->name);
 			return false;
 		} else if (end.val_known && node->offset > end.val) {
-			fprintf(stderr, "ERROR: Section '%s' starts too high\n",
-								node->name);
+			ERROR("Section '%s' starts too high\n", node->name);
 			return false;
 		}
 	}
 
 	if (node->size_known) {
 		if (node->size == 0) {
-			fprintf(stderr, "ERROR: Section '%s' given no space\n",
-								node->name);
+			ERROR("Section '%s' given no space\n", node->name);
 			return false;
 		} else if (node->offset_known) {
 			unsigned node_end = node->offset + node->size;
 			if (end.val_known && node_end > end.val) {
-				fprintf(stderr, "ERROR: Section '%s' too big\n",
-								node->name);
+				ERROR("Section '%s' too big\n", node->name);
 				return false;
 			}
 		}
@@ -120,16 +116,14 @@ static bool complete_missing_info_backward(
 		assert(cur->offset_known || cur->size_known);
 		if (!cur->offset_known) {
 			if (cur->size > end_watermark) {
-				fprintf(stderr, "ERROR: Section '%s' too big\n",
-								cur->name);
+				ERROR("Section '%s' too big\n", cur->name);
 				return false;
 			}
 			cur->offset_known = true;
 			cur->offset = end_watermark -= cur->size;
 		} else if (!cur->size_known) {
 			if (cur->offset > end_watermark) {
-				fprintf(stderr,
-					"ERROR: Section '%s' starts too high\n",
+				ERROR("Section '%s' starts too high\n",
 								cur->name);
 				return false;
 			}
@@ -230,8 +224,7 @@ static bool validate_and_complete_info(struct flashmap_descriptor *cur_level)
 
 		if (!cur_section->size_known) {
 			if (!cur_section->offset_known) {
-				fprintf(stderr,
-					"ERROR: Cannot determine either offset or size of section '%s'\n",
+				ERROR("Cannot determine either offset or size of section '%s'\n",
 							cur_section->name);
 				return false;
 			} else if (!first_incomplete_it) {
@@ -315,7 +308,7 @@ struct flashmap_descriptor *fmd_create(FILE *stream)
 		// This hash table is used to store the declared name of each
 		// section and ensure that each is globally unique.
 		if (!hcreate(fmd_count_nodes(ret))) {
-			perror("ERROR: While initializing hashtable");
+			perror("E: While initializing hashtable");
 			fmd_cleanup(ret);
 			return NULL;
 		}
diff --git a/util/cbfstool/fmd_parser.c b/util/cbfstool/fmd_parser.c
index d97e743..d463393 100644
--- a/util/cbfstool/fmd_parser.c
+++ b/util/cbfstool/fmd_parser.c
@@ -65,12 +65,13 @@
 #line 20 "fmd_parser.y" /* yacc.c:339  */
 
 #include "fmd_scanner.h"
+#include "common.h"
 
 #include <stdlib.h>
 
 struct flashmap_descriptor *res = NULL;
 
-#line 74 "y.tab.c" /* yacc.c:339  */
+#line 75 "y.tab.c" /* yacc.c:339  */
 
 # ifndef YY_NULLPTR
 #  if defined __cplusplus && 201103L <= __cplusplus
@@ -100,7 +101,7 @@ struct flashmap_descriptor *res = NULL;
 extern int yydebug;
 #endif
 /* "%code requires" blocks.  */
-#line 36 "fmd_parser.y" /* yacc.c:355  */
+#line 37 "fmd_parser.y" /* yacc.c:355  */
 
 #include "fmd.h"
 #include "option.h"
@@ -125,7 +126,7 @@ struct flashmap_descriptor *parse_descriptor(char *name,
 					struct descriptor_list children);
 void yyerror(const char *s);
 
-#line 129 "y.tab.c" /* yacc.c:355  */
+#line 130 "y.tab.c" /* yacc.c:355  */
 
 /* Token type.  */
 #ifndef YYTOKENTYPE
@@ -147,7 +148,7 @@ void yyerror(const char *s);
 typedef union YYSTYPE YYSTYPE;
 union YYSTYPE
 {
-#line 28 "fmd_parser.y" /* yacc.c:355  */
+#line 29 "fmd_parser.y" /* yacc.c:355  */
 
 	unsigned intval;
 	char *strval;
@@ -155,7 +156,7 @@ union YYSTYPE
 	struct flashmap_descriptor *region_ptr;
 	struct descriptor_list region_listhdr;
 
-#line 159 "y.tab.c" /* yacc.c:355  */
+#line 160 "y.tab.c" /* yacc.c:355  */
 };
 # define YYSTYPE_IS_TRIVIAL 1
 # define YYSTYPE_IS_DECLARED 1
@@ -170,7 +171,7 @@ int yyparse (void);
 
 /* Copy the second part of user declarations.  */
 
-#line 174 "y.tab.c" /* yacc.c:358  */
+#line 175 "y.tab.c" /* yacc.c:358  */
 
 #ifdef short
 # undef short
@@ -468,8 +469,8 @@ static const yytype_uint8 yytranslate[] =
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint8 yyrline[] =
 {
-       0,    79,    79,    84,   101,   108,   109,   110,   111,   112,
-     113,   114,   115,   116,   118,   122,   123,   124,   135
+       0,    80,    80,    85,   102,   109,   110,   111,   112,   113,
+     114,   115,   116,   117,   119,   123,   124,   125,   136
 };
 #endif
 
@@ -1251,16 +1252,16 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-#line 80 "fmd_parser.y" /* yacc.c:1646  */
+#line 81 "fmd_parser.y" /* yacc.c:1646  */
     {
 	if (!(res = parse_descriptor((yyvsp[-3].strval), (yyvsp[-2].maybe_intval), (yyvsp[-1].maybe_intval), (yyvsp[0].region_listhdr))))
 		YYABORT;
 }
-#line 1260 "y.tab.c" /* yacc.c:1646  */
+#line 1261 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 3:
-#line 86 "fmd_parser.y" /* yacc.c:1646  */
+#line 87 "fmd_parser.y" /* yacc.c:1646  */
     {
 	struct flashmap_descriptor *node = parse_descriptor((yyvsp[-4].strval), (yyvsp[-2].maybe_intval), (yyvsp[-1].maybe_intval), (yyvsp[0].region_listhdr));
 	if (!node)
@@ -1268,7 +1269,7 @@ yyreduce:
 
 	char *annotation = (yyvsp[-3].strval);
 	if (annotation && !fmd_process_annotation_impl(node, annotation)) {
-		fprintf(stderr, "ERROR: Section '%s' has unexpected annotation '(%s)'\n",
+		ERROR("Section '%s' has unexpected annotation '(%s)'\n",
 							node->name, annotation);
 		YYABORT;
 	}
@@ -1276,92 +1277,92 @@ yyreduce:
 
 	(yyval.region_ptr) = node;
 }
-#line 1280 "y.tab.c" /* yacc.c:1646  */
+#line 1281 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 4:
-#line 102 "fmd_parser.y" /* yacc.c:1646  */
+#line 103 "fmd_parser.y" /* yacc.c:1646  */
     {
 	if (!(yyvsp[0].strval)) {
-		perror("ERROR: While allocating section name");
+		perror("E: While allocating section name");
 		YYABORT;
 	}
 }
-#line 1291 "y.tab.c" /* yacc.c:1646  */
+#line 1292 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 5:
-#line 108 "fmd_parser.y" /* yacc.c:1646  */
+#line 109 "fmd_parser.y" /* yacc.c:1646  */
     { (yyval.strval) = NULL; }
-#line 1297 "y.tab.c" /* yacc.c:1646  */
+#line 1298 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 7:
-#line 110 "fmd_parser.y" /* yacc.c:1646  */
+#line 111 "fmd_parser.y" /* yacc.c:1646  */
     { (yyval.strval) = (yyvsp[-1].strval); }
-#line 1303 "y.tab.c" /* yacc.c:1646  */
+#line 1304 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 8:
-#line 111 "fmd_parser.y" /* yacc.c:1646  */
+#line 112 "fmd_parser.y" /* yacc.c:1646  */
     { (yyval.maybe_intval) = (struct unsigned_option){false, 0}; }
-#line 1309 "y.tab.c" /* yacc.c:1646  */
+#line 1310 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 10:
-#line 113 "fmd_parser.y" /* yacc.c:1646  */
+#line 114 "fmd_parser.y" /* yacc.c:1646  */
     { (yyval.maybe_intval) = (struct unsigned_option){true, (yyvsp[0].intval)}; }
-#line 1315 "y.tab.c" /* yacc.c:1646  */
+#line 1316 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 11:
-#line 114 "fmd_parser.y" /* yacc.c:1646  */
+#line 115 "fmd_parser.y" /* yacc.c:1646  */
     { (yyval.maybe_intval) = (struct unsigned_option){false, 0}; }
-#line 1321 "y.tab.c" /* yacc.c:1646  */
+#line 1322 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 13:
-#line 116 "fmd_parser.y" /* yacc.c:1646  */
+#line 117 "fmd_parser.y" /* yacc.c:1646  */
     { (yyval.maybe_intval) = (struct unsigned_option){true, (yyvsp[0].intval)}; }
-#line 1327 "y.tab.c" /* yacc.c:1646  */
+#line 1328 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 14:
-#line 118 "fmd_parser.y" /* yacc.c:1646  */
+#line 119 "fmd_parser.y" /* yacc.c:1646  */
     {
 	(yyval.region_listhdr) = (struct descriptor_list)
 					{.len = 0, .head = NULL, .tail = NULL};
 }
-#line 1336 "y.tab.c" /* yacc.c:1646  */
+#line 1337 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 16:
-#line 123 "fmd_parser.y" /* yacc.c:1646  */
+#line 124 "fmd_parser.y" /* yacc.c:1646  */
     { (yyval.region_listhdr) = (yyvsp[-1].region_listhdr); }
-#line 1342 "y.tab.c" /* yacc.c:1646  */
+#line 1343 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 17:
-#line 125 "fmd_parser.y" /* yacc.c:1646  */
+#line 126 "fmd_parser.y" /* yacc.c:1646  */
     {
 	struct descriptor_node *node = malloc(sizeof(*node));
 	if (!node) {
-		perror("ERROR: While allocating linked list node");
+		perror("E: While allocating linked list node");
 		YYABORT;
 	}
 	node->val = (yyvsp[0].region_ptr);
 	node->next = NULL;
 	(yyval.region_listhdr) = (struct descriptor_list){.len = 1, .head = node, .tail = node};
 }
-#line 1357 "y.tab.c" /* yacc.c:1646  */
+#line 1358 "y.tab.c" /* yacc.c:1646  */
     break;
 
   case 18:
-#line 136 "fmd_parser.y" /* yacc.c:1646  */
+#line 137 "fmd_parser.y" /* yacc.c:1646  */
     {
 	struct descriptor_node *node = malloc(sizeof(*node));
 	if (!node) {
-		perror("ERROR: While allocating linked list node");
+		perror("E: While allocating linked list node");
 		YYABORT;
 	}
 	node->val = (yyvsp[0].region_ptr);
@@ -1371,11 +1372,11 @@ yyreduce:
 	(yyval.region_listhdr) = (struct descriptor_list)
 			{.len = (yyvsp[-1].region_listhdr).len + 1, .head = (yyvsp[-1].region_listhdr).head, .tail = node};
 }
-#line 1375 "y.tab.c" /* yacc.c:1646  */
+#line 1376 "y.tab.c" /* yacc.c:1646  */
     break;
 
 
-#line 1379 "y.tab.c" /* yacc.c:1646  */
+#line 1380 "y.tab.c" /* yacc.c:1646  */
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -1603,7 +1604,7 @@ yyreturn:
 #endif
   return yyresult;
 }
-#line 150 "fmd_parser.y" /* yacc.c:1906  */
+#line 151 "fmd_parser.y" /* yacc.c:1906  */
 
 
 struct flashmap_descriptor *parse_descriptor(char *name,
@@ -1612,7 +1613,7 @@ struct flashmap_descriptor *parse_descriptor(char *name,
 {
 	struct flashmap_descriptor *region = malloc(sizeof(*region));
 	if (!region) {
-		perror("ERROR: While allocating descriptor section");
+		perror("E: While allocating descriptor section");
 		return NULL;
 	}
 	region->name = name;
@@ -1624,7 +1625,7 @@ struct flashmap_descriptor *parse_descriptor(char *name,
 	if (region->list_len) {
 		region->list = malloc(region->list_len * sizeof(*region->list));
 		if (!region->list) {
-			perror("ERROR: While allocating node children array");
+			perror("E: While allocating node children array");
 			return NULL;
 		}
 		struct descriptor_node *cur_node = children.head;
diff --git a/util/cbfstool/fmd_parser.h b/util/cbfstool/fmd_parser.h
index 393a8ff..dc6301d 100644
--- a/util/cbfstool/fmd_parser.h
+++ b/util/cbfstool/fmd_parser.h
@@ -40,7 +40,7 @@
 extern int yydebug;
 #endif
 /* "%code requires" blocks.  */
-#line 36 "fmd_parser.y" /* yacc.c:1909  */
+#line 37 "fmd_parser.y" /* yacc.c:1909  */
 
 #include "fmd.h"
 #include "option.h"
@@ -87,7 +87,7 @@ void yyerror(const char *s);
 typedef union YYSTYPE YYSTYPE;
 union YYSTYPE
 {
-#line 28 "fmd_parser.y" /* yacc.c:1909  */
+#line 29 "fmd_parser.y" /* yacc.c:1909  */
 
 	unsigned intval;
 	char *strval;
diff --git a/util/cbfstool/fmd_parser.y b/util/cbfstool/fmd_parser.y
index 292fba3..2327ae4 100644
--- a/util/cbfstool/fmd_parser.y
+++ b/util/cbfstool/fmd_parser.y
@@ -19,6 +19,7 @@
 
 %{
 #include "fmd_scanner.h"
+#include "common.h"
 
 #include <stdlib.h>
 
@@ -90,7 +91,7 @@ flash_region: region_name region_annotation_opt region_offset_opt
 
 	char *annotation = $2;
 	if (annotation && !fmd_process_annotation_impl(node, annotation)) {
-		fprintf(stderr, "ERROR: Section '%s' has unexpected annotation '(%s)'\n",
+		ERROR("Section '%s' has unexpected annotation '(%s)'\n",
 							node->name, annotation);
 		YYABORT;
 	}
@@ -101,7 +102,7 @@ flash_region: region_name region_annotation_opt region_offset_opt
 region_name: STRING
 {
 	if (!$1) {
-		perror("ERROR: While allocating section name");
+		perror("E: While allocating section name");
 		YYABORT;
 	}
 };
@@ -125,7 +126,7 @@ region_list_entries: flash_region
 {
 	struct descriptor_node *node = malloc(sizeof(*node));
 	if (!node) {
-		perror("ERROR: While allocating linked list node");
+		perror("E: While allocating linked list node");
 		YYABORT;
 	}
 	node->val = $1;
@@ -136,7 +137,7 @@ region_list_entries: flash_region
 {
 	struct descriptor_node *node = malloc(sizeof(*node));
 	if (!node) {
-		perror("ERROR: While allocating linked list node");
+		perror("E: While allocating linked list node");
 		YYABORT;
 	}
 	node->val = $2;
@@ -155,7 +156,7 @@ struct flashmap_descriptor *parse_descriptor(char *name,
 {
 	struct flashmap_descriptor *region = malloc(sizeof(*region));
 	if (!region) {
-		perror("ERROR: While allocating descriptor section");
+		perror("E: While allocating descriptor section");
 		return NULL;
 	}
 	region->name = name;
@@ -167,7 +168,7 @@ struct flashmap_descriptor *parse_descriptor(char *name,
 	if (region->list_len) {
 		region->list = malloc(region->list_len * sizeof(*region->list));
 		if (!region->list) {
-			perror("ERROR: While allocating node children array");
+			perror("E: While allocating node children array");
 			return NULL;
 		}
 		struct descriptor_node *cur_node = children.head;



More information about the coreboot-gerrit mailing list