Commit graph

31 commits

Author SHA1 Message Date
Simon Glass
fc03c4a2e0 libfdt: Add support for disabling rollback handling
Allow enabling FDT_ASSUME_NO_ROLLBACK to disable rolling back after a
failed operation.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Message-Id: <20200220214557.176528-6-sjg@chromium.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2020-02-24 13:38:44 +11:00
Simon Glass
57bc6327b8 libfdt: Add support for disabling dtb checks
Support ASSUME_VALID_DTB to disable some sanity checks

If we assume that the DTB itself is valid then we can skip some checks and
save code space. Add various conditions to handle this.

Signed-off-by: Simon Glass <sjg@chromium.org>
Message-Id: <20200220214557.176528-4-sjg@chromium.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2020-02-24 13:38:44 +11:00
Rob Herring
7fb0f4db2e libfdt: Replace GPL/BSD boilerplate/reference with SPDX tags
Replace instances of dual GPLv2 or BSD license boilerplate with SPDX tags.

Signed-off-by: Rob Herring <robh@kernel.org>
Message-Id: <20190620211944.9378-3-robh@kernel.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-06-21 21:06:10 +10:00
Nicholas Piggin
228a44cce8 libfdt: Ensure fdt_add_property frees allocated name string on failure
If fdt_add_property or fdt_property_placeholder fail after allocating
a string for the name, they return without freeing that string. This
does not change the structure of the tree, but in very specific cases
it could lead to undesirable space consumption.

Fix this by rolling back the string allocation in this situation.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Message-Id: <20190509094122.834-2-npiggin@gmail.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-05-10 11:53:10 +10:00
David Gibson
04b5b4062c libfdt: Clean up header checking functions
Many of the libfdt entry points call some sort of sanity check function
before doing anything else.  These need to do slightly different things for
the various classes of functions.

The read-only version is shared with the exported fdt_check_header(), which
limits us a bit in how we can improve it.  For that reason split the two
functions apart (though the exported one just calls the ro one for now).

We also rename the functions for more consistency - they're all named
fdt_XX_probe_() where the XX indicates which class of functions they're
for.  "probe" is a better "term" than the previous check, since they really
only do minimal validation.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Tested-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
2018-06-07 11:45:44 +10:00
David Gibson
c8b38f65fd libfdt: Remove leading underscores from identifiers
In a lot of places libfdt uses a leading _ character to mark an identifier
as "internal" (not part of the published libfdt API).  This is a bad idea,
because identifiers with a leading _ are generally reserved by the C
library or system.  It's particularly dangerous for libfdt, because it's
designed to be able to be integrated into lots of different environments.

In some cases the leading _ has no purpose, so we simply drop it.  In most
cases we move it to the end, as our new convention for marking internal
identifiers.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2017-10-26 09:25:14 +02:00
Pantelis Antoniou
a33c2247ac Introduce fdt_setprop_placeholder() method
In some cases you need to add a property but the contents of it
are not known at creation time, merely the extend of it.

This method allows you to create a property of a given size (filled
with garbage) while a pointer to the property data will be provided.

Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
[dwg: Corrected commit message]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2017-07-28 14:34:36 +10:00
Simon Glass
9067ee4be0 Fix a few whitespace and style nits
These were noticed when synching with U-Boot's downstream tree.

Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2017-04-09 20:56:37 +10:00
David Gibson
69a1bd6ad3 libfdt: Remove undefined behaviour setting empty properties
The standard way of setting an empty property using libfdt is:
    fdt_setprop(fdt, nodeoffset, propname, NULL, 0);
However, the implementation of this includes an unconditional:
     memcpy(prop->data, NULL, 0);
Which although it will be a no-op (which is what we want) on many platforms
is technically undefined behaviour.  Correct this, so that when passing
a 0 length, passing a NULL pointer as the value to fdt_setprop() is
definitely safe.  This should quiet static checkers which complain about
this.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2017-02-24 10:51:05 +11:00
Masahiro Yamada
36fd7331fb libfdt: simplify fdt_del_mem_rsv()
The variable "err" is unneeded.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2016-08-22 06:53:54 -04:00
Courtney Cavin
d4c7c25c9e libfdt: check for potential overrun in _fdt_splice()
This patch catches the conditions where:
 - 'splicepoint' is set to a point outside of [ fdt, fdt_totalsize(fdt) )
 - 'newlen' is negative, or 'splicepoint' plus 'newlen' results in overflow

