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 a53ebf0de529690383dbc5f9a0012304effb1728 Author: Patrick Georgi pgeorgi@chromium.org Date: Wed Jul 15 20:49:00 2015 +0200
cbfstool: add extended attributes macros for cbfs_file
CBFS_FILE_FIRST_ATTR(struct cbfs_file *) and CBFS_FILE_NEXT_ATTR(struct cbfs_file *, struct cbfs_file_attribute *) help navigate through extended attributes.
cbfs_add_file_attr(header, tag, size) adds a new file attribute to header.
Change-Id: I325965286c44f31abd95df684d340cebb0e68b75 Signed-off-by: Patrick Georgi pgeorgi@chromium.org --- util/cbfstool/cbfs.h | 12 ++++++++++++ util/cbfstool/cbfs_image.c | 35 +++++++++++++++++++++++++++++++++++ util/cbfstool/cbfs_image.h | 6 ++++++ 3 files changed, 53 insertions(+)
diff --git a/util/cbfstool/cbfs.h b/util/cbfstool/cbfs.h index 3f80a04..d45fc67 100644 --- a/util/cbfstool/cbfs.h +++ b/util/cbfstool/cbfs.h @@ -77,6 +77,7 @@ struct cbfs_file { /* length of file data */ uint32_t len; uint32_t type; + /* offset to struct cbfs_file_attribute or 0 */ uint32_t attributes_offset; /* length of header incl. variable data */ uint32_t offset; @@ -95,6 +96,9 @@ struct cbfs_file_attribute { uint8_t data[0]; } __PACKED;
+#define CBFS_FILE_ATTR_UNUSED 0 +#define CBFS_FILE_ATTR_UNUSED2 0xffffffff + struct cbfs_stage { uint32_t compression; uint64_t entry; @@ -155,6 +159,14 @@ struct cbfs_payload { #define CBFS_COMPONENT_NULL 0xFFFFFFFF
#define CBFS_SUBHEADER(_p) ( (void *) ((((uint8_t *) (_p)) + ntohl((_p)->offset))) ) +#define CBFS_FILE_FIRST_ATTR(_p) (((_p)->attributes_offset <= sizeof(_p)) ? NULL : \ + (struct cbfs_file_attribute *)(((uint8_t *)(_p)) + ntohl((_p)->attributes_offset))) +#define CBFS_FILE_NEXT_ATTR(_p, _a) (!(_a)?NULL: \ + ((((uint8_t *)(_a)) + (_a)->len) >= ((uint8_t*)(_p)) + ntohl((_p)->offset))?NULL: \ + ((((struct cbfs_file_attribute *)(((uint8_t *)(_a)) + (_a)->len))->tag == CBFS_FILE_ATTR_UNUSED) || \ + (((struct cbfs_file_attribute *)(((uint8_t *)(_a)) + (_a)->len))->tag == CBFS_FILE_ATTR_UNUSED2))?NULL: \ + (struct cbfs_file_attribute *)(((uint8_t *)(_a)) + (_a)->len)) + /* 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 315cbe5..0bba33f 100644 --- a/util/cbfstool/cbfs_image.c +++ b/util/cbfstool/cbfs_image.c @@ -1018,6 +1018,41 @@ int cbfs_create_empty_entry(struct cbfs_file *entry, int type, return 0; }
+struct cbfs_file_attribute *cbfs_add_file_attr(struct cbfs_file *header, + uint32_t tag, + uint16_t size) +{ + struct cbfs_file_attribute *attr, *next; + next = CBFS_FILE_FIRST_ATTR(header); + do { + attr = next; + next = CBFS_FILE_NEXT_ATTR(header, attr); + } while (next != NULL); + uint32_t header_size = ntohl(header->offset) + size; + /* FIXME: see hardcode elsewhere */ + if (header_size > 1024) { + DEBUG("exceeding allocated space for cbfs_file headers"); + return NULL; + } + /* attr points to the last valid attribute now. + * If NULL, we have to create the first one. */ + if (attr == NULL) { + header->attributes_offset = header->offset; + attr = (struct cbfs_file_attribute *) + (((uint8_t *)header) + + ntohl(header->attributes_offset)); + } else { + attr = (struct cbfs_file_attribute *) + (((uint8_t *)attr) + + ntohl(attr->len)); + } + header->offset = htonl(header_size); + memset(attr, 0xff, size); + attr->tag = tag; + attr->len = htonl(size); + return attr; +} + /* Finds a place to hold whole data in same memory page. */ static int is_in_same_page(uint32_t start, uint32_t size, uint32_t page) { diff --git a/util/cbfstool/cbfs_image.h b/util/cbfstool/cbfs_image.h index 7a9b484..fae9948 100644 --- a/util/cbfstool/cbfs_image.h +++ b/util/cbfstool/cbfs_image.h @@ -170,4 +170,10 @@ int cbfs_merge_empty_entry(struct cbfs_image *image, struct cbfs_file *entry,
/* Returns the size of a cbfs file header with no extensions */ size_t cbfs_calculate_file_header_size(const char *name); + +/* Adds to header a new extended attribute tagged 'tag', sized 'size'. + * Returns pointer to the new attribute, or NULL on error. */ +struct cbfs_file_attribute *cbfs_add_file_attr(struct cbfs_file *header, + uint32_t tag, + uint16_t size); #endif