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