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