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