History

scripts/dtc: Update to upstream commit b06e55c88b9b

Sync to upstream dtc commit b06e55c88b9b ("Prevent crash on modulo by zero"). This adds the following commits from upstream: b06e55c Prevent crash on modulo by zero b433450 Fix some bugs in processing of line directives d728ad5 Fix crash on nul character in string escape sequence 1ab2205 Gracefully handle bad octal literals 1937095 Prevent crash on division by zero d0b3ab0 libfdt: Fix undefined behaviour in fdt_offset_ptr() d4c7c25 libfdt: check for potential overrun in _fdt_splice() f58799b libfdt: Add some missing symbols to version.lds af9f26d Remove duplicated -Werror in dtc Makefile 604e61e fdt: Add functions to retrieve strings 8702bd1 fdt: Add a function to get the index of a string 2218387 fdt: Add a function to count strings 554fde2 libfdt: fix comment block of fdt_get_property_namelen() e5e6df7 fdtdump: Fix bug printing bytestrings with negative values 067829e Remove redundant fdtdump test code 897a429 Move fdt_path_offset alias tests to right tests section 2d1417c Add simple .travis.yml f6dbc6c guess output file format 5e78dff guess input file format based on file content or file name 8b927bf tests: convert `echo -n` to `printf` 64c46b0 Fix crash with poorly defined #size-cells

Rob Herring committed 10 years ago

Commit 91feabc1 parent 76df69812 files · +390 −111Browse files

Showing the changes to scripts (12 of 12 files). Show all

Unified · Split

12 files
  1. scripts/dtc/checks.c +1 −1
  2. scripts/dtc/dtc-lexer.l +25 −14
  3. scripts/dtc/dtc-lexer.lex.c_shipped +56 −45
  4. scripts/dtc/dtc-parser.tab.c_shipped +49 −35
  5. scripts/dtc/dtc-parser.y +18 −2
  6. scripts/dtc/dtc.c +60 −2
  7. scripts/dtc/libfdt/fdt.c +7 −6
  8. scripts/dtc/libfdt/fdt_ro.c +100 −0
  9. scripts/dtc/libfdt/fdt_rw.c +2 −0
  10. scripts/dtc/libfdt/libfdt.h +70 −3
  11. scripts/dtc/util.c +1 −2
  12. scripts/dtc/version_gen.h +1 −1
