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