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> Reviewed-on: https://review.coreboot.org/29616 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-by: Patrick Georgi <pgeorgi@google.com> Reviewed-by: Julius Werner <jwerner@chromium.org>
This commit is contained in:
parent
73bbcee932
commit
21fdd89b0c
|
@ -1286,7 +1286,7 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
int cbfs_export_entry(struct cbfs_image *image, const char *entry_name,
|
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 cbfs_file *entry = cbfs_get_entry(image, entry_name);
|
||||||
struct buffer buffer;
|
struct buffer buffer;
|
||||||
|
@ -1295,26 +1295,37 @@ int cbfs_export_entry(struct cbfs_image *image, const char *entry_name,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int compressed_size = ntohl(entry->len);
|
||||||
unsigned int decompressed_size = 0;
|
unsigned int decompressed_size = 0;
|
||||||
unsigned int compression = cbfs_file_get_compression_info(entry,
|
unsigned int compression = cbfs_file_get_compression_info(entry,
|
||||||
&decompressed_size);
|
&decompressed_size);
|
||||||
|
unsigned int buffer_size;
|
||||||
|
decomp_func_ptr decompress;
|
||||||
|
|
||||||
decomp_func_ptr decompress = decompression_function(compression);
|
if (do_processing) {
|
||||||
if (!decompress) {
|
decompress = decompression_function(compression);
|
||||||
ERROR("looking up decompression routine failed\n");
|
if (!decompress) {
|
||||||
return -1;
|
ERROR("looking up decompression routine failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
buffer_size = decompressed_size;
|
||||||
|
} else {
|
||||||
|
/* Force nop decompression */
|
||||||
|
decompress = decompression_function(CBFS_COMPRESS_NONE);
|
||||||
|
buffer_size = compressed_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
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),
|
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);
|
||||||
|
|
||||||
buffer_init(&buffer, strdup("(cbfs_export_entry)"), NULL, 0);
|
buffer_init(&buffer, strdup("(cbfs_export_entry)"), NULL, 0);
|
||||||
|
buffer.data = malloc(buffer_size);
|
||||||
|
buffer.size = buffer_size;
|
||||||
|
|
||||||
buffer.data = malloc(decompressed_size);
|
if (decompress(CBFS_SUBHEADER(entry), compressed_size,
|
||||||
buffer.size = decompressed_size;
|
buffer.data, buffer.size, NULL)) {
|
||||||
if (decompress(CBFS_SUBHEADER(entry), ntohl(entry->len),
|
|
||||||
buffer.data, buffer.size, NULL)) {
|
|
||||||
ERROR("decompression failed for %s\n", entry_name);
|
ERROR("decompression failed for %s\n", entry_name);
|
||||||
buffer_delete(&buffer);
|
buffer_delete(&buffer);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1326,13 +1337,19 @@ int cbfs_export_entry(struct cbfs_image *image, const char *entry_name,
|
||||||
* one has to do a second pass for stages to potentially decompress
|
* one has to do a second pass for stages to potentially decompress
|
||||||
* the stage data to make it more meaningful.
|
* the stage data to make it more meaningful.
|
||||||
*/
|
*/
|
||||||
if (ntohl(entry->type) == CBFS_COMPONENT_STAGE) {
|
if (do_processing) {
|
||||||
if (cbfs_stage_make_elf(&buffer, arch)) {
|
int (*make_elf)(struct buffer *, uint32_t) = NULL;
|
||||||
buffer_delete(&buffer);
|
switch (ntohl(entry->type)) {
|
||||||
return -1;
|
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 (make_elf && make_elf(&buffer, arch)) {
|
||||||
if (cbfs_payload_make_elf(&buffer, arch)) {
|
ERROR("Failed to write %s into %s.\n",
|
||||||
|
entry_name, filename);
|
||||||
buffer_delete(&buffer);
|
buffer_delete(&buffer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,10 +95,11 @@ int cbfs_image_delete(struct cbfs_image *image);
|
||||||
/* Returns a pointer to entry by name, or NULL if name is not found. */
|
/* Returns a pointer to entry by name, or NULL if name is not found. */
|
||||||
struct cbfs_file *cbfs_get_entry(struct cbfs_image *image, const char *name);
|
struct cbfs_file *cbfs_get_entry(struct cbfs_image *image, const char *name);
|
||||||
|
|
||||||
/* Exports an entry to external file.
|
/* Exports an entry to external file. If do_processing is true, file contents
|
||||||
|
* will be decompressed, and also turned into an ELF if appropriate.
|
||||||
* Returns 0 on success, otherwise (ex, not found) non-zero. */
|
* Returns 0 on success, otherwise (ex, not found) non-zero. */
|
||||||
int cbfs_export_entry(struct cbfs_image *image, const char *entry_name,
|
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
|
/* 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.
|
* non-zero, try to align "content" (CBFS_SUBHEADER(p)) at content_offset.
|
||||||
|
|
|
@ -83,6 +83,7 @@ static struct param {
|
||||||
bool stage_xip;
|
bool stage_xip;
|
||||||
bool autogen_attr;
|
bool autogen_attr;
|
||||||
bool machine_parseable;
|
bool machine_parseable;
|
||||||
|
bool unprocessed;
|
||||||
int fit_empty_entries;
|
int fit_empty_entries;
|
||||||
enum comp_algo compression;
|
enum comp_algo compression;
|
||||||
int precompression;
|
int precompression;
|
||||||
|
@ -1095,7 +1096,7 @@ static int cbfs_extract(void)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return cbfs_export_entry(&image, param.name, param.filename,
|
return cbfs_export_entry(&image, param.name, param.filename,
|
||||||
param.arch);
|
param.arch, !param.unprocessed);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cbfs_write(void)
|
static int cbfs_write(void)
|
||||||
|
@ -1314,7 +1315,7 @@ static const struct command commands[] = {
|
||||||
{"compact", "r:h?", cbfs_compact, true, true},
|
{"compact", "r:h?", cbfs_compact, true, true},
|
||||||
{"copy", "r:R:h?", cbfs_copy, true, true},
|
{"copy", "r:R:h?", cbfs_copy, true, true},
|
||||||
{"create", "M:r:s:B:b:H:o:m:vh?", cbfs_create, 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},
|
{"layout", "wvh?", cbfs_layout, false, false},
|
||||||
{"print", "H:r:vkh?", cbfs_print, true, false},
|
{"print", "H:r:vkh?", cbfs_print, true, false},
|
||||||
{"read", "r:f:vh?", cbfs_read, true, false},
|
{"read", "r:f:vh?", cbfs_read, true, false},
|
||||||
|
@ -1362,6 +1363,7 @@ static struct option long_options[] = {
|
||||||
{"xip", no_argument, 0, 'y' },
|
{"xip", no_argument, 0, 'y' },
|
||||||
{"gen-attribute", no_argument, 0, 'g' },
|
{"gen-attribute", no_argument, 0, 'g' },
|
||||||
{"mach-parseable",no_argument, 0, 'k' },
|
{"mach-parseable",no_argument, 0, 'k' },
|
||||||
|
{"unprocessed", no_argument, 0, 'U' },
|
||||||
{NULL, 0, 0, 0 }
|
{NULL, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1428,6 +1430,7 @@ static void usage(char *name)
|
||||||
" -d Accept short data; fill downward/from top\n"
|
" -d Accept short data; fill downward/from top\n"
|
||||||
" -F Force action\n"
|
" -F Force action\n"
|
||||||
" -g Generate position and alignment arguments\n"
|
" -g Generate position and alignment arguments\n"
|
||||||
|
" -U Unprocessed; don't decompress or make ELF\n"
|
||||||
" -v Provide verbose output\n"
|
" -v Provide verbose output\n"
|
||||||
" -h Display this help message\n\n"
|
" -h Display this help message\n\n"
|
||||||
"COMMANDs:\n"
|
"COMMANDs:\n"
|
||||||
|
@ -1473,8 +1476,8 @@ static void usage(char *name)
|
||||||
"List mutable (or, with -w, readable) image regions\n"
|
"List mutable (or, with -w, readable) image regions\n"
|
||||||
" print [-r image,regions] "
|
" print [-r image,regions] "
|
||||||
"Show the contents of the ROM\n"
|
"Show the contents of the ROM\n"
|
||||||
" extract [-r image,regions] [-m ARCH] -n NAME -f FILE "
|
" extract [-r image,regions] [-m ARCH] -n NAME -f FILE [-U] "
|
||||||
"Extracts a raw payload from ROM\n"
|
"Extracts a file from ROM\n"
|
||||||
" write [-F] -r image,regions -f file [-u | -d] [-i int] "
|
" write [-F] -r image,regions -f file [-u | -d] [-i int] "
|
||||||
"Write file into same-size [or larger] raw region\n"
|
"Write file into same-size [or larger] raw region\n"
|
||||||
" read [-r fmap-region] -f file "
|
" read [-r fmap-region] -f file "
|
||||||
|
@ -1770,6 +1773,9 @@ int main(int argc, char **argv)
|
||||||
case 'k':
|
case 'k':
|
||||||
param.machine_parseable = true;
|
param.machine_parseable = true;
|
||||||
break;
|
break;
|
||||||
|
case 'U':
|
||||||
|
param.unprocessed = true;
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
case '?':
|
case '?':
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
|
|
Loading…
Reference in New Issue