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 }