diff options
-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" | ||