From a26ef6400bd845beb6e7f369809ca1c42d856904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 19 Sep 2025 11:29:19 +0200 Subject: [PATCH] Restore phandle references from __fixups__ node MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The __fixups__ node contains information about labels. Parse its properties to create phandle markers which improve the resulting dts when decompiling a device tree blob. Reviewed-by: David Gibson Signed-off-by: Uwe Kleine-König Message-ID: <20250919092912.663304-14-u.kleine-koenig@baylibre.com> Signed-off-by: David Gibson --- dtc.c | 1 + dtc.h | 3 ++ livetree.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++ treesource.c | 6 ++++ 4 files changed, 106 insertions(+) diff --git a/dtc.c b/dtc.c index 9f90b37..6dae60d 100644 --- a/dtc.c +++ b/dtc.c @@ -343,6 +343,7 @@ int main(int argc, char *argv[]) if (generate_symbols) generate_label_tree(dti, "__symbols__", true); + fixup_phandles(dti, "__fixups__"); local_fixup_phandles(dti, "__local_fixups__"); if (generate_fixups) { diff --git a/dtc.h b/dtc.h index d07a583..7231200 100644 --- a/dtc.h +++ b/dtc.h @@ -342,6 +342,7 @@ void sort_tree(struct dt_info *dti); void generate_labels_from_tree(struct dt_info *dti, const char *name); void generate_label_tree(struct dt_info *dti, const char *name, bool allocph); void generate_fixups_tree(struct dt_info *dti, const char *name); +void fixup_phandles(struct dt_info *dti, const char *name); void generate_local_fixups_tree(struct dt_info *dti, const char *name); void local_fixup_phandles(struct dt_info *dti, const char *name); @@ -359,6 +360,8 @@ struct dt_info *dt_from_blob(const char *fname); /* Tree source */ +void property_add_marker(struct property *prop, + enum markertype type, unsigned int offset, char *ref); void add_phandle_marker(struct dt_info *dti, struct property *prop, unsigned int offset); void dt_to_source(FILE *f, struct dt_info *dti); struct dt_info *dt_from_source(const char *f); diff --git a/livetree.c b/livetree.c index 3dbef90..5d72abc 100644 --- a/livetree.c +++ b/livetree.c @@ -1151,6 +1151,102 @@ void generate_fixups_tree(struct dt_info *dti, const char *name) name); } +void fixup_phandles(struct dt_info *dti, const char *name) +{ + struct node *an; + struct property *fp; + + an = get_subnode(dti->dt, name); + if (!an) + return; + + for_each_property(an, fp) { + char *fnext = fp->val.val; + char *fv; + unsigned int fl; + + while ((fl = fp->val.len - (fnext - fp->val.val))) { + char *propname, *soffset; + struct node *n; + struct property *p; + long offset; + + fv = fnext; + fnext = memchr(fv, 0, fl); + + if (!fnext) { + if (quiet < 1) + fprintf(stderr, "Warning: Malformed fixup entry for label %s\n", + fp->name); + break; + } + fnext += 1; + + propname = memchr(fv, ':', fnext - 1 - fv); + if (!propname) { + if (quiet < 1) + fprintf(stderr, "Warning: Malformed fixup entry for label %s\n", + fp->name); + continue; + } + propname++; + + soffset = memchr(propname, ':', fnext - 1 - propname); + if (!soffset) { + if (quiet < 1) + fprintf(stderr, "Warning: Malformed fixup entry for label %s\n", + fp->name); + continue; + } + soffset++; + + /* + * temporarily modify the property to not have to create + * a copy for the node path. + */ + *(propname - 1) = '\0'; + + n = get_node_by_path(dti->dt, fv); + if (!n && quiet < 1) + fprintf(stderr, "Warning: Label %s references non-existing node %s\n", + fp->name, fv); + + *(propname - 1) = ':'; + + if (!n) + continue; + + /* + * temporarily modify the property to not have to create + * a copy for the property name. + */ + *(soffset - 1) = '\0'; + + p = get_property(n, propname); + + if (!p && quiet < 1) + fprintf(stderr, "Warning: Label %s references non-existing property %s in node %s\n", + fp->name, n->fullpath, propname); + + *(soffset - 1) = ':'; + + if (!p) + continue; + + offset = strtol(soffset, NULL, 0); + if (offset < 0 || offset + 4 > p->val.len) { + if (quiet < 1) + fprintf(stderr, + "Warning: Label %s contains invalid offset for property %s in node %s\n", + fp->name, p->name, n->fullpath); + continue; + } + + property_add_marker(p, REF_PHANDLE, offset, fp->name); + } + } +} + void generate_local_fixups_tree(struct dt_info *dti, const char *name) { if (!any_local_fixup_tree(dti, dti->dt)) diff --git a/treesource.c b/treesource.c index e2eca63..bf648bf 100644 --- a/treesource.c +++ b/treesource.c @@ -173,6 +173,12 @@ static struct marker **add_marker(struct marker **mi, return &nm->next; } +void property_add_marker(struct property *prop, + enum markertype type, unsigned int offset, char *ref) +{ + add_marker(&prop->val.markers, type, offset, ref); +} + static void add_string_markers(struct property *prop, unsigned int offset, int len) { int l;