From 95c74d71f0904235d44892627322f60a18c9a28c Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 27 Oct 2023 09:29:01 -0500 Subject: [PATCH] treesource: Restore string list output when no type markers 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 Signed-off-by: Rob Herring Message-ID: <20231027142901.2536622-1-robh@kernel.org> Signed-off-by: David Gibson --- 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 c4f8b9b..bb2ec95 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 1e4d314..c06fcd4 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 9b17b37..ae15839 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;