Skip to content

Commit

Permalink
lib: libfdt: Import libfdt v1.7.0
Browse files Browse the repository at this point in the history
From https://git.kernel.org/pub/scm/utils/dtc/dtc.git tag v1.7.0
subdirectory libfdt
  • Loading branch information
stephan-gh committed Apr 16, 2023
1 parent 541d9bf commit 9708d01
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 34 deletions.
20 changes: 12 additions & 8 deletions lib/libfdt/fdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ int fdt_check_header(const void *fdt)
}
hdrsize = fdt_header_size(fdt);
if (!can_assume(VALID_DTB)) {

if ((fdt_totalsize(fdt) < hdrsize)
|| (fdt_totalsize(fdt) > INT_MAX))
return -FDT_ERR_TRUNCATED;
Expand All @@ -115,9 +114,7 @@ int fdt_check_header(const void *fdt)
if (!check_off_(hdrsize, fdt_totalsize(fdt),
fdt_off_mem_rsvmap(fdt)))
return -FDT_ERR_TRUNCATED;
}

if (!can_assume(VALID_DTB)) {
/* Bounds check structure block */
if (!can_assume(LATEST) && fdt_version(fdt) < 17) {
if (!check_off_(hdrsize, fdt_totalsize(fdt),
Expand Down Expand Up @@ -165,7 +162,7 @@ const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
{
const fdt32_t *tagp, *lenp;
uint32_t tag;
uint32_t tag, len, sum;
int offset = startoffset;
const char *p;

Expand All @@ -191,12 +188,19 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
if (!can_assume(VALID_DTB) && !lenp)
return FDT_END; /* premature end */

len = fdt32_to_cpu(*lenp);
sum = len + offset;
if (!can_assume(VALID_DTB) &&
(INT_MAX <= sum || sum < (uint32_t) offset))
return FDT_END; /* premature end */

/* skip-name offset, length and value */
offset += sizeof(struct fdt_property) - FDT_TAGSIZE
+ fdt32_to_cpu(*lenp);
offset += sizeof(struct fdt_property) - FDT_TAGSIZE + len;

if (!can_assume(LATEST) &&
fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 &&
((offset - fdt32_to_cpu(*lenp)) % 8) != 0)
fdt_version(fdt) < 0x10 && len >= 8 &&
((offset - len) % 8) != 0)
offset += 4;
break;

Expand Down
4 changes: 2 additions & 2 deletions lib/libfdt/fdt.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ struct fdt_reserve_entry {

struct fdt_node_header {
fdt32_t tag;
char name[0];
char name[];
};

struct fdt_property {
fdt32_t tag;
fdt32_t len;
fdt32_t nameoff;
char data[0];
char data[];
};

#endif /* !__ASSEMBLY */
Expand Down
2 changes: 1 addition & 1 deletion lib/libfdt/fdt_addresses.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,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);
Expand Down
3 changes: 3 additions & 0 deletions lib/libfdt/fdt_check.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ int fdt_check_full(const void *fdt, size_t bufsize)
int len;

name = fdt_get_name(fdt, offset, &len);
if (!name)
return len;

if (*name || len)
return -FDT_ERR_BADSTRUCTURE;
}
Expand Down
29 changes: 7 additions & 22 deletions lib/libfdt/fdt_overlay.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,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 targeting is
* done (through a phandle or a path)
*
* returns:
* the targeted 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
Expand Down Expand Up @@ -636,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;

Expand Down Expand Up @@ -779,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;
Expand All @@ -801,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;
Expand Down
2 changes: 1 addition & 1 deletion lib/libfdt/fdt_ro.c
Original file line number Diff line number Diff line change
Expand Up @@ -481,12 +481,12 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset,
if (!can_assume(VALID_INPUT)) {
name = fdt_get_string(fdt, fdt32_ld_(&prop->nameoff),
&namelen);
*namep = name;
if (!name) {
if (lenp)
*lenp = namelen;
return NULL;
}
*namep = name;
} else {
*namep = fdt_string(fdt, fdt32_ld_(&prop->nameoff));
}
Expand Down
1 change: 1 addition & 0 deletions lib/libfdt/fdt_strerror.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ 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 ((int)(sizeof(fdt_errtable) / sizeof(fdt_errtable[0])))

Expand Down
32 changes: 32 additions & 0 deletions lib/libfdt/libfdt.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,13 @@ uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
* 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)
{
const uint8_t *bp = (const uint8_t *)p;
Expand Down Expand Up @@ -653,6 +660,13 @@ int fdt_next_property_offset(const void *fdt, int offset);
const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
int offset,
int *lenp);
static inline struct fdt_property *fdt_get_property_by_offset_w(void *fdt,
int offset,
int *lenp)
{
return (struct fdt_property *)(uintptr_t)
fdt_get_property_by_offset(fdt, offset, lenp);
}

/**
* fdt_get_property_namelen - find a property based on substring
Expand Down Expand Up @@ -2109,6 +2123,24 @@ 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 */
/**********************************************************************/
Expand Down
1 change: 1 addition & 0 deletions lib/libfdt/version.lds
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ LIBFDT_1.2 {
fdt_appendprop_addrrange;
fdt_setprop_inplace_namelen_partial;
fdt_create_with_flags;
fdt_overlay_target_offset;
local:
*;
};

0 comments on commit 9708d01

Please sign in to comment.