overlay_symbol_update() updates the base blob's symbol section to reflect new position of nodes from overlay blob. This allows us to discard the symbol section of overlay blob alltogether. However for case where an external reference found in overlay blob was not resolved by base blob, we will need to merge the symbol section of overlay blob with base blob, except those entries that had a target in base blob and thus could be repositioned in base blob. Signed-off-by: Srivatsa Vaddagiri <vatsa@xxxxxxxxxxxxxx> --- libfdt/fdt_overlay.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/libfdt/fdt_overlay.c b/libfdt/fdt_overlay.c index 560bb27..ac07158 100644 --- a/libfdt/fdt_overlay.c +++ b/libfdt/fdt_overlay.c @@ -1087,6 +1087,55 @@ static int get_path_len(const void *fdt, int nodeoffset) return len; } +int *del_symbol; +int del_symbol_idx; +int del_symbol_size = 512; + +/* + * Symbols in overlay blob that were fixed up to reflect their new position in + * base blob needs to be removed from overlay blob's symbol section. This is + * because for such symbol entries, we would have updated base blob symbol + * section to reflect the new position of nodes in base blob and when we finally + * merge symbol sections of all blobs, we don't want dupicate entries for same + * symbol. + */ +static int delete_symbols(void *fdto, int symb_offset) +{ + int i, rc; + + if (!base_has_fixups) + return 0; + + for (i = 0; i < del_symbol_idx; ++i) { + int prop = del_symbol[i]; + const char *name, *value; + int len; + + value = fdt_getprop_by_offset(fdto, prop, &name, &len); + if (!value) + return len; + + dprintf("Deleting symbol %s from fdto\n", name); + rc = fdt_delprop(fdto, symb_offset, name); + if (rc < 0) + return rc; + } + + return 0; +} + +static void mark_symbol_for_deletion(int prop) +{ + if (!del_symbol) + del_symbol = xmalloc(del_symbol_size); + + del_symbol[del_symbol_idx++] = prop; + if (del_symbol_idx * sizeof(int) >= del_symbol_size) { + del_symbol = xrealloc(del_symbol, del_symbol_size + 512); + del_symbol_size += 512; + } +} + /** * overlay_symbol_update - Update the symbols of base tree after a merge * @fdt: Base Device Tree blob @@ -1181,8 +1230,11 @@ static int overlay_symbol_update(void *fdt, void *fdto) /* get the target of the fragment */ ret = overlay_get_target(fdt, fdto, fragment, &target_path); - if (ret < 0) + if (ret < 0) { + if (ret == -FDT_ERR_BADPHANDLE && base_has_fixups) + continue; return ret; + } target = ret; /* if we have a target path use */ @@ -1223,9 +1275,11 @@ static int overlay_symbol_update(void *fdt, void *fdto) buf[len] = '/'; memcpy(buf + len + 1, rel_path, rel_path_len); buf[len + 1 + rel_path_len] = '\0'; + + mark_symbol_for_deletion(prop); } - return 0; + return delete_symbols(fdto, ov_sym); } /* Return maximum count of nodes that are named fragment@xyz */ -- 2.7.4 -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation -- To unsubscribe from this list: send the line "unsubscribe devicetree-compiler" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html