• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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-2015 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) || defined(VGO_solaris)
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 debuginfo_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 to 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) || defined(VGO_solaris)
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%-16lx    size %-8lu    "
625                    "foff %-8lld    %s %s %s\n",
626                    i, 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) || defined(VGO_solaris)
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 defined(VGO_solaris)
969    is_rx_map = seg->hasR && seg->hasX && !seg->hasW;
970    is_rw_map = seg->hasR && seg->hasW;
971 #  endif
972 
973    if (debug)
974       VG_(printf)("di_notify_mmap-3: "
975                   "is_rx_map %d, is_rw_map %d, is_ro_map %d\n",
976                   (Int)is_rx_map, (Int)is_rw_map, (Int)is_ro_map);
977 
978    /* Ignore mappings with permissions we can't possibly be interested in. */
979    if (!(is_rx_map || is_rw_map || is_ro_map))
980       return 0;
981 
982    /* Peer at the first few bytes of the file, to see if it is an ELF */
983    /* object file. Ignore the file if we do not have read permission. */
984    VG_(memset)(buf1k, 0, sizeof(buf1k));
985    oflags = VKI_O_RDONLY;
986 #  if defined(VKI_O_LARGEFILE)
987    oflags |= VKI_O_LARGEFILE;
988 #  endif
989 
990    if (use_fd == -1) {
991       SysRes fd = VG_(open)( filename, oflags, 0 );
992       if (sr_isError(fd)) {
993          if (sr_Err(fd) != VKI_EACCES) {
994             DebugInfo fake_di;
995             VG_(memset)(&fake_di, 0, sizeof(fake_di));
996             fake_di.fsm.filename = ML_(dinfo_strdup)("di.debuginfo.nmm",
997                                                      filename);
998             ML_(symerr)(&fake_di, True,
999                         "can't open file to inspect ELF header");
1000          }
1001          return 0;
1002       }
1003       actual_fd = sr_Res(fd);
1004    } else {
1005       actual_fd = use_fd;
1006    }
1007 
1008    preadres = VG_(pread)( actual_fd, buf1k, sizeof(buf1k), 0 );
1009    if (use_fd == -1) {
1010       VG_(close)( actual_fd );
1011    }
1012 
1013    if (sr_isError(preadres)) {
1014       DebugInfo fake_di;
1015       VG_(memset)(&fake_di, 0, sizeof(fake_di));
1016       fake_di.fsm.filename = ML_(dinfo_strdup)("di.debuginfo.nmm", filename);
1017       ML_(symerr)(&fake_di, True, "can't read file to inspect ELF header");
1018       return 0;
1019    }
1020    if (sr_Res(preadres) == 0)
1021       return 0;
1022    vg_assert(sr_Res(preadres) > 0 && sr_Res(preadres) <= sizeof(buf1k) );
1023 
1024    /* We're only interested in mappings of object files. */
1025 #  if defined(VGO_linux) || defined(VGO_solaris)
1026    if (!ML_(is_elf_object_file)( buf1k, (SizeT)sr_Res(preadres), False ))
1027       return 0;
1028 #  elif defined(VGO_darwin)
1029    if (!ML_(is_macho_object_file)( buf1k, (SizeT)sr_Res(preadres) ))
1030       return 0;
1031 #  else
1032 #    error "unknown OS"
1033 #  endif
1034 
1035    /* See if we have a DebugInfo for this filename.  If not,
1036       create one. */
1037    di = find_or_create_DebugInfo_for( filename );
1038    vg_assert(di);
1039 
1040    if (debug)
1041       VG_(printf)("di_notify_mmap-4: "
1042                   "noting details in DebugInfo* at %p\n", di);
1043 
1044    /* Note the details about the mapping. */
1045    DebugInfoMapping map;
1046    map.avma = seg->start;
1047    map.size = seg->end + 1 - seg->start;
1048    map.foff = seg->offset;
1049    map.rx   = is_rx_map;
1050    map.rw   = is_rw_map;
1051    map.ro   = is_ro_map;
1052    VG_(addToXA)(di->fsm.maps, &map);
1053 
1054    /* Update flags about what kind of mappings we've already seen. */
1055    di->fsm.have_rx_map |= is_rx_map;
1056    di->fsm.have_rw_map |= is_rw_map;
1057    di->fsm.have_ro_map |= is_ro_map;
1058 
1059    /* So, finally, are we in an accept state? */
1060    if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) {
1061       /* Ok, so, finally, we found what we need, and we haven't
1062          already read debuginfo for this object.  So let's do so now.
1063          Yee-ha! */
1064       if (debug)
1065          VG_(printf)("di_notify_mmap-5: "
1066                      "achieved accept state for %s\n", filename);
1067       return di_notify_ACHIEVE_ACCEPT_STATE ( di );
1068    } else {
1069       /* If we don't have an rx and rw mapping, or if we already have
1070          debuginfo for this mapping for whatever reason, go no
1071          further. */
1072       return 0;
1073    }
1074 }
1075 
1076 
1077 /* Unmap is simpler - throw away any SegInfos intersecting
1078    [a, a+len).  */
VG_(di_notify_munmap)1079 void VG_(di_notify_munmap)( Addr a, SizeT len )
1080 {
1081    Bool anyFound;
1082    if (0) VG_(printf)("DISCARD %#lx %#lx\n", a, a+len);
1083    anyFound = discard_syms_in_range(a, len);
1084    if (anyFound)
1085       cfsi_m_cache__invalidate();
1086 }
1087 
1088 
1089 /* Uh, this doesn't do anything at all.  IIRC glibc (or ld.so, I don't
1090    remember) does a bunch of mprotects on itself, and if we follow
1091    through here, it causes the debug info for that object to get
1092    discarded. */
VG_(di_notify_mprotect)1093 void VG_(di_notify_mprotect)( Addr a, SizeT len, UInt prot )
1094 {
1095    Bool exe_ok = toBool(prot & VKI_PROT_EXEC);
1096 #  if defined(VGA_x86)
1097    exe_ok = exe_ok || toBool(prot & VKI_PROT_READ);
1098 #  endif
1099    if (0 && !exe_ok) {
1100       Bool anyFound = discard_syms_in_range(a, len);
1101       if (anyFound)
1102          cfsi_m_cache__invalidate();
1103    }
1104 }
1105 
1106 
1107 /* This is a MacOSX >= 10.7 32-bit only special.  See comments on the
1108    declaration of struct _DebugInfoFSM for details. */
VG_(di_notify_vm_protect)1109 void VG_(di_notify_vm_protect)( Addr a, SizeT len, UInt prot )
1110 {
1111    Bool debug = (DEBUG_FSM != 0);
1112 
1113    Bool r_ok = toBool(prot & VKI_PROT_READ);
1114    Bool w_ok = toBool(prot & VKI_PROT_WRITE);
1115    Bool x_ok = toBool(prot & VKI_PROT_EXEC);
1116    if (debug) {
1117       VG_(printf)("di_notify_vm_protect-0:\n");
1118       VG_(printf)("di_notify_vm_protect-1: %#lx-%#lx %c%c%c\n",
1119                   a, a + len - 1,
1120                   r_ok ? 'r' : '-', w_ok ? 'w' : '-', x_ok ? 'x' : '-' );
1121    }
1122 
1123    Bool do_nothing = True;
1124 #  if defined(VGP_x86_darwin) && (DARWIN_VERS >= DARWIN_10_7)
1125    do_nothing = False;
1126 #  endif
1127    if (do_nothing /* wrong platform */) {
1128       if (debug)
1129          VG_(printf)("di_notify_vm_protect-2: wrong platform, "
1130                      "doing nothing.\n");
1131       return;
1132    }
1133 
1134    if (! (r_ok && !w_ok && x_ok))
1135       return; /* not an upgrade to r-x */
1136 
1137    /* Find a DebugInfo containing a FSM that has [a, +len) previously
1138       observed as a r-- mapping, plus some other rw- mapping.  If such
1139       is found, conclude we're in an accept state and read debuginfo
1140       accordingly. */
1141    if (debug)
1142       VG_(printf)("di_notify_vm_protect-3: looking for existing DebugInfo*\n");
1143    DebugInfo* di;
1144    DebugInfoMapping *map = NULL;
1145    Word i;
1146    for (di = debugInfo_list; di; di = di->next) {
1147       vg_assert(di->fsm.filename);
1148       if (di->have_dinfo)
1149          continue; /* already have debuginfo for this object */
1150       if (!di->fsm.have_ro_map)
1151          continue; /* need to have a r-- mapping for this object */
1152       if (di->fsm.have_rx_map)
1153          continue; /* rx- mapping already exists */
1154       if (!di->fsm.have_rw_map)
1155          continue; /* need to have a rw- mapping */
1156       /* Try to find a mapping matching the memory area. */
1157       for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1158          map = VG_(indexXA)(di->fsm.maps, i);
1159          if (map->ro && map->avma == a && map->size == len)
1160             break;
1161          map = NULL;
1162       }
1163       if (!map)
1164          continue; /* this isn't an upgrade of an r-- mapping */
1165       /* looks like we're in luck! */
1166       break;
1167    }
1168    if (di == NULL)
1169       return; /* didn't find anything */
1170 
1171    if (debug)
1172      VG_(printf)("di_notify_vm_protect-4: found existing DebugInfo* at %p\n",
1173                  di);
1174 
1175    /* Do the upgrade.  Simply update the flags of the mapping
1176       and pretend we never saw the RO map at all. */
1177    vg_assert(di->fsm.have_ro_map);
1178    map->rx = True;
1179    map->ro = False;
1180    di->fsm.have_rx_map = True;
1181    di->fsm.have_ro_map = False;
1182    /* See if there are any more ro mappings */
1183    for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1184       map = VG_(indexXA)(di->fsm.maps, i);
1185       if (map->ro) {
1186          di->fsm.have_ro_map = True;
1187          break;
1188       }
1189    }
1190 
1191    /* Check if we're now in an accept state and read debuginfo.  Finally. */
1192    if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) {
1193       if (debug)
1194          VG_(printf)("di_notify_vm_protect-5: "
1195                      "achieved accept state for %s\n", di->fsm.filename);
1196       ULong di_handle __attribute__((unused))
1197          = di_notify_ACHIEVE_ACCEPT_STATE( di );
1198       /* di_handle is ignored. That's not a problem per se -- it just
1199          means nobody will ever be able to refer to this debuginfo by
1200          handle since nobody will know what the handle value is. */
1201    }
1202 }
1203 
1204 
1205 /*--------- PDB (windows debug info) reading --------- */
1206 
1207 /* this should really return ULong, as per VG_(di_notify_mmap). */
VG_(di_notify_pdb_debuginfo)1208 void VG_(di_notify_pdb_debuginfo)( Int fd_obj, Addr avma_obj,
1209                                    SizeT total_size, PtrdiffT bias_obj )
1210 {
1211    Int    i, r, sz_exename;
1212    ULong  obj_mtime, pdb_mtime;
1213    HChar* pdbname = NULL;
1214    HChar* dot;
1215    SysRes sres;
1216    Int    fd_pdbimage;
1217    SizeT  n_pdbimage;
1218    struct vg_stat stat_buf;
1219 
1220    if (VG_(clo_verbosity) > 0) {
1221       VG_(message)(Vg_UserMsg, "\n");
1222       VG_(message)(Vg_UserMsg,
1223          "LOAD_PDB_DEBUGINFO: clreq:   fd=%d, avma=%#lx, total_size=%lu, "
1224          "bias=%#lx\n",
1225          fd_obj, avma_obj, total_size, (UWord)bias_obj
1226       );
1227    }
1228 
1229    /* 'fd' refers to the .exe/.dll we're dealing with.  Get its modification
1230       time into obj_mtime. */
1231    r = VG_(fstat)(fd_obj, &stat_buf);
1232    if (r == -1)
1233       return; /* stat failed ?! */
1234    vg_assert(r == 0);
1235    obj_mtime = stat_buf.mtime;
1236 
1237    /* and get its name into exename. */
1238    const HChar *exe;
1239    if (! VG_(resolve_filename)(fd_obj, &exe))
1240       return; /*  failed */
1241    sz_exename = VG_(strlen)(exe);
1242    HChar exename[sz_exename + 1];
1243    VG_(strcpy)(exename, exe);  // make a copy on the stack
1244 
1245    if (VG_(clo_verbosity) > 0) {
1246       VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: objname: %s\n", exename);
1247    }
1248 
1249    /* Try to get the PDB file name from the executable. */
1250    pdbname = ML_(find_name_of_pdb_file)(exename);
1251    if (pdbname) {
1252       vg_assert(VG_(strlen)(pdbname) >= 5); /* 5 = strlen("X.pdb") */
1253       /* So we successfully extracted a name from the PE file.  But it's
1254          likely to be of the form
1255             e:\foo\bar\xyzzy\wibble.pdb
1256          and we need to change it into something we can actually open
1257          in Wine-world, which basically means turning it into
1258             $HOME/.wine/drive_e/foo/bar/xyzzy/wibble.pdb
1259          We also take into account $WINEPREFIX, if it is set.
1260          For the moment, if the name isn't fully qualified, just forget it
1261          (we'd have to root around to find where the pdb actually is)
1262       */
1263       /* Change all the backslashes to forward slashes */
1264       for (i = 0; pdbname[i]; i++) {
1265          if (pdbname[i] == '\\')
1266             pdbname[i] = '/';
1267       }
1268       Bool is_quald
1269          = ('a' <= VG_(tolower)(pdbname[0]) && VG_(tolower)(pdbname[0]) <= 'z')
1270            && pdbname[1] == ':'
1271            && pdbname[2] == '/';
1272       HChar* home = VG_(getenv)("HOME");
1273       HChar* wpfx = VG_(getenv)("WINEPREFIX");
1274       if (is_quald && wpfx) {
1275          /* Change e:/foo/bar/xyzzy/wibble.pdb
1276                 to $WINEPREFIX/drive_e/foo/bar/xyzzy/wibble.pdb
1277          */
1278          Int mashedSzB = VG_(strlen)(pdbname) + VG_(strlen)(wpfx) + 50/*misc*/;
1279          HChar* mashed = ML_(dinfo_zalloc)("di.debuginfo.dnpdi.1", mashedSzB);
1280          VG_(snprintf)(mashed, mashedSzB, "%s/drive_%c%s",
1281                        wpfx, pdbname[0], &pdbname[2]);
1282          vg_assert(mashed[mashedSzB-1] == 0);
1283          ML_(dinfo_free)(pdbname);
1284          pdbname = mashed;
1285       }
1286       else if (is_quald && home && !wpfx) {
1287          /* Change e:/foo/bar/xyzzy/wibble.pdb
1288                 to $HOME/.wine/drive_e/foo/bar/xyzzy/wibble.pdb
1289          */
1290          Int mashedSzB = VG_(strlen)(pdbname) + VG_(strlen)(home) + 50/*misc*/;
1291          HChar* mashed = ML_(dinfo_zalloc)("di.debuginfo.dnpdi.2", mashedSzB);
1292          VG_(snprintf)(mashed, mashedSzB, "%s/.wine/drive_%c%s",
1293 		       home, pdbname[0], &pdbname[2]);
1294          vg_assert(mashed[mashedSzB-1] == 0);
1295          ML_(dinfo_free)(pdbname);
1296          pdbname = mashed;
1297       } else {
1298          /* It's not a fully qualified path, or neither $HOME nor $WINE
1299             are set (strange).  Give up. */
1300          ML_(dinfo_free)(pdbname);
1301          pdbname = NULL;
1302       }
1303    }
1304 
1305    /* Try s/exe/pdb/ if we don't have a valid pdbname. */
1306    if (!pdbname) {
1307       /* Try to find a matching PDB file from which to read debuginfo.
1308          Windows PE files have symbol tables and line number information,
1309          but MSVC doesn't seem to use them. */
1310       /* Why +5 ?  Because in the worst case, we could find a dot as the
1311          last character of pdbname, and we'd then put "pdb" right after
1312          it, hence extending it a bit. */
1313       pdbname = ML_(dinfo_zalloc)("di.debuginfo.lpd1", sz_exename+5);
1314       VG_(strcpy)(pdbname, exename);
1315       vg_assert(pdbname[sz_exename+5-1] == 0);
1316       dot = VG_(strrchr)(pdbname, '.');
1317       if (!dot)
1318          goto out; /* there's no dot in the exe's name ?! */
1319       if (dot[1] == 0)
1320          goto out; /* hmm, path ends in "." */
1321 
1322       if ('A' <= dot[1] && dot[1] <= 'Z')
1323          VG_(strcpy)(dot, ".PDB");
1324       else
1325          VG_(strcpy)(dot, ".pdb");
1326 
1327       vg_assert(pdbname[sz_exename+5-1] == 0);
1328    }
1329 
1330    /* See if we can find it, and check it's in-dateness. */
1331    sres = VG_(stat)(pdbname, &stat_buf);
1332    if (sr_isError(sres)) {
1333       VG_(message)(Vg_UserMsg, "Warning: Missing or un-stat-able %s\n",
1334                                pdbname);
1335    if (VG_(clo_verbosity) > 0)
1336       VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: missing: %s\n", pdbname);
1337       goto out;
1338    }
1339    pdb_mtime = stat_buf.mtime;
1340 
1341    if (obj_mtime > pdb_mtime + 60ULL) {
1342       /* PDB file is older than PE file.  Really, the PDB should be
1343          newer than the PE, but that doesn't always seem to be the
1344          case.  Allow the PDB to be up to one minute older.
1345          Otherwise, it's probably out of date, in which case ignore it
1346          or we will either (a) print wrong stack traces or more likely
1347          (b) crash.
1348       */
1349       VG_(message)(Vg_UserMsg,
1350                    "Warning:       %s (mtime = %llu)\n"
1351                    " is older than %s (mtime = %llu)\n",
1352                    pdbname, pdb_mtime, exename, obj_mtime);
1353    }
1354 
1355    sres = VG_(open)(pdbname, VKI_O_RDONLY, 0);
1356    if (sr_isError(sres)) {
1357       VG_(message)(Vg_UserMsg, "Warning: Can't open %s\n", pdbname);
1358       goto out;
1359    }
1360 
1361    /* Looks promising; go on to try and read stuff from it.  But don't
1362       mmap the file.  Instead mmap free space and read the file into
1363       it.  This is because files on CIFS filesystems that are mounted
1364       '-o directio' can't be mmap'd, and that mount option is needed
1365       to make CIFS work reliably.  (See
1366       http://www.nabble.com/Corrupted-data-on-write-to-
1367                             Windows-2003-Server-t2782623.html)
1368       This is slower, but at least it works reliably. */
1369    fd_pdbimage = sr_Res(sres);
1370    n_pdbimage  = stat_buf.size;
1371    if (n_pdbimage == 0 || n_pdbimage > 0x7FFFFFFF) {
1372       // 0x7FFFFFFF: why?  Because the VG_(read) just below only
1373       // can deal with a signed int as the size of data to read,
1374       // so we can't reliably check for read failure for files
1375       // greater than that size.  Hence just skip them; we're
1376       // unlikely to encounter a PDB that large anyway.
1377       VG_(close)(fd_pdbimage);
1378       goto out;
1379    }
1380    sres = VG_(am_mmap_anon_float_valgrind)( n_pdbimage );
1381    if (sr_isError(sres)) {
1382       VG_(close)(fd_pdbimage);
1383       goto out;
1384    }
1385 
1386    void* pdbimage = (void*)sr_Res(sres);
1387    r = VG_(read)( fd_pdbimage, pdbimage, (Int)n_pdbimage );
1388    if (r < 0 || r != (Int)n_pdbimage) {
1389       VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage );
1390       VG_(close)(fd_pdbimage);
1391       goto out;
1392    }
1393 
1394    if (VG_(clo_verbosity) > 0)
1395       VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: pdbname: %s\n", pdbname);
1396 
1397    /* play safe; always invalidate the CFI cache.  I don't know if
1398       this is necessary, but anyway .. */
1399    cfsi_m_cache__invalidate();
1400    /* dump old info for this range, if any */
1401    discard_syms_in_range( avma_obj, total_size );
1402 
1403    { DebugInfo* di = find_or_create_DebugInfo_for(exename);
1404 
1405      /* this di must be new, since we just nuked any old stuff in the range */
1406      vg_assert(di && !di->fsm.have_rx_map && !di->fsm.have_rw_map);
1407      vg_assert(!di->have_dinfo);
1408 
1409      /* don't set up any of the di-> fields; let
1410         ML_(read_pdb_debug_info) do it. */
1411      ML_(read_pdb_debug_info)( di, avma_obj, bias_obj,
1412                                pdbimage, n_pdbimage, pdbname, pdb_mtime );
1413      // JRS fixme: take notice of return value from read_pdb_debug_info,
1414      // and handle failure
1415      vg_assert(di->have_dinfo); // fails if PDB read failed
1416      VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage );
1417      VG_(close)(fd_pdbimage);
1418 
1419      if (VG_(clo_verbosity) > 0) {
1420         VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: done:    "
1421                                  "%lu syms, %lu src locs, %lu fpo recs\n",
1422                      di->symtab_used, di->loctab_used, di->fpo_size);
1423      }
1424    }
1425 
1426   out:
1427    if (pdbname) ML_(dinfo_free)(pdbname);
1428 }
1429 
1430 #endif /* defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) */
1431 
1432 
1433 /*------------------------------------------------------------*/
1434 /*---                                                      ---*/
1435 /*--- TOP LEVEL: QUERYING EXISTING DEBUG INFO              ---*/
1436 /*---                                                      ---*/
1437 /*------------------------------------------------------------*/
1438 
VG_(di_discard_ALL_debuginfo)1439 void VG_(di_discard_ALL_debuginfo)( void )
1440 {
1441    DebugInfo *di, *di2;
1442    di = debugInfo_list;
1443    while (di) {
1444       di2 = di->next;
1445       VG_(printf)("XXX rm %p\n", di);
1446       free_DebugInfo( di );
1447       di = di2;
1448    }
1449 }
1450 
1451 
ML_(find_rx_mapping)1452 DebugInfoMapping* ML_(find_rx_mapping) ( DebugInfo* di, Addr lo, Addr hi )
1453 {
1454    Word i;
1455    vg_assert(lo <= hi);
1456 
1457    /* Optimization: Try to use the last matched rx mapping first */
1458    if (   di->last_rx_map
1459        && lo >= di->last_rx_map->avma
1460        && hi <  di->last_rx_map->avma + di->last_rx_map->size)
1461       return di->last_rx_map;
1462 
1463    for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1464       DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1465       if (   map->rx && map->size > 0
1466           && lo >= map->avma && hi < map->avma + map->size) {
1467          di->last_rx_map = map;
1468          return map;
1469       }
1470    }
1471 
1472    return NULL;
1473 }
1474 
1475 /*------------------------------------------------------------*/
1476 /*--- Types and functions for inlined IP cursor            ---*/
1477 /*------------------------------------------------------------*/
1478 struct _InlIPCursor {
1479    Addr eip;             // Cursor used to describe calls at eip.
1480    DebugInfo* di;        // DebugInfo describing inlined calls at eip
1481 
1482    Word    inltab_lopos; // The inlined fn calls covering eip are in
1483    Word    inltab_hipos; // di->inltab[inltab_lopos..inltab_hipos].
1484                          // Note that not all inlined fn calls in this range
1485                          // are necessarily covering eip.
1486 
1487    Int   curlevel;       // Current level to describe.
1488                          // 0 means to describe eip itself.
1489    Word  cur_inltab;     // inltab pos for call inlined at current level.
1490    Word  next_inltab;    // inltab pos for call inlined at next (towards main)
1491                          // level.
1492 };
1493 
is_top(const InlIPCursor * iipc)1494 static Bool is_top(const InlIPCursor *iipc)
1495 {
1496    return !iipc || iipc->cur_inltab == -1;
1497 }
1498 
is_bottom(const InlIPCursor * iipc)1499 static Bool is_bottom(const InlIPCursor *iipc)
1500 {
1501    return !iipc || iipc->next_inltab == -1;
1502 }
1503 
VG_(next_IIPC)1504 Bool VG_(next_IIPC)(InlIPCursor *iipc)
1505 {
1506    Word i;
1507    DiInlLoc *hinl = NULL;
1508    Word hinl_pos = -1;
1509    DebugInfo *di;
1510 
1511    if (iipc == NULL)
1512       return False;
1513 
1514    if (iipc->curlevel <= 0) {
1515       iipc->curlevel--;
1516       return False;
1517    }
1518 
1519    di = iipc->di;
1520    for (i = iipc->inltab_lopos; i <= iipc->inltab_hipos; i++) {
1521       if (di->inltab[i].addr_lo <= iipc->eip
1522           && iipc->eip < di->inltab[i].addr_hi
1523           && di->inltab[i].level < iipc->curlevel
1524           && (!hinl || hinl->level < di->inltab[i].level)) {
1525          hinl = &di->inltab[i];
1526          hinl_pos = i;
1527       }
1528    }
1529 
1530    iipc->cur_inltab = iipc->next_inltab;
1531    iipc->next_inltab = hinl_pos;
1532    if (iipc->next_inltab < 0)
1533       iipc->curlevel = 0; // no inlined call anymore, describe eip itself
1534    else
1535       iipc->curlevel = di->inltab[iipc->next_inltab].level;
1536 
1537    return True;
1538 }
1539 
1540 /* Forward */
1541 static void search_all_loctabs ( Addr ptr, /*OUT*/DebugInfo** pdi,
1542                                            /*OUT*/Word* locno );
1543 
1544 /* Returns the position after which eip would be inserted in inltab.
1545    (-1 if eip should be inserted before position 0).
1546    This is the highest position with an addr_lo <= eip.
1547    As inltab is sorted on addr_lo, dichotomic search can be done
1548    (note that inltab might have duplicates addr_lo). */
inltab_insert_pos(DebugInfo * di,Addr eip)1549 static Word inltab_insert_pos (DebugInfo *di, Addr eip)
1550 {
1551    Word mid,
1552         lo = 0,
1553         hi = di->inltab_used-1;
1554    while (lo <= hi) {
1555       mid      = (lo + hi) / 2;
1556       if (eip < di->inltab[mid].addr_lo) { hi = mid-1; continue; }
1557       if (eip > di->inltab[mid].addr_lo) { lo = mid+1; continue; }
1558       lo = mid; break;
1559    }
1560 
1561    while (lo <= di->inltab_used-1 && di->inltab[lo].addr_lo <= eip)
1562       lo++;
1563 #if 0
1564    for (mid = 0; mid <= di->inltab_used-1; mid++)
1565       if (eip < di->inltab[mid].addr_lo)
1566          break;
1567    vg_assert (lo - 1 == mid - 1);
1568 #endif
1569    return lo - 1;
1570 }
1571 
VG_(new_IIPC)1572 InlIPCursor* VG_(new_IIPC)(Addr eip)
1573 {
1574    DebugInfo*  di;
1575    Word        locno;
1576    Word        i;
1577    InlIPCursor *ret;
1578    Bool        avail;
1579 
1580    if (!VG_(clo_read_inline_info))
1581       return NULL; // No way we can find inlined calls.
1582 
1583    /* Search the DebugInfo for eip */
1584    search_all_loctabs ( eip, &di, &locno );
1585    if (di == NULL || di->inltab_used == 0)
1586       return NULL; // No di (with inltab) containing eip.
1587 
1588    /* Search the entry in di->inltab with the highest addr_lo that
1589       contains eip. */
1590    /* We start from the highest pos in inltab after which eip would
1591       be inserted. */
1592    for (i = inltab_insert_pos (di, eip); i >= 0; i--) {
1593       if (di->inltab[i].addr_lo <= eip && eip < di->inltab[i].addr_hi) {
1594          break;
1595       }
1596       /* Stop the backward scan when reaching an addr_lo which
1597          cannot anymore contain eip : we know that all ranges before
1598          i also cannot contain eip. */
1599       if (di->inltab[i].addr_lo < eip - di->maxinl_codesz)
1600          return NULL;
1601    }
1602 
1603    if (i < 0)
1604       return NULL; // No entry containing eip.
1605 
1606    /* We have found the highest entry containing eip.
1607       Build a cursor. */
1608    ret = ML_(dinfo_zalloc) ("dinfo.new_IIPC", sizeof(*ret));
1609    ret->eip = eip;
1610    ret->di = di;
1611    ret->inltab_hipos = i;
1612    for (i = ret->inltab_hipos - 1; i >= 0; i--) {
1613 
1614       if (di->inltab[i].addr_lo < eip - di->maxinl_codesz)
1615          break; /* Similar stop backward scan logic as above. */
1616    }
1617    ret->inltab_lopos = i + 1;
1618    ret->curlevel = MAX_LEVEL;
1619    ret->cur_inltab = -1;
1620    ret->next_inltab = -1;
1621 
1622    /* MAX_LEVEL is higher than any stored level. We can use
1623       VG_(next_IIPC) to get to the 'real' first highest call level. */
1624    avail = VG_(next_IIPC) (ret);
1625    vg_assert (avail);
1626 
1627    return ret;
1628 }
1629 
VG_(delete_IIPC)1630 void VG_(delete_IIPC)(InlIPCursor *iipc)
1631 {
1632    if (iipc)
1633       ML_(dinfo_free)( iipc );
1634 }
1635 
1636 
1637 /*------------------------------------------------------------*/
1638 /*--- Use of symbol table & location info to create        ---*/
1639 /*--- plausible-looking stack dumps.                       ---*/
1640 /*------------------------------------------------------------*/
1641 
1642 /* Search all symtabs that we know about to locate ptr.  If found, set
1643    *pdi to the relevant DebugInfo, and *symno to the symtab entry
1644    *number within that.  If not found, *psi is set to NULL.
1645    If findText==True,  only text symbols are searched for.
1646    If findText==False, only data symbols are searched for.
1647 */
search_all_symtabs(Addr ptr,DebugInfo ** pdi,Word * symno,Bool match_anywhere_in_sym,Bool findText)1648 static void search_all_symtabs ( Addr ptr, /*OUT*/DebugInfo** pdi,
1649                                            /*OUT*/Word* symno,
1650                                  Bool match_anywhere_in_sym,
1651                                  Bool findText )
1652 {
1653    Word       sno;
1654    DebugInfo* di;
1655    Bool       inRange;
1656 
1657    for (di = debugInfo_list; di != NULL; di = di->next) {
1658 
1659       if (findText) {
1660          /* Consider any symbol in the r-x mapped area to be text.
1661             See Comment_Regarding_Text_Range_Checks in storage.c for
1662             details. */
1663          inRange = di->fsm.have_rx_map
1664                    && (ML_(find_rx_mapping)(di, ptr, ptr) != NULL);
1665       } else {
1666          inRange = (di->data_present
1667                     && di->data_size > 0
1668                     && di->data_avma <= ptr
1669                     && ptr < di->data_avma + di->data_size)
1670                    ||
1671                    (di->sdata_present
1672                     && di->sdata_size > 0
1673                     && di->sdata_avma <= ptr
1674                     && ptr < di->sdata_avma + di->sdata_size)
1675                    ||
1676                    (di->bss_present
1677                     && di->bss_size > 0
1678                     && di->bss_avma <= ptr
1679                     && ptr < di->bss_avma + di->bss_size)
1680                    ||
1681                    (di->sbss_present
1682                     && di->sbss_size > 0
1683                     && di->sbss_avma <= ptr
1684                     && ptr < di->sbss_avma + di->sbss_size)
1685                    ||
1686                    (di->rodata_present
1687                     && di->rodata_size > 0
1688                     && di->rodata_avma <= ptr
1689                     && ptr < di->rodata_avma + di->rodata_size);
1690       }
1691 
1692       if (!inRange) continue;
1693 
1694       sno = ML_(search_one_symtab) (
1695                di, ptr, match_anywhere_in_sym, findText );
1696       if (sno == -1) goto not_found;
1697       *symno = sno;
1698       *pdi = di;
1699       return;
1700 
1701    }
1702   not_found:
1703    *pdi = NULL;
1704 }
1705 
1706 
1707 /* Search all loctabs that we know about to locate ptr.  If found, set
1708    *pdi to the relevant DebugInfo, and *locno to the loctab entry
1709    *number within that.  If not found, *pdi is set to NULL. */
search_all_loctabs(Addr ptr,DebugInfo ** pdi,Word * locno)1710 static void search_all_loctabs ( Addr ptr, /*OUT*/DebugInfo** pdi,
1711                                            /*OUT*/Word* locno )
1712 {
1713    Word       lno;
1714    DebugInfo* di;
1715    for (di = debugInfo_list; di != NULL; di = di->next) {
1716       if (di->text_present
1717           && di->text_size > 0
1718           && di->text_avma <= ptr
1719           && ptr < di->text_avma + di->text_size) {
1720          lno = ML_(search_one_loctab) ( di, ptr );
1721          if (lno == -1) goto not_found;
1722          *locno = lno;
1723          *pdi = di;
1724          return;
1725       }
1726    }
1727   not_found:
1728    *pdi = NULL;
1729 }
1730 
1731 
1732 /* The whole point of this whole big deal: map a code address to a
1733    plausible symbol name.  Returns False if no idea; otherwise True.
1734    Caller supplies buf.  If do_cxx_demangling is False, don't do
1735    C++ demangling, regardless of VG_(clo_demangle) -- probably because the
1736    call has come from VG_(get_fnname_raw)().  findText
1737    indicates whether we're looking for a text symbol or a data symbol
1738    -- caller must choose one kind or the other.
1739    Note: the string returned in *BUF is persistent as long as
1740    (1) the DebugInfo it belongs to is not discarded
1741    (2) the segment containing the address is not merged with another segment
1742    (3) the demangler is not invoked again
1743    In other words: if in doubt, save it away.
1744    Also, the returned string is owned by "somebody else". Callers must
1745    not free it or modify it. */
1746 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)1747 Bool get_sym_name ( Bool do_cxx_demangling, Bool do_z_demangling,
1748                     Bool do_below_main_renaming,
1749                     Addr a, const HChar** buf,
1750                     Bool match_anywhere_in_sym, Bool show_offset,
1751                     Bool findText, /*OUT*/PtrdiffT* offsetP )
1752 {
1753    DebugInfo* di;
1754    Word       sno;
1755    PtrdiffT   offset;
1756 
1757    search_all_symtabs ( a, &di, &sno, match_anywhere_in_sym, findText );
1758    if (di == NULL) {
1759       *buf = "";
1760       return False;
1761    }
1762 
1763    vg_assert(di->symtab[sno].pri_name);
1764    VG_(demangle) ( do_cxx_demangling, do_z_demangling,
1765                    di->symtab[sno].pri_name, buf );
1766 
1767    /* Do the below-main hack */
1768    // To reduce the endless nuisance of multiple different names
1769    // for "the frame below main()" screwing up the testsuite, change all
1770    // known incarnations of said into a single name, "(below main)", if
1771    // --show-below-main=yes.
1772    if ( do_below_main_renaming && ! VG_(clo_show_below_main) &&
1773         Vg_FnNameBelowMain == VG_(get_fnname_kind)(*buf) )
1774    {
1775      *buf = "(below main)";
1776    }
1777    offset = a - di->symtab[sno].avmas.main;
1778    if (offsetP) *offsetP = offset;
1779 
1780    if (show_offset && offset != 0) {
1781       static HChar *bufwo;      // buf with offset
1782       static SizeT  bufwo_szB;
1783       SizeT  need, len;
1784 
1785       len = VG_(strlen)(*buf);
1786       need = len + 1 + 19 + 1;
1787       if (need > bufwo_szB) {
1788         bufwo = ML_(dinfo_realloc)("get_sym_size", bufwo, need);
1789         bufwo_szB = need;
1790       }
1791 
1792       VG_(strcpy)(bufwo, *buf);
1793       VG_(sprintf)(bufwo + len, "%c%ld",
1794                    offset < 0 ? '-' : '+',
1795                    offset < 0 ? -offset : offset);
1796       *buf = bufwo;
1797    }
1798 
1799    return True;
1800 }
1801 
1802 /* ppc64be-linux only: find the TOC pointer (R2 value) that should be in
1803    force at the entry point address of the function containing
1804    guest_code_addr.  Returns 0 if not known. */
VG_(get_tocptr)1805 Addr VG_(get_tocptr) ( Addr guest_code_addr )
1806 {
1807 #if defined(VGA_ppc64be) || defined(VGA_ppc64le)
1808    DebugInfo* si;
1809    Word       sno;
1810    search_all_symtabs ( guest_code_addr,
1811                         &si, &sno,
1812                         True/*match_anywhere_in_fun*/,
1813                         True/*consider text symbols only*/ );
1814    if (si == NULL)
1815       return 0;
1816    else
1817       return GET_TOCPTR_AVMA(si->symtab[sno].avmas);
1818 #else
1819    return 0;
1820 #endif
1821 }
1822 
1823 /* This is available to tools... always demangle C++ names,
1824    match anywhere in function, but don't show offsets.
1825    NOTE: See important comment about the persistence and memory ownership
1826    of the return string at function get_sym_name */
VG_(get_fnname)1827 Bool VG_(get_fnname) ( Addr a, const HChar** buf )
1828 {
1829    return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True,
1830                          /*below-main-renaming*/True,
1831                          a, buf,
1832                          /*match_anywhere_in_fun*/True,
1833                          /*show offset?*/False,
1834                          /*text syms only*/True,
1835                          /*offsetP*/NULL );
1836 }
1837 
1838 /* This is available to tools... always demangle C++ names,
1839    match anywhere in function, and show offset if nonzero.
1840    NOTE: See important comment about the persistence and memory ownership
1841    of the return string at function get_sym_name */
VG_(get_fnname_w_offset)1842 Bool VG_(get_fnname_w_offset) ( Addr a, const HChar** buf )
1843 {
1844    return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True,
1845                          /*below-main-renaming*/True,
1846                          a, buf,
1847                          /*match_anywhere_in_fun*/True,
1848                          /*show offset?*/True,
1849                          /*text syms only*/True,
1850                          /*offsetP*/NULL );
1851 }
1852 
1853 /* This is available to tools... always demangle C++ names,
1854    only succeed if 'a' matches first instruction of function,
1855    and don't show offsets.
1856    NOTE: See important comment about the persistence and memory ownership
1857    of the return string at function get_sym_name */
VG_(get_fnname_if_entry)1858 Bool VG_(get_fnname_if_entry) ( Addr a, const HChar** buf )
1859 {
1860    const HChar *tmp;
1861    Bool res;
1862 
1863    res =  get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True,
1864                          /*below-main-renaming*/True,
1865                          a, &tmp,
1866                          /*match_anywhere_in_fun*/False,
1867                          /*show offset?*/False,
1868                          /*text syms only*/True,
1869                          /*offsetP*/NULL );
1870    if (res)
1871       *buf = tmp;
1872    return res;
1873 }
1874 
1875 /* This is only available to core... don't C++-demangle, don't Z-demangle,
1876    don't rename below-main, match anywhere in function, and don't show
1877    offsets.
1878    NOTE: See important comment about the persistence and memory ownership
1879    of the return string at function get_sym_name */
VG_(get_fnname_raw)1880 Bool VG_(get_fnname_raw) ( Addr a, const HChar** buf )
1881 {
1882    return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False,
1883                          /*below-main-renaming*/False,
1884                          a, buf,
1885                          /*match_anywhere_in_fun*/True,
1886                          /*show offset?*/False,
1887                          /*text syms only*/True,
1888                          /*offsetP*/NULL );
1889 }
1890 
1891 /* This is only available to core... don't demangle C++ names, but do
1892    do Z-demangling and below-main-renaming, match anywhere in function, and
1893    don't show offsets.
1894    NOTE: See important comment about the persistence and memory ownership
1895    of the return string at function get_sym_name */
VG_(get_fnname_no_cxx_demangle)1896 Bool VG_(get_fnname_no_cxx_demangle) ( Addr a, const HChar** buf,
1897                                        const InlIPCursor* iipc )
1898 {
1899    if (is_bottom(iipc)) {
1900       // At the bottom (towards main), we describe the fn at eip.
1901       return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/True,
1902                             /*below-main-renaming*/True,
1903                             a, buf,
1904                             /*match_anywhere_in_fun*/True,
1905                             /*show offset?*/False,
1906                             /*text syms only*/True,
1907                             /*offsetP*/NULL );
1908    } else {
1909       const DiInlLoc *next_inl = iipc && iipc->next_inltab >= 0
1910          ? & iipc->di->inltab[iipc->next_inltab]
1911          : NULL;
1912       vg_assert (next_inl);
1913       // The function we are in is called by next_inl.
1914       *buf = next_inl->inlinedfn;
1915       return True;
1916    }
1917 }
1918 
1919 /* mips-linux only: find the offset of current address. This is needed for
1920    stack unwinding for MIPS.
1921 */
VG_(get_inst_offset_in_function)1922 Bool VG_(get_inst_offset_in_function)( Addr a,
1923                                        /*OUT*/PtrdiffT* offset )
1924 {
1925    const HChar *fnname;
1926    return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False,
1927                          /*below-main-renaming*/False,
1928                          a, &fnname,
1929                          /*match_anywhere_in_sym*/True,
1930                          /*show offset?*/False,
1931                          /*text syms only*/True,
1932                          offset );
1933 }
1934 
VG_(get_fnname_kind)1935 Vg_FnNameKind VG_(get_fnname_kind) ( const HChar* name )
1936 {
1937    if (VG_STREQ("main", name)) {
1938       return Vg_FnNameMain;
1939 
1940    } else if (
1941 #      if defined(VGO_linux)
1942        VG_STREQ("__libc_start_main",  name) ||  // glibc glibness
1943        VG_STREQ("generic_start_main", name) ||  // Yellow Dog doggedness
1944 #      elif defined(VGO_darwin)
1945        // See readmacho.c for an explanation of this.
1946        VG_STREQ("start_according_to_valgrind", name) ||  // Darwin, darling
1947 #      elif defined(VGO_solaris)
1948        VG_STREQ("_start", name) || // main() is called directly from _start
1949 #      else
1950 #        error "Unknown OS"
1951 #      endif
1952        0) {
1953       return Vg_FnNameBelowMain;
1954 
1955    } else {
1956       return Vg_FnNameNormal;
1957    }
1958 }
1959 
VG_(get_fnname_kind_from_IP)1960 Vg_FnNameKind VG_(get_fnname_kind_from_IP) ( Addr ip )
1961 {
1962    const HChar *buf;
1963 
1964    // We don't demangle, because it's faster not to, and the special names
1965    // we're looking for won't be mangled.
1966    if (VG_(get_fnname_raw) ( ip, &buf )) {
1967 
1968       return VG_(get_fnname_kind)(buf);
1969    } else {
1970       return Vg_FnNameNormal;    // Don't know the name, treat it as normal.
1971    }
1972 }
1973 
1974 /* Looks up data_addr in the collection of data symbols, and if found
1975    puts a pointer to its name into dname. The name is zero terminated.
1976    Also data_addr's offset from the symbol start is put into *offset.
1977    NOTE: See important comment about the persistence and memory ownership
1978    of the return string at function get_sym_name */
VG_(get_datasym_and_offset)1979 Bool VG_(get_datasym_and_offset)( Addr data_addr,
1980                                   /*OUT*/const HChar** dname,
1981                                   /*OUT*/PtrdiffT* offset )
1982 {
1983    return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False,
1984                        /*below-main-renaming*/False,
1985                        data_addr, dname,
1986                        /*match_anywhere_in_sym*/True,
1987                        /*show offset?*/False,
1988                        /*data syms only please*/False,
1989                        offset );
1990 }
1991 
1992 /* Map a code address to the name of a shared object file or the
1993    executable.  Returns False if no idea; otherwise True.
1994    Note: the string returned in *BUF is persistent as long as
1995    (1) the DebugInfo it belongs to is not discarded
1996    (2) the segment containing the address is not merged with another segment
1997 */
VG_(get_objname)1998 Bool VG_(get_objname) ( Addr a, const HChar** buf )
1999 {
2000    DebugInfo* di;
2001    const NSegment *seg;
2002    const HChar* filename;
2003 
2004    /* Look in the debugInfo_list to find the name.  In most cases we
2005       expect this to produce a result. */
2006    for (di = debugInfo_list; di != NULL; di = di->next) {
2007       if (di->text_present
2008           && di->text_size > 0
2009           && di->text_avma <= a
2010           && a < di->text_avma + di->text_size) {
2011          *buf = di->fsm.filename;
2012          return True;
2013       }
2014    }
2015    /* Last-ditch fallback position: if we don't find the address in
2016       the debugInfo_list, ask the address space manager whether it
2017       knows the name of the file associated with this mapping.  This
2018       allows us to print the names of exe/dll files in the stack trace
2019       when running programs under wine. */
2020    if ( (seg = VG_(am_find_nsegment(a))) != NULL
2021         && (filename = VG_(am_get_filename)(seg)) != NULL ) {
2022      *buf = filename;
2023       return True;
2024    }
2025    return False;
2026 }
2027 
2028 /* Map a code address to its DebugInfo.  Returns NULL if not found.  Doesn't
2029    require debug info. */
VG_(find_DebugInfo)2030 DebugInfo* VG_(find_DebugInfo) ( Addr a )
2031 {
2032    static UWord n_search = 0;
2033    DebugInfo* di;
2034    n_search++;
2035    for (di = debugInfo_list; di != NULL; di = di->next) {
2036       if (di->text_present
2037           && di->text_size > 0
2038           && di->text_avma <= a
2039           && a < di->text_avma + di->text_size) {
2040          if (0 == (n_search & 0xF))
2041             move_DebugInfo_one_step_forward( di );
2042          return di;
2043       }
2044    }
2045    return NULL;
2046 }
2047 
2048 /* Map a code address to a filename.  Returns True if successful. The
2049    returned string is persistent as long as the DebugInfo to which it
2050    belongs is not discarded. */
VG_(get_filename)2051 Bool VG_(get_filename)( Addr a, const HChar** filename )
2052 {
2053    DebugInfo* si;
2054    Word       locno;
2055    UInt       fndn_ix;
2056 
2057    search_all_loctabs ( a, &si, &locno );
2058    if (si == NULL)
2059       return False;
2060    fndn_ix = ML_(fndn_ix) (si, locno);
2061    *filename = ML_(fndn_ix2filename) (si, fndn_ix);
2062    return True;
2063 }
2064 
2065 /* Map a code address to a line number.  Returns True if successful. */
VG_(get_linenum)2066 Bool VG_(get_linenum)( Addr a, UInt* lineno )
2067 {
2068    DebugInfo* si;
2069    Word       locno;
2070    search_all_loctabs ( a, &si, &locno );
2071    if (si == NULL)
2072       return False;
2073    *lineno = si->loctab[locno].lineno;
2074 
2075    return True;
2076 }
2077 
2078 /* Map a code address to a filename/line number/dir name info.
2079    See prototype for detailed description of behaviour.
2080 */
VG_(get_filename_linenum)2081 Bool VG_(get_filename_linenum) ( Addr a,
2082                                  /*OUT*/const HChar** filename,
2083                                  /*OUT*/const HChar** dirname,
2084                                  /*OUT*/UInt* lineno )
2085 {
2086    DebugInfo* si;
2087    Word       locno;
2088    UInt       fndn_ix;
2089 
2090    search_all_loctabs ( a, &si, &locno );
2091    if (si == NULL) {
2092       if (dirname) {
2093          *dirname = "";
2094       }
2095       *filename = "";      // this used to be not initialised....
2096       return False;
2097    }
2098 
2099    fndn_ix = ML_(fndn_ix)(si, locno);
2100    *filename = ML_(fndn_ix2filename) (si, fndn_ix);
2101    *lineno = si->loctab[locno].lineno;
2102 
2103    if (dirname) {
2104       /* caller wants directory info too .. */
2105       *dirname = ML_(fndn_ix2dirname) (si, fndn_ix);
2106    }
2107 
2108    return True;
2109 }
2110 
2111 
2112 /* Map a function name to its entry point and toc pointer.  Is done by
2113    sequential search of all symbol tables, so is very slow.  To
2114    mitigate the worst performance effects, you may specify a soname
2115    pattern, and only objects matching that pattern are searched.
2116    Therefore specify "*" to search all the objects.  On TOC-afflicted
2117    platforms, a symbol is deemed to be found only if it has a nonzero
2118    TOC pointer.  */
VG_(lookup_symbol_SLOW)2119 Bool VG_(lookup_symbol_SLOW)(const HChar* sopatt, const HChar* name,
2120                              SymAVMAs* avmas)
2121 {
2122    Bool     require_pToc = False;
2123    Int      i;
2124    const DebugInfo* si;
2125    Bool     debug = False;
2126 #  if defined(VG_PLAT_USES_PPCTOC)
2127    require_pToc = True;
2128 #  endif
2129    for (si = debugInfo_list; si; si = si->next) {
2130       if (debug)
2131          VG_(printf)("lookup_symbol_SLOW: considering %s\n", si->soname);
2132       if (!VG_(string_match)(sopatt, si->soname)) {
2133          if (debug)
2134             VG_(printf)(" ... skip\n");
2135          continue;
2136       }
2137       for (i = 0; i < si->symtab_used; i++) {
2138          const HChar* pri_name = si->symtab[i].pri_name;
2139          vg_assert(pri_name);
2140          if (0==VG_(strcmp)(name, pri_name)
2141              && (require_pToc ? GET_TOCPTR_AVMA(si->symtab[i].avmas) : True)) {
2142             *avmas = si->symtab[i].avmas;
2143             return True;
2144          }
2145          const HChar** sec_names = si->symtab[i].sec_names;
2146          if (sec_names) {
2147             vg_assert(sec_names[0]);
2148             while (*sec_names) {
2149                if (0==VG_(strcmp)(name, *sec_names)
2150                    && (require_pToc
2151                        ? GET_TOCPTR_AVMA(si->symtab[i].avmas) : True)) {
2152                   *avmas = si->symtab[i].avmas;
2153                   return True;
2154                }
2155                sec_names++;
2156             }
2157          }
2158       }
2159    }
2160    return False;
2161 }
2162 
2163 
2164 /* VG_(describe_IP): return info on code address, function name and
2165    filename. The returned string is allocated in a static buffer and will
2166    be overwritten in the next invocation. */
2167 
2168 /* Copy str into *buf starting at n, ensuring that buf is zero-terminated.
2169    Return the index of the terminating null character. */
2170 static SizeT
putStr(SizeT n,HChar ** buf,SizeT * bufsiz,const HChar * str)2171 putStr( SizeT n, HChar** buf, SizeT *bufsiz, const HChar* str )
2172 {
2173    SizeT slen = VG_(strlen)(str);
2174    SizeT need = n + slen + 1;
2175 
2176    if (need > *bufsiz) {
2177       if (need < 256) need = 256;
2178       *bufsiz = need;
2179       *buf = ML_(dinfo_realloc)("putStr", *buf, *bufsiz);
2180    }
2181 
2182    VG_(strcpy)(*buf + n, str);
2183 
2184    return n + slen;
2185 }
2186 
2187 /* Same as putStr, but escaping chars for XML output. */
2188 static SizeT
putStrEsc(SizeT n,HChar ** buf,SizeT * bufsiz,const HChar * str)2189 putStrEsc( SizeT n, HChar** buf, SizeT *bufsiz, const HChar* str )
2190 {
2191    HChar alt[2];
2192 
2193    for (; *str != 0; str++) {
2194       switch (*str) {
2195          case '&':
2196             n = putStr( n, buf, bufsiz, "&amp;");
2197             break;
2198          case '<':
2199             n = putStr( n, buf, bufsiz, "&lt;");
2200             break;
2201          case '>':
2202             n = putStr( n, buf, bufsiz, "&gt;");
2203             break;
2204          default:
2205             alt[0] = *str;
2206             alt[1] = 0;
2207             n = putStr( n, buf, bufsiz, alt );
2208             break;
2209       }
2210    }
2211    return n;
2212 }
2213 
VG_(describe_IP)2214 const HChar* VG_(describe_IP)(Addr eip, const InlIPCursor *iipc)
2215 {
2216    static HChar *buf = NULL;
2217    static SizeT bufsiz = 0;
2218 #  define APPEND(_str) \
2219       n = putStr(n, &buf, &bufsiz, _str)
2220 #  define APPEND_ESC(_str) \
2221       n = putStrEsc(n, &buf, &bufsiz, _str)
2222 
2223    UInt  lineno;
2224    HChar ibuf[50];   // large enough
2225    SizeT n = 0;
2226 
2227    vg_assert (!iipc || iipc->eip == eip);
2228 
2229    const HChar *buf_fn;
2230    const HChar *buf_obj;
2231    const HChar *buf_srcloc;
2232    const HChar *buf_dirname;
2233 
2234    Bool  know_dirinfo;
2235    Bool  know_fnname;
2236    Bool  know_objname;
2237    Bool  know_srcloc;
2238 
2239    if (is_bottom(iipc)) {
2240       // At the bottom (towards main), we describe the fn at eip.
2241       know_fnname = VG_(clo_sym_offsets)
2242                     ? VG_(get_fnname_w_offset) (eip, &buf_fn)
2243                     : VG_(get_fnname) (eip, &buf_fn);
2244    } else {
2245       const DiInlLoc *next_inl = iipc && iipc->next_inltab >= 0
2246          ? & iipc->di->inltab[iipc->next_inltab]
2247          : NULL;
2248       vg_assert (next_inl);
2249       // The function we are in is called by next_inl.
2250       buf_fn = next_inl->inlinedfn;
2251       know_fnname = True;
2252 
2253       // INLINED????
2254       // ??? Can we compute an offset for an inlined fn call ?
2255       // ??? Offset from what ? The beginning of the inl info ?
2256       // ??? But that is not necessarily the beginning of the fn
2257       // ??? as e.g. an inlined fn call can be in several ranges.
2258       // ??? Currently never showing an offset.
2259    }
2260 
2261    know_objname = VG_(get_objname)(eip, &buf_obj);
2262 
2263    if (is_top(iipc)) {
2264       // The source for the highest level is in the loctab entry.
2265       know_srcloc  = VG_(get_filename_linenum)(
2266                         eip,
2267                         &buf_srcloc,
2268                         &buf_dirname,
2269                         &lineno
2270                      );
2271       know_dirinfo = buf_dirname[0] != '\0';
2272    } else {
2273       const DiInlLoc *cur_inl = iipc && iipc->cur_inltab >= 0
2274          ? & iipc->di->inltab[iipc->cur_inltab]
2275          : NULL;
2276       vg_assert (cur_inl);
2277 
2278       know_dirinfo = False;
2279       buf_dirname  = "";
2280       // The fndn_ix and lineno for the caller of the inlined fn is in cur_inl.
2281       if (cur_inl->fndn_ix == 0) {
2282          buf_srcloc = "???";
2283       } else {
2284          FnDn *fndn = VG_(indexEltNumber) (iipc->di->fndnpool,
2285                                            cur_inl->fndn_ix);
2286          if (fndn->dirname) {
2287             buf_dirname = fndn->dirname;
2288             know_dirinfo = True;
2289          }
2290          buf_srcloc = fndn->filename;
2291       }
2292       lineno = cur_inl->lineno;
2293       know_srcloc = True;
2294    }
2295 
2296    if (VG_(clo_xml)) {
2297 
2298       Bool   human_readable = True;
2299       const HChar* maybe_newline  = human_readable ? "\n      " : "";
2300       const HChar* maybe_newline2 = human_readable ? "\n    "   : "";
2301 
2302       /* Print in XML format, dumping in as much info as we know.
2303          Ensure all tags are balanced. */
2304       APPEND("<frame>");
2305       VG_(sprintf)(ibuf,"<ip>0x%lX</ip>", eip);
2306       APPEND(maybe_newline);
2307       APPEND(ibuf);
2308       if (know_objname) {
2309          APPEND(maybe_newline);
2310          APPEND("<obj>");
2311          APPEND_ESC(buf_obj);
2312          APPEND("</obj>");
2313       }
2314       if (know_fnname) {
2315          APPEND(maybe_newline);
2316          APPEND("<fn>");
2317          APPEND_ESC(buf_fn);
2318          APPEND("</fn>");
2319       }
2320       if (know_srcloc) {
2321          if (know_dirinfo) {
2322             APPEND(maybe_newline);
2323             APPEND("<dir>");
2324             APPEND_ESC(buf_dirname);
2325             APPEND("</dir>");
2326          }
2327          APPEND(maybe_newline);
2328          APPEND("<file>");
2329          APPEND_ESC(buf_srcloc);
2330          APPEND("</file>");
2331          APPEND(maybe_newline);
2332          APPEND("<line>");
2333          VG_(sprintf)(ibuf,"%u",lineno);
2334          APPEND(ibuf);
2335          APPEND("</line>");
2336       }
2337       APPEND(maybe_newline2);
2338       APPEND("</frame>");
2339 
2340    } else {
2341 
2342       /* Print for humans to read */
2343       //
2344       // Possible forms:
2345       //
2346       //   0x80483BF: really (a.c:20)
2347       //   0x80483BF: really (in /foo/a.out)
2348       //   0x80483BF: really (in ???)
2349       //   0x80483BF: ??? (in /foo/a.out)
2350       //   0x80483BF: ??? (a.c:20)
2351       //   0x80483BF: ???
2352       //
2353       VG_(sprintf)(ibuf,"0x%lX: ", eip);
2354       APPEND(ibuf);
2355       if (know_fnname) {
2356          APPEND(buf_fn);
2357       } else {
2358          APPEND("???");
2359       }
2360       if (know_srcloc) {
2361          APPEND(" (");
2362          // Get the directory name, if any, possibly pruned, into dirname.
2363          const HChar* dirname = NULL;
2364          if (know_dirinfo && VG_(sizeXA)(VG_(clo_fullpath_after)) > 0) {
2365             Int i;
2366             dirname = buf_dirname;
2367             // Remove leading prefixes from the dirname.
2368             // If user supplied --fullpath-after=foo, this will remove
2369             // a leading string which matches '.*foo' (not greedy).
2370             for (i = 0; i < VG_(sizeXA)(VG_(clo_fullpath_after)); i++) {
2371                const HChar* prefix =
2372                   *(HChar**) VG_(indexXA)( VG_(clo_fullpath_after), i );
2373                HChar* str    = VG_(strstr)(dirname, prefix);
2374                if (str) {
2375                   dirname = str + VG_(strlen)(prefix);
2376                   break;
2377                }
2378             }
2379             /* remove leading "./" */
2380             if (dirname[0] == '.' && dirname[1] == '/')
2381                dirname += 2;
2382          }
2383          // do we have any interesting directory name to show?  If so
2384          // add it in.
2385          if (dirname && dirname[0] != 0) {
2386             APPEND(dirname);
2387             APPEND("/");
2388          }
2389          APPEND(buf_srcloc);
2390          APPEND(":");
2391          VG_(sprintf)(ibuf,"%u",lineno);
2392          APPEND(ibuf);
2393          APPEND(")");
2394       } else if (know_objname) {
2395          APPEND(" (in ");
2396          APPEND(buf_obj);
2397          APPEND(")");
2398       } else if (know_fnname) {
2399          // Nb: do this in two steps because "??)" is a trigraph!
2400          APPEND(" (in ???");
2401          APPEND(")");
2402       }
2403 
2404    }
2405    return buf;
2406 
2407 #  undef APPEND
2408 #  undef APPEND_ESC
2409 }
2410 
2411 
2412 /*--------------------------------------------------------------*/
2413 /*---                                                        ---*/
2414 /*--- TOP LEVEL: FOR UNWINDING THE STACK USING               ---*/
2415 /*---            DWARF3 .eh_frame INFO                       ---*/
2416 /*---                                                        ---*/
2417 /*--------------------------------------------------------------*/
2418 
2419 /* Gather up all the constant pieces of info needed to evaluate
2420    a CfiExpr into one convenient struct. */
2421 typedef
2422    struct {
2423       const D3UnwindRegs* uregs;
2424       Addr          min_accessible;
2425       Addr          max_accessible;
2426    }
2427    CfiExprEvalContext;
2428 
2429 /* Evaluate the CfiExpr rooted at ix in exprs given the context eec.
2430    *ok is set to False on failure, but not to True on success.  The
2431    caller must set it to True before calling. */
2432 __attribute__((noinline))
2433 static
evalCfiExpr(const XArray * exprs,Int ix,const CfiExprEvalContext * eec,Bool * ok)2434 UWord evalCfiExpr ( const XArray* exprs, Int ix,
2435                     const CfiExprEvalContext* eec, Bool* ok )
2436 {
2437    UWord w, wL, wR;
2438    Addr  a;
2439    const CfiExpr* e;
2440    vg_assert(sizeof(Addr) == sizeof(UWord));
2441    e = VG_(indexXA)( exprs, ix );
2442    switch (e->tag) {
2443       case Cex_Unop:
2444          w = evalCfiExpr( exprs, e->Cex.Unop.ix, eec, ok );
2445          if (!(*ok)) return 0;
2446          switch (e->Cex.Unop.op) {
2447             case Cunop_Abs: return (Word) w < 0 ? - w : w;
2448             case Cunop_Neg: return - (Word) w;
2449             case Cunop_Not: return ~ w;
2450             default: goto unhandled;
2451          }
2452          /*NOTREACHED*/
2453       case Cex_Binop:
2454          wL = evalCfiExpr( exprs, e->Cex.Binop.ixL, eec, ok );
2455          if (!(*ok)) return 0;
2456          wR = evalCfiExpr( exprs, e->Cex.Binop.ixR, eec, ok );
2457          if (!(*ok)) return 0;
2458          switch (e->Cex.Binop.op) {
2459             case Cbinop_Add: return wL + wR;
2460             case Cbinop_Sub: return wL - wR;
2461             case Cbinop_And: return wL & wR;
2462             case Cbinop_Mul: return wL * wR;
2463             case Cbinop_Shl: return wL << wR;
2464             case Cbinop_Shr: return wL >> wR;
2465             case Cbinop_Eq: return wL == wR ? 1 : 0;
2466             case Cbinop_Ge: return (Word) wL >= (Word) wR ? 1 : 0;
2467             case Cbinop_Gt: return (Word) wL > (Word) wR ? 1 : 0;
2468             case Cbinop_Le: return (Word) wL <= (Word) wR ? 1 : 0;
2469             case Cbinop_Lt: return (Word) wL < (Word) wR ? 1 : 0;
2470             case Cbinop_Ne: return wL != wR ? 1 : 0;
2471             default: goto unhandled;
2472          }
2473          /*NOTREACHED*/
2474       case Cex_CfiReg:
2475          switch (e->Cex.CfiReg.reg) {
2476 #           if defined(VGA_x86) || defined(VGA_amd64)
2477             case Creg_IA_IP: return eec->uregs->xip;
2478             case Creg_IA_SP: return eec->uregs->xsp;
2479             case Creg_IA_BP: return eec->uregs->xbp;
2480 #           elif defined(VGA_arm)
2481             case Creg_ARM_R15: return eec->uregs->r15;
2482             case Creg_ARM_R14: return eec->uregs->r14;
2483             case Creg_ARM_R13: return eec->uregs->r13;
2484             case Creg_ARM_R12: return eec->uregs->r12;
2485             case Creg_ARM_R7:  return eec->uregs->r7;
2486 #           elif defined(VGA_s390x)
2487             case Creg_S390_IA: return eec->uregs->ia;
2488             case Creg_S390_SP: return eec->uregs->sp;
2489             case Creg_S390_FP: return eec->uregs->fp;
2490             case Creg_S390_LR: return eec->uregs->lr;
2491 #           elif defined(VGA_mips32) || defined(VGA_mips64)
2492             case Creg_IA_IP: return eec->uregs->pc;
2493             case Creg_IA_SP: return eec->uregs->sp;
2494             case Creg_IA_BP: return eec->uregs->fp;
2495             case Creg_MIPS_RA: return eec->uregs->ra;
2496 #           elif defined(VGA_ppc32) || defined(VGA_ppc64be) \
2497                || defined(VGA_ppc64le)
2498 #           elif defined(VGP_arm64_linux)
2499             case Creg_ARM64_X30: return eec->uregs->x30;
2500 #           elif defined(VGA_tilegx)
2501             case Creg_TILEGX_IP: return eec->uregs->pc;
2502             case Creg_TILEGX_SP: return eec->uregs->sp;
2503             case Creg_TILEGX_BP: return eec->uregs->fp;
2504             case Creg_TILEGX_LR: return eec->uregs->lr;
2505 #           else
2506 #             error "Unsupported arch"
2507 #           endif
2508             default: goto unhandled;
2509          }
2510          /*NOTREACHED*/
2511       case Cex_Const:
2512          return e->Cex.Const.con;
2513       case Cex_Deref:
2514          a = evalCfiExpr( exprs, e->Cex.Deref.ixAddr, eec, ok );
2515          if (!(*ok)) return 0;
2516          if (a < eec->min_accessible
2517              || a > eec->max_accessible - sizeof(UWord) + 1) {
2518             *ok = False;
2519             return 0;
2520          }
2521          /* let's hope it doesn't trap! */
2522          return ML_(read_UWord)((void *)a);
2523       default:
2524          goto unhandled;
2525    }
2526    /*NOTREACHED*/
2527   unhandled:
2528    VG_(printf)("\n\nevalCfiExpr: unhandled\n");
2529    ML_(ppCfiExpr)( exprs, ix );
2530    VG_(printf)("\n");
2531    vg_assert(0);
2532    /*NOTREACHED*/
2533    return 0;
2534 }
2535 
2536 
2537 /* Search all the DebugInfos in the entire system, to find the DiCfSI_m
2538    that pertains to 'ip'.
2539 
2540    If found, set *diP to the DebugInfo in which it resides, and
2541    *cfsi_mP to the cfsi_m pointer in that DebugInfo's cfsi_m_pool.
2542 
2543    If not found, set *diP to (DebugInfo*)1 and *cfsi_mP to zero.
2544 */
2545 __attribute__((noinline))
find_DiCfSI(DebugInfo ** diP,DiCfSI_m ** cfsi_mP,Addr ip)2546 static void find_DiCfSI ( /*OUT*/DebugInfo** diP,
2547                           /*OUT*/DiCfSI_m** cfsi_mP,
2548                           Addr ip )
2549 {
2550    DebugInfo* di;
2551    Word       i = -1;
2552 
2553    static UWord n_search = 0;
2554    static UWord n_steps = 0;
2555    n_search++;
2556 
2557    if (0) VG_(printf)("search for %#lx\n", ip);
2558 
2559    for (di = debugInfo_list; di != NULL; di = di->next) {
2560       Word j;
2561       n_steps++;
2562 
2563       /* Use the per-DebugInfo summary address ranges to skip
2564          inapplicable DebugInfos quickly. */
2565       if (di->cfsi_used == 0)
2566          continue;
2567       if (ip < di->cfsi_minavma || ip > di->cfsi_maxavma)
2568          continue;
2569 
2570       /* It might be in this DebugInfo.  Search it. */
2571       j = ML_(search_one_cfitab)( di, ip );
2572       vg_assert(j >= -1 && j < (Word)di->cfsi_used);
2573 
2574       if (j != -1) {
2575          i = j;
2576          break; /* found it */
2577       }
2578    }
2579 
2580    if (i == -1) {
2581 
2582       /* we didn't find it. */
2583       *diP = (DebugInfo*)1;
2584       *cfsi_mP = 0;
2585 
2586    } else {
2587 
2588       /* found a di corresponding to ip. */
2589       /* ensure that di is 4-aligned (at least), so it can't possibly
2590          be equal to (DebugInfo*)1. */
2591       vg_assert(di && VG_IS_4_ALIGNED(di));
2592       *cfsi_mP = ML_(get_cfsi_m) (di, i);
2593       if (*cfsi_mP == NULL) {
2594          // This is a cfsi hole. Report no cfi information found.
2595          *diP = (DebugInfo*)1;
2596          // But we will still perform the hack below.
2597       } else {
2598          *diP = di;
2599       }
2600 
2601       /* Start of performance-enhancing hack: once every 64 (chosen
2602          hackily after profiling) successful searches, move the found
2603          DebugInfo one step closer to the start of the list.  This
2604          makes future searches cheaper.  For starting konqueror on
2605          amd64, this in fact reduces the total amount of searching
2606          done by the above find-the-right-DebugInfo loop by more than
2607          a factor of 20. */
2608       if ((n_search & 0xF) == 0) {
2609          /* Move di one step closer to the start of the list. */
2610          move_DebugInfo_one_step_forward( di );
2611       }
2612       /* End of performance-enhancing hack. */
2613 
2614       if (0 && ((n_search & 0x7FFFF) == 0))
2615          VG_(printf)("find_DiCfSI: %lu searches, "
2616                      "%lu DebugInfos looked at\n",
2617                      n_search, n_steps);
2618 
2619    }
2620 
2621 }
2622 
2623 
2624 /* Now follows a mechanism for caching queries to find_DiCfSI, since
2625    they are extremely frequent on amd64-linux, during stack unwinding.
2626 
2627    Each cache entry binds an ip value to a (di, cfsi_m*) pair.  Possible
2628    values:
2629 
2630    di is non-null, cfsi_m* >= 0  ==>  cache slot in use, "cfsi_m*"
2631    di is (DebugInfo*)1           ==>  cache slot in use, no associated di
2632    di is NULL                    ==>  cache slot not in use
2633 
2634    Hence simply zeroing out the entire cache invalidates all
2635    entries.
2636 
2637    We can map an ip value directly to a (di, cfsi_m*) pair as
2638    once a DebugInfo is read, adding new DiCfSI_m* is not possible
2639    anymore, as the cfsi_m_pool is frozen once the reading is terminated.
2640    Also, the cache is invalidated when new debuginfo is read due to
2641    an mmap or some debuginfo is discarded due to an munmap. */
2642 
2643 // Prime number, giving about 6Kbytes cache on 32 bits,
2644 //                           12Kbytes cache on 64 bits.
2645 #define N_CFSI_M_CACHE 509
2646 
2647 typedef
2648    struct { Addr ip; DebugInfo* di; DiCfSI_m* cfsi_m; }
2649    CFSI_m_CacheEnt;
2650 
2651 static CFSI_m_CacheEnt cfsi_m_cache[N_CFSI_M_CACHE];
2652 
cfsi_m_cache__invalidate(void)2653 static void cfsi_m_cache__invalidate ( void ) {
2654    VG_(memset)(&cfsi_m_cache, 0, sizeof(cfsi_m_cache));
2655    debuginfo_generation++;
2656 }
2657 
VG_(debuginfo_generation)2658 UInt VG_(debuginfo_generation) (void)
2659 {
2660    return debuginfo_generation;
2661 }
2662 
cfsi_m_cache__find(Addr ip)2663 static inline CFSI_m_CacheEnt* cfsi_m_cache__find ( Addr ip )
2664 {
2665    UWord         hash = ip % N_CFSI_M_CACHE;
2666    CFSI_m_CacheEnt* ce = &cfsi_m_cache[hash];
2667    static UWord  n_q = 0, n_m = 0;
2668 
2669    n_q++;
2670    if (0 && 0 == (n_q & 0x1FFFFF))
2671       VG_(printf)("QQQ %lu %lu\n", n_q, n_m);
2672 
2673    if (LIKELY(ce->ip == ip) && LIKELY(ce->di != NULL)) {
2674       /* found an entry in the cache .. */
2675    } else {
2676       /* not found in cache.  Search and update. */
2677       n_m++;
2678       ce->ip = ip;
2679       find_DiCfSI( &ce->di, &ce->cfsi_m, ip );
2680    }
2681 
2682    if (UNLIKELY(ce->di == (DebugInfo*)1)) {
2683       /* no DiCfSI for this address */
2684       return NULL;
2685    } else {
2686       /* found a DiCfSI for this address */
2687       return ce;
2688    }
2689 }
2690 
2691 
2692 inline
compute_cfa(const D3UnwindRegs * uregs,Addr min_accessible,Addr max_accessible,const DebugInfo * di,const DiCfSI_m * cfsi_m)2693 static Addr compute_cfa ( const D3UnwindRegs* uregs,
2694                           Addr min_accessible, Addr max_accessible,
2695                           const DebugInfo* di, const DiCfSI_m* cfsi_m )
2696 {
2697    CfiExprEvalContext eec;
2698    Addr               cfa;
2699    Bool               ok;
2700 
2701    /* Compute the CFA. */
2702    cfa = 0;
2703    switch (cfsi_m->cfa_how) {
2704 #     if defined(VGA_x86) || defined(VGA_amd64)
2705       case CFIC_IA_SPREL:
2706          cfa = cfsi_m->cfa_off + uregs->xsp;
2707          break;
2708       case CFIC_IA_BPREL:
2709          cfa = cfsi_m->cfa_off + uregs->xbp;
2710          break;
2711 #     elif defined(VGA_arm)
2712       case CFIC_ARM_R13REL:
2713          cfa = cfsi_m->cfa_off + uregs->r13;
2714          break;
2715       case CFIC_ARM_R12REL:
2716          cfa = cfsi_m->cfa_off + uregs->r12;
2717          break;
2718       case CFIC_ARM_R11REL:
2719          cfa = cfsi_m->cfa_off + uregs->r11;
2720          break;
2721       case CFIC_ARM_R7REL:
2722          cfa = cfsi_m->cfa_off + uregs->r7;
2723          break;
2724 #     elif defined(VGA_s390x)
2725       case CFIC_IA_SPREL:
2726          cfa = cfsi_m->cfa_off + uregs->sp;
2727          break;
2728       case CFIR_MEMCFAREL:
2729       {
2730          Addr a = uregs->sp + cfsi_m->cfa_off;
2731          if (a < min_accessible || a > max_accessible-sizeof(Addr))
2732             break;
2733          cfa = ML_(read_Addr)((void *)a);
2734          break;
2735       }
2736       case CFIR_SAME:
2737          cfa = uregs->fp;
2738          break;
2739       case CFIC_IA_BPREL:
2740          cfa = cfsi_m->cfa_off + uregs->fp;
2741          break;
2742 #     elif defined(VGA_mips32) || defined(VGA_mips64)
2743       case CFIC_IA_SPREL:
2744          cfa = cfsi_m->cfa_off + uregs->sp;
2745          break;
2746       case CFIR_SAME:
2747          cfa = uregs->fp;
2748          break;
2749       case CFIC_IA_BPREL:
2750          cfa = cfsi_m->cfa_off + uregs->fp;
2751          break;
2752 #     elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le)
2753 #     elif defined(VGP_arm64_linux)
2754       case CFIC_ARM64_SPREL:
2755          cfa = cfsi_m->cfa_off + uregs->sp;
2756          break;
2757       case CFIC_ARM64_X29REL:
2758          cfa = cfsi_m->cfa_off + uregs->x29;
2759          break;
2760 #     elif defined(VGA_tilegx)
2761       case CFIC_IA_SPREL:
2762          cfa = cfsi_m->cfa_off + uregs->sp;
2763          break;
2764       case CFIR_SAME:
2765          cfa = uregs->fp;
2766          break;
2767       case CFIC_IA_BPREL:
2768          cfa = cfsi_m->cfa_off + uregs->fp;
2769          break;
2770 #     else
2771 #       error "Unsupported arch"
2772 #     endif
2773       case CFIC_EXPR: /* available on all archs */
2774          if (0) {
2775             VG_(printf)("CFIC_EXPR: ");
2776             ML_(ppCfiExpr)(di->cfsi_exprs, cfsi_m->cfa_off);
2777             VG_(printf)("\n");
2778          }
2779          eec.uregs          = uregs;
2780          eec.min_accessible = min_accessible;
2781          eec.max_accessible = max_accessible;
2782          ok = True;
2783          cfa = evalCfiExpr(di->cfsi_exprs, cfsi_m->cfa_off, &eec, &ok );
2784          if (!ok) return 0;
2785          break;
2786       default:
2787          vg_assert(0);
2788    }
2789    return cfa;
2790 }
2791 
2792 
2793 /* Get the call frame address (CFA) given an IP/SP/FP triple. */
2794 /* NOTE: This function may rearrange the order of entries in the
2795    DebugInfo list. */
ML_(get_CFA)2796 Addr ML_(get_CFA) ( Addr ip, Addr sp, Addr fp,
2797                     Addr min_accessible, Addr max_accessible )
2798 {
2799    CFSI_m_CacheEnt* ce;
2800 
2801    ce = cfsi_m_cache__find(ip);
2802 
2803    if (UNLIKELY(ce == NULL))
2804       return 0; /* no info.  Nothing we can do. */
2805 
2806    /* Temporary impedance-matching kludge so that this keeps working
2807       on x86-linux and amd64-linux. */
2808 #  if defined(VGA_x86) || defined(VGA_amd64)
2809    { D3UnwindRegs uregs;
2810      uregs.xip = ip;
2811      uregs.xsp = sp;
2812      uregs.xbp = fp;
2813      return compute_cfa(&uregs,
2814                         min_accessible,  max_accessible, ce->di, ce->cfsi_m);
2815    }
2816 #elif defined(VGA_s390x)
2817    { D3UnwindRegs uregs;
2818      uregs.ia = ip;
2819      uregs.sp = sp;
2820      uregs.fp = fp;
2821      return compute_cfa(&uregs,
2822                         min_accessible,  max_accessible, ce->di, ce->cfsi_m);
2823    }
2824 #elif defined(VGA_mips32) || defined(VGA_mips64) || defined(VGA_tilegx)
2825    { D3UnwindRegs uregs;
2826      uregs.pc = ip;
2827      uregs.sp = sp;
2828      uregs.fp = fp;
2829      return compute_cfa(&uregs,
2830                         min_accessible,  max_accessible, ce->di, ce->cfsi_m);
2831    }
2832 
2833 #  else
2834    return 0; /* indicates failure */
2835 #  endif
2836 }
2837 
VG_(ppUnwindInfo)2838 void VG_(ppUnwindInfo) (Addr from, Addr to)
2839 {
2840    DebugInfo*         di;
2841    CFSI_m_CacheEnt*   ce;
2842    Addr ce_from;
2843    CFSI_m_CacheEnt*   next_ce;
2844 
2845 
2846    ce = cfsi_m_cache__find(from);
2847    ce_from = from;
2848    while (from <= to) {
2849       from++;
2850       next_ce = cfsi_m_cache__find(from);
2851       if ((ce == NULL && next_ce != NULL)
2852           || (ce != NULL && next_ce == NULL)
2853           || (ce != NULL && next_ce != NULL && ce->cfsi_m != next_ce->cfsi_m)
2854           || from > to) {
2855          if (ce == NULL) {
2856             VG_(printf)("[%#lx .. %#lx]: no CFI info\n", ce_from, from-1);
2857          } else {
2858             di = ce->di;
2859             ML_(ppDiCfSI)(di->cfsi_exprs,
2860                           ce_from, from - ce_from,
2861                           ce->cfsi_m);
2862          }
2863          ce = next_ce;
2864          ce_from = from;
2865       }
2866    }
2867 }
2868 
2869 
2870 /* The main function for DWARF2/3 CFI-based stack unwinding.  Given a
2871    set of registers in UREGS, modify it to hold the register values
2872    for the previous frame, if possible.  Returns True if successful.
2873    If not successful, *UREGS is not changed.
2874 
2875    For x86 and amd64, the unwound registers are: {E,R}IP,
2876    {E,R}SP, {E,R}BP.
2877 
2878    For arm, the unwound registers are: R7 R11 R12 R13 R14 R15.
2879 
2880    For arm64, the unwound registers are: X29(FP) X30(LR) SP PC.
2881 */
VG_(use_CF_info)2882 Bool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere,
2883                         Addr min_accessible,
2884                         Addr max_accessible )
2885 {
2886    DebugInfo*         di;
2887    DiCfSI_m*          cfsi_m = NULL;
2888    Addr               cfa, ipHere = 0;
2889    CFSI_m_CacheEnt*   ce;
2890    CfiExprEvalContext eec __attribute__((unused));
2891    D3UnwindRegs       uregsPrev;
2892 
2893 #  if defined(VGA_x86) || defined(VGA_amd64)
2894    ipHere = uregsHere->xip;
2895 #  elif defined(VGA_arm)
2896    ipHere = uregsHere->r15;
2897 #  elif defined(VGA_s390x)
2898    ipHere = uregsHere->ia;
2899 #  elif defined(VGA_mips32) || defined(VGA_mips64)
2900    ipHere = uregsHere->pc;
2901 #  elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le)
2902 #  elif defined(VGP_arm64_linux)
2903    ipHere = uregsHere->pc;
2904 #  elif defined(VGA_tilegx)
2905    ipHere = uregsHere->pc;
2906 #  else
2907 #    error "Unknown arch"
2908 #  endif
2909    ce = cfsi_m_cache__find(ipHere);
2910 
2911    if (UNLIKELY(ce == NULL))
2912       return False; /* no info.  Nothing we can do. */
2913 
2914    di = ce->di;
2915    cfsi_m = ce->cfsi_m;
2916 
2917    if (0) {
2918       VG_(printf)("found cfsi_m (but printing fake base/len): ");
2919       ML_(ppDiCfSI)(di->cfsi_exprs, 0, 0, cfsi_m);
2920    }
2921 
2922    VG_(bzero_inline)(&uregsPrev, sizeof(uregsPrev));
2923 
2924    /* First compute the CFA. */
2925    cfa = compute_cfa(uregsHere,
2926                      min_accessible, max_accessible, di, cfsi_m);
2927    if (UNLIKELY(cfa == 0))
2928       return False;
2929 
2930    /* Now we know the CFA, use it to roll back the registers we're
2931       interested in. */
2932 
2933 #  define COMPUTE(_prev, _here, _how, _off)             \
2934       do {                                              \
2935          switch (_how) {                                \
2936             case CFIR_UNKNOWN:                          \
2937                return False;                            \
2938             case CFIR_SAME:                             \
2939                _prev = _here; break;                    \
2940             case CFIR_MEMCFAREL: {                      \
2941                Addr a = cfa + (Word)_off;               \
2942                if (a < min_accessible                   \
2943                    || a > max_accessible-sizeof(Addr))  \
2944                   return False;                         \
2945                _prev = ML_(read_Addr)((void *)a);       \
2946                break;                                   \
2947             }                                           \
2948             case CFIR_CFAREL:                           \
2949                _prev = cfa + (Word)_off;                \
2950                break;                                   \
2951             case CFIR_EXPR:                             \
2952                if (0)                                   \
2953                   ML_(ppCfiExpr)(di->cfsi_exprs,_off);  \
2954                eec.uregs = uregsHere;                   \
2955                eec.min_accessible = min_accessible;     \
2956                eec.max_accessible = max_accessible;     \
2957                Bool ok = True;                          \
2958                _prev = evalCfiExpr(di->cfsi_exprs, _off, &eec, &ok ); \
2959                if (!ok) return False;                   \
2960                break;                                   \
2961             default:                                    \
2962                vg_assert(0);                            \
2963          }                                              \
2964       } while (0)
2965 
2966 #  if defined(VGA_x86) || defined(VGA_amd64)
2967    COMPUTE(uregsPrev.xip, uregsHere->xip, cfsi_m->ra_how, cfsi_m->ra_off);
2968    COMPUTE(uregsPrev.xsp, uregsHere->xsp, cfsi_m->sp_how, cfsi_m->sp_off);
2969    COMPUTE(uregsPrev.xbp, uregsHere->xbp, cfsi_m->bp_how, cfsi_m->bp_off);
2970 #  elif defined(VGA_arm)
2971    COMPUTE(uregsPrev.r15, uregsHere->r15, cfsi_m->ra_how,  cfsi_m->ra_off);
2972    COMPUTE(uregsPrev.r14, uregsHere->r14, cfsi_m->r14_how, cfsi_m->r14_off);
2973    COMPUTE(uregsPrev.r13, uregsHere->r13, cfsi_m->r13_how, cfsi_m->r13_off);
2974    COMPUTE(uregsPrev.r12, uregsHere->r12, cfsi_m->r12_how, cfsi_m->r12_off);
2975    COMPUTE(uregsPrev.r11, uregsHere->r11, cfsi_m->r11_how, cfsi_m->r11_off);
2976    COMPUTE(uregsPrev.r7,  uregsHere->r7,  cfsi_m->r7_how,  cfsi_m->r7_off);
2977 #  elif defined(VGA_s390x)
2978    COMPUTE(uregsPrev.ia, uregsHere->ia, cfsi_m->ra_how, cfsi_m->ra_off);
2979    COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off);
2980    COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi_m->fp_how, cfsi_m->fp_off);
2981 #  elif defined(VGA_mips32) || defined(VGA_mips64)
2982    COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi_m->ra_how, cfsi_m->ra_off);
2983    COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off);
2984    COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi_m->fp_how, cfsi_m->fp_off);
2985 #  elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le)
2986 #  elif defined(VGP_arm64_linux)
2987    COMPUTE(uregsPrev.pc,  uregsHere->pc,  cfsi_m->ra_how,  cfsi_m->ra_off);
2988    COMPUTE(uregsPrev.sp,  uregsHere->sp,  cfsi_m->sp_how,  cfsi_m->sp_off);
2989    COMPUTE(uregsPrev.x30, uregsHere->x30, cfsi_m->x30_how, cfsi_m->x30_off);
2990    COMPUTE(uregsPrev.x29, uregsHere->x29, cfsi_m->x29_how, cfsi_m->x29_off);
2991 #  elif defined(VGA_tilegx)
2992    COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi_m->ra_how, cfsi_m->ra_off);
2993    COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off);
2994    COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi_m->fp_how, cfsi_m->fp_off);
2995 #  else
2996 #    error "Unknown arch"
2997 #  endif
2998 
2999 #  undef COMPUTE
3000 
3001    *uregsHere = uregsPrev;
3002    return True;
3003 }
3004 
3005 
3006 /*--------------------------------------------------------------*/
3007 /*---                                                        ---*/
3008 /*--- TOP LEVEL: FOR UNWINDING THE STACK USING               ---*/
3009 /*---            MSVC FPO INFO                               ---*/
3010 /*---                                                        ---*/
3011 /*--------------------------------------------------------------*/
3012 
VG_(use_FPO_info)3013 Bool VG_(use_FPO_info) ( /*MOD*/Addr* ipP,
3014                          /*MOD*/Addr* spP,
3015                          /*MOD*/Addr* fpP,
3016                          Addr min_accessible,
3017                          Addr max_accessible )
3018 {
3019    Word       i;
3020    const DebugInfo* di;
3021    FPO_DATA*  fpo = NULL;
3022    Addr       spHere;
3023 
3024    static UWord n_search = 0;
3025    static UWord n_steps = 0;
3026    n_search++;
3027 
3028    if (0) VG_(printf)("search FPO for %#lx\n", *ipP);
3029 
3030    for (di = debugInfo_list; di != NULL; di = di->next) {
3031       n_steps++;
3032 
3033       /* Use the per-DebugInfo summary address ranges to skip
3034          inapplicable DebugInfos quickly. */
3035       if (di->fpo == NULL)
3036          continue;
3037       if (*ipP < di->fpo_minavma || *ipP > di->fpo_maxavma)
3038          continue;
3039 
3040       i = ML_(search_one_fpotab)( di, *ipP );
3041       if (i != -1) {
3042          Word j;
3043          if (0) {
3044             /* debug printing only */
3045             VG_(printf)("look for %#lx  size %lu i %ld\n",
3046                         *ipP, di->fpo_size, i);
3047             for (j = 0; j < di->fpo_size; j++)
3048                VG_(printf)("[%02ld] %#x %u\n",
3049                             j, di->fpo[j].ulOffStart, di->fpo[j].cbProcSize);
3050          }
3051          vg_assert(i >= 0 && i < di->fpo_size);
3052          fpo = &di->fpo[i];
3053          break;
3054       }
3055    }
3056 
3057    if (fpo == NULL)
3058       return False;
3059 
3060    if (0 && ((n_search & 0x7FFFF) == 0))
3061       VG_(printf)("VG_(use_FPO_info): %lu searches, "
3062                   "%lu DebugInfos looked at\n",
3063                   n_search, n_steps);
3064 
3065 
3066    /* Start of performance-enhancing hack: once every 64 (chosen
3067       hackily after profiling) successful searches, move the found
3068       DebugInfo one step closer to the start of the list.  This makes
3069       future searches cheaper.  For starting konqueror on amd64, this
3070       in fact reduces the total amount of searching done by the above
3071       find-the-right-DebugInfo loop by more than a factor of 20. */
3072    if ((n_search & 0x3F) == 0) {
3073       /* Move si one step closer to the start of the list. */
3074       //move_DebugInfo_one_step_forward( di );
3075    }
3076    /* End of performance-enhancing hack. */
3077 
3078    if (0) {
3079       VG_(printf)("found fpo: ");
3080       //ML_(ppFPO)(fpo);
3081    }
3082 
3083    /*
3084    Stack layout is:
3085    %esp->
3086       4*.cbRegs  {%edi, %esi, %ebp, %ebx}
3087       4*.cdwLocals
3088       return_pc
3089       4*.cdwParams
3090    prior_%esp->
3091 
3092    Typical code looks like:
3093       sub $4*.cdwLocals,%esp
3094          Alternative to above for >=4KB (and sometimes for smaller):
3095             mov $size,%eax
3096             call __chkstk  # WinNT performs page-by-page probe!
3097                __chkstk is much like alloc(), except that on return
3098                %eax= 5+ &CALL.  Thus it could be used as part of
3099                Position Independent Code to locate the Global Offset Table.
3100       push %ebx
3101       push %ebp
3102       push %esi
3103          Other once-only instructions often scheduled >here<.
3104       push %edi
3105 
3106    If the pc is within the first .cbProlog bytes of the function,
3107    then you must disassemble to see how many registers have been pushed,
3108    because instructions in the prolog may be scheduled for performance.
3109    The order of PUSH is always %ebx, %ebp, %esi, %edi, with trailing
3110    registers not pushed when .cbRegs < 4.  This seems somewhat strange
3111    because %ebp is the register whose usage you want to minimize,
3112    yet it is in the first half of the PUSH list.
3113 
3114    I don't know what happens when the compiler constructs an outgoing CALL.
3115    %esp could move if outgoing parameters are PUSHed, and this affects
3116    traceback for errors during the PUSHes. */
3117 
3118    spHere = *spP;
3119 
3120    *ipP = ML_(read_Addr)((void *)(spHere + 4*(fpo->cbRegs + fpo->cdwLocals)));
3121    *spP =                         spHere + 4*(fpo->cbRegs + fpo->cdwLocals + 1
3122                                                           + fpo->cdwParams);
3123    *fpP = ML_(read_Addr)((void *)(spHere + 4*2));
3124    return True;
3125 }
3126 
VG_(FPO_info_present)3127 Bool VG_(FPO_info_present)(void)
3128 {
3129    const DebugInfo* di;
3130    for (di = debugInfo_list; di != NULL; di = di->next) {
3131       if (di->fpo != NULL)
3132          return True;
3133    }
3134    return False;
3135 }
3136 
3137 
3138 /*--------------------------------------------------------------*/
3139 /*---                                                        ---*/
3140 /*--- TOP LEVEL: GENERATE DESCRIPTION OF DATA ADDRESSES      ---*/
3141 /*---            FROM DWARF3 DEBUG INFO                      ---*/
3142 /*---                                                        ---*/
3143 /*--------------------------------------------------------------*/
3144 
3145 /* Try to make p2XA(dst, fmt, args..) turn into
3146    VG_(xaprintf)(dst, fmt, args) without having to resort to
3147    vararg macros.  As usual with everything to do with varargs, it's
3148    an ugly hack.
3149 
3150    //#define p2XA(dstxa, format, args...)
3151    //   VG_(xaprintf)(dstxa, format, ##args)
3152 */
3153 #define  p2XA  VG_(xaprintf)
3154 
3155 /* Add a zero-terminating byte to DST, which must be an XArray* of
3156    HChar. */
zterm_XA(XArray * dst)3157 static void zterm_XA ( XArray* dst )
3158 {
3159    HChar zero = 0;
3160    (void) VG_(addBytesToXA)( dst, &zero, 1 );
3161 }
3162 
3163 
3164 /* Evaluate the location expression/list for var, to see whether or
3165    not data_addr falls within the variable.  If so also return the
3166    offset of data_addr from the start of the variable.  Note that
3167    regs, which supplies ip,sp,fp values, will be NULL for global
3168    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)3169 static Bool data_address_is_in_var ( /*OUT*/PtrdiffT* offset,
3170                                      const XArray* /* TyEnt */ tyents,
3171                                      const DiVariable*   var,
3172                                      const RegSummary*   regs,
3173                                      Addr  data_addr,
3174                                      const DebugInfo* di )
3175 {
3176    MaybeULong mul;
3177    SizeT      var_szB;
3178    GXResult   res;
3179    Bool       show = False;
3180 
3181    vg_assert(var->name);
3182    vg_assert(var->gexpr);
3183 
3184    /* Figure out how big the variable is. */
3185    mul = ML_(sizeOfType)(tyents, var->typeR);
3186    /* If this var has a type whose size is unknown, zero, or
3187       impossibly large, it should never have been added.  ML_(addVar)
3188       should have rejected it. */
3189    vg_assert(mul.b == True);
3190    vg_assert(mul.ul > 0);
3191    if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
3192    /* After this point, we assume we can truncate mul.ul to a host word
3193       safely (without loss of info). */
3194 
3195    var_szB = (SizeT)mul.ul; /* NB: truncate to host word */
3196 
3197    if (show) {
3198       VG_(printf)("VVVV: data_address_%#lx_is_in_var: %s :: ",
3199                   data_addr, var->name );
3200       ML_(pp_TyEnt_C_ishly)( tyents, var->typeR );
3201       VG_(printf)("\n");
3202    }
3203 
3204    /* ignore zero-sized vars; they can never match anything. */
3205    if (var_szB == 0) {
3206       if (show)
3207          VG_(printf)("VVVV: -> Fail (variable is zero sized)\n");
3208       return False;
3209    }
3210 
3211    res = ML_(evaluate_GX)( var->gexpr, var->fbGX, regs, di );
3212 
3213    if (show) {
3214       VG_(printf)("VVVV: -> ");
3215       ML_(pp_GXResult)( res );
3216       VG_(printf)("\n");
3217    }
3218 
3219    if (res.kind == GXR_Addr
3220        && res.word <= data_addr
3221        && data_addr < res.word + var_szB) {
3222       *offset = data_addr - res.word;
3223       return True;
3224    } else {
3225       return False;
3226    }
3227 }
3228 
3229 
3230 /* Format the acquired information into DN(AME)1 and DN(AME)2, which
3231    are XArray*s of HChar, that have been initialised by the caller.
3232    Resulting strings will be zero terminated.  Information is
3233    formatted in an understandable way.  Not so easy.  If frameNo is
3234    -1, this is assumed to be a global variable; else a local
3235    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)3236 static void format_message ( /*MOD*/XArray* /* of HChar */ dn1,
3237                              /*MOD*/XArray* /* of HChar */ dn2,
3238                              Addr     data_addr,
3239                              const DebugInfo* di,
3240                              const DiVariable* var,
3241                              PtrdiffT var_offset,
3242                              PtrdiffT residual_offset,
3243                              const XArray* /*HChar*/ described,
3244                              Int      frameNo,
3245                              ThreadId tid )
3246 {
3247    Bool   have_descr, have_srcloc;
3248    Bool   xml       = VG_(clo_xml);
3249    const HChar* vo_plural = var_offset == 1 ? "" : "s";
3250    const HChar* ro_plural = residual_offset == 1 ? "" : "s";
3251    const HChar* basetag   = "auxwhat"; /* a constant */
3252    HChar tagL[32], tagR[32], xagL[32], xagR[32];
3253    const HChar *fileName = ML_(fndn_ix2filename)(di, var->fndn_ix);
3254    // fileName will be "???" if var->fndn_ix == 0.
3255    // fileName will only be used if have_descr is True.
3256 
3257    if (frameNo < -1) {
3258       vg_assert(0); /* Not allowed */
3259    }
3260    else if (frameNo == -1) {
3261       vg_assert(tid == VG_INVALID_THREADID);
3262    }
3263    else /* (frameNo >= 0) */ {
3264       vg_assert(tid != VG_INVALID_THREADID);
3265    }
3266 
3267    vg_assert(dn1 && dn2);
3268    vg_assert(described);
3269    vg_assert(var && var->name);
3270    have_descr = VG_(sizeXA)(described) > 0
3271                 && *(HChar*)VG_(indexXA)(described,0) != '\0';
3272    have_srcloc = var->fndn_ix > 0 && var->lineNo > 0;
3273 
3274    tagL[0] = tagR[0] = xagL[0] = xagR[0] = 0;
3275    if (xml) {
3276       VG_(sprintf)(tagL, "<%s>",   basetag); // <auxwhat>
3277       VG_(sprintf)(tagR, "</%s>",  basetag); // </auxwhat>
3278       VG_(sprintf)(xagL, "<x%s>",  basetag); // <xauxwhat>
3279       VG_(sprintf)(xagR, "</x%s>", basetag); // </xauxwhat>
3280    }
3281 
3282 #  define TAGL(_xa) p2XA(_xa, "%s", tagL)
3283 #  define TAGR(_xa) p2XA(_xa, "%s", tagR)
3284 #  define XAGL(_xa) p2XA(_xa, "%s", xagL)
3285 #  define XAGR(_xa) p2XA(_xa, "%s", xagR)
3286 #  define TXTL(_xa) p2XA(_xa, "%s", "<text>")
3287 #  define TXTR(_xa) p2XA(_xa, "%s", "</text>")
3288 
3289    /* ------ local cases ------ */
3290 
3291    if ( frameNo >= 0 && (!have_srcloc) && (!have_descr) ) {
3292       /* no srcloc, no description:
3293          Location 0x7fefff6cf is 543 bytes inside local var "a",
3294          in frame #1 of thread 1
3295       */
3296       if (xml) {
3297          TAGL( dn1 );
3298          p2XA( dn1,
3299                "Location 0x%lx is %ld byte%s inside local var \"%pS\",",
3300                data_addr, var_offset, vo_plural, var->name );
3301          TAGR( dn1 );
3302          TAGL( dn2 );
3303          p2XA( dn2,
3304                "in frame #%d of thread %u", frameNo, tid );
3305          TAGR( dn2 );
3306       } else {
3307          p2XA( dn1,
3308                "Location 0x%lx is %ld byte%s inside local var \"%s\",",
3309                data_addr, var_offset, vo_plural, var->name );
3310          p2XA( dn2,
3311                "in frame #%d of thread %u", frameNo, tid );
3312       }
3313    }
3314    else
3315    if ( frameNo >= 0 && have_srcloc && (!have_descr) ) {
3316       /* no description:
3317          Location 0x7fefff6cf is 543 bytes inside local var "a"
3318          declared at dsyms7.c:17, in frame #1 of thread 1
3319       */
3320       if (xml) {
3321          TAGL( dn1 );
3322          p2XA( dn1,
3323                "Location 0x%lx is %ld byte%s inside local var \"%pS\"",
3324                data_addr, var_offset, vo_plural, var->name );
3325          TAGR( dn1 );
3326          XAGL( dn2 );
3327          TXTL( dn2 );
3328          p2XA( dn2,
3329                "declared at %pS:%d, in frame #%d of thread %u",
3330                fileName, var->lineNo, frameNo, tid );
3331          TXTR( dn2 );
3332          // FIXME: also do <dir>
3333          p2XA( dn2,
3334                " <file>%pS</file> <line>%d</line> ",
3335                fileName, var->lineNo );
3336          XAGR( dn2 );
3337       } else {
3338          p2XA( dn1,
3339                "Location 0x%lx is %ld byte%s inside local var \"%s\"",
3340                data_addr, var_offset, vo_plural, var->name );
3341          p2XA( dn2,
3342                "declared at %s:%d, in frame #%d of thread %u",
3343                fileName, var->lineNo, frameNo, tid );
3344       }
3345    }
3346    else
3347    if ( frameNo >= 0 && (!have_srcloc) && have_descr ) {
3348       /* no srcloc:
3349          Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2
3350          in frame #1 of thread 1
3351       */
3352       if (xml) {
3353          TAGL( dn1 );
3354          p2XA( dn1,
3355                "Location 0x%lx is %ld byte%s inside %pS%pS",
3356                data_addr, residual_offset, ro_plural, var->name,
3357                (HChar*)(VG_(indexXA)(described,0)) );
3358          TAGR( dn1 );
3359          TAGL( dn2 );
3360          p2XA( dn2,
3361                "in frame #%d of thread %u", frameNo, tid );
3362          TAGR( dn2 );
3363       } else {
3364          p2XA( dn1,
3365                "Location 0x%lx is %ld byte%s inside %s%s",
3366                data_addr, residual_offset, ro_plural, var->name,
3367                (HChar*)(VG_(indexXA)(described,0)) );
3368          p2XA( dn2,
3369                "in frame #%d of thread %u", frameNo, tid );
3370       }
3371    }
3372    else
3373    if ( frameNo >= 0 && have_srcloc && have_descr ) {
3374       /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
3375          declared at dsyms7.c:17, in frame #1 of thread 1 */
3376       if (xml) {
3377          TAGL( dn1 );
3378          p2XA( dn1,
3379                "Location 0x%lx is %ld byte%s inside %pS%pS,",
3380                data_addr, residual_offset, ro_plural, var->name,
3381                (HChar*)(VG_(indexXA)(described,0)) );
3382          TAGR( dn1 );
3383          XAGL( dn2 );
3384          TXTL( dn2 );
3385          p2XA( dn2,
3386                "declared at %pS:%d, in frame #%d of thread %u",
3387                fileName, var->lineNo, frameNo, tid );
3388          TXTR( dn2 );
3389          // FIXME: also do <dir>
3390          p2XA( dn2,
3391                " <file>%pS</file> <line>%d</line> ",
3392                fileName, var->lineNo );
3393          XAGR( dn2 );
3394       } else {
3395          p2XA( dn1,
3396                "Location 0x%lx is %ld byte%s inside %s%s,",
3397                data_addr, residual_offset, ro_plural, var->name,
3398                (HChar*)(VG_(indexXA)(described,0)) );
3399          p2XA( dn2,
3400                "declared at %s:%d, in frame #%d of thread %u",
3401                fileName, var->lineNo, frameNo, tid );
3402       }
3403    }
3404    else
3405    /* ------ global cases ------ */
3406    if ( frameNo >= -1 && (!have_srcloc) && (!have_descr) ) {
3407       /* no srcloc, no description:
3408          Location 0x7fefff6cf is 543 bytes inside global var "a"
3409       */
3410       if (xml) {
3411          TAGL( dn1 );
3412          p2XA( dn1,
3413                "Location 0x%lx is %ld byte%s inside global var \"%pS\"",
3414                data_addr, var_offset, vo_plural, var->name );
3415          TAGR( dn1 );
3416       } else {
3417          p2XA( dn1,
3418                "Location 0x%lx is %ld byte%s inside global var \"%s\"",
3419                data_addr, var_offset, vo_plural, var->name );
3420       }
3421    }
3422    else
3423    if ( frameNo >= -1 && have_srcloc && (!have_descr) ) {
3424       /* no description:
3425          Location 0x7fefff6cf is 543 bytes inside global var "a"
3426          declared at dsyms7.c:17
3427       */
3428       if (xml) {
3429          TAGL( dn1 );
3430          p2XA( dn1,
3431                "Location 0x%lx is %ld byte%s inside global var \"%pS\"",
3432                data_addr, var_offset, vo_plural, var->name );
3433          TAGR( dn1 );
3434          XAGL( dn2 );
3435          TXTL( dn2 );
3436          p2XA( dn2,
3437                "declared at %pS:%d",
3438                fileName, var->lineNo);
3439          TXTR( dn2 );
3440          // FIXME: also do <dir>
3441          p2XA( dn2,
3442                " <file>%pS</file> <line>%d</line> ",
3443                fileName, var->lineNo );
3444          XAGR( dn2 );
3445       } else {
3446          p2XA( dn1,
3447                "Location 0x%lx is %ld byte%s inside global var \"%s\"",
3448                data_addr, var_offset, vo_plural, var->name );
3449          p2XA( dn2,
3450                "declared at %s:%d",
3451                fileName, var->lineNo);
3452       }
3453    }
3454    else
3455    if ( frameNo >= -1 && (!have_srcloc) && have_descr ) {
3456       /* no srcloc:
3457          Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
3458          a global variable
3459       */
3460       if (xml) {
3461          TAGL( dn1 );
3462          p2XA( dn1,
3463                "Location 0x%lx is %ld byte%s inside %pS%pS,",
3464                data_addr, residual_offset, ro_plural, var->name,
3465                (HChar*)(VG_(indexXA)(described,0)) );
3466          TAGR( dn1 );
3467          TAGL( dn2 );
3468          p2XA( dn2,
3469                "a global variable");
3470          TAGR( dn2 );
3471       } else {
3472          p2XA( dn1,
3473                "Location 0x%lx is %ld byte%s inside %s%s,",
3474                data_addr, residual_offset, ro_plural, var->name,
3475                (HChar*)(VG_(indexXA)(described,0)) );
3476          p2XA( dn2,
3477                "a global variable");
3478       }
3479    }
3480    else
3481    if ( frameNo >= -1 && have_srcloc && have_descr ) {
3482       /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
3483          a global variable declared at dsyms7.c:17 */
3484       if (xml) {
3485          TAGL( dn1 );
3486          p2XA( dn1,
3487                "Location 0x%lx is %ld byte%s inside %pS%pS,",
3488                data_addr, residual_offset, ro_plural, var->name,
3489                (HChar*)(VG_(indexXA)(described,0)) );
3490          TAGR( dn1 );
3491          XAGL( dn2 );
3492          TXTL( dn2 );
3493          p2XA( dn2,
3494                "a global variable declared at %pS:%d",
3495                fileName, var->lineNo);
3496          TXTR( dn2 );
3497          // FIXME: also do <dir>
3498          p2XA( dn2,
3499                " <file>%pS</file> <line>%d</line> ",
3500                fileName, var->lineNo );
3501          XAGR( dn2 );
3502       } else {
3503          p2XA( dn1,
3504                "Location 0x%lx is %ld byte%s inside %s%s,",
3505                data_addr, residual_offset, ro_plural, var->name,
3506                (HChar*)(VG_(indexXA)(described,0)) );
3507          p2XA( dn2,
3508                "a global variable declared at %s:%d",
3509                fileName, var->lineNo);
3510       }
3511    }
3512    else
3513       vg_assert(0);
3514 
3515    /* Zero terminate both strings */
3516    zterm_XA( dn1 );
3517    zterm_XA( dn2 );
3518 
3519 #  undef TAGL
3520 #  undef TAGR
3521 #  undef XAGL
3522 #  undef XAGR
3523 #  undef TXTL
3524 #  undef TXTR
3525 }
3526 
3527 
3528 /* Determine if data_addr is a local variable in the frame
3529    characterised by (ip,sp,fp), and if so write its description at the
3530    ends of DNAME{1,2}, which are XArray*s of HChar, that have been
3531    initialised by the caller, zero terminate both, and return True.
3532    If it's not a local variable in said frame, return False. */
3533 static
consider_vars_in_frame(XArray * dname1,XArray * dname2,Addr data_addr,Addr ip,Addr sp,Addr fp,ThreadId tid,Int frameNo)3534 Bool consider_vars_in_frame ( /*MOD*/XArray* /* of HChar */ dname1,
3535                               /*MOD*/XArray* /* of HChar */ dname2,
3536                               Addr data_addr,
3537                               Addr ip, Addr sp, Addr fp,
3538                               /* shown to user: */
3539                               ThreadId tid, Int frameNo )
3540 {
3541    Word       i;
3542    DebugInfo* di;
3543    RegSummary regs;
3544    Bool debug = False;
3545 
3546    static UInt n_search = 0;
3547    static UInt n_steps = 0;
3548    n_search++;
3549    if (debug)
3550       VG_(printf)("QQQQ: cvif: ip,sp,fp %#lx,%#lx,%#lx\n", ip,sp,fp);
3551    /* first, find the DebugInfo that pertains to 'ip'. */
3552    for (di = debugInfo_list; di; di = di->next) {
3553       n_steps++;
3554       /* text segment missing? unlikely, but handle it .. */
3555       if (!di->text_present || di->text_size == 0)
3556          continue;
3557       /* Ok.  So does this text mapping bracket the ip? */
3558       if (di->text_avma <= ip && ip < di->text_avma + di->text_size)
3559          break;
3560    }
3561 
3562    /* Didn't find it.  Strange -- means ip is a code address outside
3563       of any mapped text segment.  Unlikely but not impossible -- app
3564       could be generating code to run. */
3565    if (!di)
3566       return False;
3567 
3568    if (0 && ((n_search & 0x1) == 0))
3569       VG_(printf)("consider_vars_in_frame: %u searches, "
3570                   "%u DebugInfos looked at\n",
3571                   n_search, n_steps);
3572    /* Start of performance-enhancing hack: once every ??? (chosen
3573       hackily after profiling) successful searches, move the found
3574       DebugInfo one step closer to the start of the list.  This makes
3575       future searches cheaper. */
3576    if ((n_search & 0xFFFF) == 0) {
3577       /* Move si one step closer to the start of the list. */
3578       move_DebugInfo_one_step_forward( di );
3579    }
3580    /* End of performance-enhancing hack. */
3581 
3582    /* any var info at all? */
3583    if (!di->varinfo)
3584       return False;
3585 
3586    /* Work through the scopes from most deeply nested outwards,
3587       looking for code address ranges that bracket 'ip'.  The
3588       variables on each such address range found are in scope right
3589       now.  Don't descend to level zero as that is the global
3590       scope. */
3591    regs.ip = ip;
3592    regs.sp = sp;
3593    regs.fp = fp;
3594 
3595    /* "for each scope, working outwards ..." */
3596    for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) {
3597       XArray*      vars;
3598       Word         j;
3599       DiAddrRange* arange;
3600       OSet*        this_scope
3601          = *(OSet**)VG_(indexXA)( di->varinfo, i );
3602       if (debug)
3603          VG_(printf)("QQQQ:   considering scope %ld\n", (Word)i);
3604       if (!this_scope)
3605          continue;
3606       /* Find the set of variables in this scope that
3607          bracket the program counter. */
3608       arange = VG_(OSetGen_LookupWithCmp)(
3609                   this_scope, &ip,
3610                   ML_(cmp_for_DiAddrRange_range)
3611                );
3612       if (!arange)
3613          continue;
3614       /* stay sane */
3615       vg_assert(arange->aMin <= arange->aMax);
3616       /* It must bracket the ip we asked for, else
3617          ML_(cmp_for_DiAddrRange_range) is somehow broken. */
3618       vg_assert(arange->aMin <= ip && ip <= arange->aMax);
3619       /* It must have an attached XArray of DiVariables. */
3620       vars = arange->vars;
3621       vg_assert(vars);
3622       /* But it mustn't cover the entire address range.  We only
3623          expect that to happen for the global scope (level 0), which
3624          we're not looking at here.  Except, it may cover the entire
3625          address range, but in that case the vars array must be
3626          empty. */
3627       vg_assert(! (arange->aMin == (Addr)0
3628                    && arange->aMax == ~(Addr)0
3629                    && VG_(sizeXA)(vars) > 0) );
3630       for (j = 0; j < VG_(sizeXA)( vars ); j++) {
3631          DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j );
3632          PtrdiffT    offset;
3633          if (debug)
3634             VG_(printf)("QQQQ:    var:name=%s %#lx-%#lx %#lx\n",
3635                         var->name,arange->aMin,arange->aMax,ip);
3636          if (data_address_is_in_var( &offset, di->admin_tyents,
3637                                      var, &regs,
3638                                      data_addr, di )) {
3639             PtrdiffT residual_offset = 0;
3640             XArray* described = ML_(describe_type)( &residual_offset,
3641                                                     di->admin_tyents,
3642                                                     var->typeR, offset );
3643             format_message( dname1, dname2,
3644                             data_addr, di, var, offset, residual_offset,
3645                             described, frameNo, tid );
3646             VG_(deleteXA)( described );
3647             return True;
3648          }
3649       }
3650    }
3651 
3652    return False;
3653 }
3654 
3655 /* Try to form some description of DATA_ADDR by looking at the DWARF3
3656    debug info we have.  This considers all global variables, and 8
3657    frames in the stacks of all threads.  Result is written at the ends
3658    of DNAME{1,2}V, which are XArray*s of HChar, that have been
3659    initialised by the caller, and True is returned.  If no description
3660    is created, False is returned.  Regardless of the return value,
3661    DNAME{1,2}V are guaranteed to be zero terminated after the call.
3662 
3663    Note that after the call, DNAME{1,2} may have more than one
3664    trailing zero, so callers should establish the useful text length
3665    using VG_(strlen) on the contents, rather than VG_(sizeXA) on the
3666    XArray itself.
3667 */
VG_(get_data_description)3668 Bool VG_(get_data_description)(
3669         /*MOD*/ XArray* /* of HChar */ dname1,
3670         /*MOD*/ XArray* /* of HChar */ dname2,
3671         Addr data_addr
3672      )
3673 {
3674 #  define N_FRAMES 8
3675    Addr ips[N_FRAMES], sps[N_FRAMES], fps[N_FRAMES];
3676    UInt n_frames;
3677 
3678    Addr       stack_min, stack_max;
3679    ThreadId   tid;
3680    Bool       found;
3681    DebugInfo* di;
3682    Word       j;
3683 
3684    if (0) VG_(printf)("get_data_description: dataaddr %#lx\n", data_addr);
3685    /* First, see if data_addr is (or is part of) a global variable.
3686       Loop over the DebugInfos we have.  Check data_addr against the
3687       outermost scope of all of them, as that should be a global
3688       scope. */
3689    for (di = debugInfo_list; di != NULL; di = di->next) {
3690       OSet*        global_scope;
3691       Word         gs_size;
3692       Addr         zero;
3693       DiAddrRange* global_arange;
3694       Word         i;
3695       XArray*      vars;
3696 
3697       /* text segment missing? unlikely, but handle it .. */
3698       if (!di->text_present || di->text_size == 0)
3699          continue;
3700       /* any var info at all? */
3701       if (!di->varinfo)
3702          continue;
3703       /* perhaps this object didn't contribute any vars at all? */
3704       if (VG_(sizeXA)( di->varinfo ) == 0)
3705          continue;
3706       global_scope = *(OSet**)VG_(indexXA)( di->varinfo, 0 );
3707       vg_assert(global_scope);
3708       gs_size = VG_(OSetGen_Size)( global_scope );
3709       /* The global scope might be completely empty if this
3710          compilation unit declared locals but nothing global. */
3711       if (gs_size == 0)
3712           continue;
3713       /* But if it isn't empty, then it must contain exactly one
3714          element, which covers the entire address range. */
3715       vg_assert(gs_size == 1);
3716       /* Fish out the global scope and check it is as expected. */
3717       zero = 0;
3718       global_arange
3719          = VG_(OSetGen_Lookup)( global_scope, &zero );
3720       /* The global range from (Addr)0 to ~(Addr)0 must exist */
3721       vg_assert(global_arange);
3722       vg_assert(global_arange->aMin == (Addr)0
3723                 && global_arange->aMax == ~(Addr)0);
3724       /* Any vars in this range? */
3725       if (!global_arange->vars)
3726          continue;
3727       /* Ok, there are some vars in the global scope of this
3728          DebugInfo.  Wade through them and see if the data addresses
3729          of any of them bracket data_addr. */
3730       vars = global_arange->vars;
3731       for (i = 0; i < VG_(sizeXA)( vars ); i++) {
3732          PtrdiffT offset;
3733          DiVariable* var = (DiVariable*)VG_(indexXA)( vars, i );
3734          vg_assert(var->name);
3735          /* Note we use a NULL RegSummary* here.  It can't make any
3736             sense for a global variable to have a location expression
3737             which depends on a SP/FP/IP value.  So don't supply any.
3738             This means, if the evaluation of the location
3739             expression/list requires a register, we have to let it
3740             fail. */
3741          if (data_address_is_in_var( &offset, di->admin_tyents, var,
3742                                      NULL/* RegSummary* */,
3743                                      data_addr, di )) {
3744             PtrdiffT residual_offset = 0;
3745             XArray* described = ML_(describe_type)( &residual_offset,
3746                                                     di->admin_tyents,
3747                                                     var->typeR, offset );
3748             format_message( dname1, dname2,
3749                             data_addr, di, var, offset, residual_offset,
3750                             described, -1/*frameNo*/,
3751                             VG_INVALID_THREADID );
3752             VG_(deleteXA)( described );
3753             zterm_XA( dname1 );
3754             zterm_XA( dname2 );
3755             return True;
3756          }
3757       }
3758    }
3759 
3760    /* Ok, well it's not a global variable.  So now let's snoop around
3761       in the stacks of all the threads.  First try to figure out which
3762       thread's stack data_addr is in. */
3763 
3764    /* Perhaps it's on a thread's stack? */
3765    found = False;
3766    VG_(thread_stack_reset_iter)(&tid);
3767    while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) {
3768       if (stack_min >= stack_max)
3769          continue; /* ignore obviously stupid cases */
3770       if (stack_min - VG_STACK_REDZONE_SZB <= data_addr
3771           && data_addr <= stack_max) {
3772          found = True;
3773          break;
3774       }
3775    }
3776    if (!found) {
3777       zterm_XA( dname1 );
3778       zterm_XA( dname2 );
3779       return False;
3780    }
3781 
3782    /* We conclude data_addr is in thread tid's stack.  Unwind the
3783       stack to get a bunch of (ip,sp,fp) triples describing the
3784       frames, and for each frame, consider the local variables. */
3785    n_frames = VG_(get_StackTrace)( tid, ips, N_FRAMES,
3786                                    sps, fps, 0/*first_ip_delta*/ );
3787 
3788    vg_assert(n_frames >= 0 && n_frames <= N_FRAMES);
3789    for (j = 0; j < n_frames; j++) {
3790       if (consider_vars_in_frame( dname1, dname2,
3791                                   data_addr,
3792                                   ips[j],
3793                                   sps[j], fps[j], tid, j )) {
3794          zterm_XA( dname1 );
3795          zterm_XA( dname2 );
3796          return True;
3797       }
3798       /* Now, it appears that gcc sometimes appears to produce
3799          location lists whose ranges don't actually cover the call
3800          instruction, even though the address of the variable in
3801          question is passed as a parameter in the call.  AFAICS this
3802          is simply a bug in gcc - how can the variable be claimed not
3803          exist in memory (on the stack) for the duration of a call in
3804          which its address is passed?  But anyway, in the particular
3805          case I investigated (memcheck/tests/varinfo6.c, call to croak
3806          on line 2999, local var budget declared at line 3115
3807          appearing not to exist across the call to mainSort on line
3808          3143, "gcc.orig (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2)" on
3809          amd64), the variable's location list does claim it exists
3810          starting at the first byte of the first instruction after the
3811          call instruction.  So, call consider_vars_in_frame a second
3812          time, but this time add 1 to the IP.  GDB handles this
3813          example with no difficulty, which leads me to believe that
3814          either (1) I misunderstood something, or (2) GDB has an
3815          equivalent kludge. */
3816       if (j > 0 /* this is a non-innermost frame */
3817           && consider_vars_in_frame( dname1, dname2,
3818                                      data_addr,
3819                                      ips[j] + 1,
3820                                      sps[j], fps[j], tid, j )) {
3821          zterm_XA( dname1 );
3822          zterm_XA( dname2 );
3823          return True;
3824       }
3825    }
3826 
3827    /* We didn't find anything useful. */
3828    zterm_XA( dname1 );
3829    zterm_XA( dname2 );
3830    return False;
3831 #  undef N_FRAMES
3832 }
3833 
3834 
3835 //////////////////////////////////////////////////////////////////
3836 //                                                              //
3837 // Support for other kinds of queries to the Dwarf3 var info    //
3838 //                                                              //
3839 //////////////////////////////////////////////////////////////////
3840 
3841 /* Figure out if the variable 'var' has a location that is linearly
3842    dependent on a stack pointer value, or a frame pointer value, and
3843    if it is, add a description of it to 'blocks'.  Otherwise ignore
3844    it.  If 'arrays_only' is True, also ignore it unless it has an
3845    array type. */
3846 
3847 static
analyse_deps(XArray * blocks,const XArray * tyents,Addr ip,const DebugInfo * di,const DiVariable * var,Bool arrays_only)3848 void analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks,
3849                     const XArray* /* TyEnt */ tyents,
3850                     Addr ip, const DebugInfo* di, const DiVariable* var,
3851                     Bool arrays_only )
3852 {
3853    GXResult   res_sp_6k, res_sp_7k, res_fp_6k, res_fp_7k;
3854    RegSummary regs;
3855    MaybeULong mul;
3856    Bool       isVec;
3857    TyEnt*     ty;
3858 
3859    Bool debug = False;
3860    if (0&&debug)
3861       VG_(printf)("adeps: var %s\n", var->name );
3862 
3863    /* Figure out how big the variable is. */
3864    mul = ML_(sizeOfType)(tyents, var->typeR);
3865    /* If this var has a type whose size is unknown, zero, or
3866       impossibly large, it should never have been added.  ML_(addVar)
3867       should have rejected it. */
3868    vg_assert(mul.b == True);
3869    vg_assert(mul.ul > 0);
3870    if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
3871    /* After this point, we assume we can truncate mul.ul to a host word
3872       safely (without loss of info). */
3873 
3874    /* skip if non-array and we're only interested in arrays */
3875    ty = ML_(TyEnts__index_by_cuOff)( tyents, NULL, var->typeR );
3876    vg_assert(ty);
3877    vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty));
3878    if (ty->tag == Te_UNKNOWN)
3879       return; /* perhaps we should complain in this case? */
3880    isVec = ty->tag == Te_TyArray;
3881    if (arrays_only && !isVec)
3882       return;
3883 
3884    if (0) {ML_(pp_TyEnt_C_ishly)(tyents, var->typeR);
3885            VG_(printf)("  %s\n", var->name);}
3886 
3887    /* Do some test evaluations of the variable's location expression,
3888       in order to guess whether it is sp-relative, fp-relative, or
3889       none.  A crude hack, which can be interpreted roughly as finding
3890       the first derivative of the location expression w.r.t. the
3891       supplied frame and stack pointer values. */
3892    regs.fp   = 0;
3893    regs.ip   = ip;
3894    regs.sp   = 6 * 1024;
3895    res_sp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
3896 
3897    regs.fp   = 0;
3898    regs.ip   = ip;
3899    regs.sp   = 7 * 1024;
3900    res_sp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
3901 
3902    regs.fp   = 6 * 1024;
3903    regs.ip   = ip;
3904    regs.sp   = 0;
3905    res_fp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
3906 
3907    regs.fp   = 7 * 1024;
3908    regs.ip   = ip;
3909    regs.sp   = 0;
3910    res_fp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
3911 
3912    vg_assert(res_sp_6k.kind == res_sp_7k.kind);
3913    vg_assert(res_sp_6k.kind == res_fp_6k.kind);
3914    vg_assert(res_sp_6k.kind == res_fp_7k.kind);
3915 
3916    if (res_sp_6k.kind == GXR_Addr) {
3917       StackBlock block;
3918       GXResult res;
3919       UWord sp_delta = res_sp_7k.word - res_sp_6k.word;
3920       UWord fp_delta = res_fp_7k.word - res_fp_6k.word;
3921       vg_assert(sp_delta == 0 || sp_delta == 1024);
3922       vg_assert(fp_delta == 0 || fp_delta == 1024);
3923 
3924       if (sp_delta == 0 && fp_delta == 0) {
3925          /* depends neither on sp nor fp, so it can't be a stack
3926             local.  Ignore it. */
3927       }
3928       else
3929       if (sp_delta == 1024 && fp_delta == 0) {
3930          regs.sp = regs.fp = 0;
3931          regs.ip = ip;
3932          res = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
3933          vg_assert(res.kind == GXR_Addr);
3934          if (debug)
3935          VG_(printf)("   %5lu .. %5llu (sp) %s\n",
3936                      res.word, res.word + mul.ul - 1, var->name);
3937          block.base  = res.word;
3938          block.szB   = (SizeT)mul.ul;
3939          block.spRel = True;
3940          block.isVec = isVec;
3941          VG_(memset)( &block.name[0], 0, sizeof(block.name) );
3942          if (var->name)
3943             VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 );
3944          block.name[ sizeof(block.name)-1 ] = 0;
3945          VG_(addToXA)( blocks, &block );
3946       }
3947       else
3948       if (sp_delta == 0 && fp_delta == 1024) {
3949          regs.sp = regs.fp = 0;
3950          regs.ip = ip;
3951          res = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
3952          vg_assert(res.kind == GXR_Addr);
3953          if (debug)
3954          VG_(printf)("   %5lu .. %5llu (FP) %s\n",
3955                      res.word, res.word + mul.ul - 1, var->name);
3956          block.base  = res.word;
3957          block.szB   = (SizeT)mul.ul;
3958          block.spRel = False;
3959          block.isVec = isVec;
3960          VG_(memset)( &block.name[0], 0, sizeof(block.name) );
3961          if (var->name)
3962             VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 );
3963          block.name[ sizeof(block.name)-1 ] = 0;
3964          VG_(addToXA)( blocks, &block );
3965       }
3966       else {
3967          vg_assert(0);
3968       }
3969    }
3970 }
3971 
3972 
3973 /* Get an XArray of StackBlock which describe the stack (auto) blocks
3974    for this ip.  The caller is expected to free the XArray at some
3975    point.  If 'arrays_only' is True, only array-typed blocks are
3976    returned; otherwise blocks of all types are returned. */
3977 
3978 XArray* /* of StackBlock */
VG_(di_get_stack_blocks_at_ip)3979 VG_(di_get_stack_blocks_at_ip)( Addr ip, Bool arrays_only )
3980 {
3981    /* This is a derivation of consider_vars_in_frame() above. */
3982    Word       i;
3983    DebugInfo* di;
3984    Bool debug = False;
3985 
3986    XArray* res = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dgsbai.1",
3987                              ML_(dinfo_free),
3988                              sizeof(StackBlock) );
3989 
3990    static UInt n_search = 0;
3991    static UInt n_steps = 0;
3992    n_search++;
3993    if (debug)
3994       VG_(printf)("QQQQ: dgsbai: ip %#lx\n", ip);
3995    /* first, find the DebugInfo that pertains to 'ip'. */
3996    for (di = debugInfo_list; di; di = di->next) {
3997       n_steps++;
3998       /* text segment missing? unlikely, but handle it .. */
3999       if (!di->text_present || di->text_size == 0)
4000          continue;
4001       /* Ok.  So does this text mapping bracket the ip? */
4002       if (di->text_avma <= ip && ip < di->text_avma + di->text_size)
4003          break;
4004    }
4005 
4006    /* Didn't find it.  Strange -- means ip is a code address outside
4007       of any mapped text segment.  Unlikely but not impossible -- app
4008       could be generating code to run. */
4009    if (!di)
4010       return res; /* currently empty */
4011 
4012    if (0 && ((n_search & 0x1) == 0))
4013       VG_(printf)("VG_(di_get_stack_blocks_at_ip): %u searches, "
4014                   "%u DebugInfos looked at\n",
4015                   n_search, n_steps);
4016    /* Start of performance-enhancing hack: once every ??? (chosen
4017       hackily after profiling) successful searches, move the found
4018       DebugInfo one step closer to the start of the list.  This makes
4019       future searches cheaper. */
4020    if ((n_search & 0xFFFF) == 0) {
4021       /* Move si one step closer to the start of the list. */
4022       move_DebugInfo_one_step_forward( di );
4023    }
4024    /* End of performance-enhancing hack. */
4025 
4026    /* any var info at all? */
4027    if (!di->varinfo)
4028       return res; /* currently empty */
4029 
4030    /* Work through the scopes from most deeply nested outwards,
4031       looking for code address ranges that bracket 'ip'.  The
4032       variables on each such address range found are in scope right
4033       now.  Don't descend to level zero as that is the global
4034       scope. */
4035 
4036    /* "for each scope, working outwards ..." */
4037    for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) {
4038       XArray*      vars;
4039       Word         j;
4040       DiAddrRange* arange;
4041       OSet*        this_scope
4042          = *(OSet**)VG_(indexXA)( di->varinfo, i );
4043       if (debug)
4044          VG_(printf)("QQQQ:   considering scope %ld\n", (Word)i);
4045       if (!this_scope)
4046          continue;
4047       /* Find the set of variables in this scope that
4048          bracket the program counter. */
4049       arange = VG_(OSetGen_LookupWithCmp)(
4050                   this_scope, &ip,
4051                   ML_(cmp_for_DiAddrRange_range)
4052                );
4053       if (!arange)
4054          continue;
4055       /* stay sane */
4056       vg_assert(arange->aMin <= arange->aMax);
4057       /* It must bracket the ip we asked for, else
4058          ML_(cmp_for_DiAddrRange_range) is somehow broken. */
4059       vg_assert(arange->aMin <= ip && ip <= arange->aMax);
4060       /* It must have an attached XArray of DiVariables. */
4061       vars = arange->vars;
4062       vg_assert(vars);
4063       /* But it mustn't cover the entire address range.  We only
4064          expect that to happen for the global scope (level 0), which
4065          we're not looking at here.  Except, it may cover the entire
4066          address range, but in that case the vars array must be
4067          empty. */
4068       vg_assert(! (arange->aMin == (Addr)0
4069                    && arange->aMax == ~(Addr)0
4070                    && VG_(sizeXA)(vars) > 0) );
4071       for (j = 0; j < VG_(sizeXA)( vars ); j++) {
4072          DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j );
4073          if (debug)
4074             VG_(printf)("QQQQ:    var:name=%s %#lx-%#lx %#lx\n",
4075                         var->name,arange->aMin,arange->aMax,ip);
4076          analyse_deps( res, di->admin_tyents, ip,
4077                        di, var, arrays_only );
4078       }
4079    }
4080 
4081    return res;
4082 }
4083 
4084 
4085 /* Get an array of GlobalBlock which describe the global blocks owned
4086    by the shared object characterised by the given di_handle.  Asserts
4087    if the handle is invalid.  The caller is responsible for freeing
4088    the array at some point.  If 'arrays_only' is True, only
4089    array-typed blocks are returned; otherwise blocks of all types are
4090    returned. */
4091 
4092 XArray* /* of GlobalBlock */
VG_(di_get_global_blocks_from_dihandle)4093 VG_(di_get_global_blocks_from_dihandle) ( ULong di_handle, Bool  arrays_only )
4094 {
4095    /* This is a derivation of consider_vars_in_frame() above. */
4096 
4097    DebugInfo* di;
4098    XArray* gvars; /* XArray* of GlobalBlock */
4099    Word nScopes, scopeIx;
4100 
4101    /* The first thing to do is find the DebugInfo that
4102       pertains to 'di_handle'. */
4103    vg_assert(di_handle > 0);
4104    for (di = debugInfo_list; di; di = di->next) {
4105       if (di->handle == di_handle)
4106          break;
4107    }
4108 
4109    /* If this fails, we were unable to find any DebugInfo with the
4110       given handle.  This is considered an error on the part of the
4111       caller. */
4112    vg_assert(di != NULL);
4113 
4114    /* we'll put the collected variables in here. */
4115    gvars = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dggbfd.1",
4116                        ML_(dinfo_free), sizeof(GlobalBlock) );
4117 
4118    /* any var info at all? */
4119    if (!di->varinfo)
4120       return gvars;
4121 
4122    /* we'll iterate over all the variables we can find, even if
4123       it seems senseless to visit stack-allocated variables */
4124    /* Iterate over all scopes */
4125    nScopes = VG_(sizeXA)( di->varinfo );
4126    for (scopeIx = 0; scopeIx < nScopes; scopeIx++) {
4127 
4128       /* Iterate over each (code) address range at the current scope */
4129       DiAddrRange* range;
4130       OSet* /* of DiAddrInfo */ scope
4131          = *(OSet**)VG_(indexXA)( di->varinfo, scopeIx );
4132       vg_assert(scope);
4133       VG_(OSetGen_ResetIter)(scope);
4134       while ( (range = VG_(OSetGen_Next)(scope)) ) {
4135 
4136          /* Iterate over each variable in the current address range */
4137          Word nVars, varIx;
4138          vg_assert(range->vars);
4139          nVars = VG_(sizeXA)( range->vars );
4140          for (varIx = 0; varIx < nVars; varIx++) {
4141 
4142             Bool        isVec;
4143             GXResult    res;
4144             MaybeULong  mul;
4145             GlobalBlock gb;
4146             TyEnt*      ty;
4147             DiVariable* var = VG_(indexXA)( range->vars, varIx );
4148             vg_assert(var->name);
4149             if (0) VG_(printf)("at depth %ld var %s ", scopeIx, var->name );
4150 
4151             /* Now figure out if this variable has a constant address
4152                (that is, independent of FP, SP, phase of moon, etc),
4153                and if so, what the address is.  Any variable with a
4154                constant address is deemed to be a global so we collect
4155                it. */
4156             if (0) { VG_(printf)("EVAL: "); ML_(pp_GX)(var->gexpr);
4157                      VG_(printf)("\n"); }
4158             res = ML_(evaluate_trivial_GX)( var->gexpr, di );
4159 
4160             /* Not a constant address => not interesting */
4161             if (res.kind != GXR_Addr) {
4162                if (0) VG_(printf)("FAIL\n");
4163                continue;
4164             }
4165 
4166             /* Ok, it's a constant address.  See if we want to collect
4167                it. */
4168             if (0) VG_(printf)("%#lx\n", res.word);
4169 
4170             /* Figure out how big the variable is. */
4171             mul = ML_(sizeOfType)(di->admin_tyents, var->typeR);
4172 
4173             /* If this var has a type whose size is unknown, zero, or
4174                impossibly large, it should never have been added.
4175                ML_(addVar) should have rejected it. */
4176             vg_assert(mul.b == True);
4177             vg_assert(mul.ul > 0);
4178             if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
4179             /* After this point, we assume we can truncate mul.ul to a
4180                host word safely (without loss of info). */
4181 
4182             /* skip if non-array and we're only interested in
4183                arrays */
4184             ty = ML_(TyEnts__index_by_cuOff)( di->admin_tyents, NULL,
4185                                               var->typeR );
4186             vg_assert(ty);
4187             vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty));
4188             if (ty->tag == Te_UNKNOWN)
4189                continue; /* perhaps we should complain in this case? */
4190 
4191             isVec = ty->tag == Te_TyArray;
4192             if (arrays_only && !isVec) continue;
4193 
4194             /* Ok, so collect it! */
4195             vg_assert(var->name);
4196             vg_assert(di->soname);
4197             if (0) VG_(printf)("XXXX %s %s %d\n", var->name,
4198                                ML_(fndn_ix2filename)(di, var->fndn_ix),
4199                                var->lineNo);
4200             VG_(memset)(&gb, 0, sizeof(gb));
4201             gb.addr  = res.word;
4202             gb.szB   = (SizeT)mul.ul;
4203             gb.isVec = isVec;
4204             VG_(strncpy)(&gb.name[0], var->name, sizeof(gb.name)-1);
4205             VG_(strncpy)(&gb.soname[0], di->soname, sizeof(gb.soname)-1);
4206             vg_assert(gb.name[ sizeof(gb.name)-1 ] == 0);
4207             vg_assert(gb.soname[ sizeof(gb.soname)-1 ] == 0);
4208 
4209             VG_(addToXA)( gvars, &gb );
4210 
4211          } /* for (varIx = 0; varIx < nVars; varIx++) */
4212 
4213       } /* while ( (range = VG_(OSetGen_Next)(scope)) ) */
4214 
4215    } /* for (scopeIx = 0; scopeIx < nScopes; scopeIx++) */
4216 
4217    return gvars;
4218 }
4219 
4220 
4221 /*------------------------------------------------------------*/
4222 /*--- DebugInfo accessor functions                         ---*/
4223 /*------------------------------------------------------------*/
4224 
VG_(next_DebugInfo)4225 const DebugInfo* VG_(next_DebugInfo)(const DebugInfo* di)
4226 {
4227    if (di == NULL)
4228       return debugInfo_list;
4229    return di->next;
4230 }
4231 
VG_(DebugInfo_get_text_avma)4232 Addr VG_(DebugInfo_get_text_avma)(const DebugInfo* di)
4233 {
4234    return di->text_present ? di->text_avma : 0;
4235 }
4236 
VG_(DebugInfo_get_text_size)4237 SizeT VG_(DebugInfo_get_text_size)(const DebugInfo* di)
4238 {
4239    return di->text_present ? di->text_size : 0;
4240 }
4241 
VG_(DebugInfo_get_bss_avma)4242 Addr VG_(DebugInfo_get_bss_avma)(const DebugInfo* di)
4243 {
4244    return di->bss_present ? di->bss_avma : 0;
4245 }
4246 
VG_(DebugInfo_get_bss_size)4247 SizeT VG_(DebugInfo_get_bss_size)(const DebugInfo* di)
4248 {
4249    return di->bss_present ? di->bss_size : 0;
4250 }
4251 
VG_(DebugInfo_get_plt_avma)4252 Addr VG_(DebugInfo_get_plt_avma)(const DebugInfo* di)
4253 {
4254    return di->plt_present ? di->plt_avma : 0;
4255 }
4256 
VG_(DebugInfo_get_plt_size)4257 SizeT VG_(DebugInfo_get_plt_size)(const DebugInfo* di)
4258 {
4259    return di->plt_present ? di->plt_size : 0;
4260 }
4261 
VG_(DebugInfo_get_gotplt_avma)4262 Addr VG_(DebugInfo_get_gotplt_avma)(const DebugInfo* di)
4263 {
4264    return di->gotplt_present ? di->gotplt_avma : 0;
4265 }
4266 
VG_(DebugInfo_get_gotplt_size)4267 SizeT VG_(DebugInfo_get_gotplt_size)(const DebugInfo* di)
4268 {
4269    return di->gotplt_present ? di->gotplt_size : 0;
4270 }
4271 
VG_(DebugInfo_get_got_avma)4272 Addr VG_(DebugInfo_get_got_avma)(const DebugInfo* di)
4273 {
4274    return di->got_present ? di->got_avma : 0;
4275 }
4276 
VG_(DebugInfo_get_got_size)4277 SizeT VG_(DebugInfo_get_got_size)(const DebugInfo* di)
4278 {
4279    return di->got_present ? di->got_size : 0;
4280 }
4281 
VG_(DebugInfo_get_soname)4282 const HChar* VG_(DebugInfo_get_soname)(const DebugInfo* di)
4283 {
4284    return di->soname;
4285 }
4286 
VG_(DebugInfo_get_filename)4287 const HChar* VG_(DebugInfo_get_filename)(const DebugInfo* di)
4288 {
4289    return di->fsm.filename;
4290 }
4291 
VG_(DebugInfo_get_text_bias)4292 PtrdiffT VG_(DebugInfo_get_text_bias)(const DebugInfo* di)
4293 {
4294    return di->text_present ? di->text_bias : 0;
4295 }
4296 
VG_(DebugInfo_syms_howmany)4297 Int VG_(DebugInfo_syms_howmany) ( const DebugInfo *si )
4298 {
4299    return si->symtab_used;
4300 }
4301 
VG_(DebugInfo_syms_getidx)4302 void VG_(DebugInfo_syms_getidx) ( const DebugInfo *si,
4303                                         Int idx,
4304                                   /*OUT*/SymAVMAs* avmas,
4305                                   /*OUT*/UInt*     size,
4306                                   /*OUT*/const HChar**   pri_name,
4307                                   /*OUT*/const HChar***  sec_names,
4308                                   /*OUT*/Bool*     isText,
4309                                   /*OUT*/Bool*     isIFunc )
4310 {
4311    vg_assert(idx >= 0 && idx < si->symtab_used);
4312    if (avmas)     *avmas     = si->symtab[idx].avmas;
4313    if (size)      *size      = si->symtab[idx].size;
4314    if (pri_name)  *pri_name  = si->symtab[idx].pri_name;
4315    if (sec_names) *sec_names = si->symtab[idx].sec_names;
4316    if (isText)    *isText    = si->symtab[idx].isText;
4317    if (isIFunc)   *isIFunc   = si->symtab[idx].isIFunc;
4318 }
4319 
4320 
4321 /*------------------------------------------------------------*/
4322 /*--- SectKind query functions                             ---*/
4323 /*------------------------------------------------------------*/
4324 
4325 /* Convert a VgSectKind to a string, which must be copied if you want
4326    to change it. */
VG_(pp_SectKind)4327 const HChar* VG_(pp_SectKind)( VgSectKind kind )
4328 {
4329    switch (kind) {
4330       case Vg_SectUnknown: return "Unknown";
4331       case Vg_SectText:    return "Text";
4332       case Vg_SectData:    return "Data";
4333       case Vg_SectBSS:     return "BSS";
4334       case Vg_SectGOT:     return "GOT";
4335       case Vg_SectPLT:     return "PLT";
4336       case Vg_SectOPD:     return "OPD";
4337       case Vg_SectGOTPLT:  return "GOTPLT";
4338       default:             vg_assert(0);
4339    }
4340 }
4341 
4342 /* Given an address 'a', make a guess of which section of which object
4343    it comes from.  If name is non-NULL, then the object's name is put
4344    in *name. The returned name, if any, should be saved away, if there is
4345    a chance that a debug-info will be discarded and the name is being
4346    used later on. */
VG_(DebugInfo_sect_kind)4347 VgSectKind VG_(DebugInfo_sect_kind)( /*OUT*/const HChar** name, Addr a)
4348 {
4349    DebugInfo* di;
4350    VgSectKind res = Vg_SectUnknown;
4351 
4352    for (di = debugInfo_list; di != NULL; di = di->next) {
4353 
4354       if (0)
4355          VG_(printf)(
4356             "addr=%#lx di=%p %s got=%#lx,%lu plt=%#lx,%lu "
4357             "data=%#lx,%lu bss=%#lx,%lu\n",
4358             a, di, di->fsm.filename,
4359             di->got_avma,  di->got_size,
4360             di->plt_avma,  di->plt_size,
4361             di->data_avma, di->data_size,
4362             di->bss_avma,  di->bss_size);
4363 
4364       if (di->text_present
4365           && di->text_size > 0
4366           && a >= di->text_avma && a < di->text_avma + di->text_size) {
4367          res = Vg_SectText;
4368          break;
4369       }
4370       if (di->data_present
4371           && di->data_size > 0
4372           && a >= di->data_avma && a < di->data_avma + di->data_size) {
4373          res = Vg_SectData;
4374          break;
4375       }
4376       if (di->sdata_present
4377           && di->sdata_size > 0
4378           && a >= di->sdata_avma && a < di->sdata_avma + di->sdata_size) {
4379          res = Vg_SectData;
4380          break;
4381       }
4382       if (di->bss_present
4383           && di->bss_size > 0
4384           && a >= di->bss_avma && a < di->bss_avma + di->bss_size) {
4385          res = Vg_SectBSS;
4386          break;
4387       }
4388       if (di->sbss_present
4389           && di->sbss_size > 0
4390           && a >= di->sbss_avma && a < di->sbss_avma + di->sbss_size) {
4391          res = Vg_SectBSS;
4392          break;
4393       }
4394       if (di->plt_present
4395           && di->plt_size > 0
4396           && a >= di->plt_avma && a < di->plt_avma + di->plt_size) {
4397          res = Vg_SectPLT;
4398          break;
4399       }
4400       if (di->got_present
4401           && di->got_size > 0
4402           && a >= di->got_avma && a < di->got_avma + di->got_size) {
4403          res = Vg_SectGOT;
4404          break;
4405       }
4406       if (di->gotplt_present
4407           && di->gotplt_size > 0
4408           && a >= di->gotplt_avma && a < di->gotplt_avma + di->gotplt_size) {
4409          res = Vg_SectGOTPLT;
4410          break;
4411       }
4412       if (di->opd_present
4413           && di->opd_size > 0
4414           && a >= di->opd_avma && a < di->opd_avma + di->opd_size) {
4415          res = Vg_SectOPD;
4416          break;
4417       }
4418       /* we could also check for .eh_frame, if anyone really cares */
4419    }
4420 
4421    vg_assert( (di == NULL && res == Vg_SectUnknown)
4422               || (di != NULL && res != Vg_SectUnknown) );
4423 
4424    if (name) {
4425       if (di && di->fsm.filename) {
4426          *name = di->fsm.filename;
4427       } else {
4428          *name = "???";
4429       }
4430    }
4431 
4432    return res;
4433 
4434 }
4435 
4436 /*--------------------------------------------------------------------*/
4437 /*--- end                                                          ---*/
4438 /*--------------------------------------------------------------------*/
4439