FreeCalypso > hg > freecalypso-reveng
view leo-obj/tool/hints.c @ 215:d69f7512e3c1
Pirelli: documented and verified the checksum scheme used for the factory block
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 25 Dec 2016 23:48:16 +0000 |
parents | 81fc8da9a29c |
children |
line wrap: on
line source
/* * Parsing of the disassembly hints file */ #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include <strings.h> #include "intstruct.h" #include "globals.h" static char *filename_for_err; static int lineno; static struct internal_scnhdr *section; static struct hint *lasthint; static void set_section(name) char *name; { unsigned n; struct internal_scnhdr *sec = 0; for (n = 0; n < nsections; n++) if (!strcmp(sections[n].name, name)) { sec = sections + n; break; } if (!sec) { fprintf(stderr, "%s line %d: no section named \"%s\" in %s\n", filename_for_err, lineno, name, objfilename); exit(1); } if (sec->hints) { fprintf(stderr, "%s line %d: [%s] given more than once\n", filename_for_err, lineno, name); exit(1); } section = sec; lasthint = 0; } static void set_mode(arg) char *arg; { char *cp; if (!section) { fprintf(stderr, "%s line %d: error: mode line outside of section\n", filename_for_err, lineno); exit(1); } while (isspace(*arg)) arg++; if (!*arg) { fprintf(stderr, "%s line %d: mode line: missing argument\n", filename_for_err, lineno); exit(1); } for (cp = arg; *cp && !isspace(*cp); cp++) ; if (*cp) *cp++ = '\0'; if (!strcmp(arg, "code")) section->disasm_mode = DISASM_MODE_CODE; else if (!strcmp(arg, "data")) section->disasm_mode = DISASM_MODE_DATA; else if (!strcmp(arg, "bss")) section->disasm_mode = DISASM_MODE_BSS; else { fprintf(stderr, "%s line %d: unknown mode \"%s\"\n", filename_for_err, lineno, arg); exit(1); } } static void regular_hint(arg1, arg2) char *arg1, *arg2; { struct hint *hint; char *cp, *np; if (!section) { fprintf(stderr, "%s line %d: error: hint line outside of section\n", filename_for_err, lineno); exit(1); } hint = malloc(sizeof(struct hint)); if (!hint) { perror("malloc"); exit(1); } hint->pos = strtoul(arg1, &cp, 16); if (*cp == '-') { cp++; hint->endpos = strtoul(cp, &cp, 16); } else hint->endpos = hint->pos; if (*cp) { fprintf(stderr, "%s line %d: invalid hint position syntax\n", filename_for_err, lineno); exit(1); } if (hint->endpos < hint->pos) { fprintf(stderr, "%s line %d: range going backward\n", filename_for_err, lineno); exit(1); } if (lasthint && hint->pos <= lasthint->endpos) { fprintf(stderr, "%s line %d: hint pos <= previous\n", filename_for_err, lineno); exit(1); } hint->type = 0; hint->linebrk = 0; hint->next = 0; for (cp = arg2; isspace(*cp); cp++) ; if (!*cp) { fprintf(stderr, "%s line %d: no keyword after hint pos\n", filename_for_err, lineno); exit(1); } for (np = cp; *cp && !isspace(*cp); cp++) ; if (*cp) *cp++ = '\0'; if (!strcmp(np, "linebrk") || !strcmp(np, "linebreak")) { hint->linebrk = 1; while (isspace(*cp)) cp++; if (!*cp || *cp == '#') { if (hint->endpos != hint->pos) { fprintf(stderr, "%s line %d: no range allowed for linebrk hints\n", filename_for_err, lineno); exit(1); } goto out; } for (np = cp; *cp && !isspace(*cp); cp++) ; if (*cp) *cp++ = '\0'; } if (!strcmp(np, "d8")) hint->type = HINT_D8; else if (!strcmp(np, "d16")) hint->type = HINT_D16; else if (!strcmp(np, "d32")) hint->type = HINT_D32; else if (!strcmp(np, "asciz")) hint->type = HINT_ASCIZ; else { fprintf(stderr, "%s line %d: unknown hint keyword \"%s\"\n", filename_for_err, lineno, np); exit(1); } /* enforce alignment and range restrictions */ switch (hint->type) { case HINT_D16: if (hint->pos & 1 || hint->endpos & 1) { fprintf(stderr, "%s line %d: d16 hint misaligned\n", filename_for_err, lineno); exit(1); } break; case HINT_D32: if (hint->pos & 3 || hint->endpos & 3) { fprintf(stderr, "%s line %d: d32 hint misaligned\n", filename_for_err, lineno); exit(1); } break; case HINT_ASCIZ: if (hint->endpos != hint->pos) { fprintf(stderr, "%s line %d: no range allowed for asciz hints\n", filename_for_err, lineno); exit(1); } break; } out: if (lasthint) lasthint->next = hint; else section->hints = hint; lasthint = hint; } read_hints_file(filename) char *filename; { FILE *f; char linebuf[128], *cp, *np; f = fopen(filename, "r"); if (!f) { perror(filename); exit(1); } filename_for_err = filename; for (lineno = 1; fgets(linebuf, sizeof linebuf, f); lineno++) { for (cp = linebuf; isspace(*cp); cp++) ; if (!*cp || *cp == '#') continue; if (*cp == '[') { np = ++cp; cp = index(cp, ']'); if (!cp) { fprintf(stderr, "%s line %d: invalid section syntax\n", filename, lineno); exit(1); } *cp = '\0'; set_section(np); continue; } for (np = cp; *cp && !isspace(*cp); cp++) ; if (*cp) *cp++ = '\0'; if (!strcmp(np, "mode")) { set_mode(cp); continue; } regular_hint(np, cp); } fclose(f); return(0); }