1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21: ^L
22: #include "gprof.h"
23: #include "search_list.h"
24: #include "source.h"
25: #include "symtab.h"
26: #include "cg_arcs.h"
27: #include "corefile.h"
28:
29: static int cmp_addr (const PTR, const PTR);
30:
31: Sym_Table symtab;
32:
33:
34:
35:
36: void
37: sym_init (Sym *sym)
38: {
39: memset (sym, 0, sizeof (*sym));
40:
41:
42:
43: sym->hist.time = 0.0;
44: sym->cg.child_time = 0.0;
45: sym->cg.prop.fract = 0.0;
46: sym->cg.prop.self = 0.0;
47: sym->cg.prop.child = 0.0;
48: }
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60: static int
61: cmp_addr (const PTR lp, const PTR rp)
62: {
63: const Sym *left = (const Sym *) lp;
64: const Sym *right = (const Sym *) rp;
65:
66: if (left->addr > right->addr)
67: return 1;
68: else if (left->addr < right->addr)
69: return -1;
70:
71: if (left->is_func != right->is_func)
72: return right->is_func - left->is_func;
73:
74: return left->is_static - right->is_static;
75: }
76:
77:
78: void
79: symtab_finalize (Sym_Table *tab)
80: {
81: Sym *src, *dst;
82: bfd_vma prev_addr;
83:
84: if (!tab->len)
85: return;
86:
87:
88: qsort (tab->base, tab->len, sizeof (Sym), cmp_addr);
89:
90:
91:
92: prev_addr = tab->base[0].addr + 1;
93:
94: for (src = dst = tab->base; src < tab->limit; ++src)
95: {
96: if (src->addr == prev_addr)
97: {
98:
99:
100:
101:
102:
103:
104:
105: if ((!src->is_static && dst[-1].is_static)
106: || ((src->is_static == dst[-1].is_static)
107: && ((src->is_func && !dst[-1].is_func)
108: || ((src->is_func == dst[-1].is_func)
109: && ((src->name[0] != '_' && dst[-1].name[0] == '_')
110: || (src->name[0]
111: && src->name[1] != '_'
112: && dst[-1].name[1] == '_'))))))
113: {
114: DBG (AOUTDEBUG | IDDEBUG,
115: printf ("[symtab_finalize] favor %s@%c%c over %s@%c%c",
116: src->name, src->is_static ? 't' : 'T',
117: src->is_func ? 'F' : 'f',
118: dst[-1].name, dst[-1].is_static ? 't' : 'T',
119: dst[-1].is_func ? 'F' : 'f');
120: printf (" (addr=%lx)\n", (unsigned long) src->addr));
121:
122: dst[-1] = *src;
123: }
124: else
125: {
126: DBG (AOUTDEBUG | IDDEBUG,
127: printf ("[symtab_finalize] favor %s@%c%c over %s@%c%c",
128: dst[-1].name, dst[-1].is_static ? 't' : 'T',
129: dst[-1].is_func ? 'F' : 'f',
130: src->name, src->is_static ? 't' : 'T',
131: src->is_func ? 'F' : 'f');
132: printf (" (addr=%lx)\n", (unsigned long) src->addr));
133: }
134: }
135: else
136: {
137: if (dst > tab->base && dst[-1].end_addr == 0)
138: dst[-1].end_addr = src->addr - 1;
139:
140:
141: if (!src->end_addr || src->addr <= src->end_addr)
142: {
143: *dst = *src;
144: dst++;
145: prev_addr = src->addr;
146: }
147: }
148: }
149:
150: if (tab->len > 0 && dst[-1].end_addr == 0)
151: dst[-1].end_addr
152: = core_text_sect->vma + bfd_get_section_size (core_text_sect) - 1;
153:
154: DBG (AOUTDEBUG | IDDEBUG,
155: printf ("[symtab_finalize]: removed %d duplicate entries\n",
156: tab->len - (int) (dst - tab->base)));
157:
158: tab->limit = dst;
159: tab->len = tab->limit - tab->base;
160:
161: DBG (AOUTDEBUG | IDDEBUG,
162: unsigned int j;
163:
164: for (j = 0; j < tab->len; ++j)
165: {
166: printf ("[symtab_finalize] 0x%lx-0x%lx\t%s\n",
167: (long) tab->base[j].addr, (long) tab->base[j].end_addr,
168: tab->base[j].name);
169: }
170: );
171: }
172:
173:
174: #ifdef DEBUG
175:
176: Sym *
177: dbg_sym_lookup (Sym_Table *sym_tab, bfd_vma address)
178: {
179: long low, mid, high;
180: Sym *sym;
181:
182: fprintf (stderr, "[dbg_sym_lookup] address 0x%lx\n",
183: (unsigned long) address);
184:
185: sym = sym_tab->base;
186: for (low = 0, high = sym_tab->len - 1; low != high;)
187: {
188: mid = (high + low) >> 1;
189:
190: fprintf (stderr, "[dbg_sym_lookup] low=0x%lx, mid=0x%lx, high=0x%lx\n",
191: low, mid, high);
192: fprintf (stderr, "[dbg_sym_lookup] sym[m]=0x%lx sym[m + 1]=0x%lx\n",
193: (unsigned long) sym[mid].addr,
194: (unsigned long) sym[mid + 1].addr);
195:
196: if (sym[mid].addr <= address && sym[mid + 1].addr > address)
197: return &sym[mid];
198:
199: if (sym[mid].addr > address)
200: high = mid;
201: else
202: low = mid + 1;
203: }
204:
205: fprintf (stderr, "[dbg_sym_lookup] binary search fails???\n");
206:
207: return 0;
208: }
209:
210: #endif
211:
212:
213:
214:
215: Sym *
216: sym_lookup (Sym_Table *sym_tab, bfd_vma address)
217: {
218: long low, high;
219: long mid = -1;
220: Sym *sym;
221: #ifdef DEBUG
222: int probes = 0;
223: #endif
224:
225: if (!sym_tab->len)
226: return 0;
227:
228: sym = sym_tab->base;
229: for (low = 0, high = sym_tab->len - 1; low != high;)
230: {
231: DBG (LOOKUPDEBUG, ++probes);
232: mid = (high + low) / 2;
233:
234: if (sym[mid].addr <= address && sym[mid + 1].addr > address)
235: {
236: if (address > sym[mid].end_addr)
237: {
238:
239:
240: return 0;
241: }
242: else
243: {
244: DBG (LOOKUPDEBUG,
245: printf ("[sym_lookup] %d probes (symtab->len=%u)\n",
246: probes, sym_tab->len - 1));
247: return &sym[mid];
248: }
249: }
250:
251: if (sym[mid].addr > address)
252: high = mid;
253: else
254: low = mid + 1;
255: }
256:
257: if (sym[mid + 1].addr <= address)
258: {
259: if (address > sym[mid + 1].end_addr)
260: {
261:
262: return 0;
263: }
264: else
265: {
266: DBG (LOOKUPDEBUG, printf ("[sym_lookup] %d (%u) probes, fall off\n",
267: probes, sym_tab->len - 1));
268: return &sym[mid + 1];
269: }
270: }
271:
272: return 0;
273: }