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, ...);
return DT_REF; return DT_REF;
} }


<*>"&{/"{PATHCHAR}+\} { /* new-style path reference */ <*>"&{/"{PATHCHAR}*\} { /* new-style path reference */
yytext[yyleng-1] = '\0'; yytext[yyleng-1] = '\0';
DPRINT("Ref: %s\n", yytext+2); DPRINT("Ref: %s\n", yytext+2);
yylval.labelref = xstrdup(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)


struct node *get_node_by_ref(struct node *tree, const char *ref) 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); return get_node_by_path(tree, ref);
else else
return get_node_by_label(tree, ref); return get_node_by_label(tree, ref);

2
tests/multilabel.dts

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


rref = <&{/}>;

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

4
tests/multilabel_merge.dts

@ -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)
node, p, 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[]) int main(int argc, char *argv[])
{ {
void *fdt; void *fdt;
@ -78,5 +92,7 @@ int main(int argc, char *argv[])
if ((!streq(p, "/node1") || !streq(p + strlen("/node1") + 1, "/node2"))) if ((!streq(p, "/node1") || !streq(p + strlen("/node1") + 1, "/node2")))
FAIL("multiref has wrong value"); FAIL("multiref has wrong value");


check_rref(fdt);

PASS(); PASS();
} }

1
tests/path-references.dts

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


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

19
tests/references.c

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


check_rref(fdt);

PASS(); PASS();
} }

2
tests/references.dts

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


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

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

Loading…
Cancel
Save