summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util/cbfstool/cbfs_image.c40
-rw-r--r--util/cbfstool/cbfs_image.h6
-rw-r--r--util/cbfstool/cbfstool.c58
3 files changed, 69 insertions, 35 deletions
diff --git a/util/cbfstool/cbfs_image.c b/util/cbfstool/cbfs_image.c
index 0230d8032e..621a35d16f 100644
--- a/util/cbfstool/cbfs_image.c
+++ b/util/cbfstool/cbfs_image.c
@@ -267,7 +267,8 @@ int cbfs_image_create(struct cbfs_image *image,
return 0;
}
-int cbfs_image_from_file(struct cbfs_image *image, const char *filename)
+int cbfs_image_from_file(struct cbfs_image *image,
+ const char *filename, uint32_t offset)
{
void *header_loc;
@@ -275,7 +276,9 @@ int cbfs_image_from_file(struct cbfs_image *image, const char *filename)
return -1;
DEBUG("read_cbfs_image: %s (%zd bytes)\n", image->buffer.name,
image->buffer.size);
- header_loc = cbfs_find_header(image->buffer.data, image->buffer.size);
+ header_loc = cbfs_find_header(image->buffer.data,
+ image->buffer.size,
+ offset);
if (!header_loc) {
ERROR("%s does not have CBFS master header.\n", filename);
cbfs_image_delete(image);
@@ -767,21 +770,41 @@ int cbfs_walk(struct cbfs_image *image, cbfs_entry_callback callback,
return count;
}
-struct cbfs_header *cbfs_find_header(char *data, size_t size)
+static int cbfs_header_valid(struct cbfs_header *header, size_t size)
+{
+ if ((ntohl(header->magic) == CBFS_HEADER_MAGIC) &&
+ ((ntohl(header->version) == CBFS_HEADER_VERSION1) ||
+ (ntohl(header->version) == CBFS_HEADER_VERSION2)) &&
+ (ntohl(header->romsize) <= size) &&
+ (ntohl(header->offset) < ntohl(header->romsize)))
+ return 1;
+ return 0;
+}
+
+struct cbfs_header *cbfs_find_header(char *data, size_t size,
+ uint32_t forced_offset)
{
size_t offset;
int found = 0;
int32_t rel_offset;
struct cbfs_header *header, *result = NULL;
+ if (forced_offset < (size - sizeof(struct cbfs_header))) {
+ /* Check if the forced header is valid. */
+ header = (struct cbfs_header *)(data + forced_offset);
+ if (cbfs_header_valid(header, size))
+ return header;
+ return NULL;
+ }
+
// Try finding relative offset of master header at end of file first.
rel_offset = *(int32_t *)(data + size - sizeof(int32_t));
offset = size + rel_offset;
DEBUG("relative offset: %#zx(-%#zx), offset: %#zx\n",
(size_t)rel_offset, (size_t)-rel_offset, offset);
+
if (offset >= size - sizeof(*header) ||
- ntohl(((struct cbfs_header *)(data + offset))->magic) !=
- CBFS_HEADER_MAGIC) {
+ !cbfs_header_valid((struct cbfs_header *)(data + offset), size)) {
// Some use cases append non-CBFS data to the end of the ROM.
DEBUG("relative offset seems wrong, scanning whole image...\n");
offset = 0;
@@ -789,13 +812,8 @@ struct cbfs_header *cbfs_find_header(char *data, size_t size)
for (; offset + sizeof(*header) < size; offset++) {
header = (struct cbfs_header *)(data + offset);
- if (ntohl(header->magic) !=(CBFS_HEADER_MAGIC))
- continue;
- if (ntohl(header->version) != CBFS_HEADER_VERSION1 &&
- ntohl(header->version) != CBFS_HEADER_VERSION2) {
- // Probably not a real CBFS header?
+ if (!cbfs_header_valid(header, size))
continue;
- }
if (!found++)
result = header;
}
diff --git a/util/cbfstool/cbfs_image.h b/util/cbfstool/cbfs_image.h
index 0a05eb2841..2c1be3da1c 100644
--- a/util/cbfstool/cbfs_image.h
+++ b/util/cbfstool/cbfs_image.h
@@ -52,7 +52,8 @@ int cbfs_image_create(struct cbfs_image *image,
int32_t entries_offset);
/* Loads a CBFS image from file. Returns 0 on success, otherwise non-zero. */
-int cbfs_image_from_file(struct cbfs_image *image, const char *filename);
+int cbfs_image_from_file(struct cbfs_image *image,
+ const char *filename, uint32_t offset);
/* Writes a CBFS image into file. Returns 0 on success, otherwise non-zero. */
int cbfs_image_write_file(struct cbfs_image *image, const char *filename);
@@ -106,7 +107,8 @@ int cbfs_walk(struct cbfs_image *image, cbfs_entry_callback callback, void *arg)
* NULL (including when multiple headers were found). If there is a X86 ROM
* style signature (pointer at 0xfffffffc) found in ROM, it will be selected as
* the only header.*/
-struct cbfs_header *cbfs_find_header(char *data, size_t size);
+struct cbfs_header *cbfs_find_header(char *data, size_t size,
+ uint32_t forced_offset);
/* Returns the first cbfs_file entry in CBFS image by CBFS header (no matter if
* the entry has valid content or not), otherwise NULL. */
diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c
index 9c611197cf..20e5e0c78a 100644
--- a/util/cbfstool/cbfstool.c
+++ b/util/cbfstool/cbfstool.c
@@ -66,6 +66,7 @@ static struct param {
/* All variables not listed are initialized as zero. */
.arch = CBFS_ARCHITECTURE_UNKNOWN,
.algo = CBFS_COMPRESS_NONE,
+ .headeroffset = ~0,
};
typedef int (*convert_buffer_t)(struct buffer *buffer, uint32_t *offset);
@@ -73,7 +74,8 @@ typedef int (*convert_buffer_t)(struct buffer *buffer, uint32_t *offset);
static int cbfs_add_integer_component(const char *cbfs_name,
const char *name,
uint64_t u64val,
- uint32_t offset) {
+ uint32_t offset,
+ uint32_t headeroffset) {
struct cbfs_image image;
struct buffer buffer;
int i, ret = 1;
@@ -89,7 +91,7 @@ static int cbfs_add_integer_component(const char *cbfs_name,
for (i = 0; i < 8; i++)
buffer.data[i] = (u64val >> i*8) & 0xff;
- if (cbfs_image_from_file(&image, cbfs_name) != 0) {
+ if (cbfs_image_from_file(&image, cbfs_name, headeroffset) != 0) {
ERROR("Could not load ROM image '%s'.\n", cbfs_name);
buffer_delete(&buffer);
return 1;
@@ -119,6 +121,7 @@ static int cbfs_add_component(const char *cbfs_name,
const char *name,
uint32_t type,
uint32_t offset,
+ uint32_t headeroffset,
convert_buffer_t convert)
{
struct cbfs_image image;
@@ -139,7 +142,7 @@ static int cbfs_add_component(const char *cbfs_name,
return 1;
}
- if (cbfs_image_from_file(&image, cbfs_name) != 0) {
+ if (cbfs_image_from_file(&image, cbfs_name, headeroffset) != 0) {
ERROR("Could not load ROM image '%s'.\n", cbfs_name);
return 1;
}
@@ -249,6 +252,7 @@ static int cbfs_add(void)
param.name,
param.type,
param.baseaddress,
+ param.headeroffset,
NULL);
}
@@ -259,6 +263,7 @@ static int cbfs_add_stage(void)
param.name,
CBFS_COMPONENT_STAGE,
param.baseaddress,
+ param.headeroffset,
cbfstool_convert_mkstage);
}
@@ -269,6 +274,7 @@ static int cbfs_add_payload(void)
param.name,
CBFS_COMPONENT_PAYLOAD,
param.baseaddress,
+ param.headeroffset,
cbfstool_convert_mkpayload);
}
@@ -289,6 +295,7 @@ static int cbfs_add_flat_binary(void)
param.name,
CBFS_COMPONENT_PAYLOAD,
param.baseaddress,
+ param.headeroffset,
cbfstool_convert_mkflatpayload);
}
@@ -297,7 +304,8 @@ static int cbfs_add_integer(void)
return cbfs_add_integer_component(param.cbfs_name,
param.name,
param.u64val,
- param.baseaddress);
+ param.baseaddress,
+ param.headeroffset);
}
static int cbfs_remove(void)
@@ -309,7 +317,8 @@ static int cbfs_remove(void)
return 1;
}
- if (cbfs_image_from_file(&image, param.cbfs_name) != 0) {
+ if (cbfs_image_from_file(&image, param.cbfs_name,
+ param.headeroffset) != 0) {
ERROR("Could not load ROM image '%s'.\n",
param.cbfs_name);
return 1;
@@ -433,7 +442,8 @@ static int cbfs_locate(void)
return 1;
}
- if (cbfs_image_from_file(&image, param.cbfs_name) != 0) {
+ if (cbfs_image_from_file(&image, param.cbfs_name,
+ param.headeroffset) != 0) {
ERROR("Failed to load %s.\n", param.cbfs_name);
return 1;
}
@@ -469,7 +479,8 @@ static int cbfs_locate(void)
static int cbfs_print(void)
{
struct cbfs_image image;
- if (cbfs_image_from_file(&image, param.cbfs_name) != 0) {
+ if (cbfs_image_from_file(&image, param.cbfs_name,
+ param.headeroffset) != 0) {
ERROR("Could not load ROM image '%s'.\n",
param.cbfs_name);
return 1;
@@ -494,7 +505,8 @@ static int cbfs_extract(void)
return 1;
}
- if (cbfs_image_from_file(&image, param.cbfs_name) != 0) {
+ if (cbfs_image_from_file(&image, param.cbfs_name,
+ param.headeroffset) != 0) {
ERROR("Could not load ROM image '%s'.\n",
param.cbfs_name);
result = 1;
@@ -523,7 +535,8 @@ static int cbfs_update_fit(void)
return 1;
}
- if (cbfs_image_from_file(&image, param.cbfs_name) != 0) {
+ if (cbfs_image_from_file(&image, param.cbfs_name,
+ param.headeroffset) != 0) {
ERROR("Could not load ROM image '%s'.\n",
param.cbfs_name);
return 1;
@@ -538,17 +551,17 @@ static int cbfs_update_fit(void)
}
static const struct command commands[] = {
- {"add", "f:n:t:b:vh?", cbfs_add},
- {"add-payload", "f:n:t:c:b:vh?C:I:", cbfs_add_payload},
- {"add-stage", "f:n:t:c:b:S:vh?", cbfs_add_stage},
- {"add-flat-binary", "f:n:l:e:c:b:vh?", cbfs_add_flat_binary},
- {"add-int", "i:n:b:vh?", cbfs_add_integer},
- {"remove", "n:vh?", cbfs_remove},
+ {"add", "H;f:n:t:b:vh?", cbfs_add},
+ {"add-payload", "H:f:n:t:c:b:vh?C:I:", cbfs_add_payload},
+ {"add-stage", "H:f:n:t:c:b:S:vh?", cbfs_add_stage},
+ {"add-flat-binary", "H:f:n:l:e:c:b:vh?", cbfs_add_flat_binary},
+ {"add-int", "H:i:n:b:vh?", cbfs_add_integer},
+ {"remove", "H:n:vh?", cbfs_remove},
{"create", "s:B:b:H:a:o:m:vh?", cbfs_create},
- {"locate", "f:n:P:a:Tvh?", cbfs_locate},
- {"print", "vh?", cbfs_print},
- {"extract", "n:f:vh?", cbfs_extract},
- {"update-fit", "n:x:vh?", cbfs_update_fit},
+ {"locate", "H:f:n:P:a:Tvh?", cbfs_locate},
+ {"print", "H:vh?", cbfs_print},
+ {"extract", "H:n:f:vh?", cbfs_extract},
+ {"update-fit", "H:n:x:vh?", cbfs_update_fit},
};
static struct option long_options[] = {
@@ -583,9 +596,10 @@ static void usage(char *name)
("cbfstool: Management utility for CBFS formatted ROM images\n\n"
"USAGE:\n" " %s [-h]\n"
" %s FILE COMMAND [-v] [PARAMETERS]...\n\n" "OPTIONs:\n"
- " -T Output top-aligned memory address\n"
- " -v Provide verbose output\n"
- " -h Display this help message\n\n"
+ " -H header_offset Do not search for header, use this offset\n"
+ " -T Output top-aligned memory address\n"
+ " -v Provide verbose output\n"
+ " -h Display this help message\n\n"
"COMMANDs:\n"
" add -f FILE -n NAME -t TYPE [-b base-address] "
"Add a component\n"