Either of these cases can be caused by math which overflows in calling
functions, or by sizes specified through dynamic means.

Signed-off-by: Courtney Cavin <courtney.cavin@sonymobile.com>
Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
2015-12-02 13:11:11 +11:00
Florian Fainelli
3a584d4760 libfdt: avoid shadowing "err" in FDT_RW_CHECK_HEADER
FDT_RW_CHECK_HEADER declares an internal variable named "err" which is
far too generic and will produce the following -Wshadow warnings:

libfdt/fdt_rw.c: In function 'fdt_add_mem_rsv':
libfdt/fdt_rw.c:177:2: error: declaration of 'err' shadows a previous
local [-Werror=shadow]
libfdt/fdt_rw.c:175:6: error: shadowed declaration is here
[-Werror=shadow]
libfdt/fdt_rw.c: In function 'fdt_del_mem_rsv':
libfdt/fdt_rw.c:194:2: error: declaration of 'err' shadows a previous
local [-Werror=shadow]
libfdt/fdt_rw.c:192:6: error: shadowed declaration is here
[-Werror=shadow]
libfdt/fdt_rw.c: In function 'fdt_set_name':
...

Since this variable is only used internally in the macro, rename to
__err which should be prefixed enough not to cause new shadow warnings.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
2014-01-25 15:11:20 +11:00
Kim Phillips
142419e43c dtc/libfdt: sparse fixes
libfdt/fdt.c:104:28: warning: incorrect type in argument 1 (different base types)
libfdt/fdt.c:104:28:    expected restricted fdt32_t [usertype] x
libfdt/fdt.c:104:28:    got unsigned int const [unsigned] [usertype] <noident>
libfdt/fdt.c:124:40: warning: incorrect type in argument 1 (different base types)
libfdt/fdt.c:124:40:    expected restricted fdt32_t [usertype] x
libfdt/fdt.c:124:40:    got unsigned int const [unsigned] [usertype] <noident>
libfdt/fdt_ro.c:337:29: warning: incorrect type in argument 1 (different base types)
libfdt/fdt_ro.c:337:29:    expected restricted fdt32_t [usertype] x
libfdt/fdt_ro.c:337:29:    got unsigned int const [unsigned] [usertype] <noident>
libfdt/fdt_rw.c:370:17: warning: incorrect type in assignment (different base types)
libfdt/fdt_rw.c:370:17:    expected unsigned int [unsigned] [usertype] <noident>
libfdt/fdt_rw.c:370:17:    got restricted fdt32_t
libfdt/fdt_sw.c:164:13: warning: incorrect type in assignment (different base types)
libfdt/fdt_sw.c:164:13:    expected unsigned int [unsigned] [usertype] <noident>
libfdt/fdt_sw.c:164:13:    got restricted fdt32_t
libfdt/fdt_sw.c:227:14: warning: incorrect type in assignment (different base types)
libfdt/fdt_sw.c:227:14:    expected unsigned int [unsigned] [usertype] <noident>
libfdt/fdt_sw.c:227:14:    got restricted fdt32_t
libfdt/fdt_wip.c:80:20: warning: incorrect type in assignment (different base types)
libfdt/fdt_wip.c:80:20:    expected unsigned int [unsigned] [usertype] <noident>
libfdt/fdt_wip.c:80:20:    got restricted fdt32_t
libfdt/libfdt.h:1001:13: warning: incorrect type in assignment (different base types)
libfdt/libfdt.h:1001:13:    expected unsigned long [unsigned] [usertype] val
libfdt/libfdt.h:1001:13:    got restricted fdt64_t
libfdt/libfdt.h:1157:13: warning: incorrect type in assignment (different base types)
libfdt/libfdt.h:1157:13:    expected unsigned int [unsigned] [usertype] val
libfdt/libfdt.h:1157:13:    got restricted fdt32_t
libfdt/libfdt.h:1192:13: warning: incorrect type in assignment (different base types)
libfdt/libfdt.h:1192:13:    expected unsigned long [unsigned] [usertype] val
libfdt/libfdt.h:1192:13:    got restricted fdt64_t
libfdt/libfdt.h:1299:13: warning: incorrect type in assignment (different base types)
libfdt/libfdt.h:1299:13:    expected unsigned int [unsigned] [usertype] val
libfdt/libfdt.h:1299:13:    got restricted fdt32_t
libfdt/libfdt.h:1334:13: warning: incorrect type in assignment (different base types)
libfdt/libfdt.h:1334:13:    expected unsigned long [unsigned] [usertype] val
libfdt/libfdt.h:1334:13:    got restricted fdt64_t
libfdt/libfdt.h:885:13: warning: incorrect type in assignment (different base types)
libfdt/libfdt.h:885:13:    expected unsigned int [unsigned] [usertype] val
libfdt/libfdt.h:885:13:    got restricted fdt32_t
libfdt/libfdt.h:920:13: warning: incorrect type in assignment (different base types)
libfdt/libfdt.h:920:13:    expected unsigned long [unsigned] [usertype] val
libfdt/libfdt.h:920:13:    got restricted fdt64_t
libfdt/libfdt.h:996:13: warning: incorrect type in assignment (different base types)
libfdt/libfdt.h:996:13:    expected unsigned int [unsigned] [usertype] val
libfdt/libfdt.h:996:13:    got restricted fdt32_t

Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
2013-01-06 15:58:23 -06:00
Minghuan Lian
a31e3ef83b libfdt: Add support for appending the values to a existing property
Some properties may contain multiple values, these values may need
to be added to the property respectively. this patch provides this
functionality. The main purpose of fdt_append_prop() is to append
the values to a existing property, or create a new property if it
dose not exist.

