From fdc7387845420168ee5dd479fbe4391ff93bddab Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 15 Apr 2013 22:13:13 -0400 Subject: fdtdump: add a --scan option Often times, fdts get embedded in other larger files. Rather than force people to `dd` the blob out themselves, make the fdtdump file smarter. It can now scan the blob looking for the fdt magic. Once locate, it does a little validation on the main struct to make sure we didn't hit random binary data. Signed-off-by: Mike Frysinger Signed-off-by: David Gibson --- fdtdump.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) (limited to 'fdtdump.c') diff --git a/fdtdump.c b/fdtdump.c index a6e522c..c8a3ee7 100644 --- a/fdtdump.c +++ b/fdtdump.c @@ -2,12 +2,14 @@ * fdtdump.c - Contributed by Pantelis Antoniou */ +#include #include #include #include #include #include +#include #include #include @@ -119,11 +121,13 @@ static void dump_blob(void *blob) /* Usage related data. */ static const char usage_synopsis[] = "fdtdump [options] "; -static const char usage_short_opts[] = USAGE_COMMON_SHORT_OPTS; +static const char usage_short_opts[] = "s" USAGE_COMMON_SHORT_OPTS; static struct option const usage_long_opts[] = { + {"scan", no_argument, NULL, 's'}, USAGE_COMMON_LONG_OPTS }; static const char * const usage_opts_help[] = { + "Scan for an embedded fdt in file", USAGE_COMMON_OPTS_HELP }; @@ -132,20 +136,58 @@ int main(int argc, char *argv[]) int opt; const char *file; char *buf; + bool scan = false; + off_t len; while ((opt = util_getopt_long()) != EOF) { switch (opt) { case_USAGE_COMMON_FLAGS + + case 's': + scan = true; + break; } } if (optind != argc - 1) long_usage("missing input filename"); file = argv[optind]; - buf = utilfdt_read(file); + buf = utilfdt_read_len(file, &len); if (!buf) die("could not read: %s\n", file); + /* try and locate an embedded fdt in a bigger blob */ + if (scan) { + unsigned char smagic[4]; + char *p = buf; + char *endp = buf + len; + + fdt_set_magic(smagic, FDT_MAGIC); + + /* poor man's memmem */ + while (true) { + p = memchr(p, smagic[0], endp - p - 4); + if (!p) + break; + if (fdt_magic(p) == FDT_MAGIC) { + /* try and validate the main struct */ + off_t this_len = endp - p; + fdt32_t max_version = 17; + if (fdt_version(p) <= max_version && + fdt_last_comp_version(p) < max_version && + fdt_totalsize(p) < this_len && + fdt_off_dt_struct(p) < this_len && + fdt_off_dt_strings(p) < this_len) + break; + } + ++p; + } + if (!p) + die("%s: could not locate fdt magic\n", file); + printf("%s: found fdt at offset %#zx\n", file, p - buf); + buf = p; + } + dump_blob(buf); return 0; -- cgit v1.2.1