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, "&amp;");
2190             break;
2191          case '<':
2192             n = putStr( n, buf, bufsiz, "&lt;");
2193             break;
2194          case '>':
2195             n = putStr( n, buf, bufsiz, "&gt;");
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, &regs,
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, &regs, 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, &regs, 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, &regs, 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, &regs, 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, &regs, 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, &regs, 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