FreeCalypso > hg > freecalypso-reveng
comparison ticoff/profile.c @ 119:fb1e47bebe00
tiobjd: sorted profile output
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Fri, 04 Apr 2014 05:11:32 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
118:193926ccd1ec | 119:fb1e47bebe00 |
---|---|
1 /* | |
2 * It is handy to have a "profile" of what functions and variables | |
3 * a given module defines (presents to the rest of the fw) and what | |
4 * it references. This profile is constructed from the symbol table. | |
5 * | |
6 * Experience indicates that the order of these symbols in the | |
7 * artifact symtab is often "random", and an alphabetic sort is | |
8 * expected to improve readability. This module contains the | |
9 * messy code. | |
10 */ | |
11 | |
12 #include <sys/types.h> | |
13 #include <stdio.h> | |
14 #include <stdlib.h> | |
15 #include <string.h> | |
16 #include <strings.h> | |
17 #include "intstruct.h" | |
18 #include "coffconst.h" | |
19 #include "globals.h" | |
20 | |
21 static int | |
22 is_symbol_text_def(sym) | |
23 struct internal_syment *sym; | |
24 { | |
25 if (!sym->section) | |
26 return(0); | |
27 if (!strncmp(sym->section->name, ".text", 5)) | |
28 return(1); | |
29 else | |
30 return(0); | |
31 } | |
32 | |
33 static int | |
34 is_symbol_nontext_def(sym) | |
35 struct internal_syment *sym; | |
36 { | |
37 if (!sym->section) | |
38 return(0); | |
39 if (!strncmp(sym->section->name, ".text", 5)) | |
40 return(0); | |
41 else | |
42 return(1); | |
43 } | |
44 | |
45 static int | |
46 is_symbol_extref(sym) | |
47 struct internal_syment *sym; | |
48 { | |
49 if (sym->section) | |
50 return(0); | |
51 else | |
52 return(1); | |
53 } | |
54 | |
55 static int | |
56 compare_for_sort(p1, p2) | |
57 struct internal_syment **p1, **p2; | |
58 { | |
59 return strcmp((*p1)->name, (*p2)->name); | |
60 } | |
61 | |
62 static void | |
63 list_class(firstidx, lastidx, total, checkfunc, printsec) | |
64 unsigned firstidx, lastidx, total; | |
65 int (*checkfunc)(); | |
66 { | |
67 struct internal_syment **array, *sym; | |
68 unsigned n, m; | |
69 | |
70 array = malloc(sizeof(void *) * total); | |
71 if (!array) { | |
72 perror("malloc"); | |
73 exit(1); | |
74 } | |
75 m = 0; | |
76 for (n = firstidx; n <= lastidx; n++) { | |
77 sym = symtab[n]; | |
78 if (!sym) | |
79 continue; | |
80 if (sym->class != C_EXT) | |
81 continue; | |
82 if (!checkfunc(sym)) | |
83 continue; | |
84 array[m++] = sym; | |
85 } | |
86 if (m != total) { | |
87 fprintf(stderr, "BUG: symbol class miscount in profile gen\n"); | |
88 exit(1); | |
89 } | |
90 qsort(array, total, sizeof(void *), compare_for_sort); | |
91 for (n = 0; n < total; n++) { | |
92 sym = array[n]; | |
93 if (printsec) | |
94 printf("%s (%s)\n", sym->name, sym->section->name); | |
95 else | |
96 printf("%s\n", sym->name); | |
97 } | |
98 free(array); | |
99 putchar('\n'); | |
100 } | |
101 | |
102 extern_profile_report(heading) | |
103 char *heading; | |
104 { | |
105 unsigned n; | |
106 int first_extern = -1, last_extern; | |
107 struct internal_syment *sym; | |
108 unsigned defs_text = 0, defs_nontext = 0, extrefs = 0; | |
109 | |
110 for (n = 0; n < nsymtab; n++) { | |
111 sym = symtab[n]; | |
112 if (!sym) | |
113 continue; | |
114 if (sym->class != C_EXT) | |
115 continue; | |
116 if (first_extern < 0) | |
117 first_extern = n; | |
118 last_extern = n; | |
119 if (sym->scnum < 0) { | |
120 fprintf(stderr, | |
121 "symbol entry #%u: unexpected negative scnum for C_EXT\n", n); | |
122 exit(1); | |
123 } | |
124 if (sym->scnum == 0) | |
125 extrefs++; | |
126 else if (!strncmp(sym->section->name, ".text", 5)) | |
127 defs_text++; | |
128 else | |
129 defs_nontext++; | |
130 } | |
131 if (first_extern < 0) { | |
132 printf("%s has no external symbols!\n", heading); | |
133 return(1); | |
134 } | |
135 if (defs_text || defs_nontext) { | |
136 printf("%s defines:\n\n", heading); | |
137 if (defs_text) | |
138 list_class(first_extern, last_extern, defs_text, | |
139 is_symbol_text_def, 1); | |
140 if (defs_nontext) | |
141 list_class(first_extern, last_extern, defs_nontext, | |
142 is_symbol_nontext_def, 1); | |
143 } | |
144 if (extrefs) { | |
145 printf("%s references:\n\n", heading); | |
146 list_class(first_extern, last_extern, extrefs, | |
147 is_symbol_extref, 0); | |
148 } | |
149 return(0); | |
150 } | |
151 | |
152 cmd_profile() | |
153 { | |
154 get_int_section_table(); | |
155 get_int_symbol_table(); | |
156 extern_profile_report(objfilename); | |
157 exit(0); | |
158 } |