Signed-off-by: Minghuan Lian <Minghuan.Lian@freescale.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2011-12-05 10:17:58 -06:00
David Gibson
1a020e4030 libfdt: Rework/cleanup fdt_next_tag()
Currently, callers of fdt_next_tag() must usually follow the call with
some sort of call to fdt_offset_ptr() to verify that the blob isn't
truncated in the middle of the tag data they're going to process.
This is a bit silly, since fdt_next_tag() generally has to call
fdt_offset_ptr() on at least some of the data following the tag for
its own operation.

This patch alters fdt_next_tag() to always use fdt_offset_ptr() to
verify the data between its starting offset and the offset it returns
in nextoffset.  This simplifies fdt_get_property() which no longer has
to verify itself that the property data is all present.

At the same time, I neaten and clarify the error handling for
fdt_next_tag().  Previously, fdt_next_tag() could return -1 instead of
a tag value in some circumstances - which almost none of the callers
checked for.  Also, fdt_next_tag() could return FDT_END either because
it encountered an FDT_END tag, or because it reached the end of the
structure block - no way was provided to tell between these cases.

With this patch, fdt_next_tag() always returns FDT_END with a negative
value in nextoffset for an error.  This means the several places which
loop looking for FDT_END will still work correctly - they only need to
check for errors at the end.  The errors which fdt_next_tag() can
report are:
	- -FDT_ERR_TRUNCATED if it reached the end of the structure
	   block instead of finding a tag.

	- -FDT_BADSTRUCTURE if a bad tag was encountered, or if the
           tag data couldn't be verified with fdt_offset_ptr().

This patch also updates the callers of fdt_next_tag(), where
appropriate, to make use of the new error reporting.

Finally, the prototype for the long gone _fdt_next_tag() is removed
from libfdt_internal.h.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2009-02-06 11:19:14 -06:00
David Gibson
b6d80a20fc libfdt: Increase namespace-pollution paranoia
libfdt is supposed to easy to embed in projects all and sundry.
Often, it won't be practical to separate the embedded libfdt's
namespace from that of the surrounding project.  Which means there can
be namespace conflicts between even libfdt's internal/static functions
and functions or macros coming from the surrounding project's headers
via libfdt_env.h.

