futility: Use flashrom for 'dump_fmap -x'

New ARM boards use an FDTMAP, which is basically just an FDT. This means
that we don't have two potentially conflicting flash maps in the image.
Flashrom supports this without issue, but the firmware signer needs
dump_fmap to support it also.

It would be nice if we had libfmap implementing all this, but this is
apparently a long-running clean-up task. So the next best thing is to
deal with the flashmap in one program - i.e. flashrom.

So support FDTMAP in futility by redirecting 'dump_fmap -x' to flashrom.

BUG=chromium:256912
BRANCH=none
TEST=manual
With the flashrom -x option added, run this:
sudo futility dump_fmap -x /build/peach_pit/firmware/image-peach-pit.bin
gbb_utility --rootkey=rootkey.bin GBB

See that the various chunks of data from the image are output and that
gbb_utility completes without error.

Change-Id: Id8b2c774a16bdd07968765be5e6609b1b0661a0f
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/60862
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
diff --git a/futility/cmd_dump_fmap.c b/futility/cmd_dump_fmap.c
index 4faf221..18a75de 100644
--- a/futility/cmd_dump_fmap.c
+++ b/futility/cmd_dump_fmap.c
@@ -79,30 +79,6 @@
       printf("area_size:       0x%08x (%d)\n", ah->area_size, ah->area_size);
       printf("area_name:       %s\n", buf);
     }
-
-    if (opt_extract) {
-      char *s;
-      for (s = buf; *s; s++)
-        if (*s == ' ')
-          *s = '_';
-      FILE *fp = fopen(buf,"wb");
-      if (!fp) {
-        fprintf(stderr, "%s: can't open %s: %s\n",
-                progname, buf, strerror(errno));
-        retval = 1;
-      } else {
-        if (ah->area_size &&
-            1 != fwrite(base_of_rom + ah->area_offset, ah->area_size, 1, fp)) {
-          fprintf(stderr, "%s: can't write %s: %s\n",
-                  progname, buf, strerror(errno));
-          retval = 1;
-        } else {
-          if (FMT_NORMAL == opt_format)
-            printf("saved as \"%s\"\n", buf);
-        }
-        fclose(fp);
-      }
-    }
   }
 
   return retval;
@@ -351,6 +327,35 @@
 /* End of human-reable stuff */
 /****************************************************************************/
 
+/**
+ * Extract components from an image and write them to separate files
+ *
+ * This uses flashrom so that we don't repeat the FMAP code
+ */
+static int extract_components(const char *fname)
+{
+  static char *flashrom = "/usr/sbin/flashrom";
+  char image_arg[256];
+  char * const argv[] = {
+    flashrom,
+    "-p",
+    image_arg,
+    "-x",
+    "--ignore-lock",
+    "-V",
+    NULL,
+  };
+
+  snprintf(image_arg, sizeof(image_arg),
+           "dummy:emulate=VARIABLE_SIZE,size=auto,image=%s",
+           fname);
+
+  if (execv(flashrom, argv))
+      fprintf(stderr, "%s: Cannot run flashrom\n", progname);
+
+  return 1;
+}
+
 static int do_dump_fmap(int argc, char *argv[])
 {
   int c;
@@ -425,6 +430,11 @@
     return 1;
   }
 
+  if (opt_extract) {
+    retval = extract_components(argv[optind]);
+    return retval;
+  }
+
   fd = open(argv[optind], O_RDONLY);
   if (fd < 0) {
     fprintf(stderr, "%s: can't open %s: %s\n",