When the DTS output has no type markers, we have to guess the type. Prior to commit 32b9c6130762 ("Preserve datatype markers when emitting dts format"), instances of string lists would be delimited. Since then, a single string with embedded "\0"s are emitted. An embedded "\0" is valid for DTS files, but that's a rare exception and lists of strings are the overwhelming majority. Restore the prior behavior. stringlist.dts is reused for testing this, but needs a couple of tweaks in order to match the dts output. Reported-by: Geert Uytterhoeven <geert+renesas@xxxxxxxxx> Signed-off-by: Rob Herring <robh@xxxxxxxxxx> --- tests/run_tests.sh | 4 ++++ tests/stringlist.dts | 4 ++-- treesource.c | 24 ++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/tests/run_tests.sh b/tests/run_tests.sh index c4f8b9b25577..bb2ec959a6e4 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -634,6 +634,10 @@ dtc_tests () { done # Check -Odts preserving type information + run_dtc_test -I dts -O dtb -o stringlist.test.dtb "$SRCDIR/stringlist.dts" + run_dtc_test -I dtb -O dts -o stringlist.test.dts stringlist.test.dtb + run_wrap_test cmp "$SRCDIR/stringlist.dts" stringlist.test.dts + for tree in type-preservation.dts; do run_dtc_test -I dts -O dts -o $tree.test.dts "$SRCDIR/$tree" run_dtc_test -I dts -O dts $tree.test.dts diff --git a/tests/stringlist.dts b/tests/stringlist.dts index 1e4d3140458f..c06fcd498191 100644 --- a/tests/stringlist.dts +++ b/tests/stringlist.dts @@ -2,8 +2,8 @@ / { compatible = "test-strings"; - #address-cells = <2>; - #size-cells = <2>; + #address-cells = <0x02>; + #size-cells = <0x02>; device { compatible = "foo", "bar"; diff --git a/treesource.c b/treesource.c index 9b17b3768a66..ae15839ba6a5 100644 --- a/treesource.c +++ b/treesource.c @@ -139,6 +139,28 @@ static const char *delim_end[] = { [TYPE_STRING] = "", }; +static void add_string_markers(struct property *prop) +{ + int l, len = prop->val.len; + const char *p = prop->val.val; + + 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; + } +} + static enum markertype guess_value_type(struct property *prop) { int len = prop->val.len; @@ -164,6 +186,8 @@ static enum markertype guess_value_type(struct property *prop) if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul <= (len-nnul)) && (nnotstringlbl == 0)) { + if (nnul > 1) + add_string_markers(prop); return TYPE_STRING; } else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) { return TYPE_UINT32; -- 2.42.0