DTC 1.7.0

Changes since v1.6.1 include:
  * dtc
    * Fix -Oasm output on PA-RISC by avoiding ';' separators
    * Put symbolic label references in -Odts output when possible
    * Add label relative path references
    * Don't incorrectly attempt to create fixups for reference to path
      in overlays
    * Warning rather than hard error if integer expression results are
      truncated due to cell size
  * libfdt
    * Add fdt_get_property_by_offset_w() function
  * pylibfdt
    * Fixed to work with Python 3.10
    * A number of extra methods
    * Fix out of tree build
  * fdtget
    * Add raw bytes output mode
  * General
    * Fixes for mixed-signedness comparison warnings
    * Assorted other warning fixes
    * Assorted updates to checks
    * Assorted bugfixes
    * Fix scripts to work with dash as well as bash
    * Allow static builds
    * Formalize Signed-off-by usage
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEO+dNsU4E3yXUXRK2zQJF27ox2GcFAmPkzC8ACgkQzQJF27ox
 2GdBWBAAorY2l5Xj9GZgyZlM/amfuEVWfcFBccWi5r71NkiIfGhEoBRr4MR+Q1Wq
 /6RzxKj2lgIivNWWQdWbsJp6QKDpEL+LYspzFz3V18olKMwd2e2upJ2ChxlXJnWp
 3gcSfTYmmlflrMTy7VemRdMOX5lCK1dcLxl4Lq8XxPFYipPxppvbDgcII3j5n37S
 R6lBNigTRle6y7OpVtoFfHeBfm7U5YVTamyUDui36ql3txHHsZnCwliU/lhJBLMz
 TbM+K602rlR7j6YhR2n/7L6AsEzcNXRMArg72PejwZIyOpxTUPDQ5NtfSTy9Ghxb
 gmUMwFuQ13BwgjhjCVSAxPMphsuyV+Njy2xfWNfjg204ZhmX3Lw0NLE2GmbZU3Wc
 m4+HdwwxJLZbhJ+MNvkYYy5Fv22JHTV8aPKoiBCsjtUumrnEqm5ge6DI0PVkroa6
 3V/9a/qiOKb796JP7oixxaEuGMXXp6+BPDJz27O7782yDR8Dh2S3febEZTxlmkcP
 IS67RrAc61o5Qpm4+EjPpG6PadlKJpdsZwP+ABDxB1/CY/s+Id3noP8ca7gZ5kye
 iZK8mAebAm5PnRU3sHIDVkB3Tu7cDxb8ZH1S4ILU1OznhVVo/EDux9SZcrNpBoTK
 1cFbVdY02ZKMb4YDv/xTAXnMXvEIQNA9oSZP6K0nAr8YsPoDo9I=
 =XrsV
 -----END PGP SIGNATURE-----

Upgrade dtc to v1.7.0

This project was upgraded with external_updater.
Usage: tools/external_updater/updater.sh update external/dtc
For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md

Test: TreeHugger
Change-Id: I7c3774a5f8fbc6ddf0926df9db3450c4dce54cf9
This commit is contained in:
Sadaf Ebrahimi 2024-03-26 21:39:49 +00:00
commit 835431ed39
22 changed files with 187 additions and 33 deletions

View file

@ -43,9 +43,8 @@ The gitweb interface for the upstream repository is:
1.1) Submitting Patches 1.1) Submitting Patches
Patches should be sent to the maintainers: Patches should be sent to the maintainer:
David Gibson <david@gibson.dropbear.id.au> David Gibson <david@gibson.dropbear.id.au>
Jon Loeliger <loeliger@gmail.com>
and CCed to <devicetree-compiler@vger.kernel.org>. and CCed to <devicetree-compiler@vger.kernel.org>.
2) Description 2) Description

View file

@ -1,7 +1,7 @@
# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) # SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
global-exclude * global-exclude *
include README include README.md
include GPL include GPL
include BSD-2-Clause include BSD-2-Clause
include setup.py include setup.py

View file

