blob: c2fb5b8e62c1f04a3c192a4ed0e434e6fcb78108 [file] [log] [blame]
sewardjeadcd862006-04-04 15:12:44 +00001
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
sewardj4d474d02008-02-11 11:34:59 +000011 Copyright (C) 2000-2008 Julian Seward
sewardjeadcd862006-04-04 15:12:44 +000012 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 Stabs reader greatly improved by Nick Nethercote, Apr 02.
33 This module was also extensively hacked on by Jeremy Fitzhardinge
34 and Tom Hughes.
35*/
36
37#include "pub_core_basics.h"
sewardj4cfea4f2006-10-14 19:26:10 +000038#include "pub_core_vki.h"
sewardjeadcd862006-04-04 15:12:44 +000039#include "pub_core_threadstate.h"
sewardjb8b79ad2008-03-03 01:35:41 +000040#include "pub_core_debuginfo.h" /* self */
sewardjeadcd862006-04-04 15:12:44 +000041#include "pub_core_demangle.h"
42#include "pub_core_libcbase.h"
43#include "pub_core_libcassert.h"
44#include "pub_core_libcprint.h"
sewardjb8b79ad2008-03-03 01:35:41 +000045#include "pub_core_libcfile.h"
sewardjeadcd862006-04-04 15:12:44 +000046#include "pub_core_options.h"
sewardjb8b79ad2008-03-03 01:35:41 +000047#include "pub_core_redir.h" // VG_(redir_notify_{new,delete}_SegInfo)
sewardjeadcd862006-04-04 15:12:44 +000048#include "pub_core_aspacemgr.h"
sewardjb8b79ad2008-03-03 01:35:41 +000049#include "pub_core_machine.h" // VG_PLAT_USES_PPCTOC
sewardj72427fa2007-02-27 16:52:23 +000050#include "pub_core_xarray.h"
sewardjb8b79ad2008-03-03 01:35:41 +000051#include "pub_core_oset.h"
52#include "pub_core_stacktrace.h" // VG_(get_StackTrace)
53
54#include "priv_misc.h" /* dinfo_zalloc/free */
55#include "priv_d3basics.h" /* ML_(pp_GX) */
56#include "priv_tytypes.h"
sewardjeadcd862006-04-04 15:12:44 +000057#include "priv_storage.h"
58#include "priv_readdwarf.h"
59#include "priv_readstabs.h"
sewardj4ee4f982006-10-17 01:37:10 +000060#if defined(VGO_linux)
61# include "priv_readelf.h"
sewardjb8b79ad2008-03-03 01:35:41 +000062# include "priv_readdwarf3.h"
sewardj4ee4f982006-10-17 01:37:10 +000063#elif defined(VGO_aix5)
64# include "pub_core_debuglog.h"
65# include "pub_core_libcproc.h"
66# include "pub_core_libcfile.h"
67# include "priv_readxcoff.h"
68#endif
sewardjeadcd862006-04-04 15:12:44 +000069
sewardjc6d3f6f2007-01-11 19:42:11 +000070
71/*------------------------------------------------------------*/
72/*--- The _svma / _avma / _image / _bias naming scheme ---*/
73/*------------------------------------------------------------*/
74
75/* JRS 11 Jan 07: I find the different kinds of addresses involved in
76 debuginfo reading confusing. Recently I arrived at some
77 terminology which makes it clearer (to me, at least). There are 3
78 kinds of address used in the debuginfo reading process:
79
80 stated VMAs - the address where (eg) a .so says a symbol is, that
81 is, what it tells you if you consider the .so in
82 isolation
83
84 actual VMAs - the address where (eg) said symbol really wound up
85 after the .so was mapped into memory
86
87 image addresses - pointers into the copy of the .so (etc)
88 transiently mmaped aboard whilst we read its info
89
90 Additionally I use the term 'bias' to denote the difference
91 between stated and actual VMAs for a given entity.
92
93 This terminology is not used consistently, but a start has been
94 made. readelf.c and the call-frame info reader in readdwarf.c now
95 use it. Specifically, various variables and structure fields have
sewardjf767d962007-02-12 17:47:14 +000096 been annotated with _avma / _svma / _image / _bias. In places _img
97 is used instead of _image for the sake of brevity.
sewardjc6d3f6f2007-01-11 19:42:11 +000098*/
99
100
sewardjeadcd862006-04-04 15:12:44 +0000101/*------------------------------------------------------------*/
102/*--- Root structure ---*/
103/*------------------------------------------------------------*/
104
sewardjb8b79ad2008-03-03 01:35:41 +0000105/* The root structure for the entire debug info system. It is a
106 linked list of DebugInfos. */
107static DebugInfo* debugInfo_list = NULL;
108
109
110/* Find 'di' in the debugInfo_list and move it one step closer the the
111 front of the list, so as to make subsequent searches for it
112 cheaper. When used in a controlled way, makes a major improvement
113 in some DebugInfo-search-intensive situations, most notably stack
114 unwinding on amd64-linux. */
115static void move_DebugInfo_one_step_forward ( DebugInfo* di )
116{
117 DebugInfo *di0, *di1, *di2;
118 if (di == debugInfo_list)
119 return; /* already at head of list */
120 vg_assert(di != NULL);
121 di0 = debugInfo_list;
122 di1 = NULL;
123 di2 = NULL;
124 while (True) {
125 if (di0 == NULL || di0 == di) break;
126 di2 = di1;
127 di1 = di0;
128 di0 = di0->next;
129 }
130 vg_assert(di0 == di);
131 if (di0 != NULL && di1 != NULL && di2 != NULL) {
132 DebugInfo* tmp;
133 /* di0 points to di, di1 to its predecessor, and di2 to di1's
134 predecessor. Swap di0 and di1, that is, move di0 one step
135 closer to the start of the list. */
136 vg_assert(di2->next == di1);
137 vg_assert(di1->next == di0);
138 tmp = di0->next;
139 di2->next = di0;
140 di0->next = di1;
141 di1->next = tmp;
142 }
143 else
144 if (di0 != NULL && di1 != NULL && di2 == NULL) {
145 /* it's second in the list. */
146 vg_assert(debugInfo_list == di1);
147 vg_assert(di1->next == di0);
148 di1->next = di0->next;
149 di0->next = di1;
150 debugInfo_list = di0;
151 }
152}
sewardjeadcd862006-04-04 15:12:44 +0000153
154
155/*------------------------------------------------------------*/
156/*--- Notification (acquire/discard) helpers ---*/
157/*------------------------------------------------------------*/
158
sewardjb8b79ad2008-03-03 01:35:41 +0000159/* Allocate and zero out a new DebugInfo record. */
sewardjeadcd862006-04-04 15:12:44 +0000160static
sewardjb8b79ad2008-03-03 01:35:41 +0000161DebugInfo* alloc_DebugInfo( const UChar* filename,
162 const UChar* memname )
sewardjeadcd862006-04-04 15:12:44 +0000163{
sewardjb8b79ad2008-03-03 01:35:41 +0000164 Bool traceme;
165 DebugInfo* di;
sewardjeadcd862006-04-04 15:12:44 +0000166
sewardjf767d962007-02-12 17:47:14 +0000167 vg_assert(filename);
168
sewardjb8b79ad2008-03-03 01:35:41 +0000169 di = ML_(dinfo_zalloc)(sizeof(DebugInfo));
170 di->filename = ML_(dinfo_strdup)(filename);
171 di->memname = memname ? ML_(dinfo_strdup)(memname)
172 : NULL;
sewardjeadcd862006-04-04 15:12:44 +0000173
sewardjf767d962007-02-12 17:47:14 +0000174 /* Everything else -- pointers, sizes, arrays -- is zeroed by calloc.
175 Now set up the debugging-output flags. */
176 traceme
177 = VG_(string_match)( VG_(clo_trace_symtab_patt), filename )
178 || (memname && VG_(string_match)( VG_(clo_trace_symtab_patt),
179 memname ));
180 if (traceme) {
sewardjb8b79ad2008-03-03 01:35:41 +0000181 di->trace_symtab = VG_(clo_trace_symtab);
182 di->trace_cfi = VG_(clo_trace_cfi);
183 di->ddump_syms = VG_(clo_debug_dump_syms);
184 di->ddump_line = VG_(clo_debug_dump_line);
185 di->ddump_frames = VG_(clo_debug_dump_frames);
sewardjf767d962007-02-12 17:47:14 +0000186 }
187
sewardjb8b79ad2008-03-03 01:35:41 +0000188 return di;
sewardjeadcd862006-04-04 15:12:44 +0000189}
190
191
sewardjb8b79ad2008-03-03 01:35:41 +0000192/* Free a DebugInfo, and also all the stuff hanging off it. */
193static void free_DebugInfo ( DebugInfo* di )
sewardjeadcd862006-04-04 15:12:44 +0000194{
sewardjb8b79ad2008-03-03 01:35:41 +0000195 Word i, j;
sewardjeadcd862006-04-04 15:12:44 +0000196 struct strchunk *chunk, *next;
sewardjb8b79ad2008-03-03 01:35:41 +0000197 TyAdmin *admin1, *admin2;
198 GExpr *gexpr1, *gexpr2;
sewardjeadcd862006-04-04 15:12:44 +0000199
sewardjb8b79ad2008-03-03 01:35:41 +0000200 vg_assert(di != NULL);
201 if (di->filename) ML_(dinfo_free)(di->filename);
202 if (di->symtab) ML_(dinfo_free)(di->symtab);
203 if (di->loctab) ML_(dinfo_free)(di->loctab);
204 if (di->cfsi) ML_(dinfo_free)(di->cfsi);
205 if (di->cfsi_exprs) VG_(deleteXA)(di->cfsi_exprs);
206
207 for (chunk = di->strchunks; chunk != NULL; chunk = next) {
sewardjeadcd862006-04-04 15:12:44 +0000208 next = chunk->next;
sewardjb8b79ad2008-03-03 01:35:41 +0000209 ML_(dinfo_free)(chunk);
sewardjeadcd862006-04-04 15:12:44 +0000210 }
sewardjb8b79ad2008-03-03 01:35:41 +0000211
212 /* Delete the two admin lists. These lists exist purely so that we
213 can visit each object exactly once when we need to delete
214 them. */
215 for (admin1 = di->admin_tyadmins; admin1; admin1 = admin2) {
216 admin2 = admin1->next;
217 ML_(delete_TyAdmin_and_payload)(admin1);
218 }
219 for (gexpr1 = di->admin_gexprs; gexpr1; gexpr1 = gexpr2) {
220 gexpr2 = gexpr1->next;
221 ML_(dinfo_free)(gexpr1);
222 }
223
224 /* Dump the variable info. This is kinda complex: we must take
225 care not to free items which reside in either the admin lists
226 (as we have just freed them) or which reside in the DebugInfo's
227 string table. */
228 if (di->varinfo) {
229 for (i = 0; i < VG_(sizeXA)(di->varinfo); i++) {
230 OSet* scope = *(OSet**)VG_(indexXA)(di->varinfo, i);
231 if (!scope) continue;
232 /* iterate over all entries in 'scope' */
233 VG_(OSetGen_ResetIter)(scope);
234 while (True) {
235 DiAddrRange* arange = VG_(OSetGen_Next)(scope);
236 if (!arange) break;
237 /* for each var in 'arange' */
238 vg_assert(arange->vars);
239 for (j = 0; j < VG_(sizeXA)( arange->vars ); j++) {
240 DiVariable* var = (DiVariable*)VG_(indexXA)(arange->vars,j);
241 vg_assert(var);
242 /* Nothing to free in var: all the pointer fields refer
243 to stuff either on an admin list, or in
244 .strchunks */
245 }
246 VG_(deleteXA)(arange->vars);
247 /* Don't free arange itself, as OSetGen_Destroy does
248 that */
249 }
250 VG_(OSetGen_Destroy)(scope);
251 }
252 VG_(deleteXA)(di->varinfo);
253 }
254
255 ML_(dinfo_free)(di);
sewardjeadcd862006-04-04 15:12:44 +0000256}
257
258
sewardjb8b79ad2008-03-03 01:35:41 +0000259/* 'si' is a member of debugInfo_list. Find it, remove it from the
sewardjeadcd862006-04-04 15:12:44 +0000260 list, notify m_redir that this has happened, and free all storage
261 reachable from it.
262*/
sewardjb8b79ad2008-03-03 01:35:41 +0000263static void discard_DebugInfo ( DebugInfo* di )
sewardjeadcd862006-04-04 15:12:44 +0000264{
sewardj4ee4f982006-10-17 01:37:10 +0000265# if defined(VGP_ppc32_aix5)
266 HChar* reason = "__unload";
267# elif defined(VGP_ppc64_aix5)
268 HChar* reason = "kunload64";
269# else
270 HChar* reason = "munmap";
271# endif
272
sewardjb8b79ad2008-03-03 01:35:41 +0000273 DebugInfo** prev_next_ptr = &debugInfo_list;
274 DebugInfo* curr = debugInfo_list;
sewardjeadcd862006-04-04 15:12:44 +0000275
276 while (curr) {
sewardjb8b79ad2008-03-03 01:35:41 +0000277 if (curr == di) {
278 /* Found it; remove from list and free it. */
sewardj33e4e7e2008-03-06 18:31:42 +0000279 if (curr->have_dinfo
280 && (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir)))
sewardjeadcd862006-04-04 15:12:44 +0000281 VG_(message)(Vg_DebugMsg,
sewardj4ee4f982006-10-17 01:37:10 +0000282 "Discarding syms at %p-%p in %s due to %s()",
sewardjb8b79ad2008-03-03 01:35:41 +0000283 di->text_avma,
284 di->text_avma + di->text_size,
sewardj4ee4f982006-10-17 01:37:10 +0000285 curr->filename ? curr->filename : (UChar*)"???",
286 reason);
sewardjeadcd862006-04-04 15:12:44 +0000287 vg_assert(*prev_next_ptr == curr);
288 *prev_next_ptr = curr->next;
sewardj33e4e7e2008-03-06 18:31:42 +0000289 if (curr->have_dinfo)
290 VG_(redir_notify_delete_DebugInfo)( curr );
sewardjb8b79ad2008-03-03 01:35:41 +0000291 free_DebugInfo(curr);
sewardjeadcd862006-04-04 15:12:44 +0000292 return;
293 }
294 prev_next_ptr = &curr->next;
295 curr = curr->next;
296 }
297
sewardjb8b79ad2008-03-03 01:35:41 +0000298 /* Not found. */
sewardjeadcd862006-04-04 15:12:44 +0000299}
300
301
sewardjb8b79ad2008-03-03 01:35:41 +0000302/* Repeatedly scan debugInfo_list, looking for DebugInfos with text
303 AVMAs intersecting [start,start+length), and call discard_DebugInfo
304 to get rid of them. This modifies the list, hence the multiple
305 iterations.
306*/
sewardjeadcd862006-04-04 15:12:44 +0000307static void discard_syms_in_range ( Addr start, SizeT length )
308{
sewardjb8b79ad2008-03-03 01:35:41 +0000309 Bool found;
310 DebugInfo* curr;
sewardjeadcd862006-04-04 15:12:44 +0000311
312 while (True) {
313 found = False;
314
sewardjb8b79ad2008-03-03 01:35:41 +0000315 curr = debugInfo_list;
sewardjeadcd862006-04-04 15:12:44 +0000316 while (True) {
317 if (curr == NULL)
318 break;
sewardjb8b79ad2008-03-03 01:35:41 +0000319 if (curr->text_present
320 && curr->text_size > 0
321 && (start+length - 1 < curr->text_avma
322 || curr->text_avma + curr->text_size - 1 < start)) {
sewardjeadcd862006-04-04 15:12:44 +0000323 /* no overlap */
324 } else {
325 found = True;
326 break;
327 }
328 curr = curr->next;
329 }
330
331 if (!found) break;
sewardjb8b79ad2008-03-03 01:35:41 +0000332 discard_DebugInfo( curr );
sewardjeadcd862006-04-04 15:12:44 +0000333 }
334}
335
336
sewardjb8b79ad2008-03-03 01:35:41 +0000337/* Does [s1,+len1) overlap [s2,+len2) ? Note: does not handle
338 wraparound at the end of the address space -- just asserts in that
339 case. */
340static Bool ranges_overlap (Addr s1, SizeT len1, Addr s2, SizeT len2 )
sewardjeadcd862006-04-04 15:12:44 +0000341{
sewardjb8b79ad2008-03-03 01:35:41 +0000342 Addr e1, e2;
343 if (len1 == 0 || len2 == 0)
344 return False;
345 e1 = s1 + len1 - 1;
346 e2 = s2 + len2 - 1;
347 /* Assert that we don't have wraparound. If we do it would imply
348 that file sections are getting mapped around the end of the
349 address space, which sounds unlikely. */
350 vg_assert(s1 <= e1);
351 vg_assert(s2 <= e2);
352 if (e1 < s2 || e2 < s1) return False;
353 return True;
354}
sewardjeadcd862006-04-04 15:12:44 +0000355
sewardjeadcd862006-04-04 15:12:44 +0000356
sewardjb8b79ad2008-03-03 01:35:41 +0000357/* Do the basic rx_ and rw_ mappings of the two DebugInfos overlap in
358 any way? */
359static Bool do_DebugInfos_overlap ( DebugInfo* di1, DebugInfo* di2 )
360{
361 vg_assert(di1);
362 vg_assert(di2);
sewardjeadcd862006-04-04 15:12:44 +0000363
sewardjb8b79ad2008-03-03 01:35:41 +0000364 if (di1->have_rx_map && di2->have_rx_map
365 && ranges_overlap(di1->rx_map_avma, di1->rx_map_size,
366 di2->rx_map_avma, di2->rx_map_size))
367 return True;
sewardjeadcd862006-04-04 15:12:44 +0000368
sewardjb8b79ad2008-03-03 01:35:41 +0000369 if (di1->have_rx_map && di2->have_rw_map
370 && ranges_overlap(di1->rx_map_avma, di1->rx_map_size,
371 di2->rw_map_avma, di2->rw_map_size))
372 return True;
373
374 if (di1->have_rw_map && di2->have_rx_map
375 && ranges_overlap(di1->rw_map_avma, di1->rw_map_size,
376 di2->rx_map_avma, di2->rx_map_size))
377 return True;
378
379 if (di1->have_rw_map && di2->have_rw_map
380 && ranges_overlap(di1->rw_map_avma, di1->rw_map_size,
381 di2->rw_map_avma, di2->rw_map_size))
382 return True;
383
384 return False;
385}
386
387
388/* Discard all elements of debugInfo_list whose .mark bit is set.
389*/
390static void discard_marked_DebugInfos ( void )
391{
392 DebugInfo* curr;
393
394 while (True) {
395
396 curr = debugInfo_list;
397 while (True) {
398 if (!curr)
399 break;
400 if (curr->mark)
401 break;
402 curr = curr->next;
403 }
404
405 if (!curr) break;
406 discard_DebugInfo( curr );
407
sewardjeadcd862006-04-04 15:12:44 +0000408 }
sewardjb8b79ad2008-03-03 01:35:41 +0000409}
sewardjeadcd862006-04-04 15:12:44 +0000410
sewardjb8b79ad2008-03-03 01:35:41 +0000411
412/* Discard any elements of debugInfo_list which overlap with diRef.
413 Clearly diRef must have its rx_ and rw_ mapping information set to
414 something sane. */
415#if defined(VGO_aix5)
416__attribute__((unused))
417#endif
418static void discard_DebugInfos_which_overlap_with ( DebugInfo* diRef )
419{
420 DebugInfo* di;
421 /* Mark all the DebugInfos in debugInfo_list that need to be
422 deleted. First, clear all the mark bits; then set them if they
423 overlap with siRef. Since siRef itself is in this list we at
424 least expect its own mark bit to be set. */
425 for (di = debugInfo_list; di; di = di->next) {
426 di->mark = do_DebugInfos_overlap( di, diRef );
427 if (di == diRef) {
428 vg_assert(di->mark);
429 di->mark = False;
430 }
431 }
432 discard_marked_DebugInfos();
433}
434
435
436/* Find the existing DebugInfo for (memname,filename) or if not found,
437 create one. In the latter case memname and filename are strdup'd
438 into VG_AR_DINFO, and the new DebugInfo is added to
439 debugInfo_list. */
440static
441DebugInfo* find_or_create_DebugInfo_for ( UChar* filename, UChar* memname )
442{
443 DebugInfo* di;
444 vg_assert(filename);
445 for (di = debugInfo_list; di; di = di->next) {
446 vg_assert(di->filename);
447 if (0==VG_(strcmp)(di->filename, filename)
448 && ( (memname && di->memname)
449 ? 0==VG_(strcmp)(memname, di->memname)
450 : True ))
451 break;
452 }
453 if (!di) {
454 di = alloc_DebugInfo(filename, memname);
455 vg_assert(di);
456 di->next = debugInfo_list;
457 debugInfo_list = di;
458 }
459 return di;
sewardjeadcd862006-04-04 15:12:44 +0000460}
461
462
sewardj4ee4f982006-10-17 01:37:10 +0000463/*--------------------------------------------------------------*/
464/*--- ---*/
465/*--- TOP LEVEL: NOTIFICATION (ACQUIRE/DISCARD INFO) (LINUX) ---*/
466/*--- ---*/
467/*--------------------------------------------------------------*/
468
469#if defined(VGO_linux)
sewardjeadcd862006-04-04 15:12:44 +0000470
471/* The debug info system is driven by notifications that a text
472 segment has been mapped in, or unmapped. When that happens it
473 tries to acquire/discard whatever info is available for the
474 corresponding object. This section contains the notification
475 handlers. */
476
477/* Notify the debuginfo system about a new mapping. This is the way
478 new debug information gets loaded. If allow_SkFileV is True, it
479 will try load debug info if the mapping at 'a' belongs to Valgrind;
480 whereas normally (False) it will not do that. This allows us to
481 carefully control when the thing will read symbols from the
482 Valgrind executable itself. */
483
484void VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV )
485{
sewardj4ee4f982006-10-17 01:37:10 +0000486 NSegment const * seg;
sewardjb8b79ad2008-03-03 01:35:41 +0000487 HChar* filename;
488 Bool ok, is_rx_map, is_rw_map;
489 DebugInfo* di;
490 SysRes fd;
491 Int nread;
492 HChar buf1k[1024];
493 Bool debug = False;
bart15728ab2008-04-09 16:21:34 +0000494 SysRes statres;
495 struct vki_stat statbuf;
sewardjeadcd862006-04-04 15:12:44 +0000496
sewardjb8b79ad2008-03-03 01:35:41 +0000497 /* In short, figure out if this mapping is of interest to us, and
498 if so, try to guess what ld.so is doing and when/if we should
499 read debug info. */
500 seg = VG_(am_find_nsegment)(a);
501 vg_assert(seg);
sewardjeadcd862006-04-04 15:12:44 +0000502
sewardjb8b79ad2008-03-03 01:35:41 +0000503 if (debug)
504 VG_(printf)("di_notify_mmap-1: %p-%p %c%c%c\n",
505 seg->start, seg->end,
506 seg->hasR ? 'r' : '-',
507 seg->hasW ? 'w' : '-',seg->hasX ? 'x' : '-' );
508
509 /* guaranteed by aspacemgr-linux.c, sane_NSegment() */
510 vg_assert(seg->end > seg->start);
511
512 /* Ignore non-file mappings */
513 if ( ! (seg->kind == SkFileC
514 || (seg->kind == SkFileV && allow_SkFileV)) )
515 return;
516
517 /* If the file doesn't have a name, we're hosed. Give up. */
518 filename = VG_(am_get_filename)( (NSegment*)seg );
519 if (!filename)
520 return;
521
522 if (debug)
523 VG_(printf)("di_notify_mmap-2: %s\n", filename);
524
bart15728ab2008-04-09 16:21:34 +0000525 /* Only try to read debug information from regular files. */
526 statres = VG_(stat)(filename, &statbuf);
527 /* If the assert below ever fails, replace the VG_(stat)() call above */
528 /* by a VG_(lstat)() call. */
529 vg_assert(statres.isError || ! VKI_S_ISLNK(statbuf.st_mode));
530 if (statres.isError || ! VKI_S_ISREG(statbuf.st_mode))
531 {
sewardj2ac79d32008-03-17 16:23:54 +0000532 return;
533 }
sewardj2ac79d32008-03-17 16:23:54 +0000534
bart15728ab2008-04-09 16:21:34 +0000535
536 /* Peer at the first few bytes of the file, to see if it is an ELF */
537 /* object file. Ignore the file if we do not have read permission. */
sewardjb8b79ad2008-03-03 01:35:41 +0000538 VG_(memset)(buf1k, 0, sizeof(buf1k));
539 fd = VG_(open)( filename, VKI_O_RDONLY, 0 );
540 if (fd.isError) {
541 DebugInfo fake_di;
bart15728ab2008-04-09 16:21:34 +0000542 if (fd.err != VKI_EACCES)
543 {
544 VG_(memset)(&fake_di, 0, sizeof(fake_di));
545 fake_di.filename = filename;
546 ML_(symerr)(&fake_di, True, "can't open file to inspect ELF header");
547 }
sewardjb8b79ad2008-03-03 01:35:41 +0000548 return;
549 }
550 nread = VG_(read)( fd.res, buf1k, sizeof(buf1k) );
551 VG_(close)( fd.res );
552
553 if (nread <= 0) {
554 ML_(symerr)(NULL, True, "can't read file to inspect ELF header");
555 return;
556 }
557 vg_assert(nread > 0 && nread <= sizeof(buf1k) );
558
559 /* We're only interested in mappings of ELF object files. */
560 if (!ML_(is_elf_object_file)( buf1k, (SizeT)nread ))
561 return;
562
563 /* Now we have to guess if this is a text-like mapping, a data-like
564 mapping, neither or both. The rules are:
565
566 text if: x86-linux r and x
567 other-linux r and x and not w
568
569 data if: x86-linux r and w
570 other-linux r and w and not x
571
572 Background: On x86-linux, objects are typically mapped twice:
sewardjeadcd862006-04-04 15:12:44 +0000573
574 1b8fb000-1b8ff000 r-xp 00000000 08:02 4471477 vgpreload_memcheck.so
575 1b8ff000-1b900000 rw-p 00004000 08:02 4471477 vgpreload_memcheck.so
576
577 whereas ppc32-linux mysteriously does this:
578
579 118a6000-118ad000 r-xp 00000000 08:05 14209428 vgpreload_memcheck.so
580 118ad000-118b6000 ---p 00007000 08:05 14209428 vgpreload_memcheck.so
581 118b6000-118bd000 rwxp 00000000 08:05 14209428 vgpreload_memcheck.so
582
583 The third mapping should not be considered to have executable
584 code in. Therefore a test which works for both is: r and x and
585 NOT w. Reading symbols from the rwx segment -- which overlaps
586 the r-x segment in the file -- causes the redirection mechanism
587 to redirect to addresses in that third segment, which is wrong
588 and causes crashes.
589
sewardjeadcd862006-04-04 15:12:44 +0000590 JRS 28 Dec 05: unfortunately icc 8.1 on x86 has been seen to
591 produce executables with a single rwx segment rather than a
592 (r-x,rw-) pair. That means the rules have to be modified thusly:
593
594 x86-linux: consider if r and x
sewardjb8b79ad2008-03-03 01:35:41 +0000595 all others: consider if r and x and not w
sewardjeadcd862006-04-04 15:12:44 +0000596 */
sewardjb8b79ad2008-03-03 01:35:41 +0000597 is_rx_map = False;
598 is_rw_map = False;
sewardjeadcd862006-04-04 15:12:44 +0000599# if defined(VGP_x86_linux)
sewardjb8b79ad2008-03-03 01:35:41 +0000600 is_rx_map = seg->hasR && seg->hasX;
601 is_rw_map = seg->hasR && seg->hasW;
602# elif defined(VGP_amd64_linux) \
603 || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
604 is_rx_map = seg->hasR && seg->hasX && !seg->hasW;
605 is_rw_map = seg->hasR && seg->hasW && !seg->hasX;
sewardjeadcd862006-04-04 15:12:44 +0000606# else
sewardjb8b79ad2008-03-03 01:35:41 +0000607# error "Unknown platform"
sewardjeadcd862006-04-04 15:12:44 +0000608# endif
609
sewardjb8b79ad2008-03-03 01:35:41 +0000610 if (debug)
611 VG_(printf)("di_notify_mmap-3: is_rx_map %d, is_rw_map %d\n",
612 (Int)is_rx_map, (Int)is_rw_map);
sewardjeadcd862006-04-04 15:12:44 +0000613
sewardjb8b79ad2008-03-03 01:35:41 +0000614 /* If it is neither text-ish nor data-ish, we're not interested. */
615 if (!(is_rx_map || is_rw_map))
sewardjeadcd862006-04-04 15:12:44 +0000616 return;
617
sewardjb8b79ad2008-03-03 01:35:41 +0000618 /* See if we have a DebugInfo for this filename. If not,
619 create one. */
620 di = find_or_create_DebugInfo_for( filename, NULL/*membername*/ );
621 vg_assert(di);
sewardjeadcd862006-04-04 15:12:44 +0000622
sewardjb8b79ad2008-03-03 01:35:41 +0000623 if (is_rx_map) {
624 /* We have a text-like mapping. Note the details. */
625 if (!di->have_rx_map) {
626 di->have_rx_map = True;
627 di->rx_map_avma = a;
628 di->rx_map_size = seg->end + 1 - seg->start;
629 di->rx_map_foff = seg->offset;
630 } else {
631 /* FIXME: complain about a second text-like mapping */
632 }
sewardjeadcd862006-04-04 15:12:44 +0000633 }
634
sewardjb8b79ad2008-03-03 01:35:41 +0000635 if (is_rw_map) {
636 /* We have a data-like mapping. Note the details. */
637 if (!di->have_rw_map) {
638 di->have_rw_map = True;
639 di->rw_map_avma = a;
640 di->rw_map_size = seg->end + 1 - seg->start;
641 di->rw_map_foff = seg->offset;
642 } else {
643 /* FIXME: complain about a second data-like mapping */
644 }
645 }
sewardjeadcd862006-04-04 15:12:44 +0000646
sewardjb8b79ad2008-03-03 01:35:41 +0000647 if (di->have_rx_map && di->have_rw_map && !di->have_dinfo) {
sewardjeadcd862006-04-04 15:12:44 +0000648
sewardjb8b79ad2008-03-03 01:35:41 +0000649 vg_assert(di->filename);
650 TRACE_SYMTAB("\n");
651 TRACE_SYMTAB("------ start ELF OBJECT "
652 "------------------------------\n");
653 TRACE_SYMTAB("------ name = %s\n", di->filename);
654 TRACE_SYMTAB("\n");
655
656 /* We're going to read symbols and debug info for the avma
657 ranges [rx_map_avma, +rx_map_size) and [rw_map_avma,
658 +rw_map_size). First get rid of any other DebugInfos which
659 overlap either of those ranges (to avoid total confusion). */
660 discard_DebugInfos_which_overlap_with( di );
661
662 /* .. and acquire new info. */
663 ok = ML_(read_elf_debug_info)( di );
664
665 if (ok) {
666 TRACE_SYMTAB("\n------ Canonicalising the "
667 "acquired info ------\n");
668 /* prepare read data for use */
669 ML_(canonicaliseTables)( di );
670 /* notify m_redir about it */
671 TRACE_SYMTAB("\n------ Notifying m_redir ------\n");
672 VG_(redir_notify_new_DebugInfo)( di );
673 /* Note that we succeeded */
674 di->have_dinfo = True;
675 } else {
676 TRACE_SYMTAB("\n------ ELF reading failed ------\n");
677 /* Something went wrong (eg. bad ELF file). Should we delete
678 this DebugInfo? No - it contains info on the rw/rx
679 mappings, at least. */
680 }
681
682 TRACE_SYMTAB("\n");
683 TRACE_SYMTAB("------ name = %s\n", di->filename);
684 TRACE_SYMTAB("------ end ELF OBJECT "
685 "------------------------------\n");
686 TRACE_SYMTAB("\n");
687
688 }
sewardjeadcd862006-04-04 15:12:44 +0000689}
690
691
692/* Unmap is simpler - throw away any SegInfos intersecting
693 [a, a+len). */
694void VG_(di_notify_munmap)( Addr a, SizeT len )
695{
sewardjb8b79ad2008-03-03 01:35:41 +0000696 if (0) VG_(printf)("DISCARD %p %p\n", a, a+len);
sewardjeadcd862006-04-04 15:12:44 +0000697 discard_syms_in_range(a, len);
698}
699
700
701/* Uh, this doesn't do anything at all. IIRC glibc (or ld.so, I don't
702 remember) does a bunch of mprotects on itself, and if we follow
703 through here, it causes the debug info for that object to get
704 discarded. */
705void VG_(di_notify_mprotect)( Addr a, SizeT len, UInt prot )
706{
707 Bool exe_ok = toBool(prot & VKI_PROT_EXEC);
708# if defined(VGP_x86_linux)
709 exe_ok = exe_ok || toBool(prot & VKI_PROT_READ);
710# endif
711 if (0 && !exe_ok)
712 discard_syms_in_range(a, len);
713}
714
sewardj4ee4f982006-10-17 01:37:10 +0000715#endif /* defined(VGO_linux) */
716
717
718/*-------------------------------------------------------------*/
719/*--- ---*/
720/*--- TOP LEVEL: NOTIFICATION (ACQUIRE/DISCARD INFO) (AIX5) ---*/
721/*--- ---*/
722/*-------------------------------------------------------------*/
723
724#if defined(VGO_aix5)
725
726/* The supplied parameters describe a code segment and its associated
727 data segment, that have recently been mapped in -- so we need to
728 read debug info for it -- or conversely, have recently been dumped,
729 in which case the relevant debug info has to be unloaded. */
730
731void VG_(di_aix5_notify_segchange)(
732 Addr code_start,
733 Word code_len,
734 Addr data_start,
735 Word data_len,
736 UChar* file_name,
737 UChar* mem_name,
738 Bool is_mainexe,
739 Bool acquire )
740{
sewardj4ee4f982006-10-17 01:37:10 +0000741 if (acquire) {
742
sewardjb8b79ad2008-03-03 01:35:41 +0000743 Bool ok;
744 DebugInfo* di;
745 di = find_or_create_DebugInfo_for( file_name, mem_name );
746 vg_assert(di);
747
748 if (code_len > 0) {
749 di->text_present = True;
750 di->text_svma = 0; /* don't know yet */
751 di->text_bias = 0; /* don't know yet */
752 di->text_avma = code_start;
753 di->text_size = code_len;
754 }
755 if (data_len > 0) {
756 di->data_present = True;
757 di->data_svma = 0; /* don't know yet */
758 di->data_bias = 0; /* don't know yet */
759 di->data_avma = data_start;
760 di->data_size = data_len;
761 }
762
763 /* These need to be filled in in order to keep various
764 assertions in storage.c happy. In particular see
765 "Comment_Regarding_Text_Range_Checks" in that file. */
766 di->have_rx_map = True;
767 di->rx_map_avma = code_start;
768 di->rx_map_size = code_len;
769 di->have_rw_map = True;
770 di->rw_map_avma = data_start;
771 di->rw_map_size = data_len;
772
773 ok = ML_(read_xcoff_debug_info) ( di, is_mainexe );
774
775 if (ok) {
776 /* prepare read data for use */
777 ML_(canonicaliseTables)( di );
778 /* notify m_redir about it */
779 VG_(redir_notify_new_DebugInfo)( di );
780 /* Note that we succeeded */
781 di->have_dinfo = True;
782 } else {
783 /* Something went wrong (eg. bad XCOFF file). */
784 discard_DebugInfo( di );
785 di = NULL;
786 }
sewardj4ee4f982006-10-17 01:37:10 +0000787
788 } else {
789
sewardjb8b79ad2008-03-03 01:35:41 +0000790 /* Dump all the debugInfos whose text segments intersect
sewardjf7cdfe22007-02-09 02:11:06 +0000791 code_start/code_len. */
sewardjb8b79ad2008-03-03 01:35:41 +0000792 if (code_len > 0)
793 discard_syms_in_range( code_start, code_len );
sewardj4ee4f982006-10-17 01:37:10 +0000794
795 }
796}
797
798
799#endif /* defined(VGO_aix5) */
800
sewardjeadcd862006-04-04 15:12:44 +0000801
802/*------------------------------------------------------------*/
803/*--- ---*/
804/*--- TOP LEVEL: QUERYING EXISTING DEBUG INFO ---*/
805/*--- ---*/
806/*------------------------------------------------------------*/
807
808/*------------------------------------------------------------*/
809/*--- Use of symbol table & location info to create ---*/
810/*--- plausible-looking stack dumps. ---*/
811/*------------------------------------------------------------*/
812
813/* Search all symtabs that we know about to locate ptr. If found, set
sewardjb8b79ad2008-03-03 01:35:41 +0000814 *pdi to the relevant DebugInfo, and *symno to the symtab entry
815 *number within that. If not found, *psi is set to NULL.
816 If findText==True, only text symbols are searched for.
817 If findText==False, only data symbols are searched for.
818*/
819static void search_all_symtabs ( Addr ptr, /*OUT*/DebugInfo** pdi,
sewardjeadcd862006-04-04 15:12:44 +0000820 /*OUT*/Int* symno,
sewardjb8b79ad2008-03-03 01:35:41 +0000821 Bool match_anywhere_in_sym,
822 Bool findText )
sewardjeadcd862006-04-04 15:12:44 +0000823{
sewardjb8b79ad2008-03-03 01:35:41 +0000824 Int sno;
825 DebugInfo* di;
826 Bool inRange;
sewardjeadcd862006-04-04 15:12:44 +0000827
sewardjb8b79ad2008-03-03 01:35:41 +0000828 for (di = debugInfo_list; di != NULL; di = di->next) {
829
830 if (findText) {
831 inRange = di->text_present
832 && di->text_size > 0
833 && di->text_avma <= ptr
834 && ptr < di->text_avma + di->text_size;
835 } else {
836 inRange = (di->data_present
837 && di->data_size > 0
838 && di->data_avma <= ptr
839 && ptr < di->data_avma + di->data_size)
840 ||
841 (di->sdata_present
842 && di->sdata_size > 0
843 && di->sdata_avma <= ptr
844 && ptr < di->sdata_avma + di->sdata_size)
845 ||
846 (di->bss_present
847 && di->bss_size > 0
848 && di->bss_avma <= ptr
849 && ptr < di->bss_avma + di->bss_size);
sewardjeadcd862006-04-04 15:12:44 +0000850 }
sewardjb8b79ad2008-03-03 01:35:41 +0000851
852 if (!inRange) continue;
853
854 sno = ML_(search_one_symtab) (
855 di, ptr, match_anywhere_in_sym, findText );
856 if (sno == -1) goto not_found;
857 *symno = sno;
858 *pdi = di;
859 return;
860
sewardjeadcd862006-04-04 15:12:44 +0000861 }
862 not_found:
sewardjb8b79ad2008-03-03 01:35:41 +0000863 *pdi = NULL;
sewardjeadcd862006-04-04 15:12:44 +0000864}
865
866
867/* Search all loctabs that we know about to locate ptr. If found, set
sewardjb8b79ad2008-03-03 01:35:41 +0000868 *pdi to the relevant DebugInfo, and *locno to the loctab entry
869 *number within that. If not found, *pdi is set to NULL. */
870static void search_all_loctabs ( Addr ptr, /*OUT*/DebugInfo** pdi,
sewardjeadcd862006-04-04 15:12:44 +0000871 /*OUT*/Int* locno )
872{
sewardjb8b79ad2008-03-03 01:35:41 +0000873 Int lno;
874 DebugInfo* di;
875 for (di = debugInfo_list; di != NULL; di = di->next) {
876 if (di->text_present
877 && di->text_avma <= ptr
878 && ptr < di->text_avma + di->text_size) {
879 lno = ML_(search_one_loctab) ( di, ptr );
sewardjeadcd862006-04-04 15:12:44 +0000880 if (lno == -1) goto not_found;
881 *locno = lno;
sewardjb8b79ad2008-03-03 01:35:41 +0000882 *pdi = di;
sewardjeadcd862006-04-04 15:12:44 +0000883 return;
884 }
885 }
886 not_found:
sewardjb8b79ad2008-03-03 01:35:41 +0000887 *pdi = NULL;
sewardjeadcd862006-04-04 15:12:44 +0000888}
889
890
891/* The whole point of this whole big deal: map a code address to a
892 plausible symbol name. Returns False if no idea; otherwise True.
893 Caller supplies buf and nbuf. If demangle is False, don't do
894 demangling, regardless of VG_(clo_demangle) -- probably because the
sewardjb8b79ad2008-03-03 01:35:41 +0000895 call has come from VG_(get_fnname_nodemangle)(). findText
896 indicates whether we're looking for a text symbol or a data symbol
897 -- caller must choose one kind or the other. */
sewardjeadcd862006-04-04 15:12:44 +0000898static
sewardjb8b79ad2008-03-03 01:35:41 +0000899Bool get_sym_name ( Bool demangle, Addr a, Char* buf, Int nbuf,
900 Bool match_anywhere_in_sym, Bool show_offset,
901 Bool findText, /*OUT*/OffT* offsetP )
sewardjeadcd862006-04-04 15:12:44 +0000902{
sewardjb8b79ad2008-03-03 01:35:41 +0000903 DebugInfo* di;
904 Int sno;
905 Int offset;
sewardjeadcd862006-04-04 15:12:44 +0000906
sewardjb8b79ad2008-03-03 01:35:41 +0000907 search_all_symtabs ( a, &di, &sno, match_anywhere_in_sym, findText );
908 if (di == NULL)
sewardjeadcd862006-04-04 15:12:44 +0000909 return False;
910 if (demangle) {
911 VG_(demangle) ( True/*do C++ demangle*/,
sewardjb8b79ad2008-03-03 01:35:41 +0000912 di->symtab[sno].name, buf, nbuf );
sewardjeadcd862006-04-04 15:12:44 +0000913 } else {
sewardjb8b79ad2008-03-03 01:35:41 +0000914 VG_(strncpy_safely) ( buf, di->symtab[sno].name, nbuf );
sewardjeadcd862006-04-04 15:12:44 +0000915 }
916
sewardjb8b79ad2008-03-03 01:35:41 +0000917 offset = a - di->symtab[sno].addr;
918 if (offsetP) *offsetP = (OffT)offset;
919
sewardjeadcd862006-04-04 15:12:44 +0000920 if (show_offset && offset != 0) {
921 Char buf2[12];
922 Char* symend = buf + VG_(strlen)(buf);
923 Char* end = buf + nbuf;
924 Int len;
925
926 len = VG_(sprintf)(buf2, "%c%d",
927 offset < 0 ? '-' : '+',
928 offset < 0 ? -offset : offset);
929 vg_assert(len < (Int)sizeof(buf2));
930
931 if (len < (end - symend)) {
932 Char *cp = buf2;
933 VG_(memcpy)(symend, cp, len+1);
934 }
935 }
936
937 return True;
938}
939
940/* ppc64-linux only: find the TOC pointer (R2 value) that should be in
941 force at the entry point address of the function containing
942 guest_code_addr. Returns 0 if not known. */
943Addr VG_(get_tocptr) ( Addr guest_code_addr )
944{
sewardjb8b79ad2008-03-03 01:35:41 +0000945 DebugInfo* si;
946 Int sno;
sewardjeadcd862006-04-04 15:12:44 +0000947 search_all_symtabs ( guest_code_addr,
sewardjb8b79ad2008-03-03 01:35:41 +0000948 &si, &sno,
949 True/*match_anywhere_in_fun*/,
950 True/*consider text symbols only*/ );
sewardjeadcd862006-04-04 15:12:44 +0000951 if (si == NULL)
952 return 0;
953 else
954 return si->symtab[sno].tocptr;
955}
956
957/* This is available to tools... always demangle C++ names,
958 match anywhere in function, but don't show offsets. */
959Bool VG_(get_fnname) ( Addr a, Char* buf, Int nbuf )
960{
sewardjb8b79ad2008-03-03 01:35:41 +0000961 return get_sym_name ( /*demangle*/True, a, buf, nbuf,
962 /*match_anywhere_in_fun*/True,
963 /*show offset?*/False,
964 /*text syms only*/True,
965 /*offsetP*/NULL );
sewardjeadcd862006-04-04 15:12:44 +0000966}
967
968/* This is available to tools... always demangle C++ names,
969 match anywhere in function, and show offset if nonzero. */
970Bool VG_(get_fnname_w_offset) ( Addr a, Char* buf, Int nbuf )
971{
sewardjb8b79ad2008-03-03 01:35:41 +0000972 return get_sym_name ( /*demangle*/True, a, buf, nbuf,
973 /*match_anywhere_in_fun*/True,
974 /*show offset?*/True,
975 /*text syms only*/True,
976 /*offsetP*/NULL );
sewardjeadcd862006-04-04 15:12:44 +0000977}
978
979/* This is available to tools... always demangle C++ names,
980 only succeed if 'a' matches first instruction of function,
981 and don't show offsets. */
982Bool VG_(get_fnname_if_entry) ( Addr a, Char* buf, Int nbuf )
983{
sewardjb8b79ad2008-03-03 01:35:41 +0000984 return get_sym_name ( /*demangle*/True, a, buf, nbuf,
985 /*match_anywhere_in_fun*/False,
986 /*show offset?*/False,
987 /*text syms only*/True,
988 /*offsetP*/NULL );
sewardjeadcd862006-04-04 15:12:44 +0000989}
990
991/* This is only available to core... don't demangle C++ names,
992 match anywhere in function, and don't show offsets. */
993Bool VG_(get_fnname_nodemangle) ( Addr a, Char* buf, Int nbuf )
994{
sewardjb8b79ad2008-03-03 01:35:41 +0000995 return get_sym_name ( /*demangle*/False, a, buf, nbuf,
996 /*match_anywhere_in_fun*/True,
997 /*show offset?*/False,
998 /*text syms only*/True,
999 /*offsetP*/NULL );
sewardjeadcd862006-04-04 15:12:44 +00001000}
1001
1002/* This is only available to core... don't demangle C++ names, but do
1003 do Z-demangling, match anywhere in function, and don't show
1004 offsets. */
1005Bool VG_(get_fnname_Z_demangle_only) ( Addr a, Char* buf, Int nbuf )
1006{
1007# define N_TMPBUF 4096 /* arbitrary, 4096 == ERRTXT_LEN */
1008 Char tmpbuf[N_TMPBUF];
1009 Bool ok;
1010 vg_assert(nbuf > 0);
sewardjb8b79ad2008-03-03 01:35:41 +00001011 ok = get_sym_name ( /*demangle*/False, a, tmpbuf, N_TMPBUF,
1012 /*match_anywhere_in_fun*/True,
1013 /*show offset?*/False,
1014 /*text syms only*/True,
1015 /*offsetP*/NULL );
sewardjeadcd862006-04-04 15:12:44 +00001016 tmpbuf[N_TMPBUF-1] = 0; /* paranoia */
1017 if (!ok)
1018 return False;
1019
1020 /* We have something, at least. Try to Z-demangle it. */
1021 VG_(demangle)( False/*don't do C++ demangling*/, tmpbuf, buf, nbuf);
1022
1023 buf[nbuf-1] = 0; /* paranoia */
1024 return True;
1025# undef N_TMPBUF
1026}
1027
sewardjb8b79ad2008-03-03 01:35:41 +00001028/* Looks up data_addr in the collection of data symbols, and if found
1029 puts its name (or as much as will fit) into dname[0 .. n_dname-1],
1030 which is guaranteed to be zero terminated. Also data_addr's offset
1031 from the symbol start is put into *offset. */
1032Bool VG_(get_datasym_and_offset)( Addr data_addr,
1033 /*OUT*/Char* dname, Int n_dname,
1034 /*OUT*/OffT* offset )
1035{
1036 Bool ok;
1037 vg_assert(n_dname > 1);
1038 ok = get_sym_name ( /*demangle*/False, data_addr, dname, n_dname,
1039 /*match_anywhere_in_sym*/True,
1040 /*show offset?*/False,
1041 /*data syms only please*/False,
1042 offset );
1043 if (!ok)
1044 return False;
1045 dname[n_dname-1] = 0;
1046 return True;
1047}
1048
1049/* Map a code address to the name of a shared object file or the
1050 executable. Returns False if no idea; otherwise True. Doesn't
1051 require debug info. Caller supplies buf and nbuf. */
sewardjeadcd862006-04-04 15:12:44 +00001052Bool VG_(get_objname) ( Addr a, Char* buf, Int nbuf )
1053{
sewardj4ee4f982006-10-17 01:37:10 +00001054 Int used;
sewardjb8b79ad2008-03-03 01:35:41 +00001055 DebugInfo* di;
tomf32ec7f2008-01-08 17:44:04 +00001056 const NSegment *seg;
1057 HChar* filename;
sewardj4ee4f982006-10-17 01:37:10 +00001058 vg_assert(nbuf > 0);
sewardjb8b79ad2008-03-03 01:35:41 +00001059 for (di = debugInfo_list; di != NULL; di = di->next) {
1060 if (di->text_present
1061 && di->text_avma <= a
1062 && a < di->text_avma + di->text_size) {
1063 VG_(strncpy_safely)(buf, di->filename, nbuf);
1064 if (di->memname) {
sewardj4ee4f982006-10-17 01:37:10 +00001065 used = VG_(strlen)(buf);
1066 if (used < nbuf)
1067 VG_(strncpy_safely)(&buf[used], "(", nbuf-used);
1068 used = VG_(strlen)(buf);
1069 if (used < nbuf)
sewardjb8b79ad2008-03-03 01:35:41 +00001070 VG_(strncpy_safely)(&buf[used], di->memname, nbuf-used);
sewardj4ee4f982006-10-17 01:37:10 +00001071 used = VG_(strlen)(buf);
1072 if (used < nbuf)
1073 VG_(strncpy_safely)(&buf[used], ")", nbuf-used);
1074 }
1075 buf[nbuf-1] = 0;
sewardjeadcd862006-04-04 15:12:44 +00001076 return True;
1077 }
1078 }
tomf32ec7f2008-01-08 17:44:04 +00001079 if ((seg = VG_(am_find_nsegment(a))) != NULL &&
1080 (filename = VG_(am_get_filename)(seg)) != NULL)
1081 {
1082 VG_(strncpy_safely)(buf, filename, nbuf);
1083 return True;
1084 }
sewardjeadcd862006-04-04 15:12:44 +00001085 return False;
1086}
1087
sewardjb8b79ad2008-03-03 01:35:41 +00001088/* Map a code address to its DebugInfo. Returns NULL if not found. Doesn't
sewardjeadcd862006-04-04 15:12:44 +00001089 require debug info. */
sewardjb8b79ad2008-03-03 01:35:41 +00001090DebugInfo* VG_(find_seginfo) ( Addr a )
sewardjeadcd862006-04-04 15:12:44 +00001091{
sewardjb8b79ad2008-03-03 01:35:41 +00001092 DebugInfo* di;
1093 for (di = debugInfo_list; di != NULL; di = di->next) {
1094 if (di->text_present
1095 && di->text_avma <= a
1096 && a < di->text_avma + di->text_size) {
1097 return di;
sewardjeadcd862006-04-04 15:12:44 +00001098 }
1099 }
1100 return NULL;
1101}
1102
1103/* Map a code address to a filename. Returns True if successful. */
1104Bool VG_(get_filename)( Addr a, Char* filename, Int n_filename )
1105{
sewardjb8b79ad2008-03-03 01:35:41 +00001106 DebugInfo* si;
sewardjeadcd862006-04-04 15:12:44 +00001107 Int locno;
1108 search_all_loctabs ( a, &si, &locno );
1109 if (si == NULL)
1110 return False;
1111 VG_(strncpy_safely)(filename, si->loctab[locno].filename, n_filename);
1112 return True;
1113}
1114
1115/* Map a code address to a line number. Returns True if successful. */
1116Bool VG_(get_linenum)( Addr a, UInt* lineno )
1117{
sewardjb8b79ad2008-03-03 01:35:41 +00001118 DebugInfo* si;
sewardjeadcd862006-04-04 15:12:44 +00001119 Int locno;
1120 search_all_loctabs ( a, &si, &locno );
1121 if (si == NULL)
1122 return False;
1123 *lineno = si->loctab[locno].lineno;
1124
1125 return True;
1126}
1127
1128/* Map a code address to a filename/line number/dir name info.
1129 See prototype for detailed description of behaviour.
1130*/
1131Bool VG_(get_filename_linenum) ( Addr a,
1132 /*OUT*/Char* filename, Int n_filename,
1133 /*OUT*/Char* dirname, Int n_dirname,
1134 /*OUT*/Bool* dirname_available,
1135 /*OUT*/UInt* lineno )
1136{
sewardjb8b79ad2008-03-03 01:35:41 +00001137 DebugInfo* si;
sewardjeadcd862006-04-04 15:12:44 +00001138 Int locno;
1139
1140 vg_assert( (dirname == NULL && dirname_available == NULL)
1141 ||
1142 (dirname != NULL && dirname_available != NULL) );
1143
1144 search_all_loctabs ( a, &si, &locno );
njnc1b1d422007-04-19 23:35:42 +00001145 if (si == NULL) {
njndb5c6572007-04-20 02:15:28 +00001146 if (dirname_available) {
1147 *dirname_available = False;
1148 *dirname = 0;
1149 }
sewardjeadcd862006-04-04 15:12:44 +00001150 return False;
njnc1b1d422007-04-19 23:35:42 +00001151 }
1152
sewardjeadcd862006-04-04 15:12:44 +00001153 VG_(strncpy_safely)(filename, si->loctab[locno].filename, n_filename);
1154 *lineno = si->loctab[locno].lineno;
1155
1156 if (dirname) {
1157 /* caller wants directory info too .. */
1158 vg_assert(n_dirname > 0);
1159 if (si->loctab[locno].dirname) {
1160 /* .. and we have some */
1161 *dirname_available = True;
1162 VG_(strncpy_safely)(dirname, si->loctab[locno].dirname,
1163 n_dirname);
1164 } else {
1165 /* .. but we don't have any */
1166 *dirname_available = False;
1167 *dirname = 0;
1168 }
1169 }
1170
1171 return True;
1172}
1173
1174
sewardj4ee4f982006-10-17 01:37:10 +00001175/* Map a function name to its entry point and toc pointer. Is done by
1176 sequential search of all symbol tables, so is very slow. To
1177 mitigate the worst performance effects, you may specify a soname
1178 pattern, and only objects matching that pattern are searched.
1179 Therefore specify "*" to search all the objects. On TOC-afflicted
1180 platforms, a symbol is deemed to be found only if it has a nonzero
1181 TOC pointer. */
sewardjb8b79ad2008-03-03 01:35:41 +00001182Bool VG_(lookup_symbol_SLOW)(UChar* sopatt, UChar* name,
1183 Addr* pEnt, Addr* pToc)
sewardj4ee4f982006-10-17 01:37:10 +00001184{
1185 Bool require_pToc = False;
1186 Int i;
sewardjb8b79ad2008-03-03 01:35:41 +00001187 DebugInfo* si;
sewardj4ee4f982006-10-17 01:37:10 +00001188 Bool debug = False;
1189# if defined(VG_PLAT_USES_PPCTOC)
1190 require_pToc = True;
1191# endif
sewardjb8b79ad2008-03-03 01:35:41 +00001192 for (si = debugInfo_list; si; si = si->next) {
sewardj4ee4f982006-10-17 01:37:10 +00001193 if (debug)
1194 VG_(printf)("lookup_symbol_SLOW: considering %s\n", si->soname);
1195 if (!VG_(string_match)(sopatt, si->soname)) {
1196 if (debug)
1197 VG_(printf)(" ... skip\n");
1198 continue;
1199 }
1200 for (i = 0; i < si->symtab_used; i++) {
1201 if (0==VG_(strcmp)(name, si->symtab[i].name)
1202 && (require_pToc ? si->symtab[i].tocptr : True)) {
1203 *pEnt = si->symtab[i].addr;
1204 *pToc = si->symtab[i].tocptr;
1205 return True;
1206 }
1207 }
1208 }
1209 return False;
1210}
1211
1212
sewardje872fec2007-01-10 15:42:15 +00001213/* VG_(describe_IP): print into buf info on code address, function
1214 name and filename. */
1215
1216/* Copy str into buf starting at n, but not going past buf[n_buf-1]
1217 and always ensuring that buf is zero-terminated. */
sewardjeadcd862006-04-04 15:12:44 +00001218
1219static Int putStr ( Int n, Int n_buf, Char* buf, Char* str )
1220{
sewardje872fec2007-01-10 15:42:15 +00001221 vg_assert(n_buf > 0);
1222 vg_assert(n >= 0 && n < n_buf);
sewardjeadcd862006-04-04 15:12:44 +00001223 for (; n < n_buf-1 && *str != 0; n++,str++)
1224 buf[n] = *str;
sewardje872fec2007-01-10 15:42:15 +00001225 vg_assert(n >= 0 && n < n_buf);
sewardjeadcd862006-04-04 15:12:44 +00001226 buf[n] = '\0';
1227 return n;
1228}
sewardje872fec2007-01-10 15:42:15 +00001229
1230/* Same as putStr, but escaping chars for XML output, and
1231 also not adding more than count chars to n_buf. */
1232
1233static Int putStrEsc ( Int n, Int n_buf, Int count, Char* buf, Char* str )
sewardjeadcd862006-04-04 15:12:44 +00001234{
1235 Char alt[2];
sewardje872fec2007-01-10 15:42:15 +00001236 vg_assert(n_buf > 0);
1237 vg_assert(count >= 0 && count < n_buf);
1238 vg_assert(n >= 0 && n < n_buf);
sewardjeadcd862006-04-04 15:12:44 +00001239 for (; *str != 0; str++) {
sewardje872fec2007-01-10 15:42:15 +00001240 vg_assert(count >= 0);
1241 if (count <= 0)
1242 goto done;
sewardjeadcd862006-04-04 15:12:44 +00001243 switch (*str) {
sewardje872fec2007-01-10 15:42:15 +00001244 case '&':
1245 if (count < 5) goto done;
1246 n = putStr( n, n_buf, buf, "&amp;");
1247 count -= 5;
1248 break;
1249 case '<':
1250 if (count < 4) goto done;
1251 n = putStr( n, n_buf, buf, "&lt;");
1252 count -= 4;
1253 break;
1254 case '>':
1255 if (count < 4) goto done;
1256 n = putStr( n, n_buf, buf, "&gt;");
1257 count -= 4;
1258 break;
1259 default:
1260 if (count < 1) goto done;
1261 alt[0] = *str;
1262 alt[1] = 0;
1263 n = putStr( n, n_buf, buf, alt );
1264 count -= 1;
1265 break;
sewardjeadcd862006-04-04 15:12:44 +00001266 }
1267 }
sewardje872fec2007-01-10 15:42:15 +00001268 done:
1269 vg_assert(count >= 0); /* should not go -ve in loop */
1270 vg_assert(n >= 0 && n < n_buf);
sewardjeadcd862006-04-04 15:12:44 +00001271 return n;
1272}
1273
1274Char* VG_(describe_IP)(Addr eip, Char* buf, Int n_buf)
1275{
1276# define APPEND(_str) \
sewardje872fec2007-01-10 15:42:15 +00001277 n = putStr(n, n_buf, buf, _str)
1278# define APPEND_ESC(_count,_str) \
1279 n = putStrEsc(n, n_buf, (_count), buf, (_str))
sewardjeadcd862006-04-04 15:12:44 +00001280# define BUF_LEN 4096
1281
1282 UInt lineno;
1283 UChar ibuf[50];
1284 Int n = 0;
1285 static UChar buf_fn[BUF_LEN];
1286 static UChar buf_obj[BUF_LEN];
1287 static UChar buf_srcloc[BUF_LEN];
1288 static UChar buf_dirname[BUF_LEN];
1289 Bool know_dirinfo = False;
sewardj4ee4f982006-10-17 01:37:10 +00001290 Bool know_fnname = VG_(clo_sym_offsets)
1291 ? VG_(get_fnname_w_offset) (eip, buf_fn, BUF_LEN)
1292 : VG_(get_fnname) (eip, buf_fn, BUF_LEN);
sewardjeadcd862006-04-04 15:12:44 +00001293 Bool know_objname = VG_(get_objname)(eip, buf_obj, BUF_LEN);
1294 Bool know_srcloc = VG_(get_filename_linenum)(
1295 eip,
1296 buf_srcloc, BUF_LEN,
1297 buf_dirname, BUF_LEN, &know_dirinfo,
1298 &lineno
1299 );
1300 if (VG_(clo_xml)) {
1301
1302 Bool human_readable = True;
1303 HChar* maybe_newline = human_readable ? "\n " : "";
1304 HChar* maybe_newline2 = human_readable ? "\n " : "";
1305
sewardje872fec2007-01-10 15:42:15 +00001306 /* Print in XML format, dumping in as much info as we know.
1307 Ensure all tags are balanced even if the individual strings
1308 are too long. Allocate 1/10 of BUF_LEN to the object name,
1309 6/10s to the function name, 1/10 to the directory name and
1310 1/10 to the file name, leaving 1/10 for all the fixed-length
1311 stuff. */
sewardjeadcd862006-04-04 15:12:44 +00001312 APPEND("<frame>");
sewardja44b15f2007-02-16 14:10:24 +00001313 VG_(sprintf)(ibuf,"<ip>0x%llX</ip>", (ULong)eip);
sewardjeadcd862006-04-04 15:12:44 +00001314 APPEND(maybe_newline);
1315 APPEND(ibuf);
1316 if (know_objname) {
1317 APPEND(maybe_newline);
1318 APPEND("<obj>");
sewardje872fec2007-01-10 15:42:15 +00001319 APPEND_ESC(1*BUF_LEN/10, buf_obj);
sewardjeadcd862006-04-04 15:12:44 +00001320 APPEND("</obj>");
1321 }
1322 if (know_fnname) {
1323 APPEND(maybe_newline);
1324 APPEND("<fn>");
sewardje872fec2007-01-10 15:42:15 +00001325 APPEND_ESC(6*BUF_LEN/10, buf_fn);
sewardjeadcd862006-04-04 15:12:44 +00001326 APPEND("</fn>");
1327 }
1328 if (know_srcloc) {
1329 if (know_dirinfo) {
1330 APPEND(maybe_newline);
1331 APPEND("<dir>");
sewardje872fec2007-01-10 15:42:15 +00001332 APPEND_ESC(1*BUF_LEN/10, buf_dirname);
sewardjeadcd862006-04-04 15:12:44 +00001333 APPEND("</dir>");
1334 }
1335 APPEND(maybe_newline);
1336 APPEND("<file>");
sewardje872fec2007-01-10 15:42:15 +00001337 APPEND_ESC(1*BUF_LEN/10, buf_srcloc);
sewardjeadcd862006-04-04 15:12:44 +00001338 APPEND("</file>");
1339 APPEND(maybe_newline);
1340 APPEND("<line>");
1341 VG_(sprintf)(ibuf,"%d",lineno);
1342 APPEND(ibuf);
1343 APPEND("</line>");
1344 }
1345 APPEND(maybe_newline2);
1346 APPEND("</frame>");
1347
1348 } else {
1349
1350 /* Print for humans to read */
sewardja44b15f2007-02-16 14:10:24 +00001351 VG_(sprintf)(ibuf,"0x%llX: ", (ULong)eip);
sewardjeadcd862006-04-04 15:12:44 +00001352 APPEND(ibuf);
1353 if (know_fnname) {
1354 APPEND(buf_fn);
1355 if (!know_srcloc && know_objname) {
1356 APPEND(" (in ");
1357 APPEND(buf_obj);
1358 APPEND(")");
1359 }
1360 } else if (know_objname && !know_srcloc) {
1361 APPEND("(within ");
1362 APPEND(buf_obj);
1363 APPEND(")");
1364 } else {
1365 APPEND("???");
1366 }
1367 if (know_srcloc) {
1368 APPEND(" (");
1369 APPEND(buf_srcloc);
1370 APPEND(":");
1371 VG_(sprintf)(ibuf,"%d",lineno);
1372 APPEND(ibuf);
1373 APPEND(")");
1374 }
1375
1376 }
1377 return buf;
1378
1379# undef APPEND
1380# undef APPEND_ESC
1381# undef BUF_LEN
1382}
1383
sewardj72427fa2007-02-27 16:52:23 +00001384
sewardjb8b79ad2008-03-03 01:35:41 +00001385/*--------------------------------------------------------------*/
1386/*--- ---*/
1387/*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/
1388/*--- DWARF3 .eh_frame INFO ---*/
1389/*--- ---*/
1390/*--------------------------------------------------------------*/
sewardj72427fa2007-02-27 16:52:23 +00001391
1392/* Gather up all the constant pieces of info needed to evaluate
1393 a CfiExpr into one convenient struct. */
1394typedef
1395 struct {
1396 Addr ipHere;
1397 Addr spHere;
1398 Addr fpHere;
1399 Addr min_accessible;
1400 Addr max_accessible;
1401 }
1402 CfiExprEvalContext;
1403
1404/* Evaluate the CfiExpr rooted at ix in exprs given the context eec.
1405 *ok is set to False on failure, but not to True on success. The
1406 caller must set it to True before calling. */
1407static
1408UWord evalCfiExpr ( XArray* exprs, Int ix,
1409 CfiExprEvalContext* eec, Bool* ok )
1410{
1411 UWord wL, wR;
sewardj19dc88f2007-02-28 01:46:30 +00001412 Addr a;
sewardj72427fa2007-02-27 16:52:23 +00001413 CfiExpr* e = VG_(indexXA)( exprs, ix );
1414 switch (e->tag) {
1415 case Cex_Binop:
1416 wL = evalCfiExpr( exprs, e->Cex.Binop.ixL, eec, ok );
1417 if (!(*ok)) return 0;
1418 wR = evalCfiExpr( exprs, e->Cex.Binop.ixR, eec, ok );
1419 if (!(*ok)) return 0;
1420 switch (e->Cex.Binop.op) {
1421 case Cop_Add: return wL + wR;
1422 case Cop_Sub: return wL - wR;
sewardj19dc88f2007-02-28 01:46:30 +00001423 case Cop_And: return wL & wR;
sewardj7888e222007-02-28 13:03:27 +00001424 case Cop_Mul: return wL * wR;
sewardj72427fa2007-02-27 16:52:23 +00001425 default: goto unhandled;
1426 }
1427 /*NOTREACHED*/
1428 case Cex_CfiReg:
1429 switch (e->Cex.CfiReg.reg) {
1430 case Creg_IP: return (Addr)eec->ipHere;
1431 case Creg_SP: return (Addr)eec->spHere;
1432 case Creg_FP: return (Addr)eec->fpHere;
1433 default: goto unhandled;
1434 }
1435 /*NOTREACHED*/
1436 case Cex_Const:
1437 return e->Cex.Const.con;
sewardj19dc88f2007-02-28 01:46:30 +00001438 case Cex_Deref:
1439 a = evalCfiExpr( exprs, e->Cex.Deref.ixAddr, eec, ok );
1440 if (!(*ok)) return 0;
1441 if (a < eec->min_accessible
1442 || (a + sizeof(UWord) - 1) > eec->max_accessible) {
1443 *ok = False;
1444 return 0;
1445 }
1446 /* let's hope it doesn't trap! */
1447 return * ((UWord*)a);
sewardj72427fa2007-02-27 16:52:23 +00001448 default:
1449 goto unhandled;
1450 }
1451 /*NOTREACHED*/
1452 unhandled:
1453 VG_(printf)("\n\nevalCfiExpr: unhandled\n");
1454 ML_(ppCfiExpr)( exprs, ix );
1455 VG_(printf)("\n");
1456 vg_assert(0);
1457 /*NOTREACHED*/
1458 return 0;
1459}
1460
1461
1462/* The main function for DWARF2/3 CFI-based stack unwinding.
1463 Given an IP/SP/FP triple, produce the IP/SP/FP values for the
1464 previous frame, if possible. */
sewardjeadcd862006-04-04 15:12:44 +00001465/* Returns True if OK. If not OK, *{ip,sp,fp}P are not changed. */
1466/* NOTE: this function may rearrange the order of entries in the
sewardjb8b79ad2008-03-03 01:35:41 +00001467 DebugInfo list. */
sewardjeadcd862006-04-04 15:12:44 +00001468Bool VG_(use_CF_info) ( /*MOD*/Addr* ipP,
1469 /*MOD*/Addr* spP,
1470 /*MOD*/Addr* fpP,
1471 Addr min_accessible,
1472 Addr max_accessible )
1473{
sewardj72427fa2007-02-27 16:52:23 +00001474 Bool ok;
sewardjeadcd862006-04-04 15:12:44 +00001475 Int i;
sewardjb8b79ad2008-03-03 01:35:41 +00001476 DebugInfo* si;
sewardjeadcd862006-04-04 15:12:44 +00001477 DiCfSI* cfsi = NULL;
1478 Addr cfa, ipHere, spHere, fpHere, ipPrev, spPrev, fpPrev;
1479
sewardj72427fa2007-02-27 16:52:23 +00001480 CfiExprEvalContext eec;
1481
sewardjeadcd862006-04-04 15:12:44 +00001482 static UInt n_search = 0;
1483 static UInt n_steps = 0;
1484 n_search++;
1485
1486 if (0) VG_(printf)("search for %p\n", *ipP);
1487
sewardjb8b79ad2008-03-03 01:35:41 +00001488 for (si = debugInfo_list; si != NULL; si = si->next) {
sewardjeadcd862006-04-04 15:12:44 +00001489 n_steps++;
1490
sewardjb8b79ad2008-03-03 01:35:41 +00001491 /* Use the per-DebugInfo summary address ranges to skip
1492 inapplicable DebugInfos quickly. */
sewardjeadcd862006-04-04 15:12:44 +00001493 if (si->cfsi_used == 0)
1494 continue;
sewardjb8b79ad2008-03-03 01:35:41 +00001495 if (*ipP < si->cfsi_minavma || *ipP > si->cfsi_maxavma)
sewardjeadcd862006-04-04 15:12:44 +00001496 continue;
1497
1498 i = ML_(search_one_cfitab)( si, *ipP );
1499 if (i != -1) {
1500 vg_assert(i >= 0 && i < si->cfsi_used);
1501 cfsi = &si->cfsi[i];
1502 break;
1503 }
1504 }
1505
1506 if (cfsi == NULL)
1507 return False;
1508
sewardjb8b79ad2008-03-03 01:35:41 +00001509 if (0 && ((n_search & 0x7FFFF) == 0))
1510 VG_(printf)("VG_(use_CF_info): %u searches, "
1511 "%u DebugInfos looked at\n",
1512 n_search, n_steps);
sewardjeadcd862006-04-04 15:12:44 +00001513
sewardjb8b79ad2008-03-03 01:35:41 +00001514 /* Start of performance-enhancing hack: once every 64 (chosen
sewardj72427fa2007-02-27 16:52:23 +00001515 hackily after profiling) successful searches, move the found
sewardjb8b79ad2008-03-03 01:35:41 +00001516 DebugInfo one step closer to the start of the list. This makes
sewardjeadcd862006-04-04 15:12:44 +00001517 future searches cheaper. For starting konqueror on amd64, this
1518 in fact reduces the total amount of searching done by the above
sewardjb8b79ad2008-03-03 01:35:41 +00001519 find-the-right-DebugInfo loop by more than a factor of 20. */
1520 if ((n_search & 0x3F) == 0) {
sewardjeadcd862006-04-04 15:12:44 +00001521 /* Move si one step closer to the start of the list. */
sewardjb8b79ad2008-03-03 01:35:41 +00001522 move_DebugInfo_one_step_forward( si );
sewardjeadcd862006-04-04 15:12:44 +00001523 }
1524 /* End of performance-enhancing hack. */
1525
1526 if (0) {
1527 VG_(printf)("found cfisi: ");
sewardj72427fa2007-02-27 16:52:23 +00001528 ML_(ppDiCfSI)(si->cfsi_exprs, cfsi);
sewardjeadcd862006-04-04 15:12:44 +00001529 }
1530
1531 ipPrev = spPrev = fpPrev = 0;
1532
1533 ipHere = *ipP;
1534 spHere = *spP;
1535 fpHere = *fpP;
1536
sewardj72427fa2007-02-27 16:52:23 +00001537 /* First compute the CFA. */
1538 cfa = 0;
1539 switch (cfsi->cfa_how) {
1540 case CFIC_SPREL:
1541 cfa = cfsi->cfa_off + spHere;
1542 break;
1543 case CFIC_FPREL:
1544 cfa = cfsi->cfa_off + fpHere;
1545 break;
1546 case CFIC_EXPR:
sewardj7888e222007-02-28 13:03:27 +00001547 if (0) {
1548 VG_(printf)("CFIC_EXPR: ");
1549 ML_(ppCfiExpr)(si->cfsi_exprs, cfsi->cfa_off);
1550 VG_(printf)("\n");
1551 }
1552 eec.ipHere = ipHere;
1553 eec.spHere = spHere;
1554 eec.fpHere = fpHere;
1555 eec.min_accessible = min_accessible;
1556 eec.max_accessible = max_accessible;
1557 ok = True;
1558 cfa = evalCfiExpr(si->cfsi_exprs, cfsi->cfa_off, &eec, &ok );
1559 if (!ok) return False;
sewardj72427fa2007-02-27 16:52:23 +00001560 break;
1561 default:
1562 vg_assert(0);
1563 }
1564
1565 /* Now we know the CFA, use it to roll back the registers we're
1566 interested in. */
sewardjeadcd862006-04-04 15:12:44 +00001567
1568# define COMPUTE(_prev, _here, _how, _off) \
1569 do { \
1570 switch (_how) { \
1571 case CFIR_UNKNOWN: \
1572 return False; \
1573 case CFIR_SAME: \
1574 _prev = _here; break; \
1575 case CFIR_MEMCFAREL: { \
1576 Addr a = cfa + (Word)_off; \
1577 if (a < min_accessible \
1578 || a+sizeof(Addr) > max_accessible) \
1579 return False; \
1580 _prev = *(Addr*)a; \
1581 break; \
1582 } \
1583 case CFIR_CFAREL: \
1584 _prev = cfa + (Word)_off; \
1585 break; \
sewardj72427fa2007-02-27 16:52:23 +00001586 case CFIR_EXPR: \
1587 if (0) \
1588 ML_(ppCfiExpr)(si->cfsi_exprs,_off); \
1589 eec.ipHere = ipHere; \
1590 eec.spHere = spHere; \
1591 eec.fpHere = fpHere; \
1592 eec.min_accessible = min_accessible; \
1593 eec.max_accessible = max_accessible; \
1594 ok = True; \
1595 _prev = evalCfiExpr(si->cfsi_exprs, _off, &eec, &ok ); \
1596 if (!ok) return False; \
1597 break; \
1598 default: \
1599 vg_assert(0); \
sewardjeadcd862006-04-04 15:12:44 +00001600 } \
1601 } while (0)
1602
1603 COMPUTE(ipPrev, ipHere, cfsi->ra_how, cfsi->ra_off);
1604 COMPUTE(spPrev, spHere, cfsi->sp_how, cfsi->sp_off);
1605 COMPUTE(fpPrev, fpHere, cfsi->fp_how, cfsi->fp_off);
1606
1607# undef COMPUTE
1608
1609 *ipP = ipPrev;
1610 *spP = spPrev;
1611 *fpP = fpPrev;
1612 return True;
1613}
1614
1615
sewardjb8b79ad2008-03-03 01:35:41 +00001616/*--------------------------------------------------------------*/
1617/*--- ---*/
1618/*--- TOP LEVEL: GENERATE DESCRIPTION OF DATA ADDRESSES ---*/
1619/*--- FROM DWARF3 DEBUG INFO ---*/
1620/*--- ---*/
1621/*--------------------------------------------------------------*/
sewardjeadcd862006-04-04 15:12:44 +00001622
sewardjb8b79ad2008-03-03 01:35:41 +00001623/* Evaluate the location expression/list for var, to see whether or
1624 not data_addr falls within the variable. If so also return the
1625 offset of data_addr from the start of the variable. Note that
1626 regs, which supplies ip,sp,fp values, will be NULL for global
1627 variables, and non-NULL for local variables. */
1628static Bool data_address_is_in_var ( /*OUT*/UWord* offset,
1629 DiVariable* var,
1630 RegSummary* regs,
1631 Addr data_addr,
1632 Addr data_bias )
sewardjeadcd862006-04-04 15:12:44 +00001633{
sewardjb8b79ad2008-03-03 01:35:41 +00001634 MaybeUWord muw;
1635 SizeT var_szB;
1636 GXResult res;
1637 Bool show = False;
1638 vg_assert(var->name);
1639 vg_assert(var->type);
1640 vg_assert(var->gexpr);
1641
1642 /* Figure out how big the variable is. */
1643 muw = ML_(sizeOfType)(var->type);
1644 /* if this var has a type whose size is unknown, it should never
1645 have been added. ML_(addVar) should have rejected it. */
1646 vg_assert(muw.b == True);
1647
1648 var_szB = muw.w;
1649
1650 if (show) {
1651 VG_(printf)("VVVV: data_address_%p_is_in_var: %s :: ",
1652 data_addr, var->name );
1653 ML_(pp_Type_C_ishly)( var->type );
1654 VG_(printf)("\n");
1655 }
1656
1657 /* ignore zero-sized vars; they can never match anything. */
1658 if (var_szB == 0) {
1659 if (show)
1660 VG_(printf)("VVVV: -> Fail (variable is zero sized)\n");
1661 return False;
1662 }
1663
1664 res = ML_(evaluate_GX)( var->gexpr, var->fbGX, regs, data_bias );
1665
1666 if (show) {
1667 VG_(printf)("VVVV: -> ");
1668 ML_(pp_GXResult)( res );
1669 VG_(printf)("\n");
1670 }
1671
1672 if (res.kind == GXR_Value
1673 && res.word <= data_addr
1674 && data_addr < res.word + var_szB) {
1675 *offset = data_addr - res.word;
1676 return True;
1677 } else {
1678 return False;
1679 }
sewardjeadcd862006-04-04 15:12:44 +00001680}
1681
sewardjb8b79ad2008-03-03 01:35:41 +00001682
1683/* Format the acquired information into dname1[0 .. n_dname-1] and
1684 dname2[0 .. n_dname-1] in an understandable way. Not so easy.
1685 If frameNo is -1, this is assumed to be a global variable; else
1686 a local variable. */
1687static void format_message ( /*OUT*/Char* dname1,
1688 /*OUT*/Char* dname2,
1689 Int n_dname,
1690 Addr data_addr,
1691 DiVariable* var,
1692 OffT var_offset,
1693 OffT residual_offset,
1694 XArray* /*UChar*/ described,
1695 Int frameNo,
1696 ThreadId tid )
sewardjeadcd862006-04-04 15:12:44 +00001697{
sewardjb8b79ad2008-03-03 01:35:41 +00001698 Bool have_descr, have_srcloc;
1699 UChar* vo_plural = var_offset == 1 ? "" : "s";
1700 UChar* ro_plural = residual_offset == 1 ? "" : "s";
1701
1702 vg_assert(frameNo >= -1);
1703 vg_assert(dname1 && dname2 && n_dname > 1);
1704 vg_assert(described);
1705 vg_assert(var && var->name);
1706 have_descr = VG_(sizeXA)(described) > 0
1707 && *(UChar*)VG_(indexXA)(described,0) != '\0';
1708 have_srcloc = var->fileName && var->lineNo > 0;
1709
1710 dname1[0] = dname2[0] = '\0';
1711
1712 /* ------ local cases ------ */
1713
1714 if ( frameNo >= 0 && (!have_srcloc) && (!have_descr) ) {
1715 /* no srcloc, no description:
1716 Location 0x7fefff6cf is 543 bytes inside local var "a",
1717 in frame #1 of thread 1
1718 */
1719 VG_(snprintf)(
1720 dname1, n_dname,
1721 "Location 0x%lx is %lu byte%s inside local var \"%s\",",
1722 data_addr, var_offset, vo_plural, var->name );
1723 VG_(snprintf)(
1724 dname2, n_dname,
1725 "in frame #%d of thread %d", frameNo, (Int)tid);
1726 }
1727 else
1728 if ( frameNo >= 0 && have_srcloc && (!have_descr) ) {
1729 /* no description:
1730 Location 0x7fefff6cf is 543 bytes inside local var "a"
1731 declared at dsyms7.c:17, in frame #1 of thread 1
1732 */
1733 VG_(snprintf)(
1734 dname1, n_dname,
1735 "Location 0x%lx is %lu byte%s inside local var \"%s\"",
1736 data_addr, var_offset, vo_plural, var->name );
1737 VG_(snprintf)(
1738 dname2, n_dname,
1739 "declared at %s:%d, in frame #%d of thread %d",
1740 var->fileName, var->lineNo, frameNo, (Int)tid);
1741 }
1742 else
1743 if ( frameNo >= 0 && (!have_srcloc) && have_descr ) {
1744 /* no srcloc:
1745 Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2
1746 in frame #1 of thread 1
1747 */
1748 VG_(snprintf)(
1749 dname1, n_dname,
1750 "Location 0x%lx is %lu byte%s inside %s%s",
1751 data_addr, residual_offset, ro_plural, var->name,
1752 VG_(indexXA)(described,0) );
1753 VG_(snprintf)(
1754 dname2, n_dname,
1755 "in frame #%d of thread %d", frameNo, (Int)tid);
1756 }
1757 else
1758 if ( frameNo >= 0 && have_srcloc && have_descr ) {
1759 /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
1760 declared at dsyms7.c:17, in frame #1 of thread 1 */
1761 VG_(snprintf)(
1762 dname1, n_dname,
1763 "Location 0x%lx is %lu byte%s inside %s%s,",
1764 data_addr, residual_offset, ro_plural, var->name,
1765 VG_(indexXA)(described,0) );
1766 VG_(snprintf)(
1767 dname2, n_dname,
1768 "declared at %s:%d, in frame #%d of thread %d",
1769 var->fileName, var->lineNo, frameNo, (Int)tid);
1770 }
1771 else
1772 /* ------ global cases ------ */
1773 if ( frameNo >= -1 && (!have_srcloc) && (!have_descr) ) {
1774 /* no srcloc, no description:
1775 Location 0x7fefff6cf is 543 bytes inside global var "a"
1776 */
1777 VG_(snprintf)(
1778 dname1, n_dname,
1779 "Location 0x%lx is %lu byte%s inside global var \"%s\"",
1780 data_addr, var_offset, vo_plural, var->name );
1781 }
1782 else
1783 if ( frameNo >= -1 && have_srcloc && (!have_descr) ) {
1784 /* no description:
1785 Location 0x7fefff6cf is 543 bytes inside global var "a"
1786 declared at dsyms7.c:17
1787 */
1788 VG_(snprintf)(
1789 dname1, n_dname,
1790 "Location 0x%lx is %lu byte%s inside global var \"%s\"",
1791 data_addr, var_offset, vo_plural, var->name );
1792 VG_(snprintf)(
1793 dname2, n_dname,
1794 "declared at %s:%d",
1795 var->fileName, var->lineNo);
1796 }
1797 else
1798 if ( frameNo >= -1 && (!have_srcloc) && have_descr ) {
1799 /* no srcloc:
1800 Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
1801 a global variable
1802 */
1803 VG_(snprintf)(
1804 dname1, n_dname,
1805 "Location 0x%lx is %lu byte%s inside %s%s,",
1806 data_addr, residual_offset, ro_plural, var->name,
1807 VG_(indexXA)(described,0) );
1808 VG_(snprintf)(
1809 dname2, n_dname,
1810 "a global variable");
1811 }
1812 else
1813 if ( frameNo >= -1 && have_srcloc && have_descr ) {
1814 /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
1815 a global variable declared at dsyms7.c:17 */
1816 VG_(snprintf)(
1817 dname1, n_dname,
1818 "Location 0x%lx is %lu byte%s inside %s%s,",
1819 data_addr, residual_offset, ro_plural, var->name,
1820 VG_(indexXA)(described,0) );
1821 VG_(snprintf)(
1822 dname2, n_dname,
1823 "a global variable declared at %s:%d",
1824 var->fileName, var->lineNo);
1825 }
1826 else
1827 vg_assert(0);
1828
1829 dname1[n_dname-1] = dname2[n_dname-1] = 0;
sewardjeadcd862006-04-04 15:12:44 +00001830}
1831
sewardjb8b79ad2008-03-03 01:35:41 +00001832
1833/* Determine if data_addr is a local variable in the frame
1834 characterised by (ip,sp,fp), and if so write its description into
1835 dname{1,2}[0..n_dname-1], and return True. If not, return
1836 False. */
1837static
1838Bool consider_vars_in_frame ( /*OUT*/Char* dname1,
1839 /*OUT*/Char* dname2,
1840 Int n_dname,
1841 Addr data_addr,
1842 Addr ip, Addr sp, Addr fp,
1843 /* shown to user: */
1844 ThreadId tid, Int frameNo )
sewardjeadcd862006-04-04 15:12:44 +00001845{
sewardjb8b79ad2008-03-03 01:35:41 +00001846 Word i;
1847 DebugInfo* di;
1848 RegSummary regs;
1849 Bool debug = False;
sewardjeadcd862006-04-04 15:12:44 +00001850
sewardjb8b79ad2008-03-03 01:35:41 +00001851 static UInt n_search = 0;
1852 static UInt n_steps = 0;
1853 n_search++;
1854 if (debug)
1855 VG_(printf)("QQQQ: cvif: ip,sp,fp %p,%p,%p\n", ip,sp,fp);
1856 /* first, find the DebugInfo that pertains to 'ip'. */
1857 for (di = debugInfo_list; di; di = di->next) {
1858 n_steps++;
1859 /* text segment missing? unlikely, but handle it .. */
1860 if (!di->text_present || di->text_size == 0)
1861 continue;
1862 /* Ok. So does this text mapping bracket the ip? */
1863 if (di->text_avma <= ip && ip < di->text_avma + di->text_size)
1864 break;
1865 }
1866
1867 /* Didn't find it. Strange -- means ip is a code address outside
1868 of any mapped text segment. Unlikely but not impossible -- app
1869 could be generating code to run. */
1870 if (!di)
1871 return False;
sewardjeadcd862006-04-04 15:12:44 +00001872
sewardjb8b79ad2008-03-03 01:35:41 +00001873 if (0 && ((n_search & 0x1) == 0))
1874 VG_(printf)("consider_vars_in_frame: %u searches, "
1875 "%u DebugInfos looked at\n",
1876 n_search, n_steps);
1877 /* Start of performance-enhancing hack: once every ??? (chosen
1878 hackily after profiling) successful searches, move the found
1879 DebugInfo one step closer to the start of the list. This makes
1880 future searches cheaper. */
1881 if ((n_search & 0xFFFF) == 0) {
1882 /* Move si one step closer to the start of the list. */
1883 move_DebugInfo_one_step_forward( di );
1884 }
1885 /* End of performance-enhancing hack. */
sewardjeadcd862006-04-04 15:12:44 +00001886
sewardjb8b79ad2008-03-03 01:35:41 +00001887 /* any var info at all? */
1888 if (!di->varinfo)
1889 return False;
sewardjeadcd862006-04-04 15:12:44 +00001890
sewardjb8b79ad2008-03-03 01:35:41 +00001891 /* Work through the scopes from most deeply nested outwards,
1892 looking for code address ranges that bracket 'ip'. The
1893 variables on each such address range found are in scope right
1894 now. Don't descend to level zero as that is the global
1895 scope. */
1896 regs.ip = ip;
1897 regs.sp = sp;
1898 regs.fp = fp;
sewardjeadcd862006-04-04 15:12:44 +00001899
sewardjb8b79ad2008-03-03 01:35:41 +00001900 /* "for each scope, working outwards ..." */
1901 for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) {
1902 XArray* vars;
1903 Word j;
1904 DiAddrRange* arange;
1905 OSet* this_scope
1906 = *(OSet**)VG_(indexXA)( di->varinfo, i );
1907 if (debug)
1908 VG_(printf)("QQQQ: considering scope %ld\n", (Word)i);
1909 if (!this_scope)
1910 continue;
1911 /* Find the set of variables in this scope that
1912 bracket the program counter. */
1913 arange = VG_(OSetGen_LookupWithCmp)(
1914 this_scope, &ip,
1915 ML_(cmp_for_DiAddrRange_range)
1916 );
1917 if (!arange)
1918 continue;
1919 /* stay sane */
1920 vg_assert(arange->aMin <= arange->aMax);
1921 /* It must bracket the ip we asked for, else
1922 ML_(cmp_for_DiAddrRange_range) is somehow broken. */
1923 vg_assert(arange->aMin <= ip && ip <= arange->aMax);
1924 /* It must have an attached XArray of DiVariables. */
1925 vars = arange->vars;
1926 vg_assert(vars);
1927 /* But it mustn't cover the entire address range. We only
1928 expect that to happen for the global scope (level 0), which
1929 we're not looking at here. Except, it may cover the entire
1930 address range, but in that case the vars array must be
1931 empty. */
1932 vg_assert(! (arange->aMin == (Addr)0
1933 && arange->aMax == ~(Addr)0
1934 && VG_(sizeXA)(vars) > 0) );
1935 for (j = 0; j < VG_(sizeXA)( vars ); j++) {
1936 DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j );
1937 SizeT offset;
1938 if (debug)
1939 VG_(printf)("QQQQ: var:name=%s %p-%p %p\n",
1940 var->name,arange->aMin,arange->aMax,ip);
1941 if (data_address_is_in_var( &offset, var, &regs, data_addr,
1942 di->data_bias )) {
1943 OffT residual_offset = 0;
1944 XArray* described = ML_(describe_type)( &residual_offset,
1945 var->type, offset );
1946 format_message( dname1, dname2, n_dname,
1947 data_addr, var, offset, residual_offset,
1948 described, frameNo, tid );
1949 VG_(deleteXA)( described );
1950 return True;
1951 }
sewardjab3698a2007-12-02 22:03:43 +00001952 }
sewardjeadcd862006-04-04 15:12:44 +00001953 }
1954
sewardjb8b79ad2008-03-03 01:35:41 +00001955 return False;
sewardjeadcd862006-04-04 15:12:44 +00001956}
1957
sewardjb8b79ad2008-03-03 01:35:41 +00001958/* Try to form some description of data_addr by looking at the DWARF3
1959 debug info we have. This considers all global variables, and all
1960 frames in the stacks of all threads. Result (or as much as will
1961 fit) is put into into dname{1,2}[0 .. n_dname-1] and is guaranteed
1962 to be zero terminated. */
1963Bool VG_(get_data_description)( /*OUT*/Char* dname1,
1964 /*OUT*/Char* dname2,
1965 Int n_dname,
1966 Addr data_addr )
sewardjbbec7722007-11-25 14:08:53 +00001967{
sewardjb8b79ad2008-03-03 01:35:41 +00001968# define N_FRAMES 8
1969 Addr ips[N_FRAMES], sps[N_FRAMES], fps[N_FRAMES];
1970 UInt n_frames;
1971
1972 Addr stack_min, stack_max;
1973 ThreadId tid;
1974 Bool found;
1975 DebugInfo* di;
1976 Word j;
1977
1978 vg_assert(n_dname > 1);
1979 dname1[n_dname-1] = dname2[n_dname-1] = 0;
1980
1981 if (0) VG_(printf)("get_data_description: dataaddr %p\n", data_addr);
1982 /* First, see if data_addr is (or is part of) a global variable.
1983 Loop over the DebugInfos we have. Check data_addr against the
1984 outermost scope of all of them, as that should be a global
1985 scope. */
1986 for (di = debugInfo_list; di != NULL; di = di->next) {
1987 OSet* global_scope;
1988 Int gs_size;
1989 Addr zero;
1990 DiAddrRange* global_arange;
1991 Word i;
1992 XArray* vars;
1993
1994 /* text segment missing? unlikely, but handle it .. */
1995 if (!di->text_present || di->text_size == 0)
1996 continue;
1997 /* any var info at all? */
1998 if (!di->varinfo)
1999 continue;
2000 /* perhaps this object didn't contribute any vars at all? */
2001 if (VG_(sizeXA)( di->varinfo ) == 0)
2002 continue;
2003 global_scope = *(OSet**)VG_(indexXA)( di->varinfo, 0 );
2004 vg_assert(global_scope);
2005 gs_size = VG_(OSetGen_Size)( global_scope );
2006 /* The global scope might be completely empty if this
2007 compilation unit declared locals but nothing global. */
2008 if (gs_size == 0)
2009 continue;
2010 /* But if it isn't empty, then it must contain exactly one
2011 element, which covers the entire address range. */
2012 vg_assert(gs_size == 1);
2013 /* Fish out the global scope and check it is as expected. */
2014 zero = 0;
2015 global_arange
2016 = VG_(OSetGen_Lookup)( global_scope, &zero );
2017 /* The global range from (Addr)0 to ~(Addr)0 must exist */
2018 vg_assert(global_arange);
2019 vg_assert(global_arange->aMin == (Addr)0
2020 && global_arange->aMax == ~(Addr)0);
2021 /* Any vars in this range? */
2022 if (!global_arange->vars)
2023 continue;
2024 /* Ok, there are some vars in the global scope of this
2025 DebugInfo. Wade through them and see if the data addresses
2026 of any of them bracket data_addr. */
2027 vars = global_arange->vars;
2028 for (i = 0; i < VG_(sizeXA)( vars ); i++) {
2029 SizeT offset;
2030 DiVariable* var = (DiVariable*)VG_(indexXA)( vars, i );
2031 vg_assert(var->name);
2032 /* Note we use a NULL RegSummary* here. It can't make any
2033 sense for a global variable to have a location expression
2034 which depends on a SP/FP/IP value. So don't supply any.
2035 This means, if the evaluation of the location
2036 expression/list requires a register, we have to let it
2037 fail. */
2038 if (data_address_is_in_var( &offset, var,
2039 NULL/* RegSummary* */,
2040 data_addr, di->data_bias )) {
2041 OffT residual_offset = 0;
2042 XArray* described = ML_(describe_type)( &residual_offset,
2043 var->type, offset );
2044 format_message( dname1, dname2, n_dname,
2045 data_addr, var, offset, residual_offset,
2046 described, -1/*frameNo*/, tid );
2047 VG_(deleteXA)( described );
2048 dname1[n_dname-1] = dname2[n_dname-1] = 0;
2049 return True;
2050 }
2051 }
sewardjbbec7722007-11-25 14:08:53 +00002052 }
sewardjb8b79ad2008-03-03 01:35:41 +00002053
2054 /* Ok, well it's not a global variable. So now let's snoop around
2055 in the stacks of all the threads. First try to figure out which
2056 thread's stack data_addr is in. */
2057
2058 /* --- KLUDGE --- Try examining the top frame of all thread stacks.
2059 This finds variables which are not stack allocated but are not
2060 globally visible either; specifically it appears to pick up
2061 variables which are visible only within a compilation unit.
2062 These will have the address range of the compilation unit and
2063 tend to live at Scope level 1. */
2064 VG_(thread_stack_reset_iter)(&tid);
2065 while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) {
2066 if (stack_min >= stack_max)
2067 continue; /* ignore obviously stupid cases */
2068 if (consider_vars_in_frame( dname1, dname2, n_dname,
2069 data_addr,
2070 VG_(get_IP)(tid),
2071 VG_(get_SP)(tid),
2072 VG_(get_FP)(tid), tid, 0 )) {
2073 dname1[n_dname-1] = dname2[n_dname-1] = 0;
2074 return True;
2075 }
2076 }
2077 /* --- end KLUDGE --- */
2078
2079 /* Perhaps it's on a thread's stack? */
2080 found = False;
2081 VG_(thread_stack_reset_iter)(&tid);
2082 while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) {
2083 if (stack_min >= stack_max)
2084 continue; /* ignore obviously stupid cases */
2085 if (stack_min - VG_STACK_REDZONE_SZB <= data_addr
2086 && data_addr <= stack_max) {
2087 found = True;
2088 break;
2089 }
2090 }
2091 if (!found) {
2092 dname1[n_dname-1] = dname2[n_dname-1] = 0;
2093 return False;
2094 }
2095
2096 /* We conclude data_addr is in thread tid's stack. Unwind the
2097 stack to get a bunch of (ip,sp,fp) triples describing the
2098 frames, and for each frame, consider the local variables. */
2099 n_frames = VG_(get_StackTrace)( tid, ips, N_FRAMES,
2100 sps, fps, 0/*first_ip_delta*/ );
2101 /* Re ip_delta in the next loop: There's a subtlety in the meaning
2102 of the IP values in a stack obtained from VG_(get_StackTrace).
2103 The innermost value really is simply the thread's program
2104 counter at the time the snapshot was taken. However, all the
2105 other values are actually return addresses, and so point just
2106 after the call instructions. Hence they notionally reflect not
2107 what the program counters were at the time those calls were
2108 made, but what they will be when those calls return. This can
2109 be of significance should an address range happen to end at the
2110 end of a call instruction -- we may ignore the range when in
2111 fact it should be considered. Hence, back up the IPs by 1 for
2112 all non-innermost IPs. Note that VG_(get_StackTrace_wrk) itself
2113 has to use the same trick in order to use CFI data to unwind the
2114 stack (as documented therein in comments). */
2115 /* As a result of KLUDGE above, starting the loop at j = 0
2116 duplicates examination of the top frame and so isn't necessary.
2117 Oh well. */
2118 vg_assert(n_frames >= 0 && n_frames <= N_FRAMES);
2119 for (j = 0; j < n_frames; j++) {
2120 Word ip_delta = j == 0 ? 0 : 1;
2121 if (consider_vars_in_frame( dname1, dname2, n_dname,
2122 data_addr,
2123 ips[j] - ip_delta,
2124 sps[j], fps[j], tid, j )) {
2125 dname1[n_dname-1] = dname2[n_dname-1] = 0;
2126 return True;
2127 }
2128 /* Now, it appears that gcc sometimes appears to produce
2129 location lists whose ranges don't actually cover the call
2130 instruction, even though the address of the variable in
2131 question is passed as a parameter in the call. AFAICS this
2132 is simply a bug in gcc - how can the variable be claimed not
2133 exist in memory (on the stack) for the duration of a call in
2134 which its address is passed? But anyway, in the particular
2135 case I investigated (memcheck/tests/varinfo6.c, call to croak
2136 on line 2999, local var budget declared at line 3115
2137 appearing not to exist across the call to mainSort on line
2138 3143, "gcc.orig (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2)" on
2139 amd64), the variable's location list does claim it exists
2140 starting at the first byte of the first instruction after the
2141 call instruction. So, call consider_vars_in_frame a second
2142 time, but this time don't subtract 1 from the IP. GDB
2143 handles this example with no difficulty, which leads me to
2144 believe that either (1) I misunderstood something, or (2) GDB
2145 has an equivalent kludge. */
2146 if (consider_vars_in_frame( dname1, dname2, n_dname,
2147 data_addr,
2148 ips[j],
2149 sps[j], fps[j], tid, j )) {
2150 dname1[n_dname-1] = dname2[n_dname-1] = 0;
2151 return True;
2152 }
2153 }
2154
2155 /* We didn't find anything useful. */
2156 dname1[n_dname-1] = dname2[n_dname-1] = 0;
2157 return False;
2158# undef N_FRAMES
sewardjbbec7722007-11-25 14:08:53 +00002159}
2160
sewardjb8b79ad2008-03-03 01:35:41 +00002161
2162/*------------------------------------------------------------*/
2163/*--- DebugInfo accessor functions ---*/
2164/*------------------------------------------------------------*/
2165
2166const DebugInfo* VG_(next_seginfo)(const DebugInfo* di)
2167{
2168 if (di == NULL)
2169 return debugInfo_list;
2170 return di->next;
2171}
2172
2173Addr VG_(seginfo_get_text_avma)(const DebugInfo* di)
2174{
2175 return di->text_present ? di->text_avma : 0;
2176}
2177
2178SizeT VG_(seginfo_get_text_size)(const DebugInfo* di)
2179{
2180 return di->text_present ? di->text_size : 0;
2181}
2182
2183const UChar* VG_(seginfo_soname)(const DebugInfo* di)
2184{
2185 return di->soname;
2186}
2187
2188const UChar* VG_(seginfo_filename)(const DebugInfo* di)
2189{
2190 return di->filename;
2191}
2192
2193ULong VG_(seginfo_get_text_bias)(const DebugInfo* di)
2194{
2195 return di->text_present ? di->text_bias : 0;
2196}
2197
2198Int VG_(seginfo_syms_howmany) ( const DebugInfo *si )
sewardjeadcd862006-04-04 15:12:44 +00002199{
2200 return si->symtab_used;
2201}
2202
sewardjb8b79ad2008-03-03 01:35:41 +00002203void VG_(seginfo_syms_getidx) ( const DebugInfo *si,
sewardjeadcd862006-04-04 15:12:44 +00002204 Int idx,
sewardjb8b79ad2008-03-03 01:35:41 +00002205 /*OUT*/Addr* avma,
sewardj4ee4f982006-10-17 01:37:10 +00002206 /*OUT*/Addr* tocptr,
sewardjeadcd862006-04-04 15:12:44 +00002207 /*OUT*/UInt* size,
sewardjb8b79ad2008-03-03 01:35:41 +00002208 /*OUT*/HChar** name,
2209 /*OUT*/Bool* isText )
sewardjeadcd862006-04-04 15:12:44 +00002210{
2211 vg_assert(idx >= 0 && idx < si->symtab_used);
sewardjb8b79ad2008-03-03 01:35:41 +00002212 if (avma) *avma = si->symtab[idx].addr;
sewardj4ee4f982006-10-17 01:37:10 +00002213 if (tocptr) *tocptr = si->symtab[idx].tocptr;
2214 if (size) *size = si->symtab[idx].size;
2215 if (name) *name = (HChar*)si->symtab[idx].name;
sewardjb8b79ad2008-03-03 01:35:41 +00002216 if (isText) *isText = si->symtab[idx].isText;
2217}
2218
2219
2220/*------------------------------------------------------------*/
2221/*--- SectKind query functions ---*/
2222/*------------------------------------------------------------*/
2223
2224/* Convert a VgSectKind to a string, which must be copied if you want
2225 to change it. */
2226const HChar* VG_(pp_SectKind)( VgSectKind kind )
2227{
2228 switch (kind) {
2229 case Vg_SectUnknown: return "Unknown";
2230 case Vg_SectText: return "Text";
2231 case Vg_SectData: return "Data";
2232 case Vg_SectBSS: return "BSS";
2233 case Vg_SectGOT: return "GOT";
2234 case Vg_SectPLT: return "PLT";
2235 case Vg_SectOPD: return "OPD";
2236 default: vg_assert(0);
2237 }
2238}
2239
2240/* Given an address 'a', make a guess of which section of which object
2241 it comes from. If name is non-NULL, then the last n_name-1
2242 characters of the object's name is put in name[0 .. n_name-2], and
2243 name[n_name-1] is set to zero (guaranteed zero terminated). */
2244
2245VgSectKind VG_(seginfo_sect_kind)( /*OUT*/UChar* name, SizeT n_name,
2246 Addr a)
2247{
2248 DebugInfo* di;
2249 VgSectKind res = Vg_SectUnknown;
2250
2251 for (di = debugInfo_list; di != NULL; di = di->next) {
2252
2253 if (0)
2254 VG_(printf)(
2255 "addr=%p di=%p %s got=%p,%ld plt=%p,%ld data=%p,%ld bss=%p,%ld\n",
2256 a, di, di->filename,
2257 di->got_avma, di->got_size,
2258 di->plt_avma, di->plt_size,
2259 di->data_avma, di->data_size,
2260 di->bss_avma, di->bss_size);
2261
2262 if (di->text_present
2263 && di->text_size > 0
2264 && a >= di->text_avma && a < di->text_avma + di->text_size) {
2265 res = Vg_SectText;
2266 break;
2267 }
2268 if (di->data_present
2269 && di->data_size > 0
2270 && a >= di->data_avma && a < di->data_avma + di->data_size) {
2271 res = Vg_SectData;
2272 break;
2273 }
2274 if (di->sdata_present
2275 && di->sdata_size > 0
2276 && a >= di->sdata_avma && a < di->sdata_avma + di->sdata_size) {
2277 res = Vg_SectData;
2278 break;
2279 }
2280 if (di->bss_present
2281 && di->bss_size > 0
2282 && a >= di->bss_avma && a < di->bss_avma + di->bss_size) {
2283 res = Vg_SectBSS;
2284 break;
2285 }
2286 if (di->plt_present
2287 && di->plt_size > 0
2288 && a >= di->plt_avma && a < di->plt_avma + di->plt_size) {
2289 res = Vg_SectPLT;
2290 break;
2291 }
2292 if (di->got_present
2293 && di->got_size > 0
2294 && a >= di->got_avma && a < di->got_avma + di->got_size) {
2295 res = Vg_SectGOT;
2296 break;
2297 }
2298 if (di->opd_present
2299 && di->opd_size > 0
2300 && a >= di->opd_avma && a < di->opd_avma + di->opd_size) {
2301 res = Vg_SectOPD;
2302 break;
2303 }
2304 /* we could also check for .eh_frame, if anyone really cares */
2305 }
2306
2307 vg_assert( (di == NULL && res == Vg_SectUnknown)
2308 || (di != NULL && res != Vg_SectUnknown) );
2309
2310 if (name) {
2311
2312 vg_assert(n_name >= 8);
2313
2314 if (di && di->filename) {
2315 Int i, j;
2316 Int fnlen = VG_(strlen)(di->filename);
2317 Int start_at = 1 + fnlen - n_name;
2318 if (start_at < 0) start_at = 0;
2319 vg_assert(start_at < fnlen);
2320 i = start_at; j = 0;
2321 while (True) {
2322 vg_assert(j >= 0 && j+1 < n_name);
2323 vg_assert(i >= 0 && i <= fnlen);
2324 name[j] = di->filename[i];
2325 name[j+1] = 0;
2326 if (di->filename[i] == 0) break;
2327 i++; j++;
2328 }
2329 } else {
2330 VG_(snprintf)(name, n_name, "%s", "???");
2331 }
2332
2333 name[n_name-1] = 0;
2334 }
2335
2336 return res;
2337
sewardjeadcd862006-04-04 15:12:44 +00002338}
2339
2340
2341/*--------------------------------------------------------------------*/
2342/*--- end ---*/
2343/*--------------------------------------------------------------------*/