Refactored overlay_fixup_phandle to optimize efficiency by moving the
phandle lookup logic based on label outside the overlay_fixup_one_phandle call.
This avoids redundant phandle lookups when a single label is associated with multiple modifications.
Signed-off-by: Zheng Guangyuan <1628513611@qq.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
A phandle in an overlay is not supposed to overwrite a phandle that
already exists in the base dtb as this breaks references to the
respective node in the base.
So add another iteration over the fdto that checks for such overwrites
and fixes the fdto phandle's value to match the fdt's.
A test is added that checks that newly added phandles and existing
phandles work as expected.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Message-ID: <20240225175422.156393-2-u.kleine-koenig@pengutronix.de>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
In a couple of places in fdt_overlay.c we need to adjust a phandle value
in a property (either a node's phandle itself or a reference) by some
delta. Currently this is done if a fairly convoluted way, open-coding
loading the value and handling of a non-aligned reference, and then using
fdt_setprop_inplace_partial() to replace the value. This becomes much
simpler if we use fdt_getprop_w() to get a writable pointer to the value
then we can just load/store it with fdt32_{ld,st}().
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Instead of creating 2 libraries manualy, just call both_libraries and
link to the appropriate one as requested.
Fixes compilation when passing -Ddefault_libraries=both as the
static_library name is duplicated.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
If default_library is set to static, the libfdt target (which just
uses library()) is already static, so we should just use that.
This fixes this Meson error:
libfdt/meson.build:37:11: ERROR: Tried to create target "fdt", but a target of that name already exists.
Signed-off-by: Alyssa Ross <hi@alyssa.is>
Message-ID: <20240123130742.185409-1-hi@alyssa.is>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reject empty paths and negative lengths, according to the DT spec v0.4:
The convention for specifying a device path is:
/node-name-1/node-name-2/node-name-N
The path to the root node is /.
This prevents the access to path[0] from ever being out-of-bounds.
Signed-off-by: Pierre-Clément Tosi <ptosi@google.com>
Message-ID: <20231010092822.qo2nxc3g47t26dqs@google.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Ensure that the alias found matches the device tree specification v0.4:
Each property of the /aliases node defines an alias. The property
name specifies the alias name. The property value specifies the full
path to a node in the devicetree.
This protects against a stack overflow caused by
fdt_path_offset_namelen(fdt, path, namelen)
calling
fdt_path_offset(fdt, fdt_get_alias_namelen(fdt, path, namelen))
leading to infinite recursion on DTs with "circular" aliases.
This fix was originally written by Mike McTernan for Android in [1].
[1]: 9308e7f977
Signed-off-by: Pierre-Clément Tosi <ptosi@google.com>
Acked-by: Mike McTernan <mikemcternan@google.com>
Message-ID: <20231010092725.63h7c45p2fnmj577@google.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
According to the documentation, the function should default to the very
common property name <reg> when none is "specified". However, neither
passing NULL (ends up calling strlen(NULL) and segfaults) nor ""
(appends a property with an empty name) implements this behavior.
Furthermore, the test case supposed to cover this default value actually
passes the value to the function, somewhat defeating its own purpose:
/* 2. default property name */
// ...
err = fdt_appendprop_addrrange(fdt, 0, offset, "reg", addr, size);
if (err)
FAIL("Failed to set \"reg\": %s", fdt_strerror(err));
check_getprop_addrrange(fdt, 0, offset, "reg", 1);
Finally, nothing in the implementation of the function seems to attempt
to cover that use-case.
As the feature can't ever have been used by clients and as the resulting
reduced readability of the caller seems (IMO) to outweigh any potential
benefit this API would bring, remove the erroneous documentation instead
of trying to fix the function.
Reported-by: Mostafa Saleh <smostafa@google.com>
Signed-off-by: Pierre-Clément Tosi <ptosi@google.com>
Message-ID: <20230831123918.rf54emwkzgtcb7aw@google.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
The Meson build system requires that the generated shared library uses
the libfdt.so.X.Y.Z naming scheme. But the Makefile is generating
libfdt-X.Y.Z.so. We want to keep the output of both systems the same to
avoid issues, so we rename the Makefile to match Meson.
Additionally, Meson generates the base "libfdt.so -> libfdt.so.1"
symlink which the Makefile hasn't been doing, add that as well.
This shouldn't impact existing users as the linker should be looking for
libfdt.so.1 which won't change and will still point to the correct file.
Signed-off-by: Brandon Maier <brandon.maier@collins.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
These symbols were not added to the version script when they were added
to libfdt.
Signed-off-by: Brandon Maier <brandon.maier@collins.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This file is indented with tabs, but editorconfig defaults all files to
spaces.
Signed-off-by: Brandon Maier <brandon.maier@collins.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Build the libfdt with the correct version number by pulling the version
from the top-level project.
Change as suggested from https://github.com/dgibson/dtc/pull/95#issuecomment-1546933095
Signed-off-by: Brandon Maier <brandon.maier@collins.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
The function mentioned in the comment, fdt_finished(), should be
changed to fdt_finish().
Signed-off-by: Yan-Jie Wang <yanjiewtw@gmail.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
-undefined error is the equivalent of --no-undefined for the macOS
linker, but -undefined would also be understood as a valid argument for
GNU ld so we use the supported linker variant.
Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
The current documentation doesn't mention the possibility of passing a
non-absolute path and having that treated as an alias. Add that
information, along with an example (which will further be expanded in
a subsequent patch), and clarify when -FDT_ERR_BADPATH can be returned.
Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
The fdt_get_symbol_namelen() function will be used in a subsequent
patch.
Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Simplify the code by making use of the new helper.
Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Add a wrapper for fdt_getprop_namelen() allowing one to specify the node
by path instead of offset.
Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Replace the 0-length arrays in structures with proper flexible
arrays. This will avoid warnings when building under GCC 13 with
-fstrict-flex-arrays, which the Linux kernel will be doing soon:
In file included from ../lib/fdt_ro.c:2:
../lib/../scripts/dtc/libfdt/fdt_ro.c: In function 'fdt_get_name':
../lib/../scripts/dtc/libfdt/fdt_ro.c:319:24: warning: 'strrchr' reading 1 or more bytes from a region of size 0 [-Wstringop-overread]
319 | leaf = strrchr(nameptr, '/');
| ^~~~~~~~~~~~~~~~~~~~~
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Since fdt_next_tag() in a public API function all input parameters,
including the fdt blob should not be trusted. It is possible to forge
a blob with invalid property length that will cause integer overflow
during offset calculation. To prevent that, validate the property length
read from the blob before doing calculations.
Signed-off-by: Tadeusz Struk <tadeusz.struk@linaro.org>
Message-Id: <20221005232931.3016047-1-tadeusz.struk@linaro.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Add a new fdt_get_property_by_offset_w helper function.
It is a wrapper on fdt_get_property_by_offset that returns
a writable pointer to a property at a given offset.
Signed-off-by: Tadeusz Struk <tadeusz.struk@linaro.org>
Message-Id: <20221011182611.116011-1-tadeusz.struk@linaro.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
There is no need to check the VALID_DTB repeatedly, and can be combined
into one if statement.
Signed-off-by: Jia Xianhua <jiaxianhua@gmail.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Return the error code from fdt_get_name() (contained in len when the
result is NULL) instead of masking it with FDT_ERR_BADSTRUCTURE.
Fixes: fda71da26e ("libfdt: Handle failed get_name() on BEGIN_NODE")
Reported-by: Mike McTernan <mikemcternan@google.com>
Signed-off-by: Pierre-Clément Tosi <ptosi@google.com>
Message-Id: <20220729130019.804288-1-ptosi@google.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Added "static-build" option in the meson_options.txt.
Setting it to "true" allows static building.
Signed-off-by: Tero Tervala <tero.tervala@unikie.com>
Message-Id: <20220629163557.932298-1-tero.tervala@unikie.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Validate the return value of fdt_get_name() as an ill-formed DT, causing
it to fail, could result in fdt_check_full() dereferencing NULL.
fixes: a2def54799 ("libfdt: Check that the root-node name is empty")
Signed-off-by: Pierre-Clément Tosi <ptosi@google.com>
Message-Id: <20220714083848.958492-1-ptosi@google.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
When fdt_get_string return null, `namep` is not correctly reset.
From the document of `fdt_getprop_by_offset`, the parameter `namep` will
be always overwritten (that is, it will be overwritten without exception
of error occurance).
As for the caller (like
e097c097fe/native/jni/magiskboot/dtb.cpp (L42)),
the code may be like:
```cpp
size_t size;
const char *name;
auto *value = fdt_getprop_by_offset(fdt, prop, &name, &size);
```
and if `value == nullptr`, `size` is also be overwritten correctly but
`name` is not, which is quite inconsistent.
This commit makes sure `name` and `size` behavior consistently (reset to
reasonable value) when error occurs.
Signed-off-by: LoveSy <shana@zju.edu.cn>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This is done to get the target path for the overlay nodes which is very useful
in many cases. For example, Xen hypervisor needs it when applying overlays
because Xen needs to do further processing of the overlay nodes, e.g. mapping of
resources(IRQs and IOMMUs) to other VMs, creation of SMMU pagetables, etc.
Signed-off-by: Vikram Garhwal <fnu.vikram@xilinx.com>
Message-Id: <1637204036-382159-2-git-send-email-fnu.vikram@xilinx.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
UINT32_MAX is an integer of type unsigned int. UINT32_MAX + 1 overflows
unless explicitly computed as unsigned long long. This led to some
invalid addresses being treated as valid.
Cast UINT32_MAX to uint64_t explicitly.
Signed-off-by: Elvira Khabirova <e.khabirova@omp.ru>
The meson build is not building the static libfdt, so add it.
Signed-off-by: Rob Herring <robh@kernel.org>
Message-Id: <20211111003329.2347536-1-robh@kernel.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
Tested-by: Simon Glass <sjg@chromium.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
The ALIGNMENT error was missing a string, leading to <unknown error>
being returned.
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
With -Wsign-compare, compilers warn about a mismatching signedness in
the different legs of the conditional operator, in fdtget.c.
In the questionable expression, we are constructing a 16-bit value out of
two unsigned 8-bit values, however are relying on the compiler's
automatic expansion of the uint8_t to a larger type, to survive the left
shift. This larger type happens to be an "int", so this part of the
expression becomes signed.
Fix this by explicitly blowing up the uint8_t to a larger *unsigned* type,
before doing the left shift. And while we are at it, convert the hardly
readable conditional operator usage into a sane switch/case expression.
This fixes "make fdtget", when compiled with -Wsign-compare.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Message-Id: <20210618172030.9684-3-andre.przywara@arm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Coverity gets a bit confused by loading fdt_size_dt_strings() and
using it in a memmove(). In fact this is safe because the callers
have verified this information (via FDT_RW_PROBE() in fdt_pack() or
construction in fdt_open_into()).
Passing in strings_size like we already do struct_size seems to get
Coverity to follow what's going on here.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Only checking the FDT alignment in fdt_ro_probe_() means that
fdt_check_header() can pass, but then subsequent API calls fail on
alignment checks. Let's add an alignment check to fdt_check_header() so
alignment errors are found up front.
Cc: Tom Rini <trini@konsulko.com>
Cc: Frank Rowand <frowand.list@gmail.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Message-Id: <20210406190712.2118098-1-robh@kernel.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
The root node is supposed to have an empty name, but at present this is
not checked. The behaviour of such a tree is not well defined. Most
software rightly assumes that the root node is at offset 0 and does not
check the name. This oddity was discovered as part of a security
investigation into U-Boot verified boot.
Add a check for this to fdt_check_full().
Signed-off-by: Simon Glass <sjg@chromium.org>
Reported-by: Arie Haenel <arie.haenel@intel.com>
Reported-by: Julien Lenoir <julien.lenoir@intel.com>
Message-Id: <20210323010410.3222701-2-sjg@chromium.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
At present it is possible to have two root nodes and even access nodes
in the 'second' root. Such trees should not be considered valid. This
was discovered as part of a security investigation into U-Boot verified
boot.
Add a check for this to fdt_check_full().
Signed-off-by: Simon Glass <sjg@chromium.org>
Reported-by: Arie Haenel <arie.haenel@intel.com>
Reported-by: Julien Lenoir <julien.lenoir@intel.com>
Message-Id: <20210323000926.3210733-1-sjg@chromium.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Apparently the unchecked return value of the first fdt_next_tag() call in
fdt_add_subnode_namelen() is tripping Coverity Scan in some circumstances,
although it appears not to for the scan on our project itself.
This fdt_next_tag() should always return FDT_BEGIN_NODE, since otherwise
the fdt_subnode_offset_namelen() above would have returned BADOFFSET or
BADSTRUCTURE.
Still, add a check to shut Coverity up, gated by a can_assume() to avoid
bloat in small builds.
Reported-by: Ryan Long <ryan.long@oarcorp.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Changes in v3:
- Remove noop version sets
- Set version correctly on loaded fdt in fdt_open_into
Fixes: f1879e1a50 ("Add limited read-only support for older (V2 and V3) device tree to libfdt.")
Signed-off-by: Justin Covell <jujugoboom@gmail.com>
Message-Id: <20201229041749.2187-1-jujugoboom@gmail.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
There's a small inaccuracy in the comment describing these new helpers.
This corrects it, and reformats while we're there.
Fixes: f98f28ab ("libfdt: Internally perform potentially unaligned loads")
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Commits 6dcb8ba4 "libfdt: Add helpers for accessing unaligned words"
introduced changes to support unaligned reads for ARM platforms and
11738cf01f "libfdt: Don't use memcpy to handle unaligned reads on ARM"
improved the performance of these helpers.
On further discussion, while there are potential cases where we could be
used on platforms that do not fixup unaligned reads for us, making this
choice the default is very expensive in terms of binary size and access
time. To address this, introduce and use new fdt{32,64}_ld_ functions
that call fdt{32,64}_to_cpu() as was done prior to the above mentioned
commits. Leave the existing load functions as unaligned-safe and
include comments in both cases.
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Tom Rini <trini@konsulko.com>
Message-Id: <20201211022736.31657-1-trini@konsulko.com>
Tested-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
The device tree must be loaded in to memory at an 8-byte aligned
address. Add a check for this condition in fdt_ro_probe_() and a new
error code to return if we are not.
Signed-off-by: Tom Rini <trini@konsulko.com>
Message-Id: <20201104130605.28874-1-trini@konsulko.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
The meson build system allows projects to "vendor" dtc easily, thanks to
subproject(). QEMU has recently switched to meson, and adding meson
support to dtc will help to handle the QEMU submodule.
meson rules are arguably simpler to write and maintain than
the hand-crafted/custom Makefile. meson support various backends, and
default build options (including coverage, sanitizer, debug/release
etc, see: https://mesonbuild.com/Builtin-options.html)
Compare to the Makefiles, the same build targets should be built and
installed and the same tests should be run ("meson test" can be provided
extra test arguments for running the equivalent of checkm/checkv).
There is no support EXTRAVERSION/LOCAL_VERSION/CONFIG_LOCALVERSION,
instead the version is simply set with project(), and vcs_tag() is
used for git/dirty version reporting (This is most common and is
hopefully enough. If necessary, configure-time options could be added
for extra versioning.).
libfdt shared library is build following regular naming conventions:
instead of libfdt.so.1 -> libfdt-1.6.0.so (with current build-sys),
libfdt.so.1 -> libfdt.so.1.6.0. I am not sure why the current build
system use an uncommon naming pattern. I also included a libfdt.pc
pkg-config file, as convenience.
Both Linux native build and mingw cross-build pass. CI pass. Tests are
only run on native build.
The current Makefiles are left in-tree, and make/check still work.
Eventually, the Makefiles could be marked as deprecated, to start a
transition period and avoid having to maintain 2 build systems in the
near future.
(run_tests.sh could eventually be replaced by the meson test runner,
which would have several advantages in term of flexibility/features,
but this is left for another day)
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20201012073405.1682782-3-marcandre.lureau@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
The API documentation in libfdt.h seems to follow the Linux kernel's
kernel-doc format[1].
Running "scripts/kernel-doc -v -none" on the file reports some problems,
mostly missing return values and missing parameter descriptions.
Fix those up by providing the missing bits, and fixing the other small
issues reported by the script.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/doc-guide/kernel-doc.rst
Message-Id: <20201012165331.25016-1-andre.przywara@arm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
With -Wsign-compare, compilers warn about a mismatching signedness
in a comparison in fdt_strerror().
Force FDT_ERRTABSIZE to be signed (it's surely small enough to fit), so
that the types match. Also move the minus sign to errval, as this is
actually what we use in the next line.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Message-Id: <20201001164630.4980-7-andre.przywara@arm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
With -Wsign-compare, compilers warn about a mismatching signedness in
comparisons in fdt_get_string().
Introduce a new usigned variable, which holds the actual (negated)
stroffset value, so we avoid negating all the other variables and have
proper types everywhere.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Message-Id: <20201001164630.4980-6-andre.przywara@arm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
With -Wsign-compare, compilers warn about a mismatching signedness
in a comparison in fdt_setprop_inplace_namelen_partial().
fdt_getprop_namelen() will only return negative error values in "proplen"
if the return value is NULL. So we can rely on "proplen" being positive
in our case and can safely cast it to an unsigned type.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Message-Id: <20201001164630.4980-5-andre.przywara@arm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
With -Wsign-compare, compilers warn about a mismatching signedness
in a comparison in fdt_create_with_flags().
By making hdrsize a signed integer (we are sure it's a very small
number), we avoid all the casts and have matching types.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Message-Id: <20201001164630.4980-4-andre.przywara@arm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
With -Wsign-compare, compilers warn about a mismatching signedness
in comparisons in fdt_move().
This stems from "bufsize" being passed in as a signed integer, even
though we would expect a buffer size to be positive.
Short of changing the prototype, check that bufsize is not negative, and
cast it to an unsigned type in the comparison.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Message-Id: <20201001164630.4980-3-andre.przywara@arm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
With -Wsign-compare, compilers warn about a mismatching signedness
in a comparison in fdt_add_string_().
Make all variables unsigned, and express the negative offset trick via
subtractions in the code.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Message-Id: <20201001164630.4980-2-andre.przywara@arm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
With -Wsign-compare, compilers warn about a mismatching signedness
in a comparison in fdt_node_offset_by_phandle().
Uses a better suited bitwise NOT operator to denote the special value of
-1, which automatically results in an unsigned type.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Message-Id: <20200921165303.9115-14-andre.przywara@arm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
With -Wsign-compare, compilers warn about a mismatching signedness in
a comparison in overlay_update_local_node_references().
This happens because the division of a signed int by an unsigned int
promotes the dividend to unsigned first (ANSI C standard 6.1.3.8).
As in this case we basically just divide by 4, we can do the division
separately earlier, which preserves the original type.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Message-Id: <20200921165303.9115-12-andre.przywara@arm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>