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