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>
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 @@
 			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_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 @@
 / {
 	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 @@
 	};
 
 };
+
+/ {
+	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 @@
 		     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 @@
 	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 @@
 		     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 @@
 	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>;