diff options
author | Rob Herring <robh@kernel.org> | 2016-01-26 10:04:11 -0500 |
---|---|---|
committer | Rob Herring <robh@kernel.org> | 2016-02-11 20:45:09 -0500 |
commit | 91feabc2e2240ee80dc8ac08103cb83f497e4d12 (patch) | |
tree | 8bd53e02910f0d15b3516d7af298b03b19ca5dac /scripts | |
parent | 76df69806b7fafea013e2f4f82b0bd54498f3406 (diff) |
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
Cc: Grant Likely <grant.likely@linaro.org>
Tested-by: Frank Rowand <frank.rowand@sonymobile.com>
Reviewed-by: Frank Rowand <frank.rowand@sonymobile.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/dtc/checks.c | 2 | ||||
-rw-r--r-- | scripts/dtc/dtc-lexer.l | 39 | ||||
-rw-r--r-- | scripts/dtc/dtc-lexer.lex.c_shipped | 101 | ||||
-rw-r--r-- | scripts/dtc/dtc-parser.tab.c_shipped | 84 | ||||
-rw-r--r-- | scripts/dtc/dtc-parser.y | 20 | ||||
-rw-r--r-- | scripts/dtc/dtc.c | 62 | ||||
-rw-r--r-- | scripts/dtc/libfdt/fdt.c | 13 | ||||
-rw-r--r-- | scripts/dtc/libfdt/fdt_ro.c | 100 | ||||
-rw-r--r-- | scripts/dtc/libfdt/fdt_rw.c | 2 | ||||
-rw-r--r-- | scripts/dtc/libfdt/libfdt.h | 73 | ||||
-rw-r--r-- | scripts/dtc/util.c | 3 | ||||
-rw-r--r-- | scripts/dtc/version_gen.h | 2 |
12 files changed, 390 insertions, 111 deletions
diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c index e81a8c74b8d2..0c03ac9159c1 100644 --- a/scripts/dtc/checks.c +++ b/scripts/dtc/checks.c | |||
@@ -560,7 +560,7 @@ static void check_reg_format(struct check *c, struct node *dt, | |||
560 | size_cells = node_size_cells(node->parent); | 560 | size_cells = node_size_cells(node->parent); |
561 | entrylen = (addr_cells + size_cells) * sizeof(cell_t); | 561 | entrylen = (addr_cells + size_cells) * sizeof(cell_t); |
562 | 562 | ||
563 | if ((prop->val.len % entrylen) != 0) | 563 | if (!entrylen || (prop->val.len % entrylen) != 0) |
564 | FAIL(c, "\"reg\" property in %s has invalid length (%d bytes) " | 564 | FAIL(c, "\"reg\" property in %s has invalid length (%d bytes) " |
565 | "(#address-cells == %d, #size-cells == %d)", | 565 | "(#address-cells == %d, #size-cells == %d)", |
566 | node->fullpath, prop->val.len, addr_cells, size_cells); | 566 | node->fullpath, prop->val.len, addr_cells, size_cells); |
diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l index 0ee1caf03dd0..790fbf6cf2d7 100644 --- a/scripts/dtc/dtc-lexer.l +++ b/scripts/dtc/dtc-lexer.l | |||
@@ -73,24 +73,32 @@ static void lexical_error(const char *fmt, ...); | |||
73 | } | 73 | } |
74 | 74 | ||
75 | <*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)? { | 75 | <*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)? { |
76 | char *line, *tmp, *fn; | 76 | char *line, *fnstart, *fnend; |
77 | struct data fn; | ||
77 | /* skip text before line # */ | 78 | /* skip text before line # */ |
78 | line = yytext; | 79 | line = yytext; |
79 | while (!isdigit((unsigned char)*line)) | 80 | while (!isdigit((unsigned char)*line)) |
80 | line++; | 81 | line++; |
81 | /* skip digits in line # */ | 82 | |
82 | tmp = line; | 83 | /* regexp ensures that first and list " |
83 | while (!isspace((unsigned char)*tmp)) | 84 | * in the whole yytext are those at |
84 | tmp++; | 85 | * beginning and end of the filename string */ |
85 | /* "NULL"-terminate line # */ | 86 | fnstart = memchr(yytext, '"', yyleng); |
86 | *tmp = '\0'; | 87 | for (fnend = yytext + yyleng - 1; |
87 | /* start of filename */ | 88 | *fnend != '"'; fnend--) |
88 | fn = strchr(tmp + 1, '"') + 1; | 89 | ; |
89 | /* strip trailing " from filename */ | 90 | assert(fnstart && fnend && (fnend > fnstart)); |
90 | tmp = strchr(fn, '"'); | 91 | |
91 | *tmp = 0; | 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 | |||
92 | /* -1 since #line is the number of the next line */ | 99 | /* -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); | ||
94 | } | 102 | } |
95 | 103 | ||
96 | <*><<EOF>> { | 104 | <*><<EOF>> { |
@@ -153,7 +161,10 @@ static void lexical_error(const char *fmt, ...); | |||
153 | errno = 0; | 161 | errno = 0; |
154 | yylval.integer = strtoull(yytext, &e, 0); | 162 | yylval.integer = strtoull(yytext, &e, 0); |
155 | 163 | ||
156 | assert(!(*e) || !e[strspn(e, "UL")]); | 164 | if (*e && e[strspn(e, "UL")]) { |
165 | lexical_error("Bad integer literal '%s'", | ||
166 | yytext); | ||
167 | } | ||
157 | 168 | ||
158 | if (errno == ERANGE) | 169 | if (errno == ERANGE) |
159 | lexical_error("Integer literal '%s' out of range", | 170 | lexical_error("Integer literal '%s' out of range", |
diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped index 11cd78e72305..ba525c2f9fc2 100644 --- a/scripts/dtc/dtc-lexer.lex.c_shipped +++ b/scripts/dtc/dtc-lexer.lex.c_shipped | |||
@@ -951,31 +951,39 @@ case 2: | |||
951 | YY_RULE_SETUP | 951 | YY_RULE_SETUP |
952 | #line 75 "dtc-lexer.l" | 952 | #line 75 "dtc-lexer.l" |
953 | { | 953 | { |
954 | char *line, *tmp, *fn; | 954 | char *line, *fnstart, *fnend; |
955 | struct data fn; | ||
955 | /* skip text before line # */ | 956 | /* skip text before line # */ |
956 | line = yytext; | 957 | line = yytext; |
957 | while (!isdigit((unsigned char)*line)) | 958 | while (!isdigit((unsigned char)*line)) |
958 | line++; | 959 | line++; |
959 | /* skip digits in line # */ | 960 | |
960 | tmp = line; | 961 | /* regexp ensures that first and list " |
961 | while (!isspace((unsigned char)*tmp)) | 962 | * in the whole yytext are those at |
962 | tmp++; | 963 | * beginning and end of the filename string */ |
963 | /* "NULL"-terminate line # */ | 964 | fnstart = memchr(yytext, '"', yyleng); |
964 | *tmp = '\0'; | 965 | for (fnend = yytext + yyleng - 1; |
965 | /* start of filename */ | 966 | *fnend != '"'; fnend--) |
966 | fn = strchr(tmp + 1, '"') + 1; | 967 | ; |
967 | /* strip trailing " from filename */ | 968 | assert(fnstart && fnend && (fnend > fnstart)); |
968 | tmp = strchr(fn, '"'); | 969 | |
969 | *tmp = 0; | 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 | |||
970 | /* -1 since #line is the number of the next line */ | 977 | /* -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); | ||
972 | } | 980 | } |
973 | YY_BREAK | 981 | YY_BREAK |
974 | case YY_STATE_EOF(INITIAL): | 982 | case YY_STATE_EOF(INITIAL): |
975 | case YY_STATE_EOF(BYTESTRING): | 983 | case YY_STATE_EOF(BYTESTRING): |
976 | case YY_STATE_EOF(PROPNODENAME): | 984 | case YY_STATE_EOF(PROPNODENAME): |
977 | case YY_STATE_EOF(V1): | 985 | case YY_STATE_EOF(V1): |
978 | #line 96 "dtc-lexer.l" | 986 | #line 104 "dtc-lexer.l" |
979 | { | 987 | { |
980 | if (!pop_input_file()) { | 988 | if (!pop_input_file()) { |
981 | yyterminate(); | 989 | yyterminate(); |
@@ -985,7 +993,7 @@ case YY_STATE_EOF(V1): | |||
985 | case 3: | 993 | case 3: |
986 | /* rule 3 can match eol */ | 994 | /* rule 3 can match eol */ |
987 | YY_RULE_SETUP | 995 | YY_RULE_SETUP |
988 | #line 102 "dtc-lexer.l" | 996 | #line 110 "dtc-lexer.l" |
989 | { | 997 | { |
990 | DPRINT("String: %s\n", yytext); | 998 | DPRINT("String: %s\n", yytext); |
991 | yylval.data = data_copy_escape_string(yytext+1, | 999 | yylval.data = data_copy_escape_string(yytext+1, |
@@ -995,7 +1003,7 @@ YY_RULE_SETUP | |||
995 | YY_BREAK | 1003 | YY_BREAK |
996 | case 4: | 1004 | case 4: |
997 | YY_RULE_SETUP | 1005 | YY_RULE_SETUP |
998 | #line 109 "dtc-lexer.l" | 1006 | #line 117 "dtc-lexer.l" |
999 | { | 1007 | { |
1000 | DPRINT("Keyword: /dts-v1/\n"); | 1008 | DPRINT("Keyword: /dts-v1/\n"); |
1001 | dts_version = 1; | 1009 | dts_version = 1; |
@@ -1005,7 +1013,7 @@ YY_RULE_SETUP | |||
1005 | YY_BREAK | 1013 | YY_BREAK |
1006 | case 5: | 1014 | case 5: |
1007 | YY_RULE_SETUP | 1015 | YY_RULE_SETUP |
1008 | #line 116 "dtc-lexer.l" | 1016 | #line 124 "dtc-lexer.l" |
1009 | { | 1017 | { |
1010 | DPRINT("Keyword: /memreserve/\n"); | 1018 | DPRINT("Keyword: /memreserve/\n"); |
1011 | BEGIN_DEFAULT(); | 1019 | BEGIN_DEFAULT(); |
@@ -1014,7 +1022,7 @@ YY_RULE_SETUP | |||
1014 | YY_BREAK | 1022 | YY_BREAK |
1015 | case 6: | 1023 | case 6: |
1016 | YY_RULE_SETUP | 1024 | YY_RULE_SETUP |
1017 | #line 122 "dtc-lexer.l" | 1025 | #line 130 "dtc-lexer.l" |
1018 | { | 1026 | { |
1019 | DPRINT("Keyword: /bits/\n"); | 1027 | DPRINT("Keyword: /bits/\n"); |
1020 | BEGIN_DEFAULT(); | 1028 | BEGIN_DEFAULT(); |
@@ -1023,7 +1031,7 @@ YY_RULE_SETUP | |||
1023 | YY_BREAK | 1031 | YY_BREAK |
1024 | case 7: | 1032 | case 7: |
1025 | YY_RULE_SETUP | 1033 | YY_RULE_SETUP |
1026 | #line 128 "dtc-lexer.l" | 1034 | #line 136 "dtc-lexer.l" |
1027 | { | 1035 | { |
1028 | DPRINT("Keyword: /delete-property/\n"); | 1036 | DPRINT("Keyword: /delete-property/\n"); |
1029 | DPRINT("<PROPNODENAME>\n"); | 1037 | DPRINT("<PROPNODENAME>\n"); |
@@ -1033,7 +1041,7 @@ YY_RULE_SETUP | |||
1033 | YY_BREAK | 1041 | YY_BREAK |
1034 | case 8: | 1042 | case 8: |
1035 | YY_RULE_SETUP | 1043 | YY_RULE_SETUP |
1036 | #line 135 "dtc-lexer.l" | 1044 | #line 143 "dtc-lexer.l" |
1037 | { | 1045 | { |
1038 | DPRINT("Keyword: /delete-node/\n"); | 1046 | DPRINT("Keyword: /delete-node/\n"); |
1039 | DPRINT("<PROPNODENAME>\n"); | 1047 | DPRINT("<PROPNODENAME>\n"); |
@@ -1043,7 +1051,7 @@ YY_RULE_SETUP | |||
1043 | YY_BREAK | 1051 | YY_BREAK |
1044 | case 9: | 1052 | case 9: |
1045 | YY_RULE_SETUP | 1053 | YY_RULE_SETUP |
1046 | #line 142 "dtc-lexer.l" | 1054 | #line 150 "dtc-lexer.l" |
1047 | { | 1055 | { |
1048 | DPRINT("Label: %s\n", yytext); | 1056 | DPRINT("Label: %s\n", yytext); |
1049 | yylval.labelref = xstrdup(yytext); | 1057 | yylval.labelref = xstrdup(yytext); |
@@ -1053,7 +1061,7 @@ YY_RULE_SETUP | |||
1053 | YY_BREAK | 1061 | YY_BREAK |
1054 | case 10: | 1062 | case 10: |
1055 | YY_RULE_SETUP | 1063 | YY_RULE_SETUP |
1056 | #line 149 "dtc-lexer.l" | 1064 | #line 157 "dtc-lexer.l" |
1057 | { | 1065 | { |
1058 | char *e; | 1066 | char *e; |
1059 | DPRINT("Integer Literal: '%s'\n", yytext); | 1067 | DPRINT("Integer Literal: '%s'\n", yytext); |
@@ -1061,7 +1069,10 @@ YY_RULE_SETUP | |||
1061 | errno = 0; | 1069 | errno = 0; |
1062 | yylval.integer = strtoull(yytext, &e, 0); | 1070 | yylval.integer = strtoull(yytext, &e, 0); |
1063 | 1071 | ||
1064 | assert(!(*e) || !e[strspn(e, "UL")]); | 1072 | if (*e && e[strspn(e, "UL")]) { |
1073 | lexical_error("Bad integer literal '%s'", | ||
1074 | yytext); | ||
1075 | } | ||
1065 | 1076 | ||
1066 | if (errno == ERANGE) | 1077 | if (errno == ERANGE) |
1067 | lexical_error("Integer literal '%s' out of range", | 1078 | lexical_error("Integer literal '%s' out of range", |
@@ -1076,7 +1087,7 @@ YY_RULE_SETUP | |||
1076 | case 11: | 1087 | case 11: |
1077 | /* rule 11 can match eol */ | 1088 | /* rule 11 can match eol */ |
1078 | YY_RULE_SETUP | 1089 | YY_RULE_SETUP |
1079 | #line 168 "dtc-lexer.l" | 1090 | #line 179 "dtc-lexer.l" |
1080 | { | 1091 | { |
1081 | struct data d; | 1092 | struct data d; |
1082 | DPRINT("Character literal: %s\n", yytext); | 1093 | DPRINT("Character literal: %s\n", yytext); |
@@ -1100,7 +1111,7 @@ YY_RULE_SETUP | |||
1100 | YY_BREAK | 1111 | YY_BREAK |
1101 | case 12: | 1112 | case 12: |
1102 | YY_RULE_SETUP | 1113 | YY_RULE_SETUP |
1103 | #line 189 "dtc-lexer.l" | 1114 | #line 200 "dtc-lexer.l" |
1104 | { /* label reference */ | 1115 | { /* label reference */ |
1105 | DPRINT("Ref: %s\n", yytext+1); | 1116 | DPRINT("Ref: %s\n", yytext+1); |
1106 | yylval.labelref = xstrdup(yytext+1); | 1117 | yylval.labelref = xstrdup(yytext+1); |
@@ -1109,7 +1120,7 @@ YY_RULE_SETUP | |||
1109 | YY_BREAK | 1120 | YY_BREAK |
1110 | case 13: | 1121 | case 13: |
1111 | YY_RULE_SETUP | 1122 | YY_RULE_SETUP |
1112 | #line 195 "dtc-lexer.l" | 1123 | #line 206 "dtc-lexer.l" |
1113 | { /* new-style path reference */ | 1124 | { /* new-style path reference */ |
1114 | yytext[yyleng-1] = '\0'; | 1125 | yytext[yyleng-1] = '\0'; |
1115 | DPRINT("Ref: %s\n", yytext+2); | 1126 | DPRINT("Ref: %s\n", yytext+2); |
@@ -1119,7 +1130,7 @@ YY_RULE_SETUP | |||
1119 | YY_BREAK | 1130 | YY_BREAK |
1120 | case 14: | 1131 | case 14: |
1121 | YY_RULE_SETUP | 1132 | YY_RULE_SETUP |
1122 | #line 202 "dtc-lexer.l" | 1133 | #line 213 "dtc-lexer.l" |
1123 | { | 1134 | { |
1124 | yylval.byte = strtol(yytext, NULL, 16); | 1135 | yylval.byte = strtol(yytext, NULL, 16); |
1125 | DPRINT("Byte: %02x\n", (int)yylval.byte); | 1136 | DPRINT("Byte: %02x\n", (int)yylval.byte); |
@@ -1128,7 +1139,7 @@ YY_RULE_SETUP | |||
1128 | YY_BREAK | 1139 | YY_BREAK |
1129 | case 15: | 1140 | case 15: |
1130 | YY_RULE_SETUP | 1141 | YY_RULE_SETUP |
1131 | #line 208 "dtc-lexer.l" | 1142 | #line 219 "dtc-lexer.l" |
1132 | { | 1143 | { |
1133 | DPRINT("/BYTESTRING\n"); | 1144 | DPRINT("/BYTESTRING\n"); |
1134 | BEGIN_DEFAULT(); | 1145 | BEGIN_DEFAULT(); |
@@ -1137,7 +1148,7 @@ YY_RULE_SETUP | |||
1137 | YY_BREAK | 1148 | YY_BREAK |
1138 | case 16: | 1149 | case 16: |
1139 | YY_RULE_SETUP | 1150 | YY_RULE_SETUP |
1140 | #line 214 "dtc-lexer.l" | 1151 | #line 225 "dtc-lexer.l" |
1141 | { | 1152 | { |
1142 | DPRINT("PropNodeName: %s\n", yytext); | 1153 | DPRINT("PropNodeName: %s\n", yytext); |
1143 | yylval.propnodename = xstrdup((yytext[0] == '\\') ? | 1154 | yylval.propnodename = xstrdup((yytext[0] == '\\') ? |
@@ -1148,7 +1159,7 @@ YY_RULE_SETUP | |||
1148 | YY_BREAK | 1159 | YY_BREAK |
1149 | case 17: | 1160 | case 17: |
1150 | YY_RULE_SETUP | 1161 | YY_RULE_SETUP |
1151 | #line 222 "dtc-lexer.l" | 1162 | #line 233 "dtc-lexer.l" |
1152 | { | 1163 | { |
1153 | DPRINT("Binary Include\n"); | 1164 | DPRINT("Binary Include\n"); |
1154 | return DT_INCBIN; | 1165 | return DT_INCBIN; |
@@ -1157,64 +1168,64 @@ YY_RULE_SETUP | |||
1157 | case 18: | 1168 | case 18: |
1158 | /* rule 18 can match eol */ | 1169 | /* rule 18 can match eol */ |
1159 | YY_RULE_SETUP | 1170 | YY_RULE_SETUP |
1160 | #line 227 "dtc-lexer.l" | 1171 | #line 238 "dtc-lexer.l" |
1161 | /* eat whitespace */ | 1172 | /* eat whitespace */ |
1162 | YY_BREAK | 1173 | YY_BREAK |
1163 | case 19: | 1174 | case 19: |
1164 | /* rule 19 can match eol */ | 1175 | /* rule 19 can match eol */ |
1165 | YY_RULE_SETUP | 1176 | YY_RULE_SETUP |
1166 | #line 228 "dtc-lexer.l" | 1177 | #line 239 "dtc-lexer.l" |
1167 | /* eat C-style comments */ | 1178 | /* eat C-style comments */ |
1168 | YY_BREAK | 1179 | YY_BREAK |
1169 | case 20: | 1180 | case 20: |
1170 | /* rule 20 can match eol */ | 1181 | /* rule 20 can match eol */ |
1171 | YY_RULE_SETUP | 1182 | YY_RULE_SETUP |
1172 | #line 229 "dtc-lexer.l" | 1183 | #line 240 "dtc-lexer.l" |
1173 | /* eat C++-style comments */ | 1184 | /* eat C++-style comments */ |
1174 | YY_BREAK | 1185 | YY_BREAK |
1175 | case 21: | 1186 | case 21: |
1176 | YY_RULE_SETUP | 1187 | YY_RULE_SETUP |
1177 | #line 231 "dtc-lexer.l" | 1188 | #line 242 "dtc-lexer.l" |
1178 | { return DT_LSHIFT; }; | 1189 | { return DT_LSHIFT; }; |
1179 | YY_BREAK | 1190 | YY_BREAK |
1180 | case 22: | 1191 | case 22: |
1181 | YY_RULE_SETUP | 1192 | YY_RULE_SETUP |
1182 | #line 232 "dtc-lexer.l" | 1193 | #line 243 "dtc-lexer.l" |
1183 | { return DT_RSHIFT; }; | 1194 | { return DT_RSHIFT; }; |
1184 | YY_BREAK | 1195 | YY_BREAK |
1185 | case 23: | 1196 | case 23: |
1186 | YY_RULE_SETUP | 1197 | YY_RULE_SETUP |
1187 | #line 233 "dtc-lexer.l" | 1198 | #line 244 "dtc-lexer.l" |
1188 | { return DT_LE; }; | 1199 | { return DT_LE; }; |
1189 | YY_BREAK | 1200 | YY_BREAK |
1190 | case 24: | 1201 | case 24: |
1191 | YY_RULE_SETUP | 1202 | YY_RULE_SETUP |
1192 | #line 234 "dtc-lexer.l" | 1203 | #line 245 "dtc-lexer.l" |
1193 | { return DT_GE; }; | 1204 | { return DT_GE; }; |
1194 | YY_BREAK | 1205 | YY_BREAK |
1195 | case 25: | 1206 | case 25: |
1196 | YY_RULE_SETUP | 1207 | YY_RULE_SETUP |
1197 | #line 235 "dtc-lexer.l" | 1208 | #line 246 "dtc-lexer.l" |
1198 | { return DT_EQ; }; | 1209 | { return DT_EQ; }; |
1199 | YY_BREAK | 1210 | YY_BREAK |
1200 | case 26: | 1211 | case 26: |
1201 | YY_RULE_SETUP | 1212 | YY_RULE_SETUP |
1202 | #line 236 "dtc-lexer.l" | 1213 | #line 247 "dtc-lexer.l" |
1203 | { return DT_NE; }; | 1214 | { return DT_NE; }; |
1204 | YY_BREAK | 1215 | YY_BREAK |
1205 | case 27: | 1216 | case 27: |
1206 | YY_RULE_SETUP | 1217 | YY_RULE_SETUP |
1207 | #line 237 "dtc-lexer.l" | 1218 | #line 248 "dtc-lexer.l" |
1208 | { return DT_AND; }; | 1219 | { return DT_AND; }; |
1209 | YY_BREAK | 1220 | YY_BREAK |
1210 | case 28: | 1221 | case 28: |
1211 | YY_RULE_SETUP | 1222 | YY_RULE_SETUP |
1212 | #line 238 "dtc-lexer.l" | 1223 | #line 249 "dtc-lexer.l" |
1213 | { return DT_OR; }; | 1224 | { return DT_OR; }; |
1214 | YY_BREAK | 1225 | YY_BREAK |
1215 | case 29: | 1226 | case 29: |
1216 | YY_RULE_SETUP | 1227 | YY_RULE_SETUP |
1217 | #line 240 "dtc-lexer.l" | 1228 | #line 251 "dtc-lexer.l" |
1218 | { | 1229 | { |
1219 | DPRINT("Char: %c (\\x%02x)\n", yytext[0], | 1230 | DPRINT("Char: %c (\\x%02x)\n", yytext[0], |
1220 | (unsigned)yytext[0]); | 1231 | (unsigned)yytext[0]); |
@@ -1232,10 +1243,10 @@ YY_RULE_SETUP | |||
1232 | YY_BREAK | 1243 | YY_BREAK |
1233 | case 30: | 1244 | case 30: |
1234 | YY_RULE_SETUP | 1245 | YY_RULE_SETUP |
1235 | #line 255 "dtc-lexer.l" | 1246 | #line 266 "dtc-lexer.l" |
1236 | ECHO; | 1247 | ECHO; |
1237 | YY_BREAK | 1248 | YY_BREAK |
1238 | #line 1239 "dtc-lexer.lex.c" | 1249 | #line 1250 "dtc-lexer.lex.c" |
1239 | 1250 | ||
1240 | case YY_END_OF_BUFFER: | 1251 | case YY_END_OF_BUFFER: |
1241 | { | 1252 | { |
@@ -2195,7 +2206,7 @@ void yyfree (void * ptr ) | |||
2195 | 2206 | ||
2196 | #define YYTABLES_NAME "yytables" | 2207 | #define YYTABLES_NAME "yytables" |
2197 | 2208 | ||
2198 | #line 254 "dtc-lexer.l" | 2209 | #line 265 "dtc-lexer.l" |
2199 | 2210 | ||
2200 | 2211 | ||
2201 | 2212 | ||
diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped index 116458c8dfc4..31cec50a1265 100644 --- a/scripts/dtc/dtc-parser.tab.c_shipped +++ b/scripts/dtc/dtc-parser.tab.c_shipped | |||
@@ -499,9 +499,9 @@ static const yytype_uint16 yyrline[] = | |||
499 | 298, 303, 322, 336, 343, 344, 345, 352, 356, 357, | 499 | 298, 303, 322, 336, 343, 344, 345, 352, 356, 357, |
500 | 361, 362, 366, 367, 371, 372, 376, 377, 381, 382, | 500 | 361, 362, 366, 367, 371, 372, 376, 377, 381, 382, |
501 | 386, 387, 388, 392, 393, 394, 395, 396, 400, 401, | 501 | 386, 387, 388, 392, 393, 394, 395, 396, 400, 401, |
502 | 402, 406, 407, 408, 412, 413, 414, 415, 419, 420, | 502 | 402, 406, 407, 408, 412, 413, 422, 431, 435, 436, |
503 | 421, 422, 427, 430, 434, 442, 445, 449, 457, 461, | 503 | 437, 438, 443, 446, 450, 458, 461, 465, 473, 477, |
504 | 465 | 504 | 481 |
505 | }; | 505 | }; |
506 | #endif | 506 | #endif |
507 | 507 | ||
@@ -1909,111 +1909,125 @@ yyreduce: | |||
1909 | break; | 1909 | break; |
1910 | 1910 | ||
1911 | case 65: | 1911 | case 65: |
1912 | #line 413 "dtc-parser.y" /* yacc.c:1646 */ | 1912 | #line 414 "dtc-parser.y" /* yacc.c:1646 */ |
1913 | { (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); } | 1913 | { |
1914 | #line 1915 "dtc-parser.tab.c" /* yacc.c:1646 */ | 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 */ | ||
1915 | break; | 1922 | break; |
1916 | 1923 | ||
1917 | case 66: | 1924 | case 66: |
1918 | #line 414 "dtc-parser.y" /* yacc.c:1646 */ | 1925 | #line 423 "dtc-parser.y" /* yacc.c:1646 */ |
1919 | { (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); } | 1926 | { |
1920 | #line 1921 "dtc-parser.tab.c" /* yacc.c:1646 */ | 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 */ | ||
1921 | break; | 1935 | break; |
1922 | 1936 | ||
1923 | case 69: | 1937 | case 69: |
1924 | #line 420 "dtc-parser.y" /* yacc.c:1646 */ | 1938 | #line 436 "dtc-parser.y" /* yacc.c:1646 */ |
1925 | { (yyval.integer) = -(yyvsp[0].integer); } | 1939 | { (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 */ |
1927 | break; | 1941 | break; |
1928 | 1942 | ||
1929 | case 70: | 1943 | case 70: |
1930 | #line 421 "dtc-parser.y" /* yacc.c:1646 */ | 1944 | #line 437 "dtc-parser.y" /* yacc.c:1646 */ |
1931 | { (yyval.integer) = ~(yyvsp[0].integer); } | 1945 | { (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 */ |
1933 | break; | 1947 | break; |
1934 | 1948 | ||
1935 | case 71: | 1949 | case 71: |
1936 | #line 422 "dtc-parser.y" /* yacc.c:1646 */ | 1950 | #line 438 "dtc-parser.y" /* yacc.c:1646 */ |
1937 | { (yyval.integer) = !(yyvsp[0].integer); } | 1951 | { (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 */ |
1939 | break; | 1953 | break; |
1940 | 1954 | ||
1941 | case 72: | 1955 | case 72: |
1942 | #line 427 "dtc-parser.y" /* yacc.c:1646 */ | 1956 | #line 443 "dtc-parser.y" /* yacc.c:1646 */ |
1943 | { | 1957 | { |
1944 | (yyval.data) = empty_data; | 1958 | (yyval.data) = empty_data; |
1945 | } | 1959 | } |
1946 | #line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */ | 1960 | #line 1961 "dtc-parser.tab.c" /* yacc.c:1646 */ |
1947 | break; | 1961 | break; |
1948 | 1962 | ||
1949 | case 73: | 1963 | case 73: |
1950 | #line 431 "dtc-parser.y" /* yacc.c:1646 */ | 1964 | #line 447 "dtc-parser.y" /* yacc.c:1646 */ |
1951 | { | 1965 | { |
1952 | (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); | 1966 | (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); |
1953 | } | 1967 | } |
1954 | #line 1955 "dtc-parser.tab.c" /* yacc.c:1646 */ | 1968 | #line 1969 "dtc-parser.tab.c" /* yacc.c:1646 */ |
1955 | break; | 1969 | break; |
1956 | 1970 | ||
1957 | case 74: | 1971 | case 74: |
1958 | #line 435 "dtc-parser.y" /* yacc.c:1646 */ | 1972 | #line 451 "dtc-parser.y" /* yacc.c:1646 */ |
1959 | { | 1973 | { |
1960 | (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); | 1974 | (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); |
1961 | } | 1975 | } |
1962 | #line 1963 "dtc-parser.tab.c" /* yacc.c:1646 */ | 1976 | #line 1977 "dtc-parser.tab.c" /* yacc.c:1646 */ |
1963 | break; | 1977 | break; |
1964 | 1978 | ||
1965 | case 75: | 1979 | case 75: |
1966 | #line 442 "dtc-parser.y" /* yacc.c:1646 */ | 1980 | #line 458 "dtc-parser.y" /* yacc.c:1646 */ |
1967 | { | 1981 | { |
1968 | (yyval.nodelist) = NULL; | 1982 | (yyval.nodelist) = NULL; |
1969 | } | 1983 | } |
1970 | #line 1971 "dtc-parser.tab.c" /* yacc.c:1646 */ | 1984 | #line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */ |
1971 | break; | 1985 | break; |
1972 | 1986 | ||
1973 | case 76: | 1987 | case 76: |
1974 | #line 446 "dtc-parser.y" /* yacc.c:1646 */ | 1988 | #line 462 "dtc-parser.y" /* yacc.c:1646 */ |
1975 | { | 1989 | { |
1976 | (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); | 1990 | (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); |
1977 | } | 1991 | } |
1978 | #line 1979 "dtc-parser.tab.c" /* yacc.c:1646 */ | 1992 | #line 1993 "dtc-parser.tab.c" /* yacc.c:1646 */ |
1979 | break; | 1993 | break; |
1980 | 1994 | ||
1981 | case 77: | 1995 | case 77: |
1982 | #line 450 "dtc-parser.y" /* yacc.c:1646 */ | 1996 | #line 466 "dtc-parser.y" /* yacc.c:1646 */ |
1983 | { | 1997 | { |
1984 | ERROR(&(yylsp[0]), "Properties must precede subnodes"); | 1998 | ERROR(&(yylsp[0]), "Properties must precede subnodes"); |
1985 | YYERROR; | 1999 | YYERROR; |
1986 | } | 2000 | } |
1987 | #line 1988 "dtc-parser.tab.c" /* yacc.c:1646 */ | 2001 | #line 2002 "dtc-parser.tab.c" /* yacc.c:1646 */ |
1988 | break; | 2002 | break; |
1989 | 2003 | ||
1990 | case 78: | 2004 | case 78: |
1991 | #line 458 "dtc-parser.y" /* yacc.c:1646 */ | 2005 | #line 474 "dtc-parser.y" /* yacc.c:1646 */ |
1992 | { | 2006 | { |
1993 | (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); | 2007 | (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); |
1994 | } | 2008 | } |
1995 | #line 1996 "dtc-parser.tab.c" /* yacc.c:1646 */ | 2009 | #line 2010 "dtc-parser.tab.c" /* yacc.c:1646 */ |
1996 | break; | 2010 | break; |
1997 | 2011 | ||
1998 | case 79: | 2012 | case 79: |
1999 | #line 462 "dtc-parser.y" /* yacc.c:1646 */ | 2013 | #line 478 "dtc-parser.y" /* yacc.c:1646 */ |
2000 | { | 2014 | { |
2001 | (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); | 2015 | (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); |
2002 | } | 2016 | } |
2003 | #line 2004 "dtc-parser.tab.c" /* yacc.c:1646 */ | 2017 | #line 2018 "dtc-parser.tab.c" /* yacc.c:1646 */ |
2004 | break; | 2018 | break; |
2005 | 2019 | ||
2006 | case 80: | 2020 | case 80: |
2007 | #line 466 "dtc-parser.y" /* yacc.c:1646 */ | 2021 | #line 482 "dtc-parser.y" /* yacc.c:1646 */ |
2008 | { | 2022 | { |
2009 | add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); | 2023 | add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); |
2010 | (yyval.node) = (yyvsp[0].node); | 2024 | (yyval.node) = (yyvsp[0].node); |
2011 | } | 2025 | } |
2012 | #line 2013 "dtc-parser.tab.c" /* yacc.c:1646 */ | 2026 | #line 2027 "dtc-parser.tab.c" /* yacc.c:1646 */ |
2013 | break; | 2027 | break; |
2014 | 2028 | ||
2015 | 2029 | ||
2016 | #line 2017 "dtc-parser.tab.c" /* yacc.c:1646 */ | 2030 | #line 2031 "dtc-parser.tab.c" /* yacc.c:1646 */ |
2017 | default: break; | 2031 | default: break; |
2018 | } | 2032 | } |
2019 | /* User semantic actions sometimes alter yychar, and that requires | 2033 | /* User semantic actions sometimes alter yychar, and that requires |
@@ -2248,7 +2262,7 @@ yyreturn: | |||
2248 | #endif | 2262 | #endif |
2249 | return yyresult; | 2263 | return yyresult; |
2250 | } | 2264 | } |
2251 | #line 472 "dtc-parser.y" /* yacc.c:1906 */ | 2265 | #line 488 "dtc-parser.y" /* yacc.c:1906 */ |
2252 | 2266 | ||
2253 | 2267 | ||
2254 | void yyerror(char const *s) | 2268 | void yyerror(char const *s) |
diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y index 5a897e36562d..000873f070fd 100644 --- a/scripts/dtc/dtc-parser.y +++ b/scripts/dtc/dtc-parser.y | |||
@@ -410,8 +410,24 @@ integer_add: | |||
410 | 410 | ||
411 | integer_mul: | 411 | integer_mul: |
412 | integer_mul '*' integer_unary { $$ = $1 * $3; } | 412 | integer_mul '*' integer_unary { $$ = $1 * $3; } |
413 | | integer_mul '/' integer_unary { $$ = $1 / $3; } | 413 | | integer_mul '/' integer_unary |
414 | | integer_mul '%' integer_unary { $$ = $1 % $3; } | 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 | } | ||
415 | | integer_unary | 431 | | integer_unary |
416 | ; | 432 | ; |
417 | 433 | ||
diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c index 8c4add69a765..5fa23c406266 100644 --- a/scripts/dtc/dtc.c +++ b/scripts/dtc/dtc.c | |||
@@ -18,6 +18,8 @@ | |||
18 | * USA | 18 | * USA |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <sys/stat.h> | ||
22 | |||
21 | #include "dtc.h" | 23 | #include "dtc.h" |
22 | #include "srcpos.h" | 24 | #include "srcpos.h" |
23 | 25 | ||
@@ -104,11 +106,56 @@ static const char * const usage_opts_help[] = { | |||
104 | NULL, | 106 | NULL, |
105 | }; | 107 | }; |
106 | 108 | ||
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 | |||
107 | int main(int argc, char *argv[]) | 154 | int main(int argc, char *argv[]) |
108 | { | 155 | { |
109 | struct boot_info *bi; | 156 | struct boot_info *bi; |
110 | const char *inform = "dts"; | 157 | const char *inform = NULL; |
111 | const char *outform = "dts"; | 158 | const char *outform = NULL; |
112 | const char *outname = "-"; | 159 | const char *outname = "-"; |
113 | const char *depname = NULL; | 160 | const char *depname = NULL; |
114 | bool force = false, sort = false; | 161 | bool force = false, sort = false; |
@@ -213,6 +260,17 @@ int main(int argc, char *argv[]) | |||
213 | fprintf(depfile, "%s:", outname); | 260 | fprintf(depfile, "%s:", outname); |
214 | } | 261 | } |
215 | 262 | ||
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 | } | ||
216 | if (streq(inform, "dts")) | 274 | if (streq(inform, "dts")) |
217 | bi = dt_from_source(arg); | 275 | bi = dt_from_source(arg); |
218 | else if (streq(inform, "fs")) | 276 | else if (streq(inform, "fs")) |
diff --git a/scripts/dtc/libfdt/fdt.c b/scripts/dtc/libfdt/fdt.c index 2ce6a44179de..22286a1aaeaf 100644 --- a/scripts/dtc/libfdt/fdt.c +++ b/scripts/dtc/libfdt/fdt.c | |||
@@ -76,18 +76,19 @@ int fdt_check_header(const void *fdt) | |||
76 | 76 | ||
77 | const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len) | 77 | const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len) |
78 | { | 78 | { |
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; | ||
80 | 85 | ||
81 | if (fdt_version(fdt) >= 0x11) | 86 | if (fdt_version(fdt) >= 0x11) |
82 | if (((offset + len) < offset) | 87 | if (((offset + len) < offset) |
83 | || ((offset + len) > fdt_size_dt_struct(fdt))) | 88 | || ((offset + len) > fdt_size_dt_struct(fdt))) |
84 | return NULL; | 89 | return NULL; |
85 | 90 | ||
86 | p = _fdt_offset_ptr(fdt, offset); | 91 | return _fdt_offset_ptr(fdt, offset); |
87 | |||
88 | if (p + len < p) | ||
89 | return NULL; | ||
90 | return p; | ||
91 | } | 92 | } |
92 | 93 | ||
93 | uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) | 94 | uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) |
diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c index a65e4b5b72b6..e5b313682007 100644 --- a/scripts/dtc/libfdt/fdt_ro.c +++ b/scripts/dtc/libfdt/fdt_ro.c | |||
@@ -538,6 +538,106 @@ int fdt_stringlist_contains(const char *strlist, int listlen, const char *str) | |||
538 | return 0; | 538 | return 0; |
539 | } | 539 | } |
540 | 540 | ||
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 | |||
541 | int fdt_node_check_compatible(const void *fdt, int nodeoffset, | 641 | int fdt_node_check_compatible(const void *fdt, int nodeoffset, |
542 | const char *compatible) | 642 | const char *compatible) |
543 | { | 643 | { |
diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c index 70adec6c371b..8be02b1f68f3 100644 --- a/scripts/dtc/libfdt/fdt_rw.c +++ b/scripts/dtc/libfdt/fdt_rw.c | |||
@@ -101,6 +101,8 @@ static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen) | |||
101 | 101 | ||
102 | if (((p + oldlen) < p) || ((p + oldlen) > end)) | 102 | if (((p + oldlen) < p) || ((p + oldlen) > end)) |
103 | return -FDT_ERR_BADOFFSET; | 103 | return -FDT_ERR_BADOFFSET; |
104 | if ((p < (char *)fdt) || ((end - oldlen + newlen) < (char *)fdt)) | ||
105 | return -FDT_ERR_BADOFFSET; | ||
104 | if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt))) | 106 | if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt))) |
105 | return -FDT_ERR_NOSPACE; | 107 | return -FDT_ERR_NOSPACE; |
106 | memmove(p + newlen, p + oldlen, end - p - oldlen); | 108 | memmove(p + newlen, p + oldlen, end - p - oldlen); |
diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h index ea35ac3c9be4..59ca33976e56 100644 --- a/scripts/dtc/libfdt/libfdt.h +++ b/scripts/dtc/libfdt/libfdt.h | |||
@@ -121,7 +121,12 @@ | |||
121 | /* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells | 121 | /* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells |
122 | * or similar property with a bad format or value */ | 122 | * or similar property with a bad format or value */ |
123 | 123 | ||
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 | ||
125 | 130 | ||
126 | /**********************************************************************/ | 131 | /**********************************************************************/ |
127 | /* Low-level functions (you probably don't need these) */ | 132 | /* 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, | |||
457 | * @namelen: number of characters of name to consider | 462 | * @namelen: number of characters of name to consider |
458 | * @lenp: pointer to an integer variable (will be overwritten) or NULL | 463 | * @lenp: pointer to an integer variable (will be overwritten) or NULL |
459 | * | 464 | * |
460 | * Identical to fdt_get_property_namelen(), but only examine the first | 465 | * Identical to fdt_get_property(), but only examine the first namelen |
461 | * namelen characters of name for matching the property name. | 466 | * characters of name for matching the property name. |
462 | */ | 467 | */ |
463 | const struct fdt_property *fdt_get_property_namelen(const void *fdt, | 468 | const struct fdt_property *fdt_get_property_namelen(const void *fdt, |
464 | int nodeoffset, | 469 | int nodeoffset, |
@@ -868,6 +873,68 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset, | |||
868 | */ | 873 | */ |
869 | int fdt_stringlist_contains(const char *strlist, int listlen, const char *str); | 874 | int fdt_stringlist_contains(const char *strlist, int listlen, const char *str); |
870 | 875 | ||
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 | |||
871 | /**********************************************************************/ | 938 | /**********************************************************************/ |
872 | /* Read-only functions (addressing related) */ | 939 | /* Read-only functions (addressing related) */ |
873 | /**********************************************************************/ | 940 | /**********************************************************************/ |
diff --git a/scripts/dtc/util.c b/scripts/dtc/util.c index 9d65226df9e4..fb124eea4919 100644 --- a/scripts/dtc/util.c +++ b/scripts/dtc/util.c | |||
@@ -152,7 +152,6 @@ char get_escape_char(const char *s, int *i) | |||
152 | int j = *i + 1; | 152 | int j = *i + 1; |
153 | char val; | 153 | char val; |
154 | 154 | ||
155 | assert(c); | ||
156 | switch (c) { | 155 | switch (c) { |
157 | case 'a': | 156 | case 'a': |
158 | val = '\a'; | 157 | val = '\a'; |
@@ -349,7 +348,6 @@ int utilfdt_decode_type(const char *fmt, int *type, int *size) | |||
349 | void utilfdt_print_data(const char *data, int len) | 348 | void utilfdt_print_data(const char *data, int len) |
350 | { | 349 | { |
351 | int i; | 350 | int i; |
352 | const char *p = data; | ||
353 | const char *s; | 351 | const char *s; |
354 | 352 | ||
355 | /* no data, don't print */ | 353 | /* no data, don't print */ |
@@ -376,6 +374,7 @@ void utilfdt_print_data(const char *data, int len) | |||
376 | i < (len - 1) ? " " : ""); | 374 | i < (len - 1) ? " " : ""); |
377 | printf(">"); | 375 | printf(">"); |
378 | } else { | 376 | } else { |
377 | const unsigned char *p = (const unsigned char *)data; | ||
379 | printf(" = ["); | 378 | printf(" = ["); |
380 | for (i = 0; i < len; i++) | 379 | for (i = 0; i < len; i++) |
381 | printf("%02x%s", *p++, i < len - 1 ? " " : ""); | 380 | printf("%02x%s", *p++, i < len - 1 ? " " : ""); |
diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h index 5b8c7d53d608..11d93e6d8220 100644 --- a/scripts/dtc/version_gen.h +++ b/scripts/dtc/version_gen.h | |||
@@ -1 +1 @@ | |||
#define DTC_VERSION "DTC 1.4.1-g9d3649bd" | #define DTC_VERSION "DTC 1.4.1-gb06e55c8" | ||