Patrick Georgi (pgeorgi@google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/10934
-gerrit
commit 0c19aacfd35eff7df6bc71a2afdcf399e39f6cfb Author: Patrick Georgi pgeorgi@chromium.org Date: Wed Jul 15 20:49:00 2015 +0200
cbfstool: add extended attributes structure to cbfs_file
This is a forward and backward compatible approach to extending the cbfs format. Unfortunately we forgot to add a header length or offset to the file name, making old implementations depend on it starting 24 bytes after the cbfs_file structure.
To work around that, add another, extensible structure after the file name, and point to it through an offset, so we can add more variable length structures in the future when necessary.
The offset field which points to the file data is adjusted appropriately and so old implementations still know where to find both any file's data and its successor in the directory.
Files within CBFS that don't use advanced features remain fully usable by old implementations. Files that use advanced features still don't break the data structures.
Change-Id: I325965286c44f31abd95df684d340cebb0e68b75 Signed-off-by: Patrick Georgi pgeorgi@chromium.org --- util/cbfstool/cbfs.h | 8 ++++++++ util/cbfstool/cbfs_image.c | 11 +++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/util/cbfstool/cbfs.h b/util/cbfstool/cbfs.h index 05eabe8..c53ac0e 100644 --- a/util/cbfstool/cbfs.h +++ b/util/cbfstool/cbfs.h @@ -74,6 +74,7 @@ struct cbfs_file { /* length of file data */ uint32_t len; uint32_t type; + /* offset to struct cbfs_file_attributes or 0 */ uint32_t attributes; /* length of header incl. variable data */ uint32_t offset; @@ -82,6 +83,10 @@ struct cbfs_file {
_Static_assert(sizeof(struct cbfs_file) == 24, "cbfs_file size mismatch");
+struct cbfs_file_attributes { + uint32_t len; +} __PACKED; + struct cbfs_stage { uint32_t compression; uint64_t entry; @@ -142,6 +147,9 @@ struct cbfs_payload { #define CBFS_COMPONENT_NULL 0xFFFFFFFF
#define CBFS_SUBHEADER(_p) ( (void *) ((((uint8_t *) (_p)) + ntohl((_p)->offset))) ) +#define CBFS_FILE_ATTRIBUTES(_p) (((_p)->attributes == 0) ? NULL : \ + (struct cbfs_file_attributes *)(((uint8_t *)(_p)) + ntohl((_p)->attributes))) + /* cbfs_image.c */ uint32_t get_cbfs_entry_type(const char *name, uint32_t default_value); uint32_t get_cbfs_compression(const char *name, uint32_t unknown); diff --git a/util/cbfstool/cbfs_image.c b/util/cbfstool/cbfs_image.c index 47aa5aa..9724543 100644 --- a/util/cbfstool/cbfs_image.c +++ b/util/cbfstool/cbfs_image.c @@ -118,7 +118,8 @@ int cbfs_parse_comp_algo(const char *name) static size_t cbfs_calculate_file_header_size(const char *name) { return (sizeof(struct cbfs_file) + - align_up(strlen(name) + 1, CBFS_FILENAME_ALIGN)); + align_up(strlen(name) + 1, CBFS_FILENAME_ALIGN) + + sizeof(struct cbfs_file_attributes)); }
/* Only call on legacy CBFSes possessing a master header. */ @@ -1035,11 +1036,17 @@ int cbfs_create_empty_entry(struct cbfs_file *entry, memcpy(entry->magic, CBFS_FILE_MAGIC, sizeof(entry->magic)); entry->type = htonl(CBFS_COMPONENT_NULL); entry->len = htonl(len); - entry->attributes = 0; + /* FIXME: it doesn't make much sense to have the calculation elsewhere + * while setting all kinds of offsets here, with more to come. */ entry->offset = htonl(cbfs_calculate_file_header_size(name)); + entry->attributes = htonl(cbfs_calculate_file_header_size(name) - + sizeof(struct cbfs_file_attributes)); memset(entry->filename, 0, ntohl(entry->offset) - sizeof(*entry)); strcpy(entry->filename, name); memset(CBFS_SUBHEADER(entry), CBFS_CONTENT_DEFAULT_VALUE, len); + + struct cbfs_file_attributes *attr = CBFS_FILE_ATTRIBUTES(entry); + attr->len = sizeof(struct cbfs_file_attributes); return 0; }