@ -1,19 +1,19 @@
# This project was upgraded with external_updater. # This project was upgraded with external_updater.
# Usage: tools/external_updater/updater.sh update dtc # Usage: tools/external_updater/updater.sh update external/dtc
# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md # For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md
name: "dtc" name: "dtc"
description: "Device tree compiler tools (dtc) and libfdt." description: "Device tree compiler tools (dtc) and libfdt."
third_party { third_party {
url {
type: GIT
value: "https://git.kernel.org/pub/scm/utils/dtc/dtc.git"
}
version: "v1.6.1"
license_type: RESTRICTED license_type: RESTRICTED
last_upgrade_date { last_upgrade_date {
year: 2023 year: 2024
month: 1 month: 3
day: 18 day: 26
}
identifier {
type: "Git"
value: "https://git.kernel.org/pub/scm/utils/dtc/dtc.git"
version: "v1.7.0"
} }
} }

View file

@ -10,8 +10,8 @@
# CONFIG_LOCALVERSION from some future config system. # CONFIG_LOCALVERSION from some future config system.
# #
VERSION = 1 VERSION = 1
PATCHLEVEL = 6 PATCHLEVEL = 7
SUBLEVEL = 1 SUBLEVEL = 0
EXTRAVERSION = EXTRAVERSION =
LOCAL_VERSION = LOCAL_VERSION =
CONFIG_LOCALVERSION = CONFIG_LOCALVERSION =
@ -384,7 +384,7 @@ clean: libfdt_clean pylibfdt_clean tests_clean
@$(VECHO) LEX $@ @$(VECHO) LEX $@
$(LEX) -o$@ $< $(LEX) -o$@ $<
%.tab.c %.tab.h %.output: %.y %.tab.c %.tab.h: %.y
@$(VECHO) BISON $@ @$(VECHO) BISON $@
$(BISON) -b $(basename $(basename $@)) -d $< $(BISON) -b $(basename $(basename $@)) -d $<
@ -393,3 +393,7 @@ dtc-parser.h: dtc-parser.tab.h
ln -s $^ $@ ln -s $^ $@
FORCE: FORCE:
ifeq ($(MAKE_RESTARTS),10)
$(error "Make re-executed itself $(MAKE_RESTARTS) times. Infinite recursion?")
endif

View file

@ -1222,7 +1222,7 @@ static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *d
if (!node->parent || node->addr_cells < 0 || node->size_cells < 0) if (!node->parent || node->addr_cells < 0 || node->size_cells < 0)
return; return;
if (get_property(node, "ranges") || !node->children) if (get_property(node, "ranges") || get_property(node, "dma-ranges") || !node->children)
return; return;
for_each_child(node, child) { for_each_child(node, child) {
@ -1232,7 +1232,7 @@ static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *d
} }
if (!has_reg) if (!has_reg)
FAIL(c, dti, node, "unnecessary #address-cells/#size-cells without \"ranges\" or child \"reg\" property"); FAIL(c, dti, node, "unnecessary #address-cells/#size-cells without \"ranges\", \"dma-ranges\" or child \"reg\" property");
} }
WARNING(avoid_unnecessary_addr_size, check_avoid_unnecessary_addr_size, NULL, &avoid_default_addr_size); WARNING(avoid_unnecessary_addr_size, check_avoid_unnecessary_addr_size, NULL, &avoid_default_addr_size);

View file

@ -409,9 +409,14 @@ arrayprefix:
* within the mask to one (i.e. | in the * within the mask to one (i.e. | in the
* mask), all bits are one. * mask), all bits are one.
*/ */
if (($2 > mask) && (($2 | mask) != -1ULL)) if (($2 > mask) && (($2 | mask) != -1ULL)) {
ERROR(&@2, "Value out of range for" char *loc = srcpos_string(&@2);
" %d-bit array element", $1.bits); fprintf(stderr,
"WARNING: %s: Value 0x%016" PRIx64
" truncated to 0x%0*" PRIx64 "\n",
loc, $2, $1.bits / 4, ($2 & mask));
free(loc);
}
} }
$$.data = data_append_integer($1.data, $2, $1.bits); $$.data = data_append_integer($1.data, $2, $1.bits);

View file

