Restore phandle references from __fixups__ node
Some checks failed
Build test / build-make (ubuntu) (push) Has been cancelled
Build test / build-make (alpine) (push) Has been cancelled
Build test / build-make (archlinux) (push) Has been cancelled
Build test / build-make (fedora) (push) Has been cancelled
Build test / build-meson (alpine) (push) Has been cancelled
Build test / build-meson (archlinux) (push) Has been cancelled
Build test / build-meson (fedora) (push) Has been cancelled
Build test / build-meson (ubuntu) (push) Has been cancelled
Build test / clang64 (push) Has been cancelled
Build test / mingw32 (push) Has been cancelled
Build test / mingw64 (push) Has been cancelled
Build test / ucrt64 (push) Has been cancelled

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 <david@gibson.dropbear.id.au>
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
Message-ID: <20250919092912.663304-14-u.kleine-koenig@baylibre.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
Uwe Kleine-König 2025-09-19 11:29:19 +02:00 committed by David Gibson
parent 05c524db44
commit a26ef6400b
4 changed files with 106 additions and 0 deletions

1
dtc.c
View file

@ -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) {

3
dtc.h
View file

@ -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);

View file

@ -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))

View file

@ -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;