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