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 } |