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