diff options
author | 2018-04-13 10:57:13 +0530 | |
---|---|---|
committer | 2025-06-15 18:57:38 +0300 | |
commit | 2aeee9e5d83107acb1e07c4e6cc3b0bee754a9bc (patch) | |
tree | 9eedce0b9379b78cf5ce7b0fc165e7dcbae9e697 | |
parent | 497cefcbff4e49727699ab4667ba72de54daef28 (diff) |
libfdt: overlay_merge: remove resolved symbols
Merging two overlay blobs will involve merging contents of nodes such as
__symbols__. Not all properties need to be merged however at the end of merge
process. overlay_symbol_update() may already have updated base blob's
__symbols__ node to reflect new position of some nodes from overlay blob. Remove
such symbols from overlay blob's __symbols__ node, to prevent a subsequent merge
of __symbols__ node of both blobs from creating duplicate entries representing
same node.
Change-Id: I8ce45011db3f565d903ace922870a2c2616a560c
Signed-off-by: Srivatsa Vaddagiri <vatsa@codeaurora.org>
-rw-r--r-- | libfdt/fdt_overlay.c | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/libfdt/fdt_overlay.c b/libfdt/fdt_overlay.c index 1491ccc..da27d69 100644 --- a/libfdt/fdt_overlay.c +++ b/libfdt/fdt_overlay.c @@ -855,6 +855,7 @@ static int get_path_len(const void *fdt, int nodeoffset) * overlay_symbol_update - Update the symbols of base tree after a merge * @fdt: Base Device Tree blob * @fdto: Device tree overlay blob + * @merge: Both input blobs are overlay blobs that are being merged * * overlay_symbol_update() updates the symbols of the base tree with the * symbols of the applied overlay @@ -867,9 +868,9 @@ static int get_path_len(const void *fdt, int nodeoffset) * 0 on success * Negative error code on failure */ -static int overlay_symbol_update(void *fdt, void *fdto) +static int overlay_symbol_update(void *fdt, void *fdto, int merge) { - int root_sym, ov_sym, prop, path_len, fragment, target; + int root_sym, ov_sym, prop, next_prop, path_len, fragment, target; int len, frag_name_len, ret, rel_path_len; const char *s, *e; const char *path; @@ -897,7 +898,12 @@ static int overlay_symbol_update(void *fdt, void *fdto) return root_sym; /* iterate over each overlay symbol */ - fdt_for_each_property_offset(prop, fdto, ov_sym) { + + /* Safeguard against property being possibly deleted in this loop */ + prop = fdt_first_property_offset(fdto, ov_sym); + while (prop >= 0) { + next_prop = fdt_next_property_offset(fdto, prop); + path = fdt_getprop_by_offset(fdto, prop, &name, &path_len); if (!path) return path_len; @@ -955,8 +961,14 @@ static int overlay_symbol_update(void *fdt, void *fdto) /* get the target of the fragment */ ret = fdt_overlay_target_offset(fdt, fdto, fragment, &target_path); - if (ret < 0) + if (ret < 0) { + if (ret == -FDT_ERR_BADPHANDLE && merge) { + prop = next_prop; + continue; + } + return ret; + } target = ret; /* if we have a target path use */ @@ -997,6 +1009,31 @@ 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'; + + /* + * In case of merging two overlay blobs, we will be merging + * contents of nodes such as __symbols__ from both overlay + * blobs. Delete this property in __symbols__ node of second + * overlay blob, as it has already been reflected in + * first/combined blob's __symbols__ node. + */ + if (merge) { + ret = fdt_delprop(fdto, ov_sym, name); + if (ret < 0) + return ret; + + /* Bail if this was the last property */ + if (next_prop < 0) + break; + + /* + * Continue with same 'prop' offset, as the next + * property is now available at the same offset + */ + continue; + } + + prop = next_prop; } return 0; @@ -1030,7 +1067,7 @@ int fdt_overlay_apply(void *fdt, void *fdto) if (ret) goto err; - ret = overlay_symbol_update(fdt, fdto); + ret = overlay_symbol_update(fdt, fdto, 0); if (ret) goto err; @@ -1383,7 +1420,7 @@ int fdt_overlay_merge(void *fdt, void *fdto, int *fdto_nospace) if (ret) goto err; - ret = overlay_symbol_update(fdt, fdto); + ret = overlay_symbol_update(fdt, fdto, 1); if (ret) goto err; |