This file provides read-only access to the device tree and includes many sanity checks. Allow these checks to be disabled to reduce code size. Signed-off-by: Simon Glass <sjg@xxxxxxxxxxxx> --- libfdt/fdt_ro.c | 73 +++++++++++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 26 deletions(-) diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index 6fd9ec1..bc1b4e0 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -14,9 +14,13 @@ static int fdt_nodename_eq_(const void *fdt, int offset, const char *s, int len) { int olen; - const char *p = fdt_get_name(fdt, offset, &olen); + const char *p; - if (!p || olen < len) + if (_check2()) + p = fdt_get_name(fdt, offset, &olen); + else + p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1); + if (!p || (_check2() && olen < len)) /* short match */ return 0; @@ -33,16 +37,19 @@ 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); + uint32_t absoffset; size_t len; int err; const char *s, *n; + if (!_check2()) + return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset; err = fdt_ro_probe_(fdt); if (err != 0) goto fail; err = -FDT_ERR_BADOFFSET; + absoffset = stroffset + fdt_off_dt_strings(fdt); if (absoffset >= fdt_totalsize(fdt)) goto fail; len = fdt_totalsize(fdt) - absoffset; @@ -150,10 +157,13 @@ 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; - if (absoffset < fdt_off_mem_rsvmap(fdt)) - return NULL; - if (absoffset > fdt_totalsize(fdt) - sizeof(struct fdt_reserve_entry)) - return NULL; + if (_check2()) { + 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); } @@ -163,7 +173,7 @@ 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 (_check2() && !re) return -FDT_ERR_BADOFFSET; *address = fdt64_ld(&re->address); @@ -288,13 +298,14 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *len) const char *nameptr; int err; - if (((err = fdt_ro_probe_(fdt)) != 0) - || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0)) - goto fail; + if (_check2() && + (((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 (_check1() && fdt_version(fdt) < 0x10) { /* * For old FDT versions, match the naming conventions of V16: * give only the leaf name (after all /). The actual tree @@ -345,7 +356,7 @@ 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 (_check1() && (err = fdt_check_prop_offset_(fdt, offset)) < 0) { if (lenp) *lenp = err; return NULL; @@ -387,7 +398,8 @@ 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 (_check2() && !prop) { offset = -FDT_ERR_INTERNAL; break; } @@ -460,14 +472,19 @@ 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 (_check2()) { + 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 */ @@ -597,10 +614,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 (_check2()) { + 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() */ } @@ -612,7 +631,7 @@ 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 (!_check2() || err < 0) ? err : -FDT_ERR_INTERNAL; return nodedepth; } @@ -833,6 +852,7 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset, return offset; /* error from fdt_next_node() */ } +#if !defined(CHECK_LEVEL) || CHECK_LEVEL > 0 int fdt_check_full(const void *fdt, size_t bufsize) { int err; @@ -895,3 +915,4 @@ int fdt_check_full(const void *fdt, size_t bufsize) } } } +#endif -- 2.22.0.657.g960e92d24f-goog