FreeCalypso > hg > freecalypso-reveng
diff leo-obj/tool/chararray.c @ 184:069b79b36228
tiobjd: chararray extraction command implemented
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Mon, 04 Aug 2014 21:17:06 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/leo-obj/tool/chararray.c Mon Aug 04 21:17:06 2014 +0000 @@ -0,0 +1,90 @@ +/* + * Some COFF objects in TI's firmware semi-src are the result of compiling + * a *.c file that contains nothing more than a const char array. Here + * we support the extraction of these char arrays, to enable recompilation + * with our choice of compiler toolchain. + */ + +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include "intstruct.h" +#include "coffconst.h" +#include "globals.h" + +extern unsigned get_u16(), get_u32(); + +cmd_chararray(argc, argv) + char **argv; +{ + int c, sflag = 0; + unsigned n, array_len; + char *array_name; + struct internal_syment *sym; + u_char *dp; + extern int optind; + extern char *optarg; + + while ((c = getopt(argc, argv, "s:")) != EOF) + switch (c) { + case 's': + array_len = strtoul(optarg, 0, 16); + sflag = 1; + continue; + default: + /* error msg already printed */ + exit(1); + } + if (argc != optind + 1) { + fprintf(stderr, "tiobjd chararray: name argument required\n"); + exit(1); + } + array_name = argv[optind]; + + get_int_section_table(); + get_int_symbol_table(); + for (n = 0; n < nsymtab; n++) { + sym = symtab[n]; + if (!sym) + continue; + if (sym->class != C_EXT) + continue; + if (sym->name[0] != '_') + continue; + if (!strcmp(sym->name + 1, array_name)) + goto found; + } + fprintf(stderr, "error: found no global symbol named %s\n", array_name); + exit(1); + +found: if (!sym->section) { + fprintf(stderr, "error: %s is not defined in a section\n", + array_name); + exit(1); + } + if (!sflag) { + if (sym->type != 0x003C) { + fprintf(stderr, + "error: %s has type != array of u_char\n", + array_name); + exit(1); + } + if (!sym->aux) { + fprintf(stderr, "error: %s has no Aux record\n", + array_name); + exit(1); + } + array_len = get_u16(sym->aux + 8); + } + dp = filemap + sym->section->data_offset + sym->value; + printf("const unsigned char %s[%u] = {", array_name, array_len); + for (n = 0; n < array_len; n++) { + if (!(n & 15)) + putchar('\n'); + printf("0x%02X,", *dp++); + } + puts("\n};"); + exit(0); +}