<p>Joel Kitching has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/29616">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">cbfstool: add unprocessed flag for file exporting<br><br>Add an unprocessed flag (-U) which modifies how files are exported.<br>In the case of a compressed raw file, extract without decompressing.<br>In the case of a stage or payload, extract without decompressing or<br>converting to an ELF.<br><br>This can be useful for verifying the integrity of a stage or payload,<br>since converting to an ELF may not be a deterministic process on<br>different platforms or coreboot versions.<br><br>BUG=b:111577108<br>TEST=USE=cb_legacy_tianocore emerge-eve edk2 coreboot-utils chromeos-bootimage<br>     cd /build/eve/firmware<br>     /build/eve/usr/bin/cbfstool image.bin extract -r RW_LEGACY \<br>       -n payload -f /tmp/payload_1 -U<br>     START=$((16#`xxd -s 20 -l 4 -p tianocore.cbfs`))<br>     SIZE=$((16#`xxd -s 8 -l 4 -p tianocore.cbfs`))<br>     dd if=tianocore.cbfs skip=$START count=$SIZE bs=1 > /tmp/payload_2<br>     diff /tmp/payload_1 /tmp/payload_2<br>     rm /tmp/payload_1 /tmp/payload_2<br><br>Change-Id: I351d471d699daedd51adf4a860661877f25607e6<br>Signed-off-by: Joel Kitching <kitching@chromium.org><br>---<br>M util/cbfstool/cbfs_image.c<br>M util/cbfstool/cbfs_image.h<br>M util/cbfstool/cbfstool.c<br>3 files changed, 42 insertions(+), 23 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/16/29616/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/util/cbfstool/cbfs_image.c b/util/cbfstool/cbfs_image.c</span><br><span>index 74572a9..d50ebbb 100644</span><br><span>--- a/util/cbfstool/cbfs_image.c</span><br><span>+++ b/util/cbfstool/cbfs_image.c</span><br><span>@@ -1283,7 +1283,7 @@</span><br><span> }</span><br><span> </span><br><span> int cbfs_export_entry(struct cbfs_image *image, const char *entry_name,</span><br><span style="color: hsl(0, 100%, 40%);">-               const char *filename, uint32_t arch)</span><br><span style="color: hsl(120, 100%, 40%);">+                  const char *filename, uint32_t arch, bool do_processing)</span><br><span> {</span><br><span>  struct cbfs_file *entry = cbfs_get_entry(image, entry_name);</span><br><span>         struct buffer buffer;</span><br><span>@@ -1292,26 +1292,33 @@</span><br><span>              return -1;</span><br><span>   }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int compressed_size = ntohl(entry->len);</span><br><span>         unsigned int decompressed_size = 0;</span><br><span>  unsigned int compression = cbfs_file_get_compression_info(entry,</span><br><span>             &decompressed_size);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        decomp_func_ptr decompress = decompression_function(compression);</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!decompress) {</span><br><span style="color: hsl(0, 100%, 40%);">-              ERROR("looking up decompression routine failed\n");</span><br><span style="color: hsl(0, 100%, 40%);">-           return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Force nop decompression */</span><br><span style="color: hsl(120, 100%, 40%);">+ decomp_func_ptr decompress = decompression_function(CBFS_COMPRESS_NONE);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (do_processing) {</span><br><span style="color: hsl(120, 100%, 40%);">+          decompress = decompression_function(compression);</span><br><span style="color: hsl(120, 100%, 40%);">+             if (!decompress) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    ERROR("looking up decompression routine failed\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                 return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+            }</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   LOG("Found file %.30s at 0x%x, type %.12s, size %d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+      LOG("Found file %.30s at 0x%x, type %.12s, compressed %d, size %d\n",</span><br><span>          entry_name, cbfs_get_entry_addr(image, entry),</span><br><span style="color: hsl(0, 100%, 40%);">-          get_cbfs_entry_type_name(ntohl(entry->type)), decompressed_size);</span><br><span style="color: hsl(120, 100%, 40%);">+          get_cbfs_entry_type_name(ntohl(entry->type)), compressed_size,</span><br><span style="color: hsl(120, 100%, 40%);">+     decompressed_size);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned int buffer_size =</span><br><span style="color: hsl(120, 100%, 40%);">+            do_processing ? decompressed_size : compressed_size;</span><br><span>         buffer_init(&buffer, strdup("(cbfs_export_entry)"), NULL, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+   buffer.data = malloc(buffer_size);</span><br><span style="color: hsl(120, 100%, 40%);">+    buffer.size = buffer_size;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  buffer.data = malloc(decompressed_size);</span><br><span style="color: hsl(0, 100%, 40%);">-        buffer.size = decompressed_size;</span><br><span style="color: hsl(0, 100%, 40%);">-        if (decompress(CBFS_SUBHEADER(entry), ntohl(entry->len),</span><br><span style="color: hsl(0, 100%, 40%);">-             buffer.data, buffer.size, NULL)) {</span><br><span style="color: hsl(120, 100%, 40%);">+    if (decompress(CBFS_SUBHEADER(entry), compressed_size,</span><br><span style="color: hsl(120, 100%, 40%);">+                       buffer.data, buffer.size, NULL)) {</span><br><span>            ERROR("decompression failed for %s\n", entry_name);</span><br><span>                buffer_delete(&buffer);</span><br><span>          return -1;</span><br><span>@@ -1323,13 +1330,19 @@</span><br><span>          * one has to do a second pass for stages to potentially decompress</span><br><span>   * the stage data to make it more meaningful.</span><br><span>         */</span><br><span style="color: hsl(0, 100%, 40%);">-     if (ntohl(entry->type) == CBFS_COMPONENT_STAGE) {</span><br><span style="color: hsl(0, 100%, 40%);">-            if (cbfs_stage_make_elf(&buffer, arch)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   buffer_delete(&buffer);</span><br><span style="color: hsl(0, 100%, 40%);">-                     return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (do_processing) {</span><br><span style="color: hsl(120, 100%, 40%);">+          int (*make_elf)(struct buffer *, uint32_t) = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+            switch (ntohl(entry->type)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              case CBFS_COMPONENT_STAGE:</span><br><span style="color: hsl(120, 100%, 40%);">+                    make_elf = cbfs_stage_make_elf;</span><br><span style="color: hsl(120, 100%, 40%);">+                       break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case CBFS_COMPONENT_SELF:</span><br><span style="color: hsl(120, 100%, 40%);">+                     make_elf = cbfs_payload_make_elf;</span><br><span style="color: hsl(120, 100%, 40%);">+                     break;</span><br><span>               }</span><br><span style="color: hsl(0, 100%, 40%);">-       } else if (ntohl(entry->type) == CBFS_COMPONENT_SELF) {</span><br><span style="color: hsl(0, 100%, 40%);">-              if (cbfs_payload_make_elf(&buffer, arch)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               if (make_elf && make_elf(&buffer, arch)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        ERROR("Failed to write %s into %s.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                            entry_name, filename);</span><br><span>                         buffer_delete(&buffer);</span><br><span>                  return -1;</span><br><span>           }</span><br><span>diff --git a/util/cbfstool/cbfs_image.h b/util/cbfstool/cbfs_image.h</span><br><span>index 5772b1b..0cffb9c 100644</span><br><span>--- a/util/cbfstool/cbfs_image.h</span><br><span>+++ b/util/cbfstool/cbfs_image.h</span><br><span>@@ -98,7 +98,7 @@</span><br><span> /* Exports an entry to external file.</span><br><span>  * Returns 0 on success, otherwise (ex, not found) non-zero. */</span><br><span> int cbfs_export_entry(struct cbfs_image *image, const char *entry_name,</span><br><span style="color: hsl(0, 100%, 40%);">-                     const char *filename, uint32_t arch);</span><br><span style="color: hsl(120, 100%, 40%);">+                 const char *filename, uint32_t arch, bool do_processing);</span><br><span> </span><br><span> /* Adds an entry to CBFS image by given name and type. If content_offset is</span><br><span>  * non-zero, try to align "content" (CBFS_SUBHEADER(p)) at content_offset.</span><br><span>diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c</span><br><span>index 28e0e5d..f0fbf5a 100644</span><br><span>--- a/util/cbfstool/cbfstool.c</span><br><span>+++ b/util/cbfstool/cbfstool.c</span><br><span>@@ -83,6 +83,7 @@</span><br><span>  bool stage_xip;</span><br><span>      bool autogen_attr;</span><br><span>   bool machine_parseable;</span><br><span style="color: hsl(120, 100%, 40%);">+       bool unprocessed;</span><br><span>    int fit_empty_entries;</span><br><span>       enum comp_algo compression;</span><br><span>  int precompression;</span><br><span>@@ -1095,7 +1096,7 @@</span><br><span>          return 1;</span><br><span> </span><br><span>        return cbfs_export_entry(&image, param.name, param.filename,</span><br><span style="color: hsl(0, 100%, 40%);">-                                param.arch);</span><br><span style="color: hsl(120, 100%, 40%);">+                          param.arch, !param.unprocessed);</span><br><span> }</span><br><span> </span><br><span> static int cbfs_write(void)</span><br><span>@@ -1314,7 +1315,7 @@</span><br><span>     {"compact", "r:h?", cbfs_compact, true, true},</span><br><span>   {"copy", "r:R:h?", cbfs_copy, true, true},</span><br><span>       {"create", "M:r:s:B:b:H:o:m:vh?", cbfs_create, true, true},</span><br><span style="color: hsl(0, 100%, 40%);">- {"extract", "H:r:m:n:f:vh?", cbfs_extract, true, false},</span><br><span style="color: hsl(120, 100%, 40%);">+  {"extract", "H:r:m:n:f:Uvh?", cbfs_extract, true, false},</span><br><span>        {"layout", "wvh?", cbfs_layout, false, false},</span><br><span>   {"print", "H:r:vkh?", cbfs_print, true, false},</span><br><span>  {"read", "r:f:vh?", cbfs_read, true, false},</span><br><span>@@ -1362,6 +1363,7 @@</span><br><span>     {"xip",           no_argument,       0, 'y' },</span><br><span>     {"gen-attribute", no_argument,       0, 'g' },</span><br><span>     {"mach-parseable",no_argument,       0, 'k' },</span><br><span style="color: hsl(120, 100%, 40%);">+      {"unprocessed",   no_argument,       0, 'U' },</span><br><span>     {NULL,            0,                 0,  0  }</span><br><span> };</span><br><span> </span><br><span>@@ -1428,6 +1430,7 @@</span><br><span>           "  -d               Accept short data; fill downward/from top\n"</span><br><span>           "  -F               Force action\n"</span><br><span>        "  -g               Generate position and alignment arguments\n"</span><br><span style="color: hsl(120, 100%, 40%);">+            "  -U               Unprocessed; don't decompress or make ELF\n"</span><br><span>       "  -v               Provide verbose output\n"</span><br><span>              "  -h               Display this help message\n\n"</span><br><span>         "COMMANDs:\n"</span><br><span>@@ -1473,8 +1476,8 @@</span><br><span>                         "List mutable (or, with -w, readable) image regions\n"</span><br><span>          " print [-r image,regions]                                    "</span><br><span>                       "Show the contents of the ROM\n"</span><br><span style="color: hsl(0, 100%, 40%);">-           " extract [-r image,regions] [-m ARCH] -n NAME -f FILE        "</span><br><span style="color: hsl(0, 100%, 40%);">-                  "Extracts a raw payload from ROM\n"</span><br><span style="color: hsl(120, 100%, 40%);">+      " extract [-r image,regions] [-m ARCH] -n NAME -f FILE [-U]   "</span><br><span style="color: hsl(120, 100%, 40%);">+                        "Extracts a file from ROM\n"</span><br><span>            " write [-F] -r image,regions -f file [-u | -d] [-i int]      "</span><br><span>                       "Write file into same-size [or larger] raw region\n"</span><br><span>            " read [-r fmap-region] -f file                               "</span><br><span>@@ -1770,6 +1773,9 @@</span><br><span>                       case 'k':</span><br><span>                            param.machine_parseable = true;</span><br><span>                              break;</span><br><span style="color: hsl(120, 100%, 40%);">+                        case 'U':</span><br><span style="color: hsl(120, 100%, 40%);">+                             param.unprocessed = true;</span><br><span style="color: hsl(120, 100%, 40%);">+                             break;</span><br><span>                       case 'h':</span><br><span>                    case '?':</span><br><span>                            usage(argv[0]);</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/29616">change 29616</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/29616"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I351d471d699daedd51adf4a860661877f25607e6 </div>
<div style="display:none"> Gerrit-Change-Number: 29616 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Joel Kitching <kitching@google.com> </div>