FreeCalypso > hg > freecalypso-reveng
comparison objgrep/frontend.c @ 174:10c0cdc18208
objgrep-fe written, compiles
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Fri, 04 Jul 2014 08:46:32 +0000 |
parents | |
children | 928ed52930aa |
comparison
equal
deleted
inserted
replaced
173:77cd647375e5 | 174:10c0cdc18208 |
---|---|
1 /* | |
2 * This program is a front-end to objgrep. It takes an ASCII text file as | |
3 * input that lists the modules and sections to be grepped for, and it | |
4 * invokes objgrep via popen() for each listed section, all on the same | |
5 * unknown binary. We collect the symbol addresses printed by objgrep | |
6 * via our pipe, and then we sort them to produce the final report. | |
7 */ | |
8 | |
9 #include <stdio.h> | |
10 #include <stdlib.h> | |
11 #include <ctype.h> | |
12 #include <string.h> | |
13 #include <strings.h> | |
14 #include <unistd.h> | |
15 | |
16 #define RAM_BOUNDARY 0x800000 | |
17 | |
18 #define SYMFLAG_AMBIG 8 | |
19 #define SYMSRC_TEXTMATCH 4 | |
20 #define SYMSRC_EXTRELOC 2 | |
21 #define SYMSRC_INTRELOC 1 | |
22 | |
23 struct symbol { | |
24 char *name; | |
25 unsigned value; | |
26 int flags; | |
27 struct symbol *next; | |
28 }; | |
29 | |
30 struct symbol *flash_symbols, *ram_symbols; | |
31 unsigned num_flash_symbols, num_ram_symbols; | |
32 char *binfilename; | |
33 | |
34 enter_symbol(name, valstr, symsrc) | |
35 char *name, *valstr; | |
36 { | |
37 struct symbol *newsym; | |
38 | |
39 newsym = malloc(sizeof(struct symbol) + strlen(name) + 1); | |
40 if (!newsym) { | |
41 perror("malloc"); | |
42 exit(1); | |
43 } | |
44 newsym->name = (char *)(newsym + 1); | |
45 strcpy(newsym->name, name); | |
46 newsym->value = strtoul(valstr, 0, 16); | |
47 newsym->flags = symsrc; | |
48 if (newsym->value < RAM_BOUNDARY) { | |
49 newsym->next = flash_symbols; | |
50 flash_symbols = newsym; | |
51 num_flash_symbols++; | |
52 } else { | |
53 newsym->next = ram_symbols; | |
54 ram_symbols = newsym; | |
55 num_ram_symbols++; | |
56 } | |
57 } | |
58 | |
59 process_section(objfile, secname) | |
60 char *objfile, *secname; | |
61 { | |
62 char cmdline[1024], linebuf[512], *cp, *fields[3]; | |
63 FILE *f; | |
64 int symsrc, i; | |
65 static char headline_textmatch[] = "This source section's symbols:"; | |
66 static char headline_extreloc[] = "Externals deduced from relocs:"; | |
67 static char headline_intreloc[] = | |
68 "This module's symbols deduced from section relocs:"; | |
69 | |
70 sprintf(cmdline, "objgrep -rs %s %s %s", objfile, secname, binfilename); | |
71 f = popen(cmdline, "r"); | |
72 if (!f) { | |
73 perror("popen"); | |
74 exit(1); | |
75 } | |
76 symsrc = 0; | |
77 while (fgets(linebuf, sizeof linebuf, f)) { | |
78 cp = index(linebuf, '\n'); | |
79 if (!cp) { | |
80 fprintf(stderr, | |
81 "error: objgrep output line has no terminating newline\n"); | |
82 exit(1); | |
83 } | |
84 *cp = '\0'; | |
85 if (!strcmp(linebuf, headline_textmatch)) { | |
86 symsrc = SYMSRC_TEXTMATCH; | |
87 continue; | |
88 } | |
89 if (!strcmp(linebuf, headline_extreloc)) { | |
90 symsrc = SYMSRC_EXTRELOC; | |
91 continue; | |
92 } | |
93 if (!strcmp(linebuf, headline_intreloc)) { | |
94 symsrc = SYMSRC_INTRELOC; | |
95 continue; | |
96 } | |
97 cp = linebuf; | |
98 for (i = 0; ; i++) { | |
99 while (isspace(*cp)) | |
100 cp++; | |
101 if (!*cp) | |
102 break; | |
103 if (i == 3) { | |
104 i++; | |
105 break; | |
106 } | |
107 for (fields[i] = cp; *cp && !isspace(*cp); cp++) | |
108 ; | |
109 if (*cp) | |
110 *cp++ = '\0'; | |
111 } | |
112 if (i != 3) | |
113 continue; | |
114 if (fields[1][0] != '=' || fields[1][1]) | |
115 continue; | |
116 if (!symsrc) { | |
117 fprintf(stderr, | |
118 "error: symbol output from objgrep w/o source indication\n"); | |
119 exit(1); | |
120 } | |
121 enter_symbol(fields[0], fields[2], symsrc); | |
122 } | |
123 pclose(f); | |
124 } | |
125 | |
126 process_list_file(listfilename) | |
127 char *listfilename; | |
128 { | |
129 FILE *f; | |
130 char linebuf[512], *objname, *cp, *np; | |
131 int lineno; | |
132 | |
133 f = fopen(listfilename, "r"); | |
134 if (!f) { | |
135 perror(listfilename); | |
136 exit(1); | |
137 } | |
138 for (lineno = 1; fgets(linebuf, sizeof linebuf, f); lineno++) { | |
139 for (cp = linebuf; isspace(*cp); cp++) | |
140 ; | |
141 if (*cp == '\0' || *cp == '#') | |
142 continue; | |
143 for (objname = cp; *cp && !isspace(*cp); cp++) | |
144 ; | |
145 if (*cp) | |
146 *cp++ = '\0'; | |
147 while (isspace(*cp)) | |
148 cp++; | |
149 if (*cp == '\0' || *cp == '#') { | |
150 process_section(objname, ".text"); | |
151 continue; | |
152 } | |
153 while (*cp && *cp != '#') { | |
154 for (np = cp; *cp && !isspace(*cp); cp++) | |
155 ; | |
156 if (*cp) | |
157 *cp++ = '\0'; | |
158 process_section(objname, np); | |
159 while (isspace(*cp)) | |
160 cp++; | |
161 } | |
162 } | |
163 fclose(f); | |
164 } | |
165 | |
166 sort_by_value(sym1, sym2) | |
167 struct symbol **sym1, **sym2; | |
168 { | |
169 if ((*sym1)->value < (*sym2)->value) | |
170 return(-1); | |
171 if ((*sym1)->value > (*sym2)->value) | |
172 return(1); | |
173 return(0); | |
174 } | |
175 | |
176 sort_by_name(sym1, sym2) | |
177 struct symbol **sym1, **sym2; | |
178 { | |
179 int i; | |
180 | |
181 i = strcmp((*sym1)->name, (*sym2)->name); | |
182 if (i) | |
183 return i; | |
184 else | |
185 return sort_by_value(sym1, sym2); | |
186 } | |
187 | |
188 fill_input_array(head, buf) | |
189 struct symbol *head, **buf; | |
190 { | |
191 struct symbol *sym, **p; | |
192 | |
193 p = buf; | |
194 for (sym = head; sym; sym = sym->next) | |
195 *p = sym; | |
196 } | |
197 | |
198 unsigned | |
199 dedup_symbols(inbuf, outbuf, total) | |
200 struct symbol **inbuf, **outbuf; | |
201 unsigned total; | |
202 { | |
203 struct symbol **ip, **op, **input_end, *nsym; | |
204 | |
205 op = outbuf; | |
206 input_end = inbuf + total; | |
207 for (ip = inbuf; ip < input_end; ip++) { | |
208 nsym = *ip; | |
209 if (op == outbuf || strcmp(nsym->name, op[-1]->name)) { | |
210 *op++ = nsym; | |
211 continue; | |
212 } | |
213 if (nsym->value == op[-1]->value) { | |
214 op[-1]->flags |= nsym->flags; | |
215 continue; | |
216 } | |
217 op[-1]->flags |= SYMFLAG_AMBIG; | |
218 nsym->flags |= SYMFLAG_AMBIG; | |
219 *op++ = nsym; | |
220 } | |
221 return(op - outbuf); | |
222 } | |
223 | |
224 emit_final_symbols(buf, total) | |
225 struct symbol **buf; | |
226 unsigned total; | |
227 { | |
228 struct symbol **p, **endbuf, *sym; | |
229 | |
230 endbuf = buf + total; | |
231 for (p = buf; p < endbuf; p++) { | |
232 sym = *p; | |
233 printf("%08X %s (", sym->value, sym->name); | |
234 if (sym->flags & SYMSRC_TEXTMATCH) | |
235 putchar('S'); | |
236 if (sym->flags & SYMSRC_EXTRELOC) | |
237 putchar('R'); | |
238 if (sym->flags & SYMSRC_INTRELOC) | |
239 putchar('r'); | |
240 if (sym->flags & SYMFLAG_AMBIG) | |
241 fputs(", ambiguous", stdout); | |
242 putchar(')'); | |
243 putchar('\n'); | |
244 } | |
245 } | |
246 | |
247 sort_and_emit_symbols(head, total) | |
248 struct symbol *head; | |
249 unsigned total; | |
250 { | |
251 struct symbol **input, **output; | |
252 unsigned final_count; | |
253 | |
254 input = malloc(sizeof(void *) * total); | |
255 if (!input) { | |
256 perror("malloc"); | |
257 exit(1); | |
258 } | |
259 fill_input_array(head, input); | |
260 qsort(input, total, sizeof(void *), sort_by_name); | |
261 output = malloc(sizeof(void *) * total); | |
262 if (!output) { | |
263 perror("malloc"); | |
264 exit(1); | |
265 } | |
266 final_count = dedup_symbols(input, output, total); | |
267 free(input); | |
268 qsort(output, final_count, sizeof(void *), sort_by_value); | |
269 emit_final_symbols(output, final_count); | |
270 free(output); | |
271 putchar('\n'); | |
272 } | |
273 | |
274 main(argc, argv) | |
275 char **argv; | |
276 { | |
277 if (argc != 3) { | |
278 fprintf(stderr, "usage: %s listfile binfile\n", argv[0]); | |
279 exit(1); | |
280 } | |
281 binfilename = argv[2]; | |
282 process_list_file(argv[1]); | |
283 if (flash_symbols) { | |
284 printf("Flash symbols:\n\n"); | |
285 sort_and_emit_symbols(flash_symbols, num_flash_symbols); | |
286 } | |
287 if (ram_symbols) { | |
288 printf("RAM symbols:\n\n"); | |
289 sort_and_emit_symbols(ram_symbols, num_ram_symbols); | |
290 } | |
291 exit(0); | |
292 } |