This patch, therefore, renames a bunch of libfdt internal functions
and macros and makes a few other chances to reduce the chances of
namespace collisions with embedding projects.  Specifically:
	- Internal functions (even static ones) are now named _fdt_*()

	- The type and (static) global for the error table in
          fdt_strerror() gain an fdt_ prefix

	- The unused macro PALIGN is removed

	- The memeq and streq macros are removed and open-coded in the
          users (they were only used once each)

	- Other macros gain an FDT_ prefix

	- To save some of the bulk from the previous change, an
          FDT_TAGALIGN() macro is introduced, where FDT_TAGALIGN(x) ==
          FDT_ALIGN(x, FDT_TAGSIZE)

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2008-07-14 12:36:27 -05:00
David Gibson
1409097db8 dtc: Enable and fix -Wcast-qual warnings
Enabling -Wcast-qual warnings in dtc shows up a number of places where
we are incorrectly discarding a const qualification.  There are also
some places where we are intentionally discarding the 'const', and we
need an ugly cast through uintptr_t to suppress the warning.  However,
most of these are pretty well isolated with the *_w() functions.  So
in the interests of maximum safety with const qualifications, this
patch enables the warnings and fixes the existing complaints.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2008-07-14 12:36:08 -05:00
David Gibson
36786db615 dtc: Enable and fix -Wpointer-arith warnings
This patch turns on the -Wpointer-arith option in the dtc Makefile,
and fixes the resulting warnings due to using (void *) in pointer
arithmetic.  While convenient, pointer arithmetic on void * is not
portable, so it's better that we avoid it, particularly in libfdt.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2008-07-14 12:36:08 -05:00
David Gibson
aa1baab3cc libfdt: Several cleanups to parameter checking
This patch makes a couple of small cleanups to parameter checking of
libfdt functions.

	- In several functions which take a node offset, we use an
idiom involving fdt_next_tag() first to check that we have indeed been
given a node offset.  This patch adds a helper function
_fdt_check_node_offset() to encapsulate this usage of fdt_next_tag().

	- In fdt_rw.c in several places we have the expanded version
of the RW_CHECK_HEADER() macro for no particular reason.  This patch
replaces those instances with an invocation of the macro; that's what
it's for.

	- In fdt_sw.c we rename the check_header_sw() function to
sw_check_header() to match the analgous function in fdt_rw.c, and we
provide an SW_CHECK_HEADER() wrapper macro as RW_CHECK_HEADER()
functions in fdt_rw.c

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2008-05-29 08:15:53 -05:00
David Gibson
8a4e75049d libfdt: Trivial cleanup for CHECK_HEADER)
Currently the CHECK_HEADER() macro is defined local to fdt_ro.c.
However, there are a handful of functions (fdt_move, rw_check_header,
fdt_open_into) from other files which could also use it (currently
they open-code something more-or-less identical).  Therefore, this
patch moves CHECK_HEADER() to libfdt_internal.h and uses it in those
places.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2008-02-18 08:27:13 -06:00
David Gibson
089adb9964 libfdt: Fix NOP handling bug in fdt_add_subnode_namelen()
fdt_add_subnode_namelen() has a bug if asked to add a subnode to a
node which has NOP tags interspersed with its properties.  In this
case fdt_add_subnode_namelen() will put the new subnode before the
first NOP tag, even if there are properties after it, which will
result in an invalid blob.

This patch fixes the bug, and adds a testcase for it.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2008-02-14 08:02:41 -06:00
David Gibson
82b327d380 libfdt: Add fdt_set_name() function
This patch adds an fdt_set_name() function to libfdt, mirroring
fdt_get_name().  This is a r/w function which alters the name of a
given device tree node.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2008-01-11 07:40:40 -06:00
David Gibson
67b6b33b9b dtc: Add valgrind support to testsuite
This patch adds some options to the run_tests.sh script allowing it to
run all the testcases under valgrind to check for pointer corruption
bugs and memory leaks.  Invoking "make checkm" will run the testsuite
with valgrind.

It include a mechanism for specifying valgrind errors to be suppressed
on a per-testcase basis, and adds a couple of such suppression files
for the mangle-layout and open_pack testcases which dump for use by
other testcases a buffer which may contain uninitialized sections.  We
use suppressions rather than initializing the buffer so that valgrind
will catch any internal access s to the uninitialized data, which
would be a bug.

