2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2013 David Chisnall
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.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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
47 * Base class for all checkers. This will visit the entire tree and perform
48 * semantic checks defined in subclasses. Note that device trees are generally
49 * small (a few dozen nodes at most) and so we optimise for flexibility and
50 * extensibility here, not for performance. Each checker will visit the entire
56 * The path to the current node being checked. This is used for
57 * printing error messages.
59 device_tree::node_path path;
61 * The name of the checker. This is used for printing error messages
62 * and for enabling / disabling specific checkers from the command
65 const char *checker_name;
67 * Visits each node, calling the checker functions on properties and
70 bool visit_node(device_tree *tree, const node_ptr &n);
73 * Prints the error message, along with the path to the node that
74 * caused the error and the name of the checker.
76 void report_error(const char *errmsg);
79 * Constructor. Takes the name of this checker, which is which is used
80 * when reporting errors.
82 checker(const char *name) : checker_name(name) {}
84 * Virtual destructor in case any subclasses need to do cleanup.
88 * Method for checking that a node is valid. The root class version
89 * does nothing, subclasses should override this.
91 virtual bool check_node(device_tree *, const node_ptr &)
96 * Method for checking that a property is valid. The root class
97 * version does nothing, subclasses should override this.
99 virtual bool check_property(device_tree *, const node_ptr &, property_ptr )
104 * Runs the checker on the specified device tree.
106 bool check_tree(fdt::device_tree *tree)
108 return visit_node(tree, tree->get_root());
113 * Abstract base class for simple property checks. This class defines a check
114 * method for subclasses, which is invoked only when it finds a property with
115 * the matching name. To define simple property checkers, just subclass this
116 * and override the check() method.
118 class property_checker : public checker
121 * The name of the property that this checker is looking for.
126 * Implementation of the generic property-checking method that checks
127 * for a property with the name specified in the constructor.
129 virtual bool check_property(device_tree *tree, const node_ptr &n, property_ptr p);
131 * Constructor. Takes the name of the checker and the name of the
134 property_checker(const char* name, const std::string &property_name)
135 : checker(name), key(property_name) {}
137 * The check method, which subclasses should implement.
139 virtual bool check(device_tree *tree, const node_ptr &n, property_ptr p) = 0;
143 * Property type checker.
145 template<property_value::value_type T>
146 struct property_type_checker : public property_checker
149 * Constructor, takes the name of the checker and the name of the
150 * property to check as arguments.
152 property_type_checker(const char* name, const std::string &property_name) :
153 property_checker(name, property_name) {}
154 virtual bool check(device_tree *tree, const node_ptr &n, property_ptr p) = 0;
158 * Empty property checker. This checks that the property has no value.
161 struct property_type_checker <property_value::EMPTY> : public property_checker
163 property_type_checker(const char* name, const std::string &property_name) :
164 property_checker(name, property_name) {}
165 virtual bool check(device_tree *, const node_ptr &, property_ptr p)
167 return p->begin() == p->end();
172 * String property checker. This checks that the property has exactly one
173 * value, which is a string.
176 struct property_type_checker <property_value::STRING> : public property_checker
178 property_type_checker(const char* name, const std::string &property_name) :
179 property_checker(name, property_name) {}
180 virtual bool check(device_tree *, const node_ptr &, property_ptr p)
182 return (p->begin() + 1 == p->end()) && p->begin()->is_string();
186 * String list property checker. This checks that the property has at least
187 * one value, all of which are strings.
190 struct property_type_checker <property_value::STRING_LIST> :
191 public property_checker
193 property_type_checker(const char* name, const std::string &property_name) :
194 property_checker(name, property_name) {}
195 virtual bool check(device_tree *, const node_ptr &, property_ptr p)
197 for (property::value_iterator i=p->begin(),e=p->end() ; i!=e ;
200 if (!(i->is_string() || i->is_string_list()))
205 return p->begin() != p->end();
210 * Phandle property checker. This checks that the property has exactly one
211 * value, which is a valid phandle.
214 struct property_type_checker <property_value::PHANDLE> : public property_checker
216 property_type_checker(const char* name, const std::string &property_name) :
217 property_checker(name, property_name) {}
218 virtual bool check(device_tree *tree, const node_ptr &, property_ptr p)
220 return (p->begin() + 1 == p->end()) &&
221 (tree->referenced_node(*p->begin()) != 0);
226 * Check that a property has the correct size.
228 struct property_size_checker : public property_checker
231 * The expected size of the property.
236 * Constructor, takes the name of the checker, the name of the property
237 * to check, and its expected size as arguments.
239 property_size_checker(const char* name,
240 const std::string &property_name,
242 : property_checker(name, property_name), size(bytes) {}
244 * Check, validates that the property has the correct size.
246 virtual bool check(device_tree *tree, const node_ptr &n, property_ptr p);
251 * The check manager is the interface to running the checks. This allows
252 * default checks to be enabled, non-default checks to be enabled, and so on.
257 * The enabled checkers, indexed by their names. The name is used when
258 * disabling checkers from the command line. When this manager runs,
259 * it will only run the checkers from this map.
261 std::unordered_map<std::string, checker*> checkers;
263 * The disabled checkers. Moving checkers to this list disables them,
264 * but allows them to be easily moved back.
266 std::unordered_map<std::string, checker*> disabled_checkers;
268 * Helper function for adding a property value checker.
270 template<property_value::value_type T>
271 void add_property_type_checker(const char *name, const std::string &prop);
273 * Helper function for adding a simple type checker.
275 void add_property_type_checker(const char *name, const std::string &prop);
277 * Helper function for adding a property value checker.
279 void add_property_size_checker(const char *name,
280 const std::string &prop,
284 * Delete all of the checkers that are part of this checker manager.
288 * Default constructor, creates check manager containing all of the
293 * Run all of the checks on the specified tree.
295 bool run_checks(device_tree *tree, bool keep_going);
297 * Disables the named checker.
299 bool disable_checker(const std::string &name);
301 * Enables the named checker.
303 bool enable_checker(const std::string &name);
306 } // namespace checking
312 #endif // !_CHECKING_HH_