From nobody Wed Jan 10 18:51:53 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4T9H2y0P0fz55dPK; Wed, 10 Jan 2024 18:51:54 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4T9H2y06Pfz4PhT; Wed, 10 Jan 2024 18:51:54 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1704912714; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=kySqlvO/+KKFSYAWLysr8qPWNYW7rqZofFVH0mToQOw=; b=kWEjJ9zu/x19wQMyalox5Alt52zc/tV/NuP9PlOcKhdmnH5fPfUaMadOd1LG1TrYVLHQRJ BBEUqtxxtOQfSjooBgVu/IOx0WqujN/Za4SZnXm0CQhCpaauHY8bKxb48bVcwokHoT2Ajv WXIZGYUXdbAWwzU4df/FuvyXjHo1h0VcJzJTqmcBUfCGz9wnDOyJN/YEJB4ATBjI2cpDea bOfbLo2p3FzykYE/HfHFenX1+VcPYSwYMZNydqNdpN2xpa7PZYj/NVH/sWRlLJgYg7I/kP pJmBEP7LM8rjIymQKP66SQuzKogsJNuEtBClcVcRpGlGZr8iXttIL+Bjvmkn5w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1704912714; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=kySqlvO/+KKFSYAWLysr8qPWNYW7rqZofFVH0mToQOw=; b=Pqx77iYIKvPKYY8MmKpuLQ/Mu1MhcYVR6vgRckjbbxgb0ssR7hJfJRiy04PyzC+CqoaZx0 p6imUo8a3htnQU7knam8qoJpugVtdkhw8kKjylEg6JYRLBfJJSxl0VvkKGlO3WvR+YsdRx lLlstpL1se/BXYpA9a3N0BWVNYA95J/nr/4/6rXWNqw0+hwzRAOqfpPgMF9bpSeinBnuy2 h1pXGD6Z2H/lkX4wv3NfpVKJhPSBTHlYk7GWDvOyoKw0Hw7Pgf3QK/anHZwUTkoxAAXFYz nP0dvMyFldahz13eGjCS/MIQjj8pCwsjD2PAlfD6EgYMe9626cjaaL+k7K6Z/Q== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1704912714; a=rsa-sha256; cv=none; b=pj1k8H9n22Y5C33xbtLD67pGSN6irQGNw1f35CZTeMSLqVWMSvvH5h+MrGhNmtjSzrPx3x 9nxWcMCHFjGVFzIxhaJ/L4EWhtsijHBIjN8Vv/2JpTfbJUmMrIz7b8VaTR5gL/FbrS4eS0 MLsFi7QLhspr12+VuXJdCWlzg6OniuMusmod5ysL5UOx1AII8gsHIVnQEhPC50EKKOiCb+ m5TApYlm11xkg1BPIgKEmySqAKvQNzXMSjopeABRVjVP5yG77GMzTN1E+ZRVvV8jJDgY8/ 0mFd3esgiLXx9NSWjVf+TJBIUYXbCiCfkHIDdZY+R8+iefkX3AhOwBZVA4dERQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4T9H2x6Dz6zmrJ; Wed, 10 Jan 2024 18:51:53 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 40AIprp8010118; Wed, 10 Jan 2024 18:51:53 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 40AIprr2010115; Wed, 10 Jan 2024 18:51:53 GMT (envelope-from git) Date: Wed, 10 Jan 2024 18:51:53 GMT Message-Id: <202401101851.40AIprr2010115@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Ed Maste Subject: git: 38fe4bc08264 - stable/14 - dtc: Sync with upstream commit 26a0fe5 List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: emaste X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: 38fe4bc08264652cd33964ba6042bd4c0faf6b76 Auto-Submitted: auto-generated The branch stable/14 has been updated by emaste: URL: https://cgit.FreeBSD.org/src/commit/?id=38fe4bc08264652cd33964ba6042bd4c0faf6b76 commit 38fe4bc08264652cd33964ba6042bd4c0faf6b76 Author: Jose Luis Duran AuthorDate: 2023-09-26 16:37:52 +0000 Commit: Ed Maste CommitDate: 2024-01-10 18:50:53 +0000 dtc: Sync with upstream commit 26a0fe5 - 0206c0f ("Handle top-level /delete-node/ directives.") - d612a9e ("Remove C++11 standard constrain") - Remove extra white lines after the $FreeBSD$ tag removal Reviewed by: kevans (earlier), theraven, emaste Differential Revision: https://reviews.freebsd.org/D41482 (cherry picked from commit 29a55fd09b0a3cc4c888f7a630fde41694699343) (cherry picked from commit f147cf0ee2b2642c0a133a71c8a5dc018518d923) --- usr.bin/dtc/HACKING | 1 - usr.bin/dtc/Makefile | 3 +- usr.bin/dtc/fdt.cc | 134 ++++++++++++++++++++++++++++++++++++++++----------- usr.bin/dtc/fdt.hh | 24 ++++++--- 4 files changed, 122 insertions(+), 40 deletions(-) diff --git a/usr.bin/dtc/HACKING b/usr.bin/dtc/HACKING index 9447c4f6ebf9..ef858c8885c0 100644 --- a/usr.bin/dtc/HACKING +++ b/usr.bin/dtc/HACKING @@ -1,4 +1,3 @@ - Notes for people hacking on dtc =============================== diff --git a/usr.bin/dtc/Makefile b/usr.bin/dtc/Makefile index d242ed80e8b1..9b1aff13511f 100644 --- a/usr.bin/dtc/Makefile +++ b/usr.bin/dtc/Makefile @@ -1,4 +1,3 @@ - PROG_CXX=dtc SRCS= dtc.cc input_buffer.cc string.cc dtb.cc fdt.cc checking.cc MAN= dtc.1 @@ -7,7 +6,7 @@ WARNS?= 3 CXXFLAGS+= -fno-rtti -fno-exceptions -CXXSTD= c++11 +CXXSTD= c++17 NO_SHARED?=NO diff --git a/usr.bin/dtc/fdt.cc b/usr.bin/dtc/fdt.cc index 5ab9ba10d2f0..f0b98cfe720c 100644 --- a/usr.bin/dtc/fdt.cc +++ b/usr.bin/dtc/fdt.cc @@ -861,7 +861,15 @@ node::node(const string &n, node_ptr node::create_special_node(const string &name, const std::vector &props) { - node_ptr n(new node(name, props)); + // Work around for the fact that we can't call make_shared on something + // with a private constructor. Instead create a subclass with a public + // constructor that is visible only in this function and construct that + // instead. + struct constructable_node : public node + { + constructable_node(const string &n, const std::vector &p) : node(n, p) {} + }; + node_ptr n{std::make_shared(name, props)}; return n; } @@ -1035,12 +1043,31 @@ node::parse(text_input_buffer &input, string &&address, define_map *defines) { - node_ptr n(new node(input, - tree, - std::move(name), - std::move(label), - std::move(address), - defines)); + // Work around for the fact that we can't call make_shared on something + // with a private constructor. Instead create a subclass with a public + // constructor that is visible only in this function and construct that + // instead. + struct constructable_node : public node + { + constructable_node(text_input_buffer &input, + device_tree &tree, + std::string &&n, + std::unordered_set &&l, + std::string &&a, + define_map*m) : node(input, + tree, + std::move(n), + std::move(l), + std::move(a), + m) + {} + }; + node_ptr n{std::make_shared(input, + tree, + std::move(name), + std::move(label), + std::move(address), + defines)}; if (!n->valid) { n = 0; @@ -1208,7 +1235,7 @@ node::write_dts(FILE *file, int indent) } void -device_tree::collect_names_recursive(node_ptr &n, node_path &path) +device_tree::collect_names_recursive(node_ptr parent, node_ptr n, node_path &path) { path.push_back(std::make_pair(n->name, n->unit_address)); for (const string &name : n->labels) @@ -1218,9 +1245,13 @@ device_tree::collect_names_recursive(node_ptr &n, node_path &path) auto iter = node_names.find(name); if (iter == node_names.end()) { - node_names.insert(std::make_pair(name, n.get())); + node_names.insert(std::make_pair(name, n)); node_paths.insert(std::make_pair(name, path)); ordered_node_paths.push_back({name, path}); + if (parent) + { + node_name_parents.insert({name, parent}); + } } else { @@ -1236,7 +1267,7 @@ device_tree::collect_names_recursive(node_ptr &n, node_path &path) } for (auto &c : n->child_nodes()) { - collect_names_recursive(c, path); + collect_names_recursive(n, c, path); } // Now we collect the phandles and properties that reference // other nodes. @@ -1264,7 +1295,7 @@ device_tree::collect_names_recursive(node_ptr &n, node_path &path) else { uint32_t phandle = p->begin()->get_as_uint32(); - used_phandles.insert(std::make_pair(phandle, n.get())); + used_phandles.insert(std::make_pair(phandle, n)); } } } @@ -1280,11 +1311,11 @@ device_tree::collect_names() ordered_node_paths.clear(); cross_references.clear(); fixups.clear(); - collect_names_recursive(root, p); + collect_names_recursive(nullptr, root, p); } property_ptr -device_tree::assign_phandle(node *n, uint32_t &phandle) +device_tree::assign_phandle(node_ptr n, uint32_t &phandle) { // If there is an existing phandle, use it property_ptr p = n->get_property("phandle"); @@ -1329,11 +1360,11 @@ device_tree::assign_phandle(node *n, uint32_t &phandle) } void -device_tree::assign_phandles(node_ptr &n, uint32_t &next) +device_tree::assign_phandles(node_ptr n, uint32_t &next) { if (!n->labels.empty()) { - assign_phandle(n.get(), next); + assign_phandle(n, next); } for (auto &c : n->child_nodes()) @@ -1391,14 +1422,14 @@ device_tree::resolve_cross_references(uint32_t &phandle) for (auto &i : sorted_phandles) { string target_name = i.get().val.string_data; - node *target = nullptr; + node_ptr target; string possible; // If the node name is a path, then look it up by following the path, // otherwise jump directly to the named node. if (target_name[0] == '/') { string path; - target = root.get(); + target = root; std::istringstream ss(target_name); string path_element; // Read the leading / @@ -1412,14 +1443,14 @@ device_tree::resolve_cross_references(uint32_t &phandle) string node_name, node_address; std::getline(nss, node_name, '@'); std::getline(nss, node_address, '@'); - node *next = nullptr; + node_ptr next; for (auto &c : target->child_nodes()) { if (c->name == node_name) { if (c->unit_address == node_address) { - next = c.get(); + next = c; break; } else @@ -1478,8 +1509,8 @@ device_tree::resolve_cross_references(uint32_t &phandle) bool device_tree::garbage_collect_marked_nodes() { - std::unordered_set previously_referenced_nodes; - std::unordered_set newly_referenced_nodes; + std::unordered_set previously_referenced_nodes; + std::unordered_set newly_referenced_nodes; auto mark_referenced_nodes_used = [&](node &n) { @@ -1489,7 +1520,7 @@ device_tree::garbage_collect_marked_nodes() { if (v.is_phandle()) { - node *nx = node_names[v.string_data]; + node_ptr nx = node_names[v.string_data]; if (nx == nullptr) { // Try it again, but as a path @@ -1534,8 +1565,9 @@ device_tree::garbage_collect_marked_nodes() while (!newly_referenced_nodes.empty()) { - previously_referenced_nodes = std::move(newly_referenced_nodes); - for (auto *n : previously_referenced_nodes) + previously_referenced_nodes = newly_referenced_nodes; + newly_referenced_nodes.clear(); + for (auto &n : previously_referenced_nodes) { mark_referenced_nodes_used(*n); } @@ -1617,7 +1649,38 @@ device_tree::parse_file(text_input_buffer &input, while (valid && !input.finished()) { node_ptr n; - if (input.consume('/')) + if (input.consume("/delete-node/")) + { + // Top-level /delete-node/ directives refer to references that must + // be deleted later. + input.next_token(); + auto expect = [&](auto token, const char *msg) + { + if (!input.consume(token)) + { + input.parse_error(msg); + valid = false; + } + input.next_token(); + return valid; + }; + if (expect('&', "Expected reference after top-level /delete-node/.")) + { + string ref = input.parse_node_name(); + if (ref == string()) + { + input.parse_error("Expected label name for top-level /delete-node/."); + valid = false; + } + else + { + deletions.push_back(std::move(ref)); + } + expect(';', "Missing semicolon."); + } + continue; + } + else if (input.consume('/')) { input.next_token(); n = node::parse(input, *this, string(), string_set(), string(), &defines); @@ -1732,7 +1795,7 @@ device_tree::write(int fd) strings_writer.write_to_file(fd); } -node* +node_ptr device_tree::referenced_node(property_value &v) { if (v.is_phandle()) @@ -2032,6 +2095,19 @@ device_tree::parse_dts(const string &fn, FILE *depfile) } } collect_names(); + for (auto &ref : deletions) + { + auto parent = node_name_parents[ref]; + auto node = node_names[ref]; + if (!parent) + { + fprintf(stderr, "Top-level /delete-node/ directive refers to label %s, which is not found.\n", ref.c_str()); + } + else + { + parent->delete_children_if([&](node_ptr &child) { return child == node; }); + } + } // Return value indicates whether we've dirtied the tree or not and need to // recollect names if (garbage_collect && garbage_collect_marked_nodes()) @@ -2127,7 +2203,7 @@ device_tree::parse_dts(const string &fn, FILE *depfile) { continue; } - node *n = local_fixups.get(); + node_ptr n = local_fixups; for (auto &p : i.path) { // Skip the implicit root @@ -2142,7 +2218,7 @@ device_tree::parse_dts(const string &fn, FILE *depfile) { if (c->unit_address == p.second) { - n = c.get(); + n = c; found = true; break; } @@ -2157,7 +2233,7 @@ device_tree::parse_dts(const string &fn, FILE *depfile) path += p.second; } n->add_child(node::create_special_node(path, symbols)); - n = (--n->child_end())->get(); + n = *(--(n->child_end())); } } assert(n); diff --git a/usr.bin/dtc/fdt.hh b/usr.bin/dtc/fdt.hh index 86c9ff153b80..fad9609d40bb 100644 --- a/usr.bin/dtc/fdt.hh +++ b/usr.bin/dtc/fdt.hh @@ -71,7 +71,7 @@ typedef std::shared_ptr property_ptr; /** * Owning pointer to a node. */ -typedef std::unique_ptr node_ptr; +typedef std::shared_ptr node_ptr; /** * Map from macros to property pointers. */ @@ -663,7 +663,7 @@ class node /** * Deletes any children from this node. */ - inline void delete_children_if(bool (*predicate)(node_ptr &)) + inline void delete_children_if(std::function predicate) { children.erase(std::remove_if(children.begin(), children.end(), predicate), children.end()); } @@ -761,7 +761,11 @@ class device_tree * Mapping from names to nodes. Only unambiguous names are recorded, * duplicate names are stored as (node*)-1. */ - std::unordered_map node_names; + std::unordered_map node_names; + /** + * Mapping from names to the nodes that contain them. + */ + std::unordered_map node_name_parents; /** * A map from labels to node paths. When resolving cross references, * we look up referenced nodes in this and replace the cross reference @@ -779,6 +783,10 @@ class device_tree * These should be expanded to the full path of their targets. */ std::vector cross_references; + /** + * Labels collected from top-level /delete-node/ directives. + */ + std::vector deletions; /** * The location of something requiring a fixup entry. */ @@ -827,7 +835,7 @@ class device_tree * find phandles that were provided by the user explicitly when we are * doing checking. */ - std::unordered_map used_phandles; + std::unordered_map used_phandles; /** * Paths to search for include files. This contains a set of * nul-terminated strings, which are not owned by this class and so @@ -864,19 +872,19 @@ class device_tree * used in resolving cross references. Also collects phandle * properties that have been explicitly added. */ - void collect_names_recursive(node_ptr &n, node_path &path); + void collect_names_recursive(node_ptr parent, node_ptr n, node_path &path); /** * Assign a phandle property to a single node. The next parameter * holds the phandle to be assigned, and will be incremented upon * assignment. */ - property_ptr assign_phandle(node *n, uint32_t &next); + property_ptr assign_phandle(node_ptr n, uint32_t &next); /** * Assign phandle properties to all nodes that have been referenced and * require one. This method will recursively visit the tree starting at * the node that it is passed. */ - void assign_phandles(node_ptr &n, uint32_t &next); + void assign_phandles(node_ptr n, uint32_t &next); /** * Calls the recursive version of this method on every root node. */ @@ -925,7 +933,7 @@ class device_tree * is in source form, then we have a string that we can use to index * the cross_references array and so we can just look that up. */ - node *referenced_node(property_value &v); + node_ptr referenced_node(property_value &v); /** * Writes this FDT as a DTB to the specified output. */