[Skiboot] [PATCH] libfdt: sync to upstream dtc.git commit 45f3d1a095dd

Cédric Le Goater clg at kaod.org
Thu Dec 9 19:07:25 AEDT 2021


On 12/8/21 09:18, Nicholas Piggin wrote:
> sync to upstream dtc.git commit 45f3d1a095dd ("libfdt: overlay: make
> overlay_get_target() public") from previous upstream sync commit 243176c
> ("Fix bogus error on rebuild"). This mainly updates license headers,
> fixes one or two small bugs, sign mismatches, integer overflow, and
> cases of undefined behaviour, compile warnings for newer compilers, and
> introduces some checking options (which might be useful to speed up fdt
> operations on awan).
> 
> The recipe for this patch is:
> 
>    $ cp ../dtc/libfdt/* libfdt/
>    $ git add libfdt/fdt_check.c
>    $ rm libfdt/meson.build
> 
>    Then add the INT32_MAX define to libc/include/limits.h, and update
>    libfdt/Makefile.inc and libfdt/README.skiboot.
> 
> Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
> ---
> No particular reason for the update except to stay somewhat current
> with upstream.

A test failed once :

   https://github.com/ruscur/skiboot/runs/4454512450?check_suite_focus=true

but I could not reproduce. Bizarre.

Thanks,

C.

> 
> Thanks,
> Nick
> 
>   libc/include/limits.h    |   1 +
>   libfdt/Makefile.inc      |   3 +-
>   libfdt/Makefile.libfdt   |   3 +-
>   libfdt/README.skiboot    |   8 +-
>   libfdt/fdt.c             | 186 +++++++++++++++----------------
>   libfdt/fdt.h             |  47 +-------
>   libfdt/fdt_addresses.c   |  57 ++--------
>   libfdt/fdt_check.c       |  93 ++++++++++++++++
>   libfdt/fdt_empty_tree.c  |  47 +-------
>   libfdt/fdt_overlay.c     | 107 +++++-------------
>   libfdt/fdt_ro.c          | 229 +++++++++++++--------------------------
>   libfdt/fdt_rw.c          | 111 ++++++++-----------
>   libfdt/fdt_strerror.c    |  51 +--------
>   libfdt/fdt_sw.c          |  97 +++++------------
>   libfdt/fdt_wip.c         |  49 +--------
>   libfdt/libfdt.h          | 215 ++++++++++++++++++++----------------
>   libfdt/libfdt_env.h      |  47 +-------
>   libfdt/libfdt_internal.h | 200 +++++++++++++++++++++++++---------
>   libfdt/version.lds       |   3 +
>   19 files changed, 665 insertions(+), 889 deletions(-)
>   create mode 100644 libfdt/fdt_check.c
> 
> diff --git a/libc/include/limits.h b/libc/include/limits.h
> index bd67c7ecc..bfde9635b 100644
> --- a/libc/include/limits.h
> +++ b/libc/include/limits.h
> @@ -32,5 +32,6 @@
>   #define		CHAR_BIT	8
>   
>   #define 	UINT32_MAX	UINT_MAX
> +#define 	INT32_MAX	INT_MAX
>   
>   #endif
> diff --git a/libfdt/Makefile.inc b/libfdt/Makefile.inc
> index f0dd995ec..06f4429a9 100644
> --- a/libfdt/Makefile.inc
> +++ b/libfdt/Makefile.inc
> @@ -1,10 +1,11 @@
> +# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
>   # Makefile.inc
>   #
>   # LIBFDT_ variables are taken from Makefile.libfdt
>   
>   LIBFDT_INCLUDES = fdt.h libfdt.h libfdt_env.h
>   LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c fdt_empty_tree.c \
> -	fdt_addresses.c fdt_overlay.c
> +	fdt_addresses.c fdt_overlay.c fdt_check.c
>   LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)
>   
>   CFLAGS_SKIP_libfdt/ = -Wsuggest-attribute=const -Wsuggest-attribute=noreturn
> diff --git a/libfdt/Makefile.libfdt b/libfdt/Makefile.libfdt
> index 193da8c99..b6d8fc02d 100644
> --- a/libfdt/Makefile.libfdt
> +++ b/libfdt/Makefile.libfdt
> @@ -1,3 +1,4 @@
> +# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
>   # Makefile.libfdt
>   #
>   # This is not a complete Makefile of itself.  Instead, it is designed to
> @@ -7,7 +8,7 @@ LIBFDT_soname = libfdt.$(SHAREDLIB_EXT).1
>   LIBFDT_INCLUDES = fdt.h libfdt.h libfdt_env.h
>   LIBFDT_VERSION = version.lds
>   LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c fdt_empty_tree.c \
> -	fdt_addresses.c fdt_overlay.c
> +	fdt_addresses.c fdt_overlay.c fdt_check.c
>   LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)
>   LIBFDT_LIB = libfdt-$(DTC_VERSION).$(SHAREDLIB_EXT)
>   
> diff --git a/libfdt/README.skiboot b/libfdt/README.skiboot
> index 5225af37c..365c285dc 100644
> --- a/libfdt/README.skiboot
> +++ b/libfdt/README.skiboot
> @@ -1,10 +1,12 @@
>   skiboot/libfdt/ is a minimally modified version of upstream libfdt that is
>   distributed with the dtc project hosted at github.com/dgibson/dtc.git.
>   
> -This version is taken from dtc commit 243176c ("Fix bogus error on rebuild")
> +This version is taken from dtc.git commit 45f3d1a095dd ("libfdt: overlay: make
> +overlay_get_target() public") by copying all files from the libfdt/ directory.
>   
> -The modifications from upstream are the additions of this file, and
> -Makefile.inc which has been derived from Makefile.libfdt.
> +The only modifications from the upstream source are the additions of this
> +file, and Makefile.inc which has been derived from Makefile.libfdt, and
> +the removal of meson.build.
>   
>   Local libfdt changes should be kept to a minimum, and submitted upstream if
>   possible.
> diff --git a/libfdt/fdt.c b/libfdt/fdt.c
> index ae03b1112..9fe7cf4b7 100644
> --- a/libfdt/fdt.c
> +++ b/libfdt/fdt.c
> @@ -1,52 +1,7 @@
> +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
>   /*
>    * libfdt - Flat Device Tree manipulation
>    * Copyright (C) 2006 David Gibson, IBM Corporation.
> - *
> - * libfdt is dual licensed: you can use it either under the terms of
> - * the GPL, or the BSD license, at your option.
> - *
> - *  a) This library is free software; you can redistribute it and/or
> - *     modify it under the terms of the GNU General Public License as
> - *     published by the Free Software Foundation; either version 2 of the
> - *     License, or (at your option) any later version.
> - *
> - *     This library is distributed in the hope that it will be useful,
> - *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> - *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - *     GNU General Public License for more details.
> - *
> - *     You should have received a copy of the GNU General Public
> - *     License along with this library; if not, write to the Free
> - *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
> - *     MA 02110-1301 USA
> - *
> - * Alternatively,
> - *
> - *  b) Redistribution and use in source and binary forms, with or
> - *     without modification, are permitted provided that the following
> - *     conditions are met:
> - *
> - *     1. Redistributions of source code must retain the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer.
> - *     2. Redistributions in binary form must reproduce the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer in the documentation and/or other materials
> - *        provided with the distribution.
> - *
> - *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> - *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
> - *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> - *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
> - *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> - *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> - *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> - *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> - *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
> - *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>    */
>   #include "libfdt_env.h"
>   
> @@ -60,23 +15,38 @@
>    * that the given buffer contains what appears to be a flattened
>    * device tree with sane information in its header.
>    */
> -int fdt_ro_probe_(const void *fdt)
> +int32_t fdt_ro_probe_(const void *fdt)
>   {
> +	uint32_t totalsize = fdt_totalsize(fdt);
> +
> +	if (can_assume(VALID_DTB))
> +		return totalsize;
> +
> +	/* The device tree must be at an 8-byte aligned address */
> +	if ((uintptr_t)fdt & 7)
> +		return -FDT_ERR_ALIGNMENT;
> +
>   	if (fdt_magic(fdt) == FDT_MAGIC) {
>   		/* Complete tree */
> -		if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
> -			return -FDT_ERR_BADVERSION;
> -		if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
> -			return -FDT_ERR_BADVERSION;
> +		if (!can_assume(LATEST)) {
> +			if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
> +				return -FDT_ERR_BADVERSION;
> +			if (fdt_last_comp_version(fdt) >
> +					FDT_LAST_SUPPORTED_VERSION)
> +				return -FDT_ERR_BADVERSION;
> +		}
>   	} else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
>   		/* Unfinished sequential-write blob */
> -		if (fdt_size_dt_struct(fdt) == 0)
> +		if (!can_assume(VALID_INPUT) && fdt_size_dt_struct(fdt) == 0)
>   			return -FDT_ERR_BADSTATE;
>   	} else {
>   		return -FDT_ERR_BADMAGIC;
>   	}
>   
> -	return 0;
> +	if (totalsize < INT32_MAX)
> +		return totalsize;
> +	else
> +		return -FDT_ERR_TRUNCATED;
>   }
>   
>   static int check_off_(uint32_t hdrsize, uint32_t totalsize, uint32_t off)
> @@ -110,58 +80,82 @@ size_t fdt_header_size_(uint32_t version)
>   		return FDT_V17_SIZE;
>   }
>   
> +size_t fdt_header_size(const void *fdt)
> +{
> +	return can_assume(LATEST) ? FDT_V17_SIZE :
> +		fdt_header_size_(fdt_version(fdt));
> +}
> +
>   int fdt_check_header(const void *fdt)
>   {
>   	size_t hdrsize;
>   
> +	/* The device tree must be at an 8-byte aligned address */
> +	if ((uintptr_t)fdt & 7)
> +		return -FDT_ERR_ALIGNMENT;
> +
>   	if (fdt_magic(fdt) != FDT_MAGIC)
>   		return -FDT_ERR_BADMAGIC;
> +	if (!can_assume(LATEST)) {
> +		if ((fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
> +		    || (fdt_last_comp_version(fdt) >
> +			FDT_LAST_SUPPORTED_VERSION))
> +			return -FDT_ERR_BADVERSION;
> +		if (fdt_version(fdt) < fdt_last_comp_version(fdt))
> +			return -FDT_ERR_BADVERSION;
> +	}
>   	hdrsize = fdt_header_size(fdt);
> -	if ((fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
> -	    || (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION))
> -		return -FDT_ERR_BADVERSION;
> -	if (fdt_version(fdt) < fdt_last_comp_version(fdt))
> -		return -FDT_ERR_BADVERSION;
> -
> -	if ((fdt_totalsize(fdt) < hdrsize)
> -	    || (fdt_totalsize(fdt) > INT_MAX))
> -		return -FDT_ERR_TRUNCATED;
> +	if (!can_assume(VALID_DTB)) {
>   
> -	/* Bounds check memrsv block */
> -	if (!check_off_(hdrsize, fdt_totalsize(fdt), fdt_off_mem_rsvmap(fdt)))
> -		return -FDT_ERR_TRUNCATED;
> +		if ((fdt_totalsize(fdt) < hdrsize)
> +		    || (fdt_totalsize(fdt) > INT_MAX))
> +			return -FDT_ERR_TRUNCATED;
>   
> -	/* Bounds check structure block */
> -	if (fdt_version(fdt) < 17) {
> +		/* Bounds check memrsv block */
>   		if (!check_off_(hdrsize, fdt_totalsize(fdt),
> -				fdt_off_dt_struct(fdt)))
> +				fdt_off_mem_rsvmap(fdt)))
>   			return -FDT_ERR_TRUNCATED;
> -	} else {
> +	}
> +
> +	if (!can_assume(VALID_DTB)) {
> +		/* Bounds check structure block */
> +		if (!can_assume(LATEST) && fdt_version(fdt) < 17) {
> +			if (!check_off_(hdrsize, fdt_totalsize(fdt),
> +					fdt_off_dt_struct(fdt)))
> +				return -FDT_ERR_TRUNCATED;
> +		} else {
> +			if (!check_block_(hdrsize, fdt_totalsize(fdt),
> +					  fdt_off_dt_struct(fdt),
> +					  fdt_size_dt_struct(fdt)))
> +				return -FDT_ERR_TRUNCATED;
> +		}
> +
> +		/* Bounds check strings block */
>   		if (!check_block_(hdrsize, fdt_totalsize(fdt),
> -				  fdt_off_dt_struct(fdt),
> -				  fdt_size_dt_struct(fdt)))
> +				  fdt_off_dt_strings(fdt),
> +				  fdt_size_dt_strings(fdt)))
>   			return -FDT_ERR_TRUNCATED;
>   	}
>   
> -	/* Bounds check strings block */
> -	if (!check_block_(hdrsize, fdt_totalsize(fdt),
> -			  fdt_off_dt_strings(fdt), fdt_size_dt_strings(fdt)))
> -		return -FDT_ERR_TRUNCATED;
> -
>   	return 0;
>   }
>   
>   const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
>   {
> -	unsigned absoffset = offset + fdt_off_dt_struct(fdt);
> +	unsigned int uoffset = offset;
> +	unsigned int absoffset = offset + fdt_off_dt_struct(fdt);
>   
> -	if ((absoffset < offset)
> -	    || ((absoffset + len) < absoffset)
> -	    || (absoffset + len) > fdt_totalsize(fdt))
> +	if (offset < 0)
>   		return NULL;
>   
> -	if (fdt_version(fdt) >= 0x11)
> -		if (((offset + len) < offset)
> +	if (!can_assume(VALID_INPUT))
> +		if ((absoffset < uoffset)
> +		    || ((absoffset + len) < absoffset)
> +		    || (absoffset + len) > fdt_totalsize(fdt))
> +			return NULL;
> +
> +	if (can_assume(LATEST) || fdt_version(fdt) >= 0x11)
> +		if (((uoffset + len) < uoffset)
>   		    || ((offset + len) > fdt_size_dt_struct(fdt)))
>   			return NULL;
>   
> @@ -177,7 +171,7 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
>   
>   	*nextoffset = -FDT_ERR_TRUNCATED;
>   	tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
> -	if (!tagp)
> +	if (!can_assume(VALID_DTB) && !tagp)
>   		return FDT_END; /* premature end */
>   	tag = fdt32_to_cpu(*tagp);
>   	offset += FDT_TAGSIZE;
> @@ -189,18 +183,19 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
>   		do {
>   			p = fdt_offset_ptr(fdt, offset++, 1);
>   		} while (p && (*p != '\0'));
> -		if (!p)
> +		if (!can_assume(VALID_DTB) && !p)
>   			return FDT_END; /* premature end */
>   		break;
>   
>   	case FDT_PROP:
>   		lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
> -		if (!lenp)
> +		if (!can_assume(VALID_DTB) && !lenp)
>   			return FDT_END; /* premature end */
>   		/* skip-name offset, length and value */
>   		offset += sizeof(struct fdt_property) - FDT_TAGSIZE
>   			+ fdt32_to_cpu(*lenp);
> -		if (fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 &&
> +		if (!can_assume(LATEST) &&
> +		    fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 &&
>   		    ((offset - fdt32_to_cpu(*lenp)) % 8) != 0)
>   			offset += 4;
>   		break;
> @@ -223,8 +218,11 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
>   
>   int fdt_check_node_offset_(const void *fdt, int offset)
>   {
> -	if ((offset < 0) || (offset % FDT_TAGSIZE)
> -	    || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
> +	if (!can_assume(VALID_INPUT)
> +	    && ((offset < 0) || (offset % FDT_TAGSIZE)))
> +		return -FDT_ERR_BADOFFSET;
> +
> +	if (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE)
>   		return -FDT_ERR_BADOFFSET;
>   
>   	return offset;
> @@ -232,8 +230,11 @@ int fdt_check_node_offset_(const void *fdt, int offset)
>   
>   int fdt_check_prop_offset_(const void *fdt, int offset)
>   {
> -	if ((offset < 0) || (offset % FDT_TAGSIZE)
> -	    || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP))
> +	if (!can_assume(VALID_INPUT)
> +	    && ((offset < 0) || (offset % FDT_TAGSIZE)))
> +		return -FDT_ERR_BADOFFSET;
> +
> +	if (fdt_next_tag(fdt, offset, &offset) != FDT_PROP)
>   		return -FDT_ERR_BADOFFSET;
>   
>   	return offset;
> @@ -321,9 +322,12 @@ const char *fdt_find_string_(const char *strtab, int tabsize, const char *s)
>   
>   int fdt_move(const void *fdt, void *buf, int bufsize)
>   {
> +	if (!can_assume(VALID_INPUT) && bufsize < 0)
> +		return -FDT_ERR_NOSPACE;
> +
>   	FDT_RO_PROBE(fdt);
>   
> -	if (fdt_totalsize(fdt) > bufsize)
> +	if (fdt_totalsize(fdt) > (unsigned int)bufsize)
>   		return -FDT_ERR_NOSPACE;
>   
>   	memmove(buf, fdt, fdt_totalsize(fdt));
> diff --git a/libfdt/fdt.h b/libfdt/fdt.h
> index 74961f902..f2e68807f 100644
> --- a/libfdt/fdt.h
> +++ b/libfdt/fdt.h
> @@ -1,55 +1,10 @@
> +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */
>   #ifndef FDT_H
>   #define FDT_H
>   /*
>    * libfdt - Flat Device Tree manipulation
>    * Copyright (C) 2006 David Gibson, IBM Corporation.
>    * Copyright 2012 Kim Phillips, Freescale Semiconductor.
> - *
> - * libfdt is dual licensed: you can use it either under the terms of
> - * the GPL, or the BSD license, at your option.
> - *
> - *  a) This library is free software; you can redistribute it and/or
> - *     modify it under the terms of the GNU General Public License as
> - *     published by the Free Software Foundation; either version 2 of the
> - *     License, or (at your option) any later version.
> - *
> - *     This library is distributed in the hope that it will be useful,
> - *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> - *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - *     GNU General Public License for more details.
> - *
> - *     You should have received a copy of the GNU General Public
> - *     License along with this library; if not, write to the Free
> - *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
> - *     MA 02110-1301 USA
> - *
> - * Alternatively,
> - *
> - *  b) Redistribution and use in source and binary forms, with or
> - *     without modification, are permitted provided that the following
> - *     conditions are met:
> - *
> - *     1. Redistributions of source code must retain the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer.
> - *     2. Redistributions in binary form must reproduce the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer in the documentation and/or other materials
> - *        provided with the distribution.
> - *
> - *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> - *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
> - *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> - *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
> - *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> - *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> - *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> - *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> - *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
> - *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>    */
>   
>   #ifndef __ASSEMBLY__
> diff --git a/libfdt/fdt_addresses.c b/libfdt/fdt_addresses.c
> index 2cc997ea5..c40ba094f 100644
> --- a/libfdt/fdt_addresses.c
> +++ b/libfdt/fdt_addresses.c
> @@ -1,53 +1,8 @@
> +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
>   /*
>    * libfdt - Flat Device Tree manipulation
>    * Copyright (C) 2014 David Gibson <david at gibson.dropbear.id.au>
>    * Copyright (C) 2018 embedded brains GmbH
> - *
> - * libfdt is dual licensed: you can use it either under the terms of
> - * the GPL, or the BSD license, at your option.
> - *
> - *  a) This library is free software; you can redistribute it and/or
> - *     modify it under the terms of the GNU General Public License as
> - *     published by the Free Software Foundation; either version 2 of the
> - *     License, or (at your option) any later version.
> - *
> - *     This library is distributed in the hope that it will be useful,
> - *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> - *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - *     GNU General Public License for more details.
> - *
> - *     You should have received a copy of the GNU General Public
> - *     License along with this library; if not, write to the Free
> - *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
> - *     MA 02110-1301 USA
> - *
> - * Alternatively,
> - *
> - *  b) Redistribution and use in source and binary forms, with or
> - *     without modification, are permitted provided that the following
> - *     conditions are met:
> - *
> - *     1. Redistributions of source code must retain the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer.
> - *     2. Redistributions in binary form must reproduce the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer in the documentation and/or other materials
> - *        provided with the distribution.
> - *
> - *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> - *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
> - *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> - *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
> - *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> - *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> - *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> - *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> - *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
> - *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>    */
>   #include "libfdt_env.h"
>   
> @@ -59,7 +14,7 @@
>   static int fdt_cells(const void *fdt, int nodeoffset, const char *name)
>   {
>   	const fdt32_t *c;
> -	int val;
> +	uint32_t val;
>   	int len;
>   
>   	c = fdt_getprop(fdt, nodeoffset, name, &len);
> @@ -70,10 +25,10 @@ static int fdt_cells(const void *fdt, int nodeoffset, const char *name)
>   		return -FDT_ERR_BADNCELLS;
>   
>   	val = fdt32_to_cpu(*c);
> -	if ((val <= 0) || (val > FDT_MAX_NCELLS))
> +	if (val > FDT_MAX_NCELLS)
>   		return -FDT_ERR_BADNCELLS;
>   
> -	return val;
> +	return (int)val;
>   }
>   
>   int fdt_address_cells(const void *fdt, int nodeoffset)
> @@ -81,6 +36,8 @@ int fdt_address_cells(const void *fdt, int nodeoffset)
>   	int val;
>   
>   	val = fdt_cells(fdt, nodeoffset, "#address-cells");
> +	if (val == 0)
> +		return -FDT_ERR_BADNCELLS;
>   	if (val == -FDT_ERR_NOTFOUND)
>   		return 2;
>   	return val;
> @@ -116,7 +73,7 @@ int fdt_appendprop_addrrange(void *fdt, int parent, int nodeoffset,
>   	/* check validity of address */
>   	prop = data;
>   	if (addr_cells == 1) {
> -		if ((addr > UINT32_MAX) || ((UINT32_MAX + 1 - addr) < size))
> +		if ((addr > UINT32_MAX) || (((uint64_t) UINT32_MAX + 1 - addr) < size))
>   			return -FDT_ERR_BADVALUE;
>   
>   		fdt32_st(prop, (uint32_t)addr);
> diff --git a/libfdt/fdt_check.c b/libfdt/fdt_check.c
> new file mode 100644
> index 000000000..fa410a86e
> --- /dev/null
> +++ b/libfdt/fdt_check.c
> @@ -0,0 +1,93 @@
> +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
> +/*
> + * libfdt - Flat Device Tree manipulation
> + * Copyright (C) 2006 David Gibson, IBM Corporation.
> + */
> +#include "libfdt_env.h"
> +
> +#include <fdt.h>
> +#include <libfdt.h>
> +
> +#include "libfdt_internal.h"
> +
> +int fdt_check_full(const void *fdt, size_t bufsize)
> +{
> +	int err;
> +	int num_memrsv;
> +	int offset, nextoffset = 0;
> +	uint32_t tag;
> +	unsigned int depth = 0;
> +	const void *prop;
> +	const char *propname;
> +	bool expect_end = false;
> +
> +	if (bufsize < FDT_V1_SIZE)
> +		return -FDT_ERR_TRUNCATED;
> +	if (bufsize < fdt_header_size(fdt))
> +		return -FDT_ERR_TRUNCATED;
> +	err = fdt_check_header(fdt);
> +	if (err != 0)
> +		return err;
> +	if (bufsize < fdt_totalsize(fdt))
> +		return -FDT_ERR_TRUNCATED;
> +
> +	num_memrsv = fdt_num_mem_rsv(fdt);
> +	if (num_memrsv < 0)
> +		return num_memrsv;
> +
> +	while (1) {
> +		offset = nextoffset;
> +		tag = fdt_next_tag(fdt, offset, &nextoffset);
> +
> +		if (nextoffset < 0)
> +			return nextoffset;
> +
> +		/* If we see two root nodes, something is wrong */
> +		if (expect_end && tag != FDT_END)
> +			return -FDT_ERR_BADSTRUCTURE;
> +
> +		switch (tag) {
> +		case FDT_NOP:
> +			break;
> +
> +		case FDT_END:
> +			if (depth != 0)
> +				return -FDT_ERR_BADSTRUCTURE;
> +			return 0;
> +
> +		case FDT_BEGIN_NODE:
> +			depth++;
> +			if (depth > INT_MAX)
> +				return -FDT_ERR_BADSTRUCTURE;
> +
> +			/* The root node must have an empty name */
> +			if (depth == 1) {
> +				const char *name;
> +				int len;
> +
> +				name = fdt_get_name(fdt, offset, &len);
> +				if (*name || len)
> +					return -FDT_ERR_BADSTRUCTURE;
> +			}
> +			break;
> +
> +		case FDT_END_NODE:
> +			if (depth == 0)
> +				return -FDT_ERR_BADSTRUCTURE;
> +			depth--;
> +			if (depth == 0)
> +				expect_end = true;
> +			break;
> +
> +		case FDT_PROP:
> +			prop = fdt_getprop_by_offset(fdt, offset, &propname,
> +						     &err);
> +			if (!prop)
> +				return err;
> +			break;
> +
> +		default:
> +			return -FDT_ERR_INTERNAL;
> +		}
> +	}
> +}
> diff --git a/libfdt/fdt_empty_tree.c b/libfdt/fdt_empty_tree.c
> index f2ae9b77c..49d54d44b 100644
> --- a/libfdt/fdt_empty_tree.c
> +++ b/libfdt/fdt_empty_tree.c
> @@ -1,52 +1,7 @@
> +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
>   /*
>    * libfdt - Flat Device Tree manipulation
>    * Copyright (C) 2012 David Gibson, IBM Corporation.
> - *
> - * libfdt is dual licensed: you can use it either under the terms of
> - * the GPL, or the BSD license, at your option.
> - *
> - *  a) This library is free software; you can redistribute it and/or
> - *     modify it under the terms of the GNU General Public License as
> - *     published by the Free Software Foundation; either version 2 of the
> - *     License, or (at your option) any later version.
> - *
> - *     This library is distributed in the hope that it will be useful,
> - *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> - *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - *     GNU General Public License for more details.
> - *
> - *     You should have received a copy of the GNU General Public
> - *     License along with this library; if not, write to the Free
> - *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
> - *     MA 02110-1301 USA
> - *
> - * Alternatively,
> - *
> - *  b) Redistribution and use in source and binary forms, with or
> - *     without modification, are permitted provided that the following
> - *     conditions are met:
> - *
> - *     1. Redistributions of source code must retain the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer.
> - *     2. Redistributions in binary form must reproduce the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer in the documentation and/or other materials
> - *        provided with the distribution.
> - *
> - *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> - *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
> - *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> - *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
> - *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> - *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> - *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> - *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> - *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
> - *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>    */
>   #include "libfdt_env.h"
>   
> diff --git a/libfdt/fdt_overlay.c b/libfdt/fdt_overlay.c
> index 2ad93d223..5c0c3981b 100644
> --- a/libfdt/fdt_overlay.c
> +++ b/libfdt/fdt_overlay.c
> @@ -1,53 +1,8 @@
> +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
>   /*
>    * libfdt - Flat Device Tree manipulation
>    * Copyright (C) 2016 Free Electrons
>    * Copyright (C) 2016 NextThing Co.
> - *
> - * libfdt is dual licensed: you can use it either under the terms of
> - * the GPL, or the BSD license, at your option.
> - *
> - *  a) This library is free software; you can redistribute it and/or
> - *     modify it under the terms of the GNU General Public License as
> - *     published by the Free Software Foundation; either version 2 of the
> - *     License, or (at your option) any later version.
> - *
> - *     This library is distributed in the hope that it will be useful,
> - *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> - *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - *     GNU General Public License for more details.
> - *
> - *     You should have received a copy of the GNU General Public
> - *     License along with this library; if not, write to the Free
> - *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
> - *     MA 02110-1301 USA
> - *
> - * Alternatively,
> - *
> - *  b) Redistribution and use in source and binary forms, with or
> - *     without modification, are permitted provided that the following
> - *     conditions are met:
> - *
> - *     1. Redistributions of source code must retain the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer.
> - *     2. Redistributions in binary form must reproduce the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer in the documentation and/or other materials
> - *        provided with the distribution.
> - *
> - *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> - *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
> - *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> - *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
> - *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> - *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> - *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> - *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> - *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
> - *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>    */
>   #include "libfdt_env.h"
>   
> @@ -85,37 +40,22 @@ static uint32_t overlay_get_target_phandle(const void *fdto, int fragment)
>   	return fdt32_to_cpu(*val);
>   }
>   
> -/**
> - * overlay_get_target - retrieves the offset of a fragment's target
> - * @fdt: Base device tree blob
> - * @fdto: Device tree overlay blob
> - * @fragment: node offset of the fragment in the overlay
> - * @pathp: pointer which receives the path of the target (or NULL)
> - *
> - * overlay_get_target() retrieves the target offset in the base
> - * device tree of a fragment, no matter how the actual targetting is
> - * done (through a phandle or a path)
> - *
> - * returns:
> - *      the targetted node offset in the base device tree
> - *      Negative error code on error
> - */
> -static int overlay_get_target(const void *fdt, const void *fdto,
> -			      int fragment, char const **pathp)
> +int fdt_overlay_target_offset(const void *fdt, const void *fdto,
> +			      int fragment_offset, char const **pathp)
>   {
>   	uint32_t phandle;
>   	const char *path = NULL;
>   	int path_len = 0, ret;
>   
>   	/* Try first to do a phandle based lookup */
> -	phandle = overlay_get_target_phandle(fdto, fragment);
> +	phandle = overlay_get_target_phandle(fdto, fragment_offset);
>   	if (phandle == (uint32_t)-1)
>   		return -FDT_ERR_BADPHANDLE;
>   
>   	/* no phandle, try path */
>   	if (!phandle) {
>   		/* And then a path based lookup */
> -		path = fdt_getprop(fdto, fragment, "target-path", &path_len);
> +		path = fdt_getprop(fdto, fragment_offset, "target-path", &path_len);
>   		if (path)
>   			ret = fdt_path_offset(fdt, path);
>   		else
> @@ -286,6 +226,7 @@ static int overlay_update_local_node_references(void *fdto,
>   
>   		if (fixup_len % sizeof(uint32_t))
>   			return -FDT_ERR_BADOVERLAY;
> +		fixup_len /= sizeof(uint32_t);
>   
>   		tree_val = fdt_getprop(fdto, tree_node, name, &tree_len);
>   		if (!tree_val) {
> @@ -295,7 +236,7 @@ static int overlay_update_local_node_references(void *fdto,
>   			return tree_len;
>   		}
>   
> -		for (i = 0; i < (fixup_len / sizeof(uint32_t)); i++) {
> +		for (i = 0; i < fixup_len; i++) {
>   			fdt32_t adj_val;
>   			uint32_t poffset;
>   
> @@ -680,7 +621,7 @@ static int overlay_merge(void *fdt, void *fdto)
>   		if (overlay < 0)
>   			return overlay;
>   
> -		target = overlay_get_target(fdt, fdto, fragment, NULL);
> +		target = fdt_overlay_target_offset(fdt, fdto, fragment, NULL);
>   		if (target < 0)
>   			return target;
>   
> @@ -778,26 +719,36 @@ static int overlay_symbol_update(void *fdt, void *fdto)
>   		/* keep end marker to avoid strlen() */
>   		e = path + path_len;
>   
> -		/* format: /<fragment-name>/__overlay__/<relative-subnode-path> */
> -
>   		if (*path != '/')
>   			return -FDT_ERR_BADVALUE;
>   
>   		/* get fragment name first */
>   		s = strchr(path + 1, '/');
> -		if (!s)
> -			return -FDT_ERR_BADOVERLAY;
> +		if (!s) {
> +			/* Symbol refers to something that won't end
> +			 * up in the target tree */
> +			continue;
> +		}
>   
>   		frag_name = path + 1;
>   		frag_name_len = s - path - 1;
>   
>   		/* verify format; safe since "s" lies in \0 terminated prop */
>   		len = sizeof("/__overlay__/") - 1;
> -		if ((e - s) < len || memcmp(s, "/__overlay__/", len))
> -			return -FDT_ERR_BADOVERLAY;
> -
> -		rel_path = s + len;
> -		rel_path_len = e - rel_path;
> +		if ((e - s) > len && (memcmp(s, "/__overlay__/", len) == 0)) {
> +			/* /<fragment-name>/__overlay__/<relative-subnode-path> */
> +			rel_path = s + len;
> +			rel_path_len = e - rel_path - 1;
> +		} else if ((e - s) == len
> +			   && (memcmp(s, "/__overlay__", len - 1) == 0)) {
> +			/* /<fragment-name>/__overlay__ */
> +			rel_path = "";
> +			rel_path_len = 0;
> +		} else {
> +			/* Symbol refers to something that won't end
> +			 * up in the target tree */
> +			continue;
> +		}
>   
>   		/* find the fragment index in which the symbol lies */
>   		ret = fdt_subnode_offset_namelen(fdto, 0, frag_name,
> @@ -813,7 +764,7 @@ static int overlay_symbol_update(void *fdt, void *fdto)
>   			return -FDT_ERR_BADOVERLAY;
>   
>   		/* get the target of the fragment */
> -		ret = overlay_get_target(fdt, fdto, fragment, &target_path);
> +		ret = fdt_overlay_target_offset(fdt, fdto, fragment, &target_path);
>   		if (ret < 0)
>   			return ret;
>   		target = ret;
> @@ -835,7 +786,7 @@ static int overlay_symbol_update(void *fdt, void *fdto)
>   
>   		if (!target_path) {
>   			/* again in case setprop_placeholder changed it */
> -			ret = overlay_get_target(fdt, fdto, fragment, &target_path);
> +			ret = fdt_overlay_target_offset(fdt, fdto, fragment, &target_path);
>   			if (ret < 0)
>   				return ret;
>   			target = ret;
> diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c
> index 2c393a100..17584da25 100644
> --- a/libfdt/fdt_ro.c
> +++ b/libfdt/fdt_ro.c
> @@ -1,52 +1,7 @@
> +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
>   /*
>    * libfdt - Flat Device Tree manipulation
>    * Copyright (C) 2006 David Gibson, IBM Corporation.
> - *
> - * libfdt is dual licensed: you can use it either under the terms of
> - * the GPL, or the BSD license, at your option.
> - *
> - *  a) This library is free software; you can redistribute it and/or
> - *     modify it under the terms of the GNU General Public License as
> - *     published by the Free Software Foundation; either version 2 of the
> - *     License, or (at your option) any later version.
> - *
> - *     This library is distributed in the hope that it will be useful,
> - *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> - *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - *     GNU General Public License for more details.
> - *
> - *     You should have received a copy of the GNU General Public
> - *     License along with this library; if not, write to the Free
> - *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
> - *     MA 02110-1301 USA
> - *
> - * Alternatively,
> - *
> - *  b) Redistribution and use in source and binary forms, with or
> - *     without modification, are permitted provided that the following
> - *     conditions are met:
> - *
> - *     1. Redistributions of source code must retain the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer.
> - *     2. Redistributions in binary form must reproduce the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer in the documentation and/or other materials
> - *        provided with the distribution.
> - *
> - *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> - *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
> - *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> - *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
> - *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> - *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> - *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> - *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> - *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
> - *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>    */
>   #include "libfdt_env.h"
>   
> @@ -78,35 +33,47 @@ static int fdt_nodename_eq_(const void *fdt, int offset,
>   
>   const char *fdt_get_string(const void *fdt, int stroffset, int *lenp)
>   {
> -	uint32_t absoffset = stroffset + fdt_off_dt_strings(fdt);
> +	int32_t totalsize;
> +	uint32_t absoffset;
>   	size_t len;
>   	int err;
>   	const char *s, *n;
>   
> -	err = fdt_ro_probe_(fdt);
> -	if (err != 0)
> +	if (can_assume(VALID_INPUT)) {
> +		s = (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
> +
> +		if (lenp)
> +			*lenp = strlen(s);
> +		return s;
> +	}
> +	totalsize = fdt_ro_probe_(fdt);
> +	err = totalsize;
> +	if (totalsize < 0)
>   		goto fail;
>   
>   	err = -FDT_ERR_BADOFFSET;
> -	if (absoffset >= fdt_totalsize(fdt))
> +	absoffset = stroffset + fdt_off_dt_strings(fdt);
> +	if (absoffset >= (unsigned)totalsize)
>   		goto fail;
> -	len = fdt_totalsize(fdt) - absoffset;
> +	len = totalsize - absoffset;
>   
>   	if (fdt_magic(fdt) == FDT_MAGIC) {
>   		if (stroffset < 0)
>   			goto fail;
> -		if (fdt_version(fdt) >= 17) {
> -			if (stroffset >= fdt_size_dt_strings(fdt))
> +		if (can_assume(LATEST) || fdt_version(fdt) >= 17) {
> +			if ((unsigned)stroffset >= fdt_size_dt_strings(fdt))
>   				goto fail;
>   			if ((fdt_size_dt_strings(fdt) - stroffset) < len)
>   				len = fdt_size_dt_strings(fdt) - stroffset;
>   		}
>   	} else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
> -		if ((stroffset >= 0)
> -		    || (stroffset < -fdt_size_dt_strings(fdt)))
> +		unsigned int sw_stroffset = -stroffset;
> +
> +		if ((stroffset >= 0) ||
> +		    (sw_stroffset > fdt_size_dt_strings(fdt)))
>   			goto fail;
> -		if ((-stroffset) < len)
> -			len = -stroffset;
> +		if (sw_stroffset < len)
> +			len = sw_stroffset;
>   	} else {
>   		err = -FDT_ERR_INTERNAL;
>   		goto fail;
> @@ -192,13 +159,16 @@ int fdt_generate_phandle(const void *fdt, uint32_t *phandle)
>   
>   static const struct fdt_reserve_entry *fdt_mem_rsv(const void *fdt, int n)
>   {
> -	int offset = n * sizeof(struct fdt_reserve_entry);
> -	int absoffset = fdt_off_mem_rsvmap(fdt) + offset;
> +	unsigned int offset = n * sizeof(struct fdt_reserve_entry);
> +	unsigned int absoffset = fdt_off_mem_rsvmap(fdt) + offset;
>   
> -	if (absoffset < fdt_off_mem_rsvmap(fdt))
> -		return NULL;
> -	if (absoffset > fdt_totalsize(fdt) - sizeof(struct fdt_reserve_entry))
> -		return NULL;
> +	if (!can_assume(VALID_INPUT)) {
> +		if (absoffset < fdt_off_mem_rsvmap(fdt))
> +			return NULL;
> +		if (absoffset > fdt_totalsize(fdt) -
> +		    sizeof(struct fdt_reserve_entry))
> +			return NULL;
> +	}
>   	return fdt_mem_rsv_(fdt, n);
>   }
>   
> @@ -208,11 +178,11 @@ int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
>   
>   	FDT_RO_PROBE(fdt);
>   	re = fdt_mem_rsv(fdt, n);
> -	if (!re)
> +	if (!can_assume(VALID_INPUT) && !re)
>   		return -FDT_ERR_BADOFFSET;
>   
> -	*address = fdt64_ld(&re->address);
> -	*size = fdt64_ld(&re->size);
> +	*address = fdt64_ld_(&re->address);
> +	*size = fdt64_ld_(&re->size);
>   	return 0;
>   }
>   
> @@ -222,7 +192,7 @@ int fdt_num_mem_rsv(const void *fdt)
>   	const struct fdt_reserve_entry *re;
>   
>   	for (i = 0; (re = fdt_mem_rsv(fdt, i)) != NULL; i++) {
> -		if (fdt64_ld(&re->size) == 0)
> +		if (fdt64_ld_(&re->size) == 0)
>   			return i;
>   	}
>   	return -FDT_ERR_TRUNCATED;
> @@ -333,13 +303,13 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
>   	const char *nameptr;
>   	int err;
>   
> -	if (((err = fdt_ro_probe_(fdt)) != 0)
> +	if (((err = fdt_ro_probe_(fdt)) < 0)
>   	    || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0))
>   			goto fail;
>   
>   	nameptr = nh->name;
>   
> -	if (fdt_version(fdt) < 0x10) {
> +	if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) {
>   		/*
>   		 * For old FDT versions, match the naming conventions of V16:
>   		 * give only the leaf name (after all /). The actual tree
> @@ -390,7 +360,8 @@ static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt,
>   	int err;
>   	const struct fdt_property *prop;
>   
> -	if ((err = fdt_check_prop_offset_(fdt, offset)) < 0) {
> +	if (!can_assume(VALID_INPUT) &&
> +	    (err = fdt_check_prop_offset_(fdt, offset)) < 0) {
>   		if (lenp)
>   			*lenp = err;
>   		return NULL;
> @@ -399,7 +370,7 @@ static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt,
>   	prop = fdt_offset_ptr_(fdt, offset);
>   
>   	if (lenp)
> -		*lenp = fdt32_ld(&prop->len);
> +		*lenp = fdt32_ld_(&prop->len);
>   
>   	return prop;
>   }
> @@ -411,7 +382,7 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
>   	/* Prior to version 16, properties may need realignment
>   	 * and this API does not work. fdt_getprop_*() will, however. */
>   
> -	if (fdt_version(fdt) < 0x10) {
> +	if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) {
>   		if (lenp)
>   			*lenp = -FDT_ERR_BADVERSION;
>   		return NULL;
> @@ -432,11 +403,12 @@ static const struct fdt_property *fdt_get_property_namelen_(const void *fdt,
>   	     (offset = fdt_next_property_offset(fdt, offset))) {
>   		const struct fdt_property *prop;
>   
> -		if (!(prop = fdt_get_property_by_offset_(fdt, offset, lenp))) {
> +		prop = fdt_get_property_by_offset_(fdt, offset, lenp);
> +		if (!can_assume(LIBFDT_FLAWLESS) && !prop) {
>   			offset = -FDT_ERR_INTERNAL;
>   			break;
>   		}
> -		if (fdt_string_eq_(fdt, fdt32_ld(&prop->nameoff),
> +		if (fdt_string_eq_(fdt, fdt32_ld_(&prop->nameoff),
>   				   name, namelen)) {
>   			if (poffset)
>   				*poffset = offset;
> @@ -457,7 +429,7 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt,
>   {
>   	/* Prior to version 16, properties may need realignment
>   	 * and this API does not work. fdt_getprop_*() will, however. */
> -	if (fdt_version(fdt) < 0x10) {
> +	if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) {
>   		if (lenp)
>   			*lenp = -FDT_ERR_BADVERSION;
>   		return NULL;
> @@ -488,8 +460,8 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
>   		return NULL;
>   
>   	/* Handle realignment */
> -	if (fdt_version(fdt) < 0x10 && (poffset + sizeof(*prop)) % 8 &&
> -	    fdt32_ld(&prop->len) >= 8)
> +	if (!can_assume(LATEST) && fdt_version(fdt) < 0x10 &&
> +	    (poffset + sizeof(*prop)) % 8 && fdt32_ld_(&prop->len) >= 8)
>   		return prop->data + 4;
>   	return prop->data;
>   }
> @@ -505,19 +477,24 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset,
>   	if (namep) {
>   		const char *name;
>   		int namelen;
> -		name = fdt_get_string(fdt, fdt32_ld(&prop->nameoff),
> -				      &namelen);
> -		if (!name) {
> -			if (lenp)
> -				*lenp = namelen;
> -			return NULL;
> +
> +		if (!can_assume(VALID_INPUT)) {
> +			name = fdt_get_string(fdt, fdt32_ld_(&prop->nameoff),
> +					      &namelen);
> +			if (!name) {
> +				if (lenp)
> +					*lenp = namelen;
> +				return NULL;
> +			}
> +			*namep = name;
> +		} else {
> +			*namep = fdt_string(fdt, fdt32_ld_(&prop->nameoff));
>   		}
> -		*namep = name;
>   	}
>   
>   	/* Handle realignment */
> -	if (fdt_version(fdt) < 0x10 && (offset + sizeof(*prop)) % 8 &&
> -	    fdt32_ld(&prop->len) >= 8)
> +	if (!can_assume(LATEST) && fdt_version(fdt) < 0x10 &&
> +	    (offset + sizeof(*prop)) % 8 && fdt32_ld_(&prop->len) >= 8)
>   		return prop->data + 4;
>   	return prop->data;
>   }
> @@ -542,7 +519,7 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
>   			return 0;
>   	}
>   
> -	return fdt32_ld(php);
> +	return fdt32_ld_(php);
>   }
>   
>   const char *fdt_get_alias_namelen(const void *fdt,
> @@ -642,10 +619,12 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
>   		}
>   	}
>   
> -	if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
> -		return -FDT_ERR_BADOFFSET;
> -	else if (offset == -FDT_ERR_BADOFFSET)
> -		return -FDT_ERR_BADSTRUCTURE;
> +	if (!can_assume(VALID_INPUT)) {
> +		if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
> +			return -FDT_ERR_BADOFFSET;
> +		else if (offset == -FDT_ERR_BADOFFSET)
> +			return -FDT_ERR_BADSTRUCTURE;
> +	}
>   
>   	return offset; /* error from fdt_next_node() */
>   }
> @@ -657,7 +636,8 @@ int fdt_node_depth(const void *fdt, int nodeoffset)
>   
>   	err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);
>   	if (err)
> -		return (err < 0) ? err : -FDT_ERR_INTERNAL;
> +		return (can_assume(LIBFDT_FLAWLESS) || err < 0) ? err :
> +			-FDT_ERR_INTERNAL;
>   	return nodedepth;
>   }
>   
> @@ -702,7 +682,7 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
>   {
>   	int offset;
>   
> -	if ((phandle == 0) || (phandle == -1))
> +	if ((phandle == 0) || (phandle == ~0U))
>   		return -FDT_ERR_BADPHANDLE;
>   
>   	FDT_RO_PROBE(fdt);
> @@ -877,66 +857,3 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
>   
>   	return offset; /* error from fdt_next_node() */
>   }
> -
> -int fdt_check_full(const void *fdt, size_t bufsize)
> -{
> -	int err;
> -	int num_memrsv;
> -	int offset, nextoffset = 0;
> -	uint32_t tag;
> -	unsigned depth = 0;
> -	const void *prop;
> -	const char *propname;
> -
> -	if (bufsize < FDT_V1_SIZE)
> -		return -FDT_ERR_TRUNCATED;
> -	err = fdt_check_header(fdt);
> -	if (err != 0)
> -		return err;
> -	if (bufsize < fdt_totalsize(fdt))
> -		return -FDT_ERR_TRUNCATED;
> -
> -	num_memrsv = fdt_num_mem_rsv(fdt);
> -	if (num_memrsv < 0)
> -		return num_memrsv;
> -
> -	while (1) {
> -		offset = nextoffset;
> -		tag = fdt_next_tag(fdt, offset, &nextoffset);
> -
> -		if (nextoffset < 0)
> -			return nextoffset;
> -
> -		switch (tag) {
> -		case FDT_NOP:
> -			break;
> -
> -		case FDT_END:
> -			if (depth != 0)
> -				return -FDT_ERR_BADSTRUCTURE;
> -			return 0;
> -
> -		case FDT_BEGIN_NODE:
> -			depth++;
> -			if (depth > INT_MAX)
> -				return -FDT_ERR_BADSTRUCTURE;
> -			break;
> -
> -		case FDT_END_NODE:
> -			if (depth == 0)
> -				return -FDT_ERR_BADSTRUCTURE;
> -			depth--;
> -			break;
> -
> -		case FDT_PROP:
> -			prop = fdt_getprop_by_offset(fdt, offset, &propname,
> -						     &err);
> -			if (!prop)
> -				return err;
> -			break;
> -
> -		default:
> -			return -FDT_ERR_INTERNAL;
> -		}
> -	}
> -}
> diff --git a/libfdt/fdt_rw.c b/libfdt/fdt_rw.c
> index 9e7661509..3621d3651 100644
> --- a/libfdt/fdt_rw.c
> +++ b/libfdt/fdt_rw.c
> @@ -1,52 +1,7 @@
> +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
>   /*
>    * libfdt - Flat Device Tree manipulation
>    * Copyright (C) 2006 David Gibson, IBM Corporation.
> - *
> - * libfdt is dual licensed: you can use it either under the terms of
> - * the GPL, or the BSD license, at your option.
> - *
> - *  a) This library is free software; you can redistribute it and/or
> - *     modify it under the terms of the GNU General Public License as
> - *     published by the Free Software Foundation; either version 2 of the
> - *     License, or (at your option) any later version.
> - *
> - *     This library is distributed in the hope that it will be useful,
> - *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> - *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - *     GNU General Public License for more details.
> - *
> - *     You should have received a copy of the GNU General Public
> - *     License along with this library; if not, write to the Free
> - *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
> - *     MA 02110-1301 USA
> - *
> - * Alternatively,
> - *
> - *  b) Redistribution and use in source and binary forms, with or
> - *     without modification, are permitted provided that the following
> - *     conditions are met:
> - *
> - *     1. Redistributions of source code must retain the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer.
> - *     2. Redistributions in binary form must reproduce the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer in the documentation and/or other materials
> - *        provided with the distribution.
> - *
> - *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> - *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
> - *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> - *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
> - *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> - *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> - *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> - *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> - *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
> - *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>    */
>   #include "libfdt_env.h"
>   
> @@ -69,14 +24,16 @@ static int fdt_blocks_misordered_(const void *fdt,
>   
>   static int fdt_rw_probe_(void *fdt)
>   {
> +	if (can_assume(VALID_DTB))
> +		return 0;
>   	FDT_RO_PROBE(fdt);
>   
> -	if (fdt_version(fdt) < 17)
> +	if (!can_assume(LATEST) && fdt_version(fdt) < 17)
>   		return -FDT_ERR_BADVERSION;
>   	if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry),
>   				   fdt_size_dt_struct(fdt)))
>   		return -FDT_ERR_BADLAYOUT;
> -	if (fdt_version(fdt) > 17)
> +	if (!can_assume(LATEST) && fdt_version(fdt) > 17)
>   		fdt_set_version(fdt, 17);
>   
>   	return 0;
> @@ -89,7 +46,7 @@ static int fdt_rw_probe_(void *fdt)
>   			return err_; \
>   	}
>   
> -static inline int fdt_data_size_(void *fdt)
> +static inline unsigned int fdt_data_size_(void *fdt)
>   {
>   	return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
>   }
> @@ -97,15 +54,16 @@ static inline int fdt_data_size_(void *fdt)
>   static int fdt_splice_(void *fdt, void *splicepoint, int oldlen, int newlen)
>   {
>   	char *p = splicepoint;
> -	char *end = (char *)fdt + fdt_data_size_(fdt);
> +	unsigned int dsize = fdt_data_size_(fdt);
> +	size_t soff = p - (char *)fdt;
>   
> -	if (((p + oldlen) < p) || ((p + oldlen) > end))
> +	if ((oldlen < 0) || (soff + oldlen < soff) || (soff + oldlen > dsize))
>   		return -FDT_ERR_BADOFFSET;
> -	if ((p < (char *)fdt) || ((end - oldlen + newlen) < (char *)fdt))
> +	if ((p < (char *)fdt) || (dsize + newlen < (unsigned)oldlen))
>   		return -FDT_ERR_BADOFFSET;
> -	if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))
> +	if (dsize - oldlen + newlen > fdt_totalsize(fdt))
>   		return -FDT_ERR_NOSPACE;
> -	memmove(p + newlen, p + oldlen, end - p - oldlen);
> +	memmove(p + newlen, p + oldlen, ((char *)fdt + dsize) - (p + oldlen));
>   	return 0;
>   }
>   
> @@ -157,6 +115,15 @@ static int fdt_splice_string_(void *fdt, int newlen)
>   	return 0;
>   }
>   
> +/**
> + * fdt_find_add_string_() - Find or allocate a string
> + *
> + * @fdt: pointer to the device tree to check/adjust
> + * @s: string to find/add
> + * @allocated: Set to 0 if the string was found, 1 if not found and so
> + *	allocated. Ignored if can_assume(NO_ROLLBACK)
> + * @return offset of string in the string table (whether found or added)
> + */
>   static int fdt_find_add_string_(void *fdt, const char *s, int *allocated)
>   {
>   	char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
> @@ -165,7 +132,8 @@ static int fdt_find_add_string_(void *fdt, const char *s, int *allocated)
>   	int len = strlen(s) + 1;
>   	int err;
>   
> -	*allocated = 0;
> +	if (!can_assume(NO_ROLLBACK))
> +		*allocated = 0;
>   
>   	p = fdt_find_string_(strtab, fdt_size_dt_strings(fdt), s);
>   	if (p)
> @@ -177,7 +145,8 @@ static int fdt_find_add_string_(void *fdt, const char *s, int *allocated)
>   	if (err)
>   		return err;
>   
> -	*allocated = 1;
> +	if (!can_assume(NO_ROLLBACK))
> +		*allocated = 1;
>   
>   	memcpy(new, s, len);
>   	return (new - strtab);
> @@ -251,7 +220,8 @@ static int fdt_add_property_(void *fdt, int nodeoffset, const char *name,
>   
>   	err = fdt_splice_struct_(fdt, *prop, 0, proplen);
>   	if (err) {
> -		if (allocated)
> +		/* Delete the string if we failed to add it */
> +		if (!can_assume(NO_ROLLBACK) && allocated)
>   			fdt_del_last_string_(fdt, name);
>   		return err;
>   	}
> @@ -379,7 +349,10 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
>   		return offset;
>   
>   	/* Try to place the new node after the parent's properties */
> -	fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */
> +	tag = fdt_next_tag(fdt, parentoffset, &nextoffset);
> +	/* the fdt_subnode_offset_namelen() should ensure this never hits */
> +	if (!can_assume(LIBFDT_FLAWLESS) && (tag != FDT_BEGIN_NODE))
> +		return -FDT_ERR_INTERNAL;
>   	do {
>   		offset = nextoffset;
>   		tag = fdt_next_tag(fdt, offset, &nextoffset);
> @@ -421,7 +394,9 @@ int fdt_del_node(void *fdt, int nodeoffset)
>   }
>   
>   static void fdt_packblocks_(const char *old, char *new,
> -			    int mem_rsv_size, int struct_size)
> +			    int mem_rsv_size,
> +			    int struct_size,
> +			    int strings_size)
>   {
>   	int mem_rsv_off, struct_off, strings_off;
>   
> @@ -436,8 +411,7 @@ static void fdt_packblocks_(const char *old, char *new,
>   	fdt_set_off_dt_struct(new, struct_off);
>   	fdt_set_size_dt_struct(new, struct_size);
>   
> -	memmove(new + strings_off, old + fdt_off_dt_strings(old),
> -		fdt_size_dt_strings(old));
> +	memmove(new + strings_off, old + fdt_off_dt_strings(old), strings_size);
>   	fdt_set_off_dt_strings(new, strings_off);
>   	fdt_set_size_dt_strings(new, fdt_size_dt_strings(old));
>   }
> @@ -456,17 +430,20 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
>   	mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
>   		* sizeof(struct fdt_reserve_entry);
>   
> -	if (fdt_version(fdt) >= 17) {
> +	if (can_assume(LATEST) || fdt_version(fdt) >= 17) {
>   		struct_size = fdt_size_dt_struct(fdt);
> -	} else {
> +	} else if (fdt_version(fdt) == 16) {
>   		struct_size = 0;
>   		while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
>   			;
>   		if (struct_size < 0)
>   			return struct_size;
> +	} else {
> +		return -FDT_ERR_BADVERSION;
>   	}
>   
> -	if (!fdt_blocks_misordered_(fdt, mem_rsv_size, struct_size)) {
> +	if (can_assume(LIBFDT_ORDER) ||
> +	    !fdt_blocks_misordered_(fdt, mem_rsv_size, struct_size)) {
>   		/* no further work necessary */
>   		err = fdt_move(fdt, buf, bufsize);
>   		if (err)
> @@ -494,7 +471,8 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
>   			return -FDT_ERR_NOSPACE;
>   	}
>   
> -	fdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size);
> +	fdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size,
> +			fdt_size_dt_strings(fdt));
>   	memmove(buf, tmp, newsize);
>   
>   	fdt_set_magic(buf, FDT_MAGIC);
> @@ -514,7 +492,8 @@ int fdt_pack(void *fdt)
>   
>   	mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
>   		* sizeof(struct fdt_reserve_entry);
> -	fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
> +	fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt),
> +			fdt_size_dt_strings(fdt));
>   	fdt_set_totalsize(fdt, fdt_data_size_(fdt));
>   
>   	return 0;
> diff --git a/libfdt/fdt_strerror.c b/libfdt/fdt_strerror.c
> index 0e6b4fd5e..d852b77e8 100644
> --- a/libfdt/fdt_strerror.c
> +++ b/libfdt/fdt_strerror.c
> @@ -1,51 +1,7 @@
> +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
>   /*
>    * libfdt - Flat Device Tree manipulation
>    * Copyright (C) 2006 David Gibson, IBM Corporation.
> - *
> - * libfdt is dual licensed: you can use it either under the terms of
> - * the GPL, or the BSD license, at your option.
> - *
> - *  a) This library is free software; you can redistribute it and/or
> - *     modify it under the terms of the GNU General Public License as
> - *     published by the Free Software Foundation; either version 2 of the
> - *     License, or (at your option) any later version.
> - *
> - *     This library is distributed in the hope that it will be useful,
> - *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> - *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - *     GNU General Public License for more details.
> - *
> - *     You should have received a copy of the GNU General Public
> - *     License along with this library; if not, write to the Free
> - *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
> - *     MA 02110-1301 USA
> - *
> - * Alternatively,
> - *
> - *  b) Redistribution and use in source and binary forms, with or
> - *     without modification, are permitted provided that the following
> - *     conditions are met:
> - *
> - *     1. Redistributions of source code must retain the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer.
> - *     2. Redistributions in binary form must reproduce the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer in the documentation and/or other materials
> - *        provided with the distribution.
> - *
> - *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> - *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
> - *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> - *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
> - *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> - *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> - *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> - *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> - *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
>    *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>    */
>   #include "libfdt_env.h"
> @@ -83,8 +39,9 @@ static struct fdt_errtabent fdt_errtable[] = {
>   	FDT_ERRTABENT(FDT_ERR_BADOVERLAY),
>   	FDT_ERRTABENT(FDT_ERR_NOPHANDLES),
>   	FDT_ERRTABENT(FDT_ERR_BADFLAGS),
> +	FDT_ERRTABENT(FDT_ERR_ALIGNMENT),
>   };
> -#define FDT_ERRTABSIZE	(sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))
> +#define FDT_ERRTABSIZE	((int)(sizeof(fdt_errtable) / sizeof(fdt_errtable[0])))
>   
>   const char *fdt_strerror(int errval)
>   {
> @@ -92,7 +49,7 @@ const char *fdt_strerror(int errval)
>   		return "<valid offset/length>";
>   	else if (errval == 0)
>   		return "<no error>";
> -	else if (errval > -FDT_ERRTABSIZE) {
> +	else if (-errval < FDT_ERRTABSIZE) {
>   		const char *s = fdt_errtable[-errval].str;
>   
>   		if (s)
> diff --git a/libfdt/fdt_sw.c b/libfdt/fdt_sw.c
> index e773157d0..4c569ee7e 100644
> --- a/libfdt/fdt_sw.c
> +++ b/libfdt/fdt_sw.c
> @@ -1,52 +1,7 @@
> +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
>   /*
>    * libfdt - Flat Device Tree manipulation
>    * Copyright (C) 2006 David Gibson, IBM Corporation.
> - *
> - * libfdt is dual licensed: you can use it either under the terms of
> - * the GPL, or the BSD license, at your option.
> - *
> - *  a) This library is free software; you can redistribute it and/or
> - *     modify it under the terms of the GNU General Public License as
> - *     published by the Free Software Foundation; either version 2 of the
> - *     License, or (at your option) any later version.
> - *
> - *     This library is distributed in the hope that it will be useful,
> - *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> - *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - *     GNU General Public License for more details.
> - *
> - *     You should have received a copy of the GNU General Public
> - *     License along with this library; if not, write to the Free
> - *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
> - *     MA 02110-1301 USA
> - *
> - * Alternatively,
> - *
> - *  b) Redistribution and use in source and binary forms, with or
> - *     without modification, are permitted provided that the following
> - *     conditions are met:
> - *
> - *     1. Redistributions of source code must retain the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer.
> - *     2. Redistributions in binary form must reproduce the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer in the documentation and/or other materials
> - *        provided with the distribution.
> - *
> - *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> - *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
> - *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> - *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
> - *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> - *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> - *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> - *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> - *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
> - *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>    */
>   #include "libfdt_env.h"
>   
> @@ -57,10 +12,13 @@
>   
>   static int fdt_sw_probe_(void *fdt)
>   {
> -	if (fdt_magic(fdt) == FDT_MAGIC)
> -		return -FDT_ERR_BADSTATE;
> -	else if (fdt_magic(fdt) != FDT_SW_MAGIC)
> -		return -FDT_ERR_BADMAGIC;
> +	if (!can_assume(VALID_INPUT)) {
> +		if (fdt_magic(fdt) == FDT_MAGIC)
> +			return -FDT_ERR_BADSTATE;
> +		else if (fdt_magic(fdt) != FDT_SW_MAGIC)
> +			return -FDT_ERR_BADMAGIC;
> +	}
> +
>   	return 0;
>   }
>   
> @@ -74,7 +32,7 @@ static int fdt_sw_probe_(void *fdt)
>   /* 'memrsv' state:	Initial state after fdt_create()
>    *
>    * Allowed functions:
> - *	fdt_add_reservmap_entry()
> + *	fdt_add_reservemap_entry()
>    *	fdt_finish_reservemap()		[moves to 'struct' state]
>    */
>   static int fdt_sw_probe_memrsv_(void *fdt)
> @@ -83,7 +41,7 @@ static int fdt_sw_probe_memrsv_(void *fdt)
>   	if (err)
>   		return err;
>   
> -	if (fdt_off_dt_strings(fdt) != 0)
> +	if (!can_assume(VALID_INPUT) && fdt_off_dt_strings(fdt) != 0)
>   		return -FDT_ERR_BADSTATE;
>   	return 0;
>   }
> @@ -109,7 +67,8 @@ static int fdt_sw_probe_struct_(void *fdt)
>   	if (err)
>   		return err;
>   
> -	if (fdt_off_dt_strings(fdt) != fdt_totalsize(fdt))
> +	if (!can_assume(VALID_INPUT) &&
> +	    fdt_off_dt_strings(fdt) != fdt_totalsize(fdt))
>   		return -FDT_ERR_BADSTATE;
>   	return 0;
>   }
> @@ -134,8 +93,8 @@ static inline uint32_t sw_flags(void *fdt)
>   
>   static void *fdt_grab_space_(void *fdt, size_t len)
>   {
> -	int offset = fdt_size_dt_struct(fdt);
> -	int spaceleft;
> +	unsigned int offset = fdt_size_dt_struct(fdt);
> +	unsigned int spaceleft;
>   
>   	spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt)
>   		- fdt_size_dt_strings(fdt);
> @@ -149,8 +108,8 @@ static void *fdt_grab_space_(void *fdt, size_t len)
>   
>   int fdt_create_with_flags(void *buf, int bufsize, uint32_t flags)
>   {
> -	const size_t hdrsize = FDT_ALIGN(sizeof(struct fdt_header),
> -					 sizeof(struct fdt_reserve_entry));
> +	const int hdrsize = FDT_ALIGN(sizeof(struct fdt_header),
> +				      sizeof(struct fdt_reserve_entry));
>   	void *fdt = buf;
>   
>   	if (bufsize < hdrsize)
> @@ -193,13 +152,17 @@ int fdt_resize(void *fdt, void *buf, int bufsize)
>   
>   	FDT_SW_PROBE(fdt);
>   
> +	if (bufsize < 0)
> +		return -FDT_ERR_NOSPACE;
> +
>   	headsize = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
>   	tailsize = fdt_size_dt_strings(fdt);
>   
> -	if ((headsize + tailsize) > fdt_totalsize(fdt))
> +	if (!can_assume(VALID_DTB) &&
> +	    headsize + tailsize > fdt_totalsize(fdt))
>   		return -FDT_ERR_INTERNAL;
>   
> -	if ((headsize + tailsize) > bufsize)
> +	if ((headsize + tailsize) > (unsigned)bufsize)
>   		return -FDT_ERR_NOSPACE;
>   
>   	oldtail = (char *)fdt + fdt_totalsize(fdt) - tailsize;
> @@ -287,18 +250,18 @@ int fdt_end_node(void *fdt)
>   static int fdt_add_string_(void *fdt, const char *s)
>   {
>   	char *strtab = (char *)fdt + fdt_totalsize(fdt);
> -	int strtabsize = fdt_size_dt_strings(fdt);
> -	int len = strlen(s) + 1;
> -	int struct_top, offset;
> +	unsigned int strtabsize = fdt_size_dt_strings(fdt);
> +	unsigned int len = strlen(s) + 1;
> +	unsigned int struct_top, offset;
>   
> -	offset = -strtabsize - len;
> +	offset = strtabsize + len;
>   	struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
> -	if (fdt_totalsize(fdt) + offset < struct_top)
> +	if (fdt_totalsize(fdt) - offset < struct_top)
>   		return 0; /* no more room :( */
>   
> -	memcpy(strtab + offset, s, len);
> +	memcpy(strtab - offset, s, len);
>   	fdt_set_size_dt_strings(fdt, strtabsize + len);
> -	return offset;
> +	return -offset;
>   }
>   
>   /* Must only be used to roll back in case of error */
> @@ -414,7 +377,7 @@ int fdt_finish(void *fdt)
>   	fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));
>   
>   	/* And fix up fields that were keeping intermediate state. */
> -	fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
> +	fdt_set_last_comp_version(fdt, FDT_LAST_COMPATIBLE_VERSION);
>   	fdt_set_magic(fdt, FDT_MAGIC);
>   
>   	return 0;
> diff --git a/libfdt/fdt_wip.c b/libfdt/fdt_wip.c
> index 534c1cbbb..c2d7566a6 100644
> --- a/libfdt/fdt_wip.c
> +++ b/libfdt/fdt_wip.c
> @@ -1,52 +1,7 @@
> +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
>   /*
>    * libfdt - Flat Device Tree manipulation
>    * Copyright (C) 2006 David Gibson, IBM Corporation.
> - *
> - * libfdt is dual licensed: you can use it either under the terms of
> - * the GPL, or the BSD license, at your option.
> - *
> - *  a) This library is free software; you can redistribute it and/or
> - *     modify it under the terms of the GNU General Public License as
> - *     published by the Free Software Foundation; either version 2 of the
> - *     License, or (at your option) any later version.
> - *
> - *     This library is distributed in the hope that it will be useful,
> - *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> - *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - *     GNU General Public License for more details.
> - *
> - *     You should have received a copy of the GNU General Public
> - *     License along with this library; if not, write to the Free
> - *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
> - *     MA 02110-1301 USA
> - *
> - * Alternatively,
> - *
> - *  b) Redistribution and use in source and binary forms, with or
> - *     without modification, are permitted provided that the following
> - *     conditions are met:
> - *
> - *     1. Redistributions of source code must retain the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer.
> - *     2. Redistributions in binary form must reproduce the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer in the documentation and/or other materials
> - *        provided with the distribution.
> - *
> - *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> - *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
> - *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> - *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
> - *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> - *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> - *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> - *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> - *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
> - *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>    */
>   #include "libfdt_env.h"
>   
> @@ -68,7 +23,7 @@ int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,
>   	if (!propval)
>   		return proplen;
>   
> -	if (proplen < (len + idx))
> +	if ((unsigned)proplen < (len + idx))
>   		return -FDT_ERR_NOSPACE;
>   
>   	memcpy((char *)propval + idx, val, len);
> diff --git a/libfdt/libfdt.h b/libfdt/libfdt.h
> index 0684ec22e..a7f432c80 100644
> --- a/libfdt/libfdt.h
> +++ b/libfdt/libfdt.h
> @@ -1,60 +1,20 @@
> +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */
>   #ifndef LIBFDT_H
>   #define LIBFDT_H
>   /*
>    * libfdt - Flat Device Tree manipulation
>    * Copyright (C) 2006 David Gibson, IBM Corporation.
> - *
> - * libfdt is dual licensed: you can use it either under the terms of
> - * the GPL, or the BSD license, at your option.
> - *
> - *  a) This library is free software; you can redistribute it and/or
> - *     modify it under the terms of the GNU General Public License as
> - *     published by the Free Software Foundation; either version 2 of the
> - *     License, or (at your option) any later version.
> - *
> - *     This library is distributed in the hope that it will be useful,
> - *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> - *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - *     GNU General Public License for more details.
> - *
> - *     You should have received a copy of the GNU General Public
> - *     License along with this library; if not, write to the Free
> - *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
> - *     MA 02110-1301 USA
> - *
> - * Alternatively,
> - *
> - *  b) Redistribution and use in source and binary forms, with or
> - *     without modification, are permitted provided that the following
> - *     conditions are met:
> - *
> - *     1. Redistributions of source code must retain the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer.
> - *     2. Redistributions in binary form must reproduce the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer in the documentation and/or other materials
> - *        provided with the distribution.
> - *
> - *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> - *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
> - *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> - *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
> - *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> - *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> - *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> - *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> - *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
> - *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>    */
>   
>   #include <libfdt_env.h>
>   #include <fdt.h>
>   
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
>   #define FDT_FIRST_SUPPORTED_VERSION	0x02
> +#define FDT_LAST_COMPATIBLE_VERSION 0x10
>   #define FDT_LAST_SUPPORTED_VERSION	0x11
>   
>   /* Error codes: informative error codes */
> @@ -142,7 +102,11 @@
>   	/* FDT_ERR_BADFLAGS: The function was passed a flags field that
>   	 * contains invalid flags or an invalid combination of flags. */
>   
> -#define FDT_ERR_MAX		18
> +#define FDT_ERR_ALIGNMENT	19
> +	/* FDT_ERR_ALIGNMENT: The device tree base address is not 8-byte
> +	 * aligned. */
> +
> +#define FDT_ERR_MAX		19
>   
>   /* constants */
>   #define FDT_MAX_PHANDLE 0xfffffffe
> @@ -163,11 +127,16 @@ static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
>   uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
>   
>   /*
> - * Alignment helpers:
> - *     These helpers access words from a device tree blob.  They're
> - *     built to work even with unaligned pointers on platforms (ike
> - *     ARM) that don't like unaligned loads and stores
> + * External helpers to access words from a device tree blob. They're built
> + * to work even with unaligned pointers on platforms (such as ARMv5) that don't
> + * like unaligned loads and stores.
>    */
> +static inline uint16_t fdt16_ld(const fdt16_t *p)
> +{
> +	const uint8_t *bp = (const uint8_t *)p;
> +
> +	return ((uint16_t)bp[0] << 8) | bp[1];
> +}
>   
>   static inline uint32_t fdt32_ld(const fdt32_t *p)
>   {
> @@ -181,7 +150,7 @@ static inline uint32_t fdt32_ld(const fdt32_t *p)
>   
>   static inline void fdt32_st(void *property, uint32_t value)
>   {
> -	uint8_t *bp = property;
> +	uint8_t *bp = (uint8_t *)property;
>   
>   	bp[0] = value >> 24;
>   	bp[1] = (value >> 16) & 0xff;
> @@ -205,7 +174,7 @@ static inline uint64_t fdt64_ld(const fdt64_t *p)
>   
>   static inline void fdt64_st(void *property, uint64_t value)
>   {
> -	uint8_t *bp = property;
> +	uint8_t *bp = (uint8_t *)property;
>   
>   	bp[0] = value >> 56;
>   	bp[1] = (value >> 48) & 0xff;
> @@ -225,23 +194,23 @@ int fdt_next_node(const void *fdt, int offset, int *depth);
>   
>   /**
>    * fdt_first_subnode() - get offset of first direct subnode
> - *
>    * @fdt:	FDT blob
>    * @offset:	Offset of node to check
> - * @return offset of first subnode, or -FDT_ERR_NOTFOUND if there is none
> + *
> + * Return: offset of first subnode, or -FDT_ERR_NOTFOUND if there is none
>    */
>   int fdt_first_subnode(const void *fdt, int offset);
>   
>   /**
>    * fdt_next_subnode() - get offset of next direct subnode
> + * @fdt:	FDT blob
> + * @offset:	Offset of previous subnode
>    *
>    * After first calling fdt_first_subnode(), call this function repeatedly to
>    * get direct subnodes of a parent node.
>    *
> - * @fdt:	FDT blob
> - * @offset:	Offset of previous subnode
> - * @return offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more
> - * subnodes
> + * Return: offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more
> + *         subnodes
>    */
>   int fdt_next_subnode(const void *fdt, int offset);
>   
> @@ -266,7 +235,6 @@ int fdt_next_subnode(const void *fdt, int offset);
>    * Note that this is implemented as a macro and @node is used as
>    * iterator in the loop. The parent variable be constant or even a
>    * literal.
> - *
>    */
>   #define fdt_for_each_subnode(node, fdt, parent)		\
>   	for (node = fdt_first_subnode(fdt, parent);	\
> @@ -310,16 +278,21 @@ fdt_set_hdr_(size_dt_struct);
>   /**
>    * fdt_header_size - return the size of the tree's header
>    * @fdt: pointer to a flattened device tree
> + *
> + * Return: size of DTB header in bytes
> + */
> +size_t fdt_header_size(const void *fdt);
> +
> +/**
> + * fdt_header_size_ - internal function to get header size from a version number
> + * @version: devicetree version number
> + *
> + * Return: size of DTB header in bytes
>    */
>   size_t fdt_header_size_(uint32_t version);
> -static inline size_t fdt_header_size(const void *fdt)
> -{
> -	return fdt_header_size_(fdt_version(fdt));
> -}
>   
>   /**
>    * fdt_check_header - sanity check a device tree header
> -
>    * @fdt: pointer to data which might be a flattened device tree
>    *
>    * fdt_check_header() checks that the given buffer contains what
> @@ -444,8 +417,7 @@ static inline uint32_t fdt_get_max_phandle(const void *fdt)
>    * highest phandle value in the device tree blob) will be returned in the
>    * @phandle parameter.
>    *
> - * Returns:
> - *   0 on success or a negative error-code on failure
> + * Return: 0 on success or a negative error-code on failure
>    */
>   int fdt_generate_phandle(const void *fdt, uint32_t *phandle);
>   
> @@ -465,9 +437,11 @@ int fdt_num_mem_rsv(const void *fdt);
>   /**
>    * fdt_get_mem_rsv - retrieve one memory reserve map entry
>    * @fdt: pointer to the device tree blob
> - * @address, @size: pointers to 64-bit variables
> + * @n: index of reserve map entry
> + * @address: pointer to 64-bit variable to hold the start address
> + * @size: pointer to 64-bit variable to hold the size of the entry
>    *
> - * On success, *address and *size will contain the address and size of
> + * On success, @address and @size will contain the address and size of
>    * the n-th reserve map entry from the device tree blob, in
>    * native-endian format.
>    *
> @@ -490,6 +464,8 @@ int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
>    * namelen characters of name for matching the subnode name.  This is
>    * useful for finding subnodes based on a portion of a larger string,
>    * such as a full path.
> + *
> + * Return: offset of the subnode or -FDT_ERR_NOTFOUND if name not found.
>    */
>   #ifndef SWIG /* Not available in Python */
>   int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
> @@ -529,6 +505,8 @@ int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
>    *
>    * Identical to fdt_path_offset(), but only consider the first namelen
>    * characters of path as the path name.
> + *
> + * Return: offset of the node or negative libfdt error value otherwise
>    */
>   #ifndef SWIG /* Not available in Python */
>   int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen);
> @@ -628,9 +606,9 @@ int fdt_next_property_offset(const void *fdt, int offset);
>   /**
>    * fdt_for_each_property_offset - iterate over all properties of a node
>    *
> - * @property_offset:	property offset (int, lvalue)
> - * @fdt:		FDT blob (const void *)
> - * @node:		node offset (int)
> + * @property:	property offset (int, lvalue)
> + * @fdt:	FDT blob (const void *)
> + * @node:	node offset (int)
>    *
>    * This is actually a wrapper around a for loop and would be used like so:
>    *
> @@ -693,6 +671,9 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
>    *
>    * Identical to fdt_get_property(), but only examine the first namelen
>    * characters of name for matching the property name.
> + *
> + * Return: pointer to the structure representing the property, or NULL
> + *         if not found
>    */
>   #ifndef SWIG /* Not available in Python */
>   const struct fdt_property *fdt_get_property_namelen(const void *fdt,
> @@ -785,6 +766,8 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset,
>    *
>    * Identical to fdt_getprop(), but only examine the first namelen
>    * characters of name for matching the property name.
> + *
> + * Return: pointer to the property's value or NULL on error
>    */
>   #ifndef SWIG /* Not available in Python */
>   const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
> @@ -806,10 +789,10 @@ static inline void *fdt_getprop_namelen_w(void *fdt, int nodeoffset,
>    * @lenp: pointer to an integer variable (will be overwritten) or NULL
>    *
>    * fdt_getprop() retrieves a pointer to the value of the property
> - * named 'name' of the node at offset nodeoffset (this will be a
> + * named @name of the node at offset @nodeoffset (this will be a
>    * pointer to within the device blob itself, not a copy of the value).
> - * If lenp is non-NULL, the length of the property value is also
> - * returned, in the integer pointed to by lenp.
> + * If @lenp is non-NULL, the length of the property value is also
> + * returned, in the integer pointed to by @lenp.
>    *
>    * returns:
>    *	pointer to the property's value
> @@ -854,8 +837,11 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
>    * @name: name of the alias th look up
>    * @namelen: number of characters of name to consider
>    *
> - * Identical to fdt_get_alias(), but only examine the first namelen
> - * characters of name for matching the alias name.
> + * Identical to fdt_get_alias(), but only examine the first @namelen
> + * characters of @name for matching the alias name.
> + *
> + * Return: a pointer to the expansion of the alias named @name, if it exists,
> + *	   NULL otherwise
>    */
>   #ifndef SWIG /* Not available in Python */
>   const char *fdt_get_alias_namelen(const void *fdt,
> @@ -868,7 +854,7 @@ const char *fdt_get_alias_namelen(const void *fdt,
>    * @name: name of the alias th look up
>    *
>    * fdt_get_alias() retrieves the value of a given alias.  That is, the
> - * value of the property named 'name' in the node /aliases.
> + * value of the property named @name in the node /aliases.
>    *
>    * returns:
>    *	a pointer to the expansion of the alias named 'name', if it exists
> @@ -1044,14 +1030,13 @@ int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
>   int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
>   
>   /**
> - * fdt_node_check_compatible: check a node's compatible property
> + * fdt_node_check_compatible - check a node's compatible property
>    * @fdt: pointer to the device tree blob
>    * @nodeoffset: offset of a tree node
>    * @compatible: string to match against
>    *
> - *
>    * fdt_node_check_compatible() returns 0 if the given node contains a
> - * 'compatible' property with the given string as one of its elements,
> + * @compatible property with the given string as one of its elements,
>    * it returns non-zero otherwise, or on error.
>    *
>    * returns:
> @@ -1115,7 +1100,7 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
>    * one or more strings, each terminated by \0, as is found in a device tree
>    * "compatible" property.
>    *
> - * @return: 1 if the string is found in the list, 0 not found, or invalid list
> + * Return: 1 if the string is found in the list, 0 not found, or invalid list
>    */
>   int fdt_stringlist_contains(const char *strlist, int listlen, const char *str);
>   
> @@ -1124,7 +1109,8 @@ int fdt_stringlist_contains(const char *strlist, int listlen, const char *str);
>    * @fdt: pointer to the device tree blob
>    * @nodeoffset: offset of a tree node
>    * @property: name of the property containing the string list
> - * @return:
> + *
> + * Return:
>    *   the number of strings in the given property
>    *   -FDT_ERR_BADVALUE if the property value is not NUL-terminated
>    *   -FDT_ERR_NOTFOUND if the property does not exist
> @@ -1144,7 +1130,7 @@ int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property);
>    * small-valued cell properties, such as #address-cells, when searching for
>    * the empty string.
>    *
> - * @return:
> + * return:
>    *   the index of the string in the list of strings
>    *   -FDT_ERR_BADVALUE if the property value is not NUL-terminated
>    *   -FDT_ERR_NOTFOUND if the property does not exist or does not contain
> @@ -1168,7 +1154,7 @@ int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property,
>    * If non-NULL, the length of the string (on success) or a negative error-code
>    * (on failure) will be stored in the integer pointer to by lenp.
>    *
> - * @return:
> + * Return:
>    *   A pointer to the string at the given index in the string list or NULL on
>    *   failure. On success the length of the string will be stored in the memory
>    *   location pointed to by the lenp parameter, if non-NULL. On failure one of
> @@ -1257,6 +1243,8 @@ int fdt_size_cells(const void *fdt, int nodeoffset);
>    * starting from the given index, and using only the first characters
>    * of the name. It is useful when you want to manipulate only one value of
>    * an array and you have a string that doesn't end with \0.
> + *
> + * Return: 0 on success, negative libfdt error value otherwise
>    */
>   #ifndef SWIG /* Not available in Python */
>   int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,
> @@ -1370,8 +1358,13 @@ static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset,
>   
>   /**
>    * fdt_setprop_inplace_cell - change the value of a single-cell property
> + * @fdt: pointer to the device tree blob
> + * @nodeoffset: offset of the node containing the property
> + * @name: name of the property to change the value of
> + * @val: new value of the 32-bit cell
>    *
>    * This is an alternative name for fdt_setprop_inplace_u32()
> + * Return: 0 on success, negative libfdt error number otherwise.
>    */
>   static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
>   					   const char *name, uint32_t val)
> @@ -1443,7 +1436,7 @@ int fdt_nop_node(void *fdt, int nodeoffset);
>   
>   /**
>    * fdt_create_with_flags - begin creation of a new fdt
> - * @fdt: pointer to memory allocated where fdt will be created
> + * @buf: pointer to memory allocated where fdt will be created
>    * @bufsize: size of the memory space at fdt
>    * @flags: a valid combination of FDT_CREATE_FLAG_ flags, or 0.
>    *
> @@ -1461,7 +1454,7 @@ int fdt_create_with_flags(void *buf, int bufsize, uint32_t flags);
>   
>   /**
>    * fdt_create - begin creation of a new fdt
> - * @fdt: pointer to memory allocated where fdt will be created
> + * @buf: pointer to memory allocated where fdt will be created
>    * @bufsize: size of the memory space at fdt
>    *
>    * fdt_create() is equivalent to fdt_create_with_flags() with flags=0.
> @@ -1526,7 +1519,8 @@ int fdt_pack(void *fdt);
>   /**
>    * fdt_add_mem_rsv - add one memory reserve map entry
>    * @fdt: pointer to the device tree blob
> - * @address, @size: 64-bit values (native endian)
> + * @address: 64-bit start address of the reserve map entry
> + * @size: 64-bit size of the reserved region
>    *
>    * Adds a reserve map entry to the given blob reserving a region at
>    * address address of length size.
> @@ -1731,8 +1725,14 @@ static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name,
>   
>   /**
>    * fdt_setprop_cell - set a property to a single cell value
> + * @fdt: pointer to the device tree blob
> + * @nodeoffset: offset of the node whose property to change
> + * @name: name of the property to change
> + * @val: 32-bit integer value for the property (native endian)
>    *
>    * This is an alternative name for fdt_setprop_u32()
> + *
> + * Return: 0 on success, negative libfdt error value otherwise.
>    */
>   static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
>   				   uint32_t val)
> @@ -1903,8 +1903,14 @@ static inline int fdt_appendprop_u64(void *fdt, int nodeoffset,
>   
>   /**
>    * fdt_appendprop_cell - append a single cell value to a property
> + * @fdt: pointer to the device tree blob
> + * @nodeoffset: offset of the node whose property to change
> + * @name: name of the property to change
> + * @val: 32-bit integer value to append to the property (native endian)
>    *
>    * This is an alternative name for fdt_appendprop_u32()
> + *
> + * Return: 0 on success, negative libfdt error value otherwise.
>    */
>   static inline int fdt_appendprop_cell(void *fdt, int nodeoffset,
>   				      const char *name, uint32_t val)
> @@ -2007,13 +2013,16 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name);
>    * fdt_add_subnode_namelen - creates a new node based on substring
>    * @fdt: pointer to the device tree blob
>    * @parentoffset: structure block offset of a node
> - * @name: name of the subnode to locate
> + * @name: name of the subnode to create
>    * @namelen: number of characters of name to consider
>    *
> - * Identical to fdt_add_subnode(), but use only the first namelen
> - * characters of name as the name of the new node.  This is useful for
> + * Identical to fdt_add_subnode(), but use only the first @namelen
> + * characters of @name as the name of the new node.  This is useful for
>    * creating subnodes based on a portion of a larger string, such as a
>    * full path.
> + *
> + * Return: structure block offset of the created subnode (>=0),
> + *	   negative libfdt error value otherwise
>    */
>   #ifndef SWIG /* Not available in Python */
>   int fdt_add_subnode_namelen(void *fdt, int parentoffset,
> @@ -2032,7 +2041,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
>    *
>    * This function will insert data into the blob, and will therefore
>    * change the offsets of some existing nodes.
> -
> + *
>    * returns:
>    *	structure block offset of the created nodeequested subnode (>=0), on
>    *		success
> @@ -2107,10 +2116,32 @@ int fdt_del_node(void *fdt, int nodeoffset);
>    */
>   int fdt_overlay_apply(void *fdt, void *fdto);
>   
> +/**
> + * fdt_overlay_target_offset - retrieves the offset of a fragment's target
> + * @fdt: Base device tree blob
> + * @fdto: Device tree overlay blob
> + * @fragment_offset: node offset of the fragment in the overlay
> + * @pathp: pointer which receives the path of the target (or NULL)
> + *
> + * fdt_overlay_target_offset() retrieves the target offset in the base
> + * device tree of a fragment, no matter how the actual targeting is
> + * done (through a phandle or a path)
> + *
> + * returns:
> + *      the targeted node offset in the base device tree
> + *      Negative error code on error
> + */
> +int fdt_overlay_target_offset(const void *fdt, const void *fdto,
> +			      int fragment_offset, char const **pathp);
> +
>   /**********************************************************************/
>   /* Debugging / informational functions                                */
>   /**********************************************************************/
>   
>   const char *fdt_strerror(int errval);
>   
> +#ifdef __cplusplus
> +}
> +#endif
> +
>   #endif /* LIBFDT_H */
> diff --git a/libfdt/libfdt_env.h b/libfdt/libfdt_env.h
> index 4d1cdfa58..73b6d4045 100644
> --- a/libfdt/libfdt_env.h
> +++ b/libfdt/libfdt_env.h
> @@ -1,55 +1,10 @@
> +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */
>   #ifndef LIBFDT_ENV_H
>   #define LIBFDT_ENV_H
>   /*
>    * libfdt - Flat Device Tree manipulation
>    * Copyright (C) 2006 David Gibson, IBM Corporation.
>    * Copyright 2012 Kim Phillips, Freescale Semiconductor.
> - *
> - * libfdt is dual licensed: you can use it either under the terms of
> - * the GPL, or the BSD license, at your option.
> - *
> - *  a) This library is free software; you can redistribute it and/or
> - *     modify it under the terms of the GNU General Public License as
> - *     published by the Free Software Foundation; either version 2 of the
> - *     License, or (at your option) any later version.
> - *
> - *     This library is distributed in the hope that it will be useful,
> - *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> - *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - *     GNU General Public License for more details.
> - *
> - *     You should have received a copy of the GNU General Public
> - *     License along with this library; if not, write to the Free
> - *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
> - *     MA 02110-1301 USA
> - *
> - * Alternatively,
> - *
> - *  b) Redistribution and use in source and binary forms, with or
> - *     without modification, are permitted provided that the following
> - *     conditions are met:
> - *
> - *     1. Redistributions of source code must retain the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer.
> - *     2. Redistributions in binary form must reproduce the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer in the documentation and/or other materials
> - *        provided with the distribution.
> - *
> - *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> - *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
> - *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> - *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
> - *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> - *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> - *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> - *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> - *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
> - *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>    */
>   
>   #include <stdbool.h>
> diff --git a/libfdt/libfdt_internal.h b/libfdt/libfdt_internal.h
> index 4109f890a..16bda1906 100644
> --- a/libfdt/libfdt_internal.h
> +++ b/libfdt/libfdt_internal.h
> @@ -1,66 +1,21 @@
> +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */
>   #ifndef LIBFDT_INTERNAL_H
>   #define LIBFDT_INTERNAL_H
>   /*
>    * libfdt - Flat Device Tree manipulation
>    * Copyright (C) 2006 David Gibson, IBM Corporation.
> - *
> - * libfdt is dual licensed: you can use it either under the terms of
> - * the GPL, or the BSD license, at your option.
> - *
> - *  a) This library is free software; you can redistribute it and/or
> - *     modify it under the terms of the GNU General Public License as
> - *     published by the Free Software Foundation; either version 2 of the
> - *     License, or (at your option) any later version.
> - *
> - *     This library is distributed in the hope that it will be useful,
> - *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> - *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - *     GNU General Public License for more details.
> - *
> - *     You should have received a copy of the GNU General Public
> - *     License along with this library; if not, write to the Free
> - *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
> - *     MA 02110-1301 USA
> - *
> - * Alternatively,
> - *
> - *  b) Redistribution and use in source and binary forms, with or
> - *     without modification, are permitted provided that the following
> - *     conditions are met:
> - *
> - *     1. Redistributions of source code must retain the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer.
> - *     2. Redistributions in binary form must reproduce the above
> - *        copyright notice, this list of conditions and the following
> - *        disclaimer in the documentation and/or other materials
> - *        provided with the distribution.
> - *
> - *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> - *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
> - *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> - *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
> - *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> - *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> - *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> - *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> - *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
> - *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>    */
>   #include <fdt.h>
>   
>   #define FDT_ALIGN(x, a)		(((x) + (a) - 1) & ~((a) - 1))
>   #define FDT_TAGALIGN(x)		(FDT_ALIGN((x), FDT_TAGSIZE))
>   
> -int fdt_ro_probe_(const void *fdt);
> -#define FDT_RO_PROBE(fdt)			\
> -	{ \
> -		int err_; \
> -		if ((err_ = fdt_ro_probe_(fdt)) != 0)	\
> -			return err_; \
> +int32_t fdt_ro_probe_(const void *fdt);
> +#define FDT_RO_PROBE(fdt)					\
> +	{							\
> +		int32_t totalsize_;				\
> +		if ((totalsize_ = fdt_ro_probe_(fdt)) < 0)	\
> +			return totalsize_;			\
>   	}
>   
>   int fdt_check_node_offset_(const void *fdt, int offset);
> @@ -91,6 +46,147 @@ static inline struct fdt_reserve_entry *fdt_mem_rsv_w_(void *fdt, int n)
>   	return (void *)(uintptr_t)fdt_mem_rsv_(fdt, n);
>   }
>   
> +/*
> + * Internal helpers to access tructural elements of the device tree
> + * blob (rather than for exaple reading integers from within property
> + * values).  We assume that we are either given a naturally aligned
> + * address for the platform or if we are not, we are on a platform
> + * where unaligned memory reads will be handled in a graceful manner.
> + * If not the external helpers fdtXX_ld() from libfdt.h can be used
> + * instead.
> + */
> +static inline uint32_t fdt32_ld_(const fdt32_t *p)
> +{
> +	return fdt32_to_cpu(*p);
> +}
> +
> +static inline uint64_t fdt64_ld_(const fdt64_t *p)
> +{
> +	return fdt64_to_cpu(*p);
> +}
> +
>   #define FDT_SW_MAGIC		(~FDT_MAGIC)
>   
> +/**********************************************************************/
> +/* Checking controls                                                  */
> +/**********************************************************************/
> +
> +#ifndef FDT_ASSUME_MASK
> +#define FDT_ASSUME_MASK 0
> +#endif
> +
> +/*
> + * Defines assumptions which can be enabled. Each of these can be enabled
> + * individually. For maximum safety, don't enable any assumptions!
> + *
> + * For minimal code size and no safety, use ASSUME_PERFECT at your own risk.
> + * You should have another method of validating the device tree, such as a
> + * signature or hash check before using libfdt.
> + *
> + * For situations where security is not a concern it may be safe to enable
> + * ASSUME_SANE.
> + */
> +enum {
> +	/*
> +	 * This does essentially no checks. Only the latest device-tree
> +	 * version is correctly handled. Inconsistencies or errors in the device
> +	 * tree may cause undefined behaviour or crashes. Invalid parameters
> +	 * passed to libfdt may do the same.
> +	 *
> +	 * If an error occurs when modifying the tree it may leave the tree in
> +	 * an intermediate (but valid) state. As an example, adding a property
> +	 * where there is insufficient space may result in the property name
> +	 * being added to the string table even though the property itself is
> +	 * not added to the struct section.
> +	 *
> +	 * Only use this if you have a fully validated device tree with
> +	 * the latest supported version and wish to minimise code size.
> +	 */
> +	ASSUME_PERFECT		= 0xff,
> +
> +	/*
> +	 * This assumes that the device tree is sane. i.e. header metadata
> +	 * and basic hierarchy are correct.
> +	 *
> +	 * With this assumption enabled, normal device trees produced by libfdt
> +	 * and the compiler should be handled safely. Malicious device trees and
> +	 * complete garbage may cause libfdt to behave badly or crash. Truncated
> +	 * device trees (e.g. those only partially loaded) can also cause
> +	 * problems.
> +	 *
> +	 * Note: Only checks that relate exclusively to the device tree itself
> +	 * (not the parameters passed to libfdt) are disabled by this
> +	 * assumption. This includes checking headers, tags and the like.
> +	 */
> +	ASSUME_VALID_DTB	= 1 << 0,
> +
> +	/*
> +	 * This builds on ASSUME_VALID_DTB and further assumes that libfdt
> +	 * functions are called with valid parameters, i.e. not trigger
> +	 * FDT_ERR_BADOFFSET or offsets that are out of bounds. It disables any
> +	 * extensive checking of parameters and the device tree, making various
> +	 * assumptions about correctness.
> +	 *
> +	 * It doesn't make sense to enable this assumption unless
> +	 * ASSUME_VALID_DTB is also enabled.
> +	 */
> +	ASSUME_VALID_INPUT	= 1 << 1,
> +
> +	/*
> +	 * This disables checks for device-tree version and removes all code
> +	 * which handles older versions.
> +	 *
> +	 * Only enable this if you know you have a device tree with the latest
> +	 * version.
> +	 */
> +	ASSUME_LATEST		= 1 << 2,
> +
> +	/*
> +	 * This assumes that it is OK for a failed addition to the device tree,
> +	 * due to lack of space or some other problem, to skip any rollback
> +	 * steps (such as dropping the property name from the string table).
> +	 * This is safe to enable in most circumstances, even though it may
> +	 * leave the tree in a sub-optimal state.
> +	 */
> +	ASSUME_NO_ROLLBACK	= 1 << 3,
> +
> +	/*
> +	 * This assumes that the device tree components appear in a 'convenient'
> +	 * order, i.e. the memory reservation block first, then the structure
> +	 * block and finally the string block.
> +	 *
> +	 * This order is not specified by the device-tree specification,
> +	 * but is expected by libfdt. The device-tree compiler always created
> +	 * device trees with this order.
> +	 *
> +	 * This assumption disables a check in fdt_open_into() and removes the
> +	 * ability to fix the problem there. This is safe if you know that the
> +	 * device tree is correctly ordered. See fdt_blocks_misordered_().
> +	 */
> +	ASSUME_LIBFDT_ORDER	= 1 << 4,
> +
> +	/*
> +	 * This assumes that libfdt itself does not have any internal bugs. It
> +	 * drops certain checks that should never be needed unless libfdt has an
> +	 * undiscovered bug.
> +	 *
> +	 * This can generally be considered safe to enable.
> +	 */
> +	ASSUME_LIBFDT_FLAWLESS	= 1 << 5,
> +};
> +
> +/**
> + * can_assume_() - check if a particular assumption is enabled
> + *
> + * @mask: Mask to check (ASSUME_...)
> + * @return true if that assumption is enabled, else false
> + */
> +static inline bool can_assume_(int mask)
> +{
> +	return FDT_ASSUME_MASK & mask;
> +}
> +
> +/** helper macros for checking assumptions */
> +#define can_assume(_assume)	can_assume_(ASSUME_ ## _assume)
> +
>   #endif /* LIBFDT_INTERNAL_H */
> diff --git a/libfdt/version.lds b/libfdt/version.lds
> index 0d52217eb..cbce5d4a8 100644
> --- a/libfdt/version.lds
> +++ b/libfdt/version.lds
> @@ -1,3 +1,4 @@
> +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */
>   LIBFDT_1.2 {
>   	global:
>   		fdt_next_node;
> @@ -19,6 +20,7 @@ LIBFDT_1.2 {
>   		fdt_get_alias_namelen;
>   		fdt_get_alias;
>   		fdt_get_path;
> +                fdt_header_size;
>   		fdt_supernode_atdepth_offset;
>   		fdt_node_depth;
>   		fdt_parent_offset;
> @@ -75,6 +77,7 @@ LIBFDT_1.2 {
>   		fdt_appendprop_addrrange;
>   		fdt_setprop_inplace_namelen_partial;
>   		fdt_create_with_flags;
> +		fdt_overlay_target_offset;
>   	local:
>   		*;
>   };
> 



More information about the Skiboot mailing list