scripts/dtc/checks.c+1−1
@@ -560,7 +560,7 @@ static void check_reg_format(struct check *c, struct node *dt, · 559 unmodified lines
560560 size_cells = node_size_cells(node->parent);
561561 entrylen = (addr_cells + size_cells) * sizeof(cell_t);
562562
563− if ((prop->val.len % entrylen) != 0)
563+ if (!entrylen || (prop->val.len % entrylen) != 0)
564564 FAIL(c, "\"reg\" property in %s has invalid length (%d bytes) "
565565 "(#address-cells == %d, #size-cells == %d)",
566566 node->fullpath, prop->val.len, addr_cells, size_cells);
scripts/dtc/dtc-lexer.l+25−14
@@ -73,24 +73,32 @@ static void lexical_error(const char *fmt, ...); · 72 unmodified lines
7373 }
7474
7575 <*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)? {
76− char *line, *tmp, *fn;
76+ char *line, *fnstart, *fnend;
77+ struct data fn;
7778 /* skip text before line # */
7879 line = yytext;
7980 while (!isdigit((unsigned char)*line))
8081 line++;
81− /* skip digits in line # */
82− tmp = line;
83− while (!isspace((unsigned char)*tmp))
84− tmp++;
85− /* "NULL"-terminate line # */
86− *tmp = '\0';
87− /* start of filename */
88− fn = strchr(tmp + 1, '"') + 1;
89− /* strip trailing " from filename */
90− tmp = strchr(fn, '"');
91− *tmp = 0;
82+
83+ /* regexp ensures that first and list "
84+ * in the whole yytext are those at
85+ * beginning and end of the filename string */
86+ fnstart = memchr(yytext, '"', yyleng);
87+ for (fnend = yytext + yyleng - 1;
88+ *fnend != '"'; fnend--)
89+ ;
90+ assert(fnstart && fnend && (fnend > fnstart));
91+
92+ fn = data_copy_escape_string(fnstart + 1,
93+ fnend - fnstart - 1);
94+
95+ /* Don't allow nuls in filenames */
96+ if (memchr(fn.val, '\0', fn.len - 1))
97+ lexical_error("nul in line number directive");
98+
9299 /* -1 since #line is the number of the next line */
93− srcpos_set_line(xstrdup(fn), atoi(line) - 1);
100+ srcpos_set_line(xstrdup(fn.val), atoi(line) - 1);
101+ data_free(fn);
94102 }
95103
96104 <*><<EOF>> {
@@ -153,7 +161,10 @@ static void lexical_error(const char *fmt, ...); · 56 unmodified lines
153161 errno = 0;
154162 yylval.integer = strtoull(yytext, &e, 0);
155163
156− assert(!(*e) || !e[strspn(e, "UL")]);
164+ if (*e && e[strspn(e, "UL")]) {
165+ lexical_error("Bad integer literal '%s'",
166+ yytext);
167+ }
157168
158169 if (errno == ERANGE)
159170 lexical_error("Integer literal '%s' out of range",
scripts/dtc/dtc-lexer.lex.c_shipped+56−45
@@ -951,31 +951,39 @@ case 2: · 950 unmodified lines
951951 YY_RULE_SETUP
952952 #line 75 "dtc-lexer.l"
953953 {
954− char *line, *tmp, *fn;
954+ char *line, *fnstart, *fnend;
955+ struct data fn;
955956 /* skip text before line # */
956957 line = yytext;
957958 while (!isdigit((unsigned char)*line))
958959 line++;
959− /* skip digits in line # */
960− tmp = line;
961− while (!isspace((unsigned char)*tmp))
962− tmp++;
963− /* "NULL"-terminate line # */
964− *tmp = '\0';
965− /* start of filename */
966− fn = strchr(tmp + 1, '"') + 1;
967− /* strip trailing " from filename */
968− tmp = strchr(fn, '"');
969− *tmp = 0;
960+
961+ /* regexp ensures that first and list "
962+ * in the whole yytext are those at
963+ * beginning and end of the filename string */
964+ fnstart = memchr(yytext, '"', yyleng);
965+ for (fnend = yytext + yyleng - 1;
966+ *fnend != '"'; fnend--)
967+ ;
968+ assert(fnstart && fnend && (fnend > fnstart));
969+
970+ fn = data_copy_escape_string(fnstart + 1,
971+ fnend - fnstart - 1);
972+
973+ /* Don't allow nuls in filenames */
974+ if (memchr(fn.val, '\0', fn.len - 1))
975+ lexical_error("nul in line number directive");
976+
970977 /* -1 since #line is the number of the next line */
971− srcpos_set_line(xstrdup(fn), atoi(line) - 1);
978+ srcpos_set_line(xstrdup(fn.val), atoi(line) - 1);
979+ data_free(fn);
972980 }
973981 YY_BREAK
974982 case YY_STATE_EOF(INITIAL):
975983 case YY_STATE_EOF(BYTESTRING):
976984 case YY_STATE_EOF(PROPNODENAME):
977985 case YY_STATE_EOF(V1):
978−#line 96 "dtc-lexer.l"
986+#line 104 "dtc-lexer.l"
979987 {
980988 if (!pop_input_file()) {
981989 yyterminate();
@@ -985,7 +993,7 @@ case YY_STATE_EOF(V1): · 3 unmodified lines
985993 case 3:
986994 /* rule 3 can match eol */
987995 YY_RULE_SETUP
988−#line 102 "dtc-lexer.l"
996+#line 110 "dtc-lexer.l"
989997 {
990998 DPRINT("String: %s\n", yytext);
991999 yylval.data = data_copy_escape_string(yytext+1,
@@ -995,7 +1003,7 @@ YY_RULE_SETUP · 3 unmodified lines
9951003 YY_BREAK
9961004 case 4:
9971005 YY_RULE_SETUP
998−#line 109 "dtc-lexer.l"
1006+#line 117 "dtc-lexer.l"
9991007 {
10001008 DPRINT("Keyword: /dts-v1/\n");
10011009 dts_version = 1;
@@ -1005,7 +1013,7 @@ YY_RULE_SETUP · 3 unmodified lines
10051013 YY_BREAK
10061014 case 5:
10071015 YY_RULE_SETUP
1008−#line 116 "dtc-lexer.l"
1016+#line 124 "dtc-lexer.l"
10091017 {
10101018 DPRINT("Keyword: /memreserve/\n");
10111019 BEGIN_DEFAULT();
@@ -1014,7 +1022,7 @@ YY_RULE_SETUP · 2 unmodified lines
10141022 YY_BREAK
10151023 case 6:
10161024 YY_RULE_SETUP
1017−#line 122 "dtc-lexer.l"
1025+#line 130 "dtc-lexer.l"
10181026 {
10191027 DPRINT("Keyword: /bits/\n");
10201028 BEGIN_DEFAULT();
@@ -1023,7 +1031,7 @@ YY_RULE_SETUP · 2 unmodified lines
10231031 YY_BREAK
10241032 case 7:
10251033 YY_RULE_SETUP
1026−#line 128 "dtc-lexer.l"
1034+#line 136 "dtc-lexer.l"
10271035 {
10281036 DPRINT("Keyword: /delete-property/\n");
10291037 DPRINT("<PROPNODENAME>\n");
@@ -1033,7 +1041,7 @@ YY_RULE_SETUP · 3 unmodified lines
10331041 YY_BREAK
10341042 case 8:
10351043 YY_RULE_SETUP
1036−#line 135 "dtc-lexer.l"
1044+#line 143 "dtc-lexer.l"
10371045 {
10381046 DPRINT("Keyword: /delete-node/\n");
10391047 DPRINT("<PROPNODENAME>\n");
@@ -1043,7 +1051,7 @@ YY_RULE_SETUP · 3 unmodified lines
10431051 YY_BREAK
10441052 case 9:
10451053 YY_RULE_SETUP
1046−#line 142 "dtc-lexer.l"
1054+#line 150 "dtc-lexer.l"
10471055 {
10481056 DPRINT("Label: %s\n", yytext);
10491057 yylval.labelref = xstrdup(yytext);
@@ -1053,7 +1061,7 @@ YY_RULE_SETUP · 3 unmodified lines
10531061 YY_BREAK
10541062 case 10:
10551063 YY_RULE_SETUP
1056−#line 149 "dtc-lexer.l"
1064+#line 157 "dtc-lexer.l"
10571065 {
10581066 char *e;
10591067 DPRINT("Integer Literal: '%s'\n", yytext);
@@ -1061,7 +1069,10 @@ YY_RULE_SETUP · 1 unmodified line
10611069 errno = 0;
10621070 yylval.integer = strtoull(yytext, &e, 0);
10631071
1064− assert(!(*e) || !e[strspn(e, "UL")]);
1072+ if (*e && e[strspn(e, "UL")]) {
1073+ lexical_error("Bad integer literal '%s'",
1074+ yytext);
1075+ }
10651076
10661077 if (errno == ERANGE)
10671078 lexical_error("Integer literal '%s' out of range",
@@ -1076,7 +1087,7 @@ YY_RULE_SETUP · 8 unmodified lines
10761087 case 11:
10771088 /* rule 11 can match eol */
10781089 YY_RULE_SETUP
1079−#line 168 "dtc-lexer.l"
1090+#line 179 "dtc-lexer.l"
10801091 {
10811092 struct data d;
10821093 DPRINT("Character literal: %s\n", yytext);
@@ -1100,7 +1111,7 @@ YY_RULE_SETUP · 17 unmodified lines
11001111 YY_BREAK
11011112 case 12:
11021113 YY_RULE_SETUP
1103−#line 189 "dtc-lexer.l"
1114+#line 200 "dtc-lexer.l"
11041115 { /* label reference */
11051116 DPRINT("Ref: %s\n", yytext+1);
11061117 yylval.labelref = xstrdup(yytext+1);
@@ -1109,7 +1120,7 @@ YY_RULE_SETUP · 2 unmodified lines
11091120 YY_BREAK
11101121 case 13:
11111122 YY_RULE_SETUP
1112−#line 195 "dtc-lexer.l"
1123+#line 206 "dtc-lexer.l"
11131124 { /* new-style path reference */
11141125 yytext[yyleng-1] = '\0';
11151126 DPRINT("Ref: %s\n", yytext+2);
@@ -1119,7 +1130,7 @@ YY_RULE_SETUP · 3 unmodified lines
11191130 YY_BREAK
11201131 case 14:
11211132 YY_RULE_SETUP
1122−#line 202 "dtc-lexer.l"
1133+#line 213 "dtc-lexer.l"
11231134 {
11241135 yylval.byte = strtol(yytext, NULL, 16);
11251136 DPRINT("Byte: %02x\n", (int)yylval.byte);
@@ -1128,7 +1139,7 @@ YY_RULE_SETUP · 2 unmodified lines
11281139 YY_BREAK
11291140 case 15:
11301141 YY_RULE_SETUP
1131−#line 208 "dtc-lexer.l"
1142+#line 219 "dtc-lexer.l"
11321143 {
11331144 DPRINT("/BYTESTRING\n");
11341145 BEGIN_DEFAULT();
@@ -1137,7 +1148,7 @@ YY_RULE_SETUP · 2 unmodified lines
11371148 YY_BREAK
11381149 case 16:
11391150 YY_RULE_SETUP
1140−#line 214 "dtc-lexer.l"
1151+#line 225 "dtc-lexer.l"
11411152 {
11421153 DPRINT("PropNodeName: %s\n", yytext);
11431154 yylval.propnodename = xstrdup((yytext[0] == '\\') ?
@@ -1148,7 +1159,7 @@ YY_RULE_SETUP · 4 unmodified lines
11481159 YY_BREAK
11491160 case 17:
11501161 YY_RULE_SETUP
1151−#line 222 "dtc-lexer.l"
1162+#line 233 "dtc-lexer.l"
11521163 {
11531164 DPRINT("Binary Include\n");
11541165 return DT_INCBIN;
@@ -1157,64 +1168,64 @@ YY_RULE_SETUP · 2 unmodified lines
11571168 case 18:
11581169 /* rule 18 can match eol */
11591170 YY_RULE_SETUP
1160−#line 227 "dtc-lexer.l"
1171+#line 238 "dtc-lexer.l"
11611172 /* eat whitespace */
11621173 YY_BREAK
11631174 case 19:
11641175 /* rule 19 can match eol */
11651176 YY_RULE_SETUP
1166−#line 228 "dtc-lexer.l"
1177+#line 239 "dtc-lexer.l"
11671178 /* eat C-style comments */
11681179 YY_BREAK
11691180 case 20:
11701181 /* rule 20 can match eol */
11711182 YY_RULE_SETUP
1172−#line 229 "dtc-lexer.l"
1183+#line 240 "dtc-lexer.l"
11731184 /* eat C++-style comments */
11741185 YY_BREAK
11751186 case 21:
11761187 YY_RULE_SETUP
1177−#line 231 "dtc-lexer.l"
1188+#line 242 "dtc-lexer.l"
11781189 { return DT_LSHIFT; };
11791190 YY_BREAK
11801191 case 22:
11811192 YY_RULE_SETUP
1182−#line 232 "dtc-lexer.l"
1193+#line 243 "dtc-lexer.l"
11831194 { return DT_RSHIFT; };
11841195 YY_BREAK
11851196 case 23:
11861197 YY_RULE_SETUP
1187−#line 233 "dtc-lexer.l"
1198+#line 244 "dtc-lexer.l"
11881199 { return DT_LE; };
11891200 YY_BREAK
11901201 case 24:
11911202 YY_RULE_SETUP
1192−#line 234 "dtc-lexer.l"
1203+#line 245 "dtc-lexer.l"
11931204 { return DT_GE; };
11941205 YY_BREAK
11951206 case 25:
11961207 YY_RULE_SETUP
1197−#line 235 "dtc-lexer.l"
1208+#line 246 "dtc-lexer.l"
11981209 { return DT_EQ; };
11991210 YY_BREAK
12001211 case 26:
12011212 YY_RULE_SETUP
1202−#line 236 "dtc-lexer.l"
1213+#line 247 "dtc-lexer.l"
12031214 { return DT_NE; };
12041215 YY_BREAK
12051216 case 27:
12061217 YY_RULE_SETUP
1207−#line 237 "dtc-lexer.l"
1218+#line 248 "dtc-lexer.l"
12081219 { return DT_AND; };
12091220 YY_BREAK
12101221 case 28:
12111222 YY_RULE_SETUP
1212−#line 238 "dtc-lexer.l"
1223+#line 249 "dtc-lexer.l"
12131224 { return DT_OR; };
12141225 YY_BREAK
12151226 case 29:
12161227 YY_RULE_SETUP
1217−#line 240 "dtc-lexer.l"
1228+#line 251 "dtc-lexer.l"
12181229 {
12191230 DPRINT("Char: %c (\\x%02x)\n", yytext[0],
12201231 (unsigned)yytext[0]);
@@ -1232,10 +1243,10 @@ YY_RULE_SETUP · 11 unmodified lines
12321243 YY_BREAK
12331244 case 30:
12341245 YY_RULE_SETUP
1235−#line 255 "dtc-lexer.l"
1246+#line 266 "dtc-lexer.l"
12361247 ECHO;
12371248 YY_BREAK
1238−#line 1239 "dtc-lexer.lex.c"
1249+#line 1250 "dtc-lexer.lex.c"
12391250
12401251 case YY_END_OF_BUFFER:
12411252 {
@@ -2195,7 +2206,7 @@ void yyfree (void * ptr ) · 953 unmodified lines
21952206
21962207 #define YYTABLES_NAME "yytables"
21972208
2198−#line 254 "dtc-lexer.l"
2209+#line 265 "dtc-lexer.l"
21992210
22002211
22012212
scripts/dtc/dtc-parser.tab.c_shipped+49−35
@@ -499,9 +499,9 @@ static const yytype_uint16 yyrline[] = · 498 unmodified lines
499499 298, 303, 322, 336, 343, 344, 345, 352, 356, 357,
500500 361, 362, 366, 367, 371, 372, 376, 377, 381, 382,
501501 386, 387, 388, 392, 393, 394, 395, 396, 400, 401,
502− 402, 406, 407, 408, 412, 413, 414, 415, 419, 420,
503− 421, 422, 427, 430, 434, 442, 445, 449, 457, 461,
504− 465
502+ 402, 406, 407, 408, 412, 413, 422, 431, 435, 436,
503+ 437, 438, 443, 446, 450, 458, 461, 465, 473, 477,
504+ 481
505505 };
506506 #endif
507507
@@ -1909,111 +1909,125 @@ yyreduce: · 1401 unmodified lines
19091909 break;
19101910
19111911 case 65:
1912−#line 413 "dtc-parser.y" /* yacc.c:1646 */
1913− { (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); }
1914−#line 1915 "dtc-parser.tab.c" /* yacc.c:1646 */
1912+#line 414 "dtc-parser.y" /* yacc.c:1646 */
1913+ {
1914+ if ((yyvsp[0].integer) != 0) {
1915+ (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer);
1916+ } else {
1917+ ERROR(&(yyloc), "Division by zero");
1918+ (yyval.integer) = 0;
1919+ }
1920+ }
1921+#line 1922 "dtc-parser.tab.c" /* yacc.c:1646 */
19151922 break;
19161923
19171924 case 66:
1918−#line 414 "dtc-parser.y" /* yacc.c:1646 */
1919− { (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); }
1920−#line 1921 "dtc-parser.tab.c" /* yacc.c:1646 */
1925+#line 423 "dtc-parser.y" /* yacc.c:1646 */
1926+ {
1927+ if ((yyvsp[0].integer) != 0) {
1928+ (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer);
1929+ } else {
1930+ ERROR(&(yyloc), "Division by zero");
1931+ (yyval.integer) = 0;
1932+ }
1933+ }
1934+#line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */
19211935 break;
19221936
19231937 case 69:
1924−#line 420 "dtc-parser.y" /* yacc.c:1646 */
1938+#line 436 "dtc-parser.y" /* yacc.c:1646 */
19251939 { (yyval.integer) = -(yyvsp[0].integer); }
1926−#line 1927 "dtc-parser.tab.c" /* yacc.c:1646 */
1940+#line 1941 "dtc-parser.tab.c" /* yacc.c:1646 */
19271941 break;
19281942
19291943 case 70:
1930−#line 421 "dtc-parser.y" /* yacc.c:1646 */
1944+#line 437 "dtc-parser.y" /* yacc.c:1646 */
19311945 { (yyval.integer) = ~(yyvsp[0].integer); }
1932−#line 1933 "dtc-parser.tab.c" /* yacc.c:1646 */
1946+#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */
19331947 break;
19341948
19351949 case 71:
1936−#line 422 "dtc-parser.y" /* yacc.c:1646 */
1950+#line 438 "dtc-parser.y" /* yacc.c:1646 */
19371951 { (yyval.integer) = !(yyvsp[0].integer); }
1938−#line 1939 "dtc-parser.tab.c" /* yacc.c:1646 */
1952+#line 1953 "dtc-parser.tab.c" /* yacc.c:1646 */
19391953 break;
19401954
19411955 case 72:
1942−#line 427 "dtc-parser.y" /* yacc.c:1646 */
1956+#line 443 "dtc-parser.y" /* yacc.c:1646 */
19431957 {
19441958 (yyval.data) = empty_data;
19451959 }
1946−#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */
1960+#line 1961 "dtc-parser.tab.c" /* yacc.c:1646 */
19471961 break;
19481962
19491963 case 73:
1950−#line 431 "dtc-parser.y" /* yacc.c:1646 */
1964+#line 447 "dtc-parser.y" /* yacc.c:1646 */
19511965 {
19521966 (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte));
19531967 }
1954−#line 1955 "dtc-parser.tab.c" /* yacc.c:1646 */
1968+#line 1969 "dtc-parser.tab.c" /* yacc.c:1646 */
19551969 break;
19561970
19571971 case 74:
1958−#line 435 "dtc-parser.y" /* yacc.c:1646 */
1972+#line 451 "dtc-parser.y" /* yacc.c:1646 */
19591973 {
19601974 (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
19611975 }
1962−#line 1963 "dtc-parser.tab.c" /* yacc.c:1646 */
1976+#line 1977 "dtc-parser.tab.c" /* yacc.c:1646 */
19631977 break;
19641978
19651979 case 75:
1966−#line 442 "dtc-parser.y" /* yacc.c:1646 */
1980+#line 458 "dtc-parser.y" /* yacc.c:1646 */
19671981 {
19681982 (yyval.nodelist) = NULL;
19691983 }
1970−#line 1971 "dtc-parser.tab.c" /* yacc.c:1646 */
1984+#line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */
19711985 break;
19721986
19731987 case 76:
1974−#line 446 "dtc-parser.y" /* yacc.c:1646 */
1988+#line 462 "dtc-parser.y" /* yacc.c:1646 */
19751989 {
19761990 (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist));
19771991 }
1978−#line 1979 "dtc-parser.tab.c" /* yacc.c:1646 */
1992+#line 1993 "dtc-parser.tab.c" /* yacc.c:1646 */
19791993 break;
19801994
19811995 case 77:
1982−#line 450 "dtc-parser.y" /* yacc.c:1646 */
1996+#line 466 "dtc-parser.y" /* yacc.c:1646 */
19831997 {
19841998 ERROR(&(yylsp[0]), "Properties must precede subnodes");
19851999 YYERROR;
19862000 }
1987−#line 1988 "dtc-parser.tab.c" /* yacc.c:1646 */
2001+#line 2002 "dtc-parser.tab.c" /* yacc.c:1646 */
19882002 break;
19892003
19902004 case 78:
1991−#line 458 "dtc-parser.y" /* yacc.c:1646 */
2005+#line 474 "dtc-parser.y" /* yacc.c:1646 */
19922006 {
19932007 (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename));
19942008 }
1995−#line 1996 "dtc-parser.tab.c" /* yacc.c:1646 */
2009+#line 2010 "dtc-parser.tab.c" /* yacc.c:1646 */
19962010 break;
19972011
19982012 case 79:
1999−#line 462 "dtc-parser.y" /* yacc.c:1646 */
2013+#line 478 "dtc-parser.y" /* yacc.c:1646 */
20002014 {
20012015 (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename));
20022016 }
2003−#line 2004 "dtc-parser.tab.c" /* yacc.c:1646 */
2017+#line 2018 "dtc-parser.tab.c" /* yacc.c:1646 */
20042018 break;
20052019
20062020 case 80:
2007−#line 466 "dtc-parser.y" /* yacc.c:1646 */
2021+#line 482 "dtc-parser.y" /* yacc.c:1646 */
20082022 {
20092023 add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref));
20102024 (yyval.node) = (yyvsp[0].node);
20112025 }
2012−#line 2013 "dtc-parser.tab.c" /* yacc.c:1646 */
2026+#line 2027 "dtc-parser.tab.c" /* yacc.c:1646 */
20132027 break;
20142028
20152029
2016−#line 2017 "dtc-parser.tab.c" /* yacc.c:1646 */
2030+#line 2031 "dtc-parser.tab.c" /* yacc.c:1646 */
20172031 default: break;
20182032 }
20192033 /* User semantic actions sometimes alter yychar, and that requires
@@ -2248,7 +2262,7 @@ yyreturn: · 228 unmodified lines
22482262 #endif
22492263 return yyresult;
22502264 }
2251−#line 472 "dtc-parser.y" /* yacc.c:1906 */
2265+#line 488 "dtc-parser.y" /* yacc.c:1906 */
22522266
22532267
22542268 void yyerror(char const *s)
scripts/dtc/dtc-parser.y+18−2
@@ -410,8 +410,24 @@ integer_add: · 409 unmodified lines
410410
411411 integer_mul:
412412 integer_mul '*' integer_unary { $$ = $1 * $3; }
413− | integer_mul '/' integer_unary { $$ = $1 / $3; }
414− | integer_mul '%' integer_unary { $$ = $1 % $3; }
413+ | integer_mul '/' integer_unary
414+ {
415+ if ($3 != 0) {
416+ $$ = $1 / $3;
417+ } else {
418+ ERROR(&@$, "Division by zero");
419+ $$ = 0;
420+ }
421+ }
422+ | integer_mul '%' integer_unary
423+ {
424+ if ($3 != 0) {
425+ $$ = $1 % $3;
426+ } else {
427+ ERROR(&@$, "Division by zero");
428+ $$ = 0;
429+ }
430+ }
415431 | integer_unary
416432 ;
417433
scripts/dtc/dtc.c+60−2
@@ -18,6 +18,8 @@ · 17 unmodified lines
1818 * USA
1919 */
2020
21+#include <sys/stat.h>
22+
2123 #include "dtc.h"
2224 #include "srcpos.h"
2325
@@ -104,11 +106,56 @@ static const char * const usage_opts_help[] = { · 80 unmodified lines
104106 NULL,
105107 };
106108
109+static const char *guess_type_by_name(const char *fname, const char *fallback)
110+{
111+ const char *s;
112+
113+ s = strrchr(fname, '.');
114+ if (s == NULL)
115+ return fallback;
116+ if (!strcasecmp(s, ".dts"))
117+ return "dts";
118+ if (!strcasecmp(s, ".dtb"))
119+ return "dtb";
120+ return fallback;
121+}
122+
123+static const char *guess_input_format(const char *fname, const char *fallback)
124+{
125+ struct stat statbuf;
126+ uint32_t magic;
127+ FILE *f;
128+
129+ if (stat(fname, &statbuf) != 0)
130+ return fallback;
131+
132+ if (S_ISDIR(statbuf.st_mode))
133+ return "fs";
134+
135+ if (!S_ISREG(statbuf.st_mode))
136+ return fallback;
137+
138+ f = fopen(fname, "r");
139+ if (f == NULL)
140+ return fallback;
141+ if (fread(&magic, 4, 1, f) != 1) {
142+ fclose(f);
143+ return fallback;
144+ }
145+ fclose(f);
146+
147+ magic = fdt32_to_cpu(magic);
148+ if (magic == FDT_MAGIC)
149+ return "dtb";
150+
151+ return guess_type_by_name(fname, fallback);
152+}
153+
107154 int main(int argc, char *argv[])
108155 {
109156 struct boot_info *bi;
110− const char *inform = "dts";
111− const char *outform = "dts";
157+ const char *inform = NULL;
158+ const char *outform = NULL;
112159 const char *outname = "-";
113160 const char *depname = NULL;
114161 bool force = false, sort = false;
@@ -213,6 +260,17 @@ int main(int argc, char *argv[]) · 98 unmodified lines
213260 fprintf(depfile, "%s:", outname);
214261 }
215262
263+ if (inform == NULL)
264+ inform = guess_input_format(arg, "dts");
265+ if (outform == NULL) {
266+ outform = guess_type_by_name(outname, NULL);
267+ if (outform == NULL) {
268+ if (streq(inform, "dts"))
269+ outform = "dtb";
270+ else
271+ outform = "dts";
272+ }
273+ }
216274 if (streq(inform, "dts"))
217275 bi = dt_from_source(arg);
218276 else if (streq(inform, "fs"))
scripts/dtc/libfdt/fdt.c+7−6
@@ -76,18 +76,19 @@ int fdt_check_header(const void *fdt) · 75 unmodified lines
7676
7777 const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
7878 {
79− const char *p;
79+ unsigned absoffset = offset + fdt_off_dt_struct(fdt);
80+
81+ if ((absoffset < offset)
82+ || ((absoffset + len) < absoffset)
83+ || (absoffset + len) > fdt_totalsize(fdt))
84+ return NULL;
8085
8186 if (fdt_version(fdt) >= 0x11)
8287 if (((offset + len) < offset)
8388 || ((offset + len) > fdt_size_dt_struct(fdt)))
8489 return NULL;
8590
86− p = _fdt_offset_ptr(fdt, offset);
87−
88− if (p + len < p)
89− return NULL;
90− return p;
91+ return _fdt_offset_ptr(fdt, offset);
9192 }
9293
9394 uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
scripts/dtc/libfdt/fdt_ro.c+100−0
@@ -538,6 +538,106 @@ int fdt_stringlist_contains(const char *strlist, int listlen, const char *str) · 537 unmodified lines
538538 return 0;
539539 }
540540
541+int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property)
542+{
543+ const char *list, *end;
544+ int length, count = 0;
545+
546+ list = fdt_getprop(fdt, nodeoffset, property, &length);
547+ if (!list)
548+ return -length;
549+
550+ end = list + length;
551+
552+ while (list < end) {
553+ length = strnlen(list, end - list) + 1;
554+
555+ /* Abort if the last string isn't properly NUL-terminated. */
556+ if (list + length > end)
557+ return -FDT_ERR_BADVALUE;
558+
559+ list += length;
560+ count++;
561+ }
562+
563+ return count;
564+}
565+
566+int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property,
567+ const char *string)
568+{
569+ int length, len, idx = 0;
570+ const char *list, *end;
571+
572+ list = fdt_getprop(fdt, nodeoffset, property, &length);
573+ if (!list)
574+ return -length;
575+
576+ len = strlen(string) + 1;
577+ end = list + length;
578+
579+ while (list < end) {
580+ length = strnlen(list, end - list) + 1;
581+
582+ /* Abort if the last string isn't properly NUL-terminated. */
583+ if (list + length > end)
584+ return -FDT_ERR_BADVALUE;
585+
586+ if (length == len && memcmp(list, string, length) == 0)
587+ return idx;
588+
589+ list += length;
590+ idx++;
591+ }
592+
593+ return -FDT_ERR_NOTFOUND;
594+}
595+
596+const char *fdt_stringlist_get(const void *fdt, int nodeoffset,
597+ const char *property, int idx,
598+ int *lenp)
599+{
600+ const char *list, *end;
601+ int length;
602+
603+ list = fdt_getprop(fdt, nodeoffset, property, &length);
604+ if (!list) {
605+ if (lenp)
606+ *lenp = length;
607+
608+ return NULL;
609+ }
610+
611+ end = list + length;
612+
613+ while (list < end) {
614+ length = strnlen(list, end - list) + 1;
615+
616+ /* Abort if the last string isn't properly NUL-terminated. */
617+ if (list + length > end) {
618+ if (lenp)
619+ *lenp = -FDT_ERR_BADVALUE;
620+
621+ return NULL;
622+ }
623+
624+ if (idx == 0) {
625+ if (lenp)
626+ *lenp = length - 1;
627+
628+ return list;
629+ }
630+
631+ list += length;
632+ idx--;
633+ }
634+
635+ if (lenp)
636+ *lenp = -FDT_ERR_NOTFOUND;
637+
638+ return NULL;
639+}
640+
541641 int fdt_node_check_compatible(const void *fdt, int nodeoffset,
542642 const char *compatible)
543643 {
scripts/dtc/libfdt/fdt_rw.c+2−0
@@ -101,6 +101,8 @@ static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen) · 100 unmodified lines
101101
102102 if (((p + oldlen) < p) || ((p + oldlen) > end))
103103 return -FDT_ERR_BADOFFSET;
104+ if ((p < (char *)fdt) || ((end - oldlen + newlen) < (char *)fdt))
105+ return -FDT_ERR_BADOFFSET;
104106 if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))
105107 return -FDT_ERR_NOSPACE;
106108 memmove(p + newlen, p + oldlen, end - p - oldlen);
scripts/dtc/libfdt/libfdt.h+70−3
@@ -121,7 +121,12 @@ · 120 unmodified lines
121121 /* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells
122122 * or similar property with a bad format or value */
123123
124−#define FDT_ERR_MAX 14
124+#define FDT_ERR_BADVALUE 15
125+ /* FDT_ERR_BADVALUE: Device tree has a property with an unexpected
126+ * value. For example: a property expected to contain a string list
127+ * is not NUL-terminated within the length of its value. */
128+
129+#define FDT_ERR_MAX 15
125130
126131 /**********************************************************************/
127132 /* Low-level functions (you probably don't need these) */
@@ -457,8 +462,8 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt, · 329 unmodified lines
457462 * @namelen: number of characters of name to consider
458463 * @lenp: pointer to an integer variable (will be overwritten) or NULL
459464 *
460− * Identical to fdt_get_property_namelen(), but only examine the first
461− * namelen characters of name for matching the property name.
465+ * Identical to fdt_get_property(), but only examine the first namelen
466+ * characters of name for matching the property name.
462467 */
463468 const struct fdt_property *fdt_get_property_namelen(const void *fdt,
464469 int nodeoffset,
@@ -868,6 +873,68 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset, · 403 unmodified lines
868873 */
869874 int fdt_stringlist_contains(const char *strlist, int listlen, const char *str);
870875
876+/**
877+ * fdt_stringlist_count - count the number of strings in a string list
878+ * @fdt: pointer to the device tree blob
879+ * @nodeoffset: offset of a tree node
880+ * @property: name of the property containing the string list
881+ * @return:
882+ * the number of strings in the given property
883+ * -FDT_ERR_BADVALUE if the property value is not NUL-terminated
884+ * -FDT_ERR_NOTFOUND if the property does not exist
885+ */
886+int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property);
887+
888+/**
889+ * fdt_stringlist_search - find a string in a string list and return its index
890+ * @fdt: pointer to the device tree blob
891+ * @nodeoffset: offset of a tree node
892+ * @property: name of the property containing the string list
893+ * @string: string to look up in the string list
894+ *
895+ * Note that it is possible for this function to succeed on property values
896+ * that are not NUL-terminated. That's because the function will stop after
897+ * finding the first occurrence of @string. This can for example happen with
898+ * small-valued cell properties, such as #address-cells, when searching for
899+ * the empty string.
900+ *
901+ * @return:
902+ * the index of the string in the list of strings
903+ * -FDT_ERR_BADVALUE if the property value is not NUL-terminated
904+ * -FDT_ERR_NOTFOUND if the property does not exist or does not contain
905+ * the given string
906+ */
907+int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property,
908+ const char *string);
909+
910+/**
911+ * fdt_stringlist_get() - obtain the string at a given index in a string list
912+ * @fdt: pointer to the device tree blob
913+ * @nodeoffset: offset of a tree node
914+ * @property: name of the property containing the string list
915+ * @index: index of the string to return
916+ * @lenp: return location for the string length or an error code on failure
917+ *
918+ * Note that this will successfully extract strings from properties with
919+ * non-NUL-terminated values. For example on small-valued cell properties
920+ * this function will return the empty string.
921+ *
922+ * If non-NULL, the length of the string (on success) or a negative error-code
923+ * (on failure) will be stored in the integer pointer to by lenp.
924+ *
925+ * @return:
926+ * A pointer to the string at the given index in the string list or NULL on
927+ * failure. On success the length of the string will be stored in the memory
928+ * location pointed to by the lenp parameter, if non-NULL. On failure one of
929+ * the following negative error codes will be returned in the lenp parameter
930+ * (if non-NULL):
931+ * -FDT_ERR_BADVALUE if the property value is not NUL-terminated
932+ * -FDT_ERR_NOTFOUND if the property does not exist
933+ */
934+const char *fdt_stringlist_get(const void *fdt, int nodeoffset,
935+ const char *property, int index,
936+ int *lenp);
937+
871938 /**********************************************************************/
872939 /* Read-only functions (addressing related) */
873940 /**********************************************************************/
scripts/dtc/util.c+1−2
@@ -152,7 +152,6 @@ char get_escape_char(const char *s, int *i) · 151 unmodified lines
152152 int j = *i + 1;
153153 char val;
154154
155− assert(c);
156155 switch (c) {
157156 case 'a':
158157 val = '\a';
@@ -349,7 +348,6 @@ int utilfdt_decode_type(const char *fmt, int *type, int *size) · 190 unmodified lines
349348 void utilfdt_print_data(const char *data, int len)
350349 {
351350 int i;
352− const char *p = data;
353351 const char *s;
354352
355353 /* no data, don't print */
@@ -376,6 +374,7 @@ void utilfdt_print_data(const char *data, int len) · 20 unmodified lines
376374 i < (len - 1) ? " " : "");
377375 printf(">");
378376 } else {
377+ const unsigned char *p = (const unsigned char *)data;
379378 printf(" = [");
380379 for (i = 0; i < len; i++)
381380 printf("%02x%s", *p++, i < len - 1 ? " " : "");
scripts/dtc/version_gen.h+1−1
@@ -1 +1 @@
1−#define DTC_VERSION "DTC 1.4.1-g9d3649bd"
1+#define DTC_VERSION "DTC 1.4.1-gb06e55c8"