FreeCalypso > hg > freecalypso-reveng
view blobstat/grokmap.c @ 293:23e5b940cb8b
blobstat: mostly complete
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 21 Sep 2019 21:07:45 +0000 |
parents | |
children | ff2a6433687f |
line wrap: on
line source
#include <sys/types.h> #include <ctype.h> #include <string.h> #include <strings.h> #include <stdio.h> #include <stdlib.h> #include "struct.h" extern struct libentry *libentry_list; static FILE *mapfile; static char linebuf[1024]; static int lineno; static char *filename_for_errs; static struct category * find_category_of_object(libname, member) char *libname, *member; { struct libentry *p; for (p = libentry_list; p; p = p->next) { if (strcmp(p->libname, libname)) continue; if (!p->member || !strcmp(p->member, member)) return(p->cat); } return(0); } static void getline() { char *cp; if (!fgets(linebuf, sizeof linebuf, mapfile)) { fprintf(stderr, "%s: premature EOF\n", filename_for_errs); exit(1); } lineno++; cp = index(linebuf, '\n'); if (!cp) { fprintf(stderr, "%s line %d: too long or unterminated\n", filename_for_errs, lineno); exit(1); } if (cp > linebuf && cp[-1] == '\r') *--cp = '\0'; } static valid_section_name_char(c, first) { if (isalpha(c) || c == '_' || c == '.' || c == '$') return(1); else if (isdigit(c) && !first) return(1); else return(0); } static parse_input_section_line(libnameout, memberout) char *libnameout, **memberout; { int i; char *cp; for (i = 0; i < 18; i++) if (linebuf[i] != ' ') { inv_input_sec_line: fprintf(stderr, "%s line %d: invalid input section line\n", filename_for_errs, lineno); exit(1); } while (i < 26) if (!isxdigit(linebuf[i++])) goto inv_input_sec_line; while (i < 30) if (linebuf[i++] != ' ') goto inv_input_sec_line; while (i < 38) if (!isxdigit(linebuf[i++])) goto inv_input_sec_line; while (i < 43) if (linebuf[i++] != ' ') goto inv_input_sec_line; if (isalpha(linebuf[43])) { cp = linebuf + 43; while (isalnum(*cp) || *cp == '_') cp++; if (strncmp(cp, ".lib : ", 7)) return(0); cp += 4; *cp++ = '\0'; strcpy(libnameout, linebuf + 43); cp += 2; if (!isalpha(*cp)) goto inv_input_sec_line; *memberout = cp; while (isalnum(*cp) || *cp == '_' || *cp == '.') cp++; if (*cp != ' ') goto inv_input_sec_line; *cp = '\0'; return(1); } else if (linebuf[43] == ' ') { cp = linebuf + 43; while (*cp == ' ') cp++; if (*cp++ != ':') goto inv_input_sec_line; if (*cp++ != ' ') goto inv_input_sec_line; if (!isalpha(*cp)) goto inv_input_sec_line; *memberout = cp; while (isalnum(*cp) || *cp == '_' || *cp == '.') cp++; if (*cp != ' ') goto inv_input_sec_line; *cp = '\0'; return(1); } else return(0); } static process_output_section() { int c, i; int uninit; char libname[1024], *member; struct category *cat; getline(); if (!linebuf[0]) return(1); if (!valid_section_name_char(linebuf[0], 1)) { inv_outsec_line: fprintf(stderr, "%s line %d: invalid output section beginning line\n", filename_for_errs, lineno); exit(1); } for (i = 1; ; i++) { c = linebuf[i]; if (c == '\0' || c == ' ') break; if (!valid_section_name_char(c, 0)) goto inv_outsec_line; } if (!c) { if (i < 8) goto inv_outsec_line; getline(); for (i = 0; i < 8; i++) if (linebuf[i] != ' ') goto inv_outsec_line; } else { if (i > 7) goto inv_outsec_line; for (; i < 8; i++) if (linebuf[i] != ' ') goto inv_outsec_line; } if (linebuf[i++] != '0') goto inv_outsec_line; while (i < 13) if (linebuf[i++] != ' ') goto inv_outsec_line; while (i < 21) if (!isxdigit(linebuf[i++])) goto inv_outsec_line; while (i < 25) if (linebuf[i++] != ' ') goto inv_outsec_line; while (i < 33) if (!isxdigit(linebuf[i++])) goto inv_outsec_line; while (i < 38) if (linebuf[i++] != ' ') goto inv_outsec_line; uninit = !strcmp(linebuf + 38, "UNINITIALIZED"); /* input section lines */ libname[0] = '\0'; for (;;) { getline(); if (!linebuf[0]) break; if (!parse_input_section_line(libname, &member)) continue; if (!libname[0]) { fprintf(stderr, "%s line %d: missing library name\n", filename_for_errs, lineno); exit(1); } cat = find_category_of_object(libname, member); if (!cat) { fprintf(stderr, "%s line %d: unknown library object\n", filename_for_errs, lineno); exit(1); } if (!uninit) cat->accum += strtoul(linebuf + 30, 0, 16); } return(0); } process_map_file(filename) char *filename; { filename_for_errs = filename; mapfile = fopen(filename, "r"); if (!mapfile) { perror(filename); exit(1); } do getline(); while (strcmp(linebuf, "SECTION ALLOCATION MAP")); /* 4 fixed info lines */ getline(); if (linebuf[0]) { bad_sectionmap_hdr: fprintf(stderr, "%s line %d: wrong lines after SECTION ALLOCATION MAP\n", filename_for_errs, lineno); exit(1); } getline(); if (strcmp(linebuf, " output attributes/")) goto bad_sectionmap_hdr; getline(); if (strcmp(linebuf, "section page origin length input sections")) goto bad_sectionmap_hdr; getline(); if (strcmp(linebuf, "-------- ---- ---------- ---------- ----------------")) goto bad_sectionmap_hdr; while (!process_output_section()) ; fclose(mapfile); return(0); }