summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2014-05-09 20:48:49 +1000
committerDavid Gibson <david@gibson.dropbear.id.au>2014-05-09 20:48:49 +1000
commitf240527e54021f82d70d8a09035e575f864c1fbd (patch)
tree5f0741ac7d48cad3fbba9182fa21a6d175a4e806
parent55a3a8823d433f2922cce7bf424ee32e241076c4 (diff)
downloaddevice-tree-compiler-f240527e54021f82d70d8a09035e575f864c1fbd.tar.gz
Fix bug with references to root node
At present, the lexer token for references to a path doesn't permit a reference to the root node &{/}. Fixing the lexer exposes another bug handling this case. This patch fixes both bugs and adds testcases. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
-rw-r--r--dtc-lexer.l2
-rw-r--r--livetree.c4
-rw-r--r--tests/multilabel.dts2
-rw-r--r--tests/multilabel_merge.dts4
-rw-r--r--tests/path-references.c16
-rw-r--r--tests/path-references.dts1
-rw-r--r--tests/references.c19
-rw-r--r--tests/references.dts2
8 files changed, 48 insertions, 2 deletions
diff --git a/dtc-lexer.l b/dtc-lexer.l
index 0821bde..5c9969f 100644
--- a/dtc-lexer.l
+++ b/dtc-lexer.l
@@ -193,7 +193,7 @@ static void lexical_error(const char *fmt, ...);
return DT_REF;
}
-<*>"&{/"{PATHCHAR}+\} { /* new-style path reference */
+<*>"&{/"{PATHCHAR}*\} { /* new-style path reference */
yytext[yyleng-1] = '\0';
DPRINT("Ref: %s\n", yytext+2);
yylval.labelref = xstrdup(yytext+2);
diff --git a/livetree.c b/livetree.c
index b61465f..e229b84 100644
--- a/livetree.c
+++ b/livetree.c
@@ -511,7 +511,9 @@ struct node *get_node_by_phandle(struct node *tree, cell_t phandle)
struct node *get_node_by_ref(struct node *tree, const char *ref)
{
- if (ref[0] == '/')
+ if (streq(ref, "/"))
+ return tree;
+ else if (ref[0] == '/')
return get_node_by_path(tree, ref);
else
return get_node_by_label(tree, ref);
diff --git a/tests/multilabel.dts b/tests/multilabel.dts
index 31116ce..77da06c 100644
--- a/tests/multilabel.dts
+++ b/tests/multilabel.dts
@@ -5,6 +5,8 @@ m1: mq: /memreserve/ 0 0x1000;
/ {
p0: pw: prop = "foo";
+ rref = <&{/}>;
+
/* Explicit phandles */
n1: nx: node1 {
linux,phandle = <0x2000>;
diff --git a/tests/multilabel_merge.dts b/tests/multilabel_merge.dts
index 1632300..3e80298 100644
--- a/tests/multilabel_merge.dts
+++ b/tests/multilabel_merge.dts
@@ -64,3 +64,7 @@ m1: mq: /memreserve/ 0 0x1000;
};
};
+
+/ {
+ rref = <&{/}>;
+};
diff --git a/tests/path-references.c b/tests/path-references.c
index 0746b3f..c8d25fb 100644
--- a/tests/path-references.c
+++ b/tests/path-references.c
@@ -47,6 +47,20 @@ static void check_ref(const void *fdt, int node, const char *checkpath)
node, p, checkpath);
}
+static void check_rref(const void *fdt)
+{
+ const char *p;
+ int len;
+
+ /* Check reference to root node */
+ p = fdt_getprop(fdt, 0, "rref", &len);
+ if (!p)
+ FAIL("fdt_getprop(0, \"rref\"): %s", fdt_strerror(len));
+ if (!streq(p, "/"))
+ FAIL("'rref' in root node has value \"%s\" instead of \"/\"",
+ p);
+}
+
int main(int argc, char *argv[])
{
void *fdt;
@@ -78,5 +92,7 @@ int main(int argc, char *argv[])
if ((!streq(p, "/node1") || !streq(p + strlen("/node1") + 1, "/node2")))
FAIL("multiref has wrong value");
+ check_rref(fdt);
+
PASS();
}
diff --git a/tests/path-references.dts b/tests/path-references.dts
index 91e7ef7..b00fd79 100644
--- a/tests/path-references.dts
+++ b/tests/path-references.dts
@@ -1,6 +1,7 @@
/dts-v1/;
/ {
+ rref = &{/};
/* Check multiple references case */
multiref = &n1 , &n2;
n1: node1 {
diff --git a/tests/references.c b/tests/references.c
index c9d05a2..46662fc 100644
--- a/tests/references.c
+++ b/tests/references.c
@@ -56,6 +56,23 @@ static void check_ref(const void *fdt, int node, uint32_t checkref)
node, ref, checkref);
}
+static void check_rref(const void *fdt)
+{
+ const uint32_t *p;
+ uint32_t ref;
+ int len;
+
+ p = fdt_getprop(fdt, 0, "rref", &len);
+ if (!p)
+ FAIL("fdt_getprop(0, \"rref\"): %s", fdt_strerror(len));
+ if (len != sizeof(*p))
+ FAIL("'rref' in root node has wrong size (%d instead of %zd)",
+ len, sizeof(*p));
+ ref = fdt32_to_cpu(*p);
+ if (ref != fdt_get_phandle(fdt, 0))
+ FAIL("'rref' in root node has value 0x%x instead of 0x0", ref);
+}
+
int main(int argc, char *argv[])
{
void *fdt;
@@ -104,5 +121,7 @@ int main(int argc, char *argv[])
check_ref(fdt, n2, h1);
check_ref(fdt, n3, h4);
+ check_rref(fdt);
+
PASS();
}
diff --git a/tests/references.dts b/tests/references.dts
index 640c931..f783e8b 100644
--- a/tests/references.dts
+++ b/tests/references.dts
@@ -1,6 +1,8 @@
/dts-v1/;
/ {
+ rref = <&{/}>;
+
/* Explicit phandles */
n1: node1 {
linux,phandle = <0x2000>;