~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/scripts/dtc/treesource.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
  4  */
  5 
  6 #include "dtc.h"
  7 #include "srcpos.h"
  8 
  9 extern FILE *yyin;
 10 extern int yyparse(void);
 11 extern YYLTYPE yylloc;
 12 
 13 struct dt_info *parser_output;
 14 bool treesource_error;
 15 
 16 struct dt_info *dt_from_source(const char *fname)
 17 {
 18         parser_output = NULL;
 19         treesource_error = false;
 20 
 21         srcfile_push(fname);
 22         yyin = current_srcfile->f;
 23         yylloc.file = current_srcfile;
 24 
 25         if (yyparse() != 0)
 26                 die("Unable to parse input tree\n");
 27 
 28         if (treesource_error)
 29                 die("Syntax error parsing input tree\n");
 30 
 31         return parser_output;
 32 }
 33 
 34 static void write_prefix(FILE *f, int level)
 35 {
 36         int i;
 37 
 38         for (i = 0; i < level; i++)
 39                 fputc('\t', f);
 40 }
 41 
 42 static bool isstring(char c)
 43 {
 44         return (isprint((unsigned char)c)
 45                 || (c == '\0')
 46                 || strchr("\a\b\t\n\v\f\r", c));
 47 }
 48 
 49 static void write_propval_string(FILE *f, const char *s, size_t len)
 50 {
 51         const char *end = s + len - 1;
 52 
 53         if (!len)
 54                 return;
 55 
 56         assert(*end == '\0');
 57 
 58         fprintf(f, "\"");
 59         while (s < end) {
 60                 char c = *s++;
 61                 switch (c) {
 62                 case '\a':
 63                         fprintf(f, "\\a");
 64                         break;
 65                 case '\b':
 66                         fprintf(f, "\\b");
 67                         break;
 68                 case '\t':
 69                         fprintf(f, "\\t");
 70                         break;
 71                 case '\n':
 72                         fprintf(f, "\\n");
 73                         break;
 74                 case '\v':
 75                         fprintf(f, "\\v");
 76                         break;
 77                 case '\f':
 78                         fprintf(f, "\\f");
 79                         break;
 80                 case '\r':
 81                         fprintf(f, "\\r");
 82                         break;
 83                 case '\\':
 84                         fprintf(f, "\\\\");
 85                         break;
 86                 case '\"':
 87                         fprintf(f, "\\\"");
 88                         break;
 89                 case '\0':
 90                         fprintf(f, "\\");
 91                         break;
 92                 default:
 93                         if (isprint((unsigned char)c))
 94                                 fprintf(f, "%c", c);
 95                         else
 96                                 fprintf(f, "\\x%02"PRIx8, c);
 97                 }
 98         }
 99         fprintf(f, "\"");
100 }
101 
102 static void write_propval_int(FILE *f, const char *p, size_t len, size_t width)
103 {
104         const char *end = p + len;
105         assert(len % width == 0);
106 
107         for (; p < end; p += width) {
108                 switch (width) {
109                 case 1:
110                         fprintf(f, "%02"PRIx8, *(const uint8_t*)p);
111                         break;
112                 case 2:
113                         fprintf(f, "0x%02"PRIx16, dtb_ld16(p));
114                         break;
115                 case 4:
116                         fprintf(f, "0x%02"PRIx32, dtb_ld32(p));
117                         break;
118                 case 8:
119                         fprintf(f, "0x%02"PRIx64, dtb_ld64(p));
120                         break;
121                 }
122                 if (p + width < end)
123                         fputc(' ', f);
124         }
125 }
126 
127 static const char *delim_start[] = {
128         [TYPE_UINT8] = "[",
129         [TYPE_UINT16] = "/bits/ 16 <",
130         [TYPE_UINT32] = "<",
131         [TYPE_UINT64] = "/bits/ 64 <",
132         [TYPE_STRING] = "",
133 };
134 static const char *delim_end[] = {
135         [TYPE_UINT8] = "]",
136         [TYPE_UINT16] = ">",
137         [TYPE_UINT32] = ">",
138         [TYPE_UINT64] = ">",
139         [TYPE_STRING] = "",
140 };
141 
142 static void add_string_markers(struct property *prop)
143 {
144         int l, len = prop->val.len;
145         const char *p = prop->val.val;
146 
147         for (l = strlen(p) + 1; l < len; l += strlen(p + l) + 1) {
148                 struct marker *m, **nextp;
149 
150                 m = xmalloc(sizeof(*m));
151                 m->offset = l;
152                 m->type = TYPE_STRING;
153                 m->ref = NULL;
154                 m->next = NULL;
155 
156                 /* Find the end of the markerlist */
157                 nextp = &prop->val.markers;
158                 while (*nextp)
159                         nextp = &((*nextp)->next);
160                 *nextp = m;
161         }
162 }
163 
164 static enum markertype guess_value_type(struct property *prop)
165 {
166         int len = prop->val.len;
167         const char *p = prop->val.val;
168         struct marker *m = prop->val.markers;
169         int nnotstring = 0, nnul = 0;
170         int nnotstringlbl = 0, nnotcelllbl = 0;
171         int i;
172 
173         for (i = 0; i < len; i++) {
174                 if (! isstring(p[i]))
175                         nnotstring++;
176                 if (p[i] == '\0')
177                         nnul++;
178         }
179 
180         for_each_marker_of_type(m, LABEL) {
181                 if ((m->offset > 0) && (prop->val.val[m->offset - 1] != '\0'))
182                         nnotstringlbl++;
183                 if ((m->offset % sizeof(cell_t)) != 0)
184                         nnotcelllbl++;
185         }
186 
187         if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul <= (len-nnul))
188             && (nnotstringlbl == 0)) {
189                 if (nnul > 1)
190                         add_string_markers(prop);
191                 return TYPE_STRING;
192         } else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) {
193                 return TYPE_UINT32;
194         }
195 
196         return TYPE_UINT8;
197 }
198 
199 static void write_propval(FILE *f, struct property *prop)
200 {
201         size_t len = prop->val.len;
202         struct marker *m = prop->val.markers;
203         struct marker dummy_marker;
204         enum markertype emit_type = TYPE_NONE;
205         char *srcstr;
206 
207         if (len == 0) {
208                 fprintf(f, ";");
209                 if (annotate) {
210                         srcstr = srcpos_string_first(prop->srcpos, annotate);
211                         if (srcstr) {
212                                 fprintf(f, " /* %s */", srcstr);
213                                 free(srcstr);
214                         }
215                 }
216                 fprintf(f, "\n");
217                 return;
218         }
219 
220         fprintf(f, " =");
221 
222         if (!next_type_marker(m)) {
223                 /* data type information missing, need to guess */
224                 dummy_marker.type = guess_value_type(prop);
225                 dummy_marker.next = prop->val.markers;
226                 dummy_marker.offset = 0;
227                 dummy_marker.ref = NULL;
228                 m = &dummy_marker;
229         }
230 
231         for_each_marker(m) {
232                 size_t chunk_len = (m->next ? m->next->offset : len) - m->offset;
233                 size_t data_len = type_marker_length(m) ? : len - m->offset;
234                 const char *p = &prop->val.val[m->offset];
235                 struct marker *m_phandle;
236 
237                 if (is_type_marker(m->type)) {
238                         emit_type = m->type;
239                         fprintf(f, " %s", delim_start[emit_type]);
240                 } else if (m->type == LABEL)
241                         fprintf(f, " %s:", m->ref);
242 
243                 if (emit_type == TYPE_NONE || chunk_len == 0)
244                         continue;
245 
246                 switch(emit_type) {
247                 case TYPE_UINT16:
248                         write_propval_int(f, p, chunk_len, 2);
249                         break;
250                 case TYPE_UINT32:
251                         m_phandle = prop->val.markers;
252                         for_each_marker_of_type(m_phandle, REF_PHANDLE)
253                                 if (m->offset == m_phandle->offset)
254                                         break;
255 
256                         if (m_phandle) {
257                                 if (m_phandle->ref[0] == '/')
258                                         fprintf(f, "&{%s}", m_phandle->ref);
259                                 else
260                                         fprintf(f, "&%s", m_phandle->ref);
261                                 if (chunk_len > 4) {
262                                         fputc(' ', f);
263                                         write_propval_int(f, p + 4, chunk_len - 4, 4);
264                                 }
265                         } else {
266                                 write_propval_int(f, p, chunk_len, 4);
267                         }
268                         if (data_len > chunk_len)
269                                 fputc(' ', f);
270                         break;
271                 case TYPE_UINT64:
272                         write_propval_int(f, p, chunk_len, 8);
273                         break;
274                 case TYPE_STRING:
275                         write_propval_string(f, p, chunk_len);
276                         break;
277                 default:
278                         write_propval_int(f, p, chunk_len, 1);
279                 }
280 
281                 if (chunk_len == data_len) {
282                         size_t pos = m->offset + chunk_len;
283                         fprintf(f, pos == len ? "%s" : "%s,",
284                                 delim_end[emit_type] ? : "");
285                         emit_type = TYPE_NONE;
286                 }
287         }
288         fprintf(f, ";");
289         if (annotate) {
290                 srcstr = srcpos_string_first(prop->srcpos, annotate);
291                 if (srcstr) {
292                         fprintf(f, " /* %s */", srcstr);
293                         free(srcstr);
294                 }
295         }
296         fprintf(f, "\n");
297 }
298 
299 static void write_tree_source_node(FILE *f, struct node *tree, int level)
300 {
301         struct property *prop;
302         struct node *child;
303         struct label *l;
304         char *srcstr;
305 
306         write_prefix(f, level);
307         for_each_label(tree->labels, l)
308                 fprintf(f, "%s: ", l->label);
309         if (tree->name && (*tree->name))
310                 fprintf(f, "%s {", tree->name);
311         else
312                 fprintf(f, "/ {");
313 
314         if (annotate) {
315                 srcstr = srcpos_string_first(tree->srcpos, annotate);
316                 if (srcstr) {
317                         fprintf(f, " /* %s */", srcstr);
318                         free(srcstr);
319                 }
320         }
321         fprintf(f, "\n");
322 
323         for_each_property(tree, prop) {
324                 write_prefix(f, level+1);
325                 for_each_label(prop->labels, l)
326                         fprintf(f, "%s: ", l->label);
327                 fprintf(f, "%s", prop->name);
328                 write_propval(f, prop);
329         }
330         for_each_child(tree, child) {
331                 fprintf(f, "\n");
332                 write_tree_source_node(f, child, level+1);
333         }
334         write_prefix(f, level);
335         fprintf(f, "};");
336         if (annotate) {
337                 srcstr = srcpos_string_last(tree->srcpos, annotate);
338                 if (srcstr) {
339                         fprintf(f, " /* %s */", srcstr);
340                         free(srcstr);
341                 }
342         }
343         fprintf(f, "\n");
344 }
345 
346 void dt_to_source(FILE *f, struct dt_info *dti)
347 {
348         struct reserve_info *re;
349 
350         fprintf(f, "/dts-v1/;\n\n");
351 
352         for (re = dti->reservelist; re; re = re->next) {
353                 struct label *l;
354 
355                 for_each_label(re->labels, l)
356                         fprintf(f, "%s: ", l->label);
357                 fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n",
358                         (unsigned long long)re->address,
359                         (unsigned long long)re->size);
360         }
361 
362         write_tree_source_node(f, dti->dt, 0);
363 }
364 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php