diff options
| -rw-r--r-- | tools/fit_image.c | 99 | ||||
| -rw-r--r-- | tools/mkimage.c | 3 |
2 files changed, 101 insertions, 1 deletions
diff --git a/tools/fit_image.c b/tools/fit_image.c index 7e59bc43b77..f0fe68894d6 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -24,6 +24,18 @@ static struct legacy_img_hdr header; +struct fit_region { + ulong load; + ulong size; + const char *name; +}; + +static bool fit_regions_overlap(const struct fit_region *a, + const struct fit_region *b) +{ + return a->load < b->load + b->size && b->load < a->load + a->size; +} + static int fit_estimate_hash_sig_size(struct image_tool_params *params, const char *fname) { bool signing = IMAGE_ENABLE_SIGN && @@ -905,6 +917,8 @@ static int fit_import_data(struct image_tool_params *params, const char *fname) int images; int confs; int node; + struct fit_region *regions = NULL; + unsigned int regions_alloc = 0; fd = mmap_fdt(params->cmdname, fname, 0, &old_fdt, &sbuf, false, false); if (fd < 0) @@ -1009,6 +1023,7 @@ static int fit_import_data(struct image_tool_params *params, const char *fname) fdt_for_each_subnode(node, fdt, confs) { const char *conf_name = fdt_get_name(fdt, node, NULL); + unsigned int reg_count = 0; for (int i = 0; i < ARRAY_SIZE(props); i++) { int count = fdt_stringlist_count(fdt, node, props[i]); @@ -1017,6 +1032,11 @@ static int fit_import_data(struct image_tool_params *params, const char *fname) continue; for (int j = 0; j < count; j++) { + const char *img_data; + ulong img_load; + int img_size; + unsigned int k; + const char *img_name = fdt_stringlist_get(fdt, node, props[i], j, NULL); if (!img_name || !*img_name) @@ -1031,10 +1051,88 @@ static int fit_import_data(struct image_tool_params *params, const char *fname) ret = FDT_ERR_NOTFOUND; goto err_munmap; } + + /* + * Collect the memory region the image is + * loaded to. Images without a load address or + * without data are never copied anywhere, so + * they cannot conflict. + */ + if (fit_image_get_load(fdt, img, &img_load)) + continue; + img_data = fdt_getprop(fdt, img, FIT_DATA_PROP, + &img_size); + if (!img_data || img_size <= 0) + continue; + + /* + * A configuration may reference one image + * through several properties, for example + * both "firmware" and "loadables". Count + * each image only once. + */ + for (k = 0; k < reg_count; k++) { + if (!strcmp(regions[k].name, img_name)) + break; + } + if (k < reg_count) + continue; + + if (reg_count == regions_alloc) { + struct fit_region *tmp; + + regions_alloc = regions_alloc ? + regions_alloc * 2 : 8; + tmp = realloc(regions, regions_alloc * + sizeof(*regions)); + if (!tmp) { + fprintf(stderr, + "%s: Out of memory for %u load regions\n", + params->cmdname, + regions_alloc); + ret = -ENOMEM; + goto err_munmap; + } + regions = tmp; + } + + regions[reg_count].load = img_load; + regions[reg_count].size = img_size; + regions[reg_count].name = img_name; + reg_count++; + } + } + + /* + * All images referenced by one configuration are loaded + * together, so no two of them may claim overlapping memory + * regions. Images sharing a load address across different + * configurations are fine, since only one configuration is + * selected at runtime. + */ + for (unsigned int i = 0; i < reg_count; i++) { + for (unsigned int j = i + 1; j < reg_count; j++) { + if (!fit_regions_overlap(®ions[i], + ®ions[j])) + continue; + fprintf(stderr, + "Error: configuration '%s' has overlapping load regions:\n" + " - %s: [0x%lx - 0x%lx]\n" + " - %s: [0x%lx - 0x%lx]\n", + conf_name, + regions[i].name, regions[i].load, + regions[i].load + regions[i].size, + regions[j].name, regions[j].load, + regions[j].load + regions[j].size); + ret = FDT_ERR_BADSTRUCTURE; + goto err_munmap; } } } + free(regions); + regions = NULL; + munmap(old_fdt, sbuf.st_size); /* Close the old fd so we can re-use it. */ @@ -1067,6 +1165,7 @@ static int fit_import_data(struct image_tool_params *params, const char *fname) err_munmap: munmap(old_fdt, sbuf.st_size); err: + free(regions); free(fdt); close(fd); return ret; diff --git a/tools/mkimage.c b/tools/mkimage.c index 3c43962807d..6b3fd60adbf 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -550,7 +550,8 @@ int main(int argc, char **argv) retval = tparams->fflag_handle(¶ms); if (retval != EXIT_SUCCESS) { - if (retval == FDT_ERR_NOTFOUND) { + if (retval == FDT_ERR_NOTFOUND || + retval == FDT_ERR_BADSTRUCTURE) { // Already printed error, exit cleanly exit(EXIT_FAILURE); } |
