diff --git a/fdt_ro.c b/fdt_ro.c index bbc380a..bd58227 100644 --- a/fdt_ro.c +++ b/fdt_ro.c @@ -30,6 +30,13 @@ return OFFSET_ERROR(err); \ } +#define PTR_CHECK_HEADER(fdt) \ + { \ + int err; \ + if ((err = _fdt_check_header(fdt)) != 0) \ + return PTR_ERROR(err); \ + } + static int offset_streq(const struct fdt_header *fdt, int offset, const char *s, int len) { @@ -53,66 +60,6 @@ char *fdt_string(const struct fdt_header *fdt, int stroffset) return (char *)fdt + fdt_off_dt_strings(fdt) + stroffset; } -int fdt_property_offset(const struct fdt_header *fdt, int nodeoffset, - const char *name) -{ - int level = 0; - uint32_t tag; - struct fdt_property *prop; - int namestroff; - int offset, nextoffset; - - OFFSET_CHECK_HEADER(fdt); - - if (nodeoffset % FDT_TAGSIZE) - return OFFSET_ERROR(FDT_ERR_BADOFFSET); - - tag = _fdt_next_tag(fdt, nodeoffset, &nextoffset); - if (tag != FDT_BEGIN_NODE) - return OFFSET_ERROR(FDT_ERR_BADOFFSET); - - do { - offset = nextoffset; - if (offset % FDT_TAGSIZE) - return OFFSET_ERROR(FDT_ERR_INTERNAL); - - tag = _fdt_next_tag(fdt, offset, &nextoffset); - switch (tag) { - case FDT_END: - return OFFSET_ERROR(FDT_ERR_TRUNCATED); - - case FDT_BEGIN_NODE: - level++; - break; - - case FDT_END_NODE: - level--; - break; - - case FDT_PROP: - if (level != 0) - continue; - - prop = fdt_offset_ptr_typed(fdt, offset, prop); - if (! prop) - return OFFSET_ERROR(FDT_ERR_BADSTRUCTURE); - namestroff = fdt32_to_cpu(prop->nameoff); - if (streq(fdt_string(fdt, namestroff), name)) - /* Found it! */ - return offset; - break; - - case FDT_NOP: - break; - - default: - return OFFSET_ERROR(FDT_ERR_BADSTRUCTURE); - } - } while (level >= 0); - - return OFFSET_ERROR(FDT_ERR_NOTFOUND); -} - int fdt_subnode_offset_namelen(const struct fdt_header *fdt, int parentoffset, const char *name, int namelen) { @@ -197,30 +144,75 @@ int fdt_path_offset(const struct fdt_header *fdt, const char *path) return offset; } -struct fdt_property *_fdt_getprop(const struct fdt_header *fdt, int nodeoffset, - const char *name, int *lenp) +struct fdt_property *fdt_get_property(const struct fdt_header *fdt, + int nodeoffset, + const char *name, int *lenp) { - int propoffset; + int level = 0; + uint32_t tag; struct fdt_property *prop; - int err; - int len; + int namestroff; + int offset, nextoffset; - propoffset = fdt_property_offset(fdt, nodeoffset, name); - if ((err = fdt_offset_error(propoffset))) - return PTR_ERROR(err); + PTR_CHECK_HEADER(fdt); - prop = fdt_offset_ptr(fdt, propoffset, sizeof(prop)); - if (! prop) - return PTR_ERROR(FDT_ERR_BADSTRUCTURE); - len = fdt32_to_cpu(prop->len); - prop = fdt_offset_ptr(fdt, propoffset, sizeof(prop) + len); - if (! prop) - return PTR_ERROR(FDT_ERR_BADSTRUCTURE); + if (nodeoffset % FDT_TAGSIZE) + return PTR_ERROR(FDT_ERR_BADOFFSET); - if (lenp) - *lenp = len; + tag = _fdt_next_tag(fdt, nodeoffset, &nextoffset); + if (tag != FDT_BEGIN_NODE) + return PTR_ERROR(FDT_ERR_BADOFFSET); + + do { + offset = nextoffset; + if (offset % FDT_TAGSIZE) + return PTR_ERROR(FDT_ERR_INTERNAL); + + tag = _fdt_next_tag(fdt, offset, &nextoffset); + switch (tag) { + case FDT_END: + return PTR_ERROR(FDT_ERR_TRUNCATED); + + case FDT_BEGIN_NODE: + level++; + break; + + case FDT_END_NODE: + level--; + break; + + case FDT_PROP: + if (level != 0) + continue; + + prop = fdt_offset_ptr_typed(fdt, offset, prop); + if (! prop) + return PTR_ERROR(FDT_ERR_BADSTRUCTURE); + namestroff = fdt32_to_cpu(prop->nameoff); + if (streq(fdt_string(fdt, namestroff), name)) { + /* Found it! */ + int len = fdt32_to_cpu(prop->len); + prop = fdt_offset_ptr(fdt, offset, + sizeof(prop)+len); + if (! prop) + return PTR_ERROR(FDT_ERR_BADSTRUCTURE); + + if (lenp) + *lenp = len; + + return prop; + } + break; + + case FDT_NOP: + break; + + default: + return PTR_ERROR(FDT_ERR_BADSTRUCTURE); + } + } while (level >= 0); - return prop; + return PTR_ERROR(FDT_ERR_NOTFOUND); } void *fdt_getprop(const struct fdt_header *fdt, int nodeoffset, @@ -229,7 +221,7 @@ void *fdt_getprop(const struct fdt_header *fdt, int nodeoffset, const struct fdt_property *prop; int err; - prop = _fdt_getprop(fdt, nodeoffset, name, lenp); + prop = fdt_get_property(fdt, nodeoffset, name, lenp); if ((err = fdt_ptr_error(prop))) return PTR_ERROR(err); diff --git a/fdt_rw.c b/fdt_rw.c index 45f1fa4..5cdb8c1 100644 --- a/fdt_rw.c +++ b/fdt_rw.c @@ -126,7 +126,7 @@ static struct fdt_property *_resize_property(struct fdt_header *fdt, int nodeoff int oldlen; int err; - prop = _fdt_getprop(fdt, nodeoffset, name, &oldlen); + prop = fdt_get_property(fdt, nodeoffset, name, &oldlen); if ((err = fdt_ptr_error(prop))) return PTR_ERROR(err); @@ -203,7 +203,7 @@ int fdt_delprop(struct fdt_header *fdt, int nodeoffset, const char *name) RW_OFFSET_CHECK_HEADER(fdt); - prop = _fdt_getprop(fdt, nodeoffset, name, &len); + prop = fdt_get_property(fdt, nodeoffset, name, &len); if ((err = fdt_ptr_error(prop))) return err; diff --git a/fdt_wip.c b/fdt_wip.c index 6e617ba..fa0df78 100644 --- a/fdt_wip.c +++ b/fdt_wip.c @@ -55,7 +55,7 @@ int fdt_nop_property(struct fdt_header *fdt, int nodeoffset, const char *name) int len; int err; - prop = _fdt_getprop(fdt, nodeoffset, name, &len); + prop = fdt_get_property(fdt, nodeoffset, name, &len); if ((err = fdt_ptr_error(prop))) return err; diff --git a/libfdt.h b/libfdt.h index 8216655..cee2b3c 100644 --- a/libfdt.h +++ b/libfdt.h @@ -72,8 +72,6 @@ struct fdt_header *fdt_move(const struct fdt_header *fdt, void *buf, int bufsize /* Read-only functions */ char *fdt_string(const struct fdt_header *fdt, int stroffset); -int fdt_property_offset(const struct fdt_header *fdt, int nodeoffset, - const char *name); int fdt_subnode_offset_namelen(const struct fdt_header *fdt, int parentoffset, const char *name, int namelen); int fdt_subnode_offset(const struct fdt_header *fdt, int parentoffset, @@ -81,6 +79,9 @@ int fdt_subnode_offset(const struct fdt_header *fdt, int parentoffset, int fdt_path_offset(const struct fdt_header *fdt, const char *path); +struct fdt_property *fdt_get_property(const struct fdt_header *fdt, + int nodeoffset, + const char *name, int *lenp); void *fdt_getprop(const struct fdt_header *fdt, int nodeoffset, const char *name, int *lenp); diff --git a/libfdt_internal.h b/libfdt_internal.h index 7dfa8df..b3da790 100644 --- a/libfdt_internal.h +++ b/libfdt_internal.h @@ -35,8 +35,6 @@ static inline int _ptr_offset(struct fdt_header *fdt, void *p) int _fdt_check_header(const struct fdt_header *fdt); uint32_t _fdt_next_tag(const struct fdt_header *fdt, int startoffset, int *nextoffset); -struct fdt_property *_fdt_getprop(const struct fdt_header *fdt, int nodeoffset, - const char *name, int *lenp); const char *_fdt_find_string(const char *strtab, int tabsize, const char *s); int _fdt_node_end_offset(struct fdt_header *fdt, int nodeoffset); diff --git a/tests/Makefile b/tests/Makefile index c9271a7..b0c4571 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,6 +1,6 @@ PREFIX = /usr/local -LIB_TESTS = root_node property_offset subnode_offset path_offset getprop \ +LIB_TESTS = root_node find_property subnode_offset path_offset getprop \ notfound \ setprop_inplace nop_property nop_node \ sw_tree1 \ diff --git a/tests/property_offset.c b/tests/find_property.c similarity index 100% rename from tests/property_offset.c rename to tests/find_property.c diff --git a/tests/notfound.c b/tests/notfound.c index 1dd8bc7..9cdc29c 100644 --- a/tests/notfound.c +++ b/tests/notfound.c @@ -36,6 +36,7 @@ void check_error(const char *s, int err) int main(int argc, char *argv[]) { + struct fdt_property *prop; struct fdt_header *fdt; int offset; int subnode1_offset; @@ -45,9 +46,9 @@ int main(int argc, char *argv[]) test_init(argc, argv); fdt = load_blob_arg(argc, argv); - offset = fdt_property_offset(fdt, 0, "nonexistant-property"); - check_error("fdt_property_offset(\"nonexistant-property\")", - fdt_offset_error(offset)); + prop = fdt_get_property(fdt, 0, "nonexistant-property", NULL); + check_error("fdt_get_property(\"nonexistant-property\")", + fdt_ptr_error(prop)); val = fdt_getprop(fdt, 0, "nonexistant-property", NULL); check_error("fdt_getprop(\"nonexistant-property\"", diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 1e2da40..c9c9879 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -14,7 +14,7 @@ tree1_tests () { # Read-only tests run_test root_node $TREE - run_test property_offset $TREE + run_test find_property $TREE run_test subnode_offset $TREE run_test path_offset $TREE run_test getprop $TREE diff --git a/tests/testutils.c b/tests/testutils.c index 4997a8e..994cdae 100644 --- a/tests/testutils.c +++ b/tests/testutils.c @@ -106,20 +106,12 @@ const char *fdt_strerror(int errval) void check_property(struct fdt_header *fdt, int nodeoffset, const char *name, int len, const void *val) { - int offset; const struct fdt_property *prop; uint32_t tag, nameoff, proplen; const char *propname; - int err; verbose_printf("Checking property \"%s\"...", name); - offset = fdt_property_offset(fdt, nodeoffset, name); - verbose_printf("offset %d...", offset); - if ((err = fdt_offset_error(offset))) - FAIL("fdt_property_offset(\"%s\"): %s", name, - fdt_strerror(err)); - - prop = fdt_offset_ptr_typed(fdt, offset, prop); + prop = fdt_get_property(fdt, nodeoffset, name, NULL); verbose_printf("pointer %p\n", prop); if (! prop) FAIL("NULL retreiving \"%s\" pointer", name);