FreeBSD: fix reading debuginfo of the tool itself
[valgrind.git] / coregrind / m_debuginfo / debuginfo.c
blob0ffab17922a61c1d66c365f51e6161cdad677e8f
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 * PJF 2023-09-23
555 * FreeBSD can perform a temporary mapping when loading exes
556 * and shared libraries. This is seen as a single page mapped
557 * before the ro/rx/rw mappings from the ELF file itself. More
558 * importantly, FreeBSD can reuse that same page when loading
559 * subsequent shared libraries. That means that we see this
560 * page as an overlap. Previously we noted that the mapping
561 * was not fixed and ignored it by returning early from
562 * VG_(di_notify_mmap).
564 * That works OK in general, but not for the tool itself.
565 * In order to read symbols for the tool, ML_(read_elf_object)
566 * needs to match up the ELF headers with the DebugInfo maps
567 * (populated from the global nsegments array).
569 * Two possible solutions would be to hack parse_procselfmaps
570 * even more so that it doesn't record the ro segment (is
571 * that info in kve_flags?). The other, which was also my
572 * original fix for this problem, is to just ignore identical
573 * ro mappings for different files on FreeBSD. I'm not certain
574 * that the size is always one page - that could be used to
575 * tighten the check even more.
578 /* Do the basic mappings of the two DebugInfos overlap in any way? */
579 static Bool do_DebugInfos_overlap ( const DebugInfo* di1, const DebugInfo* di2 )
581 Word i, j;
582 vg_assert(di1);
583 vg_assert(di2);
584 for (i = 0; i < VG_(sizeXA)(di1->fsm.maps); i++) {
585 const DebugInfoMapping* map1 = VG_(indexXA)(di1->fsm.maps, i);
586 for (j = 0; j < VG_(sizeXA)(di2->fsm.maps); j++) {
587 const DebugInfoMapping* map2 = VG_(indexXA)(di2->fsm.maps, j);
588 if (ranges_overlap(map1->avma, map1->size, map2->avma, map2->size)) {
589 #if defined(VGO_freebsd)
590 if (di1 != di2 && map1->ro && map2->ro &&
591 map1->avma == map2->avma && map1->size == map2->size) {
592 if (VG_(debugLog_getLevel)() >= 3) {
593 VG_(dmsg)("do_DebugInfos_overlap-0: identical ro mappings from files %s and %s\n",
594 di1->fsm.filename, di2->fsm.filename);
596 continue;
598 #endif
599 return True;
604 return False;
608 /* Discard or archive all elements of debugInfo_list whose .mark bit is set.
610 static void discard_or_archive_marked_DebugInfos ( void )
612 DebugInfo* curr;
614 while (True) {
616 curr = debugInfo_list;
617 while (True) {
618 if (!curr)
619 break;
620 if (curr->mark)
621 break;
622 curr = curr->next;
625 if (!curr) break;
627 // If |curr| is going to remain in the debugInfo_list, and merely change
628 // state, then we need to clear its mark bit so we don't subsequently
629 // try to archive it again later. Possibly related to #393146.
630 if (VG_(clo_keep_debuginfo))
631 curr->mark = False;
633 discard_or_archive_DebugInfo( curr );
639 /* Discard any elements of debugInfo_list which overlap with diRef.
640 Clearly diRef must have its mapping information set to something sane. */
641 static void discard_DebugInfos_which_overlap_with ( DebugInfo* diRef )
643 vg_assert(is_DebugInfo_allocated(diRef));
644 DebugInfo* di;
645 /* Mark all the DebugInfos in debugInfo_list that need to be
646 deleted. First, clear all the mark bits; then set them if they
647 overlap with siRef. Since siRef itself is in this list we at
648 least expect its own mark bit to be set. */
649 for (di = debugInfo_list; di; di = di->next) {
650 di->mark = False;
651 if (is_DebugInfo_archived(di))
652 continue;
653 di->mark = do_DebugInfos_overlap( di, diRef );
654 if (di == diRef) {
655 vg_assert(di->mark);
656 di->mark = False;
659 discard_or_archive_marked_DebugInfos();
663 /* Find the existing DebugInfo for |filename| or if not found, create
664 one. In the latter case |filename| is strdup'd into VG_AR_DINFO,
665 and the new DebugInfo is added to debugInfo_list. */
666 static DebugInfo* find_or_create_DebugInfo_for ( const HChar* filename )
668 DebugInfo* di;
669 vg_assert(filename);
670 for (di = debugInfo_list; di; di = di->next) {
671 if (is_DebugInfo_archived(di))
672 continue;
673 vg_assert(di->fsm.filename);
674 if (0==VG_(strcmp)(di->fsm.filename, filename))
675 break;
677 if (!di) {
678 di = alloc_DebugInfo(filename);
679 vg_assert(di);
680 di->next = debugInfo_list;
681 debugInfo_list = di;
683 vg_assert(!is_DebugInfo_archived(di));
684 return di;
688 /* Debuginfo reading for 'di' has just been successfully completed.
689 Check that the invariants stated in
690 "Comment_on_IMPORTANT_CFSI_REPRESENTATIONAL_INVARIANTS" in
691 priv_storage.h are observed. */
692 static void check_CFSI_related_invariants ( const DebugInfo* di )
694 DebugInfo* di2 = NULL;
695 Bool has_nonempty_rx = False;
696 Word i, j;
697 const Bool debug = VG_(debugLog_getLevel)() >= 3;
699 vg_assert(di);
700 /* This fn isn't called until after debuginfo for this object has
701 been successfully read. And that shouldn't happen until we have
702 both a r-x and rw- mapping for the object. Hence: */
703 vg_assert(di->fsm.have_rx_map);
704 vg_assert(di->fsm.rw_map_count);
705 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
706 const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
707 /* We are interested in r-x mappings only */
708 if (!map->rx)
709 continue;
711 /* degenerate case: r-x section is empty */
712 if (map->size == 0)
713 continue;
714 has_nonempty_rx = True;
716 /* normal case: r-x section is nonempty */
717 /* invariant (0) */
718 vg_assert(map->size > 0);
720 /* invariant (1) */
721 for (di2 = debugInfo_list; di2; di2 = di2->next) {
722 if (di2 == di || is_DebugInfo_archived(di2))
723 continue;
724 for (j = 0; j < VG_(sizeXA)(di2->fsm.maps); j++) {
725 const DebugInfoMapping* map2 = VG_(indexXA)(di2->fsm.maps, j);
726 if (!map2->rx || map2->size == 0)
727 continue;
728 vg_assert2(!ranges_overlap(map->avma, map->size,
729 map2->avma, map2->size),
730 "DiCfsi invariant (1) verification failed");
733 di2 = NULL;
736 /* degenerate case: all r-x sections are empty */
737 if (!has_nonempty_rx) {
738 vg_assert(di->cfsi_rd == NULL);
739 return;
742 /* invariant (2) */
743 if (di->cfsi_rd) {
744 vg_assert(di->cfsi_minavma <= di->cfsi_maxavma); /* duh! */
745 /* It may be that the cfsi range doesn't fit into any one individual
746 mapping, but it is covered by the combination of all the mappings.
747 That's a bit tricky to establish. To do so, create a RangeMap with
748 the cfsi range as the single only non-zero mapping, then zero out all
749 the parts described by di->fsm.maps, and check that there's nothing
750 left. */
751 RangeMap* rm = VG_(newRangeMap)( ML_(dinfo_zalloc),
752 "di.debuginfo. cCri.1", ML_(dinfo_free),
753 /*initialVal*/0 );
754 VG_(bindRangeMap)(rm, di->cfsi_minavma, di->cfsi_maxavma, 1);
755 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
756 const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
757 /* We are interested in r-x mappings only */
758 if (!map->rx)
759 continue;
760 if (map->size > 0)
761 VG_(bindRangeMap)(rm, map->avma, map->avma + map->size - 1, 0);
763 /* Typically, the range map contains one single range with value 0,
764 meaning that the cfsi range is entirely covered by the rx mappings.
765 However, in some cases, there are holes in the rx mappings
766 (see BZ #398028).
767 In such a case, check that no cfsi refers to these holes. */
768 Bool cfsi_fits = VG_(sizeRangeMap)(rm) >= 1;
769 // Check the ranges in the map.
770 for (Word ix = 0; ix < VG_(sizeRangeMap)(rm); ix++) {
771 UWord key_min = 0x55, key_max = 0x56, val = 0x57;
772 VG_(indexRangeMap)(&key_min, &key_max, &val, rm, ix);
773 if (debug)
774 VG_(dmsg)("cfsi range rx-mappings coverage check: %s %#lx-%#lx\n",
775 val == 1 ? "Uncovered" : "Covered",
776 key_min, key_max);
778 // Sanity-check the range-map operation
779 UWord check_key_min = 0x55, check_key_max = 0x56, check_val = 0x57;
780 VG_(lookupRangeMap)(&check_key_min, &check_key_max, &check_val, rm,
781 key_min + (key_max - key_min) / 2);
782 if (ix == 0)
783 vg_assert(key_min == (UWord)0);
784 if (ix == VG_(sizeRangeMap)(rm) - 1)
785 vg_assert(key_max == ~(UWord)0);
786 vg_assert(key_min == check_key_min);
787 vg_assert(key_max == check_key_max);
788 vg_assert(val == 0 || val == 1);
789 vg_assert(val == check_val);
791 if (val == 1) {
792 /* This is a part of cfsi_minavma .. cfsi_maxavma not covered.
793 Check no cfsi overlaps with this range. */
794 for (i = 0; i < di->cfsi_used; i++) {
795 DiCfSI* cfsi = &di->cfsi_rd[i];
796 vg_assert2(cfsi->base > key_max
797 || cfsi->base + cfsi->len - 1 < key_min,
798 "DiCfsi invariant (2) verification failed");
802 vg_assert(cfsi_fits);
804 VG_(deleteRangeMap)(rm);
807 /* invariants (3) and (4) */
808 if (di->cfsi_rd) {
809 vg_assert(di->cfsi_used > 0);
810 vg_assert(di->cfsi_size > 0);
811 for (i = 0; i < di->cfsi_used; i++) {
812 DiCfSI* cfsi = &di->cfsi_rd[i];
813 vg_assert(cfsi->len > 0);
814 vg_assert(cfsi->base >= di->cfsi_minavma);
815 vg_assert(cfsi->base + cfsi->len - 1 <= di->cfsi_maxavma);
816 if (i > 0) {
817 DiCfSI* cfsip = &di->cfsi_rd[i-1];
818 vg_assert(cfsip->base + cfsip->len <= cfsi->base);
821 } else {
822 vg_assert(di->cfsi_used == 0);
823 vg_assert(di->cfsi_size == 0);
828 /*--------------------------------------------------------------*/
829 /*--- ---*/
830 /*--- TOP LEVEL: INITIALISE THE DEBUGINFO SYSTEM ---*/
831 /*--- ---*/
832 /*--------------------------------------------------------------*/
834 void VG_(di_initialise) ( void )
836 /* There's actually very little to do here, since everything
837 centers around the DebugInfos in debugInfo_list, they are
838 created and destroyed on demand, and each one is treated more or
839 less independently. */
840 vg_assert(debugInfo_list == NULL);
842 /* flush the debug info caches. */
843 caches__invalidate();
847 /*--------------------------------------------------------------*/
848 /*--- ---*/
849 /*--- TOP LEVEL: NOTIFICATION (ACQUIRE/DISCARD INFO) (LINUX) ---*/
850 /*--- ---*/
851 /*--------------------------------------------------------------*/
853 #if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd)
855 /* Helper (indirect) for di_notify_ACHIEVE_ACCEPT_STATE */
856 static Bool overlaps_DebugInfoMappings ( const DebugInfoMapping* map1,
857 const DebugInfoMapping* map2 )
859 vg_assert(map1 && map2 && map1 != map2);
860 vg_assert(map1->size != 0 && map2->size != 0);
861 if (map1->avma + map1->size <= map2->avma) return False;
862 if (map2->avma + map2->size <= map1->avma) return False;
863 return True;
867 /* Helper (indirect) for di_notify_ACHIEVE_ACCEPT_STATE */
868 static void show_DebugInfoMappings
869 ( const DebugInfo* di,
870 /*MOD*/XArray* maps /* XArray<DebugInfoMapping> */ )
872 Word i, n;
873 vg_assert(maps);
874 n = VG_(sizeXA)(maps);
875 for (i = 0; i < n; i++) {
876 const DebugInfoMapping* map = VG_(indexXA)(maps, i);
877 TRACE_SYMTAB(" [%ld] avma 0x%-16lx size %-8lu "
878 "foff %-8lld %s %s %s\n",
879 i, map->avma, map->size, (Long)map->foff,
880 map->rx ? "rx" : "--",
881 map->rw ? "rw" : "--",
882 map->ro ? "ro" : "--");
887 /* Helper for di_notify_ACHIEVE_ACCEPT_STATE. This removes overlaps
888 in |maps|, in a fairly weak way, by truncating overlapping ends.
889 This may need to be strengthened in future. Currently it performs
890 a post-fixup check, so as least we can be sure that if this
891 function returns (rather than asserts) that |maps| is overlap
892 free. */
893 static void truncate_DebugInfoMapping_overlaps
894 ( const DebugInfo* di,
895 /*MOD*/XArray* maps /* XArray<DebugInfoMapping> */ )
897 TRACE_SYMTAB("Un-de-overlapped _DebugInfoMappings:\n");
898 show_DebugInfoMappings(di, maps);
899 TRACE_SYMTAB("\n");
901 Word i, j, n;
902 DebugInfoMapping *map_i, *map_j;
904 n = VG_(sizeXA)(maps);
905 for (i = 0; i < n; i++) {
907 map_i = VG_(indexXA)(maps, i);
908 if (map_i->size == 0)
909 continue; // Hmm, mutancy. Shouldn't happen.
911 for (j = i+1; j < n; j++) {
913 map_j = VG_(indexXA)(maps, j);
914 if (map_j->size == 0)
915 continue; // Hmm, mutancy. Shouldn't happen.
917 /* map_j was observed later than map_i, since the entries are
918 in the XArray in the order in which they were observed.
919 If map_j starts inside map_i, trim map_i's end so it does
920 not overlap map_j. This reflects the reality that when
921 two mmaped areas overlap, the later mmap silently
922 overwrites the earlier mmap's mapping. */
923 if (map_j->avma >= map_i->avma
924 && map_j->avma < map_i->avma + map_i->size) {
925 SizeT map_i_newsize = map_j->avma - map_i->avma;
926 vg_assert(map_i_newsize < map_i->size);
927 map_i->size = map_i_newsize;
933 TRACE_SYMTAB("De-overlapped DebugInfoMappings:\n");
934 show_DebugInfoMappings(di, maps);
935 TRACE_SYMTAB("\n");
936 TRACE_SYMTAB("Checking that there are no remaining overlaps.\n");
938 for (i = 0; i < n; i++) {
939 map_i = VG_(indexXA)(maps, i);
940 if (map_i->size == 0)
941 continue;
942 for (j = i+1; j < n; j++) {
943 map_j = VG_(indexXA)(maps, j);
944 if (map_j->size == 0)
945 continue;
946 Bool overlap
947 = overlaps_DebugInfoMappings( map_i, map_j );
948 /* If the following assert ever fails, it means the de-overlapping
949 scheme above is too weak, and needs improvement. */
950 vg_assert(!overlap);
954 TRACE_SYMTAB("Check successful.\n");
958 /* The debug info system is driven by notifications that a text
959 segment has been mapped in, or unmapped, or when sections change
960 permission. It's all a bit kludgey and basically means watching
961 syscalls, trying to second-guess when the system's dynamic linker
962 is done with mapping in a new object for execution. This is all
963 tracked using the DebugInfoFSM struct for the object. Anyway, once
964 we finally decide we've got to an accept state, this section then
965 will acquire whatever info is available for the corresponding
966 object. This section contains the notification handlers, which
967 update the FSM and determine when an accept state has been reached.
970 /* When the sequence of observations causes a DebugInfoFSM to move
971 into the accept state, call here to actually get the debuginfo read
972 in. Returns a ULong whose purpose is described in comments
973 preceding VG_(di_notify_mmap) just below.
975 static ULong di_notify_ACHIEVE_ACCEPT_STATE ( struct _DebugInfo* di )
977 ULong di_handle;
978 Bool ok;
980 advance_current_DiEpoch("di_notify_ACHIEVE_ACCEPT_STATE");
982 vg_assert(di->fsm.filename);
983 TRACE_SYMTAB("\n");
984 TRACE_SYMTAB("------ start ELF OBJECT "
985 "-------------------------"
986 "------------------------------\n");
987 TRACE_SYMTAB("------ name = %s\n", di->fsm.filename);
988 TRACE_SYMTAB("\n");
990 /* We're going to read symbols and debug info for the avma
991 ranges specified in the _DebugInfoFsm mapping array. First
992 get rid of any other DebugInfos which overlap any of those
993 ranges (to avoid total confusion). But only those valid in
994 the current epoch. We don't want to discard archived DebugInfos. */
995 discard_DebugInfos_which_overlap_with( di );
997 /* The DebugInfoMappings that now exist in the FSM may involve
998 overlaps. This confuses ML_(read_elf_*), and may cause
999 it to compute wrong biases. So de-overlap them now.
1000 See http://bugzilla.mozilla.org/show_bug.cgi?id=788974 */
1001 truncate_DebugInfoMapping_overlaps( di, di->fsm.maps );
1003 /* And acquire new info. */
1004 # if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
1005 ok = ML_(read_elf_object)( di );
1006 if (ok)
1007 di->deferred = True;
1008 # elif defined(VGO_darwin)
1009 ok = ML_(read_macho_debug_info)( di );
1010 # else
1011 # error "unknown OS"
1012 # endif
1014 if (ok) {
1016 TRACE_SYMTAB("\n------ Canonicalising the "
1017 "acquired info ------\n");
1018 /* invalidate the debug info caches. */
1019 caches__invalidate();
1020 /* prepare read data for use */
1021 ML_(canonicaliseTables)( di );
1022 /* Check invariants listed in
1023 Comment_on_IMPORTANT_REPRESENTATIONAL_INVARIANTS in
1024 priv_storage.h. */
1025 check_CFSI_related_invariants(di);
1026 ML_(finish_CFSI_arrays)(di);
1028 // Mark di's first epoch point as a valid epoch. Because its
1029 // last_epoch value is still invalid, this changes di's state from
1030 // "allocated" to "active".
1031 vg_assert(is_DebugInfo_allocated(di));
1032 di->first_epoch = VG_(current_DiEpoch)();
1033 vg_assert(is_DebugInfo_active(di));
1034 show_epochs("di_notify_ACHIEVE_ACCEPT_STATE success");
1036 /* notify m_redir about it */
1037 TRACE_SYMTAB("\n------ Notifying m_redir ------\n");
1038 VG_(redir_notify_new_DebugInfo)( di );
1039 /* Note that we succeeded */
1040 di->have_dinfo = True;
1041 vg_assert(di->handle > 0);
1042 di_handle = di->handle;
1044 } else {
1045 TRACE_SYMTAB("\n------ ELF reading failed ------\n");
1046 /* Something went wrong (eg. bad ELF file). Should we delete
1047 this DebugInfo? No - it contains info on the rw/rx
1048 mappings, at least. */
1049 di_handle = 0;
1050 vg_assert(di->have_dinfo == False);
1053 TRACE_SYMTAB("\n");
1054 TRACE_SYMTAB("------ name = %s\n", di->fsm.filename);
1055 TRACE_SYMTAB("------ end ELF OBJECT "
1056 "-------------------------"
1057 "------------------------------\n");
1058 TRACE_SYMTAB("\n");
1060 return di_handle;
1064 /* Notify the debuginfo system about a new mapping. This is the way
1065 new debug information gets loaded.
1067 readelf -e will output something like
1069 Program Headers:
1070 Type Offset VirtAddr PhysAddr
1071 FileSiz MemSiz Flg Align
1072 PHDR 0x0000000000000040 0x0000000000200040 0x0000000000200040
1073 0x0000000000000268 0x0000000000000268 R 0x8
1074 INTERP 0x00000000000002a8 0x00000000002002a8 0x00000000002002a8
1075 0x0000000000000015 0x0000000000000015 R 0x1
1076 [Requesting program interpreter: /libexec/ld-elf.so.1]
1077 LOAD 0x0000000000000000 0x0000000000200000 0x0000000000200000
1078 0x0000000000002acc 0x0000000000002acc R 0x1000
1079 LOAD 0x0000000000002ad0 0x0000000000203ad0 0x0000000000203ad0
1080 0x0000000000004a70 0x0000000000004a70 R E 0x1000
1081 LOAD 0x0000000000007540 0x0000000000209540 0x0000000000209540
1082 0x00000000000001d8 0x00000000000001d8 RW 0x1000
1083 LOAD 0x0000000000007720 0x000000000020a720 0x000000000020a720
1084 0x00000000000002b8 0x00000000000005a0 RW 0x1000
1085 DYNAMIC 0x0000000000007570 0x0000000000209570 0x0000000000209570
1086 0x00000000000001a0 0x00000000000001a0 RW 0x8
1087 GNU_RELRO 0x0000000000007540 0x0000000000209540 0x0000000000209540
1088 0x00000000000001d8 0x00000000000001d8 R 0x1
1089 GNU_EH_FRAME 0x0000000000002334 0x0000000000202334 0x0000000000202334
1090 0x000000000000012c 0x000000000000012c R 0x4
1091 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
1092 0x0000000000000000 0x0000000000000000 RW 0
1093 NOTE 0x00000000000002c0 0x00000000002002c0 0x00000000002002c0
1094 0x0000000000000048 0x0000000000000048 R 0x4
1096 This function will be called for the "LOAD" segments above.
1098 This function gets called from 2 contexts
1100 "HOST TRIGGERED"
1102 1a. For the tool exe, called from valgrind_main. This is already
1103 mmap'd when the host starts so we look at something like the
1104 /proc filesystem to get the mapping after the event and build
1105 up the NSegments from that.
1107 1b. Then the host loads ld.so and the guest exe. This is done in
1108 the sequence
1109 load_client -> VG_(do_exec) -> VG_(do_exec_inner) ->
1110 exe_handlers->load_fn ( == VG_(load_ELF) )
1111 [or load_MACHO].
1113 This does the mmap'ing and creates the associated NSegments.
1115 The NSegments may get merged, (see maybe_merge_nsegments)
1116 so there could be more PT_LOADs than there are NSegments.
1117 VG_(di_notify_mmap) is called by iterating over the
1118 NSegments
1120 "GUEST TRIGGERED"
1122 2. When the guest loads any further shared libs (valgrind core and
1123 tool preload shared libraries, libc, other dependencies, dlopens)
1124 using mmap. The call will be from ML_(generic_PRE_sys_mmap) or
1125 a platform-specific variation.
1127 There are a few variations for syswraps/platforms.
1129 In this case the NSegment could possibly be merged,
1130 but that is irrelevant because di_notify_mmap is being
1131 called directly on the mmap result.
1133 If allow_SkFileV is True, it will try load debug info if the
1134 mapping at 'a' belongs to Valgrind; whereas normally (False)
1135 it will not do that. This allows us to carefully control when
1136 the thing will read symbols from the Valgrind executable itself.
1138 If use_fd is not -1, that is used instead of the filename; this
1139 avoids perturbing fcntl locks, which are released by simply
1140 re-opening and closing the same file (even via different fd!).
1142 Read-only mappings will be ignored.
1143 There may be 1 or 2 RW mappings.
1144 There will also be 1 RX mapping.
1146 If there is no RX or no RW mapping then we will not attempt to
1147 read debuginfo for the file.
1149 In order to know whether there are 1 or 2 RW mappings we
1150 need to check the ELF headers. And in the case that we
1151 detect 2 RW mappings we need to double check that they
1152 aren't contiguous in memory resulting in merged NSegemnts.
1154 This does not apply to Darwin which just checks the Mach-O header
1156 If a call to VG_(di_notify_mmap) causes debug info to be read, then
1157 the returned ULong is an abstract handle which can later be used to
1158 refer to the debuginfo read as a result of this specific mapping,
1159 in later queries to m_debuginfo. In this case the handle value
1160 will be one or above. If the returned value is zero, no debug info
1161 was read. */
1163 ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd )
1165 NSegment const * seg;
1166 Int rw_load_count;
1167 const HChar* filename;
1168 Bool is_rx_map, is_rw_map, is_ro_map;
1170 DebugInfo* di;
1171 Int actual_fd, oflags;
1172 #if defined(VGO_darwin)
1173 SysRes preadres;
1174 HChar buf1k[1024];
1175 #else
1176 Bool elf_ok;
1177 #endif
1179 const Bool debug = VG_(debugLog_getLevel)() >= 3;
1180 SysRes statres;
1181 struct vg_stat statbuf;
1183 vg_assert(use_fd >= -1);
1185 /* In short, figure out if this mapping is of interest to us, and
1186 if so, try to guess what ld.so is doing and when/if we should
1187 read debug info. */
1188 seg = VG_(am_find_nsegment)(a);
1189 vg_assert(seg);
1191 if (debug) {
1192 VG_(dmsg)("di_notify_mmap-0:\n");
1193 VG_(dmsg)("di_notify_mmap-1: %#lx-%#lx %c%c%c\n",
1194 seg->start, seg->end,
1195 seg->hasR ? 'r' : '-',
1196 seg->hasW ? 'w' : '-',seg->hasX ? 'x' : '-' );
1199 /* guaranteed by aspacemgr-linux.c, sane_NSegment() */
1200 vg_assert(seg->end > seg->start);
1202 /* Ignore non-file mappings */
1203 if ( ! (seg->kind == SkFileC
1204 || (seg->kind == SkFileV && allow_SkFileV)) )
1205 return 0;
1207 /* If the file doesn't have a name, we're hosed. Give up. */
1208 filename = VG_(am_get_filename)( seg );
1209 if (!filename)
1210 return 0;
1213 * Cannot read from these magic files:
1214 * --20208-- WARNING: Serious error when reading debug info
1215 * --20208-- When reading debug info from /proc/xen/privcmd:
1216 * --20208-- can't read file to inspect ELF header
1218 if (VG_(strncmp)(filename, "/proc/xen/", 10) == 0)
1219 return 0;
1221 if (debug)
1222 VG_(dmsg)("di_notify_mmap-2: %s\n", filename);
1224 /* Only try to read debug information from regular files. */
1225 statres = VG_(stat)(filename, &statbuf);
1227 /* stat dereferences symlinks, so we don't expect it to succeed and
1228 yet produce something that is a symlink. */
1229 vg_assert(sr_isError(statres) || ! VKI_S_ISLNK(statbuf.mode));
1231 /* Don't let the stat call fail silently. Filter out some known
1232 sources of noise before complaining, though. */
1233 if (sr_isError(statres)) {
1234 DebugInfo fake_di;
1235 Bool quiet = VG_(strstr)(filename, "/var/run/nscd/") != NULL
1236 || VG_(strstr)(filename, "/dev/shm/") != NULL;
1237 if (!quiet && VG_(clo_verbosity) > 1) {
1238 VG_(memset)(&fake_di, 0, sizeof(fake_di));
1239 fake_di.fsm.filename = ML_(dinfo_strdup)("di.debuginfo.nmm", filename);
1240 ML_(symerr)(&fake_di, True, "failed to stat64/stat this file");
1242 return 0;
1245 /* Finally, the point of all this stattery: if it's not a regular file,
1246 don't try to read debug info from it. */
1247 if (! VKI_S_ISREG(statbuf.mode))
1248 return 0;
1250 /* no uses of statbuf below here. */
1252 /* Now we have to guess if this is a text-like mapping, a data-like
1253 mapping, neither or both. The rules are:
1255 text if: x86-linux r and x
1256 other-linux r and x and not w
1258 data if: x86-linux r and w
1259 other-linux r and w and not x
1261 Background: On x86-linux, objects are typically mapped twice:
1263 1b8fb000-1b8ff000 r-xp 00000000 08:02 4471477 vgpreload_memcheck.so
1264 1b8ff000-1b900000 rw-p 00004000 08:02 4471477 vgpreload_memcheck.so
1266 whereas ppc32-linux mysteriously does this:
1268 118a6000-118ad000 r-xp 00000000 08:05 14209428 vgpreload_memcheck.so
1269 118ad000-118b6000 ---p 00007000 08:05 14209428 vgpreload_memcheck.so
1270 118b6000-118bd000 rwxp 00000000 08:05 14209428 vgpreload_memcheck.so
1272 The third mapping should not be considered to have executable
1273 code in. Therefore a test which works for both is: r and x and
1274 NOT w. Reading symbols from the rwx segment -- which overlaps
1275 the r-x segment in the file -- causes the redirection mechanism
1276 to redirect to addresses in that third segment, which is wrong
1277 and causes crashes.
1279 JRS 28 Dec 05: unfortunately icc 8.1 on x86 has been seen to
1280 produce executables with a single rwx segment rather than a
1281 (r-x,rw-) pair. That means the rules have to be modified thusly:
1283 x86-linux: consider if r and x
1284 all others: consider if r and x and not w
1286 2009 Aug 16: apply similar kludge to ppc32-linux.
1287 See http://bugs.kde.org/show_bug.cgi?id=190820
1289 There are two modes on s390x: with and without the noexec kernel
1290 parameter. Together with some older kernels, this leads to several
1291 variants:
1292 executable: r and x
1293 data: r and w and x
1295 executable: r and x
1296 data: r and w
1298 is_rx_map = False;
1299 is_rw_map = False;
1300 is_ro_map = False;
1302 # if defined(VGA_x86) || defined(VGA_ppc32) || defined(VGA_mips32) \
1303 || defined(VGA_mips64) || defined(VGA_nanomips)
1304 is_rx_map = seg->hasR && seg->hasX;
1305 is_rw_map = seg->hasR && seg->hasW;
1306 # elif defined(VGA_amd64) || defined(VGA_ppc64be) || defined(VGA_ppc64le) \
1307 || defined(VGA_arm) || defined(VGA_arm64)
1308 is_rx_map = seg->hasR && seg->hasX && !seg->hasW;
1309 is_rw_map = seg->hasR && seg->hasW && !seg->hasX;
1310 # elif defined(VGP_s390x_linux)
1311 is_rx_map = seg->hasR && seg->hasX && !seg->hasW;
1312 is_rw_map = seg->hasR && seg->hasW;
1313 # else
1314 # error "Unknown platform"
1315 # endif
1317 is_ro_map = seg->hasR && !seg->hasW && !seg->hasX;
1319 # if defined(VGO_solaris)
1320 is_rx_map = seg->hasR && seg->hasX && !seg->hasW;
1321 is_rw_map = seg->hasR && seg->hasW;
1322 # endif
1324 if (debug)
1325 VG_(dmsg)("di_notify_mmap-3: "
1326 "is_rx_map %d, is_rw_map %d, is_ro_map %d\n",
1327 (Int)is_rx_map, (Int)is_rw_map, (Int)is_ro_map);
1329 /* Ignore mappings with permissions we can't possibly be interested in. */
1330 if (!(is_rx_map || is_rw_map || is_ro_map))
1331 return 0;
1333 #if defined(VGO_freebsd)
1334 /* Ignore non-fixed read-only mappings. The dynamic linker may be
1335 * mapping something for its own transient purposes. */
1336 if (!seg->isFF && is_ro_map && debug) {
1337 VG_(dmsg)("di_notify_mmap-4: non-fixed ro map\n");
1339 #endif
1341 #if defined(VGO_darwin)
1342 /* Peer at the first few bytes of the file, to see if it is an ELF */
1343 /* object file. Ignore the file if we do not have read permission. */
1344 VG_(memset)(buf1k, 0, sizeof(buf1k));
1345 #endif
1347 oflags = VKI_O_RDONLY;
1348 # if defined(VKI_O_LARGEFILE)
1349 oflags |= VKI_O_LARGEFILE;
1350 # endif
1352 if (use_fd == -1) {
1353 SysRes fd = VG_(open)( filename, oflags, 0 );
1354 if (sr_isError(fd)) {
1355 if (sr_Err(fd) != VKI_EACCES) {
1356 DebugInfo fake_di;
1357 VG_(memset)(&fake_di, 0, sizeof(fake_di));
1358 fake_di.fsm.filename = ML_(dinfo_strdup)("di.debuginfo.nmm",
1359 filename);
1360 ML_(symerr)(&fake_di, True,
1361 "can't open file to inspect ELF header");
1363 return 0;
1365 actual_fd = sr_Res(fd);
1366 } else {
1367 actual_fd = use_fd;
1370 #if defined(VGO_darwin)
1371 preadres = VG_(pread)( actual_fd, buf1k, sizeof(buf1k), 0 );
1372 if (use_fd == -1) {
1373 VG_(close)( actual_fd );
1376 if (sr_isError(preadres)) {
1377 DebugInfo fake_di;
1378 VG_(memset)(&fake_di, 0, sizeof(fake_di));
1379 fake_di.fsm.filename = ML_(dinfo_strdup)("di.debuginfo.nmm", filename);
1380 ML_(symerr)(&fake_di, True, "can't read file to inspect Mach-O headers");
1381 return 0;
1383 if (sr_Res(preadres) == 0)
1384 return 0;
1385 vg_assert(sr_Res(preadres) > 0 && sr_Res(preadres) <= sizeof(buf1k) );
1386 #endif
1388 /* We're only interested in mappings of object files. */
1389 # if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
1391 rw_load_count = 0;
1393 elf_ok = ML_(check_elf_and_get_rw_loads) ( actual_fd, filename, &rw_load_count );
1395 if (use_fd == -1) {
1396 VG_(close)( actual_fd );
1399 if (!elf_ok) {
1400 return 0;
1403 # elif defined(VGO_darwin)
1404 if (!ML_(is_macho_object_file)( buf1k, (SizeT)sr_Res(preadres) ))
1405 return 0;
1406 rw_load_count = 1;
1407 # else
1408 # error "unknown OS"
1409 # endif
1411 /* See if we have a DebugInfo for this filename. If not,
1412 create one. */
1413 di = find_or_create_DebugInfo_for( filename );
1414 vg_assert(di);
1416 /* Ignore all mappings for this filename once we've read debuginfo for it.
1417 This avoids the confusion of picking up "irrelevant" mappings in
1418 applications which mmap their objects outside of ld.so, for example
1419 Firefox's Gecko profiler.
1421 What happens in that case is: the application maps the object "ro" for
1422 whatever reason. We record the mapping di->fsm.maps. The application
1423 later unmaps the object. However, the mapping is not removed from
1424 di->fsm.maps. Later, when some other (unrelated) object is mapped (via
1425 ld.so) into that address space, we first unload any debuginfo that has a
1426 mapping intersecting that area. That means we will end up incorrectly
1427 unloading debuginfo for the object with the "irrelevant" mappings. This
1428 causes various problems, not least because it can unload the debuginfo
1429 for libc.so and so cause malloc intercepts to become un-intercepted.
1431 This fix assumes that all mappings made once we've read debuginfo for
1432 an object are irrelevant. I think that's OK, but need to check with
1433 mjw/thh. */
1434 if (di->have_dinfo) {
1435 if (debug)
1436 VG_(dmsg)("di_notify_mmap-4x: "
1437 "ignoring mapping because we already read debuginfo "
1438 "for DebugInfo* %p\n", di);
1439 return 0;
1442 if (debug)
1443 VG_(dmsg)("di_notify_mmap-4: "
1444 "noting details in DebugInfo* at %p\n", di);
1446 /* Note the details about the mapping. */
1447 DebugInfoMapping map;
1448 map.avma = seg->start;
1449 map.size = seg->end + 1 - seg->start;
1450 map.foff = seg->offset;
1451 #if defined(VGO_freebsd)
1452 map.ignore_foff = seg->ignore_offset;
1453 #endif
1454 map.rx = is_rx_map;
1455 map.rw = is_rw_map;
1456 map.ro = is_ro_map;
1457 VG_(addToXA)(di->fsm.maps, &map);
1459 /* Update flags about what kind of mappings we've already seen. */
1460 di->fsm.have_rx_map |= is_rx_map;
1461 /* This is a bit of a hack, using a Bool as a counter */
1462 if (is_rw_map)
1463 ++di->fsm.rw_map_count;
1464 di->fsm.have_ro_map |= is_ro_map;
1466 /* So, finally, are we in an accept state? */
1467 vg_assert(!di->have_dinfo);
1468 if (di->fsm.have_rx_map &&
1469 rw_load_count >= 1 &&
1470 di->fsm.rw_map_count == rw_load_count) {
1471 /* Ok, so, finally, we found what we need, and we haven't
1472 already read debuginfo for this object. So let's do so now.
1473 Yee-ha! */
1475 if (debug)
1476 VG_(dmsg)("di_notify_mmap-5: "
1477 "achieved accept state for %s\n", filename);
1478 return di_notify_ACHIEVE_ACCEPT_STATE ( di );
1479 } else {
1480 /* If we don't have an rx and rw mapping, go no further. */
1481 if (debug)
1482 VG_(dmsg)("di_notify_mmap-6: "
1483 "no dinfo loaded %s (no rx or no rw mapping)\n", filename);
1484 return 0;
1488 /* Load DI if it hasn't already been been loaded. */
1489 void VG_(di_load_di)( DebugInfo *di )
1491 if (di->deferred) {
1492 di->deferred = False;
1493 #if defined(VGO_darwin)
1494 ML_(read_macho_debug_info) (di);
1495 #else
1496 ML_(read_elf_debug) (di);
1497 #endif
1498 ML_(canonicaliseTables)( di );
1500 /* Check invariants listed in
1501 Comment_on_IMPORTANT_REPRESENTATIONAL_INVARIANTS in
1502 priv_storage.h. */
1503 check_CFSI_related_invariants(di);
1504 ML_(finish_CFSI_arrays)(di);
1508 /* Load DI if it has a text segment containing A and DI hasn't already
1509 been loaded. */
1511 void VG_(load_di)( DebugInfo *di, Addr a)
1513 if (!di->text_present
1514 || di->text_size <= 0
1515 || di->text_avma > a
1516 || a >= di->text_avma + di->text_size)
1517 return;
1519 VG_(di_load_di)(di);
1522 /* Attempt to load DebugInfo with a text segment containing A,
1523 if such a debuginfo hasn't already been loaded. */
1525 void VG_(addr_load_di)( Addr a )
1527 DebugInfo *di;
1529 di = VG_(find_DebugInfo)(VG_(current_DiEpoch)(), a);
1530 if (di != NULL)
1531 VG_(di_load_di)(di);
1534 /* Unmap is simpler - throw away any SegInfos intersecting
1535 [a, a+len). */
1536 void VG_(di_notify_munmap)( Addr a, SizeT len )
1538 Bool anyFound;
1539 if (0) VG_(printf)("DISCARD %#lx %#lx\n", a, a+len);
1540 anyFound = discard_syms_in_range(a, len);
1541 if (anyFound) {
1542 caches__invalidate();
1543 advance_current_DiEpoch("VG_(di_notify_munmap)");
1544 show_epochs("VG_(di_notify_munmap)");
1549 /* Uh, this doesn't do anything at all. IIRC glibc (or ld.so, I don't
1550 remember) does a bunch of mprotects on itself, and if we follow
1551 through here, it causes the debug info for that object to get
1552 discarded. */
1553 void VG_(di_notify_mprotect)( Addr a, SizeT len, UInt prot )
1555 Bool exe_ok = toBool(prot & VKI_PROT_EXEC);
1556 # if defined(VGA_x86)
1557 exe_ok = exe_ok || toBool(prot & VKI_PROT_READ);
1558 # endif
1559 if (0 && !exe_ok) {
1560 Bool anyFound = discard_syms_in_range(a, len);
1561 if (anyFound) {
1562 caches__invalidate();
1563 advance_current_DiEpoch("VG_(di_notify_mprotect)");
1569 /* This is a MacOSX >= 10.7 32-bit only special. See comments on the
1570 declaration of struct _DebugInfoFSM for details. */
1571 void VG_(di_notify_vm_protect)( Addr a, SizeT len, UInt prot )
1573 const Bool debug = VG_(debugLog_getLevel)() >= 3;
1575 Bool r_ok = toBool(prot & VKI_PROT_READ);
1576 Bool w_ok = toBool(prot & VKI_PROT_WRITE);
1577 Bool x_ok = toBool(prot & VKI_PROT_EXEC);
1578 if (debug) {
1579 VG_(dmsg)("di_notify_vm_protect-0:\n");
1580 VG_(dmsg)("di_notify_vm_protect-1: %#lx-%#lx %c%c%c\n",
1581 a, a + len - 1,
1582 r_ok ? 'r' : '-', w_ok ? 'w' : '-', x_ok ? 'x' : '-' );
1585 Bool do_nothing = True;
1586 # if defined(VGP_x86_darwin) && (DARWIN_VERS >= DARWIN_10_7)
1587 do_nothing = False;
1588 # endif
1589 if (do_nothing /* wrong platform */) {
1590 if (debug)
1591 VG_(dmsg)("di_notify_vm_protect-2: wrong platform, "
1592 "doing nothing.\n");
1593 return;
1596 if (! (r_ok && !w_ok && x_ok))
1597 return; /* not an upgrade to r-x */
1599 /* Find a DebugInfo containing a FSM that has [a, +len) previously
1600 observed as a r-- mapping, plus some other rw- mapping. If such
1601 is found, conclude we're in an accept state and read debuginfo
1602 accordingly. */
1603 if (debug)
1604 VG_(dmsg)("di_notify_vm_protect-3: looking for existing DebugInfo*\n");
1605 DebugInfo* di;
1606 DebugInfoMapping *map = NULL;
1607 Word i;
1608 for (di = debugInfo_list; di; di = di->next) {
1609 vg_assert(di->fsm.filename);
1610 if (di->have_dinfo)
1611 continue; /* already have debuginfo for this object */
1612 if (!di->fsm.have_ro_map)
1613 continue; /* need to have a r-- mapping for this object */
1614 if (di->fsm.have_rx_map)
1615 continue; /* rx- mapping already exists */
1616 if (!di->fsm.rw_map_count)
1617 continue; /* need to have a rw- mapping */
1618 /* Try to find a mapping matching the memory area. */
1619 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1620 map = VG_(indexXA)(di->fsm.maps, i);
1621 if (map->ro && map->avma == a && map->size == len)
1622 break;
1623 map = NULL;
1625 if (!map)
1626 continue; /* this isn't an upgrade of an r-- mapping */
1627 /* looks like we're in luck! */
1628 break;
1630 if (di == NULL)
1631 return; /* didn't find anything */
1633 if (debug)
1634 VG_(dmsg)("di_notify_vm_protect-4: found existing DebugInfo* at %p\n",
1635 di);
1637 /* Do the upgrade. Simply update the flags of the mapping
1638 and pretend we never saw the RO map at all. */
1639 vg_assert(di->fsm.have_ro_map);
1640 map->rx = True;
1641 map->ro = False;
1642 di->fsm.have_rx_map = True;
1643 di->fsm.have_ro_map = False;
1644 /* See if there are any more ro mappings */
1645 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1646 map = VG_(indexXA)(di->fsm.maps, i);
1647 if (map->ro) {
1648 di->fsm.have_ro_map = True;
1649 break;
1653 /* Check if we're now in an accept state and read debuginfo. Finally. */
1654 if (di->fsm.have_rx_map && di->fsm.rw_map_count && !di->have_dinfo) {
1655 if (debug)
1656 VG_(dmsg)("di_notify_vm_protect-5: "
1657 "achieved accept state for %s\n", di->fsm.filename);
1658 ULong di_handle __attribute__((unused))
1659 = di_notify_ACHIEVE_ACCEPT_STATE( di );
1660 /* di_handle is ignored. That's not a problem per se -- it just
1661 means nobody will ever be able to refer to this debuginfo by
1662 handle since nobody will know what the handle value is. */
1667 /*--------- PDB (windows debug info) reading --------- */
1669 /* this should really return ULong, as per VG_(di_notify_mmap). */
1670 void VG_(di_notify_pdb_debuginfo)( Int fd_obj, Addr avma_obj,
1671 SizeT total_size, PtrdiffT bias_obj )
1673 Int i, r, sz_exename;
1674 ULong obj_mtime, pdb_mtime;
1675 HChar* pdbname = NULL;
1676 HChar* dot;
1677 SysRes sres;
1678 Int fd_pdbimage;
1679 SizeT n_pdbimage;
1680 struct vg_stat stat_buf;
1682 if (VG_(clo_verbosity) > 0) {
1683 VG_(message)(Vg_UserMsg, "\n");
1684 VG_(message)(Vg_UserMsg,
1685 "LOAD_PDB_DEBUGINFO: clreq: fd=%d, avma=%#lx, total_size=%lu, "
1686 "bias=%#lx\n",
1687 fd_obj, avma_obj, total_size, (UWord)bias_obj
1691 /* 'fd' refers to the .exe/.dll we're dealing with. Get its modification
1692 time into obj_mtime. */
1693 r = VG_(fstat)(fd_obj, &stat_buf);
1694 if (r == -1)
1695 return; /* stat failed ?! */
1696 vg_assert(r == 0);
1697 obj_mtime = stat_buf.mtime;
1699 /* and get its name into exename. */
1700 const HChar *exe;
1701 if (! VG_(resolve_filename)(fd_obj, &exe))
1702 return; /* failed */
1703 sz_exename = VG_(strlen)(exe);
1704 HChar exename[sz_exename + 1];
1705 VG_(strcpy)(exename, exe); // make a copy on the stack
1707 if (VG_(clo_verbosity) > 0) {
1708 VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: objname: %s\n", exename);
1711 /* Try to get the PDB file name from the executable. */
1712 pdbname = ML_(find_name_of_pdb_file)(exename);
1713 if (pdbname) {
1714 vg_assert(VG_(strlen)(pdbname) >= 5); /* 5 = strlen("X.pdb") */
1715 /* So we successfully extracted a name from the PE file. But it's
1716 likely to be of the form
1717 e:\foo\bar\xyzzy\wibble.pdb
1718 and we need to change it into something we can actually open
1719 in Wine-world, which basically means turning it into
1720 $HOME/.wine/drive_e/foo/bar/xyzzy/wibble.pdb
1721 We also take into account $WINEPREFIX, if it is set.
1722 For the moment, if the name isn't fully qualified, just forget it
1723 (we'd have to root around to find where the pdb actually is)
1725 /* Change all the backslashes to forward slashes */
1726 for (i = 0; pdbname[i]; i++) {
1727 if (pdbname[i] == '\\')
1728 pdbname[i] = '/';
1730 Bool is_quald
1731 = ('a' <= VG_(tolower)(pdbname[0]) && VG_(tolower)(pdbname[0]) <= 'z')
1732 && pdbname[1] == ':'
1733 && pdbname[2] == '/';
1734 HChar* home = VG_(getenv)("HOME");
1735 HChar* wpfx = VG_(getenv)("WINEPREFIX");
1736 if (is_quald && wpfx) {
1737 /* Change e:/foo/bar/xyzzy/wibble.pdb
1738 to $WINEPREFIX/drive_e/foo/bar/xyzzy/wibble.pdb
1740 Int mashedSzB = VG_(strlen)(pdbname) + VG_(strlen)(wpfx) + 50/*misc*/;
1741 HChar* mashed = ML_(dinfo_zalloc)("di.debuginfo.dnpdi.1", mashedSzB);
1742 VG_(snprintf)(mashed, mashedSzB, "%s/drive_%c%s",
1743 wpfx, pdbname[0], &pdbname[2]);
1744 vg_assert(mashed[mashedSzB-1] == 0);
1745 ML_(dinfo_free)(pdbname);
1746 pdbname = mashed;
1748 else if (is_quald && home && !wpfx) {
1749 /* Change e:/foo/bar/xyzzy/wibble.pdb
1750 to $HOME/.wine/drive_e/foo/bar/xyzzy/wibble.pdb
1752 Int mashedSzB = VG_(strlen)(pdbname) + VG_(strlen)(home) + 50/*misc*/;
1753 HChar* mashed = ML_(dinfo_zalloc)("di.debuginfo.dnpdi.2", mashedSzB);
1754 VG_(snprintf)(mashed, mashedSzB, "%s/.wine/drive_%c%s",
1755 home, pdbname[0], &pdbname[2]);
1756 vg_assert(mashed[mashedSzB-1] == 0);
1757 ML_(dinfo_free)(pdbname);
1758 pdbname = mashed;
1759 } else {
1760 /* It's not a fully qualified path, or neither $HOME nor $WINE
1761 are set (strange). Give up. */
1762 ML_(dinfo_free)(pdbname);
1763 pdbname = NULL;
1767 /* Try s/exe/pdb/ if we don't have a valid pdbname. */
1768 if (!pdbname) {
1769 /* Try to find a matching PDB file from which to read debuginfo.
1770 Windows PE files have symbol tables and line number information,
1771 but MSVC doesn't seem to use them. */
1772 /* Why +5 ? Because in the worst case, we could find a dot as the
1773 last character of pdbname, and we'd then put "pdb" right after
1774 it, hence extending it a bit. */
1775 pdbname = ML_(dinfo_zalloc)("di.debuginfo.lpd1", sz_exename+5);
1776 VG_(strcpy)(pdbname, exename);
1777 vg_assert(pdbname[sz_exename+5-1] == 0);
1778 dot = VG_(strrchr)(pdbname, '.');
1779 if (!dot)
1780 goto out; /* there's no dot in the exe's name ?! */
1781 if (dot[1] == 0)
1782 goto out; /* hmm, path ends in "." */
1784 if ('A' <= dot[1] && dot[1] <= 'Z')
1785 VG_(strcpy)(dot, ".PDB");
1786 else
1787 VG_(strcpy)(dot, ".pdb");
1789 vg_assert(pdbname[sz_exename+5-1] == 0);
1792 /* See if we can find it, and check it's in-dateness. */
1793 sres = VG_(stat)(pdbname, &stat_buf);
1794 if (sr_isError(sres)) {
1795 VG_(message)(Vg_UserMsg, "Warning: Missing or un-stat-able %s\n",
1796 pdbname);
1797 if (VG_(clo_verbosity) > 0)
1798 VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: missing: %s\n", pdbname);
1799 goto out;
1801 pdb_mtime = stat_buf.mtime;
1803 if (obj_mtime > pdb_mtime + 60ULL) {
1804 /* PDB file is older than PE file. Really, the PDB should be
1805 newer than the PE, but that doesn't always seem to be the
1806 case. Allow the PDB to be up to one minute older.
1807 Otherwise, it's probably out of date, in which case ignore it
1808 or we will either (a) print wrong stack traces or more likely
1809 (b) crash.
1811 VG_(message)(Vg_UserMsg,
1812 "Warning: %s (mtime = %llu)\n"
1813 " is older than %s (mtime = %llu)\n",
1814 pdbname, pdb_mtime, exename, obj_mtime);
1817 sres = VG_(open)(pdbname, VKI_O_RDONLY, 0);
1818 if (sr_isError(sres)) {
1819 VG_(message)(Vg_UserMsg, "Warning: Can't open %s\n", pdbname);
1820 goto out;
1823 /* Looks promising; go on to try and read stuff from it. But don't
1824 mmap the file. Instead mmap free space and read the file into
1825 it. This is because files on CIFS filesystems that are mounted
1826 '-o directio' can't be mmap'd, and that mount option is needed
1827 to make CIFS work reliably. (See
1828 http://www.nabble.com/Corrupted-data-on-write-to-
1829 Windows-2003-Server-t2782623.html)
1830 This is slower, but at least it works reliably. */
1831 fd_pdbimage = sr_Res(sres);
1832 n_pdbimage = stat_buf.size;
1833 if (n_pdbimage == 0 || n_pdbimage > 0x7FFFFFFF) {
1834 // 0x7FFFFFFF: why? Because the VG_(read) just below only
1835 // can deal with a signed int as the size of data to read,
1836 // so we can't reliably check for read failure for files
1837 // greater than that size. Hence just skip them; we're
1838 // unlikely to encounter a PDB that large anyway.
1839 VG_(close)(fd_pdbimage);
1840 goto out;
1842 sres = VG_(am_mmap_anon_float_valgrind)( n_pdbimage );
1843 if (sr_isError(sres)) {
1844 VG_(close)(fd_pdbimage);
1845 goto out;
1848 void* pdbimage = (void*)(Addr)sr_Res(sres);
1849 r = VG_(read)( fd_pdbimage, pdbimage, (Int)n_pdbimage );
1850 if (r < 0 || r != (Int)n_pdbimage) {
1851 VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage );
1852 VG_(close)(fd_pdbimage);
1853 goto out;
1856 if (VG_(clo_verbosity) > 0)
1857 VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: pdbname: %s\n", pdbname);
1859 /* play safe; always invalidate the debug info caches. I don't know if
1860 this is necessary, but anyway .. */
1861 caches__invalidate();
1862 /* dump old info for this range, if any */
1863 discard_syms_in_range( avma_obj, total_size );
1864 advance_current_DiEpoch("VG_(di_notify_pdb_debuginfo)");
1866 { DebugInfo* di = find_or_create_DebugInfo_for(exename);
1868 /* this di must be new, since we just nuked any old stuff in the range */
1869 vg_assert(di && !di->fsm.have_rx_map && !di->fsm.rw_map_count);
1870 vg_assert(!di->have_dinfo);
1872 /* don't set up any of the di-> fields; let
1873 ML_(read_pdb_debug_info) do it. */
1874 if (ML_(read_pdb_debug_info)( di, avma_obj, bias_obj,
1875 pdbimage, n_pdbimage, pdbname, pdb_mtime )) {
1876 vg_assert(di->have_dinfo); // fails if PDB read failed
1877 if (VG_(clo_verbosity) > 0) {
1878 VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: done: "
1879 "%lu syms, %lu src locs, %lu fpo recs\n",
1880 di->symtab_used, di->loctab_used, di->fpo_size);
1882 } else {
1883 VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: failed loading info "
1884 "from %s\n", pdbname);
1885 /* We cannot make any sense of this pdb, so (force) discard it,
1886 even if VG_(clo_keep_debuginfo) is True. */
1887 const Bool save_clo_keep_debuginfo = VG_(clo_keep_debuginfo);
1888 VG_(clo_keep_debuginfo) = False;
1889 // The below will assert if di is not active. Not too sure what
1890 // the state of di in this failed loading state.
1891 discard_or_archive_DebugInfo (di);
1892 VG_(clo_keep_debuginfo) = save_clo_keep_debuginfo;
1894 VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage );
1895 VG_(close)(fd_pdbimage);
1899 out:
1900 if (pdbname) ML_(dinfo_free)(pdbname);
1903 #endif /* defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd) */
1906 /*------------------------------------------------------------*/
1907 /*--- ---*/
1908 /*--- TOP LEVEL: QUERYING EXISTING DEBUG INFO ---*/
1909 /*--- ---*/
1910 /*------------------------------------------------------------*/
1912 void VG_(di_discard_ALL_debuginfo)( void )
1914 DebugInfo *di, *di2;
1915 di = debugInfo_list;
1916 while (di) {
1917 di2 = di->next;
1918 VG_(printf)("XXX rm %p\n", di);
1919 free_DebugInfo( di );
1920 di = di2;
1925 DebugInfoMapping* ML_(find_rx_mapping) ( DebugInfo* di, Addr lo, Addr hi )
1927 Word i;
1928 vg_assert(lo <= hi);
1930 /* Optimization: Try to use the last matched rx mapping first */
1931 if ( di->last_rx_map
1932 && lo >= di->last_rx_map->avma
1933 && hi < di->last_rx_map->avma + di->last_rx_map->size)
1934 return di->last_rx_map;
1936 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1937 DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1938 if ( map->rx && map->size > 0
1939 && lo >= map->avma && hi < map->avma + map->size) {
1940 di->last_rx_map = map;
1941 return map;
1945 return NULL;
1948 /*------------------------------------------------------------*/
1949 /*--- Types and functions for inlined IP cursor ---*/
1950 /*------------------------------------------------------------*/
1952 struct _InlIPCursor {
1953 Addr eip; // Cursor used to describe calls at eip.
1954 DebugInfo* di; // DebugInfo describing inlined calls at eip
1956 Word inltab_lopos; // The inlined fn calls covering eip are in
1957 Word inltab_hipos; // di->inltab[inltab_lopos..inltab_hipos].
1958 // Note that not all inlined fn calls in this range
1959 // are necessarily covering eip.
1961 Int curlevel; // Current level to describe.
1962 // 0 means to describe eip itself.
1963 Word cur_inltab; // inltab pos for call inlined at current level.
1964 Word next_inltab; // inltab pos for call inlined at next (towards main)
1965 // level.
1968 static Bool is_top(const InlIPCursor *iipc)
1970 return !iipc || iipc->cur_inltab == -1;
1973 static Bool is_bottom(const InlIPCursor *iipc)
1975 return !iipc || iipc->next_inltab == -1;
1978 Bool VG_(next_IIPC)(InlIPCursor *iipc)
1980 Word i;
1981 DiInlLoc *hinl = NULL;
1982 Word hinl_pos = -1;
1983 DebugInfo *di;
1985 if (iipc == NULL)
1986 return False;
1988 if (iipc->curlevel <= 0) {
1989 iipc->curlevel--;
1990 return False;
1993 di = iipc->di;
1994 for (i = iipc->inltab_lopos; i <= iipc->inltab_hipos; i++) {
1995 if (di->inltab[i].addr_lo <= iipc->eip
1996 && iipc->eip < di->inltab[i].addr_hi
1997 && di->inltab[i].level < iipc->curlevel
1998 && (!hinl || hinl->level < di->inltab[i].level)) {
1999 hinl = &di->inltab[i];
2000 hinl_pos = i;
2004 iipc->cur_inltab = iipc->next_inltab;
2005 iipc->next_inltab = hinl_pos;
2006 if (iipc->next_inltab < 0)
2007 iipc->curlevel = 0; // no inlined call anymore, describe eip itself
2008 else
2009 iipc->curlevel = di->inltab[iipc->next_inltab].level;
2011 return True;
2014 /* Forward */
2015 static void search_all_loctabs ( DiEpoch ep, Addr ptr,
2016 /*OUT*/DebugInfo** pdi, /*OUT*/Word* locno );
2018 /* Returns the position after which eip would be inserted in inltab.
2019 (-1 if eip should be inserted before position 0).
2020 This is the highest position with an addr_lo <= eip.
2021 As inltab is sorted on addr_lo, dichotomic search can be done
2022 (note that inltab might have duplicates addr_lo). */
2023 static Word inltab_insert_pos (DebugInfo *di, Addr eip)
2025 Word mid,
2026 lo = 0,
2027 hi = di->inltab_used-1;
2028 while (lo <= hi) {
2029 mid = (lo + hi) / 2;
2030 if (eip < di->inltab[mid].addr_lo) { hi = mid-1; continue; }
2031 if (eip > di->inltab[mid].addr_lo) { lo = mid+1; continue; }
2032 lo = mid; break;
2035 while (lo <= di->inltab_used-1 && di->inltab[lo].addr_lo <= eip)
2036 lo++;
2037 #if 0
2038 for (mid = 0; mid <= di->inltab_used-1; mid++)
2039 if (eip < di->inltab[mid].addr_lo)
2040 break;
2041 vg_assert (lo - 1 == mid - 1);
2042 #endif
2043 return lo - 1;
2046 InlIPCursor* VG_(new_IIPC)(DiEpoch ep, Addr eip)
2048 DebugInfo* di;
2049 Word locno;
2050 Word i;
2051 InlIPCursor *ret;
2052 Bool avail;
2054 if (!VG_(clo_read_inline_info))
2055 return NULL; // No way we can find inlined calls.
2057 /* Search the DebugInfo for (ep, eip) */
2058 search_all_loctabs ( ep, eip, &di, &locno );
2059 if (di == NULL || di->inltab_used == 0)
2060 return NULL; // No di (with inltab) containing eip.
2062 /* Search the entry in di->inltab with the highest addr_lo that
2063 contains eip. */
2064 /* We start from the highest pos in inltab after which eip would
2065 be inserted. */
2066 for (i = inltab_insert_pos (di, eip); i >= 0; i--) {
2067 if (di->inltab[i].addr_lo <= eip && eip < di->inltab[i].addr_hi) {
2068 break;
2070 /* Stop the backward scan when reaching an addr_lo which
2071 cannot anymore contain eip : we know that all ranges before
2072 i also cannot contain eip. */
2073 if (di->inltab[i].addr_lo < eip - di->maxinl_codesz)
2074 return NULL;
2077 if (i < 0)
2078 return NULL; // No entry containing eip.
2080 /* We have found the highest entry containing eip.
2081 Build a cursor. */
2082 ret = ML_(dinfo_zalloc) ("dinfo.new_IIPC", sizeof(*ret));
2083 ret->eip = eip;
2084 ret->di = di;
2085 ret->inltab_hipos = i;
2086 for (i = ret->inltab_hipos - 1; i >= 0; i--) {
2088 if (di->inltab[i].addr_lo < eip - di->maxinl_codesz)
2089 break; /* Similar stop backward scan logic as above. */
2091 ret->inltab_lopos = i + 1;
2092 ret->curlevel = MAX_LEVEL;
2093 ret->cur_inltab = -1;
2094 ret->next_inltab = -1;
2096 /* MAX_LEVEL is higher than any stored level. We can use
2097 VG_(next_IIPC) to get to the 'real' first highest call level. */
2098 avail = VG_(next_IIPC) (ret);
2099 vg_assert (avail);
2101 return ret;
2104 void VG_(delete_IIPC)(InlIPCursor *iipc)
2106 if (iipc)
2107 ML_(dinfo_free)( iipc );
2111 /*------------------------------------------------------------*/
2112 /*--- Use of symbol table & location info to create ---*/
2113 /*--- plausible-looking stack dumps. ---*/
2114 /*------------------------------------------------------------*/
2116 /* Search all symtabs that we know about to locate ptr. If found, set
2117 *pdi to the relevant DebugInfo, and *symno to the symtab entry
2118 *number within that. If not found, *psi is set to NULL.
2119 If findText==True, only text symbols are searched for.
2120 If findText==False, only data symbols are searched for.
2122 static void search_all_symtabs ( DiEpoch ep, Addr ptr,
2123 /*OUT*/DebugInfo** pdi, /*OUT*/Word* symno,
2124 Bool findText )
2126 Word sno;
2127 DebugInfo* di;
2128 Bool inRange;
2130 for (di = debugInfo_list; di != NULL; di = di->next) {
2132 if (!is_DI_valid_for_epoch(di, ep))
2133 continue;
2135 if (findText) {
2136 /* Consider any symbol in the r-x mapped area to be text.
2137 See Comment_Regarding_Text_Range_Checks in storage.c for
2138 details. */
2139 inRange = di->fsm.have_rx_map
2140 && (ML_(find_rx_mapping)(di, ptr, ptr) != NULL);
2141 } else {
2142 inRange = (di->data_present
2143 && di->data_size > 0
2144 && di->data_avma <= ptr
2145 && ptr < di->data_avma + di->data_size)
2147 (di->sdata_present
2148 && di->sdata_size > 0
2149 && di->sdata_avma <= ptr
2150 && ptr < di->sdata_avma + di->sdata_size)
2152 (di->bss_present
2153 && di->bss_size > 0
2154 && di->bss_avma <= ptr
2155 && ptr < di->bss_avma + di->bss_size)
2157 (di->sbss_present
2158 && di->sbss_size > 0
2159 && di->sbss_avma <= ptr
2160 && ptr < di->sbss_avma + di->sbss_size)
2162 (di->rodata_present
2163 && di->rodata_size > 0
2164 && di->rodata_avma <= ptr
2165 && ptr < di->rodata_avma + di->rodata_size);
2168 if (!inRange) continue;
2170 sno = ML_(search_one_symtab) ( di, ptr, findText );
2171 if (sno == -1) goto not_found;
2172 *symno = sno;
2173 *pdi = di;
2174 return;
2177 not_found:
2178 *pdi = NULL;
2182 /* Search all loctabs that we know about to locate ptr at epoch ep. If
2183 *found, set pdi to the relevant DebugInfo, and *locno to the loctab entry
2184 *number within that. If not found, *pdi is set to NULL. */
2185 static void search_all_loctabs ( DiEpoch ep, Addr ptr,
2186 /*OUT*/DebugInfo** pdi, /*OUT*/Word* locno )
2188 Word lno;
2189 DebugInfo* di;
2190 for (di = debugInfo_list; di != NULL; di = di->next) {
2191 if (!is_DI_valid_for_epoch(di, ep))
2192 continue;
2193 if (di->text_present
2194 && di->text_size > 0
2195 && di->text_avma <= ptr
2196 && ptr < di->text_avma + di->text_size) {
2197 lno = ML_(search_one_loctab) ( di, ptr );
2198 if (lno == -1) goto not_found;
2199 *locno = lno;
2200 *pdi = di;
2201 return;
2204 not_found:
2205 *pdi = NULL;
2208 /* Caching of queries to symbol names. */
2209 // Prime number, giving about 6Kbytes cache on 32 bits,
2210 // 12Kbytes cache on 64 bits.
2211 #define N_SYM_NAME_CACHE 509
2213 typedef
2214 struct {
2215 // (sym_epoch, sym_avma) are the hash table key.
2216 DiEpoch sym_epoch;
2217 Addr sym_avma;
2218 // Fields below here are not part of the key.
2219 const HChar* sym_name;
2220 PtrdiffT offset : (sizeof(PtrdiffT)*8)-1;
2221 Bool isText : 1;
2223 Sym_Name_CacheEnt;
2224 /* Sym_Name_CacheEnt associates a queried (epoch, address) pair to the sym
2225 name found. By nature, if a sym name was found, it means the searched
2226 address stored in the cache is an avma (see e.g. search_all_symtabs).
2227 Note however that the caller is responsible to work with 'avma' addresses
2228 e.g. when calling VG_(get_fnname) : m_debuginfo.c has no way to
2229 differentiate an 'svma a' from an 'avma a'. It is however unlikely that
2230 svma would percolate outside of this module. */
2232 static Sym_Name_CacheEnt sym_name_cache[N_SYM_NAME_CACHE];
2234 static const HChar* no_sym_name = "<<<noname>>>";
2235 /* We need a special marker for the address 0 : a not used entry has
2236 a zero sym_avma. So, if ever the 0 address is really queried, we need
2237 to be able to detect there is no sym name for this address.
2238 If on some platforms, 0 is associated to a symbol, the cache would
2239 work properly. */
2241 static void sym_name_cache__invalidate ( void ) {
2242 VG_(memset)(&sym_name_cache, 0, sizeof(sym_name_cache));
2243 sym_name_cache[0].sym_name = no_sym_name;
2246 /* The whole point of this whole big deal: map an (epoch, code address) pair
2247 to a plausible symbol name. Returns False if no idea; otherwise True.
2249 Caller supplies buf. If do_cxx_demangling is False, don't do
2250 C++ demangling, regardless of VG_(clo_demangle) -- probably because the
2251 call has come from VG_(get_fnname_raw)(). findText
2252 indicates whether we're looking for a text symbol or a data symbol
2253 -- caller must choose one kind or the other.
2255 NOTE: See IMPORTANT COMMENT above about persistence and ownership
2256 in pub_tool_debuginfo.h
2257 get_sym_name and the fact it calls the demangler is the main reason
2258 for non persistence of the information returned by m_debuginfo.c
2259 functions : the string returned in *BUF is persistent as long as
2260 (1) the DebugInfo it belongs to is not discarded
2261 (2) the demangler is not invoked again
2262 Also, the returned string is owned by "somebody else". Callers must
2263 not free it or modify it. */
2264 static
2265 Bool get_sym_name ( Bool do_cxx_demangling, Bool do_z_demangling,
2266 Bool do_below_main_renaming,
2267 DiEpoch ep, Addr a, const HChar** buf,
2268 Bool match_anywhere_in_sym, Bool show_offset,
2269 Bool findText, /*OUT*/PtrdiffT* offsetP )
2271 // Compute the hash from 'ep' and 'a'. The latter contains lots of
2272 // significant bits, but 'ep' is expected to be a small number, typically
2273 // less than 500. So rotate it around a bit in the hope of spreading the
2274 // bits out somewhat.
2275 vg_assert(!is_DiEpoch_INVALID(ep));
2276 UWord hash = a ^ (UWord)(ep.n ^ ROL32(ep.n, 5)
2277 ^ ROL32(ep.n, 13) ^ ROL32(ep.n, 19));
2278 hash %= N_SYM_NAME_CACHE;
2280 Sym_Name_CacheEnt* se = &sym_name_cache[hash];
2282 if (UNLIKELY(se->sym_epoch.n != ep.n || se->sym_avma != a
2283 || se->isText != findText)) {
2284 DebugInfo* di;
2285 Word sno;
2287 search_all_symtabs ( ep, a, &di, &sno, findText );
2288 se->sym_epoch = ep;
2289 se->sym_avma = a;
2290 se->isText = findText;
2291 if (di == NULL || a == 0)
2292 se->sym_name = no_sym_name;
2293 else {
2294 vg_assert(di->symtab[sno].pri_name);
2295 se->sym_name = di->symtab[sno].pri_name;
2296 se->offset = a - di->symtab[sno].avmas.main;
2300 if (se->sym_name == no_sym_name
2301 || (!match_anywhere_in_sym && se->offset != 0)) {
2302 *buf = "";
2303 return False;
2306 VG_(demangle) ( do_cxx_demangling, do_z_demangling,
2307 se->sym_name, buf );
2309 /* Do the below-main hack */
2310 // To reduce the endless nuisance of multiple different names
2311 // for "the frame below main()" screwing up the testsuite, change all
2312 // known incarnations of said into a single name, "(below main)", if
2313 // --show-below-main=yes.
2314 if ( do_below_main_renaming && ! VG_(clo_show_below_main)
2315 && Vg_FnNameBelowMain == VG_(get_fnname_kind)(*buf) )
2317 *buf = "(below main)";
2320 if (offsetP) *offsetP = se->offset;
2322 if (show_offset && se->offset != 0) {
2323 static HChar *bufwo; // buf with offset
2324 static SizeT bufwo_szB;
2325 SizeT need, len;
2327 len = VG_(strlen)(*buf);
2328 need = len + 1 + 19 + 1;
2329 if (need > bufwo_szB) {
2330 bufwo = ML_(dinfo_realloc)("get_sym_size", bufwo, need);
2331 bufwo_szB = need;
2334 VG_(strcpy)(bufwo, *buf);
2335 VG_(sprintf)(bufwo + len, "%c%ld",
2336 se->offset < 0 ? '-' : '+',
2337 (PtrdiffT) (se->offset < 0 ? -se->offset : se->offset));
2338 *buf = bufwo;
2341 return True;
2344 /* ppc64be-linux only: find the TOC pointer (R2 value) that should be in
2345 force at the entry point address of the function containing
2346 guest_code_addr. Returns 0 if not known. */
2347 Addr VG_(get_tocptr) ( DiEpoch ep, Addr guest_code_addr )
2349 #if defined(VGA_ppc64be) || defined(VGA_ppc64le)
2350 DebugInfo* si;
2351 Word sno;
2352 search_all_symtabs ( ep, guest_code_addr,
2353 &si, &sno,
2354 True/*consider text symbols only*/ );
2355 if (si == NULL)
2356 return 0;
2357 else
2358 return GET_TOCPTR_AVMA(si->symtab[sno].avmas);
2359 #else
2360 return 0;
2361 #endif
2364 /* This is available to tools... always demangle C++ names,
2365 match anywhere in function, but don't show offsets.
2366 NOTE: See IMPORTANT COMMENT above about persistence and ownership
2367 in pub_tool_debuginfo.h */
2368 Bool VG_(get_fnname) ( DiEpoch ep, Addr a, const HChar** buf )
2370 return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True,
2371 /*below-main-renaming*/True,
2372 ep, a, buf,
2373 /*match_anywhere_in_fun*/True,
2374 /*show offset?*/False,
2375 /*text sym*/True,
2376 /*offsetP*/NULL );
2380 Bool VG_(get_fnname_inl) ( DiEpoch ep, Addr a, const HChar** buf,
2381 const InlIPCursor* iipc )
2383 if (iipc) {
2384 vg_assert(is_DI_valid_for_epoch(iipc->di, ep));
2387 if (is_bottom(iipc)) {
2388 return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True,
2389 /*below-main-renaming*/True,
2390 ep, a, buf,
2391 /*match_anywhere_in_fun*/True,
2392 /*show offset?*/False,
2393 /*text sym*/True,
2394 /*offsetP*/NULL );
2395 } else {
2396 const DiInlLoc *next_inl = iipc && iipc->next_inltab >= 0
2397 ? & iipc->di->inltab[iipc->next_inltab]
2398 : NULL;
2399 vg_assert (next_inl);
2400 *buf = next_inl->inlinedfn;
2401 return True;
2405 /* This is available to tools... always demangle C++ names,
2406 match anywhere in function, and show offset if nonzero.
2407 NOTE: See IMPORTANT COMMENT above about persistence and ownership
2408 in pub_tool_debuginfo.h */
2409 Bool VG_(get_fnname_w_offset) ( DiEpoch ep, Addr a, const HChar** buf )
2411 return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True,
2412 /*below-main-renaming*/True,
2413 ep, a, buf,
2414 /*match_anywhere_in_fun*/True,
2415 /*show offset?*/True,
2416 /*text sym*/True,
2417 /*offsetP*/NULL );
2420 /* This is available to tools... always demangle C++ names,
2421 only succeed if 'a' matches first instruction of function,
2422 and don't show offsets.
2423 NOTE: See IMPORTANT COMMENT above about persistence and ownership
2424 in pub_tool_debuginfo.h */
2425 Bool VG_(get_fnname_if_entry) ( DiEpoch ep, Addr a, const HChar** buf )
2427 const HChar *tmp;
2428 Bool res;
2430 res = get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True,
2431 /*below-main-renaming*/True,
2432 ep, a, &tmp,
2433 /*match_anywhere_in_fun*/False,
2434 /*show offset?*/False,
2435 /*text sym*/True,
2436 /*offsetP*/NULL );
2437 if (res)
2438 *buf = tmp;
2439 return res;
2442 /* This is only available to core... don't C++-demangle, don't Z-demangle,
2443 don't rename below-main, match anywhere in function, and don't show
2444 offsets.
2445 NOTE: See IMPORTANT COMMENT above about persistence and ownership
2446 in pub_tool_debuginfo.h */
2447 Bool VG_(get_fnname_raw) ( DiEpoch ep, Addr a, const HChar** buf )
2449 return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False,
2450 /*below-main-renaming*/False,
2451 ep, a, buf,
2452 /*match_anywhere_in_fun*/True,
2453 /*show offset?*/False,
2454 /*text sym*/True,
2455 /*offsetP*/NULL );
2458 /* This is only available to core... don't demangle C++ names, but do
2459 do Z-demangling and below-main-renaming, match anywhere in function, and
2460 don't show offsets.
2461 NOTE: See IMPORTANT COMMENT above about persistence and ownership
2462 in pub_tool_debuginfo.h */
2463 Bool VG_(get_fnname_no_cxx_demangle) ( DiEpoch ep, Addr a, const HChar** buf,
2464 const InlIPCursor* iipc )
2466 // All the callers of VG_(get_fnname_no_cxx_demangle) must build
2467 // the iipc with the same ep as provided to VG_(get_fnname_no_cxx_demangle).
2468 // So, if we have an iipc, iipc->di must be valid in the provided ep.
2469 // Functionally, we could equally use iipc->di->first_epoch or ep, as
2470 // all the inlined fn calls will be described by the same di.
2471 if (iipc) {
2472 vg_assert(is_DI_valid_for_epoch(iipc->di, ep));
2475 if (is_bottom(iipc)) {
2476 // At the bottom (towards main), we describe the fn at eip.
2477 return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/True,
2478 /*below-main-renaming*/True,
2479 ep, a, buf,
2480 /*match_anywhere_in_fun*/True,
2481 /*show offset?*/False,
2482 /*text sym*/True,
2483 /*offsetP*/NULL );
2484 } else {
2485 const DiInlLoc *next_inl = iipc && iipc->next_inltab >= 0
2486 ? & iipc->di->inltab[iipc->next_inltab]
2487 : NULL;
2488 vg_assert (next_inl);
2489 // The function we are in is called by next_inl.
2490 *buf = next_inl->inlinedfn;
2491 return True;
2495 /* mips-linux only: find the offset of current address. This is needed for
2496 stack unwinding for MIPS.
2498 Bool VG_(get_inst_offset_in_function)( DiEpoch ep, Addr a,
2499 /*OUT*/PtrdiffT* offset )
2501 const HChar *fnname;
2502 return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False,
2503 /*below-main-renaming*/False,
2504 ep, a, &fnname,
2505 /*match_anywhere_in_sym*/True,
2506 /*show offset?*/False,
2507 /*text sym*/True,
2508 offset );
2511 Vg_FnNameKind VG_(get_fnname_kind) ( const HChar* name )
2513 if (VG_STREQ("main", name)) {
2514 return Vg_FnNameMain;
2516 } else if (
2517 # if defined(VGO_linux)
2518 VG_STREQ("__libc_start_main", name) || // glibc glibness
2519 VG_STREQ("__libc_start_call_main", name) || // glibc glibness
2520 VG_STREQN(18, "__libc_start_main.", name) || // gcc optimization
2521 VG_STREQ("generic_start_main", name) || // Yellow Dog doggedness
2522 VG_STREQN(19, "generic_start_main.", name) || // gcc optimization
2523 VG_STREQ("_start", name) ||
2524 # elif defined(VGO_freebsd)
2525 VG_STREQ("_start", name) || // FreeBSD libc
2526 # elif defined(VGO_darwin)
2527 // See readmacho.c for an explanation of this.
2528 VG_STREQ("start_according_to_valgrind", name) || // Darwin, darling
2529 # elif defined(VGO_solaris)
2530 VG_STREQ("_start", name) || // main() is called directly from _start
2531 # else
2532 # error "Unknown OS"
2533 # endif
2534 0) {
2535 return Vg_FnNameBelowMain;
2537 } else {
2538 return Vg_FnNameNormal;
2542 Vg_FnNameKind VG_(get_fnname_kind_from_IP) ( DiEpoch ep, Addr ip )
2544 const HChar *buf;
2546 // We don't demangle, because it's faster not to, and the special names
2547 // we're looking for won't be mangled.
2548 if (VG_(get_fnname_raw) ( ep, ip, &buf )) {
2550 return VG_(get_fnname_kind)(buf);
2551 } else {
2552 return Vg_FnNameNormal; // Don't know the name, treat it as normal.
2556 /* Looks up data_addr in the collection of data symbols, and if found
2557 puts a pointer to its name into dname. The name is zero terminated.
2558 Also data_addr's offset from the symbol start is put into *offset.
2559 NOTE: See IMPORTANT COMMENT above about persistence and ownership
2560 in pub_tool_debuginfo.h */
2561 Bool VG_(get_datasym_and_offset)( DiEpoch ep, Addr data_addr,
2562 /*OUT*/const HChar** dname,
2563 /*OUT*/PtrdiffT* offset )
2565 return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False,
2566 /*below-main-renaming*/False,
2567 ep, data_addr, dname,
2568 /*match_anywhere_in_sym*/True,
2569 /*show offset?*/False,
2570 /*text sym*/False,
2571 offset );
2574 /* Map a code address to the name of a shared object file or the
2575 executable. Returns False if no idea; otherwise True.
2576 Note: the string returned in *BUF is persistent as long as
2577 (1) the DebugInfo it belongs to is not discarded
2578 (2) the segment containing the address is not merged with another segment
2580 Bool VG_(get_objname) ( DiEpoch ep, Addr a, const HChar** objname )
2582 DebugInfo* di;
2583 const NSegment *seg;
2584 const HChar* filename;
2586 /* Look in the debugInfo_list to find the name. In most cases we
2587 expect this to produce a result. */
2588 for (di = debugInfo_list; di != NULL; di = di->next) {
2589 if (!is_DI_valid_for_epoch(di, ep))
2590 continue;
2591 if (di->text_present
2592 && di->text_size > 0
2593 && di->text_avma <= a
2594 && a < di->text_avma + di->text_size) {
2595 *objname = di->fsm.filename;
2596 return True;
2599 /* Last-ditch fallback position: if we don't find the address in
2600 the debugInfo_list, ask the address space manager whether it
2601 knows the name of the file associated with this mapping. This
2602 allows us to print the names of exe/dll files in the stack trace
2603 when running programs under wine.
2605 Restrict this to the case where 'ep' is the current epoch, though, so
2606 that we don't return information about this epoch when the caller was
2607 enquiring about a different one. */
2608 if ( eq_DiEpoch(ep, VG_(current_DiEpoch)())
2609 && (seg = VG_(am_find_nsegment)(a)) != NULL
2610 && (filename = VG_(am_get_filename)(seg)) != NULL ) {
2611 *objname = filename;
2612 return True;
2614 return False;
2617 /* Map a code address to its DebugInfo. Returns NULL if not found. Doesn't
2618 require debug info. */
2619 DebugInfo* VG_(find_DebugInfo) ( DiEpoch ep, Addr a )
2621 static UWord n_search = 0;
2622 DebugInfo* di;
2623 n_search++;
2624 for (di = debugInfo_list; di != NULL; di = di->next) {
2625 if (!is_DI_valid_for_epoch(di, ep))
2626 continue;
2627 if (di->text_present
2628 && di->text_size > 0
2629 && di->text_avma <= a
2630 && a < di->text_avma + di->text_size) {
2631 if (0 == (n_search & 0xF))
2632 move_DebugInfo_one_step_forward( di );
2633 return di;
2636 return NULL;
2639 /* Map a code address to a filename. Returns True if successful. The
2640 returned string is persistent as long as the DebugInfo to which it
2641 belongs is not discarded. */
2642 Bool VG_(get_filename)( DiEpoch ep, Addr a, const HChar** filename )
2644 DebugInfo* si;
2645 Word locno;
2646 UInt fndn_ix;
2648 search_all_loctabs ( ep, a, &si, &locno );
2649 if (si == NULL)
2650 return False;
2651 fndn_ix = ML_(fndn_ix) (si, locno);
2652 *filename = ML_(fndn_ix2filename) (si, fndn_ix);
2653 return True;
2656 /* Map a code address to a line number. Returns True if successful. */
2657 Bool VG_(get_linenum)( DiEpoch ep, Addr a, UInt* lineno )
2659 DebugInfo* si;
2660 Word locno;
2661 search_all_loctabs ( ep, a, &si, &locno );
2662 if (si == NULL)
2663 return False;
2664 *lineno = si->loctab[locno].lineno;
2666 return True;
2669 /* Map a code address to a filename/line number/dir name info.
2670 See prototype for detailed description of behaviour.
2672 Bool VG_(get_filename_linenum) ( DiEpoch ep, Addr a,
2673 /*OUT*/const HChar** filename,
2674 /*OUT*/const HChar** dirname,
2675 /*OUT*/UInt* lineno )
2677 DebugInfo* si;
2678 Word locno;
2679 UInt fndn_ix;
2681 search_all_loctabs ( ep, a, &si, &locno );
2682 if (si == NULL) {
2683 if (dirname) {
2684 *dirname = "";
2686 *filename = ""; // this used to be not initialised....
2687 return False;
2690 fndn_ix = ML_(fndn_ix)(si, locno);
2691 *filename = ML_(fndn_ix2filename) (si, fndn_ix);
2692 *lineno = si->loctab[locno].lineno;
2694 if (dirname) {
2695 /* caller wants directory info too .. */
2696 *dirname = ML_(fndn_ix2dirname) (si, fndn_ix);
2699 return True;
2703 /* Map a function name to its entry point and toc pointer. Is done by
2704 sequential search of all symbol tables, so is very slow. To
2705 mitigate the worst performance effects, you may specify a soname
2706 pattern, and only objects matching that pattern are searched.
2707 Therefore specify "*" to search all the objects. On TOC-afflicted
2708 platforms, a symbol is deemed to be found only if it has a nonzero
2709 TOC pointer. */
2710 Bool VG_(lookup_symbol_SLOW)(DiEpoch ep,
2711 const HChar* sopatt, const HChar* name,
2712 SymAVMAs* avmas)
2714 Bool require_pToc = False;
2715 Int i;
2716 const DebugInfo* si;
2717 Bool debug = False;
2718 # if defined(VG_PLAT_USES_PPCTOC)
2719 require_pToc = True;
2720 # endif
2721 for (si = debugInfo_list; si; si = si->next) {
2722 if (debug)
2723 VG_(printf)("lookup_symbol_SLOW: considering %s\n", si->soname);
2724 if (!is_DI_valid_for_epoch(si, ep))
2725 continue;
2726 if (!VG_(string_match)(sopatt, si->soname)) {
2727 if (debug)
2728 VG_(printf)(" ... skip\n");
2729 continue;
2731 for (i = 0; i < si->symtab_used; i++) {
2732 const HChar* pri_name = si->symtab[i].pri_name;
2733 vg_assert(pri_name);
2734 if (0==VG_(strcmp)(name, pri_name)
2735 && (require_pToc ? GET_TOCPTR_AVMA(si->symtab[i].avmas) : True)) {
2736 *avmas = si->symtab[i].avmas;
2737 return True;
2739 const HChar** sec_names = si->symtab[i].sec_names;
2740 if (sec_names) {
2741 vg_assert(sec_names[0]);
2742 while (*sec_names) {
2743 if (0==VG_(strcmp)(name, *sec_names)
2744 && (require_pToc
2745 ? GET_TOCPTR_AVMA(si->symtab[i].avmas) : True)) {
2746 *avmas = si->symtab[i].avmas;
2747 return True;
2749 sec_names++;
2754 return False;
2758 /* VG_(describe_IP): return info on code address, function name and
2759 filename. The returned string is allocated in a static buffer and will
2760 be overwritten in the next invocation. */
2762 /* Copy str into *buf starting at n, ensuring that buf is zero-terminated.
2763 Return the index of the terminating null character. */
2764 static SizeT
2765 putStr( SizeT n, HChar** buf, SizeT *bufsiz, const HChar* str )
2767 SizeT slen = VG_(strlen)(str);
2768 SizeT need = n + slen + 1;
2770 if (need > *bufsiz) {
2771 if (need < 256) need = 256;
2772 *bufsiz = need;
2773 *buf = ML_(dinfo_realloc)("putStr", *buf, *bufsiz);
2776 VG_(strcpy)(*buf + n, str);
2778 return n + slen;
2781 /* Same as putStr, but escaping chars for XML output. */
2782 static SizeT
2783 putStrEsc( SizeT n, HChar** buf, SizeT *bufsiz, const HChar* str )
2785 HChar alt[2];
2787 for (; *str != 0; str++) {
2788 switch (*str) {
2789 case '&':
2790 n = putStr( n, buf, bufsiz, "&amp;");
2791 break;
2792 case '<':
2793 n = putStr( n, buf, bufsiz, "&lt;");
2794 break;
2795 case '>':
2796 n = putStr( n, buf, bufsiz, "&gt;");
2797 break;
2798 default:
2799 alt[0] = *str;
2800 alt[1] = 0;
2801 n = putStr( n, buf, bufsiz, alt );
2802 break;
2805 return n;
2808 const HChar* VG_(describe_IP)(DiEpoch ep, Addr eip, const InlIPCursor *iipc)
2810 static HChar *buf = NULL;
2811 static SizeT bufsiz = 0;
2812 # define APPEND(_str) \
2813 n = putStr(n, &buf, &bufsiz, _str)
2814 # define APPEND_ESC(_str) \
2815 n = putStrEsc(n, &buf, &bufsiz, _str)
2817 UInt lineno;
2818 HChar ibuf[50]; // large enough
2819 SizeT n = 0;
2821 // An InlIPCursor is associated with one specific DebugInfo. So if
2822 // it exists, make sure that it is valid for the specified DiEpoch.
2823 vg_assert (!iipc
2824 || (is_DI_valid_for_epoch(iipc->di, ep) && iipc->eip == eip));
2826 const HChar *buf_fn;
2827 const HChar *buf_obj;
2828 const HChar *buf_srcloc;
2829 const HChar *buf_dirname;
2831 Bool know_dirinfo;
2832 Bool know_fnname;
2833 Bool know_objname;
2834 Bool know_srcloc;
2836 if (iipc && iipc->di)
2837 VG_(load_di) (iipc->di, eip);
2838 else
2839 VG_(addr_load_di) (eip);
2841 if (is_bottom(iipc)) {
2842 // At the bottom (towards main), we describe the fn at eip.
2843 know_fnname = VG_(clo_sym_offsets)
2844 ? VG_(get_fnname_w_offset) (ep, eip, &buf_fn)
2845 : VG_(get_fnname) (ep, eip, &buf_fn);
2846 } else {
2847 const DiInlLoc *next_inl = iipc && iipc->next_inltab >= 0
2848 ? & iipc->di->inltab[iipc->next_inltab]
2849 : NULL;
2850 vg_assert (next_inl);
2851 // The function we are in is called by next_inl.
2852 buf_fn = next_inl->inlinedfn;
2853 know_fnname = True;
2855 // INLINED????
2856 // ??? Can we compute an offset for an inlined fn call ?
2857 // ??? Offset from what ? The beginning of the inl info ?
2858 // ??? But that is not necessarily the beginning of the fn
2859 // ??? as e.g. an inlined fn call can be in several ranges.
2860 // ??? Currently never showing an offset.
2863 know_objname = VG_(get_objname)(ep, eip, &buf_obj);
2865 if (is_top(iipc)) {
2866 // The source for the highest level is in the loctab entry.
2867 know_srcloc = VG_(get_filename_linenum)(
2868 ep, eip,
2869 &buf_srcloc,
2870 &buf_dirname,
2871 &lineno
2873 know_dirinfo = buf_dirname[0] != '\0';
2874 } else {
2875 const DiInlLoc *cur_inl = iipc && iipc->di && iipc->cur_inltab >= 0
2876 ? & iipc->di->inltab[iipc->cur_inltab]
2877 : NULL;
2878 vg_assert (cur_inl);
2880 know_dirinfo = False;
2881 buf_dirname = "";
2882 // The fndn_ix and lineno for the caller of the inlined fn is in cur_inl.
2883 if (cur_inl->fndn_ix == 0) {
2884 buf_srcloc = "???";
2885 } else {
2886 FnDn *fndn = VG_(indexEltNumber) (iipc->di->fndnpool,
2887 cur_inl->fndn_ix);
2888 if (fndn->dirname) {
2889 buf_dirname = fndn->dirname;
2890 know_dirinfo = True;
2892 buf_srcloc = fndn->filename;
2894 lineno = cur_inl->lineno;
2895 know_srcloc = True;
2898 if (VG_(clo_xml)) {
2900 Bool human_readable = True;
2901 const HChar* maybe_newline = human_readable ? "\n " : "";
2902 const HChar* maybe_newline2 = human_readable ? "\n " : "";
2904 /* Print in XML format, dumping in as much info as we know.
2905 Ensure all tags are balanced. */
2906 APPEND("<frame>");
2907 VG_(sprintf)(ibuf,"<ip>0x%lX</ip>", eip);
2908 APPEND(maybe_newline);
2909 APPEND(ibuf);
2910 if (know_objname) {
2911 APPEND(maybe_newline);
2912 APPEND("<obj>");
2913 APPEND_ESC(buf_obj);
2914 APPEND("</obj>");
2916 if (know_fnname) {
2917 APPEND(maybe_newline);
2918 APPEND("<fn>");
2919 APPEND_ESC(buf_fn);
2920 APPEND("</fn>");
2922 if (know_srcloc) {
2923 if (know_dirinfo) {
2924 APPEND(maybe_newline);
2925 APPEND("<dir>");
2926 APPEND_ESC(buf_dirname);
2927 APPEND("</dir>");
2929 APPEND(maybe_newline);
2930 APPEND("<file>");
2931 APPEND_ESC(buf_srcloc);
2932 APPEND("</file>");
2933 APPEND(maybe_newline);
2934 APPEND("<line>");
2935 VG_(sprintf)(ibuf,"%u",lineno);
2936 APPEND(ibuf);
2937 APPEND("</line>");
2939 APPEND(maybe_newline2);
2940 APPEND("</frame>");
2942 } else {
2944 /* Print for humans to read */
2946 // Possible forms:
2948 // 0x80483BF: really (a.c:20)
2949 // 0x80483BF: really (in /foo/a.out)
2950 // 0x80483BF: really (in ???)
2951 // 0x80483BF: ??? (in /foo/a.out)
2952 // 0x80483BF: ??? (a.c:20)
2953 // 0x80483BF: ???
2955 VG_(sprintf)(ibuf,"0x%lX: ", eip);
2956 APPEND(ibuf);
2957 if (know_fnname) {
2958 APPEND(buf_fn);
2959 } else {
2960 APPEND("???");
2962 if (know_srcloc) {
2963 APPEND(" (");
2964 // Get the directory name, if any, possibly pruned, into dirname.
2965 const HChar* dirname = NULL;
2966 if (know_dirinfo && VG_(sizeXA)(VG_(clo_fullpath_after)) > 0) {
2967 Int i;
2968 dirname = buf_dirname;
2969 // Remove leading prefixes from the dirname.
2970 // If user supplied --fullpath-after=foo, this will remove
2971 // a leading string which matches '.*foo' (not greedy).
2972 for (i = 0; i < VG_(sizeXA)(VG_(clo_fullpath_after)); i++) {
2973 const HChar* prefix =
2974 *(HChar**) VG_(indexXA)( VG_(clo_fullpath_after), i );
2975 HChar* str = VG_(strstr)(dirname, prefix);
2976 if (str) {
2977 dirname = str + VG_(strlen)(prefix);
2978 break;
2981 /* remove leading "./" */
2982 if (dirname[0] == '.' && dirname[1] == '/')
2983 dirname += 2;
2985 // do we have any interesting directory name to show? If so
2986 // add it in.
2987 if (dirname && dirname[0] != 0) {
2988 APPEND(dirname);
2989 APPEND("/");
2991 APPEND(buf_srcloc);
2992 APPEND(":");
2993 VG_(sprintf)(ibuf,"%u",lineno);
2994 APPEND(ibuf);
2995 APPEND(")");
2996 } else if (know_objname) {
2997 APPEND(" (in ");
2998 APPEND(buf_obj);
2999 APPEND(")");
3000 } else if (know_fnname) {
3001 // Nb: do this in two steps because "??)" is a trigraph!
3002 APPEND(" (in ???");
3003 APPEND(")");
3007 return buf;
3009 # undef APPEND
3010 # undef APPEND_ESC
3014 /*--------------------------------------------------------------*/
3015 /*--- ---*/
3016 /*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/
3017 /*--- DWARF3 .eh_frame INFO ---*/
3018 /*--- ---*/
3019 /*--------------------------------------------------------------*/
3021 /* Note that the CFI machinery pertains to unwinding the stack "right now".
3022 There is no support for unwinding stack images obtained from some time in
3023 the past. That means that:
3025 (1) We only deal with CFI from DebugInfos that are valid for the current
3026 debuginfo epoch. Unlike in the rest of the file, there is no
3027 epoch-awareness.
3029 (2) We assume that the CFI cache will be invalidated every time the the
3030 epoch changes. This is done by ensuring (in the file above) that
3031 every call to advance_current_DiEpoch has a call to
3032 caches__invalidate alongside it.
3035 /* Gather up all the constant pieces of info needed to evaluate
3036 a CfiExpr into one convenient struct. */
3037 typedef
3038 struct {
3039 const D3UnwindRegs* uregs;
3040 Addr min_accessible;
3041 Addr max_accessible;
3043 CfiExprEvalContext;
3045 /* Evaluate the CfiExpr rooted at ix in exprs given the context eec.
3046 *ok is set to False on failure, but not to True on success. The
3047 caller must set it to True before calling. */
3048 __attribute__((noinline))
3049 static
3050 UWord evalCfiExpr ( const XArray* exprs, Int ix,
3051 const CfiExprEvalContext* eec, Bool* ok )
3053 UWord w, wL, wR;
3054 Addr a;
3055 const CfiExpr* e;
3056 vg_assert(sizeof(Addr) == sizeof(UWord));
3057 e = VG_(indexXA)( exprs, ix );
3058 switch (e->tag) {
3059 case Cex_Unop:
3060 w = evalCfiExpr( exprs, e->Cex.Unop.ix, eec, ok );
3061 if (!(*ok)) return 0;
3062 switch (e->Cex.Unop.op) {
3063 case Cunop_Abs: return (Word) w < 0 ? - w : w;
3064 case Cunop_Neg: return - (Word) w;
3065 case Cunop_Not: return ~ w;
3066 default: goto unhandled;
3068 /*NOTREACHED*/
3069 case Cex_Binop:
3070 wL = evalCfiExpr( exprs, e->Cex.Binop.ixL, eec, ok );
3071 if (!(*ok)) return 0;
3072 wR = evalCfiExpr( exprs, e->Cex.Binop.ixR, eec, ok );
3073 if (!(*ok)) return 0;
3074 switch (e->Cex.Binop.op) {
3075 case Cbinop_Add: return wL + wR;
3076 case Cbinop_Sub: return wL - wR;
3077 case Cbinop_And: return wL & wR;
3078 case Cbinop_Mul: return wL * wR;
3079 case Cbinop_Shl: return wL << wR;
3080 case Cbinop_Shr: return wL >> wR;
3081 case Cbinop_Eq: return wL == wR ? 1 : 0;
3082 case Cbinop_Ge: return (Word) wL >= (Word) wR ? 1 : 0;
3083 case Cbinop_Gt: return (Word) wL > (Word) wR ? 1 : 0;
3084 case Cbinop_Le: return (Word) wL <= (Word) wR ? 1 : 0;
3085 case Cbinop_Lt: return (Word) wL < (Word) wR ? 1 : 0;
3086 case Cbinop_Ne: return wL != wR ? 1 : 0;
3087 default: goto unhandled;
3089 /*NOTREACHED*/
3090 case Cex_CfiReg:
3091 switch (e->Cex.CfiReg.reg) {
3092 # if defined(VGA_x86) || defined(VGA_amd64)
3093 case Creg_IA_IP: return eec->uregs->xip;
3094 case Creg_IA_SP: return eec->uregs->xsp;
3095 case Creg_IA_BP: return eec->uregs->xbp;
3096 # elif defined(VGA_arm)
3097 case Creg_ARM_R15: return eec->uregs->r15;
3098 case Creg_ARM_R14: return eec->uregs->r14;
3099 case Creg_ARM_R13: return eec->uregs->r13;
3100 case Creg_ARM_R12: return eec->uregs->r12;
3101 case Creg_ARM_R7: return eec->uregs->r7;
3102 # elif defined(VGA_s390x)
3103 case Creg_S390_IA: return eec->uregs->ia;
3104 case Creg_S390_SP: return eec->uregs->sp;
3105 case Creg_S390_FP: return eec->uregs->fp;
3106 case Creg_S390_LR: return eec->uregs->lr;
3107 # elif defined(VGA_mips32) || defined(VGA_mips64) \
3108 || defined(VGA_nanomips)
3109 case Creg_IA_IP: return eec->uregs->pc;
3110 case Creg_IA_SP: return eec->uregs->sp;
3111 case Creg_IA_BP: return eec->uregs->fp;
3112 case Creg_MIPS_RA: return eec->uregs->ra;
3113 # elif defined(VGA_ppc32) || defined(VGA_ppc64be) \
3114 || defined(VGA_ppc64le)
3115 # elif defined(VGP_arm64_linux)
3116 case Creg_ARM64_SP: return eec->uregs->sp;
3117 case Creg_ARM64_X30: return eec->uregs->x30;
3118 case Creg_ARM64_X29: return eec->uregs->x29;
3119 # else
3120 # error "Unsupported arch"
3121 # endif
3122 default: goto unhandled;
3124 /*NOTREACHED*/
3125 case Cex_Const:
3126 return e->Cex.Const.con;
3127 case Cex_Deref:
3128 a = evalCfiExpr( exprs, e->Cex.Deref.ixAddr, eec, ok );
3129 if (!(*ok)) return 0;
3130 if (a < eec->min_accessible
3131 || a > eec->max_accessible - sizeof(UWord) + 1) {
3132 *ok = False;
3133 return 0;
3135 /* let's hope it doesn't trap! */
3136 return ML_(read_UWord)((void *)a);
3137 default:
3138 goto unhandled;
3140 /*NOTREACHED*/
3141 unhandled:
3142 VG_(printf)("\n\nevalCfiExpr: unhandled\n");
3143 ML_(ppCfiExpr)( exprs, ix );
3144 VG_(printf)("\n");
3145 vg_assert(0);
3146 /*NOTREACHED*/
3147 return 0;
3151 /* Search all the DebugInfos in the entire system, to find the DiCfSI_m
3152 that pertains to 'ip'.
3154 If found, set *diP to the DebugInfo in which it resides, and
3155 *cfsi_mP to the cfsi_m pointer in that DebugInfo's cfsi_m_pool.
3157 If not found, set *diP to (DebugInfo*)1 and *cfsi_mP to zero.
3159 Per comments at the top of this section, we only look for CFI in
3160 DebugInfos that are valid for the current epoch.
3162 __attribute__((noinline))
3163 static void find_DiCfSI ( /*OUT*/DebugInfo** diP,
3164 /*OUT*/DiCfSI_m** cfsi_mP,
3165 Addr ip )
3167 DebugInfo* di;
3168 Word i = -1;
3170 static UWord n_search = 0;
3171 static UWord n_steps = 0;
3172 n_search++;
3174 if (0) VG_(printf)("search for %#lx\n", ip);
3176 DiEpoch curr_epoch = VG_(current_DiEpoch)();
3178 for (di = debugInfo_list; di != NULL; di = di->next) {
3179 Word j;
3180 n_steps++;
3182 if (!is_DI_valid_for_epoch(di, curr_epoch))
3183 continue;
3185 VG_(load_di)(di, ip);
3187 /* Use the per-DebugInfo summary address ranges to skip
3188 inapplicable DebugInfos quickly. */
3189 if (di->cfsi_used == 0)
3190 continue;
3191 if (ip < di->cfsi_minavma || ip > di->cfsi_maxavma)
3192 continue;
3194 // This di must be active (because we have explicitly chosen not to
3195 // allow unwinding stacks that pertain to some past epoch). It can't
3196 // be archived or not-yet-active.
3197 vg_assert(is_DebugInfo_active(di));
3199 /* It might be in this DebugInfo. Search it. */
3200 j = ML_(search_one_cfitab)( di, ip );
3201 vg_assert(j >= -1 && j < (Word)di->cfsi_used);
3203 if (j != -1) {
3204 i = j;
3205 break; /* found it */
3209 if (i == -1) {
3211 /* we didn't find it. */
3212 *diP = (DebugInfo*)1;
3213 *cfsi_mP = 0;
3215 } else {
3217 /* found a di corresponding to ip. */
3218 /* ensure that di is 4-aligned (at least), so it can't possibly
3219 be equal to (DebugInfo*)1. */
3220 vg_assert(di && VG_IS_4_ALIGNED(di));
3221 *cfsi_mP = ML_(get_cfsi_m) (di, i);
3222 if (*cfsi_mP == NULL) {
3223 // This is a cfsi hole. Report no cfi information found.
3224 *diP = (DebugInfo*)1;
3225 // But we will still perform the hack below.
3226 } else {
3227 *diP = di;
3230 /* Start of performance-enhancing hack: once every 64 (chosen
3231 hackily after profiling) successful searches, move the found
3232 DebugInfo one step closer to the start of the list. This
3233 makes future searches cheaper. For starting konqueror on
3234 amd64, this in fact reduces the total amount of searching
3235 done by the above find-the-right-DebugInfo loop by more than
3236 a factor of 20. */
3237 if ((n_search & 0xF) == 0) {
3238 /* Move di one step closer to the start of the list. */
3239 move_DebugInfo_one_step_forward( di );
3241 /* End of performance-enhancing hack. */
3243 if (0 && ((n_search & 0x7FFFF) == 0))
3244 VG_(printf)("find_DiCfSI: %lu searches, "
3245 "%lu DebugInfos looked at\n",
3246 n_search, n_steps);
3253 /* Now follows a mechanism for caching queries to find_DiCfSI, since
3254 they are extremely frequent on amd64-linux, during stack unwinding.
3256 Each cache entry binds an ip value to a (di, cfsi_m*) pair. Possible
3257 values:
3259 di is non-null, cfsi_m* >= 0 ==> cache slot in use, "cfsi_m*"
3260 di is (DebugInfo*)1 ==> cache slot in use, no associated di
3261 di is NULL ==> cache slot not in use
3263 Hence simply zeroing out the entire cache invalidates all
3264 entries.
3266 We can map an ip value directly to a (di, cfsi_m*) pair as
3267 once a DebugInfo is read, adding new DiCfSI_m* is not possible
3268 anymore, as the cfsi_m_pool is frozen once the reading is terminated.
3269 Also, the cache is invalidated when new debuginfo is read due to
3270 an mmap or some debuginfo is discarded due to an munmap. */
3272 // Prime number, giving about 6Kbytes cache on 32 bits,
3273 // 12Kbytes cache on 64 bits.
3274 #define N_CFSI_M_CACHE 509
3276 typedef
3277 struct { Addr ip; DebugInfo* di; DiCfSI_m* cfsi_m; }
3278 CFSI_m_CacheEnt;
3280 static CFSI_m_CacheEnt cfsi_m_cache[N_CFSI_M_CACHE];
3282 static void cfsi_m_cache__invalidate ( void ) {
3283 VG_(memset)(&cfsi_m_cache, 0, sizeof(cfsi_m_cache));
3286 static inline CFSI_m_CacheEnt* cfsi_m_cache__find ( Addr ip )
3288 UWord hash = ip % N_CFSI_M_CACHE;
3289 CFSI_m_CacheEnt* ce = &cfsi_m_cache[hash];
3290 # ifdef N_Q_M_STATS
3291 static UWord n_q = 0, n_m = 0;
3292 n_q++;
3293 if (0 == (n_q & 0x1FFFFF))
3294 VG_(printf)("QQQ %lu %lu\n", n_q, n_m);
3295 # endif
3297 if (LIKELY(ce->ip == ip) && LIKELY(ce->di != NULL)) {
3298 /* found an entry in the cache .. */
3299 } else {
3300 /* not found in cache. Search and update. */
3301 # ifdef N_Q_M_STATS
3302 n_m++;
3303 # endif
3304 ce->ip = ip;
3305 find_DiCfSI( &ce->di, &ce->cfsi_m, ip );
3308 if (UNLIKELY(ce->di == (DebugInfo*)1)) {
3309 /* no DiCfSI for this address */
3310 return NULL;
3311 } else {
3312 /* found a DiCfSI for this address */
3313 return ce;
3317 Bool VG_(has_CF_info)(Addr a)
3319 return cfsi_m_cache__find (a) != NULL;
3324 inline
3325 static Addr compute_cfa ( const D3UnwindRegs* uregs,
3326 Addr min_accessible, Addr max_accessible,
3327 const DebugInfo* di, const DiCfSI_m* cfsi_m )
3329 CfiExprEvalContext eec;
3330 Addr cfa;
3331 Bool ok;
3333 /* Compute the CFA. */
3334 cfa = 0;
3335 switch (cfsi_m->cfa_how) {
3336 # if defined(VGA_x86) || defined(VGA_amd64)
3337 case CFIC_IA_SPREL:
3338 cfa = cfsi_m->cfa_off + uregs->xsp;
3339 break;
3340 case CFIC_IA_BPREL:
3341 cfa = cfsi_m->cfa_off + uregs->xbp;
3342 break;
3343 # elif defined(VGA_arm)
3344 case CFIC_ARM_R13REL:
3345 cfa = cfsi_m->cfa_off + uregs->r13;
3346 break;
3347 case CFIC_ARM_R12REL:
3348 cfa = cfsi_m->cfa_off + uregs->r12;
3349 break;
3350 case CFIC_ARM_R11REL:
3351 cfa = cfsi_m->cfa_off + uregs->r11;
3352 break;
3353 case CFIC_ARM_R7REL:
3354 cfa = cfsi_m->cfa_off + uregs->r7;
3355 break;
3356 # elif defined(VGA_s390x)
3357 case CFIC_IA_SPREL:
3358 cfa = cfsi_m->cfa_off + uregs->sp;
3359 break;
3360 case CFIR_MEMCFAREL:
3362 Addr a = uregs->sp + cfsi_m->cfa_off;
3363 if (a < min_accessible || a > max_accessible-sizeof(Addr))
3364 break;
3365 cfa = ML_(read_Addr)((void *)a);
3366 break;
3368 case CFIR_SAME:
3369 cfa = uregs->fp;
3370 break;
3371 case CFIC_IA_BPREL:
3372 cfa = cfsi_m->cfa_off + uregs->fp;
3373 break;
3374 # elif defined(VGA_mips32) || defined(VGA_mips64) || defined(VGA_nanomips)
3375 case CFIC_IA_SPREL:
3376 cfa = cfsi_m->cfa_off + uregs->sp;
3377 break;
3378 case CFIR_SAME:
3379 cfa = uregs->fp;
3380 break;
3381 case CFIC_IA_BPREL:
3382 cfa = cfsi_m->cfa_off + uregs->fp;
3383 break;
3384 # elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le)
3385 # elif defined(VGP_arm64_linux)
3386 case CFIC_ARM64_SPREL:
3387 cfa = cfsi_m->cfa_off + uregs->sp;
3388 break;
3389 case CFIC_ARM64_X29REL:
3390 cfa = cfsi_m->cfa_off + uregs->x29;
3391 break;
3392 # else
3393 # error "Unsupported arch"
3394 # endif
3395 case CFIC_EXPR: /* available on all archs */
3396 if (0) {
3397 VG_(printf)("CFIC_EXPR: ");
3398 ML_(ppCfiExpr)(di->cfsi_exprs, cfsi_m->cfa_off);
3399 VG_(printf)("\n");
3401 eec.uregs = uregs;
3402 eec.min_accessible = min_accessible;
3403 eec.max_accessible = max_accessible;
3404 ok = True;
3405 cfa = evalCfiExpr(di->cfsi_exprs, cfsi_m->cfa_off, &eec, &ok );
3406 if (!ok) return 0;
3407 break;
3408 default:
3409 vg_assert(0);
3411 return cfa;
3415 /* Get the call frame address (CFA) given an IP/SP/FP triple. */
3416 /* NOTE: This function may rearrange the order of entries in the
3417 DebugInfo list. */
3418 Addr ML_(get_CFA) ( Addr ip, Addr sp, Addr fp,
3419 Addr min_accessible, Addr max_accessible )
3421 CFSI_m_CacheEnt* ce;
3423 ce = cfsi_m_cache__find(ip);
3425 if (UNLIKELY(ce == NULL))
3426 return 0; /* no info. Nothing we can do. */
3428 /* Temporary impedance-matching kludge so that this keeps working
3429 on x86-linux and amd64-linux. */
3430 # if defined(VGA_x86) || defined(VGA_amd64)
3431 { D3UnwindRegs uregs;
3432 uregs.xip = ip;
3433 uregs.xsp = sp;
3434 uregs.xbp = fp;
3435 return compute_cfa(&uregs,
3436 min_accessible, max_accessible, ce->di, ce->cfsi_m);
3438 #elif defined(VGA_s390x)
3439 { D3UnwindRegs uregs;
3440 uregs.ia = ip;
3441 uregs.sp = sp;
3442 uregs.fp = fp;
3443 /* JRS FIXME 3 Apr 2019: surely we can do better for f0..f7 */
3444 uregs.f0 = 0;
3445 uregs.f1 = 0;
3446 uregs.f2 = 0;
3447 uregs.f3 = 0;
3448 uregs.f4 = 0;
3449 uregs.f5 = 0;
3450 uregs.f6 = 0;
3451 uregs.f7 = 0;
3452 return compute_cfa(&uregs,
3453 min_accessible, max_accessible, ce->di, ce->cfsi_m);
3455 #elif defined(VGA_mips32) || defined(VGA_mips64)
3456 { D3UnwindRegs uregs;
3457 uregs.pc = ip;
3458 uregs.sp = sp;
3459 uregs.fp = fp;
3460 return compute_cfa(&uregs,
3461 min_accessible, max_accessible, ce->di, ce->cfsi_m);
3464 # else
3465 return 0; /* indicates failure */
3466 # endif
3469 void VG_(ppUnwindInfo) (Addr from, Addr to)
3471 DebugInfo* di;
3472 CFSI_m_CacheEnt* ce;
3473 Addr ce_from;
3474 CFSI_m_CacheEnt* next_ce;
3477 ce = cfsi_m_cache__find(from);
3478 ce_from = from;
3479 while (from <= to) {
3480 from++;
3481 next_ce = cfsi_m_cache__find(from);
3482 if ((ce == NULL && next_ce != NULL)
3483 || (ce != NULL && next_ce == NULL)
3484 || (ce != NULL && next_ce != NULL && ce->cfsi_m != next_ce->cfsi_m)
3485 || from > to) {
3486 if (ce == NULL) {
3487 VG_(printf)("[%#lx .. %#lx]: no CFI info\n", ce_from, from-1);
3488 } else {
3489 di = ce->di;
3490 ML_(ppDiCfSI)(di->cfsi_exprs,
3491 ce_from, from - ce_from,
3492 ce->cfsi_m);
3494 ce = next_ce;
3495 ce_from = from;
3501 /* The main function for DWARF2/3 CFI-based stack unwinding. Given a
3502 set of registers in UREGS, modify it to hold the register values
3503 for the previous frame, if possible. Returns True if successful.
3504 If not successful, *UREGS is not changed.
3506 For x86 and amd64, the unwound registers are: {E,R}IP,
3507 {E,R}SP, {E,R}BP.
3509 For arm, the unwound registers are: R7 R11 R12 R13 R14 R15.
3511 For arm64, the unwound registers are: X29(FP) X30(LR) SP PC.
3513 For s390, the unwound registers are: R11(FP) R14(LR) R15(SP) F0..F7 PC.
3515 Bool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere,
3516 Addr min_accessible,
3517 Addr max_accessible )
3519 DebugInfo* di;
3520 DiCfSI_m* cfsi_m = NULL;
3521 Addr cfa, ipHere = 0;
3522 CFSI_m_CacheEnt* ce;
3523 CfiExprEvalContext eec __attribute__((unused));
3524 D3UnwindRegs uregsPrev;
3526 # if defined(VGA_x86) || defined(VGA_amd64)
3527 ipHere = uregsHere->xip;
3528 # elif defined(VGA_arm)
3529 ipHere = uregsHere->r15;
3530 # elif defined(VGA_s390x)
3531 ipHere = uregsHere->ia;
3532 # elif defined(VGA_mips32) || defined(VGA_mips64) || defined(VGA_nanomips)
3533 ipHere = uregsHere->pc;
3534 # elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le)
3535 # elif defined(VGP_arm64_linux)
3536 ipHere = uregsHere->pc;
3537 # else
3538 # error "Unknown arch"
3539 # endif
3540 ce = cfsi_m_cache__find(ipHere);
3542 if (UNLIKELY(ce == NULL))
3543 return False; /* no info. Nothing we can do. */
3545 di = ce->di;
3546 cfsi_m = ce->cfsi_m;
3548 if (0) {
3549 VG_(printf)("found cfsi_m (but printing fake base/len): ");
3550 ML_(ppDiCfSI)(di->cfsi_exprs, 0, 0, cfsi_m);
3553 VG_(bzero_inline)(&uregsPrev, sizeof(uregsPrev));
3555 /* First compute the CFA. */
3556 cfa = compute_cfa(uregsHere,
3557 min_accessible, max_accessible, di, cfsi_m);
3558 if (UNLIKELY(cfa == 0))
3559 return False;
3561 /* Now we know the CFA, use it to roll back the registers we're
3562 interested in. */
3564 # if defined(VGA_mips64) && defined(VGABI_N32)
3565 # define READ_REGISTER(addr) ML_(read_ULong)((addr))
3566 # else
3567 # define READ_REGISTER(addr) ML_(read_Addr)((addr))
3568 # endif
3570 # if defined(VGA_s390x)
3571 const Bool is_s390x = True;
3572 const Addr old_S390X_F0 = uregsHere->f0;
3573 const Addr old_S390X_F1 = uregsHere->f1;
3574 const Addr old_S390X_F2 = uregsHere->f2;
3575 const Addr old_S390X_F3 = uregsHere->f3;
3576 const Addr old_S390X_F4 = uregsHere->f4;
3577 const Addr old_S390X_F5 = uregsHere->f5;
3578 const Addr old_S390X_F6 = uregsHere->f6;
3579 const Addr old_S390X_F7 = uregsHere->f7;
3580 # else
3581 const Bool is_s390x = False;
3582 const Addr old_S390X_F0 = 0;
3583 const Addr old_S390X_F1 = 0;
3584 const Addr old_S390X_F2 = 0;
3585 const Addr old_S390X_F3 = 0;
3586 const Addr old_S390X_F4 = 0;
3587 const Addr old_S390X_F5 = 0;
3588 const Addr old_S390X_F6 = 0;
3589 const Addr old_S390X_F7 = 0;
3590 # endif
3592 # define COMPUTE(_prev, _here, _how, _off) \
3593 do { \
3594 switch (_how) { \
3595 case CFIR_UNKNOWN: \
3596 return False; \
3597 case CFIR_SAME: \
3598 _prev = _here; break; \
3599 case CFIR_MEMCFAREL: { \
3600 Addr a = cfa + (Word)_off; \
3601 if (a < min_accessible \
3602 || a > max_accessible-sizeof(Addr)) \
3603 return False; \
3604 _prev = READ_REGISTER((void *)a); \
3605 break; \
3607 case CFIR_CFAREL: \
3608 _prev = cfa + (Word)_off; \
3609 break; \
3610 case CFIR_EXPR: \
3611 if (0) \
3612 ML_(ppCfiExpr)(di->cfsi_exprs,_off); \
3613 eec.uregs = uregsHere; \
3614 eec.min_accessible = min_accessible; \
3615 eec.max_accessible = max_accessible; \
3616 Bool ok = True; \
3617 _prev = evalCfiExpr(di->cfsi_exprs, _off, &eec, &ok ); \
3618 if (!ok) return False; \
3619 break; \
3620 case CFIR_S390X_F0: \
3621 if (is_s390x) { _prev = old_S390X_F0; break; } \
3622 vg_assert(0+0-0); \
3623 case CFIR_S390X_F1: \
3624 if (is_s390x) { _prev = old_S390X_F1; break; } \
3625 vg_assert(0+1-1); \
3626 case CFIR_S390X_F2: \
3627 if (is_s390x) { _prev = old_S390X_F2; break; } \
3628 vg_assert(0+2-2); \
3629 case CFIR_S390X_F3: \
3630 if (is_s390x) { _prev = old_S390X_F3; break; } \
3631 vg_assert(0+3-3); \
3632 case CFIR_S390X_F4: \
3633 if (is_s390x) { _prev = old_S390X_F4; break; } \
3634 vg_assert(0+4-4); \
3635 case CFIR_S390X_F5: \
3636 if (is_s390x) { _prev = old_S390X_F5; break; } \
3637 vg_assert(0+5-5); \
3638 case CFIR_S390X_F6: \
3639 if (is_s390x) { _prev = old_S390X_F6; break; } \
3640 vg_assert(0+6-6); \
3641 case CFIR_S390X_F7: \
3642 if (is_s390x) { _prev = old_S390X_F7; break; } \
3643 vg_assert(0+7-7); \
3644 default: \
3645 vg_assert(0*0); \
3647 } while (0)
3649 # if defined(VGA_x86) || defined(VGA_amd64)
3650 COMPUTE(uregsPrev.xip, uregsHere->xip, cfsi_m->ra_how, cfsi_m->ra_off);
3651 COMPUTE(uregsPrev.xsp, uregsHere->xsp, cfsi_m->sp_how, cfsi_m->sp_off);
3652 COMPUTE(uregsPrev.xbp, uregsHere->xbp, cfsi_m->bp_how, cfsi_m->bp_off);
3653 # elif defined(VGA_arm)
3654 COMPUTE(uregsPrev.r15, uregsHere->r15, cfsi_m->ra_how, cfsi_m->ra_off);
3655 COMPUTE(uregsPrev.r14, uregsHere->r14, cfsi_m->r14_how, cfsi_m->r14_off);
3656 COMPUTE(uregsPrev.r13, uregsHere->r13, cfsi_m->r13_how, cfsi_m->r13_off);
3657 COMPUTE(uregsPrev.r12, uregsHere->r12, cfsi_m->r12_how, cfsi_m->r12_off);
3658 COMPUTE(uregsPrev.r11, uregsHere->r11, cfsi_m->r11_how, cfsi_m->r11_off);
3659 COMPUTE(uregsPrev.r7, uregsHere->r7, cfsi_m->r7_how, cfsi_m->r7_off);
3660 # elif defined(VGA_s390x)
3661 COMPUTE(uregsPrev.ia, uregsHere->ia, cfsi_m->ra_how, cfsi_m->ra_off);
3662 COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off);
3663 COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi_m->fp_how, cfsi_m->fp_off);
3664 COMPUTE(uregsPrev.f0, uregsHere->f0, cfsi_m->f0_how, cfsi_m->f0_off);
3665 COMPUTE(uregsPrev.f1, uregsHere->f1, cfsi_m->f1_how, cfsi_m->f1_off);
3666 COMPUTE(uregsPrev.f2, uregsHere->f2, cfsi_m->f2_how, cfsi_m->f2_off);
3667 COMPUTE(uregsPrev.f3, uregsHere->f3, cfsi_m->f3_how, cfsi_m->f3_off);
3668 COMPUTE(uregsPrev.f4, uregsHere->f4, cfsi_m->f4_how, cfsi_m->f4_off);
3669 COMPUTE(uregsPrev.f5, uregsHere->f5, cfsi_m->f5_how, cfsi_m->f5_off);
3670 COMPUTE(uregsPrev.f6, uregsHere->f6, cfsi_m->f6_how, cfsi_m->f6_off);
3671 COMPUTE(uregsPrev.f7, uregsHere->f7, cfsi_m->f7_how, cfsi_m->f7_off);
3672 # elif defined(VGA_mips32) || defined(VGA_mips64) || defined(VGA_nanomips)
3673 COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi_m->ra_how, cfsi_m->ra_off);
3674 COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off);
3675 COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi_m->fp_how, cfsi_m->fp_off);
3676 # elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le)
3677 # elif defined(VGP_arm64_linux)
3678 COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi_m->ra_how, cfsi_m->ra_off);
3679 COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off);
3680 COMPUTE(uregsPrev.x30, uregsHere->x30, cfsi_m->x30_how, cfsi_m->x30_off);
3681 COMPUTE(uregsPrev.x29, uregsHere->x29, cfsi_m->x29_how, cfsi_m->x29_off);
3682 # else
3683 # error "Unknown arch"
3684 # endif
3686 # undef READ_REGISTER
3687 # undef COMPUTE
3689 *uregsHere = uregsPrev;
3690 return True;
3694 /*--------------------------------------------------------------*/
3695 /*--- ---*/
3696 /*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/
3697 /*--- MSVC FPO INFO ---*/
3698 /*--- ---*/
3699 /*--------------------------------------------------------------*/
3701 Bool VG_(use_FPO_info) ( /*MOD*/Addr* ipP,
3702 /*MOD*/Addr* spP,
3703 /*MOD*/Addr* fpP,
3704 DiEpoch ep,
3705 Addr min_accessible,
3706 Addr max_accessible )
3708 Word i;
3709 const DebugInfo* di;
3710 FPO_DATA* fpo = NULL;
3711 Addr spHere;
3713 static UWord n_search = 0;
3714 static UWord n_steps = 0;
3715 n_search++;
3717 if (0) VG_(printf)("search FPO for %#lx\n", *ipP);
3719 for (di = debugInfo_list; di != NULL; di = di->next) {
3720 n_steps++;
3722 if (!is_DI_valid_for_epoch(di, ep))
3723 continue;
3725 /* Use the per-DebugInfo summary address ranges to skip
3726 inapplicable DebugInfos quickly. */
3727 if (di->fpo == NULL)
3728 continue;
3729 if (*ipP < di->fpo_minavma || *ipP > di->fpo_maxavma)
3730 continue;
3732 i = ML_(search_one_fpotab)( di, *ipP );
3733 if (i != -1) {
3734 Word j;
3735 if (0) {
3736 /* debug printing only */
3737 VG_(printf)("look for %#lx size %lu i %ld\n",
3738 *ipP, di->fpo_size, i);
3739 for (j = 0; j < di->fpo_size; j++)
3740 VG_(printf)("[%02ld] %#x %u\n",
3741 j, di->fpo[j].ulOffStart, di->fpo[j].cbProcSize);
3743 vg_assert(i >= 0 && i < di->fpo_size);
3744 fpo = &di->fpo[i];
3745 break;
3749 if (fpo == NULL)
3750 return False;
3752 if (0 && ((n_search & 0x7FFFF) == 0))
3753 VG_(printf)("VG_(use_FPO_info): %lu searches, "
3754 "%lu DebugInfos looked at\n",
3755 n_search, n_steps);
3758 /* Start of performance-enhancing hack: once every 64 (chosen
3759 hackily after profiling) successful searches, move the found
3760 DebugInfo one step closer to the start of the list. This makes
3761 future searches cheaper. For starting konqueror on amd64, this
3762 in fact reduces the total amount of searching done by the above
3763 find-the-right-DebugInfo loop by more than a factor of 20. */
3764 if ((n_search & 0x3F) == 0) {
3765 /* Move si one step closer to the start of the list. */
3766 //move_DebugInfo_one_step_forward( di );
3768 /* End of performance-enhancing hack. */
3770 if (0) {
3771 VG_(printf)("found fpo: ");
3772 //ML_(ppFPO)(fpo);
3776 Stack layout is:
3777 %esp->
3778 4*.cbRegs {%edi, %esi, %ebp, %ebx}
3779 4*.cdwLocals
3780 return_pc
3781 4*.cdwParams
3782 prior_%esp->
3784 Typical code looks like:
3785 sub $4*.cdwLocals,%esp
3786 Alternative to above for >=4KB (and sometimes for smaller):
3787 mov $size,%eax
3788 call __chkstk # WinNT performs page-by-page probe!
3789 __chkstk is much like alloc(), except that on return
3790 %eax= 5+ &CALL. Thus it could be used as part of
3791 Position Independent Code to locate the Global Offset Table.
3792 push %ebx
3793 push %ebp
3794 push %esi
3795 Other once-only instructions often scheduled >here<.
3796 push %edi
3798 If the pc is within the first .cbProlog bytes of the function,
3799 then you must disassemble to see how many registers have been pushed,
3800 because instructions in the prolog may be scheduled for performance.
3801 The order of PUSH is always %ebx, %ebp, %esi, %edi, with trailing
3802 registers not pushed when .cbRegs < 4. This seems somewhat strange
3803 because %ebp is the register whose usage you want to minimize,
3804 yet it is in the first half of the PUSH list.
3806 I don't know what happens when the compiler constructs an outgoing CALL.
3807 %esp could move if outgoing parameters are PUSHed, and this affects
3808 traceback for errors during the PUSHes. */
3810 spHere = *spP;
3812 *ipP = ML_(read_Addr)((void *)(spHere + 4*(fpo->cbRegs + fpo->cdwLocals)));
3813 *spP = spHere + 4*(fpo->cbRegs + fpo->cdwLocals + 1
3814 + fpo->cdwParams);
3815 *fpP = ML_(read_Addr)((void *)(spHere + 4*2));
3816 return True;
3819 Bool VG_(FPO_info_present)(void)
3821 const DebugInfo* di;
3822 for (di = debugInfo_list; di != NULL; di = di->next) {
3823 if (di->fpo != NULL)
3824 return True;
3826 return False;
3830 /*--------------------------------------------------------------*/
3831 /*--- ---*/
3832 /*--- TOP LEVEL: GENERATE DESCRIPTION OF DATA ADDRESSES ---*/
3833 /*--- FROM DWARF3 DEBUG INFO ---*/
3834 /*--- ---*/
3835 /*--------------------------------------------------------------*/
3837 /* Try to make p2XA(dst, fmt, args..) turn into
3838 VG_(xaprintf)(dst, fmt, args) without having to resort to
3839 vararg macros. As usual with everything to do with varargs, it's
3840 an ugly hack.
3842 //#define p2XA(dstxa, format, args...)
3843 // VG_(xaprintf)(dstxa, format, ##args)
3845 #define p2XA VG_(xaprintf)
3847 /* Add a zero-terminating byte to DST, which must be an XArray* of
3848 HChar. */
3849 static void zterm_XA ( XArray* dst )
3851 HChar zero = 0;
3852 (void) VG_(addBytesToXA)( dst, &zero, 1 );
3856 /* Evaluate the location expression/list for var, to see whether or
3857 not data_addr falls within the variable. If so also return the
3858 offset of data_addr from the start of the variable. Note that
3859 regs, which supplies ip,sp,fp values, will be NULL for global
3860 variables, and non-NULL for local variables. */
3861 static Bool data_address_is_in_var ( /*OUT*/PtrdiffT* offset,
3862 const XArray* /* TyEnt */ tyents,
3863 const DiVariable* var,
3864 const RegSummary* regs,
3865 Addr data_addr,
3866 const DebugInfo* di )
3868 MaybeULong mul;
3869 SizeT var_szB;
3870 GXResult res;
3871 Bool show = False;
3873 vg_assert(var->name);
3874 vg_assert(var->gexpr);
3876 /* Figure out how big the variable is. */
3877 mul = ML_(sizeOfType)(tyents, var->typeR);
3878 /* If this var has a type whose size is unknown, zero, or
3879 impossibly large, it should never have been added. ML_(addVar)
3880 should have rejected it. */
3881 vg_assert(mul.b == True);
3882 vg_assert(mul.ul > 0);
3883 if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
3884 /* After this point, we assume we can truncate mul.ul to a host word
3885 safely (without loss of info). */
3887 var_szB = (SizeT)mul.ul; /* NB: truncate to host word */
3889 if (show) {
3890 VG_(printf)("VVVV: data_address_%#lx_is_in_var: %s :: ",
3891 data_addr, var->name );
3892 ML_(pp_TyEnt_C_ishly)( tyents, var->typeR );
3893 VG_(printf)("\n");
3896 /* ignore zero-sized vars; they can never match anything. */
3897 if (var_szB == 0) {
3898 if (show)
3899 VG_(printf)("VVVV: -> Fail (variable is zero sized)\n");
3900 return False;
3903 res = ML_(evaluate_GX)( var->gexpr, var->fbGX, regs, di );
3905 if (show) {
3906 VG_(printf)("VVVV: -> ");
3907 ML_(pp_GXResult)( res );
3908 VG_(printf)("\n");
3911 if (res.kind == GXR_Addr
3912 && res.word <= data_addr
3913 && data_addr < res.word + var_szB) {
3914 *offset = data_addr - res.word;
3915 return True;
3916 } else {
3917 return False;
3922 /* Format the acquired information into DN(AME)1 and DN(AME)2, which
3923 are XArray*s of HChar, that have been initialised by the caller.
3924 Resulting strings will be zero terminated. Information is
3925 formatted in an understandable way. Not so easy. If frameNo is
3926 -1, this is assumed to be a global variable; else a local
3927 variable. */
3928 static void format_message ( /*MOD*/XArray* /* of HChar */ dn1,
3929 /*MOD*/XArray* /* of HChar */ dn2,
3930 Addr data_addr,
3931 const DebugInfo* di,
3932 const DiVariable* var,
3933 PtrdiffT var_offset,
3934 PtrdiffT residual_offset,
3935 const XArray* /*HChar*/ described,
3936 Int frameNo,
3937 ThreadId tid )
3939 Bool have_descr, have_srcloc;
3940 Bool xml = VG_(clo_xml);
3941 const HChar* vo_plural = var_offset == 1 ? "" : "s";
3942 const HChar* ro_plural = residual_offset == 1 ? "" : "s";
3943 const HChar* basetag = "auxwhat"; /* a constant */
3944 HChar tagL[32], tagR[32], xagL[32], xagR[32];
3945 const HChar *fileName = ML_(fndn_ix2filename)(di, var->fndn_ix);
3946 // fileName will be "???" if var->fndn_ix == 0.
3947 // fileName will only be used if have_descr is True.
3949 if (frameNo < -1) {
3950 vg_assert(0); /* Not allowed */
3952 else if (frameNo == -1) {
3953 vg_assert(tid == VG_INVALID_THREADID);
3955 else /* (frameNo >= 0) */ {
3956 vg_assert(tid != VG_INVALID_THREADID);
3959 vg_assert(dn1 && dn2);
3960 vg_assert(described);
3961 vg_assert(var && var->name);
3962 have_descr = VG_(sizeXA)(described) > 0
3963 && *(HChar*)VG_(indexXA)(described,0) != '\0';
3964 have_srcloc = var->fndn_ix > 0 && var->lineNo > 0;
3966 tagL[0] = tagR[0] = xagL[0] = xagR[0] = 0;
3967 if (xml) {
3968 VG_(sprintf)(tagL, "<%s>", basetag); // <auxwhat>
3969 VG_(sprintf)(tagR, "</%s>", basetag); // </auxwhat>
3970 VG_(sprintf)(xagL, "<x%s>", basetag); // <xauxwhat>
3971 VG_(sprintf)(xagR, "</x%s>", basetag); // </xauxwhat>
3974 # define TAGL(_xa) p2XA(_xa, "%s", tagL)
3975 # define TAGR(_xa) p2XA(_xa, "%s", tagR)
3976 # define XAGL(_xa) p2XA(_xa, "%s", xagL)
3977 # define XAGR(_xa) p2XA(_xa, "%s", xagR)
3978 # define TXTL(_xa) p2XA(_xa, "%s", "<text>")
3979 # define TXTR(_xa) p2XA(_xa, "%s", "</text>")
3981 /* ------ local cases ------ */
3983 if ( frameNo >= 0 && (!have_srcloc) && (!have_descr) ) {
3984 /* no srcloc, no description:
3985 Location 0x7fefff6cf is 543 bytes inside local var "a",
3986 in frame #1 of thread 1
3988 if (xml) {
3989 TAGL( dn1 );
3990 p2XA( dn1,
3991 "Location 0x%lx is %ld byte%s inside local var \"%pS\",",
3992 data_addr, var_offset, vo_plural, var->name );
3993 TAGR( dn1 );
3994 TAGL( dn2 );
3995 p2XA( dn2,
3996 "in frame #%d of thread %u", frameNo, tid );
3997 TAGR( dn2 );
3998 } else {
3999 p2XA( dn1,
4000 "Location 0x%lx is %ld byte%s inside local var \"%s\",",
4001 data_addr, var_offset, vo_plural, var->name );
4002 p2XA( dn2,
4003 "in frame #%d of thread %u", frameNo, tid );
4006 else
4007 if ( frameNo >= 0 && have_srcloc && (!have_descr) ) {
4008 /* no description:
4009 Location 0x7fefff6cf is 543 bytes inside local var "a"
4010 declared at dsyms7.c:17, in frame #1 of thread 1
4012 if (xml) {
4013 TAGL( dn1 );
4014 p2XA( dn1,
4015 "Location 0x%lx is %ld byte%s inside local var \"%pS\"",
4016 data_addr, var_offset, vo_plural, var->name );
4017 TAGR( dn1 );
4018 XAGL( dn2 );
4019 TXTL( dn2 );
4020 p2XA( dn2,
4021 "declared at %pS:%d, in frame #%d of thread %u",
4022 fileName, var->lineNo, frameNo, tid );
4023 TXTR( dn2 );
4024 // FIXME: also do <dir>
4025 p2XA( dn2,
4026 " <file>%pS</file> <line>%d</line> ",
4027 fileName, var->lineNo );
4028 XAGR( dn2 );
4029 } else {
4030 p2XA( dn1,
4031 "Location 0x%lx is %ld byte%s inside local var \"%s\"",
4032 data_addr, var_offset, vo_plural, var->name );
4033 p2XA( dn2,
4034 "declared at %s:%d, in frame #%d of thread %u",
4035 fileName, var->lineNo, frameNo, tid );
4038 else
4039 if ( frameNo >= 0 && (!have_srcloc) && have_descr ) {
4040 /* no srcloc:
4041 Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2
4042 in frame #1 of thread 1
4044 if (xml) {
4045 TAGL( dn1 );
4046 p2XA( dn1,
4047 "Location 0x%lx is %ld byte%s inside %pS%pS",
4048 data_addr, residual_offset, ro_plural, var->name,
4049 (HChar*)(VG_(indexXA)(described,0)) );
4050 TAGR( dn1 );
4051 TAGL( dn2 );
4052 p2XA( dn2,
4053 "in frame #%d of thread %u", frameNo, tid );
4054 TAGR( dn2 );
4055 } else {
4056 p2XA( dn1,
4057 "Location 0x%lx is %ld byte%s inside %s%s",
4058 data_addr, residual_offset, ro_plural, var->name,
4059 (HChar*)(VG_(indexXA)(described,0)) );
4060 p2XA( dn2,
4061 "in frame #%d of thread %u", frameNo, tid );
4064 else
4065 if ( frameNo >= 0 && have_srcloc && have_descr ) {
4066 /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
4067 declared at dsyms7.c:17, in frame #1 of thread 1 */
4068 if (xml) {
4069 TAGL( dn1 );
4070 p2XA( dn1,
4071 "Location 0x%lx is %ld byte%s inside %pS%pS,",
4072 data_addr, residual_offset, ro_plural, var->name,
4073 (HChar*)(VG_(indexXA)(described,0)) );
4074 TAGR( dn1 );
4075 XAGL( dn2 );
4076 TXTL( dn2 );
4077 p2XA( dn2,
4078 "declared at %pS:%d, in frame #%d of thread %u",
4079 fileName, var->lineNo, frameNo, tid );
4080 TXTR( dn2 );
4081 // FIXME: also do <dir>
4082 p2XA( dn2,
4083 " <file>%pS</file> <line>%d</line> ",
4084 fileName, var->lineNo );
4085 XAGR( dn2 );
4086 } else {
4087 p2XA( dn1,
4088 "Location 0x%lx is %ld byte%s inside %s%s,",
4089 data_addr, residual_offset, ro_plural, var->name,
4090 (HChar*)(VG_(indexXA)(described,0)) );
4091 p2XA( dn2,
4092 "declared at %s:%d, in frame #%d of thread %u",
4093 fileName, var->lineNo, frameNo, tid );
4096 else
4097 /* ------ global cases ------ */
4098 if ( frameNo >= -1 && (!have_srcloc) && (!have_descr) ) {
4099 /* no srcloc, no description:
4100 Location 0x7fefff6cf is 543 bytes inside global var "a"
4102 if (xml) {
4103 TAGL( dn1 );
4104 p2XA( dn1,
4105 "Location 0x%lx is %ld byte%s inside global var \"%pS\"",
4106 data_addr, var_offset, vo_plural, var->name );
4107 TAGR( dn1 );
4108 } else {
4109 p2XA( dn1,
4110 "Location 0x%lx is %ld byte%s inside global var \"%s\"",
4111 data_addr, var_offset, vo_plural, var->name );
4114 else
4115 if ( frameNo >= -1 && have_srcloc && (!have_descr) ) {
4116 /* no description:
4117 Location 0x7fefff6cf is 543 bytes inside global var "a"
4118 declared at dsyms7.c:17
4120 if (xml) {
4121 TAGL( dn1 );
4122 p2XA( dn1,
4123 "Location 0x%lx is %ld byte%s inside global var \"%pS\"",
4124 data_addr, var_offset, vo_plural, var->name );
4125 TAGR( dn1 );
4126 XAGL( dn2 );
4127 TXTL( dn2 );
4128 p2XA( dn2,
4129 "declared at %pS:%d",
4130 fileName, var->lineNo);
4131 TXTR( dn2 );
4132 // FIXME: also do <dir>
4133 p2XA( dn2,
4134 " <file>%pS</file> <line>%d</line> ",
4135 fileName, var->lineNo );
4136 XAGR( dn2 );
4137 } else {
4138 p2XA( dn1,
4139 "Location 0x%lx is %ld byte%s inside global var \"%s\"",
4140 data_addr, var_offset, vo_plural, var->name );
4141 p2XA( dn2,
4142 "declared at %s:%d",
4143 fileName, var->lineNo);
4146 else
4147 if ( frameNo >= -1 && (!have_srcloc) && have_descr ) {
4148 /* no srcloc:
4149 Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
4150 a global variable
4152 if (xml) {
4153 TAGL( dn1 );
4154 p2XA( dn1,
4155 "Location 0x%lx is %ld byte%s inside %pS%pS,",
4156 data_addr, residual_offset, ro_plural, var->name,
4157 (HChar*)(VG_(indexXA)(described,0)) );
4158 TAGR( dn1 );
4159 TAGL( dn2 );
4160 p2XA( dn2,
4161 "a global variable");
4162 TAGR( dn2 );
4163 } else {
4164 p2XA( dn1,
4165 "Location 0x%lx is %ld byte%s inside %s%s,",
4166 data_addr, residual_offset, ro_plural, var->name,
4167 (HChar*)(VG_(indexXA)(described,0)) );
4168 p2XA( dn2,
4169 "a global variable");
4172 else
4173 if ( frameNo >= -1 && have_srcloc && have_descr ) {
4174 /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
4175 a global variable declared at dsyms7.c:17 */
4176 if (xml) {
4177 TAGL( dn1 );
4178 p2XA( dn1,
4179 "Location 0x%lx is %ld byte%s inside %pS%pS,",
4180 data_addr, residual_offset, ro_plural, var->name,
4181 (HChar*)(VG_(indexXA)(described,0)) );
4182 TAGR( dn1 );
4183 XAGL( dn2 );
4184 TXTL( dn2 );
4185 p2XA( dn2,
4186 "a global variable declared at %pS:%d",
4187 fileName, var->lineNo);
4188 TXTR( dn2 );
4189 // FIXME: also do <dir>
4190 p2XA( dn2,
4191 " <file>%pS</file> <line>%d</line> ",
4192 fileName, var->lineNo );
4193 XAGR( dn2 );
4194 } else {
4195 p2XA( dn1,
4196 "Location 0x%lx is %ld byte%s inside %s%s,",
4197 data_addr, residual_offset, ro_plural, var->name,
4198 (HChar*)(VG_(indexXA)(described,0)) );
4199 p2XA( dn2,
4200 "a global variable declared at %s:%d",
4201 fileName, var->lineNo);
4204 else
4205 vg_assert(0);
4207 /* Zero terminate both strings */
4208 zterm_XA( dn1 );
4209 zterm_XA( dn2 );
4211 # undef TAGL
4212 # undef TAGR
4213 # undef XAGL
4214 # undef XAGR
4215 # undef TXTL
4216 # undef TXTR
4220 /* Determine if data_addr is a local variable in the frame
4221 characterised by (ip,sp,fp), and if so write its description at the
4222 ends of DNAME{1,2}, which are XArray*s of HChar, that have been
4223 initialised by the caller, zero terminate both, and return True.
4224 If it's not a local variable in said frame, return False. */
4225 static
4226 Bool consider_vars_in_frame ( /*MOD*/XArray* /* of HChar */ dname1,
4227 /*MOD*/XArray* /* of HChar */ dname2,
4228 DiEpoch ep,
4229 Addr data_addr,
4230 Addr ip, Addr sp, Addr fp,
4231 /* shown to user: */
4232 ThreadId tid, Int frameNo )
4234 Word i;
4235 DebugInfo* di;
4236 RegSummary regs;
4237 Bool debug = False;
4239 static UInt n_search = 0;
4240 static UInt n_steps = 0;
4241 n_search++;
4242 if (debug)
4243 VG_(printf)("QQQQ: cvif: ip,sp,fp %#lx,%#lx,%#lx\n", ip,sp,fp);
4244 /* first, find the DebugInfo that pertains to 'ip'. */
4245 for (di = debugInfo_list; di; di = di->next) {
4246 n_steps++;
4247 if (!is_DI_valid_for_epoch(di, ep))
4248 continue;
4249 /* text segment missing? unlikely, but handle it .. */
4250 if (!di->text_present || di->text_size == 0)
4251 continue;
4252 /* Ok. So does this text mapping bracket the ip? */
4253 if (di->text_avma <= ip && ip < di->text_avma + di->text_size)
4254 break;
4257 /* Didn't find it. Strange -- means ip is a code address outside
4258 of any mapped text segment. Unlikely but not impossible -- app
4259 could be generating code to run. */
4260 if (!di)
4261 return False;
4263 if (0 && ((n_search & 0x1) == 0))
4264 VG_(printf)("consider_vars_in_frame: %u searches, "
4265 "%u DebugInfos looked at\n",
4266 n_search, n_steps);
4267 /* Start of performance-enhancing hack: once every ??? (chosen
4268 hackily after profiling) successful searches, move the found
4269 DebugInfo one step closer to the start of the list. This makes
4270 future searches cheaper. */
4271 if ((n_search & 0xFFFF) == 0) {
4272 /* Move si one step closer to the start of the list. */
4273 move_DebugInfo_one_step_forward( di );
4275 /* End of performance-enhancing hack. */
4277 /* any var info at all? */
4278 if (!di->varinfo)
4279 return False;
4281 /* Work through the scopes from most deeply nested outwards,
4282 looking for code address ranges that bracket 'ip'. The
4283 variables on each such address range found are in scope right
4284 now. Don't descend to level zero as that is the global
4285 scope. */
4286 regs.ip = ip;
4287 regs.sp = sp;
4288 regs.fp = fp;
4290 /* "for each scope, working outwards ..." */
4291 for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) {
4292 XArray* vars;
4293 Word j;
4294 DiAddrRange* arange;
4295 OSet* this_scope
4296 = *(OSet**)VG_(indexXA)( di->varinfo, i );
4297 if (debug)
4298 VG_(printf)("QQQQ: considering scope %ld\n", (Word)i);
4299 if (!this_scope)
4300 continue;
4301 /* Find the set of variables in this scope that
4302 bracket the program counter. */
4303 arange = VG_(OSetGen_LookupWithCmp)(
4304 this_scope, &ip,
4305 ML_(cmp_for_DiAddrRange_range)
4307 if (!arange)
4308 continue;
4309 /* stay sane */
4310 vg_assert(arange->aMin <= arange->aMax);
4311 /* It must bracket the ip we asked for, else
4312 ML_(cmp_for_DiAddrRange_range) is somehow broken. */
4313 vg_assert(arange->aMin <= ip && ip <= arange->aMax);
4314 /* It must have an attached XArray of DiVariables. */
4315 vars = arange->vars;
4316 vg_assert(vars);
4317 /* But it mustn't cover the entire address range. We only
4318 expect that to happen for the global scope (level 0), which
4319 we're not looking at here. Except, it may cover the entire
4320 address range, but in that case the vars array must be
4321 empty. */
4322 vg_assert(! (arange->aMin == (Addr)0
4323 && arange->aMax == ~(Addr)0
4324 && VG_(sizeXA)(vars) > 0) );
4325 for (j = 0; j < VG_(sizeXA)( vars ); j++) {
4326 DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j );
4327 PtrdiffT offset;
4328 if (debug)
4329 VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n",
4330 var->name,arange->aMin,arange->aMax,ip);
4331 if (data_address_is_in_var( &offset, di->admin_tyents,
4332 var, &regs,
4333 data_addr, di )) {
4334 PtrdiffT residual_offset = 0;
4335 XArray* described = ML_(describe_type)( &residual_offset,
4336 di->admin_tyents,
4337 var->typeR, offset );
4338 format_message( dname1, dname2,
4339 data_addr, di, var, offset, residual_offset,
4340 described, frameNo, tid );
4341 VG_(deleteXA)( described );
4342 return True;
4347 return False;
4350 /* Try to form some description of DATA_ADDR by looking at the DWARF3
4351 debug info we have. This considers all global variables, and 8
4352 frames in the stacks of all threads. Result is written at the ends
4353 of DNAME{1,2}V, which are XArray*s of HChar, that have been
4354 initialised by the caller, and True is returned. If no description
4355 is created, False is returned. Regardless of the return value,
4356 DNAME{1,2}V are guaranteed to be zero terminated after the call.
4358 Note that after the call, DNAME{1,2} may have more than one
4359 trailing zero, so callers should establish the useful text length
4360 using VG_(strlen) on the contents, rather than VG_(sizeXA) on the
4361 XArray itself.
4363 Bool VG_(get_data_description)(
4364 /*MOD*/ XArray* /* of HChar */ dname1,
4365 /*MOD*/ XArray* /* of HChar */ dname2,
4366 DiEpoch ep, Addr data_addr
4369 # define N_FRAMES 8
4370 Addr ips[N_FRAMES], sps[N_FRAMES], fps[N_FRAMES];
4371 UInt n_frames;
4373 Addr stack_min, stack_max;
4374 ThreadId tid;
4375 Bool found;
4376 DebugInfo* di;
4377 Word j;
4379 if (0) VG_(printf)("get_data_description: dataaddr %#lx\n", data_addr);
4380 /* First, see if data_addr is (or is part of) a global variable.
4381 Loop over the DebugInfos we have. Check data_addr against the
4382 outermost scope of all of them, as that should be a global
4383 scope. */
4384 for (di = debugInfo_list; di != NULL; di = di->next) {
4385 OSet* global_scope;
4386 Word gs_size;
4387 Addr zero;
4388 DiAddrRange* global_arange;
4389 Word i;
4390 XArray* vars;
4392 /* text segment missing? unlikely, but handle it .. */
4393 if (!di->text_present || di->text_size == 0)
4394 continue;
4395 /* any var info at all? */
4396 if (!di->varinfo)
4397 continue;
4398 /* perhaps this object didn't contribute any vars at all? */
4399 if (VG_(sizeXA)( di->varinfo ) == 0)
4400 continue;
4401 global_scope = *(OSet**)VG_(indexXA)( di->varinfo, 0 );
4402 vg_assert(global_scope);
4403 gs_size = VG_(OSetGen_Size)( global_scope );
4404 /* The global scope might be completely empty if this
4405 compilation unit declared locals but nothing global. */
4406 if (gs_size == 0)
4407 continue;
4408 /* But if it isn't empty, then it must contain exactly one
4409 element, which covers the entire address range. */
4410 vg_assert(gs_size == 1);
4411 /* Fish out the global scope and check it is as expected. */
4412 zero = 0;
4413 global_arange
4414 = VG_(OSetGen_Lookup)( global_scope, &zero );
4415 /* The global range from (Addr)0 to ~(Addr)0 must exist */
4416 vg_assert(global_arange);
4417 vg_assert(global_arange->aMin == (Addr)0
4418 && global_arange->aMax == ~(Addr)0);
4419 /* Any vars in this range? */
4420 if (!global_arange->vars)
4421 continue;
4422 /* Ok, there are some vars in the global scope of this
4423 DebugInfo. Wade through them and see if the data addresses
4424 of any of them bracket data_addr. */
4425 vars = global_arange->vars;
4426 for (i = 0; i < VG_(sizeXA)( vars ); i++) {
4427 PtrdiffT offset;
4428 DiVariable* var = (DiVariable*)VG_(indexXA)( vars, i );
4429 vg_assert(var->name);
4430 /* Note we use a NULL RegSummary* here. It can't make any
4431 sense for a global variable to have a location expression
4432 which depends on a SP/FP/IP value. So don't supply any.
4433 This means, if the evaluation of the location
4434 expression/list requires a register, we have to let it
4435 fail. */
4436 if (data_address_is_in_var( &offset, di->admin_tyents, var,
4437 NULL/* RegSummary* */,
4438 data_addr, di )) {
4439 PtrdiffT residual_offset = 0;
4440 XArray* described = ML_(describe_type)( &residual_offset,
4441 di->admin_tyents,
4442 var->typeR, offset );
4443 format_message( dname1, dname2,
4444 data_addr, di, var, offset, residual_offset,
4445 described, -1/*frameNo*/,
4446 VG_INVALID_THREADID );
4447 VG_(deleteXA)( described );
4448 zterm_XA( dname1 );
4449 zterm_XA( dname2 );
4450 return True;
4455 /* Ok, well it's not a global variable. So now let's snoop around
4456 in the stacks of all the threads. First try to figure out which
4457 thread's stack data_addr is in. */
4459 /* Perhaps it's on a thread's stack? */
4460 found = False;
4461 VG_(thread_stack_reset_iter)(&tid);
4462 while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) {
4463 if (stack_min >= stack_max)
4464 continue; /* ignore obviously stupid cases */
4465 if (stack_min - VG_STACK_REDZONE_SZB <= data_addr
4466 && data_addr <= stack_max) {
4467 found = True;
4468 break;
4471 if (!found) {
4472 zterm_XA( dname1 );
4473 zterm_XA( dname2 );
4474 return False;
4477 /* We conclude data_addr is in thread tid's stack. Unwind the
4478 stack to get a bunch of (ip,sp,fp) triples describing the
4479 frames, and for each frame, consider the local variables. */
4480 n_frames = VG_(get_StackTrace)( tid, ips, N_FRAMES,
4481 sps, fps, 0/*first_ip_delta*/ );
4483 vg_assert(n_frames >= 0 && n_frames <= N_FRAMES);
4484 for (j = 0; j < n_frames; j++) {
4485 if (consider_vars_in_frame( dname1, dname2,
4486 ep, data_addr,
4487 ips[j],
4488 sps[j], fps[j], tid, j )) {
4489 zterm_XA( dname1 );
4490 zterm_XA( dname2 );
4491 return True;
4493 /* Now, it appears that gcc sometimes appears to produce
4494 location lists whose ranges don't actually cover the call
4495 instruction, even though the address of the variable in
4496 question is passed as a parameter in the call. AFAICS this
4497 is simply a bug in gcc - how can the variable be claimed not
4498 exist in memory (on the stack) for the duration of a call in
4499 which its address is passed? But anyway, in the particular
4500 case I investigated (memcheck/tests/varinfo6.c, call to croak
4501 on line 2999, local var budget declared at line 3115
4502 appearing not to exist across the call to mainSort on line
4503 3143, "gcc.orig (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2)" on
4504 amd64), the variable's location list does claim it exists
4505 starting at the first byte of the first instruction after the
4506 call instruction. So, call consider_vars_in_frame a second
4507 time, but this time add 1 to the IP. GDB handles this
4508 example with no difficulty, which leads me to believe that
4509 either (1) I misunderstood something, or (2) GDB has an
4510 equivalent kludge. */
4511 if (j > 0 /* this is a non-innermost frame */
4512 && consider_vars_in_frame( dname1, dname2,
4513 ep, data_addr,
4514 ips[j] + 1,
4515 sps[j], fps[j], tid, j )) {
4516 zterm_XA( dname1 );
4517 zterm_XA( dname2 );
4518 return True;
4522 /* We didn't find anything useful. */
4523 zterm_XA( dname1 );
4524 zterm_XA( dname2 );
4525 return False;
4526 # undef N_FRAMES
4530 //////////////////////////////////////////////////////////////////
4531 // //
4532 // Support for other kinds of queries to the Dwarf3 var info //
4533 // //
4534 //////////////////////////////////////////////////////////////////
4536 /* Figure out if the variable 'var' has a location that is linearly
4537 dependent on a stack pointer value, or a frame pointer value, and
4538 if it is, add a description of it to 'blocks'. Otherwise ignore
4539 it. If 'arrays_only' is True, also ignore it unless it has an
4540 array type. */
4542 static
4543 void analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks,
4544 const XArray* /* TyEnt */ tyents,
4545 Addr ip, const DebugInfo* di, const DiVariable* var,
4546 Bool arrays_only )
4548 GXResult res_sp_6k, res_sp_7k, res_fp_6k, res_fp_7k;
4549 RegSummary regs;
4550 MaybeULong mul;
4551 Bool isVec;
4552 TyEnt* ty;
4554 Bool debug = False;
4555 if (0&&debug)
4556 VG_(printf)("adeps: var %s\n", var->name );
4558 /* Figure out how big the variable is. */
4559 mul = ML_(sizeOfType)(tyents, var->typeR);
4560 /* If this var has a type whose size is unknown, zero, or
4561 impossibly large, it should never have been added. ML_(addVar)
4562 should have rejected it. */
4563 vg_assert(mul.b == True);
4564 vg_assert(mul.ul > 0);
4565 if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
4566 /* After this point, we assume we can truncate mul.ul to a host word
4567 safely (without loss of info). */
4569 /* skip if non-array and we're only interested in arrays */
4570 ty = ML_(TyEnts__index_by_cuOff)( tyents, NULL, var->typeR );
4571 vg_assert(ty);
4572 vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty));
4573 if (ty->tag == Te_UNKNOWN)
4574 return; /* perhaps we should complain in this case? */
4575 isVec = ty->tag == Te_TyArray;
4576 if (arrays_only && !isVec)
4577 return;
4579 if (0) {ML_(pp_TyEnt_C_ishly)(tyents, var->typeR);
4580 VG_(printf)(" %s\n", var->name);}
4582 /* Do some test evaluations of the variable's location expression,
4583 in order to guess whether it is sp-relative, fp-relative, or
4584 none. A crude hack, which can be interpreted roughly as finding
4585 the first derivative of the location expression w.r.t. the
4586 supplied frame and stack pointer values. */
4587 regs.fp = 0;
4588 regs.ip = ip;
4589 regs.sp = 6 * 1024;
4590 res_sp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
4592 regs.fp = 0;
4593 regs.ip = ip;
4594 regs.sp = 7 * 1024;
4595 res_sp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
4597 regs.fp = 6 * 1024;
4598 regs.ip = ip;
4599 regs.sp = 0;
4600 res_fp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
4602 regs.fp = 7 * 1024;
4603 regs.ip = ip;
4604 regs.sp = 0;
4605 res_fp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
4607 vg_assert(res_sp_6k.kind == res_sp_7k.kind);
4608 vg_assert(res_sp_6k.kind == res_fp_6k.kind);
4609 vg_assert(res_sp_6k.kind == res_fp_7k.kind);
4611 if (res_sp_6k.kind == GXR_Addr) {
4612 StackBlock block;
4613 GXResult res;
4614 UWord sp_delta = res_sp_7k.word - res_sp_6k.word;
4615 UWord fp_delta = res_fp_7k.word - res_fp_6k.word;
4616 vg_assert(sp_delta == 0 || sp_delta == 1024);
4617 vg_assert(fp_delta == 0 || fp_delta == 1024);
4619 if (sp_delta == 0 && fp_delta == 0) {
4620 /* depends neither on sp nor fp, so it can't be a stack
4621 local. Ignore it. */
4623 else
4624 if (sp_delta == 1024 && fp_delta == 0) {
4625 regs.sp = regs.fp = 0;
4626 regs.ip = ip;
4627 res = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
4628 vg_assert(res.kind == GXR_Addr);
4629 if (debug)
4630 VG_(printf)(" %5lu .. %5llu (sp) %s\n",
4631 res.word, res.word + mul.ul - 1, var->name);
4632 block.base = res.word;
4633 block.szB = (SizeT)mul.ul;
4634 block.spRel = True;
4635 block.isVec = isVec;
4636 VG_(memset)( &block.name[0], 0, sizeof(block.name) );
4637 if (var->name)
4638 VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 );
4639 block.name[ sizeof(block.name)-1 ] = 0;
4640 VG_(addToXA)( blocks, &block );
4642 else
4643 if (sp_delta == 0 && fp_delta == 1024) {
4644 regs.sp = regs.fp = 0;
4645 regs.ip = ip;
4646 res = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
4647 vg_assert(res.kind == GXR_Addr);
4648 if (debug)
4649 VG_(printf)(" %5lu .. %5llu (FP) %s\n",
4650 res.word, res.word + mul.ul - 1, var->name);
4651 block.base = res.word;
4652 block.szB = (SizeT)mul.ul;
4653 block.spRel = False;
4654 block.isVec = isVec;
4655 VG_(memset)( &block.name[0], 0, sizeof(block.name) );
4656 if (var->name)
4657 VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 );
4658 block.name[ sizeof(block.name)-1 ] = 0;
4659 VG_(addToXA)( blocks, &block );
4661 else {
4662 vg_assert(0);
4668 /* Get an XArray of StackBlock which describe the stack (auto) blocks
4669 for this ip. The caller is expected to free the XArray at some
4670 point. If 'arrays_only' is True, only array-typed blocks are
4671 returned; otherwise blocks of all types are returned. */
4673 XArray* /* of StackBlock */
4674 VG_(di_get_stack_blocks_at_ip)( Addr ip, Bool arrays_only )
4676 /* This is a derivation of consider_vars_in_frame() above. */
4677 Word i;
4678 DebugInfo* di;
4679 Bool debug = False;
4681 XArray* res = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dgsbai.1",
4682 ML_(dinfo_free),
4683 sizeof(StackBlock) );
4685 static UInt n_search = 0;
4686 static UInt n_steps = 0;
4687 n_search++;
4688 if (debug)
4689 VG_(printf)("QQQQ: dgsbai: ip %#lx\n", ip);
4690 /* first, find the DebugInfo that pertains to 'ip'. */
4691 for (di = debugInfo_list; di; di = di->next) {
4692 n_steps++;
4693 /* text segment missing? unlikely, but handle it .. */
4694 if (!di->text_present || di->text_size == 0)
4695 continue;
4696 /* Ok. So does this text mapping bracket the ip? */
4697 if (di->text_avma <= ip && ip < di->text_avma + di->text_size)
4698 break;
4701 /* Didn't find it. Strange -- means ip is a code address outside
4702 of any mapped text segment. Unlikely but not impossible -- app
4703 could be generating code to run. */
4704 if (!di)
4705 return res; /* currently empty */
4707 if (0 && ((n_search & 0x1) == 0))
4708 VG_(printf)("VG_(di_get_stack_blocks_at_ip): %u searches, "
4709 "%u DebugInfos looked at\n",
4710 n_search, n_steps);
4711 /* Start of performance-enhancing hack: once every ??? (chosen
4712 hackily after profiling) successful searches, move the found
4713 DebugInfo one step closer to the start of the list. This makes
4714 future searches cheaper. */
4715 if ((n_search & 0xFFFF) == 0) {
4716 /* Move si one step closer to the start of the list. */
4717 move_DebugInfo_one_step_forward( di );
4719 /* End of performance-enhancing hack. */
4721 /* any var info at all? */
4722 if (!di->varinfo)
4723 return res; /* currently empty */
4725 /* Work through the scopes from most deeply nested outwards,
4726 looking for code address ranges that bracket 'ip'. The
4727 variables on each such address range found are in scope right
4728 now. Don't descend to level zero as that is the global
4729 scope. */
4731 /* "for each scope, working outwards ..." */
4732 for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) {
4733 XArray* vars;
4734 Word j;
4735 DiAddrRange* arange;
4736 OSet* this_scope
4737 = *(OSet**)VG_(indexXA)( di->varinfo, i );
4738 if (debug)
4739 VG_(printf)("QQQQ: considering scope %ld\n", (Word)i);
4740 if (!this_scope)
4741 continue;
4742 /* Find the set of variables in this scope that
4743 bracket the program counter. */
4744 arange = VG_(OSetGen_LookupWithCmp)(
4745 this_scope, &ip,
4746 ML_(cmp_for_DiAddrRange_range)
4748 if (!arange)
4749 continue;
4750 /* stay sane */
4751 vg_assert(arange->aMin <= arange->aMax);
4752 /* It must bracket the ip we asked for, else
4753 ML_(cmp_for_DiAddrRange_range) is somehow broken. */
4754 vg_assert(arange->aMin <= ip && ip <= arange->aMax);
4755 /* It must have an attached XArray of DiVariables. */
4756 vars = arange->vars;
4757 vg_assert(vars);
4758 /* But it mustn't cover the entire address range. We only
4759 expect that to happen for the global scope (level 0), which
4760 we're not looking at here. Except, it may cover the entire
4761 address range, but in that case the vars array must be
4762 empty. */
4763 vg_assert(! (arange->aMin == (Addr)0
4764 && arange->aMax == ~(Addr)0
4765 && VG_(sizeXA)(vars) > 0) );
4766 for (j = 0; j < VG_(sizeXA)( vars ); j++) {
4767 DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j );
4768 if (debug)
4769 VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n",
4770 var->name,arange->aMin,arange->aMax,ip);
4771 analyse_deps( res, di->admin_tyents, ip,
4772 di, var, arrays_only );
4776 return res;
4780 /* Get an array of GlobalBlock which describe the global blocks owned
4781 by the shared object characterised by the given di_handle. Asserts
4782 if the handle is invalid. The caller is responsible for freeing
4783 the array at some point. If 'arrays_only' is True, only
4784 array-typed blocks are returned; otherwise blocks of all types are
4785 returned. */
4787 XArray* /* of GlobalBlock */
4788 VG_(di_get_global_blocks_from_dihandle) ( ULong di_handle, Bool arrays_only )
4790 /* This is a derivation of consider_vars_in_frame() above. */
4792 DebugInfo* di;
4793 XArray* gvars; /* XArray* of GlobalBlock */
4794 Word nScopes, scopeIx;
4796 /* The first thing to do is find the DebugInfo that
4797 pertains to 'di_handle'. */
4798 vg_assert(di_handle > 0);
4799 for (di = debugInfo_list; di; di = di->next) {
4800 if (di->handle == di_handle)
4801 break;
4804 /* If this fails, we were unable to find any DebugInfo with the
4805 given handle. This is considered an error on the part of the
4806 caller. */
4807 vg_assert(di != NULL);
4809 /* we'll put the collected variables in here. */
4810 gvars = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dggbfd.1",
4811 ML_(dinfo_free), sizeof(GlobalBlock) );
4813 /* any var info at all? */
4814 if (!di->varinfo)
4815 return gvars;
4817 /* we'll iterate over all the variables we can find, even if
4818 it seems senseless to visit stack-allocated variables */
4819 /* Iterate over all scopes */
4820 nScopes = VG_(sizeXA)( di->varinfo );
4821 for (scopeIx = 0; scopeIx < nScopes; scopeIx++) {
4823 /* Iterate over each (code) address range at the current scope */
4824 DiAddrRange* range;
4825 OSet* /* of DiAddrInfo */ scope
4826 = *(OSet**)VG_(indexXA)( di->varinfo, scopeIx );
4827 vg_assert(scope);
4828 VG_(OSetGen_ResetIter)(scope);
4829 while ( (range = VG_(OSetGen_Next)(scope)) ) {
4831 /* Iterate over each variable in the current address range */
4832 Word nVars, varIx;
4833 vg_assert(range->vars);
4834 nVars = VG_(sizeXA)( range->vars );
4835 for (varIx = 0; varIx < nVars; varIx++) {
4837 Bool isVec;
4838 GXResult res;
4839 MaybeULong mul;
4840 GlobalBlock gb;
4841 TyEnt* ty;
4842 DiVariable* var = VG_(indexXA)( range->vars, varIx );
4843 vg_assert(var->name);
4844 if (0) VG_(printf)("at depth %ld var %s ", scopeIx, var->name );
4846 /* Now figure out if this variable has a constant address
4847 (that is, independent of FP, SP, phase of moon, etc),
4848 and if so, what the address is. Any variable with a
4849 constant address is deemed to be a global so we collect
4850 it. */
4851 if (0) { VG_(printf)("EVAL: "); ML_(pp_GX)(var->gexpr);
4852 VG_(printf)("\n"); }
4853 res = ML_(evaluate_trivial_GX)( var->gexpr, di );
4855 /* Not a constant address => not interesting */
4856 if (res.kind != GXR_Addr) {
4857 if (0) VG_(printf)("FAIL\n");
4858 continue;
4861 /* Ok, it's a constant address. See if we want to collect
4862 it. */
4863 if (0) VG_(printf)("%#lx\n", res.word);
4865 /* Figure out how big the variable is. */
4866 mul = ML_(sizeOfType)(di->admin_tyents, var->typeR);
4868 /* If this var has a type whose size is unknown, zero, or
4869 impossibly large, it should never have been added.
4870 ML_(addVar) should have rejected it. */
4871 vg_assert(mul.b == True);
4872 vg_assert(mul.ul > 0);
4873 if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
4874 /* After this point, we assume we can truncate mul.ul to a
4875 host word safely (without loss of info). */
4877 /* skip if non-array and we're only interested in
4878 arrays */
4879 ty = ML_(TyEnts__index_by_cuOff)( di->admin_tyents, NULL,
4880 var->typeR );
4881 vg_assert(ty);
4882 vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty));
4883 if (ty->tag == Te_UNKNOWN)
4884 continue; /* perhaps we should complain in this case? */
4886 isVec = ty->tag == Te_TyArray;
4887 if (arrays_only && !isVec) continue;
4889 /* Ok, so collect it! */
4890 vg_assert(var->name);
4891 vg_assert(di->soname);
4892 if (0) VG_(printf)("XXXX %s %s %d\n", var->name,
4893 ML_(fndn_ix2filename)(di, var->fndn_ix),
4894 var->lineNo);
4895 VG_(memset)(&gb, 0, sizeof(gb));
4896 gb.addr = res.word;
4897 gb.szB = (SizeT)mul.ul;
4898 gb.isVec = isVec;
4899 VG_(strncpy)(&gb.name[0], var->name, sizeof(gb.name)-1);
4900 VG_(strncpy)(&gb.soname[0], di->soname, sizeof(gb.soname)-1);
4901 vg_assert(gb.name[ sizeof(gb.name)-1 ] == 0);
4902 vg_assert(gb.soname[ sizeof(gb.soname)-1 ] == 0);
4904 VG_(addToXA)( gvars, &gb );
4906 } /* for (varIx = 0; varIx < nVars; varIx++) */
4908 } /* while ( (range = VG_(OSetGen_Next)(scope)) ) */
4910 } /* for (scopeIx = 0; scopeIx < nScopes; scopeIx++) */
4912 return gvars;
4916 /*------------------------------------------------------------*/
4917 /*--- DebugInfo accessor functions ---*/
4918 /*------------------------------------------------------------*/
4920 const DebugInfo* VG_(next_DebugInfo)(const DebugInfo* di)
4922 if (di == NULL)
4923 return debugInfo_list;
4924 return di->next;
4927 Addr VG_(DebugInfo_get_text_avma)(const DebugInfo* di)
4929 return di->text_present ? di->text_avma : 0;
4932 SizeT VG_(DebugInfo_get_text_size)(const DebugInfo* di)
4934 return di->text_present ? di->text_size : 0;
4937 Addr VG_(DebugInfo_get_bss_avma)(const DebugInfo* di)
4939 return di->bss_present ? di->bss_avma : 0;
4942 SizeT VG_(DebugInfo_get_bss_size)(const DebugInfo* di)
4944 return di->bss_present ? di->bss_size : 0;
4947 Addr VG_(DebugInfo_get_plt_avma)(const DebugInfo* di)
4949 return di->plt_present ? di->plt_avma : 0;
4952 SizeT VG_(DebugInfo_get_plt_size)(const DebugInfo* di)
4954 return di->plt_present ? di->plt_size : 0;
4957 Addr VG_(DebugInfo_get_gotplt_avma)(const DebugInfo* di)
4959 return di->gotplt_present ? di->gotplt_avma : 0;
4962 SizeT VG_(DebugInfo_get_gotplt_size)(const DebugInfo* di)
4964 return di->gotplt_present ? di->gotplt_size : 0;
4967 Addr VG_(DebugInfo_get_got_avma)(const DebugInfo* di)
4969 return di->got_present ? di->got_avma : 0;
4972 SizeT VG_(DebugInfo_get_got_size)(const DebugInfo* di)
4974 return di->got_present ? di->got_size : 0;
4977 const HChar* VG_(DebugInfo_get_soname)(const DebugInfo* di)
4979 return di->soname;
4982 const HChar* VG_(DebugInfo_get_filename)(const DebugInfo* di)
4984 return di->fsm.filename;
4987 PtrdiffT VG_(DebugInfo_get_text_bias)(const DebugInfo* di)
4989 return di->text_present ? di->text_bias : 0;
4992 Int VG_(DebugInfo_syms_howmany) ( const DebugInfo *si )
4994 return si->symtab_used;
4997 void VG_(DebugInfo_syms_getidx) ( const DebugInfo *si,
4998 Int idx,
4999 /*OUT*/SymAVMAs* avmas,
5000 /*OUT*/UInt* size,
5001 /*OUT*/const HChar** pri_name,
5002 /*OUT*/const HChar*** sec_names,
5003 /*OUT*/Bool* isText,
5004 /*OUT*/Bool* isIFunc,
5005 /*OUT*/Bool* isGlobal )
5007 vg_assert(idx >= 0 && idx < si->symtab_used);
5008 if (avmas) *avmas = si->symtab[idx].avmas;
5009 if (size) *size = si->symtab[idx].size;
5010 if (pri_name) *pri_name = si->symtab[idx].pri_name;
5011 if (sec_names) *sec_names = si->symtab[idx].sec_names;
5012 if (isText) *isText = si->symtab[idx].isText;
5013 if (isIFunc) *isIFunc = si->symtab[idx].isIFunc;
5014 if (isGlobal) *isGlobal = si->symtab[idx].isGlobal;
5018 /*------------------------------------------------------------*/
5019 /*--- SectKind query functions ---*/
5020 /*------------------------------------------------------------*/
5022 /* Convert a VgSectKind to a string, which must be copied if you want
5023 to change it. */
5024 const HChar* VG_(pp_SectKind)( VgSectKind kind )
5026 switch (kind) {
5027 case Vg_SectUnknown: return "Unknown";
5028 case Vg_SectText: return "Text";
5029 case Vg_SectData: return "Data";
5030 case Vg_SectBSS: return "BSS";
5031 case Vg_SectGOT: return "GOT";
5032 case Vg_SectPLT: return "PLT";
5033 case Vg_SectOPD: return "OPD";
5034 case Vg_SectGOTPLT: return "GOTPLT";
5035 default: vg_assert(0);
5039 /* Given an address 'a', make a guess of which section of which object
5040 it comes from. If name is non-NULL, then the object's name is put
5041 in *name. The returned name, if any, should be saved away, if there is
5042 a chance that a debug-info will be discarded and the name is being
5043 used later on. */
5044 VgSectKind VG_(DebugInfo_sect_kind)( /*OUT*/const HChar** objname, Addr a)
5046 DebugInfo* di;
5047 VgSectKind res = Vg_SectUnknown;
5049 for (di = debugInfo_list; di != NULL; di = di->next) {
5051 if (0)
5052 VG_(printf)(
5053 "addr=%#lx di=%p %s got=%#lx,%lu plt=%#lx,%lu "
5054 "data=%#lx,%lu bss=%#lx,%lu\n",
5055 a, di, di->fsm.filename,
5056 di->got_avma, di->got_size,
5057 di->plt_avma, di->plt_size,
5058 di->data_avma, di->data_size,
5059 di->bss_avma, di->bss_size);
5061 if (di->text_present
5062 && di->text_size > 0
5063 && a >= di->text_avma && a < di->text_avma + di->text_size) {
5064 res = Vg_SectText;
5065 break;
5067 if (di->data_present
5068 && di->data_size > 0
5069 && a >= di->data_avma && a < di->data_avma + di->data_size) {
5070 res = Vg_SectData;
5071 break;
5073 if (di->sdata_present
5074 && di->sdata_size > 0
5075 && a >= di->sdata_avma && a < di->sdata_avma + di->sdata_size) {
5076 res = Vg_SectData;
5077 break;
5079 if (di->bss_present
5080 && di->bss_size > 0
5081 && a >= di->bss_avma && a < di->bss_avma + di->bss_size) {
5082 res = Vg_SectBSS;
5083 break;
5085 if (di->sbss_present
5086 && di->sbss_size > 0
5087 && a >= di->sbss_avma && a < di->sbss_avma + di->sbss_size) {
5088 res = Vg_SectBSS;
5089 break;
5091 if (di->plt_present
5092 && di->plt_size > 0
5093 && a >= di->plt_avma && a < di->plt_avma + di->plt_size) {
5094 res = Vg_SectPLT;
5095 break;
5097 if (di->got_present
5098 && di->got_size > 0
5099 && a >= di->got_avma && a < di->got_avma + di->got_size) {
5100 res = Vg_SectGOT;
5101 break;
5103 if (di->gotplt_present
5104 && di->gotplt_size > 0
5105 && a >= di->gotplt_avma && a < di->gotplt_avma + di->gotplt_size) {
5106 res = Vg_SectGOTPLT;
5107 break;
5109 if (di->opd_present
5110 && di->opd_size > 0
5111 && a >= di->opd_avma && a < di->opd_avma + di->opd_size) {
5112 res = Vg_SectOPD;
5113 break;
5115 /* we could also check for .eh_frame, if anyone really cares */
5118 vg_assert( (di == NULL && res == Vg_SectUnknown)
5119 || (di != NULL && res != Vg_SectUnknown) );
5121 if (objname) {
5122 if (di && di->fsm.filename) {
5123 *objname = di->fsm.filename;
5124 } else {
5125 *objname = "???";
5129 return res;
5133 static UInt debuginfo_generation = 0;
5135 UInt VG_(debuginfo_generation) (void)
5137 return debuginfo_generation;
5140 static void caches__invalidate ( void ) {
5141 cfsi_m_cache__invalidate();
5142 sym_name_cache__invalidate();
5143 debuginfo_generation++;
5146 #if defined(VGO_freebsd)
5148 * Used by FreeBSD if we detect a syscall cap_enter. That
5149 * means capability mode, and lots of things won't work any more.
5150 * Like opening new file handles. So try to make the most of a bad job
5151 * and read all debuginfo in one go.
5153 void VG_(load_all_debuginfo) (void)
5155 for (DebugInfo* di = debugInfo_list; di; di = di->next) {
5156 VG_(di_load_di)(di);
5159 #endif
5161 /*--------------------------------------------------------------------*/
5162 /*--- end ---*/
5163 /*--------------------------------------------------------------------*/