]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/dtc/fdt.hh
bhnd(9): Fix a few mandoc related issues
[FreeBSD/FreeBSD.git] / usr.bin / dtc / fdt.hh
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$
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
47 namespace dtc
48 {
49
50 namespace dtb 
51 {
52 struct output_writer;
53 class string_table;
54 }
55
56 namespace fdt
57 {
58 class property;
59 class node;
60 class device_tree;
61 /**
62  * Type for device tree write functions.
63  */
64 typedef void (device_tree::* tree_write_fn_ptr)(int);
65 /**
66  * Type for device tree read functions.
67  */
68 typedef void (device_tree::* tree_read_fn_ptr)(const std::string &, FILE *);
69 /**
70  * Type for (owned) pointers to properties.
71  */
72 typedef std::shared_ptr<property> property_ptr;
73 /**
74  * Owning pointer to a node.
75  */
76 typedef std::unique_ptr<node> node_ptr;
77 /**
78  * Map from macros to property pointers.
79  */
80 typedef std::unordered_map<std::string, property_ptr> define_map;
81 /**
82  * Set of strings used for label names.
83  */
84 typedef 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  */
89 struct 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  */
268 class 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  */
409 class 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  */
705 class 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_