Merge pull request #773 from dp-arm/dp/fiptool-enhancements

Various fiptool enhancements and bug fixes
diff --git a/tools/fiptool/fiptool.c b/tools/fiptool/fiptool.c
index 0084edf..7145815 100644
--- a/tools/fiptool/fiptool.c
+++ b/tools/fiptool/fiptool.c
@@ -82,7 +82,7 @@
 static uuid_t uuid_null = { 0 };
 static int verbose;
 
-static void vlog(int prio, char *msg, va_list ap)
+static void vlog(int prio, const char *msg, va_list ap)
 {
 	char *prefix[] = { "DEBUG", "WARN", "ERROR" };
 
@@ -91,7 +91,7 @@
 	fputc('\n', stderr);
 }
 
-static void log_dbgx(char *msg, ...)
+static void log_dbgx(const char *msg, ...)
 {
 	va_list ap;
 
@@ -100,7 +100,7 @@
 	va_end(ap);
 }
 
-static void log_warnx(char *msg, ...)
+static void log_warnx(const char *msg, ...)
 {
 	va_list ap;
 
@@ -109,7 +109,7 @@
 	va_end(ap);
 }
 
-static void log_err(char *msg, ...)
+static void log_err(const char *msg, ...)
 {
 	char buf[512];
 	va_list ap;
@@ -121,7 +121,7 @@
 	exit(1);
 }
 
-static void log_errx(char *msg, ...)
+static void log_errx(const char *msg, ...)
 {
 	va_list ap;
 
@@ -131,6 +131,26 @@
 	exit(1);
 }
 
+static char *xstrdup(const char *s, const char *msg)
+{
+	char *d;
+
+	d = strdup(s);
+	if (d == NULL)
+		log_errx("strdup: ", msg);
+	return d;
+}
+
+static void *xmalloc(size_t size, const char *msg)
+{
+	void *d;
+
+	d = malloc(size);
+	if (d == NULL)
+		log_errx("malloc: ", msg);
+	return d;
+}
+
 static void add_image(image_t *image)
 {
 	if (nr_images + 1 > MAX_IMAGES)
@@ -210,7 +230,7 @@
 	return NULL;
 }
 
-static int parse_fip(char *filename, fip_toc_header_t *toc_header_out)
+static int parse_fip(const char *filename, fip_toc_header_t *toc_header_out)
 {
 	struct stat st;
 	FILE *fp;
@@ -227,10 +247,7 @@
 	if (fstat(fileno(fp), &st) == -1)
 		log_err("fstat %s", filename);
 
-	buf = malloc(st.st_size);
-	if (buf == NULL)
-		log_err("malloc");
-
+	buf = xmalloc(st.st_size, "failed to load file into memory");
 	if (fread(buf, 1, st.st_size, fp) != st.st_size)
 		log_errx("Failed to read %s", filename);
 	bufend = buf + st.st_size;
@@ -261,16 +278,11 @@
 		 * Build a new image out of the ToC entry and add it to the
 		 * table of images.
 		 */
-		image = malloc(sizeof(*image));
-		if (image == NULL)
-			log_err("malloc");
-
+		image = xmalloc(sizeof(*image),
+		    "failed to allocate memory for image");
 		memcpy(&image->uuid, &toc_entry->uuid, sizeof(uuid_t));
-
-		image->buffer = malloc(toc_entry->size);
-		if (image->buffer == NULL)
-			log_err("malloc");
-
+		image->buffer = xmalloc(toc_entry->size,
+		    "failed to allocate image buffer, is FIP file corrupted?");
 		/* Overflow checks before memory copy. */
 		if (toc_entry->size > (uint64_t)-1 - toc_entry->offset_address)
 			log_errx("FIP %s is corrupted", filename);
@@ -293,7 +305,7 @@
 	return 0;
 }
 
-static image_t *read_image_from_file(uuid_t *uuid, char *filename)
+static image_t *read_image_from_file(const uuid_t *uuid, const char *filename)
 {
 	struct stat st;
 	image_t *image;
@@ -308,15 +320,9 @@
 	if (fstat(fileno(fp), &st) == -1)
 		log_errx("fstat %s", filename);
 
-	image = malloc(sizeof(*image));
-	if (image == NULL)
-		log_err("malloc");
-
+	image = xmalloc(sizeof(*image), "failed to allocate memory for image");
 	memcpy(&image->uuid, uuid, sizeof(uuid_t));
-
-	image->buffer = malloc(st.st_size);
-	if (image->buffer == NULL)
-		log_err("malloc");
+	image->buffer = xmalloc(st.st_size, "failed to allocate image buffer");
 	if (fread(image->buffer, 1, st.st_size, fp) != st.st_size)
 		log_errx("Failed to read %s", filename);
 	image->size = st.st_size;
@@ -325,7 +331,7 @@
 	return image;
 }
 
