FreeCalypso > hg > freecalypso-reveng
diff 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 diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/blobstat/grokmap.c Sat Sep 21 21:07:45 2019 +0000 @@ -0,0 +1,247 @@ +#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); +}