The patch also fixes one genuine bug caught by valgrind -
_packblocks() in fdt_rw.c was using memcpy() where it should have been
using memmove().

At present the valgrinding won't do anything useful for testcases
invoked via a shell script - which includes all the dtc testcases.  I
plan to fix that later.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2007-11-26 15:57:58 -06:00
David Gibson
a041dcdc48 libfdt: Handle v16 and re-ordered trees for r/w
Currently all the read/write functions in libfdt require that the
given tree be v17, and further, that the tree has the memory
reservation block, structure block and strings block stored in that
physical order.

This patch eases these constraints, by making fdt_open_int() reorder
the blocks, and/or convert the tree to v17, so that it will then be
ready for the other read-write functions.

It also extends fdt_pack() to actually remove any gaps between blocks
that might be present.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2007-11-01 08:03:31 -05:00
David Gibson
4a5df5c026 libfdt: Correctly handle versions > 17
If future dtb version > 17 are defined, that are still backwards
compatible with v16, libfdt will of course be able to read and
understand them.  However, when modifying such a tree, it can't
guarantee that it won't clobber additional structure from the new
version which it doesn't know about.  Therefore, before making
modifications to a tree of version >17, we must change it's version to
be exactly 17.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2007-10-30 07:48:35 -05:00
David Gibson
9b91134ba3 libfdt: Remove un-const-safe fdt_set_header macro
The fdt_set_header() macro casts an arbitrary pointer into (struct
fdt_header *) to set fdt header fields.  While we need to change the
type, so that we can use this macro on the usual (void *) used to
represent a device tree blob, the current macro also casts away any
const on the input pointer, which loses an important check.

This patch replaces the fdt_set_header() macro with a set of inline
functions, one for each header field which do a similar thing, but
which won't silently remove const from a given pointer.  This approach
is also more in keeping with the individual accessor macros we use for
reading fdt header fields.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2007-10-25 09:49:18 -05:00
David Gibson
3c44c87bde libfdt: Rename and publish _fdt_next_tag()
Although it's a low-level function that shouldn't normally be needed,
there are circumstances where it's useful for users of libfdt to use
the _fdt_next_tag() function.  Therefore, this patch renames it to
fdt_next_tag() and publishes it in libfdt.h.

In addition, this patch adds a new testcase using fdt_next_tag(),
dtbs_equal_ordered.  This testcase tests for structural equality of
two dtbs, including the order of properties and subnodes, but ignoring
NOP tags, the order of the dtb sections and the layout of strings in
the strings block.  This will be useful for testing other dtc
functionality in the future.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2007-10-24 09:56:27 -05:00
David Gibson
96b5fad3a1 libfdt: Rename and publish _fdt_check_header()
It's potentially useful for users of libfdt to sanity check a device
tree (or, rather, a blob of data which may or may not be a device
tree) before processing it in more detail with libfdt.

This patch renames the libfdt internal function _fdt_check_header() to
fdt_check_header() and makes it a published function, so it can now be
used for this purpose.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2007-10-24 07:58:13 -05:00
David Gibson
394e47208d libfdt: Add missing RW_CHECK_HEADER to fdt_del_node()
fdt_del_node(), unlike most of the rw functions does not check the
fdt's header with RW_CHECK_HEADER.  However, it could make a mess of
things if the conditions in RW_CHECK_HEADER aren't met.  So, this
patch adds the omitted check.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2007-10-22 09:52:18 -05:00
David Gibson
fd1bf3a5ae libfdt: Add functions to get/add/delete memory reservemap entries
This patch adds functions to libfdt for accessing the memory
reservation map section of a device tree blob.  fdt_num_mem_rsv()
retreives the number of reservation entries in a dtb, and
fdt_get_mem_rsv() retreives a specific reservation entry.
fdt_add_mem_rsv() adds a new entry, and fdt_del_mem_rsv() removes a
specific numbered entry.

Testcases for these new functions are also included.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2007-10-15 08:31:52 -05:00
David Gibson
23cdf2379f Move everything into a subdirectory in preparation for merge into dtc. 2007-06-14 11:58:35 +10:00
Renamed from fdt_rw.c (Browse further)