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