dtc: Fix some lexical problems with references
The recent change to the lexer to only recognize property and node names in the appropriate context removed a number of lexical warts in our language that would have gotten ugly as we add expression support and so forth. But there's one nasty one remaining: references can contain a full path, including the various problematic node name characters (',', '+' and '-', for example). This would cause trouble with expressions, and it also causes trouble with the patch I'm working on to allow expanding references to paths rather than phandles. This patch therefore reworks the lexer to mitigate these problems. - References to labels cause no problems. These are now recognized separately from references to full paths. No syntax change here. - References to full paths, including problematic characters are allowed by "quoting" the path with braces e.g. &{/pci@10000/somedevice@3,8000}. The braces protect any internal problematic characters from being confused with operators or whatever. - For compatibility with existing dts files, in v0 dts files we allow bare references to paths as before &/foo/bar/whatever - but *only* if the path contains no troublesome characters. Specifically only [a-zA-Z0-9_@/] are allowed. This is an incompatible change to the dts-v1 format, but since AFAIK no-one has yet switched to dts-v1 files, I think we can get away with it. Better to make the transition when people to convert to v1, and get rid of the problematic old syntax. Strictly speaking, it's also an incompatible change to the v0 format, since some path references that were allowed before are no longer allowed. I suspect no-one has been using the no-longer-supported forms (certainly none of the kernel dts files will cause trouble). We might need to think about this harder, though. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
f29454eb7e
commit
7c44c2f9cb
5 changed files with 53 additions and 12 deletions
31
dtc-lexer.l
31
dtc-lexer.l
|
@ -25,12 +25,12 @@
|
||||||
%x PROPNODENAME
|
%x PROPNODENAME
|
||||||
%s V1
|
%s V1
|
||||||
|
|
||||||
PROPCHAR [a-zA-Z0-9,._+*#?-]
|
PROPNODECHAR [a-zA-Z0-9,._+*#?@-]
|
||||||
UNITCHAR [0-9a-f,]
|
PATHCHAR ({PROPNODECHAR}|[/])
|
||||||
|
LEGACYPATHCHAR [a-zA-Z0-9_@/]
|
||||||
|
LABEL [a-zA-Z_][a-zA-Z0-9_]*
|
||||||
WS [[:space:]]
|
WS [[:space:]]
|
||||||
|
|
||||||
REFCHAR ({PROPCHAR}|{UNITCHAR}|[/@])
|
|
||||||
|
|
||||||
%{
|
%{
|
||||||
#include "dtc.h"
|
#include "dtc.h"
|
||||||
#include "srcpos.h"
|
#include "srcpos.h"
|
||||||
|
@ -102,7 +102,7 @@ static int dts_version; /* = 0 */
|
||||||
return DT_MEMRESERVE;
|
return DT_MEMRESERVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
<*>[a-zA-Z_][a-zA-Z0-9_]*: {
|
<*>{LABEL}: {
|
||||||
yylloc.filenum = srcpos_filenum;
|
yylloc.filenum = srcpos_filenum;
|
||||||
yylloc.first_line = yylineno;
|
yylloc.first_line = yylineno;
|
||||||
DPRINT("Label: %s\n", yytext);
|
DPRINT("Label: %s\n", yytext);
|
||||||
|
@ -142,7 +142,24 @@ static int dts_version; /* = 0 */
|
||||||
return DT_LITERAL;
|
return DT_LITERAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
\&{REFCHAR}* {
|
\&{LABEL} { /* label reference */
|
||||||
|
yylloc.filenum = srcpos_filenum;
|
||||||
|
yylloc.first_line = yylineno;
|
||||||
|
DPRINT("Ref: %s\n", yytext+1);
|
||||||
|
yylval.labelref = strdup(yytext+1);
|
||||||
|
return DT_REF;
|
||||||
|
}
|
||||||
|
|
||||||
|
"&{/"{PATHCHAR}+\} { /* new-style path reference */
|
||||||
|
yylloc.filenum = srcpos_filenum;
|
||||||
|
yylloc.first_line = yylineno;
|
||||||
|
yytext[yyleng-1] = '\0';
|
||||||
|
DPRINT("Ref: %s\n", yytext+2);
|
||||||
|
yylval.labelref = strdup(yytext+2);
|
||||||
|
return DT_REF;
|
||||||
|
}
|
||||||
|
|
||||||
|
<INITIAL>"&/"{LEGACYPATHCHAR}+ { /* old-style path reference */
|
||||||
yylloc.filenum = srcpos_filenum;
|
yylloc.filenum = srcpos_filenum;
|
||||||
yylloc.first_line = yylineno;
|
yylloc.first_line = yylineno;
|
||||||
DPRINT("Ref: %s\n", yytext+1);
|
DPRINT("Ref: %s\n", yytext+1);
|
||||||
|
@ -166,7 +183,7 @@ static int dts_version; /* = 0 */
|
||||||
return ']';
|
return ']';
|
||||||
}
|
}
|
||||||
|
|
||||||
<PROPNODENAME>{PROPCHAR}+(@{UNITCHAR}+)? {
|
<PROPNODENAME>{PROPNODECHAR}+ {
|
||||||
yylloc.filenum = srcpos_filenum;
|
yylloc.filenum = srcpos_filenum;
|
||||||
yylloc.first_line = yylineno;
|
yylloc.first_line = yylineno;
|
||||||
DPRINT("PropNodeName: %s\n", yytext);
|
DPRINT("PropNodeName: %s\n", yytext);
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/dts-v1/;
|
/dts-v1/;
|
||||||
|
|
||||||
/ {
|
/ {
|
||||||
ref = < &/node >;
|
ref = < &{/node} >;
|
||||||
badref = < &/nosuchnode >;
|
badref = < &{/nosuchnode} >;
|
||||||
label: node {
|
label: node {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,18 +4,18 @@
|
||||||
/* Explicit phandles */
|
/* Explicit phandles */
|
||||||
n1: node1 {
|
n1: node1 {
|
||||||
linux,phandle = <0x2000>;
|
linux,phandle = <0x2000>;
|
||||||
ref = <&/node2>; /* reference precedes target */
|
ref = <&{/node2}>; /* reference precedes target */
|
||||||
lref = <&n2>;
|
lref = <&n2>;
|
||||||
};
|
};
|
||||||
n2: node2 {
|
n2: node2 {
|
||||||
linux,phandle = <0x1>;
|
linux,phandle = <0x1>;
|
||||||
ref = <&/node1>; /* reference after target */
|
ref = <&{/node1}>; /* reference after target */
|
||||||
lref = <&n1>;
|
lref = <&n1>;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Implicit phandles */
|
/* Implicit phandles */
|
||||||
n3: node3 {
|
n3: node3 {
|
||||||
ref = <&/node4>;
|
ref = <&{/node4}>;
|
||||||
lref = <&n4>;
|
lref = <&n4>;
|
||||||
};
|
};
|
||||||
n4: node4 {
|
n4: node4 {
|
||||||
|
|
21
tests/references_dts0.dts
Normal file
21
tests/references_dts0.dts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
/ {
|
||||||
|
/* Explicit phandles */
|
||||||
|
n1: node1 {
|
||||||
|
linux,phandle = <2000>;
|
||||||
|
ref = <&/node2>; /* reference precedes target */
|
||||||
|
lref = <&n2>;
|
||||||
|
};
|
||||||
|
n2: node2 {
|
||||||
|
linux,phandle = <1>;
|
||||||
|
ref = <&/node1>; /* reference after target */
|
||||||
|
lref = <&n1>;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Implicit phandles */
|
||||||
|
n3: node3 {
|
||||||
|
ref = <&/node4>;
|
||||||
|
lref = <&n4>;
|
||||||
|
};
|
||||||
|
n4: node4 {
|
||||||
|
};
|
||||||
|
};
|
|
@ -144,6 +144,9 @@ dtc_tests () {
|
||||||
run_test dtc.sh -I dts -O dtb -o dtc_references.test.dtb references.dts
|
run_test dtc.sh -I dts -O dtb -o dtc_references.test.dtb references.dts
|
||||||
run_test references dtc_references.test.dtb
|
run_test references dtc_references.test.dtb
|
||||||
|
|
||||||
|
run_test dtc.sh -I dts -O dtb -o dtc_references_dts0.test.dtb references_dts0.dts
|
||||||
|
run_test references dtc_references_dts0.test.dtb
|
||||||
|
|
||||||
# Check -Odts mode preserve all dtb information
|
# Check -Odts mode preserve all dtb information
|
||||||
for tree in test_tree1.dtb dtc_tree1.test.dtb dtc_escapes.test.dtb ; do
|
for tree in test_tree1.dtb dtc_tree1.test.dtb dtc_escapes.test.dtb ; do
|
||||||
run_test dtc.sh -I dtb -O dts -o odts_$tree.test.dts $tree
|
run_test dtc.sh -I dtb -O dts -o odts_$tree.test.dts $tree
|
||||||
|
|
Loading…
Reference in a new issue