* corefile.c (core_init): Use a separate local variable,
[deliverable/binutils-gdb.git] / gprof / symtab.c
CommitLineData
ef368dac
NC
1/* symtab.c
2
1355568a 3 Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
ef368dac
NC
4
5 This file is part of GNU Binutils.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
21\f
252b5132 22#include "gprof.h"
6d9c411a
AM
23#include "search_list.h"
24#include "source.h"
25#include "symtab.h"
252b5132
RH
26#include "cg_arcs.h"
27#include "corefile.h"
252b5132 28
1355568a
AM
29static int cmp_addr PARAMS ((const PTR, const PTR));
30
252b5132
RH
31Sym_Table symtab;
32
33
ef368dac
NC
34/* Initialize a symbol (so it's empty). */
35
252b5132 36void
1355568a
AM
37sym_init (sym)
38 Sym *sym;
252b5132
RH
39{
40 memset (sym, 0, sizeof (*sym));
0eee5820 41
ef368dac
NC
42 /* It is not safe to assume that a binary zero corresponds
43 to a floating-point 0.0, so initialize floats explicitly. */
252b5132
RH
44 sym->hist.time = 0.0;
45 sym->cg.child_time = 0.0;
46 sym->cg.prop.fract = 0.0;
47 sym->cg.prop.self = 0.0;
48 sym->cg.prop.child = 0.0;
49}
50
51
ef368dac
NC
52/* Compare the function entry-point of two symbols and return <0, =0,
53 or >0 depending on whether the left value is smaller than, equal
54 to, or greater than the right value. If two symbols are equal
55 but one has is_func set and the other doesn't, we make the
56 non-function symbol one "bigger" so that the function symbol will
57 survive duplicate removal. Finally, if both symbols have the
58 same is_func value, we discriminate against is_static such that
59 the global symbol survives. */
60
252b5132 61static int
1355568a
AM
62cmp_addr (lp, rp)
63 const PTR lp;
64 const PTR rp;
252b5132 65{
1355568a
AM
66 const Sym *left = (const Sym *) lp;
67 const Sym *right = (const Sym *) rp;
252b5132
RH
68
69 if (left->addr > right->addr)
ef368dac 70 return 1;
252b5132 71 else if (left->addr < right->addr)
ef368dac 72 return -1;
252b5132
RH
73
74 if (left->is_func != right->is_func)
ef368dac 75 return right->is_func - left->is_func;
252b5132
RH
76
77 return left->is_static - right->is_static;
78}
79
80
81void
1355568a
AM
82symtab_finalize (tab)
83 Sym_Table *tab;
252b5132
RH
84{
85 Sym *src, *dst;
86 bfd_vma prev_addr;
87
88 if (!tab->len)
ef368dac 89 return;
252b5132 90
ef368dac 91 /* Sort symbol table in order of increasing function addresses. */
252b5132
RH
92 qsort (tab->base, tab->len, sizeof (Sym), cmp_addr);
93
ef368dac
NC
94 /* Remove duplicate entries to speed-up later processing and
95 set end_addr if its not set yet. */
252b5132 96 prev_addr = tab->base[0].addr + 1;
0eee5820 97
252b5132
RH
98 for (src = dst = tab->base; src < tab->limit; ++src)
99 {
100 if (src->addr == prev_addr)
101 {
ef368dac
NC
102 /* If same address, favor global symbol over static one,
103 then function over line number. If both symbols are
104 either static or global and either function or line, check
105 whether one has name beginning with underscore while
106 the other doesn't. In such cases, keep sym without
107 underscore. This takes cares of compiler generated
108 symbols (such as __gnu_compiled, __c89_used, etc.). */
252b5132
RH
109 if ((!src->is_static && dst[-1].is_static)
110 || ((src->is_static == dst[-1].is_static)
111 && ((src->is_func && !dst[-1].is_func)
112 || ((src->is_func == dst[-1].is_func)
113 && ((src->name[0] != '_' && dst[-1].name[0] == '_')
114 || (src->name[0]
115 && src->name[1] != '_'
116 && dst[-1].name[1] == '_'))))))
117 {
118 DBG (AOUTDEBUG | IDDEBUG,
119 printf ("[symtab_finalize] favor %s@%c%c over %s@%c%c",
120 src->name, src->is_static ? 't' : 'T',
121 src->is_func ? 'F' : 'f',
122 dst[-1].name, dst[-1].is_static ? 't' : 'T',
123 dst[-1].is_func ? 'F' : 'f');
fdcf7d43 124 printf (" (addr=%lx)\n", (unsigned long) src->addr));
0eee5820 125
252b5132
RH
126 dst[-1] = *src;
127 }
128 else
129 {
130 DBG (AOUTDEBUG | IDDEBUG,
131 printf ("[symtab_finalize] favor %s@%c%c over %s@%c%c",
132 dst[-1].name, dst[-1].is_static ? 't' : 'T',
133 dst[-1].is_func ? 'F' : 'f',
134 src->name, src->is_static ? 't' : 'T',
135 src->is_func ? 'F' : 'f');
fdcf7d43 136 printf (" (addr=%lx)\n", (unsigned long) src->addr));
252b5132
RH
137 }
138 }
139 else
140 {
141 if (dst > tab->base && dst[-1].end_addr == 0)
ef368dac 142 dst[-1].end_addr = src->addr - 1;
252b5132 143
ef368dac 144 /* Retain sym only if it has a non-empty address range. */
252b5132
RH
145 if (!src->end_addr || src->addr <= src->end_addr)
146 {
ccb57eba
AM
147 *dst = *src;
148 dst++;
252b5132
RH
149 prev_addr = src->addr;
150 }
151 }
152 }
0eee5820 153
252b5132 154 if (tab->len > 0 && dst[-1].end_addr == 0)
ef368dac 155 dst[-1].end_addr = core_text_sect->vma + core_text_sect->_raw_size - 1;
252b5132
RH
156
157 DBG (AOUTDEBUG | IDDEBUG,
158 printf ("[symtab_finalize]: removed %d duplicate entries\n",
159 tab->len - (int) (dst - tab->base)));
160
161 tab->limit = dst;
162 tab->len = tab->limit - tab->base;
163
164 DBG (AOUTDEBUG | IDDEBUG,
165 unsigned int j;
166
167 for (j = 0; j < tab->len; ++j)
0eee5820 168 {
ef368dac
NC
169 printf ("[symtab_finalize] 0x%lx-0x%lx\t%s\n",
170 (long) tab->base[j].addr, (long) tab->base[j].end_addr,
171 tab->base[j].name);
0eee5820 172 }
252b5132
RH
173 );
174}
175
176
177#ifdef DEBUG
178
179Sym *
1355568a
AM
180dbg_sym_lookup (sym_tab, address)
181 Sym_Table *sym_tab;
182 bfd_vma address;
252b5132
RH
183{
184 long low, mid, high;
185 Sym *sym;
186
fdcf7d43
ILT
187 fprintf (stderr, "[dbg_sym_lookup] address 0x%lx\n",
188 (unsigned long) address);
252b5132 189
1355568a
AM
190 sym = sym_tab->base;
191 for (low = 0, high = sym_tab->len - 1; low != high;)
252b5132
RH
192 {
193 mid = (high + low) >> 1;
0eee5820 194
252b5132
RH
195 fprintf (stderr, "[dbg_sym_lookup] low=0x%lx, mid=0x%lx, high=0x%lx\n",
196 low, mid, high);
197 fprintf (stderr, "[dbg_sym_lookup] sym[m]=0x%lx sym[m + 1]=0x%lx\n",
fdcf7d43
ILT
198 (unsigned long) sym[mid].addr,
199 (unsigned long) sym[mid + 1].addr);
0eee5820 200
252b5132 201 if (sym[mid].addr <= address && sym[mid + 1].addr > address)
ef368dac
NC
202 return &sym[mid];
203
252b5132 204 if (sym[mid].addr > address)
ef368dac 205 high = mid;
252b5132 206 else
ef368dac 207 low = mid + 1;
252b5132 208 }
0eee5820 209
252b5132 210 fprintf (stderr, "[dbg_sym_lookup] binary search fails???\n");
0eee5820 211
252b5132
RH
212 return 0;
213}
214
215#endif /* DEBUG */
216
217
ef368dac
NC
218/* Look up an address in the symbol-table that is sorted by address.
219 If address does not hit any symbol, 0 is returned. */
252b5132 220Sym *
1355568a
AM
221sym_lookup (sym_tab, address)
222 Sym_Table *sym_tab;
223 bfd_vma address;
252b5132
RH
224{
225 long low, high;
226 long mid = -1;
227 Sym *sym;
228#ifdef DEBUG
229 int probes = 0;
230#endif /* DEBUG */
231
1355568a 232 if (!sym_tab->len)
ef368dac 233 return 0;
252b5132 234
1355568a
AM
235 sym = sym_tab->base;
236 for (low = 0, high = sym_tab->len - 1; low != high;)
252b5132
RH
237 {
238 DBG (LOOKUPDEBUG, ++probes);
239 mid = (high + low) / 2;
0eee5820 240
252b5132
RH
241 if (sym[mid].addr <= address && sym[mid + 1].addr > address)
242 {
243 if (address > sym[mid].end_addr)
244 {
ef368dac
NC
245 /* Address falls into gap between
246 sym[mid] and sym[mid + 1]. */
252b5132
RH
247 return 0;
248 }
249 else
250 {
251 DBG (LOOKUPDEBUG,
252 printf ("[sym_lookup] %d probes (symtab->len=%u)\n",
1355568a 253 probes, sym_tab->len - 1));
252b5132
RH
254 return &sym[mid];
255 }
256 }
0eee5820 257
252b5132 258 if (sym[mid].addr > address)
ef368dac 259 high = mid;
252b5132 260 else
ef368dac 261 low = mid + 1;
252b5132 262 }
0eee5820 263
252b5132
RH
264 if (sym[mid + 1].addr <= address)
265 {
266 if (address > sym[mid + 1].end_addr)
267 {
ef368dac 268 /* Address is beyond end of sym[mid + 1]. */
252b5132
RH
269 return 0;
270 }
271 else
272 {
273 DBG (LOOKUPDEBUG, printf ("[sym_lookup] %d (%u) probes, fall off\n",
1355568a 274 probes, sym_tab->len - 1));
252b5132
RH
275 return &sym[mid + 1];
276 }
277 }
0eee5820 278
252b5132
RH
279 return 0;
280}
This page took 0.238651 seconds and 4 git commands to generate.