blob: 04d762f226184536beca125881130f8f4f9069df [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001/*--------------------------------------------------------------------*/
2/*--- Management of symbols and debugging information. ---*/
3/*--- vg_symtab2.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, an x86 protected-mode emulator
8 designed for debugging and profiling binaries on x86-Unixes.
9
10 Copyright (C) 2000-2002 Julian Seward
11 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file LICENSE.
29*/
30
31#include "vg_include.h"
sewardjde4a1d02002-03-22 01:27:54 +000032
33#include <elf.h> /* ELF defns */
34#include <a.out.h> /* stabs defns */
35
njn9aae6742002-04-30 13:44:01 +000036
sewardjde4a1d02002-03-22 01:27:54 +000037/* Majorly rewritten Sun 3 Feb 02 to enable loading symbols from
38 dlopen()ed libraries, which is something that KDE3 does a lot.
sewardjde4a1d02002-03-22 01:27:54 +000039
sewardj18d75132002-05-16 11:06:21 +000040 Stabs reader greatly improved by Nick Nethercode, Apr 02.
sewardjde4a1d02002-03-22 01:27:54 +000041
sewardj18d75132002-05-16 11:06:21 +000042 16 May 02: when notified about munmap, return a Bool indicating
43 whether or not the area being munmapped had executable permissions.
44 This is then used to determine whether or not
45 VG_(invalid_translations) should be called for that area. In order
46 that this work even if --instrument=no, in this case we still keep
47 track of the mapped executable segments, but do not load any debug
48 info or symbols.
sewardjde4a1d02002-03-22 01:27:54 +000049*/
50
51/*------------------------------------------------------------*/
52/*--- Structs n stuff ---*/
53/*------------------------------------------------------------*/
54
55/* A structure to hold an ELF symbol (very crudely). */
56typedef
57 struct {
58 Addr addr; /* lowest address of entity */
59 UInt size; /* size in bytes */
60 Int nmoff; /* offset of name in this SegInfo's str tab */
61 }
62 RiSym;
63
njne0ee0712002-05-03 16:41:05 +000064/* Line count at which overflow happens, due to line numbers being stored as
65 * shorts in `struct nlist' in a.out.h. */
66#define LINENO_OVERFLOW (1 << (sizeof(short) * 8))
sewardjde4a1d02002-03-22 01:27:54 +000067
njne0ee0712002-05-03 16:41:05 +000068#define LINENO_BITS 20
69#define LOC_SIZE_BITS (32 - LINENO_BITS)
sewardj97ff05f2002-05-09 01:32:57 +000070#define MAX_LINENO ((1 << LINENO_BITS) - 1)
njne0ee0712002-05-03 16:41:05 +000071
72/* Unlikely to have any lines with instruction ranges > 4096 bytes */
sewardj97ff05f2002-05-09 01:32:57 +000073#define MAX_LOC_SIZE ((1 << LOC_SIZE_BITS) - 1)
njne0ee0712002-05-03 16:41:05 +000074
75/* Number used to detect line number overflows; if one line is 60000-odd
76 * smaller than the previous, is was probably an overflow.
77 */
78#define OVERFLOW_DIFFERENCE (LINENO_OVERFLOW - 5000)
79
80/* A structure to hold addr-to-source info for a single line. There can be a
81 * lot of these, hence the dense packing. */
sewardjde4a1d02002-03-22 01:27:54 +000082typedef
83 struct {
njne0ee0712002-05-03 16:41:05 +000084 /* Word 1 */
85 Addr addr; /* lowest address for this line */
86 /* Word 2 */
87 UShort size:LOC_SIZE_BITS; /* byte size; we catch overflows of this */
88 UInt lineno:LINENO_BITS; /* source line number, or zero */
89 /* Word 3 */
90 UInt fnmoff; /* source filename; offset in this
91 SegInfo's str tab */
sewardjde4a1d02002-03-22 01:27:54 +000092 }
93 RiLoc;
94
95
96/* A structure which contains information pertaining to one mapped
97 text segment. */
98typedef
99 struct _SegInfo {
100 struct _SegInfo* next;
101 /* Description of the mapped segment. */
102 Addr start;
103 UInt size;
104 UChar* filename; /* in mallocville */
105 UInt foffset;
106 /* An expandable array of symbols. */
107 RiSym* symtab;
108 UInt symtab_used;
109 UInt symtab_size;
110 /* An expandable array of locations. */
111 RiLoc* loctab;
112 UInt loctab_used;
113 UInt loctab_size;
114 /* An expandable array of characters -- the string table. */
115 Char* strtab;
116 UInt strtab_used;
117 UInt strtab_size;
118 /* offset is what we need to add to symbol table entries
119 to get the real location of that symbol in memory.
120 For executables, offset is zero.
121 For .so's, offset == base_addr.
122 This seems like a giant kludge to me.
123 */
124 UInt offset;
125 }
126 SegInfo;
127
128
129/* -- debug helper -- */
130static void ppSegInfo ( SegInfo* si )
131{
132 VG_(printf)("name: %s\n"
133 "start %p, size %d, foffset %d\n",
134 si->filename?si->filename : (UChar*)"NULL",
135 si->start, si->size, si->foffset );
136}
137
138static void freeSegInfo ( SegInfo* si )
139{
140 vg_assert(si != NULL);
141 if (si->filename) VG_(free)(VG_AR_SYMTAB, si->filename);
142 if (si->symtab) VG_(free)(VG_AR_SYMTAB, si->symtab);
143 if (si->loctab) VG_(free)(VG_AR_SYMTAB, si->loctab);
144 if (si->strtab) VG_(free)(VG_AR_SYMTAB, si->strtab);
145 VG_(free)(VG_AR_SYMTAB, si);
146}
147
148
149/*------------------------------------------------------------*/
150/*--- Adding stuff ---*/
151/*------------------------------------------------------------*/
152
153/* Add a str to the string table, including terminating zero, and
154 return offset of the string in vg_strtab. */
155
156static __inline__
157Int addStr ( SegInfo* si, Char* str )
158{
159 Char* new_tab;
160 Int new_sz, i, space_needed;
161
162 space_needed = 1 + VG_(strlen)(str);
163 if (si->strtab_used + space_needed > si->strtab_size) {
164 new_sz = 2 * si->strtab_size;
165 if (new_sz == 0) new_sz = 5000;
166 new_tab = VG_(malloc)(VG_AR_SYMTAB, new_sz);
167 if (si->strtab != NULL) {
168 for (i = 0; i < si->strtab_used; i++)
169 new_tab[i] = si->strtab[i];
170 VG_(free)(VG_AR_SYMTAB, si->strtab);
171 }
172 si->strtab = new_tab;
173 si->strtab_size = new_sz;
174 }
175
176 for (i = 0; i < space_needed; i++)
177 si->strtab[si->strtab_used+i] = str[i];
178
179 si->strtab_used += space_needed;
180 vg_assert(si->strtab_used <= si->strtab_size);
181 return si->strtab_used - space_needed;
182}
183
184/* Add a symbol to the symbol table. */
185
186static __inline__
187void addSym ( SegInfo* si, RiSym* sym )
188{
189 Int new_sz, i;
190 RiSym* new_tab;
191
192 /* Ignore zero-sized syms. */
193 if (sym->size == 0) return;
194
195 if (si->symtab_used == si->symtab_size) {
196 new_sz = 2 * si->symtab_size;
197 if (new_sz == 0) new_sz = 500;
198 new_tab = VG_(malloc)(VG_AR_SYMTAB, new_sz * sizeof(RiSym) );
199 if (si->symtab != NULL) {
200 for (i = 0; i < si->symtab_used; i++)
201 new_tab[i] = si->symtab[i];
202 VG_(free)(VG_AR_SYMTAB, si->symtab);
203 }
204 si->symtab = new_tab;
205 si->symtab_size = new_sz;
206 }
207
208 si->symtab[si->symtab_used] = *sym;
209 si->symtab_used++;
210 vg_assert(si->symtab_used <= si->symtab_size);
211}
212
213/* Add a location to the location table. */
214
215static __inline__
216void addLoc ( SegInfo* si, RiLoc* loc )
217{
218 Int new_sz, i;
219 RiLoc* new_tab;
220
njne0ee0712002-05-03 16:41:05 +0000221 /* Zero-sized locs should have been ignored earlier */
222 vg_assert(loc->size > 0);
sewardjde4a1d02002-03-22 01:27:54 +0000223
224 if (si->loctab_used == si->loctab_size) {
225 new_sz = 2 * si->loctab_size;
226 if (new_sz == 0) new_sz = 500;
227 new_tab = VG_(malloc)(VG_AR_SYMTAB, new_sz * sizeof(RiLoc) );
228 if (si->loctab != NULL) {
229 for (i = 0; i < si->loctab_used; i++)
230 new_tab[i] = si->loctab[i];
231 VG_(free)(VG_AR_SYMTAB, si->loctab);
232 }
233 si->loctab = new_tab;
234 si->loctab_size = new_sz;
235 }
236
237 si->loctab[si->loctab_used] = *loc;
238 si->loctab_used++;
239 vg_assert(si->loctab_used <= si->loctab_size);
240}
241
242
sewardjb51f2e62002-06-01 23:11:19 +0000243/* Top-level place to call to add a source-location mapping entry. */
244
245static __inline__
246void addLineInfo ( SegInfo* si,
247 Int fnmoff,
248 Addr this,
249 Addr next,
250 Int lineno,
251 Int entry )
252{
253 RiLoc loc;
254 Int size = next - this;
255
256 /* Ignore zero-sized locs */
257 if (this == next) return;
258
259 /* Maximum sanity checking. Some versions of GNU as do a shabby
260 * job with stabs entries; if anything looks suspicious, revert to
261 * a size of 1. This should catch the instruction of interest
262 * (since if using asm-level debug info, one instruction will
263 * correspond to one line, unlike with C-level debug info where
264 * multiple instructions can map to the one line), but avoid
265 * catching any other instructions bogusly. */
266 if (this > next) {
267 VG_(message)(Vg_DebugMsg,
268 "warning: stabs addresses out of order "
269 "at entry %d: 0x%x 0x%x", entry, this, next);
270 size = 1;
271 }
272
273 if (size > MAX_LOC_SIZE) {
274 VG_(message)(Vg_DebugMsg,
275 "warning: stabs line address range too large "
276 "at entry %d: %d", entry, size);
277 size = 1;
278 }
279
sewardje509f4f2002-06-04 17:11:03 +0000280 /* hack! */
281 if (this >= 0 && this <= 100) {
282 VG_(message)(Vg_DebugMsg,
283 "warning: ignoring bogus stabs entry "
284 "%p %p %d: %d", this, next, entry, size);
285 return;
286 }
287
sewardjb51f2e62002-06-01 23:11:19 +0000288 vg_assert(this < si->start + si->size && next-1 >= si->start);
289 vg_assert(lineno >= 0 && lineno <= MAX_LINENO);
290
291 loc.addr = this;
292 loc.size = (UShort)size;
293 loc.lineno = lineno;
294 loc.fnmoff = fnmoff;
295 addLoc ( si, &loc );
296}
297
sewardjde4a1d02002-03-22 01:27:54 +0000298
299/*------------------------------------------------------------*/
300/*--- Helpers ---*/
301/*------------------------------------------------------------*/
302
303/* Non-fatal -- use vg_panic if terminal. */
304static
305void vg_symerr ( Char* msg )
306{
307 if (VG_(clo_verbosity) > 1)
308 VG_(message)(Vg_UserMsg,"%s", msg );
309}
310
311
312/* Print a symbol. */
313static
314void printSym ( SegInfo* si, Int i )
315{
316 VG_(printf)( "%5d: %8p .. %8p (%d) %s\n",
317 i,
318 si->symtab[i].addr,
319 si->symtab[i].addr + si->symtab[i].size - 1, si->symtab[i].size,
320 &si->strtab[si->symtab[i].nmoff] );
321}
322
323
324#if 0
325/* Print the entire sym tab. */
326static __attribute__ ((unused))
327void printSymtab ( void )
328{
329 Int i;
330 VG_(printf)("\n------ BEGIN vg_symtab ------\n");
331 for (i = 0; i < vg_symtab_used; i++)
332 printSym(i);
333 VG_(printf)("------ BEGIN vg_symtab ------\n");
334}
335#endif
336
337#if 0
338/* Paranoid strcat. */
339static
340void safeCopy ( UChar* dst, UInt maxlen, UChar* src )
341{
342 UInt i = 0, j = 0;
343 while (True) {
344 if (i >= maxlen) return;
345 if (dst[i] == 0) break;
346 i++;
347 }
348 while (True) {
349 if (i >= maxlen) return;
350 dst[i] = src[j];
351 if (src[j] == 0) return;
352 i++; j++;
353 }
354}
355#endif
356
sewardjb51f2e62002-06-01 23:11:19 +0000357
sewardjde4a1d02002-03-22 01:27:54 +0000358/*------------------------------------------------------------*/
359/*--- Canonicalisers ---*/
360/*------------------------------------------------------------*/
361
362/* Sort the symtab by starting address, and emit warnings if any
363 symbols have overlapping address ranges. We use that old chestnut,
364 shellsort. Mash the table around so as to establish the property
365 that addresses are in order and the ranges to not overlap. This
366 facilitates using binary search to map addresses to symbols when we
367 come to query the table.
368*/
369static
370void canonicaliseSymtab ( SegInfo* si )
371{
372 /* Magic numbers due to Janet Incerpi and Robert Sedgewick. */
373 Int incs[16] = { 1, 3, 7, 21, 48, 112, 336, 861, 1968,
374 4592, 13776, 33936, 86961, 198768,
375 463792, 1391376 };
376 Int lo = 0;
377 Int hi = si->symtab_used-1;
378 Int i, j, h, bigN, hp, n_merged, n_truncated;
379 RiSym v;
380 Addr s1, s2, e1, e2;
381
382# define SWAP(ty,aa,bb) \
383 do { ty tt = (aa); (aa) = (bb); (bb) = tt; } while (0)
384
385 bigN = hi - lo + 1; if (bigN < 2) return;
386 hp = 0; while (hp < 16 && incs[hp] < bigN) hp++; hp--;
387 vg_assert(0 <= hp && hp < 16);
388
389 for (; hp >= 0; hp--) {
390 h = incs[hp];
391 i = lo + h;
392 while (1) {
393 if (i > hi) break;
394 v = si->symtab[i];
395 j = i;
396 while (si->symtab[j-h].addr > v.addr) {
397 si->symtab[j] = si->symtab[j-h];
398 j = j - h;
399 if (j <= (lo + h - 1)) break;
400 }
401 si->symtab[j] = v;
402 i++;
403 }
404 }
405
406 cleanup_more:
407
408 /* If two symbols have identical address ranges, favour the
409 one with the longer name.
410 */
411 do {
412 n_merged = 0;
413 j = si->symtab_used;
414 si->symtab_used = 0;
415 for (i = 0; i < j; i++) {
416 if (i < j-1
417 && si->symtab[i].addr == si->symtab[i+1].addr
418 && si->symtab[i].size == si->symtab[i+1].size) {
419 n_merged++;
420 /* merge the two into one */
421 if (VG_(strlen)(&si->strtab[si->symtab[i].nmoff])
422 > VG_(strlen)(&si->strtab[si->symtab[i+1].nmoff])) {
423 si->symtab[si->symtab_used++] = si->symtab[i];
424 } else {
425 si->symtab[si->symtab_used++] = si->symtab[i+1];
426 }
427 i++;
428 } else {
429 si->symtab[si->symtab_used++] = si->symtab[i];
430 }
431 }
432 if (VG_(clo_trace_symtab))
433 VG_(printf)( "%d merged\n", n_merged);
434 }
435 while (n_merged > 0);
436
437 /* Detect and "fix" overlapping address ranges. */
438 n_truncated = 0;
439
440 for (i = 0; i < si->symtab_used-1; i++) {
441
442 vg_assert(si->symtab[i].addr <= si->symtab[i+1].addr);
443
444 /* Check for common (no overlap) case. */
445 if (si->symtab[i].addr + si->symtab[i].size
446 <= si->symtab[i+1].addr)
447 continue;
448
449 /* There's an overlap. Truncate one or the other. */
450 if (VG_(clo_trace_symtab)) {
451 VG_(printf)("overlapping address ranges in symbol table\n\t");
452 printSym(si,i);
453 VG_(printf)("\t");
454 printSym(si,i+1);
455 VG_(printf)("\n");
456 }
457
458 /* Truncate one or the other. */
459 s1 = si->symtab[i].addr;
460 s2 = si->symtab[i+1].addr;
461 e1 = s1 + si->symtab[i].size - 1;
462 e2 = s2 + si->symtab[i+1].size - 1;
463 if (s1 < s2) {
464 e1 = s2-1;
465 } else {
466 vg_assert(s1 == s2);
467 if (e1 > e2) {
468 s1 = e2+1; SWAP(Addr,s1,s2); SWAP(Addr,e1,e2);
469 } else
470 if (e1 < e2) {
471 s2 = e1+1;
472 } else {
473 /* e1 == e2. Identical addr ranges. We'll eventually wind
474 up back at cleanup_more, which will take care of it. */
475 }
476 }
477 si->symtab[i].addr = s1;
478 si->symtab[i+1].addr = s2;
479 si->symtab[i].size = e1 - s1 + 1;
480 si->symtab[i+1].size = e2 - s2 + 1;
481 vg_assert(s1 <= s2);
482 vg_assert(si->symtab[i].size > 0);
483 vg_assert(si->symtab[i+1].size > 0);
484 /* It may be that the i+1 entry now needs to be moved further
485 along to maintain the address order requirement. */
486 j = i+1;
487 while (j < si->symtab_used-1
488 && si->symtab[j].addr > si->symtab[j+1].addr) {
489 SWAP(RiSym,si->symtab[j],si->symtab[j+1]);
490 j++;
491 }
492 n_truncated++;
493 }
494
495 if (n_truncated > 0) goto cleanup_more;
496
497 /* Ensure relevant postconditions hold. */
498 for (i = 0; i < si->symtab_used-1; i++) {
499 /* No zero-sized symbols. */
500 vg_assert(si->symtab[i].size > 0);
501 /* In order. */
502 vg_assert(si->symtab[i].addr < si->symtab[i+1].addr);
503 /* No overlaps. */
504 vg_assert(si->symtab[i].addr + si->symtab[i].size - 1
505 < si->symtab[i+1].addr);
506 }
507# undef SWAP
508}
509
510
511
512/* Sort the location table by starting address. Mash the table around
513 so as to establish the property that addresses are in order and the
514 ranges do not overlap. This facilitates using binary search to map
sewardjb51f2e62002-06-01 23:11:19 +0000515 addresses to locations when we come to query the table.
516*/
sewardjde4a1d02002-03-22 01:27:54 +0000517static
518void canonicaliseLoctab ( SegInfo* si )
519{
520 /* Magic numbers due to Janet Incerpi and Robert Sedgewick. */
521 Int incs[16] = { 1, 3, 7, 21, 48, 112, 336, 861, 1968,
522 4592, 13776, 33936, 86961, 198768,
523 463792, 1391376 };
524 Int lo = 0;
525 Int hi = si->loctab_used-1;
526 Int i, j, h, bigN, hp;
527 RiLoc v;
528
529# define SWAP(ty,aa,bb) \
530 do { ty tt = (aa); (aa) = (bb); (bb) = tt; } while (0);
531
532 /* Sort by start address. */
533
534 bigN = hi - lo + 1; if (bigN < 2) return;
535 hp = 0; while (hp < 16 && incs[hp] < bigN) hp++; hp--;
536 vg_assert(0 <= hp && hp < 16);
537
538 for (; hp >= 0; hp--) {
539 h = incs[hp];
540 i = lo + h;
541 while (1) {
542 if (i > hi) break;
543 v = si->loctab[i];
544 j = i;
545 while (si->loctab[j-h].addr > v.addr) {
546 si->loctab[j] = si->loctab[j-h];
547 j = j - h;
548 if (j <= (lo + h - 1)) break;
549 }
550 si->loctab[j] = v;
551 i++;
552 }
553 }
554
555 /* If two adjacent entries overlap, truncate the first. */
556 for (i = 0; i < si->loctab_used-1; i++) {
557 vg_assert(si->loctab[i].size < 10000);
558 if (si->loctab[i].addr + si->loctab[i].size > si->loctab[i+1].addr) {
559 /* Do this in signed int32 because the actual .size fields
560 are unsigned 16s. */
561 Int new_size = si->loctab[i+1].addr - si->loctab[i].addr;
562 if (new_size < 0) {
563 si->loctab[i].size = 0;
564 } else
565 if (new_size >= 65536) {
566 si->loctab[i].size = 65535;
567 } else {
568 si->loctab[i].size = (UShort)new_size;
569 }
570 }
571 }
572
573 /* Zap any zero-sized entries resulting from the truncation
574 process. */
575 j = 0;
576 for (i = 0; i < si->loctab_used; i++) {
577 if (si->loctab[i].size > 0) {
578 si->loctab[j] = si->loctab[i];
579 j++;
580 }
581 }
582 si->loctab_used = j;
583
584 /* Ensure relevant postconditions hold. */
585 for (i = 0; i < si->loctab_used-1; i++) {
586 /*
587 VG_(printf)("%d (%d) %d 0x%x\n",
588 i, si->loctab[i+1].confident,
589 si->loctab[i+1].size, si->loctab[i+1].addr );
590 */
591 /* No zero-sized symbols. */
592 vg_assert(si->loctab[i].size > 0);
593 /* In order. */
594 vg_assert(si->loctab[i].addr < si->loctab[i+1].addr);
595 /* No overlaps. */
596 vg_assert(si->loctab[i].addr + si->loctab[i].size - 1
597 < si->loctab[i+1].addr);
598 }
599# undef SWAP
600}
601
602
603/*------------------------------------------------------------*/
sewardjb51f2e62002-06-01 23:11:19 +0000604/*--- Read STABS format debug info. ---*/
sewardjde4a1d02002-03-22 01:27:54 +0000605/*------------------------------------------------------------*/
606
sewardjb51f2e62002-06-01 23:11:19 +0000607/* Stabs entry types, from:
608 * The "stabs" debug format
609 * Menapace, Kingdon and MacKenzie
610 * Cygnus Support
611 */
612typedef enum { N_GSYM = 32, /* Global symbol */
613 N_FUN = 36, /* Function start or end */
614 N_STSYM = 38, /* Data segment file-scope variable */
615 N_LCSYM = 40, /* BSS segment file-scope variable */
616 N_RSYM = 64, /* Register variable */
617 N_SLINE = 68, /* Source line number */
618 N_SO = 100, /* Source file path and name */
619 N_LSYM = 128, /* Stack variable or type */
620 N_SOL = 132, /* Include file name */
621 N_LBRAC = 192, /* Start of lexical block */
622 N_RBRAC = 224 /* End of lexical block */
623 } stab_types;
624
625
626/* Read stabs-format debug info. This is all rather horrible because
627 stabs is a underspecified, kludgy hack.
628*/
629static
630void read_debuginfo_stabs ( SegInfo* si,
631 UChar* stabC, Int stab_sz,
632 UChar* stabstr, Int stabstr_sz )
sewardjde4a1d02002-03-22 01:27:54 +0000633{
sewardjb51f2e62002-06-01 23:11:19 +0000634 Int i;
635 Int curr_filenmoff;
njnb79ad342002-06-05 15:30:30 +0000636 Addr curr_fn_stabs_addr = (Addr)NULL;
637 Addr curr_fnbaseaddr = (Addr)NULL;
sewardjb51f2e62002-06-01 23:11:19 +0000638 Char *curr_file_name, *curr_fn_name;
639 Int n_stab_entries;
njnb79ad342002-06-05 15:30:30 +0000640 Int prev_lineno = 0, lineno = 0;
641 Int lineno_overflows = 0;
642 Bool same_file = True;
sewardjb51f2e62002-06-01 23:11:19 +0000643 struct nlist* stab = (struct nlist*)stabC;
njnb79ad342002-06-05 15:30:30 +0000644
sewardjb51f2e62002-06-01 23:11:19 +0000645 /* Ok. It all looks plausible. Go on and read debug data.
646 stab kinds: 100 N_SO a source file name
647 68 N_SLINE a source line number
648 36 N_FUN start of a function
njn4f9c9342002-04-29 16:03:24 +0000649
sewardjb51f2e62002-06-01 23:11:19 +0000650 In this loop, we maintain a current file name, updated as
651 N_SO/N_SOLs appear, and a current function base address,
652 updated as N_FUNs appear. Based on that, address ranges for
653 N_SLINEs are calculated, and stuffed into the line info table.
sewardjde4a1d02002-03-22 01:27:54 +0000654
sewardjb51f2e62002-06-01 23:11:19 +0000655 Finding the instruction address range covered by an N_SLINE is
656 complicated; see the N_SLINE case below.
657 */
njnb79ad342002-06-05 15:30:30 +0000658 curr_filenmoff = addStr(si,"???");
659 curr_file_name = curr_fn_name = (Char*)NULL;
sewardjde4a1d02002-03-22 01:27:54 +0000660
sewardjb51f2e62002-06-01 23:11:19 +0000661 n_stab_entries = stab_sz/(int)sizeof(struct nlist);
njne0ee0712002-05-03 16:41:05 +0000662
sewardjb51f2e62002-06-01 23:11:19 +0000663 for (i = 0; i < n_stab_entries; i++) {
664# if 0
665 VG_(printf) ( " %2d ", i );
666 VG_(printf) ( "type=0x%x othr=%d desc=%d value=0x%x strx=%d %s",
667 stab[i].n_type, stab[i].n_other, stab[i].n_desc,
668 (int)stab[i].n_value,
669 (int)stab[i].n_un.n_strx,
670 stabstr + stab[i].n_un.n_strx );
671 VG_(printf)("\n");
672# endif
njne0ee0712002-05-03 16:41:05 +0000673
sewardjb51f2e62002-06-01 23:11:19 +0000674 Char *no_fn_name = "???";
675
676 switch (stab[i].n_type) {
677 UInt next_addr;
678
679 /* Two complicated things here:
680 *
681 * 1. the n_desc field in 'struct n_list' in a.out.h is only
682 * 16-bits, which gives a maximum of 65535 lines. We handle
683 * files bigger than this by detecting heuristically
684 * overflows -- if the line count goes from 65000-odd to
685 * 0-odd within the same file, we assume it's an overflow.
686 * Once we switch files, we zero the overflow count.
687 *
688 * 2. To compute the instr address range covered by a single
689 * line, find the address of the next thing and compute the
690 * difference. The approach used depends on what kind of
691 * entry/entries follow...
692 */
693 case N_SLINE: {
694 Int this_addr = (UInt)stab[i].n_value;
695
696 /* Although stored as a short, neg values really are >
697 * 32768, hence the UShort cast. Then we use an Int to
698 * handle overflows. */
699 prev_lineno = lineno;
700 lineno = (Int)((UShort)stab[i].n_desc);
701
702 if (prev_lineno > lineno + OVERFLOW_DIFFERENCE && same_file) {
703 VG_(message)(Vg_DebugMsg,
704 "Line number overflow detected (%d --> %d) in %s",
705 prev_lineno, lineno, curr_file_name);
706 lineno_overflows++;
707 }
708 same_file = True;
709
710 LOOP:
711 if (i+1 >= n_stab_entries) {
712 /* If it's the last entry, just guess the range is
713 * four; can't do any better */
714 next_addr = this_addr + 4;
715 } else {
716 switch (stab[i+1].n_type) {
717 /* Easy, common case: use address of next entry */
718 case N_SLINE: case N_SO:
719 next_addr = (UInt)stab[i+1].n_value;
720 break;
721
722 /* Boring one: skip, look for something more
723 useful. */
724 case N_RSYM: case N_LSYM: case N_LBRAC: case N_RBRAC:
725 case N_STSYM: case N_LCSYM: case N_GSYM:
726 i++;
727 goto LOOP;
728
njnb79ad342002-06-05 15:30:30 +0000729 /* If end-of-this-fun entry, use its address.
730 * If start-of-next-fun entry, find difference between start
731 * of current function and start of next function to work
732 * it out.
733 */
sewardjb51f2e62002-06-01 23:11:19 +0000734 case N_FUN:
735 if ('\0' == * (stabstr + stab[i+1].n_un.n_strx) ) {
736 next_addr = (UInt)stab[i+1].n_value;
737 } else {
njnb79ad342002-06-05 15:30:30 +0000738 next_addr =
739 (UInt)stab[i+1].n_value - curr_fn_stabs_addr;
sewardjb51f2e62002-06-01 23:11:19 +0000740 }
741 break;
742
743 /* N_SOL should be followed by an N_SLINE which can
744 be used */
745 case N_SOL:
746 if (i+2 < n_stab_entries && N_SLINE == stab[i+2].n_type) {
747 next_addr = (UInt)stab[i+2].n_value;
748 break;
749 } else {
750 VG_(printf)("unhandled N_SOL stabs case: %d %d %d",
751 stab[i+1].n_type, i, n_stab_entries);
752 VG_(panic)("unhandled N_SOL stabs case");
753 }
754
755 default:
756 VG_(printf)("unhandled (other) stabs case: %d %d",
757 stab[i+1].n_type,i);
758 /* VG_(panic)("unhandled (other) stabs case"); */
759 next_addr = this_addr + 4;
760 break;
761 }
762 }
763
764 addLineInfo ( si, curr_filenmoff, curr_fnbaseaddr + this_addr,
765 curr_fnbaseaddr + next_addr,
766 lineno + lineno_overflows * LINENO_OVERFLOW, i);
767 break;
768 }
769
770 case N_FUN: {
771 if ('\0' != (stabstr + stab[i].n_un.n_strx)[0] ) {
772 /* N_FUN with a name -- indicates the start of a fn. */
njnb79ad342002-06-05 15:30:30 +0000773 curr_fn_stabs_addr = (Addr)stab[i].n_value;
774 curr_fnbaseaddr = si->offset + curr_fn_stabs_addr;
sewardjb51f2e62002-06-01 23:11:19 +0000775 curr_fn_name = stabstr + stab[i].n_un.n_strx;
776 } else {
777 curr_fn_name = no_fn_name;
778 }
779 break;
780 }
781
782 case N_SOL:
783 if (lineno_overflows != 0) {
784 VG_(message)(Vg_UserMsg,
785 "Warning: file %s is very big (> 65535 lines) "
786 "Line numbers and annotation for this file might "
787 "be wrong. Sorry",
788 curr_file_name);
789 }
790 /* fall through! */
791 case N_SO:
792 lineno_overflows = 0;
793
794 /* seems to give lots of locations in header files */
795 /* case 130: */ /* BINCL */
796 {
797 UChar* nm = stabstr + stab[i].n_un.n_strx;
798 UInt len = VG_(strlen)(nm);
799
800 if (len > 0 && nm[len-1] != '/') {
801 curr_filenmoff = addStr ( si, nm );
802 curr_file_name = stabstr + stab[i].n_un.n_strx;
803 }
804 else
805 if (len == 0)
806 curr_filenmoff = addStr ( si, "?1\0" );
807
808 break;
809 }
810
811# if 0
812 case 162: /* EINCL */
813 curr_filenmoff = addStr ( si, "?2\0" );
814 break;
815# endif
816
817 default:
818 break;
819 }
820 } /* for (i = 0; i < stab_sz/(int)sizeof(struct nlist); i++) */
sewardjde4a1d02002-03-22 01:27:54 +0000821}
822
823
sewardjb51f2e62002-06-01 23:11:19 +0000824/*------------------------------------------------------------*/
825/*--- Read DWARF2 format debug info. ---*/
826/*------------------------------------------------------------*/
sewardjc134dd92002-06-01 14:21:36 +0000827
828/* Structure found in the .debug_line section. */
829typedef struct
830{
831 UChar li_length [4];
832 UChar li_version [2];
833 UChar li_prologue_length [4];
834 UChar li_min_insn_length [1];
835 UChar li_default_is_stmt [1];
836 UChar li_line_base [1];
837 UChar li_line_range [1];
838 UChar li_opcode_base [1];
839}
840DWARF2_External_LineInfo;
841typedef struct
842{
843 UInt li_length;
844 UShort li_version;
845 UInt li_prologue_length;
846 UChar li_min_insn_length;
847 UChar li_default_is_stmt;
848 Int li_line_base;
849 UChar li_line_range;
850 UChar li_opcode_base;
851}
852DWARF2_Internal_LineInfo;
853/* Line number opcodes. */
854enum dwarf_line_number_ops
855 {
856 DW_LNS_extended_op = 0,
857 DW_LNS_copy = 1,
858 DW_LNS_advance_pc = 2,
859 DW_LNS_advance_line = 3,
860 DW_LNS_set_file = 4,
861 DW_LNS_set_column = 5,
862 DW_LNS_negate_stmt = 6,
863 DW_LNS_set_basic_block = 7,
864 DW_LNS_const_add_pc = 8,
865 DW_LNS_fixed_advance_pc = 9,
866 /* DWARF 3. */
867 DW_LNS_set_prologue_end = 10,
868 DW_LNS_set_epilogue_begin = 11,
869 DW_LNS_set_isa = 12
870 };
871
872/* Line number extended opcodes. */
873enum dwarf_line_number_x_ops
874 {
875 DW_LNE_end_sequence = 1,
876 DW_LNE_set_address = 2,
877 DW_LNE_define_file = 3
878 };
879
880typedef struct State_Machine_Registers
881{
882 Addr address;
883 UInt file;
884 UInt line;
885 UInt column;
886 Int is_stmt;
887 Int basic_block;
888 Int end_sequence;
889/* This variable hold the number of the last entry seen
890 in the File Table. */
891 UInt last_file_entry;
892} SMR;
893
sewardjb51f2e62002-06-01 23:11:19 +0000894
895static
896UInt read_leb128 ( UChar* data, Int* length_return, Int sign )
897{
898 UInt result = 0;
899 UInt num_read = 0;
900 Int shift = 0;
901 UChar byte;
902
903 do
904 {
905 byte = * data ++;
906 num_read ++;
907
908 result |= (byte & 0x7f) << shift;
909
910 shift += 7;
911
912 }
913 while (byte & 0x80);
914
915 if (length_return != NULL)
916 * length_return = num_read;
917
918 if (sign && (shift < 32) && (byte & 0x40))
919 result |= -1 << shift;
920
921 return result;
922}
923
924
sewardjc134dd92002-06-01 14:21:36 +0000925static SMR state_machine_regs;
926
927static void
928reset_state_machine (is_stmt)
929 Int is_stmt;
930{
931 state_machine_regs.address = 0;
932 state_machine_regs.file = 1;
933 state_machine_regs.line = 1;
934 state_machine_regs.column = 0;
935 state_machine_regs.is_stmt = is_stmt;
936 state_machine_regs.basic_block = 0;
937 state_machine_regs.end_sequence = 0;
938 state_machine_regs.last_file_entry = 0;
939}
940
941/* Handled an extend line op. Returns true if this is the end
942 of sequence. */
943static int
944process_extended_line_op (si, fnames, data, is_stmt, pointer_size)
945 SegInfo *si;
946 UInt **fnames;
947 UChar * data;
948 Int is_stmt;
949 Int pointer_size;
950{
951 UChar op_code;
952 Int bytes_read;
953 UInt len;
954 UChar * name;
955 Addr adr;
956
957 len = read_leb128 (data, & bytes_read, 0);
958 data += bytes_read;
959
960 if (len == 0)
961 {
962 VG_(message) (Vg_UserMsg,"badly formed extended line op encountered!\n");
963 return bytes_read;
964 }
965
966 len += bytes_read;
967 op_code = * data ++;
968
969
970 switch (op_code)
971 {
972 case DW_LNE_end_sequence:
973 addLineInfo (si, (*fnames)[state_machine_regs.file], si->offset + (state_machine_regs.address - 1), si->offset + (state_machine_regs.address), 0, 0);
974 reset_state_machine (is_stmt);
975 break;
976
977 case DW_LNE_set_address:
978 /* XXX: Pointer size could be 8 */
979 adr = *((Addr *)data);
980 state_machine_regs.address = adr;
981 break;
982
983 case DW_LNE_define_file:
984
985 ++ state_machine_regs.last_file_entry;
986 name = data;
987 if (*fnames == NULL)
988 *fnames = VG_(malloc)(VG_AR_SYMTAB, sizeof (UInt) * 2);
989 else
990 *fnames = VG_(realloc)(VG_AR_SYMTAB, *fnames, sizeof (UInt) * (state_machine_regs.last_file_entry + 1));
991 (*fnames)[state_machine_regs.last_file_entry] = addStr (si,name);
992 data += VG_(strlen) ((char *) data) + 1;
993 read_leb128 (data, & bytes_read, 0);
994 data += bytes_read;
995 read_leb128 (data, & bytes_read, 0);
996 data += bytes_read;
997 read_leb128 (data, & bytes_read, 0);
998 break;
999
1000 default:
1001 break;
1002 }
1003
1004 return len;
1005}
1006
1007
sewardjb51f2e62002-06-01 23:11:19 +00001008static
1009void read_debuginfo_dwarf2 ( SegInfo* si, UChar* dwarf2, Int dwarf2_sz )
sewardjc134dd92002-06-01 14:21:36 +00001010{
1011 DWARF2_External_LineInfo * external;
1012 DWARF2_Internal_LineInfo info;
1013 UChar * standard_opcodes;
sewardjb51f2e62002-06-01 23:11:19 +00001014 UChar * data = dwarf2;
1015 UChar * end = dwarf2 + dwarf2_sz;
sewardjc134dd92002-06-01 14:21:36 +00001016 UChar * end_of_sequence;
1017 UInt *fnames = NULL;
1018
1019
1020 while (data < end)
1021 {
1022 external = (DWARF2_External_LineInfo *) data;
1023
1024 /* Check the length of the block. */
1025 info.li_length =*((UInt *)(external->li_length));
1026
1027 if (info.li_length == 0xffffffff)
1028 {
sewardjb51f2e62002-06-01 23:11:19 +00001029 vg_symerr("64-bit DWARF line info is not supported yet.");
sewardjc134dd92002-06-01 14:21:36 +00001030 break;
1031 }
1032
sewardjb51f2e62002-06-01 23:11:19 +00001033 if (info.li_length + sizeof (external->li_length) > dwarf2_sz)
sewardjc134dd92002-06-01 14:21:36 +00001034 {
sewardjb51f2e62002-06-01 23:11:19 +00001035 vg_symerr("DWARF line info appears to be corrupt - the section is too small");
1036 return;
sewardjc134dd92002-06-01 14:21:36 +00001037 }
1038
1039 /* Check its version number. */
1040 info.li_version =*((UShort *) (external->li_version));
1041 if (info.li_version != 2)
1042 {
sewardjb51f2e62002-06-01 23:11:19 +00001043 vg_symerr("Only DWARF version 2 line info is currently supported.");
1044 return;
sewardjc134dd92002-06-01 14:21:36 +00001045 }
1046
1047 info.li_prologue_length = *((UInt *)(external->li_prologue_length));
1048 info.li_min_insn_length = *((UChar *) (external->li_min_insn_length));
1049 info.li_default_is_stmt = *((UChar *) (external->li_default_is_stmt));
1050 info.li_line_base = *((Int *) (external->li_line_base));
1051 info.li_line_range = *((UChar *) (external->li_line_range));
1052 info.li_opcode_base = *((UChar *) (external->li_opcode_base));
1053
1054 /* Sign extend the line base field. */
1055 info.li_line_base <<= 24;
1056 info.li_line_base >>= 24;
1057
1058 end_of_sequence = data + info.li_length + sizeof (external->li_length);
1059
1060 reset_state_machine (info.li_default_is_stmt);
1061
1062 /* Read the contents of the Opcodes table. */
1063 standard_opcodes = data + sizeof (* external);
1064
1065
1066
1067 /* Read the contents of the Directory table. */
1068 data = standard_opcodes + info.li_opcode_base - 1;
1069
1070 if (* data == 0);
1071 else
1072 {
1073 /* We ignore the directory table, since gcc gives the entire path as part of the filename */
1074 while (* data != 0)
1075 {
1076 data += VG_(strlen) ((char *) data) + 1;
1077 }
1078 }
1079
1080 /* Skip the NUL at the end of the table. */
1081 data ++;
1082
1083 /* Read the contents of the File Name table. */
1084 if (* data == 0);
1085 else
1086 {
1087
1088 while (* data != 0)
1089 {
1090 UChar * name;
1091 Int bytes_read;
1092
1093 ++ state_machine_regs.last_file_entry;
1094 name = data;
1095 /* Since we don't have realloc (0, ....) == malloc (...) semantics, we need to malloc the first time. */
1096
1097 if (fnames == NULL)
1098 fnames = VG_(malloc)(VG_AR_SYMTAB, sizeof (UInt) * 2);
1099 else
1100 fnames = VG_(realloc)(VG_AR_SYMTAB, fnames, sizeof (UInt) * (state_machine_regs.last_file_entry + 1));
1101 data += VG_(strlen) ((char *) data) + 1;
1102 fnames[state_machine_regs.last_file_entry] = addStr (si,name);
1103
1104 read_leb128 (data, & bytes_read, 0);
1105 data += bytes_read;
1106 read_leb128 (data, & bytes_read, 0);
1107 data += bytes_read;
1108 read_leb128 (data, & bytes_read, 0);
1109 data += bytes_read;
1110 }
1111 }
1112
1113 /* Skip the NUL at the end of the table. */
1114 data ++;
1115
1116 /* Now display the statements. */
1117
1118 while (data < end_of_sequence)
1119 {
1120 UChar op_code;
1121 Int adv;
1122 Int bytes_read;
1123
1124 op_code = * data ++;
1125
1126 if (op_code >= info.li_opcode_base)
1127 {
1128 Int advAddr;
1129 op_code -= info.li_opcode_base;
1130 adv = (op_code / info.li_line_range) * info.li_min_insn_length;
1131 advAddr = adv;
1132 state_machine_regs.address += adv;
1133 adv = (op_code % info.li_line_range) + info.li_line_base;
1134 addLineInfo (si, fnames[state_machine_regs.file], si->offset + (state_machine_regs.address - advAddr), si->offset + (state_machine_regs.address), state_machine_regs.line, 0);
1135 state_machine_regs.line += adv;
1136 }
1137 else switch (op_code)
1138 {
1139 case DW_LNS_extended_op:
1140 data += process_extended_line_op (si, &fnames, data, info.li_default_is_stmt,
1141 sizeof (Addr));
1142 break;
1143
1144 case DW_LNS_copy:
1145 addLineInfo (si, fnames[state_machine_regs.file], si->offset + state_machine_regs.address, si->offset + (state_machine_regs.address + 1), state_machine_regs.line , 0);
1146 break;
1147
1148 case DW_LNS_advance_pc:
1149 adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
1150 data += bytes_read;
1151 state_machine_regs.address += adv;
1152 break;
1153
1154 case DW_LNS_advance_line:
1155 adv = read_leb128 (data, & bytes_read, 1);
1156 data += bytes_read;
1157 state_machine_regs.line += adv;
1158 break;
1159
1160 case DW_LNS_set_file:
1161 adv = read_leb128 (data, & bytes_read, 0);
1162 data += bytes_read;
1163 state_machine_regs.file = adv;
1164 break;
1165
1166 case DW_LNS_set_column:
1167 adv = read_leb128 (data, & bytes_read, 0);
1168 data += bytes_read;
1169 state_machine_regs.column = adv;
1170 break;
1171
1172 case DW_LNS_negate_stmt:
1173 adv = state_machine_regs.is_stmt;
1174 adv = ! adv;
1175 state_machine_regs.is_stmt = adv;
1176 break;
1177
1178 case DW_LNS_set_basic_block:
1179 state_machine_regs.basic_block = 1;
1180 break;
1181
1182 case DW_LNS_const_add_pc:
1183 adv = (((255 - info.li_opcode_base) / info.li_line_range)
1184 * info.li_min_insn_length);
1185 state_machine_regs.address += adv;
1186 break;
1187
1188 case DW_LNS_fixed_advance_pc:
1189 /* XXX: Need something to get 2 bytes */
1190 adv = *((UShort *)data);
1191 data += 2;
1192 state_machine_regs.address += adv;
1193 break;
1194
1195 case DW_LNS_set_prologue_end:
1196 break;
1197
1198 case DW_LNS_set_epilogue_begin:
1199 break;
1200
1201 case DW_LNS_set_isa:
1202 adv = read_leb128 (data, & bytes_read, 0);
1203 data += bytes_read;
1204 break;
1205
1206 default:
1207 {
1208 int j;
1209 for (j = standard_opcodes[op_code - 1]; j > 0 ; --j)
1210 {
1211 read_leb128 (data, &bytes_read, 0);
1212 data += bytes_read;
1213 }
1214 }
1215 break;
1216 }
1217 }
1218 VG_(free)(VG_AR_SYMTAB, fnames);
1219 fnames = NULL;
1220 }
sewardjc134dd92002-06-01 14:21:36 +00001221}
1222
sewardjb51f2e62002-06-01 23:11:19 +00001223
1224/*------------------------------------------------------------*/
1225/*--- Read info from a .so/exe file. ---*/
1226/*------------------------------------------------------------*/
1227
sewardjde4a1d02002-03-22 01:27:54 +00001228/* Read the symbols from the object/exe specified by the SegInfo into
1229 the tables within the supplied SegInfo. */
1230static
1231void vg_read_lib_symbols ( SegInfo* si )
1232{
1233 Elf32_Ehdr* ehdr; /* The ELF header */
1234 Elf32_Shdr* shdr; /* The section table */
1235 UChar* sh_strtab; /* The section table's string table */
sewardjb51f2e62002-06-01 23:11:19 +00001236 UChar* stab; /* The .stab table */
sewardjde4a1d02002-03-22 01:27:54 +00001237 UChar* stabstr; /* The .stab string table */
sewardjb51f2e62002-06-01 23:11:19 +00001238 UChar* dwarf2; /* The DWARF2 location info table */
sewardjde4a1d02002-03-22 01:27:54 +00001239 Int stab_sz; /* Size in bytes of the .stab table */
1240 Int stabstr_sz; /* Size in bytes of the .stab string table */
sewardjb51f2e62002-06-01 23:11:19 +00001241 Int dwarf2_sz; /* Size in bytes of the DWARF2 srcloc table*/
sewardjde4a1d02002-03-22 01:27:54 +00001242 Int fd;
1243 Int i;
1244 Bool ok;
1245 Addr oimage;
1246 Int n_oimage;
sewardjb3586202002-05-09 17:38:13 +00001247 struct vki_stat stat_buf;
sewardjde4a1d02002-03-22 01:27:54 +00001248
sewardjde4a1d02002-03-22 01:27:54 +00001249 oimage = (Addr)NULL;
1250 if (VG_(clo_verbosity) > 1)
njne0ee0712002-05-03 16:41:05 +00001251 VG_(message)(Vg_UserMsg, "Reading syms from %s", si->filename );
sewardjde4a1d02002-03-22 01:27:54 +00001252
1253 /* mmap the object image aboard, so that we can read symbols and
1254 line number info out of it. It will be munmapped immediately
1255 thereafter; it is only aboard transiently. */
1256
sewardjb3586202002-05-09 17:38:13 +00001257 i = VG_(stat)(si->filename, &stat_buf);
sewardjde4a1d02002-03-22 01:27:54 +00001258 if (i != 0) {
1259 vg_symerr("Can't stat .so/.exe (to determine its size)?!");
1260 return;
1261 }
1262 n_oimage = stat_buf.st_size;
1263
1264 fd = VG_(open_read)(si->filename);
1265 if (fd == -1) {
1266 vg_symerr("Can't open .so/.exe to read symbols?!");
1267 return;
1268 }
1269
sewardjb3586202002-05-09 17:38:13 +00001270 oimage = (Addr)VG_(mmap)( NULL, n_oimage,
1271 VKI_PROT_READ, VKI_MAP_PRIVATE, fd, 0 );
sewardjde4a1d02002-03-22 01:27:54 +00001272 if (oimage == ((Addr)(-1))) {
1273 VG_(message)(Vg_UserMsg,
1274 "mmap failed on %s", si->filename );
1275 VG_(close)(fd);
1276 return;
1277 }
1278
1279 VG_(close)(fd);
1280
1281 /* Ok, the object image is safely in oimage[0 .. n_oimage-1].
1282 Now verify that it is a valid ELF .so or executable image.
1283 */
1284 ok = (n_oimage >= sizeof(Elf32_Ehdr));
1285 ehdr = (Elf32_Ehdr*)oimage;
1286
1287 if (ok) {
1288 ok &= (ehdr->e_ident[EI_MAG0] == 0x7F
1289 && ehdr->e_ident[EI_MAG1] == 'E'
1290 && ehdr->e_ident[EI_MAG2] == 'L'
1291 && ehdr->e_ident[EI_MAG3] == 'F');
1292 ok &= (ehdr->e_ident[EI_CLASS] == ELFCLASS32
1293 && ehdr->e_ident[EI_DATA] == ELFDATA2LSB
1294 && ehdr->e_ident[EI_VERSION] == EV_CURRENT);
1295 ok &= (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN);
1296 ok &= (ehdr->e_machine == EM_386);
1297 ok &= (ehdr->e_version == EV_CURRENT);
1298 ok &= (ehdr->e_shstrndx != SHN_UNDEF);
1299 ok &= (ehdr->e_shoff != 0 && ehdr->e_shnum != 0);
1300 }
1301
1302 if (!ok) {
1303 vg_symerr("Invalid ELF header, or missing stringtab/sectiontab.");
1304 VG_(munmap) ( (void*)oimage, n_oimage );
1305 return;
1306 }
1307
1308 if (VG_(clo_trace_symtab))
1309 VG_(printf)(
1310 "shoff = %d, shnum = %d, size = %d, n_vg_oimage = %d\n",
1311 ehdr->e_shoff, ehdr->e_shnum, sizeof(Elf32_Shdr), n_oimage );
1312
1313 if (ehdr->e_shoff + ehdr->e_shnum*sizeof(Elf32_Shdr) > n_oimage) {
1314 vg_symerr("ELF section header is beyond image end?!");
1315 VG_(munmap) ( (void*)oimage, n_oimage );
1316 return;
1317 }
1318
1319 shdr = (Elf32_Shdr*)(oimage + ehdr->e_shoff);
1320 sh_strtab = (UChar*)(oimage + shdr[ehdr->e_shstrndx].sh_offset);
1321
1322 /* try and read the object's symbol table */
1323 {
1324 UChar* o_strtab = NULL;
1325 Elf32_Sym* o_symtab = NULL;
1326 UInt o_strtab_sz = 0;
1327 UInt o_symtab_sz = 0;
1328
1329 UChar* o_got = NULL;
1330 UChar* o_plt = NULL;
1331 UInt o_got_sz = 0;
1332 UInt o_plt_sz = 0;
1333
1334 Bool snaffle_it;
1335 Addr sym_addr;
1336
1337 /* find the .stabstr and .stab sections */
1338 for (i = 0; i < ehdr->e_shnum; i++) {
1339 if (0 == VG_(strcmp)(".symtab",sh_strtab + shdr[i].sh_name)) {
1340 o_symtab = (Elf32_Sym*)(oimage + shdr[i].sh_offset);
1341 o_symtab_sz = shdr[i].sh_size;
1342 vg_assert((o_symtab_sz % sizeof(Elf32_Sym)) == 0);
1343 /* check image overrun here */
1344 }
1345 if (0 == VG_(strcmp)(".strtab",sh_strtab + shdr[i].sh_name)) {
1346 o_strtab = (UChar*)(oimage + shdr[i].sh_offset);
1347 o_strtab_sz = shdr[i].sh_size;
1348 /* check image overrun here */
1349 }
1350
1351 /* find out where the .got and .plt sections will be in the
1352 executable image, not in the object image transiently loaded.
1353 */
1354 if (0 == VG_(strcmp)(".got",sh_strtab + shdr[i].sh_name)) {
1355 o_got = (UChar*)(si->offset
1356 + shdr[i].sh_offset);
1357 o_got_sz = shdr[i].sh_size;
1358 /* check image overrun here */
1359 }
1360 if (0 == VG_(strcmp)(".plt",sh_strtab + shdr[i].sh_name)) {
1361 o_plt = (UChar*)(si->offset
1362 + shdr[i].sh_offset);
1363 o_plt_sz = shdr[i].sh_size;
1364 /* check image overrun here */
1365 }
1366
1367 }
1368
1369 if (VG_(clo_trace_symtab)) {
1370 if (o_plt) VG_(printf)( "PLT: %p .. %p\n",
1371 o_plt, o_plt + o_plt_sz - 1 );
1372 if (o_got) VG_(printf)( "GOT: %p .. %p\n",
1373 o_got, o_got + o_got_sz - 1 );
1374 }
1375
1376 if (o_strtab == NULL || o_symtab == NULL) {
1377 vg_symerr(" object doesn't have a symbol table");
1378 } else {
1379 /* Perhaps should start at i = 1; ELF docs suggest that entry
1380 0 always denotes `unknown symbol'. */
1381 for (i = 1; i < o_symtab_sz/sizeof(Elf32_Sym); i++){
1382# if 0
1383 VG_(printf)("raw symbol: ");
1384 switch (ELF32_ST_BIND(o_symtab[i].st_info)) {
1385 case STB_LOCAL: VG_(printf)("LOC "); break;
1386 case STB_GLOBAL: VG_(printf)("GLO "); break;
1387 case STB_WEAK: VG_(printf)("WEA "); break;
1388 case STB_LOPROC: VG_(printf)("lop "); break;
1389 case STB_HIPROC: VG_(printf)("hip "); break;
1390 default: VG_(printf)("??? "); break;
1391 }
1392 switch (ELF32_ST_TYPE(o_symtab[i].st_info)) {
1393 case STT_NOTYPE: VG_(printf)("NOT "); break;
1394 case STT_OBJECT: VG_(printf)("OBJ "); break;
1395 case STT_FUNC: VG_(printf)("FUN "); break;
1396 case STT_SECTION: VG_(printf)("SEC "); break;
1397 case STT_FILE: VG_(printf)("FIL "); break;
1398 case STT_LOPROC: VG_(printf)("lop "); break;
1399 case STT_HIPROC: VG_(printf)("hip "); break;
1400 default: VG_(printf)("??? "); break;
1401 }
1402 VG_(printf)(
1403 ": value %p, size %d, name %s\n",
1404 si->offset+(UChar*)o_symtab[i].st_value,
1405 o_symtab[i].st_size,
1406 o_symtab[i].st_name
1407 ? ((Char*)o_strtab+o_symtab[i].st_name)
1408 : (Char*)"NONAME");
1409# endif
1410
1411 /* Figure out if we're interested in the symbol.
1412 Firstly, is it of the right flavour?
1413 */
1414 snaffle_it
1415 = ( (ELF32_ST_BIND(o_symtab[i].st_info) == STB_GLOBAL ||
1416 ELF32_ST_BIND(o_symtab[i].st_info) == STB_LOCAL /* ||
1417 ELF32_ST_BIND(o_symtab[i].st_info) == STB_WEAK */)
1418 &&
1419 (ELF32_ST_TYPE(o_symtab[i].st_info) == STT_FUNC /*||
1420 ELF32_ST_TYPE(o_symtab[i].st_info) == STT_OBJECT*/)
1421 );
1422
1423 /* Secondly, if it's apparently in a GOT or PLT, it's really
1424 a reference to a symbol defined elsewhere, so ignore it.
1425 */
1426 sym_addr = si->offset
1427 + (UInt)o_symtab[i].st_value;
1428 if (o_got != NULL
1429 && sym_addr >= (Addr)o_got
1430 && sym_addr < (Addr)(o_got+o_got_sz)) {
1431 snaffle_it = False;
1432 if (VG_(clo_trace_symtab)) {
1433 VG_(printf)( "in GOT: %s\n",
1434 o_strtab+o_symtab[i].st_name);
1435 }
1436 }
1437 if (o_plt != NULL
1438 && sym_addr >= (Addr)o_plt
1439 && sym_addr < (Addr)(o_plt+o_plt_sz)) {
1440 snaffle_it = False;
1441 if (VG_(clo_trace_symtab)) {
1442 VG_(printf)( "in PLT: %s\n",
1443 o_strtab+o_symtab[i].st_name);
1444 }
1445 }
1446
1447 /* Don't bother if nameless, or zero-sized. */
1448 if (snaffle_it
1449 && (o_symtab[i].st_name == (Elf32_Word)NULL
1450 || /* VG_(strlen)(o_strtab+o_symtab[i].st_name) == 0 */
1451 /* equivalent but cheaper ... */
1452 * ((UChar*)(o_strtab+o_symtab[i].st_name)) == 0
1453 || o_symtab[i].st_size == 0)) {
1454 snaffle_it = False;
1455 if (VG_(clo_trace_symtab)) {
1456 VG_(printf)( "size=0: %s\n",
1457 o_strtab+o_symtab[i].st_name);
1458 }
1459 }
1460
1461# if 0
1462 /* Avoid _dl_ junk. (Why?) */
1463 /* 01-02-24: disabled until I find out if it really helps. */
1464 if (snaffle_it
1465 && (VG_(strncmp)("_dl_", o_strtab+o_symtab[i].st_name, 4) == 0
1466 || VG_(strncmp)("_r_debug",
1467 o_strtab+o_symtab[i].st_name, 8) == 0)) {
1468 snaffle_it = False;
1469 if (VG_(clo_trace_symtab)) {
1470 VG_(printf)( "_dl_ junk: %s\n",
1471 o_strtab+o_symtab[i].st_name);
1472 }
1473 }
1474# endif
1475
1476 /* This seems to significantly reduce the number of junk
1477 symbols, and particularly reduces the number of
1478 overlapping address ranges. Don't ask me why ... */
1479 if (snaffle_it && (Int)o_symtab[i].st_value == 0) {
1480 snaffle_it = False;
1481 if (VG_(clo_trace_symtab)) {
1482 VG_(printf)( "valu=0: %s\n",
1483 o_strtab+o_symtab[i].st_name);
1484 }
1485 }
1486
1487 /* If no part of the symbol falls within the mapped range,
1488 ignore it. */
1489 if (sym_addr+o_symtab[i].st_size <= si->start
1490 || sym_addr >= si->start+si->size) {
1491 snaffle_it = False;
1492 }
1493
1494 if (snaffle_it) {
1495 /* it's an interesting symbol; record ("snaffle") it. */
1496 RiSym sym;
1497 Char* t0 = o_symtab[i].st_name
1498 ? (Char*)(o_strtab+o_symtab[i].st_name)
1499 : (Char*)"NONAME";
1500 Int nmoff = addStr ( si, t0 );
1501 vg_assert(nmoff >= 0
1502 /* && 0==VG_(strcmp)(t0,&vg_strtab[nmoff]) */ );
1503 vg_assert( (Int)o_symtab[i].st_value >= 0);
1504 /* VG_(printf)("%p + %d: %s\n", si->addr,
1505 (Int)o_symtab[i].st_value, t0 ); */
1506 sym.addr = sym_addr;
1507 sym.size = o_symtab[i].st_size;
1508 sym.nmoff = nmoff;
1509 addSym ( si, &sym );
1510 }
1511 }
1512 }
1513 }
1514
sewardjb51f2e62002-06-01 23:11:19 +00001515 /* Reading of the stabs and/or dwarf2 debug format information, if
1516 any. */
sewardjde4a1d02002-03-22 01:27:54 +00001517 stabstr = NULL;
1518 stab = NULL;
sewardjb51f2e62002-06-01 23:11:19 +00001519 dwarf2 = NULL;
sewardjde4a1d02002-03-22 01:27:54 +00001520 stabstr_sz = 0;
1521 stab_sz = 0;
sewardjb51f2e62002-06-01 23:11:19 +00001522 dwarf2_sz = 0;
1523
1524 /* find the .stabstr / .stab / .debug_line sections */
sewardjde4a1d02002-03-22 01:27:54 +00001525 for (i = 0; i < ehdr->e_shnum; i++) {
1526 if (0 == VG_(strcmp)(".stab",sh_strtab + shdr[i].sh_name)) {
sewardjb51f2e62002-06-01 23:11:19 +00001527 stab = (UChar*)(oimage + shdr[i].sh_offset);
sewardjde4a1d02002-03-22 01:27:54 +00001528 stab_sz = shdr[i].sh_size;
1529 }
1530 if (0 == VG_(strcmp)(".stabstr",sh_strtab + shdr[i].sh_name)) {
1531 stabstr = (UChar*)(oimage + shdr[i].sh_offset);
1532 stabstr_sz = shdr[i].sh_size;
1533 }
sewardjc134dd92002-06-01 14:21:36 +00001534 if (0 == VG_(strcmp)(".debug_line",sh_strtab + shdr[i].sh_name)) {
sewardjb51f2e62002-06-01 23:11:19 +00001535 dwarf2 = (UChar *)(oimage + shdr[i].sh_offset);
1536 dwarf2_sz = shdr[i].sh_size;
sewardjc134dd92002-06-01 14:21:36 +00001537 }
sewardjde4a1d02002-03-22 01:27:54 +00001538 }
1539
sewardjb51f2e62002-06-01 23:11:19 +00001540 if ((stab == NULL || stabstr == NULL) && dwarf2 == NULL) {
sewardjde4a1d02002-03-22 01:27:54 +00001541 vg_symerr(" object doesn't have any debug info");
1542 VG_(munmap) ( (void*)oimage, n_oimage );
1543 return;
1544 }
1545
1546 if ( stab_sz + (UChar*)stab > n_oimage + (UChar*)oimage
1547 || stabstr_sz + (UChar*)stabstr
1548 > n_oimage + (UChar*)oimage ) {
sewardjb51f2e62002-06-01 23:11:19 +00001549 vg_symerr(" ELF (stabs) debug data is beyond image end?!");
sewardjde4a1d02002-03-22 01:27:54 +00001550 VG_(munmap) ( (void*)oimage, n_oimage );
1551 return;
1552 }
1553
sewardjb51f2e62002-06-01 23:11:19 +00001554 if ( dwarf2_sz + (UChar*)dwarf2 > n_oimage + (UChar*)oimage ) {
1555 vg_symerr(" ELF (dwarf2) debug data is beyond image end?!");
1556 VG_(munmap) ( (void*)oimage, n_oimage );
1557 return;
1558 }
sewardjde4a1d02002-03-22 01:27:54 +00001559
sewardjb51f2e62002-06-01 23:11:19 +00001560 /* Looks plausible. Go on and read debug data. */
1561 if (stab != NULL && stabstr != NULL) {
1562 read_debuginfo_stabs ( si, stab, stab_sz, stabstr, stabstr_sz );
1563 }
sewardjde4a1d02002-03-22 01:27:54 +00001564
sewardjb51f2e62002-06-01 23:11:19 +00001565 if (dwarf2 != NULL) {
1566 read_debuginfo_dwarf2 ( si, dwarf2, dwarf2_sz );
1567 }
sewardjde4a1d02002-03-22 01:27:54 +00001568
1569 /* Last, but not least, heave the oimage back overboard. */
1570 VG_(munmap) ( (void*)oimage, n_oimage );
1571}
1572
1573
1574/*------------------------------------------------------------*/
1575/*--- Main entry point for symbols table reading. ---*/
1576/*------------------------------------------------------------*/
1577
1578/* The root structure for the entire symbol table system. It is a
1579 linked list of SegInfos. Note that this entire mechanism assumes
1580 that what we read from /proc/self/maps doesn't contain overlapping
1581 address ranges, and as a result the SegInfos in this list describe
1582 disjoint address ranges.
1583*/
1584static SegInfo* segInfo = NULL;
1585
1586
1587static
1588void read_symtab_callback (
1589 Addr start, UInt size,
1590 Char rr, Char ww, Char xx,
1591 UInt foffset, UChar* filename )
1592{
1593 SegInfo* si;
1594
1595 /* Stay sane ... */
1596 if (size == 0)
1597 return;
1598
1599 /* We're only interested in collecting symbols in executable
1600 segments which are associated with a real file. Hence: */
1601 if (filename == NULL || xx != 'x')
1602 return;
1603 if (0 == VG_(strcmp)(filename, "/dev/zero"))
1604 return;
1605
1606 /* Perhaps we already have this one? If so, skip. */
1607 for (si = segInfo; si != NULL; si = si->next) {
1608 /*
1609 if (0==VG_(strcmp)(si->filename, filename))
1610 VG_(printf)("same fnames: %c%c%c (%p, %d) (%p, %d) %s\n",
1611 rr,ww,xx,si->start,si->size,start,size,filename);
1612 */
1613 /* For some reason the observed size of a mapping can change, so
1614 we don't use that to determine uniqueness. */
1615 if (si->start == start
1616 /* && si->size == size */
1617 && 0==VG_(strcmp)(si->filename, filename)) {
1618 return;
1619 }
1620 }
1621
1622 /* Get the record initialised right. */
1623 si = VG_(malloc)(VG_AR_SYMTAB, sizeof(SegInfo));
1624 si->next = segInfo;
1625 segInfo = si;
1626
1627 si->start = start;
1628 si->size = size;
1629 si->foffset = foffset;
1630 si->filename = VG_(malloc)(VG_AR_SYMTAB, 1 + VG_(strlen)(filename));
1631 VG_(strcpy)(si->filename, filename);
1632
1633 si->symtab = NULL;
1634 si->symtab_size = si->symtab_used = 0;
1635 si->loctab = NULL;
1636 si->loctab_size = si->loctab_used = 0;
1637 si->strtab = NULL;
1638 si->strtab_size = si->strtab_used = 0;
1639
1640 /* Kludge ... */
1641 si->offset
1642 = si->start==VG_ASSUMED_EXE_BASE ? 0 : si->start;
1643
1644 /* And actually fill it up. */
sewardj18d75132002-05-16 11:06:21 +00001645 if (VG_(clo_instrument) || VG_(clo_cachesim)) {
1646 vg_read_lib_symbols ( si );
1647 canonicaliseSymtab ( si );
1648 canonicaliseLoctab ( si );
1649 }
sewardjde4a1d02002-03-22 01:27:54 +00001650}
1651
1652
1653/* This one really is the Head Honcho. Update the symbol tables to
1654 reflect the current state of /proc/self/maps. Rather than re-read
1655 everything, just read the entries which are not already in segInfo.
1656 So we can call here repeatedly, after every mmap of a non-anonymous
1657 segment with execute permissions, for example, to pick up new
1658 libraries as they are dlopen'd. Conversely, when the client does
1659 munmap(), vg_symtab_notify_munmap() throws away any symbol tables
1660 which happen to correspond to the munmap()d area. */
1661void VG_(read_symbols) ( void )
1662{
sewardjde4a1d02002-03-22 01:27:54 +00001663 VG_(read_procselfmaps) ( read_symtab_callback );
1664
1665 /* Do a sanity check on the symbol tables: ensure that the address
1666 space pieces they cover do not overlap (otherwise we are severely
1667 hosed). This is a quadratic algorithm, but there shouldn't be
1668 many of them.
1669 */
1670 { SegInfo *si, *si2;
1671 for (si = segInfo; si != NULL; si = si->next) {
1672 /* Check no overlap between *si and those in the rest of the
1673 list. */
1674 for (si2 = si->next; si2 != NULL; si2 = si2->next) {
1675 Addr lo = si->start;
1676 Addr hi = si->start + si->size - 1;
1677 Addr lo2 = si2->start;
1678 Addr hi2 = si2->start + si2->size - 1;
1679 Bool overlap;
1680 vg_assert(lo < hi);
1681 vg_assert(lo2 < hi2);
1682 /* the main assertion */
1683 overlap = (lo <= lo2 && lo2 <= hi)
1684 || (lo <= hi2 && hi2 <= hi);
sewardjde4a1d02002-03-22 01:27:54 +00001685 if (overlap) {
1686 VG_(printf)("\n\nOVERLAPPING SEGMENTS\n" );
1687 ppSegInfo ( si );
1688 ppSegInfo ( si2 );
1689 VG_(printf)("\n\n");
1690 vg_assert(! overlap);
1691 }
1692 }
1693 }
1694 }
1695}
1696
1697
1698/* When an munmap() call happens, check to see whether it corresponds
1699 to a segment for a .so, and if so discard the relevant SegInfo.
1700 This might not be a very clever idea from the point of view of
1701 accuracy of error messages, but we need to do it in order to
sewardj18d75132002-05-16 11:06:21 +00001702 maintain the no-overlapping invariant.
1703
1704 16 May 02: Returns a Bool indicating whether or not the discarded
1705 range falls inside a known executable segment. See comment at top
1706 of file for why.
sewardjde4a1d02002-03-22 01:27:54 +00001707*/
sewardj18d75132002-05-16 11:06:21 +00001708Bool VG_(symtab_notify_munmap) ( Addr start, UInt length )
sewardjde4a1d02002-03-22 01:27:54 +00001709{
1710 SegInfo *prev, *curr;
1711
sewardjde4a1d02002-03-22 01:27:54 +00001712 prev = NULL;
1713 curr = segInfo;
1714 while (True) {
1715 if (curr == NULL) break;
1716 if (start == curr->start) break;
1717 prev = curr;
1718 curr = curr->next;
1719 }
sewardj18d75132002-05-16 11:06:21 +00001720 if (curr == NULL)
1721 return False;
sewardjde4a1d02002-03-22 01:27:54 +00001722
1723 VG_(message)(Vg_UserMsg,
1724 "discard syms in %s due to munmap()",
1725 curr->filename ? curr->filename : (UChar*)"???");
1726
1727 vg_assert(prev == NULL || prev->next == curr);
1728
1729 if (prev == NULL) {
1730 segInfo = curr->next;
1731 } else {
1732 prev->next = curr->next;
1733 }
1734
1735 freeSegInfo(curr);
sewardj18d75132002-05-16 11:06:21 +00001736 return True;
sewardjde4a1d02002-03-22 01:27:54 +00001737}
1738
1739
1740/*------------------------------------------------------------*/
1741/*--- Use of symbol table & location info to create ---*/
1742/*--- plausible-looking stack dumps. ---*/
1743/*------------------------------------------------------------*/
1744
1745/* Find a symbol-table index containing the specified pointer, or -1
1746 if not found. Binary search. */
1747
1748static Int search_one_symtab ( SegInfo* si, Addr ptr )
1749{
1750 Addr a_mid_lo, a_mid_hi;
1751 Int mid,
1752 lo = 0,
1753 hi = si->symtab_used-1;
1754 while (True) {
1755 /* current unsearched space is from lo to hi, inclusive. */
1756 if (lo > hi) return -1; /* not found */
1757 mid = (lo + hi) / 2;
1758 a_mid_lo = si->symtab[mid].addr;
1759 a_mid_hi = ((Addr)si->symtab[mid].addr) + si->symtab[mid].size - 1;
1760
1761 if (ptr < a_mid_lo) { hi = mid-1; continue; }
1762 if (ptr > a_mid_hi) { lo = mid+1; continue; }
1763 vg_assert(ptr >= a_mid_lo && ptr <= a_mid_hi);
1764 return mid;
1765 }
1766}
1767
1768
1769/* Search all symtabs that we know about to locate ptr. If found, set
1770 *psi to the relevant SegInfo, and *symno to the symtab entry number
1771 within that. If not found, *psi is set to NULL. */
1772
1773static void search_all_symtabs ( Addr ptr, SegInfo** psi, Int* symno )
1774{
1775 Int sno;
1776 SegInfo* si;
1777 for (si = segInfo; si != NULL; si = si->next) {
1778 if (si->start <= ptr && ptr < si->start+si->size) {
1779 sno = search_one_symtab ( si, ptr );
1780 if (sno == -1) goto not_found;
1781 *symno = sno;
1782 *psi = si;
1783 return;
1784 }
1785 }
1786 not_found:
1787 *psi = NULL;
1788}
1789
1790
1791/* Find a location-table index containing the specified pointer, or -1
1792 if not found. Binary search. */
1793
1794static Int search_one_loctab ( SegInfo* si, Addr ptr )
1795{
1796 Addr a_mid_lo, a_mid_hi;
1797 Int mid,
1798 lo = 0,
1799 hi = si->loctab_used-1;
1800 while (True) {
1801 /* current unsearched space is from lo to hi, inclusive. */
1802 if (lo > hi) return -1; /* not found */
1803 mid = (lo + hi) / 2;
1804 a_mid_lo = si->loctab[mid].addr;
1805 a_mid_hi = ((Addr)si->loctab[mid].addr) + si->loctab[mid].size - 1;
1806
1807 if (ptr < a_mid_lo) { hi = mid-1; continue; }
1808 if (ptr > a_mid_hi) { lo = mid+1; continue; }
1809 vg_assert(ptr >= a_mid_lo && ptr <= a_mid_hi);
1810 return mid;
1811 }
1812}
1813
1814
1815/* Search all loctabs that we know about to locate ptr. If found, set
1816 *psi to the relevant SegInfo, and *locno to the loctab entry number
1817 within that. If not found, *psi is set to NULL.
1818*/
1819static void search_all_loctabs ( Addr ptr, SegInfo** psi, Int* locno )
1820{
1821 Int lno;
1822 SegInfo* si;
1823 for (si = segInfo; si != NULL; si = si->next) {
1824 if (si->start <= ptr && ptr < si->start+si->size) {
1825 lno = search_one_loctab ( si, ptr );
1826 if (lno == -1) goto not_found;
1827 *locno = lno;
1828 *psi = si;
1829 return;
1830 }
1831 }
1832 not_found:
1833 *psi = NULL;
1834}
1835
1836
1837/* The whole point of this whole big deal: map a code address to a
1838 plausible symbol name. Returns False if no idea; otherwise True.
1839 Caller supplies buf and nbuf. If no_demangle is True, don't do
1840 demangling, regardless of vg_clo_demangle -- probably because the
1841 call has come from vg_what_fn_or_object_is_this. */
njn4f9c9342002-04-29 16:03:24 +00001842Bool VG_(what_fn_is_this) ( Bool no_demangle, Addr a,
1843 Char* buf, Int nbuf )
sewardjde4a1d02002-03-22 01:27:54 +00001844{
1845 SegInfo* si;
1846 Int sno;
1847 search_all_symtabs ( a, &si, &sno );
1848 if (si == NULL)
1849 return False;
1850 if (no_demangle) {
1851 VG_(strncpy_safely)
1852 ( buf, & si->strtab[si->symtab[sno].nmoff], nbuf );
1853 } else {
1854 VG_(demangle) ( & si->strtab[si->symtab[sno].nmoff], buf, nbuf );
1855 }
1856 return True;
1857}
1858
1859
1860/* Map a code address to the name of a shared object file. Returns
1861 False if no idea; otherwise False. Caller supplies buf and
1862 nbuf. */
1863static
1864Bool vg_what_object_is_this ( Addr a, Char* buf, Int nbuf )
1865{
1866 SegInfo* si;
1867 for (si = segInfo; si != NULL; si = si->next) {
1868 if (si->start <= a && a < si->start+si->size) {
1869 VG_(strncpy_safely)(buf, si->filename, nbuf);
1870 return True;
1871 }
1872 }
1873 return False;
1874}
1875
1876/* Return the name of an erring fn in a way which is useful
1877 for comparing against the contents of a suppressions file.
1878 Always writes something to buf. Also, doesn't demangle the
1879 name, because we want to refer to mangled names in the
1880 suppressions file.
1881*/
1882void VG_(what_obj_and_fun_is_this) ( Addr a,
1883 Char* obj_buf, Int n_obj_buf,
1884 Char* fun_buf, Int n_fun_buf )
1885{
1886 (void)vg_what_object_is_this ( a, obj_buf, n_obj_buf );
njn4f9c9342002-04-29 16:03:24 +00001887 (void)VG_(what_fn_is_this) ( True, a, fun_buf, n_fun_buf );
sewardjde4a1d02002-03-22 01:27:54 +00001888}
1889
1890
1891/* Map a code address to a (filename, line number) pair.
1892 Returns True if successful.
1893*/
njn4f9c9342002-04-29 16:03:24 +00001894Bool VG_(what_line_is_this)( Addr a,
1895 UChar* filename, Int n_filename,
1896 UInt* lineno )
sewardjde4a1d02002-03-22 01:27:54 +00001897{
1898 SegInfo* si;
1899 Int locno;
1900 search_all_loctabs ( a, &si, &locno );
1901 if (si == NULL)
1902 return False;
1903 VG_(strncpy_safely)(filename, & si->strtab[si->loctab[locno].fnmoff],
1904 n_filename);
1905 *lineno = si->loctab[locno].lineno;
njn4f9c9342002-04-29 16:03:24 +00001906
sewardjde4a1d02002-03-22 01:27:54 +00001907 return True;
1908}
1909
1910
1911/* Print a mini stack dump, showing the current location. */
1912void VG_(mini_stack_dump) ( ExeContext* ec )
1913{
1914
1915#define APPEND(str) \
1916 { UChar* sss; \
1917 for (sss = str; n < M_VG_ERRTXT-1 && *sss != 0; n++,sss++) \
1918 buf[n] = *sss; \
1919 buf[n] = 0; \
1920 }
1921
1922 Bool know_fnname;
1923 Bool know_objname;
1924 Bool know_srcloc;
1925 UInt lineno;
1926 UChar ibuf[20];
sewardj04b91062002-06-05 21:22:04 +00001927 UInt i, n;
sewardjde4a1d02002-03-22 01:27:54 +00001928
1929 UChar buf[M_VG_ERRTXT];
1930 UChar buf_fn[M_VG_ERRTXT];
1931 UChar buf_obj[M_VG_ERRTXT];
1932 UChar buf_srcloc[M_VG_ERRTXT];
1933
1934 Int stop_at = VG_(clo_backtrace_size);
1935
1936 n = 0;
1937
njn4f9c9342002-04-29 16:03:24 +00001938 know_fnname = VG_(what_fn_is_this)(False,ec->eips[0], buf_fn, M_VG_ERRTXT);
sewardjde4a1d02002-03-22 01:27:54 +00001939 know_objname = vg_what_object_is_this(ec->eips[0], buf_obj, M_VG_ERRTXT);
njn4f9c9342002-04-29 16:03:24 +00001940 know_srcloc = VG_(what_line_is_this)(ec->eips[0],
1941 buf_srcloc, M_VG_ERRTXT,
1942 &lineno);
sewardjde4a1d02002-03-22 01:27:54 +00001943
1944 APPEND(" at ");
1945 VG_(sprintf)(ibuf,"0x%x: ", ec->eips[0]);
1946 APPEND(ibuf);
1947 if (know_fnname) {
1948 APPEND(buf_fn);
1949 if (!know_srcloc && know_objname) {
1950 APPEND(" (in ");
1951 APPEND(buf_obj);
1952 APPEND(")");
1953 }
1954 } else if (know_objname && !know_srcloc) {
1955 APPEND("(within ");
1956 APPEND(buf_obj);
1957 APPEND(")");
1958 } else {
1959 APPEND("???");
1960 }
1961 if (know_srcloc) {
1962 APPEND(" (");
1963 APPEND(buf_srcloc);
1964 APPEND(":");
1965 VG_(sprintf)(ibuf,"%d",lineno);
1966 APPEND(ibuf);
1967 APPEND(")");
1968 }
1969 VG_(message)(Vg_UserMsg, "%s", buf);
1970
sewardj04b91062002-06-05 21:22:04 +00001971 for (i = 1; i < stop_at && ec->eips[i] != 0; i++) {
njn4f9c9342002-04-29 16:03:24 +00001972 know_fnname = VG_(what_fn_is_this)(False,ec->eips[i], buf_fn, M_VG_ERRTXT);
sewardjde4a1d02002-03-22 01:27:54 +00001973 know_objname = vg_what_object_is_this(ec->eips[i],buf_obj, M_VG_ERRTXT);
njn4f9c9342002-04-29 16:03:24 +00001974 know_srcloc = VG_(what_line_is_this)(ec->eips[i],
sewardjde4a1d02002-03-22 01:27:54 +00001975 buf_srcloc, M_VG_ERRTXT,
1976 &lineno);
1977 n = 0;
1978 APPEND(" by ");
sewardj04b91062002-06-05 21:22:04 +00001979 VG_(sprintf)(ibuf,"0x%x: ",ec->eips[i]);
1980 APPEND(ibuf);
sewardjde4a1d02002-03-22 01:27:54 +00001981 if (know_fnname) {
1982 APPEND(buf_fn)
1983 if (!know_srcloc && know_objname) {
1984 APPEND(" (in ");
1985 APPEND(buf_obj);
1986 APPEND(")");
1987 }
1988 } else {
1989 if (know_objname && !know_srcloc) {
1990 APPEND("(within ");
1991 APPEND(buf_obj);
1992 APPEND(")");
1993 } else {
1994 APPEND("???");
1995 }
sewardjde4a1d02002-03-22 01:27:54 +00001996 };
1997 if (know_srcloc) {
1998 APPEND(" (");
1999 APPEND(buf_srcloc);
2000 APPEND(":");
2001 VG_(sprintf)(ibuf,"%d",lineno);
2002 APPEND(ibuf);
2003 APPEND(")");
2004 }
2005 VG_(message)(Vg_UserMsg, "%s", buf);
2006 }
2007}
2008
2009#undef APPEND
2010
2011/*--------------------------------------------------------------------*/
2012/*--- end vg_symtab2.c ---*/
2013/*--------------------------------------------------------------------*/