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