summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorRob Herring <robh@kernel.org>2018-11-28 19:37:35 -0500
committerRob Herring <robh@kernel.org>2018-11-28 19:37:35 -0500
commitc2e7075ca83036317cee4a564729eb82a5433169 (patch)
tree3172d34d5620eaa9066c0934410b4eeb33d37269 /scripts
parente8b1dee21420f871e300d46342f2c98a2e08158d (diff)
scripts/dtc: Update to upstream version v1.4.7-57-gf267e674d145
This adds the following commits from upstream: f267e674d145 checks: Fix crash with multiple source annotations 3616b9a811b6 checks: Use source position information for check failures 2bdbd07a1223 checks: Make each message output atomic a1eff70c02cf util: Add xa{v}sprintf_append functions 82a52ce4573b libfdt: Add a test for fdt_getprop_by_offset() 607b8586b383 PEP8 / Flake8 cleanups for setup.py f9c0a425b648 Remove broken objdir / srcdir support 5182b5e6f28c pylibfdt: Use common PREFIX variable d45bf1f5f2a6 Refine make tests_clean target 99284c4db9cb Refine pylibfdt_clean target a4629cfaedfb Refine libfdt_clean target 08380fc43aa2 tests: Use modern octal literals for Python 8113c00b99d3 pylibfdt: Allow switch to Python 3 via environment variable PYTHON 11738cf01f15 libfdt: Don't use memcpy to handle unaligned reads on ARM 86a288a73670 checks: Restructure check_msg to decrease indentation 5667e7ef9a9a annotations: add the annotation functionality 8e20ccf52f90 annotations: add positions ca930e20bb54 tests: Don't lose errors from make checkm 43366bb4eeee tests: Property count valgrind errors in wrapped tests 5062516fb8cb srcpos: Remove srcpos_empty a3143fafbf83 Revert "annotations: add positions" 403cc79f06a1 checks: Update SPI bus check for 'spi-slave' baa1d2cf7894 annotations: add positions ff2ad38f6a5a Merge remote-tracking branch 'origin/pr/18' aa7254d9cb17 libfdt: return correct value if #size-cells property is not present 49903aed7783 use ptrdiff_t modifier for printing pointer differences da2b691ccf68 treesource: Fix dts output for phandles in middle of a sequence of ints 8f8b77a0d62d tests: Wrap check_align() calls with base_run_test() 522d81d572f2 Fix dts output with a REF_PATH marker e45198c98359 Added test cases for target references 0fcffda15e9f Merge nodes with local target label references 1e4a0928f3b3 pylibfdt: Don't have setup.py depend on where it's invoked from ca399b14956f pylibfdt: Eliminate run_setup make function 98972f1b3e33 pylibfdt: Improved version extraction 7ba2be6cda5f pylibfdt: Don't silence setup.py when V=1 7691f9d39301 pylibfdt: Make SETUP make variable 855b9963def9 pylibfdt: Simpler CFLAGS handling 47cafbeeb977 pylibfdt: Link extension module with libfdt rather than rebuilding dd695d6afb19 pylibfdt: Correctly set build output directory 59327523d0d8 pylibfdt: We don't need include files from the base directory e84742aa7b93 checks: fix simple-bus compatible matching 8c59a97ce096 Fix missing labels when emitting dts format d448f9a5fd94 Revert dts output formatting changes of spaces around brackets Signed-off-by: Rob Herring <robh@kernel.org>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/dtc/checks.c73
-rw-r--r--scripts/dtc/dtc-lexer.l4
-rw-r--r--scripts/dtc/dtc-parser.y52
-rw-r--r--scripts/dtc/dtc.c11
-rw-r--r--scripts/dtc/dtc.h11
-rw-r--r--scripts/dtc/flattree.c4
-rw-r--r--scripts/dtc/fstree.c5
-rw-r--r--scripts/dtc/libfdt/Makefile.libfdt4
-rw-r--r--scripts/dtc/libfdt/fdt_addresses.c16
-rw-r--r--scripts/dtc/libfdt/libfdt.h24
-rw-r--r--scripts/dtc/livetree.c33
-rw-r--r--scripts/dtc/srcpos.c153
-rw-r--r--scripts/dtc/srcpos.h14
-rw-r--r--scripts/dtc/treesource.c115
-rw-r--r--scripts/dtc/util.c60
-rw-r--r--scripts/dtc/util.h2
-rw-r--r--scripts/dtc/version_gen.h2
17 files changed, 436 insertions, 147 deletions
diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c
index 9c9b0c328af6..4834e44b37b2 100644
--- a/scripts/dtc/checks.c
+++ b/scripts/dtc/checks.c
@@ -19,6 +19,7 @@
19 */ 19 */
20 20
21#include "dtc.h" 21#include "dtc.h"
22#include "srcpos.h"
22 23
23#ifdef TRACE_CHECKS 24#ifdef TRACE_CHECKS
24#define TRACE(c, ...) \ 25#define TRACE(c, ...) \
@@ -78,23 +79,56 @@ static inline void PRINTF(5, 6) check_msg(struct check *c, struct dt_info *dti,
78 const char *fmt, ...) 79 const char *fmt, ...)
79{ 80{
80 va_list ap; 81 va_list ap;
81 va_start(ap, fmt); 82 char *str = NULL;
83 struct srcpos *pos = NULL;
84 char *file_str;
85
86 if (!(c->warn && (quiet < 1)) && !(c->error && (quiet < 2)))
87 return;
88
89 if (prop && prop->srcpos)
90 pos = prop->srcpos;
91 else if (node && node->srcpos)
92 pos = node->srcpos;
93
94 if (pos) {
95 file_str = srcpos_string(pos);
96 xasprintf(&str, "%s", file_str);
97 free(file_str);
98 } else if (streq(dti->outname, "-")) {
99 xasprintf(&str, "<stdout>");
100 } else {
101 xasprintf(&str, "%s", dti->outname);
102 }
82 103
83 if ((c->warn && (quiet < 1)) 104 xasprintf_append(&str, ": %s (%s): ",
84 || (c->error && (quiet < 2))) {
85 fprintf(stderr, "%s: %s (%s): ",
86 strcmp(dti->outname, "-") ? dti->outname : "<stdout>",
87 (c->error) ? "ERROR" : "Warning", c->name); 105 (c->error) ? "ERROR" : "Warning", c->name);
88 if (node) { 106
89 fprintf(stderr, "%s", node->fullpath); 107 if (node) {
90 if (prop) 108 if (prop)
91 fprintf(stderr, ":%s", prop->name); 109 xasprintf_append(&str, "%s:%s: ", node->fullpath, prop->name);
92 fputs(": ", stderr); 110 else
93 } 111 xasprintf_append(&str, "%s: ", node->fullpath);
94 vfprintf(stderr, fmt, ap);
95 fprintf(stderr, "\n");
96 } 112 }
113
114 va_start(ap, fmt);
115 xavsprintf_append(&str, fmt, ap);
97 va_end(ap); 116 va_end(ap);
117
118 xasprintf_append(&str, "\n");
119
120 if (!prop && pos) {
121 pos = node->srcpos;
122 while (pos->next) {
123 pos = pos->next;
124
125 file_str = srcpos_string(pos);
126 xasprintf_append(&str, " also defined at %s\n", file_str);
127 free(file_str);
128 }
129 }
130
131 fputs(str, stderr);
98} 132}
99 133
100#define FAIL(c, dti, node, ...) \ 134#define FAIL(c, dti, node, ...) \
@@ -910,7 +944,7 @@ static bool node_is_compatible(struct node *node, const char *compat)
910 944
911 for (str = prop->val.val, end = str + prop->val.len; str < end; 945 for (str = prop->val.val, end = str + prop->val.len; str < end;
912 str += strnlen(str, end - str) + 1) { 946 str += strnlen(str, end - str) + 1) {
913 if (strprefixeq(str, end - str, compat)) 947 if (streq(str, compat))
914 return true; 948 return true;
915 } 949 }
916 return false; 950 return false;
@@ -921,7 +955,8 @@ static void check_simple_bus_bridge(struct check *c, struct dt_info *dti, struct
921 if (node_is_compatible(node, "simple-bus")) 955 if (node_is_compatible(node, "simple-bus"))
922 node->bus = &simple_bus; 956 node->bus = &simple_bus;
923} 957}
924WARNING(simple_bus_bridge, check_simple_bus_bridge, NULL, &addr_size_cells); 958WARNING(simple_bus_bridge, check_simple_bus_bridge, NULL,
959 &addr_size_cells, &compatible_is_string_list);
925 960
926static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct node *node) 961static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct node *node)
927{ 962{
@@ -1035,6 +1070,7 @@ static const struct bus_type spi_bus = {
1035 1070
1036static void check_spi_bus_bridge(struct check *c, struct dt_info *dti, struct node *node) 1071static void check_spi_bus_bridge(struct check *c, struct dt_info *dti, struct node *node)
1037{ 1072{
1073 int spi_addr_cells = 1;
1038 1074
1039 if (strprefixeq(node->name, node->basenamelen, "spi")) { 1075 if (strprefixeq(node->name, node->basenamelen, "spi")) {
1040 node->bus = &spi_bus; 1076 node->bus = &spi_bus;
@@ -1063,7 +1099,9 @@ static void check_spi_bus_bridge(struct check *c, struct dt_info *dti, struct no
1063 if (node->bus != &spi_bus || !node->children) 1099 if (node->bus != &spi_bus || !node->children)
1064 return; 1100 return;
1065 1101
1066 if (node_addr_cells(node) != 1) 1102 if (get_property(node, "spi-slave"))
1103 spi_addr_cells = 0;
1104 if (node_addr_cells(node) != spi_addr_cells)
1067 FAIL(c, dti, node, "incorrect #address-cells for SPI bus"); 1105 FAIL(c, dti, node, "incorrect #address-cells for SPI bus");
1068 if (node_size_cells(node) != 0) 1106 if (node_size_cells(node) != 0)
1069 FAIL(c, dti, node, "incorrect #size-cells for SPI bus"); 1107 FAIL(c, dti, node, "incorrect #size-cells for SPI bus");
@@ -1082,6 +1120,9 @@ static void check_spi_bus_reg(struct check *c, struct dt_info *dti, struct node
1082 if (!node->parent || (node->parent->bus != &spi_bus)) 1120 if (!node->parent || (node->parent->bus != &spi_bus))
1083 return; 1121 return;
1084 1122
1123 if (get_property(node->parent, "spi-slave"))
1124 return;
1125
1085 prop = get_property(node, "reg"); 1126 prop = get_property(node, "reg");
1086 if (prop) 1127 if (prop)
1087 cells = (cell_t *)prop->val.val; 1128 cells = (cell_t *)prop->val.val;
diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l
index 615b7ec6588f..06c040902444 100644
--- a/scripts/dtc/dtc-lexer.l
+++ b/scripts/dtc/dtc-lexer.l
@@ -213,14 +213,14 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
213<*>\&{LABEL} { /* label reference */ 213<*>\&{LABEL} { /* label reference */
214 DPRINT("Ref: %s\n", yytext+1); 214 DPRINT("Ref: %s\n", yytext+1);
215 yylval.labelref = xstrdup(yytext+1); 215 yylval.labelref = xstrdup(yytext+1);
216 return DT_REF; 216 return DT_LABEL_REF;
217 } 217 }
218 218
219<*>"&{/"{PATHCHAR}*\} { /* new-style path reference */ 219<*>"&{/"{PATHCHAR}*\} { /* new-style path reference */
220 yytext[yyleng-1] = '\0'; 220 yytext[yyleng-1] = '\0';
221 DPRINT("Ref: %s\n", yytext+2); 221 DPRINT("Ref: %s\n", yytext+2);
222 yylval.labelref = xstrdup(yytext+2); 222 yylval.labelref = xstrdup(yytext+2);
223 return DT_REF; 223 return DT_PATH_REF;
224 } 224 }
225 225
226<BYTESTRING>[0-9a-fA-F]{2} { 226<BYTESTRING>[0-9a-fA-F]{2} {
diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y
index dd70ebf386f4..2ec981e86111 100644
--- a/scripts/dtc/dtc-parser.y
+++ b/scripts/dtc/dtc-parser.y
@@ -70,7 +70,8 @@ extern bool treesource_error;
70%token <byte> DT_BYTE 70%token <byte> DT_BYTE
71%token <data> DT_STRING 71%token <data> DT_STRING
72%token <labelref> DT_LABEL 72%token <labelref> DT_LABEL
73%token <labelref> DT_REF 73%token <labelref> DT_LABEL_REF
74%token <labelref> DT_PATH_REF
74%token DT_INCBIN 75%token DT_INCBIN
75 76
76%type <data> propdata 77%type <data> propdata
@@ -83,6 +84,7 @@ extern bool treesource_error;
83%type <data> bytestring 84%type <data> bytestring
84%type <prop> propdef 85%type <prop> propdef
85%type <proplist> proplist 86%type <proplist> proplist
87%type <labelref> dt_ref
86 88
87%type <node> devicetree 89%type <node> devicetree
88%type <node> nodedef 90%type <node> nodedef
@@ -158,6 +160,8 @@ memreserve:
158 } 160 }
159 ; 161 ;
160 162
163dt_ref: DT_LABEL_REF | DT_PATH_REF;
164
161devicetree: 165devicetree:
162 '/' nodedef 166 '/' nodedef
163 { 167 {
@@ -167,7 +171,7 @@ devicetree:
167 { 171 {
168 $$ = merge_nodes($1, $3); 172 $$ = merge_nodes($1, $3);
169 } 173 }
170 | DT_REF nodedef 174 | dt_ref nodedef
171 { 175 {
172 /* 176 /*
173 * We rely on the rule being always: 177 * We rely on the rule being always:
@@ -176,9 +180,12 @@ devicetree:
176 */ 180 */
177 if (!($<flags>-1 & DTSF_PLUGIN)) 181 if (!($<flags>-1 & DTSF_PLUGIN))
178 ERROR(&@2, "Label or path %s not found", $1); 182 ERROR(&@2, "Label or path %s not found", $1);
179 $$ = add_orphan_node(name_node(build_node(NULL, NULL), ""), $2, $1); 183 $$ = add_orphan_node(
184 name_node(build_node(NULL, NULL, NULL),
185 ""),
186 $2, $1);
180 } 187 }
181 | devicetree DT_LABEL DT_REF nodedef 188 | devicetree DT_LABEL dt_ref nodedef
182 { 189 {
183 struct node *target = get_node_by_ref($1, $3); 190 struct node *target = get_node_by_ref($1, $3);
184 191
@@ -189,7 +196,7 @@ devicetree:
189 ERROR(&@3, "Label or path %s not found", $3); 196 ERROR(&@3, "Label or path %s not found", $3);
190 $$ = $1; 197 $$ = $1;
191 } 198 }
192 | devicetree DT_REF nodedef 199 | devicetree DT_PATH_REF nodedef
193 { 200 {
194 /* 201 /*
195 * We rely on the rule being always: 202 * We rely on the rule being always:
@@ -208,7 +215,26 @@ devicetree:
208 } 215 }
209 $$ = $1; 216 $$ = $1;
210 } 217 }
211 | devicetree DT_DEL_NODE DT_REF ';' 218 | devicetree DT_LABEL_REF nodedef
219 {
220 struct node *target = get_node_by_ref($1, $2);
221
222 if (target) {
223 merge_nodes(target, $3);
224 } else {
225 /*
226 * We rely on the rule being always:
227 * versioninfo plugindecl memreserves devicetree
228 * so $-1 is what we want (plugindecl)
229 */
230 if ($<flags>-1 & DTSF_PLUGIN)
231 add_orphan_node($1, $3, $2);
232 else
233 ERROR(&@2, "Label or path %s not found", $2);
234 }
235 $$ = $1;
236 }
237 | devicetree DT_DEL_NODE dt_ref ';'
212 { 238 {
213 struct node *target = get_node_by_ref($1, $3); 239 struct node *target = get_node_by_ref($1, $3);
214 240
@@ -220,7 +246,7 @@ devicetree:
220 246
221 $$ = $1; 247 $$ = $1;
222 } 248 }
223 | devicetree DT_OMIT_NO_REF DT_REF ';' 249 | devicetree DT_OMIT_NO_REF dt_ref ';'
224 { 250 {
225 struct node *target = get_node_by_ref($1, $3); 251 struct node *target = get_node_by_ref($1, $3);
226 252
@@ -237,7 +263,7 @@ devicetree:
237nodedef: 263nodedef:
238 '{' proplist subnodes '}' ';' 264 '{' proplist subnodes '}' ';'
239 { 265 {
240 $$ = build_node($2, $3); 266 $$ = build_node($2, $3, &@$);
241 } 267 }
242 ; 268 ;
243 269
@@ -255,11 +281,11 @@ proplist:
255propdef: 281propdef:
256 DT_PROPNODENAME '=' propdata ';' 282 DT_PROPNODENAME '=' propdata ';'
257 { 283 {
258 $$ = build_property($1, $3); 284 $$ = build_property($1, $3, &@$);
259 } 285 }
260 | DT_PROPNODENAME ';' 286 | DT_PROPNODENAME ';'
261 { 287 {
262 $$ = build_property($1, empty_data); 288 $$ = build_property($1, empty_data, &@$);
263 } 289 }
264 | DT_DEL_PROP DT_PROPNODENAME ';' 290 | DT_DEL_PROP DT_PROPNODENAME ';'
265 { 291 {
@@ -285,7 +311,7 @@ propdata:
285 { 311 {
286 $$ = data_merge($1, $3); 312 $$ = data_merge($1, $3);
287 } 313 }
288 | propdataprefix DT_REF 314 | propdataprefix dt_ref
289 { 315 {
290 $1 = data_add_marker($1, TYPE_STRING, $2); 316 $1 = data_add_marker($1, TYPE_STRING, $2);
291 $$ = data_add_marker($1, REF_PATH, $2); 317 $$ = data_add_marker($1, REF_PATH, $2);
@@ -383,7 +409,7 @@ arrayprefix:
383 409
384 $$.data = data_append_integer($1.data, $2, $1.bits); 410 $$.data = data_append_integer($1.data, $2, $1.bits);
385 } 411 }
386 | arrayprefix DT_REF 412 | arrayprefix dt_ref
387 { 413 {
388 uint64_t val = ~0ULL >> (64 - $1.bits); 414 uint64_t val = ~0ULL >> (64 - $1.bits);
389 415
@@ -540,7 +566,7 @@ subnode:
540 } 566 }
541 | DT_DEL_NODE DT_PROPNODENAME ';' 567 | DT_DEL_NODE DT_PROPNODENAME ';'
542 { 568 {
543 $$ = name_node(build_node_delete(), $2); 569 $$ = name_node(build_node_delete(&@$), $2);
544 } 570 }
545 | DT_OMIT_NO_REF subnode 571 | DT_OMIT_NO_REF subnode
546 { 572 {
diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c
index 64134aadb997..695e1f789fc7 100644
--- a/scripts/dtc/dtc.c
+++ b/scripts/dtc/dtc.c
@@ -35,6 +35,8 @@ int phandle_format = PHANDLE_EPAPR; /* Use linux,phandle or phandle properties *
35int generate_symbols; /* enable symbols & fixup support */ 35int generate_symbols; /* enable symbols & fixup support */
36int generate_fixups; /* suppress generation of fixups on symbol support */ 36int generate_fixups; /* suppress generation of fixups on symbol support */
37int auto_label_aliases; /* auto generate labels -> aliases */ 37int auto_label_aliases; /* auto generate labels -> aliases */
38int annotate; /* Level of annotation: 1 for input source location
39 >1 for full input source location. */
38 40
39static int is_power_of_2(int x) 41static int is_power_of_2(int x)
40{ 42{
@@ -60,7 +62,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix)
60 62
61/* Usage related data. */ 63/* Usage related data. */
62static const char usage_synopsis[] = "dtc [options] <input file>"; 64static const char usage_synopsis[] = "dtc [options] <input file>";
63static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@Ahv"; 65static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@AThv";
64static struct option const usage_long_opts[] = { 66static struct option const usage_long_opts[] = {
65 {"quiet", no_argument, NULL, 'q'}, 67 {"quiet", no_argument, NULL, 'q'},
66 {"in-format", a_argument, NULL, 'I'}, 68 {"in-format", a_argument, NULL, 'I'},
@@ -81,6 +83,7 @@ static struct option const usage_long_opts[] = {
81 {"error", a_argument, NULL, 'E'}, 83 {"error", a_argument, NULL, 'E'},
82 {"symbols", no_argument, NULL, '@'}, 84 {"symbols", no_argument, NULL, '@'},
83 {"auto-alias", no_argument, NULL, 'A'}, 85 {"auto-alias", no_argument, NULL, 'A'},
86 {"annotate", no_argument, NULL, 'T'},
84 {"help", no_argument, NULL, 'h'}, 87 {"help", no_argument, NULL, 'h'},
85 {"version", no_argument, NULL, 'v'}, 88 {"version", no_argument, NULL, 'v'},
86 {NULL, no_argument, NULL, 0x0}, 89 {NULL, no_argument, NULL, 0x0},
@@ -117,6 +120,7 @@ static const char * const usage_opts_help[] = {
117 "\n\tEnable/disable errors (prefix with \"no-\")", 120 "\n\tEnable/disable errors (prefix with \"no-\")",
118 "\n\tEnable generation of symbols", 121 "\n\tEnable generation of symbols",
119 "\n\tEnable auto-alias of labels", 122 "\n\tEnable auto-alias of labels",
123 "\n\tAnnotate output .dts with input source file and line (-T -T for more details)",
120 "\n\tPrint this help and exit", 124 "\n\tPrint this help and exit",
121 "\n\tPrint version and exit", 125 "\n\tPrint version and exit",
122 NULL, 126 NULL,
@@ -264,6 +268,9 @@ int main(int argc, char *argv[])
264 case 'A': 268 case 'A':
265 auto_label_aliases = 1; 269 auto_label_aliases = 1;
266 break; 270 break;
271 case 'T':
272 annotate++;
273 break;
267 274
268 case 'h': 275 case 'h':
269 usage(NULL); 276 usage(NULL);
@@ -302,6 +309,8 @@ int main(int argc, char *argv[])
302 outform = "dts"; 309 outform = "dts";
303 } 310 }
304 } 311 }
312 if (annotate && (!streq(inform, "dts") || !streq(outform, "dts")))
313 die("--annotate requires -I dts -O dts\n");
305 if (streq(inform, "dts")) 314 if (streq(inform, "dts"))
306 dti = dt_from_source(arg); 315 dti = dt_from_source(arg);
307 else if (streq(inform, "fs")) 316 else if (streq(inform, "fs"))
diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h
index cbe541525c2c..789e0b1bc057 100644
--- a/scripts/dtc/dtc.h
+++ b/scripts/dtc/dtc.h
@@ -58,6 +58,7 @@ extern int phandle_format; /* Use linux,phandle or phandle properties */
58extern int generate_symbols; /* generate symbols for nodes with labels */ 58extern int generate_symbols; /* generate symbols for nodes with labels */
59extern int generate_fixups; /* generate fixups */ 59extern int generate_fixups; /* generate fixups */
60extern int auto_label_aliases; /* auto generate labels -> aliases */ 60extern int auto_label_aliases; /* auto generate labels -> aliases */
61extern int annotate; /* annotate .dts with input source location */
61 62
62#define PHANDLE_LEGACY 0x1 63#define PHANDLE_LEGACY 0x1
63#define PHANDLE_EPAPR 0x2 64#define PHANDLE_EPAPR 0x2
@@ -158,6 +159,7 @@ struct property {
158 struct property *next; 159 struct property *next;
159 160
160 struct label *labels; 161 struct label *labels;
162 struct srcpos *srcpos;
161}; 163};
162 164
163struct node { 165struct node {
@@ -177,6 +179,7 @@ struct node {
177 179
178 struct label *labels; 180 struct label *labels;
179 const struct bus_type *bus; 181 const struct bus_type *bus;
182 struct srcpos *srcpos;
180 183
181 bool omit_if_unused, is_referenced; 184 bool omit_if_unused, is_referenced;
182}; 185};
@@ -205,13 +208,15 @@ struct node {
205void add_label(struct label **labels, char *label); 208void add_label(struct label **labels, char *label);
206void delete_labels(struct label **labels); 209void delete_labels(struct label **labels);
207 210
208struct property *build_property(char *name, struct data val); 211struct property *build_property(char *name, struct data val,
212 struct srcpos *srcpos);
209struct property *build_property_delete(char *name); 213struct property *build_property_delete(char *name);
210struct property *chain_property(struct property *first, struct property *list); 214struct property *chain_property(struct property *first, struct property *list);
211struct property *reverse_properties(struct property *first); 215struct property *reverse_properties(struct property *first);
212 216
213struct node *build_node(struct property *proplist, struct node *children); 217struct node *build_node(struct property *proplist, struct node *children,
214struct node *build_node_delete(void); 218 struct srcpos *srcpos);
219struct node *build_node_delete(struct srcpos *srcpos);
215struct node *name_node(struct node *node, char *name); 220struct node *name_node(struct node *node, char *name);
216struct node *omit_node_if_unused(struct node *node); 221struct node *omit_node_if_unused(struct node *node);
217struct node *reference_node(struct node *node); 222struct node *reference_node(struct node *node);
diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c
index 851ea87dbc0f..acf04c30669f 100644
--- a/scripts/dtc/flattree.c
+++ b/scripts/dtc/flattree.c
@@ -692,7 +692,7 @@ static struct property *flat_read_property(struct inbuf *dtbuf,
692 692
693 val = flat_read_data(dtbuf, proplen); 693 val = flat_read_data(dtbuf, proplen);
694 694
695 return build_property(name, val); 695 return build_property(name, val, NULL);
696} 696}
697 697
698 698
@@ -750,7 +750,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
750 char *flatname; 750 char *flatname;
751 uint32_t val; 751 uint32_t val;
752 752
753 node = build_node(NULL, NULL); 753 node = build_node(NULL, NULL, NULL);
754 754
755 flatname = flat_read_string(dtbuf); 755 flatname = flat_read_string(dtbuf);
756 756
diff --git a/scripts/dtc/fstree.c b/scripts/dtc/fstree.c
index ae7d06c3c492..1e7eeba47ff6 100644
--- a/scripts/dtc/fstree.c
+++ b/scripts/dtc/fstree.c
@@ -34,7 +34,7 @@ static struct node *read_fstree(const char *dirname)
34 if (!d) 34 if (!d)
35 die("Couldn't opendir() \"%s\": %s\n", dirname, strerror(errno)); 35 die("Couldn't opendir() \"%s\": %s\n", dirname, strerror(errno));
36 36
37 tree = build_node(NULL, NULL); 37 tree = build_node(NULL, NULL, NULL);
38 38
39 while ((de = readdir(d)) != NULL) { 39 while ((de = readdir(d)) != NULL) {
40 char *tmpname; 40 char *tmpname;
@@ -60,7 +60,8 @@ static struct node *read_fstree(const char *dirname)
60 } else { 60 } else {
61 prop = build_property(xstrdup(de->d_name), 61 prop = build_property(xstrdup(de->d_name),
62 data_copy_file(pfile, 62 data_copy_file(pfile,
63 st.st_size)); 63 st.st_size),
64 NULL);
64 add_property(tree, prop); 65 add_property(tree, prop);
65 fclose(pfile); 66 fclose(pfile);
66 } 67 }
diff --git a/scripts/dtc/libfdt/Makefile.libfdt b/scripts/dtc/libfdt/Makefile.libfdt
index 098b3f36e668..3af3656df801 100644
--- a/scripts/dtc/libfdt/Makefile.libfdt
+++ b/scripts/dtc/libfdt/Makefile.libfdt
@@ -9,3 +9,7 @@ LIBFDT_VERSION = version.lds
9LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c fdt_empty_tree.c \ 9LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c fdt_empty_tree.c \
10 fdt_addresses.c fdt_overlay.c 10 fdt_addresses.c fdt_overlay.c
11LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o) 11LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)
12
13libfdt_clean:
14 @$(VECHO) CLEAN "(libfdt)"
15 rm -f $(STD_CLEANFILES:%=$(LIBFDT_dir)/%)
diff --git a/scripts/dtc/libfdt/fdt_addresses.c b/scripts/dtc/libfdt/fdt_addresses.c
index 49537b578d03..f13a87dfa068 100644
--- a/scripts/dtc/libfdt/fdt_addresses.c
+++ b/scripts/dtc/libfdt/fdt_addresses.c
@@ -64,7 +64,7 @@ static int fdt_cells(const void *fdt, int nodeoffset, const char *name)
64 64
65 c = fdt_getprop(fdt, nodeoffset, name, &len); 65 c = fdt_getprop(fdt, nodeoffset, name, &len);
66 if (!c) 66 if (!c)
67 return 2; 67 return len;
68 68
69 if (len != sizeof(*c)) 69 if (len != sizeof(*c))
70 return -FDT_ERR_BADNCELLS; 70 return -FDT_ERR_BADNCELLS;
@@ -78,10 +78,20 @@ static int fdt_cells(const void *fdt, int nodeoffset, const char *name)
78 78
79int fdt_address_cells(const void *fdt, int nodeoffset) 79int fdt_address_cells(const void *fdt, int nodeoffset)
80{ 80{
81 return fdt_cells(fdt, nodeoffset, "#address-cells"); 81 int val;
82
83 val = fdt_cells(fdt, nodeoffset, "#address-cells");
84 if (val == -FDT_ERR_NOTFOUND)
85 return 2;
86 return val;
82} 87}
83 88
84int fdt_size_cells(const void *fdt, int nodeoffset) 89int fdt_size_cells(const void *fdt, int nodeoffset)
85{ 90{
86 return fdt_cells(fdt, nodeoffset, "#size-cells"); 91 int val;
92
93 val = fdt_cells(fdt, nodeoffset, "#size-cells");
94 if (val == -FDT_ERR_NOTFOUND)
95 return 1;
96 return val;
87} 97}
diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h
index 2bd151dd355f..627da2e079c9 100644
--- a/scripts/dtc/libfdt/libfdt.h
+++ b/scripts/dtc/libfdt/libfdt.h
@@ -163,18 +163,26 @@ uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
163 163
164static inline uint32_t fdt32_ld(const fdt32_t *p) 164static inline uint32_t fdt32_ld(const fdt32_t *p)
165{ 165{
166 fdt32_t v; 166 const uint8_t *bp = (const uint8_t *)p;
167 167
168 memcpy(&v, p, sizeof(v)); 168 return ((uint32_t)bp[0] << 24)
169 return fdt32_to_cpu(v); 169 | ((uint32_t)bp[1] << 16)
170 | ((uint32_t)bp[2] << 8)
171 | bp[3];
170} 172}
171 173
172static inline uint64_t fdt64_ld(const fdt64_t *p) 174static inline uint64_t fdt64_ld(const fdt64_t *p)
173{ 175{
174 fdt64_t v; 176 const uint8_t *bp = (const uint8_t *)p;
175 177
176 memcpy(&v, p, sizeof(v)); 178 return ((uint64_t)bp[0] << 56)
177 return fdt64_to_cpu(v); 179 | ((uint64_t)bp[1] << 48)
180 | ((uint64_t)bp[2] << 40)
181 | ((uint64_t)bp[3] << 32)
182 | ((uint64_t)bp[4] << 24)
183 | ((uint64_t)bp[5] << 16)
184 | ((uint64_t)bp[6] << 8)
185 | bp[7];
178} 186}
179 187
180/**********************************************************************/ 188/**********************************************************************/
@@ -1145,7 +1153,7 @@ int fdt_address_cells(const void *fdt, int nodeoffset);
1145 * 1153 *
1146 * returns: 1154 * returns:
1147 * 0 <= n < FDT_MAX_NCELLS, on success 1155 * 0 <= n < FDT_MAX_NCELLS, on success
1148 * 2, if the node has no #size-cells property 1156 * 1, if the node has no #size-cells property
1149 * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid 1157 * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
1150 * #size-cells property 1158 * #size-cells property
1151 * -FDT_ERR_BADMAGIC, 1159 * -FDT_ERR_BADMAGIC,
diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c
index 4ff0679e0062..7a2e6446a17b 100644
--- a/scripts/dtc/livetree.c
+++ b/scripts/dtc/livetree.c
@@ -19,6 +19,7 @@
19 */ 19 */
20 20
21#include "dtc.h" 21#include "dtc.h"
22#include "srcpos.h"
22 23
23/* 24/*
24 * Tree building functions 25 * Tree building functions
@@ -50,7 +51,8 @@ void delete_labels(struct label **labels)
50 label->deleted = 1; 51 label->deleted = 1;
51} 52}
52 53
53struct property *build_property(char *name, struct data val) 54struct property *build_property(char *name, struct data val,
55 struct srcpos *srcpos)
54{ 56{
55 struct property *new = xmalloc(sizeof(*new)); 57 struct property *new = xmalloc(sizeof(*new));
56 58
@@ -58,6 +60,7 @@ struct property *build_property(char *name, struct data val)
58 60
59 new->name = name; 61 new->name = name;
60 new->val = val; 62 new->val = val;
63 new->srcpos = srcpos_copy(srcpos);
61 64
62 return new; 65 return new;
63} 66}
@@ -97,7 +100,8 @@ struct property *reverse_properties(struct property *first)
97 return head; 100 return head;
98} 101}
99 102
100struct node *build_node(struct property *proplist, struct node *children) 103struct node *build_node(struct property *proplist, struct node *children,
104 struct srcpos *srcpos)
101{ 105{
102 struct node *new = xmalloc(sizeof(*new)); 106 struct node *new = xmalloc(sizeof(*new));
103 struct node *child; 107 struct node *child;
@@ -106,6 +110,7 @@ struct node *build_node(struct property *proplist, struct node *children)
106 110
107 new->proplist = reverse_properties(proplist); 111 new->proplist = reverse_properties(proplist);
108 new->children = children; 112 new->children = children;
113 new->srcpos = srcpos_copy(srcpos);
109 114
110 for_each_child(new, child) { 115 for_each_child(new, child) {
111 child->parent = new; 116 child->parent = new;
@@ -114,13 +119,14 @@ struct node *build_node(struct property *proplist, struct node *children)
114 return new; 119 return new;
115} 120}
116 121
117struct node *build_node_delete(void) 122struct node *build_node_delete(struct srcpos *srcpos)
118{ 123{
119 struct node *new = xmalloc(sizeof(*new)); 124 struct node *new = xmalloc(sizeof(*new));
120 125
121 memset(new, 0, sizeof(*new)); 126 memset(new, 0, sizeof(*new));
122 127
123 new->deleted = 1; 128 new->deleted = 1;
129 new->srcpos = srcpos_copy(srcpos);
124 130
125 return new; 131 return new;
126} 132}
@@ -183,6 +189,8 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
183 189
184 old_prop->val = new_prop->val; 190 old_prop->val = new_prop->val;
185 old_prop->deleted = 0; 191 old_prop->deleted = 0;
192 free(old_prop->srcpos);
193 old_prop->srcpos = new_prop->srcpos;
186 free(new_prop); 194 free(new_prop);
187 new_prop = NULL; 195 new_prop = NULL;
188 break; 196 break;
@@ -223,6 +231,8 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
223 add_child(old_node, new_child); 231 add_child(old_node, new_child);
224 } 232 }
225 233
234 old_node->srcpos = srcpos_extend(old_node->srcpos, new_node->srcpos);
235
226 /* The new node contents are now merged into the old node. Free 236 /* The new node contents are now merged into the old node. Free
227 * the new node. */ 237 * the new node. */
228 free(new_node); 238 free(new_node);
@@ -241,18 +251,18 @@ struct node * add_orphan_node(struct node *dt, struct node *new_node, char *ref)
241 if (ref[0] == '/') { 251 if (ref[0] == '/') {
242 d = data_append_data(d, ref, strlen(ref) + 1); 252 d = data_append_data(d, ref, strlen(ref) + 1);
243 253
244 p = build_property("target-path", d); 254 p = build_property("target-path", d, NULL);
245 } else { 255 } else {
246 d = data_add_marker(d, REF_PHANDLE, ref); 256 d = data_add_marker(d, REF_PHANDLE, ref);
247 d = data_append_integer(d, 0xffffffff, 32); 257 d = data_append_integer(d, 0xffffffff, 32);
248 258
249 p = build_property("target", d); 259 p = build_property("target", d, NULL);
250 } 260 }
251 261
252 xasprintf(&name, "fragment@%u", 262 xasprintf(&name, "fragment@%u",
253 next_orphan_fragment++); 263 next_orphan_fragment++);
254 name_node(new_node, "__overlay__"); 264 name_node(new_node, "__overlay__");
255 node = build_node(p, new_node); 265 node = build_node(p, new_node, NULL);
256 name_node(node, name); 266 name_node(node, name);
257 267
258 add_child(dt, node); 268 add_child(dt, node);
@@ -351,7 +361,7 @@ void append_to_property(struct node *node,
351 p->val = d; 361 p->val = d;
352 } else { 362 } else {
353 d = data_append_data(empty_data, data, len); 363 d = data_append_data(empty_data, data, len);
354 p = build_property(name, d); 364 p = build_property(name, d, NULL);
355 add_property(node, p); 365 add_property(node, p);
356 } 366 }
357} 367}
@@ -609,11 +619,11 @@ cell_t get_node_phandle(struct node *root, struct node *node)
609 619
610 if (!get_property(node, "linux,phandle") 620 if (!get_property(node, "linux,phandle")
611 && (phandle_format & PHANDLE_LEGACY)) 621 && (phandle_format & PHANDLE_LEGACY))
612 add_property(node, build_property("linux,phandle", d)); 622 add_property(node, build_property("linux,phandle", d, NULL));
613 623
614 if (!get_property(node, "phandle") 624 if (!get_property(node, "phandle")
615 && (phandle_format & PHANDLE_EPAPR)) 625 && (phandle_format & PHANDLE_EPAPR))
616 add_property(node, build_property("phandle", d)); 626 add_property(node, build_property("phandle", d, NULL));
617 627
618 /* If the node *does* have a phandle property, we must 628 /* If the node *does* have a phandle property, we must
619 * be dealing with a self-referencing phandle, which will be 629 * be dealing with a self-referencing phandle, which will be
@@ -787,7 +797,7 @@ static struct node *build_and_name_child_node(struct node *parent, char *name)
787{ 797{
788 struct node *node; 798 struct node *node;
789 799
790 node = build_node(NULL, NULL); 800 node = build_node(NULL, NULL, NULL);
791 name_node(node, xstrdup(name)); 801 name_node(node, xstrdup(name));
792 add_child(parent, node); 802 add_child(parent, node);
793 803
@@ -849,7 +859,8 @@ static void generate_label_tree_internal(struct dt_info *dti,
849 /* insert it */ 859 /* insert it */
850 p = build_property(l->label, 860 p = build_property(l->label,
851 data_copy_mem(node->fullpath, 861 data_copy_mem(node->fullpath,
852 strlen(node->fullpath) + 1)); 862 strlen(node->fullpath) + 1),
863 NULL);
853 add_property(an, p); 864 add_property(an, p);
854 } 865 }
855 866
diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c
index cb6ed0e3e5e4..41f83700ee91 100644
--- a/scripts/dtc/srcpos.c
+++ b/scripts/dtc/srcpos.c
@@ -33,6 +33,9 @@ struct search_path {
33/* This is the list of directories that we search for source files */ 33/* This is the list of directories that we search for source files */
34static struct search_path *search_path_head, **search_path_tail; 34static struct search_path *search_path_head, **search_path_tail;
35 35
36/* Detect infinite include recursion. */
37#define MAX_SRCFILE_DEPTH (100)
38static int srcfile_depth; /* = 0 */
36 39
37static char *get_dirname(const char *path) 40static char *get_dirname(const char *path)
38{ 41{
@@ -51,11 +54,51 @@ static char *get_dirname(const char *path)
51 54
52FILE *depfile; /* = NULL */ 55FILE *depfile; /* = NULL */
53struct srcfile_state *current_srcfile; /* = NULL */ 56struct srcfile_state *current_srcfile; /* = NULL */
57static char *initial_path; /* = NULL */
58static int initial_pathlen; /* = 0 */
59static bool initial_cpp = true;
54 60
55/* Detect infinite include recursion. */ 61static void set_initial_path(char *fname)
56#define MAX_SRCFILE_DEPTH (100) 62{
57static int srcfile_depth; /* = 0 */ 63 int i, len = strlen(fname);
58 64
65 xasprintf(&initial_path, "%s", fname);
66 initial_pathlen = 0;
67 for (i = 0; i != len; i++)
68 if (initial_path[i] == '/')
69 initial_pathlen++;
70}
71
72static char *shorten_to_initial_path(char *fname)
73{
74 char *p1, *p2, *prevslash1 = NULL;
75 int slashes = 0;
76
77 for (p1 = fname, p2 = initial_path; *p1 && *p2; p1++, p2++) {
78 if (*p1 != *p2)
79 break;
80 if (*p1 == '/') {
81 prevslash1 = p1;
82 slashes++;
83 }
84 }
85 p1 = prevslash1 + 1;
86 if (prevslash1) {
87 int diff = initial_pathlen - slashes, i, j;
88 int restlen = strlen(fname) - (p1 - fname);
89 char *res;
90
91 res = xmalloc((3 * diff) + restlen + 1);
92 for (i = 0, j = 0; i != diff; i++) {
93 res[j++] = '.';
94 res[j++] = '.';
95 res[j++] = '/';
96 }
97 strcpy(res + j, p1);
98 return res;
99 }
100 return NULL;
101}
59 102
60/** 103/**
61 * Try to open a file in a given directory. 104 * Try to open a file in a given directory.
@@ -157,6 +200,9 @@ void srcfile_push(const char *fname)
157 srcfile->colno = 1; 200 srcfile->colno = 1;
158 201
159 current_srcfile = srcfile; 202 current_srcfile = srcfile;
203
204 if (srcfile_depth == 1)
205 set_initial_path(srcfile->name);
160} 206}
161 207
162bool srcfile_pop(void) 208bool srcfile_pop(void)
@@ -197,18 +243,6 @@ void srcfile_add_search_path(const char *dirname)
197 search_path_tail = &node->next; 243 search_path_tail = &node->next;
198} 244}
199 245
200/*
201 * The empty source position.
202 */
203
204struct srcpos srcpos_empty = {
205 .first_line = 0,
206 .first_column = 0,
207 .last_line = 0,
208 .last_column = 0,
209 .file = NULL,
210};
211
212void srcpos_update(struct srcpos *pos, const char *text, int len) 246void srcpos_update(struct srcpos *pos, const char *text, int len)
213{ 247{
214 int i; 248 int i;
@@ -234,13 +268,35 @@ struct srcpos *
234srcpos_copy(struct srcpos *pos) 268srcpos_copy(struct srcpos *pos)
235{ 269{
236 struct srcpos *pos_new; 270 struct srcpos *pos_new;
271 struct srcfile_state *srcfile_state;
272
273 if (!pos)
274 return NULL;
237 275
238 pos_new = xmalloc(sizeof(struct srcpos)); 276 pos_new = xmalloc(sizeof(struct srcpos));
277 assert(pos->next == NULL);
239 memcpy(pos_new, pos, sizeof(struct srcpos)); 278 memcpy(pos_new, pos, sizeof(struct srcpos));
240 279
280 /* allocate without free */
281 srcfile_state = xmalloc(sizeof(struct srcfile_state));
282 memcpy(srcfile_state, pos->file, sizeof(struct srcfile_state));
283 pos_new->file = srcfile_state;
284
241 return pos_new; 285 return pos_new;
242} 286}
243 287
288struct srcpos *srcpos_extend(struct srcpos *pos, struct srcpos *newtail)
289{
290 struct srcpos *p;
291
292 if (!pos)
293 return newtail;
294
295 for (p = pos; p->next != NULL; p = p->next);
296 p->next = newtail;
297 return pos;
298}
299
244char * 300char *
245srcpos_string(struct srcpos *pos) 301srcpos_string(struct srcpos *pos)
246{ 302{
@@ -266,6 +322,68 @@ srcpos_string(struct srcpos *pos)
266 return pos_str; 322 return pos_str;
267} 323}
268 324
325static char *
326srcpos_string_comment(struct srcpos *pos, bool first_line, int level)
327{
328 char *pos_str, *fname, *first, *rest;
329 bool fresh_fname = false;
330
331 if (!pos) {
332 if (level > 1) {
333 xasprintf(&pos_str, "<no-file>:<no-line>");
334 return pos_str;
335 } else {
336 return NULL;
337 }
338 }
339
340 if (!pos->file)
341 fname = "<no-file>";
342 else if (!pos->file->name)
343 fname = "<no-filename>";
344 else if (level > 1)
345 fname = pos->file->name;
346 else {
347 fname = shorten_to_initial_path(pos->file->name);
348 if (fname)
349 fresh_fname = true;
350 else
351 fname = pos->file->name;
352 }
353
354 if (level > 1)
355 xasprintf(&first, "%s:%d:%d-%d:%d", fname,
356 pos->first_line, pos->first_column,
357 pos->last_line, pos->last_column);
358 else
359 xasprintf(&first, "%s:%d", fname,
360 first_line ? pos->first_line : pos->last_line);
361
362 if (fresh_fname)
363 free(fname);
364
365 if (pos->next != NULL) {
366 rest = srcpos_string_comment(pos->next, first_line, level);
367 xasprintf(&pos_str, "%s, %s", first, rest);
368 free(first);
369 free(rest);
370 } else {
371 pos_str = first;
372 }
373
374 return pos_str;
375}
376
377char *srcpos_string_first(struct srcpos *pos, int level)
378{
379 return srcpos_string_comment(pos, true, level);
380}
381
382char *srcpos_string_last(struct srcpos *pos, int level)
383{
384 return srcpos_string_comment(pos, false, level);
385}
386
269void srcpos_verror(struct srcpos *pos, const char *prefix, 387void srcpos_verror(struct srcpos *pos, const char *prefix,
270 const char *fmt, va_list va) 388 const char *fmt, va_list va)
271{ 389{
@@ -294,4 +412,9 @@ void srcpos_set_line(char *f, int l)
294{ 412{
295 current_srcfile->name = f; 413 current_srcfile->name = f;
296 current_srcfile->lineno = l; 414 current_srcfile->lineno = l;
415
416 if (initial_cpp) {
417 initial_cpp = false;
418 set_initial_path(f);
419 }
297} 420}
diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h
index 9ded12a3830a..6326a952c40e 100644
--- a/scripts/dtc/srcpos.h
+++ b/scripts/dtc/srcpos.h
@@ -74,6 +74,7 @@ struct srcpos {
74 int last_line; 74 int last_line;
75 int last_column; 75 int last_column;
76 struct srcfile_state *file; 76 struct srcfile_state *file;
77 struct srcpos *next;
77}; 78};
78 79
79#define YYLTYPE struct srcpos 80#define YYLTYPE struct srcpos
@@ -93,19 +94,18 @@ struct srcpos {
93 YYRHSLOC(Rhs, 0).last_column; \ 94 YYRHSLOC(Rhs, 0).last_column; \
94 (Current).file = YYRHSLOC (Rhs, 0).file; \ 95 (Current).file = YYRHSLOC (Rhs, 0).file; \
95 } \ 96 } \
97 (Current).next = NULL; \
96 } while (0) 98 } while (0)
97 99
98 100
99/*
100 * Fictional source position used for IR nodes that are
101 * created without otherwise knowing a true source position.
102 * For example,constant definitions from the command line.
103 */
104extern struct srcpos srcpos_empty;
105
106extern void srcpos_update(struct srcpos *pos, const char *text, int len); 101extern void srcpos_update(struct srcpos *pos, const char *text, int len);
107extern struct srcpos *srcpos_copy(struct srcpos *pos); 102extern struct srcpos *srcpos_copy(struct srcpos *pos);
103extern struct srcpos *srcpos_extend(struct srcpos *new_srcpos,
104 struct srcpos *old_srcpos);
108extern char *srcpos_string(struct srcpos *pos); 105extern char *srcpos_string(struct srcpos *pos);
106extern char *srcpos_string_first(struct srcpos *pos, int level);
107extern char *srcpos_string_last(struct srcpos *pos, int level);
108
109 109
110extern void PRINTF(3, 0) srcpos_verror(struct srcpos *pos, const char *prefix, 110extern void PRINTF(3, 0) srcpos_verror(struct srcpos *pos, const char *prefix,
111 const char *fmt, va_list va); 111 const char *fmt, va_list va);
diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c
index f2874f1d1465..1af36628b75f 100644
--- a/scripts/dtc/treesource.c
+++ b/scripts/dtc/treesource.c
@@ -64,6 +64,10 @@ static bool isstring(char c)
64static void write_propval_string(FILE *f, const char *s, size_t len) 64static void write_propval_string(FILE *f, const char *s, size_t len)
65{ 65{
66 const char *end = s + len - 1; 66 const char *end = s + len - 1;
67
68 if (!len)
69 return;
70
67 assert(*end == '\0'); 71 assert(*end == '\0');
68 72
69 fprintf(f, "\""); 73 fprintf(f, "\"");
@@ -118,18 +122,20 @@ static void write_propval_int(FILE *f, const char *p, size_t len, size_t width)
118 for (; p < end; p += width) { 122 for (; p < end; p += width) {
119 switch (width) { 123 switch (width) {
120 case 1: 124 case 1:
121 fprintf(f, " %02"PRIx8, *(const uint8_t*)p); 125 fprintf(f, "%02"PRIx8, *(const uint8_t*)p);
122 break; 126 break;
123 case 2: 127 case 2:
124 fprintf(f, " 0x%02"PRIx16, fdt16_to_cpu(*(const fdt16_t*)p)); 128 fprintf(f, "0x%02"PRIx16, fdt16_to_cpu(*(const fdt16_t*)p));
125 break; 129 break;
126 case 4: 130 case 4:
127 fprintf(f, " 0x%02"PRIx32, fdt32_to_cpu(*(const fdt32_t*)p)); 131 fprintf(f, "0x%02"PRIx32, fdt32_to_cpu(*(const fdt32_t*)p));
128 break; 132 break;
129 case 8: 133 case 8:
130 fprintf(f, " 0x%02"PRIx64, fdt64_to_cpu(*(const fdt64_t*)p)); 134 fprintf(f, "0x%02"PRIx64, fdt64_to_cpu(*(const fdt64_t*)p));
131 break; 135 break;
132 } 136 }
137 if (p + width < end)
138 fputc(' ', f);
133 } 139 }
134} 140}
135 141
@@ -162,10 +168,10 @@ static const char *delim_start[] = {
162 [TYPE_STRING] = "", 168 [TYPE_STRING] = "",
163}; 169};
164static const char *delim_end[] = { 170static const char *delim_end[] = {
165 [TYPE_UINT8] = " ]", 171 [TYPE_UINT8] = "]",
166 [TYPE_UINT16] = " >", 172 [TYPE_UINT16] = ">",
167 [TYPE_UINT32] = " >", 173 [TYPE_UINT32] = ">",
168 [TYPE_UINT64] = " >", 174 [TYPE_UINT64] = ">",
169 [TYPE_STRING] = "", 175 [TYPE_STRING] = "",
170}; 176};
171 177
@@ -208,13 +214,22 @@ static void write_propval(FILE *f, struct property *prop)
208 struct marker *m = prop->val.markers; 214 struct marker *m = prop->val.markers;
209 struct marker dummy_marker; 215 struct marker dummy_marker;
210 enum markertype emit_type = TYPE_NONE; 216 enum markertype emit_type = TYPE_NONE;
217 char *srcstr;
211 218
212 if (len == 0) { 219 if (len == 0) {
213 fprintf(f, ";\n"); 220 fprintf(f, ";");
221 if (annotate) {
222 srcstr = srcpos_string_first(prop->srcpos, annotate);
223 if (srcstr) {
224 fprintf(f, " /* %s */", srcstr);
225 free(srcstr);
226 }
227 }
228 fprintf(f, "\n");
214 return; 229 return;
215 } 230 }
216 231
217 fprintf(f, " = "); 232 fprintf(f, " =");
218 233
219 if (!next_type_marker(m)) { 234 if (!next_type_marker(m)) {
220 /* data type information missing, need to guess */ 235 /* data type information missing, need to guess */
@@ -225,32 +240,23 @@ static void write_propval(FILE *f, struct property *prop)
225 m = &dummy_marker; 240 m = &dummy_marker;
226 } 241 }
227 242
228 struct marker *m_label = prop->val.markers;
229 for_each_marker(m) { 243 for_each_marker(m) {
230 size_t chunk_len; 244 size_t chunk_len = (m->next ? m->next->offset : len) - m->offset;
245 size_t data_len = type_marker_length(m) ? : len - m->offset;
231 const char *p = &prop->val.val[m->offset]; 246 const char *p = &prop->val.val[m->offset];
232 247
233 if (!has_data_type_information(m)) 248 if (has_data_type_information(m)) {
234 continue; 249 emit_type = m->type;
235 250 fprintf(f, " %s", delim_start[emit_type]);
236 chunk_len = type_marker_length(m); 251 } else if (m->type == LABEL)
237 if (!chunk_len) 252 fprintf(f, " %s:", m->ref);
238 chunk_len = len - m->offset; 253 else if (m->offset)
239 254 fputc(' ', f);
240 if (emit_type != TYPE_NONE)
241 fprintf(f, "%s, ", delim_end[emit_type]);
242 emit_type = m->type;
243
244 for_each_marker_of_type(m_label, LABEL) {
245 if (m_label->offset > m->offset)
246 break;
247 fprintf(f, "%s: ", m_label->ref);
248 }
249
250 fprintf(f, "%s", delim_start[emit_type]);
251 255
252 if (chunk_len <= 0) 256 if (emit_type == TYPE_NONE) {
257 assert(chunk_len == 0);
253 continue; 258 continue;
259 }
254 260
255 switch(emit_type) { 261 switch(emit_type) {
256 case TYPE_UINT16: 262 case TYPE_UINT16:
@@ -268,15 +274,23 @@ static void write_propval(FILE *f, struct property *prop)
268 default: 274 default:
269 write_propval_int(f, p, chunk_len, 1); 275 write_propval_int(f, p, chunk_len, 1);
270 } 276 }
271 }
272 277
273 /* Wrap up any labels at the end of the value */ 278 if (chunk_len == data_len) {
274 for_each_marker_of_type(m_label, LABEL) { 279 size_t pos = m->offset + chunk_len;
275 assert (m_label->offset == len); 280 fprintf(f, pos == len ? "%s" : "%s,",
276 fprintf(f, " %s:", m_label->ref); 281 delim_end[emit_type] ? : "");
282 emit_type = TYPE_NONE;
283 }
277 } 284 }
278 285 fprintf(f, ";");
279 fprintf(f, "%s;\n", delim_end[emit_type] ? : ""); 286 if (annotate) {
287 srcstr = srcpos_string_first(prop->srcpos, annotate);
288 if (srcstr) {
289 fprintf(f, " /* %s */", srcstr);
290 free(srcstr);
291 }
292 }
293 fprintf(f, "\n");
280} 294}
281 295
282static void write_tree_source_node(FILE *f, struct node *tree, int level) 296static void write_tree_source_node(FILE *f, struct node *tree, int level)
@@ -284,14 +298,24 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level)
284 struct property *prop; 298 struct property *prop;
285 struct node *child; 299 struct node *child;
286 struct label *l; 300 struct label *l;
301 char *srcstr;
287 302
288 write_prefix(f, level); 303 write_prefix(f, level);
289 for_each_label(tree->labels, l) 304 for_each_label(tree->labels, l)
290 fprintf(f, "%s: ", l->label); 305 fprintf(f, "%s: ", l->label);
291 if (tree->name && (*tree->name)) 306 if (tree->name && (*tree->name))
292 fprintf(f, "%s {\n", tree->name); 307 fprintf(f, "%s {", tree->name);
293 else 308 else
294 fprintf(f, "/ {\n"); 309 fprintf(f, "/ {");
310
311 if (annotate) {
312 srcstr = srcpos_string_first(tree->srcpos, annotate);
313 if (srcstr) {
314 fprintf(f, " /* %s */", srcstr);
315 free(srcstr);
316 }
317 }
318 fprintf(f, "\n");
295 319
296 for_each_property(tree, prop) { 320 for_each_property(tree, prop) {
297 write_prefix(f, level+1); 321 write_prefix(f, level+1);
@@ -305,10 +329,17 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level)
305 write_tree_source_node(f, child, level+1); 329 write_tree_source_node(f, child, level+1);
306 } 330 }
307 write_prefix(f, level); 331 write_prefix(f, level);
308 fprintf(f, "};\n"); 332 fprintf(f, "};");
333 if (annotate) {
334 srcstr = srcpos_string_last(tree->srcpos, annotate);
335 if (srcstr) {
336 fprintf(f, " /* %s */", srcstr);
337 free(srcstr);
338 }
339 }
340 fprintf(f, "\n");
309} 341}
310 342
311
312void dt_to_source(FILE *f, struct dt_info *dti) 343void dt_to_source(FILE *f, struct dt_info *dti)
313{ 344{
314 struct reserve_info *re; 345 struct reserve_info *re;
diff --git a/scripts/dtc/util.c b/scripts/dtc/util.c
index a69b7a13463d..9c6fb5f286ae 100644
--- a/scripts/dtc/util.c
+++ b/scripts/dtc/util.c
@@ -46,36 +46,54 @@ char *xstrdup(const char *s)
46 return d; 46 return d;
47} 47}
48 48
49/* based in part from (3) vsnprintf */ 49int xavsprintf_append(char **strp, const char *fmt, va_list ap)
50int xasprintf(char **strp, const char *fmt, ...)
51{ 50{
52 int n, size = 128; /* start with 128 bytes */ 51 int n, size = 0; /* start with 128 bytes */
53 char *p; 52 char *p;
54 va_list ap; 53 va_list ap_copy;
55 54
56 /* initial pointer is NULL making the fist realloc to be malloc */ 55 p = *strp;
57 p = NULL; 56 if (p)
58 while (1) { 57 size = strlen(p);
59 p = xrealloc(p, size);
60 58
61 /* Try to print in the allocated space. */ 59 va_copy(ap_copy, ap);
62 va_start(ap, fmt); 60 n = vsnprintf(NULL, 0, fmt, ap_copy) + 1;
63 n = vsnprintf(p, size, fmt, ap); 61 va_end(ap_copy);
64 va_end(ap); 62
63 p = xrealloc(p, size + n);
64
65 n = vsnprintf(p + size, n, fmt, ap);
65 66
66 /* If that worked, return the string. */
67 if (n > -1 && n < size)
68 break;
69 /* Else try again with more space. */
70 if (n > -1) /* glibc 2.1 */
71 size = n + 1; /* precisely what is needed */
72 else /* glibc 2.0 */
73 size *= 2; /* twice the old size */
74 }
75 *strp = p; 67 *strp = p;
76 return strlen(p); 68 return strlen(p);
77} 69}
78 70
71int xasprintf_append(char **strp, const char *fmt, ...)
72{
73 int n;
74 va_list ap;
75
76 va_start(ap, fmt);
77 n = xavsprintf_append(strp, fmt, ap);
78 va_end(ap);
79
80 return n;
81}
82
83int xasprintf(char **strp, const char *fmt, ...)
84{
85 int n;
86 va_list ap;
87
88 *strp = NULL;
89
90 va_start(ap, fmt);
91 n = xavsprintf_append(strp, fmt, ap);
92 va_end(ap);
93
94 return n;
95}
96
79char *join_path(const char *path, const char *name) 97char *join_path(const char *path, const char *name)
80{ 98{
81 int lenp = strlen(path); 99 int lenp = strlen(path);
diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h
index f6cea8274174..7658781a6200 100644
--- a/scripts/dtc/util.h
+++ b/scripts/dtc/util.h
@@ -72,6 +72,8 @@ static inline void *xrealloc(void *p, size_t len)
72extern char *xstrdup(const char *s); 72extern char *xstrdup(const char *s);
73 73
74extern int PRINTF(2, 3) xasprintf(char **strp, const char *fmt, ...); 74extern int PRINTF(2, 3) xasprintf(char **strp, const char *fmt, ...);
75extern int PRINTF(2, 3) xasprintf_append(char **strp, const char *fmt, ...);
76extern int xavsprintf_append(char **strp, const char *fmt, va_list ap);
75extern char *join_path(const char *path, const char *name); 77extern char *join_path(const char *path, const char *name);
76 78
77/** 79/**
diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h
index 6d23fd095f16..75f383c0b9d3 100644
--- a/scripts/dtc/version_gen.h
+++ b/scripts/dtc/version_gen.h
@@ -1 +1 @@
#define DTC_VERSION "DTC 1.4.7-gc86da84d" #define DTC_VERSION "DTC 1.4.7-gf267e674"