Bug 469146 - massif --ignore-fn does not ignore inlined functions
[valgrind.git] / coregrind / m_debuginfo / debuginfo.c
blob22b41def211b08a745e7aa630b093e5a8bc92ae3
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 );
2293 Bool VG_(get_fnname_inl) ( DiEpoch ep, Addr a, const HChar** buf,
2294 const InlIPCursor* iipc )
2296 if (iipc) {
2297 vg_assert(is_DI_valid_for_epoch(iipc->di, ep));
2300 if (is_bottom(iipc)) {
2301 return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True,
2302 /*below-main-renaming*/True,
2303 ep, a, buf,
2304 /*match_anywhere_in_fun*/True,
2305 /*show offset?*/False,
2306 /*text sym*/True,
2307 /*offsetP*/NULL );
2308 } else {
2309 const DiInlLoc *next_inl = iipc && iipc->next_inltab >= 0
2310 ? & iipc->di->inltab[iipc->next_inltab]
2311 : NULL;
2312 vg_assert (next_inl);
2313 *buf = next_inl->inlinedfn;
2314 return True;
2318 /* This is available to tools... always demangle C++ names,
2319 match anywhere in function, and show offset if nonzero.
2320 NOTE: See IMPORTANT COMMENT above about persistence and ownership
2321 in pub_tool_debuginfo.h */
2322 Bool VG_(get_fnname_w_offset) ( DiEpoch ep, Addr a, const HChar** buf )
2324 return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True,
2325 /*below-main-renaming*/True,
2326 ep, a, buf,
2327 /*match_anywhere_in_fun*/True,
2328 /*show offset?*/True,
2329 /*text sym*/True,
2330 /*offsetP*/NULL );
2333 /* This is available to tools... always demangle C++ names,
2334 only succeed if 'a' matches first instruction of function,
2335 and don't show offsets.
2336 NOTE: See IMPORTANT COMMENT above about persistence and ownership
2337 in pub_tool_debuginfo.h */
2338 Bool VG_(get_fnname_if_entry) ( DiEpoch ep, Addr a, const HChar** buf )
2340 const HChar *tmp;
2341 Bool res;
2343 res = get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True,
2344 /*below-main-renaming*/True,
2345 ep, a, &tmp,
2346 /*match_anywhere_in_fun*/False,
2347 /*show offset?*/False,
2348 /*text sym*/True,
2349 /*offsetP*/NULL );
2350 if (res)
2351 *buf = tmp;
2352 return res;
2355 /* This is only available to core... don't C++-demangle, don't Z-demangle,
2356 don't rename below-main, match anywhere in function, and don't show
2357 offsets.
2358 NOTE: See IMPORTANT COMMENT above about persistence and ownership
2359 in pub_tool_debuginfo.h */
2360 Bool VG_(get_fnname_raw) ( DiEpoch ep, Addr a, const HChar** buf )
2362 return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False,
2363 /*below-main-renaming*/False,
2364 ep, a, buf,
2365 /*match_anywhere_in_fun*/True,
2366 /*show offset?*/False,
2367 /*text sym*/True,
2368 /*offsetP*/NULL );
2371 /* This is only available to core... don't demangle C++ names, but do
2372 do Z-demangling and below-main-renaming, match anywhere in function, and
2373 don't show offsets.
2374 NOTE: See IMPORTANT COMMENT above about persistence and ownership
2375 in pub_tool_debuginfo.h */
2376 Bool VG_(get_fnname_no_cxx_demangle) ( DiEpoch ep, Addr a, const HChar** buf,
2377 const InlIPCursor* iipc )
2379 // All the callers of VG_(get_fnname_no_cxx_demangle) must build
2380 // the iipc with the same ep as provided to VG_(get_fnname_no_cxx_demangle).
2381 // So, if we have an iipc, iipc->di must be valid in the provided ep.
2382 // Functionally, we could equally use iipc->di->first_epoch or ep, as
2383 // all the inlined fn calls will be described by the same di.
2384 if (iipc) {
2385 vg_assert(is_DI_valid_for_epoch(iipc->di, ep));
2388 if (is_bottom(iipc)) {
2389 // At the bottom (towards main), we describe the fn at eip.
2390 return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/True,
2391 /*below-main-renaming*/True,
2392 ep, a, buf,
2393 /*match_anywhere_in_fun*/True,
2394 /*show offset?*/False,
2395 /*text sym*/True,
2396 /*offsetP*/NULL );
2397 } else {
2398 const DiInlLoc *next_inl = iipc && iipc->next_inltab >= 0
2399 ? & iipc->di->inltab[iipc->next_inltab]
2400 : NULL;
2401 vg_assert (next_inl);
2402 // The function we are in is called by next_inl.
2403 *buf = next_inl->inlinedfn;
2404 return True;
2408 /* mips-linux only: find the offset of current address. This is needed for
2409 stack unwinding for MIPS.
2411 Bool VG_(get_inst_offset_in_function)( DiEpoch ep, Addr a,
2412 /*OUT*/PtrdiffT* offset )
2414 const HChar *fnname;
2415 return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False,
2416 /*below-main-renaming*/False,
2417 ep, a, &fnname,
2418 /*match_anywhere_in_sym*/True,
2419 /*show offset?*/False,
2420 /*text sym*/True,
2421 offset );
2424 Vg_FnNameKind VG_(get_fnname_kind) ( const HChar* name )
2426 if (VG_STREQ("main", name)) {
2427 return Vg_FnNameMain;
2429 } else if (
2430 # if defined(VGO_linux)
2431 VG_STREQ("__libc_start_main", name) || // glibc glibness
2432 VG_STREQ("__libc_start_call_main", name) || // glibc glibness
2433 VG_STREQN(18, "__libc_start_main.", name) || // gcc optimization
2434 VG_STREQ("generic_start_main", name) || // Yellow Dog doggedness
2435 VG_STREQN(19, "generic_start_main.", name) || // gcc optimization
2436 VG_STREQ("_start", name) ||
2437 # elif defined(VGO_freebsd)
2438 VG_STREQ("_start", name) || // FreeBSD libc
2439 # elif defined(VGO_darwin)
2440 // See readmacho.c for an explanation of this.
2441 VG_STREQ("start_according_to_valgrind", name) || // Darwin, darling
2442 # elif defined(VGO_solaris)
2443 VG_STREQ("_start", name) || // main() is called directly from _start
2444 # else
2445 # error "Unknown OS"
2446 # endif
2447 0) {
2448 return Vg_FnNameBelowMain;
2450 } else {
2451 return Vg_FnNameNormal;
2455 Vg_FnNameKind VG_(get_fnname_kind_from_IP) ( DiEpoch ep, Addr ip )
2457 const HChar *buf;
2459 // We don't demangle, because it's faster not to, and the special names
2460 // we're looking for won't be mangled.
2461 if (VG_(get_fnname_raw) ( ep, ip, &buf )) {
2463 return VG_(get_fnname_kind)(buf);
2464 } else {
2465 return Vg_FnNameNormal; // Don't know the name, treat it as normal.
2469 /* Looks up data_addr in the collection of data symbols, and if found
2470 puts a pointer to its name into dname. The name is zero terminated.
2471 Also data_addr's offset from the symbol start is put into *offset.
2472 NOTE: See IMPORTANT COMMENT above about persistence and ownership
2473 in pub_tool_debuginfo.h */
2474 Bool VG_(get_datasym_and_offset)( DiEpoch ep, Addr data_addr,
2475 /*OUT*/const HChar** dname,
2476 /*OUT*/PtrdiffT* offset )
2478 return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False,
2479 /*below-main-renaming*/False,
2480 ep, data_addr, dname,
2481 /*match_anywhere_in_sym*/True,
2482 /*show offset?*/False,
2483 /*text sym*/False,
2484 offset );
2487 /* Map a code address to the name of a shared object file or the
2488 executable. Returns False if no idea; otherwise True.
2489 Note: the string returned in *BUF is persistent as long as
2490 (1) the DebugInfo it belongs to is not discarded
2491 (2) the segment containing the address is not merged with another segment
2493 Bool VG_(get_objname) ( DiEpoch ep, Addr a, const HChar** objname )
2495 DebugInfo* di;
2496 const NSegment *seg;
2497 const HChar* filename;
2499 /* Look in the debugInfo_list to find the name. In most cases we
2500 expect this to produce a result. */
2501 for (di = debugInfo_list; di != NULL; di = di->next) {
2502 if (!is_DI_valid_for_epoch(di, ep))
2503 continue;
2504 if (di->text_present
2505 && di->text_size > 0
2506 && di->text_avma <= a
2507 && a < di->text_avma + di->text_size) {
2508 *objname = di->fsm.filename;
2509 return True;
2512 /* Last-ditch fallback position: if we don't find the address in
2513 the debugInfo_list, ask the address space manager whether it
2514 knows the name of the file associated with this mapping. This
2515 allows us to print the names of exe/dll files in the stack trace
2516 when running programs under wine.
2518 Restrict this to the case where 'ep' is the current epoch, though, so
2519 that we don't return information about this epoch when the caller was
2520 enquiring about a different one. */
2521 if ( eq_DiEpoch(ep, VG_(current_DiEpoch)())
2522 && (seg = VG_(am_find_nsegment)(a)) != NULL
2523 && (filename = VG_(am_get_filename)(seg)) != NULL ) {
2524 *objname = filename;
2525 return True;
2527 return False;
2530 /* Map a code address to its DebugInfo. Returns NULL if not found. Doesn't
2531 require debug info. */
2532 DebugInfo* VG_(find_DebugInfo) ( DiEpoch ep, Addr a )
2534 static UWord n_search = 0;
2535 DebugInfo* di;
2536 n_search++;
2537 for (di = debugInfo_list; di != NULL; di = di->next) {
2538 if (!is_DI_valid_for_epoch(di, ep))
2539 continue;
2540 if (di->text_present
2541 && di->text_size > 0
2542 && di->text_avma <= a
2543 && a < di->text_avma + di->text_size) {
2544 if (0 == (n_search & 0xF))
2545 move_DebugInfo_one_step_forward( di );
2546 return di;
2549 return NULL;
2552 /* Map a code address to a filename. Returns True if successful. The
2553 returned string is persistent as long as the DebugInfo to which it
2554 belongs is not discarded. */
2555 Bool VG_(get_filename)( DiEpoch ep, Addr a, const HChar** filename )
2557 DebugInfo* si;
2558 Word locno;
2559 UInt fndn_ix;
2561 search_all_loctabs ( ep, a, &si, &locno );
2562 if (si == NULL)
2563 return False;
2564 fndn_ix = ML_(fndn_ix) (si, locno);
2565 *filename = ML_(fndn_ix2filename) (si, fndn_ix);
2566 return True;
2569 /* Map a code address to a line number. Returns True if successful. */
2570 Bool VG_(get_linenum)( DiEpoch ep, Addr a, UInt* lineno )
2572 DebugInfo* si;
2573 Word locno;
2574 search_all_loctabs ( ep, a, &si, &locno );
2575 if (si == NULL)
2576 return False;
2577 *lineno = si->loctab[locno].lineno;
2579 return True;
2582 /* Map a code address to a filename/line number/dir name info.
2583 See prototype for detailed description of behaviour.
2585 Bool VG_(get_filename_linenum) ( DiEpoch ep, Addr a,
2586 /*OUT*/const HChar** filename,
2587 /*OUT*/const HChar** dirname,
2588 /*OUT*/UInt* lineno )
2590 DebugInfo* si;
2591 Word locno;
2592 UInt fndn_ix;
2594 search_all_loctabs ( ep, a, &si, &locno );
2595 if (si == NULL) {
2596 if (dirname) {
2597 *dirname = "";
2599 *filename = ""; // this used to be not initialised....
2600 return False;
2603 fndn_ix = ML_(fndn_ix)(si, locno);
2604 *filename = ML_(fndn_ix2filename) (si, fndn_ix);
2605 *lineno = si->loctab[locno].lineno;
2607 if (dirname) {
2608 /* caller wants directory info too .. */
2609 *dirname = ML_(fndn_ix2dirname) (si, fndn_ix);
2612 return True;
2616 /* Map a function name to its entry point and toc pointer. Is done by
2617 sequential search of all symbol tables, so is very slow. To
2618 mitigate the worst performance effects, you may specify a soname
2619 pattern, and only objects matching that pattern are searched.
2620 Therefore specify "*" to search all the objects. On TOC-afflicted
2621 platforms, a symbol is deemed to be found only if it has a nonzero
2622 TOC pointer. */
2623 Bool VG_(lookup_symbol_SLOW)(DiEpoch ep,
2624 const HChar* sopatt, const HChar* name,
2625 SymAVMAs* avmas)
2627 Bool require_pToc = False;
2628 Int i;
2629 const DebugInfo* si;
2630 Bool debug = False;
2631 # if defined(VG_PLAT_USES_PPCTOC)
2632 require_pToc = True;
2633 # endif
2634 for (si = debugInfo_list; si; si = si->next) {
2635 if (debug)
2636 VG_(printf)("lookup_symbol_SLOW: considering %s\n", si->soname);
2637 if (!is_DI_valid_for_epoch(si, ep))
2638 continue;
2639 if (!VG_(string_match)(sopatt, si->soname)) {
2640 if (debug)
2641 VG_(printf)(" ... skip\n");
2642 continue;
2644 for (i = 0; i < si->symtab_used; i++) {
2645 const HChar* pri_name = si->symtab[i].pri_name;
2646 vg_assert(pri_name);
2647 if (0==VG_(strcmp)(name, pri_name)
2648 && (require_pToc ? GET_TOCPTR_AVMA(si->symtab[i].avmas) : True)) {
2649 *avmas = si->symtab[i].avmas;
2650 return True;
2652 const HChar** sec_names = si->symtab[i].sec_names;
2653 if (sec_names) {
2654 vg_assert(sec_names[0]);
2655 while (*sec_names) {
2656 if (0==VG_(strcmp)(name, *sec_names)
2657 && (require_pToc
2658 ? GET_TOCPTR_AVMA(si->symtab[i].avmas) : True)) {
2659 *avmas = si->symtab[i].avmas;
2660 return True;
2662 sec_names++;
2667 return False;
2671 /* VG_(describe_IP): return info on code address, function name and
2672 filename. The returned string is allocated in a static buffer and will
2673 be overwritten in the next invocation. */
2675 /* Copy str into *buf starting at n, ensuring that buf is zero-terminated.
2676 Return the index of the terminating null character. */
2677 static SizeT
2678 putStr( SizeT n, HChar** buf, SizeT *bufsiz, const HChar* str )
2680 SizeT slen = VG_(strlen)(str);
2681 SizeT need = n + slen + 1;
2683 if (need > *bufsiz) {
2684 if (need < 256) need = 256;
2685 *bufsiz = need;
2686 *buf = ML_(dinfo_realloc)("putStr", *buf, *bufsiz);
2689 VG_(strcpy)(*buf + n, str);
2691 return n + slen;
2694 /* Same as putStr, but escaping chars for XML output. */
2695 static SizeT
2696 putStrEsc( SizeT n, HChar** buf, SizeT *bufsiz, const HChar* str )
2698 HChar alt[2];
2700 for (; *str != 0; str++) {
2701 switch (*str) {
2702 case '&':
2703 n = putStr( n, buf, bufsiz, "&amp;");
2704 break;
2705 case '<':
2706 n = putStr( n, buf, bufsiz, "&lt;");
2707 break;
2708 case '>':
2709 n = putStr( n, buf, bufsiz, "&gt;");
2710 break;
2711 default:
2712 alt[0] = *str;
2713 alt[1] = 0;
2714 n = putStr( n, buf, bufsiz, alt );
2715 break;
2718 return n;
2721 const HChar* VG_(describe_IP)(DiEpoch ep, Addr eip, const InlIPCursor *iipc)
2723 static HChar *buf = NULL;
2724 static SizeT bufsiz = 0;
2725 # define APPEND(_str) \
2726 n = putStr(n, &buf, &bufsiz, _str)
2727 # define APPEND_ESC(_str) \
2728 n = putStrEsc(n, &buf, &bufsiz, _str)
2730 UInt lineno;
2731 HChar ibuf[50]; // large enough
2732 SizeT n = 0;
2734 // An InlIPCursor is associated with one specific DebugInfo. So if
2735 // it exists, make sure that it is valid for the specified DiEpoch.
2736 vg_assert (!iipc
2737 || (is_DI_valid_for_epoch(iipc->di, ep) && iipc->eip == eip));
2739 const HChar *buf_fn;
2740 const HChar *buf_obj;
2741 const HChar *buf_srcloc;
2742 const HChar *buf_dirname;
2744 Bool know_dirinfo;
2745 Bool know_fnname;
2746 Bool know_objname;
2747 Bool know_srcloc;
2749 if (is_bottom(iipc)) {
2750 // At the bottom (towards main), we describe the fn at eip.
2751 know_fnname = VG_(clo_sym_offsets)
2752 ? VG_(get_fnname_w_offset) (ep, eip, &buf_fn)
2753 : VG_(get_fnname) (ep, eip, &buf_fn);
2754 } else {
2755 const DiInlLoc *next_inl = iipc && iipc->next_inltab >= 0
2756 ? & iipc->di->inltab[iipc->next_inltab]
2757 : NULL;
2758 vg_assert (next_inl);
2759 // The function we are in is called by next_inl.
2760 buf_fn = next_inl->inlinedfn;
2761 know_fnname = True;
2763 // INLINED????
2764 // ??? Can we compute an offset for an inlined fn call ?
2765 // ??? Offset from what ? The beginning of the inl info ?
2766 // ??? But that is not necessarily the beginning of the fn
2767 // ??? as e.g. an inlined fn call can be in several ranges.
2768 // ??? Currently never showing an offset.
2771 know_objname = VG_(get_objname)(ep, eip, &buf_obj);
2773 if (is_top(iipc)) {
2774 // The source for the highest level is in the loctab entry.
2775 know_srcloc = VG_(get_filename_linenum)(
2776 ep, eip,
2777 &buf_srcloc,
2778 &buf_dirname,
2779 &lineno
2781 know_dirinfo = buf_dirname[0] != '\0';
2782 } else {
2783 const DiInlLoc *cur_inl = iipc && iipc->cur_inltab >= 0
2784 ? & iipc->di->inltab[iipc->cur_inltab]
2785 : NULL;
2786 vg_assert (cur_inl);
2788 know_dirinfo = False;
2789 buf_dirname = "";
2790 // The fndn_ix and lineno for the caller of the inlined fn is in cur_inl.
2791 if (cur_inl->fndn_ix == 0) {
2792 buf_srcloc = "???";
2793 } else {
2794 FnDn *fndn = VG_(indexEltNumber) (iipc->di->fndnpool,
2795 cur_inl->fndn_ix);
2796 if (fndn->dirname) {
2797 buf_dirname = fndn->dirname;
2798 know_dirinfo = True;
2800 buf_srcloc = fndn->filename;
2802 lineno = cur_inl->lineno;
2803 know_srcloc = True;
2806 if (VG_(clo_xml)) {
2808 Bool human_readable = True;
2809 const HChar* maybe_newline = human_readable ? "\n " : "";
2810 const HChar* maybe_newline2 = human_readable ? "\n " : "";
2812 /* Print in XML format, dumping in as much info as we know.
2813 Ensure all tags are balanced. */
2814 APPEND("<frame>");
2815 VG_(sprintf)(ibuf,"<ip>0x%lX</ip>", eip);
2816 APPEND(maybe_newline);
2817 APPEND(ibuf);
2818 if (know_objname) {
2819 APPEND(maybe_newline);
2820 APPEND("<obj>");
2821 APPEND_ESC(buf_obj);
2822 APPEND("</obj>");
2824 if (know_fnname) {
2825 APPEND(maybe_newline);
2826 APPEND("<fn>");
2827 APPEND_ESC(buf_fn);
2828 APPEND("</fn>");
2830 if (know_srcloc) {
2831 if (know_dirinfo) {
2832 APPEND(maybe_newline);
2833 APPEND("<dir>");
2834 APPEND_ESC(buf_dirname);
2835 APPEND("</dir>");
2837 APPEND(maybe_newline);
2838 APPEND("<file>");
2839 APPEND_ESC(buf_srcloc);
2840 APPEND("</file>");
2841 APPEND(maybe_newline);
2842 APPEND("<line>");
2843 VG_(sprintf)(ibuf,"%u",lineno);
2844 APPEND(ibuf);
2845 APPEND("</line>");
2847 APPEND(maybe_newline2);
2848 APPEND("</frame>");
2850 } else {
2852 /* Print for humans to read */
2854 // Possible forms:
2856 // 0x80483BF: really (a.c:20)
2857 // 0x80483BF: really (in /foo/a.out)
2858 // 0x80483BF: really (in ???)
2859 // 0x80483BF: ??? (in /foo/a.out)
2860 // 0x80483BF: ??? (a.c:20)
2861 // 0x80483BF: ???
2863 VG_(sprintf)(ibuf,"0x%lX: ", eip);
2864 APPEND(ibuf);
2865 if (know_fnname) {
2866 APPEND(buf_fn);
2867 } else {
2868 APPEND("???");
2870 if (know_srcloc) {
2871 APPEND(" (");
2872 // Get the directory name, if any, possibly pruned, into dirname.
2873 const HChar* dirname = NULL;
2874 if (know_dirinfo && VG_(sizeXA)(VG_(clo_fullpath_after)) > 0) {
2875 Int i;
2876 dirname = buf_dirname;
2877 // Remove leading prefixes from the dirname.
2878 // If user supplied --fullpath-after=foo, this will remove
2879 // a leading string which matches '.*foo' (not greedy).
2880 for (i = 0; i < VG_(sizeXA)(VG_(clo_fullpath_after)); i++) {
2881 const HChar* prefix =
2882 *(HChar**) VG_(indexXA)( VG_(clo_fullpath_after), i );
2883 HChar* str = VG_(strstr)(dirname, prefix);
2884 if (str) {
2885 dirname = str + VG_(strlen)(prefix);
2886 break;
2889 /* remove leading "./" */
2890 if (dirname[0] == '.' && dirname[1] == '/')
2891 dirname += 2;
2893 // do we have any interesting directory name to show? If so
2894 // add it in.
2895 if (dirname && dirname[0] != 0) {
2896 APPEND(dirname);
2897 APPEND("/");
2899 APPEND(buf_srcloc);
2900 APPEND(":");
2901 VG_(sprintf)(ibuf,"%u",lineno);
2902 APPEND(ibuf);
2903 APPEND(")");
2904 } else if (know_objname) {
2905 APPEND(" (in ");
2906 APPEND(buf_obj);
2907 APPEND(")");
2908 } else if (know_fnname) {
2909 // Nb: do this in two steps because "??)" is a trigraph!
2910 APPEND(" (in ???");
2911 APPEND(")");
2915 return buf;
2917 # undef APPEND
2918 # undef APPEND_ESC
2922 /*--------------------------------------------------------------*/
2923 /*--- ---*/
2924 /*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/
2925 /*--- DWARF3 .eh_frame INFO ---*/
2926 /*--- ---*/
2927 /*--------------------------------------------------------------*/
2929 /* Note that the CFI machinery pertains to unwinding the stack "right now".
2930 There is no support for unwinding stack images obtained from some time in
2931 the past. That means that:
2933 (1) We only deal with CFI from DebugInfos that are valid for the current
2934 debuginfo epoch. Unlike in the rest of the file, there is no
2935 epoch-awareness.
2937 (2) We assume that the CFI cache will be invalidated every time the the
2938 epoch changes. This is done by ensuring (in the file above) that
2939 every call to advance_current_DiEpoch has a call to
2940 caches__invalidate alongside it.
2943 /* Gather up all the constant pieces of info needed to evaluate
2944 a CfiExpr into one convenient struct. */
2945 typedef
2946 struct {
2947 const D3UnwindRegs* uregs;
2948 Addr min_accessible;
2949 Addr max_accessible;
2951 CfiExprEvalContext;
2953 /* Evaluate the CfiExpr rooted at ix in exprs given the context eec.
2954 *ok is set to False on failure, but not to True on success. The
2955 caller must set it to True before calling. */
2956 __attribute__((noinline))
2957 static
2958 UWord evalCfiExpr ( const XArray* exprs, Int ix,
2959 const CfiExprEvalContext* eec, Bool* ok )
2961 UWord w, wL, wR;
2962 Addr a;
2963 const CfiExpr* e;
2964 vg_assert(sizeof(Addr) == sizeof(UWord));
2965 e = VG_(indexXA)( exprs, ix );
2966 switch (e->tag) {
2967 case Cex_Unop:
2968 w = evalCfiExpr( exprs, e->Cex.Unop.ix, eec, ok );
2969 if (!(*ok)) return 0;
2970 switch (e->Cex.Unop.op) {
2971 case Cunop_Abs: return (Word) w < 0 ? - w : w;
2972 case Cunop_Neg: return - (Word) w;
2973 case Cunop_Not: return ~ w;
2974 default: goto unhandled;
2976 /*NOTREACHED*/
2977 case Cex_Binop:
2978 wL = evalCfiExpr( exprs, e->Cex.Binop.ixL, eec, ok );
2979 if (!(*ok)) return 0;
2980 wR = evalCfiExpr( exprs, e->Cex.Binop.ixR, eec, ok );
2981 if (!(*ok)) return 0;
2982 switch (e->Cex.Binop.op) {
2983 case Cbinop_Add: return wL + wR;
2984 case Cbinop_Sub: return wL - wR;
2985 case Cbinop_And: return wL & wR;
2986 case Cbinop_Mul: return wL * wR;
2987 case Cbinop_Shl: return wL << wR;
2988 case Cbinop_Shr: return wL >> wR;
2989 case Cbinop_Eq: return wL == wR ? 1 : 0;
2990 case Cbinop_Ge: return (Word) wL >= (Word) wR ? 1 : 0;
2991 case Cbinop_Gt: return (Word) wL > (Word) wR ? 1 : 0;
2992 case Cbinop_Le: return (Word) wL <= (Word) wR ? 1 : 0;
2993 case Cbinop_Lt: return (Word) wL < (Word) wR ? 1 : 0;
2994 case Cbinop_Ne: return wL != wR ? 1 : 0;
2995 default: goto unhandled;
2997 /*NOTREACHED*/
2998 case Cex_CfiReg:
2999 switch (e->Cex.CfiReg.reg) {
3000 # if defined(VGA_x86) || defined(VGA_amd64)
3001 case Creg_IA_IP: return eec->uregs->xip;
3002 case Creg_IA_SP: return eec->uregs->xsp;
3003 case Creg_IA_BP: return eec->uregs->xbp;
3004 # elif defined(VGA_arm)
3005 case Creg_ARM_R15: return eec->uregs->r15;
3006 case Creg_ARM_R14: return eec->uregs->r14;
3007 case Creg_ARM_R13: return eec->uregs->r13;
3008 case Creg_ARM_R12: return eec->uregs->r12;
3009 case Creg_ARM_R7: return eec->uregs->r7;
3010 # elif defined(VGA_s390x)
3011 case Creg_S390_IA: return eec->uregs->ia;
3012 case Creg_S390_SP: return eec->uregs->sp;
3013 case Creg_S390_FP: return eec->uregs->fp;
3014 case Creg_S390_LR: return eec->uregs->lr;
3015 # elif defined(VGA_mips32) || defined(VGA_mips64) \
3016 || defined(VGA_nanomips)
3017 case Creg_IA_IP: return eec->uregs->pc;
3018 case Creg_IA_SP: return eec->uregs->sp;
3019 case Creg_IA_BP: return eec->uregs->fp;
3020 case Creg_MIPS_RA: return eec->uregs->ra;
3021 # elif defined(VGA_ppc32) || defined(VGA_ppc64be) \
3022 || defined(VGA_ppc64le)
3023 # elif defined(VGP_arm64_linux)
3024 case Creg_ARM64_SP: return eec->uregs->sp;
3025 case Creg_ARM64_X30: return eec->uregs->x30;
3026 case Creg_ARM64_X29: return eec->uregs->x29;
3027 # else
3028 # error "Unsupported arch"
3029 # endif
3030 default: goto unhandled;
3032 /*NOTREACHED*/
3033 case Cex_Const:
3034 return e->Cex.Const.con;
3035 case Cex_Deref:
3036 a = evalCfiExpr( exprs, e->Cex.Deref.ixAddr, eec, ok );
3037 if (!(*ok)) return 0;
3038 if (a < eec->min_accessible
3039 || a > eec->max_accessible - sizeof(UWord) + 1) {
3040 *ok = False;
3041 return 0;
3043 /* let's hope it doesn't trap! */
3044 return ML_(read_UWord)((void *)a);
3045 default:
3046 goto unhandled;
3048 /*NOTREACHED*/
3049 unhandled:
3050 VG_(printf)("\n\nevalCfiExpr: unhandled\n");
3051 ML_(ppCfiExpr)( exprs, ix );
3052 VG_(printf)("\n");
3053 vg_assert(0);
3054 /*NOTREACHED*/
3055 return 0;
3059 /* Search all the DebugInfos in the entire system, to find the DiCfSI_m
3060 that pertains to 'ip'.
3062 If found, set *diP to the DebugInfo in which it resides, and
3063 *cfsi_mP to the cfsi_m pointer in that DebugInfo's cfsi_m_pool.
3065 If not found, set *diP to (DebugInfo*)1 and *cfsi_mP to zero.
3067 Per comments at the top of this section, we only look for CFI in
3068 DebugInfos that are valid for the current epoch.
3070 __attribute__((noinline))
3071 static void find_DiCfSI ( /*OUT*/DebugInfo** diP,
3072 /*OUT*/DiCfSI_m** cfsi_mP,
3073 Addr ip )
3075 DebugInfo* di;
3076 Word i = -1;
3078 static UWord n_search = 0;
3079 static UWord n_steps = 0;
3080 n_search++;
3082 if (0) VG_(printf)("search for %#lx\n", ip);
3084 DiEpoch curr_epoch = VG_(current_DiEpoch)();
3086 for (di = debugInfo_list; di != NULL; di = di->next) {
3087 Word j;
3088 n_steps++;
3090 if (!is_DI_valid_for_epoch(di, curr_epoch))
3091 continue;
3093 /* Use the per-DebugInfo summary address ranges to skip
3094 inapplicable DebugInfos quickly. */
3095 if (di->cfsi_used == 0)
3096 continue;
3097 if (ip < di->cfsi_minavma || ip > di->cfsi_maxavma)
3098 continue;
3100 // This di must be active (because we have explicitly chosen not to
3101 // allow unwinding stacks that pertain to some past epoch). It can't
3102 // be archived or not-yet-active.
3103 vg_assert(is_DebugInfo_active(di));
3105 /* It might be in this DebugInfo. Search it. */
3106 j = ML_(search_one_cfitab)( di, ip );
3107 vg_assert(j >= -1 && j < (Word)di->cfsi_used);
3109 if (j != -1) {
3110 i = j;
3111 break; /* found it */
3115 if (i == -1) {
3117 /* we didn't find it. */
3118 *diP = (DebugInfo*)1;
3119 *cfsi_mP = 0;
3121 } else {
3123 /* found a di corresponding to ip. */
3124 /* ensure that di is 4-aligned (at least), so it can't possibly
3125 be equal to (DebugInfo*)1. */
3126 vg_assert(di && VG_IS_4_ALIGNED(di));
3127 *cfsi_mP = ML_(get_cfsi_m) (di, i);
3128 if (*cfsi_mP == NULL) {
3129 // This is a cfsi hole. Report no cfi information found.
3130 *diP = (DebugInfo*)1;
3131 // But we will still perform the hack below.
3132 } else {
3133 *diP = di;
3136 /* Start of performance-enhancing hack: once every 64 (chosen
3137 hackily after profiling) successful searches, move the found
3138 DebugInfo one step closer to the start of the list. This
3139 makes future searches cheaper. For starting konqueror on
3140 amd64, this in fact reduces the total amount of searching
3141 done by the above find-the-right-DebugInfo loop by more than
3142 a factor of 20. */
3143 if ((n_search & 0xF) == 0) {
3144 /* Move di one step closer to the start of the list. */
3145 move_DebugInfo_one_step_forward( di );
3147 /* End of performance-enhancing hack. */
3149 if (0 && ((n_search & 0x7FFFF) == 0))
3150 VG_(printf)("find_DiCfSI: %lu searches, "
3151 "%lu DebugInfos looked at\n",
3152 n_search, n_steps);
3159 /* Now follows a mechanism for caching queries to find_DiCfSI, since
3160 they are extremely frequent on amd64-linux, during stack unwinding.
3162 Each cache entry binds an ip value to a (di, cfsi_m*) pair. Possible
3163 values:
3165 di is non-null, cfsi_m* >= 0 ==> cache slot in use, "cfsi_m*"
3166 di is (DebugInfo*)1 ==> cache slot in use, no associated di
3167 di is NULL ==> cache slot not in use
3169 Hence simply zeroing out the entire cache invalidates all
3170 entries.
3172 We can map an ip value directly to a (di, cfsi_m*) pair as
3173 once a DebugInfo is read, adding new DiCfSI_m* is not possible
3174 anymore, as the cfsi_m_pool is frozen once the reading is terminated.
3175 Also, the cache is invalidated when new debuginfo is read due to
3176 an mmap or some debuginfo is discarded due to an munmap. */
3178 // Prime number, giving about 6Kbytes cache on 32 bits,
3179 // 12Kbytes cache on 64 bits.
3180 #define N_CFSI_M_CACHE 509
3182 typedef
3183 struct { Addr ip; DebugInfo* di; DiCfSI_m* cfsi_m; }
3184 CFSI_m_CacheEnt;
3186 static CFSI_m_CacheEnt cfsi_m_cache[N_CFSI_M_CACHE];
3188 static void cfsi_m_cache__invalidate ( void ) {
3189 VG_(memset)(&cfsi_m_cache, 0, sizeof(cfsi_m_cache));
3192 static inline CFSI_m_CacheEnt* cfsi_m_cache__find ( Addr ip )
3194 UWord hash = ip % N_CFSI_M_CACHE;
3195 CFSI_m_CacheEnt* ce = &cfsi_m_cache[hash];
3196 # ifdef N_Q_M_STATS
3197 static UWord n_q = 0, n_m = 0;
3198 n_q++;
3199 if (0 == (n_q & 0x1FFFFF))
3200 VG_(printf)("QQQ %lu %lu\n", n_q, n_m);
3201 # endif
3203 if (LIKELY(ce->ip == ip) && LIKELY(ce->di != NULL)) {
3204 /* found an entry in the cache .. */
3205 } else {
3206 /* not found in cache. Search and update. */
3207 # ifdef N_Q_M_STATS
3208 n_m++;
3209 # endif
3210 ce->ip = ip;
3211 find_DiCfSI( &ce->di, &ce->cfsi_m, ip );
3214 if (UNLIKELY(ce->di == (DebugInfo*)1)) {
3215 /* no DiCfSI for this address */
3216 return NULL;
3217 } else {
3218 /* found a DiCfSI for this address */
3219 return ce;
3223 Bool VG_(has_CF_info)(Addr a)
3225 return cfsi_m_cache__find (a) != NULL;
3230 inline
3231 static Addr compute_cfa ( const D3UnwindRegs* uregs,
3232 Addr min_accessible, Addr max_accessible,
3233 const DebugInfo* di, const DiCfSI_m* cfsi_m )
3235 CfiExprEvalContext eec;
3236 Addr cfa;
3237 Bool ok;
3239 /* Compute the CFA. */
3240 cfa = 0;
3241 switch (cfsi_m->cfa_how) {
3242 # if defined(VGA_x86) || defined(VGA_amd64)
3243 case CFIC_IA_SPREL:
3244 cfa = cfsi_m->cfa_off + uregs->xsp;
3245 break;
3246 case CFIC_IA_BPREL:
3247 cfa = cfsi_m->cfa_off + uregs->xbp;
3248 break;
3249 # elif defined(VGA_arm)
3250 case CFIC_ARM_R13REL:
3251 cfa = cfsi_m->cfa_off + uregs->r13;
3252 break;
3253 case CFIC_ARM_R12REL:
3254 cfa = cfsi_m->cfa_off + uregs->r12;
3255 break;
3256 case CFIC_ARM_R11REL:
3257 cfa = cfsi_m->cfa_off + uregs->r11;
3258 break;
3259 case CFIC_ARM_R7REL:
3260 cfa = cfsi_m->cfa_off + uregs->r7;
3261 break;
3262 # elif defined(VGA_s390x)
3263 case CFIC_IA_SPREL:
3264 cfa = cfsi_m->cfa_off + uregs->sp;
3265 break;
3266 case CFIR_MEMCFAREL:
3268 Addr a = uregs->sp + cfsi_m->cfa_off;
3269 if (a < min_accessible || a > max_accessible-sizeof(Addr))
3270 break;
3271 cfa = ML_(read_Addr)((void *)a);
3272 break;
3274 case CFIR_SAME:
3275 cfa = uregs->fp;
3276 break;
3277 case CFIC_IA_BPREL:
3278 cfa = cfsi_m->cfa_off + uregs->fp;
3279 break;
3280 # elif defined(VGA_mips32) || defined(VGA_mips64) || defined(VGA_nanomips)
3281 case CFIC_IA_SPREL:
3282 cfa = cfsi_m->cfa_off + uregs->sp;
3283 break;
3284 case CFIR_SAME:
3285 cfa = uregs->fp;
3286 break;
3287 case CFIC_IA_BPREL:
3288 cfa = cfsi_m->cfa_off + uregs->fp;
3289 break;
3290 # elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le)
3291 # elif defined(VGP_arm64_linux)
3292 case CFIC_ARM64_SPREL:
3293 cfa = cfsi_m->cfa_off + uregs->sp;
3294 break;
3295 case CFIC_ARM64_X29REL:
3296 cfa = cfsi_m->cfa_off + uregs->x29;
3297 break;
3298 # else
3299 # error "Unsupported arch"
3300 # endif
3301 case CFIC_EXPR: /* available on all archs */
3302 if (0) {
3303 VG_(printf)("CFIC_EXPR: ");
3304 ML_(ppCfiExpr)(di->cfsi_exprs, cfsi_m->cfa_off);
3305 VG_(printf)("\n");
3307 eec.uregs = uregs;
3308 eec.min_accessible = min_accessible;
3309 eec.max_accessible = max_accessible;
3310 ok = True;
3311 cfa = evalCfiExpr(di->cfsi_exprs, cfsi_m->cfa_off, &eec, &ok );
3312 if (!ok) return 0;
3313 break;
3314 default:
3315 vg_assert(0);
3317 return cfa;
3321 /* Get the call frame address (CFA) given an IP/SP/FP triple. */
3322 /* NOTE: This function may rearrange the order of entries in the
3323 DebugInfo list. */
3324 Addr ML_(get_CFA) ( Addr ip, Addr sp, Addr fp,
3325 Addr min_accessible, Addr max_accessible )
3327 CFSI_m_CacheEnt* ce;
3329 ce = cfsi_m_cache__find(ip);
3331 if (UNLIKELY(ce == NULL))
3332 return 0; /* no info. Nothing we can do. */
3334 /* Temporary impedance-matching kludge so that this keeps working
3335 on x86-linux and amd64-linux. */
3336 # if defined(VGA_x86) || defined(VGA_amd64)
3337 { D3UnwindRegs uregs;
3338 uregs.xip = ip;
3339 uregs.xsp = sp;
3340 uregs.xbp = fp;
3341 return compute_cfa(&uregs,
3342 min_accessible, max_accessible, ce->di, ce->cfsi_m);
3344 #elif defined(VGA_s390x)
3345 { D3UnwindRegs uregs;
3346 uregs.ia = ip;
3347 uregs.sp = sp;
3348 uregs.fp = fp;
3349 /* JRS FIXME 3 Apr 2019: surely we can do better for f0..f7 */
3350 uregs.f0 = 0;
3351 uregs.f1 = 0;
3352 uregs.f2 = 0;
3353 uregs.f3 = 0;
3354 uregs.f4 = 0;
3355 uregs.f5 = 0;
3356 uregs.f6 = 0;
3357 uregs.f7 = 0;
3358 return compute_cfa(&uregs,
3359 min_accessible, max_accessible, ce->di, ce->cfsi_m);
3361 #elif defined(VGA_mips32) || defined(VGA_mips64)
3362 { D3UnwindRegs uregs;
3363 uregs.pc = ip;
3364 uregs.sp = sp;
3365 uregs.fp = fp;
3366 return compute_cfa(&uregs,
3367 min_accessible, max_accessible, ce->di, ce->cfsi_m);
3370 # else
3371 return 0; /* indicates failure */
3372 # endif
3375 void VG_(ppUnwindInfo) (Addr from, Addr to)
3377 DebugInfo* di;
3378 CFSI_m_CacheEnt* ce;
3379 Addr ce_from;
3380 CFSI_m_CacheEnt* next_ce;
3383 ce = cfsi_m_cache__find(from);
3384 ce_from = from;
3385 while (from <= to) {
3386 from++;
3387 next_ce = cfsi_m_cache__find(from);
3388 if ((ce == NULL && next_ce != NULL)
3389 || (ce != NULL && next_ce == NULL)
3390 || (ce != NULL && next_ce != NULL && ce->cfsi_m != next_ce->cfsi_m)
3391 || from > to) {
3392 if (ce == NULL) {
3393 VG_(printf)("[%#lx .. %#lx]: no CFI info\n", ce_from, from-1);
3394 } else {
3395 di = ce->di;
3396 ML_(ppDiCfSI)(di->cfsi_exprs,
3397 ce_from, from - ce_from,
3398 ce->cfsi_m);
3400 ce = next_ce;
3401 ce_from = from;
3407 /* The main function for DWARF2/3 CFI-based stack unwinding. Given a
3408 set of registers in UREGS, modify it to hold the register values
3409 for the previous frame, if possible. Returns True if successful.
3410 If not successful, *UREGS is not changed.
3412 For x86 and amd64, the unwound registers are: {E,R}IP,
3413 {E,R}SP, {E,R}BP.
3415 For arm, the unwound registers are: R7 R11 R12 R13 R14 R15.
3417 For arm64, the unwound registers are: X29(FP) X30(LR) SP PC.
3419 For s390, the unwound registers are: R11(FP) R14(LR) R15(SP) F0..F7 PC.
3421 Bool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere,
3422 Addr min_accessible,
3423 Addr max_accessible )
3425 DebugInfo* di;
3426 DiCfSI_m* cfsi_m = NULL;
3427 Addr cfa, ipHere = 0;
3428 CFSI_m_CacheEnt* ce;
3429 CfiExprEvalContext eec __attribute__((unused));
3430 D3UnwindRegs uregsPrev;
3432 # if defined(VGA_x86) || defined(VGA_amd64)
3433 ipHere = uregsHere->xip;
3434 # elif defined(VGA_arm)
3435 ipHere = uregsHere->r15;
3436 # elif defined(VGA_s390x)
3437 ipHere = uregsHere->ia;
3438 # elif defined(VGA_mips32) || defined(VGA_mips64) || defined(VGA_nanomips)
3439 ipHere = uregsHere->pc;
3440 # elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le)
3441 # elif defined(VGP_arm64_linux)
3442 ipHere = uregsHere->pc;
3443 # else
3444 # error "Unknown arch"
3445 # endif
3446 ce = cfsi_m_cache__find(ipHere);
3448 if (UNLIKELY(ce == NULL))
3449 return False; /* no info. Nothing we can do. */
3451 di = ce->di;
3452 cfsi_m = ce->cfsi_m;
3454 if (0) {
3455 VG_(printf)("found cfsi_m (but printing fake base/len): ");
3456 ML_(ppDiCfSI)(di->cfsi_exprs, 0, 0, cfsi_m);
3459 VG_(bzero_inline)(&uregsPrev, sizeof(uregsPrev));
3461 /* First compute the CFA. */
3462 cfa = compute_cfa(uregsHere,
3463 min_accessible, max_accessible, di, cfsi_m);
3464 if (UNLIKELY(cfa == 0))
3465 return False;
3467 /* Now we know the CFA, use it to roll back the registers we're
3468 interested in. */
3470 # if defined(VGA_mips64) && defined(VGABI_N32)
3471 # define READ_REGISTER(addr) ML_(read_ULong)((addr))
3472 # else
3473 # define READ_REGISTER(addr) ML_(read_Addr)((addr))
3474 # endif
3476 # if defined(VGA_s390x)
3477 const Bool is_s390x = True;
3478 const Addr old_S390X_F0 = uregsHere->f0;
3479 const Addr old_S390X_F1 = uregsHere->f1;
3480 const Addr old_S390X_F2 = uregsHere->f2;
3481 const Addr old_S390X_F3 = uregsHere->f3;
3482 const Addr old_S390X_F4 = uregsHere->f4;
3483 const Addr old_S390X_F5 = uregsHere->f5;
3484 const Addr old_S390X_F6 = uregsHere->f6;
3485 const Addr old_S390X_F7 = uregsHere->f7;
3486 # else
3487 const Bool is_s390x = False;
3488 const Addr old_S390X_F0 = 0;
3489 const Addr old_S390X_F1 = 0;
3490 const Addr old_S390X_F2 = 0;
3491 const Addr old_S390X_F3 = 0;
3492 const Addr old_S390X_F4 = 0;
3493 const Addr old_S390X_F5 = 0;
3494 const Addr old_S390X_F6 = 0;
3495 const Addr old_S390X_F7 = 0;
3496 # endif
3498 # define COMPUTE(_prev, _here, _how, _off) \
3499 do { \
3500 switch (_how) { \
3501 case CFIR_UNKNOWN: \
3502 return False; \
3503 case CFIR_SAME: \
3504 _prev = _here; break; \
3505 case CFIR_MEMCFAREL: { \
3506 Addr a = cfa + (Word)_off; \
3507 if (a < min_accessible \
3508 || a > max_accessible-sizeof(Addr)) \
3509 return False; \
3510 _prev = READ_REGISTER((void *)a); \
3511 break; \
3513 case CFIR_CFAREL: \
3514 _prev = cfa + (Word)_off; \
3515 break; \
3516 case CFIR_EXPR: \
3517 if (0) \
3518 ML_(ppCfiExpr)(di->cfsi_exprs,_off); \
3519 eec.uregs = uregsHere; \
3520 eec.min_accessible = min_accessible; \
3521 eec.max_accessible = max_accessible; \
3522 Bool ok = True; \
3523 _prev = evalCfiExpr(di->cfsi_exprs, _off, &eec, &ok ); \
3524 if (!ok) return False; \
3525 break; \
3526 case CFIR_S390X_F0: \
3527 if (is_s390x) { _prev = old_S390X_F0; break; } \
3528 vg_assert(0+0-0); \
3529 case CFIR_S390X_F1: \
3530 if (is_s390x) { _prev = old_S390X_F1; break; } \
3531 vg_assert(0+1-1); \
3532 case CFIR_S390X_F2: \
3533 if (is_s390x) { _prev = old_S390X_F2; break; } \
3534 vg_assert(0+2-2); \
3535 case CFIR_S390X_F3: \
3536 if (is_s390x) { _prev = old_S390X_F3; break; } \
3537 vg_assert(0+3-3); \
3538 case CFIR_S390X_F4: \
3539 if (is_s390x) { _prev = old_S390X_F4; break; } \
3540 vg_assert(0+4-4); \
3541 case CFIR_S390X_F5: \
3542 if (is_s390x) { _prev = old_S390X_F5; break; } \
3543 vg_assert(0+5-5); \
3544 case CFIR_S390X_F6: \
3545 if (is_s390x) { _prev = old_S390X_F6; break; } \
3546 vg_assert(0+6-6); \
3547 case CFIR_S390X_F7: \
3548 if (is_s390x) { _prev = old_S390X_F7; break; } \
3549 vg_assert(0+7-7); \
3550 default: \
3551 vg_assert(0*0); \
3553 } while (0)
3555 # if defined(VGA_x86) || defined(VGA_amd64)
3556 COMPUTE(uregsPrev.xip, uregsHere->xip, cfsi_m->ra_how, cfsi_m->ra_off);
3557 COMPUTE(uregsPrev.xsp, uregsHere->xsp, cfsi_m->sp_how, cfsi_m->sp_off);
3558 COMPUTE(uregsPrev.xbp, uregsHere->xbp, cfsi_m->bp_how, cfsi_m->bp_off);
3559 # elif defined(VGA_arm)
3560 COMPUTE(uregsPrev.r15, uregsHere->r15, cfsi_m->ra_how, cfsi_m->ra_off);
3561 COMPUTE(uregsPrev.r14, uregsHere->r14, cfsi_m->r14_how, cfsi_m->r14_off);
3562 COMPUTE(uregsPrev.r13, uregsHere->r13, cfsi_m->r13_how, cfsi_m->r13_off);
3563 COMPUTE(uregsPrev.r12, uregsHere->r12, cfsi_m->r12_how, cfsi_m->r12_off);
3564 COMPUTE(uregsPrev.r11, uregsHere->r11, cfsi_m->r11_how, cfsi_m->r11_off);
3565 COMPUTE(uregsPrev.r7, uregsHere->r7, cfsi_m->r7_how, cfsi_m->r7_off);
3566 # elif defined(VGA_s390x)
3567 COMPUTE(uregsPrev.ia, uregsHere->ia, cfsi_m->ra_how, cfsi_m->ra_off);
3568 COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off);
3569 COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi_m->fp_how, cfsi_m->fp_off);
3570 COMPUTE(uregsPrev.f0, uregsHere->f0, cfsi_m->f0_how, cfsi_m->f0_off);
3571 COMPUTE(uregsPrev.f1, uregsHere->f1, cfsi_m->f1_how, cfsi_m->f1_off);
3572 COMPUTE(uregsPrev.f2, uregsHere->f2, cfsi_m->f2_how, cfsi_m->f2_off);
3573 COMPUTE(uregsPrev.f3, uregsHere->f3, cfsi_m->f3_how, cfsi_m->f3_off);
3574 COMPUTE(uregsPrev.f4, uregsHere->f4, cfsi_m->f4_how, cfsi_m->f4_off);
3575 COMPUTE(uregsPrev.f5, uregsHere->f5, cfsi_m->f5_how, cfsi_m->f5_off);
3576 COMPUTE(uregsPrev.f6, uregsHere->f6, cfsi_m->f6_how, cfsi_m->f6_off);
3577 COMPUTE(uregsPrev.f7, uregsHere->f7, cfsi_m->f7_how, cfsi_m->f7_off);
3578 # elif defined(VGA_mips32) || defined(VGA_mips64) || defined(VGA_nanomips)
3579 COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi_m->ra_how, cfsi_m->ra_off);
3580 COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off);
3581 COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi_m->fp_how, cfsi_m->fp_off);
3582 # elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le)
3583 # elif defined(VGP_arm64_linux)
3584 COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi_m->ra_how, cfsi_m->ra_off);
3585 COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off);
3586 COMPUTE(uregsPrev.x30, uregsHere->x30, cfsi_m->x30_how, cfsi_m->x30_off);
3587 COMPUTE(uregsPrev.x29, uregsHere->x29, cfsi_m->x29_how, cfsi_m->x29_off);
3588 # else
3589 # error "Unknown arch"
3590 # endif
3592 # undef READ_REGISTER
3593 # undef COMPUTE
3595 *uregsHere = uregsPrev;
3596 return True;
3600 /*--------------------------------------------------------------*/
3601 /*--- ---*/
3602 /*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/
3603 /*--- MSVC FPO INFO ---*/
3604 /*--- ---*/
3605 /*--------------------------------------------------------------*/
3607 Bool VG_(use_FPO_info) ( /*MOD*/Addr* ipP,
3608 /*MOD*/Addr* spP,
3609 /*MOD*/Addr* fpP,
3610 DiEpoch ep,
3611 Addr min_accessible,
3612 Addr max_accessible )
3614 Word i;
3615 const DebugInfo* di;
3616 FPO_DATA* fpo = NULL;
3617 Addr spHere;
3619 static UWord n_search = 0;
3620 static UWord n_steps = 0;
3621 n_search++;
3623 if (0) VG_(printf)("search FPO for %#lx\n", *ipP);
3625 for (di = debugInfo_list; di != NULL; di = di->next) {
3626 n_steps++;
3628 if (!is_DI_valid_for_epoch(di, ep))
3629 continue;
3631 /* Use the per-DebugInfo summary address ranges to skip
3632 inapplicable DebugInfos quickly. */
3633 if (di->fpo == NULL)
3634 continue;
3635 if (*ipP < di->fpo_minavma || *ipP > di->fpo_maxavma)
3636 continue;
3638 i = ML_(search_one_fpotab)( di, *ipP );
3639 if (i != -1) {
3640 Word j;
3641 if (0) {
3642 /* debug printing only */
3643 VG_(printf)("look for %#lx size %lu i %ld\n",
3644 *ipP, di->fpo_size, i);
3645 for (j = 0; j < di->fpo_size; j++)
3646 VG_(printf)("[%02ld] %#x %u\n",
3647 j, di->fpo[j].ulOffStart, di->fpo[j].cbProcSize);
3649 vg_assert(i >= 0 && i < di->fpo_size);
3650 fpo = &di->fpo[i];
3651 break;
3655 if (fpo == NULL)
3656 return False;
3658 if (0 && ((n_search & 0x7FFFF) == 0))
3659 VG_(printf)("VG_(use_FPO_info): %lu searches, "
3660 "%lu DebugInfos looked at\n",
3661 n_search, n_steps);
3664 /* Start of performance-enhancing hack: once every 64 (chosen
3665 hackily after profiling) successful searches, move the found
3666 DebugInfo one step closer to the start of the list. This makes
3667 future searches cheaper. For starting konqueror on amd64, this
3668 in fact reduces the total amount of searching done by the above
3669 find-the-right-DebugInfo loop by more than a factor of 20. */
3670 if ((n_search & 0x3F) == 0) {
3671 /* Move si one step closer to the start of the list. */
3672 //move_DebugInfo_one_step_forward( di );
3674 /* End of performance-enhancing hack. */
3676 if (0) {
3677 VG_(printf)("found fpo: ");
3678 //ML_(ppFPO)(fpo);
3682 Stack layout is:
3683 %esp->
3684 4*.cbRegs {%edi, %esi, %ebp, %ebx}
3685 4*.cdwLocals
3686 return_pc
3687 4*.cdwParams
3688 prior_%esp->
3690 Typical code looks like:
3691 sub $4*.cdwLocals,%esp
3692 Alternative to above for >=4KB (and sometimes for smaller):
3693 mov $size,%eax
3694 call __chkstk # WinNT performs page-by-page probe!
3695 __chkstk is much like alloc(), except that on return
3696 %eax= 5+ &CALL. Thus it could be used as part of
3697 Position Independent Code to locate the Global Offset Table.
3698 push %ebx
3699 push %ebp
3700 push %esi
3701 Other once-only instructions often scheduled >here<.
3702 push %edi
3704 If the pc is within the first .cbProlog bytes of the function,
3705 then you must disassemble to see how many registers have been pushed,
3706 because instructions in the prolog may be scheduled for performance.
3707 The order of PUSH is always %ebx, %ebp, %esi, %edi, with trailing
3708 registers not pushed when .cbRegs < 4. This seems somewhat strange
3709 because %ebp is the register whose usage you want to minimize,
3710 yet it is in the first half of the PUSH list.
3712 I don't know what happens when the compiler constructs an outgoing CALL.
3713 %esp could move if outgoing parameters are PUSHed, and this affects
3714 traceback for errors during the PUSHes. */
3716 spHere = *spP;
3718 *ipP = ML_(read_Addr)((void *)(spHere + 4*(fpo->cbRegs + fpo->cdwLocals)));
3719 *spP = spHere + 4*(fpo->cbRegs + fpo->cdwLocals + 1
3720 + fpo->cdwParams);
3721 *fpP = ML_(read_Addr)((void *)(spHere + 4*2));
3722 return True;
3725 Bool VG_(FPO_info_present)(void)
3727 const DebugInfo* di;
3728 for (di = debugInfo_list; di != NULL; di = di->next) {
3729 if (di->fpo != NULL)
3730 return True;
3732 return False;
3736 /*--------------------------------------------------------------*/
3737 /*--- ---*/
3738 /*--- TOP LEVEL: GENERATE DESCRIPTION OF DATA ADDRESSES ---*/
3739 /*--- FROM DWARF3 DEBUG INFO ---*/
3740 /*--- ---*/
3741 /*--------------------------------------------------------------*/
3743 /* Try to make p2XA(dst, fmt, args..) turn into
3744 VG_(xaprintf)(dst, fmt, args) without having to resort to
3745 vararg macros. As usual with everything to do with varargs, it's
3746 an ugly hack.
3748 //#define p2XA(dstxa, format, args...)
3749 // VG_(xaprintf)(dstxa, format, ##args)
3751 #define p2XA VG_(xaprintf)
3753 /* Add a zero-terminating byte to DST, which must be an XArray* of
3754 HChar. */
3755 static void zterm_XA ( XArray* dst )
3757 HChar zero = 0;
3758 (void) VG_(addBytesToXA)( dst, &zero, 1 );
3762 /* Evaluate the location expression/list for var, to see whether or
3763 not data_addr falls within the variable. If so also return the
3764 offset of data_addr from the start of the variable. Note that
3765 regs, which supplies ip,sp,fp values, will be NULL for global
3766 variables, and non-NULL for local variables. */
3767 static Bool data_address_is_in_var ( /*OUT*/PtrdiffT* offset,
3768 const XArray* /* TyEnt */ tyents,
3769 const DiVariable* var,
3770 const RegSummary* regs,
3771 Addr data_addr,
3772 const DebugInfo* di )
3774 MaybeULong mul;
3775 SizeT var_szB;
3776 GXResult res;
3777 Bool show = False;
3779 vg_assert(var->name);
3780 vg_assert(var->gexpr);
3782 /* Figure out how big the variable is. */
3783 mul = ML_(sizeOfType)(tyents, var->typeR);
3784 /* If this var has a type whose size is unknown, zero, or
3785 impossibly large, it should never have been added. ML_(addVar)
3786 should have rejected it. */
3787 vg_assert(mul.b == True);
3788 vg_assert(mul.ul > 0);
3789 if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
3790 /* After this point, we assume we can truncate mul.ul to a host word
3791 safely (without loss of info). */
3793 var_szB = (SizeT)mul.ul; /* NB: truncate to host word */
3795 if (show) {
3796 VG_(printf)("VVVV: data_address_%#lx_is_in_var: %s :: ",
3797 data_addr, var->name );
3798 ML_(pp_TyEnt_C_ishly)( tyents, var->typeR );
3799 VG_(printf)("\n");
3802 /* ignore zero-sized vars; they can never match anything. */
3803 if (var_szB == 0) {
3804 if (show)
3805 VG_(printf)("VVVV: -> Fail (variable is zero sized)\n");
3806 return False;
3809 res = ML_(evaluate_GX)( var->gexpr, var->fbGX, regs, di );
3811 if (show) {
3812 VG_(printf)("VVVV: -> ");
3813 ML_(pp_GXResult)( res );
3814 VG_(printf)("\n");
3817 if (res.kind == GXR_Addr
3818 && res.word <= data_addr
3819 && data_addr < res.word + var_szB) {
3820 *offset = data_addr - res.word;
3821 return True;
3822 } else {
3823 return False;
3828 /* Format the acquired information into DN(AME)1 and DN(AME)2, which
3829 are XArray*s of HChar, that have been initialised by the caller.
3830 Resulting strings will be zero terminated. Information is
3831 formatted in an understandable way. Not so easy. If frameNo is
3832 -1, this is assumed to be a global variable; else a local
3833 variable. */
3834 static void format_message ( /*MOD*/XArray* /* of HChar */ dn1,
3835 /*MOD*/XArray* /* of HChar */ dn2,
3836 Addr data_addr,
3837 const DebugInfo* di,
3838 const DiVariable* var,
3839 PtrdiffT var_offset,
3840 PtrdiffT residual_offset,
3841 const XArray* /*HChar*/ described,
3842 Int frameNo,
3843 ThreadId tid )
3845 Bool have_descr, have_srcloc;
3846 Bool xml = VG_(clo_xml);
3847 const HChar* vo_plural = var_offset == 1 ? "" : "s";
3848 const HChar* ro_plural = residual_offset == 1 ? "" : "s";
3849 const HChar* basetag = "auxwhat"; /* a constant */
3850 HChar tagL[32], tagR[32], xagL[32], xagR[32];
3851 const HChar *fileName = ML_(fndn_ix2filename)(di, var->fndn_ix);
3852 // fileName will be "???" if var->fndn_ix == 0.
3853 // fileName will only be used if have_descr is True.
3855 if (frameNo < -1) {
3856 vg_assert(0); /* Not allowed */
3858 else if (frameNo == -1) {
3859 vg_assert(tid == VG_INVALID_THREADID);
3861 else /* (frameNo >= 0) */ {
3862 vg_assert(tid != VG_INVALID_THREADID);
3865 vg_assert(dn1 && dn2);
3866 vg_assert(described);
3867 vg_assert(var && var->name);
3868 have_descr = VG_(sizeXA)(described) > 0
3869 && *(HChar*)VG_(indexXA)(described,0) != '\0';
3870 have_srcloc = var->fndn_ix > 0 && var->lineNo > 0;
3872 tagL[0] = tagR[0] = xagL[0] = xagR[0] = 0;
3873 if (xml) {
3874 VG_(sprintf)(tagL, "<%s>", basetag); // <auxwhat>
3875 VG_(sprintf)(tagR, "</%s>", basetag); // </auxwhat>
3876 VG_(sprintf)(xagL, "<x%s>", basetag); // <xauxwhat>
3877 VG_(sprintf)(xagR, "</x%s>", basetag); // </xauxwhat>
3880 # define TAGL(_xa) p2XA(_xa, "%s", tagL)
3881 # define TAGR(_xa) p2XA(_xa, "%s", tagR)
3882 # define XAGL(_xa) p2XA(_xa, "%s", xagL)
3883 # define XAGR(_xa) p2XA(_xa, "%s", xagR)
3884 # define TXTL(_xa) p2XA(_xa, "%s", "<text>")
3885 # define TXTR(_xa) p2XA(_xa, "%s", "</text>")
3887 /* ------ local cases ------ */
3889 if ( frameNo >= 0 && (!have_srcloc) && (!have_descr) ) {
3890 /* no srcloc, no description:
3891 Location 0x7fefff6cf is 543 bytes inside local var "a",
3892 in frame #1 of thread 1
3894 if (xml) {
3895 TAGL( dn1 );
3896 p2XA( dn1,
3897 "Location 0x%lx is %ld byte%s inside local var \"%pS\",",
3898 data_addr, var_offset, vo_plural, var->name );
3899 TAGR( dn1 );
3900 TAGL( dn2 );
3901 p2XA( dn2,
3902 "in frame #%d of thread %u", frameNo, tid );
3903 TAGR( dn2 );
3904 } else {
3905 p2XA( dn1,
3906 "Location 0x%lx is %ld byte%s inside local var \"%s\",",
3907 data_addr, var_offset, vo_plural, var->name );
3908 p2XA( dn2,
3909 "in frame #%d of thread %u", frameNo, tid );
3912 else
3913 if ( frameNo >= 0 && have_srcloc && (!have_descr) ) {
3914 /* no description:
3915 Location 0x7fefff6cf is 543 bytes inside local var "a"
3916 declared at dsyms7.c:17, in frame #1 of thread 1
3918 if (xml) {
3919 TAGL( dn1 );
3920 p2XA( dn1,
3921 "Location 0x%lx is %ld byte%s inside local var \"%pS\"",
3922 data_addr, var_offset, vo_plural, var->name );
3923 TAGR( dn1 );
3924 XAGL( dn2 );
3925 TXTL( dn2 );
3926 p2XA( dn2,
3927 "declared at %pS:%d, in frame #%d of thread %u",
3928 fileName, var->lineNo, frameNo, tid );
3929 TXTR( dn2 );
3930 // FIXME: also do <dir>
3931 p2XA( dn2,
3932 " <file>%pS</file> <line>%d</line> ",
3933 fileName, var->lineNo );
3934 XAGR( dn2 );
3935 } else {
3936 p2XA( dn1,
3937 "Location 0x%lx is %ld byte%s inside local var \"%s\"",
3938 data_addr, var_offset, vo_plural, var->name );
3939 p2XA( dn2,
3940 "declared at %s:%d, in frame #%d of thread %u",
3941 fileName, var->lineNo, frameNo, tid );
3944 else
3945 if ( frameNo >= 0 && (!have_srcloc) && have_descr ) {
3946 /* no srcloc:
3947 Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2
3948 in frame #1 of thread 1
3950 if (xml) {
3951 TAGL( dn1 );
3952 p2XA( dn1,
3953 "Location 0x%lx is %ld byte%s inside %pS%pS",
3954 data_addr, residual_offset, ro_plural, var->name,
3955 (HChar*)(VG_(indexXA)(described,0)) );
3956 TAGR( dn1 );
3957 TAGL( dn2 );
3958 p2XA( dn2,
3959 "in frame #%d of thread %u", frameNo, tid );
3960 TAGR( dn2 );
3961 } else {
3962 p2XA( dn1,
3963 "Location 0x%lx is %ld byte%s inside %s%s",
3964 data_addr, residual_offset, ro_plural, var->name,
3965 (HChar*)(VG_(indexXA)(described,0)) );
3966 p2XA( dn2,
3967 "in frame #%d of thread %u", frameNo, tid );
3970 else
3971 if ( frameNo >= 0 && have_srcloc && have_descr ) {
3972 /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
3973 declared at dsyms7.c:17, in frame #1 of thread 1 */
3974 if (xml) {
3975 TAGL( dn1 );
3976 p2XA( dn1,
3977 "Location 0x%lx is %ld byte%s inside %pS%pS,",
3978 data_addr, residual_offset, ro_plural, var->name,
3979 (HChar*)(VG_(indexXA)(described,0)) );
3980 TAGR( dn1 );
3981 XAGL( dn2 );
3982 TXTL( dn2 );
3983 p2XA( dn2,
3984 "declared at %pS:%d, in frame #%d of thread %u",
3985 fileName, var->lineNo, frameNo, tid );
3986 TXTR( dn2 );
3987 // FIXME: also do <dir>
3988 p2XA( dn2,
3989 " <file>%pS</file> <line>%d</line> ",
3990 fileName, var->lineNo );
3991 XAGR( dn2 );
3992 } else {
3993 p2XA( dn1,
3994 "Location 0x%lx is %ld byte%s inside %s%s,",
3995 data_addr, residual_offset, ro_plural, var->name,
3996 (HChar*)(VG_(indexXA)(described,0)) );
3997 p2XA( dn2,
3998 "declared at %s:%d, in frame #%d of thread %u",
3999 fileName, var->lineNo, frameNo, tid );
4002 else
4003 /* ------ global cases ------ */
4004 if ( frameNo >= -1 && (!have_srcloc) && (!have_descr) ) {
4005 /* no srcloc, no description:
4006 Location 0x7fefff6cf is 543 bytes inside global var "a"
4008 if (xml) {
4009 TAGL( dn1 );
4010 p2XA( dn1,
4011 "Location 0x%lx is %ld byte%s inside global var \"%pS\"",
4012 data_addr, var_offset, vo_plural, var->name );
4013 TAGR( dn1 );
4014 } else {
4015 p2XA( dn1,
4016 "Location 0x%lx is %ld byte%s inside global var \"%s\"",
4017 data_addr, var_offset, vo_plural, var->name );
4020 else
4021 if ( frameNo >= -1 && have_srcloc && (!have_descr) ) {
4022 /* no description:
4023 Location 0x7fefff6cf is 543 bytes inside global var "a"
4024 declared at dsyms7.c:17
4026 if (xml) {
4027 TAGL( dn1 );
4028 p2XA( dn1,
4029 "Location 0x%lx is %ld byte%s inside global var \"%pS\"",
4030 data_addr, var_offset, vo_plural, var->name );
4031 TAGR( dn1 );
4032 XAGL( dn2 );
4033 TXTL( dn2 );
4034 p2XA( dn2,
4035 "declared at %pS:%d",
4036 fileName, var->lineNo);
4037 TXTR( dn2 );
4038 // FIXME: also do <dir>
4039 p2XA( dn2,
4040 " <file>%pS</file> <line>%d</line> ",
4041 fileName, var->lineNo );
4042 XAGR( dn2 );
4043 } else {
4044 p2XA( dn1,
4045 "Location 0x%lx is %ld byte%s inside global var \"%s\"",
4046 data_addr, var_offset, vo_plural, var->name );
4047 p2XA( dn2,
4048 "declared at %s:%d",
4049 fileName, var->lineNo);
4052 else
4053 if ( frameNo >= -1 && (!have_srcloc) && have_descr ) {
4054 /* no srcloc:
4055 Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
4056 a global variable
4058 if (xml) {
4059 TAGL( dn1 );
4060 p2XA( dn1,
4061 "Location 0x%lx is %ld byte%s inside %pS%pS,",
4062 data_addr, residual_offset, ro_plural, var->name,
4063 (HChar*)(VG_(indexXA)(described,0)) );
4064 TAGR( dn1 );
4065 TAGL( dn2 );
4066 p2XA( dn2,
4067 "a global variable");
4068 TAGR( dn2 );
4069 } else {
4070 p2XA( dn1,
4071 "Location 0x%lx is %ld byte%s inside %s%s,",
4072 data_addr, residual_offset, ro_plural, var->name,
4073 (HChar*)(VG_(indexXA)(described,0)) );
4074 p2XA( dn2,
4075 "a global variable");
4078 else
4079 if ( frameNo >= -1 && have_srcloc && have_descr ) {
4080 /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
4081 a global variable declared at dsyms7.c:17 */
4082 if (xml) {
4083 TAGL( dn1 );
4084 p2XA( dn1,
4085 "Location 0x%lx is %ld byte%s inside %pS%pS,",
4086 data_addr, residual_offset, ro_plural, var->name,
4087 (HChar*)(VG_(indexXA)(described,0)) );
4088 TAGR( dn1 );
4089 XAGL( dn2 );
4090 TXTL( dn2 );
4091 p2XA( dn2,
4092 "a global variable declared at %pS:%d",
4093 fileName, var->lineNo);
4094 TXTR( dn2 );
4095 // FIXME: also do <dir>
4096 p2XA( dn2,
4097 " <file>%pS</file> <line>%d</line> ",
4098 fileName, var->lineNo );
4099 XAGR( dn2 );
4100 } else {
4101 p2XA( dn1,
4102 "Location 0x%lx is %ld byte%s inside %s%s,",
4103 data_addr, residual_offset, ro_plural, var->name,
4104 (HChar*)(VG_(indexXA)(described,0)) );
4105 p2XA( dn2,
4106 "a global variable declared at %s:%d",
4107 fileName, var->lineNo);
4110 else
4111 vg_assert(0);
4113 /* Zero terminate both strings */
4114 zterm_XA( dn1 );
4115 zterm_XA( dn2 );
4117 # undef TAGL
4118 # undef TAGR
4119 # undef XAGL
4120 # undef XAGR
4121 # undef TXTL
4122 # undef TXTR
4126 /* Determine if data_addr is a local variable in the frame
4127 characterised by (ip,sp,fp), and if so write its description at the
4128 ends of DNAME{1,2}, which are XArray*s of HChar, that have been
4129 initialised by the caller, zero terminate both, and return True.
4130 If it's not a local variable in said frame, return False. */
4131 static
4132 Bool consider_vars_in_frame ( /*MOD*/XArray* /* of HChar */ dname1,
4133 /*MOD*/XArray* /* of HChar */ dname2,
4134 DiEpoch ep,
4135 Addr data_addr,
4136 Addr ip, Addr sp, Addr fp,
4137 /* shown to user: */
4138 ThreadId tid, Int frameNo )
4140 Word i;
4141 DebugInfo* di;
4142 RegSummary regs;
4143 Bool debug = False;
4145 static UInt n_search = 0;
4146 static UInt n_steps = 0;
4147 n_search++;
4148 if (debug)
4149 VG_(printf)("QQQQ: cvif: ip,sp,fp %#lx,%#lx,%#lx\n", ip,sp,fp);
4150 /* first, find the DebugInfo that pertains to 'ip'. */
4151 for (di = debugInfo_list; di; di = di->next) {
4152 n_steps++;
4153 if (!is_DI_valid_for_epoch(di, ep))
4154 continue;
4155 /* text segment missing? unlikely, but handle it .. */
4156 if (!di->text_present || di->text_size == 0)
4157 continue;
4158 /* Ok. So does this text mapping bracket the ip? */
4159 if (di->text_avma <= ip && ip < di->text_avma + di->text_size)
4160 break;
4163 /* Didn't find it. Strange -- means ip is a code address outside
4164 of any mapped text segment. Unlikely but not impossible -- app
4165 could be generating code to run. */
4166 if (!di)
4167 return False;
4169 if (0 && ((n_search & 0x1) == 0))
4170 VG_(printf)("consider_vars_in_frame: %u searches, "
4171 "%u DebugInfos looked at\n",
4172 n_search, n_steps);
4173 /* Start of performance-enhancing hack: once every ??? (chosen
4174 hackily after profiling) successful searches, move the found
4175 DebugInfo one step closer to the start of the list. This makes
4176 future searches cheaper. */
4177 if ((n_search & 0xFFFF) == 0) {
4178 /* Move si one step closer to the start of the list. */
4179 move_DebugInfo_one_step_forward( di );
4181 /* End of performance-enhancing hack. */
4183 /* any var info at all? */
4184 if (!di->varinfo)
4185 return False;
4187 /* Work through the scopes from most deeply nested outwards,
4188 looking for code address ranges that bracket 'ip'. The
4189 variables on each such address range found are in scope right
4190 now. Don't descend to level zero as that is the global
4191 scope. */
4192 regs.ip = ip;
4193 regs.sp = sp;
4194 regs.fp = fp;
4196 /* "for each scope, working outwards ..." */
4197 for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) {
4198 XArray* vars;
4199 Word j;
4200 DiAddrRange* arange;
4201 OSet* this_scope
4202 = *(OSet**)VG_(indexXA)( di->varinfo, i );
4203 if (debug)
4204 VG_(printf)("QQQQ: considering scope %ld\n", (Word)i);
4205 if (!this_scope)
4206 continue;
4207 /* Find the set of variables in this scope that
4208 bracket the program counter. */
4209 arange = VG_(OSetGen_LookupWithCmp)(
4210 this_scope, &ip,
4211 ML_(cmp_for_DiAddrRange_range)
4213 if (!arange)
4214 continue;
4215 /* stay sane */
4216 vg_assert(arange->aMin <= arange->aMax);
4217 /* It must bracket the ip we asked for, else
4218 ML_(cmp_for_DiAddrRange_range) is somehow broken. */
4219 vg_assert(arange->aMin <= ip && ip <= arange->aMax);
4220 /* It must have an attached XArray of DiVariables. */
4221 vars = arange->vars;
4222 vg_assert(vars);
4223 /* But it mustn't cover the entire address range. We only
4224 expect that to happen for the global scope (level 0), which
4225 we're not looking at here. Except, it may cover the entire
4226 address range, but in that case the vars array must be
4227 empty. */
4228 vg_assert(! (arange->aMin == (Addr)0
4229 && arange->aMax == ~(Addr)0
4230 && VG_(sizeXA)(vars) > 0) );
4231 for (j = 0; j < VG_(sizeXA)( vars ); j++) {
4232 DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j );
4233 PtrdiffT offset;
4234 if (debug)
4235 VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n",
4236 var->name,arange->aMin,arange->aMax,ip);
4237 if (data_address_is_in_var( &offset, di->admin_tyents,
4238 var, &regs,
4239 data_addr, di )) {
4240 PtrdiffT residual_offset = 0;
4241 XArray* described = ML_(describe_type)( &residual_offset,
4242 di->admin_tyents,
4243 var->typeR, offset );
4244 format_message( dname1, dname2,
4245 data_addr, di, var, offset, residual_offset,
4246 described, frameNo, tid );
4247 VG_(deleteXA)( described );
4248 return True;
4253 return False;
4256 /* Try to form some description of DATA_ADDR by looking at the DWARF3
4257 debug info we have. This considers all global variables, and 8
4258 frames in the stacks of all threads. Result is written at the ends
4259 of DNAME{1,2}V, which are XArray*s of HChar, that have been
4260 initialised by the caller, and True is returned. If no description
4261 is created, False is returned. Regardless of the return value,
4262 DNAME{1,2}V are guaranteed to be zero terminated after the call.
4264 Note that after the call, DNAME{1,2} may have more than one
4265 trailing zero, so callers should establish the useful text length
4266 using VG_(strlen) on the contents, rather than VG_(sizeXA) on the
4267 XArray itself.
4269 Bool VG_(get_data_description)(
4270 /*MOD*/ XArray* /* of HChar */ dname1,
4271 /*MOD*/ XArray* /* of HChar */ dname2,
4272 DiEpoch ep, Addr data_addr
4275 # define N_FRAMES 8
4276 Addr ips[N_FRAMES], sps[N_FRAMES], fps[N_FRAMES];
4277 UInt n_frames;
4279 Addr stack_min, stack_max;
4280 ThreadId tid;
4281 Bool found;
4282 DebugInfo* di;
4283 Word j;
4285 if (0) VG_(printf)("get_data_description: dataaddr %#lx\n", data_addr);
4286 /* First, see if data_addr is (or is part of) a global variable.
4287 Loop over the DebugInfos we have. Check data_addr against the
4288 outermost scope of all of them, as that should be a global
4289 scope. */
4290 for (di = debugInfo_list; di != NULL; di = di->next) {
4291 OSet* global_scope;
4292 Word gs_size;
4293 Addr zero;
4294 DiAddrRange* global_arange;
4295 Word i;
4296 XArray* vars;
4298 /* text segment missing? unlikely, but handle it .. */
4299 if (!di->text_present || di->text_size == 0)
4300 continue;
4301 /* any var info at all? */
4302 if (!di->varinfo)
4303 continue;
4304 /* perhaps this object didn't contribute any vars at all? */
4305 if (VG_(sizeXA)( di->varinfo ) == 0)
4306 continue;
4307 global_scope = *(OSet**)VG_(indexXA)( di->varinfo, 0 );
4308 vg_assert(global_scope);
4309 gs_size = VG_(OSetGen_Size)( global_scope );
4310 /* The global scope might be completely empty if this
4311 compilation unit declared locals but nothing global. */
4312 if (gs_size == 0)
4313 continue;
4314 /* But if it isn't empty, then it must contain exactly one
4315 element, which covers the entire address range. */
4316 vg_assert(gs_size == 1);
4317 /* Fish out the global scope and check it is as expected. */
4318 zero = 0;
4319 global_arange
4320 = VG_(OSetGen_Lookup)( global_scope, &zero );
4321 /* The global range from (Addr)0 to ~(Addr)0 must exist */
4322 vg_assert(global_arange);
4323 vg_assert(global_arange->aMin == (Addr)0
4324 && global_arange->aMax == ~(Addr)0);
4325 /* Any vars in this range? */
4326 if (!global_arange->vars)
4327 continue;
4328 /* Ok, there are some vars in the global scope of this
4329 DebugInfo. Wade through them and see if the data addresses
4330 of any of them bracket data_addr. */
4331 vars = global_arange->vars;
4332 for (i = 0; i < VG_(sizeXA)( vars ); i++) {
4333 PtrdiffT offset;
4334 DiVariable* var = (DiVariable*)VG_(indexXA)( vars, i );
4335 vg_assert(var->name);
4336 /* Note we use a NULL RegSummary* here. It can't make any
4337 sense for a global variable to have a location expression
4338 which depends on a SP/FP/IP value. So don't supply any.
4339 This means, if the evaluation of the location
4340 expression/list requires a register, we have to let it
4341 fail. */
4342 if (data_address_is_in_var( &offset, di->admin_tyents, var,
4343 NULL/* RegSummary* */,
4344 data_addr, di )) {
4345 PtrdiffT residual_offset = 0;
4346 XArray* described = ML_(describe_type)( &residual_offset,
4347 di->admin_tyents,
4348 var->typeR, offset );
4349 format_message( dname1, dname2,
4350 data_addr, di, var, offset, residual_offset,
4351 described, -1/*frameNo*/,
4352 VG_INVALID_THREADID );
4353 VG_(deleteXA)( described );
4354 zterm_XA( dname1 );
4355 zterm_XA( dname2 );
4356 return True;
4361 /* Ok, well it's not a global variable. So now let's snoop around
4362 in the stacks of all the threads. First try to figure out which
4363 thread's stack data_addr is in. */
4365 /* Perhaps it's on a thread's stack? */
4366 found = False;
4367 VG_(thread_stack_reset_iter)(&tid);
4368 while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) {
4369 if (stack_min >= stack_max)
4370 continue; /* ignore obviously stupid cases */
4371 if (stack_min - VG_STACK_REDZONE_SZB <= data_addr
4372 && data_addr <= stack_max) {
4373 found = True;
4374 break;
4377 if (!found) {
4378 zterm_XA( dname1 );
4379 zterm_XA( dname2 );
4380 return False;
4383 /* We conclude data_addr is in thread tid's stack. Unwind the
4384 stack to get a bunch of (ip,sp,fp) triples describing the
4385 frames, and for each frame, consider the local variables. */
4386 n_frames = VG_(get_StackTrace)( tid, ips, N_FRAMES,
4387 sps, fps, 0/*first_ip_delta*/ );
4389 vg_assert(n_frames >= 0 && n_frames <= N_FRAMES);
4390 for (j = 0; j < n_frames; j++) {
4391 if (consider_vars_in_frame( dname1, dname2,
4392 ep, data_addr,
4393 ips[j],
4394 sps[j], fps[j], tid, j )) {
4395 zterm_XA( dname1 );
4396 zterm_XA( dname2 );
4397 return True;
4399 /* Now, it appears that gcc sometimes appears to produce
4400 location lists whose ranges don't actually cover the call
4401 instruction, even though the address of the variable in
4402 question is passed as a parameter in the call. AFAICS this
4403 is simply a bug in gcc - how can the variable be claimed not
4404 exist in memory (on the stack) for the duration of a call in
4405 which its address is passed? But anyway, in the particular
4406 case I investigated (memcheck/tests/varinfo6.c, call to croak
4407 on line 2999, local var budget declared at line 3115
4408 appearing not to exist across the call to mainSort on line
4409 3143, "gcc.orig (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2)" on
4410 amd64), the variable's location list does claim it exists
4411 starting at the first byte of the first instruction after the
4412 call instruction. So, call consider_vars_in_frame a second
4413 time, but this time add 1 to the IP. GDB handles this
4414 example with no difficulty, which leads me to believe that
4415 either (1) I misunderstood something, or (2) GDB has an
4416 equivalent kludge. */
4417 if (j > 0 /* this is a non-innermost frame */
4418 && consider_vars_in_frame( dname1, dname2,
4419 ep, data_addr,
4420 ips[j] + 1,
4421 sps[j], fps[j], tid, j )) {
4422 zterm_XA( dname1 );
4423 zterm_XA( dname2 );
4424 return True;
4428 /* We didn't find anything useful. */
4429 zterm_XA( dname1 );
4430 zterm_XA( dname2 );
4431 return False;
4432 # undef N_FRAMES
4436 //////////////////////////////////////////////////////////////////
4437 // //
4438 // Support for other kinds of queries to the Dwarf3 var info //
4439 // //
4440 //////////////////////////////////////////////////////////////////
4442 /* Figure out if the variable 'var' has a location that is linearly
4443 dependent on a stack pointer value, or a frame pointer value, and
4444 if it is, add a description of it to 'blocks'. Otherwise ignore
4445 it. If 'arrays_only' is True, also ignore it unless it has an
4446 array type. */
4448 static
4449 void analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks,
4450 const XArray* /* TyEnt */ tyents,
4451 Addr ip, const DebugInfo* di, const DiVariable* var,
4452 Bool arrays_only )
4454 GXResult res_sp_6k, res_sp_7k, res_fp_6k, res_fp_7k;
4455 RegSummary regs;
4456 MaybeULong mul;
4457 Bool isVec;
4458 TyEnt* ty;
4460 Bool debug = False;
4461 if (0&&debug)
4462 VG_(printf)("adeps: var %s\n", var->name );
4464 /* Figure out how big the variable is. */
4465 mul = ML_(sizeOfType)(tyents, var->typeR);
4466 /* If this var has a type whose size is unknown, zero, or
4467 impossibly large, it should never have been added. ML_(addVar)
4468 should have rejected it. */
4469 vg_assert(mul.b == True);
4470 vg_assert(mul.ul > 0);
4471 if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
4472 /* After this point, we assume we can truncate mul.ul to a host word
4473 safely (without loss of info). */
4475 /* skip if non-array and we're only interested in arrays */
4476 ty = ML_(TyEnts__index_by_cuOff)( tyents, NULL, var->typeR );
4477 vg_assert(ty);
4478 vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty));
4479 if (ty->tag == Te_UNKNOWN)
4480 return; /* perhaps we should complain in this case? */
4481 isVec = ty->tag == Te_TyArray;
4482 if (arrays_only && !isVec)
4483 return;
4485 if (0) {ML_(pp_TyEnt_C_ishly)(tyents, var->typeR);
4486 VG_(printf)(" %s\n", var->name);}
4488 /* Do some test evaluations of the variable's location expression,
4489 in order to guess whether it is sp-relative, fp-relative, or
4490 none. A crude hack, which can be interpreted roughly as finding
4491 the first derivative of the location expression w.r.t. the
4492 supplied frame and stack pointer values. */
4493 regs.fp = 0;
4494 regs.ip = ip;
4495 regs.sp = 6 * 1024;
4496 res_sp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
4498 regs.fp = 0;
4499 regs.ip = ip;
4500 regs.sp = 7 * 1024;
4501 res_sp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
4503 regs.fp = 6 * 1024;
4504 regs.ip = ip;
4505 regs.sp = 0;
4506 res_fp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
4508 regs.fp = 7 * 1024;
4509 regs.ip = ip;
4510 regs.sp = 0;
4511 res_fp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
4513 vg_assert(res_sp_6k.kind == res_sp_7k.kind);
4514 vg_assert(res_sp_6k.kind == res_fp_6k.kind);
4515 vg_assert(res_sp_6k.kind == res_fp_7k.kind);
4517 if (res_sp_6k.kind == GXR_Addr) {
4518 StackBlock block;
4519 GXResult res;
4520 UWord sp_delta = res_sp_7k.word - res_sp_6k.word;
4521 UWord fp_delta = res_fp_7k.word - res_fp_6k.word;
4522 vg_assert(sp_delta == 0 || sp_delta == 1024);
4523 vg_assert(fp_delta == 0 || fp_delta == 1024);
4525 if (sp_delta == 0 && fp_delta == 0) {
4526 /* depends neither on sp nor fp, so it can't be a stack
4527 local. Ignore it. */
4529 else
4530 if (sp_delta == 1024 && fp_delta == 0) {
4531 regs.sp = regs.fp = 0;
4532 regs.ip = ip;
4533 res = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
4534 vg_assert(res.kind == GXR_Addr);
4535 if (debug)
4536 VG_(printf)(" %5lu .. %5llu (sp) %s\n",
4537 res.word, res.word + mul.ul - 1, var->name);
4538 block.base = res.word;
4539 block.szB = (SizeT)mul.ul;
4540 block.spRel = True;
4541 block.isVec = isVec;
4542 VG_(memset)( &block.name[0], 0, sizeof(block.name) );
4543 if (var->name)
4544 VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 );
4545 block.name[ sizeof(block.name)-1 ] = 0;
4546 VG_(addToXA)( blocks, &block );
4548 else
4549 if (sp_delta == 0 && fp_delta == 1024) {
4550 regs.sp = regs.fp = 0;
4551 regs.ip = ip;
4552 res = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
4553 vg_assert(res.kind == GXR_Addr);
4554 if (debug)
4555 VG_(printf)(" %5lu .. %5llu (FP) %s\n",
4556 res.word, res.word + mul.ul - 1, var->name);
4557 block.base = res.word;
4558 block.szB = (SizeT)mul.ul;
4559 block.spRel = False;
4560 block.isVec = isVec;
4561 VG_(memset)( &block.name[0], 0, sizeof(block.name) );
4562 if (var->name)
4563 VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 );
4564 block.name[ sizeof(block.name)-1 ] = 0;
4565 VG_(addToXA)( blocks, &block );
4567 else {
4568 vg_assert(0);
4574 /* Get an XArray of StackBlock which describe the stack (auto) blocks
4575 for this ip. The caller is expected to free the XArray at some
4576 point. If 'arrays_only' is True, only array-typed blocks are
4577 returned; otherwise blocks of all types are returned. */
4579 XArray* /* of StackBlock */
4580 VG_(di_get_stack_blocks_at_ip)( Addr ip, Bool arrays_only )
4582 /* This is a derivation of consider_vars_in_frame() above. */
4583 Word i;
4584 DebugInfo* di;
4585 Bool debug = False;
4587 XArray* res = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dgsbai.1",
4588 ML_(dinfo_free),
4589 sizeof(StackBlock) );
4591 static UInt n_search = 0;
4592 static UInt n_steps = 0;
4593 n_search++;
4594 if (debug)
4595 VG_(printf)("QQQQ: dgsbai: ip %#lx\n", ip);
4596 /* first, find the DebugInfo that pertains to 'ip'. */
4597 for (di = debugInfo_list; di; di = di->next) {
4598 n_steps++;
4599 /* text segment missing? unlikely, but handle it .. */
4600 if (!di->text_present || di->text_size == 0)
4601 continue;
4602 /* Ok. So does this text mapping bracket the ip? */
4603 if (di->text_avma <= ip && ip < di->text_avma + di->text_size)
4604 break;
4607 /* Didn't find it. Strange -- means ip is a code address outside
4608 of any mapped text segment. Unlikely but not impossible -- app
4609 could be generating code to run. */
4610 if (!di)
4611 return res; /* currently empty */
4613 if (0 && ((n_search & 0x1) == 0))
4614 VG_(printf)("VG_(di_get_stack_blocks_at_ip): %u searches, "
4615 "%u DebugInfos looked at\n",
4616 n_search, n_steps);
4617 /* Start of performance-enhancing hack: once every ??? (chosen
4618 hackily after profiling) successful searches, move the found
4619 DebugInfo one step closer to the start of the list. This makes
4620 future searches cheaper. */
4621 if ((n_search & 0xFFFF) == 0) {
4622 /* Move si one step closer to the start of the list. */
4623 move_DebugInfo_one_step_forward( di );
4625 /* End of performance-enhancing hack. */
4627 /* any var info at all? */
4628 if (!di->varinfo)
4629 return res; /* currently empty */
4631 /* Work through the scopes from most deeply nested outwards,
4632 looking for code address ranges that bracket 'ip'. The
4633 variables on each such address range found are in scope right
4634 now. Don't descend to level zero as that is the global
4635 scope. */
4637 /* "for each scope, working outwards ..." */
4638 for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) {
4639 XArray* vars;
4640 Word j;
4641 DiAddrRange* arange;
4642 OSet* this_scope
4643 = *(OSet**)VG_(indexXA)( di->varinfo, i );
4644 if (debug)
4645 VG_(printf)("QQQQ: considering scope %ld\n", (Word)i);
4646 if (!this_scope)
4647 continue;
4648 /* Find the set of variables in this scope that
4649 bracket the program counter. */
4650 arange = VG_(OSetGen_LookupWithCmp)(
4651 this_scope, &ip,
4652 ML_(cmp_for_DiAddrRange_range)
4654 if (!arange)
4655 continue;
4656 /* stay sane */
4657 vg_assert(arange->aMin <= arange->aMax);
4658 /* It must bracket the ip we asked for, else
4659 ML_(cmp_for_DiAddrRange_range) is somehow broken. */
4660 vg_assert(arange->aMin <= ip && ip <= arange->aMax);
4661 /* It must have an attached XArray of DiVariables. */
4662 vars = arange->vars;
4663 vg_assert(vars);
4664 /* But it mustn't cover the entire address range. We only
4665 expect that to happen for the global scope (level 0), which
4666 we're not looking at here. Except, it may cover the entire
4667 address range, but in that case the vars array must be
4668 empty. */
4669 vg_assert(! (arange->aMin == (Addr)0
4670 && arange->aMax == ~(Addr)0
4671 && VG_(sizeXA)(vars) > 0) );
4672 for (j = 0; j < VG_(sizeXA)( vars ); j++) {
4673 DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j );
4674 if (debug)
4675 VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n",
4676 var->name,arange->aMin,arange->aMax,ip);
4677 analyse_deps( res, di->admin_tyents, ip,
4678 di, var, arrays_only );
4682 return res;
4686 /* Get an array of GlobalBlock which describe the global blocks owned
4687 by the shared object characterised by the given di_handle. Asserts
4688 if the handle is invalid. The caller is responsible for freeing
4689 the array at some point. If 'arrays_only' is True, only
4690 array-typed blocks are returned; otherwise blocks of all types are
4691 returned. */
4693 XArray* /* of GlobalBlock */
4694 VG_(di_get_global_blocks_from_dihandle) ( ULong di_handle, Bool arrays_only )
4696 /* This is a derivation of consider_vars_in_frame() above. */
4698 DebugInfo* di;
4699 XArray* gvars; /* XArray* of GlobalBlock */
4700 Word nScopes, scopeIx;
4702 /* The first thing to do is find the DebugInfo that
4703 pertains to 'di_handle'. */
4704 vg_assert(di_handle > 0);
4705 for (di = debugInfo_list; di; di = di->next) {
4706 if (di->handle == di_handle)
4707 break;
4710 /* If this fails, we were unable to find any DebugInfo with the
4711 given handle. This is considered an error on the part of the
4712 caller. */
4713 vg_assert(di != NULL);
4715 /* we'll put the collected variables in here. */
4716 gvars = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dggbfd.1",
4717 ML_(dinfo_free), sizeof(GlobalBlock) );
4719 /* any var info at all? */
4720 if (!di->varinfo)
4721 return gvars;
4723 /* we'll iterate over all the variables we can find, even if
4724 it seems senseless to visit stack-allocated variables */
4725 /* Iterate over all scopes */
4726 nScopes = VG_(sizeXA)( di->varinfo );
4727 for (scopeIx = 0; scopeIx < nScopes; scopeIx++) {
4729 /* Iterate over each (code) address range at the current scope */
4730 DiAddrRange* range;
4731 OSet* /* of DiAddrInfo */ scope
4732 = *(OSet**)VG_(indexXA)( di->varinfo, scopeIx );
4733 vg_assert(scope);
4734 VG_(OSetGen_ResetIter)(scope);
4735 while ( (range = VG_(OSetGen_Next)(scope)) ) {
4737 /* Iterate over each variable in the current address range */
4738 Word nVars, varIx;
4739 vg_assert(range->vars);
4740 nVars = VG_(sizeXA)( range->vars );
4741 for (varIx = 0; varIx < nVars; varIx++) {
4743 Bool isVec;
4744 GXResult res;
4745 MaybeULong mul;
4746 GlobalBlock gb;
4747 TyEnt* ty;
4748 DiVariable* var = VG_(indexXA)( range->vars, varIx );
4749 vg_assert(var->name);
4750 if (0) VG_(printf)("at depth %ld var %s ", scopeIx, var->name );
4752 /* Now figure out if this variable has a constant address
4753 (that is, independent of FP, SP, phase of moon, etc),
4754 and if so, what the address is. Any variable with a
4755 constant address is deemed to be a global so we collect
4756 it. */
4757 if (0) { VG_(printf)("EVAL: "); ML_(pp_GX)(var->gexpr);
4758 VG_(printf)("\n"); }
4759 res = ML_(evaluate_trivial_GX)( var->gexpr, di );
4761 /* Not a constant address => not interesting */
4762 if (res.kind != GXR_Addr) {
4763 if (0) VG_(printf)("FAIL\n");
4764 continue;
4767 /* Ok, it's a constant address. See if we want to collect
4768 it. */
4769 if (0) VG_(printf)("%#lx\n", res.word);
4771 /* Figure out how big the variable is. */
4772 mul = ML_(sizeOfType)(di->admin_tyents, var->typeR);
4774 /* If this var has a type whose size is unknown, zero, or
4775 impossibly large, it should never have been added.
4776 ML_(addVar) should have rejected it. */
4777 vg_assert(mul.b == True);
4778 vg_assert(mul.ul > 0);
4779 if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
4780 /* After this point, we assume we can truncate mul.ul to a
4781 host word safely (without loss of info). */
4783 /* skip if non-array and we're only interested in
4784 arrays */
4785 ty = ML_(TyEnts__index_by_cuOff)( di->admin_tyents, NULL,
4786 var->typeR );
4787 vg_assert(ty);
4788 vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty));
4789 if (ty->tag == Te_UNKNOWN)
4790 continue; /* perhaps we should complain in this case? */
4792 isVec = ty->tag == Te_TyArray;
4793 if (arrays_only && !isVec) continue;
4795 /* Ok, so collect it! */
4796 vg_assert(var->name);
4797 vg_assert(di->soname);
4798 if (0) VG_(printf)("XXXX %s %s %d\n", var->name,
4799 ML_(fndn_ix2filename)(di, var->fndn_ix),
4800 var->lineNo);
4801 VG_(memset)(&gb, 0, sizeof(gb));
4802 gb.addr = res.word;
4803 gb.szB = (SizeT)mul.ul;
4804 gb.isVec = isVec;
4805 VG_(strncpy)(&gb.name[0], var->name, sizeof(gb.name)-1);
4806 VG_(strncpy)(&gb.soname[0], di->soname, sizeof(gb.soname)-1);
4807 vg_assert(gb.name[ sizeof(gb.name)-1 ] == 0);
4808 vg_assert(gb.soname[ sizeof(gb.soname)-1 ] == 0);
4810 VG_(addToXA)( gvars, &gb );
4812 } /* for (varIx = 0; varIx < nVars; varIx++) */
4814 } /* while ( (range = VG_(OSetGen_Next)(scope)) ) */
4816 } /* for (scopeIx = 0; scopeIx < nScopes; scopeIx++) */
4818 return gvars;
4822 /*------------------------------------------------------------*/
4823 /*--- DebugInfo accessor functions ---*/
4824 /*------------------------------------------------------------*/
4826 const DebugInfo* VG_(next_DebugInfo)(const DebugInfo* di)
4828 if (di == NULL)
4829 return debugInfo_list;
4830 return di->next;
4833 Addr VG_(DebugInfo_get_text_avma)(const DebugInfo* di)
4835 return di->text_present ? di->text_avma : 0;
4838 SizeT VG_(DebugInfo_get_text_size)(const DebugInfo* di)
4840 return di->text_present ? di->text_size : 0;
4843 Addr VG_(DebugInfo_get_bss_avma)(const DebugInfo* di)
4845 return di->bss_present ? di->bss_avma : 0;
4848 SizeT VG_(DebugInfo_get_bss_size)(const DebugInfo* di)
4850 return di->bss_present ? di->bss_size : 0;
4853 Addr VG_(DebugInfo_get_plt_avma)(const DebugInfo* di)
4855 return di->plt_present ? di->plt_avma : 0;
4858 SizeT VG_(DebugInfo_get_plt_size)(const DebugInfo* di)
4860 return di->plt_present ? di->plt_size : 0;
4863 Addr VG_(DebugInfo_get_gotplt_avma)(const DebugInfo* di)
4865 return di->gotplt_present ? di->gotplt_avma : 0;
4868 SizeT VG_(DebugInfo_get_gotplt_size)(const DebugInfo* di)
4870 return di->gotplt_present ? di->gotplt_size : 0;
4873 Addr VG_(DebugInfo_get_got_avma)(const DebugInfo* di)
4875 return di->got_present ? di->got_avma : 0;
4878 SizeT VG_(DebugInfo_get_got_size)(const DebugInfo* di)
4880 return di->got_present ? di->got_size : 0;
4883 const HChar* VG_(DebugInfo_get_soname)(const DebugInfo* di)
4885 return di->soname;
4888 const HChar* VG_(DebugInfo_get_filename)(const DebugInfo* di)
4890 return di->fsm.filename;
4893 PtrdiffT VG_(DebugInfo_get_text_bias)(const DebugInfo* di)
4895 return di->text_present ? di->text_bias : 0;
4898 Int VG_(DebugInfo_syms_howmany) ( const DebugInfo *si )
4900 return si->symtab_used;
4903 void VG_(DebugInfo_syms_getidx) ( const DebugInfo *si,
4904 Int idx,
4905 /*OUT*/SymAVMAs* avmas,
4906 /*OUT*/UInt* size,
4907 /*OUT*/const HChar** pri_name,
4908 /*OUT*/const HChar*** sec_names,
4909 /*OUT*/Bool* isText,
4910 /*OUT*/Bool* isIFunc,
4911 /*OUT*/Bool* isGlobal )
4913 vg_assert(idx >= 0 && idx < si->symtab_used);
4914 if (avmas) *avmas = si->symtab[idx].avmas;
4915 if (size) *size = si->symtab[idx].size;
4916 if (pri_name) *pri_name = si->symtab[idx].pri_name;
4917 if (sec_names) *sec_names = si->symtab[idx].sec_names;
4918 if (isText) *isText = si->symtab[idx].isText;
4919 if (isIFunc) *isIFunc = si->symtab[idx].isIFunc;
4920 if (isGlobal) *isGlobal = si->symtab[idx].isGlobal;
4924 /*------------------------------------------------------------*/
4925 /*--- SectKind query functions ---*/
4926 /*------------------------------------------------------------*/
4928 /* Convert a VgSectKind to a string, which must be copied if you want
4929 to change it. */
4930 const HChar* VG_(pp_SectKind)( VgSectKind kind )
4932 switch (kind) {
4933 case Vg_SectUnknown: return "Unknown";
4934 case Vg_SectText: return "Text";
4935 case Vg_SectData: return "Data";
4936 case Vg_SectBSS: return "BSS";
4937 case Vg_SectGOT: return "GOT";
4938 case Vg_SectPLT: return "PLT";
4939 case Vg_SectOPD: return "OPD";
4940 case Vg_SectGOTPLT: return "GOTPLT";
4941 default: vg_assert(0);
4945 /* Given an address 'a', make a guess of which section of which object
4946 it comes from. If name is non-NULL, then the object's name is put
4947 in *name. The returned name, if any, should be saved away, if there is
4948 a chance that a debug-info will be discarded and the name is being
4949 used later on. */
4950 VgSectKind VG_(DebugInfo_sect_kind)( /*OUT*/const HChar** objname, Addr a)
4952 DebugInfo* di;
4953 VgSectKind res = Vg_SectUnknown;
4955 for (di = debugInfo_list; di != NULL; di = di->next) {
4957 if (0)
4958 VG_(printf)(
4959 "addr=%#lx di=%p %s got=%#lx,%lu plt=%#lx,%lu "
4960 "data=%#lx,%lu bss=%#lx,%lu\n",
4961 a, di, di->fsm.filename,
4962 di->got_avma, di->got_size,
4963 di->plt_avma, di->plt_size,
4964 di->data_avma, di->data_size,
4965 di->bss_avma, di->bss_size);
4967 if (di->text_present
4968 && di->text_size > 0
4969 && a >= di->text_avma && a < di->text_avma + di->text_size) {
4970 res = Vg_SectText;
4971 break;
4973 if (di->data_present
4974 && di->data_size > 0
4975 && a >= di->data_avma && a < di->data_avma + di->data_size) {
4976 res = Vg_SectData;
4977 break;
4979 if (di->sdata_present
4980 && di->sdata_size > 0
4981 && a >= di->sdata_avma && a < di->sdata_avma + di->sdata_size) {
4982 res = Vg_SectData;
4983 break;
4985 if (di->bss_present
4986 && di->bss_size > 0
4987 && a >= di->bss_avma && a < di->bss_avma + di->bss_size) {
4988 res = Vg_SectBSS;
4989 break;
4991 if (di->sbss_present
4992 && di->sbss_size > 0
4993 && a >= di->sbss_avma && a < di->sbss_avma + di->sbss_size) {
4994 res = Vg_SectBSS;
4995 break;
4997 if (di->plt_present
4998 && di->plt_size > 0
4999 && a >= di->plt_avma && a < di->plt_avma + di->plt_size) {
5000 res = Vg_SectPLT;
5001 break;
5003 if (di->got_present
5004 && di->got_size > 0
5005 && a >= di->got_avma && a < di->got_avma + di->got_size) {
5006 res = Vg_SectGOT;
5007 break;
5009 if (di->gotplt_present
5010 && di->gotplt_size > 0
5011 && a >= di->gotplt_avma && a < di->gotplt_avma + di->gotplt_size) {
5012 res = Vg_SectGOTPLT;
5013 break;
5015 if (di->opd_present
5016 && di->opd_size > 0
5017 && a >= di->opd_avma && a < di->opd_avma + di->opd_size) {
5018 res = Vg_SectOPD;
5019 break;
5021 /* we could also check for .eh_frame, if anyone really cares */
5024 vg_assert( (di == NULL && res == Vg_SectUnknown)
5025 || (di != NULL && res != Vg_SectUnknown) );
5027 if (objname) {
5028 if (di && di->fsm.filename) {
5029 *objname = di->fsm.filename;
5030 } else {
5031 *objname = "???";
5035 return res;
5039 static UInt debuginfo_generation = 0;
5041 UInt VG_(debuginfo_generation) (void)
5043 return debuginfo_generation;
5046 static void caches__invalidate ( void ) {
5047 cfsi_m_cache__invalidate();
5048 sym_name_cache__invalidate();
5049 debuginfo_generation++;
5052 /*--------------------------------------------------------------------*/
5053 /*--- end ---*/
5054 /*--------------------------------------------------------------------*/