xref: /freebsd/usr.bin/dtc/fdt.cc (revision af0dd31fc469cac25e441ff350ccda958ea5c8df)
1 /*-
2  * Copyright (c) 2013 David Chisnall
3  * All rights reserved.
4  *
5  * This software was developed by SRI International and the University of
6  * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
7  * ("CTSRD"), as part of the DARPA CRASH research programme.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  * $FreeBSD$
31  */
32 
33 #include "fdt.hh"
34 
35 #include <algorithm>
36 #include <inttypes.h>
37 #include <fcntl.h>
38 #include <libgen.h>
39 #include "dtb.hh"
40 
41 namespace dtc
42 {
43 
44 namespace fdt
45 {
46 
47 uint32_t
48 property_value::get_as_uint32()
49 {
50 	if (byte_data.size() != 4)
51 	{
52 		return 0;
53 	}
54 	uint32_t v = 0;
55 	v &= byte_data[0] << 24;
56 	v &= byte_data[1] << 16;
57 	v &= byte_data[2] << 8;
58 	v &= byte_data[3] << 0;
59 	return v;
60 }
61 
62 void
63 property_value::push_to_buffer(byte_buffer &buffer)
64 {
65 	if (!byte_data.empty())
66 	{
67 		buffer.insert(buffer.end(), byte_data.begin(), byte_data.end());
68 	}
69 	else
70 	{
71 		string_data.push_to_buffer(buffer, true);
72 		// Trailing nul
73 		buffer.push_back(0);
74 	}
75 }
76 
77 void
78 property_value::write_dts(FILE *file)
79 {
80 	resolve_type();
81 	switch (type)
82 	{
83 		default:
84 			assert(0 && "Invalid type");
85 		case STRING:
86 		case STRING_LIST:
87 		case CROSS_REFERENCE:
88 			write_as_string(file);
89 			break;
90 		case PHANDLE:
91 			write_as_cells(file);
92 			break;
93 		case BINARY:
94 			if (byte_data.size() % 4 == 0)
95 			{
96 				write_as_cells(file);
97 				break;
98 			}
99 			write_as_bytes(file);
100 			break;
101 	}
102 }
103 
104 void
105 property_value::resolve_type()
106 {
107 	if (type != UNKNOWN)
108 	{
109 		return;
110 	}
111 	if (byte_data.empty())
112 	{
113 		type = STRING;
114 		return;
115 	}
116 	if (byte_data.back() == 0)
117 	{
118 		bool is_all_printable = true;
119 		int nuls = 0;
120 		int bytes = 0;
121 		for (byte_buffer::iterator i=byte_data.begin(), e=byte_data.end()-1; i<e ; i++)
122 		{
123 			bytes++;
124 			is_all_printable &= (*i == '\0') || isprint(*i);
125 			if (*i == '\0')
126 			{
127 				nuls++;
128 			}
129 			if (!is_all_printable)
130 			{
131 				break;
132 			}
133 		}
134 		if (is_all_printable && (bytes > nuls))
135 		{
136 			type = STRING;
137 			if (nuls > 0)
138 			{
139 				type = STRING_LIST;
140 			}
141 			return;
142 		}
143 	}
144 	type = BINARY;
145 }
146 
147 void
148 property_value::write_as_string(FILE *file)
149 {
150 	putc('"', file);
151 	if (byte_data.empty())
152 	{
153 		string_data.print(file);
154 	}
155 	else
156 	{
157 		for (byte_buffer::iterator i=byte_data.begin(), e=byte_data.end()-1; i!=e ; ++i)
158 		{
159 			// FIXME Escape tabs, newlines, and so on.
160 			if (*i == '\0')
161 			{
162 				fputs("\", \"", file);
163 				continue;
164 			}
165 			putc(*i, file);
166 		}
167 	}
168 	putc('"', file);
169 }
170 
171 void
172 property_value::write_as_cells(FILE *file)
173 {
174 	putc('<', file);
175 	assert((byte_data.size() % 4) == 0);
176 	for (byte_buffer::iterator i=byte_data.begin(), e=byte_data.end(); i!=e ; ++i)
177 	{
178 		uint32_t v = 0;
179 		v = (v << 8) | *i;
180 		++i;
181 		v = (v << 8) | *i;
182 		++i;
183 		v = (v << 8) | *i;
184 		++i;
185 		v = (v << 8) | *i;
186 		fprintf(file, "0x%" PRIx32, v);
187 		if (i+1 != e)
188 		{
189 			putc(' ', file);
190 		}
191 	}
192 	putc('>', file);
193 }
194 
195 void
196 property_value::write_as_bytes(FILE *file)
197 {
198 	putc('[', file);
199 	for (byte_buffer::iterator i=byte_data.begin(), e=byte_data.end(); i!=e ; i++)
200 	{
201 		fprintf(file, "%hhx", *i);
202 		if (i+1 != e)
203 		{
204 			putc(' ', file);
205 		}
206 	}
207 	putc(']', file);
208 }
209 
210 void
211 property::parse_string(input_buffer &input)
212 {
213 	property_value v;
214 	assert(input[0] == '"');
215 	++input;
216 	const char *start = (const char*)input;
217 	int length = 0;
218 	while (char c = input[0])
219 	{
220 		if (c == '"' && input[-1] != '\\')
221 		{
222 			input.consume('"');
223 			break;
224 		}
225 		++input;
226 		++length;
227 	}
228 	v.string_data = string(start, length);
229 	values.push_back(v);
230 }
231 
232 void
233 property::parse_cells(input_buffer &input)
234 {
235 	assert(input[0] == '<');
236 	++input;
237 	property_value v;
238 	input.next_token();
239 	while (!input.consume('>'))
240 	{
241 		input.next_token();
242 		// If this is a phandle then we need to get the name of the
243 		// referenced node
244 		if (input.consume('&'))
245 		{
246 			input.next_token();
247 			// FIXME: We should support full paths here, but we
248 			// don't.
249 			string referenced = string::parse_node_name(input);
250 			if (referenced.empty())
251 			{
252 				input.parse_error("Expected node name");
253 				valid = false;
254 				return;
255 			}
256 			input.next_token();
257 			// If we already have some bytes, make the phandle a
258 			// separate component.
259 			if (!v.byte_data.empty())
260 			{
261 				values.push_back(v);
262 				v = property_value();
263 			}
264 			v.string_data = referenced;
265 			v.type = property_value::PHANDLE;
266 			values.push_back(v);
267 			v = property_value();
268 		}
269 		else
270 		{
271 			//FIXME: We should support labels in the middle
272 			//of these, but we don't.
273 			long long val;
274 			if (!input.consume_integer(val))
275 			{
276 				input.parse_error("Expected numbers in array of cells");
277 				valid = false;
278 				return;
279 			}
280 			push_big_endian(v.byte_data, (uint32_t)val);
281 			input.next_token();
282 		}
283 	}
284 	// Don't store an empty string value here.
285 	if (v.byte_data.size() > 0)
286 	{
287 		values.push_back(v);
288 	}
289 }
290 
291 void
292 property::parse_bytes(input_buffer &input)
293 {
294 	assert(input[0] == '[');
295 	++input;
296 	property_value v;
297 	input.next_token();
298 	while (!input.consume(']'))
299 	{
300 		{
301 			//FIXME: We should support
302 			//labels in the middle of
303 			//these, but we don't.
304 			uint8_t val;
305 			if (!input.consume_hex_byte(val))
306 			{
307 				input.parse_error("Expected hex bytes in array of bytes");
308 				valid = false;
309 				return;
310 			}
311 			v.byte_data.push_back(val);
312 			input.next_token();
313 		}
314 	}
315 	values.push_back(v);
316 }
317 
318 void
319 property::parse_reference(input_buffer &input)
320 {
321 	assert(input[0] == '&');
322 	++input;
323 	input.next_token();
324 	property_value v;
325 	v.string_data = string::parse_node_name(input);
326 	if (v.string_data.empty())
327 	{
328 		input.parse_error("Expected node name");
329 		valid = false;
330 		return;
331 	}
332 	v.type = property_value::CROSS_REFERENCE;
333 	values.push_back(v);
334 }
335 
336 property::property(input_buffer &structs, input_buffer &strings)
337 {
338 	uint32_t name_offset;
339 	uint32_t length;
340 	valid = structs.consume_binary(length) &&
341 		structs.consume_binary(name_offset);
342 	if (!valid)
343 	{
344 		fprintf(stderr, "Failed to read property\n");
345 		return;
346 	}
347 	// Find the name
348 	input_buffer name_buffer = strings.buffer_from_offset(name_offset);
349 	if (name_buffer.empty())
350 	{
351 		fprintf(stderr, "Property name offset %" PRIu32
352 			" is past the end of the strings table\n",
353 			name_offset);
354 		valid = false;
355 		return;
356 	}
357 	key = string(name_buffer);
358 	// Read the value
359 	uint8_t byte;
360 	property_value v;
361 	for (uint32_t i=0 ; i<length ; i++)
362 	{
363 		if (!(valid = structs.consume_binary(byte)))
364 		{
365 			fprintf(stderr, "Failed to read property value\n");
366 			return;
367 		}
368 		v.byte_data.push_back(byte);
369 	}
370 	values.push_back(v);
371 }
372 
373 property::property(input_buffer &input, string k, string l) : key(k), label(l),
374 	valid(true)
375 {
376 	do {
377 		input.next_token();
378 		switch (input[0])
379 		{
380 			default:
381 				input.parse_error("Invalid property value.");
382 				valid = false;
383 				return;
384 			case '"':
385 				parse_string(input);
386 				break;
387 			case '<':
388 				parse_cells(input);
389 				break;
390 			case '[':
391 				parse_bytes(input);
392 				break;
393 			case '&':
394 				parse_reference(input);
395 				break;
396 			case ';':
397 			{
398 				break;
399 			}
400 		}
401 		input.next_token();
402 	} while (input.consume(','));
403 	if (!input.consume(';'))
404 	{
405 		input.parse_error("Expected ; at end of property");
406 		valid = false;
407 	}
408 }
409 
410 property*
411 property::parse_dtb(input_buffer &structs, input_buffer &strings)
412 {
413 	property *p = new property(structs, strings);
414 	if (!p->valid)
415 	{
416 		delete p;
417 		p = 0;
418 	}
419 	return p;
420 }
421 
422 property*
423 property::parse(input_buffer &input, string key, string label)
424 {
425 	property *p = new property(input, key, label);
426 	if (!p->valid)
427 	{
428 		delete p;
429 		p = 0;
430 	}
431 	return p;
432 }
433 
434 void
435 property::write(dtb::output_writer &writer, dtb::string_table &strings)
436 {
437 	writer.write_token(dtb::FDT_PROP);
438 	byte_buffer value_buffer;
439 	for (value_iterator i=begin(), e=end() ; i!=e ; ++i)
440 	{
441 		i->push_to_buffer(value_buffer);
442 	}
443 	writer.write_data((uint32_t)value_buffer.size());
444 	writer.write_comment(key);
445 	writer.write_data(strings.add_string(key));
446 	writer.write_data(value_buffer);
447 }
448 
449 void
450 property::write_dts(FILE *file, int indent)
451 {
452 	for (int i=0 ; i<indent ; i++)
453 	{
454 		putc('\t', file);
455 	}
456 	if (label != string())
457 	{
458 		label.print(file);
459 		fputs(": ", file);
460 	}
461 	if (key != string())
462 	{
463 		key.print(file);
464 	}
465 	if (!values.empty())
466 	{
467 		fputs(" = ", file);
468 		for (value_iterator i=begin(), e=end() ; i!=e ; ++i)
469 		{
470 			i->write_dts(file);
471 			if (i+1 != e)
472 			{
473 				putc(',', file);
474 				putc(' ', file);
475 			}
476 		}
477 	}
478 	fputs(";\n", file);
479 }
480 
481 string
482 node::parse_name(input_buffer &input, bool &is_property, const char *error)
483 {
484 	if (!valid)
485 	{
486 		return string();
487 	}
488 	input.next_token();
489 	if (is_property)
490 	{
491 		return string::parse_property_name(input);
492 	}
493 	string n = string::parse_node_or_property_name(input, is_property);
494 	if (n.empty())
495 	{
496 		if (n.empty())
497 		{
498 			input.parse_error(error);
499 			valid = false;
500 		}
501 	}
502 	return n;
503 }
504 
505 node::node(input_buffer &structs, input_buffer &strings) : valid(true)
506 {
507 	const char *name_start = (const char*)structs;
508 	int name_length = 0;
509 	while (structs[0] != '\0' && structs[0] != '@')
510 	{
511 		name_length++;
512 		++structs;
513 	}
514 	name = string(name_start, name_length);
515 	if (structs[0] == '@')
516 	{
517 		++structs;
518 		name_start = (const char*)structs;
519 		name_length = 0;
520 		while (structs[0] != '\0')
521 		{
522 			name_length++;
523 			++structs;
524 		}
525 		unit_address = string(name_start, name_length);
526 	}
527 	++structs;
528 	uint32_t token;
529 	while (structs.consume_binary(token))
530 	{
531 		switch (token)
532 		{
533 			default:
534 				fprintf(stderr, "Unexpected token 0x%" PRIx32
535 					" while parsing node.\n", token);
536 				valid = false;
537 				return;
538 			// Child node, parse it.
539 			case dtb::FDT_BEGIN_NODE:
540 			{
541 				node *child = node::parse_dtb(structs, strings);
542 				if (child == 0)
543 				{
544 					valid = false;
545 					return;
546 				}
547 				children.push_back(child);
548 				break;
549 			}
550 			// End of this node, no errors.
551 			case dtb::FDT_END_NODE:
552 				return;
553 			// Property, parse it.
554 			case dtb::FDT_PROP:
555 			{
556 				property *prop = property::parse_dtb(structs, strings);
557 				if (prop == 0)
558 				{
559 					valid = false;
560 					return;
561 				}
562 				properties.push_back(prop);
563 				break;
564 			}
565 				break;
566 			// End of structs table.  Should appear after
567 			// the end of the last node.
568 			case dtb::FDT_END:
569 				fprintf(stderr, "Unexpected FDT_END token while parsing node.\n");
570 				valid = false;
571 				return;
572 			// NOPs are padding.  Ignore them.
573 			case dtb::FDT_NOP:
574 				break;
575 		}
576 	}
577 	fprintf(stderr, "Failed to read token from structs table while parsing node.\n");
578 	valid = false;
579 	return;
580 }
581 
582 node::node(input_buffer &input, string n, string l, string a) :
583 	label(l), name(n), unit_address(a), valid(true)
584 {
585 	if (!input.consume('{'))
586 	{
587 		input.parse_error("Expected { to start new device tree node.\n");
588 	}
589 	input.next_token();
590 	while (valid && !input.consume('}'))
591 	{
592 		// flag set if we find any characters that are only in
593 		// the property name character set, not the node
594 		bool is_property = false;
595 		string child_name, child_label, child_address;
596 		child_name = parse_name(input, is_property,
597 				"Expected property or node name");
598 		if (input.consume(':'))
599 		{
600 			// Node labels can contain any characters?  The
601 			// spec doesn't say, so we guess so...
602 			is_property = false;
603 			child_label = child_name;
604 			child_name = parse_name(input, is_property, "Expected property or node name");
605 		}
606 		if (input.consume('@'))
607 		{
608 			child_address = parse_name(input, is_property, "Expected unit address");
609 		}
610 		if (!valid)
611 		{
612 			return;
613 		}
614 		input.next_token();
615 		// If we're parsing a property, then we must actually do that.
616 		if (input.consume('='))
617 		{
618 			property *p= property::parse(input, child_name,
619 					child_label);
620 			if (p == 0)
621 			{
622 				valid = false;
623 			}
624 			else
625 			{
626 				properties.push_back(p);
627 			}
628 		}
629 		else if (!is_property && input[0] == ('{'))
630 		{
631 			node *child = node::parse(input, child_name,
632 					child_label, child_address);
633 			if (child)
634 			{
635 				children.push_back(child);
636 			}
637 			else
638 			{
639 				valid = false;
640 			}
641 		}
642 		else if (input.consume(';'))
643 		{
644 			properties.push_back(new property(child_name, child_label));
645 		}
646 		else
647 		{
648 			input.parse_error("Error parsing property.");
649 			valid = false;
650 		}
651 		input.next_token();
652 	}
653 	input.consume(';');
654 }
655 
656 bool
657 node::cmp_properties(property *p1, property *p2)
658 {
659 	return p1->get_key() < p2->get_key();
660 }
661 
662 bool
663 node::cmp_children(node *c1, node *c2)
664 {
665 	if (c1->name == c2->name)
666 	{
667 		return c1->unit_address < c2->unit_address;
668 	}
669 	return c1->name < c2->name;
670 }
671 
672 void
673 node::sort()
674 {
675 	std::sort(property_begin(), property_end(), cmp_properties);
676 	std::sort(child_begin(), child_end(), cmp_children);
677 	for (child_iterator i=child_begin(), e=child_end() ; i!=e ; ++i)
678 	{
679 		(*i)->sort();
680 	}
681 }
682 
683 node*
684 node::parse(input_buffer &input, string name, string label, string address)
685 {
686 	node *n = new node(input, name, label, address);
687 	if (!n->valid)
688 	{
689 		delete n;
690 		n = 0;
691 	}
692 	return n;
693 }
694 
695 node*
696 node::parse_dtb(input_buffer &structs, input_buffer &strings)
697 {
698 	node *n = new node(structs, strings);
699 	if (!n->valid)
700 	{
701 		delete n;
702 		n = 0;
703 	}
704 	return n;
705 }
706 
707 node::~node()
708 {
709 	while (!children.empty())
710 	{
711 		delete children.back();
712 		children.pop_back();
713 	}
714 	while (!properties.empty())
715 	{
716 		delete properties.back();
717 		properties.pop_back();
718 	}
719 }
720 
721 property*
722 node::get_property(string key)
723 {
724 	for (property_iterator i=property_begin(), e=property_end() ; i!=e ; ++i)
725 	{
726 		if ((*i)->get_key() == key)
727 		{
728 			return *i;
729 		}
730 	}
731 	return 0;
732 }
733 
734 void
735 node::merge_node(node *other)
736 {
737 	if (!other->label.empty())
738 	{
739 		label = other->label;
740 	}
741 	// Note: this is an O(n*m) operation.  It might be sensible to
742 	// optimise this if we find that there are nodes with very
743 	// large numbers of properties, but for typical usage the
744 	// entire vector will fit (easily) into cache, so iterating
745 	// over it repeatedly isn't that expensive.
746 	while (!other->properties.empty())
747 	{
748 		property *p = other->properties.front();
749 		for (property_iterator i=property_begin(), e=property_end() ; i!=e ; ++i)
750 		{
751 			if ((*i)->get_key() == p->get_key())
752 			{
753 				delete *i;
754 				properties.erase(i);
755 				break;
756 			}
757 		}
758 		add_property(p);
759 		other->properties.erase(other->properties.begin());
760 	}
761 	while (!other->children.empty())
762 	{
763 		node *c = other->children.front();
764 		bool found = false;
765 		for (child_iterator i=child_begin(), e=child_end() ; i!=e ; ++i)
766 		{
767 			if ((*i)->name == c->name && (*i)->unit_address == c->unit_address)
768 			{
769 				(*i)->merge_node(c);
770 				delete c;
771 				found = true;
772 				break;
773 			}
774 		}
775 		if (!found)
776 		{
777 			children.push_back(c);
778 		}
779 		other->children.erase(other->children.begin());
780 	}
781 }
782 
783 void
784 node::write(dtb::output_writer &writer, dtb::string_table &strings)
785 {
786 	writer.write_token(dtb::FDT_BEGIN_NODE);
787 	byte_buffer name_buffer;
788 	name.push_to_buffer(name_buffer);
789 	if (unit_address != string())
790 	{
791 		name_buffer.push_back('@');
792 		unit_address.push_to_buffer(name_buffer);
793 	}
794 	writer.write_comment(name);
795 	writer.write_data(name_buffer);
796 	writer.write_data((uint8_t)0);
797 	for (property_iterator i=property_begin(), e=property_end() ; i!=e ; ++i)
798 	{
799 		(*i)->write(writer, strings);
800 	}
801 	for (child_iterator i=child_begin(), e=child_end() ; i!=e ; ++i)
802 	{
803 		(*i)->write(writer, strings);
804 	}
805 	writer.write_token(dtb::FDT_END_NODE);
806 }
807 
808 void
809 node::write_dts(FILE *file, int indent)
810 {
811 	for (int i=0 ; i<indent ; i++)
812 	{
813 		putc('\t', file);
814 	}
815 	if (label != string())
816 	{
817 		label.print(file);
818 		fputs(": ", file);
819 	}
820 	if (name != string())
821 	{
822 		name.print(file);
823 	}
824 	if (unit_address != string())
825 	{
826 		putc('@', file);
827 		unit_address.print(file);
828 	}
829 	fputs(" {\n\n", file);
830 	for (property_iterator i=property_begin(), e=property_end() ; i!=e ; ++i)
831 	{
832 		(*i)->write_dts(file, indent+1);
833 	}
834 	for (child_iterator i=child_begin(), e=child_end() ; i!=e ; ++i)
835 	{
836 		(*i)->write_dts(file, indent+1);
837 	}
838 	for (int i=0 ; i<indent ; i++)
839 	{
840 		putc('\t', file);
841 	}
842 	fputs("};\n", file);
843 }
844 
845 void
846 device_tree::collect_names_recursive(node* n, node_path &path)
847 {
848 	string name = n->label;
849 	path.push_back(std::make_pair(n->name, n->unit_address));
850 	if (name != string())
851 	{
852 		if (node_names.find(name) == node_names.end())
853 		{
854 			node_names.insert(std::make_pair(name, n));
855 			node_paths.insert(std::make_pair(name, path));
856 		}
857 		else
858 		{
859 			node_names[name] = (node*)-1;
860 			std::map<string, node_path>::iterator i = node_paths.find(name);
861 			if (i != node_paths.end())
862 			{
863 				node_paths.erase(name);
864 			}
865 			fprintf(stderr, "Label not unique: ");
866 			name.dump();
867 			fprintf(stderr, ".  References to this label will not be resolved.");
868 		}
869 	}
870 	for (node::child_iterator i=n->child_begin(), e=n->child_end() ; i!=e ; ++i)
871 	{
872 		collect_names_recursive(*i, path);
873 	}
874 	path.pop_back();
875 	// Now we collect the phandles and properties that reference
876 	// other nodes.
877 	for (node::property_iterator i=n->property_begin(), e=n->property_end() ; i!=e ; ++i)
878 	{
879 		for (property::value_iterator p=(*i)->begin(),pe=(*i)->end() ; p!=pe ; ++p)
880 		{
881 			if (p->is_phandle())
882 			{
883 				phandles.push_back(&*p);
884 			}
885 			if (p->is_cross_reference())
886 			{
887 				cross_references.push_back(&*p);
888 			}
889 		}
890 		if ((*i)->get_key() == string("phandle") ||
891 		    (*i)->get_key() == string("linux,phandle"))
892 		{
893 			if ((*i)->begin()->byte_data.size() != 4)
894 			{
895 				fprintf(stderr, "Invalid phandle value for node ");
896 				n->name.dump();
897 				fprintf(stderr, ".  Should be a 4-byte value.\n");
898 				valid = false;
899 			}
900 			else
901 			{
902 				uint32_t phandle = (*i)->begin()->get_as_uint32();
903 				used_phandles.insert(std::make_pair(phandle, n));
904 			}
905 		}
906 	}
907 }
908 
909 void
910 device_tree::collect_names()
911 {
912 	node_path p;
913 	collect_names_recursive(root, p);
914 }
915 
916 void
917 device_tree::resolve_cross_references()
918 {
919 	for (std::vector<property_value*>::iterator i=cross_references.begin(), e=cross_references.end() ; i!=e ; ++i)
920 	{
921 		property_value* pv = *i;
922 		node_path path = node_paths[pv->string_data];
923 		// Skip the first name in the path.  It's always "", and implicitly /
924 		for (node_path::iterator p=path.begin()+1, pe=path.end() ; p!=pe ; ++p)
925 		{
926 			pv->byte_data.push_back('/');
927 			p->first.push_to_buffer(pv->byte_data);
928 			if (!(p->second.empty()))
929 			{
930 				pv->byte_data.push_back('@');
931 				p->second.push_to_buffer(pv->byte_data);
932 			}
933 		}
934 		pv->byte_data.push_back(0);
935 	}
936 	uint32_t phandle = 1;
937 	for (std::vector<property_value*>::iterator i=phandles.begin(), e=phandles.end() ; i!=e ; ++i)
938 	{
939 		string target_name = (*i)->string_data;
940 		node *target = node_names[target_name];
941 		if (target == 0)
942 		{
943 			fprintf(stderr, "Failed to find node with label:");
944 			target_name.dump();
945 			fprintf(stderr, "\n");
946 			valid = 0;
947 			return;
948 		}
949 		// If there is an existing phandle, use it
950 		property *p = target->get_property("phandle");
951 		if (p == 0)
952 		{
953 			p = target->get_property("linux,phandle");
954 		}
955 		if (p == 0)
956 		{
957 			// Otherwise insert a new phandle node
958 			property_value v;
959 			while (used_phandles.find(phandle) != used_phandles.end())
960 			{
961 				// Note that we only don't need to
962 				// store this phandle in the set,
963 				// because we are monotonically
964 				// increasing the value of phandle and
965 				// so will only ever revisit this value
966 				// if we have used 2^32 phandles, at
967 				// which point our blob won't fit in
968 				// any 32-bit system and we've done
969 				// something badly wrong elsewhere
970 				// already.
971 				phandle++;
972 			}
973 			push_big_endian(v.byte_data, phandle++);
974 			if (phandle_node_name == BOTH || phandle_node_name == LINUX)
975 			{
976 				p = new property(string("linux,phandle"));
977 				p->add_value(v);
978 				target->add_property(p);
979 			}
980 			if (phandle_node_name == BOTH || phandle_node_name == EPAPR)
981 			{
982 				p = new property(string("phandle"));
983 				p->add_value(v);
984 				target->add_property(p);
985 			}
986 		}
987 		p->begin()->push_to_buffer((*i)->byte_data);
988 		assert((*i)->byte_data.size() == 4);
989 	}
990 }
991 
992 void
993 device_tree::parse_roots(input_buffer &input, std::vector<node*> &roots)
994 {
995 	input.next_token();
996 	while (valid && input.consume('/'))
997 	{
998 		input.next_token();
999 		node *n = node::parse(input, string("", 1));
1000 		if (n)
1001 		{
1002 			roots.push_back(n);
1003 		}
1004 		else
1005 		{
1006 			valid = false;
1007 		}
1008 	}
1009 }
1010 
1011 input_buffer*
1012 device_tree::buffer_for_file(const char *path)
1013 {
1014 	if (string(path) == string("-"))
1015 	{
1016 		input_buffer *b = new stream_input_buffer();
1017 		buffers.push_back(b);
1018 		return b;
1019 	}
1020 	int source = open(path, O_RDONLY);
1021 	if (source == -1)
1022 	{
1023 		fprintf(stderr, "Unable to open file %s\n", path);
1024 		return 0;
1025 	}
1026 	input_buffer *b = new mmap_input_buffer(source);
1027 	// Keep the buffer that owns the memory around for the lifetime
1028 	// of this FDT.  Ones simply referring to it may have shorter
1029 	// lifetimes.
1030 	buffers.push_back(b);
1031 	close(source);
1032 	return b;
1033 }
1034 
1035 template<class writer> void
1036 device_tree::write(int fd)
1037 {
1038 	dtb::string_table st;
1039 	dtb::header head;
1040 	writer head_writer;
1041 	writer reservation_writer;
1042 	writer struct_writer;
1043 	writer strings_writer;
1044 
1045 	// Build the reservation table
1046 	reservation_writer.write_comment(string("Memory reservations"));
1047 	reservation_writer.write_label(string("dt_reserve_map"));
1048 	for (std::vector<reservation>::iterator i=reservations.begin(),
1049 	     e=reservations.end() ; i!=e ; ++i)
1050 	{
1051 		reservation_writer.write_comment(string("Reservation start"));
1052 		reservation_writer.write_data(i->first);
1053 		reservation_writer.write_comment(string("Reservation length"));
1054 		reservation_writer.write_data(i->first);
1055 	}
1056 	// Write n spare reserve map entries, plus the trailing 0.
1057 	for (uint32_t i=0 ; i<=spare_reserve_map_entries ; i++)
1058 	{
1059 		reservation_writer.write_data((uint64_t)0);
1060 		reservation_writer.write_data((uint64_t)0);
1061 	}
1062 
1063 
1064 	struct_writer.write_comment(string("Device tree"));
1065 	struct_writer.write_label(string("dt_struct_start"));
1066 	root->write(struct_writer, st);
1067 	struct_writer.write_token(dtb::FDT_END);
1068 	struct_writer.write_label(string("dt_struct_end"));
1069 
1070 	st.write(strings_writer);
1071 	// Find the strings size before we stick padding on the end.
1072 	// Note: We should possibly use a new writer for the padding.
1073 	head.size_dt_strings = strings_writer.size();
1074 
1075 	// Stick the padding in the strings writer, but after the
1076 	// marker indicating that it's the end.
1077 	// Note: We probably should add a padding call to the writer so
1078 	// that the asm back end can write padding directives instead
1079 	// of a load of 0 bytes.
1080 	for (uint32_t i=0 ; i<blob_padding ; i++)
1081 	{
1082 		strings_writer.write_data((uint8_t)0);
1083 	}
1084 	head.totalsize = sizeof(head) + strings_writer.size() +
1085 		struct_writer.size() + reservation_writer.size();
1086 	while (head.totalsize < minimum_blob_size)
1087 	{
1088 		head.totalsize++;
1089 		strings_writer.write_data((uint8_t)0);
1090 	}
1091 	head.off_dt_struct = sizeof(head) + reservation_writer.size();;
1092 	head.off_dt_strings = head.off_dt_struct + struct_writer.size();
1093 	head.off_mem_rsvmap = sizeof(head);
1094 	head.boot_cpuid_phys = boot_cpu;
1095 	head.size_dt_struct = struct_writer.size();
1096 	head.write(head_writer);
1097 
1098 	head_writer.write_to_file(fd);
1099 	reservation_writer.write_to_file(fd);
1100 	struct_writer.write_to_file(fd);
1101 	strings_writer.write_label(string("dt_blob_end"));
1102 	strings_writer.write_to_file(fd);
1103 }
1104 
1105 node*
1106 device_tree::referenced_node(property_value &v)
1107 {
1108 	if (v.is_phandle())
1109 	{
1110 		return node_names[v.string_data];
1111 	}
1112 	if (v.is_binary())
1113 	{
1114 		return used_phandles[v.get_as_uint32()];
1115 	}
1116 	return 0;
1117 }
1118 
1119 void
1120 device_tree::write_binary(int fd)
1121 {
1122 	write<dtb::binary_writer>(fd);
1123 }
1124 
1125 void
1126 device_tree::write_asm(int fd)
1127 {
1128 	write<dtb::asm_writer>(fd);
1129 }
1130 
1131 void
1132 device_tree::write_dts(int fd)
1133 {
1134 	FILE *file = fdopen(fd, "w");
1135 	fputs("/dtc-v1/;\n\n", file);
1136 
1137 	if (!reservations.empty())
1138 	{
1139 		const char msg[] = "/memreserve/";
1140 		fwrite(msg, sizeof(msg), 1, file);
1141 		for (std::vector<reservation>::iterator i=reservations.begin(),
1142 		     e=reservations.end() ; i!=e ; ++i)
1143 		{
1144 			fprintf(stderr, " %" PRIx64 " %" PRIx64, i->first, i->second);
1145 		}
1146 		fputs(";\n\n", file);
1147 	}
1148 	putc('/', file);
1149 	putc(' ', file);
1150 	root->write_dts(file, 0);
1151 	fclose(file);
1152 }
1153 
1154 void
1155 device_tree::parse_dtb(const char *fn, FILE *depfile)
1156 {
1157 	input_buffer *in = buffer_for_file(fn);
1158 	if (in == 0)
1159 	{
1160 		valid = false;
1161 		return;
1162 	}
1163 	input_buffer &input = *in;
1164 	dtb::header h;
1165 	valid = h.read_dtb(input);
1166 	boot_cpu = h.boot_cpuid_phys;
1167 	if (h.last_comp_version > 17)
1168 	{
1169 		fprintf(stderr, "Don't know how to read this version of the device tree blob");
1170 		valid = false;
1171 	}
1172 	if (!valid)
1173 	{
1174 		return;
1175 	}
1176 	input_buffer reservation_map =
1177 		input.buffer_from_offset(h.off_mem_rsvmap, 0);
1178 	uint64_t start, length;
1179 	do
1180 	{
1181 		if (!(reservation_map.consume_binary(start) &&
1182 		      reservation_map.consume_binary(length)))
1183 		{
1184 			fprintf(stderr, "Failed to read memory reservation table\n");
1185 			valid = false;
1186 			return;
1187 		}
1188 	} while (!((start == 0) && (length == 0)));
1189 	input_buffer struct_table =
1190 		input.buffer_from_offset(h.off_dt_struct, h.size_dt_struct);
1191 	input_buffer strings_table =
1192 		input.buffer_from_offset(h.off_dt_strings, h.size_dt_strings);
1193 	uint32_t token;
1194 	if (!(struct_table.consume_binary(token) &&
1195 		(token == dtb::FDT_BEGIN_NODE)))
1196 	{
1197 		fprintf(stderr, "Expected FDT_BEGIN_NODE token.\n");
1198 		valid = false;
1199 		return;
1200 	}
1201 	root = node::parse_dtb(struct_table, strings_table);
1202 	if (!(struct_table.consume_binary(token) && (token == dtb::FDT_END)))
1203 	{
1204 		fprintf(stderr, "Expected FDT_END token after parsing root node.\n");
1205 		valid = false;
1206 		return;
1207 	}
1208 	valid = (root != 0);
1209 }
1210 
1211 void
1212 device_tree::parse_dts(const char *fn, FILE *depfile)
1213 {
1214 	input_buffer *in = buffer_for_file(fn);
1215 	if (in == 0)
1216 	{
1217 		valid = false;
1218 		return;
1219 	}
1220 	std::vector<node*> roots;
1221 	input_buffer &input = *in;
1222 	input.next_token();
1223 	bool read_header = false;
1224 	// Read the header
1225 	if (input.consume("/dts-v1/;"))
1226 	{
1227 		read_header = true;
1228 	}
1229 	input.next_token();
1230 	while(input.consume("/include/"))
1231 	{
1232 		input.next_token();
1233 		if (!input.consume('"'))
1234 		{
1235 			input.parse_error("Expected quoted filename");
1236 			valid = false;
1237 			return;
1238 		}
1239 		int length = 0;
1240 		while (input[length] != '"') length++;
1241 
1242 		const char *file = (const char*)input;
1243 		const char *dir = dirname(fn);
1244 		int dir_length = strlen(dir);
1245 		char *include_file = (char*)malloc(strlen(dir) + length + 2);
1246 		memcpy(include_file, dir, dir_length);
1247 		include_file[dir_length] = '/';
1248 		memcpy(include_file+dir_length+1, file, length);
1249 		include_file[dir_length+length+1] = 0;
1250 		input_buffer *include_buffer = buffer_for_file(include_file);
1251 
1252 		if (include_buffer == 0)
1253 		{
1254 			for (std::vector<const char*>::iterator i=include_paths.begin(), e=include_paths.end() ; e!=i ; ++i)
1255 			{
1256 				free(include_file);
1257 				dir = *i;
1258 				dir_length = strlen(dir);
1259 				include_file = (char*)malloc(strlen(dir) +
1260 						length + 2);
1261 				memcpy(include_file, dir, dir_length);
1262 				include_file[dir_length] = '/';
1263 				memcpy(include_file+dir_length+1, file, length);
1264 				include_file[dir_length+length+1] = 0;
1265 				include_buffer = buffer_for_file(include_file);
1266 				if (include_buffer != 0)
1267 				{
1268 					break;
1269 				}
1270 			}
1271 		}
1272 		if (depfile != 0)
1273 		{
1274 			putc(' ', depfile);
1275 			fputs(include_file, depfile);
1276 		}
1277 		if (include_buffer == 0)
1278 		{
1279 			valid = false;
1280 			return;
1281 		}
1282 		input_buffer &include = *include_buffer;
1283 		input.consume(include_file+dir_length+1);
1284 		input.consume('"');
1285 		free((void*)include_file);
1286 
1287 		if (!read_header)
1288 		{
1289 			include.next_token();
1290 			read_header = include.consume("/dts-v1/;");
1291 		}
1292 		parse_roots(include, roots);
1293 	}
1294 	input.next_token();
1295 	if (!read_header)
1296 	{
1297 		input.parse_error("Expected /dts-v1/; version string");
1298 	}
1299 	// Read any memory reservations
1300 	while(input.consume("/memreserve/"))
1301 	{
1302 		long long start, len;
1303 		input.next_token();
1304 		// Read the start and length.
1305 		if (!(input.consume_integer(start) &&
1306 		    (input.next_token(),
1307 		    input.consume_integer(len))))
1308 		{
1309 			input.parse_error("Expected /dts-v1/; version string");
1310 		}
1311 		input.next_token();
1312 		input.consume(';');
1313 		reservations.push_back(reservation(start, len));
1314 	}
1315 	parse_roots(input, roots);
1316 	switch (roots.size())
1317 	{
1318 		case 0:
1319 			valid = false;
1320 			input.parse_error("Failed to find root node /.");
1321 			return;
1322 		case 1:
1323 			root = roots[0];
1324 			break;
1325 		default:
1326 		{
1327 			root = roots[0];
1328 			for (std::vector<node*>::iterator i=roots.begin()+1,
1329 			     e=roots.end() ; i!=e ; ++i)
1330 			{
1331 				root->merge_node(*i);
1332 				delete *i;
1333 			}
1334 			roots.resize(1);
1335 		}
1336 	}
1337 	collect_names();
1338 	resolve_cross_references();
1339 }
1340 
1341 device_tree::~device_tree()
1342 {
1343 	if (root != 0)
1344 	{
1345 		delete root;
1346 	}
1347 	while (!buffers.empty())
1348 	{
1349 		delete buffers.back();
1350 		buffers.pop_back();
1351 	}
1352 }
1353 
1354 } // namespace fdt
1355 
1356 } // namespace dtc
1357 
1358