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