-static int write_image_to_file(image_t *image, char *filename)
+static int write_image_to_file(const image_t *image, const char *filename)
 {
 	FILE *fp;
 
@@ -570,9 +576,9 @@
 	add_opt(opts, ++i, NULL, 0, 0);
 
 	while (1) {
-		int c, opt_index;
+		int c, opt_index = 0;
 
-		c = getopt_long(argc, argv, "o:", opts, &opt_index);
+		c = getopt_long(argc, argv, "", opts, &opt_index);
 		if (c == -1)
 			break;
 
@@ -582,9 +588,8 @@
 
 			toc_entry = &toc_entries[opt_index];
 			toc_entry->action = DO_PACK;
-			toc_entry->action_arg = strdup(optarg);
-			if (toc_entry->action_arg == NULL)
-				log_err("strdup");
+			toc_entry->action_arg = xstrdup(optarg,
+			    "failed to allocate memory for argument");
 			break;
 		}
 		case OPT_PLAT_TOC_FLAGS:
@@ -641,7 +646,7 @@
 	add_opt(opts, ++i, NULL, 0, 0);
 
 	while (1) {
-		int c, opt_index;
+		int c, opt_index = 0;
 
 		c = getopt_long(argc, argv, "o:", opts, &opt_index);
 		if (c == -1)
@@ -653,9 +658,8 @@
 
 			toc_entry = &toc_entries[opt_index];
 			toc_entry->action = DO_PACK;
-			toc_entry->action_arg = strdup(optarg);
-			if (toc_entry->action_arg == NULL)
-				log_err("strdup");
+			toc_entry->action_arg = xstrdup(optarg,
+			    "failed to allocate memory for argument");
 			break;
 		}
 		case OPT_PLAT_TOC_FLAGS: {
@@ -728,7 +732,7 @@
 	add_opt(opts, ++i, NULL, 0, 0);
 
 	while (1) {
-		int c, opt_index;
+		int c, opt_index = 0;
 
 		c = getopt_long(argc, argv, "fo:", opts, &opt_index);
 		if (c == -1)
@@ -739,9 +743,8 @@
 			unpack_all = 0;
 			toc_entry = &toc_entries[opt_index];
 			toc_entry->action = DO_UNPACK;
-			toc_entry->action_arg = strdup(optarg);
-			if (toc_entry->action_arg == NULL)
-				log_err("strdup");
+			toc_entry->action_arg = xstrdup(optarg,
+			    "failed to allocate memory for argument");
 			break;
 		case 'f':
 			fflag = 1;
@@ -845,7 +848,7 @@
 	add_opt(opts, ++i, NULL, 0, 0);
 
 	while (1) {
-		int c, opt_index;
+		int c, opt_index = 0;
 
 		c = getopt_long(argc, argv, "fo:", opts, &opt_index);
 		if (c == -1)
@@ -977,17 +980,36 @@
 {
 	int i, ret = 0;
 
-	if (argc < 2)
-		usage();
-	argc--, argv++;
+	while (1) {
+		int c, opt_index = 0;
+		static struct option opts[] = {
+			{ "verbose", no_argument, NULL, 'v' },
+			{ NULL, no_argument, NULL, 0 }
+		};
 
-	if (strcmp(argv[0], "-v") == 0 ||
-	    strcmp(argv[0], "--verbose") == 0) {
-		verbose = 1;
-		argc--, argv++;
-		if (argc < 1)
+		/*
+		 * Set POSIX mode so getopt stops at the first non-option
+		 * which is the subcommand.
+		 */
+		c = getopt_long(argc, argv, "+v", opts, &opt_index);
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'v':
+			verbose = 1;
+			break;
+		default:
 			usage();
+		}
 	}
+	argc -= optind;
+	argv += optind;
+	/* Reset optind for subsequent getopt processing. */
+	optind = 0;
+
+	if (argc == 0)
+		usage();
 
 	for (i = 0; i < NELEM(cmds); i++) {
 		if (strcmp(cmds[i].name, argv[0]) == 0) {