1
2 /*--------------------------------------------------------------------*/
3 /*--- Top level management of symbols and debugging information. ---*/
4 /*--- debuginfo.c ---*/
5 /*--------------------------------------------------------------------*/
6
7 /*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
11 Copyright (C) 2000-2011 Julian Seward
12 jseward@acm.org
13
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file COPYING.
30 */
31
32 #include "pub_core_basics.h"
33 #include "pub_core_vki.h"
34 #include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy
35 #include "pub_core_threadstate.h"
36 #include "pub_core_debuginfo.h" /* self */
37 #include "pub_core_demangle.h"
38 #include "pub_core_libcbase.h"
39 #include "pub_core_libcassert.h"
40 #include "pub_core_libcprint.h"
41 #include "pub_core_libcfile.h"
42 #include "pub_core_libcproc.h" // VG_(getenv)
43 #include "pub_core_seqmatch.h"
44 #include "pub_core_options.h"
45 #include "pub_core_redir.h" // VG_(redir_notify_{new,delete}_SegInfo)
46 #include "pub_core_aspacemgr.h"
47 #include "pub_core_machine.h" // VG_PLAT_USES_PPCTOC
48 #include "pub_core_xarray.h"
49 #include "pub_core_oset.h"
50 #include "pub_core_stacktrace.h" // VG_(get_StackTrace) XXX: circular dependency
51 #include "pub_core_ume.h"
52
53 #include "priv_misc.h" /* dinfo_zalloc/free */
54 #include "priv_d3basics.h" /* ML_(pp_GX) */
55 #include "priv_tytypes.h"
56 #include "priv_storage.h"
57 #include "priv_readdwarf.h"
58 #include "priv_readstabs.h"
59 #if defined(VGO_linux)
60 # include "priv_readelf.h"
61 # include "priv_readdwarf3.h"
62 # include "priv_readpdb.h"
63 #elif defined(VGO_darwin)
64 # include "priv_readmacho.h"
65 # include "priv_readpdb.h"
66 #endif
67
68
69 /*------------------------------------------------------------*/
70 /*--- The _svma / _avma / _image / _bias naming scheme ---*/
71 /*------------------------------------------------------------*/
72
73 /* JRS 11 Jan 07: I find the different kinds of addresses involved in
74 debuginfo reading confusing. Recently I arrived at some
75 terminology which makes it clearer (to me, at least). There are 3
76 kinds of address used in the debuginfo reading process:
77
78 stated VMAs - the address where (eg) a .so says a symbol is, that
79 is, what it tells you if you consider the .so in
80 isolation
81
82 actual VMAs - the address where (eg) said symbol really wound up
83 after the .so was mapped into memory
84
85 image addresses - pointers into the copy of the .so (etc)
86 transiently mmaped aboard whilst we read its info
87
88 Additionally I use the term 'bias' to denote the difference
89 between stated and actual VMAs for a given entity.
90
91 This terminology is not used consistently, but a start has been
92 made. readelf.c and the call-frame info reader in readdwarf.c now
93 use it. Specifically, various variables and structure fields have
94 been annotated with _avma / _svma / _image / _bias. In places _img
95 is used instead of _image for the sake of brevity.
96 */
97
98
99 /*------------------------------------------------------------*/
100 /*--- fwdses ---*/
101 /*------------------------------------------------------------*/
102
103 static void cfsi_cache__invalidate ( void );
104
105
106 /*------------------------------------------------------------*/
107 /*--- Root structure ---*/
108 /*------------------------------------------------------------*/
109
110 /* The root structure for the entire debug info system. It is a
111 linked list of DebugInfos. */
112 static DebugInfo* debugInfo_list = NULL;
113
114
115 /* Find 'di' in the debugInfo_list and move it one step closer the the
116 front of the list, so as to make subsequent searches for it
117 cheaper. When used in a controlled way, makes a major improvement
118 in some DebugInfo-search-intensive situations, most notably stack
119 unwinding on amd64-linux. */
move_DebugInfo_one_step_forward(DebugInfo * di)120 static void move_DebugInfo_one_step_forward ( DebugInfo* di )
121 {
122 DebugInfo *di0, *di1, *di2;
123 if (di == debugInfo_list)
124 return; /* already at head of list */
125 vg_assert(di != NULL);
126 di0 = debugInfo_list;
127 di1 = NULL;
128 di2 = NULL;
129 while (True) {
130 if (di0 == NULL || di0 == di) break;
131 di2 = di1;
132 di1 = di0;
133 di0 = di0->next;
134 }
135 vg_assert(di0 == di);
136 if (di0 != NULL && di1 != NULL && di2 != NULL) {
137 DebugInfo* tmp;
138 /* di0 points to di, di1 to its predecessor, and di2 to di1's
139 predecessor. Swap di0 and di1, that is, move di0 one step
140 closer to the start of the list. */
141 vg_assert(di2->next == di1);
142 vg_assert(di1->next == di0);
143 tmp = di0->next;
144 di2->next = di0;
145 di0->next = di1;
146 di1->next = tmp;
147 }
148 else
149 if (di0 != NULL && di1 != NULL && di2 == NULL) {
150 /* it's second in the list. */
151 vg_assert(debugInfo_list == di1);
152 vg_assert(di1->next == di0);
153 di1->next = di0->next;
154 di0->next = di1;
155 debugInfo_list = di0;
156 }
157 }
158
159
160 /*------------------------------------------------------------*/
161 /*--- Notification (acquire/discard) helpers ---*/
162 /*------------------------------------------------------------*/
163
164 /* Gives out unique abstract handles for allocated DebugInfos. See
165 comment in priv_storage.h, declaration of struct _DebugInfo, for
166 details. */
167 static ULong handle_counter = 1;
168
169 /* Allocate and zero out a new DebugInfo record. */
170 static
alloc_DebugInfo(const UChar * filename)171 DebugInfo* alloc_DebugInfo( const UChar* filename )
172 {
173 Bool traceme;
174 DebugInfo* di;
175
176 vg_assert(filename);
177
178 di = ML_(dinfo_zalloc)("di.debuginfo.aDI.1", sizeof(DebugInfo));
179 di->handle = handle_counter++;
180 di->fsm.filename = ML_(dinfo_strdup)("di.debuginfo.aDI.2", filename);
181
182 /* Everything else -- pointers, sizes, arrays -- is zeroed by
183 ML_(dinfo_zalloc). Now set up the debugging-output flags. */
184 traceme
185 = VG_(string_match)( VG_(clo_trace_symtab_patt), filename );
186 if (traceme) {
187 di->trace_symtab = VG_(clo_trace_symtab);
188 di->trace_cfi = VG_(clo_trace_cfi);
189 di->ddump_syms = VG_(clo_debug_dump_syms);
190 di->ddump_line = VG_(clo_debug_dump_line);
191 di->ddump_frames = VG_(clo_debug_dump_frames);
192 }
193
194 return di;
195 }
196
197
198 /* Free a DebugInfo, and also all the stuff hanging off it. */
free_DebugInfo(DebugInfo * di)199 static void free_DebugInfo ( DebugInfo* di )
200 {
201 Word i, j, n;
202 struct strchunk *chunk, *next;
203 TyEnt* ent;
204 GExpr* gexpr;
205
206 vg_assert(di != NULL);
207 if (di->fsm.filename) ML_(dinfo_free)(di->fsm.filename);
208 if (di->loctab) ML_(dinfo_free)(di->loctab);
209 if (di->cfsi) ML_(dinfo_free)(di->cfsi);
210 if (di->cfsi_exprs) VG_(deleteXA)(di->cfsi_exprs);
211 if (di->fpo) ML_(dinfo_free)(di->fpo);
212
213 if (di->symtab) {
214 /* We have to visit all the entries so as to free up any
215 sec_names arrays that might exist. */
216 n = di->symtab_used;
217 for (i = 0; i < n; i++) {
218 DiSym* sym = &di->symtab[i];
219 if (sym->sec_names)
220 ML_(dinfo_free)(sym->sec_names);
221 }
222 /* and finally .. */
223 ML_(dinfo_free)(di->symtab);
224 }
225
226 for (chunk = di->strchunks; chunk != NULL; chunk = next) {
227 next = chunk->next;
228 ML_(dinfo_free)(chunk);
229 }
230
231 /* Delete the two admin arrays. These lists exist primarily so
232 that we can visit each object exactly once when we need to
233 delete them. */
234 if (di->admin_tyents) {
235 n = VG_(sizeXA)(di->admin_tyents);
236 for (i = 0; i < n; i++) {
237 ent = (TyEnt*)VG_(indexXA)(di->admin_tyents, i);
238 /* Dump anything hanging off this ent */
239 ML_(TyEnt__make_EMPTY)(ent);
240 }
241 VG_(deleteXA)(di->admin_tyents);
242 di->admin_tyents = NULL;
243 }
244
245 if (di->admin_gexprs) {
246 n = VG_(sizeXA)(di->admin_gexprs);
247 for (i = 0; i < n; i++) {
248 gexpr = *(GExpr**)VG_(indexXA)(di->admin_gexprs, i);
249 ML_(dinfo_free)(gexpr);
250 }
251 VG_(deleteXA)(di->admin_gexprs);
252 di->admin_gexprs = NULL;
253 }
254
255 /* Dump the variable info. This is kinda complex: we must take
256 care not to free items which reside in either the admin lists
257 (as we have just freed them) or which reside in the DebugInfo's
258 string table. */
259 if (di->varinfo) {
260 for (i = 0; i < VG_(sizeXA)(di->varinfo); i++) {
261 OSet* scope = *(OSet**)VG_(indexXA)(di->varinfo, i);
262 if (!scope) continue;
263 /* iterate over all entries in 'scope' */
264 VG_(OSetGen_ResetIter)(scope);
265 while (True) {
266 DiAddrRange* arange = VG_(OSetGen_Next)(scope);
267 if (!arange) break;
268 /* for each var in 'arange' */
269 vg_assert(arange->vars);
270 for (j = 0; j < VG_(sizeXA)( arange->vars ); j++) {
271 DiVariable* var = (DiVariable*)VG_(indexXA)(arange->vars,j);
272 vg_assert(var);
273 /* Nothing to free in var: all the pointer fields refer
274 to stuff either on an admin list, or in
275 .strchunks */
276 }
277 VG_(deleteXA)(arange->vars);
278 /* Don't free arange itself, as OSetGen_Destroy does
279 that */
280 }
281 VG_(OSetGen_Destroy)(scope);
282 }
283 VG_(deleteXA)(di->varinfo);
284 }
285
286 ML_(dinfo_free)(di);
287 }
288
289
290 /* 'si' is a member of debugInfo_list. Find it, remove it from the
291 list, notify m_redir that this has happened, and free all storage
292 reachable from it.
293 */
discard_DebugInfo(DebugInfo * di)294 static void discard_DebugInfo ( DebugInfo* di )
295 {
296 HChar* reason = "munmap";
297
298 DebugInfo** prev_next_ptr = &debugInfo_list;
299 DebugInfo* curr = debugInfo_list;
300
301 while (curr) {
302 if (curr == di) {
303 /* Found it; remove from list and free it. */
304 if (curr->have_dinfo
305 && (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir)))
306 VG_(message)(Vg_DebugMsg,
307 "Discarding syms at %#lx-%#lx in %s due to %s()\n",
308 di->text_avma,
309 di->text_avma + di->text_size,
310 curr->fsm.filename ? curr->fsm.filename
311 : (UChar*)"???",
312 reason);
313 vg_assert(*prev_next_ptr == curr);
314 *prev_next_ptr = curr->next;
315 if (curr->have_dinfo)
316 VG_(redir_notify_delete_DebugInfo)( curr );
317 free_DebugInfo(curr);
318 return;
319 }
320 prev_next_ptr = &curr->next;
321 curr = curr->next;
322 }
323
324 /* Not found. */
325 }
326
327
328 /* Repeatedly scan debugInfo_list, looking for DebugInfos with text
329 AVMAs intersecting [start,start+length), and call discard_DebugInfo
330 to get rid of them. This modifies the list, hence the multiple
331 iterations. Returns True iff any such DebugInfos were found.
332 */
discard_syms_in_range(Addr start,SizeT length)333 static Bool discard_syms_in_range ( Addr start, SizeT length )
334 {
335 Bool anyFound = False;
336 Bool found;
337 DebugInfo* curr;
338
339 while (True) {
340 found = False;
341
342 curr = debugInfo_list;
343 while (True) {
344 if (curr == NULL)
345 break;
346 if (curr->text_present
347 && curr->text_size > 0
348 && (start+length - 1 < curr->text_avma
349 || curr->text_avma + curr->text_size - 1 < start)) {
350 /* no overlap */
351 } else {
352 found = True;
353 break;
354 }
355 curr = curr->next;
356 }
357
358 if (!found) break;
359 anyFound = True;
360 discard_DebugInfo( curr );
361 }
362
363 return anyFound;
364 }
365
366
367 /* Does [s1,+len1) overlap [s2,+len2) ? Note: does not handle
368 wraparound at the end of the address space -- just asserts in that
369 case. */
ranges_overlap(Addr s1,SizeT len1,Addr s2,SizeT len2)370 static Bool ranges_overlap (Addr s1, SizeT len1, Addr s2, SizeT len2 )
371 {
372 Addr e1, e2;
373 if (len1 == 0 || len2 == 0)
374 return False;
375 e1 = s1 + len1 - 1;
376 e2 = s2 + len2 - 1;
377 /* Assert that we don't have wraparound. If we do it would imply
378 that file sections are getting mapped around the end of the
379 address space, which sounds unlikely. */
380 vg_assert(s1 <= e1);
381 vg_assert(s2 <= e2);
382 if (e1 < s2 || e2 < s1) return False;
383 return True;
384 }
385
386
387 /* Do the basic rx_ and rw_ mappings of the two DebugInfos overlap in
388 any way? */
do_DebugInfos_overlap(DebugInfo * di1,DebugInfo * di2)389 static Bool do_DebugInfos_overlap ( DebugInfo* di1, DebugInfo* di2 )
390 {
391 vg_assert(di1);
392 vg_assert(di2);
393
394 if (di1->fsm.have_rx_map && di2->fsm.have_rx_map
395 && ranges_overlap(di1->fsm.rx_map_avma, di1->fsm.rx_map_size,
396 di2->fsm.rx_map_avma, di2->fsm.rx_map_size))
397 return True;
398
399 if (di1->fsm.have_rx_map && di2->fsm.have_rw_map
400 && ranges_overlap(di1->fsm.rx_map_avma, di1->fsm.rx_map_size,
401 di2->fsm.rw_map_avma, di2->fsm.rw_map_size))
402 return True;
403
404 if (di1->fsm.have_rw_map && di2->fsm.have_rx_map
405 && ranges_overlap(di1->fsm.rw_map_avma, di1->fsm.rw_map_size,
406 di2->fsm.rx_map_avma, di2->fsm.rx_map_size))
407 return True;
408
409 if (di1->fsm.have_rw_map && di2->fsm.have_rw_map
410 && ranges_overlap(di1->fsm.rw_map_avma, di1->fsm.rw_map_size,
411 di2->fsm.rw_map_avma, di2->fsm.rw_map_size))
412 return True;
413
414 return False;
415 }
416
417
418 /* Discard all elements of debugInfo_list whose .mark bit is set.
419 */
discard_marked_DebugInfos(void)420 static void discard_marked_DebugInfos ( void )
421 {
422 DebugInfo* curr;
423
424 while (True) {
425
426 curr = debugInfo_list;
427 while (True) {
428 if (!curr)
429 break;
430 if (curr->mark)
431 break;
432 curr = curr->next;
433 }
434
435 if (!curr) break;
436 discard_DebugInfo( curr );
437
438 }
439 }
440
441
442 /* Discard any elements of debugInfo_list which overlap with diRef.
443 Clearly diRef must have its rx_ and rw_ mapping information set to
444 something sane. */
discard_DebugInfos_which_overlap_with(DebugInfo * diRef)445 static void discard_DebugInfos_which_overlap_with ( DebugInfo* diRef )
446 {
447 DebugInfo* di;
448 /* Mark all the DebugInfos in debugInfo_list that need to be
449 deleted. First, clear all the mark bits; then set them if they
450 overlap with siRef. Since siRef itself is in this list we at
451 least expect its own mark bit to be set. */
452 for (di = debugInfo_list; di; di = di->next) {
453 di->mark = do_DebugInfos_overlap( di, diRef );
454 if (di == diRef) {
455 vg_assert(di->mark);
456 di->mark = False;
457 }
458 }
459 discard_marked_DebugInfos();
460 }
461
462
463 /* Find the existing DebugInfo for |filename| or if not found, create
464 one. In the latter case |filename| is strdup'd into VG_AR_DINFO,
465 and the new DebugInfo is added to debugInfo_list. */
find_or_create_DebugInfo_for(UChar * filename)466 static DebugInfo* find_or_create_DebugInfo_for ( UChar* filename )
467 {
468 DebugInfo* di;
469 vg_assert(filename);
470 for (di = debugInfo_list; di; di = di->next) {
471 vg_assert(di->fsm.filename);
472 if (0==VG_(strcmp)(di->fsm.filename, filename))
473 break;
474 }
475 if (!di) {
476 di = alloc_DebugInfo(filename);
477 vg_assert(di);
478 di->next = debugInfo_list;
479 debugInfo_list = di;
480 }
481 return di;
482 }
483
484
485 /* Debuginfo reading for 'di' has just been successfully completed.
486 Check that the invariants stated in
487 "Comment_on_IMPORTANT_CFSI_REPRESENTATIONAL_INVARIANTS" in
488 priv_storage.h are observed. */
check_CFSI_related_invariants(DebugInfo * di)489 static void check_CFSI_related_invariants ( DebugInfo* di )
490 {
491 DebugInfo* di2 = NULL;
492 vg_assert(di);
493 /* This fn isn't called until after debuginfo for this object has
494 been successfully read. And that shouldn't happen until we have
495 both a r-x and rw- mapping for the object. Hence: */
496 vg_assert(di->fsm.have_rx_map);
497 vg_assert(di->fsm.have_rw_map);
498 /* degenerate case: r-x section is empty */
499 if (di->fsm.rx_map_size == 0) {
500 vg_assert(di->cfsi == NULL);
501 return;
502 }
503 /* normal case: r-x section is nonempty */
504 /* invariant (0) */
505 vg_assert(di->fsm.rx_map_size > 0);
506 /* invariant (1) */
507 for (di2 = debugInfo_list; di2; di2 = di2->next) {
508 if (di2 == di)
509 continue;
510 if (di2->fsm.rx_map_size == 0)
511 continue;
512 vg_assert(
513 di->fsm.rx_map_avma + di->fsm.rx_map_size <= di2->fsm.rx_map_avma
514 || di2->fsm.rx_map_avma + di2->fsm.rx_map_size <= di->fsm.rx_map_avma
515 );
516 }
517 di2 = NULL;
518 /* invariant (2) */
519 if (di->cfsi) {
520 vg_assert(di->cfsi_minavma <= di->cfsi_maxavma); /* duh! */
521 vg_assert(di->cfsi_minavma >= di->fsm.rx_map_avma);
522 vg_assert(di->cfsi_maxavma < di->fsm.rx_map_avma + di->fsm.rx_map_size);
523 }
524 /* invariants (3) and (4) */
525 if (di->cfsi) {
526 Word i;
527 vg_assert(di->cfsi_used > 0);
528 vg_assert(di->cfsi_size > 0);
529 for (i = 0; i < di->cfsi_used; i++) {
530 DiCfSI* cfsi = &di->cfsi[i];
531 vg_assert(cfsi->len > 0);
532 vg_assert(cfsi->base >= di->cfsi_minavma);
533 vg_assert(cfsi->base + cfsi->len - 1 <= di->cfsi_maxavma);
534 if (i > 0) {
535 DiCfSI* cfsip = &di->cfsi[i-1];
536 vg_assert(cfsip->base + cfsip->len <= cfsi->base);
537 }
538 }
539 } else {
540 vg_assert(di->cfsi_used == 0);
541 vg_assert(di->cfsi_size == 0);
542 }
543 }
544
545
546 /*--------------------------------------------------------------*/
547 /*--- ---*/
548 /*--- TOP LEVEL: INITIALISE THE DEBUGINFO SYSTEM ---*/
549 /*--- ---*/
550 /*--------------------------------------------------------------*/
551
VG_(di_initialise)552 void VG_(di_initialise) ( void )
553 {
554 /* There's actually very little to do here, since everything
555 centers around the DebugInfos in debugInfo_list, they are
556 created and destroyed on demand, and each one is treated more or
557 less independently. */
558 vg_assert(debugInfo_list == NULL);
559
560 /* flush the CFI fast query cache. */
561 cfsi_cache__invalidate();
562 }
563
564
565 /*--------------------------------------------------------------*/
566 /*--- ---*/
567 /*--- TOP LEVEL: NOTIFICATION (ACQUIRE/DISCARD INFO) (LINUX) ---*/
568 /*--- ---*/
569 /*--------------------------------------------------------------*/
570
571 #if defined(VGO_linux) || defined(VGO_darwin)
572
573 /* The debug info system is driven by notifications that a text
574 segment has been mapped in, or unmapped, or when sections change
575 permission. It's all a bit kludgey and basically means watching
576 syscalls, trying to second-guess when the system's dynamic linker
577 is done with mapping in a new object for execution. This is all
578 tracked using the DebugInfoFSM struct for the object. Anyway, once
579 we finally decide we've got to an accept state, this section then
580 will acquire whatever info is available for the corresponding
581 object. This section contains the notification handlers, which
582 update the FSM and determine when an accept state has been reached.
583 */
584
585 /* When the sequence of observations causes a DebugInfoFSM to move
586 into the accept state, call here to actually get the debuginfo read
587 in. Returns a ULong whose purpose is described in comments
588 preceding VG_(di_notify_mmap) just below.
589 */
di_notify_ACHIEVE_ACCEPT_STATE(struct _DebugInfo * di)590 static ULong di_notify_ACHIEVE_ACCEPT_STATE ( struct _DebugInfo* di )
591 {
592 ULong di_handle;
593 Bool ok;
594
595 vg_assert(di->fsm.filename);
596 TRACE_SYMTAB("\n");
597 TRACE_SYMTAB("------ start ELF OBJECT "
598 "------------------------------\n");
599 TRACE_SYMTAB("------ name = %s\n", di->fsm.filename);
600 TRACE_SYMTAB("\n");
601
602 /* We're going to read symbols and debug info for the avma
603 ranges [rx_map_avma, +rx_map_size) and [rw_map_avma,
604 +rw_map_size). First get rid of any other DebugInfos which
605 overlap either of those ranges (to avoid total confusion). */
606 discard_DebugInfos_which_overlap_with( di );
607
608 /* .. and acquire new info. */
609 # if defined(VGO_linux)
610 ok = ML_(read_elf_debug_info)( di );
611 # elif defined(VGO_darwin)
612 ok = ML_(read_macho_debug_info)( di );
613 # else
614 # error "unknown OS"
615 # endif
616
617 if (ok) {
618
619 TRACE_SYMTAB("\n------ Canonicalising the "
620 "acquired info ------\n");
621 /* invalidate the CFI unwind cache. */
622 cfsi_cache__invalidate();
623 /* prepare read data for use */
624 ML_(canonicaliseTables)( di );
625 /* notify m_redir about it */
626 TRACE_SYMTAB("\n------ Notifying m_redir ------\n");
627 VG_(redir_notify_new_DebugInfo)( di );
628 /* Note that we succeeded */
629 di->have_dinfo = True;
630 tl_assert(di->handle > 0);
631 di_handle = di->handle;
632 /* Check invariants listed in
633 Comment_on_IMPORTANT_REPRESENTATIONAL_INVARIANTS in
634 priv_storage.h. */
635 check_CFSI_related_invariants(di);
636
637 } else {
638 TRACE_SYMTAB("\n------ ELF reading failed ------\n");
639 /* Something went wrong (eg. bad ELF file). Should we delete
640 this DebugInfo? No - it contains info on the rw/rx
641 mappings, at least. */
642 di_handle = 0;
643 vg_assert(di->have_dinfo == False);
644 }
645
646 TRACE_SYMTAB("\n");
647 TRACE_SYMTAB("------ name = %s\n", di->fsm.filename);
648 TRACE_SYMTAB("------ end ELF OBJECT "
649 "------------------------------\n");
650 TRACE_SYMTAB("\n");
651
652 return di_handle;
653 }
654
655
656 /* Notify the debuginfo system about a new mapping. This is the way
657 new debug information gets loaded. If allow_SkFileV is True, it
658 will try load debug info if the mapping at 'a' belongs to Valgrind;
659 whereas normally (False) it will not do that. This allows us to
660 carefully control when the thing will read symbols from the
661 Valgrind executable itself.
662
663 If use_fd is not -1, that is used instead of the filename; this
664 avoids perturbing fcntl locks, which are released by simply
665 re-opening and closing the same file (even via different fd!).
666
667 If a call to VG_(di_notify_mmap) causes debug info to be read, then
668 the returned ULong is an abstract handle which can later be used to
669 refer to the debuginfo read as a result of this specific mapping,
670 in later queries to m_debuginfo. In this case the handle value
671 will be one or above. If the returned value is zero, no debug info
672 was read. */
673
VG_(di_notify_mmap)674 ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd )
675 {
676 NSegment const * seg;
677 HChar* filename;
678 Bool is_rx_map, is_rw_map, is_ro_map;
679 DebugInfo* di;
680 Int actual_fd, oflags;
681 SysRes preadres;
682 HChar buf1k[1024];
683 Bool debug = False;
684 SysRes statres;
685 struct vg_stat statbuf;
686
687 vg_assert(use_fd >= -1);
688
689 /* In short, figure out if this mapping is of interest to us, and
690 if so, try to guess what ld.so is doing and when/if we should
691 read debug info. */
692 seg = VG_(am_find_nsegment)(a);
693 vg_assert(seg);
694
695 if (debug)
696 VG_(printf)("di_notify_mmap-1: %#lx-%#lx %c%c%c\n",
697 seg->start, seg->end,
698 seg->hasR ? 'r' : '-',
699 seg->hasW ? 'w' : '-',seg->hasX ? 'x' : '-' );
700
701 /* guaranteed by aspacemgr-linux.c, sane_NSegment() */
702 vg_assert(seg->end > seg->start);
703
704 /* Ignore non-file mappings */
705 if ( ! (seg->kind == SkFileC
706 || (seg->kind == SkFileV && allow_SkFileV)) )
707 return 0;
708
709 /* If the file doesn't have a name, we're hosed. Give up. */
710 filename = VG_(am_get_filename)( (NSegment*)seg );
711 if (!filename)
712 return 0;
713
714 if (debug)
715 VG_(printf)("di_notify_mmap-2: %s\n", filename);
716
717 /* Only try to read debug information from regular files. */
718 statres = VG_(stat)(filename, &statbuf);
719
720 /* stat dereferences symlinks, so we don't expect it to succeed and
721 yet produce something that is a symlink. */
722 vg_assert(sr_isError(statres) || ! VKI_S_ISLNK(statbuf.mode));
723
724 /* Don't let the stat call fail silently. Filter out some known
725 sources of noise before complaining, though. */
726 if (sr_isError(statres)) {
727 DebugInfo fake_di;
728 Bool quiet = VG_(strstr)(filename, "/var/run/nscd/") != NULL;
729 #ifdef ANDROID
730 quiet |= VG_(strstr)(filename, "/dev/__properties__") != NULL;
731 #endif
732 if (!quiet && VG_(clo_verbosity) > 1) {
733 VG_(memset)(&fake_di, 0, sizeof(fake_di));
734 fake_di.fsm.filename = filename;
735 ML_(symerr)(&fake_di, True, "failed to stat64/stat this file");
736 }
737 return 0;
738 }
739
740 /* Finally, the point of all this stattery: if it's not a regular file,
741 don't try to read debug info from it. */
742 if (! VKI_S_ISREG(statbuf.mode))
743 return 0;
744
745 /* no uses of statbuf below here. */
746
747 /* Now we have to guess if this is a text-like mapping, a data-like
748 mapping, neither or both. The rules are:
749
750 text if: x86-linux r and x
751 other-linux r and x and not w
752
753 data if: x86-linux r and w
754 other-linux r and w and not x
755
756 Background: On x86-linux, objects are typically mapped twice:
757
758 1b8fb000-1b8ff000 r-xp 00000000 08:02 4471477 vgpreload_memcheck.so
759 1b8ff000-1b900000 rw-p 00004000 08:02 4471477 vgpreload_memcheck.so
760
761 whereas ppc32-linux mysteriously does this:
762
763 118a6000-118ad000 r-xp 00000000 08:05 14209428 vgpreload_memcheck.so
764 118ad000-118b6000 ---p 00007000 08:05 14209428 vgpreload_memcheck.so
765 118b6000-118bd000 rwxp 00000000 08:05 14209428 vgpreload_memcheck.so
766
767 The third mapping should not be considered to have executable
768 code in. Therefore a test which works for both is: r and x and
769 NOT w. Reading symbols from the rwx segment -- which overlaps
770 the r-x segment in the file -- causes the redirection mechanism
771 to redirect to addresses in that third segment, which is wrong
772 and causes crashes.
773
774 JRS 28 Dec 05: unfortunately icc 8.1 on x86 has been seen to
775 produce executables with a single rwx segment rather than a
776 (r-x,rw-) pair. That means the rules have to be modified thusly:
777
778 x86-linux: consider if r and x
779 all others: consider if r and x and not w
780
781 2009 Aug 16: apply similar kludge to ppc32-linux.
782 See http://bugs.kde.org/show_bug.cgi?id=190820
783
784 There are two modes on s390x: with and without the noexec kernel
785 parameter. Together with some older kernels, this leads to several
786 variants:
787 executable: r and x
788 data: r and w and x
789 or
790 executable: r and x
791 data: r and w
792 */
793 is_rx_map = False;
794 is_rw_map = False;
795 is_ro_map = False;
796
797 # if defined(VGA_x86) || defined(VGA_ppc32)
798 is_rx_map = seg->hasR && seg->hasX;
799 is_rw_map = seg->hasR && seg->hasW;
800 # elif defined(VGA_amd64) || defined(VGA_ppc64) || defined(VGA_arm)
801 is_rx_map = seg->hasR && seg->hasX && !seg->hasW;
802 is_rw_map = seg->hasR && seg->hasW && !seg->hasX;
803 # elif defined(VGP_s390x_linux)
804 is_rx_map = seg->hasR && seg->hasX && !seg->hasW;
805 is_rw_map = seg->hasR && seg->hasW;
806 # else
807 # error "Unknown platform"
808 # endif
809
810 # if defined(VGP_x86_darwin) && DARWIN_VERS == DARWIN_10_7
811 is_ro_map = seg->hasR && !seg->hasW && !seg->hasX;
812 # endif
813
814 if (debug)
815 VG_(printf)("di_notify_mmap-3: is_rx_map %d, is_rw_map %d\n",
816 (Int)is_rx_map, (Int)is_rw_map);
817
818 /* Ignore mappings with permissions we can't possibly be interested in. */
819 if (!(is_rx_map || is_rw_map || is_ro_map))
820 return 0;
821
822 /* Peer at the first few bytes of the file, to see if it is an ELF */
823 /* object file. Ignore the file if we do not have read permission. */
824 VG_(memset)(buf1k, 0, sizeof(buf1k));
825 oflags = VKI_O_RDONLY;
826 # if defined(VKI_O_LARGEFILE)
827 oflags |= VKI_O_LARGEFILE;
828 # endif
829
830 if (use_fd == -1) {
831 SysRes fd = VG_(open)( filename, oflags, 0 );
832 if (sr_isError(fd)) {
833 if (sr_Err(fd) != VKI_EACCES) {
834 DebugInfo fake_di;
835 VG_(memset)(&fake_di, 0, sizeof(fake_di));
836 fake_di.fsm.filename = filename;
837 ML_(symerr)(&fake_di, True,
838 "can't open file to inspect ELF header");
839 }
840 return 0;
841 }
842 actual_fd = sr_Res(fd);
843 } else {
844 actual_fd = use_fd;
845 }
846
847 preadres = VG_(pread)( actual_fd, buf1k, sizeof(buf1k), 0 );
848 if (use_fd == -1) {
849 VG_(close)( actual_fd );
850 }
851
852 if (sr_isError(preadres)) {
853 DebugInfo fake_di;
854 VG_(memset)(&fake_di, 0, sizeof(fake_di));
855 fake_di.fsm.filename = filename;
856 ML_(symerr)(&fake_di, True, "can't read file to inspect ELF header");
857 return 0;
858 }
859 if (sr_Res(preadres) == 0)
860 return 0;
861 vg_assert(sr_Res(preadres) > 0 && sr_Res(preadres) <= sizeof(buf1k) );
862
863 /* We're only interested in mappings of object files. */
864 # if defined(VGO_linux)
865 if (!ML_(is_elf_object_file)( buf1k, (SizeT)sr_Res(preadres) ))
866 return 0;
867 # elif defined(VGO_darwin)
868 if (!ML_(is_macho_object_file)( buf1k, (SizeT)sr_Res(preadres) ))
869 return 0;
870 # else
871 # error "unknown OS"
872 # endif
873
874 /* See if we have a DebugInfo for this filename. If not,
875 create one. */
876 di = find_or_create_DebugInfo_for( filename );
877 vg_assert(di);
878
879 if (is_rx_map) {
880 /* We have a text-like mapping. Note the details. */
881 if (!di->fsm.have_rx_map) {
882 di->fsm.have_rx_map = True;
883 di->fsm.rx_map_avma = a;
884 di->fsm.rx_map_size = seg->end + 1 - seg->start;
885 di->fsm.rx_map_foff = seg->offset;
886 } else {
887 /* FIXME: complain about a second text-like mapping */
888 }
889 }
890
891 if (is_rw_map) {
892 /* We have a data-like mapping. Note the details. */
893 if (!di->fsm.have_rw_map) {
894 di->fsm.have_rw_map = True;
895 di->fsm.rw_map_avma = a;
896 di->fsm.rw_map_size = seg->end + 1 - seg->start;
897 di->fsm.rw_map_foff = seg->offset;
898 } else {
899 /* FIXME: complain about a second data-like mapping */
900 }
901 }
902
903 if (is_ro_map) {
904 /* We have a r-- mapping. Note the details (OSX 10.7, 32-bit only) */
905 if (!di->fsm.have_ro_map) {
906 di->fsm.have_ro_map = True;
907 di->fsm.ro_map_avma = a;
908 di->fsm.ro_map_size = seg->end + 1 - seg->start;
909 di->fsm.ro_map_foff = seg->offset;
910 } else {
911 /* FIXME: complain about a second r-- mapping */
912 }
913 }
914
915 /* So, finally, are we in an accept state? */
916 if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) {
917 /* Ok, so, finally, we found what we need, and we haven't
918 already read debuginfo for this object. So let's do so now.
919 Yee-ha! */
920 return di_notify_ACHIEVE_ACCEPT_STATE ( di );
921 } else {
922 /* If we don't have an rx and rw mapping, or if we already have
923 debuginfo for this mapping for whatever reason, go no
924 further. */
925 return 0;
926 }
927 }
928
929
930 /* Unmap is simpler - throw away any SegInfos intersecting
931 [a, a+len). */
VG_(di_notify_munmap)932 void VG_(di_notify_munmap)( Addr a, SizeT len )
933 {
934 Bool anyFound;
935 if (0) VG_(printf)("DISCARD %#lx %#lx\n", a, a+len);
936 anyFound = discard_syms_in_range(a, len);
937 if (anyFound)
938 cfsi_cache__invalidate();
939 }
940
941
942 /* Uh, this doesn't do anything at all. IIRC glibc (or ld.so, I don't
943 remember) does a bunch of mprotects on itself, and if we follow
944 through here, it causes the debug info for that object to get
945 discarded. */
VG_(di_notify_mprotect)946 void VG_(di_notify_mprotect)( Addr a, SizeT len, UInt prot )
947 {
948 Bool exe_ok = toBool(prot & VKI_PROT_EXEC);
949 # if defined(VGA_x86)
950 exe_ok = exe_ok || toBool(prot & VKI_PROT_READ);
951 # endif
952 if (0 && !exe_ok) {
953 Bool anyFound = discard_syms_in_range(a, len);
954 if (anyFound)
955 cfsi_cache__invalidate();
956 }
957 }
958
959
960 /* This is a MacOSX 10.7 32-bit only special. See comments on the
961 declaration of struct _DebugInfoFSM for details. */
VG_(di_notify_vm_protect)962 void VG_(di_notify_vm_protect)( Addr a, SizeT len, UInt prot )
963 {
964 Bool do_nothing = True;
965 # if defined(VGP_x86_darwin) && DARWIN_VERS == DARWIN_10_7
966 do_nothing = False;
967 # endif
968 if (do_nothing /* wrong platform */)
969 return;
970
971 Bool r_ok = toBool(prot & VKI_PROT_READ);
972 Bool w_ok = toBool(prot & VKI_PROT_WRITE);
973 Bool x_ok = toBool(prot & VKI_PROT_EXEC);
974 if (! (r_ok && !w_ok && x_ok))
975 return; /* not an upgrade to r-x */
976
977 /* Find a DebugInfo containing a FSM that has [a, +len) previously
978 observed as a r-- mapping, plus some other rw- mapping. If such
979 is found, conclude we're in an accept state and read debuginfo
980 accordingly. */
981 DebugInfo* di;
982 for (di = debugInfo_list; di; di = di->next) {
983 vg_assert(di->fsm.filename);
984 if (di->have_dinfo)
985 continue; /* already have debuginfo for this object */
986 if (!di->fsm.have_ro_map)
987 continue; /* need to have a r-- mapping for this object */
988 if (di->fsm.have_rx_map)
989 continue; /* rx- mapping already exists */
990 if (!di->fsm.have_rw_map)
991 continue; /* need to have a rw- mapping */
992 if (di->fsm.ro_map_avma != a || di->fsm.ro_map_size != len)
993 continue; /* this isn't an upgrade of the r-- mapping */
994 /* looks like we're in luck! */
995 break;
996 }
997 if (di == NULL)
998 return; /* didn't find anything */
999
1000 /* Do the upgrade. Copy the RO map info into the RX map info and
1001 pretend we never saw the RO map at all. */
1002 vg_assert(di->fsm.have_rw_map);
1003 vg_assert(di->fsm.have_ro_map);
1004 vg_assert(!di->fsm.have_rx_map);
1005
1006 di->fsm.have_rx_map = True;
1007 di->fsm.rx_map_avma = di->fsm.ro_map_avma;
1008 di->fsm.rx_map_size = di->fsm.ro_map_size;
1009 di->fsm.rx_map_foff = di->fsm.ro_map_foff;
1010
1011 di->fsm.have_ro_map = False;
1012 di->fsm.ro_map_avma = 0;
1013 di->fsm.ro_map_size = 0;
1014 di->fsm.ro_map_foff = 0;
1015
1016 /* And since we're now in an accept state, read debuginfo. Finally. */
1017 ULong di_handle __attribute__((unused))
1018 = di_notify_ACHIEVE_ACCEPT_STATE( di );
1019 /* di_handle is ignored. That's not a problem per se -- it just
1020 means nobody will ever be able to refer to this debuginfo by
1021 handle since nobody will know what the handle value is. */
1022 }
1023
1024
1025 /*--------- PDB (windows debug info) reading --------- */
1026
1027 /* this should really return ULong, as per VG_(di_notify_mmap). */
VG_(di_notify_pdb_debuginfo)1028 void VG_(di_notify_pdb_debuginfo)( Int fd_obj, Addr avma_obj,
1029 SizeT total_size,
1030 PtrdiffT unknown_purpose__reloc )
1031 {
1032 Int i, r, sz_exename;
1033 ULong obj_mtime, pdb_mtime;
1034 Char exename[VKI_PATH_MAX];
1035 Char* pdbname = NULL;
1036 Char* dot;
1037 SysRes sres;
1038 Int fd_pdbimage;
1039 SizeT n_pdbimage;
1040 struct vg_stat stat_buf;
1041
1042 if (VG_(clo_verbosity) > 0) {
1043 VG_(message)(Vg_UserMsg, "\n");
1044 VG_(message)(Vg_UserMsg,
1045 "LOAD_PDB_DEBUGINFO: clreq: fd=%d, avma=%#lx, total_size=%lu, "
1046 "uu_reloc=%#lx\n",
1047 fd_obj, avma_obj, total_size, unknown_purpose__reloc
1048 );
1049 }
1050
1051 /* 'fd' refers to the .exe/.dll we're dealing with. Get its modification
1052 time into obj_mtime. */
1053 r = VG_(fstat)(fd_obj, &stat_buf);
1054 if (r == -1)
1055 goto out; /* stat failed ?! */
1056 vg_assert(r == 0);
1057 obj_mtime = stat_buf.mtime;
1058
1059 /* and get its name into exename[]. */
1060 vg_assert(VKI_PATH_MAX > 100); /* to ensure /proc/self/fd/%d is safe */
1061 VG_(memset)(exename, 0, sizeof(exename));
1062 VG_(sprintf)(exename, "/proc/self/fd/%d", fd_obj);
1063 /* convert exename from a symlink to real name .. overwrites the
1064 old contents of the buffer. Ick. */
1065 sz_exename = VG_(readlink)(exename, exename, sizeof(exename)-2 );
1066 if (sz_exename == -1)
1067 goto out; /* readlink failed ?! */
1068 vg_assert(sz_exename >= 0 && sz_exename < sizeof(exename));
1069 vg_assert(exename[sizeof(exename)-1] == 0);
1070
1071 if (VG_(clo_verbosity) > 0) {
1072 VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: objname: %s\n", exename);
1073 }
1074
1075 /* Try to get the PDB file name from the executable. */
1076 pdbname = ML_(find_name_of_pdb_file)(exename);
1077 if (pdbname) {
1078 vg_assert(VG_(strlen)(pdbname) >= 5); /* 5 = strlen("X.pdb") */
1079 /* So we successfully extracted a name from the PE file. But it's
1080 likely to be of the form
1081 e:\foo\bar\xyzzy\wibble.pdb
1082 and we need to change it into something we can actually open
1083 in Wine-world, which basically means turning it into
1084 $HOME/.wine/drive_e/foo/bar/xyzzy/wibble.pdb
1085 We also take into account $WINEPREFIX, if it is set.
1086 For the moment, if the name isn't fully qualified, just forget it
1087 (we'd have to root around to find where the pdb actually is)
1088 */
1089 /* Change all the backslashes to forward slashes */
1090 for (i = 0; pdbname[i]; i++) {
1091 if (pdbname[i] == '\\')
1092 pdbname[i] = '/';
1093 }
1094 Bool is_quald
1095 = ('a' <= VG_(tolower)(pdbname[0]) && VG_(tolower)(pdbname[0]) <= 'z')
1096 && pdbname[1] == ':'
1097 && pdbname[2] == '/';
1098 HChar* home = VG_(getenv)("HOME");
1099 HChar* wpfx = VG_(getenv)("WINEPREFIX");
1100 if (is_quald && wpfx) {
1101 /* Change e:/foo/bar/xyzzy/wibble.pdb
1102 to $WINEPREFIX/drive_e/foo/bar/xyzzy/wibble.pdb
1103 */
1104 Int mashedSzB = VG_(strlen)(pdbname) + VG_(strlen)(wpfx) + 50/*misc*/;
1105 HChar* mashed = ML_(dinfo_zalloc)("di.debuginfo.dnpdi.1", mashedSzB);
1106 VG_(sprintf)(mashed, "%s/drive_%c%s",
1107 wpfx, VG_(tolower)(pdbname[0]), &pdbname[2]);
1108 vg_assert(mashed[mashedSzB-1] == 0);
1109 ML_(dinfo_free)(pdbname);
1110 pdbname = mashed;
1111 }
1112 else if (is_quald && home && !wpfx) {
1113 /* Change e:/foo/bar/xyzzy/wibble.pdb
1114 to $HOME/.wine/drive_e/foo/bar/xyzzy/wibble.pdb
1115 */
1116 Int mashedSzB = VG_(strlen)(pdbname) + VG_(strlen)(home) + 50/*misc*/;
1117 HChar* mashed = ML_(dinfo_zalloc)("di.debuginfo.dnpdi.2", mashedSzB);
1118 VG_(sprintf)(mashed, "%s/.wine/drive_%c%s",
1119 home, VG_(tolower)(pdbname[0]), &pdbname[2]);
1120 vg_assert(mashed[mashedSzB-1] == 0);
1121 ML_(dinfo_free)(pdbname);
1122 pdbname = mashed;
1123 } else {
1124 /* It's not a fully qualified path, or neither $HOME nor $WINE
1125 are set (strange). Give up. */
1126 ML_(dinfo_free)(pdbname);
1127 pdbname = NULL;
1128 }
1129 }
1130
1131 /* Try s/exe/pdb/ if we don't have a valid pdbname. */
1132 if (!pdbname) {
1133 /* Try to find a matching PDB file from which to read debuginfo.
1134 Windows PE files have symbol tables and line number information,
1135 but MSVC doesn't seem to use them. */
1136 /* Why +5 ? Because in the worst case, we could find a dot as the
1137 last character of pdbname, and we'd then put "pdb" right after
1138 it, hence extending it a bit. */
1139 pdbname = ML_(dinfo_zalloc)("di.debuginfo.lpd1", sz_exename+5);
1140 VG_(strcpy)(pdbname, exename);
1141 vg_assert(pdbname[sz_exename+5-1] == 0);
1142 dot = VG_(strrchr)(pdbname, '.');
1143 if (!dot)
1144 goto out; /* there's no dot in the exe's name ?! */
1145 if (dot[1] == 0)
1146 goto out; /* hmm, path ends in "." */
1147
1148 if ('A' <= dot[1] && dot[1] <= 'Z')
1149 VG_(strcpy)(dot, ".PDB");
1150 else
1151 VG_(strcpy)(dot, ".pdb");
1152
1153 vg_assert(pdbname[sz_exename+5-1] == 0);
1154 }
1155
1156 /* See if we can find it, and check it's in-dateness. */
1157 sres = VG_(stat)(pdbname, &stat_buf);
1158 if (sr_isError(sres)) {
1159 VG_(message)(Vg_UserMsg, "Warning: Missing or un-stat-able %s\n",
1160 pdbname);
1161 if (VG_(clo_verbosity) > 0)
1162 VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: missing: %s\n", pdbname);
1163 goto out;
1164 }
1165 pdb_mtime = stat_buf.mtime;
1166
1167 if (obj_mtime > pdb_mtime + 60ULL) {
1168 /* PDB file is older than PE file. Really, the PDB should be
1169 newer than the PE, but that doesn't always seem to be the
1170 case. Allow the PDB to be up to one minute older.
1171 Otherwise, it's probably out of date, in which case ignore it
1172 or we will either (a) print wrong stack traces or more likely
1173 (b) crash.
1174 */
1175 VG_(message)(Vg_UserMsg,
1176 "Warning: %s (mtime = %llu)\n"
1177 " is older than %s (mtime = %llu)\n",
1178 pdbname, pdb_mtime, exename, obj_mtime);
1179 }
1180
1181 sres = VG_(open)(pdbname, VKI_O_RDONLY, 0);
1182 if (sr_isError(sres)) {
1183 VG_(message)(Vg_UserMsg, "Warning: Can't open %s\n", pdbname);
1184 goto out;
1185 }
1186
1187 /* Looks promising; go on to try and read stuff from it. But don't
1188 mmap the file. Instead mmap free space and read the file into
1189 it. This is because files on CIFS filesystems that are mounted
1190 '-o directio' can't be mmap'd, and that mount option is needed
1191 to make CIFS work reliably. (See
1192 http://www.nabble.com/Corrupted-data-on-write-to-
1193 Windows-2003-Server-t2782623.html)
1194 This is slower, but at least it works reliably. */
1195 fd_pdbimage = sr_Res(sres);
1196 n_pdbimage = stat_buf.size;
1197 if (n_pdbimage == 0 || n_pdbimage > 0x7FFFFFFF) {
1198 // 0x7FFFFFFF: why? Because the VG_(read) just below only
1199 // can deal with a signed int as the size of data to read,
1200 // so we can't reliably check for read failure for files
1201 // greater than that size. Hence just skip them; we're
1202 // unlikely to encounter a PDB that large anyway.
1203 VG_(close)(fd_pdbimage);
1204 goto out;
1205 }
1206 sres = VG_(am_mmap_anon_float_valgrind)( n_pdbimage );
1207 if (sr_isError(sres)) {
1208 VG_(close)(fd_pdbimage);
1209 goto out;
1210 }
1211
1212 void* pdbimage = (void*)sr_Res(sres);
1213 r = VG_(read)( fd_pdbimage, pdbimage, (Int)n_pdbimage );
1214 if (r < 0 || r != (Int)n_pdbimage) {
1215 VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage );
1216 VG_(close)(fd_pdbimage);
1217 goto out;
1218 }
1219
1220 if (VG_(clo_verbosity) > 0)
1221 VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: pdbname: %s\n", pdbname);
1222
1223 /* play safe; always invalidate the CFI cache. I don't know if
1224 this is necessary, but anyway .. */
1225 cfsi_cache__invalidate();
1226 /* dump old info for this range, if any */
1227 discard_syms_in_range( avma_obj, total_size );
1228
1229 { DebugInfo* di = find_or_create_DebugInfo_for(exename);
1230
1231 /* this di must be new, since we just nuked any old stuff in the range */
1232 vg_assert(di && !di->fsm.have_rx_map && !di->fsm.have_rw_map);
1233 vg_assert(!di->have_dinfo);
1234
1235 /* don't set up any of the di-> fields; let
1236 ML_(read_pdb_debug_info) do it. */
1237 ML_(read_pdb_debug_info)( di, avma_obj, unknown_purpose__reloc,
1238 pdbimage, n_pdbimage, pdbname, pdb_mtime );
1239 // JRS fixme: take notice of return value from read_pdb_debug_info,
1240 // and handle failure
1241 vg_assert(di->have_dinfo); // fails if PDB read failed
1242 VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage );
1243 VG_(close)(fd_pdbimage);
1244
1245 if (VG_(clo_verbosity) > 0) {
1246 VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: done: "
1247 "%lu syms, %lu src locs, %lu fpo recs\n",
1248 di->symtab_used, di->loctab_used, di->fpo_size);
1249 }
1250 }
1251
1252 out:
1253 if (pdbname) ML_(dinfo_free)(pdbname);
1254 }
1255
1256 #endif /* defined(VGO_linux) || defined(VGO_darwin) */
1257
1258
1259 /*------------------------------------------------------------*/
1260 /*--- ---*/
1261 /*--- TOP LEVEL: QUERYING EXISTING DEBUG INFO ---*/
1262 /*--- ---*/
1263 /*------------------------------------------------------------*/
1264
VG_(di_discard_ALL_debuginfo)1265 void VG_(di_discard_ALL_debuginfo)( void )
1266 {
1267 DebugInfo *di, *di2;
1268 di = debugInfo_list;
1269 while (di) {
1270 di2 = di->next;
1271 VG_(printf)("XXX rm %p\n", di);
1272 free_DebugInfo( di );
1273 di = di2;
1274 }
1275 }
1276
1277
1278 /*------------------------------------------------------------*/
1279 /*--- Use of symbol table & location info to create ---*/
1280 /*--- plausible-looking stack dumps. ---*/
1281 /*------------------------------------------------------------*/
1282
1283 /* Search all symtabs that we know about to locate ptr. If found, set
1284 *pdi to the relevant DebugInfo, and *symno to the symtab entry
1285 *number within that. If not found, *psi is set to NULL.
1286 If findText==True, only text symbols are searched for.
1287 If findText==False, only data symbols are searched for.
1288 */
search_all_symtabs(Addr ptr,DebugInfo ** pdi,Word * symno,Bool match_anywhere_in_sym,Bool findText)1289 static void search_all_symtabs ( Addr ptr, /*OUT*/DebugInfo** pdi,
1290 /*OUT*/Word* symno,
1291 Bool match_anywhere_in_sym,
1292 Bool findText )
1293 {
1294 Word sno;
1295 DebugInfo* di;
1296 Bool inRange;
1297
1298 for (di = debugInfo_list; di != NULL; di = di->next) {
1299
1300 if (findText) {
1301 /* Consider any symbol in the r-x mapped area to be text.
1302 See Comment_Regarding_Text_Range_Checks in storage.c for
1303 details. */
1304 inRange = di->fsm.have_rx_map
1305 && di->fsm.rx_map_size > 0
1306 && di->fsm.rx_map_avma <= ptr
1307 && ptr < di->fsm.rx_map_avma + di->fsm.rx_map_size;
1308 } else {
1309 inRange = (di->data_present
1310 && di->data_size > 0
1311 && di->data_avma <= ptr
1312 && ptr < di->data_avma + di->data_size)
1313 ||
1314 (di->sdata_present
1315 && di->sdata_size > 0
1316 && di->sdata_avma <= ptr
1317 && ptr < di->sdata_avma + di->sdata_size)
1318 ||
1319 (di->bss_present
1320 && di->bss_size > 0
1321 && di->bss_avma <= ptr
1322 && ptr < di->bss_avma + di->bss_size)
1323 ||
1324 (di->sbss_present
1325 && di->sbss_size > 0
1326 && di->sbss_avma <= ptr
1327 && ptr < di->sbss_avma + di->sbss_size)
1328 ||
1329 (di->rodata_present
1330 && di->rodata_size > 0
1331 && di->rodata_avma <= ptr
1332 && ptr < di->rodata_avma + di->rodata_size);
1333 }
1334
1335 if (!inRange) continue;
1336
1337 sno = ML_(search_one_symtab) (
1338 di, ptr, match_anywhere_in_sym, findText );
1339 if (sno == -1) goto not_found;
1340 *symno = sno;
1341 *pdi = di;
1342 return;
1343
1344 }
1345 not_found:
1346 *pdi = NULL;
1347 }
1348
1349
1350 /* Search all loctabs that we know about to locate ptr. If found, set
1351 *pdi to the relevant DebugInfo, and *locno to the loctab entry
1352 *number within that. If not found, *pdi is set to NULL. */
search_all_loctabs(Addr ptr,DebugInfo ** pdi,Word * locno)1353 static void search_all_loctabs ( Addr ptr, /*OUT*/DebugInfo** pdi,
1354 /*OUT*/Word* locno )
1355 {
1356 Word lno;
1357 DebugInfo* di;
1358 for (di = debugInfo_list; di != NULL; di = di->next) {
1359 if (di->text_present
1360 && di->text_size > 0
1361 && di->text_avma <= ptr
1362 && ptr < di->text_avma + di->text_size) {
1363 lno = ML_(search_one_loctab) ( di, ptr );
1364 if (lno == -1) goto not_found;
1365 *locno = lno;
1366 *pdi = di;
1367 return;
1368 }
1369 }
1370 not_found:
1371 *pdi = NULL;
1372 }
1373
1374
1375 /* The whole point of this whole big deal: map a code address to a
1376 plausible symbol name. Returns False if no idea; otherwise True.
1377 Caller supplies buf and nbuf. If do_cxx_demangling is False, don't do
1378 C++ demangling, regardless of VG_(clo_demangle) -- probably because the
1379 call has come from VG_(get_fnname_raw)(). findText
1380 indicates whether we're looking for a text symbol or a data symbol
1381 -- caller must choose one kind or the other. */
1382 static
get_sym_name(Bool do_cxx_demangling,Bool do_z_demangling,Bool do_below_main_renaming,Addr a,Char * buf,Int nbuf,Bool match_anywhere_in_sym,Bool show_offset,Bool findText,PtrdiffT * offsetP)1383 Bool get_sym_name ( Bool do_cxx_demangling, Bool do_z_demangling,
1384 Bool do_below_main_renaming,
1385 Addr a, Char* buf, Int nbuf,
1386 Bool match_anywhere_in_sym, Bool show_offset,
1387 Bool findText, /*OUT*/PtrdiffT* offsetP )
1388 {
1389 DebugInfo* di;
1390 Word sno;
1391 PtrdiffT offset;
1392
1393 search_all_symtabs ( a, &di, &sno, match_anywhere_in_sym, findText );
1394 if (di == NULL)
1395 return False;
1396
1397 vg_assert(di->symtab[sno].pri_name);
1398 VG_(demangle) ( do_cxx_demangling, do_z_demangling,
1399 di->symtab[sno].pri_name, buf, nbuf );
1400
1401 /* Do the below-main hack */
1402 // To reduce the endless nuisance of multiple different names
1403 // for "the frame below main()" screwing up the testsuite, change all
1404 // known incarnations of said into a single name, "(below main)", if
1405 // --show-below-main=yes.
1406 if ( do_below_main_renaming && ! VG_(clo_show_below_main) &&
1407 Vg_FnNameBelowMain == VG_(get_fnname_kind)(buf) )
1408 {
1409 VG_(strncpy_safely)(buf, "(below main)", nbuf);
1410 }
1411 offset = a - di->symtab[sno].addr;
1412 if (offsetP) *offsetP = offset;
1413
1414 if (show_offset && offset != 0) {
1415 Char buf2[12];
1416 Char* symend = buf + VG_(strlen)(buf);
1417 Char* end = buf + nbuf;
1418 Int len;
1419
1420 len = VG_(sprintf)(buf2, "%c%ld",
1421 offset < 0 ? '-' : '+',
1422 offset < 0 ? -offset : offset);
1423 vg_assert(len < (Int)sizeof(buf2));
1424
1425 if (len < (end - symend)) {
1426 Char *cp = buf2;
1427 VG_(memcpy)(symend, cp, len+1);
1428 }
1429 }
1430
1431 buf[nbuf-1] = 0; /* paranoia */
1432
1433 return True;
1434 }
1435
1436 /* ppc64-linux only: find the TOC pointer (R2 value) that should be in
1437 force at the entry point address of the function containing
1438 guest_code_addr. Returns 0 if not known. */
VG_(get_tocptr)1439 Addr VG_(get_tocptr) ( Addr guest_code_addr )
1440 {
1441 DebugInfo* si;
1442 Word sno;
1443 search_all_symtabs ( guest_code_addr,
1444 &si, &sno,
1445 True/*match_anywhere_in_fun*/,
1446 True/*consider text symbols only*/ );
1447 if (si == NULL)
1448 return 0;
1449 else
1450 return si->symtab[sno].tocptr;
1451 }
1452
1453 /* This is available to tools... always demangle C++ names,
1454 match anywhere in function, but don't show offsets. */
VG_(get_fnname)1455 Bool VG_(get_fnname) ( Addr a, Char* buf, Int nbuf )
1456 {
1457 return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True,
1458 /*below-main-renaming*/True,
1459 a, buf, nbuf,
1460 /*match_anywhere_in_fun*/True,
1461 /*show offset?*/False,
1462 /*text syms only*/True,
1463 /*offsetP*/NULL );
1464 }
1465
1466 /* This is available to tools... always demangle C++ names,
1467 match anywhere in function, and show offset if nonzero. */
VG_(get_fnname_w_offset)1468 Bool VG_(get_fnname_w_offset) ( Addr a, Char* buf, Int nbuf )
1469 {
1470 return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True,
1471 /*below-main-renaming*/True,
1472 a, buf, nbuf,
1473 /*match_anywhere_in_fun*/True,
1474 /*show offset?*/True,
1475 /*text syms only*/True,
1476 /*offsetP*/NULL );
1477 }
1478
1479 /* This is available to tools... always demangle C++ names,
1480 only succeed if 'a' matches first instruction of function,
1481 and don't show offsets. */
VG_(get_fnname_if_entry)1482 Bool VG_(get_fnname_if_entry) ( Addr a, Char* buf, Int nbuf )
1483 {
1484 return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True,
1485 /*below-main-renaming*/True,
1486 a, buf, nbuf,
1487 /*match_anywhere_in_fun*/False,
1488 /*show offset?*/False,
1489 /*text syms only*/True,
1490 /*offsetP*/NULL );
1491 }
1492
1493 /* This is only available to core... don't C++-demangle, don't Z-demangle,
1494 don't rename below-main, match anywhere in function, and don't show
1495 offsets. */
VG_(get_fnname_raw)1496 Bool VG_(get_fnname_raw) ( Addr a, Char* buf, Int nbuf )
1497 {
1498 return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False,
1499 /*below-main-renaming*/False,
1500 a, buf, nbuf,
1501 /*match_anywhere_in_fun*/True,
1502 /*show offset?*/False,
1503 /*text syms only*/True,
1504 /*offsetP*/NULL );
1505 }
1506
1507 /* This is only available to core... don't demangle C++ names, but do
1508 do Z-demangling and below-main-renaming, match anywhere in function, and
1509 don't show offsets. */
VG_(get_fnname_no_cxx_demangle)1510 Bool VG_(get_fnname_no_cxx_demangle) ( Addr a, Char* buf, Int nbuf )
1511 {
1512 return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/True,
1513 /*below-main-renaming*/True,
1514 a, buf, nbuf,
1515 /*match_anywhere_in_fun*/True,
1516 /*show offset?*/False,
1517 /*text syms only*/True,
1518 /*offsetP*/NULL );
1519 }
1520
VG_(get_fnname_kind)1521 Vg_FnNameKind VG_(get_fnname_kind) ( Char* name )
1522 {
1523 if (VG_STREQ("main", name)) {
1524 return Vg_FnNameMain;
1525
1526 } else if (
1527 # if defined(VGO_linux)
1528 VG_STREQ("__libc_start_main", name) || // glibc glibness
1529 VG_STREQ("generic_start_main", name) || // Yellow Dog doggedness
1530 # elif defined(VGO_darwin)
1531 // See readmacho.c for an explanation of this.
1532 VG_STREQ("start_according_to_valgrind", name) || // Darwin, darling
1533 # else
1534 # error "Unknown OS"
1535 # endif
1536 0) {
1537 return Vg_FnNameBelowMain;
1538
1539 } else {
1540 return Vg_FnNameNormal;
1541 }
1542 }
1543
VG_(get_fnname_kind_from_IP)1544 Vg_FnNameKind VG_(get_fnname_kind_from_IP) ( Addr ip )
1545 {
1546 // We don't need a big buffer; all the special names are small.
1547 #define BUFLEN 50
1548 Char buf[50];
1549
1550 // We don't demangle, because it's faster not to, and the special names
1551 // we're looking for won't be demangled.
1552 if (VG_(get_fnname_raw) ( ip, buf, BUFLEN )) {
1553 buf[BUFLEN-1] = '\0'; // paranoia
1554 return VG_(get_fnname_kind)(buf);
1555 } else {
1556 return Vg_FnNameNormal; // Don't know the name, treat it as normal.
1557 }
1558 }
1559
1560 /* Looks up data_addr in the collection of data symbols, and if found
1561 puts its name (or as much as will fit) into dname[0 .. n_dname-1],
1562 which is guaranteed to be zero terminated. Also data_addr's offset
1563 from the symbol start is put into *offset. */
VG_(get_datasym_and_offset)1564 Bool VG_(get_datasym_and_offset)( Addr data_addr,
1565 /*OUT*/Char* dname, Int n_dname,
1566 /*OUT*/PtrdiffT* offset )
1567 {
1568 Bool ok;
1569 vg_assert(n_dname > 1);
1570 ok = get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False,
1571 /*below-main-renaming*/False,
1572 data_addr, dname, n_dname,
1573 /*match_anywhere_in_sym*/True,
1574 /*show offset?*/False,
1575 /*data syms only please*/False,
1576 offset );
1577 if (!ok)
1578 return False;
1579 dname[n_dname-1] = 0;
1580 return True;
1581 }
1582
1583 /* Map a code address to the name of a shared object file or the
1584 executable. Returns False if no idea; otherwise True. Doesn't
1585 require debug info. Caller supplies buf and nbuf. */
VG_(get_objname)1586 Bool VG_(get_objname) ( Addr a, Char* buf, Int nbuf )
1587 {
1588 DebugInfo* di;
1589 const NSegment *seg;
1590 HChar* filename;
1591 vg_assert(nbuf > 0);
1592 /* Look in the debugInfo_list to find the name. In most cases we
1593 expect this to produce a result. */
1594 for (di = debugInfo_list; di != NULL; di = di->next) {
1595 if (di->text_present
1596 && di->text_size > 0
1597 && di->text_avma <= a
1598 && a < di->text_avma + di->text_size) {
1599 VG_(strncpy_safely)(buf, di->fsm.filename, nbuf);
1600 buf[nbuf-1] = 0;
1601 return True;
1602 }
1603 }
1604 /* Last-ditch fallback position: if we don't find the address in
1605 the debugInfo_list, ask the address space manager whether it
1606 knows the name of the file associated with this mapping. This
1607 allows us to print the names of exe/dll files in the stack trace
1608 when running programs under wine. */
1609 if ( (seg = VG_(am_find_nsegment(a))) != NULL
1610 && (filename = VG_(am_get_filename)(seg)) != NULL ) {
1611 VG_(strncpy_safely)(buf, filename, nbuf);
1612 return True;
1613 }
1614 return False;
1615 }
1616
1617 /* Map a code address to its DebugInfo. Returns NULL if not found. Doesn't
1618 require debug info. */
VG_(find_DebugInfo)1619 DebugInfo* VG_(find_DebugInfo) ( Addr a )
1620 {
1621 static UWord n_search = 0;
1622 DebugInfo* di;
1623 n_search++;
1624 for (di = debugInfo_list; di != NULL; di = di->next) {
1625 if (di->text_present
1626 && di->text_size > 0
1627 && di->text_avma <= a
1628 && a < di->text_avma + di->text_size) {
1629 if (0 == (n_search & 0xF))
1630 move_DebugInfo_one_step_forward( di );
1631 return di;
1632 }
1633 }
1634 return NULL;
1635 }
1636
1637 /* Map a code address to a filename. Returns True if successful. */
VG_(get_filename)1638 Bool VG_(get_filename)( Addr a, Char* filename, Int n_filename )
1639 {
1640 DebugInfo* si;
1641 Word locno;
1642 search_all_loctabs ( a, &si, &locno );
1643 if (si == NULL)
1644 return False;
1645 VG_(strncpy_safely)(filename, si->loctab[locno].filename, n_filename);
1646 return True;
1647 }
1648
1649 /* Map a code address to a line number. Returns True if successful. */
VG_(get_linenum)1650 Bool VG_(get_linenum)( Addr a, UInt* lineno )
1651 {
1652 DebugInfo* si;
1653 Word locno;
1654 search_all_loctabs ( a, &si, &locno );
1655 if (si == NULL)
1656 return False;
1657 *lineno = si->loctab[locno].lineno;
1658
1659 return True;
1660 }
1661
1662 /* Map a code address to a filename/line number/dir name info.
1663 See prototype for detailed description of behaviour.
1664 */
VG_(get_filename_linenum)1665 Bool VG_(get_filename_linenum) ( Addr a,
1666 /*OUT*/Char* filename, Int n_filename,
1667 /*OUT*/Char* dirname, Int n_dirname,
1668 /*OUT*/Bool* dirname_available,
1669 /*OUT*/UInt* lineno )
1670 {
1671 DebugInfo* si;
1672 Word locno;
1673
1674 vg_assert( (dirname == NULL && dirname_available == NULL)
1675 ||
1676 (dirname != NULL && dirname_available != NULL) );
1677
1678 search_all_loctabs ( a, &si, &locno );
1679 if (si == NULL) {
1680 if (dirname_available) {
1681 *dirname_available = False;
1682 *dirname = 0;
1683 }
1684 return False;
1685 }
1686
1687 VG_(strncpy_safely)(filename, si->loctab[locno].filename, n_filename);
1688 *lineno = si->loctab[locno].lineno;
1689
1690 if (dirname) {
1691 /* caller wants directory info too .. */
1692 vg_assert(n_dirname > 0);
1693 if (si->loctab[locno].dirname) {
1694 /* .. and we have some */
1695 *dirname_available = True;
1696 VG_(strncpy_safely)(dirname, si->loctab[locno].dirname,
1697 n_dirname);
1698 } else {
1699 /* .. but we don't have any */
1700 *dirname_available = False;
1701 *dirname = 0;
1702 }
1703 }
1704
1705 return True;
1706 }
1707
1708
1709 /* Map a function name to its entry point and toc pointer. Is done by
1710 sequential search of all symbol tables, so is very slow. To
1711 mitigate the worst performance effects, you may specify a soname
1712 pattern, and only objects matching that pattern are searched.
1713 Therefore specify "*" to search all the objects. On TOC-afflicted
1714 platforms, a symbol is deemed to be found only if it has a nonzero
1715 TOC pointer. */
VG_(lookup_symbol_SLOW)1716 Bool VG_(lookup_symbol_SLOW)(UChar* sopatt, UChar* name,
1717 Addr* pEnt, Addr* pToc)
1718 {
1719 Bool require_pToc = False;
1720 Int i;
1721 DebugInfo* si;
1722 Bool debug = False;
1723 # if defined(VG_PLAT_USES_PPCTOC)
1724 require_pToc = True;
1725 # endif
1726 for (si = debugInfo_list; si; si = si->next) {
1727 if (debug)
1728 VG_(printf)("lookup_symbol_SLOW: considering %s\n", si->soname);
1729 if (!VG_(string_match)(sopatt, si->soname)) {
1730 if (debug)
1731 VG_(printf)(" ... skip\n");
1732 continue;
1733 }
1734 for (i = 0; i < si->symtab_used; i++) {
1735 UChar* pri_name = si->symtab[i].pri_name;
1736 tl_assert(pri_name);
1737 if (0==VG_(strcmp)(name, pri_name)
1738 && (require_pToc ? si->symtab[i].tocptr : True)) {
1739 *pEnt = si->symtab[i].addr;
1740 *pToc = si->symtab[i].tocptr;
1741 return True;
1742 }
1743 UChar** sec_names = si->symtab[i].sec_names;
1744 if (sec_names) {
1745 tl_assert(sec_names[0]);
1746 while (*sec_names) {
1747 if (0==VG_(strcmp)(name, *sec_names)
1748 && (require_pToc ? si->symtab[i].tocptr : True)) {
1749 *pEnt = si->symtab[i].addr;
1750 *pToc = si->symtab[i].tocptr;
1751 return True;
1752 }
1753 sec_names++;
1754 }
1755 }
1756 }
1757 }
1758 return False;
1759 }
1760
1761
1762 /* VG_(describe_IP): print into buf info on code address, function
1763 name and filename. */
1764
1765 /* Copy str into buf starting at n, but not going past buf[n_buf-1]
1766 and always ensuring that buf is zero-terminated. */
1767
putStr(Int n,Int n_buf,Char * buf,Char * str)1768 static Int putStr ( Int n, Int n_buf, Char* buf, Char* str )
1769 {
1770 vg_assert(n_buf > 0);
1771 vg_assert(n >= 0 && n < n_buf);
1772 for (; n < n_buf-1 && *str != 0; n++,str++)
1773 buf[n] = *str;
1774 vg_assert(n >= 0 && n < n_buf);
1775 buf[n] = '\0';
1776 return n;
1777 }
1778
1779 /* Same as putStr, but escaping chars for XML output, and
1780 also not adding more than count chars to n_buf. */
1781
putStrEsc(Int n,Int n_buf,Int count,Char * buf,Char * str)1782 static Int putStrEsc ( Int n, Int n_buf, Int count, Char* buf, Char* str )
1783 {
1784 Char alt[2];
1785 vg_assert(n_buf > 0);
1786 vg_assert(count >= 0 && count < n_buf);
1787 vg_assert(n >= 0 && n < n_buf);
1788 for (; *str != 0; str++) {
1789 vg_assert(count >= 0);
1790 if (count <= 0)
1791 goto done;
1792 switch (*str) {
1793 case '&':
1794 if (count < 5) goto done;
1795 n = putStr( n, n_buf, buf, "&");
1796 count -= 5;
1797 break;
1798 case '<':
1799 if (count < 4) goto done;
1800 n = putStr( n, n_buf, buf, "<");
1801 count -= 4;
1802 break;
1803 case '>':
1804 if (count < 4) goto done;
1805 n = putStr( n, n_buf, buf, ">");
1806 count -= 4;
1807 break;
1808 default:
1809 if (count < 1) goto done;
1810 alt[0] = *str;
1811 alt[1] = 0;
1812 n = putStr( n, n_buf, buf, alt );
1813 count -= 1;
1814 break;
1815 }
1816 }
1817 done:
1818 vg_assert(count >= 0); /* should not go -ve in loop */
1819 vg_assert(n >= 0 && n < n_buf);
1820 return n;
1821 }
1822
VG_(describe_IP)1823 Char* VG_(describe_IP)(Addr eip, Char* buf, Int n_buf)
1824 {
1825 # define APPEND(_str) \
1826 n = putStr(n, n_buf, buf, _str)
1827 # define APPEND_ESC(_count,_str) \
1828 n = putStrEsc(n, n_buf, (_count), buf, (_str))
1829 # define BUF_LEN 4096
1830
1831 UInt lineno;
1832 UChar ibuf[50];
1833 Int n = 0;
1834
1835 static UChar buf_fn[BUF_LEN];
1836 static UChar buf_obj[BUF_LEN];
1837 static UChar buf_srcloc[BUF_LEN];
1838 static UChar buf_dirname[BUF_LEN];
1839 buf_fn[0] = buf_obj[0] = buf_srcloc[0] = buf_dirname[0] = 0;
1840
1841 Bool know_dirinfo = False;
1842 Bool know_fnname = VG_(clo_sym_offsets)
1843 ? VG_(get_fnname_w_offset) (eip, buf_fn, BUF_LEN)
1844 : VG_(get_fnname) (eip, buf_fn, BUF_LEN);
1845 Bool know_objname = VG_(get_objname)(eip, buf_obj, BUF_LEN);
1846 Bool know_srcloc = VG_(get_filename_linenum)(
1847 eip,
1848 buf_srcloc, BUF_LEN,
1849 buf_dirname, BUF_LEN, &know_dirinfo,
1850 &lineno
1851 );
1852 buf_fn [ sizeof(buf_fn)-1 ] = 0;
1853 buf_obj [ sizeof(buf_obj)-1 ] = 0;
1854 buf_srcloc [ sizeof(buf_srcloc)-1 ] = 0;
1855 buf_dirname[ sizeof(buf_dirname)-1 ] = 0;
1856
1857 if (VG_(clo_xml)) {
1858
1859 Bool human_readable = True;
1860 HChar* maybe_newline = human_readable ? "\n " : "";
1861 HChar* maybe_newline2 = human_readable ? "\n " : "";
1862
1863 /* Print in XML format, dumping in as much info as we know.
1864 Ensure all tags are balanced even if the individual strings
1865 are too long. Allocate 1/10 of BUF_LEN to the object name,
1866 6/10s to the function name, 1/10 to the directory name and
1867 1/10 to the file name, leaving 1/10 for all the fixed-length
1868 stuff. */
1869 APPEND("<frame>");
1870 VG_(sprintf)(ibuf,"<ip>0x%llX</ip>", (ULong)eip);
1871 APPEND(maybe_newline);
1872 APPEND(ibuf);
1873 if (know_objname) {
1874 APPEND(maybe_newline);
1875 APPEND("<obj>");
1876 APPEND_ESC(1*BUF_LEN/10, buf_obj);
1877 APPEND("</obj>");
1878 }
1879 if (know_fnname) {
1880 APPEND(maybe_newline);
1881 APPEND("<fn>");
1882 APPEND_ESC(6*BUF_LEN/10, buf_fn);
1883 APPEND("</fn>");
1884 }
1885 if (know_srcloc) {
1886 if (know_dirinfo) {
1887 APPEND(maybe_newline);
1888 APPEND("<dir>");
1889 APPEND_ESC(1*BUF_LEN/10, buf_dirname);
1890 APPEND("</dir>");
1891 }
1892 APPEND(maybe_newline);
1893 APPEND("<file>");
1894 APPEND_ESC(1*BUF_LEN/10, buf_srcloc);
1895 APPEND("</file>");
1896 APPEND(maybe_newline);
1897 APPEND("<line>");
1898 VG_(sprintf)(ibuf,"%d",lineno);
1899 APPEND(ibuf);
1900 APPEND("</line>");
1901 }
1902 APPEND(maybe_newline2);
1903 APPEND("</frame>");
1904
1905 } else {
1906
1907 /* Print for humans to read */
1908 //
1909 // Possible forms:
1910 //
1911 // 0x80483BF: really (a.c:20)
1912 // 0x80483BF: really (in /foo/a.out)
1913 // 0x80483BF: really (in ???)
1914 // 0x80483BF: ??? (in /foo/a.out)
1915 // 0x80483BF: ??? (a.c:20)
1916 // 0x80483BF: ???
1917 //
1918 VG_(sprintf)(ibuf,"0x%llX: ", (ULong)eip);
1919 APPEND(ibuf);
1920 if (know_fnname) {
1921 APPEND(buf_fn);
1922 } else {
1923 APPEND("???");
1924 }
1925 if (know_srcloc) {
1926 APPEND(" (");
1927 // Get the directory name, if any, possibly pruned, into dirname.
1928 UChar* dirname = NULL;
1929 if (VG_(clo_n_fullpath_after) > 0) {
1930 Int i;
1931 dirname = buf_dirname;
1932 // Remove leading prefixes from the dirname.
1933 // If user supplied --fullpath-after=foo, this will remove
1934 // a leading string which matches '.*foo' (not greedy).
1935 for (i = 0; i < VG_(clo_n_fullpath_after); i++) {
1936 UChar* prefix = VG_(clo_fullpath_after)[i];
1937 UChar* str = VG_(strstr)(dirname, prefix);
1938 if (str) {
1939 dirname = str + VG_(strlen)(prefix);
1940 break;
1941 }
1942 }
1943 /* remove leading "./" */
1944 if (dirname[0] == '.' && dirname[1] == '/')
1945 dirname += 2;
1946 }
1947 // do we have any interesting directory name to show? If so
1948 // add it in.
1949 if (dirname && dirname[0] != 0) {
1950 APPEND(dirname);
1951 APPEND("/");
1952 }
1953 APPEND(buf_srcloc);
1954 APPEND(":");
1955 VG_(sprintf)(ibuf,"%d",lineno);
1956 APPEND(ibuf);
1957 APPEND(")");
1958 } else if (know_objname) {
1959 APPEND(" (in ");
1960 APPEND(buf_obj);
1961 APPEND(")");
1962 } else if (know_fnname) {
1963 // Nb: do this in two steps because "??)" is a trigraph!
1964 APPEND(" (in ???");
1965 APPEND(")");
1966 }
1967
1968 }
1969 return buf;
1970
1971 # undef APPEND
1972 # undef APPEND_ESC
1973 # undef BUF_LEN
1974 }
1975
1976
1977 /*--------------------------------------------------------------*/
1978 /*--- ---*/
1979 /*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/
1980 /*--- DWARF3 .eh_frame INFO ---*/
1981 /*--- ---*/
1982 /*--------------------------------------------------------------*/
1983
1984 /* Gather up all the constant pieces of info needed to evaluate
1985 a CfiExpr into one convenient struct. */
1986 typedef
1987 struct {
1988 D3UnwindRegs* uregs;
1989 Addr min_accessible;
1990 Addr max_accessible;
1991 }
1992 CfiExprEvalContext;
1993
1994 /* Evaluate the CfiExpr rooted at ix in exprs given the context eec.
1995 *ok is set to False on failure, but not to True on success. The
1996 caller must set it to True before calling. */
1997 __attribute__((noinline))
1998 static
evalCfiExpr(XArray * exprs,Int ix,CfiExprEvalContext * eec,Bool * ok)1999 UWord evalCfiExpr ( XArray* exprs, Int ix,
2000 CfiExprEvalContext* eec, Bool* ok )
2001 {
2002 UWord wL, wR;
2003 Addr a;
2004 CfiExpr* e;
2005 vg_assert(sizeof(Addr) == sizeof(UWord));
2006 e = VG_(indexXA)( exprs, ix );
2007 switch (e->tag) {
2008 case Cex_Binop:
2009 wL = evalCfiExpr( exprs, e->Cex.Binop.ixL, eec, ok );
2010 if (!(*ok)) return 0;
2011 wR = evalCfiExpr( exprs, e->Cex.Binop.ixR, eec, ok );
2012 if (!(*ok)) return 0;
2013 switch (e->Cex.Binop.op) {
2014 case Cop_Add: return wL + wR;
2015 case Cop_Sub: return wL - wR;
2016 case Cop_And: return wL & wR;
2017 case Cop_Mul: return wL * wR;
2018 case Cop_Shl: return wL << wR;
2019 case Cop_Shr: return wL >> wR;
2020 case Cop_Eq: return wL == wR ? 1 : 0;
2021 case Cop_Ge: return (Word) wL >= (Word) wR ? 1 : 0;
2022 case Cop_Gt: return (Word) wL > (Word) wR ? 1 : 0;
2023 case Cop_Le: return (Word) wL <= (Word) wR ? 1 : 0;
2024 case Cop_Lt: return (Word) wL < (Word) wR ? 1 : 0;
2025 case Cop_Ne: return wL != wR ? 1 : 0;
2026 default: goto unhandled;
2027 }
2028 /*NOTREACHED*/
2029 case Cex_CfiReg:
2030 switch (e->Cex.CfiReg.reg) {
2031 # if defined(VGA_x86) || defined(VGA_amd64)
2032 case Creg_IA_IP: return eec->uregs->xip;
2033 case Creg_IA_SP: return eec->uregs->xsp;
2034 case Creg_IA_BP: return eec->uregs->xbp;
2035 # elif defined(VGA_arm)
2036 case Creg_ARM_R15: return eec->uregs->r15;
2037 case Creg_ARM_R14: return eec->uregs->r14;
2038 case Creg_ARM_R13: return eec->uregs->r13;
2039 case Creg_ARM_R12: return eec->uregs->r12;
2040 # elif defined(VGA_s390x)
2041 case Creg_IA_IP: return eec->uregs->ia;
2042 case Creg_IA_SP: return eec->uregs->sp;
2043 case Creg_IA_BP: return eec->uregs->fp;
2044 case Creg_S390_R14: return eec->uregs->lr;
2045 # elif defined(VGA_ppc32) || defined(VGA_ppc64)
2046 # else
2047 # error "Unsupported arch"
2048 # endif
2049 default: goto unhandled;
2050 }
2051 /*NOTREACHED*/
2052 case Cex_Const:
2053 return e->Cex.Const.con;
2054 case Cex_Deref:
2055 a = evalCfiExpr( exprs, e->Cex.Deref.ixAddr, eec, ok );
2056 if (!(*ok)) return 0;
2057 if (a < eec->min_accessible
2058 || a > eec->max_accessible - sizeof(UWord) + 1) {
2059 *ok = False;
2060 return 0;
2061 }
2062 /* let's hope it doesn't trap! */
2063 return ML_(read_UWord)((void *)a);
2064 default:
2065 goto unhandled;
2066 }
2067 /*NOTREACHED*/
2068 unhandled:
2069 VG_(printf)("\n\nevalCfiExpr: unhandled\n");
2070 ML_(ppCfiExpr)( exprs, ix );
2071 VG_(printf)("\n");
2072 vg_assert(0);
2073 /*NOTREACHED*/
2074 return 0;
2075 }
2076
2077
2078 /* Search all the DebugInfos in the entire system, to find the DiCfSI
2079 that pertains to 'ip'.
2080
2081 If found, set *diP to the DebugInfo in which it resides, and
2082 *ixP to the index in that DebugInfo's cfsi array.
2083
2084 If not found, set *diP to (DebugInfo*)1 and *ixP to zero.
2085 */
2086 __attribute__((noinline))
find_DiCfSI(DebugInfo ** diP,Word * ixP,Addr ip)2087 static void find_DiCfSI ( /*OUT*/DebugInfo** diP,
2088 /*OUT*/Word* ixP,
2089 Addr ip )
2090 {
2091 DebugInfo* di;
2092 Word i = -1;
2093
2094 static UWord n_search = 0;
2095 static UWord n_steps = 0;
2096 n_search++;
2097
2098 if (0) VG_(printf)("search for %#lx\n", ip);
2099
2100 for (di = debugInfo_list; di != NULL; di = di->next) {
2101 Word j;
2102 n_steps++;
2103
2104 /* Use the per-DebugInfo summary address ranges to skip
2105 inapplicable DebugInfos quickly. */
2106 if (di->cfsi_used == 0)
2107 continue;
2108 if (ip < di->cfsi_minavma || ip > di->cfsi_maxavma)
2109 continue;
2110
2111 /* It might be in this DebugInfo. Search it. */
2112 j = ML_(search_one_cfitab)( di, ip );
2113 vg_assert(j >= -1 && j < (Word)di->cfsi_used);
2114
2115 if (j != -1) {
2116 i = j;
2117 break; /* found it */
2118 }
2119 }
2120
2121 if (i == -1) {
2122
2123 /* we didn't find it. */
2124 *diP = (DebugInfo*)1;
2125 *ixP = 0;
2126
2127 } else {
2128
2129 /* found it. */
2130 /* ensure that di is 4-aligned (at least), so it can't possibly
2131 be equal to (DebugInfo*)1. */
2132 vg_assert(di && VG_IS_4_ALIGNED(di));
2133 vg_assert(i >= 0 && i < di->cfsi_used);
2134 *diP = di;
2135 *ixP = i;
2136
2137 /* Start of performance-enhancing hack: once every 64 (chosen
2138 hackily after profiling) successful searches, move the found
2139 DebugInfo one step closer to the start of the list. This
2140 makes future searches cheaper. For starting konqueror on
2141 amd64, this in fact reduces the total amount of searching
2142 done by the above find-the-right-DebugInfo loop by more than
2143 a factor of 20. */
2144 if ((n_search & 0xF) == 0) {
2145 /* Move di one step closer to the start of the list. */
2146 move_DebugInfo_one_step_forward( di );
2147 }
2148 /* End of performance-enhancing hack. */
2149
2150 if (0 && ((n_search & 0x7FFFF) == 0))
2151 VG_(printf)("find_DiCfSI: %lu searches, "
2152 "%lu DebugInfos looked at\n",
2153 n_search, n_steps);
2154
2155 }
2156
2157 }
2158
2159
2160 /* Now follows a mechanism for caching queries to find_DiCfSI, since
2161 they are extremely frequent on amd64-linux, during stack unwinding.
2162
2163 Each cache entry binds an ip value to a (di, ix) pair. Possible
2164 values:
2165
2166 di is non-null, ix >= 0 ==> cache slot in use, "di->cfsi[ix]"
2167 di is (DebugInfo*)1 ==> cache slot in use, no associated di
2168 di is NULL ==> cache slot not in use
2169
2170 Hence simply zeroing out the entire cache invalidates all
2171 entries.
2172
2173 Why not map ip values directly to DiCfSI*'s? Because this would
2174 cause problems if/when the cfsi array is moved due to resizing.
2175 Instead we cache .cfsi array index value, which should be invariant
2176 across resizing. (That said, I don't think the current
2177 implementation will resize whilst during queries, since the DiCfSI
2178 records are added all at once, when the debuginfo for an object is
2179 read, and is not changed ever thereafter. */
2180
2181 #define N_CFSI_CACHE 511
2182
2183 typedef
2184 struct { Addr ip; DebugInfo* di; Word ix; }
2185 CFSICacheEnt;
2186
2187 static CFSICacheEnt cfsi_cache[N_CFSI_CACHE];
2188
cfsi_cache__invalidate(void)2189 static void cfsi_cache__invalidate ( void ) {
2190 VG_(memset)(&cfsi_cache, 0, sizeof(cfsi_cache));
2191 }
2192
2193
cfsi_cache__find(Addr ip)2194 static inline CFSICacheEnt* cfsi_cache__find ( Addr ip )
2195 {
2196 UWord hash = ip % N_CFSI_CACHE;
2197 CFSICacheEnt* ce = &cfsi_cache[hash];
2198 static UWord n_q = 0, n_m = 0;
2199
2200 n_q++;
2201 if (0 && 0 == (n_q & 0x1FFFFF))
2202 VG_(printf)("QQQ %lu %lu\n", n_q, n_m);
2203
2204 if (LIKELY(ce->ip == ip) && LIKELY(ce->di != NULL)) {
2205 /* found an entry in the cache .. */
2206 } else {
2207 /* not found in cache. Search and update. */
2208 n_m++;
2209 ce->ip = ip;
2210 find_DiCfSI( &ce->di, &ce->ix, ip );
2211 }
2212
2213 if (UNLIKELY(ce->di == (DebugInfo*)1)) {
2214 /* no DiCfSI for this address */
2215 return NULL;
2216 } else {
2217 /* found a DiCfSI for this address */
2218 return ce;
2219 }
2220 }
2221
2222
2223 inline
compute_cfa(D3UnwindRegs * uregs,Addr min_accessible,Addr max_accessible,DebugInfo * di,DiCfSI * cfsi)2224 static Addr compute_cfa ( D3UnwindRegs* uregs,
2225 Addr min_accessible, Addr max_accessible,
2226 DebugInfo* di, DiCfSI* cfsi )
2227 {
2228 CfiExprEvalContext eec;
2229 Addr cfa;
2230 Bool ok;
2231
2232 /* Compute the CFA. */
2233 cfa = 0;
2234 switch (cfsi->cfa_how) {
2235 # if defined(VGA_x86) || defined(VGA_amd64)
2236 case CFIC_IA_SPREL:
2237 cfa = cfsi->cfa_off + uregs->xsp;
2238 break;
2239 case CFIC_IA_BPREL:
2240 cfa = cfsi->cfa_off + uregs->xbp;
2241 break;
2242 # elif defined(VGA_arm)
2243 case CFIC_ARM_R13REL:
2244 cfa = cfsi->cfa_off + uregs->r13;
2245 break;
2246 case CFIC_ARM_R12REL:
2247 cfa = cfsi->cfa_off + uregs->r12;
2248 break;
2249 case CFIC_ARM_R11REL:
2250 cfa = cfsi->cfa_off + uregs->r11;
2251 break;
2252 case CFIC_ARM_R7REL:
2253 cfa = cfsi->cfa_off + uregs->r7;
2254 break;
2255 # elif defined(VGA_s390x)
2256 case CFIC_IA_SPREL:
2257 cfa = cfsi->cfa_off + uregs->sp;
2258 break;
2259 case CFIR_MEMCFAREL:
2260 {
2261 Addr a = uregs->sp + cfsi->cfa_off;
2262 if (a < min_accessible || a > max_accessible-sizeof(Addr))
2263 break;
2264 cfa = ML_(read_Addr)((void *)a);
2265 break;
2266 }
2267 case CFIR_SAME:
2268 cfa = uregs->fp;
2269 break;
2270 case CFIC_IA_BPREL:
2271 cfa = cfsi->cfa_off + uregs->fp;
2272 break;
2273 # elif defined(VGA_ppc32) || defined(VGA_ppc64)
2274 # else
2275 # error "Unsupported arch"
2276 # endif
2277 case CFIC_EXPR: /* available on all archs */
2278 if (0) {
2279 VG_(printf)("CFIC_EXPR: ");
2280 ML_(ppCfiExpr)(di->cfsi_exprs, cfsi->cfa_off);
2281 VG_(printf)("\n");
2282 }
2283 eec.uregs = uregs;
2284 eec.min_accessible = min_accessible;
2285 eec.max_accessible = max_accessible;
2286 ok = True;
2287 cfa = evalCfiExpr(di->cfsi_exprs, cfsi->cfa_off, &eec, &ok );
2288 if (!ok) return 0;
2289 break;
2290 default:
2291 vg_assert(0);
2292 }
2293 return cfa;
2294 }
2295
2296
2297 /* Get the call frame address (CFA) given an IP/SP/FP triple. */
2298 /* NOTE: This function may rearrange the order of entries in the
2299 DebugInfo list. */
ML_(get_CFA)2300 Addr ML_(get_CFA) ( Addr ip, Addr sp, Addr fp,
2301 Addr min_accessible, Addr max_accessible )
2302 {
2303 CFSICacheEnt* ce;
2304 DebugInfo* di;
2305 DiCfSI* cfsi __attribute__((unused));
2306
2307 ce = cfsi_cache__find(ip);
2308
2309 if (UNLIKELY(ce == NULL))
2310 return 0; /* no info. Nothing we can do. */
2311
2312 di = ce->di;
2313 cfsi = &di->cfsi[ ce->ix ];
2314
2315 /* Temporary impedance-matching kludge so that this keeps working
2316 on x86-linux and amd64-linux. */
2317 # if defined(VGA_x86) || defined(VGA_amd64)
2318 { D3UnwindRegs uregs;
2319 uregs.xip = ip;
2320 uregs.xsp = sp;
2321 uregs.xbp = fp;
2322 return compute_cfa(&uregs,
2323 min_accessible, max_accessible, di, cfsi);
2324 }
2325 #elif defined(VGA_s390x)
2326 { D3UnwindRegs uregs;
2327 uregs.ia = ip;
2328 uregs.sp = sp;
2329 uregs.fp = fp;
2330 return compute_cfa(&uregs,
2331 min_accessible, max_accessible, di, cfsi);
2332 }
2333
2334 # else
2335 return 0; /* indicates failure */
2336 # endif
2337 }
2338
2339
2340 /* The main function for DWARF2/3 CFI-based stack unwinding. Given a
2341 set of registers in UREGS, modify it to hold the register values
2342 for the previous frame, if possible. Returns True if successful.
2343 If not successful, *UREGS is not changed.
2344
2345 For x86 and amd64, the unwound registers are: {E,R}IP,
2346 {E,R}SP, {E,R}BP.
2347
2348 For arm, the unwound registers are: R7 R11 R12 R13 R14 R15.
2349 */
VG_(use_CF_info)2350 Bool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere,
2351 Addr min_accessible,
2352 Addr max_accessible )
2353 {
2354 DebugInfo* di;
2355 DiCfSI* cfsi = NULL;
2356 Addr cfa, ipHere = 0;
2357 CFSICacheEnt* ce;
2358 CfiExprEvalContext eec __attribute__((unused));
2359 D3UnwindRegs uregsPrev;
2360
2361 # if defined(VGA_x86) || defined(VGA_amd64)
2362 ipHere = uregsHere->xip;
2363 # elif defined(VGA_arm)
2364 ipHere = uregsHere->r15;
2365 # elif defined(VGA_s390x)
2366 ipHere = uregsHere->ia;
2367 # elif defined(VGA_ppc32) || defined(VGA_ppc64)
2368 # else
2369 # error "Unknown arch"
2370 # endif
2371 ce = cfsi_cache__find(ipHere);
2372
2373 if (UNLIKELY(ce == NULL))
2374 return False; /* no info. Nothing we can do. */
2375
2376 di = ce->di;
2377 cfsi = &di->cfsi[ ce->ix ];
2378
2379 if (0) {
2380 VG_(printf)("found cfisi: ");
2381 ML_(ppDiCfSI)(di->cfsi_exprs, cfsi);
2382 }
2383
2384 VG_(bzero_inline)(&uregsPrev, sizeof(uregsPrev));
2385
2386 /* First compute the CFA. */
2387 cfa = compute_cfa(uregsHere,
2388 min_accessible, max_accessible, di, cfsi);
2389 if (UNLIKELY(cfa == 0))
2390 return False;
2391
2392 /* Now we know the CFA, use it to roll back the registers we're
2393 interested in. */
2394
2395 # define COMPUTE(_prev, _here, _how, _off) \
2396 do { \
2397 switch (_how) { \
2398 case CFIR_UNKNOWN: \
2399 return False; \
2400 case CFIR_SAME: \
2401 _prev = _here; break; \
2402 case CFIR_MEMCFAREL: { \
2403 Addr a = cfa + (Word)_off; \
2404 if (a < min_accessible \
2405 || a > max_accessible-sizeof(Addr)) \
2406 return False; \
2407 _prev = ML_(read_Addr)((void *)a); \
2408 break; \
2409 } \
2410 case CFIR_CFAREL: \
2411 _prev = cfa + (Word)_off; \
2412 break; \
2413 case CFIR_EXPR: \
2414 if (0) \
2415 ML_(ppCfiExpr)(di->cfsi_exprs,_off); \
2416 eec.uregs = uregsHere; \
2417 eec.min_accessible = min_accessible; \
2418 eec.max_accessible = max_accessible; \
2419 Bool ok = True; \
2420 _prev = evalCfiExpr(di->cfsi_exprs, _off, &eec, &ok ); \
2421 if (!ok) return False; \
2422 break; \
2423 default: \
2424 vg_assert(0); \
2425 } \
2426 } while (0)
2427
2428 # if defined(VGA_x86) || defined(VGA_amd64)
2429 COMPUTE(uregsPrev.xip, uregsHere->xip, cfsi->ra_how, cfsi->ra_off);
2430 COMPUTE(uregsPrev.xsp, uregsHere->xsp, cfsi->sp_how, cfsi->sp_off);
2431 COMPUTE(uregsPrev.xbp, uregsHere->xbp, cfsi->bp_how, cfsi->bp_off);
2432 # elif defined(VGA_arm)
2433 COMPUTE(uregsPrev.r15, uregsHere->r15, cfsi->ra_how, cfsi->ra_off);
2434 COMPUTE(uregsPrev.r14, uregsHere->r14, cfsi->r14_how, cfsi->r14_off);
2435 COMPUTE(uregsPrev.r13, uregsHere->r13, cfsi->r13_how, cfsi->r13_off);
2436 COMPUTE(uregsPrev.r12, uregsHere->r12, cfsi->r12_how, cfsi->r12_off);
2437 COMPUTE(uregsPrev.r11, uregsHere->r11, cfsi->r11_how, cfsi->r11_off);
2438 COMPUTE(uregsPrev.r7, uregsHere->r7, cfsi->r7_how, cfsi->r7_off);
2439 # elif defined(VGA_s390x)
2440 COMPUTE(uregsPrev.ia, uregsHere->ia, cfsi->ra_how, cfsi->ra_off);
2441 COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi->sp_how, cfsi->sp_off);
2442 COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi->fp_how, cfsi->fp_off);
2443 # elif defined(VGA_ppc32) || defined(VGA_ppc64)
2444 # else
2445 # error "Unknown arch"
2446 # endif
2447
2448 # undef COMPUTE
2449
2450 *uregsHere = uregsPrev;
2451 return True;
2452 }
2453
2454
2455 /*--------------------------------------------------------------*/
2456 /*--- ---*/
2457 /*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/
2458 /*--- MSVC FPO INFO ---*/
2459 /*--- ---*/
2460 /*--------------------------------------------------------------*/
2461
VG_(use_FPO_info)2462 Bool VG_(use_FPO_info) ( /*MOD*/Addr* ipP,
2463 /*MOD*/Addr* spP,
2464 /*MOD*/Addr* fpP,
2465 Addr min_accessible,
2466 Addr max_accessible )
2467 {
2468 Word i;
2469 DebugInfo* di;
2470 FPO_DATA* fpo = NULL;
2471 Addr spHere;
2472
2473 static UWord n_search = 0;
2474 static UWord n_steps = 0;
2475 n_search++;
2476
2477 if (0) VG_(printf)("search FPO for %#lx\n", *ipP);
2478
2479 for (di = debugInfo_list; di != NULL; di = di->next) {
2480 n_steps++;
2481
2482 /* Use the per-DebugInfo summary address ranges to skip
2483 inapplicable DebugInfos quickly. */
2484 if (di->fpo == NULL)
2485 continue;
2486 if (*ipP < di->fpo_minavma || *ipP > di->fpo_maxavma)
2487 continue;
2488
2489 i = ML_(search_one_fpotab)( di, *ipP );
2490 if (i != -1) {
2491 Word j;
2492 if (0) {
2493 /* debug printing only */
2494 VG_(printf)("look for %#lx size %ld i %ld\n",
2495 *ipP, di->fpo_size, i);
2496 for (j = 0; j < di->fpo_size; j++)
2497 VG_(printf)("[%02ld] %#x %d\n",
2498 j, di->fpo[j].ulOffStart, di->fpo[j].cbProcSize);
2499 }
2500 vg_assert(i >= 0 && i < di->fpo_size);
2501 fpo = &di->fpo[i];
2502 break;
2503 }
2504 }
2505
2506 if (fpo == NULL)
2507 return False;
2508
2509 if (0 && ((n_search & 0x7FFFF) == 0))
2510 VG_(printf)("VG_(use_FPO_info): %lu searches, "
2511 "%lu DebugInfos looked at\n",
2512 n_search, n_steps);
2513
2514
2515 /* Start of performance-enhancing hack: once every 64 (chosen
2516 hackily after profiling) successful searches, move the found
2517 DebugInfo one step closer to the start of the list. This makes
2518 future searches cheaper. For starting konqueror on amd64, this
2519 in fact reduces the total amount of searching done by the above
2520 find-the-right-DebugInfo loop by more than a factor of 20. */
2521 if ((n_search & 0x3F) == 0) {
2522 /* Move si one step closer to the start of the list. */
2523 //move_DebugInfo_one_step_forward( di );
2524 }
2525 /* End of performance-enhancing hack. */
2526
2527 if (0) {
2528 VG_(printf)("found fpo: ");
2529 //ML_(ppFPO)(fpo);
2530 }
2531
2532 /*
2533 Stack layout is:
2534 %esp->
2535 4*.cbRegs {%edi, %esi, %ebp, %ebx}
2536 4*.cdwLocals
2537 return_pc
2538 4*.cdwParams
2539 prior_%esp->
2540
2541 Typical code looks like:
2542 sub $4*.cdwLocals,%esp
2543 Alternative to above for >=4KB (and sometimes for smaller):
2544 mov $size,%eax
2545 call __chkstk # WinNT performs page-by-page probe!
2546 __chkstk is much like alloc(), except that on return
2547 %eax= 5+ &CALL. Thus it could be used as part of
2548 Position Independent Code to locate the Global Offset Table.
2549 push %ebx
2550 push %ebp
2551 push %esi
2552 Other once-only instructions often scheduled >here<.
2553 push %edi
2554
2555 If the pc is within the first .cbProlog bytes of the function,
2556 then you must disassemble to see how many registers have been pushed,
2557 because instructions in the prolog may be scheduled for performance.
2558 The order of PUSH is always %ebx, %ebp, %esi, %edi, with trailing
2559 registers not pushed when .cbRegs < 4. This seems somewhat strange
2560 because %ebp is the register whose usage you want to minimize,
2561 yet it is in the first half of the PUSH list.
2562
2563 I don't know what happens when the compiler constructs an outgoing CALL.
2564 %esp could move if outgoing parameters are PUSHed, and this affects
2565 traceback for errors during the PUSHes. */
2566
2567 spHere = *spP;
2568
2569 *ipP = ML_(read_Addr)((void *)(spHere + 4*(fpo->cbRegs + fpo->cdwLocals)));
2570 *spP = spHere + 4*(fpo->cbRegs + fpo->cdwLocals + 1
2571 + fpo->cdwParams);
2572 *fpP = ML_(read_Addr)((void *)(spHere + 4*2));
2573 return True;
2574 }
2575
2576
2577 /*--------------------------------------------------------------*/
2578 /*--- ---*/
2579 /*--- TOP LEVEL: GENERATE DESCRIPTION OF DATA ADDRESSES ---*/
2580 /*--- FROM DWARF3 DEBUG INFO ---*/
2581 /*--- ---*/
2582 /*--------------------------------------------------------------*/
2583
2584 /* Try to make p2XA(dst, fmt, args..) turn into
2585 VG_(xaprintf)(dst, fmt, args) without having to resort to
2586 vararg macros. As usual with everything to do with varargs, it's
2587 an ugly hack.
2588
2589 //#define p2XA(dstxa, format, args...)
2590 // VG_(xaprintf)(dstxa, format, ##args)
2591 */
2592 #define p2XA VG_(xaprintf)
2593
2594 /* Add a zero-terminating byte to DST, which must be an XArray* of
2595 HChar. */
zterm_XA(XArray * dst)2596 static void zterm_XA ( XArray* dst )
2597 {
2598 HChar zero = 0;
2599 (void) VG_(addBytesToXA)( dst, &zero, 1 );
2600 }
2601
2602
2603 /* Evaluate the location expression/list for var, to see whether or
2604 not data_addr falls within the variable. If so also return the
2605 offset of data_addr from the start of the variable. Note that
2606 regs, which supplies ip,sp,fp values, will be NULL for global
2607 variables, and non-NULL for local variables. */
data_address_is_in_var(PtrdiffT * offset,XArray * tyents,DiVariable * var,RegSummary * regs,Addr data_addr,const DebugInfo * di)2608 static Bool data_address_is_in_var ( /*OUT*/PtrdiffT* offset,
2609 XArray* /* TyEnt */ tyents,
2610 DiVariable* var,
2611 RegSummary* regs,
2612 Addr data_addr,
2613 const DebugInfo* di )
2614 {
2615 MaybeULong mul;
2616 SizeT var_szB;
2617 GXResult res;
2618 Bool show = False;
2619
2620 vg_assert(var->name);
2621 vg_assert(var->gexpr);
2622
2623 /* Figure out how big the variable is. */
2624 mul = ML_(sizeOfType)(tyents, var->typeR);
2625 /* If this var has a type whose size is unknown, zero, or
2626 impossibly large, it should never have been added. ML_(addVar)
2627 should have rejected it. */
2628 vg_assert(mul.b == True);
2629 vg_assert(mul.ul > 0);
2630 if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
2631 /* After this point, we assume we can truncate mul.ul to a host word
2632 safely (without loss of info). */
2633
2634 var_szB = (SizeT)mul.ul; /* NB: truncate to host word */
2635
2636 if (show) {
2637 VG_(printf)("VVVV: data_address_%#lx_is_in_var: %s :: ",
2638 data_addr, var->name );
2639 ML_(pp_TyEnt_C_ishly)( tyents, var->typeR );
2640 VG_(printf)("\n");
2641 }
2642
2643 /* ignore zero-sized vars; they can never match anything. */
2644 if (var_szB == 0) {
2645 if (show)
2646 VG_(printf)("VVVV: -> Fail (variable is zero sized)\n");
2647 return False;
2648 }
2649
2650 res = ML_(evaluate_GX)( var->gexpr, var->fbGX, regs, di );
2651
2652 if (show) {
2653 VG_(printf)("VVVV: -> ");
2654 ML_(pp_GXResult)( res );
2655 VG_(printf)("\n");
2656 }
2657
2658 if (res.kind == GXR_Addr
2659 && res.word <= data_addr
2660 && data_addr < res.word + var_szB) {
2661 *offset = data_addr - res.word;
2662 return True;
2663 } else {
2664 return False;
2665 }
2666 }
2667
2668
2669 /* Format the acquired information into DN(AME)1 and DN(AME)2, which
2670 are XArray*s of HChar, that have been initialised by the caller.
2671 Resulting strings will be zero terminated. Information is
2672 formatted in an understandable way. Not so easy. If frameNo is
2673 -1, this is assumed to be a global variable; else a local
2674 variable. */
format_message(XArray * dn1,XArray * dn2,Addr data_addr,DiVariable * var,PtrdiffT var_offset,PtrdiffT residual_offset,XArray * described,Int frameNo,ThreadId tid)2675 static void format_message ( /*MOD*/XArray* /* of HChar */ dn1,
2676 /*MOD*/XArray* /* of HChar */ dn2,
2677 Addr data_addr,
2678 DiVariable* var,
2679 PtrdiffT var_offset,
2680 PtrdiffT residual_offset,
2681 XArray* /*UChar*/ described,
2682 Int frameNo,
2683 ThreadId tid )
2684 {
2685 Bool have_descr, have_srcloc;
2686 Bool xml = VG_(clo_xml);
2687 UChar* vo_plural = var_offset == 1 ? "" : "s";
2688 UChar* ro_plural = residual_offset == 1 ? "" : "s";
2689 UChar* basetag = "auxwhat"; /* a constant */
2690 UChar tagL[32], tagR[32], xagL[32], xagR[32];
2691
2692 if (frameNo < -1) {
2693 vg_assert(0); /* Not allowed */
2694 }
2695 else if (frameNo == -1) {
2696 vg_assert(tid == VG_INVALID_THREADID);
2697 }
2698 else /* (frameNo >= 0) */ {
2699 vg_assert(tid != VG_INVALID_THREADID);
2700 }
2701
2702 vg_assert(dn1 && dn2);
2703 vg_assert(described);
2704 vg_assert(var && var->name);
2705 have_descr = VG_(sizeXA)(described) > 0
2706 && *(UChar*)VG_(indexXA)(described,0) != '\0';
2707 have_srcloc = var->fileName && var->lineNo > 0;
2708
2709 tagL[0] = tagR[0] = xagL[0] = xagR[0] = 0;
2710 if (xml) {
2711 VG_(sprintf)(tagL, "<%s>", basetag); // <auxwhat>
2712 VG_(sprintf)(tagR, "</%s>", basetag); // </auxwhat>
2713 VG_(sprintf)(xagL, "<x%s>", basetag); // <xauxwhat>
2714 VG_(sprintf)(xagR, "</x%s>", basetag); // </xauxwhat>
2715 }
2716
2717 # define TAGL(_xa) p2XA(_xa, "%s", tagL)
2718 # define TAGR(_xa) p2XA(_xa, "%s", tagR)
2719 # define XAGL(_xa) p2XA(_xa, "%s", xagL)
2720 # define XAGR(_xa) p2XA(_xa, "%s", xagR)
2721 # define TXTL(_xa) p2XA(_xa, "%s", "<text>")
2722 # define TXTR(_xa) p2XA(_xa, "%s", "</text>")
2723
2724 /* ------ local cases ------ */
2725
2726 if ( frameNo >= 0 && (!have_srcloc) && (!have_descr) ) {
2727 /* no srcloc, no description:
2728 Location 0x7fefff6cf is 543 bytes inside local var "a",
2729 in frame #1 of thread 1
2730 */
2731 if (xml) {
2732 TAGL( dn1 );
2733 p2XA( dn1,
2734 "Location 0x%lx is %lu byte%s inside local var \"%pS\",",
2735 data_addr, var_offset, vo_plural, var->name );
2736 TAGR( dn1 );
2737 TAGL( dn2 );
2738 p2XA( dn2,
2739 "in frame #%d of thread %d", frameNo, (Int)tid );
2740 TAGR( dn2 );
2741 } else {
2742 p2XA( dn1,
2743 "Location 0x%lx is %lu byte%s inside local var \"%s\",",
2744 data_addr, var_offset, vo_plural, var->name );
2745 p2XA( dn2,
2746 "in frame #%d of thread %d", frameNo, (Int)tid );
2747 }
2748 }
2749 else
2750 if ( frameNo >= 0 && have_srcloc && (!have_descr) ) {
2751 /* no description:
2752 Location 0x7fefff6cf is 543 bytes inside local var "a"
2753 declared at dsyms7.c:17, in frame #1 of thread 1
2754 */
2755 if (xml) {
2756 TAGL( dn1 );
2757 p2XA( dn1,
2758 "Location 0x%lx is %lu byte%s inside local var \"%pS\"",
2759 data_addr, var_offset, vo_plural, var->name );
2760 TAGR( dn1 );
2761 XAGL( dn2 );
2762 TXTL( dn2 );
2763 p2XA( dn2,
2764 "declared at %pS:%d, in frame #%d of thread %d",
2765 var->fileName, var->lineNo, frameNo, (Int)tid );
2766 TXTR( dn2 );
2767 // FIXME: also do <dir>
2768 p2XA( dn2,
2769 " <file>%pS</file> <line>%d</line> ",
2770 var->fileName, var->lineNo );
2771 XAGR( dn2 );
2772 } else {
2773 p2XA( dn1,
2774 "Location 0x%lx is %lu byte%s inside local var \"%s\"",
2775 data_addr, var_offset, vo_plural, var->name );
2776 p2XA( dn2,
2777 "declared at %s:%d, in frame #%d of thread %d",
2778 var->fileName, var->lineNo, frameNo, (Int)tid );
2779 }
2780 }
2781 else
2782 if ( frameNo >= 0 && (!have_srcloc) && have_descr ) {
2783 /* no srcloc:
2784 Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2
2785 in frame #1 of thread 1
2786 */
2787 if (xml) {
2788 TAGL( dn1 );
2789 p2XA( dn1,
2790 "Location 0x%lx is %lu byte%s inside %pS%pS",
2791 data_addr, residual_offset, ro_plural, var->name,
2792 (HChar*)(VG_(indexXA)(described,0)) );
2793 TAGR( dn1 );
2794 TAGL( dn2 );
2795 p2XA( dn2,
2796 "in frame #%d of thread %d", frameNo, (Int)tid );
2797 TAGR( dn2 );
2798 } else {
2799 p2XA( dn1,
2800 "Location 0x%lx is %lu byte%s inside %s%s",
2801 data_addr, residual_offset, ro_plural, var->name,
2802 (HChar*)(VG_(indexXA)(described,0)) );
2803 p2XA( dn2,
2804 "in frame #%d of thread %d", frameNo, (Int)tid );
2805 }
2806 }
2807 else
2808 if ( frameNo >= 0 && have_srcloc && have_descr ) {
2809 /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
2810 declared at dsyms7.c:17, in frame #1 of thread 1 */
2811 if (xml) {
2812 TAGL( dn1 );
2813 p2XA( dn1,
2814 "Location 0x%lx is %lu byte%s inside %pS%pS,",
2815 data_addr, residual_offset, ro_plural, var->name,
2816 (HChar*)(VG_(indexXA)(described,0)) );
2817 TAGR( dn1 );
2818 XAGL( dn2 );
2819 TXTL( dn2 );
2820 p2XA( dn2,
2821 "declared at %pS:%d, in frame #%d of thread %d",
2822 var->fileName, var->lineNo, frameNo, (Int)tid );
2823 TXTR( dn2 );
2824 // FIXME: also do <dir>
2825 p2XA( dn2,
2826 " <file>%pS</file> <line>%d</line> ",
2827 var->fileName, var->lineNo );
2828 XAGR( dn2 );
2829 } else {
2830 p2XA( dn1,
2831 "Location 0x%lx is %lu byte%s inside %s%s,",
2832 data_addr, residual_offset, ro_plural, var->name,
2833 (HChar*)(VG_(indexXA)(described,0)) );
2834 p2XA( dn2,
2835 "declared at %s:%d, in frame #%d of thread %d",
2836 var->fileName, var->lineNo, frameNo, (Int)tid );
2837 }
2838 }
2839 else
2840 /* ------ global cases ------ */
2841 if ( frameNo >= -1 && (!have_srcloc) && (!have_descr) ) {
2842 /* no srcloc, no description:
2843 Location 0x7fefff6cf is 543 bytes inside global var "a"
2844 */
2845 if (xml) {
2846 TAGL( dn1 );
2847 p2XA( dn1,
2848 "Location 0x%lx is %lu byte%s inside global var \"%pS\"",
2849 data_addr, var_offset, vo_plural, var->name );
2850 TAGR( dn1 );
2851 } else {
2852 p2XA( dn1,
2853 "Location 0x%lx is %lu byte%s inside global var \"%s\"",
2854 data_addr, var_offset, vo_plural, var->name );
2855 }
2856 }
2857 else
2858 if ( frameNo >= -1 && have_srcloc && (!have_descr) ) {
2859 /* no description:
2860 Location 0x7fefff6cf is 543 bytes inside global var "a"
2861 declared at dsyms7.c:17
2862 */
2863 if (xml) {
2864 TAGL( dn1 );
2865 p2XA( dn1,
2866 "Location 0x%lx is %lu byte%s inside global var \"%pS\"",
2867 data_addr, var_offset, vo_plural, var->name );
2868 TAGR( dn1 );
2869 XAGL( dn2 );
2870 TXTL( dn2 );
2871 p2XA( dn2,
2872 "declared at %pS:%d",
2873 var->fileName, var->lineNo);
2874 TXTR( dn2 );
2875 // FIXME: also do <dir>
2876 p2XA( dn2,
2877 " <file>%pS</file> <line>%d</line> ",
2878 var->fileName, var->lineNo );
2879 XAGR( dn2 );
2880 } else {
2881 p2XA( dn1,
2882 "Location 0x%lx is %lu byte%s inside global var \"%s\"",
2883 data_addr, var_offset, vo_plural, var->name );
2884 p2XA( dn2,
2885 "declared at %s:%d",
2886 var->fileName, var->lineNo);
2887 }
2888 }
2889 else
2890 if ( frameNo >= -1 && (!have_srcloc) && have_descr ) {
2891 /* no srcloc:
2892 Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
2893 a global variable
2894 */
2895 if (xml) {
2896 TAGL( dn1 );
2897 p2XA( dn1,
2898 "Location 0x%lx is %lu byte%s inside %pS%pS,",
2899 data_addr, residual_offset, ro_plural, var->name,
2900 (HChar*)(VG_(indexXA)(described,0)) );
2901 TAGR( dn1 );
2902 TAGL( dn2 );
2903 p2XA( dn2,
2904 "a global variable");
2905 TAGR( dn2 );
2906 } else {
2907 p2XA( dn1,
2908 "Location 0x%lx is %lu byte%s inside %s%s,",
2909 data_addr, residual_offset, ro_plural, var->name,
2910 (char*)(VG_(indexXA)(described,0)) );
2911 p2XA( dn2,
2912 "a global variable");
2913 }
2914 }
2915 else
2916 if ( frameNo >= -1 && have_srcloc && have_descr ) {
2917 /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
2918 a global variable declared at dsyms7.c:17 */
2919 if (xml) {
2920 TAGL( dn1 );
2921 p2XA( dn1,
2922 "Location 0x%lx is %lu byte%s inside %pS%pS,",
2923 data_addr, residual_offset, ro_plural, var->name,
2924 (HChar*)(VG_(indexXA)(described,0)) );
2925 TAGR( dn1 );
2926 XAGL( dn2 );
2927 TXTL( dn2 );
2928 p2XA( dn2,
2929 "a global variable declared at %pS:%d",
2930 var->fileName, var->lineNo);
2931 TXTR( dn2 );
2932 // FIXME: also do <dir>
2933 p2XA( dn2,
2934 " <file>%pS</file> <line>%d</line> ",
2935 var->fileName, var->lineNo );
2936 XAGR( dn2 );
2937 } else {
2938 p2XA( dn1,
2939 "Location 0x%lx is %lu byte%s inside %s%s,",
2940 data_addr, residual_offset, ro_plural, var->name,
2941 (HChar*)(VG_(indexXA)(described,0)) );
2942 p2XA( dn2,
2943 "a global variable declared at %s:%d",
2944 var->fileName, var->lineNo);
2945 }
2946 }
2947 else
2948 vg_assert(0);
2949
2950 /* Zero terminate both strings */
2951 zterm_XA( dn1 );
2952 zterm_XA( dn2 );
2953
2954 # undef TAGL
2955 # undef TAGR
2956 # undef XAGL
2957 # undef XAGR
2958 # undef TXTL
2959 # undef TXTR
2960 }
2961
2962
2963 /* Determine if data_addr is a local variable in the frame
2964 characterised by (ip,sp,fp), and if so write its description at the
2965 ends of DNAME{1,2}, which are XArray*s of HChar, that have been
2966 initialised by the caller, zero terminate both, and return True.
2967 If it's not a local variable in said frame, return False. */
2968 static
consider_vars_in_frame(XArray * dname1,XArray * dname2,Addr data_addr,Addr ip,Addr sp,Addr fp,ThreadId tid,Int frameNo)2969 Bool consider_vars_in_frame ( /*MOD*/XArray* /* of HChar */ dname1,
2970 /*MOD*/XArray* /* of HChar */ dname2,
2971 Addr data_addr,
2972 Addr ip, Addr sp, Addr fp,
2973 /* shown to user: */
2974 ThreadId tid, Int frameNo )
2975 {
2976 Word i;
2977 DebugInfo* di;
2978 RegSummary regs;
2979 Bool debug = False;
2980
2981 static UInt n_search = 0;
2982 static UInt n_steps = 0;
2983 n_search++;
2984 if (debug)
2985 VG_(printf)("QQQQ: cvif: ip,sp,fp %#lx,%#lx,%#lx\n", ip,sp,fp);
2986 /* first, find the DebugInfo that pertains to 'ip'. */
2987 for (di = debugInfo_list; di; di = di->next) {
2988 n_steps++;
2989 /* text segment missing? unlikely, but handle it .. */
2990 if (!di->text_present || di->text_size == 0)
2991 continue;
2992 /* Ok. So does this text mapping bracket the ip? */
2993 if (di->text_avma <= ip && ip < di->text_avma + di->text_size)
2994 break;
2995 }
2996
2997 /* Didn't find it. Strange -- means ip is a code address outside
2998 of any mapped text segment. Unlikely but not impossible -- app
2999 could be generating code to run. */
3000 if (!di)
3001 return False;
3002
3003 if (0 && ((n_search & 0x1) == 0))
3004 VG_(printf)("consider_vars_in_frame: %u searches, "
3005 "%u DebugInfos looked at\n",
3006 n_search, n_steps);
3007 /* Start of performance-enhancing hack: once every ??? (chosen
3008 hackily after profiling) successful searches, move the found
3009 DebugInfo one step closer to the start of the list. This makes
3010 future searches cheaper. */
3011 if ((n_search & 0xFFFF) == 0) {
3012 /* Move si one step closer to the start of the list. */
3013 move_DebugInfo_one_step_forward( di );
3014 }
3015 /* End of performance-enhancing hack. */
3016
3017 /* any var info at all? */
3018 if (!di->varinfo)
3019 return False;
3020
3021 /* Work through the scopes from most deeply nested outwards,
3022 looking for code address ranges that bracket 'ip'. The
3023 variables on each such address range found are in scope right
3024 now. Don't descend to level zero as that is the global
3025 scope. */
3026 regs.ip = ip;
3027 regs.sp = sp;
3028 regs.fp = fp;
3029
3030 /* "for each scope, working outwards ..." */
3031 for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) {
3032 XArray* vars;
3033 Word j;
3034 DiAddrRange* arange;
3035 OSet* this_scope
3036 = *(OSet**)VG_(indexXA)( di->varinfo, i );
3037 if (debug)
3038 VG_(printf)("QQQQ: considering scope %ld\n", (Word)i);
3039 if (!this_scope)
3040 continue;
3041 /* Find the set of variables in this scope that
3042 bracket the program counter. */
3043 arange = VG_(OSetGen_LookupWithCmp)(
3044 this_scope, &ip,
3045 ML_(cmp_for_DiAddrRange_range)
3046 );
3047 if (!arange)
3048 continue;
3049 /* stay sane */
3050 vg_assert(arange->aMin <= arange->aMax);
3051 /* It must bracket the ip we asked for, else
3052 ML_(cmp_for_DiAddrRange_range) is somehow broken. */
3053 vg_assert(arange->aMin <= ip && ip <= arange->aMax);
3054 /* It must have an attached XArray of DiVariables. */
3055 vars = arange->vars;
3056 vg_assert(vars);
3057 /* But it mustn't cover the entire address range. We only
3058 expect that to happen for the global scope (level 0), which
3059 we're not looking at here. Except, it may cover the entire
3060 address range, but in that case the vars array must be
3061 empty. */
3062 vg_assert(! (arange->aMin == (Addr)0
3063 && arange->aMax == ~(Addr)0
3064 && VG_(sizeXA)(vars) > 0) );
3065 for (j = 0; j < VG_(sizeXA)( vars ); j++) {
3066 DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j );
3067 PtrdiffT offset;
3068 if (debug)
3069 VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n",
3070 var->name,arange->aMin,arange->aMax,ip);
3071 if (data_address_is_in_var( &offset, di->admin_tyents,
3072 var, ®s,
3073 data_addr, di )) {
3074 PtrdiffT residual_offset = 0;
3075 XArray* described = ML_(describe_type)( &residual_offset,
3076 di->admin_tyents,
3077 var->typeR, offset );
3078 format_message( dname1, dname2,
3079 data_addr, var, offset, residual_offset,
3080 described, frameNo, tid );
3081 VG_(deleteXA)( described );
3082 return True;
3083 }
3084 }
3085 }
3086
3087 return False;
3088 }
3089
3090 /* Try to form some description of DATA_ADDR by looking at the DWARF3
3091 debug info we have. This considers all global variables, and all
3092 frames in the stacks of all threads. Result is written at the ends
3093 of DNAME{1,2}V, which are XArray*s of HChar, that have been
3094 initialised by the caller, and True is returned. If no description
3095 is created, False is returned. Regardless of the return value,
3096 DNAME{1,2}V are guaranteed to be zero terminated after the call.
3097
3098 Note that after the call, DNAME{1,2} may have more than one
3099 trailing zero, so callers should establish the useful text length
3100 using VG_(strlen) on the contents, rather than VG_(sizeXA) on the
3101 XArray itself.
3102 */
VG_(get_data_description)3103 Bool VG_(get_data_description)(
3104 /*MOD*/ void* /* really, XArray* of HChar */ dname1v,
3105 /*MOD*/ void* /* really, XArray* of HChar */ dname2v,
3106 Addr data_addr
3107 )
3108 {
3109 # define N_FRAMES 8
3110 Addr ips[N_FRAMES], sps[N_FRAMES], fps[N_FRAMES];
3111 UInt n_frames;
3112
3113 Addr stack_min, stack_max;
3114 ThreadId tid;
3115 Bool found;
3116 DebugInfo* di;
3117 Word j;
3118
3119 XArray* dname1 = (XArray*)dname1v;
3120 XArray* dname2 = (XArray*)dname2v;
3121
3122 if (0) VG_(printf)("get_data_description: dataaddr %#lx\n", data_addr);
3123 /* First, see if data_addr is (or is part of) a global variable.
3124 Loop over the DebugInfos we have. Check data_addr against the
3125 outermost scope of all of them, as that should be a global
3126 scope. */
3127 for (di = debugInfo_list; di != NULL; di = di->next) {
3128 OSet* global_scope;
3129 Word gs_size;
3130 Addr zero;
3131 DiAddrRange* global_arange;
3132 Word i;
3133 XArray* vars;
3134
3135 /* text segment missing? unlikely, but handle it .. */
3136 if (!di->text_present || di->text_size == 0)
3137 continue;
3138 /* any var info at all? */
3139 if (!di->varinfo)
3140 continue;
3141 /* perhaps this object didn't contribute any vars at all? */
3142 if (VG_(sizeXA)( di->varinfo ) == 0)
3143 continue;
3144 global_scope = *(OSet**)VG_(indexXA)( di->varinfo, 0 );
3145 vg_assert(global_scope);
3146 gs_size = VG_(OSetGen_Size)( global_scope );
3147 /* The global scope might be completely empty if this
3148 compilation unit declared locals but nothing global. */
3149 if (gs_size == 0)
3150 continue;
3151 /* But if it isn't empty, then it must contain exactly one
3152 element, which covers the entire address range. */
3153 vg_assert(gs_size == 1);
3154 /* Fish out the global scope and check it is as expected. */
3155 zero = 0;
3156 global_arange
3157 = VG_(OSetGen_Lookup)( global_scope, &zero );
3158 /* The global range from (Addr)0 to ~(Addr)0 must exist */
3159 vg_assert(global_arange);
3160 vg_assert(global_arange->aMin == (Addr)0
3161 && global_arange->aMax == ~(Addr)0);
3162 /* Any vars in this range? */
3163 if (!global_arange->vars)
3164 continue;
3165 /* Ok, there are some vars in the global scope of this
3166 DebugInfo. Wade through them and see if the data addresses
3167 of any of them bracket data_addr. */
3168 vars = global_arange->vars;
3169 for (i = 0; i < VG_(sizeXA)( vars ); i++) {
3170 PtrdiffT offset;
3171 DiVariable* var = (DiVariable*)VG_(indexXA)( vars, i );
3172 vg_assert(var->name);
3173 /* Note we use a NULL RegSummary* here. It can't make any
3174 sense for a global variable to have a location expression
3175 which depends on a SP/FP/IP value. So don't supply any.
3176 This means, if the evaluation of the location
3177 expression/list requires a register, we have to let it
3178 fail. */
3179 if (data_address_is_in_var( &offset, di->admin_tyents, var,
3180 NULL/* RegSummary* */,
3181 data_addr, di )) {
3182 PtrdiffT residual_offset = 0;
3183 XArray* described = ML_(describe_type)( &residual_offset,
3184 di->admin_tyents,
3185 var->typeR, offset );
3186 format_message( dname1, dname2,
3187 data_addr, var, offset, residual_offset,
3188 described, -1/*frameNo*/,
3189 VG_INVALID_THREADID );
3190 VG_(deleteXA)( described );
3191 zterm_XA( dname1 );
3192 zterm_XA( dname2 );
3193 return True;
3194 }
3195 }
3196 }
3197
3198 /* Ok, well it's not a global variable. So now let's snoop around
3199 in the stacks of all the threads. First try to figure out which
3200 thread's stack data_addr is in. */
3201
3202 /* --- KLUDGE --- Try examining the top frame of all thread stacks.
3203 This finds variables which are not stack allocated but are not
3204 globally visible either; specifically it appears to pick up
3205 variables which are visible only within a compilation unit.
3206 These will have the address range of the compilation unit and
3207 tend to live at Scope level 1. */
3208 VG_(thread_stack_reset_iter)(&tid);
3209 while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) {
3210 if (stack_min >= stack_max)
3211 continue; /* ignore obviously stupid cases */
3212 if (consider_vars_in_frame( dname1, dname2,
3213 data_addr,
3214 VG_(get_IP)(tid),
3215 VG_(get_SP)(tid),
3216 VG_(get_FP)(tid), tid, 0 )) {
3217 zterm_XA( dname1 );
3218 zterm_XA( dname2 );
3219 return True;
3220 }
3221 }
3222 /* --- end KLUDGE --- */
3223
3224 /* Perhaps it's on a thread's stack? */
3225 found = False;
3226 VG_(thread_stack_reset_iter)(&tid);
3227 while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) {
3228 if (stack_min >= stack_max)
3229 continue; /* ignore obviously stupid cases */
3230 if (stack_min - VG_STACK_REDZONE_SZB <= data_addr
3231 && data_addr <= stack_max) {
3232 found = True;
3233 break;
3234 }
3235 }
3236 if (!found) {
3237 zterm_XA( dname1 );
3238 zterm_XA( dname2 );
3239 return False;
3240 }
3241
3242 /* We conclude data_addr is in thread tid's stack. Unwind the
3243 stack to get a bunch of (ip,sp,fp) triples describing the
3244 frames, and for each frame, consider the local variables. */
3245 n_frames = VG_(get_StackTrace)( tid, ips, N_FRAMES,
3246 sps, fps, 0/*first_ip_delta*/ );
3247
3248 /* As a result of KLUDGE above, starting the loop at j = 0
3249 duplicates examination of the top frame and so isn't necessary.
3250 Oh well. */
3251 vg_assert(n_frames >= 0 && n_frames <= N_FRAMES);
3252 for (j = 0; j < n_frames; j++) {
3253 if (consider_vars_in_frame( dname1, dname2,
3254 data_addr,
3255 ips[j],
3256 sps[j], fps[j], tid, j )) {
3257 zterm_XA( dname1 );
3258 zterm_XA( dname2 );
3259 return True;
3260 }
3261 /* Now, it appears that gcc sometimes appears to produce
3262 location lists whose ranges don't actually cover the call
3263 instruction, even though the address of the variable in
3264 question is passed as a parameter in the call. AFAICS this
3265 is simply a bug in gcc - how can the variable be claimed not
3266 exist in memory (on the stack) for the duration of a call in
3267 which its address is passed? But anyway, in the particular
3268 case I investigated (memcheck/tests/varinfo6.c, call to croak
3269 on line 2999, local var budget declared at line 3115
3270 appearing not to exist across the call to mainSort on line
3271 3143, "gcc.orig (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2)" on
3272 amd64), the variable's location list does claim it exists
3273 starting at the first byte of the first instruction after the
3274 call instruction. So, call consider_vars_in_frame a second
3275 time, but this time add 1 to the IP. GDB handles this
3276 example with no difficulty, which leads me to believe that
3277 either (1) I misunderstood something, or (2) GDB has an
3278 equivalent kludge. */
3279 if (j > 0 /* this is a non-innermost frame */
3280 && consider_vars_in_frame( dname1, dname2,
3281 data_addr,
3282 ips[j] + 1,
3283 sps[j], fps[j], tid, j )) {
3284 zterm_XA( dname1 );
3285 zterm_XA( dname2 );
3286 return True;
3287 }
3288 }
3289
3290 /* We didn't find anything useful. */
3291 zterm_XA( dname1 );
3292 zterm_XA( dname2 );
3293 return False;
3294 # undef N_FRAMES
3295 }
3296
3297
3298 //////////////////////////////////////////////////////////////////
3299 // //
3300 // Support for other kinds of queries to the Dwarf3 var info //
3301 // //
3302 //////////////////////////////////////////////////////////////////
3303
3304 /* Figure out if the variable 'var' has a location that is linearly
3305 dependent on a stack pointer value, or a frame pointer value, and
3306 if it is, add a description of it to 'blocks'. Otherwise ignore
3307 it. If 'arrays_only' is True, also ignore it unless it has an
3308 array type. */
3309
3310 static
analyse_deps(XArray * blocks,XArray * tyents,Addr ip,const DebugInfo * di,DiVariable * var,Bool arrays_only)3311 void analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks,
3312 XArray* /* TyEnt */ tyents,
3313 Addr ip, const DebugInfo* di, DiVariable* var,
3314 Bool arrays_only )
3315 {
3316 GXResult res_sp_6k, res_sp_7k, res_fp_6k, res_fp_7k;
3317 RegSummary regs;
3318 MaybeULong mul;
3319 Bool isVec;
3320 TyEnt* ty;
3321
3322 Bool debug = False;
3323 if (0&&debug)
3324 VG_(printf)("adeps: var %s\n", var->name );
3325
3326 /* Figure out how big the variable is. */
3327 mul = ML_(sizeOfType)(tyents, var->typeR);
3328 /* If this var has a type whose size is unknown, zero, or
3329 impossibly large, it should never have been added. ML_(addVar)
3330 should have rejected it. */
3331 vg_assert(mul.b == True);
3332 vg_assert(mul.ul > 0);
3333 if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
3334 /* After this point, we assume we can truncate mul.ul to a host word
3335 safely (without loss of info). */
3336
3337 /* skip if non-array and we're only interested in arrays */
3338 ty = ML_(TyEnts__index_by_cuOff)( tyents, NULL, var->typeR );
3339 vg_assert(ty);
3340 vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty));
3341 if (ty->tag == Te_UNKNOWN)
3342 return; /* perhaps we should complain in this case? */
3343 isVec = ty->tag == Te_TyArray;
3344 if (arrays_only && !isVec)
3345 return;
3346
3347 if (0) {ML_(pp_TyEnt_C_ishly)(tyents, var->typeR);
3348 VG_(printf)(" %s\n", var->name);}
3349
3350 /* Do some test evaluations of the variable's location expression,
3351 in order to guess whether it is sp-relative, fp-relative, or
3352 none. A crude hack, which can be interpreted roughly as finding
3353 the first derivative of the location expression w.r.t. the
3354 supplied frame and stack pointer values. */
3355 regs.fp = 0;
3356 regs.ip = ip;
3357 regs.sp = 6 * 1024;
3358 res_sp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di );
3359
3360 regs.fp = 0;
3361 regs.ip = ip;
3362 regs.sp = 7 * 1024;
3363 res_sp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di );
3364
3365 regs.fp = 6 * 1024;
3366 regs.ip = ip;
3367 regs.sp = 0;
3368 res_fp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di );
3369
3370 regs.fp = 7 * 1024;
3371 regs.ip = ip;
3372 regs.sp = 0;
3373 res_fp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di );
3374
3375 vg_assert(res_sp_6k.kind == res_sp_7k.kind);
3376 vg_assert(res_sp_6k.kind == res_fp_6k.kind);
3377 vg_assert(res_sp_6k.kind == res_fp_7k.kind);
3378
3379 if (res_sp_6k.kind == GXR_Addr) {
3380 StackBlock block;
3381 GXResult res;
3382 UWord sp_delta = res_sp_7k.word - res_sp_6k.word;
3383 UWord fp_delta = res_fp_7k.word - res_fp_6k.word;
3384 tl_assert(sp_delta == 0 || sp_delta == 1024);
3385 tl_assert(fp_delta == 0 || fp_delta == 1024);
3386
3387 if (sp_delta == 0 && fp_delta == 0) {
3388 /* depends neither on sp nor fp, so it can't be a stack
3389 local. Ignore it. */
3390 }
3391 else
3392 if (sp_delta == 1024 && fp_delta == 0) {
3393 regs.sp = regs.fp = 0;
3394 regs.ip = ip;
3395 res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di );
3396 tl_assert(res.kind == GXR_Addr);
3397 if (debug)
3398 VG_(printf)(" %5ld .. %5ld (sp) %s\n",
3399 res.word, res.word + ((UWord)mul.ul) - 1, var->name);
3400 block.base = res.word;
3401 block.szB = (SizeT)mul.ul;
3402 block.spRel = True;
3403 block.isVec = isVec;
3404 VG_(memset)( &block.name[0], 0, sizeof(block.name) );
3405 if (var->name)
3406 VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 );
3407 block.name[ sizeof(block.name)-1 ] = 0;
3408 VG_(addToXA)( blocks, &block );
3409 }
3410 else
3411 if (sp_delta == 0 && fp_delta == 1024) {
3412 regs.sp = regs.fp = 0;
3413 regs.ip = ip;
3414 res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di );
3415 tl_assert(res.kind == GXR_Addr);
3416 if (debug)
3417 VG_(printf)(" %5ld .. %5ld (FP) %s\n",
3418 res.word, res.word + ((UWord)mul.ul) - 1, var->name);
3419 block.base = res.word;
3420 block.szB = (SizeT)mul.ul;
3421 block.spRel = False;
3422 block.isVec = isVec;
3423 VG_(memset)( &block.name[0], 0, sizeof(block.name) );
3424 if (var->name)
3425 VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 );
3426 block.name[ sizeof(block.name)-1 ] = 0;
3427 VG_(addToXA)( blocks, &block );
3428 }
3429 else {
3430 vg_assert(0);
3431 }
3432 }
3433 }
3434
3435
3436 /* Get an XArray of StackBlock which describe the stack (auto) blocks
3437 for this ip. The caller is expected to free the XArray at some
3438 point. If 'arrays_only' is True, only array-typed blocks are
3439 returned; otherwise blocks of all types are returned. */
3440
3441 void* /* really, XArray* of StackBlock */
VG_(di_get_stack_blocks_at_ip)3442 VG_(di_get_stack_blocks_at_ip)( Addr ip, Bool arrays_only )
3443 {
3444 /* This is a derivation of consider_vars_in_frame() above. */
3445 Word i;
3446 DebugInfo* di;
3447 Bool debug = False;
3448
3449 XArray* res = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dgsbai.1",
3450 ML_(dinfo_free),
3451 sizeof(StackBlock) );
3452
3453 static UInt n_search = 0;
3454 static UInt n_steps = 0;
3455 n_search++;
3456 if (debug)
3457 VG_(printf)("QQQQ: dgsbai: ip %#lx\n", ip);
3458 /* first, find the DebugInfo that pertains to 'ip'. */
3459 for (di = debugInfo_list; di; di = di->next) {
3460 n_steps++;
3461 /* text segment missing? unlikely, but handle it .. */
3462 if (!di->text_present || di->text_size == 0)
3463 continue;
3464 /* Ok. So does this text mapping bracket the ip? */
3465 if (di->text_avma <= ip && ip < di->text_avma + di->text_size)
3466 break;
3467 }
3468
3469 /* Didn't find it. Strange -- means ip is a code address outside
3470 of any mapped text segment. Unlikely but not impossible -- app
3471 could be generating code to run. */
3472 if (!di)
3473 return res; /* currently empty */
3474
3475 if (0 && ((n_search & 0x1) == 0))
3476 VG_(printf)("VG_(di_get_stack_blocks_at_ip): %u searches, "
3477 "%u DebugInfos looked at\n",
3478 n_search, n_steps);
3479 /* Start of performance-enhancing hack: once every ??? (chosen
3480 hackily after profiling) successful searches, move the found
3481 DebugInfo one step closer to the start of the list. This makes
3482 future searches cheaper. */
3483 if ((n_search & 0xFFFF) == 0) {
3484 /* Move si one step closer to the start of the list. */
3485 move_DebugInfo_one_step_forward( di );
3486 }
3487 /* End of performance-enhancing hack. */
3488
3489 /* any var info at all? */
3490 if (!di->varinfo)
3491 return res; /* currently empty */
3492
3493 /* Work through the scopes from most deeply nested outwards,
3494 looking for code address ranges that bracket 'ip'. The
3495 variables on each such address range found are in scope right
3496 now. Don't descend to level zero as that is the global
3497 scope. */
3498
3499 /* "for each scope, working outwards ..." */
3500 for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) {
3501 XArray* vars;
3502 Word j;
3503 DiAddrRange* arange;
3504 OSet* this_scope
3505 = *(OSet**)VG_(indexXA)( di->varinfo, i );
3506 if (debug)
3507 VG_(printf)("QQQQ: considering scope %ld\n", (Word)i);
3508 if (!this_scope)
3509 continue;
3510 /* Find the set of variables in this scope that
3511 bracket the program counter. */
3512 arange = VG_(OSetGen_LookupWithCmp)(
3513 this_scope, &ip,
3514 ML_(cmp_for_DiAddrRange_range)
3515 );
3516 if (!arange)
3517 continue;
3518 /* stay sane */
3519 vg_assert(arange->aMin <= arange->aMax);
3520 /* It must bracket the ip we asked for, else
3521 ML_(cmp_for_DiAddrRange_range) is somehow broken. */
3522 vg_assert(arange->aMin <= ip && ip <= arange->aMax);
3523 /* It must have an attached XArray of DiVariables. */
3524 vars = arange->vars;
3525 vg_assert(vars);
3526 /* But it mustn't cover the entire address range. We only
3527 expect that to happen for the global scope (level 0), which
3528 we're not looking at here. Except, it may cover the entire
3529 address range, but in that case the vars array must be
3530 empty. */
3531 vg_assert(! (arange->aMin == (Addr)0
3532 && arange->aMax == ~(Addr)0
3533 && VG_(sizeXA)(vars) > 0) );
3534 for (j = 0; j < VG_(sizeXA)( vars ); j++) {
3535 DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j );
3536 if (debug)
3537 VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n",
3538 var->name,arange->aMin,arange->aMax,ip);
3539 analyse_deps( res, di->admin_tyents, ip,
3540 di, var, arrays_only );
3541 }
3542 }
3543
3544 return res;
3545 }
3546
3547
3548 /* Get an array of GlobalBlock which describe the global blocks owned
3549 by the shared object characterised by the given di_handle. Asserts
3550 if the handle is invalid. The caller is responsible for freeing
3551 the array at some point. If 'arrays_only' is True, only
3552 array-typed blocks are returned; otherwise blocks of all types are
3553 returned. */
3554
3555 void* /* really, XArray* of GlobalBlock */
VG_(di_get_global_blocks_from_dihandle)3556 VG_(di_get_global_blocks_from_dihandle) ( ULong di_handle,
3557 Bool arrays_only )
3558 {
3559 /* This is a derivation of consider_vars_in_frame() above. */
3560
3561 DebugInfo* di;
3562 XArray* gvars; /* XArray* of GlobalBlock */
3563 Word nScopes, scopeIx;
3564
3565 /* The first thing to do is find the DebugInfo that
3566 pertains to 'di_handle'. */
3567 tl_assert(di_handle > 0);
3568 for (di = debugInfo_list; di; di = di->next) {
3569 if (di->handle == di_handle)
3570 break;
3571 }
3572
3573 /* If this fails, we were unable to find any DebugInfo with the
3574 given handle. This is considered an error on the part of the
3575 caller. */
3576 tl_assert(di != NULL);
3577
3578 /* we'll put the collected variables in here. */
3579 gvars = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dggbfd.1",
3580 ML_(dinfo_free), sizeof(GlobalBlock) );
3581 tl_assert(gvars);
3582
3583 /* any var info at all? */
3584 if (!di->varinfo)
3585 return gvars;
3586
3587 /* we'll iterate over all the variables we can find, even if
3588 it seems senseless to visit stack-allocated variables */
3589 /* Iterate over all scopes */
3590 nScopes = VG_(sizeXA)( di->varinfo );
3591 for (scopeIx = 0; scopeIx < nScopes; scopeIx++) {
3592
3593 /* Iterate over each (code) address range at the current scope */
3594 DiAddrRange* range;
3595 OSet* /* of DiAddrInfo */ scope
3596 = *(OSet**)VG_(indexXA)( di->varinfo, scopeIx );
3597 tl_assert(scope);
3598 VG_(OSetGen_ResetIter)(scope);
3599 while ( (range = VG_(OSetGen_Next)(scope)) ) {
3600
3601 /* Iterate over each variable in the current address range */
3602 Word nVars, varIx;
3603 tl_assert(range->vars);
3604 nVars = VG_(sizeXA)( range->vars );
3605 for (varIx = 0; varIx < nVars; varIx++) {
3606
3607 Bool isVec;
3608 GXResult res;
3609 MaybeULong mul;
3610 GlobalBlock gb;
3611 TyEnt* ty;
3612 DiVariable* var = VG_(indexXA)( range->vars, varIx );
3613 tl_assert(var->name);
3614 if (0) VG_(printf)("at depth %ld var %s ", scopeIx, var->name );
3615
3616 /* Now figure out if this variable has a constant address
3617 (that is, independent of FP, SP, phase of moon, etc),
3618 and if so, what the address is. Any variable with a
3619 constant address is deemed to be a global so we collect
3620 it. */
3621 if (0) { VG_(printf)("EVAL: "); ML_(pp_GX)(var->gexpr);
3622 VG_(printf)("\n"); }
3623 res = ML_(evaluate_trivial_GX)( var->gexpr, di );
3624
3625 /* Not a constant address => not interesting */
3626 if (res.kind != GXR_Addr) {
3627 if (0) VG_(printf)("FAIL\n");
3628 continue;
3629 }
3630
3631 /* Ok, it's a constant address. See if we want to collect
3632 it. */
3633 if (0) VG_(printf)("%#lx\n", res.word);
3634
3635 /* Figure out how big the variable is. */
3636 mul = ML_(sizeOfType)(di->admin_tyents, var->typeR);
3637
3638 /* If this var has a type whose size is unknown, zero, or
3639 impossibly large, it should never have been added.
3640 ML_(addVar) should have rejected it. */
3641 vg_assert(mul.b == True);
3642 vg_assert(mul.ul > 0);
3643 if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
3644 /* After this point, we assume we can truncate mul.ul to a
3645 host word safely (without loss of info). */
3646
3647 /* skip if non-array and we're only interested in
3648 arrays */
3649 ty = ML_(TyEnts__index_by_cuOff)( di->admin_tyents, NULL,
3650 var->typeR );
3651 vg_assert(ty);
3652 vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty));
3653 if (ty->tag == Te_UNKNOWN)
3654 continue; /* perhaps we should complain in this case? */
3655
3656 isVec = ty->tag == Te_TyArray;
3657 if (arrays_only && !isVec) continue;
3658
3659 /* Ok, so collect it! */
3660 tl_assert(var->name);
3661 tl_assert(di->soname);
3662 if (0) VG_(printf)("XXXX %s %s %d\n", var->name,
3663 var->fileName?(HChar*)var->fileName
3664 :"??",var->lineNo);
3665 VG_(memset)(&gb, 0, sizeof(gb));
3666 gb.addr = res.word;
3667 gb.szB = (SizeT)mul.ul;
3668 gb.isVec = isVec;
3669 VG_(strncpy)(&gb.name[0], var->name, sizeof(gb.name)-1);
3670 VG_(strncpy)(&gb.soname[0], di->soname, sizeof(gb.soname)-1);
3671 tl_assert(gb.name[ sizeof(gb.name)-1 ] == 0);
3672 tl_assert(gb.soname[ sizeof(gb.soname)-1 ] == 0);
3673
3674 VG_(addToXA)( gvars, &gb );
3675
3676 } /* for (varIx = 0; varIx < nVars; varIx++) */
3677
3678 } /* while ( (range = VG_(OSetGen_Next)(scope)) ) */
3679
3680 } /* for (scopeIx = 0; scopeIx < nScopes; scopeIx++) */
3681
3682 return gvars;
3683 }
3684
3685
3686 /*------------------------------------------------------------*/
3687 /*--- DebugInfo accessor functions ---*/
3688 /*------------------------------------------------------------*/
3689
VG_(next_DebugInfo)3690 const DebugInfo* VG_(next_DebugInfo)(const DebugInfo* di)
3691 {
3692 if (di == NULL)
3693 return debugInfo_list;
3694 return di->next;
3695 }
3696
VG_(DebugInfo_get_text_avma)3697 Addr VG_(DebugInfo_get_text_avma)(const DebugInfo* di)
3698 {
3699 return di->text_present ? di->text_avma : 0;
3700 }
3701
VG_(DebugInfo_get_text_size)3702 SizeT VG_(DebugInfo_get_text_size)(const DebugInfo* di)
3703 {
3704 return di->text_present ? di->text_size : 0;
3705 }
3706
VG_(DebugInfo_get_plt_avma)3707 Addr VG_(DebugInfo_get_plt_avma)(const DebugInfo* di)
3708 {
3709 return di->plt_present ? di->plt_avma : 0;
3710 }
3711
VG_(DebugInfo_get_plt_size)3712 SizeT VG_(DebugInfo_get_plt_size)(const DebugInfo* di)
3713 {
3714 return di->plt_present ? di->plt_size : 0;
3715 }
3716
VG_(DebugInfo_get_gotplt_avma)3717 Addr VG_(DebugInfo_get_gotplt_avma)(const DebugInfo* di)
3718 {
3719 return di->gotplt_present ? di->gotplt_avma : 0;
3720 }
3721
VG_(DebugInfo_get_gotplt_size)3722 SizeT VG_(DebugInfo_get_gotplt_size)(const DebugInfo* di)
3723 {
3724 return di->gotplt_present ? di->gotplt_size : 0;
3725 }
3726
VG_(DebugInfo_get_soname)3727 const UChar* VG_(DebugInfo_get_soname)(const DebugInfo* di)
3728 {
3729 return di->soname;
3730 }
3731
VG_(DebugInfo_get_filename)3732 const UChar* VG_(DebugInfo_get_filename)(const DebugInfo* di)
3733 {
3734 return di->fsm.filename;
3735 }
3736
VG_(DebugInfo_get_text_bias)3737 PtrdiffT VG_(DebugInfo_get_text_bias)(const DebugInfo* di)
3738 {
3739 return di->text_present ? di->text_bias : 0;
3740 }
3741
VG_(DebugInfo_syms_howmany)3742 Int VG_(DebugInfo_syms_howmany) ( const DebugInfo *si )
3743 {
3744 return si->symtab_used;
3745 }
3746
VG_(DebugInfo_syms_getidx)3747 void VG_(DebugInfo_syms_getidx) ( const DebugInfo *si,
3748 Int idx,
3749 /*OUT*/Addr* avma,
3750 /*OUT*/Addr* tocptr,
3751 /*OUT*/UInt* size,
3752 /*OUT*/UChar** pri_name,
3753 /*OUT*/UChar*** sec_names,
3754 /*OUT*/Bool* isText,
3755 /*OUT*/Bool* isIFunc )
3756 {
3757 vg_assert(idx >= 0 && idx < si->symtab_used);
3758 if (avma) *avma = si->symtab[idx].addr;
3759 if (tocptr) *tocptr = si->symtab[idx].tocptr;
3760 if (size) *size = si->symtab[idx].size;
3761 if (pri_name) *pri_name = si->symtab[idx].pri_name;
3762 if (sec_names) *sec_names = si->symtab[idx].sec_names;
3763 if (isText) *isText = si->symtab[idx].isText;
3764 if (isIFunc) *isIFunc = si->symtab[idx].isIFunc;
3765 }
3766
3767
3768 /*------------------------------------------------------------*/
3769 /*--- SectKind query functions ---*/
3770 /*------------------------------------------------------------*/
3771
3772 /* Convert a VgSectKind to a string, which must be copied if you want
3773 to change it. */
VG_(pp_SectKind)3774 const HChar* VG_(pp_SectKind)( VgSectKind kind )
3775 {
3776 switch (kind) {
3777 case Vg_SectUnknown: return "Unknown";
3778 case Vg_SectText: return "Text";
3779 case Vg_SectData: return "Data";
3780 case Vg_SectBSS: return "BSS";
3781 case Vg_SectGOT: return "GOT";
3782 case Vg_SectPLT: return "PLT";
3783 case Vg_SectOPD: return "OPD";
3784 case Vg_SectGOTPLT: return "GOTPLT";
3785 default: vg_assert(0);
3786 }
3787 }
3788
3789 /* Given an address 'a', make a guess of which section of which object
3790 it comes from. If name is non-NULL, then the last n_name-1
3791 characters of the object's name is put in name[0 .. n_name-2], and
3792 name[n_name-1] is set to zero (guaranteed zero terminated). */
3793
VG_(DebugInfo_sect_kind)3794 VgSectKind VG_(DebugInfo_sect_kind)( /*OUT*/UChar* name, SizeT n_name,
3795 Addr a)
3796 {
3797 DebugInfo* di;
3798 VgSectKind res = Vg_SectUnknown;
3799
3800 for (di = debugInfo_list; di != NULL; di = di->next) {
3801
3802 if (0)
3803 VG_(printf)(
3804 "addr=%#lx di=%p %s got=%#lx,%ld plt=%#lx,%ld "
3805 "data=%#lx,%ld bss=%#lx,%ld\n",
3806 a, di, di->fsm.filename,
3807 di->got_avma, di->got_size,
3808 di->plt_avma, di->plt_size,
3809 di->data_avma, di->data_size,
3810 di->bss_avma, di->bss_size);
3811
3812 if (di->text_present
3813 && di->text_size > 0
3814 && a >= di->text_avma && a < di->text_avma + di->text_size) {
3815 res = Vg_SectText;
3816 break;
3817 }
3818 if (di->data_present
3819 && di->data_size > 0
3820 && a >= di->data_avma && a < di->data_avma + di->data_size) {
3821 res = Vg_SectData;
3822 break;
3823 }
3824 if (di->sdata_present
3825 && di->sdata_size > 0
3826 && a >= di->sdata_avma && a < di->sdata_avma + di->sdata_size) {
3827 res = Vg_SectData;
3828 break;
3829 }
3830 if (di->bss_present
3831 && di->bss_size > 0
3832 && a >= di->bss_avma && a < di->bss_avma + di->bss_size) {
3833 res = Vg_SectBSS;
3834 break;
3835 }
3836 if (di->sbss_present
3837 && di->sbss_size > 0
3838 && a >= di->sbss_avma && a < di->sbss_avma + di->sbss_size) {
3839 res = Vg_SectBSS;
3840 break;
3841 }
3842 if (di->plt_present
3843 && di->plt_size > 0
3844 && a >= di->plt_avma && a < di->plt_avma + di->plt_size) {
3845 res = Vg_SectPLT;
3846 break;
3847 }
3848 if (di->got_present
3849 && di->got_size > 0
3850 && a >= di->got_avma && a < di->got_avma + di->got_size) {
3851 res = Vg_SectGOT;
3852 break;
3853 }
3854 if (di->gotplt_present
3855 && di->gotplt_size > 0
3856 && a >= di->gotplt_avma && a < di->gotplt_avma + di->gotplt_size) {
3857 res = Vg_SectGOTPLT;
3858 break;
3859 }
3860 if (di->opd_present
3861 && di->opd_size > 0
3862 && a >= di->opd_avma && a < di->opd_avma + di->opd_size) {
3863 res = Vg_SectOPD;
3864 break;
3865 }
3866 /* we could also check for .eh_frame, if anyone really cares */
3867 }
3868
3869 vg_assert( (di == NULL && res == Vg_SectUnknown)
3870 || (di != NULL && res != Vg_SectUnknown) );
3871
3872 if (name) {
3873
3874 vg_assert(n_name >= 8);
3875
3876 if (di && di->fsm.filename) {
3877 Int i, j;
3878 Int fnlen = VG_(strlen)(di->fsm.filename);
3879 Int start_at = 1 + fnlen - n_name;
3880 if (start_at < 0) start_at = 0;
3881 vg_assert(start_at < fnlen);
3882 i = start_at; j = 0;
3883 while (True) {
3884 vg_assert(j >= 0 && j < n_name);
3885 vg_assert(i >= 0 && i <= fnlen);
3886 name[j] = di->fsm.filename[i];
3887 if (di->fsm.filename[i] == 0) break;
3888 i++; j++;
3889 }
3890 vg_assert(i == fnlen);
3891 } else {
3892 VG_(snprintf)(name, n_name, "%s", "???");
3893 }
3894
3895 name[n_name-1] = 0;
3896 }
3897
3898 return res;
3899
3900 }
3901
3902 /*--------------------------------------------------------------------*/
3903 /*--- end ---*/
3904 /*--------------------------------------------------------------------*/
3905