1 /* -*- mode: C; c-basic-offset: 3; -*- */
2
3 /*--------------------------------------------------------------------*/
4 /*--- Top level management of symbols and debugging information. ---*/
5 /*--- debuginfo.c ---*/
6 /*--------------------------------------------------------------------*/
7
8 /*
9 This file is part of Valgrind, a dynamic binary instrumentation
10 framework.
11
12 Copyright (C) 2000-2013 Julian Seward
13 jseward@acm.org
14
15 This program is free software; you can redistribute it and/or
16 modify it under the terms of the GNU General Public License as
17 published by the Free Software Foundation; either version 2 of the
18 License, or (at your option) any later version.
19
20 This program is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 02111-1307, USA.
29
30 The GNU General Public License is contained in the file COPYING.
31 */
32
33 #include "pub_core_basics.h"
34 #include "pub_core_vki.h"
35 #include "pub_core_threadstate.h"
36 #include "pub_core_debuginfo.h" /* self */
37 #include "pub_core_demangle.h"
38 #include "pub_core_libcbase.h"
39 #include "pub_core_libcassert.h"
40 #include "pub_core_libcprint.h"
41 #include "pub_core_libcfile.h"
42 #include "pub_core_libcproc.h" // VG_(getenv)
43 #include "pub_core_seqmatch.h"
44 #include "pub_core_options.h"
45 #include "pub_core_redir.h" // VG_(redir_notify_{new,delete}_SegInfo)
46 #include "pub_core_aspacemgr.h"
47 #include "pub_core_machine.h" // VG_PLAT_USES_PPCTOC
48 #include "pub_core_xarray.h"
49 #include "pub_core_oset.h"
50 #include "pub_core_stacktrace.h" // VG_(get_StackTrace) XXX: circular dependency
51 #include "pub_core_ume.h"
52
53 #include "priv_misc.h" /* dinfo_zalloc/free */
54 #include "priv_image.h"
55 #include "priv_d3basics.h" /* ML_(pp_GX) */
56 #include "priv_tytypes.h"
57 #include "priv_storage.h"
58 #include "priv_readdwarf.h"
59 #if defined(VGO_linux)
60 # include "priv_readelf.h"
61 # include "priv_readdwarf3.h"
62 # include "priv_readpdb.h"
63 #elif defined(VGO_darwin)
64 # include "priv_readmacho.h"
65 # include "priv_readpdb.h"
66 #endif
67
68
69 /* Set this to 1 to enable debug printing for the
70 should-we-load-debuginfo-now? finite state machine. */
71 #define DEBUG_FSM 0
72
73
74 /*------------------------------------------------------------*/
75 /*--- The _svma / _avma / _image / _bias naming scheme ---*/
76 /*------------------------------------------------------------*/
77
78 /* JRS 11 Jan 07: I find the different kinds of addresses involved in
79 debuginfo reading confusing. Recently I arrived at some
80 terminology which makes it clearer (to me, at least). There are 3
81 kinds of address used in the debuginfo reading process:
82
83 stated VMAs - the address where (eg) a .so says a symbol is, that
84 is, what it tells you if you consider the .so in
85 isolation
86
87 actual VMAs - the address where (eg) said symbol really wound up
88 after the .so was mapped into memory
89
90 image addresses - pointers into the copy of the .so (etc)
91 transiently mmaped aboard whilst we read its info
92
93 Additionally I use the term 'bias' to denote the difference
94 between stated and actual VMAs for a given entity.
95
96 This terminology is not used consistently, but a start has been
97 made. readelf.c and the call-frame info reader in readdwarf.c now
98 use it. Specifically, various variables and structure fields have
99 been annotated with _avma / _svma / _image / _bias. In places _img
100 is used instead of _image for the sake of brevity.
101 */
102
103
104 /*------------------------------------------------------------*/
105 /*--- fwdses ---*/
106 /*------------------------------------------------------------*/
107
108 static UInt CF_info_generation = 0;
109 static void cfsi_m_cache__invalidate ( void );
110
111
112 /*------------------------------------------------------------*/
113 /*--- Root structure ---*/
114 /*------------------------------------------------------------*/
115
116 /* The root structure for the entire debug info system. It is a
117 linked list of DebugInfos. */
118 static DebugInfo* debugInfo_list = NULL;
119
120
121 /* Find 'di' in the debugInfo_list and move it one step closer the the
122 front of the list, so as to make subsequent searches for it
123 cheaper. When used in a controlled way, makes a major improvement
124 in some DebugInfo-search-intensive situations, most notably stack
125 unwinding on amd64-linux. */
move_DebugInfo_one_step_forward(DebugInfo * di)126 static void move_DebugInfo_one_step_forward ( DebugInfo* di )
127 {
128 DebugInfo *di0, *di1, *di2;
129 if (di == debugInfo_list)
130 return; /* already at head of list */
131 vg_assert(di != NULL);
132 di0 = debugInfo_list;
133 di1 = NULL;
134 di2 = NULL;
135 while (True) {
136 if (di0 == NULL || di0 == di) break;
137 di2 = di1;
138 di1 = di0;
139 di0 = di0->next;
140 }
141 vg_assert(di0 == di);
142 if (di0 != NULL && di1 != NULL && di2 != NULL) {
143 DebugInfo* tmp;
144 /* di0 points to di, di1 to its predecessor, and di2 to di1's
145 predecessor. Swap di0 and di1, that is, move di0 one step
146 closer to the start of the list. */
147 vg_assert(di2->next == di1);
148 vg_assert(di1->next == di0);
149 tmp = di0->next;
150 di2->next = di0;
151 di0->next = di1;
152 di1->next = tmp;
153 }
154 else
155 if (di0 != NULL && di1 != NULL && di2 == NULL) {
156 /* it's second in the list. */
157 vg_assert(debugInfo_list == di1);
158 vg_assert(di1->next == di0);
159 di1->next = di0->next;
160 di0->next = di1;
161 debugInfo_list = di0;
162 }
163 }
164
165
166 /*------------------------------------------------------------*/
167 /*--- Notification (acquire/discard) helpers ---*/
168 /*------------------------------------------------------------*/
169
170 /* Gives out unique abstract handles for allocated DebugInfos. See
171 comment in priv_storage.h, declaration of struct _DebugInfo, for
172 details. */
173 static ULong handle_counter = 1;
174
175 /* Allocate and zero out a new DebugInfo record. */
176 static
alloc_DebugInfo(const HChar * filename)177 DebugInfo* alloc_DebugInfo( const HChar* filename )
178 {
179 Bool traceme;
180 DebugInfo* di;
181
182 vg_assert(filename);
183
184 di = ML_(dinfo_zalloc)("di.debuginfo.aDI.1", sizeof(DebugInfo));
185 di->handle = handle_counter++;
186 di->fsm.filename = ML_(dinfo_strdup)("di.debuginfo.aDI.2", filename);
187 di->fsm.maps = VG_(newXA)(
188 ML_(dinfo_zalloc), "di.debuginfo.aDI.3",
189 ML_(dinfo_free), sizeof(DebugInfoMapping));
190
191 /* Everything else -- pointers, sizes, arrays -- is zeroed by
192 ML_(dinfo_zalloc). Now set up the debugging-output flags. */
193 traceme
194 = VG_(string_match)( VG_(clo_trace_symtab_patt), filename );
195 if (traceme) {
196 di->trace_symtab = VG_(clo_trace_symtab);
197 di->trace_cfi = VG_(clo_trace_cfi);
198 di->ddump_syms = VG_(clo_debug_dump_syms);
199 di->ddump_line = VG_(clo_debug_dump_line);
200 di->ddump_frames = VG_(clo_debug_dump_frames);
201 }
202
203 return di;
204 }
205
206
207 /* Free a DebugInfo, and also all the stuff hanging off it. */
free_DebugInfo(DebugInfo * di)208 static void free_DebugInfo ( DebugInfo* di )
209 {
210 Word i, j, n;
211 TyEnt* ent;
212 GExpr* gexpr;
213
214 vg_assert(di != NULL);
215 if (di->fsm.maps) VG_(deleteXA)(di->fsm.maps);
216 if (di->fsm.filename) ML_(dinfo_free)(di->fsm.filename);
217 if (di->fsm.dbgname) ML_(dinfo_free)(di->fsm.dbgname);
218 if (di->soname) ML_(dinfo_free)(di->soname);
219 if (di->loctab) ML_(dinfo_free)(di->loctab);
220 if (di->loctab_fndn_ix) ML_(dinfo_free)(di->loctab_fndn_ix);
221 if (di->inltab) ML_(dinfo_free)(di->inltab);
222 if (di->cfsi_base) ML_(dinfo_free)(di->cfsi_base);
223 if (di->cfsi_m_ix) ML_(dinfo_free)(di->cfsi_m_ix);
224 if (di->cfsi_rd) ML_(dinfo_free)(di->cfsi_rd);
225 if (di->cfsi_m_pool) VG_(deleteDedupPA)(di->cfsi_m_pool);
226 if (di->cfsi_exprs) VG_(deleteXA)(di->cfsi_exprs);
227 if (di->fpo) ML_(dinfo_free)(di->fpo);
228
229 if (di->symtab) {
230 /* We have to visit all the entries so as to free up any
231 sec_names arrays that might exist. */
232 n = di->symtab_used;
233 for (i = 0; i < n; i++) {
234 DiSym* sym = &di->symtab[i];
235 if (sym->sec_names)
236 ML_(dinfo_free)(sym->sec_names);
237 }
238 /* and finally .. */
239 ML_(dinfo_free)(di->symtab);
240 }
241
242 if (di->strpool)
243 VG_(deleteDedupPA) (di->strpool);
244 if (di->fndnpool)
245 VG_(deleteDedupPA) (di->fndnpool);
246
247 /* Delete the two admin arrays. These lists exist primarily so
248 that we can visit each object exactly once when we need to
249 delete them. */
250 if (di->admin_tyents) {
251 n = VG_(sizeXA)(di->admin_tyents);
252 for (i = 0; i < n; i++) {
253 ent = (TyEnt*)VG_(indexXA)(di->admin_tyents, i);
254 /* Dump anything hanging off this ent */
255 ML_(TyEnt__make_EMPTY)(ent);
256 }
257 VG_(deleteXA)(di->admin_tyents);
258 di->admin_tyents = NULL;
259 }
260
261 if (di->admin_gexprs) {
262 n = VG_(sizeXA)(di->admin_gexprs);
263 for (i = 0; i < n; i++) {
264 gexpr = *(GExpr**)VG_(indexXA)(di->admin_gexprs, i);
265 ML_(dinfo_free)(gexpr);
266 }
267 VG_(deleteXA)(di->admin_gexprs);
268 di->admin_gexprs = NULL;
269 }
270
271 /* Dump the variable info. This is kinda complex: we must take
272 care not to free items which reside in either the admin lists
273 (as we have just freed them) or which reside in the DebugInfo's
274 string table. */
275 if (di->varinfo) {
276 for (i = 0; i < VG_(sizeXA)(di->varinfo); i++) {
277 OSet* scope = *(OSet**)VG_(indexXA)(di->varinfo, i);
278 if (!scope) continue;
279 /* iterate over all entries in 'scope' */
280 VG_(OSetGen_ResetIter)(scope);
281 while (True) {
282 DiAddrRange* arange = VG_(OSetGen_Next)(scope);
283 if (!arange) break;
284 /* for each var in 'arange' */
285 vg_assert(arange->vars);
286 for (j = 0; j < VG_(sizeXA)( arange->vars ); j++) {
287 DiVariable* var = (DiVariable*)VG_(indexXA)(arange->vars,j);
288 vg_assert(var);
289 /* Nothing to free in var: all the pointer fields refer
290 to stuff either on an admin list, or in
291 .strpool */
292 }
293 VG_(deleteXA)(arange->vars);
294 /* Don't free arange itself, as OSetGen_Destroy does
295 that */
296 }
297 VG_(OSetGen_Destroy)(scope);
298 }
299 VG_(deleteXA)(di->varinfo);
300 }
301
302 ML_(dinfo_free)(di);
303 }
304
305
306 /* 'si' is a member of debugInfo_list. Find it, remove it from the
307 list, notify m_redir that this has happened, and free all storage
308 reachable from it.
309 */
discard_DebugInfo(DebugInfo * di)310 static void discard_DebugInfo ( DebugInfo* di )
311 {
312 const HChar* reason = "munmap";
313
314 DebugInfo** prev_next_ptr = &debugInfo_list;
315 DebugInfo* curr = debugInfo_list;
316
317 while (curr) {
318 if (curr == di) {
319 /* Found it; remove from list and free it. */
320 if (curr->have_dinfo
321 && (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir)))
322 VG_(message)(Vg_DebugMsg,
323 "Discarding syms at %#lx-%#lx in %s due to %s()\n",
324 di->text_avma,
325 di->text_avma + di->text_size,
326 curr->fsm.filename ? curr->fsm.filename
327 : "???",
328 reason);
329 vg_assert(*prev_next_ptr == curr);
330 *prev_next_ptr = curr->next;
331 if (curr->have_dinfo)
332 VG_(redir_notify_delete_DebugInfo)( curr );
333 free_DebugInfo(curr);
334 return;
335 }
336 prev_next_ptr = &curr->next;
337 curr = curr->next;
338 }
339
340 /* Not found. */
341 }
342
343
344 /* Repeatedly scan debugInfo_list, looking for DebugInfos with text
345 AVMAs intersecting [start,start+length), and call discard_DebugInfo
346 to get rid of them. This modifies the list, hence the multiple
347 iterations. Returns True iff any such DebugInfos were found.
348 */
discard_syms_in_range(Addr start,SizeT length)349 static Bool discard_syms_in_range ( Addr start, SizeT length )
350 {
351 Bool anyFound = False;
352 Bool found;
353 DebugInfo* curr;
354
355 while (True) {
356 found = False;
357
358 curr = debugInfo_list;
359 while (True) {
360 if (curr == NULL)
361 break;
362 if (curr->text_present
363 && curr->text_size > 0
364 && (start+length - 1 < curr->text_avma
365 || curr->text_avma + curr->text_size - 1 < start)) {
366 /* no overlap */
367 } else {
368 found = True;
369 break;
370 }
371 curr = curr->next;
372 }
373
374 if (!found) break;
375 anyFound = True;
376 discard_DebugInfo( curr );
377 }
378
379 return anyFound;
380 }
381
382
383 /* Does [s1,+len1) overlap [s2,+len2) ? Note: does not handle
384 wraparound at the end of the address space -- just asserts in that
385 case. */
ranges_overlap(Addr s1,SizeT len1,Addr s2,SizeT len2)386 static Bool ranges_overlap (Addr s1, SizeT len1, Addr s2, SizeT len2 )
387 {
388 Addr e1, e2;
389 if (len1 == 0 || len2 == 0)
390 return False;
391 e1 = s1 + len1 - 1;
392 e2 = s2 + len2 - 1;
393 /* Assert that we don't have wraparound. If we do it would imply
394 that file sections are getting mapped around the end of the
395 address space, which sounds unlikely. */
396 vg_assert(s1 <= e1);
397 vg_assert(s2 <= e2);
398 if (e1 < s2 || e2 < s1) return False;
399 return True;
400 }
401
402
403 /* Do the basic mappings of the two DebugInfos overlap in any way? */
do_DebugInfos_overlap(const DebugInfo * di1,const DebugInfo * di2)404 static Bool do_DebugInfos_overlap ( const DebugInfo* di1, const DebugInfo* di2 )
405 {
406 Word i, j;
407 vg_assert(di1);
408 vg_assert(di2);
409 for (i = 0; i < VG_(sizeXA)(di1->fsm.maps); i++) {
410 const DebugInfoMapping* map1 = VG_(indexXA)(di1->fsm.maps, i);
411 for (j = 0; j < VG_(sizeXA)(di2->fsm.maps); j++) {
412 const DebugInfoMapping* map2 = VG_(indexXA)(di2->fsm.maps, j);
413 if (ranges_overlap(map1->avma, map1->size, map2->avma, map2->size))
414 return True;
415 }
416 }
417
418 return False;
419 }
420
421
422 /* Discard all elements of debugInfo_list whose .mark bit is set.
423 */
discard_marked_DebugInfos(void)424 static void discard_marked_DebugInfos ( void )
425 {
426 DebugInfo* curr;
427
428 while (True) {
429
430 curr = debugInfo_list;
431 while (True) {
432 if (!curr)
433 break;
434 if (curr->mark)
435 break;
436 curr = curr->next;
437 }
438
439 if (!curr) break;
440 discard_DebugInfo( curr );
441
442 }
443 }
444
445
446 /* Discard any elements of debugInfo_list which overlap with diRef.
447 Clearly diRef must have its mapping information set to something sane. */
discard_DebugInfos_which_overlap_with(DebugInfo * diRef)448 static void discard_DebugInfos_which_overlap_with ( DebugInfo* diRef )
449 {
450 DebugInfo* di;
451 /* Mark all the DebugInfos in debugInfo_list that need to be
452 deleted. First, clear all the mark bits; then set them if they
453 overlap with siRef. Since siRef itself is in this list we at
454 least expect its own mark bit to be set. */
455 for (di = debugInfo_list; di; di = di->next) {
456 di->mark = do_DebugInfos_overlap( di, diRef );
457 if (di == diRef) {
458 vg_assert(di->mark);
459 di->mark = False;
460 }
461 }
462 discard_marked_DebugInfos();
463 }
464
465
466 /* Find the existing DebugInfo for |filename| or if not found, create
467 one. In the latter case |filename| is strdup'd into VG_AR_DINFO,
468 and the new DebugInfo is added to debugInfo_list. */
find_or_create_DebugInfo_for(const HChar * filename)469 static DebugInfo* find_or_create_DebugInfo_for ( const HChar* filename )
470 {
471 DebugInfo* di;
472 vg_assert(filename);
473 for (di = debugInfo_list; di; di = di->next) {
474 vg_assert(di->fsm.filename);
475 if (0==VG_(strcmp)(di->fsm.filename, filename))
476 break;
477 }
478 if (!di) {
479 di = alloc_DebugInfo(filename);
480 vg_assert(di);
481 di->next = debugInfo_list;
482 debugInfo_list = di;
483 }
484 return di;
485 }
486
487
488 /* Debuginfo reading for 'di' has just been successfully completed.
489 Check that the invariants stated in
490 "Comment_on_IMPORTANT_CFSI_REPRESENTATIONAL_INVARIANTS" in
491 priv_storage.h are observed. */
check_CFSI_related_invariants(const DebugInfo * di)492 static void check_CFSI_related_invariants ( const DebugInfo* di )
493 {
494 DebugInfo* di2 = NULL;
495 Bool has_nonempty_rx = False;
496 Bool cfsi_fits = False;
497 Word i, j;
498 vg_assert(di);
499 /* This fn isn't called until after debuginfo for this object has
500 been successfully read. And that shouldn't happen until we have
501 both a r-x and rw- mapping for the object. Hence: */
502 vg_assert(di->fsm.have_rx_map);
503 vg_assert(di->fsm.have_rw_map);
504 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
505 const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
506 /* We are interested in r-x mappings only */
507 if (!map->rx)
508 continue;
509
510 /* degenerate case: r-x section is empty */
511 if (map->size == 0)
512 continue;
513 has_nonempty_rx = True;
514
515 /* normal case: r-x section is nonempty */
516 /* invariant (0) */
517 vg_assert(map->size > 0);
518
519 /* invariant (1) */
520 for (di2 = debugInfo_list; di2; di2 = di2->next) {
521 if (di2 == di)
522 continue;
523 for (j = 0; j < VG_(sizeXA)(di2->fsm.maps); j++) {
524 const DebugInfoMapping* map2 = VG_(indexXA)(di2->fsm.maps, j);
525 if (!map2->rx || map2->size == 0)
526 continue;
527 vg_assert(!ranges_overlap(map->avma, map->size,
528 map2->avma, map2->size));
529 }
530 }
531 di2 = NULL;
532
533 /* invariant (2) */
534 if (di->cfsi_rd) {
535 vg_assert(di->cfsi_minavma <= di->cfsi_maxavma); /* duh! */
536 /* Assume the csfi fits completely into one individual mapping
537 for now. This might need to be improved/reworked later. */
538 if (di->cfsi_minavma >= map->avma &&
539 di->cfsi_maxavma < map->avma + map->size)
540 cfsi_fits = True;
541 }
542 }
543
544 /* degenerate case: all r-x sections are empty */
545 if (!has_nonempty_rx) {
546 vg_assert(di->cfsi_rd == NULL);
547 return;
548 }
549
550 /* invariant (2) - cont. */
551 if (di->cfsi_rd)
552 vg_assert(cfsi_fits);
553
554 /* invariants (3) and (4) */
555 if (di->cfsi_rd) {
556 vg_assert(di->cfsi_used > 0);
557 vg_assert(di->cfsi_size > 0);
558 for (i = 0; i < di->cfsi_used; i++) {
559 DiCfSI* cfsi = &di->cfsi_rd[i];
560 vg_assert(cfsi->len > 0);
561 vg_assert(cfsi->base >= di->cfsi_minavma);
562 vg_assert(cfsi->base + cfsi->len - 1 <= di->cfsi_maxavma);
563 if (i > 0) {
564 DiCfSI* cfsip = &di->cfsi_rd[i-1];
565 vg_assert(cfsip->base + cfsip->len <= cfsi->base);
566 }
567 }
568 } else {
569 vg_assert(di->cfsi_used == 0);
570 vg_assert(di->cfsi_size == 0);
571 }
572 }
573
574
575 /*--------------------------------------------------------------*/
576 /*--- ---*/
577 /*--- TOP LEVEL: INITIALISE THE DEBUGINFO SYSTEM ---*/
578 /*--- ---*/
579 /*--------------------------------------------------------------*/
580
VG_(di_initialise)581 void VG_(di_initialise) ( void )
582 {
583 /* There's actually very little to do here, since everything
584 centers around the DebugInfos in debugInfo_list, they are
585 created and destroyed on demand, and each one is treated more or
586 less independently. */
587 vg_assert(debugInfo_list == NULL);
588
589 /* flush the CFI fast query cache. */
590 cfsi_m_cache__invalidate();
591 }
592
593
594 /*--------------------------------------------------------------*/
595 /*--- ---*/
596 /*--- TOP LEVEL: NOTIFICATION (ACQUIRE/DISCARD INFO) (LINUX) ---*/
597 /*--- ---*/
598 /*--------------------------------------------------------------*/
599
600 #if defined(VGO_linux) || defined(VGO_darwin)
601
602 /* Helper (indirect) for di_notify_ACHIEVE_ACCEPT_STATE */
overlaps_DebugInfoMappings(const DebugInfoMapping * map1,const DebugInfoMapping * map2)603 static Bool overlaps_DebugInfoMappings ( const DebugInfoMapping* map1,
604 const DebugInfoMapping* map2 )
605 {
606 vg_assert(map1 && map2 && map1 != map2);
607 vg_assert(map1->size != 0 && map2->size != 0);
608 if (map1->avma + map1->size <= map2->avma) return False;
609 if (map2->avma + map2->size <= map1->avma) return False;
610 return True;
611 }
612
613
614 /* Helper (indirect) for di_notify_ACHIEVE_ACCEPT_STATE */
show_DebugInfoMappings(const DebugInfo * di,XArray * maps)615 static void show_DebugInfoMappings
616 ( const DebugInfo* di,
617 /*MOD*/XArray* maps /* XArray<DebugInfoMapping> */ )
618 {
619 Word i, n;
620 vg_assert(maps);
621 n = VG_(sizeXA)(maps);
622 for (i = 0; i < n; i++) {
623 const DebugInfoMapping* map = VG_(indexXA)(maps, i);
624 TRACE_SYMTAB(" [%ld] avma 0x%-16llx size %-8lu "
625 "foff %-8lld %s %s %s\n",
626 i, (ULong)map->avma, map->size, (Long)map->foff,
627 map->rx ? "rx" : "--",
628 map->rw ? "rw" : "--",
629 map->ro ? "ro" : "--");
630 }
631 }
632
633
634 /* Helper for di_notify_ACHIEVE_ACCEPT_STATE. This removes overlaps
635 in |maps|, in a fairly weak way, by truncating overlapping ends.
636 This may need to be strengthened in future. Currently it performs
637 a post-fixup check, so as least we can be sure that if this
638 function returns (rather than asserts) that |maps| is overlap
639 free. */
truncate_DebugInfoMapping_overlaps(const DebugInfo * di,XArray * maps)640 static void truncate_DebugInfoMapping_overlaps
641 ( const DebugInfo* di,
642 /*MOD*/XArray* maps /* XArray<DebugInfoMapping> */ )
643 {
644 TRACE_SYMTAB("Un-de-overlapped _DebugInfoMappings:\n");
645 show_DebugInfoMappings(di, maps);
646 TRACE_SYMTAB("\n");
647
648 Word i, j, n;
649 DebugInfoMapping *map_i, *map_j;
650
651 n = VG_(sizeXA)(maps);
652 for (i = 0; i < n; i++) {
653
654 map_i = VG_(indexXA)(maps, i);
655 if (map_i->size == 0)
656 continue; // Hmm, mutancy. Shouldn't happen.
657
658 for (j = i+1; j < n; j++) {
659
660 map_j = VG_(indexXA)(maps, j);
661 if (map_j->size == 0)
662 continue; // Hmm, mutancy. Shouldn't happen.
663
664 /* map_j was observed later than map_i, since the entries are
665 in the XArray in the order in which they were observed.
666 If map_j starts inside map_i, trim map_i's end so it does
667 not overlap map_j. This reflects the reality that when
668 two mmaped areas overlap, the later mmap silently
669 overwrites the earlier mmap's mapping. */
670 if (map_j->avma >= map_i->avma
671 && map_j->avma < map_i->avma + map_i->size) {
672 SizeT map_i_newsize = map_j->avma - map_i->avma;
673 vg_assert(map_i_newsize < map_i->size);
674 map_i->size = map_i_newsize;
675 }
676
677 }
678 }
679
680 TRACE_SYMTAB("De-overlapped DebugInfoMappings:\n");
681 show_DebugInfoMappings(di, maps);
682 TRACE_SYMTAB("\n");
683 TRACE_SYMTAB("Checking that there are no remaining overlaps.\n");
684
685 for (i = 0; i < n; i++) {
686 map_i = VG_(indexXA)(maps, i);
687 if (map_i->size == 0)
688 continue;
689 for (j = i+1; j < n; j++) {
690 map_j = VG_(indexXA)(maps, j);
691 if (map_j->size == 0)
692 continue;
693 Bool overlap
694 = overlaps_DebugInfoMappings( map_i, map_j );
695 /* If the following assert ever fails, it means the de-overlapping
696 scheme above is too weak, and needs improvement. */
697 vg_assert(!overlap);
698 }
699 }
700
701 TRACE_SYMTAB("Check successful.\n");
702 }
703
704
705 /* The debug info system is driven by notifications that a text
706 segment has been mapped in, or unmapped, or when sections change
707 permission. It's all a bit kludgey and basically means watching
708 syscalls, trying to second-guess when the system's dynamic linker
709 is done with mapping in a new object for execution. This is all
710 tracked using the DebugInfoFSM struct for the object. Anyway, once
711 we finally decide we've got to an accept state, this section then
712 will acquire whatever info is available for the corresponding
713 object. This section contains the notification handlers, which
714 update the FSM and determine when an accept state has been reached.
715 */
716
717 /* When the sequence of observations causes a DebugInfoFSM to move
718 into the accept state, call here to actually get the debuginfo read
719 in. Returns a ULong whose purpose is described in comments
720 preceding VG_(di_notify_mmap) just below.
721 */
di_notify_ACHIEVE_ACCEPT_STATE(struct _DebugInfo * di)722 static ULong di_notify_ACHIEVE_ACCEPT_STATE ( struct _DebugInfo* di )
723 {
724 ULong di_handle;
725 Bool ok;
726
727 vg_assert(di->fsm.filename);
728 TRACE_SYMTAB("\n");
729 TRACE_SYMTAB("------ start ELF OBJECT "
730 "-------------------------"
731 "------------------------------\n");
732 TRACE_SYMTAB("------ name = %s\n", di->fsm.filename);
733 TRACE_SYMTAB("\n");
734
735 /* We're going to read symbols and debug info for the avma
736 ranges specified in the _DebugInfoFsm mapping array. First
737 get rid of any other DebugInfos which overlap any of those
738 ranges (to avoid total confusion). */
739 discard_DebugInfos_which_overlap_with( di );
740
741 /* The DebugInfoMappings that now exist in the FSM may involve
742 overlaps. This confuses ML_(read_elf_debug_info), and may cause
743 it to compute wrong biases. So de-overlap them now.
744 See http://bugzilla.mozilla.org/show_bug.cgi?id=788974 */
745 truncate_DebugInfoMapping_overlaps( di, di->fsm.maps );
746
747 /* And acquire new info. */
748 # if defined(VGO_linux)
749 ok = ML_(read_elf_debug_info)( di );
750 # elif defined(VGO_darwin)
751 ok = ML_(read_macho_debug_info)( di );
752 # else
753 # error "unknown OS"
754 # endif
755
756 if (ok) {
757
758 TRACE_SYMTAB("\n------ Canonicalising the "
759 "acquired info ------\n");
760 /* invalidate the CFI unwind cache. */
761 cfsi_m_cache__invalidate();
762 /* prepare read data for use */
763 ML_(canonicaliseTables)( di );
764 /* Check invariants listed in
765 Comment_on_IMPORTANT_REPRESENTATIONAL_INVARIANTS in
766 priv_storage.h. */
767 check_CFSI_related_invariants(di);
768 ML_(finish_CFSI_arrays)(di);
769 /* notify m_redir about it */
770 TRACE_SYMTAB("\n------ Notifying m_redir ------\n");
771 VG_(redir_notify_new_DebugInfo)( di );
772 /* Note that we succeeded */
773 di->have_dinfo = True;
774 vg_assert(di->handle > 0);
775 di_handle = di->handle;
776
777 } else {
778 TRACE_SYMTAB("\n------ ELF reading failed ------\n");
779 /* Something went wrong (eg. bad ELF file). Should we delete
780 this DebugInfo? No - it contains info on the rw/rx
781 mappings, at least. */
782 di_handle = 0;
783 vg_assert(di->have_dinfo == False);
784 }
785
786 TRACE_SYMTAB("\n");
787 TRACE_SYMTAB("------ name = %s\n", di->fsm.filename);
788 TRACE_SYMTAB("------ end ELF OBJECT "
789 "-------------------------"
790 "------------------------------\n");
791 TRACE_SYMTAB("\n");
792
793 return di_handle;
794 }
795
796
797 /* Notify the debuginfo system about a new mapping. This is the way
798 new debug information gets loaded. If allow_SkFileV is True, it
799 will try load debug info if the mapping at 'a' belongs to Valgrind;
800 whereas normally (False) it will not do that. This allows us to
801 carefully control when the thing will read symbols from the
802 Valgrind executable itself.
803
804 If use_fd is not -1, that is used instead of the filename; this
805 avoids perturbing fcntl locks, which are released by simply
806 re-opening and closing the same file (even via different fd!).
807
808 If a call to VG_(di_notify_mmap) causes debug info to be read, then
809 the returned ULong is an abstract handle which can later be used to
810 refer to the debuginfo read as a result of this specific mapping,
811 in later queries to m_debuginfo. In this case the handle value
812 will be one or above. If the returned value is zero, no debug info
813 was read. */
814
VG_(di_notify_mmap)815 ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd )
816 {
817 NSegment const * seg;
818 const HChar* filename;
819 Bool is_rx_map, is_rw_map, is_ro_map;
820 DebugInfo* di;
821 Int actual_fd, oflags;
822 SysRes preadres;
823 HChar buf1k[1024];
824 Bool debug = (DEBUG_FSM != 0);
825 SysRes statres;
826 struct vg_stat statbuf;
827
828 vg_assert(use_fd >= -1);
829
830 /* In short, figure out if this mapping is of interest to us, and
831 if so, try to guess what ld.so is doing and when/if we should
832 read debug info. */
833 seg = VG_(am_find_nsegment)(a);
834 vg_assert(seg);
835
836 if (debug) {
837 VG_(printf)("di_notify_mmap-0:\n");
838 VG_(printf)("di_notify_mmap-1: %#lx-%#lx %c%c%c\n",
839 seg->start, seg->end,
840 seg->hasR ? 'r' : '-',
841 seg->hasW ? 'w' : '-',seg->hasX ? 'x' : '-' );
842 }
843
844 /* guaranteed by aspacemgr-linux.c, sane_NSegment() */
845 vg_assert(seg->end > seg->start);
846
847 /* Ignore non-file mappings */
848 if ( ! (seg->kind == SkFileC
849 || (seg->kind == SkFileV && allow_SkFileV)) )
850 return 0;
851
852 /* If the file doesn't have a name, we're hosed. Give up. */
853 filename = VG_(am_get_filename)( seg );
854 if (!filename)
855 return 0;
856
857 /*
858 * Cannot read from these magic files:
859 * --20208-- WARNING: Serious error when reading debug info
860 * --20208-- When reading debug info from /proc/xen/privcmd:
861 * --20208-- can't read file to inspect ELF header
862 */
863 if (VG_(strncmp)(filename, "/proc/xen/", 10) == 0)
864 return 0;
865
866 if (debug)
867 VG_(printf)("di_notify_mmap-2: %s\n", filename);
868
869 /* Only try to read debug information from regular files. */
870 statres = VG_(stat)(filename, &statbuf);
871
872 /* stat dereferences symlinks, so we don't expect it to succeed and
873 yet produce something that is a symlink. */
874 vg_assert(sr_isError(statres) || ! VKI_S_ISLNK(statbuf.mode));
875
876 /* Don't let the stat call fail silently. Filter out some known
877 sources of noise before complaining, though. */
878 if (sr_isError(statres)) {
879 DebugInfo fake_di;
880 Bool quiet = VG_(strstr)(filename, "/var/run/nscd/") != NULL;
881 if (!quiet && VG_(clo_verbosity) > 1) {
882 VG_(memset)(&fake_di, 0, sizeof(fake_di));
883 fake_di.fsm.filename = ML_(dinfo_strdup)("di.debuginfo.nmm", filename);
884 ML_(symerr)(&fake_di, True, "failed to stat64/stat this file");
885 }
886 return 0;
887 }
888
889 /* Finally, the point of all this stattery: if it's not a regular file,
890 don't try to read debug info from it. */
891 if (! VKI_S_ISREG(statbuf.mode))
892 return 0;
893
894 /* no uses of statbuf below here. */
895
896 /* Now we have to guess if this is a text-like mapping, a data-like
897 mapping, neither or both. The rules are:
898
899 text if: x86-linux r and x
900 other-linux r and x and not w
901
902 data if: x86-linux r and w
903 other-linux r and w and not x
904
905 Background: On x86-linux, objects are typically mapped twice:
906
907 1b8fb000-1b8ff000 r-xp 00000000 08:02 4471477 vgpreload_memcheck.so
908 1b8ff000-1b900000 rw-p 00004000 08:02 4471477 vgpreload_memcheck.so
909
910 whereas ppc32-linux mysteriously does this:
911
912 118a6000-118ad000 r-xp 00000000 08:05 14209428 vgpreload_memcheck.so
913 118ad000-118b6000 ---p 00007000 08:05 14209428 vgpreload_memcheck.so
914 118b6000-118bd000 rwxp 00000000 08:05 14209428 vgpreload_memcheck.so
915
916 The third mapping should not be considered to have executable
917 code in. Therefore a test which works for both is: r and x and
918 NOT w. Reading symbols from the rwx segment -- which overlaps
919 the r-x segment in the file -- causes the redirection mechanism
920 to redirect to addresses in that third segment, which is wrong
921 and causes crashes.
922
923 JRS 28 Dec 05: unfortunately icc 8.1 on x86 has been seen to
924 produce executables with a single rwx segment rather than a
925 (r-x,rw-) pair. That means the rules have to be modified thusly:
926
927 x86-linux: consider if r and x
928 all others: consider if r and x and not w
929
930 2009 Aug 16: apply similar kludge to ppc32-linux.
931 See http://bugs.kde.org/show_bug.cgi?id=190820
932
933 There are two modes on s390x: with and without the noexec kernel
934 parameter. Together with some older kernels, this leads to several
935 variants:
936 executable: r and x
937 data: r and w and x
938 or
939 executable: r and x
940 data: r and w
941 */
942 is_rx_map = False;
943 is_rw_map = False;
944 is_ro_map = False;
945
946 # if defined(VGA_x86) || defined(VGA_ppc32) || defined(VGA_mips32) \
947 || defined(VGA_mips64)
948 is_rx_map = seg->hasR && seg->hasX;
949 is_rw_map = seg->hasR && seg->hasW;
950 # elif defined(VGA_amd64) || defined(VGA_ppc64be) || defined(VGA_ppc64le) \
951 || defined(VGA_arm) || defined(VGA_arm64)
952 is_rx_map = seg->hasR && seg->hasX && !seg->hasW;
953 is_rw_map = seg->hasR && seg->hasW && !seg->hasX;
954 # elif defined(VGP_s390x_linux)
955 is_rx_map = seg->hasR && seg->hasX && !seg->hasW;
956 is_rw_map = seg->hasR && seg->hasW;
957 # elif defined(VGA_tilegx)
958 is_rx_map = seg->hasR && seg->hasX; // && !seg->hasW;
959 is_rw_map = seg->hasR && seg->hasW; // && !seg->hasX;
960 # else
961 # error "Unknown platform"
962 # endif
963
964 # if defined(VGP_x86_darwin) && DARWIN_VERS >= DARWIN_10_7
965 is_ro_map = seg->hasR && !seg->hasW && !seg->hasX;
966 # endif
967
968 if (debug)
969 VG_(printf)("di_notify_mmap-3: "
970 "is_rx_map %d, is_rw_map %d, is_ro_map %d\n",
971 (Int)is_rx_map, (Int)is_rw_map, (Int)is_ro_map);
972
973 /* Ignore mappings with permissions we can't possibly be interested in. */
974 if (!(is_rx_map || is_rw_map || is_ro_map))
975 return 0;
976
977 /* Peer at the first few bytes of the file, to see if it is an ELF */
978 /* object file. Ignore the file if we do not have read permission. */
979 VG_(memset)(buf1k, 0, sizeof(buf1k));
980 oflags = VKI_O_RDONLY;
981 # if defined(VKI_O_LARGEFILE)
982 oflags |= VKI_O_LARGEFILE;
983 # endif
984
985 if (use_fd == -1) {
986 SysRes fd = VG_(open)( filename, oflags, 0 );
987 if (sr_isError(fd)) {
988 if (sr_Err(fd) != VKI_EACCES) {
989 DebugInfo fake_di;
990 VG_(memset)(&fake_di, 0, sizeof(fake_di));
991 fake_di.fsm.filename = ML_(dinfo_strdup)("di.debuginfo.nmm",
992 filename);
993 ML_(symerr)(&fake_di, True,
994 "can't open file to inspect ELF header");
995 }
996 return 0;
997 }
998 actual_fd = sr_Res(fd);
999 } else {
1000 actual_fd = use_fd;
1001 }
1002
1003 preadres = VG_(pread)( actual_fd, buf1k, sizeof(buf1k), 0 );
1004 if (use_fd == -1) {
1005 VG_(close)( actual_fd );
1006 }
1007
1008 if (sr_isError(preadres)) {
1009 DebugInfo fake_di;
1010 VG_(memset)(&fake_di, 0, sizeof(fake_di));
1011 fake_di.fsm.filename = ML_(dinfo_strdup)("di.debuginfo.nmm", filename);
1012 ML_(symerr)(&fake_di, True, "can't read file to inspect ELF header");
1013 return 0;
1014 }
1015 if (sr_Res(preadres) == 0)
1016 return 0;
1017 vg_assert(sr_Res(preadres) > 0 && sr_Res(preadres) <= sizeof(buf1k) );
1018
1019 /* We're only interested in mappings of object files. */
1020 # if defined(VGO_linux)
1021 if (!ML_(is_elf_object_file)( buf1k, (SizeT)sr_Res(preadres), False ))
1022 return 0;
1023 # elif defined(VGO_darwin)
1024 if (!ML_(is_macho_object_file)( buf1k, (SizeT)sr_Res(preadres) ))
1025 return 0;
1026 # else
1027 # error "unknown OS"
1028 # endif
1029
1030 /* See if we have a DebugInfo for this filename. If not,
1031 create one. */
1032 di = find_or_create_DebugInfo_for( filename );
1033 vg_assert(di);
1034
1035 if (debug)
1036 VG_(printf)("di_notify_mmap-4: "
1037 "noting details in DebugInfo* at %p\n", di);
1038
1039 /* Note the details about the mapping. */
1040 DebugInfoMapping map;
1041 map.avma = a;
1042 map.size = seg->end + 1 - seg->start;
1043 map.foff = seg->offset;
1044 map.rx = is_rx_map;
1045 map.rw = is_rw_map;
1046 map.ro = is_ro_map;
1047 VG_(addToXA)(di->fsm.maps, &map);
1048
1049 /* Update flags about what kind of mappings we've already seen. */
1050 di->fsm.have_rx_map |= is_rx_map;
1051 di->fsm.have_rw_map |= is_rw_map;
1052 di->fsm.have_ro_map |= is_ro_map;
1053
1054 /* So, finally, are we in an accept state? */
1055 if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) {
1056 /* Ok, so, finally, we found what we need, and we haven't
1057 already read debuginfo for this object. So let's do so now.
1058 Yee-ha! */
1059 if (debug)
1060 VG_(printf)("di_notify_mmap-5: "
1061 "achieved accept state for %s\n", filename);
1062 return di_notify_ACHIEVE_ACCEPT_STATE ( di );
1063 } else {
1064 /* If we don't have an rx and rw mapping, or if we already have
1065 debuginfo for this mapping for whatever reason, go no
1066 further. */
1067 return 0;
1068 }
1069 }
1070
1071
1072 /* Unmap is simpler - throw away any SegInfos intersecting
1073 [a, a+len). */
VG_(di_notify_munmap)1074 void VG_(di_notify_munmap)( Addr a, SizeT len )
1075 {
1076 Bool anyFound;
1077 if (0) VG_(printf)("DISCARD %#lx %#lx\n", a, a+len);
1078 anyFound = discard_syms_in_range(a, len);
1079 if (anyFound)
1080 cfsi_m_cache__invalidate();
1081 }
1082
1083
1084 /* Uh, this doesn't do anything at all. IIRC glibc (or ld.so, I don't
1085 remember) does a bunch of mprotects on itself, and if we follow
1086 through here, it causes the debug info for that object to get
1087 discarded. */
VG_(di_notify_mprotect)1088 void VG_(di_notify_mprotect)( Addr a, SizeT len, UInt prot )
1089 {
1090 Bool exe_ok = toBool(prot & VKI_PROT_EXEC);
1091 # if defined(VGA_x86)
1092 exe_ok = exe_ok || toBool(prot & VKI_PROT_READ);
1093 # endif
1094 if (0 && !exe_ok) {
1095 Bool anyFound = discard_syms_in_range(a, len);
1096 if (anyFound)
1097 cfsi_m_cache__invalidate();
1098 }
1099 }
1100
1101
1102 /* This is a MacOSX >= 10.7 32-bit only special. See comments on the
1103 declaration of struct _DebugInfoFSM for details. */
VG_(di_notify_vm_protect)1104 void VG_(di_notify_vm_protect)( Addr a, SizeT len, UInt prot )
1105 {
1106 Bool debug = (DEBUG_FSM != 0);
1107
1108 Bool r_ok = toBool(prot & VKI_PROT_READ);
1109 Bool w_ok = toBool(prot & VKI_PROT_WRITE);
1110 Bool x_ok = toBool(prot & VKI_PROT_EXEC);
1111 if (debug) {
1112 VG_(printf)("di_notify_vm_protect-0:\n");
1113 VG_(printf)("di_notify_vm_protect-1: %#lx-%#lx %c%c%c\n",
1114 a, a + len - 1,
1115 r_ok ? 'r' : '-', w_ok ? 'w' : '-', x_ok ? 'x' : '-' );
1116 }
1117
1118 Bool do_nothing = True;
1119 # if defined(VGP_x86_darwin) && (DARWIN_VERS >= DARWIN_10_7)
1120 do_nothing = False;
1121 # endif
1122 if (do_nothing /* wrong platform */) {
1123 if (debug)
1124 VG_(printf)("di_notify_vm_protect-2: wrong platform, "
1125 "doing nothing.\n");
1126 return;
1127 }
1128
1129 if (! (r_ok && !w_ok && x_ok))
1130 return; /* not an upgrade to r-x */
1131
1132 /* Find a DebugInfo containing a FSM that has [a, +len) previously
1133 observed as a r-- mapping, plus some other rw- mapping. If such
1134 is found, conclude we're in an accept state and read debuginfo
1135 accordingly. */
1136 if (debug)
1137 VG_(printf)("di_notify_vm_protect-3: looking for existing DebugInfo*\n");
1138 DebugInfo* di;
1139 DebugInfoMapping *map = NULL;
1140 Word i;
1141 for (di = debugInfo_list; di; di = di->next) {
1142 vg_assert(di->fsm.filename);
1143 if (di->have_dinfo)
1144 continue; /* already have debuginfo for this object */
1145 if (!di->fsm.have_ro_map)
1146 continue; /* need to have a r-- mapping for this object */
1147 if (di->fsm.have_rx_map)
1148 continue; /* rx- mapping already exists */
1149 if (!di->fsm.have_rw_map)
1150 continue; /* need to have a rw- mapping */
1151 /* Try to find a mapping matching the memory area. */
1152 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1153 map = VG_(indexXA)(di->fsm.maps, i);
1154 if (map->ro && map->avma == a && map->size == len)
1155 break;
1156 map = NULL;
1157 }
1158 if (!map)
1159 continue; /* this isn't an upgrade of an r-- mapping */
1160 /* looks like we're in luck! */
1161 break;
1162 }
1163 if (di == NULL)
1164 return; /* didn't find anything */
1165
1166 if (debug)
1167 VG_(printf)("di_notify_vm_protect-4: found existing DebugInfo* at %p\n",
1168 di);
1169
1170 /* Do the upgrade. Simply update the flags of the mapping
1171 and pretend we never saw the RO map at all. */
1172 vg_assert(di->fsm.have_ro_map);
1173 map->rx = True;
1174 map->ro = False;
1175 di->fsm.have_rx_map = True;
1176 di->fsm.have_ro_map = False;
1177 /* See if there are any more ro mappings */
1178 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1179 map = VG_(indexXA)(di->fsm.maps, i);
1180 if (map->ro) {
1181 di->fsm.have_ro_map = True;
1182 break;
1183 }
1184 }
1185
1186 /* Check if we're now in an accept state and read debuginfo. Finally. */
1187 if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) {
1188 if (debug)
1189 VG_(printf)("di_notify_vm_protect-5: "
1190 "achieved accept state for %s\n", di->fsm.filename);
1191 ULong di_handle __attribute__((unused))
1192 = di_notify_ACHIEVE_ACCEPT_STATE( di );
1193 /* di_handle is ignored. That's not a problem per se -- it just
1194 means nobody will ever be able to refer to this debuginfo by
1195 handle since nobody will know what the handle value is. */
1196 }
1197 }
1198
1199
1200 /*--------- PDB (windows debug info) reading --------- */
1201
1202 /* this should really return ULong, as per VG_(di_notify_mmap). */
VG_(di_notify_pdb_debuginfo)1203 void VG_(di_notify_pdb_debuginfo)( Int fd_obj, Addr avma_obj,
1204 SizeT total_size, PtrdiffT bias_obj )
1205 {
1206 Int i, r, sz_exename;
1207 ULong obj_mtime, pdb_mtime;
1208 HChar* pdbname = NULL;
1209 HChar* dot;
1210 SysRes sres;
1211 Int fd_pdbimage;
1212 SizeT n_pdbimage;
1213 struct vg_stat stat_buf;
1214
1215 if (VG_(clo_verbosity) > 0) {
1216 VG_(message)(Vg_UserMsg, "\n");
1217 VG_(message)(Vg_UserMsg,
1218 "LOAD_PDB_DEBUGINFO: clreq: fd=%d, avma=%#lx, total_size=%lu, "
1219 "bias=%#lx\n",
1220 fd_obj, avma_obj, total_size, bias_obj
1221 );
1222 }
1223
1224 /* 'fd' refers to the .exe/.dll we're dealing with. Get its modification
1225 time into obj_mtime. */
1226 r = VG_(fstat)(fd_obj, &stat_buf);
1227 if (r == -1)
1228 return; /* stat failed ?! */
1229 vg_assert(r == 0);
1230 obj_mtime = stat_buf.mtime;
1231
1232 /* and get its name into exename. */
1233 const HChar *exe;
1234 if (! VG_(resolve_filename)(fd_obj, &exe))
1235 return; /* failed */
1236 sz_exename = VG_(strlen)(exe);
1237 HChar exename[sz_exename + 1];
1238 VG_(strcpy)(exename, exe); // make a copy on the stack
1239
1240 if (VG_(clo_verbosity) > 0) {
1241 VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: objname: %s\n", exename);
1242 }
1243
1244 /* Try to get the PDB file name from the executable. */
1245 pdbname = ML_(find_name_of_pdb_file)(exename);
1246 if (pdbname) {
1247 vg_assert(VG_(strlen)(pdbname) >= 5); /* 5 = strlen("X.pdb") */
1248 /* So we successfully extracted a name from the PE file. But it's
1249 likely to be of the form
1250 e:\foo\bar\xyzzy\wibble.pdb
1251 and we need to change it into something we can actually open
1252 in Wine-world, which basically means turning it into
1253 $HOME/.wine/drive_e/foo/bar/xyzzy/wibble.pdb
1254 We also take into account $WINEPREFIX, if it is set.
1255 For the moment, if the name isn't fully qualified, just forget it
1256 (we'd have to root around to find where the pdb actually is)
1257 */
1258 /* Change all the backslashes to forward slashes */
1259 for (i = 0; pdbname[i]; i++) {
1260 if (pdbname[i] == '\\')
1261 pdbname[i] = '/';
1262 }
1263 Bool is_quald
1264 = ('a' <= VG_(tolower)(pdbname[0]) && VG_(tolower)(pdbname[0]) <= 'z')
1265 && pdbname[1] == ':'
1266 && pdbname[2] == '/';
1267 HChar* home = VG_(getenv)("HOME");
1268 HChar* wpfx = VG_(getenv)("WINEPREFIX");
1269 if (is_quald && wpfx) {
1270 /* Change e:/foo/bar/xyzzy/wibble.pdb
1271 to $WINEPREFIX/drive_e/foo/bar/xyzzy/wibble.pdb
1272 */
1273 Int mashedSzB = VG_(strlen)(pdbname) + VG_(strlen)(wpfx) + 50/*misc*/;
1274 HChar* mashed = ML_(dinfo_zalloc)("di.debuginfo.dnpdi.1", mashedSzB);
1275 VG_(snprintf)(mashed, mashedSzB, "%s/drive_%c%s",
1276 wpfx, pdbname[0], &pdbname[2]);
1277 vg_assert(mashed[mashedSzB-1] == 0);
1278 ML_(dinfo_free)(pdbname);
1279 pdbname = mashed;
1280 }
1281 else if (is_quald && home && !wpfx) {
1282 /* Change e:/foo/bar/xyzzy/wibble.pdb
1283 to $HOME/.wine/drive_e/foo/bar/xyzzy/wibble.pdb
1284 */
1285 Int mashedSzB = VG_(strlen)(pdbname) + VG_(strlen)(home) + 50/*misc*/;
1286 HChar* mashed = ML_(dinfo_zalloc)("di.debuginfo.dnpdi.2", mashedSzB);
1287 VG_(snprintf)(mashed, mashedSzB, "%s/.wine/drive_%c%s",
1288 home, pdbname[0], &pdbname[2]);
1289 vg_assert(mashed[mashedSzB-1] == 0);
1290 ML_(dinfo_free)(pdbname);
1291 pdbname = mashed;
1292 } else {
1293 /* It's not a fully qualified path, or neither $HOME nor $WINE
1294 are set (strange). Give up. */
1295 ML_(dinfo_free)(pdbname);
1296 pdbname = NULL;
1297 }
1298 }
1299
1300 /* Try s/exe/pdb/ if we don't have a valid pdbname. */
1301 if (!pdbname) {
1302 /* Try to find a matching PDB file from which to read debuginfo.
1303 Windows PE files have symbol tables and line number information,
1304 but MSVC doesn't seem to use them. */
1305 /* Why +5 ? Because in the worst case, we could find a dot as the
1306 last character of pdbname, and we'd then put "pdb" right after
1307 it, hence extending it a bit. */
1308 pdbname = ML_(dinfo_zalloc)("di.debuginfo.lpd1", sz_exename+5);
1309 VG_(strcpy)(pdbname, exename);
1310 vg_assert(pdbname[sz_exename+5-1] == 0);
1311 dot = VG_(strrchr)(pdbname, '.');
1312 if (!dot)
1313 goto out; /* there's no dot in the exe's name ?! */
1314 if (dot[1] == 0)
1315 goto out; /* hmm, path ends in "." */
1316
1317 if ('A' <= dot[1] && dot[1] <= 'Z')
1318 VG_(strcpy)(dot, ".PDB");
1319 else
1320 VG_(strcpy)(dot, ".pdb");
1321
1322 vg_assert(pdbname[sz_exename+5-1] == 0);
1323 }
1324
1325 /* See if we can find it, and check it's in-dateness. */
1326 sres = VG_(stat)(pdbname, &stat_buf);
1327 if (sr_isError(sres)) {
1328 VG_(message)(Vg_UserMsg, "Warning: Missing or un-stat-able %s\n",
1329 pdbname);
1330 if (VG_(clo_verbosity) > 0)
1331 VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: missing: %s\n", pdbname);
1332 goto out;
1333 }
1334 pdb_mtime = stat_buf.mtime;
1335
1336 if (obj_mtime > pdb_mtime + 60ULL) {
1337 /* PDB file is older than PE file. Really, the PDB should be
1338 newer than the PE, but that doesn't always seem to be the
1339 case. Allow the PDB to be up to one minute older.
1340 Otherwise, it's probably out of date, in which case ignore it
1341 or we will either (a) print wrong stack traces or more likely
1342 (b) crash.
1343 */
1344 VG_(message)(Vg_UserMsg,
1345 "Warning: %s (mtime = %llu)\n"
1346 " is older than %s (mtime = %llu)\n",
1347 pdbname, pdb_mtime, exename, obj_mtime);
1348 }
1349
1350 sres = VG_(open)(pdbname, VKI_O_RDONLY, 0);
1351 if (sr_isError(sres)) {
1352 VG_(message)(Vg_UserMsg, "Warning: Can't open %s\n", pdbname);
1353 goto out;
1354 }
1355
1356 /* Looks promising; go on to try and read stuff from it. But don't
1357 mmap the file. Instead mmap free space and read the file into
1358 it. This is because files on CIFS filesystems that are mounted
1359 '-o directio' can't be mmap'd, and that mount option is needed
1360 to make CIFS work reliably. (See
1361 http://www.nabble.com/Corrupted-data-on-write-to-
1362 Windows-2003-Server-t2782623.html)
1363 This is slower, but at least it works reliably. */
1364 fd_pdbimage = sr_Res(sres);
1365 n_pdbimage = stat_buf.size;
1366 if (n_pdbimage == 0 || n_pdbimage > 0x7FFFFFFF) {
1367 // 0x7FFFFFFF: why? Because the VG_(read) just below only
1368 // can deal with a signed int as the size of data to read,
1369 // so we can't reliably check for read failure for files
1370 // greater than that size. Hence just skip them; we're
1371 // unlikely to encounter a PDB that large anyway.
1372 VG_(close)(fd_pdbimage);
1373 goto out;
1374 }
1375 sres = VG_(am_mmap_anon_float_valgrind)( n_pdbimage );
1376 if (sr_isError(sres)) {
1377 VG_(close)(fd_pdbimage);
1378 goto out;
1379 }
1380
1381 void* pdbimage = (void*)sr_Res(sres);
1382 r = VG_(read)( fd_pdbimage, pdbimage, (Int)n_pdbimage );
1383 if (r < 0 || r != (Int)n_pdbimage) {
1384 VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage );
1385 VG_(close)(fd_pdbimage);
1386 goto out;
1387 }
1388
1389 if (VG_(clo_verbosity) > 0)
1390 VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: pdbname: %s\n", pdbname);
1391
1392 /* play safe; always invalidate the CFI cache. I don't know if
1393 this is necessary, but anyway .. */
1394 cfsi_m_cache__invalidate();
1395 /* dump old info for this range, if any */
1396 discard_syms_in_range( avma_obj, total_size );
1397
1398 { DebugInfo* di = find_or_create_DebugInfo_for(exename);
1399
1400 /* this di must be new, since we just nuked any old stuff in the range */
1401 vg_assert(di && !di->fsm.have_rx_map && !di->fsm.have_rw_map);
1402 vg_assert(!di->have_dinfo);
1403
1404 /* don't set up any of the di-> fields; let
1405 ML_(read_pdb_debug_info) do it. */
1406 ML_(read_pdb_debug_info)( di, avma_obj, bias_obj,
1407 pdbimage, n_pdbimage, pdbname, pdb_mtime );
1408 // JRS fixme: take notice of return value from read_pdb_debug_info,
1409 // and handle failure
1410 vg_assert(di->have_dinfo); // fails if PDB read failed
1411 VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage );
1412 VG_(close)(fd_pdbimage);
1413
1414 if (VG_(clo_verbosity) > 0) {
1415 VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: done: "
1416 "%lu syms, %lu src locs, %lu fpo recs\n",
1417 di->symtab_used, di->loctab_used, di->fpo_size);
1418 }
1419 }
1420
1421 out:
1422 if (pdbname) ML_(dinfo_free)(pdbname);
1423 }
1424
1425 #endif /* defined(VGO_linux) || defined(VGO_darwin) */
1426
1427
1428 /*------------------------------------------------------------*/
1429 /*--- ---*/
1430 /*--- TOP LEVEL: QUERYING EXISTING DEBUG INFO ---*/
1431 /*--- ---*/
1432 /*------------------------------------------------------------*/
1433
VG_(di_discard_ALL_debuginfo)1434 void VG_(di_discard_ALL_debuginfo)( void )
1435 {
1436 DebugInfo *di, *di2;
1437 di = debugInfo_list;
1438 while (di) {
1439 di2 = di->next;
1440 VG_(printf)("XXX rm %p\n", di);
1441 free_DebugInfo( di );
1442 di = di2;
1443 }
1444 }
1445
1446
ML_(find_rx_mapping)1447 DebugInfoMapping* ML_(find_rx_mapping) ( DebugInfo* di, Addr lo, Addr hi )
1448 {
1449 Word i;
1450 vg_assert(lo <= hi);
1451
1452 /* Optimization: Try to use the last matched rx mapping first */
1453 if ( di->last_rx_map
1454 && lo >= di->last_rx_map->avma
1455 && hi < di->last_rx_map->avma + di->last_rx_map->size)
1456 return di->last_rx_map;
1457
1458 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1459 DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1460 if ( map->rx && map->size > 0
1461 && lo >= map->avma && hi < map->avma + map->size) {
1462 di->last_rx_map = map;
1463 return map;
1464 }
1465 }
1466
1467 return NULL;
1468 }
1469
1470 /*------------------------------------------------------------*/
1471 /*--- Types and functions for inlined IP cursor ---*/
1472 /*------------------------------------------------------------*/
1473 struct _InlIPCursor {
1474 Addr eip; // Cursor used to describe calls at eip.
1475 DebugInfo* di; // DebugInfo describing inlined calls at eip
1476
1477 Word inltab_lopos; // The inlined fn calls covering eip are in
1478 Word inltab_hipos; // di->inltab[inltab_lopos..inltab_hipos].
1479 // Note that not all inlined fn calls in this range
1480 // are necessarily covering eip.
1481
1482 Int curlevel; // Current level to describe.
1483 // 0 means to describe eip itself.
1484 Word cur_inltab; // inltab pos for call inlined at current level.
1485 Word next_inltab; // inltab pos for call inlined at next (towards main)
1486 // level.
1487 };
1488
is_top(const InlIPCursor * iipc)1489 static Bool is_top(const InlIPCursor *iipc)
1490 {
1491 return !iipc || iipc->cur_inltab == -1;
1492 }
1493
is_bottom(const InlIPCursor * iipc)1494 static Bool is_bottom(const InlIPCursor *iipc)
1495 {
1496 return !iipc || iipc->next_inltab == -1;
1497 }
1498
VG_(next_IIPC)1499 Bool VG_(next_IIPC)(InlIPCursor *iipc)
1500 {
1501 Word i;
1502 DiInlLoc *hinl = NULL;
1503 Word hinl_pos = -1;
1504 DebugInfo *di;
1505
1506 if (iipc == NULL)
1507 return False;
1508
1509 if (iipc->curlevel <= 0) {
1510 iipc->curlevel--;
1511 return False;
1512 }
1513
1514 di = iipc->di;
1515 for (i = iipc->inltab_lopos; i <= iipc->inltab_hipos; i++) {
1516 if (di->inltab[i].addr_lo <= iipc->eip
1517 && iipc->eip < di->inltab[i].addr_hi
1518 && di->inltab[i].level < iipc->curlevel
1519 && (!hinl || hinl->level < di->inltab[i].level)) {
1520 hinl = &di->inltab[i];
1521 hinl_pos = i;
1522 }
1523 }
1524
1525 iipc->cur_inltab = iipc->next_inltab;
1526 iipc->next_inltab = hinl_pos;
1527 if (iipc->next_inltab < 0)
1528 iipc->curlevel = 0; // no inlined call anymore, describe eip itself
1529 else
1530 iipc->curlevel = di->inltab[iipc->next_inltab].level;
1531
1532 return True;
1533 }
1534
1535 /* Forward */
1536 static void search_all_loctabs ( Addr ptr, /*OUT*/DebugInfo** pdi,
1537 /*OUT*/Word* locno );
1538
1539 /* Returns the position after which eip would be inserted in inltab.
1540 (-1 if eip should be inserted before position 0).
1541 This is the highest position with an addr_lo <= eip.
1542 As inltab is sorted on addr_lo, dichotomic search can be done
1543 (note that inltab might have duplicates addr_lo). */
inltab_insert_pos(DebugInfo * di,Addr eip)1544 static Word inltab_insert_pos (DebugInfo *di, Addr eip)
1545 {
1546 Word mid,
1547 lo = 0,
1548 hi = di->inltab_used-1;
1549 while (lo <= hi) {
1550 mid = (lo + hi) / 2;
1551 if (eip < di->inltab[mid].addr_lo) { hi = mid-1; continue; }
1552 if (eip > di->inltab[mid].addr_lo) { lo = mid+1; continue; }
1553 lo = mid; break;
1554 }
1555
1556 while (lo <= di->inltab_used-1 && di->inltab[lo].addr_lo <= eip)
1557 lo++;
1558 #if 0
1559 for (mid = 0; mid <= di->inltab_used-1; mid++)
1560 if (eip < di->inltab[mid].addr_lo)
1561 break;
1562 vg_assert (lo - 1 == mid - 1);
1563 #endif
1564 return lo - 1;
1565 }
1566
VG_(new_IIPC)1567 InlIPCursor* VG_(new_IIPC)(Addr eip)
1568 {
1569 DebugInfo* di;
1570 Word locno;
1571 Word i;
1572 InlIPCursor *ret;
1573 Bool avail;
1574
1575 if (!VG_(clo_read_inline_info))
1576 return NULL; // No way we can find inlined calls.
1577
1578 /* Search the DebugInfo for eip */
1579 search_all_loctabs ( eip, &di, &locno );
1580 if (di == NULL || di->inltab_used == 0)
1581 return NULL; // No di (with inltab) containing eip.
1582
1583 /* Search the entry in di->inltab with the highest addr_lo that
1584 contains eip. */
1585 /* We start from the highest pos in inltab after which eip would
1586 be inserted. */
1587 for (i = inltab_insert_pos (di, eip); i >= 0; i--) {
1588 if (di->inltab[i].addr_lo <= eip && eip < di->inltab[i].addr_hi) {
1589 break;
1590 }
1591 /* Stop the backward scan when reaching an addr_lo which
1592 cannot anymore contain eip : we know that all ranges before
1593 i also cannot contain eip. */
1594 if (di->inltab[i].addr_lo < eip - di->maxinl_codesz)
1595 return NULL;
1596 }
1597
1598 if (i < 0)
1599 return NULL; // No entry containing eip.
1600
1601 /* We have found the highest entry containing eip.
1602 Build a cursor. */
1603 ret = ML_(dinfo_zalloc) ("dinfo.new_IIPC", sizeof(*ret));
1604 ret->eip = eip;
1605 ret->di = di;
1606 ret->inltab_hipos = i;
1607 for (i = ret->inltab_hipos - 1; i >= 0; i--) {
1608
1609 if (di->inltab[i].addr_lo < eip - di->maxinl_codesz)
1610 break; /* Similar stop backward scan logic as above. */
1611 }
1612 ret->inltab_lopos = i + 1;
1613 ret->curlevel = MAX_LEVEL;
1614 ret->cur_inltab = -1;
1615 ret->next_inltab = -1;
1616
1617 /* MAX_LEVEL is higher than any stored level. We can use
1618 VG_(next_IIPC) to get to the 'real' first highest call level. */
1619 avail = VG_(next_IIPC) (ret);
1620 vg_assert (avail);
1621
1622 return ret;
1623 }
1624
VG_(delete_IIPC)1625 void VG_(delete_IIPC)(InlIPCursor *iipc)
1626 {
1627 if (iipc)
1628 ML_(dinfo_free)( iipc );
1629 }
1630
1631
1632 /*------------------------------------------------------------*/
1633 /*--- Use of symbol table & location info to create ---*/
1634 /*--- plausible-looking stack dumps. ---*/
1635 /*------------------------------------------------------------*/
1636
1637 /* Search all symtabs that we know about to locate ptr. If found, set
1638 *pdi to the relevant DebugInfo, and *symno to the symtab entry
1639 *number within that. If not found, *psi is set to NULL.
1640 If findText==True, only text symbols are searched for.
1641 If findText==False, only data symbols are searched for.
1642 */
search_all_symtabs(Addr ptr,DebugInfo ** pdi,Word * symno,Bool match_anywhere_in_sym,Bool findText)1643 static void search_all_symtabs ( Addr ptr, /*OUT*/DebugInfo** pdi,
1644 /*OUT*/Word* symno,
1645 Bool match_anywhere_in_sym,
1646 Bool findText )
1647 {
1648 Word sno;
1649 DebugInfo* di;
1650 Bool inRange;
1651
1652 for (di = debugInfo_list; di != NULL; di = di->next) {
1653
1654 if (findText) {
1655 /* Consider any symbol in the r-x mapped area to be text.
1656 See Comment_Regarding_Text_Range_Checks in storage.c for
1657 details. */
1658 inRange = di->fsm.have_rx_map
1659 && (ML_(find_rx_mapping)(di, ptr, ptr) != NULL);
1660 } else {
1661 inRange = (di->data_present
1662 && di->data_size > 0
1663 && di->data_avma <= ptr
1664 && ptr < di->data_avma + di->data_size)
1665 ||
1666 (di->sdata_present
1667 && di->sdata_size > 0
1668 && di->sdata_avma <= ptr
1669 && ptr < di->sdata_avma + di->sdata_size)
1670 ||
1671 (di->bss_present
1672 && di->bss_size > 0
1673 && di->bss_avma <= ptr
1674 && ptr < di->bss_avma + di->bss_size)
1675 ||
1676 (di->sbss_present
1677 && di->sbss_size > 0
1678 && di->sbss_avma <= ptr
1679 && ptr < di->sbss_avma + di->sbss_size)
1680 ||
1681 (di->rodata_present
1682 && di->rodata_size > 0
1683 && di->rodata_avma <= ptr
1684 && ptr < di->rodata_avma + di->rodata_size);
1685 }
1686
1687 if (!inRange) continue;
1688
1689 sno = ML_(search_one_symtab) (
1690 di, ptr, match_anywhere_in_sym, findText );
1691 if (sno == -1) goto not_found;
1692 *symno = sno;
1693 *pdi = di;
1694 return;
1695
1696 }
1697 not_found:
1698 *pdi = NULL;
1699 }
1700
1701
1702 /* Search all loctabs that we know about to locate ptr. If found, set
1703 *pdi to the relevant DebugInfo, and *locno to the loctab entry
1704 *number within that. If not found, *pdi is set to NULL. */
search_all_loctabs(Addr ptr,DebugInfo ** pdi,Word * locno)1705 static void search_all_loctabs ( Addr ptr, /*OUT*/DebugInfo** pdi,
1706 /*OUT*/Word* locno )
1707 {
1708 Word lno;
1709 DebugInfo* di;
1710 for (di = debugInfo_list; di != NULL; di = di->next) {
1711 if (di->text_present
1712 && di->text_size > 0
1713 && di->text_avma <= ptr
1714 && ptr < di->text_avma + di->text_size) {
1715 lno = ML_(search_one_loctab) ( di, ptr );
1716 if (lno == -1) goto not_found;
1717 *locno = lno;
1718 *pdi = di;
1719 return;
1720 }
1721 }
1722 not_found:
1723 *pdi = NULL;
1724 }
1725
1726
1727 /* The whole point of this whole big deal: map a code address to a
1728 plausible symbol name. Returns False if no idea; otherwise True.
1729 Caller supplies buf. If do_cxx_demangling is False, don't do
1730 C++ demangling, regardless of VG_(clo_demangle) -- probably because the
1731 call has come from VG_(get_fnname_raw)(). findText
1732 indicates whether we're looking for a text symbol or a data symbol
1733 -- caller must choose one kind or the other.
1734 Note: the string returned in *BUF is persistent as long as
1735 (1) the DebugInfo it belongs to is not discarded
1736 (2) the segment containing the address is not merged with another segment
1737 (3) the demangler is not invoked again
1738 In other words: if in doubt, save it away.
1739 Also, the returned string is owned by "somebody else". Callers must
1740 not free it or modify it. */
1741 static
get_sym_name(Bool do_cxx_demangling,Bool do_z_demangling,Bool do_below_main_renaming,Addr a,const HChar ** buf,Bool match_anywhere_in_sym,Bool show_offset,Bool findText,PtrdiffT * offsetP)1742 Bool get_sym_name ( Bool do_cxx_demangling, Bool do_z_demangling,
1743 Bool do_below_main_renaming,
1744 Addr a, const HChar** buf,
1745 Bool match_anywhere_in_sym, Bool show_offset,
1746 Bool findText, /*OUT*/PtrdiffT* offsetP )
1747 {
1748 DebugInfo* di;
1749 Word sno;
1750 PtrdiffT offset;
1751
1752 search_all_symtabs ( a, &di, &sno, match_anywhere_in_sym, findText );
1753 if (di == NULL) {
1754 *buf = "";
1755 return False;
1756 }
1757
1758 vg_assert(di->symtab[sno].pri_name);
1759 VG_(demangle) ( do_cxx_demangling, do_z_demangling,
1760 di->symtab[sno].pri_name, buf );
1761
1762 /* Do the below-main hack */
1763 // To reduce the endless nuisance of multiple different names
1764 // for "the frame below main()" screwing up the testsuite, change all
1765 // known incarnations of said into a single name, "(below main)", if
1766 // --show-below-main=yes.
1767 if ( do_below_main_renaming && ! VG_(clo_show_below_main) &&
1768 Vg_FnNameBelowMain == VG_(get_fnname_kind)(*buf) )
1769 {
1770 *buf = "(below main)";
1771 }
1772 offset = a - di->symtab[sno].avmas.main;
1773 if (offsetP) *offsetP = offset;
1774
1775 if (show_offset && offset != 0) {
1776 static HChar *bufwo; // buf with offset
1777 static SizeT bufwo_szB;
1778 SizeT need, len;
1779
1780 len = VG_(strlen)(*buf);
1781 need = len + 1 + 19 + 1;
1782 if (need > bufwo_szB) {
1783 bufwo = ML_(dinfo_realloc)("get_sym_size", bufwo, need);
1784 bufwo_szB = need;
1785 }
1786
1787 VG_(strcpy)(bufwo, *buf);
1788 VG_(sprintf)(bufwo + len, "%c%ld",
1789 offset < 0 ? '-' : '+',
1790 offset < 0 ? -offset : offset);
1791 *buf = bufwo;
1792 }
1793
1794 return True;
1795 }
1796
1797 /* ppc64be-linux only: find the TOC pointer (R2 value) that should be in
1798 force at the entry point address of the function containing
1799 guest_code_addr. Returns 0 if not known. */
VG_(get_tocptr)1800 Addr VG_(get_tocptr) ( Addr guest_code_addr )
1801 {
1802 #if defined(VGA_ppc64be) || defined(VGA_ppc64le)
1803 DebugInfo* si;
1804 Word sno;
1805 search_all_symtabs ( guest_code_addr,
1806 &si, &sno,
1807 True/*match_anywhere_in_fun*/,
1808 True/*consider text symbols only*/ );
1809 if (si == NULL)
1810 return 0;
1811 else
1812 return GET_TOCPTR_AVMA(si->symtab[sno].avmas);
1813 #else
1814 return 0;
1815 #endif
1816 }
1817
1818 /* This is available to tools... always demangle C++ names,
1819 match anywhere in function, but don't show offsets.
1820 NOTE: See important comment about the persistence and memory ownership
1821 of the return string at function get_sym_name */
VG_(get_fnname)1822 Bool VG_(get_fnname) ( Addr a, const HChar** buf )
1823 {
1824 return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True,
1825 /*below-main-renaming*/True,
1826 a, buf,
1827 /*match_anywhere_in_fun*/True,
1828 /*show offset?*/False,
1829 /*text syms only*/True,
1830 /*offsetP*/NULL );
1831 }
1832
1833 /* This is available to tools... always demangle C++ names,
1834 match anywhere in function, and show offset if nonzero.
1835 NOTE: See important comment about the persistence and memory ownership
1836 of the return string at function get_sym_name */
VG_(get_fnname_w_offset)1837 Bool VG_(get_fnname_w_offset) ( Addr a, const HChar** buf )
1838 {
1839 return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True,
1840 /*below-main-renaming*/True,
1841 a, buf,
1842 /*match_anywhere_in_fun*/True,
1843 /*show offset?*/True,
1844 /*text syms only*/True,
1845 /*offsetP*/NULL );
1846 }
1847
1848 /* This is available to tools... always demangle C++ names,
1849 only succeed if 'a' matches first instruction of function,
1850 and don't show offsets.
1851 NOTE: See important comment about the persistence and memory ownership
1852 of the return string at function get_sym_name */
VG_(get_fnname_if_entry)1853 Bool VG_(get_fnname_if_entry) ( Addr a, const HChar** buf )
1854 {
1855 const HChar *tmp;
1856 Bool res;
1857
1858 res = get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True,
1859 /*below-main-renaming*/True,
1860 a, &tmp,
1861 /*match_anywhere_in_fun*/False,
1862 /*show offset?*/False,
1863 /*text syms only*/True,
1864 /*offsetP*/NULL );
1865 if (res)
1866 *buf = tmp;
1867 return res;
1868 }
1869
1870 /* This is only available to core... don't C++-demangle, don't Z-demangle,
1871 don't rename below-main, match anywhere in function, and don't show
1872 offsets.
1873 NOTE: See important comment about the persistence and memory ownership
1874 of the return string at function get_sym_name */
VG_(get_fnname_raw)1875 Bool VG_(get_fnname_raw) ( Addr a, const HChar** buf )
1876 {
1877 return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False,
1878 /*below-main-renaming*/False,
1879 a, buf,
1880 /*match_anywhere_in_fun*/True,
1881 /*show offset?*/False,
1882 /*text syms only*/True,
1883 /*offsetP*/NULL );
1884 }
1885
1886 /* This is only available to core... don't demangle C++ names, but do
1887 do Z-demangling and below-main-renaming, match anywhere in function, and
1888 don't show offsets.
1889 NOTE: See important comment about the persistence and memory ownership
1890 of the return string at function get_sym_name */
VG_(get_fnname_no_cxx_demangle)1891 Bool VG_(get_fnname_no_cxx_demangle) ( Addr a, const HChar** buf,
1892 const InlIPCursor* iipc )
1893 {
1894 if (is_bottom(iipc)) {
1895 // At the bottom (towards main), we describe the fn at eip.
1896 return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/True,
1897 /*below-main-renaming*/True,
1898 a, buf,
1899 /*match_anywhere_in_fun*/True,
1900 /*show offset?*/False,
1901 /*text syms only*/True,
1902 /*offsetP*/NULL );
1903 } else {
1904 const DiInlLoc *next_inl = iipc && iipc->next_inltab >= 0
1905 ? & iipc->di->inltab[iipc->next_inltab]
1906 : NULL;
1907 vg_assert (next_inl);
1908 // The function we are in is called by next_inl.
1909 *buf = next_inl->inlinedfn;
1910 return True;
1911 }
1912 }
1913
1914 /* mips-linux only: find the offset of current address. This is needed for
1915 stack unwinding for MIPS.
1916 */
VG_(get_inst_offset_in_function)1917 Bool VG_(get_inst_offset_in_function)( Addr a,
1918 /*OUT*/PtrdiffT* offset )
1919 {
1920 const HChar *fnname;
1921 return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False,
1922 /*below-main-renaming*/False,
1923 a, &fnname,
1924 /*match_anywhere_in_sym*/True,
1925 /*show offset?*/False,
1926 /*text syms only*/True,
1927 offset );
1928 }
1929
VG_(get_fnname_kind)1930 Vg_FnNameKind VG_(get_fnname_kind) ( const HChar* name )
1931 {
1932 if (VG_STREQ("main", name)) {
1933 return Vg_FnNameMain;
1934
1935 } else if (
1936 # if defined(VGO_linux)
1937 VG_STREQ("__libc_start_main", name) || // glibc glibness
1938 VG_STREQ("generic_start_main", name) || // Yellow Dog doggedness
1939 # elif defined(VGO_darwin)
1940 // See readmacho.c for an explanation of this.
1941 VG_STREQ("start_according_to_valgrind", name) || // Darwin, darling
1942 # else
1943 # error "Unknown OS"
1944 # endif
1945 0) {
1946 return Vg_FnNameBelowMain;
1947
1948 } else {
1949 return Vg_FnNameNormal;
1950 }
1951 }
1952
VG_(get_fnname_kind_from_IP)1953 Vg_FnNameKind VG_(get_fnname_kind_from_IP) ( Addr ip )
1954 {
1955 const HChar *buf;
1956
1957 // We don't demangle, because it's faster not to, and the special names
1958 // we're looking for won't be mangled.
1959 if (VG_(get_fnname_raw) ( ip, &buf )) {
1960
1961 return VG_(get_fnname_kind)(buf);
1962 } else {
1963 return Vg_FnNameNormal; // Don't know the name, treat it as normal.
1964 }
1965 }
1966
1967 /* Looks up data_addr in the collection of data symbols, and if found
1968 puts a pointer to its name into dname. The name is zero terminated.
1969 Also data_addr's offset from the symbol start is put into *offset.
1970 NOTE: See important comment about the persistence and memory ownership
1971 of the return string at function get_sym_name */
VG_(get_datasym_and_offset)1972 Bool VG_(get_datasym_and_offset)( Addr data_addr,
1973 /*OUT*/const HChar** dname,
1974 /*OUT*/PtrdiffT* offset )
1975 {
1976 return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False,
1977 /*below-main-renaming*/False,
1978 data_addr, dname,
1979 /*match_anywhere_in_sym*/True,
1980 /*show offset?*/False,
1981 /*data syms only please*/False,
1982 offset );
1983 }
1984
1985 /* Map a code address to the name of a shared object file or the
1986 executable. Returns False if no idea; otherwise True.
1987 Note: the string returned in *BUF is persistent as long as
1988 (1) the DebugInfo it belongs to is not discarded
1989 (2) the segment containing the address is not merged with another segment
1990 */
VG_(get_objname)1991 Bool VG_(get_objname) ( Addr a, const HChar** buf )
1992 {
1993 DebugInfo* di;
1994 const NSegment *seg;
1995 const HChar* filename;
1996
1997 /* Look in the debugInfo_list to find the name. In most cases we
1998 expect this to produce a result. */
1999 for (di = debugInfo_list; di != NULL; di = di->next) {
2000 if (di->text_present
2001 && di->text_size > 0
2002 && di->text_avma <= a
2003 && a < di->text_avma + di->text_size) {
2004 *buf = di->fsm.filename;
2005 return True;
2006 }
2007 }
2008 /* Last-ditch fallback position: if we don't find the address in
2009 the debugInfo_list, ask the address space manager whether it
2010 knows the name of the file associated with this mapping. This
2011 allows us to print the names of exe/dll files in the stack trace
2012 when running programs under wine. */
2013 if ( (seg = VG_(am_find_nsegment(a))) != NULL
2014 && (filename = VG_(am_get_filename)(seg)) != NULL ) {
2015 *buf = filename;
2016 return True;
2017 }
2018 return False;
2019 }
2020
2021 /* Map a code address to its DebugInfo. Returns NULL if not found. Doesn't
2022 require debug info. */
VG_(find_DebugInfo)2023 DebugInfo* VG_(find_DebugInfo) ( Addr a )
2024 {
2025 static UWord n_search = 0;
2026 DebugInfo* di;
2027 n_search++;
2028 for (di = debugInfo_list; di != NULL; di = di->next) {
2029 if (di->text_present
2030 && di->text_size > 0
2031 && di->text_avma <= a
2032 && a < di->text_avma + di->text_size) {
2033 if (0 == (n_search & 0xF))
2034 move_DebugInfo_one_step_forward( di );
2035 return di;
2036 }
2037 }
2038 return NULL;
2039 }
2040
2041 /* Map a code address to a filename. Returns True if successful. The
2042 returned string is persistent as long as the DebugInfo to which it
2043 belongs is not discarded. */
VG_(get_filename)2044 Bool VG_(get_filename)( Addr a, const HChar** filename )
2045 {
2046 DebugInfo* si;
2047 Word locno;
2048 UInt fndn_ix;
2049
2050 search_all_loctabs ( a, &si, &locno );
2051 if (si == NULL)
2052 return False;
2053 fndn_ix = ML_(fndn_ix) (si, locno);
2054 *filename = ML_(fndn_ix2filename) (si, fndn_ix);
2055 return True;
2056 }
2057
2058 /* Map a code address to a line number. Returns True if successful. */
VG_(get_linenum)2059 Bool VG_(get_linenum)( Addr a, UInt* lineno )
2060 {
2061 DebugInfo* si;
2062 Word locno;
2063 search_all_loctabs ( a, &si, &locno );
2064 if (si == NULL)
2065 return False;
2066 *lineno = si->loctab[locno].lineno;
2067
2068 return True;
2069 }
2070
2071 /* Map a code address to a filename/line number/dir name info.
2072 See prototype for detailed description of behaviour.
2073 */
VG_(get_filename_linenum)2074 Bool VG_(get_filename_linenum) ( Addr a,
2075 /*OUT*/const HChar** filename,
2076 /*OUT*/const HChar** dirname,
2077 /*OUT*/UInt* lineno )
2078 {
2079 DebugInfo* si;
2080 Word locno;
2081 UInt fndn_ix;
2082
2083 search_all_loctabs ( a, &si, &locno );
2084 if (si == NULL) {
2085 if (dirname) {
2086 *dirname = "";
2087 }
2088 *filename = ""; // this used to be not initialised....
2089 return False;
2090 }
2091
2092 fndn_ix = ML_(fndn_ix)(si, locno);
2093 *filename = ML_(fndn_ix2filename) (si, fndn_ix);
2094 *lineno = si->loctab[locno].lineno;
2095
2096 if (dirname) {
2097 /* caller wants directory info too .. */
2098 *dirname = ML_(fndn_ix2dirname) (si, fndn_ix);
2099 }
2100
2101 return True;
2102 }
2103
2104
2105 /* Map a function name to its entry point and toc pointer. Is done by
2106 sequential search of all symbol tables, so is very slow. To
2107 mitigate the worst performance effects, you may specify a soname
2108 pattern, and only objects matching that pattern are searched.
2109 Therefore specify "*" to search all the objects. On TOC-afflicted
2110 platforms, a symbol is deemed to be found only if it has a nonzero
2111 TOC pointer. */
VG_(lookup_symbol_SLOW)2112 Bool VG_(lookup_symbol_SLOW)(const HChar* sopatt, const HChar* name,
2113 SymAVMAs* avmas)
2114 {
2115 Bool require_pToc = False;
2116 Int i;
2117 const DebugInfo* si;
2118 Bool debug = False;
2119 # if defined(VG_PLAT_USES_PPCTOC)
2120 require_pToc = True;
2121 # endif
2122 for (si = debugInfo_list; si; si = si->next) {
2123 if (debug)
2124 VG_(printf)("lookup_symbol_SLOW: considering %s\n", si->soname);
2125 if (!VG_(string_match)(sopatt, si->soname)) {
2126 if (debug)
2127 VG_(printf)(" ... skip\n");
2128 continue;
2129 }
2130 for (i = 0; i < si->symtab_used; i++) {
2131 const HChar* pri_name = si->symtab[i].pri_name;
2132 vg_assert(pri_name);
2133 if (0==VG_(strcmp)(name, pri_name)
2134 && (require_pToc ? GET_TOCPTR_AVMA(si->symtab[i].avmas) : True)) {
2135 *avmas = si->symtab[i].avmas;
2136 return True;
2137 }
2138 const HChar** sec_names = si->symtab[i].sec_names;
2139 if (sec_names) {
2140 vg_assert(sec_names[0]);
2141 while (*sec_names) {
2142 if (0==VG_(strcmp)(name, *sec_names)
2143 && (require_pToc
2144 ? GET_TOCPTR_AVMA(si->symtab[i].avmas) : True)) {
2145 *avmas = si->symtab[i].avmas;
2146 return True;
2147 }
2148 sec_names++;
2149 }
2150 }
2151 }
2152 }
2153 return False;
2154 }
2155
2156
2157 /* VG_(describe_IP): return info on code address, function name and
2158 filename. The returned string is allocated in a static buffer and will
2159 be overwritten in the next invocation. */
2160
2161 /* Copy str into *buf starting at n, ensuring that buf is zero-terminated.
2162 Return the index of the terminating null character. */
2163 static SizeT
putStr(SizeT n,HChar ** buf,SizeT * bufsiz,const HChar * str)2164 putStr( SizeT n, HChar** buf, SizeT *bufsiz, const HChar* str )
2165 {
2166 SizeT slen = VG_(strlen)(str);
2167 SizeT need = n + slen + 1;
2168
2169 if (need > *bufsiz) {
2170 if (need < 256) need = 256;
2171 *bufsiz = need;
2172 *buf = ML_(dinfo_realloc)("putStr", *buf, *bufsiz);
2173 }
2174
2175 VG_(strcpy)(*buf + n, str);
2176
2177 return n + slen;
2178 }
2179
2180 /* Same as putStr, but escaping chars for XML output. */
2181 static SizeT
putStrEsc(SizeT n,HChar ** buf,SizeT * bufsiz,const HChar * str)2182 putStrEsc( SizeT n, HChar** buf, SizeT *bufsiz, const HChar* str )
2183 {
2184 HChar alt[2];
2185
2186 for (; *str != 0; str++) {
2187 switch (*str) {
2188 case '&':
2189 n = putStr( n, buf, bufsiz, "&");
2190 break;
2191 case '<':
2192 n = putStr( n, buf, bufsiz, "<");
2193 break;
2194 case '>':
2195 n = putStr( n, buf, bufsiz, ">");
2196 break;
2197 default:
2198 alt[0] = *str;
2199 alt[1] = 0;
2200 n = putStr( n, buf, bufsiz, alt );
2201 break;
2202 }
2203 }
2204 return n;
2205 }
2206
VG_(describe_IP)2207 const HChar* VG_(describe_IP)(Addr eip, const InlIPCursor *iipc)
2208 {
2209 static HChar *buf = NULL;
2210 static SizeT bufsiz = 0;
2211 # define APPEND(_str) \
2212 n = putStr(n, &buf, &bufsiz, _str)
2213 # define APPEND_ESC(_str) \
2214 n = putStrEsc(n, &buf, &bufsiz, _str)
2215
2216 UInt lineno;
2217 HChar ibuf[50]; // large enough
2218 SizeT n = 0;
2219
2220 vg_assert (!iipc || iipc->eip == eip);
2221
2222 const HChar *buf_fn;
2223 const HChar *buf_obj;
2224 const HChar *buf_srcloc;
2225 const HChar *buf_dirname;
2226
2227 Bool know_dirinfo;
2228 Bool know_fnname;
2229 Bool know_objname;
2230 Bool know_srcloc;
2231
2232 if (is_bottom(iipc)) {
2233 // At the bottom (towards main), we describe the fn at eip.
2234 know_fnname = VG_(clo_sym_offsets)
2235 ? VG_(get_fnname_w_offset) (eip, &buf_fn)
2236 : VG_(get_fnname) (eip, &buf_fn);
2237 } else {
2238 const DiInlLoc *next_inl = iipc && iipc->next_inltab >= 0
2239 ? & iipc->di->inltab[iipc->next_inltab]
2240 : NULL;
2241 vg_assert (next_inl);
2242 // The function we are in is called by next_inl.
2243 buf_fn = next_inl->inlinedfn;
2244 know_fnname = True;
2245
2246 // INLINED????
2247 // ??? Can we compute an offset for an inlined fn call ?
2248 // ??? Offset from what ? The beginning of the inl info ?
2249 // ??? But that is not necessarily the beginning of the fn
2250 // ??? as e.g. an inlined fn call can be in several ranges.
2251 // ??? Currently never showing an offset.
2252 }
2253
2254 know_objname = VG_(get_objname)(eip, &buf_obj);
2255
2256 if (is_top(iipc)) {
2257 // The source for the highest level is in the loctab entry.
2258 know_srcloc = VG_(get_filename_linenum)(
2259 eip,
2260 &buf_srcloc,
2261 &buf_dirname,
2262 &lineno
2263 );
2264 know_dirinfo = buf_dirname[0] != '\0';
2265 } else {
2266 const DiInlLoc *cur_inl = iipc && iipc->cur_inltab >= 0
2267 ? & iipc->di->inltab[iipc->cur_inltab]
2268 : NULL;
2269 vg_assert (cur_inl);
2270
2271 know_dirinfo = False;
2272 buf_dirname = "";
2273 // The fndn_ix and lineno for the caller of the inlined fn is in cur_inl.
2274 if (cur_inl->fndn_ix == 0) {
2275 buf_srcloc = "???";
2276 } else {
2277 FnDn *fndn = VG_(indexEltNumber) (iipc->di->fndnpool,
2278 cur_inl->fndn_ix);
2279 if (fndn->dirname) {
2280 buf_dirname = fndn->dirname;
2281 know_dirinfo = True;
2282 }
2283 buf_srcloc = fndn->filename;
2284 }
2285 lineno = cur_inl->lineno;
2286 know_srcloc = True;
2287 }
2288
2289 if (VG_(clo_xml)) {
2290
2291 Bool human_readable = True;
2292 const HChar* maybe_newline = human_readable ? "\n " : "";
2293 const HChar* maybe_newline2 = human_readable ? "\n " : "";
2294
2295 /* Print in XML format, dumping in as much info as we know.
2296 Ensure all tags are balanced. */
2297 APPEND("<frame>");
2298 VG_(sprintf)(ibuf,"<ip>0x%llX</ip>", (ULong)eip);
2299 APPEND(maybe_newline);
2300 APPEND(ibuf);
2301 if (know_objname) {
2302 APPEND(maybe_newline);
2303 APPEND("<obj>");
2304 APPEND_ESC(buf_obj);
2305 APPEND("</obj>");
2306 }
2307 if (know_fnname) {
2308 APPEND(maybe_newline);
2309 APPEND("<fn>");
2310 APPEND_ESC(buf_fn);
2311 APPEND("</fn>");
2312 }
2313 if (know_srcloc) {
2314 if (know_dirinfo) {
2315 APPEND(maybe_newline);
2316 APPEND("<dir>");
2317 APPEND_ESC(buf_dirname);
2318 APPEND("</dir>");
2319 }
2320 APPEND(maybe_newline);
2321 APPEND("<file>");
2322 APPEND_ESC(buf_srcloc);
2323 APPEND("</file>");
2324 APPEND(maybe_newline);
2325 APPEND("<line>");
2326 VG_(sprintf)(ibuf,"%d",lineno);
2327 APPEND(ibuf);
2328 APPEND("</line>");
2329 }
2330 APPEND(maybe_newline2);
2331 APPEND("</frame>");
2332
2333 } else {
2334
2335 /* Print for humans to read */
2336 //
2337 // Possible forms:
2338 //
2339 // 0x80483BF: really (a.c:20)
2340 // 0x80483BF: really (in /foo/a.out)
2341 // 0x80483BF: really (in ???)
2342 // 0x80483BF: ??? (in /foo/a.out)
2343 // 0x80483BF: ??? (a.c:20)
2344 // 0x80483BF: ???
2345 //
2346 VG_(sprintf)(ibuf,"0x%llX: ", (ULong)eip);
2347 APPEND(ibuf);
2348 if (know_fnname) {
2349 APPEND(buf_fn);
2350 } else {
2351 APPEND("???");
2352 }
2353 if (know_srcloc) {
2354 APPEND(" (");
2355 // Get the directory name, if any, possibly pruned, into dirname.
2356 const HChar* dirname = NULL;
2357 if (know_dirinfo && VG_(sizeXA)(VG_(clo_fullpath_after)) > 0) {
2358 Int i;
2359 dirname = buf_dirname;
2360 // Remove leading prefixes from the dirname.
2361 // If user supplied --fullpath-after=foo, this will remove
2362 // a leading string which matches '.*foo' (not greedy).
2363 for (i = 0; i < VG_(sizeXA)(VG_(clo_fullpath_after)); i++) {
2364 const HChar* prefix =
2365 *(HChar**) VG_(indexXA)( VG_(clo_fullpath_after), i );
2366 HChar* str = VG_(strstr)(dirname, prefix);
2367 if (str) {
2368 dirname = str + VG_(strlen)(prefix);
2369 break;
2370 }
2371 }
2372 /* remove leading "./" */
2373 if (dirname[0] == '.' && dirname[1] == '/')
2374 dirname += 2;
2375 }
2376 // do we have any interesting directory name to show? If so
2377 // add it in.
2378 if (dirname && dirname[0] != 0) {
2379 APPEND(dirname);
2380 APPEND("/");
2381 }
2382 APPEND(buf_srcloc);
2383 APPEND(":");
2384 VG_(sprintf)(ibuf,"%d",lineno);
2385 APPEND(ibuf);
2386 APPEND(")");
2387 } else if (know_objname) {
2388 APPEND(" (in ");
2389 APPEND(buf_obj);
2390 APPEND(")");
2391 } else if (know_fnname) {
2392 // Nb: do this in two steps because "??)" is a trigraph!
2393 APPEND(" (in ???");
2394 APPEND(")");
2395 }
2396
2397 }
2398 return buf;
2399
2400 # undef APPEND
2401 # undef APPEND_ESC
2402 }
2403
2404
2405 /*--------------------------------------------------------------*/
2406 /*--- ---*/
2407 /*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/
2408 /*--- DWARF3 .eh_frame INFO ---*/
2409 /*--- ---*/
2410 /*--------------------------------------------------------------*/
2411
2412 /* Gather up all the constant pieces of info needed to evaluate
2413 a CfiExpr into one convenient struct. */
2414 typedef
2415 struct {
2416 const D3UnwindRegs* uregs;
2417 Addr min_accessible;
2418 Addr max_accessible;
2419 }
2420 CfiExprEvalContext;
2421
2422 /* Evaluate the CfiExpr rooted at ix in exprs given the context eec.
2423 *ok is set to False on failure, but not to True on success. The
2424 caller must set it to True before calling. */
2425 __attribute__((noinline))
2426 static
evalCfiExpr(const XArray * exprs,Int ix,const CfiExprEvalContext * eec,Bool * ok)2427 UWord evalCfiExpr ( const XArray* exprs, Int ix,
2428 const CfiExprEvalContext* eec, Bool* ok )
2429 {
2430 UWord w, wL, wR;
2431 Addr a;
2432 const CfiExpr* e;
2433 vg_assert(sizeof(Addr) == sizeof(UWord));
2434 e = VG_(indexXA)( exprs, ix );
2435 switch (e->tag) {
2436 case Cex_Unop:
2437 w = evalCfiExpr( exprs, e->Cex.Unop.ix, eec, ok );
2438 if (!(*ok)) return 0;
2439 switch (e->Cex.Unop.op) {
2440 case Cunop_Abs: return (Word) w < 0 ? - w : w;
2441 case Cunop_Neg: return - (Word) w;
2442 case Cunop_Not: return ~ w;
2443 default: goto unhandled;
2444 }
2445 /*NOTREACHED*/
2446 case Cex_Binop:
2447 wL = evalCfiExpr( exprs, e->Cex.Binop.ixL, eec, ok );
2448 if (!(*ok)) return 0;
2449 wR = evalCfiExpr( exprs, e->Cex.Binop.ixR, eec, ok );
2450 if (!(*ok)) return 0;
2451 switch (e->Cex.Binop.op) {
2452 case Cbinop_Add: return wL + wR;
2453 case Cbinop_Sub: return wL - wR;
2454 case Cbinop_And: return wL & wR;
2455 case Cbinop_Mul: return wL * wR;
2456 case Cbinop_Shl: return wL << wR;
2457 case Cbinop_Shr: return wL >> wR;
2458 case Cbinop_Eq: return wL == wR ? 1 : 0;
2459 case Cbinop_Ge: return (Word) wL >= (Word) wR ? 1 : 0;
2460 case Cbinop_Gt: return (Word) wL > (Word) wR ? 1 : 0;
2461 case Cbinop_Le: return (Word) wL <= (Word) wR ? 1 : 0;
2462 case Cbinop_Lt: return (Word) wL < (Word) wR ? 1 : 0;
2463 case Cbinop_Ne: return wL != wR ? 1 : 0;
2464 default: goto unhandled;
2465 }
2466 /*NOTREACHED*/
2467 case Cex_CfiReg:
2468 switch (e->Cex.CfiReg.reg) {
2469 # if defined(VGA_x86) || defined(VGA_amd64)
2470 case Creg_IA_IP: return eec->uregs->xip;
2471 case Creg_IA_SP: return eec->uregs->xsp;
2472 case Creg_IA_BP: return eec->uregs->xbp;
2473 # elif defined(VGA_arm)
2474 case Creg_ARM_R15: return eec->uregs->r15;
2475 case Creg_ARM_R14: return eec->uregs->r14;
2476 case Creg_ARM_R13: return eec->uregs->r13;
2477 case Creg_ARM_R12: return eec->uregs->r12;
2478 case Creg_ARM_R7: return eec->uregs->r7;
2479 # elif defined(VGA_s390x)
2480 case Creg_S390_IA: return eec->uregs->ia;
2481 case Creg_S390_SP: return eec->uregs->sp;
2482 case Creg_S390_FP: return eec->uregs->fp;
2483 case Creg_S390_LR: return eec->uregs->lr;
2484 # elif defined(VGA_mips32) || defined(VGA_mips64)
2485 case Creg_IA_IP: return eec->uregs->pc;
2486 case Creg_IA_SP: return eec->uregs->sp;
2487 case Creg_IA_BP: return eec->uregs->fp;
2488 case Creg_MIPS_RA: return eec->uregs->ra;
2489 # elif defined(VGA_ppc32) || defined(VGA_ppc64be) \
2490 || defined(VGA_ppc64le)
2491 # elif defined(VGP_arm64_linux)
2492 case Creg_ARM64_X30: return eec->uregs->x30;
2493 # elif defined(VGA_tilegx)
2494 case Creg_TILEGX_IP: return eec->uregs->pc;
2495 case Creg_TILEGX_SP: return eec->uregs->sp;
2496 case Creg_TILEGX_BP: return eec->uregs->fp;
2497 case Creg_TILEGX_LR: return eec->uregs->lr;
2498 # else
2499 # error "Unsupported arch"
2500 # endif
2501 default: goto unhandled;
2502 }
2503 /*NOTREACHED*/
2504 case Cex_Const:
2505 return e->Cex.Const.con;
2506 case Cex_Deref:
2507 a = evalCfiExpr( exprs, e->Cex.Deref.ixAddr, eec, ok );
2508 if (!(*ok)) return 0;
2509 if (a < eec->min_accessible
2510 || a > eec->max_accessible - sizeof(UWord) + 1) {
2511 *ok = False;
2512 return 0;
2513 }
2514 /* let's hope it doesn't trap! */
2515 return ML_(read_UWord)((void *)a);
2516 default:
2517 goto unhandled;
2518 }
2519 /*NOTREACHED*/
2520 unhandled:
2521 VG_(printf)("\n\nevalCfiExpr: unhandled\n");
2522 ML_(ppCfiExpr)( exprs, ix );
2523 VG_(printf)("\n");
2524 vg_assert(0);
2525 /*NOTREACHED*/
2526 return 0;
2527 }
2528
2529
2530 /* Search all the DebugInfos in the entire system, to find the DiCfSI_m
2531 that pertains to 'ip'.
2532
2533 If found, set *diP to the DebugInfo in which it resides, and
2534 *cfsi_mP to the cfsi_m pointer in that DebugInfo's cfsi_m_pool.
2535
2536 If not found, set *diP to (DebugInfo*)1 and *cfsi_mP to zero.
2537 */
2538 __attribute__((noinline))
find_DiCfSI(DebugInfo ** diP,DiCfSI_m ** cfsi_mP,Addr ip)2539 static void find_DiCfSI ( /*OUT*/DebugInfo** diP,
2540 /*OUT*/DiCfSI_m** cfsi_mP,
2541 Addr ip )
2542 {
2543 DebugInfo* di;
2544 Word i = -1;
2545
2546 static UWord n_search = 0;
2547 static UWord n_steps = 0;
2548 n_search++;
2549
2550 if (0) VG_(printf)("search for %#lx\n", ip);
2551
2552 for (di = debugInfo_list; di != NULL; di = di->next) {
2553 Word j;
2554 n_steps++;
2555
2556 /* Use the per-DebugInfo summary address ranges to skip
2557 inapplicable DebugInfos quickly. */
2558 if (di->cfsi_used == 0)
2559 continue;
2560 if (ip < di->cfsi_minavma || ip > di->cfsi_maxavma)
2561 continue;
2562
2563 /* It might be in this DebugInfo. Search it. */
2564 j = ML_(search_one_cfitab)( di, ip );
2565 vg_assert(j >= -1 && j < (Word)di->cfsi_used);
2566
2567 if (j != -1) {
2568 i = j;
2569 break; /* found it */
2570 }
2571 }
2572
2573 if (i == -1) {
2574
2575 /* we didn't find it. */
2576 *diP = (DebugInfo*)1;
2577 *cfsi_mP = 0;
2578
2579 } else {
2580
2581 /* found a di corresponding to ip. */
2582 /* ensure that di is 4-aligned (at least), so it can't possibly
2583 be equal to (DebugInfo*)1. */
2584 vg_assert(di && VG_IS_4_ALIGNED(di));
2585 *cfsi_mP = ML_(get_cfsi_m) (di, i);
2586 if (*cfsi_mP == NULL) {
2587 // This is a cfsi hole. Report no cfi information found.
2588 *diP = (DebugInfo*)1;
2589 // But we will still perform the hack below.
2590 } else {
2591 *diP = di;
2592 }
2593
2594 /* Start of performance-enhancing hack: once every 64 (chosen
2595 hackily after profiling) successful searches, move the found
2596 DebugInfo one step closer to the start of the list. This
2597 makes future searches cheaper. For starting konqueror on
2598 amd64, this in fact reduces the total amount of searching
2599 done by the above find-the-right-DebugInfo loop by more than
2600 a factor of 20. */
2601 if ((n_search & 0xF) == 0) {
2602 /* Move di one step closer to the start of the list. */
2603 move_DebugInfo_one_step_forward( di );
2604 }
2605 /* End of performance-enhancing hack. */
2606
2607 if (0 && ((n_search & 0x7FFFF) == 0))
2608 VG_(printf)("find_DiCfSI: %lu searches, "
2609 "%lu DebugInfos looked at\n",
2610 n_search, n_steps);
2611
2612 }
2613
2614 }
2615
2616
2617 /* Now follows a mechanism for caching queries to find_DiCfSI, since
2618 they are extremely frequent on amd64-linux, during stack unwinding.
2619
2620 Each cache entry binds an ip value to a (di, cfsi_m*) pair. Possible
2621 values:
2622
2623 di is non-null, cfsi_m* >= 0 ==> cache slot in use, "cfsi_m*"
2624 di is (DebugInfo*)1 ==> cache slot in use, no associated di
2625 di is NULL ==> cache slot not in use
2626
2627 Hence simply zeroing out the entire cache invalidates all
2628 entries.
2629
2630 We can map an ip value directly to a (di, cfsi_m*) pair as
2631 once a DebugInfo is read, adding new DiCfSI_m* is not possible
2632 anymore, as the cfsi_m_pool is frozen once the reading is terminated.
2633 Also, the cache is invalidated when new debuginfo is read due to
2634 an mmap or some debuginfo is discarded due to an munmap. */
2635
2636 // Prime number, giving about 6Kbytes cache on 32 bits,
2637 // 12Kbytes cache on 64 bits.
2638 #define N_CFSI_M_CACHE 509
2639
2640 typedef
2641 struct { Addr ip; DebugInfo* di; DiCfSI_m* cfsi_m; }
2642 CFSI_m_CacheEnt;
2643
2644 static CFSI_m_CacheEnt cfsi_m_cache[N_CFSI_M_CACHE];
2645
cfsi_m_cache__invalidate(void)2646 static void cfsi_m_cache__invalidate ( void ) {
2647 VG_(memset)(&cfsi_m_cache, 0, sizeof(cfsi_m_cache));
2648 CF_info_generation++;
2649 }
2650
VG_(CF_info_generation)2651 UInt VG_(CF_info_generation) (void)
2652 {
2653 return CF_info_generation;
2654 }
2655
cfsi_m_cache__find(Addr ip)2656 static inline CFSI_m_CacheEnt* cfsi_m_cache__find ( Addr ip )
2657 {
2658 UWord hash = ip % N_CFSI_M_CACHE;
2659 CFSI_m_CacheEnt* ce = &cfsi_m_cache[hash];
2660 static UWord n_q = 0, n_m = 0;
2661
2662 n_q++;
2663 if (0 && 0 == (n_q & 0x1FFFFF))
2664 VG_(printf)("QQQ %lu %lu\n", n_q, n_m);
2665
2666 if (LIKELY(ce->ip == ip) && LIKELY(ce->di != NULL)) {
2667 /* found an entry in the cache .. */
2668 } else {
2669 /* not found in cache. Search and update. */
2670 n_m++;
2671 ce->ip = ip;
2672 find_DiCfSI( &ce->di, &ce->cfsi_m, ip );
2673 }
2674
2675 if (UNLIKELY(ce->di == (DebugInfo*)1)) {
2676 /* no DiCfSI for this address */
2677 return NULL;
2678 } else {
2679 /* found a DiCfSI for this address */
2680 return ce;
2681 }
2682 }
2683
2684
2685 inline
compute_cfa(const D3UnwindRegs * uregs,Addr min_accessible,Addr max_accessible,const DebugInfo * di,const DiCfSI_m * cfsi_m)2686 static Addr compute_cfa ( const D3UnwindRegs* uregs,
2687 Addr min_accessible, Addr max_accessible,
2688 const DebugInfo* di, const DiCfSI_m* cfsi_m )
2689 {
2690 CfiExprEvalContext eec;
2691 Addr cfa;
2692 Bool ok;
2693
2694 /* Compute the CFA. */
2695 cfa = 0;
2696 switch (cfsi_m->cfa_how) {
2697 # if defined(VGA_x86) || defined(VGA_amd64)
2698 case CFIC_IA_SPREL:
2699 cfa = cfsi_m->cfa_off + uregs->xsp;
2700 break;
2701 case CFIC_IA_BPREL:
2702 cfa = cfsi_m->cfa_off + uregs->xbp;
2703 break;
2704 # elif defined(VGA_arm)
2705 case CFIC_ARM_R13REL:
2706 cfa = cfsi_m->cfa_off + uregs->r13;
2707 break;
2708 case CFIC_ARM_R12REL:
2709 cfa = cfsi_m->cfa_off + uregs->r12;
2710 break;
2711 case CFIC_ARM_R11REL:
2712 cfa = cfsi_m->cfa_off + uregs->r11;
2713 break;
2714 case CFIC_ARM_R7REL:
2715 cfa = cfsi_m->cfa_off + uregs->r7;
2716 break;
2717 # elif defined(VGA_s390x)
2718 case CFIC_IA_SPREL:
2719 cfa = cfsi_m->cfa_off + uregs->sp;
2720 break;
2721 case CFIR_MEMCFAREL:
2722 {
2723 Addr a = uregs->sp + cfsi_m->cfa_off;
2724 if (a < min_accessible || a > max_accessible-sizeof(Addr))
2725 break;
2726 cfa = ML_(read_Addr)((void *)a);
2727 break;
2728 }
2729 case CFIR_SAME:
2730 cfa = uregs->fp;
2731 break;
2732 case CFIC_IA_BPREL:
2733 cfa = cfsi_m->cfa_off + uregs->fp;
2734 break;
2735 # elif defined(VGA_mips32) || defined(VGA_mips64)
2736 case CFIC_IA_SPREL:
2737 cfa = cfsi_m->cfa_off + uregs->sp;
2738 break;
2739 case CFIR_SAME:
2740 cfa = uregs->fp;
2741 break;
2742 case CFIC_IA_BPREL:
2743 cfa = cfsi_m->cfa_off + uregs->fp;
2744 break;
2745 # elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le)
2746 # elif defined(VGP_arm64_linux)
2747 case CFIC_ARM64_SPREL:
2748 cfa = cfsi_m->cfa_off + uregs->sp;
2749 break;
2750 case CFIC_ARM64_X29REL:
2751 cfa = cfsi_m->cfa_off + uregs->x29;
2752 break;
2753 # elif defined(VGA_tilegx)
2754 case CFIC_IA_SPREL:
2755 cfa = cfsi_m->cfa_off + uregs->sp;
2756 break;
2757 case CFIR_SAME:
2758 cfa = uregs->fp;
2759 break;
2760 case CFIC_IA_BPREL:
2761 cfa = cfsi_m->cfa_off + uregs->fp;
2762 break;
2763 # else
2764 # error "Unsupported arch"
2765 # endif
2766 case CFIC_EXPR: /* available on all archs */
2767 if (0) {
2768 VG_(printf)("CFIC_EXPR: ");
2769 ML_(ppCfiExpr)(di->cfsi_exprs, cfsi_m->cfa_off);
2770 VG_(printf)("\n");
2771 }
2772 eec.uregs = uregs;
2773 eec.min_accessible = min_accessible;
2774 eec.max_accessible = max_accessible;
2775 ok = True;
2776 cfa = evalCfiExpr(di->cfsi_exprs, cfsi_m->cfa_off, &eec, &ok );
2777 if (!ok) return 0;
2778 break;
2779 default:
2780 vg_assert(0);
2781 }
2782 return cfa;
2783 }
2784
2785
2786 /* Get the call frame address (CFA) given an IP/SP/FP triple. */
2787 /* NOTE: This function may rearrange the order of entries in the
2788 DebugInfo list. */
ML_(get_CFA)2789 Addr ML_(get_CFA) ( Addr ip, Addr sp, Addr fp,
2790 Addr min_accessible, Addr max_accessible )
2791 {
2792 CFSI_m_CacheEnt* ce;
2793
2794 ce = cfsi_m_cache__find(ip);
2795
2796 if (UNLIKELY(ce == NULL))
2797 return 0; /* no info. Nothing we can do. */
2798
2799 /* Temporary impedance-matching kludge so that this keeps working
2800 on x86-linux and amd64-linux. */
2801 # if defined(VGA_x86) || defined(VGA_amd64)
2802 { D3UnwindRegs uregs;
2803 uregs.xip = ip;
2804 uregs.xsp = sp;
2805 uregs.xbp = fp;
2806 return compute_cfa(&uregs,
2807 min_accessible, max_accessible, ce->di, ce->cfsi_m);
2808 }
2809 #elif defined(VGA_s390x)
2810 { D3UnwindRegs uregs;
2811 uregs.ia = ip;
2812 uregs.sp = sp;
2813 uregs.fp = fp;
2814 return compute_cfa(&uregs,
2815 min_accessible, max_accessible, ce->di, ce->cfsi_m);
2816 }
2817 #elif defined(VGA_mips32) || defined(VGA_mips64) || defined(VGA_tilegx)
2818 { D3UnwindRegs uregs;
2819 uregs.pc = ip;
2820 uregs.sp = sp;
2821 uregs.fp = fp;
2822 return compute_cfa(&uregs,
2823 min_accessible, max_accessible, ce->di, ce->cfsi_m);
2824 }
2825
2826 # else
2827 return 0; /* indicates failure */
2828 # endif
2829 }
2830
2831
2832 /* The main function for DWARF2/3 CFI-based stack unwinding. Given a
2833 set of registers in UREGS, modify it to hold the register values
2834 for the previous frame, if possible. Returns True if successful.
2835 If not successful, *UREGS is not changed.
2836
2837 For x86 and amd64, the unwound registers are: {E,R}IP,
2838 {E,R}SP, {E,R}BP.
2839
2840 For arm, the unwound registers are: R7 R11 R12 R13 R14 R15.
2841
2842 For arm64, the unwound registers are: X29(FP) X30(LR) SP PC.
2843 */
VG_(use_CF_info)2844 Bool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere,
2845 Addr min_accessible,
2846 Addr max_accessible )
2847 {
2848 DebugInfo* di;
2849 DiCfSI_m* cfsi_m = NULL;
2850 Addr cfa, ipHere = 0;
2851 CFSI_m_CacheEnt* ce;
2852 CfiExprEvalContext eec __attribute__((unused));
2853 D3UnwindRegs uregsPrev;
2854
2855 # if defined(VGA_x86) || defined(VGA_amd64)
2856 ipHere = uregsHere->xip;
2857 # elif defined(VGA_arm)
2858 ipHere = uregsHere->r15;
2859 # elif defined(VGA_s390x)
2860 ipHere = uregsHere->ia;
2861 # elif defined(VGA_mips32) || defined(VGA_mips64)
2862 ipHere = uregsHere->pc;
2863 # elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le)
2864 # elif defined(VGP_arm64_linux)
2865 ipHere = uregsHere->pc;
2866 # elif defined(VGA_tilegx)
2867 ipHere = uregsHere->pc;
2868 # else
2869 # error "Unknown arch"
2870 # endif
2871 ce = cfsi_m_cache__find(ipHere);
2872
2873 if (UNLIKELY(ce == NULL))
2874 return False; /* no info. Nothing we can do. */
2875
2876 di = ce->di;
2877 cfsi_m = ce->cfsi_m;
2878
2879 if (0) {
2880 VG_(printf)("found cfsi_m (but printing fake base/len): ");
2881 ML_(ppDiCfSI)(di->cfsi_exprs, 0, 0, cfsi_m);
2882 }
2883
2884 VG_(bzero_inline)(&uregsPrev, sizeof(uregsPrev));
2885
2886 /* First compute the CFA. */
2887 cfa = compute_cfa(uregsHere,
2888 min_accessible, max_accessible, di, cfsi_m);
2889 if (UNLIKELY(cfa == 0))
2890 return False;
2891
2892 /* Now we know the CFA, use it to roll back the registers we're
2893 interested in. */
2894
2895 # define COMPUTE(_prev, _here, _how, _off) \
2896 do { \
2897 switch (_how) { \
2898 case CFIR_UNKNOWN: \
2899 return False; \
2900 case CFIR_SAME: \
2901 _prev = _here; break; \
2902 case CFIR_MEMCFAREL: { \
2903 Addr a = cfa + (Word)_off; \
2904 if (a < min_accessible \
2905 || a > max_accessible-sizeof(Addr)) \
2906 return False; \
2907 _prev = ML_(read_Addr)((void *)a); \
2908 break; \
2909 } \
2910 case CFIR_CFAREL: \
2911 _prev = cfa + (Word)_off; \
2912 break; \
2913 case CFIR_EXPR: \
2914 if (0) \
2915 ML_(ppCfiExpr)(di->cfsi_exprs,_off); \
2916 eec.uregs = uregsHere; \
2917 eec.min_accessible = min_accessible; \
2918 eec.max_accessible = max_accessible; \
2919 Bool ok = True; \
2920 _prev = evalCfiExpr(di->cfsi_exprs, _off, &eec, &ok ); \
2921 if (!ok) return False; \
2922 break; \
2923 default: \
2924 vg_assert(0); \
2925 } \
2926 } while (0)
2927
2928 # if defined(VGA_x86) || defined(VGA_amd64)
2929 COMPUTE(uregsPrev.xip, uregsHere->xip, cfsi_m->ra_how, cfsi_m->ra_off);
2930 COMPUTE(uregsPrev.xsp, uregsHere->xsp, cfsi_m->sp_how, cfsi_m->sp_off);
2931 COMPUTE(uregsPrev.xbp, uregsHere->xbp, cfsi_m->bp_how, cfsi_m->bp_off);
2932 # elif defined(VGA_arm)
2933 COMPUTE(uregsPrev.r15, uregsHere->r15, cfsi_m->ra_how, cfsi_m->ra_off);
2934 COMPUTE(uregsPrev.r14, uregsHere->r14, cfsi_m->r14_how, cfsi_m->r14_off);
2935 COMPUTE(uregsPrev.r13, uregsHere->r13, cfsi_m->r13_how, cfsi_m->r13_off);
2936 COMPUTE(uregsPrev.r12, uregsHere->r12, cfsi_m->r12_how, cfsi_m->r12_off);
2937 COMPUTE(uregsPrev.r11, uregsHere->r11, cfsi_m->r11_how, cfsi_m->r11_off);
2938 COMPUTE(uregsPrev.r7, uregsHere->r7, cfsi_m->r7_how, cfsi_m->r7_off);
2939 # elif defined(VGA_s390x)
2940 COMPUTE(uregsPrev.ia, uregsHere->ia, cfsi_m->ra_how, cfsi_m->ra_off);
2941 COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off);
2942 COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi_m->fp_how, cfsi_m->fp_off);
2943 # elif defined(VGA_mips32) || defined(VGA_mips64)
2944 COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi_m->ra_how, cfsi_m->ra_off);
2945 COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off);
2946 COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi_m->fp_how, cfsi_m->fp_off);
2947 # elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le)
2948 # elif defined(VGP_arm64_linux)
2949 COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi_m->ra_how, cfsi_m->ra_off);
2950 COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off);
2951 COMPUTE(uregsPrev.x30, uregsHere->x30, cfsi_m->x30_how, cfsi_m->x30_off);
2952 COMPUTE(uregsPrev.x29, uregsHere->x29, cfsi_m->x29_how, cfsi_m->x29_off);
2953 # elif defined(VGA_tilegx)
2954 COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi_m->ra_how, cfsi_m->ra_off);
2955 COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off);
2956 COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi_m->fp_how, cfsi_m->fp_off);
2957 # else
2958 # error "Unknown arch"
2959 # endif
2960
2961 # undef COMPUTE
2962
2963 *uregsHere = uregsPrev;
2964 return True;
2965 }
2966
2967
2968 /*--------------------------------------------------------------*/
2969 /*--- ---*/
2970 /*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/
2971 /*--- MSVC FPO INFO ---*/
2972 /*--- ---*/
2973 /*--------------------------------------------------------------*/
2974
VG_(use_FPO_info)2975 Bool VG_(use_FPO_info) ( /*MOD*/Addr* ipP,
2976 /*MOD*/Addr* spP,
2977 /*MOD*/Addr* fpP,
2978 Addr min_accessible,
2979 Addr max_accessible )
2980 {
2981 Word i;
2982 const DebugInfo* di;
2983 FPO_DATA* fpo = NULL;
2984 Addr spHere;
2985
2986 static UWord n_search = 0;
2987 static UWord n_steps = 0;
2988 n_search++;
2989
2990 if (0) VG_(printf)("search FPO for %#lx\n", *ipP);
2991
2992 for (di = debugInfo_list; di != NULL; di = di->next) {
2993 n_steps++;
2994
2995 /* Use the per-DebugInfo summary address ranges to skip
2996 inapplicable DebugInfos quickly. */
2997 if (di->fpo == NULL)
2998 continue;
2999 if (*ipP < di->fpo_minavma || *ipP > di->fpo_maxavma)
3000 continue;
3001
3002 i = ML_(search_one_fpotab)( di, *ipP );
3003 if (i != -1) {
3004 Word j;
3005 if (0) {
3006 /* debug printing only */
3007 VG_(printf)("look for %#lx size %ld i %ld\n",
3008 *ipP, di->fpo_size, i);
3009 for (j = 0; j < di->fpo_size; j++)
3010 VG_(printf)("[%02ld] %#x %d\n",
3011 j, di->fpo[j].ulOffStart, di->fpo[j].cbProcSize);
3012 }
3013 vg_assert(i >= 0 && i < di->fpo_size);
3014 fpo = &di->fpo[i];
3015 break;
3016 }
3017 }
3018
3019 if (fpo == NULL)
3020 return False;
3021
3022 if (0 && ((n_search & 0x7FFFF) == 0))
3023 VG_(printf)("VG_(use_FPO_info): %lu searches, "
3024 "%lu DebugInfos looked at\n",
3025 n_search, n_steps);
3026
3027
3028 /* Start of performance-enhancing hack: once every 64 (chosen
3029 hackily after profiling) successful searches, move the found
3030 DebugInfo one step closer to the start of the list. This makes
3031 future searches cheaper. For starting konqueror on amd64, this
3032 in fact reduces the total amount of searching done by the above
3033 find-the-right-DebugInfo loop by more than a factor of 20. */
3034 if ((n_search & 0x3F) == 0) {
3035 /* Move si one step closer to the start of the list. */
3036 //move_DebugInfo_one_step_forward( di );
3037 }
3038 /* End of performance-enhancing hack. */
3039
3040 if (0) {
3041 VG_(printf)("found fpo: ");
3042 //ML_(ppFPO)(fpo);
3043 }
3044
3045 /*
3046 Stack layout is:
3047 %esp->
3048 4*.cbRegs {%edi, %esi, %ebp, %ebx}
3049 4*.cdwLocals
3050 return_pc
3051 4*.cdwParams
3052 prior_%esp->
3053
3054 Typical code looks like:
3055 sub $4*.cdwLocals,%esp
3056 Alternative to above for >=4KB (and sometimes for smaller):
3057 mov $size,%eax
3058 call __chkstk # WinNT performs page-by-page probe!
3059 __chkstk is much like alloc(), except that on return
3060 %eax= 5+ &CALL. Thus it could be used as part of
3061 Position Independent Code to locate the Global Offset Table.
3062 push %ebx
3063 push %ebp
3064 push %esi
3065 Other once-only instructions often scheduled >here<.
3066 push %edi
3067
3068 If the pc is within the first .cbProlog bytes of the function,
3069 then you must disassemble to see how many registers have been pushed,
3070 because instructions in the prolog may be scheduled for performance.
3071 The order of PUSH is always %ebx, %ebp, %esi, %edi, with trailing
3072 registers not pushed when .cbRegs < 4. This seems somewhat strange
3073 because %ebp is the register whose usage you want to minimize,
3074 yet it is in the first half of the PUSH list.
3075
3076 I don't know what happens when the compiler constructs an outgoing CALL.
3077 %esp could move if outgoing parameters are PUSHed, and this affects
3078 traceback for errors during the PUSHes. */
3079
3080 spHere = *spP;
3081
3082 *ipP = ML_(read_Addr)((void *)(spHere + 4*(fpo->cbRegs + fpo->cdwLocals)));
3083 *spP = spHere + 4*(fpo->cbRegs + fpo->cdwLocals + 1
3084 + fpo->cdwParams);
3085 *fpP = ML_(read_Addr)((void *)(spHere + 4*2));
3086 return True;
3087 }
3088
3089
3090 /*--------------------------------------------------------------*/
3091 /*--- ---*/
3092 /*--- TOP LEVEL: GENERATE DESCRIPTION OF DATA ADDRESSES ---*/
3093 /*--- FROM DWARF3 DEBUG INFO ---*/
3094 /*--- ---*/
3095 /*--------------------------------------------------------------*/
3096
3097 /* Try to make p2XA(dst, fmt, args..) turn into
3098 VG_(xaprintf)(dst, fmt, args) without having to resort to
3099 vararg macros. As usual with everything to do with varargs, it's
3100 an ugly hack.
3101
3102 //#define p2XA(dstxa, format, args...)
3103 // VG_(xaprintf)(dstxa, format, ##args)
3104 */
3105 #define p2XA VG_(xaprintf)
3106
3107 /* Add a zero-terminating byte to DST, which must be an XArray* of
3108 HChar. */
zterm_XA(XArray * dst)3109 static void zterm_XA ( XArray* dst )
3110 {
3111 HChar zero = 0;
3112 (void) VG_(addBytesToXA)( dst, &zero, 1 );
3113 }
3114
3115
3116 /* Evaluate the location expression/list for var, to see whether or
3117 not data_addr falls within the variable. If so also return the
3118 offset of data_addr from the start of the variable. Note that
3119 regs, which supplies ip,sp,fp values, will be NULL for global
3120 variables, and non-NULL for local variables. */
data_address_is_in_var(PtrdiffT * offset,const XArray * tyents,const DiVariable * var,const RegSummary * regs,Addr data_addr,const DebugInfo * di)3121 static Bool data_address_is_in_var ( /*OUT*/PtrdiffT* offset,
3122 const XArray* /* TyEnt */ tyents,
3123 const DiVariable* var,
3124 const RegSummary* regs,
3125 Addr data_addr,
3126 const DebugInfo* di )
3127 {
3128 MaybeULong mul;
3129 SizeT var_szB;
3130 GXResult res;
3131 Bool show = False;
3132
3133 vg_assert(var->name);
3134 vg_assert(var->gexpr);
3135
3136 /* Figure out how big the variable is. */
3137 mul = ML_(sizeOfType)(tyents, var->typeR);
3138 /* If this var has a type whose size is unknown, zero, or
3139 impossibly large, it should never have been added. ML_(addVar)
3140 should have rejected it. */
3141 vg_assert(mul.b == True);
3142 vg_assert(mul.ul > 0);
3143 if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
3144 /* After this point, we assume we can truncate mul.ul to a host word
3145 safely (without loss of info). */
3146
3147 var_szB = (SizeT)mul.ul; /* NB: truncate to host word */
3148
3149 if (show) {
3150 VG_(printf)("VVVV: data_address_%#lx_is_in_var: %s :: ",
3151 data_addr, var->name );
3152 ML_(pp_TyEnt_C_ishly)( tyents, var->typeR );
3153 VG_(printf)("\n");
3154 }
3155
3156 /* ignore zero-sized vars; they can never match anything. */
3157 if (var_szB == 0) {
3158 if (show)
3159 VG_(printf)("VVVV: -> Fail (variable is zero sized)\n");
3160 return False;
3161 }
3162
3163 res = ML_(evaluate_GX)( var->gexpr, var->fbGX, regs, di );
3164
3165 if (show) {
3166 VG_(printf)("VVVV: -> ");
3167 ML_(pp_GXResult)( res );
3168 VG_(printf)("\n");
3169 }
3170
3171 if (res.kind == GXR_Addr
3172 && res.word <= data_addr
3173 && data_addr < res.word + var_szB) {
3174 *offset = data_addr - res.word;
3175 return True;
3176 } else {
3177 return False;
3178 }
3179 }
3180
3181
3182 /* Format the acquired information into DN(AME)1 and DN(AME)2, which
3183 are XArray*s of HChar, that have been initialised by the caller.
3184 Resulting strings will be zero terminated. Information is
3185 formatted in an understandable way. Not so easy. If frameNo is
3186 -1, this is assumed to be a global variable; else a local
3187 variable. */
format_message(XArray * dn1,XArray * dn2,Addr data_addr,const DebugInfo * di,const DiVariable * var,PtrdiffT var_offset,PtrdiffT residual_offset,const XArray * described,Int frameNo,ThreadId tid)3188 static void format_message ( /*MOD*/XArray* /* of HChar */ dn1,
3189 /*MOD*/XArray* /* of HChar */ dn2,
3190 Addr data_addr,
3191 const DebugInfo* di,
3192 const DiVariable* var,
3193 PtrdiffT var_offset,
3194 PtrdiffT residual_offset,
3195 const XArray* /*HChar*/ described,
3196 Int frameNo,
3197 ThreadId tid )
3198 {
3199 Bool have_descr, have_srcloc;
3200 Bool xml = VG_(clo_xml);
3201 const HChar* vo_plural = var_offset == 1 ? "" : "s";
3202 const HChar* ro_plural = residual_offset == 1 ? "" : "s";
3203 const HChar* basetag = "auxwhat"; /* a constant */
3204 HChar tagL[32], tagR[32], xagL[32], xagR[32];
3205 const HChar *fileName = ML_(fndn_ix2filename)(di, var->fndn_ix);
3206 // fileName will be "???" if var->fndn_ix == 0.
3207 // fileName will only be used if have_descr is True.
3208
3209 if (frameNo < -1) {
3210 vg_assert(0); /* Not allowed */
3211 }
3212 else if (frameNo == -1) {
3213 vg_assert(tid == VG_INVALID_THREADID);
3214 }
3215 else /* (frameNo >= 0) */ {
3216 vg_assert(tid != VG_INVALID_THREADID);
3217 }
3218
3219 vg_assert(dn1 && dn2);
3220 vg_assert(described);
3221 vg_assert(var && var->name);
3222 have_descr = VG_(sizeXA)(described) > 0
3223 && *(HChar*)VG_(indexXA)(described,0) != '\0';
3224 have_srcloc = var->fndn_ix > 0 && var->lineNo > 0;
3225
3226 tagL[0] = tagR[0] = xagL[0] = xagR[0] = 0;
3227 if (xml) {
3228 VG_(sprintf)(tagL, "<%s>", basetag); // <auxwhat>
3229 VG_(sprintf)(tagR, "</%s>", basetag); // </auxwhat>
3230 VG_(sprintf)(xagL, "<x%s>", basetag); // <xauxwhat>
3231 VG_(sprintf)(xagR, "</x%s>", basetag); // </xauxwhat>
3232 }
3233
3234 # define TAGL(_xa) p2XA(_xa, "%s", tagL)
3235 # define TAGR(_xa) p2XA(_xa, "%s", tagR)
3236 # define XAGL(_xa) p2XA(_xa, "%s", xagL)
3237 # define XAGR(_xa) p2XA(_xa, "%s", xagR)
3238 # define TXTL(_xa) p2XA(_xa, "%s", "<text>")
3239 # define TXTR(_xa) p2XA(_xa, "%s", "</text>")
3240
3241 /* ------ local cases ------ */
3242
3243 if ( frameNo >= 0 && (!have_srcloc) && (!have_descr) ) {
3244 /* no srcloc, no description:
3245 Location 0x7fefff6cf is 543 bytes inside local var "a",
3246 in frame #1 of thread 1
3247 */
3248 if (xml) {
3249 TAGL( dn1 );
3250 p2XA( dn1,
3251 "Location 0x%lx is %lu byte%s inside local var \"%pS\",",
3252 data_addr, var_offset, vo_plural, var->name );
3253 TAGR( dn1 );
3254 TAGL( dn2 );
3255 p2XA( dn2,
3256 "in frame #%d of thread %d", frameNo, (Int)tid );
3257 TAGR( dn2 );
3258 } else {
3259 p2XA( dn1,
3260 "Location 0x%lx is %lu byte%s inside local var \"%s\",",
3261 data_addr, var_offset, vo_plural, var->name );
3262 p2XA( dn2,
3263 "in frame #%d of thread %d", frameNo, (Int)tid );
3264 }
3265 }
3266 else
3267 if ( frameNo >= 0 && have_srcloc && (!have_descr) ) {
3268 /* no description:
3269 Location 0x7fefff6cf is 543 bytes inside local var "a"
3270 declared at dsyms7.c:17, in frame #1 of thread 1
3271 */
3272 if (xml) {
3273 TAGL( dn1 );
3274 p2XA( dn1,
3275 "Location 0x%lx is %lu byte%s inside local var \"%pS\"",
3276 data_addr, var_offset, vo_plural, var->name );
3277 TAGR( dn1 );
3278 XAGL( dn2 );
3279 TXTL( dn2 );
3280 p2XA( dn2,
3281 "declared at %pS:%d, in frame #%d of thread %d",
3282 fileName, var->lineNo, frameNo, (Int)tid );
3283 TXTR( dn2 );
3284 // FIXME: also do <dir>
3285 p2XA( dn2,
3286 " <file>%pS</file> <line>%d</line> ",
3287 fileName, var->lineNo );
3288 XAGR( dn2 );
3289 } else {
3290 p2XA( dn1,
3291 "Location 0x%lx is %lu byte%s inside local var \"%s\"",
3292 data_addr, var_offset, vo_plural, var->name );
3293 p2XA( dn2,
3294 "declared at %s:%d, in frame #%d of thread %d",
3295 fileName, var->lineNo, frameNo, (Int)tid );
3296 }
3297 }
3298 else
3299 if ( frameNo >= 0 && (!have_srcloc) && have_descr ) {
3300 /* no srcloc:
3301 Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2
3302 in frame #1 of thread 1
3303 */
3304 if (xml) {
3305 TAGL( dn1 );
3306 p2XA( dn1,
3307 "Location 0x%lx is %lu byte%s inside %pS%pS",
3308 data_addr, residual_offset, ro_plural, var->name,
3309 (HChar*)(VG_(indexXA)(described,0)) );
3310 TAGR( dn1 );
3311 TAGL( dn2 );
3312 p2XA( dn2,
3313 "in frame #%d of thread %d", frameNo, (Int)tid );
3314 TAGR( dn2 );
3315 } else {
3316 p2XA( dn1,
3317 "Location 0x%lx is %lu byte%s inside %s%s",
3318 data_addr, residual_offset, ro_plural, var->name,
3319 (HChar*)(VG_(indexXA)(described,0)) );
3320 p2XA( dn2,
3321 "in frame #%d of thread %d", frameNo, (Int)tid );
3322 }
3323 }
3324 else
3325 if ( frameNo >= 0 && have_srcloc && have_descr ) {
3326 /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
3327 declared at dsyms7.c:17, in frame #1 of thread 1 */
3328 if (xml) {
3329 TAGL( dn1 );
3330 p2XA( dn1,
3331 "Location 0x%lx is %lu byte%s inside %pS%pS,",
3332 data_addr, residual_offset, ro_plural, var->name,
3333 (HChar*)(VG_(indexXA)(described,0)) );
3334 TAGR( dn1 );
3335 XAGL( dn2 );
3336 TXTL( dn2 );
3337 p2XA( dn2,
3338 "declared at %pS:%d, in frame #%d of thread %d",
3339 fileName, var->lineNo, frameNo, (Int)tid );
3340 TXTR( dn2 );
3341 // FIXME: also do <dir>
3342 p2XA( dn2,
3343 " <file>%pS</file> <line>%d</line> ",
3344 fileName, var->lineNo );
3345 XAGR( dn2 );
3346 } else {
3347 p2XA( dn1,
3348 "Location 0x%lx is %lu byte%s inside %s%s,",
3349 data_addr, residual_offset, ro_plural, var->name,
3350 (HChar*)(VG_(indexXA)(described,0)) );
3351 p2XA( dn2,
3352 "declared at %s:%d, in frame #%d of thread %d",
3353 fileName, var->lineNo, frameNo, (Int)tid );
3354 }
3355 }
3356 else
3357 /* ------ global cases ------ */
3358 if ( frameNo >= -1 && (!have_srcloc) && (!have_descr) ) {
3359 /* no srcloc, no description:
3360 Location 0x7fefff6cf is 543 bytes inside global var "a"
3361 */
3362 if (xml) {
3363 TAGL( dn1 );
3364 p2XA( dn1,
3365 "Location 0x%lx is %lu byte%s inside global var \"%pS\"",
3366 data_addr, var_offset, vo_plural, var->name );
3367 TAGR( dn1 );
3368 } else {
3369 p2XA( dn1,
3370 "Location 0x%lx is %lu byte%s inside global var \"%s\"",
3371 data_addr, var_offset, vo_plural, var->name );
3372 }
3373 }
3374 else
3375 if ( frameNo >= -1 && have_srcloc && (!have_descr) ) {
3376 /* no description:
3377 Location 0x7fefff6cf is 543 bytes inside global var "a"
3378 declared at dsyms7.c:17
3379 */
3380 if (xml) {
3381 TAGL( dn1 );
3382 p2XA( dn1,
3383 "Location 0x%lx is %lu byte%s inside global var \"%pS\"",
3384 data_addr, var_offset, vo_plural, var->name );
3385 TAGR( dn1 );
3386 XAGL( dn2 );
3387 TXTL( dn2 );
3388 p2XA( dn2,
3389 "declared at %pS:%d",
3390 fileName, var->lineNo);
3391 TXTR( dn2 );
3392 // FIXME: also do <dir>
3393 p2XA( dn2,
3394 " <file>%pS</file> <line>%d</line> ",
3395 fileName, var->lineNo );
3396 XAGR( dn2 );
3397 } else {
3398 p2XA( dn1,
3399 "Location 0x%lx is %lu byte%s inside global var \"%s\"",
3400 data_addr, var_offset, vo_plural, var->name );
3401 p2XA( dn2,
3402 "declared at %s:%d",
3403 fileName, var->lineNo);
3404 }
3405 }
3406 else
3407 if ( frameNo >= -1 && (!have_srcloc) && have_descr ) {
3408 /* no srcloc:
3409 Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
3410 a global variable
3411 */
3412 if (xml) {
3413 TAGL( dn1 );
3414 p2XA( dn1,
3415 "Location 0x%lx is %lu byte%s inside %pS%pS,",
3416 data_addr, residual_offset, ro_plural, var->name,
3417 (HChar*)(VG_(indexXA)(described,0)) );
3418 TAGR( dn1 );
3419 TAGL( dn2 );
3420 p2XA( dn2,
3421 "a global variable");
3422 TAGR( dn2 );
3423 } else {
3424 p2XA( dn1,
3425 "Location 0x%lx is %lu byte%s inside %s%s,",
3426 data_addr, residual_offset, ro_plural, var->name,
3427 (char*)(VG_(indexXA)(described,0)) );
3428 p2XA( dn2,
3429 "a global variable");
3430 }
3431 }
3432 else
3433 if ( frameNo >= -1 && have_srcloc && have_descr ) {
3434 /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
3435 a global variable declared at dsyms7.c:17 */
3436 if (xml) {
3437 TAGL( dn1 );
3438 p2XA( dn1,
3439 "Location 0x%lx is %lu byte%s inside %pS%pS,",
3440 data_addr, residual_offset, ro_plural, var->name,
3441 (HChar*)(VG_(indexXA)(described,0)) );
3442 TAGR( dn1 );
3443 XAGL( dn2 );
3444 TXTL( dn2 );
3445 p2XA( dn2,
3446 "a global variable declared at %pS:%d",
3447 fileName, var->lineNo);
3448 TXTR( dn2 );
3449 // FIXME: also do <dir>
3450 p2XA( dn2,
3451 " <file>%pS</file> <line>%d</line> ",
3452 fileName, var->lineNo );
3453 XAGR( dn2 );
3454 } else {
3455 p2XA( dn1,
3456 "Location 0x%lx is %lu byte%s inside %s%s,",
3457 data_addr, residual_offset, ro_plural, var->name,
3458 (HChar*)(VG_(indexXA)(described,0)) );
3459 p2XA( dn2,
3460 "a global variable declared at %s:%d",
3461 fileName, var->lineNo);
3462 }
3463 }
3464 else
3465 vg_assert(0);
3466
3467 /* Zero terminate both strings */
3468 zterm_XA( dn1 );
3469 zterm_XA( dn2 );
3470
3471 # undef TAGL
3472 # undef TAGR
3473 # undef XAGL
3474 # undef XAGR
3475 # undef TXTL
3476 # undef TXTR
3477 }
3478
3479
3480 /* Determine if data_addr is a local variable in the frame
3481 characterised by (ip,sp,fp), and if so write its description at the
3482 ends of DNAME{1,2}, which are XArray*s of HChar, that have been
3483 initialised by the caller, zero terminate both, and return True.
3484 If it's not a local variable in said frame, return False. */
3485 static
consider_vars_in_frame(XArray * dname1,XArray * dname2,Addr data_addr,Addr ip,Addr sp,Addr fp,ThreadId tid,Int frameNo)3486 Bool consider_vars_in_frame ( /*MOD*/XArray* /* of HChar */ dname1,
3487 /*MOD*/XArray* /* of HChar */ dname2,
3488 Addr data_addr,
3489 Addr ip, Addr sp, Addr fp,
3490 /* shown to user: */
3491 ThreadId tid, Int frameNo )
3492 {
3493 Word i;
3494 DebugInfo* di;
3495 RegSummary regs;
3496 Bool debug = False;
3497
3498 static UInt n_search = 0;
3499 static UInt n_steps = 0;
3500 n_search++;
3501 if (debug)
3502 VG_(printf)("QQQQ: cvif: ip,sp,fp %#lx,%#lx,%#lx\n", ip,sp,fp);
3503 /* first, find the DebugInfo that pertains to 'ip'. */
3504 for (di = debugInfo_list; di; di = di->next) {
3505 n_steps++;
3506 /* text segment missing? unlikely, but handle it .. */
3507 if (!di->text_present || di->text_size == 0)
3508 continue;
3509 /* Ok. So does this text mapping bracket the ip? */
3510 if (di->text_avma <= ip && ip < di->text_avma + di->text_size)
3511 break;
3512 }
3513
3514 /* Didn't find it. Strange -- means ip is a code address outside
3515 of any mapped text segment. Unlikely but not impossible -- app
3516 could be generating code to run. */
3517 if (!di)
3518 return False;
3519
3520 if (0 && ((n_search & 0x1) == 0))
3521 VG_(printf)("consider_vars_in_frame: %u searches, "
3522 "%u DebugInfos looked at\n",
3523 n_search, n_steps);
3524 /* Start of performance-enhancing hack: once every ??? (chosen
3525 hackily after profiling) successful searches, move the found
3526 DebugInfo one step closer to the start of the list. This makes
3527 future searches cheaper. */
3528 if ((n_search & 0xFFFF) == 0) {
3529 /* Move si one step closer to the start of the list. */
3530 move_DebugInfo_one_step_forward( di );
3531 }
3532 /* End of performance-enhancing hack. */
3533
3534 /* any var info at all? */
3535 if (!di->varinfo)
3536 return False;
3537
3538 /* Work through the scopes from most deeply nested outwards,
3539 looking for code address ranges that bracket 'ip'. The
3540 variables on each such address range found are in scope right
3541 now. Don't descend to level zero as that is the global
3542 scope. */
3543 regs.ip = ip;
3544 regs.sp = sp;
3545 regs.fp = fp;
3546
3547 /* "for each scope, working outwards ..." */
3548 for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) {
3549 XArray* vars;
3550 Word j;
3551 DiAddrRange* arange;
3552 OSet* this_scope
3553 = *(OSet**)VG_(indexXA)( di->varinfo, i );
3554 if (debug)
3555 VG_(printf)("QQQQ: considering scope %ld\n", (Word)i);
3556 if (!this_scope)
3557 continue;
3558 /* Find the set of variables in this scope that
3559 bracket the program counter. */
3560 arange = VG_(OSetGen_LookupWithCmp)(
3561 this_scope, &ip,
3562 ML_(cmp_for_DiAddrRange_range)
3563 );
3564 if (!arange)
3565 continue;
3566 /* stay sane */
3567 vg_assert(arange->aMin <= arange->aMax);
3568 /* It must bracket the ip we asked for, else
3569 ML_(cmp_for_DiAddrRange_range) is somehow broken. */
3570 vg_assert(arange->aMin <= ip && ip <= arange->aMax);
3571 /* It must have an attached XArray of DiVariables. */
3572 vars = arange->vars;
3573 vg_assert(vars);
3574 /* But it mustn't cover the entire address range. We only
3575 expect that to happen for the global scope (level 0), which
3576 we're not looking at here. Except, it may cover the entire
3577 address range, but in that case the vars array must be
3578 empty. */
3579 vg_assert(! (arange->aMin == (Addr)0
3580 && arange->aMax == ~(Addr)0
3581 && VG_(sizeXA)(vars) > 0) );
3582 for (j = 0; j < VG_(sizeXA)( vars ); j++) {
3583 DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j );
3584 PtrdiffT offset;
3585 if (debug)
3586 VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n",
3587 var->name,arange->aMin,arange->aMax,ip);
3588 if (data_address_is_in_var( &offset, di->admin_tyents,
3589 var, ®s,
3590 data_addr, di )) {
3591 PtrdiffT residual_offset = 0;
3592 XArray* described = ML_(describe_type)( &residual_offset,
3593 di->admin_tyents,
3594 var->typeR, offset );
3595 format_message( dname1, dname2,
3596 data_addr, di, var, offset, residual_offset,
3597 described, frameNo, tid );
3598 VG_(deleteXA)( described );
3599 return True;
3600 }
3601 }
3602 }
3603
3604 return False;
3605 }
3606
3607 /* Try to form some description of DATA_ADDR by looking at the DWARF3
3608 debug info we have. This considers all global variables, and 8
3609 frames in the stacks of all threads. Result is written at the ends
3610 of DNAME{1,2}V, which are XArray*s of HChar, that have been
3611 initialised by the caller, and True is returned. If no description
3612 is created, False is returned. Regardless of the return value,
3613 DNAME{1,2}V are guaranteed to be zero terminated after the call.
3614
3615 Note that after the call, DNAME{1,2} may have more than one
3616 trailing zero, so callers should establish the useful text length
3617 using VG_(strlen) on the contents, rather than VG_(sizeXA) on the
3618 XArray itself.
3619 */
VG_(get_data_description)3620 Bool VG_(get_data_description)(
3621 /*MOD*/ void* /* really, XArray* of HChar */ dname1v,
3622 /*MOD*/ void* /* really, XArray* of HChar */ dname2v,
3623 Addr data_addr
3624 )
3625 {
3626 # define N_FRAMES 8
3627 Addr ips[N_FRAMES], sps[N_FRAMES], fps[N_FRAMES];
3628 UInt n_frames;
3629
3630 Addr stack_min, stack_max;
3631 ThreadId tid;
3632 Bool found;
3633 DebugInfo* di;
3634 Word j;
3635
3636 XArray* dname1 = (XArray*)dname1v;
3637 XArray* dname2 = (XArray*)dname2v;
3638
3639 if (0) VG_(printf)("get_data_description: dataaddr %#lx\n", data_addr);
3640 /* First, see if data_addr is (or is part of) a global variable.
3641 Loop over the DebugInfos we have. Check data_addr against the
3642 outermost scope of all of them, as that should be a global
3643 scope. */
3644 for (di = debugInfo_list; di != NULL; di = di->next) {
3645 OSet* global_scope;
3646 Word gs_size;
3647 Addr zero;
3648 DiAddrRange* global_arange;
3649 Word i;
3650 XArray* vars;
3651
3652 /* text segment missing? unlikely, but handle it .. */
3653 if (!di->text_present || di->text_size == 0)
3654 continue;
3655 /* any var info at all? */
3656 if (!di->varinfo)
3657 continue;
3658 /* perhaps this object didn't contribute any vars at all? */
3659 if (VG_(sizeXA)( di->varinfo ) == 0)
3660 continue;
3661 global_scope = *(OSet**)VG_(indexXA)( di->varinfo, 0 );
3662 vg_assert(global_scope);
3663 gs_size = VG_(OSetGen_Size)( global_scope );
3664 /* The global scope might be completely empty if this
3665 compilation unit declared locals but nothing global. */
3666 if (gs_size == 0)
3667 continue;
3668 /* But if it isn't empty, then it must contain exactly one
3669 element, which covers the entire address range. */
3670 vg_assert(gs_size == 1);
3671 /* Fish out the global scope and check it is as expected. */
3672 zero = 0;
3673 global_arange
3674 = VG_(OSetGen_Lookup)( global_scope, &zero );
3675 /* The global range from (Addr)0 to ~(Addr)0 must exist */
3676 vg_assert(global_arange);
3677 vg_assert(global_arange->aMin == (Addr)0
3678 && global_arange->aMax == ~(Addr)0);
3679 /* Any vars in this range? */
3680 if (!global_arange->vars)
3681 continue;
3682 /* Ok, there are some vars in the global scope of this
3683 DebugInfo. Wade through them and see if the data addresses
3684 of any of them bracket data_addr. */
3685 vars = global_arange->vars;
3686 for (i = 0; i < VG_(sizeXA)( vars ); i++) {
3687 PtrdiffT offset;
3688 DiVariable* var = (DiVariable*)VG_(indexXA)( vars, i );
3689 vg_assert(var->name);
3690 /* Note we use a NULL RegSummary* here. It can't make any
3691 sense for a global variable to have a location expression
3692 which depends on a SP/FP/IP value. So don't supply any.
3693 This means, if the evaluation of the location
3694 expression/list requires a register, we have to let it
3695 fail. */
3696 if (data_address_is_in_var( &offset, di->admin_tyents, var,
3697 NULL/* RegSummary* */,
3698 data_addr, di )) {
3699 PtrdiffT residual_offset = 0;
3700 XArray* described = ML_(describe_type)( &residual_offset,
3701 di->admin_tyents,
3702 var->typeR, offset );
3703 format_message( dname1, dname2,
3704 data_addr, di, var, offset, residual_offset,
3705 described, -1/*frameNo*/,
3706 VG_INVALID_THREADID );
3707 VG_(deleteXA)( described );
3708 zterm_XA( dname1 );
3709 zterm_XA( dname2 );
3710 return True;
3711 }
3712 }
3713 }
3714
3715 /* Ok, well it's not a global variable. So now let's snoop around
3716 in the stacks of all the threads. First try to figure out which
3717 thread's stack data_addr is in. */
3718
3719 /* Perhaps it's on a thread's stack? */
3720 found = False;
3721 VG_(thread_stack_reset_iter)(&tid);
3722 while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) {
3723 if (stack_min >= stack_max)
3724 continue; /* ignore obviously stupid cases */
3725 if (stack_min - VG_STACK_REDZONE_SZB <= data_addr
3726 && data_addr <= stack_max) {
3727 found = True;
3728 break;
3729 }
3730 }
3731 if (!found) {
3732 zterm_XA( dname1 );
3733 zterm_XA( dname2 );
3734 return False;
3735 }
3736
3737 /* We conclude data_addr is in thread tid's stack. Unwind the
3738 stack to get a bunch of (ip,sp,fp) triples describing the
3739 frames, and for each frame, consider the local variables. */
3740 n_frames = VG_(get_StackTrace)( tid, ips, N_FRAMES,
3741 sps, fps, 0/*first_ip_delta*/ );
3742
3743 vg_assert(n_frames >= 0 && n_frames <= N_FRAMES);
3744 for (j = 0; j < n_frames; j++) {
3745 if (consider_vars_in_frame( dname1, dname2,
3746 data_addr,
3747 ips[j],
3748 sps[j], fps[j], tid, j )) {
3749 zterm_XA( dname1 );
3750 zterm_XA( dname2 );
3751 return True;
3752 }
3753 /* Now, it appears that gcc sometimes appears to produce
3754 location lists whose ranges don't actually cover the call
3755 instruction, even though the address of the variable in
3756 question is passed as a parameter in the call. AFAICS this
3757 is simply a bug in gcc - how can the variable be claimed not
3758 exist in memory (on the stack) for the duration of a call in
3759 which its address is passed? But anyway, in the particular
3760 case I investigated (memcheck/tests/varinfo6.c, call to croak
3761 on line 2999, local var budget declared at line 3115
3762 appearing not to exist across the call to mainSort on line
3763 3143, "gcc.orig (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2)" on
3764 amd64), the variable's location list does claim it exists
3765 starting at the first byte of the first instruction after the
3766 call instruction. So, call consider_vars_in_frame a second
3767 time, but this time add 1 to the IP. GDB handles this
3768 example with no difficulty, which leads me to believe that
3769 either (1) I misunderstood something, or (2) GDB has an
3770 equivalent kludge. */
3771 if (j > 0 /* this is a non-innermost frame */
3772 && consider_vars_in_frame( dname1, dname2,
3773 data_addr,
3774 ips[j] + 1,
3775 sps[j], fps[j], tid, j )) {
3776 zterm_XA( dname1 );
3777 zterm_XA( dname2 );
3778 return True;
3779 }
3780 }
3781
3782 /* We didn't find anything useful. */
3783 zterm_XA( dname1 );
3784 zterm_XA( dname2 );
3785 return False;
3786 # undef N_FRAMES
3787 }
3788
3789
3790 //////////////////////////////////////////////////////////////////
3791 // //
3792 // Support for other kinds of queries to the Dwarf3 var info //
3793 // //
3794 //////////////////////////////////////////////////////////////////
3795
3796 /* Figure out if the variable 'var' has a location that is linearly
3797 dependent on a stack pointer value, or a frame pointer value, and
3798 if it is, add a description of it to 'blocks'. Otherwise ignore
3799 it. If 'arrays_only' is True, also ignore it unless it has an
3800 array type. */
3801
3802 static
analyse_deps(XArray * blocks,const XArray * tyents,Addr ip,const DebugInfo * di,const DiVariable * var,Bool arrays_only)3803 void analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks,
3804 const XArray* /* TyEnt */ tyents,
3805 Addr ip, const DebugInfo* di, const DiVariable* var,
3806 Bool arrays_only )
3807 {
3808 GXResult res_sp_6k, res_sp_7k, res_fp_6k, res_fp_7k;
3809 RegSummary regs;
3810 MaybeULong mul;
3811 Bool isVec;
3812 TyEnt* ty;
3813
3814 Bool debug = False;
3815 if (0&&debug)
3816 VG_(printf)("adeps: var %s\n", var->name );
3817
3818 /* Figure out how big the variable is. */
3819 mul = ML_(sizeOfType)(tyents, var->typeR);
3820 /* If this var has a type whose size is unknown, zero, or
3821 impossibly large, it should never have been added. ML_(addVar)
3822 should have rejected it. */
3823 vg_assert(mul.b == True);
3824 vg_assert(mul.ul > 0);
3825 if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
3826 /* After this point, we assume we can truncate mul.ul to a host word
3827 safely (without loss of info). */
3828
3829 /* skip if non-array and we're only interested in arrays */
3830 ty = ML_(TyEnts__index_by_cuOff)( tyents, NULL, var->typeR );
3831 vg_assert(ty);
3832 vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty));
3833 if (ty->tag == Te_UNKNOWN)
3834 return; /* perhaps we should complain in this case? */
3835 isVec = ty->tag == Te_TyArray;
3836 if (arrays_only && !isVec)
3837 return;
3838
3839 if (0) {ML_(pp_TyEnt_C_ishly)(tyents, var->typeR);
3840 VG_(printf)(" %s\n", var->name);}
3841
3842 /* Do some test evaluations of the variable's location expression,
3843 in order to guess whether it is sp-relative, fp-relative, or
3844 none. A crude hack, which can be interpreted roughly as finding
3845 the first derivative of the location expression w.r.t. the
3846 supplied frame and stack pointer values. */
3847 regs.fp = 0;
3848 regs.ip = ip;
3849 regs.sp = 6 * 1024;
3850 res_sp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di );
3851
3852 regs.fp = 0;
3853 regs.ip = ip;
3854 regs.sp = 7 * 1024;
3855 res_sp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di );
3856
3857 regs.fp = 6 * 1024;
3858 regs.ip = ip;
3859 regs.sp = 0;
3860 res_fp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di );
3861
3862 regs.fp = 7 * 1024;
3863 regs.ip = ip;
3864 regs.sp = 0;
3865 res_fp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di );
3866
3867 vg_assert(res_sp_6k.kind == res_sp_7k.kind);
3868 vg_assert(res_sp_6k.kind == res_fp_6k.kind);
3869 vg_assert(res_sp_6k.kind == res_fp_7k.kind);
3870
3871 if (res_sp_6k.kind == GXR_Addr) {
3872 StackBlock block;
3873 GXResult res;
3874 UWord sp_delta = res_sp_7k.word - res_sp_6k.word;
3875 UWord fp_delta = res_fp_7k.word - res_fp_6k.word;
3876 vg_assert(sp_delta == 0 || sp_delta == 1024);
3877 vg_assert(fp_delta == 0 || fp_delta == 1024);
3878
3879 if (sp_delta == 0 && fp_delta == 0) {
3880 /* depends neither on sp nor fp, so it can't be a stack
3881 local. Ignore it. */
3882 }
3883 else
3884 if (sp_delta == 1024 && fp_delta == 0) {
3885 regs.sp = regs.fp = 0;
3886 regs.ip = ip;
3887 res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di );
3888 vg_assert(res.kind == GXR_Addr);
3889 if (debug)
3890 VG_(printf)(" %5ld .. %5ld (sp) %s\n",
3891 res.word, res.word + ((UWord)mul.ul) - 1, var->name);
3892 block.base = res.word;
3893 block.szB = (SizeT)mul.ul;
3894 block.spRel = True;
3895 block.isVec = isVec;
3896 VG_(memset)( &block.name[0], 0, sizeof(block.name) );
3897 if (var->name)
3898 VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 );
3899 block.name[ sizeof(block.name)-1 ] = 0;
3900 VG_(addToXA)( blocks, &block );
3901 }
3902 else
3903 if (sp_delta == 0 && fp_delta == 1024) {
3904 regs.sp = regs.fp = 0;
3905 regs.ip = ip;
3906 res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di );
3907 vg_assert(res.kind == GXR_Addr);
3908 if (debug)
3909 VG_(printf)(" %5ld .. %5ld (FP) %s\n",
3910 res.word, res.word + ((UWord)mul.ul) - 1, var->name);
3911 block.base = res.word;
3912 block.szB = (SizeT)mul.ul;
3913 block.spRel = False;
3914 block.isVec = isVec;
3915 VG_(memset)( &block.name[0], 0, sizeof(block.name) );
3916 if (var->name)
3917 VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 );
3918 block.name[ sizeof(block.name)-1 ] = 0;
3919 VG_(addToXA)( blocks, &block );
3920 }
3921 else {
3922 vg_assert(0);
3923 }
3924 }
3925 }
3926
3927
3928 /* Get an XArray of StackBlock which describe the stack (auto) blocks
3929 for this ip. The caller is expected to free the XArray at some
3930 point. If 'arrays_only' is True, only array-typed blocks are
3931 returned; otherwise blocks of all types are returned. */
3932
3933 void* /* really, XArray* of StackBlock */
VG_(di_get_stack_blocks_at_ip)3934 VG_(di_get_stack_blocks_at_ip)( Addr ip, Bool arrays_only )
3935 {
3936 /* This is a derivation of consider_vars_in_frame() above. */
3937 Word i;
3938 DebugInfo* di;
3939 Bool debug = False;
3940
3941 XArray* res = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dgsbai.1",
3942 ML_(dinfo_free),
3943 sizeof(StackBlock) );
3944
3945 static UInt n_search = 0;
3946 static UInt n_steps = 0;
3947 n_search++;
3948 if (debug)
3949 VG_(printf)("QQQQ: dgsbai: ip %#lx\n", ip);
3950 /* first, find the DebugInfo that pertains to 'ip'. */
3951 for (di = debugInfo_list; di; di = di->next) {
3952 n_steps++;
3953 /* text segment missing? unlikely, but handle it .. */
3954 if (!di->text_present || di->text_size == 0)
3955 continue;
3956 /* Ok. So does this text mapping bracket the ip? */
3957 if (di->text_avma <= ip && ip < di->text_avma + di->text_size)
3958 break;
3959 }
3960
3961 /* Didn't find it. Strange -- means ip is a code address outside
3962 of any mapped text segment. Unlikely but not impossible -- app
3963 could be generating code to run. */
3964 if (!di)
3965 return res; /* currently empty */
3966
3967 if (0 && ((n_search & 0x1) == 0))
3968 VG_(printf)("VG_(di_get_stack_blocks_at_ip): %u searches, "
3969 "%u DebugInfos looked at\n",
3970 n_search, n_steps);
3971 /* Start of performance-enhancing hack: once every ??? (chosen
3972 hackily after profiling) successful searches, move the found
3973 DebugInfo one step closer to the start of the list. This makes
3974 future searches cheaper. */
3975 if ((n_search & 0xFFFF) == 0) {
3976 /* Move si one step closer to the start of the list. */
3977 move_DebugInfo_one_step_forward( di );
3978 }
3979 /* End of performance-enhancing hack. */
3980
3981 /* any var info at all? */
3982 if (!di->varinfo)
3983 return res; /* currently empty */
3984
3985 /* Work through the scopes from most deeply nested outwards,
3986 looking for code address ranges that bracket 'ip'. The
3987 variables on each such address range found are in scope right
3988 now. Don't descend to level zero as that is the global
3989 scope. */
3990
3991 /* "for each scope, working outwards ..." */
3992 for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) {
3993 XArray* vars;
3994 Word j;
3995 DiAddrRange* arange;
3996 OSet* this_scope
3997 = *(OSet**)VG_(indexXA)( di->varinfo, i );
3998 if (debug)
3999 VG_(printf)("QQQQ: considering scope %ld\n", (Word)i);
4000 if (!this_scope)
4001 continue;
4002 /* Find the set of variables in this scope that
4003 bracket the program counter. */
4004 arange = VG_(OSetGen_LookupWithCmp)(
4005 this_scope, &ip,
4006 ML_(cmp_for_DiAddrRange_range)
4007 );
4008 if (!arange)
4009 continue;
4010 /* stay sane */
4011 vg_assert(arange->aMin <= arange->aMax);
4012 /* It must bracket the ip we asked for, else
4013 ML_(cmp_for_DiAddrRange_range) is somehow broken. */
4014 vg_assert(arange->aMin <= ip && ip <= arange->aMax);
4015 /* It must have an attached XArray of DiVariables. */
4016 vars = arange->vars;
4017 vg_assert(vars);
4018 /* But it mustn't cover the entire address range. We only
4019 expect that to happen for the global scope (level 0), which
4020 we're not looking at here. Except, it may cover the entire
4021 address range, but in that case the vars array must be
4022 empty. */
4023 vg_assert(! (arange->aMin == (Addr)0
4024 && arange->aMax == ~(Addr)0
4025 && VG_(sizeXA)(vars) > 0) );
4026 for (j = 0; j < VG_(sizeXA)( vars ); j++) {
4027 DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j );
4028 if (debug)
4029 VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n",
4030 var->name,arange->aMin,arange->aMax,ip);
4031 analyse_deps( res, di->admin_tyents, ip,
4032 di, var, arrays_only );
4033 }
4034 }
4035
4036 return res;
4037 }
4038
4039
4040 /* Get an array of GlobalBlock which describe the global blocks owned
4041 by the shared object characterised by the given di_handle. Asserts
4042 if the handle is invalid. The caller is responsible for freeing
4043 the array at some point. If 'arrays_only' is True, only
4044 array-typed blocks are returned; otherwise blocks of all types are
4045 returned. */
4046
4047 void* /* really, XArray* of GlobalBlock */
VG_(di_get_global_blocks_from_dihandle)4048 VG_(di_get_global_blocks_from_dihandle) ( ULong di_handle,
4049 Bool arrays_only )
4050 {
4051 /* This is a derivation of consider_vars_in_frame() above. */
4052
4053 DebugInfo* di;
4054 XArray* gvars; /* XArray* of GlobalBlock */
4055 Word nScopes, scopeIx;
4056
4057 /* The first thing to do is find the DebugInfo that
4058 pertains to 'di_handle'. */
4059 vg_assert(di_handle > 0);
4060 for (di = debugInfo_list; di; di = di->next) {
4061 if (di->handle == di_handle)
4062 break;
4063 }
4064
4065 /* If this fails, we were unable to find any DebugInfo with the
4066 given handle. This is considered an error on the part of the
4067 caller. */
4068 vg_assert(di != NULL);
4069
4070 /* we'll put the collected variables in here. */
4071 gvars = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dggbfd.1",
4072 ML_(dinfo_free), sizeof(GlobalBlock) );
4073
4074 /* any var info at all? */
4075 if (!di->varinfo)
4076 return gvars;
4077
4078 /* we'll iterate over all the variables we can find, even if
4079 it seems senseless to visit stack-allocated variables */
4080 /* Iterate over all scopes */
4081 nScopes = VG_(sizeXA)( di->varinfo );
4082 for (scopeIx = 0; scopeIx < nScopes; scopeIx++) {
4083
4084 /* Iterate over each (code) address range at the current scope */
4085 DiAddrRange* range;
4086 OSet* /* of DiAddrInfo */ scope
4087 = *(OSet**)VG_(indexXA)( di->varinfo, scopeIx );
4088 vg_assert(scope);
4089 VG_(OSetGen_ResetIter)(scope);
4090 while ( (range = VG_(OSetGen_Next)(scope)) ) {
4091
4092 /* Iterate over each variable in the current address range */
4093 Word nVars, varIx;
4094 vg_assert(range->vars);
4095 nVars = VG_(sizeXA)( range->vars );
4096 for (varIx = 0; varIx < nVars; varIx++) {
4097
4098 Bool isVec;
4099 GXResult res;
4100 MaybeULong mul;
4101 GlobalBlock gb;
4102 TyEnt* ty;
4103 DiVariable* var = VG_(indexXA)( range->vars, varIx );
4104 vg_assert(var->name);
4105 if (0) VG_(printf)("at depth %ld var %s ", scopeIx, var->name );
4106
4107 /* Now figure out if this variable has a constant address
4108 (that is, independent of FP, SP, phase of moon, etc),
4109 and if so, what the address is. Any variable with a
4110 constant address is deemed to be a global so we collect
4111 it. */
4112 if (0) { VG_(printf)("EVAL: "); ML_(pp_GX)(var->gexpr);
4113 VG_(printf)("\n"); }
4114 res = ML_(evaluate_trivial_GX)( var->gexpr, di );
4115
4116 /* Not a constant address => not interesting */
4117 if (res.kind != GXR_Addr) {
4118 if (0) VG_(printf)("FAIL\n");
4119 continue;
4120 }
4121
4122 /* Ok, it's a constant address. See if we want to collect
4123 it. */
4124 if (0) VG_(printf)("%#lx\n", res.word);
4125
4126 /* Figure out how big the variable is. */
4127 mul = ML_(sizeOfType)(di->admin_tyents, var->typeR);
4128
4129 /* If this var has a type whose size is unknown, zero, or
4130 impossibly large, it should never have been added.
4131 ML_(addVar) should have rejected it. */
4132 vg_assert(mul.b == True);
4133 vg_assert(mul.ul > 0);
4134 if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
4135 /* After this point, we assume we can truncate mul.ul to a
4136 host word safely (without loss of info). */
4137
4138 /* skip if non-array and we're only interested in
4139 arrays */
4140 ty = ML_(TyEnts__index_by_cuOff)( di->admin_tyents, NULL,
4141 var->typeR );
4142 vg_assert(ty);
4143 vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty));
4144 if (ty->tag == Te_UNKNOWN)
4145 continue; /* perhaps we should complain in this case? */
4146
4147 isVec = ty->tag == Te_TyArray;
4148 if (arrays_only && !isVec) continue;
4149
4150 /* Ok, so collect it! */
4151 vg_assert(var->name);
4152 vg_assert(di->soname);
4153 if (0) VG_(printf)("XXXX %s %s %d\n", var->name,
4154 ML_(fndn_ix2filename)(di, var->fndn_ix),
4155 var->lineNo);
4156 VG_(memset)(&gb, 0, sizeof(gb));
4157 gb.addr = res.word;
4158 gb.szB = (SizeT)mul.ul;
4159 gb.isVec = isVec;
4160 VG_(strncpy)(&gb.name[0], var->name, sizeof(gb.name)-1);
4161 VG_(strncpy)(&gb.soname[0], di->soname, sizeof(gb.soname)-1);
4162 vg_assert(gb.name[ sizeof(gb.name)-1 ] == 0);
4163 vg_assert(gb.soname[ sizeof(gb.soname)-1 ] == 0);
4164
4165 VG_(addToXA)( gvars, &gb );
4166
4167 } /* for (varIx = 0; varIx < nVars; varIx++) */
4168
4169 } /* while ( (range = VG_(OSetGen_Next)(scope)) ) */
4170
4171 } /* for (scopeIx = 0; scopeIx < nScopes; scopeIx++) */
4172
4173 return gvars;
4174 }
4175
4176
4177 /*------------------------------------------------------------*/
4178 /*--- DebugInfo accessor functions ---*/
4179 /*------------------------------------------------------------*/
4180
VG_(next_DebugInfo)4181 const DebugInfo* VG_(next_DebugInfo)(const DebugInfo* di)
4182 {
4183 if (di == NULL)
4184 return debugInfo_list;
4185 return di->next;
4186 }
4187
VG_(DebugInfo_get_text_avma)4188 Addr VG_(DebugInfo_get_text_avma)(const DebugInfo* di)
4189 {
4190 return di->text_present ? di->text_avma : 0;
4191 }
4192
VG_(DebugInfo_get_text_size)4193 SizeT VG_(DebugInfo_get_text_size)(const DebugInfo* di)
4194 {
4195 return di->text_present ? di->text_size : 0;
4196 }
4197
VG_(DebugInfo_get_bss_avma)4198 Addr VG_(DebugInfo_get_bss_avma)(const DebugInfo* di)
4199 {
4200 return di->bss_present ? di->bss_avma : 0;
4201 }
4202
VG_(DebugInfo_get_bss_size)4203 SizeT VG_(DebugInfo_get_bss_size)(const DebugInfo* di)
4204 {
4205 return di->bss_present ? di->bss_size : 0;
4206 }
4207
VG_(DebugInfo_get_plt_avma)4208 Addr VG_(DebugInfo_get_plt_avma)(const DebugInfo* di)
4209 {
4210 return di->plt_present ? di->plt_avma : 0;
4211 }
4212
VG_(DebugInfo_get_plt_size)4213 SizeT VG_(DebugInfo_get_plt_size)(const DebugInfo* di)
4214 {
4215 return di->plt_present ? di->plt_size : 0;
4216 }
4217
VG_(DebugInfo_get_gotplt_avma)4218 Addr VG_(DebugInfo_get_gotplt_avma)(const DebugInfo* di)
4219 {
4220 return di->gotplt_present ? di->gotplt_avma : 0;
4221 }
4222
VG_(DebugInfo_get_gotplt_size)4223 SizeT VG_(DebugInfo_get_gotplt_size)(const DebugInfo* di)
4224 {
4225 return di->gotplt_present ? di->gotplt_size : 0;
4226 }
4227
VG_(DebugInfo_get_got_avma)4228 Addr VG_(DebugInfo_get_got_avma)(const DebugInfo* di)
4229 {
4230 return di->got_present ? di->got_avma : 0;
4231 }
4232
VG_(DebugInfo_get_got_size)4233 SizeT VG_(DebugInfo_get_got_size)(const DebugInfo* di)
4234 {
4235 return di->got_present ? di->got_size : 0;
4236 }
4237
VG_(DebugInfo_get_soname)4238 const HChar* VG_(DebugInfo_get_soname)(const DebugInfo* di)
4239 {
4240 return di->soname;
4241 }
4242
VG_(DebugInfo_get_filename)4243 const HChar* VG_(DebugInfo_get_filename)(const DebugInfo* di)
4244 {
4245 return di->fsm.filename;
4246 }
4247
VG_(DebugInfo_get_text_bias)4248 PtrdiffT VG_(DebugInfo_get_text_bias)(const DebugInfo* di)
4249 {
4250 return di->text_present ? di->text_bias : 0;
4251 }
4252
VG_(DebugInfo_syms_howmany)4253 Int VG_(DebugInfo_syms_howmany) ( const DebugInfo *si )
4254 {
4255 return si->symtab_used;
4256 }
4257
VG_(DebugInfo_syms_getidx)4258 void VG_(DebugInfo_syms_getidx) ( const DebugInfo *si,
4259 Int idx,
4260 /*OUT*/SymAVMAs* avmas,
4261 /*OUT*/UInt* size,
4262 /*OUT*/const HChar** pri_name,
4263 /*OUT*/const HChar*** sec_names,
4264 /*OUT*/Bool* isText,
4265 /*OUT*/Bool* isIFunc )
4266 {
4267 vg_assert(idx >= 0 && idx < si->symtab_used);
4268 if (avmas) *avmas = si->symtab[idx].avmas;
4269 if (size) *size = si->symtab[idx].size;
4270 if (pri_name) *pri_name = si->symtab[idx].pri_name;
4271 if (sec_names) *sec_names = si->symtab[idx].sec_names;
4272 if (isText) *isText = si->symtab[idx].isText;
4273 if (isIFunc) *isIFunc = si->symtab[idx].isIFunc;
4274 }
4275
4276
4277 /*------------------------------------------------------------*/
4278 /*--- SectKind query functions ---*/
4279 /*------------------------------------------------------------*/
4280
4281 /* Convert a VgSectKind to a string, which must be copied if you want
4282 to change it. */
VG_(pp_SectKind)4283 const HChar* VG_(pp_SectKind)( VgSectKind kind )
4284 {
4285 switch (kind) {
4286 case Vg_SectUnknown: return "Unknown";
4287 case Vg_SectText: return "Text";
4288 case Vg_SectData: return "Data";
4289 case Vg_SectBSS: return "BSS";
4290 case Vg_SectGOT: return "GOT";
4291 case Vg_SectPLT: return "PLT";
4292 case Vg_SectOPD: return "OPD";
4293 case Vg_SectGOTPLT: return "GOTPLT";
4294 default: vg_assert(0);
4295 }
4296 }
4297
4298 /* Given an address 'a', make a guess of which section of which object
4299 it comes from. If name is non-NULL, then the object's name is put
4300 in *name. The returned name, if any, should be saved away, if there is
4301 a chance that a debug-info will be discarded and the name is being
4302 used later on. */
VG_(DebugInfo_sect_kind)4303 VgSectKind VG_(DebugInfo_sect_kind)( /*OUT*/const HChar** name, Addr a)
4304 {
4305 DebugInfo* di;
4306 VgSectKind res = Vg_SectUnknown;
4307
4308 for (di = debugInfo_list; di != NULL; di = di->next) {
4309
4310 if (0)
4311 VG_(printf)(
4312 "addr=%#lx di=%p %s got=%#lx,%ld plt=%#lx,%ld "
4313 "data=%#lx,%ld bss=%#lx,%ld\n",
4314 a, di, di->fsm.filename,
4315 di->got_avma, di->got_size,
4316 di->plt_avma, di->plt_size,
4317 di->data_avma, di->data_size,
4318 di->bss_avma, di->bss_size);
4319
4320 if (di->text_present
4321 && di->text_size > 0
4322 && a >= di->text_avma && a < di->text_avma + di->text_size) {
4323 res = Vg_SectText;
4324 break;
4325 }
4326 if (di->data_present
4327 && di->data_size > 0
4328 && a >= di->data_avma && a < di->data_avma + di->data_size) {
4329 res = Vg_SectData;
4330 break;
4331 }
4332 if (di->sdata_present
4333 && di->sdata_size > 0
4334 && a >= di->sdata_avma && a < di->sdata_avma + di->sdata_size) {
4335 res = Vg_SectData;
4336 break;
4337 }
4338 if (di->bss_present
4339 && di->bss_size > 0
4340 && a >= di->bss_avma && a < di->bss_avma + di->bss_size) {
4341 res = Vg_SectBSS;
4342 break;
4343 }
4344 if (di->sbss_present
4345 && di->sbss_size > 0
4346 && a >= di->sbss_avma && a < di->sbss_avma + di->sbss_size) {
4347 res = Vg_SectBSS;
4348 break;
4349 }
4350 if (di->plt_present
4351 && di->plt_size > 0
4352 && a >= di->plt_avma && a < di->plt_avma + di->plt_size) {
4353 res = Vg_SectPLT;
4354 break;
4355 }
4356 if (di->got_present
4357 && di->got_size > 0
4358 && a >= di->got_avma && a < di->got_avma + di->got_size) {
4359 res = Vg_SectGOT;
4360 break;
4361 }
4362 if (di->gotplt_present
4363 && di->gotplt_size > 0
4364 && a >= di->gotplt_avma && a < di->gotplt_avma + di->gotplt_size) {
4365 res = Vg_SectGOTPLT;
4366 break;
4367 }
4368 if (di->opd_present
4369 && di->opd_size > 0
4370 && a >= di->opd_avma && a < di->opd_avma + di->opd_size) {
4371 res = Vg_SectOPD;
4372 break;
4373 }
4374 /* we could also check for .eh_frame, if anyone really cares */
4375 }
4376
4377 vg_assert( (di == NULL && res == Vg_SectUnknown)
4378 || (di != NULL && res != Vg_SectUnknown) );
4379
4380 if (name) {
4381 if (di && di->fsm.filename) {
4382 *name = di->fsm.filename;
4383 } else {
4384 *name = "???";
4385 }
4386 }
4387
4388 return res;
4389
4390 }
4391
4392 /*--------------------------------------------------------------------*/
4393 /*--- end ---*/
4394 /*--------------------------------------------------------------------*/
4395