diff --git a/sdbfs/userspace/sdb-read.c b/sdbfs/userspace/sdb-read.c index 626ec21c4960f9083d56539b7c94dec7983e9484..02ef101e8f89cfddde3bc4c384e73206b4ee1df9 100644 --- a/sdbfs/userspace/sdb-read.c +++ b/sdbfs/userspace/sdb-read.c @@ -22,11 +22,27 @@ char *prgname; -int opt_long, opt_verbose, opt_read, opt_entry; +int opt_long, opt_verbose, opt_read, opt_entry, opt_mem; +unsigned long opt_memaddr, opt_memsize; + +static void help(void) +{ + fprintf(stderr, "%s: Use: \"%s [options] <image-file> [<file>]\n", + prgname, prgname); + fprintf(stderr, " -l long listing (like ls -l)\n"); + fprintf(stderr, " -v verbose\n"); + fprintf(stderr, " -r force use of read(2), not mmap(2)\n"); + fprintf(stderr, " -e <num> entry point offset\n"); + fprintf(stderr, " -m <size>@<addr> memory subset to use\n"); + fprintf(stderr, " -m <addr>+<size> memory subset to use\n"); + exit(1); +} struct sdbr_drvdata { void *mapaddr; FILE *f; + unsigned long memaddr; + unsigned long memsize; }; /* @@ -46,7 +62,7 @@ static int do_read(struct sdbfs *fs, int offset, void *buf, int count) } /* not mmapped: seek and read */ - if (fseek(drvdata->f, offset, SEEK_SET) < 0) + if (fseek(drvdata->f, drvdata->memaddr + offset, SEEK_SET) < 0) return -1; return fread(buf, 1, count, drvdata->f); } @@ -143,7 +159,7 @@ int main(int argc, char **argv) prgname = argv[0]; - while ( (c = getopt(argc, argv, "lvre:")) != -1) { + while ( (c = getopt(argc, argv, "lvre:m:")) != -1) { switch (c) { case 'l': opt_long = 1; @@ -161,13 +177,24 @@ int main(int argc, char **argv) exit(1); } break; + case 'm': + /* memory: "size@addr", "addr+size" (blanks ok) */ + if (sscanf(optarg, "%li @ %li", &opt_memsize, + &opt_memaddr) == 2) + break; + if (sscanf(optarg, "%li + %li", &opt_memaddr, + &opt_memsize) == 2) + break; + + fprintf(stderr, "%s: \"%s\" must be <size>@<addr> " + "or <addr>+<size>\n", prgname, optarg); + exit(1); + break; } } - if (optind < argc - 2 || optind > argc - 1) { - fprintf(stderr, "%s: Use: \"%s [-l|-v] <image-file> [<file>]\n", - prgname, prgname); - exit(1); - } + if (optind < argc - 2 || optind > argc - 1) + help(); + fsname = argv[optind]; if (optind + 1 < argc) filearg = argv[optind + 1]; @@ -177,20 +204,25 @@ int main(int argc, char **argv) exit(1); } - /* Save the file pointer in drvdata for fseek/fread use */ - drvdata = calloc(1, sizeof(*drvdata)); - drvdata->f = f; - stbuf.st_size += pagesize - 1; stbuf.st_size &= ~(pagesize - 1); - mapaddr = mmap(0, stbuf.st_size, PROT_READ, MAP_PRIVATE, fileno(f), 0); + mapaddr = mmap(0, + opt_memsize ? opt_memsize : stbuf.st_size, + PROT_READ, MAP_PRIVATE, fileno(f), + opt_memaddr /* 0 by default */); if (mapaddr == MAP_FAILED) - drvdata->mapaddr = NULL; - else - drvdata->mapaddr = mapaddr; + mapaddr = NULL; /* We'll seek/read */ /* So, describe the filesystem instance and give it to the library */ memset(fs, 0, sizeof(*fs)); + + drvdata = calloc(1, sizeof(*drvdata)); + if (!drvdata) {perror("malloc"); exit(1);} + drvdata->f = f; + drvdata->memaddr = opt_memaddr; + drvdata->memsize = opt_memsize; + drvdata->mapaddr = mapaddr; + fs->drvdata = drvdata; fs->name = fsname; /* not mandatory */ fs->blocksize = 256; /* only used for writing, actually */