FreeCalypso > hg > freecalypso-reveng
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 292:6791499809e0 | 293:23e5b940cb8b |
|---|---|
| 1 #include <sys/types.h> | |
| 2 #include <ctype.h> | |
| 3 #include <string.h> | |
| 4 #include <strings.h> | |
| 5 #include <stdio.h> | |
| 6 #include <stdlib.h> | |
| 7 #include "struct.h" | |
| 8 | |
| 9 extern struct libentry *libentry_list; | |
| 10 | |
| 11 static FILE *mapfile; | |
| 12 static char linebuf[1024]; | |
| 13 static int lineno; | |
| 14 static char *filename_for_errs; | |
| 15 | |
| 16 static struct category * | |
| 17 find_category_of_object(libname, member) | |
| 18 char *libname, *member; | |
| 19 { | |
| 20 struct libentry *p; | |
| 21 | |
| 22 for (p = libentry_list; p; p = p->next) { | |
| 23 if (strcmp(p->libname, libname)) | |
| 24 continue; | |
| 25 if (!p->member || !strcmp(p->member, member)) | |
| 26 return(p->cat); | |
| 27 } | |
| 28 return(0); | |
| 29 } | |
| 30 | |
| 31 static void | |
| 32 getline() | |
| 33 { | |
| 34 char *cp; | |
| 35 | |
| 36 if (!fgets(linebuf, sizeof linebuf, mapfile)) { | |
| 37 fprintf(stderr, "%s: premature EOF\n", filename_for_errs); | |
| 38 exit(1); | |
| 39 } | |
| 40 lineno++; | |
| 41 cp = index(linebuf, '\n'); | |
| 42 if (!cp) { | |
| 43 fprintf(stderr, "%s line %d: too long or unterminated\n", | |
| 44 filename_for_errs, lineno); | |
| 45 exit(1); | |
| 46 } | |
| 47 if (cp > linebuf && cp[-1] == '\r') | |
| 48 *--cp = '\0'; | |
| 49 } | |
| 50 | |
| 51 static | |
| 52 valid_section_name_char(c, first) | |
| 53 { | |
| 54 if (isalpha(c) || c == '_' || c == '.' || c == '$') | |
| 55 return(1); | |
| 56 else if (isdigit(c) && !first) | |
| 57 return(1); | |
| 58 else | |
| 59 return(0); | |
| 60 } | |
| 61 | |
| 62 static | |
| 63 parse_input_section_line(libnameout, memberout) | |
| 64 char *libnameout, **memberout; | |
| 65 { | |
| 66 int i; | |
| 67 char *cp; | |
| 68 | |
| 69 for (i = 0; i < 18; i++) | |
| 70 if (linebuf[i] != ' ') { | |
| 71 inv_input_sec_line: fprintf(stderr, | |
| 72 "%s line %d: invalid input section line\n", | |
| 73 filename_for_errs, lineno); | |
| 74 exit(1); | |
| 75 } | |
| 76 while (i < 26) | |
| 77 if (!isxdigit(linebuf[i++])) | |
| 78 goto inv_input_sec_line; | |
| 79 while (i < 30) | |
| 80 if (linebuf[i++] != ' ') | |
| 81 goto inv_input_sec_line; | |
| 82 while (i < 38) | |
| 83 if (!isxdigit(linebuf[i++])) | |
| 84 goto inv_input_sec_line; | |
| 85 while (i < 43) | |
| 86 if (linebuf[i++] != ' ') | |
| 87 goto inv_input_sec_line; | |
| 88 if (isalpha(linebuf[43])) { | |
| 89 cp = linebuf + 43; | |
| 90 while (isalnum(*cp) || *cp == '_') | |
| 91 cp++; | |
| 92 if (strncmp(cp, ".lib : ", 7)) | |
| 93 return(0); | |
| 94 cp += 4; | |
| 95 *cp++ = '\0'; | |
| 96 strcpy(libnameout, linebuf + 43); | |
| 97 cp += 2; | |
| 98 if (!isalpha(*cp)) | |
| 99 goto inv_input_sec_line; | |
| 100 *memberout = cp; | |
| 101 while (isalnum(*cp) || *cp == '_' || *cp == '.') | |
| 102 cp++; | |
| 103 if (*cp != ' ') | |
| 104 goto inv_input_sec_line; | |
| 105 *cp = '\0'; | |
| 106 return(1); | |
| 107 } else if (linebuf[43] == ' ') { | |
| 108 cp = linebuf + 43; | |
| 109 while (*cp == ' ') | |
| 110 cp++; | |
| 111 if (*cp++ != ':') | |
| 112 goto inv_input_sec_line; | |
| 113 if (*cp++ != ' ') | |
| 114 goto inv_input_sec_line; | |
| 115 if (!isalpha(*cp)) | |
| 116 goto inv_input_sec_line; | |
| 117 *memberout = cp; | |
| 118 while (isalnum(*cp) || *cp == '_' || *cp == '.') | |
| 119 cp++; | |
| 120 if (*cp != ' ') | |
| 121 goto inv_input_sec_line; | |
| 122 *cp = '\0'; | |
| 123 return(1); | |
| 124 } else | |
| 125 return(0); | |
| 126 } | |
| 127 | |
| 128 static | |
| 129 process_output_section() | |
| 130 { | |
| 131 int c, i; | |
| 132 int uninit; | |
| 133 char libname[1024], *member; | |
| 134 struct category *cat; | |
| 135 | |
| 136 getline(); | |
| 137 if (!linebuf[0]) | |
| 138 return(1); | |
| 139 if (!valid_section_name_char(linebuf[0], 1)) { | |
| 140 inv_outsec_line: | |
| 141 fprintf(stderr, | |
| 142 "%s line %d: invalid output section beginning line\n", | |
| 143 filename_for_errs, lineno); | |
| 144 exit(1); | |
| 145 } | |
| 146 for (i = 1; ; i++) { | |
| 147 c = linebuf[i]; | |
| 148 if (c == '\0' || c == ' ') | |
| 149 break; | |
| 150 if (!valid_section_name_char(c, 0)) | |
| 151 goto inv_outsec_line; | |
| 152 } | |
| 153 if (!c) { | |
| 154 if (i < 8) | |
| 155 goto inv_outsec_line; | |
| 156 getline(); | |
| 157 for (i = 0; i < 8; i++) | |
| 158 if (linebuf[i] != ' ') | |
| 159 goto inv_outsec_line; | |
| 160 } else { | |
| 161 if (i > 7) | |
| 162 goto inv_outsec_line; | |
| 163 for (; i < 8; i++) | |
| 164 if (linebuf[i] != ' ') | |
| 165 goto inv_outsec_line; | |
| 166 } | |
| 167 if (linebuf[i++] != '0') | |
| 168 goto inv_outsec_line; | |
| 169 while (i < 13) | |
| 170 if (linebuf[i++] != ' ') | |
| 171 goto inv_outsec_line; | |
| 172 while (i < 21) | |
| 173 if (!isxdigit(linebuf[i++])) | |
| 174 goto inv_outsec_line; | |
| 175 while (i < 25) | |
| 176 if (linebuf[i++] != ' ') | |
| 177 goto inv_outsec_line; | |
| 178 while (i < 33) | |
| 179 if (!isxdigit(linebuf[i++])) | |
| 180 goto inv_outsec_line; | |
| 181 while (i < 38) | |
| 182 if (linebuf[i++] != ' ') | |
| 183 goto inv_outsec_line; | |
| 184 uninit = !strcmp(linebuf + 38, "UNINITIALIZED"); | |
| 185 /* input section lines */ | |
| 186 libname[0] = '\0'; | |
| 187 for (;;) { | |
| 188 getline(); | |
| 189 if (!linebuf[0]) | |
| 190 break; | |
| 191 if (!parse_input_section_line(libname, &member)) | |
| 192 continue; | |
| 193 if (!libname[0]) { | |
| 194 fprintf(stderr, "%s line %d: missing library name\n", | |
| 195 filename_for_errs, lineno); | |
| 196 exit(1); | |
| 197 } | |
| 198 cat = find_category_of_object(libname, member); | |
| 199 if (!cat) { | |
| 200 fprintf(stderr, "%s line %d: unknown library object\n", | |
| 201 filename_for_errs, lineno); | |
| 202 exit(1); | |
| 203 } | |
| 204 if (!uninit) | |
| 205 cat->accum += strtoul(linebuf + 30, 0, 16); | |
| 206 } | |
| 207 return(0); | |
| 208 } | |
| 209 | |
| 210 process_map_file(filename) | |
| 211 char *filename; | |
| 212 { | |
| 213 filename_for_errs = filename; | |
| 214 mapfile = fopen(filename, "r"); | |
| 215 if (!mapfile) { | |
| 216 perror(filename); | |
| 217 exit(1); | |
| 218 } | |
| 219 do | |
| 220 getline(); | |
| 221 while (strcmp(linebuf, "SECTION ALLOCATION MAP")); | |
| 222 /* 4 fixed info lines */ | |
| 223 getline(); | |
| 224 if (linebuf[0]) { | |
| 225 bad_sectionmap_hdr: | |
| 226 fprintf(stderr, | |
| 227 "%s line %d: wrong lines after SECTION ALLOCATION MAP\n", | |
| 228 filename_for_errs, lineno); | |
| 229 exit(1); | |
| 230 } | |
| 231 getline(); | |
| 232 if (strcmp(linebuf, | |
| 233 " output attributes/")) | |
| 234 goto bad_sectionmap_hdr; | |
| 235 getline(); | |
| 236 if (strcmp(linebuf, | |
| 237 "section page origin length input sections")) | |
| 238 goto bad_sectionmap_hdr; | |
| 239 getline(); | |
| 240 if (strcmp(linebuf, | |
| 241 "-------- ---- ---------- ---------- ----------------")) | |
| 242 goto bad_sectionmap_hdr; | |
| 243 while (!process_output_section()) | |
| 244 ; | |
| 245 fclose(mapfile); | |
| 246 return(0); | |
| 247 } |
