From 6cd2065f7dec5cbe20866dd48ec1759042b3c232 Mon Sep 17 00:00:00 2001 From: kevans Date: Wed, 3 Oct 2018 17:14:40 +0000 Subject: [PATCH] MFC r337964, r338232: dtc(1) updates r337964: dtc(1): Update to 97d2d5715eeb45108cc60367fdf6bd5b2046b050 Notable fixes: - Overlays may now be generated properly without -@ - /__local_fixups__ were not including unit address in their structure - The error reporting a magic token was misleading, reporting "Bad magic token in header. Got d00dfeed expected 0xd00dfeed" if the token was missing. This has been split out into a separate message. r338232: dtc(1): Update to 0892ec7; HACKING and implicit header fixes Fixes courtesy of arichardson and jmg: - HACKING was pointing to the wrong place - Added headers were being relied on implicitly, but libstdc++ did not comply with the unspoken wishes of dtc. --- usr.bin/dtc/HACKING | 4 +- usr.bin/dtc/dtb.cc | 9 +- usr.bin/dtc/fdt.cc | 189 ++++++++++++++++++++++-------------------- usr.bin/dtc/string.cc | 1 + usr.bin/dtc/util.hh | 3 + 5 files changed, 110 insertions(+), 96 deletions(-) diff --git a/usr.bin/dtc/HACKING b/usr.bin/dtc/HACKING index 9acaeef5bfc..d90e0f5693b 100644 --- a/usr.bin/dtc/HACKING +++ b/usr.bin/dtc/HACKING @@ -8,9 +8,9 @@ This file contains some notes for people wishing to hack on dtc. Upstreaming ----------- -This code is developed in the FreeBSD svn repository: +This code is developed in the git repository: -https://svn.freebsd.org/base/head/usr.bin/dtc +https://github.com/davidchisnall/dtc If you got the source from anywhere else and wish to make changes, please ensure that you are working against the latest version, or you may end up diff --git a/usr.bin/dtc/dtb.cc b/usr.bin/dtc/dtb.cc index 6594774df65..5808e16ec75 100644 --- a/usr.bin/dtc/dtb.cc +++ b/usr.bin/dtc/dtb.cc @@ -262,9 +262,14 @@ header::write(output_writer &out) bool header::read_dtb(input_buffer &input) { - if (!(input.consume_binary(magic) && magic == 0xd00dfeed)) + if (!input.consume_binary(magic)) { - fprintf(stderr, "Missing magic token in header. Got %" PRIx32 + fprintf(stderr, "Missing magic token in header."); + return false; + } + if (magic != 0xd00dfeed) + { + fprintf(stderr, "Bad magic token in header. Got %" PRIx32 " expected 0xd00dfeed\n", magic); return false; } diff --git a/usr.bin/dtc/fdt.cc b/usr.bin/dtc/fdt.cc index a3bc29793e5..3148ec35a41 100644 --- a/usr.bin/dtc/fdt.cc +++ b/usr.bin/dtc/fdt.cc @@ -1337,7 +1337,7 @@ device_tree::resolve_cross_references(uint32_t &phandle) phandle_set.insert({&i.val, i}); } std::vector> sorted_phandles; - root->visit([&](node &n, node *parent) { + root->visit([&](node &n, node *) { for (auto &p : n.properties()) { for (auto &v : *p) @@ -1917,116 +1917,121 @@ device_tree::parse_dts(const string &fn, FILE *depfile) symbols.push_back(prop); } root->add_child(node::create_special_node("__symbols__", symbols)); - // If this is a plugin, then we also need to create two extra nodes. - // Internal phandles will need to be renumbered to avoid conflicts with - // already-loaded nodes and external references will need to be - // resolved. - if (is_plugin) + } + // If this is a plugin, then we also need to create two extra nodes. + // Internal phandles will need to be renumbered to avoid conflicts with + // already-loaded nodes and external references will need to be + // resolved. + if (is_plugin) + { + std::vector symbols; + // Create the fixups entry. This is of the form: + // {target} = {path}:{property name}:{offset} + auto create_fixup_entry = [&](fixup &i, string target) + { + string value = i.path.to_string(); + value += ':'; + value += i.prop->get_key(); + value += ':'; + value += std::to_string(i.prop->offset_of_value(i.val)); + property_value v; + v.string_data = value; + v.type = property_value::STRING; + auto prop = std::make_shared(std::move(target)); + prop->add_value(v); + return prop; + }; + // If we have any unresolved phandle references in this plugin, + // then we must update them to 0xdeadbeef and leave a property in + // the /__fixups__ node whose key is the label and whose value is + // as described above. + if (!unresolved_fixups.empty()) { - // Create the fixups entry. This is of the form: - // {target} = {path}:{property name}:{offset} - auto create_fixup_entry = [&](fixup &i, string target) - { - string value = i.path.to_string(); - value += ':'; - value += i.prop->get_key(); - value += ':'; - value += std::to_string(i.prop->offset_of_value(i.val)); - property_value v; - v.string_data = value; - v.type = property_value::STRING; - auto prop = std::make_shared(std::move(target)); - prop->add_value(v); - return prop; - }; - // If we have any unresolved phandle references in this plugin, - // then we must update them to 0xdeadbeef and leave a property in - // the /__fixups__ node whose key is the label and whose value is - // as described above. - if (!unresolved_fixups.empty()) + for (auto &i : unresolved_fixups) { - symbols.clear(); - for (auto &i : unresolved_fixups) - { - auto &val = i.get().val; - symbols.push_back(create_fixup_entry(i, val.string_data)); - val.byte_data.push_back(0xde); - val.byte_data.push_back(0xad); - val.byte_data.push_back(0xbe); - val.byte_data.push_back(0xef); - val.type = property_value::BINARY; - } - root->add_child(node::create_special_node("__fixups__", symbols)); + auto &val = i.get().val; + symbols.push_back(create_fixup_entry(i, val.string_data)); + val.byte_data.push_back(0xde); + val.byte_data.push_back(0xad); + val.byte_data.push_back(0xbe); + val.byte_data.push_back(0xef); + val.type = property_value::BINARY; } - symbols.clear(); - // If we have any resolved phandle references in this plugin, then - // we must create a child in the __local_fixups__ node whose path - // matches the node path from the root and whose value contains the - // location of the reference within a property. - - // Create a local_fixups node that is initially empty. - node_ptr local_fixups = node::create_special_node("__local_fixups__", symbols); - for (auto &i : fixups) + root->add_child(node::create_special_node("__fixups__", symbols)); + } + symbols.clear(); + // If we have any resolved phandle references in this plugin, then + // we must create a child in the __local_fixups__ node whose path + // matches the node path from the root and whose value contains the + // location of the reference within a property. + + // Create a local_fixups node that is initially empty. + node_ptr local_fixups = node::create_special_node("__local_fixups__", symbols); + for (auto &i : fixups) + { + if (!i.val.is_phandle()) + { + continue; + } + node *n = local_fixups.get(); + for (auto &p : i.path) { - if (!i.val.is_phandle()) + // Skip the implicit root + if (p.first.empty()) { continue; } - node *n = local_fixups.get(); - for (auto &p : i.path) + bool found = false; + for (auto &c : n->child_nodes()) { - // Skip the implicit root - if (p.first.empty()) - { - continue; - } - bool found = false; - for (auto &c : n->child_nodes()) + if (c->name == p.first) { - if (c->name == p.first) + string path = p.first; + if (!(p.second.empty())) { - n = c.get(); - found = true; - break; + path += '@'; + path += p.second; } - } - if (!found) - { - n->add_child(node::create_special_node(p.first, symbols)); + n->add_child(node::create_special_node(path, symbols)); n = (--n->child_end())->get(); } } - assert(n); - property_value pv; - push_big_endian(pv.byte_data, static_cast(i.prop->offset_of_value(i.val))); - pv.type = property_value::BINARY; - auto key = i.prop->get_key(); - property_ptr prop = n->get_property(key); - // If we don't have an existing property then create one and - // use this property value - if (!prop) - { - prop = std::make_shared(std::move(key)); - n->add_property(prop); - prop->add_value(pv); - } - else + if (!found) { - // If we do have an existing property value, try to append - // this value. - property_value &old_val = *(--prop->end()); - if (!old_val.try_to_merge(pv)) - { - prop->add_value(pv); - } + n->add_child(node::create_special_node(p.first, symbols)); + n = (--n->child_end())->get(); } } - // We've iterated over all fixups, but only emit the - // __local_fixups__ if we found some that were resolved internally. - if (local_fixups->child_begin() != local_fixups->child_end()) + assert(n); + property_value pv; + push_big_endian(pv.byte_data, static_cast(i.prop->offset_of_value(i.val))); + pv.type = property_value::BINARY; + auto key = i.prop->get_key(); + property_ptr prop = n->get_property(key); + // If we don't have an existing property then create one and + // use this property value + if (!prop) { - root->add_child(std::move(local_fixups)); + prop = std::make_shared(std::move(key)); + n->add_property(prop); + prop->add_value(pv); } + else + { + // If we do have an existing property value, try to append + // this value. + property_value &old_val = *(--prop->end()); + if (!old_val.try_to_merge(pv)) + { + prop->add_value(pv); + } + } + } + // We've iterated over all fixups, but only emit the + // __local_fixups__ if we found some that were resolved internally. + if (local_fixups->child_begin() != local_fixups->child_end()) + { + root->add_child(std::move(local_fixups)); } } } diff --git a/usr.bin/dtc/string.cc b/usr.bin/dtc/string.cc index 71a304a2ea2..c5acb82687e 100644 --- a/usr.bin/dtc/string.cc +++ b/usr.bin/dtc/string.cc @@ -36,6 +36,7 @@ #include #include #include +#include #include #include diff --git a/usr.bin/dtc/util.hh b/usr.bin/dtc/util.hh index 337685ef3f4..84646b444b3 100644 --- a/usr.bin/dtc/util.hh +++ b/usr.bin/dtc/util.hh @@ -35,6 +35,9 @@ #ifndef _UTIL_HH_ #define _UTIL_HH_ +#include +#include +#include #include // If we aren't using C++11, then just ignore static asserts. -- 2.45.0