diff options
Diffstat (limited to 'util/listblob.c')
-rw-r--r-- | util/listblob.c | 240 |
1 files changed, 0 insertions, 240 deletions
diff --git a/util/listblob.c b/util/listblob.c deleted file mode 100644 index e6266a3..0000000 --- a/util/listblob.c +++ /dev/null @@ -1,240 +0,0 @@ -/** -** @file listblob.c -** -** @author Warren R. Carithers -** -** Examine a binary blob of ELF files. -*/ -#define _DEFAULT_SOURCE -#include <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <stdbool.h> -#include <string.h> -#include <unistd.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <elf.h> -#include <ctype.h> - -/* -** Blob file organization -** -** The file begins with a four-byte magic number and a four-byte integer -** indicating the number of ELF files contained in the blob. This is -** followed by an array of 32-byte file entries, and then the contents -** of the ELF files in the order they appear in the program file table. -** -** Bytes Contents -** ----- ---------------------------- -** 0 - 3 File magic number ("BLB\0") -** 4 - 7 Number of ELF files in blob ("n") -** 8 - n*32+8 Program file table -** n*32+9 - ? ELF file contents -** -** Each program file table entry contains the following information: -** -** name File name (up to 19 characters long) -** offset Byte offset to the ELF header for this file -** size Size of this ELF file, in bytes -** flags Flags related to this file -*/ - -// blob header: 8 bytes -typedef struct header_s { - char magic[4]; - uint32_t num; -} header_t; - -// The program table entry is 32 bytes long. To accomplish this, the -// name field is 20 bytes long, which allows file names of 19 characters -// (followed by a trailing NUL byte). -// -// If that field is made longer, it should be incremented in multiples -// of four to avoid the insertion of padding bytes. -#define NAMELEN 20 - -// program descriptor: 32 bytes -typedef struct prog_s { - char name[NAMELEN]; // truncated name (19 chars plus NUL) - uint32_t offset; // offset from the beginning of the blob - uint32_t size; // size of this ELF module - uint32_t flags; // miscellaneous flags -} prog_t; - -// modules must be written as multiples of eight bytes -#define FL_ROUNDUP 0x00000001 - -// mask for mod 8 checking -#define FSIZE_MASK 0x00000007 - -// program list entry -typedef struct node_s { - prog_t *data; - struct node_s *next; -} node_t; - -node_t *progs, *last_prog; // list pointers -uint32_t n_progs; // number of files being copied -uint32_t offset; // current file area offset -bool defs = false; // print CPP #defines? -bool enums = false; // print C enums? - -// header string for the userids.h file -const char header[] = - "/**\n" - "** @file userids.h\n" - "**\n" - "** @author Warren R. Carithers\n" - "**\n" - "** @brief IDs for user-level programs\n" - "**\n" - "** NOTE: this file is automatically generated when the user.img file\n" - "** is created. Do not edit this manually!\n" - "*/\n" - "\n" - "#ifndef USERIDS_H_\n" - "#define USERIDS_H_\n" - "\n" - "#ifndef ASM_SRC\n" - "/*\n" - "** These IDs are used to identify the various user programs.\n" - "** Each call to exec() will provide one of these as the first\n" - "** argument.\n" - "**\n" - "** This list should be updated if/when the collection of\n" - "** user processes changes.\n" - "*/\n" - "enum users_e {"; - -// trailer string for the userids.h file -const char trailer[] = "\n\t// sentinel\n\t, N_USERS\n" - "};\n" - "#endif /* !ASM_SRC */\n" - "\n" - "#endif"; - -/** -** Name: process -** -** Process a program list entry -** -** @param num Program list index -** @param prog Pointer to the program list entry -*/ -void process(uint32_t num, prog_t *prog) -{ - if (defs || enums) { - char *slash = strrchr(prog->name, '/'); - if (slash == NULL) { - slash = prog->name; - } else { - ++slash; - } - - slash[0] = toupper(slash[0]); - - if (defs) { - // just printing #define statements - printf("#define %-15s %2d\n", prog->name, num); - - } else { - // printing a new userids.h file - if (num == 0) { - // first one, so print the file header - puts(header); - putchar('\t'); - } else { - // second or later entry; limit to 8 per line - fputs(((num & 0x7) == 0) ? ",\n\t" : ", ", stdout); - } - printf("%s", prog->name); - } - - } else { - // just printing information - printf("Entry %2d: ", num); - printf("%-s,", prog->name); - printf(" offset 0x%x, size 0x%x, flags %08x\n", prog->offset, - prog->size, prog->flags); - } -} - -void usage(char *name) -{ - fprintf(stderr, "usage: %s [-d | -e] blob_name\n", name); -} - -int main(int argc, char *argv[]) -{ - if (argc < 2 || argc > 3) { - usage(argv[0]); - exit(1); - } - - int nameix = 1; - - // could use getopt() for this, but this is easy enough - if (argc == 3) { - if (strcmp(argv[1], "-d") == 0) { - defs = true; - } else if (strcmp(argv[1], "-e") == 0) { - enums = true; - } else { - usage(argv[0]); - exit(1); - } - nameix = 2; - } - - char *name = argv[nameix]; - - int fd = open(name, O_RDONLY); - if (fd < 0) { - perror(name); - exit(1); - } - - header_t hdr; - - int n = read(fd, &hdr, sizeof(header_t)); - if (n != sizeof(header_t)) { - fprintf(stderr, "%s: header read returned only %d bytes\n", name, n); - close(fd); - exit(1); - } - - if (strcmp(hdr.magic, "BLB") != 0) { - fprintf(stderr, "%s: bad magic number\n", name); - close(fd); - exit(1); - } - - if (hdr.num < 1) { - fprintf(stderr, "%s: no programs in blob?\n", name); - close(fd); - exit(1); - } - - prog_t progs[hdr.num]; - - n = read(fd, progs, hdr.num * sizeof(prog_t)); - if (n != (int)(hdr.num * sizeof(prog_t))) { - fprintf(stderr, "%s: prog table only %d bytes, expected %lu\n", name, n, - hdr.num * sizeof(prog_t)); - close(fd); - exit(1); - } - - for (uint32_t i = 0; i < hdr.num; ++i) { - process(i, &progs[i]); - } - - if (enums) { - // print the file trailer - puts(trailer); - } - - close(fd); - return 0; -} |