Browse Source

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>
main
David Gibson 11 years ago
parent
commit
f240527e54
  1. 2
      dtc-lexer.l
  2. 4
      livetree.c
  3. 2
      tests/multilabel.dts
  4. 4
      tests/multilabel_merge.dts
  5. 16
      tests/path-references.c
  6. 1
      tests/path-references.dts
  7. 19
      tests/references.c
  8. 2
      tests/references.dts

2
dtc-lexer.l

@ -193,7 +193,7 @@ static void lexical_error(const char *fmt, ...); @@ -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);

4
livetree.c

@ -511,7 +511,9 @@ struct node *get_node_by_phandle(struct node *tree, cell_t phandle) @@ -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);

2
tests/multilabel.dts

@ -5,6 +5,8 @@ m1: mq: /memreserve/ 0 0x1000; @@ -5,6 +5,8 @@ m1: mq: /memreserve/ 0 0x1000;
/ {
p0: pw: prop = "foo";

rref = <&{/}>;

/* Explicit phandles */
n1: nx: node1 {
linux,phandle = <0x2000>;

4
tests/multilabel_merge.dts

@ -64,3 +64,7 @@ m1: mq: /memreserve/ 0 0x1000; @@ -64,3 +64,7 @@ m1: mq: /memreserve/ 0 0x1000;
};

};

/ {
rref = <&{/}>;
};

16
tests/path-references.c

@ -47,6 +47,20 @@ static void check_ref(const void *fdt, int node, const char *checkpath) @@ -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[]) @@ -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();
}

1
tests/path-references.dts

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
/dts-v1/;

/ {
rref = &{/};
/* Check multiple references case */
multiref = &n1 , &n2;
n1: node1 {

19
tests/references.c

@ -56,6 +56,23 @@ static void check_ref(const void *fdt, int node, uint32_t checkref) @@ -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[]) @@ -104,5 +121,7 @@ int main(int argc, char *argv[])
check_ref(fdt, n2, h1);
check_ref(fdt, n3, h4);

check_rref(fdt);

PASS();
}

2
tests/references.dts

@ -1,6 +1,8 @@ @@ -1,6 +1,8 @@
/dts-v1/;

/ {
rref = <&{/}>;

/* Explicit phandles */
n1: node1 {
linux,phandle = <0x2000>;

Loading…
Cancel
Save