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