diff options
author | Mike Frysinger <vapier@gentoo.org> | 2013-04-15 22:13:13 -0400 |
---|---|---|
committer | David Gibson <david@gibson.dropbear.id.au> | 2013-05-24 18:20:53 +1000 |
commit | fdc7387845420168ee5dd479fbe4391ff93bddab (patch) | |
tree | f73410d17dd69b5002662558e205570e63804785 | |
parent | be8d1c82cb0a9caeb7e2f804f9a9f845063d7d53 (diff) | |
download | device-tree-compiler-fdc7387845420168ee5dd479fbe4391ff93bddab.tar.gz |
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 <vapier@gentoo.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
-rw-r--r-- | fdtdump.c | 46 |
1 files changed, 44 insertions, 2 deletions
@@ -2,12 +2,14 @@ * fdtdump.c - Contributed by Pantelis Antoniou <pantelis.antoniou AT gmail.com> */ +#include <stdbool.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> +#include <libfdt.h> #include <libfdt_env.h> #include <fdt.h> @@ -119,11 +121,13 @@ static void dump_blob(void *blob) /* Usage related data. */ static const char usage_synopsis[] = "fdtdump [options] <file>"; -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; |