1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2013 David Chisnall
5 * All rights reserved.
6 *
7 * This software was developed by SRI International and the University of
8 * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
9 * ("CTSRD"), as part of the DARPA CRASH research programme.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * $FreeBSD: stable/11/usr.bin/dtc/fdt.hh 358206 2020-02-21 04:38:59Z kevans $
33 */
34
35#ifndef _FDT_HH_
36#define _FDT_HH_
37#include <algorithm>
38#include <unordered_map>
39#include <unordered_set>
40#include <memory>
41#include <string>
42#include <functional>
43
44#include "util.hh"
45#include "input_buffer.hh"
46
47namespace dtc
48{
49
50namespace dtb
51{
52struct output_writer;
53class string_table;
54}
55
56namespace fdt
57{
58class property;
59class node;
60class device_tree;
61/**
62 * Type for device tree write functions.
63 */
64typedef void (device_tree::* tree_write_fn_ptr)(int);
65/**
66 * Type for device tree read functions.
67 */
68typedef void (device_tree::* tree_read_fn_ptr)(const std::string &, FILE *);
69/**
70 * Type for (owned) pointers to properties.
71 */
72typedef std::shared_ptr<property> property_ptr;
73/**
74 * Owning pointer to a node.
75 */
76typedef std::unique_ptr<node> node_ptr;
77/**
78 * Map from macros to property pointers.
79 */
80typedef std::unordered_map<std::string, property_ptr> define_map;
81/**
82 * Set of strings used for label names.
83 */
84typedef std::unordered_set<std::string> string_set;
85/**
86 * Properties may contain a number of different value, each with a different
87 * label.  This class encapsulates a single value.
88 */
89struct property_value
90{
91	/**
92	 * The label for this data.  This is usually empty.
93	 */
94	std::string label;
95	/**
96	 * If this value is a string, or something resolved from a string (a
97	 * reference) then this contains the source string.
98	 */
99	std::string string_data;
100	/**
101	 * The data that should be written to the final output.
102	 */
103	byte_buffer byte_data;
104	/**
105	 * Enumeration describing the possible types of a value.  Note that
106	 * property-coded arrays will appear simply as binary (or possibly
107	 * string, if they happen to be nul-terminated and printable), and must
108	 * be checked separately.
109	 */
110	enum value_type
111	{
112		/**
113		 * This is a list of strings.  When read from source, string
114		 * lists become one property value for each string, however
115		 * when read from binary we have a single property value
116		 * incorporating the entire text, with nul bytes separating the
117		 * strings.
118		 */
119		STRING_LIST,
120		/**
121		 * This property contains a single string.
122		 */
123		STRING,
124		/**
125		 * This is a binary value.  Check the size of byte_data to
126		 * determine how many bytes this contains.
127		 */
128		BINARY,
129		/** This contains a short-form address that should be replaced
130		 * by a fully-qualified version.  This will only appear when
131		 * the input is a device tree source.  When parsed from a
132		 * device tree blob, the cross reference will have already been
133		 * resolved and the property value will be a string containing
134		 * the full path of the target node.  */
135		CROSS_REFERENCE,
136		/**
137		 * This is a phandle reference.  When parsed from source, the
138		 * string_data will contain the node label for the target and,
139		 * after cross references have been resolved, the binary data
140		 * will contain a 32-bit integer that should match the phandle
141		 * property of the target node.
142		 */
143		PHANDLE,
144		/**
145		 * An empty property value.  This will never appear on a real
146		 * property value, it is used by checkers to indicate that no
147		 * property values should exist for a property.
148		 */
149		EMPTY,
150		/**
151		 * The type of this property has not yet been determined.
152		 */
153		UNKNOWN
154	};
155	/**
156	 * The type of this property.
157	 */
158	value_type type;
159	/**
160	 * Returns true if this value is a cross reference, false otherwise.
161	 */
162	inline bool is_cross_reference()
163	{
164		return is_type(CROSS_REFERENCE);
165	}
166	/**
167	 * Returns true if this value is a phandle reference, false otherwise.
168	 */
169	inline bool is_phandle()
170	{
171		return is_type(PHANDLE);
172	}
173	/**
174	 * Returns true if this value is a string, false otherwise.
175	 */
176	inline bool is_string()
177	{
178		return is_type(STRING);
179	}
180	/**
181	 * Returns true if this value is a string list (a nul-separated
182	 * sequence of strings), false otherwise.
183	 */
184	inline bool is_string_list()
185	{
186		return is_type(STRING_LIST);
187	}
188	/**
189	 * Returns true if this value is binary, false otherwise.
190	 */
191	inline bool is_binary()
192	{
193		return is_type(BINARY);
194	}
195	/**
196	 * Returns this property value as a 32-bit integer.  Returns 0 if this
197	 * property value is not 32 bits long.  The bytes in the property value
198	 * are assumed to be in big-endian format, but the return value is in
199	 * the host native endian.
200	 */
201	uint32_t get_as_uint32();
202	/**
203	 * Default constructor, specifying the label of the value.
204	 */
205	property_value(std::string l=std::string()) : label(l), type(UNKNOWN) {}
206	/**
207	 * Writes the data for this value into an output buffer.
208	 */
209	void push_to_buffer(byte_buffer &buffer);
210
211	/**
212	 * Writes the property value to the standard output.  This uses the
213	 * following heuristics for deciding how to print the output:
214	 *
215	 * - If the value is nul-terminated and only contains printable
216	 *   characters, it is written as a string.
217	 * - If it is a multiple of 4 bytes long, then it is printed as cells.
218	 * - Otherwise, it is printed as a byte buffer.
219	 */
220	void write_dts(FILE *file);
221	/**
222	 * Tries to merge adjacent property values, returns true if it succeeds and
223	 * false otherwise.
224	 */
225	bool try_to_merge(property_value &other);
226	/**
227	 * Returns the size (in bytes) of this property value.
228	 */
229	size_t size();
230	private:
231	/**
232	 * Returns whether the value is of the specified type.  If the type of
233	 * the value has not yet been determined, then this calculates it.
234	 */
235	inline bool is_type(value_type v)
236	{
237		if (type == UNKNOWN)
238		{
239			resolve_type();
240		}
241		return type == v;
242	}
243	/**
244	 * Determines the type of the value based on its contents.
245	 */
246	void resolve_type();
247	/**
248	 * Writes the property value to the specified file as a quoted string.
249	 * This is used when generating DTS.
250	 */
251	void write_as_string(FILE *file);
252	/**
253	 * Writes the property value to the specified file as a sequence of
254	 * 32-bit big-endian cells.  This is used when generating DTS.
255	 */
256	void write_as_cells(FILE *file);
257	/**
258	 * Writes the property value to the specified file as a sequence of
259	 * bytes.  This is used when generating DTS.
260	 */
261	void write_as_bytes(FILE *file);
262};
263
264/**
265 * A value encapsulating a single property.  This contains a key, optionally a
266 * label, and optionally one or more values.
267 */
268class property
269{
270	/**
271	 * The name of this property.
272	 */
273	std::string key;
274	/**
275	 * Zero or more labels.
276	 */
277	string_set labels;
278	/**
279	 * The values in this property.
280	 */
281	std::vector<property_value> values;
282	/**
283	 * Value indicating that this is a valid property.  If a parse error
284	 * occurs, then this value is false.
285	 */
286	bool valid;
287	/**
288	 * Parses a string property value, i.e. a value enclosed in double quotes.
289	 */
290	void parse_string(text_input_buffer &input);
291	/**
292	 * Parses one or more 32-bit values enclosed in angle brackets.
293	 */
294	void parse_cells(text_input_buffer &input, int cell_size);
295	/**
296	 * Parses an array of bytes, contained within square brackets.
297	 */
298	void parse_bytes(text_input_buffer &input);
299	/**
300	 * Parses a reference.  This is a node label preceded by an ampersand
301	 * symbol, which should expand to the full path to that node.
302	 *
303	 * Note: The specification says that the target of such a reference is
304	 * a node name, however dtc assumes that it is a label, and so we
305	 * follow their interpretation for compatibility.
306	 */
307	void parse_reference(text_input_buffer &input);
308	/**
309	 * Parse a predefined macro definition for a property.
310	 */
311	void parse_define(text_input_buffer &input, define_map *defines);
312	/**
313	 * Constructs a new property from two input buffers, pointing to the
314	 * struct and strings tables in the device tree blob, respectively.
315	 * The structs input buffer is assumed to have just consumed the
316	 * FDT_PROP token.
317	 */
318	property(input_buffer &structs, input_buffer &strings);
319	/**
320	 * Parses a new property from the input buffer.
321	 */
322	property(text_input_buffer &input,
323	         std::string &&k,
324	         string_set &&l,
325	         bool terminated,
326	         define_map *defines);
327	public:
328	/**
329	 * Creates an empty property.
330	 */
331	property(std::string &&k, string_set &&l=string_set())
332		: key(k), labels(l), valid(true) {}
333	/**
334	 * Copy constructor.
335	 */
336	property(property &p) : key(p.key), labels(p.labels), values(p.values),
337		valid(p.valid) {}
338	/**
339	 * Factory method for constructing a new property.  Attempts to parse a
340	 * property from the input, and returns it on success.  On any parse
341	 * error, this will return 0.
342	 */
343	static property_ptr parse_dtb(input_buffer &structs,
344	                              input_buffer &strings);
345	/**
346	 * Factory method for constructing a new property.  Attempts to parse a
347	 * property from the input, and returns it on success.  On any parse
348	 * error, this will return 0.
349	 */
350	static property_ptr parse(text_input_buffer &input,
351	                          std::string &&key,
352	                          string_set &&labels=string_set(),
353	                          bool semicolonTerminated=true,
354	                          define_map *defines=0);
355	/**
356	 * Iterator type used for accessing the values of a property.
357	 */
358	typedef std::vector<property_value>::iterator value_iterator;
359	/**
360	 * Returns an iterator referring to the first value in this property.
361	 */
362	inline value_iterator begin()
363	{
364		return values.begin();
365	}
366	/**
367	 * Returns an iterator referring to the last value in this property.
368	 */
369	inline value_iterator end()
370	{
371		return values.end();
372	}
373	/**
374	 * Adds a new value to an existing property.
375	 */
376	inline void add_value(property_value v)
377	{
378		values.push_back(v);
379	}
380	/**
381	 * Returns the key for this property.
382	 */
383	inline const std::string &get_key()
384	{
385		return key;
386	}
387	/**
388	 * Writes the property to the specified writer.  The property name is a
389	 * reference into the strings table.
390	 */
391	void write(dtb::output_writer &writer, dtb::string_table &strings);
392	/**
393	 * Writes in DTS format to the specified file, at the given indent
394	 * level.  This will begin the line with the number of tabs specified
395	 * as the indent level and then write the property in the most
396	 * applicable way that it can determine.
397	 */
398	void write_dts(FILE *file, int indent);
399	/**
400	 * Returns the byte offset of the specified property value.
401	 */
402	size_t offset_of_value(property_value &val);
403};
404
405/**
406 * Class encapsulating a device tree node.  Nodes may contain properties and
407 * other nodes.
408 */
409class node
410{
411	public:
412	/**
413	 * The labels for this node, if any.  Node labels are used as the
414	 * targets for cross references.
415	 */
416	std::unordered_set<std::string> labels;
417	/**
418	 * The name of the node.
419	 */
420	std::string name;
421	/**
422	 * The name of the node is a path reference.
423	 */
424	bool name_is_path_reference = false;
425	/**
426	 * The unit address of the node, which is optionally written after the
427	 * name followed by an at symbol.
428	 */
429	std::string unit_address;
430	/**
431	 * A flag indicating that this node has been marked /omit-if-no-ref/ and
432	 * will be omitted if it is not referenced, either directly or indirectly,
433	 * by a node that is not similarly denoted.
434	 */
435	bool omit_if_no_ref = false;
436	/**
437	 * A flag indicating that this node has been referenced, either directly
438	 * or indirectly, by a node that is not marked /omit-if-no-ref/.
439	 */
440	bool used = false;
441	/**
442	 * The type for the property vector.
443	 */
444	typedef std::vector<property_ptr> property_vector;
445	/**
446	 * Iterator type for child nodes.
447	 */
448	typedef std::vector<node_ptr>::iterator child_iterator;
449	/**
450	 * Recursion behavior to be observed for visiting
451	 */
452	enum visit_behavior
453	{
454		/**
455		 * Recurse as normal through the rest of the tree.
456		 */
457		VISIT_RECURSE,
458		/**
459		 * Continue recursing through the device tree, but do not
460		 * recurse through this branch of the tree any further.
461		 */
462		VISIT_CONTINUE,
463		/**
464		 * Immediately halt the visit.  No further nodes will be visited.
465		 */
466		VISIT_BREAK
467	};
468	private:
469	/**
470	 * Adaptor to use children in range-based for loops.
471	 */
472	struct child_range
473	{
474		child_range(node &nd) : n(nd) {}
475		child_iterator begin() { return n.child_begin(); }
476		child_iterator end() { return n.child_end(); }
477		private:
478		node &n;
479	};
480	/**
481	 * Adaptor to use properties in range-based for loops.
482	 */
483	struct property_range
484	{
485		property_range(node &nd) : n(nd) {}
486		property_vector::iterator begin() { return n.property_begin(); }
487		property_vector::iterator end() { return n.property_end(); }
488		private:
489		node &n;
490	};
491	/**
492	 * The properties contained within this node.
493	 */
494	property_vector props;
495	/**
496	 * The children of this node.
497	 */
498	std::vector<node_ptr> children;
499	/**
500	 * Children that should be deleted from this node when merging.
501	 */
502	std::unordered_set<std::string> deleted_children;
503	/**
504	 * Properties that should be deleted from this node when merging.
505	 */
506	std::unordered_set<std::string> deleted_props;
507	/**
508	 * A flag indicating whether this node is valid.  This is set to false
509	 * if an error occurs during parsing.
510	 */
511	bool valid;
512	/**
513	 * Parses a name inside a node, writing the string passed as the last
514	 * argument as an error if it fails.
515	 */
516	std::string parse_name(text_input_buffer &input,
517	                       bool &is_property,
518	                       const char *error);
519	/**
520	 * Constructs a new node from two input buffers, pointing to the struct
521	 * and strings tables in the device tree blob, respectively.
522	 */
523	node(input_buffer &structs, input_buffer &strings);
524	/**
525	 * Parses a new node from the specified input buffer.  This is called
526	 * when the input cursor is on the open brace for the start of the
527	 * node.  The name, and optionally label and unit address, should have
528	 * already been parsed.
529	 */
530	node(text_input_buffer &input,
531	     device_tree &tree,
532	     std::string &&n,
533	     std::unordered_set<std::string> &&l,
534	     std::string &&a,
535	     define_map*);
536	/**
537	 * Creates a special node with the specified name and properties.
538	 */
539	node(const std::string &n, const std::vector<property_ptr> &p);
540	/**
541	 * Comparison function for properties, used when sorting the properties
542	 * vector.  Orders the properties based on their names.
543	 */
544	static inline bool cmp_properties(property_ptr &p1, property_ptr &p2);
545		/*
546	{
547		return p1->get_key() < p2->get_key();
548	}
549	*/
550	/**
551	 * Comparison function for nodes, used when sorting the children
552	 * vector.  Orders the nodes based on their names or, if the names are
553	 * the same, by the unit addresses.
554	 */
555	static inline bool cmp_children(node_ptr &c1, node_ptr &c2);
556	public:
557	/**
558	 * Sorts the node's properties and children into alphabetical order and
559	 * recursively sorts the children.
560	 */
561	void sort();
562	/**
563	 * Returns an iterator for the first child of this node.
564	 */
565	inline child_iterator child_begin()
566	{
567		return children.begin();
568	}
569	/**
570	 * Returns an iterator after the last child of this node.
571	 */
572	inline child_iterator child_end()
573	{
574		return children.end();
575	}
576	/**
577	 * Returns a range suitable for use in a range-based for loop describing
578	 * the children of this node.
579	 */
580	inline child_range child_nodes()
581	{
582		return child_range(*this);
583	}
584	/**
585	 * Accessor for the deleted children.
586	 */
587	inline const std::unordered_set<std::string> &deleted_child_nodes()
588	{
589		return deleted_children;
590	}
591	/**
592	 * Accessor for the deleted properties
593	 */
594	inline const std::unordered_set<std::string> &deleted_properties()
595	{
596		return deleted_props;
597	}
598	/**
599	 * Returns a range suitable for use in a range-based for loop describing
600	 * the properties of this node.
601	 */
602	inline property_range properties()
603	{
604		return property_range(*this);
605	}
606	/**
607	 * Returns an iterator after the last property of this node.
608	 */
609	inline property_vector::iterator property_begin()
610	{
611		return props.begin();
612	}
613	/**
614	 * Returns an iterator for the first property of this node.
615	 */
616	inline property_vector::iterator property_end()
617	{
618		return props.end();
619	}
620	/**
621	 * Factory method for constructing a new node.  Attempts to parse a
622	 * node in DTS format from the input, and returns it on success.  On
623	 * any parse error, this will return 0.  This should be called with the
624	 * cursor on the open brace of the property, after the name and so on
625	 * have been parsed.
626	 */
627	static node_ptr parse(text_input_buffer &input,
628	                      device_tree &tree,
629	                      std::string &&name,
630	                      std::unordered_set<std::string> &&label=std::unordered_set<std::string>(),
631	                      std::string &&address=std::string(),
632	                      define_map *defines=0);
633	/**
634	 * Factory method for constructing a new node.  Attempts to parse a
635	 * node in DTB format from the input, and returns it on success.  On
636	 * any parse error, this will return 0.  This should be called with the
637	 * cursor on the open brace of the property, after the name and so on
638	 * have been parsed.
639	 */
640	static node_ptr parse_dtb(input_buffer &structs, input_buffer &strings);
641	/**
642	 * Construct a new special node from a name and set of properties.
643	 */
644	static node_ptr create_special_node(const std::string &name,
645			const std::vector<property_ptr> &props);
646	/**
647	 * Returns a property corresponding to the specified key, or 0 if this
648	 * node does not contain a property of that name.
649	 */
650	property_ptr get_property(const std::string &key);
651	/**
652	 * Adds a new property to this node.
653	 */
654	inline void add_property(property_ptr &p)
655	{
656		props.push_back(p);
657	}
658	/**
659	 * Adds a new child to this node.
660	 */
661	inline void add_child(node_ptr &&n)
662	{
663		children.push_back(std::move(n));
664	}
665	/**
666	 * Deletes any children from this node.
667	 */
668	inline void delete_children_if(bool (*predicate)(node_ptr &))
669	{
670		children.erase(std::remove_if(children.begin(), children.end(), predicate), children.end());
671	}
672	/**
673	 * Merges a node into this one.  Any properties present in both are
674	 * overridden, any properties present in only one are preserved.
675	 */
676	void merge_node(node_ptr &other);
677	/**
678	 * Write this node to the specified output.  Although nodes do not
679	 * refer to a string table directly, their properties do.  The string
680	 * table passed as the second argument is used for the names of
681	 * properties within this node and its children.
682	 */
683	void write(dtb::output_writer &writer, dtb::string_table &strings);
684	/**
685	 * Writes the current node as DTS to the specified file.  The second
686	 * parameter is the indent level.  This function will start every line
687	 * with this number of tabs.
688	 */
689	void write_dts(FILE *file, int indent);
690	/**
691	 * Recursively visit this node and then its children based on the
692	 * callable's return value.  The callable may return VISIT_BREAK
693	 * immediately halt all recursion and end the visit, VISIT_CONTINUE to
694	 * not recurse into the current node's children, or VISIT_RECURSE to recurse
695	 * through children as expected.  parent will be passed to the callable.
696	 */
697	visit_behavior visit(std::function<visit_behavior(node&, node*)>, node *parent);
698};
699
700/**
701 * Class encapsulating the entire parsed FDT.  This is the top-level class,
702 * which parses the entire DTS representation and write out the finished
703 * version.
704 */
705class device_tree
706{
707	public:
708	/**
709	 * Type used for node paths.  A node path is sequence of names and unit
710	 * addresses.
711	 */
712	class node_path : public std::vector<std::pair<std::string,std::string>>
713	{
714		public:
715		/**
716		 * Converts this to a string representation.
717		 */
718		std::string to_string() const;
719	};
720	/**
721	 * Name that we should use for phandle nodes.
722	 */
723	enum phandle_format
724	{
725		/** linux,phandle */
726		LINUX,
727		/** phandle */
728		EPAPR,
729		/** Create both nodes. */
730		BOTH
731	};
732	private:
733	/**
734	 * The format that we should use for writing phandles.
735	 */
736	phandle_format phandle_node_name = EPAPR;
737	/**
738	 * Flag indicating that this tree is valid.  This will be set to false
739	 * on parse errors.
740	 */
741	bool valid = true;
742	/**
743	 * Flag indicating that this tree requires garbage collection.  This will be
744	 * set to true if a node marked /omit-if-no-ref/ is encountered.
745	 */
746	bool garbage_collect = false;
747	/**
748	 * Type used for memory reservations.  A reservation is two 64-bit
749	 * values indicating a base address and length in memory that the
750	 * kernel should not use.  The high 32 bits are ignored on 32-bit
751	 * platforms.
752	 */
753	typedef std::pair<uint64_t, uint64_t> reservation;
754	/**
755	 * The memory reserves table.
756	 */
757	std::vector<reservation> reservations;
758	/**
759	 * Root node.  All other nodes are children of this node.
760	 */
761	node_ptr root;
762	/**
763	 * Mapping from names to nodes.  Only unambiguous names are recorded,
764	 * duplicate names are stored as (node*)-1.
765	 */
766	std::unordered_map<std::string, node*> node_names;
767	/**
768	 * A map from labels to node paths.  When resolving cross references,
769	 * we look up referenced nodes in this and replace the cross reference
770	 * with the full path to its target.
771	 */
772	std::unordered_map<std::string, node_path> node_paths;
773	/**
774	 * All of the elements in `node_paths` in the order that they were
775	 * created.  This is used for emitting the `__symbols__` section, where
776	 * we want to guarantee stable ordering.
777	 */
778	std::vector<std::pair<std::string, node_path>> ordered_node_paths;
779	/**
780	 * A collection of property values that are references to other nodes.
781	 * These should be expanded to the full path of their targets.
782	 */
783	std::vector<property_value*> cross_references;
784	/**
785	 * The location of something requiring a fixup entry.
786	 */
787	struct fixup
788	{
789		/**
790		 * The path to the node.
791		 */
792		node_path path;
793		/**
794		 * The property containing the reference.
795		 */
796		property_ptr prop;
797		/**
798		 * The property value that contains the reference.
799		 */
800		property_value &val;
801	};
802	/**
803	 * A collection of property values that refer to phandles.  These will
804	 * be replaced by the value of the phandle property in their
805	 * destination.
806	 */
807	std::vector<fixup> fixups;
808	/**
809	 * The locations of all of the values that are supposed to become phandle
810	 * references, but refer to things outside of this file.
811	 */
812	std::vector<std::reference_wrapper<fixup>> unresolved_fixups;
813	/**
814	 * The names of nodes that target phandles.
815	 */
816	std::unordered_set<std::string> phandle_targets;
817	/**
818	 * A collection of input buffers that we are using.  These input
819	 * buffers are the ones that own their memory, and so we must preserve
820	 * them for the lifetime of the device tree.
821	 */
822	std::vector<std::unique_ptr<input_buffer>> buffers;
823	/**
824	 * A map of used phandle values to nodes.  All phandles must be unique,
825	 * so we keep a set of ones that the user explicitly provides in the
826	 * input to ensure that we don't reuse them.
827	 *
828	 * This is a map, rather than a set, because we also want to be able to
829	 * find phandles that were provided by the user explicitly when we are
830	 * doing checking.
831	 */
832	std::unordered_map<uint32_t, node*> used_phandles;
833	/**
834	 * Paths to search for include files.  This contains a set of
835	 * nul-terminated strings, which are not owned by this class and so
836	 * must be freed separately.
837	 */
838	std::vector<std::string> include_paths;
839	/**
840	 * Dictionary of predefined macros provided on the command line.
841	 */
842	define_map               defines;
843	/**
844	 * The default boot CPU, specified in the device tree header.
845	 */
846	uint32_t boot_cpu = 0;
847	/**
848	 * The number of empty reserve map entries to generate in the blob.
849	 */
850	uint32_t spare_reserve_map_entries = 0;
851	/**
852	 * The minimum size in bytes of the blob.
853	 */
854	uint32_t minimum_blob_size = 0;
855	/**
856	 * The number of bytes of padding to add to the end of the blob.
857	 */
858	uint32_t blob_padding = 0;
859	/**
860	 * Is this tree a plugin?
861	 */
862	bool is_plugin = false;
863	/**
864	 * Visit all of the nodes recursively, and if they have labels then add
865	 * them to the node_paths and node_names vectors so that they can be
866	 * used in resolving cross references.  Also collects phandle
867	 * properties that have been explicitly added.
868	 */
869	void collect_names_recursive(node_ptr &n, node_path &path);
870	/**
871	 * Assign a phandle property to a single node.  The next parameter
872	 * holds the phandle to be assigned, and will be incremented upon
873	 * assignment.
874	 */
875	property_ptr assign_phandle(node *n, uint32_t &next);
876	/**
877	 * Assign phandle properties to all nodes that have been referenced and
878	 * require one.  This method will recursively visit the tree starting at
879	 * the node that it is passed.
880	 */
881	void assign_phandles(node_ptr &n, uint32_t &next);
882	/**
883	 * Calls the recursive version of this method on every root node.
884	 */
885	void collect_names();
886	/**
887	 * Resolves all cross references.  Any properties that refer to another
888	 * node must have their values replaced by either the node path or
889	 * phandle value.  The phandle parameter holds the next phandle to be
890	 * assigned, should the need arise.  It will be incremented upon each
891	 * assignment of a phandle.  Garbage collection of unreferenced nodes
892	 * marked for "delete if unreferenced" will also occur here.
893	 */
894	void resolve_cross_references(uint32_t &phandle);
895	/**
896	 * Garbage collects nodes that have been marked /omit-if-no-ref/ and do not
897	 * have any references to them from nodes that are similarly marked.  This
898	 * is a fairly expensive operation.  The return value indicates whether the
899	 * tree has been dirtied as a result of this operation, so that the caller
900	 * may take appropriate measures to bring the device tree into a consistent
901	 * state as needed.
902	 */
903	bool garbage_collect_marked_nodes();
904	/**
905	 * Parses a dts file in the given buffer and adds the roots to the parsed
906	 * set.  The `read_header` argument indicates whether the header has
907	 * already been read.  Some dts files place the header in an include,
908	 * rather than in the top-level file.
909	 */
910	void parse_file(text_input_buffer &input,
911	                std::vector<node_ptr> &roots,
912	                bool &read_header);
913	/**
914	 * Template function that writes a dtb blob using the specified writer.
915	 * The writer defines the output format (assembly, blob).
916	 */
917	template<class writer>
918	void write(int fd);
919	public:
920	/**
921	 * Should we write the __symbols__ node (to allow overlays to be linked
922	 * against this blob)?
923	 */
924	bool write_symbols = false;
925	/**
926	 * Returns the node referenced by the property.  If this is a tree that
927	 * is in source form, then we have a string that we can use to index
928	 * the cross_references array and so we can just look that up.
929	 */
930	node *referenced_node(property_value &v);
931	/**
932	 * Writes this FDT as a DTB to the specified output.
933	 */
934	void write_binary(int fd);
935	/**
936	 * Writes this FDT as an assembly representation of the DTB to the
937	 * specified output.  The result can then be assembled and linked into
938	 * a program.
939	 */
940	void write_asm(int fd);
941	/**
942	 * Writes the tree in DTS (source) format.
943	 */
944	void write_dts(int fd);
945	/**
946	 * Default constructor.  Creates a valid, but empty FDT.
947	 */
948	device_tree() {}
949	/**
950	 * Constructs a device tree from the specified file name, referring to
951	 * a file that contains a device tree blob.
952	 */
953	void parse_dtb(const std::string &fn, FILE *depfile);
954	/**
955	 * Construct a fragment wrapper around node.  This will assume that node's
956	 * name may be used as the target of the fragment, and the contents are to
957	 * be wrapped in an __overlay__ node.  The fragment wrapper will be assigned
958	 * fragnumas its fragment number, and fragment number will be incremented.
959	 */
960	node_ptr create_fragment_wrapper(node_ptr &node, int &fragnum);
961	/**
962	 * Generate a root node from the node passed in.  This is sensitive to
963	 * whether we're in a plugin context or not, so that if we're in a plugin we
964	 * can circumvent any errors that might normally arise from a non-/ root.
965	 * fragnum will be assigned to any fragment wrapper generated as a result
966	 * of the call, and fragnum will be incremented.
967	 */
968	node_ptr generate_root(node_ptr &node, int &fragnum);
969	/**
970	 * Reassign any fragment numbers from this new node, based on the given
971	 * delta.
972	 */
973	void reassign_fragment_numbers(node_ptr &node, int &delta);
974	/*
975	 * Constructs a device tree from the specified file name, referring to
976	 * a file that contains device tree source.
977	 */
978	void parse_dts(const std::string &fn, FILE *depfile);
979	/**
980	 * Returns whether this tree is valid.
981	 */
982	inline bool is_valid()
983	{
984		return valid;
985	}
986	/**
987	 * Mark this tree as needing garbage collection, because an /omit-if-no-ref/
988	 * node has been encountered.
989	 */
990	void set_needs_garbage_collection()
991	{
992		garbage_collect = true;
993	}
994	/**
995	 * Sets the format for writing phandle properties.
996	 */
997	inline void set_phandle_format(phandle_format f)
998	{
999		phandle_node_name = f;
1000	}
1001	/**
1002	 * Returns a pointer to the root node of this tree.  No ownership
1003	 * transfer.
1004	 */
1005	inline const node_ptr &get_root() const
1006	{
1007		return root;
1008	}
1009	/**
1010	 * Sets the physical boot CPU.
1011	 */
1012	void set_boot_cpu(uint32_t cpu)
1013	{
1014		boot_cpu = cpu;
1015	}
1016	/**
1017	 * Sorts the tree.  Useful for debugging device trees.
1018	 */
1019	void sort()
1020	{
1021		if (root)
1022		{
1023			root->sort();
1024		}
1025	}
1026	/**
1027	 * Adds a path to search for include files.  The argument must be a
1028	 * nul-terminated string representing the path.  The device tree keeps
1029	 * a pointer to this string, but does not own it: the caller is
1030	 * responsible for freeing it if required.
1031	 */
1032	void add_include_path(const char *path)
1033	{
1034		std::string p(path);
1035		include_paths.push_back(std::move(p));
1036	}
1037	/**
1038	 * Sets the number of empty reserve map entries to add.
1039	 */
1040	void set_empty_reserve_map_entries(uint32_t e)
1041	{
1042		spare_reserve_map_entries = e;
1043	}
1044	/**
1045	 * Sets the minimum size, in bytes, of the blob.
1046	 */
1047	void set_blob_minimum_size(uint32_t s)
1048	{
1049		minimum_blob_size = s;
1050	}
1051	/**
1052	 * Sets the amount of padding to add to the blob.
1053	 */
1054	void set_blob_padding(uint32_t p)
1055	{
1056		blob_padding = p;
1057	}
1058	/**
1059	 * Parses a predefined macro value.
1060	 */
1061	bool parse_define(const char *def);
1062};
1063
1064} // namespace fdt
1065
1066} // namespace dtc
1067
1068#endif // !_FDT_HH_
1069