summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHung-Te Lin <hungte@chromium.org>2013-01-29 03:16:20 +0800
committerStefan Reinauer <stefan.reinauer@coreboot.org>2013-02-05 22:26:58 +0100
commit49fcd75564e8308d695cf44f54e0e92d693df69b (patch)
tree4083f4d70d9b3856989492ea18766f070d07faa5
parentc03d9b0c4387f7218e6c9c7d94cf86a5e2b3943e (diff)
cbfstool: Fix incorrect CBFS free space by old cbfstool.
Old cbfstool may produce CBFS image with calculation error in size of last empty entry, and then corrupts master header data when you really use every bit in last entry. This fix will correct free space size when you load ROM images with cbfs_image_from_file. Change-Id: I2ada319728ef69ab9296ae446c77d37e05d05fce Signed-off-by: Hung-Te Lin <hungte@chromium.org> Reviewed-on: http://review.coreboot.org/2211 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
-rw-r--r--util/cbfstool/cbfs_image.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/util/cbfstool/cbfs_image.c b/util/cbfstool/cbfs_image.c
index cc4460c66b..f8e2ae71a6 100644
--- a/util/cbfstool/cbfs_image.c
+++ b/util/cbfstool/cbfs_image.c
@@ -105,6 +105,31 @@ static int cbfs_calculate_file_header_size(const char *name) {
align_up(strlen(name) + 1, CBFS_FILENAME_ALIGN));
}
+static int cbfs_fix_legacy_size(struct cbfs_image *image) {
+ // A bug in old cbfstool may produce extra few bytes (by alignment) and
+ // cause cbfstool to overwrite things after free space -- which is
+ // usually CBFS header on x86. We need to workaround that.
+
+ struct cbfs_file *entry, *first = NULL, *last = NULL;
+ for (first = entry = cbfs_find_first_entry(image);
+ entry && cbfs_is_valid_entry(entry);
+ entry = cbfs_find_next_entry(image, entry)) {
+ last = entry;
+ }
+ if ((char *)first < (char *)image->header &&
+ (char *)entry > (char *)image->header) {
+ WARN("CBFS image was created with old cbfstool with size bug. "
+ "Fixing size in last entry...\n");
+ last->len = htonl(ntohl(last->len) -
+ ntohl(image->header->align));
+ DEBUG("Last entry has been changed from 0x%x to 0x%x.\n",
+ cbfs_get_entry_addr(image, entry),
+ cbfs_get_entry_addr(image,
+ cbfs_find_next_entry(image, last)));
+ }
+ return 0;
+}
+
int cbfs_image_from_file(struct cbfs_image *image, const char *filename) {
if (buffer_from_file(&image->buffer, filename) != 0)
return -1;
@@ -117,6 +142,7 @@ int cbfs_image_from_file(struct cbfs_image *image, const char *filename) {
cbfs_image_delete(image);
return -1;
}
+ cbfs_fix_legacy_size(image);
return 0;
}