From a9b9a47857957b50179268f0966a2a4d94bf4f0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 1 Jul 2025 12:31:21 +0200 Subject: [PATCH 1/8] Emit /plugin/ when compiling to .dts with DTSF_PLUGIN set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes `dtc -I dts -O dts` to make the file a plugin if the source file is one. Signed-off-by: Uwe Kleine-König --- treesource.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/treesource.c b/treesource.c index ae15839..8af1780 100644 --- a/treesource.c +++ b/treesource.c @@ -347,7 +347,10 @@ void dt_to_source(FILE *f, struct dt_info *dti) { struct reserve_info *re; - fprintf(f, "/dts-v1/;\n\n"); + fprintf(f, "/dts-v1/;\n"); + if (dti->dtsflags & DTSF_PLUGIN) + fprintf(f, "/plugin/;\n"); + fprintf(f, "\n"); for (re = dti->reservelist; re; re = re->next) { struct label *l; From 4d12fac7939bdf4369b1f6a3d55f27cd577a6ed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 14 Jan 2025 09:40:10 +0100 Subject: [PATCH 2/8] tests: Check for duplication in __local_fixups__ and __fixups__ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Typically the info contained in __local_fixups__ and __fixups__ is autogenerated from phandles used in the tree. However before commit 915daadbb62d ("Start with empty __local_fixups__ and __fixups__ nodes") compiling a dts that has both the __local_fixups__ and/or __fixups__ and phandles that result in entries in these nodes, the fixups were duplicated: $ cat test.dts /dts-v1/; /plugin/; / { important: node { property = <&somenode>, "string"; phandle = <0x01>; self = <&important>; }; __fixups__ { somenode = "/node:property:0"; }; __local_fixups__ { node { self = <0x00>; }; }; __symbols__ { important = "/node"; }; }; $ dtc -v Version: DTC 1.7.2 $ dtc -O dts test2.dts /dts-v1/; / { important: node { property = <&somenode>, "string"; phandle = <0x01>; self = <&important>; }; __fixups__ { somenode = "/node:property:0", "/node:property:0"; }; __local_fixups__ { node { self = <0x00>, <0x00>; }; }; __symbols__ { important = "/node"; }; }; Add a test that ensures this issue isn't reintroduced later. Signed-off-by: Uwe Kleine-König --- tests/over-determined.dts | 23 +++++++++++++++++++++++ tests/run_tests.sh | 4 ++++ 2 files changed, 27 insertions(+) create mode 100644 tests/over-determined.dts diff --git a/tests/over-determined.dts b/tests/over-determined.dts new file mode 100644 index 0000000..fff3795 --- /dev/null +++ b/tests/over-determined.dts @@ -0,0 +1,23 @@ +/dts-v1/; +/plugin/; + +/ { + labelfornodea: nodea { + property = <&labelfornodea>; + }; + + nodeb { + property = <&nonexisting>; + }; + + __fixups__ { + nonexisting = "/nodeb:property:0"; + }; + + __local_fixups__ { + nodea { + property = <0>; + }; + }; +}; + diff --git a/tests/run_tests.sh b/tests/run_tests.sh index fecfe7c..f6c8d41 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -570,6 +570,10 @@ dtc_tests () { run_dtc_test -I dts -O dtb -o dtc_sized_cells.test.dtb "$SRCDIR/sized_cells.dts" run_test sized_cells dtc_sized_cells.test.dtb + run_dtc_test -I dts -O dts -o over-determined-once.test.dts "$SRCDIR/over-determined.dts" + run_dtc_test -I dts -O dts -o over-determined-twice.test.dts "over-determined-once.test.dts" + run_wrap_test cmp over-determined-once.test.dts over-determined-twice.test.dts + run_dtc_test -I dts -O dtb -o dtc_extra-terminating-null.test.dtb "$SRCDIR/extra-terminating-null.dts" run_test extra-terminating-null dtc_extra-terminating-null.test.dtb From 700105325f3e54af0b9f310299dfa9d7324a0739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 14 Jan 2025 11:09:29 +0100 Subject: [PATCH 3/8] New helper to add markers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The add_marker() function is used to create a new marker and add it at the right spot to the relevant marker list. Use it in the add_string_markers() helper (which gets slightly quicker by it). Signed-off-by: Uwe Kleine-König --- treesource.c | 52 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/treesource.c b/treesource.c index 8af1780..72d1cb5 100644 --- a/treesource.c +++ b/treesource.c @@ -139,26 +139,48 @@ static const char *delim_end[] = { [TYPE_STRING] = "", }; +/* + * The invariants in the marker list are: + * - offsets are non-strictly monotonically increasing + * - for a single offset there is at most one type marker + * - for a single offset that has both a type marker and non-type markers, the + * type marker appears before the others. + */ +static struct marker **add_marker(struct marker **mi, + enum markertype type, unsigned int offset, char *ref) +{ + struct marker *nm; + + while (*mi && (*mi)->offset < offset) + mi = &(*mi)->next; + + if (*mi && (*mi)->offset == offset && is_type_marker((*mi)->type)) { + if (is_type_marker(type)) + return mi; + mi = &(*mi)->next; + } + + if (*mi && (*mi)->offset == offset && type == (*mi)->type) + return mi; + + nm = xmalloc(sizeof(*nm)); + nm->type = type; + nm->offset = offset; + nm->ref = ref; + nm->next = *mi; + *mi = nm; + + return &nm->next; +} + static void add_string_markers(struct property *prop) { int l, len = prop->val.len; const char *p = prop->val.val; + struct marker **mi = &prop->val.markers; - for (l = strlen(p) + 1; l < len; l += strlen(p + l) + 1) { - struct marker *m, **nextp; - - m = xmalloc(sizeof(*m)); - m->offset = l; - m->type = TYPE_STRING; - m->ref = NULL; - m->next = NULL; - - /* Find the end of the markerlist */ - nextp = &prop->val.markers; - while (*nextp) - nextp = &((*nextp)->next); - *nextp = m; - } + for (l = strlen(p) + 1; l < len; l += strlen(p + l) + 1) + mi = add_marker(mi, TYPE_STRING, l, NULL); } static enum markertype guess_value_type(struct property *prop) From 635b958d27d3edbb0856a429b3c1c1482e47cc29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 14 Jan 2025 11:29:29 +0100 Subject: [PATCH 4/8] Improve type guessing when compiling to dts format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the presence of (non-type) markers guess the type of each chunk between markers individually instead of only once for the whole property. Note that this only gets relevant with the next few commits that restore labels and phandles. Note further that this rework is necessary with these further changes, because phandle markers are currently not considered for type guessing and so a phandle at an offset that isn't a multiple of 4 triggers an assertion if the property was guessed to have type TYPE_UINT32. Now that guess_value_type() is only called for data chunks without markers, the function can be simplified a bit. Signed-off-by: Uwe Kleine-König --- treesource.c | 70 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/treesource.c b/treesource.c index 72d1cb5..5764959 100644 --- a/treesource.c +++ b/treesource.c @@ -173,23 +173,20 @@ static struct marker **add_marker(struct marker **mi, return &nm->next; } -static void add_string_markers(struct property *prop) +static void add_string_markers(struct property *prop, unsigned int offset, int len) { - int l, len = prop->val.len; - const char *p = prop->val.val; + int l; + const char *p = prop->val.val + offset; struct marker **mi = &prop->val.markers; for (l = strlen(p) + 1; l < len; l += strlen(p + l) + 1) - mi = add_marker(mi, TYPE_STRING, l, NULL); + mi = add_marker(mi, TYPE_STRING, offset + l, NULL); } -static enum markertype guess_value_type(struct property *prop) +static enum markertype guess_value_type(struct property *prop, unsigned int offset, int len) { - int len = prop->val.len; - const char *p = prop->val.val; - struct marker *m = prop->val.markers; + const char *p = prop->val.val + offset; int nnotstring = 0, nnul = 0; - int nnotstringlbl = 0, nnotcelllbl = 0; int i; for (i = 0; i < len; i++) { @@ -199,30 +196,49 @@ static enum markertype guess_value_type(struct property *prop) nnul++; } - for_each_marker_of_type(m, LABEL) { - if ((m->offset > 0) && (prop->val.val[m->offset - 1] != '\0')) - nnotstringlbl++; - if ((m->offset % sizeof(cell_t)) != 0) - nnotcelllbl++; - } - - if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul <= (len-nnul)) - && (nnotstringlbl == 0)) { + if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul <= len - nnul)) { if (nnul > 1) - add_string_markers(prop); + add_string_markers(prop, offset, len); return TYPE_STRING; - } else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) { + } else if ((len % sizeof(cell_t)) == 0) { return TYPE_UINT32; } return TYPE_UINT8; } +static void guess_type_markers(struct property *prop) +{ + struct marker **m = &prop->val.markers; + unsigned int offset = 0; + + for (m = &prop->val.markers; *m; m = &((*m)->next)) { + if (is_type_marker((*m)->type)) + /* assume the whole property is already marked */ + return; + + if ((*m)->offset > offset) { + m = add_marker(m, guess_value_type(prop, offset, (*m)->offset - offset), + offset, NULL); + + offset = (*m)->offset; + } + + if ((*m)->type == REF_PHANDLE) { + m = add_marker(m, TYPE_UINT32, offset, NULL); + offset += 4; + } + } + + if (offset < prop->val.len) + add_marker(m, guess_value_type(prop, offset, prop->val.len - offset), + offset, NULL); +} + static void write_propval(FILE *f, struct property *prop) { size_t len = prop->val.len; - struct marker *m = prop->val.markers; - struct marker dummy_marker; + struct marker *m; enum markertype emit_type = TYPE_NONE; char *srcstr; @@ -241,14 +257,8 @@ static void write_propval(FILE *f, struct property *prop) fprintf(f, " ="); - if (!next_type_marker(m)) { - /* data type information missing, need to guess */ - dummy_marker.type = guess_value_type(prop); - dummy_marker.next = prop->val.markers; - dummy_marker.offset = 0; - dummy_marker.ref = NULL; - m = &dummy_marker; - } + guess_type_markers(prop); + m = prop->val.markers; for_each_marker(m) { size_t chunk_len = (m->next ? m->next->offset : len) - m->offset; From 6a6f5aecd4915407ff39dc030987b39a7e09c957 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sun, 20 Oct 2024 22:54:44 +0200 Subject: [PATCH 5/8] Restore labels from __symbols__ node MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the input has a __symbols__ node, restore the named labels for the respective nodes. Signed-off-by: Uwe Kleine-König --- dtc.c | 2 ++ dtc.h | 1 + livetree.c | 21 +++++++++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/dtc.c b/dtc.c index b3445b7..63a6c85 100644 --- a/dtc.c +++ b/dtc.c @@ -338,6 +338,8 @@ int main(int argc, char *argv[]) if (auto_label_aliases) generate_label_tree(dti, "aliases", false); + generate_labels_from_tree(dti, "__symbols__"); + if (generate_symbols) generate_label_tree(dti, "__symbols__", true); diff --git a/dtc.h b/dtc.h index 3a220b9..f97f3c2 100644 --- a/dtc.h +++ b/dtc.h @@ -339,6 +339,7 @@ struct dt_info *build_dt_info(unsigned int dtsflags, struct reserve_info *reservelist, struct node *tree, uint32_t boot_cpuid_phys); 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 generate_local_fixups_tree(struct dt_info *dti, const char *name); diff --git a/livetree.c b/livetree.c index d51d058..cc54f97 100644 --- a/livetree.c +++ b/livetree.c @@ -1046,6 +1046,27 @@ static void generate_local_fixups_tree_internal(struct dt_info *dti, generate_local_fixups_tree_internal(dti, lfn, c); } +void generate_labels_from_tree(struct dt_info *dti, const char *name) +{ + struct node *an; + struct property *p; + + an = get_subnode(dti->dt, name); + if (!an) + return; + + for_each_property(an, p) { + struct node *labeled_node; + + labeled_node = get_node_by_path(dti->dt, p->val.val); + if (labeled_node) + add_label(&labeled_node->labels, p->name); + else if (quiet < 1) + fprintf(stderr, "Warning: Path %s referenced in property %s/%s missing", + p->val.val, name, p->name); + } +} + void generate_label_tree(struct dt_info *dti, const char *name, bool allocph) { if (!any_label_tree(dti, dti->dt)) From c4aadcb58906f4a4c0bd120dbadb65df1f84b94c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Mon, 21 Oct 2024 09:23:56 +0200 Subject: [PATCH 6/8] Restore phandle references from __local_fixups__ node MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The __local_fixups__ node contains information about phandles. Parse it to improve the result when decompiling a device tree blob. Note that this is essential to do before the __local_fixups__ node is removed in generate_local_fixups_tree() because otherwise the information contained in that node is lost. Fixes: 915daadbb62d ("Start with empty __local_fixups__ and __fixups__ nodes") Signed-off-by: Uwe Kleine-König --- dtc.c | 2 ++ dtc.h | 2 ++ livetree.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++ treesource.c | 33 ++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+) diff --git a/dtc.c b/dtc.c index 63a6c85..9f90b37 100644 --- a/dtc.c +++ b/dtc.c @@ -343,6 +343,8 @@ int main(int argc, char *argv[]) if (generate_symbols) generate_label_tree(dti, "__symbols__", true); + local_fixup_phandles(dti, "__local_fixups__"); + if (generate_fixups) { generate_fixups_tree(dti, "__fixups__"); generate_local_fixups_tree(dti, "__local_fixups__"); diff --git a/dtc.h b/dtc.h index f97f3c2..d07a583 100644 --- a/dtc.h +++ b/dtc.h @@ -343,6 +343,7 @@ 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 generate_local_fixups_tree(struct dt_info *dti, const char *name); +void local_fixup_phandles(struct dt_info *dti, const char *name); /* Checks */ @@ -358,6 +359,7 @@ struct dt_info *dt_from_blob(const char *fname); /* Tree source */ +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 cc54f97..10b767d 100644 --- a/livetree.c +++ b/livetree.c @@ -1103,3 +1103,60 @@ void generate_local_fixups_tree(struct dt_info *dti, const char *name) build_and_name_child_node(dti->dt, name), dti->dt); } + +static void local_fixup_phandles_node(struct dt_info *dti, struct node *lf, struct node *n) +{ + struct property *lfp; + struct node *lfsubnode; + + for_each_property(lf, lfp) { + struct property *p = get_property(n, lfp->name); + fdt32_t *offsets = (fdt32_t *)lfp->val.val; + size_t i; + + if (!p) { + if (quiet < 1) + fprintf(stderr, "Warning: Property %s in %s referenced in __local_fixups__ missing\n", + lfp->name, n->fullpath); + continue; + } + + /* + * Each property in the __local_fixups__ tree is a concatenation + * of offsets, so it must be a multiple of sizeof(fdt32_t). + */ + if (lfp->val.len % sizeof(fdt32_t)) { + if (quiet < 1) + fprintf(stderr, "Warning: property %s in /__local_fixups__%s malformed\n", + lfp->name, n->fullpath); + continue; + } + + for (i = 0; i < lfp->val.len / sizeof(fdt32_t); i++) + add_phandle_marker(dti, p, dtb_ld32(offsets + i)); + } + + for_each_child(lf, lfsubnode) { + struct node *subnode = get_subnode(n, lfsubnode->name); + + if (!subnode) { + if (quiet < 1) + fprintf(stderr, "Warning: node %s/%s referenced in __local_fixups__ missing\n", + lfsubnode->name, n->fullpath); + continue; + } + + local_fixup_phandles_node(dti, lfsubnode, subnode); + } +} + +void local_fixup_phandles(struct dt_info *dti, const char *name) +{ + struct node *an; + + an = get_subnode(dti->dt, name); + if (!an) + return; + + local_fixup_phandles_node(dti, an, dti->dt); +} diff --git a/treesource.c b/treesource.c index 5764959..5b8d7a6 100644 --- a/treesource.c +++ b/treesource.c @@ -183,6 +183,39 @@ static void add_string_markers(struct property *prop, unsigned int offset, int l mi = add_marker(mi, TYPE_STRING, offset + l, NULL); } +void add_phandle_marker(struct dt_info *dti, struct property *prop, unsigned int offset) +{ + cell_t phandle; + struct node *refn; + char *ref; + + if (prop->val.len < offset + 4) { + if (quiet < 1) + fprintf(stderr, + "Warning: property %s too short to contain a phandle at offset %u\n", + prop->name, offset); + + } + + phandle = dtb_ld32(prop->val.val + offset); + refn = get_node_by_phandle(dti->dt, phandle); + + if (!refn) { + if (quiet < 1) + fprintf(stderr, + "Warning: node referenced by phandle 0x%x in property %s not found\n", + phandle, prop->name); + return; + } + + if (refn->labels) + ref = refn->labels->label; + else + ref = refn->fullpath; + + add_marker(&prop->val.markers, REF_PHANDLE, offset, ref); +} + static enum markertype guess_value_type(struct property *prop, unsigned int offset, int len) { const char *p = prop->val.val + offset; From 75ccab9a228b2186e15483c1f560bb96a3c71756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Mon, 13 Jan 2025 18:01:54 +0100 Subject: [PATCH 7/8] 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. Note that this is essential to do before the __fixups__ node is removed in generate_fixups_tree() because otherwise the information contained in that node is lost. Fixes: 915daadbb62d ("Start with empty __local_fixups__ and __fixups__ nodes") Signed-off-by: Uwe Kleine-König --- 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 10b767d..3b2fc8e 100644 --- a/livetree.c +++ b/livetree.c @@ -1090,6 +1090,102 @@ void generate_fixups_tree(struct dt_info *dti, const char *name) dti->dt); } +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) { struct node *n = get_subnode(dti->dt, name); diff --git a/treesource.c b/treesource.c index 5b8d7a6..6cd996f 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; From 64bbc331b444a38ad0f5386da473051681ef9870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 1 Jul 2025 12:55:57 +0200 Subject: [PATCH 8/8] Set DTSF_PLUGIN if needed when compiling from dtb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The need for the plugin flag is determined by the existence of __fixups__ or __local_fixups__. This is a bit simplifying because if __fixups__ or __local_fixups__ exist but don't have properties, the plugin flag isn't needed. But in practise the test should be good enough such that this corner case doesn't matter. Signed-off-by: Uwe Kleine-König --- flattree.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/flattree.c b/flattree.c index 30e6de2..f3b698c 100644 --- a/flattree.c +++ b/flattree.c @@ -807,6 +807,7 @@ struct dt_info *dt_from_blob(const char *fname) struct node *tree; uint32_t val; int flags = 0; + unsigned int dtsflags = DTSF_V1; f = srcfile_relative_open(fname, NULL); @@ -919,5 +920,8 @@ struct dt_info *dt_from_blob(const char *fname) fclose(f); - return build_dt_info(DTSF_V1, reservelist, tree, boot_cpuid_phys); + if (get_subnode(tree, "__fixups__") || get_subnode(tree, "__local_fixups__")) + dtsflags |= DTSF_PLUGIN; + + return build_dt_info(dtsflags, reservelist, tree, boot_cpuid_phys); }