From 2cd89f862cdb04d91c5d59c5b39647f7d5d5b3b8 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Mon, 21 Nov 2022 14:18:44 +1100 Subject: [PATCH] dtc: Warning rather than error on possible truncation of cell values We always evaluate integer values in cell arrays as 64-bit quantities, then truncate to the size of the array cells (32-bit by default). However to detect accidental truncation of meaningful values, we give an error if the truncated portion isn't either all 0 or all 1 bits. However, this can still give counterintuitive errors. For if the user is thinking in 2's complement 32-bit arithmetic (which would be quite natural), then they'd expect the expression (-0xffffffff-2) to evaluate to -1 (0xffffffff). However in 64-bit it evaluates to 0xfffffffeffffffff which does truncate to the expected value but trips this error message. Because of this reduce the error to only a warnings, with a somewhat more helpful message. Fixes: https://github.com/dgibson/dtc/issues/74 Signed-off-by: David Gibson --- dtc-parser.y | 11 ++++++++--- tests/cell-overflow-results.dts | 7 +++++++ tests/cell-overflow.dts | 7 +++++++ tests/run_tests.sh | 5 +++++ 4 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 tests/cell-overflow-results.dts create mode 100644 tests/cell-overflow.dts diff --git a/dtc-parser.y b/dtc-parser.y index 46457d4..bff1337 100644 --- a/dtc-parser.y +++ b/dtc-parser.y @@ -404,9 +404,14 @@ arrayprefix: * within the mask to one (i.e. | in the * mask), all bits are one. */ - if (($2 > mask) && (($2 | mask) != -1ULL)) - ERROR(&@2, "Value out of range for" - " %d-bit array element", $1.bits); + if (($2 > mask) && (($2 | mask) != -1ULL)) { + char *loc = srcpos_string(&@2); + 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); diff --git a/tests/cell-overflow-results.dts b/tests/cell-overflow-results.dts new file mode 100644 index 0000000..e7f6dad --- /dev/null +++ b/tests/cell-overflow-results.dts @@ -0,0 +1,7 @@ +/dts-v1/; + +/ { + prop1 = < 0 >; + prop2 = < 0xffffffff >; + prop3 = < 0 >; +}; diff --git a/tests/cell-overflow.dts b/tests/cell-overflow.dts new file mode 100644 index 0000000..2f940e8 --- /dev/null +++ b/tests/cell-overflow.dts @@ -0,0 +1,7 @@ +/dts-v1/; + +/ { + prop1 = < (-0xffffffff - 1) >; + prop2 = < (-0xffffffff - 2) >; + prop3 = < ((-0xffffffff - 1) * 2) >; +}; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 46678cb..91350ad 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -518,6 +518,11 @@ libfdt_tests () { ## https://github.com/dgibson/dtc/issues/64 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 for good in test_tree1.dtb; do run_test check_full $good