@ -106,7 +106,6 @@ int fdt_check_header(const void *fdt)
} }
hdrsize = fdt_header_size(fdt); hdrsize = fdt_header_size(fdt);
if (!can_assume(VALID_DTB)) { if (!can_assume(VALID_DTB)) {
if ((fdt_totalsize(fdt) < hdrsize) if ((fdt_totalsize(fdt) < hdrsize)
|| (fdt_totalsize(fdt) > INT_MAX)) || (fdt_totalsize(fdt) > INT_MAX))
return -FDT_ERR_TRUNCATED; return -FDT_ERR_TRUNCATED;
@ -115,9 +114,7 @@ int fdt_check_header(const void *fdt)
if (!check_off_(hdrsize, fdt_totalsize(fdt), if (!check_off_(hdrsize, fdt_totalsize(fdt),
fdt_off_mem_rsvmap(fdt))) fdt_off_mem_rsvmap(fdt)))
return -FDT_ERR_TRUNCATED; return -FDT_ERR_TRUNCATED;
}
if (!can_assume(VALID_DTB)) {
/* Bounds check structure block */ /* Bounds check structure block */
if (!can_assume(LATEST) && fdt_version(fdt) < 17) { if (!can_assume(LATEST) && fdt_version(fdt) < 17) {
if (!check_off_(hdrsize, fdt_totalsize(fdt), if (!check_off_(hdrsize, fdt_totalsize(fdt),

View file

@ -35,14 +35,14 @@ struct fdt_reserve_entry {
struct fdt_node_header { struct fdt_node_header {
fdt32_t tag; fdt32_t tag;
char name[0]; char name[];
}; };
struct fdt_property { struct fdt_property {
fdt32_t tag; fdt32_t tag;
fdt32_t len; fdt32_t len;
fdt32_t nameoff; fdt32_t nameoff;
char data[0]; char data[];
}; };
#endif /* !__ASSEMBLY */ #endif /* !__ASSEMBLY */

View file

@ -66,7 +66,10 @@ int fdt_check_full(const void *fdt, size_t bufsize)
int len; int len;
name = fdt_get_name(fdt, offset, &len); name = fdt_get_name(fdt, offset, &len);
if (!name || *name || len) if (!name)
return len;
if (*name || len)
return -FDT_ERR_BADSTRUCTURE; return -FDT_ERR_BADSTRUCTURE;
} }
break; break;

View file

@ -660,6 +660,13 @@ int fdt_next_property_offset(const void *fdt, int offset);
const struct fdt_property *fdt_get_property_by_offset(const void *fdt, const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
int offset, int offset,
int *lenp); int *lenp);
static inline struct fdt_property *fdt_get_property_by_offset_w(void *fdt,
int offset,
int *lenp)
{
return (struct fdt_property *)(uintptr_t)
fdt_get_property_by_offset(fdt, offset, lenp);
}
/** /**
* fdt_get_property_namelen - find a property based on substring * fdt_get_property_namelen - find a property based on substring

View file

@ -919,6 +919,12 @@ static void add_fixup_entry(struct dt_info *dti, struct node *fn,
/* m->ref can only be a REF_PHANDLE, but check anyway */ /* m->ref can only be a REF_PHANDLE, but check anyway */
assert(m->type == REF_PHANDLE); assert(m->type == REF_PHANDLE);
/* The format only permits fixups for references to label, not
* references to path */
if (strchr(m->ref, '/'))
die("Can't generate fixup for reference to path &{%s}\n",
m->ref);
/* there shouldn't be any ':' in the arguments */ /* there shouldn't be any ':' in the arguments */
if (strchr(node->fullpath, ':') || strchr(prop->name, ':')) if (strchr(node->fullpath, ':') || strchr(prop->name, ':'))
die("arguments should not contain ':'\n"); die("arguments should not contain ':'\n");

View file

@ -443,11 +443,12 @@ class FdtRo(object):
""" """
return fdt_get_alias(self._fdt, name) return fdt_get_alias(self._fdt, name)
def get_path(self, nodeoffset, quiet=()): def get_path(self, nodeoffset, size_hint=1024, quiet=()):
"""Get the full path of a node """Get the full path of a node
Args: Args:
nodeoffset: Node offset to check nodeoffset: Node offset to check
size_hint: Hint for size of returned string
Returns: Returns:
Full path to the node Full path to the node
@ -455,11 +456,10 @@ class FdtRo(object):
Raises: Raises:
FdtException if an error occurs FdtException if an error occurs
""" """
size = 1024
while True: while True:
ret, path = fdt_get_path(self._fdt, nodeoffset, size) ret, path = fdt_get_path(self._fdt, nodeoffset, size_hint)
if ret == -NOSPACE: if ret == -NOSPACE:
size = size * 2 size_hint *= 2
continue continue
err = check_err(ret, quiet) err = check_err(ret, quiet)
if err: if err:
@ -1036,6 +1036,9 @@ class NodeAdder():
%rename(fdt_property) fdt_property_func; %rename(fdt_property) fdt_property_func;
%immutable fdt_property::data;
%immutable fdt_node_header::name;
/* /*
* fdt32_t is a big-endian 32-bit value defined to uint32_t in libfdt_env.h * fdt32_t is a big-endian 32-bit value defined to uint32_t in libfdt_env.h
* so use the same type here. * so use the same type here.

View file

@ -19,7 +19,7 @@ import sys
srcdir = os.path.dirname(__file__) srcdir = os.path.dirname(__file__)
with open(os.path.join(srcdir, "README"), "r") as fh: with open(os.path.join(srcdir, "README.md"), "r") as fh:
long_description = fh.read() long_description = fh.read()
def get_top_builddir(): def get_top_builddir():

1
tests/.gitignore vendored
View file

@ -74,3 +74,4 @@ tmp.*
/truncated_memrsv /truncated_memrsv
/utilfdt_test /utilfdt_test
/value-labels /value-labels
/get_next_tag_invalid_prop_len

View file

@ -4,7 +4,7 @@ LIB_TESTS_L = get_mem_rsv \
get_path supernode_atdepth_offset parent_offset \ get_path supernode_atdepth_offset parent_offset \
node_offset_by_prop_value node_offset_by_phandle \ node_offset_by_prop_value node_offset_by_phandle \
node_check_compatible node_offset_by_compatible \ node_check_compatible node_offset_by_compatible \
get_alias \ get_alias get_next_tag_invalid_prop_len \
char_literal \ char_literal \
sized_cells \ sized_cells \
notfound \ notfound \

View file

@ -0,0 +1,7 @@
/dts-v1/;
/ {
prop1 = < 0 >;
prop2 = < 0xffffffff >;
prop3 = < 0 >;
};

7
tests/cell-overflow.dts Normal file
View file

@ -0,0 +1,7 @@
/dts-v1/;
/ {
prop1 = < (-0xffffffff - 1) >;
prop2 = < (-0xffffffff - 2) >;
prop3 = < ((-0xffffffff - 1) * 2) >;
};

View file

@ -0,0 +1,6 @@
/dts-v1/;
/plugin/;
/ {
prop = < &{/path/to/node} >;
};

View file

@ -0,0 +1,100 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* libfdt - Flat Device Tree manipulation
* Testcase for fdt_next_tag()
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <libfdt.h>
#include "tests.h"
#include "testdata.h"
#define FDT_SIZE 65536
#define CHECK_ERR(err) \
({ if (err) \
FAIL("%s: %d: %s", __FILE__, __LINE__, fdt_strerror(err)); \
})
static void fdt_next_tag_test(bool fdt_finished)
{
struct fdt_property *prp;
void *fdt;
int nextoff = 0, offset, err;
uint32_t tag;
fdt = malloc(FDT_SIZE);
if (!fdt)
FAIL("Can't allocate memory");
err = fdt_create(fdt, FDT_SIZE);
CHECK_ERR(err);
err = fdt_finish_reservemap(fdt);
CHECK_ERR(err);
/* Create a root node and add two properties */
err = fdt_begin_node(fdt, "");
CHECK_ERR(err);
err = fdt_property_u32(fdt, "prop-int-32", 0x1234);
CHECK_ERR(err);
err = fdt_property_u32(fdt, "prop2-int-32", 0x4321);
CHECK_ERR(err);
err = fdt_end_node(fdt);
CHECK_ERR(err);
if (fdt_finished) {
/* Call fdt_finish to set the correct fdt state. */
err = fdt_finish(fdt);
CHECK_ERR(err);
}
offset = fdt_first_property_offset(fdt, 0);
if (offset <= 0)
FAIL("Invalid offset %x, expected value greater than 0, finished=%d\n",
offset, fdt_finished);
/* Normal case */
tag = fdt_next_tag(fdt, offset, &nextoff);
if (tag != FDT_PROP)
FAIL("Invalid tag %x, expected FDT_PROP, finished=%d\n",
tag, fdt_finished);
if (nextoff <= 0)
FAIL("Invalid nextoff %d, expected value greater than 0, finished=%d",
nextoff, fdt_finished);
/* Get a writable ptr to the first property and corrupt the length */
prp = fdt_get_property_by_offset_w(fdt, offset, NULL);
if (!prp)
FAIL("Bad property pointer, finished=%d", fdt_finished);
/* int overflow case */
prp->len = cpu_to_fdt32(0xFFFFFFFA);
tag = fdt_next_tag(fdt, offset, &nextoff);
if (tag != FDT_END)
FAIL("Invalid tag %x, expected premature FDT_END, finished=%d",
tag, fdt_finished);
if (nextoff != -FDT_ERR_BADSTRUCTURE)
FAIL("Invalid nextoff, expected error -FDT_ERR_BADSTRUCTURE, finished=%d",
fdt_finished);
/* negative offset case */
prp->len = cpu_to_fdt32(0x7FFFFFFA);
tag = fdt_next_tag(fdt, offset, &nextoff);
if (tag != FDT_END)
FAIL("Invalid tag %x, expected premature FDT_END, finished=%d",
tag, fdt_finished);
if (nextoff != -FDT_ERR_BADSTRUCTURE)
FAIL("Invalid nextoff, expected -FDT_ERR_BADSTRUCTURE, finished=%d",
fdt_finished);
free(fdt);
}
int main(int argc, char *argv[])
{
test_init(argc, argv);
fdt_next_tag_test(false);
fdt_next_tag_test(true);
PASS();
}

View file

@ -47,6 +47,7 @@ tests = [
'get_path', 'get_path',
'get_phandle', 'get_phandle',
'get_prop_offset', 'get_prop_offset',
'get_next_tag_invalid_prop_len',
'getprop', 'getprop',
'incbin', 'incbin',
'integer-expressions', 'integer-expressions',

View file

@ -354,6 +354,7 @@ class PyLibfdtBasicTests(unittest.TestCase):
node2 = self.fdt.path_offset('/subnode@1/subsubnode') node2 = self.fdt.path_offset('/subnode@1/subsubnode')
self.assertEqual("/subnode@1", self.fdt.get_path(node)) self.assertEqual("/subnode@1", self.fdt.get_path(node))
self.assertEqual("/subnode@1/subsubnode", self.fdt.get_path(node2)) self.assertEqual("/subnode@1/subsubnode", self.fdt.get_path(node2))
self.assertEqual("/subnode@1/subsubnode", self.fdt.get_path(node2, size_hint=1))
with self.assertRaises(FdtException) as e: with self.assertRaises(FdtException) as e:
self.fdt.get_path(-1) self.fdt.get_path(-1)

View file

@ -271,6 +271,7 @@ libfdt_overlay_tests () {
run_dtc_test -I dts -O dtb -o $tree.test.dtb "$SRCDIR/$tree.dts" run_dtc_test -I dts -O dtb -o $tree.test.dtb "$SRCDIR/$tree.dts"
run_test overlay_bad_fixup overlay_base_no_symbols.test.dtb $tree.test.dtb run_test overlay_bad_fixup overlay_base_no_symbols.test.dtb $tree.test.dtb
done done
run_sh_test "$SRCDIR/dtc-fatal.sh" -I dts -O dtb -o /dev/null fixup-ref-to-path.dts
} }
# Tests to exercise dtc's overlay generation support # Tests to exercise dtc's overlay generation support
@ -512,10 +513,16 @@ libfdt_tests () {
run_dtc_test -I fs -O dts -o fs.test_tree1.test.dts $FSBASE/test_tree1 run_dtc_test -I fs -O dts -o fs.test_tree1.test.dts $FSBASE/test_tree1
run_dtc_test -I fs -O dtb -o fs.test_tree1.test.dtb $FSBASE/test_tree1 run_dtc_test -I fs -O dtb -o fs.test_tree1.test.dtb $FSBASE/test_tree1
run_test dtbs_equal_unordered -m fs.test_tree1.test.dtb test_tree1.dtb run_test dtbs_equal_unordered -m fs.test_tree1.test.dtb test_tree1.dtb
run_test get_next_tag_invalid_prop_len
## https://github.com/dgibson/dtc/issues/64 ## https://github.com/dgibson/dtc/issues/64
check_tests "$SRCDIR/phandle-args-overflow.dts" clocks_property check_tests "$SRCDIR/phandle-args-overflow.dts" clocks_property
## https://github.com/dgibson/dtc/issues/74
run_dtc_test -I dts -O dtb -o cell-overflow-results.test.dtb cell-overflow-results.dts
run_dtc_test -I dts -O dtb -o cell-overflow.test.dtb cell-overflow.dts
run_test dtbs_equal_ordered cell-overflow.test.dtb cell-overflow-results.test.dtb
# check full tests # check full tests
for good in test_tree1.dtb; do for good in test_tree1.dtb; do
run_test check_full $good run_test check_full $good