blob: 6373044db3cfdf25120dd861aa6a4e8195a7c901 [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
sewardj0f157dd2013-10-18 14:27:36 +000011 Copyright (C) 2000-2013 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*/
sewardjeadcd862006-04-04 15:12:44 +000031
32#include "pub_core_basics.h"
sewardj4cfea4f2006-10-14 19:26:10 +000033#include "pub_core_vki.h"
sewardj6c591e12011-04-11 16:17:51 +000034#include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy
sewardjeadcd862006-04-04 15:12:44 +000035#include "pub_core_threadstate.h"
sewardjb8b79ad2008-03-03 01:35:41 +000036#include "pub_core_debuginfo.h" /* self */
sewardjeadcd862006-04-04 15:12:44 +000037#include "pub_core_demangle.h"
38#include "pub_core_libcbase.h"
39#include "pub_core_libcassert.h"
40#include "pub_core_libcprint.h"
sewardjb8b79ad2008-03-03 01:35:41 +000041#include "pub_core_libcfile.h"
sewardj13ac96d2010-02-12 12:12:39 +000042#include "pub_core_libcproc.h" // VG_(getenv)
sewardjd7a02db2008-12-12 08:07:49 +000043#include "pub_core_seqmatch.h"
sewardjeadcd862006-04-04 15:12:44 +000044#include "pub_core_options.h"
sewardjb8b79ad2008-03-03 01:35:41 +000045#include "pub_core_redir.h" // VG_(redir_notify_{new,delete}_SegInfo)
sewardjeadcd862006-04-04 15:12:44 +000046#include "pub_core_aspacemgr.h"
sewardjb8b79ad2008-03-03 01:35:41 +000047#include "pub_core_machine.h" // VG_PLAT_USES_PPCTOC
sewardj72427fa2007-02-27 16:52:23 +000048#include "pub_core_xarray.h"
sewardjb8b79ad2008-03-03 01:35:41 +000049#include "pub_core_oset.h"
njn68824432009-02-10 06:48:00 +000050#include "pub_core_stacktrace.h" // VG_(get_StackTrace) XXX: circular dependency
njnf76d27a2009-05-28 01:53:07 +000051#include "pub_core_ume.h"
sewardjb8b79ad2008-03-03 01:35:41 +000052
53#include "priv_misc.h" /* dinfo_zalloc/free */
sewardj5d616df2013-07-02 08:07:15 +000054#include "priv_image.h"
sewardjb8b79ad2008-03-03 01:35:41 +000055#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"
sewardjc8259b82009-04-22 22:42:10 +000063# include "priv_readpdb.h"
njnf76d27a2009-05-28 01:53:07 +000064#elif defined(VGO_darwin)
65# include "priv_readmacho.h"
66# include "priv_readpdb.h"
sewardj4ee4f982006-10-17 01:37:10 +000067#endif
sewardjeadcd862006-04-04 15:12:44 +000068
sewardjc6d3f6f2007-01-11 19:42:11 +000069
70/*------------------------------------------------------------*/
71/*--- The _svma / _avma / _image / _bias naming scheme ---*/
72/*------------------------------------------------------------*/
73
74/* JRS 11 Jan 07: I find the different kinds of addresses involved in
75 debuginfo reading confusing. Recently I arrived at some
76 terminology which makes it clearer (to me, at least). There are 3
77 kinds of address used in the debuginfo reading process:
78
79 stated VMAs - the address where (eg) a .so says a symbol is, that
80 is, what it tells you if you consider the .so in
81 isolation
82
83 actual VMAs - the address where (eg) said symbol really wound up
84 after the .so was mapped into memory
85
86 image addresses - pointers into the copy of the .so (etc)
87 transiently mmaped aboard whilst we read its info
88
89 Additionally I use the term 'bias' to denote the difference
90 between stated and actual VMAs for a given entity.
91
92 This terminology is not used consistently, but a start has been
93 made. readelf.c and the call-frame info reader in readdwarf.c now
94 use it. Specifically, various variables and structure fields have
sewardjf767d962007-02-12 17:47:14 +000095 been annotated with _avma / _svma / _image / _bias. In places _img
96 is used instead of _image for the sake of brevity.
sewardjc6d3f6f2007-01-11 19:42:11 +000097*/
98
99
sewardjeadcd862006-04-04 15:12:44 +0000100/*------------------------------------------------------------*/
sewardjf98e1c02008-10-25 16:22:41 +0000101/*--- fwdses ---*/
102/*------------------------------------------------------------*/
103
philippe20ede3a2013-01-30 23:18:11 +0000104static UInt CF_info_generation = 0;
sewardjf98e1c02008-10-25 16:22:41 +0000105static void cfsi_cache__invalidate ( void );
106
107
108/*------------------------------------------------------------*/
sewardjeadcd862006-04-04 15:12:44 +0000109/*--- Root structure ---*/
110/*------------------------------------------------------------*/
111
sewardjb8b79ad2008-03-03 01:35:41 +0000112/* The root structure for the entire debug info system. It is a
113 linked list of DebugInfos. */
114static DebugInfo* debugInfo_list = NULL;
115
116
117/* Find 'di' in the debugInfo_list and move it one step closer the the
118 front of the list, so as to make subsequent searches for it
119 cheaper. When used in a controlled way, makes a major improvement
120 in some DebugInfo-search-intensive situations, most notably stack
121 unwinding on amd64-linux. */
122static void move_DebugInfo_one_step_forward ( DebugInfo* di )
123{
124 DebugInfo *di0, *di1, *di2;
125 if (di == debugInfo_list)
126 return; /* already at head of list */
127 vg_assert(di != NULL);
128 di0 = debugInfo_list;
129 di1 = NULL;
130 di2 = NULL;
131 while (True) {
132 if (di0 == NULL || di0 == di) break;
133 di2 = di1;
134 di1 = di0;
135 di0 = di0->next;
136 }
137 vg_assert(di0 == di);
138 if (di0 != NULL && di1 != NULL && di2 != NULL) {
139 DebugInfo* tmp;
140 /* di0 points to di, di1 to its predecessor, and di2 to di1's
141 predecessor. Swap di0 and di1, that is, move di0 one step
142 closer to the start of the list. */
143 vg_assert(di2->next == di1);
144 vg_assert(di1->next == di0);
145 tmp = di0->next;
146 di2->next = di0;
147 di0->next = di1;
148 di1->next = tmp;
149 }
150 else
151 if (di0 != NULL && di1 != NULL && di2 == NULL) {
152 /* it's second in the list. */
153 vg_assert(debugInfo_list == di1);
154 vg_assert(di1->next == di0);
155 di1->next = di0->next;
156 di0->next = di1;
157 debugInfo_list = di0;
158 }
159}
sewardjeadcd862006-04-04 15:12:44 +0000160
161
162/*------------------------------------------------------------*/
163/*--- Notification (acquire/discard) helpers ---*/
164/*------------------------------------------------------------*/
165
sewardj9c606bd2008-09-18 18:12:50 +0000166/* Gives out unique abstract handles for allocated DebugInfos. See
167 comment in priv_storage.h, declaration of struct _DebugInfo, for
168 details. */
169static ULong handle_counter = 1;
170
sewardjb8b79ad2008-03-03 01:35:41 +0000171/* Allocate and zero out a new DebugInfo record. */
sewardjeadcd862006-04-04 15:12:44 +0000172static
florian1636d332012-11-15 04:27:04 +0000173DebugInfo* alloc_DebugInfo( const HChar* filename )
sewardjeadcd862006-04-04 15:12:44 +0000174{
sewardjb8b79ad2008-03-03 01:35:41 +0000175 Bool traceme;
176 DebugInfo* di;
sewardjeadcd862006-04-04 15:12:44 +0000177
sewardjf767d962007-02-12 17:47:14 +0000178 vg_assert(filename);
179
sewardj9c606bd2008-09-18 18:12:50 +0000180 di = ML_(dinfo_zalloc)("di.debuginfo.aDI.1", sizeof(DebugInfo));
sewardja5acac32011-09-20 21:59:50 +0000181 di->handle = handle_counter++;
182 di->fsm.filename = ML_(dinfo_strdup)("di.debuginfo.aDI.2", filename);
sewardj6b5625b2012-07-13 11:24:05 +0000183 di->fsm.maps = VG_(newXA)(
184 ML_(dinfo_zalloc), "di.debuginfo.aDI.3",
185 ML_(dinfo_free), sizeof(struct _DebugInfoMapping));
sewardjeadcd862006-04-04 15:12:44 +0000186
sewardj452e89a2011-05-30 10:18:59 +0000187 /* Everything else -- pointers, sizes, arrays -- is zeroed by
188 ML_(dinfo_zalloc). Now set up the debugging-output flags. */
sewardjf767d962007-02-12 17:47:14 +0000189 traceme
sewardj0f4126c2011-09-20 16:10:59 +0000190 = VG_(string_match)( VG_(clo_trace_symtab_patt), filename );
sewardjf767d962007-02-12 17:47:14 +0000191 if (traceme) {
sewardjb8b79ad2008-03-03 01:35:41 +0000192 di->trace_symtab = VG_(clo_trace_symtab);
193 di->trace_cfi = VG_(clo_trace_cfi);
194 di->ddump_syms = VG_(clo_debug_dump_syms);
195 di->ddump_line = VG_(clo_debug_dump_line);
196 di->ddump_frames = VG_(clo_debug_dump_frames);
sewardjf767d962007-02-12 17:47:14 +0000197 }
198
sewardjb8b79ad2008-03-03 01:35:41 +0000199 return di;
sewardjeadcd862006-04-04 15:12:44 +0000200}
201
202
sewardjb8b79ad2008-03-03 01:35:41 +0000203/* Free a DebugInfo, and also all the stuff hanging off it. */
204static void free_DebugInfo ( DebugInfo* di )
sewardjeadcd862006-04-04 15:12:44 +0000205{
sewardj59a2d182008-08-22 23:18:02 +0000206 Word i, j, n;
sewardjeadcd862006-04-04 15:12:44 +0000207 struct strchunk *chunk, *next;
sewardj9c606bd2008-09-18 18:12:50 +0000208 TyEnt* ent;
sewardj59a2d182008-08-22 23:18:02 +0000209 GExpr* gexpr;
sewardjeadcd862006-04-04 15:12:44 +0000210
sewardjb8b79ad2008-03-03 01:35:41 +0000211 vg_assert(di != NULL);
sewardj6b5625b2012-07-13 11:24:05 +0000212 if (di->fsm.maps) VG_(deleteXA)(di->fsm.maps);
sewardja5acac32011-09-20 21:59:50 +0000213 if (di->fsm.filename) ML_(dinfo_free)(di->fsm.filename);
philippef1e1aa62012-03-12 22:06:57 +0000214 if (di->soname) ML_(dinfo_free)(di->soname);
sewardja5acac32011-09-20 21:59:50 +0000215 if (di->loctab) ML_(dinfo_free)(di->loctab);
216 if (di->cfsi) ML_(dinfo_free)(di->cfsi);
217 if (di->cfsi_exprs) VG_(deleteXA)(di->cfsi_exprs);
218 if (di->fpo) ML_(dinfo_free)(di->fpo);
sewardjb8b79ad2008-03-03 01:35:41 +0000219
sewardja5cace02011-08-15 09:42:34 +0000220 if (di->symtab) {
221 /* We have to visit all the entries so as to free up any
222 sec_names arrays that might exist. */
223 n = di->symtab_used;
224 for (i = 0; i < n; i++) {
225 DiSym* sym = &di->symtab[i];
226 if (sym->sec_names)
227 ML_(dinfo_free)(sym->sec_names);
228 }
229 /* and finally .. */
230 ML_(dinfo_free)(di->symtab);
231 }
232
sewardjb8b79ad2008-03-03 01:35:41 +0000233 for (chunk = di->strchunks; chunk != NULL; chunk = next) {
sewardjeadcd862006-04-04 15:12:44 +0000234 next = chunk->next;
sewardjb8b79ad2008-03-03 01:35:41 +0000235 ML_(dinfo_free)(chunk);
sewardjeadcd862006-04-04 15:12:44 +0000236 }
sewardjb8b79ad2008-03-03 01:35:41 +0000237
sewardj9c606bd2008-09-18 18:12:50 +0000238 /* Delete the two admin arrays. These lists exist primarily so
239 that we can visit each object exactly once when we need to
240 delete them. */
241 if (di->admin_tyents) {
242 n = VG_(sizeXA)(di->admin_tyents);
sewardj59a2d182008-08-22 23:18:02 +0000243 for (i = 0; i < n; i++) {
sewardj9c606bd2008-09-18 18:12:50 +0000244 ent = (TyEnt*)VG_(indexXA)(di->admin_tyents, i);
245 /* Dump anything hanging off this ent */
246 ML_(TyEnt__make_EMPTY)(ent);
sewardj59a2d182008-08-22 23:18:02 +0000247 }
sewardj9c606bd2008-09-18 18:12:50 +0000248 VG_(deleteXA)(di->admin_tyents);
249 di->admin_tyents = NULL;
sewardjb8b79ad2008-03-03 01:35:41 +0000250 }
sewardj59a2d182008-08-22 23:18:02 +0000251
252 if (di->admin_gexprs) {
253 n = VG_(sizeXA)(di->admin_gexprs);
254 for (i = 0; i < n; i++) {
255 gexpr = *(GExpr**)VG_(indexXA)(di->admin_gexprs, i);
256 ML_(dinfo_free)(gexpr);
257 }
258 VG_(deleteXA)(di->admin_gexprs);
259 di->admin_gexprs = NULL;
sewardjb8b79ad2008-03-03 01:35:41 +0000260 }
261
262 /* Dump the variable info. This is kinda complex: we must take
263 care not to free items which reside in either the admin lists
264 (as we have just freed them) or which reside in the DebugInfo's
265 string table. */
266 if (di->varinfo) {
267 for (i = 0; i < VG_(sizeXA)(di->varinfo); i++) {
268 OSet* scope = *(OSet**)VG_(indexXA)(di->varinfo, i);
269 if (!scope) continue;
270 /* iterate over all entries in 'scope' */
271 VG_(OSetGen_ResetIter)(scope);
272 while (True) {
273 DiAddrRange* arange = VG_(OSetGen_Next)(scope);
274 if (!arange) break;
275 /* for each var in 'arange' */
276 vg_assert(arange->vars);
277 for (j = 0; j < VG_(sizeXA)( arange->vars ); j++) {
278 DiVariable* var = (DiVariable*)VG_(indexXA)(arange->vars,j);
279 vg_assert(var);
280 /* Nothing to free in var: all the pointer fields refer
281 to stuff either on an admin list, or in
282 .strchunks */
283 }
284 VG_(deleteXA)(arange->vars);
285 /* Don't free arange itself, as OSetGen_Destroy does
286 that */
287 }
288 VG_(OSetGen_Destroy)(scope);
289 }
290 VG_(deleteXA)(di->varinfo);
291 }
292
293 ML_(dinfo_free)(di);
sewardjeadcd862006-04-04 15:12:44 +0000294}
295
296
sewardjb8b79ad2008-03-03 01:35:41 +0000297/* 'si' is a member of debugInfo_list. Find it, remove it from the
sewardjeadcd862006-04-04 15:12:44 +0000298 list, notify m_redir that this has happened, and free all storage
299 reachable from it.
300*/
sewardjb8b79ad2008-03-03 01:35:41 +0000301static void discard_DebugInfo ( DebugInfo* di )
sewardjeadcd862006-04-04 15:12:44 +0000302{
florian6bd9dc12012-11-23 16:17:43 +0000303 const HChar* reason = "munmap";
sewardj4ee4f982006-10-17 01:37:10 +0000304
sewardjb8b79ad2008-03-03 01:35:41 +0000305 DebugInfo** prev_next_ptr = &debugInfo_list;
306 DebugInfo* curr = debugInfo_list;
sewardjeadcd862006-04-04 15:12:44 +0000307
308 while (curr) {
sewardjb8b79ad2008-03-03 01:35:41 +0000309 if (curr == di) {
310 /* Found it; remove from list and free it. */
sewardj33e4e7e2008-03-06 18:31:42 +0000311 if (curr->have_dinfo
312 && (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir)))
sewardjeadcd862006-04-04 15:12:44 +0000313 VG_(message)(Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +0000314 "Discarding syms at %#lx-%#lx in %s due to %s()\n",
sewardjb8b79ad2008-03-03 01:35:41 +0000315 di->text_avma,
316 di->text_avma + di->text_size,
sewardja5acac32011-09-20 21:59:50 +0000317 curr->fsm.filename ? curr->fsm.filename
florian1636d332012-11-15 04:27:04 +0000318 : "???",
sewardj4ee4f982006-10-17 01:37:10 +0000319 reason);
sewardjeadcd862006-04-04 15:12:44 +0000320 vg_assert(*prev_next_ptr == curr);
321 *prev_next_ptr = curr->next;
sewardj33e4e7e2008-03-06 18:31:42 +0000322 if (curr->have_dinfo)
323 VG_(redir_notify_delete_DebugInfo)( curr );
sewardjb8b79ad2008-03-03 01:35:41 +0000324 free_DebugInfo(curr);
sewardjeadcd862006-04-04 15:12:44 +0000325 return;
326 }
327 prev_next_ptr = &curr->next;
328 curr = curr->next;
329 }
330
sewardjb8b79ad2008-03-03 01:35:41 +0000331 /* Not found. */
sewardjeadcd862006-04-04 15:12:44 +0000332}
333
334
sewardjb8b79ad2008-03-03 01:35:41 +0000335/* Repeatedly scan debugInfo_list, looking for DebugInfos with text
336 AVMAs intersecting [start,start+length), and call discard_DebugInfo
337 to get rid of them. This modifies the list, hence the multiple
sewardjf98e1c02008-10-25 16:22:41 +0000338 iterations. Returns True iff any such DebugInfos were found.
sewardjb8b79ad2008-03-03 01:35:41 +0000339*/
sewardjf98e1c02008-10-25 16:22:41 +0000340static Bool discard_syms_in_range ( Addr start, SizeT length )
sewardjeadcd862006-04-04 15:12:44 +0000341{
sewardjf98e1c02008-10-25 16:22:41 +0000342 Bool anyFound = False;
sewardjb8b79ad2008-03-03 01:35:41 +0000343 Bool found;
344 DebugInfo* curr;
sewardjeadcd862006-04-04 15:12:44 +0000345
346 while (True) {
347 found = False;
348
sewardjb8b79ad2008-03-03 01:35:41 +0000349 curr = debugInfo_list;
sewardjeadcd862006-04-04 15:12:44 +0000350 while (True) {
351 if (curr == NULL)
352 break;
sewardjb8b79ad2008-03-03 01:35:41 +0000353 if (curr->text_present
354 && curr->text_size > 0
355 && (start+length - 1 < curr->text_avma
356 || curr->text_avma + curr->text_size - 1 < start)) {
sewardjeadcd862006-04-04 15:12:44 +0000357 /* no overlap */
358 } else {
359 found = True;
360 break;
361 }
362 curr = curr->next;
363 }
364
365 if (!found) break;
sewardjf98e1c02008-10-25 16:22:41 +0000366 anyFound = True;
sewardjb8b79ad2008-03-03 01:35:41 +0000367 discard_DebugInfo( curr );
sewardjeadcd862006-04-04 15:12:44 +0000368 }
sewardjf98e1c02008-10-25 16:22:41 +0000369
370 return anyFound;
sewardjeadcd862006-04-04 15:12:44 +0000371}
372
373
sewardjb8b79ad2008-03-03 01:35:41 +0000374/* Does [s1,+len1) overlap [s2,+len2) ? Note: does not handle
375 wraparound at the end of the address space -- just asserts in that
376 case. */
377static Bool ranges_overlap (Addr s1, SizeT len1, Addr s2, SizeT len2 )
sewardjeadcd862006-04-04 15:12:44 +0000378{
sewardjb8b79ad2008-03-03 01:35:41 +0000379 Addr e1, e2;
380 if (len1 == 0 || len2 == 0)
381 return False;
382 e1 = s1 + len1 - 1;
383 e2 = s2 + len2 - 1;
384 /* Assert that we don't have wraparound. If we do it would imply
385 that file sections are getting mapped around the end of the
386 address space, which sounds unlikely. */
387 vg_assert(s1 <= e1);
388 vg_assert(s2 <= e2);
389 if (e1 < s2 || e2 < s1) return False;
390 return True;
391}
sewardjeadcd862006-04-04 15:12:44 +0000392
sewardjeadcd862006-04-04 15:12:44 +0000393
sewardj6b5625b2012-07-13 11:24:05 +0000394/* Do the basic mappings of the two DebugInfos overlap in any way? */
sewardjb8b79ad2008-03-03 01:35:41 +0000395static Bool do_DebugInfos_overlap ( DebugInfo* di1, DebugInfo* di2 )
396{
sewardj6b5625b2012-07-13 11:24:05 +0000397 Word i, j;
sewardjb8b79ad2008-03-03 01:35:41 +0000398 vg_assert(di1);
399 vg_assert(di2);
sewardj6b5625b2012-07-13 11:24:05 +0000400 for (i = 0; i < VG_(sizeXA)(di1->fsm.maps); i++) {
401 struct _DebugInfoMapping* map1 = VG_(indexXA)(di1->fsm.maps, i);
402 for (j = 0; j < VG_(sizeXA)(di2->fsm.maps); j++) {
403 struct _DebugInfoMapping* map2 = VG_(indexXA)(di2->fsm.maps, j);
404 if (ranges_overlap(map1->avma, map1->size, map2->avma, map2->size))
405 return True;
406 }
407 }
sewardjb8b79ad2008-03-03 01:35:41 +0000408
409 return False;
410}
411
412
413/* Discard all elements of debugInfo_list whose .mark bit is set.
414*/
415static void discard_marked_DebugInfos ( void )
416{
417 DebugInfo* curr;
418
419 while (True) {
420
421 curr = debugInfo_list;
422 while (True) {
423 if (!curr)
424 break;
425 if (curr->mark)
426 break;
427 curr = curr->next;
428 }
429
430 if (!curr) break;
431 discard_DebugInfo( curr );
432
sewardjeadcd862006-04-04 15:12:44 +0000433 }
sewardjb8b79ad2008-03-03 01:35:41 +0000434}
sewardjeadcd862006-04-04 15:12:44 +0000435
sewardjb8b79ad2008-03-03 01:35:41 +0000436
437/* Discard any elements of debugInfo_list which overlap with diRef.
sewardj6b5625b2012-07-13 11:24:05 +0000438 Clearly diRef must have its mapping information set to something sane. */
sewardjb8b79ad2008-03-03 01:35:41 +0000439static void discard_DebugInfos_which_overlap_with ( DebugInfo* diRef )
440{
441 DebugInfo* di;
442 /* Mark all the DebugInfos in debugInfo_list that need to be
443 deleted. First, clear all the mark bits; then set them if they
444 overlap with siRef. Since siRef itself is in this list we at
445 least expect its own mark bit to be set. */
446 for (di = debugInfo_list; di; di = di->next) {
447 di->mark = do_DebugInfos_overlap( di, diRef );
448 if (di == diRef) {
449 vg_assert(di->mark);
450 di->mark = False;
451 }
452 }
453 discard_marked_DebugInfos();
454}
455
456
sewardj0f4126c2011-09-20 16:10:59 +0000457/* Find the existing DebugInfo for |filename| or if not found, create
458 one. In the latter case |filename| is strdup'd into VG_AR_DINFO,
459 and the new DebugInfo is added to debugInfo_list. */
florian1636d332012-11-15 04:27:04 +0000460static DebugInfo* find_or_create_DebugInfo_for ( HChar* filename )
sewardjb8b79ad2008-03-03 01:35:41 +0000461{
462 DebugInfo* di;
463 vg_assert(filename);
464 for (di = debugInfo_list; di; di = di->next) {
sewardja5acac32011-09-20 21:59:50 +0000465 vg_assert(di->fsm.filename);
466 if (0==VG_(strcmp)(di->fsm.filename, filename))
sewardjb8b79ad2008-03-03 01:35:41 +0000467 break;
468 }
469 if (!di) {
sewardj0f4126c2011-09-20 16:10:59 +0000470 di = alloc_DebugInfo(filename);
sewardjb8b79ad2008-03-03 01:35:41 +0000471 vg_assert(di);
472 di->next = debugInfo_list;
473 debugInfo_list = di;
474 }
475 return di;
sewardjeadcd862006-04-04 15:12:44 +0000476}
477
478
sewardjf98e1c02008-10-25 16:22:41 +0000479/* Debuginfo reading for 'di' has just been successfully completed.
480 Check that the invariants stated in
481 "Comment_on_IMPORTANT_CFSI_REPRESENTATIONAL_INVARIANTS" in
482 priv_storage.h are observed. */
483static void check_CFSI_related_invariants ( DebugInfo* di )
484{
485 DebugInfo* di2 = NULL;
sewardj6b5625b2012-07-13 11:24:05 +0000486 Bool has_nonempty_rx = False;
487 Bool cfsi_fits = False;
488 Word i, j;
sewardjf98e1c02008-10-25 16:22:41 +0000489 vg_assert(di);
490 /* This fn isn't called until after debuginfo for this object has
491 been successfully read. And that shouldn't happen until we have
492 both a r-x and rw- mapping for the object. Hence: */
sewardja5acac32011-09-20 21:59:50 +0000493 vg_assert(di->fsm.have_rx_map);
494 vg_assert(di->fsm.have_rw_map);
sewardj6b5625b2012-07-13 11:24:05 +0000495 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
496 struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
497 /* We are interested in r-x mappings only */
498 if (!map->rx)
499 continue;
500
501 /* degenerate case: r-x section is empty */
502 if (map->size == 0)
503 continue;
504 has_nonempty_rx = True;
505
506 /* normal case: r-x section is nonempty */
507 /* invariant (0) */
508 vg_assert(map->size > 0);
509
510 /* invariant (1) */
511 for (di2 = debugInfo_list; di2; di2 = di2->next) {
512 if (di2 == di)
513 continue;
514 for (j = 0; j < VG_(sizeXA)(di2->fsm.maps); j++) {
515 struct _DebugInfoMapping* map2 = VG_(indexXA)(di2->fsm.maps, j);
516 if (!map2->rx || map2->size == 0)
517 continue;
518 vg_assert(!ranges_overlap(map->avma, map->size,
519 map2->avma, map2->size));
520 }
521 }
522 di2 = NULL;
523
524 /* invariant (2) */
525 if (di->cfsi) {
526 vg_assert(di->cfsi_minavma <= di->cfsi_maxavma); /* duh! */
527 /* Assume the csfi fits completely into one individual mapping
528 for now. This might need to be improved/reworked later. */
529 if (di->cfsi_minavma >= map->avma &&
530 di->cfsi_maxavma < map->avma + map->size)
531 cfsi_fits = True;
532 }
533 }
534
535 /* degenerate case: all r-x sections are empty */
536 if (!has_nonempty_rx) {
sewardjf98e1c02008-10-25 16:22:41 +0000537 vg_assert(di->cfsi == NULL);
538 return;
539 }
sewardj6b5625b2012-07-13 11:24:05 +0000540
541 /* invariant (2) - cont. */
542 if (di->cfsi)
543 vg_assert(cfsi_fits);
544
sewardjf98e1c02008-10-25 16:22:41 +0000545 /* invariants (3) and (4) */
546 if (di->cfsi) {
sewardjf98e1c02008-10-25 16:22:41 +0000547 vg_assert(di->cfsi_used > 0);
548 vg_assert(di->cfsi_size > 0);
549 for (i = 0; i < di->cfsi_used; i++) {
550 DiCfSI* cfsi = &di->cfsi[i];
551 vg_assert(cfsi->len > 0);
552 vg_assert(cfsi->base >= di->cfsi_minavma);
553 vg_assert(cfsi->base + cfsi->len - 1 <= di->cfsi_maxavma);
554 if (i > 0) {
555 DiCfSI* cfsip = &di->cfsi[i-1];
556 vg_assert(cfsip->base + cfsip->len <= cfsi->base);
557 }
558 }
559 } else {
560 vg_assert(di->cfsi_used == 0);
561 vg_assert(di->cfsi_size == 0);
562 }
563}
564
565
566/*--------------------------------------------------------------*/
567/*--- ---*/
568/*--- TOP LEVEL: INITIALISE THE DEBUGINFO SYSTEM ---*/
569/*--- ---*/
570/*--------------------------------------------------------------*/
571
572void VG_(di_initialise) ( void )
573{
574 /* There's actually very little to do here, since everything
575 centers around the DebugInfos in debugInfo_list, they are
576 created and destroyed on demand, and each one is treated more or
577 less independently. */
578 vg_assert(debugInfo_list == NULL);
579
580 /* flush the CFI fast query cache. */
581 cfsi_cache__invalidate();
582}
583
584
sewardj4ee4f982006-10-17 01:37:10 +0000585/*--------------------------------------------------------------*/
586/*--- ---*/
587/*--- TOP LEVEL: NOTIFICATION (ACQUIRE/DISCARD INFO) (LINUX) ---*/
588/*--- ---*/
589/*--------------------------------------------------------------*/
590
njnf76d27a2009-05-28 01:53:07 +0000591#if defined(VGO_linux) || defined(VGO_darwin)
sewardjeadcd862006-04-04 15:12:44 +0000592
593/* The debug info system is driven by notifications that a text
sewardj731f9cf2011-09-21 08:43:08 +0000594 segment has been mapped in, or unmapped, or when sections change
595 permission. It's all a bit kludgey and basically means watching
596 syscalls, trying to second-guess when the system's dynamic linker
597 is done with mapping in a new object for execution. This is all
598 tracked using the DebugInfoFSM struct for the object. Anyway, once
599 we finally decide we've got to an accept state, this section then
600 will acquire whatever info is available for the corresponding
601 object. This section contains the notification handlers, which
602 update the FSM and determine when an accept state has been reached.
603*/
604
605/* When the sequence of observations causes a DebugInfoFSM to move
606 into the accept state, call here to actually get the debuginfo read
607 in. Returns a ULong whose purpose is described in comments
608 preceding VG_(di_notify_mmap) just below.
609*/
610static ULong di_notify_ACHIEVE_ACCEPT_STATE ( struct _DebugInfo* di )
611{
612 ULong di_handle;
613 Bool ok;
614
615 vg_assert(di->fsm.filename);
616 TRACE_SYMTAB("\n");
617 TRACE_SYMTAB("------ start ELF OBJECT "
618 "------------------------------\n");
619 TRACE_SYMTAB("------ name = %s\n", di->fsm.filename);
620 TRACE_SYMTAB("\n");
621
622 /* We're going to read symbols and debug info for the avma
sewardj6b5625b2012-07-13 11:24:05 +0000623 ranges specified in the _DebugInfoFsm mapping array. First
624 get rid of any other DebugInfos which overlap any of those
625 ranges (to avoid total confusion). */
sewardj731f9cf2011-09-21 08:43:08 +0000626 discard_DebugInfos_which_overlap_with( di );
627
628 /* .. and acquire new info. */
629# if defined(VGO_linux)
630 ok = ML_(read_elf_debug_info)( di );
631# elif defined(VGO_darwin)
632 ok = ML_(read_macho_debug_info)( di );
633# else
634# error "unknown OS"
635# endif
636
637 if (ok) {
638
639 TRACE_SYMTAB("\n------ Canonicalising the "
640 "acquired info ------\n");
641 /* invalidate the CFI unwind cache. */
642 cfsi_cache__invalidate();
643 /* prepare read data for use */
644 ML_(canonicaliseTables)( di );
645 /* notify m_redir about it */
646 TRACE_SYMTAB("\n------ Notifying m_redir ------\n");
647 VG_(redir_notify_new_DebugInfo)( di );
648 /* Note that we succeeded */
649 di->have_dinfo = True;
650 tl_assert(di->handle > 0);
651 di_handle = di->handle;
652 /* Check invariants listed in
653 Comment_on_IMPORTANT_REPRESENTATIONAL_INVARIANTS in
654 priv_storage.h. */
655 check_CFSI_related_invariants(di);
656
657 } else {
658 TRACE_SYMTAB("\n------ ELF reading failed ------\n");
659 /* Something went wrong (eg. bad ELF file). Should we delete
660 this DebugInfo? No - it contains info on the rw/rx
661 mappings, at least. */
662 di_handle = 0;
663 vg_assert(di->have_dinfo == False);
664 }
665
666 TRACE_SYMTAB("\n");
667 TRACE_SYMTAB("------ name = %s\n", di->fsm.filename);
668 TRACE_SYMTAB("------ end ELF OBJECT "
669 "------------------------------\n");
670 TRACE_SYMTAB("\n");
671
672 return di_handle;
673}
674
sewardjeadcd862006-04-04 15:12:44 +0000675
676/* Notify the debuginfo system about a new mapping. This is the way
677 new debug information gets loaded. If allow_SkFileV is True, it
678 will try load debug info if the mapping at 'a' belongs to Valgrind;
679 whereas normally (False) it will not do that. This allows us to
680 carefully control when the thing will read symbols from the
sewardj9c606bd2008-09-18 18:12:50 +0000681 Valgrind executable itself.
sewardjeadcd862006-04-04 15:12:44 +0000682
sewardj5f2dcad2011-10-24 08:53:03 +0000683 If use_fd is not -1, that is used instead of the filename; this
684 avoids perturbing fcntl locks, which are released by simply
685 re-opening and closing the same file (even via different fd!).
686
sewardj9c606bd2008-09-18 18:12:50 +0000687 If a call to VG_(di_notify_mmap) causes debug info to be read, then
688 the returned ULong is an abstract handle which can later be used to
689 refer to the debuginfo read as a result of this specific mapping,
690 in later queries to m_debuginfo. In this case the handle value
691 will be one or above. If the returned value is zero, no debug info
692 was read. */
693
sewardj5f2dcad2011-10-24 08:53:03 +0000694ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd )
sewardjeadcd862006-04-04 15:12:44 +0000695{
sewardj4ee4f982006-10-17 01:37:10 +0000696 NSegment const * seg;
sewardjb8b79ad2008-03-03 01:35:41 +0000697 HChar* filename;
sewardj731f9cf2011-09-21 08:43:08 +0000698 Bool is_rx_map, is_rw_map, is_ro_map;
sewardjb8b79ad2008-03-03 01:35:41 +0000699 DebugInfo* di;
sewardj5f2dcad2011-10-24 08:53:03 +0000700 Int actual_fd, oflags;
701 SysRes preadres;
sewardjb8b79ad2008-03-03 01:35:41 +0000702 HChar buf1k[1024];
703 Bool debug = False;
sewardjec61b652008-08-19 07:03:04 +0000704 SysRes statres;
705 struct vg_stat statbuf;
sewardjeadcd862006-04-04 15:12:44 +0000706
sewardj5f2dcad2011-10-24 08:53:03 +0000707 vg_assert(use_fd >= -1);
708
sewardjb8b79ad2008-03-03 01:35:41 +0000709 /* In short, figure out if this mapping is of interest to us, and
710 if so, try to guess what ld.so is doing and when/if we should
711 read debug info. */
712 seg = VG_(am_find_nsegment)(a);
713 vg_assert(seg);
sewardjeadcd862006-04-04 15:12:44 +0000714
sewardjb8b79ad2008-03-03 01:35:41 +0000715 if (debug)
barta0b6b2c2008-07-07 06:49:24 +0000716 VG_(printf)("di_notify_mmap-1: %#lx-%#lx %c%c%c\n",
sewardjb8b79ad2008-03-03 01:35:41 +0000717 seg->start, seg->end,
718 seg->hasR ? 'r' : '-',
719 seg->hasW ? 'w' : '-',seg->hasX ? 'x' : '-' );
720
721 /* guaranteed by aspacemgr-linux.c, sane_NSegment() */
722 vg_assert(seg->end > seg->start);
723
724 /* Ignore non-file mappings */
725 if ( ! (seg->kind == SkFileC
726 || (seg->kind == SkFileV && allow_SkFileV)) )
sewardj9c606bd2008-09-18 18:12:50 +0000727 return 0;
sewardjb8b79ad2008-03-03 01:35:41 +0000728
729 /* If the file doesn't have a name, we're hosed. Give up. */
florian3e798632012-11-24 19:41:54 +0000730 filename = VG_(am_get_filename)( seg );
sewardjb8b79ad2008-03-03 01:35:41 +0000731 if (!filename)
sewardj9c606bd2008-09-18 18:12:50 +0000732 return 0;
sewardjb8b79ad2008-03-03 01:35:41 +0000733
bart0ab84fe2012-09-09 18:30:17 +0000734 /*
735 * Cannot read from these magic files:
736 * --20208-- WARNING: Serious error when reading debug info
737 * --20208-- When reading debug info from /proc/xen/privcmd:
738 * --20208-- can't read file to inspect ELF header
739 */
740 if (VG_(strncmp)(filename, "/proc/xen/", 10) == 0)
741 return 0;
742
sewardjb8b79ad2008-03-03 01:35:41 +0000743 if (debug)
744 VG_(printf)("di_notify_mmap-2: %s\n", filename);
745
sewardjec61b652008-08-19 07:03:04 +0000746 /* Only try to read debug information from regular files. */
bart15728ab2008-04-09 16:21:34 +0000747 statres = VG_(stat)(filename, &statbuf);
sewardjec61b652008-08-19 07:03:04 +0000748
749 /* stat dereferences symlinks, so we don't expect it to succeed and
750 yet produce something that is a symlink. */
njn9c20ece2009-05-20 02:02:30 +0000751 vg_assert(sr_isError(statres) || ! VKI_S_ISLNK(statbuf.mode));
sewardjec61b652008-08-19 07:03:04 +0000752
753 /* Don't let the stat call fail silently. Filter out some known
754 sources of noise before complaining, though. */
njncda2f0f2009-05-18 02:12:08 +0000755 if (sr_isError(statres)) {
sewardjec61b652008-08-19 07:03:04 +0000756 DebugInfo fake_di;
757 Bool quiet = VG_(strstr)(filename, "/var/run/nscd/") != NULL;
sewardje025eca2008-08-25 12:10:14 +0000758 if (!quiet && VG_(clo_verbosity) > 1) {
sewardjec61b652008-08-19 07:03:04 +0000759 VG_(memset)(&fake_di, 0, sizeof(fake_di));
sewardja5acac32011-09-20 21:59:50 +0000760 fake_di.fsm.filename = filename;
sewardjec61b652008-08-19 07:03:04 +0000761 ML_(symerr)(&fake_di, True, "failed to stat64/stat this file");
762 }
sewardj9c606bd2008-09-18 18:12:50 +0000763 return 0;
sewardj2ac79d32008-03-17 16:23:54 +0000764 }
sewardj2ac79d32008-03-17 16:23:54 +0000765
sewardjec61b652008-08-19 07:03:04 +0000766 /* Finally, the point of all this stattery: if it's not a regular file,
767 don't try to read debug info from it. */
njn9c20ece2009-05-20 02:02:30 +0000768 if (! VKI_S_ISREG(statbuf.mode))
sewardj9c606bd2008-09-18 18:12:50 +0000769 return 0;
sewardjec61b652008-08-19 07:03:04 +0000770
771 /* no uses of statbuf below here. */
bart15728ab2008-04-09 16:21:34 +0000772
sewardjb8b79ad2008-03-03 01:35:41 +0000773 /* Now we have to guess if this is a text-like mapping, a data-like
774 mapping, neither or both. The rules are:
775
776 text if: x86-linux r and x
777 other-linux r and x and not w
778
779 data if: x86-linux r and w
780 other-linux r and w and not x
781
782 Background: On x86-linux, objects are typically mapped twice:
sewardjeadcd862006-04-04 15:12:44 +0000783
784 1b8fb000-1b8ff000 r-xp 00000000 08:02 4471477 vgpreload_memcheck.so
785 1b8ff000-1b900000 rw-p 00004000 08:02 4471477 vgpreload_memcheck.so
786
787 whereas ppc32-linux mysteriously does this:
788
789 118a6000-118ad000 r-xp 00000000 08:05 14209428 vgpreload_memcheck.so
790 118ad000-118b6000 ---p 00007000 08:05 14209428 vgpreload_memcheck.so
791 118b6000-118bd000 rwxp 00000000 08:05 14209428 vgpreload_memcheck.so
792
793 The third mapping should not be considered to have executable
794 code in. Therefore a test which works for both is: r and x and
795 NOT w. Reading symbols from the rwx segment -- which overlaps
796 the r-x segment in the file -- causes the redirection mechanism
797 to redirect to addresses in that third segment, which is wrong
798 and causes crashes.
799
sewardjeadcd862006-04-04 15:12:44 +0000800 JRS 28 Dec 05: unfortunately icc 8.1 on x86 has been seen to
801 produce executables with a single rwx segment rather than a
802 (r-x,rw-) pair. That means the rules have to be modified thusly:
803
804 x86-linux: consider if r and x
sewardjb8b79ad2008-03-03 01:35:41 +0000805 all others: consider if r and x and not w
sewardjf56d2552009-08-16 01:48:35 +0000806
807 2009 Aug 16: apply similar kludge to ppc32-linux.
808 See http://bugs.kde.org/show_bug.cgi?id=190820
sewardjb5b87402011-03-07 16:05:35 +0000809
810 There are two modes on s390x: with and without the noexec kernel
811 parameter. Together with some older kernels, this leads to several
812 variants:
813 executable: r and x
814 data: r and w and x
815 or
816 executable: r and x
817 data: r and w
sewardjeadcd862006-04-04 15:12:44 +0000818 */
sewardjb8b79ad2008-03-03 01:35:41 +0000819 is_rx_map = False;
820 is_rw_map = False;
sewardj731f9cf2011-09-21 08:43:08 +0000821 is_ro_map = False;
822
petarj4df0bfc2013-02-27 23:17:33 +0000823# if defined(VGA_x86) || defined(VGA_ppc32) || defined(VGA_mips32) \
824 || defined(VGA_mips64)
sewardjb8b79ad2008-03-03 01:35:41 +0000825 is_rx_map = seg->hasR && seg->hasX;
826 is_rw_map = seg->hasR && seg->hasW;
sewardjf0c12502014-01-12 12:54:00 +0000827# elif defined(VGA_amd64) || defined(VGA_ppc64) || defined(VGA_arm) \
828 || defined(VGA_arm64)
sewardjb8b79ad2008-03-03 01:35:41 +0000829 is_rx_map = seg->hasR && seg->hasX && !seg->hasW;
830 is_rw_map = seg->hasR && seg->hasW && !seg->hasX;
sewardjb5b87402011-03-07 16:05:35 +0000831# elif defined(VGP_s390x_linux)
832 is_rx_map = seg->hasR && seg->hasX && !seg->hasW;
833 is_rw_map = seg->hasR && seg->hasW;
sewardjeadcd862006-04-04 15:12:44 +0000834# else
sewardjb8b79ad2008-03-03 01:35:41 +0000835# error "Unknown platform"
sewardjeadcd862006-04-04 15:12:44 +0000836# endif
837
sewardj731f9cf2011-09-21 08:43:08 +0000838# if defined(VGP_x86_darwin) && DARWIN_VERS == DARWIN_10_7
839 is_ro_map = seg->hasR && !seg->hasW && !seg->hasX;
840# endif
841
sewardjb8b79ad2008-03-03 01:35:41 +0000842 if (debug)
843 VG_(printf)("di_notify_mmap-3: is_rx_map %d, is_rw_map %d\n",
844 (Int)is_rx_map, (Int)is_rw_map);
sewardjeadcd862006-04-04 15:12:44 +0000845
sewardj731f9cf2011-09-21 08:43:08 +0000846 /* Ignore mappings with permissions we can't possibly be interested in. */
847 if (!(is_rx_map || is_rw_map || is_ro_map))
sewardj9c606bd2008-09-18 18:12:50 +0000848 return 0;
sewardjeadcd862006-04-04 15:12:44 +0000849
sewardj5a5eec02008-11-08 15:22:19 +0000850 /* Peer at the first few bytes of the file, to see if it is an ELF */
851 /* object file. Ignore the file if we do not have read permission. */
852 VG_(memset)(buf1k, 0, sizeof(buf1k));
sewardjcec083d2010-10-07 09:56:19 +0000853 oflags = VKI_O_RDONLY;
854# if defined(VKI_O_LARGEFILE)
855 oflags |= VKI_O_LARGEFILE;
856# endif
sewardj5a5eec02008-11-08 15:22:19 +0000857
sewardj5f2dcad2011-10-24 08:53:03 +0000858 if (use_fd == -1) {
859 SysRes fd = VG_(open)( filename, oflags, 0 );
860 if (sr_isError(fd)) {
861 if (sr_Err(fd) != VKI_EACCES) {
862 DebugInfo fake_di;
863 VG_(memset)(&fake_di, 0, sizeof(fake_di));
864 fake_di.fsm.filename = filename;
865 ML_(symerr)(&fake_di, True,
866 "can't open file to inspect ELF header");
867 }
868 return 0;
869 }
870 actual_fd = sr_Res(fd);
871 } else {
872 actual_fd = use_fd;
873 }
874
875 preadres = VG_(pread)( actual_fd, buf1k, sizeof(buf1k), 0 );
876 if (use_fd == -1) {
877 VG_(close)( actual_fd );
878 }
879
880 if (sr_isError(preadres)) {
sewardj5a5eec02008-11-08 15:22:19 +0000881 DebugInfo fake_di;
882 VG_(memset)(&fake_di, 0, sizeof(fake_di));
sewardja5acac32011-09-20 21:59:50 +0000883 fake_di.fsm.filename = filename;
sewardj5a5eec02008-11-08 15:22:19 +0000884 ML_(symerr)(&fake_di, True, "can't read file to inspect ELF header");
885 return 0;
886 }
sewardj5f2dcad2011-10-24 08:53:03 +0000887 if (sr_Res(preadres) == 0)
888 return 0;
889 vg_assert(sr_Res(preadres) > 0 && sr_Res(preadres) <= sizeof(buf1k) );
sewardj5a5eec02008-11-08 15:22:19 +0000890
njn8b68b642009-06-24 00:37:09 +0000891 /* We're only interested in mappings of object files. */
sewardj6e9de462011-06-28 07:25:29 +0000892# if defined(VGO_linux)
sewardjf7c97142012-07-14 09:59:01 +0000893 if (!ML_(is_elf_object_file)( buf1k, (SizeT)sr_Res(preadres), False ))
sewardj5a5eec02008-11-08 15:22:19 +0000894 return 0;
sewardj6e9de462011-06-28 07:25:29 +0000895# elif defined(VGO_darwin)
sewardj5f2dcad2011-10-24 08:53:03 +0000896 if (!ML_(is_macho_object_file)( buf1k, (SizeT)sr_Res(preadres) ))
njnf76d27a2009-05-28 01:53:07 +0000897 return 0;
sewardj6e9de462011-06-28 07:25:29 +0000898# else
899# error "unknown OS"
900# endif
sewardj5a5eec02008-11-08 15:22:19 +0000901
sewardjb8b79ad2008-03-03 01:35:41 +0000902 /* See if we have a DebugInfo for this filename. If not,
903 create one. */
sewardj0f4126c2011-09-20 16:10:59 +0000904 di = find_or_create_DebugInfo_for( filename );
sewardjb8b79ad2008-03-03 01:35:41 +0000905 vg_assert(di);
sewardjeadcd862006-04-04 15:12:44 +0000906
sewardj6b5625b2012-07-13 11:24:05 +0000907 /* Note the details about the mapping. */
908 struct _DebugInfoMapping map;
909 map.avma = a;
910 map.size = seg->end + 1 - seg->start;
911 map.foff = seg->offset;
912 map.rx = is_rx_map;
913 map.rw = is_rw_map;
914 map.ro = is_ro_map;
915 VG_(addToXA)(di->fsm.maps, &map);
sewardjeadcd862006-04-04 15:12:44 +0000916
sewardj6b5625b2012-07-13 11:24:05 +0000917 /* Update flags about what kind of mappings we've already seen. */
918 di->fsm.have_rx_map |= is_rx_map;
919 di->fsm.have_rw_map |= is_rw_map;
920 di->fsm.have_ro_map |= is_ro_map;
sewardj9c606bd2008-09-18 18:12:50 +0000921
sewardj731f9cf2011-09-21 08:43:08 +0000922 /* So, finally, are we in an accept state? */
923 if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) {
924 /* Ok, so, finally, we found what we need, and we haven't
925 already read debuginfo for this object. So let's do so now.
926 Yee-ha! */
927 return di_notify_ACHIEVE_ACCEPT_STATE ( di );
928 } else {
929 /* If we don't have an rx and rw mapping, or if we already have
930 debuginfo for this mapping for whatever reason, go no
931 further. */
932 return 0;
933 }
sewardjeadcd862006-04-04 15:12:44 +0000934}
935
936
937/* Unmap is simpler - throw away any SegInfos intersecting
938 [a, a+len). */
939void VG_(di_notify_munmap)( Addr a, SizeT len )
940{
sewardjf98e1c02008-10-25 16:22:41 +0000941 Bool anyFound;
barta0b6b2c2008-07-07 06:49:24 +0000942 if (0) VG_(printf)("DISCARD %#lx %#lx\n", a, a+len);
sewardjf98e1c02008-10-25 16:22:41 +0000943 anyFound = discard_syms_in_range(a, len);
944 if (anyFound)
945 cfsi_cache__invalidate();
sewardjeadcd862006-04-04 15:12:44 +0000946}
947
948
949/* Uh, this doesn't do anything at all. IIRC glibc (or ld.so, I don't
950 remember) does a bunch of mprotects on itself, and if we follow
951 through here, it causes the debug info for that object to get
952 discarded. */
953void VG_(di_notify_mprotect)( Addr a, SizeT len, UInt prot )
954{
955 Bool exe_ok = toBool(prot & VKI_PROT_EXEC);
njnf76d27a2009-05-28 01:53:07 +0000956# if defined(VGA_x86)
sewardjeadcd862006-04-04 15:12:44 +0000957 exe_ok = exe_ok || toBool(prot & VKI_PROT_READ);
958# endif
sewardjf98e1c02008-10-25 16:22:41 +0000959 if (0 && !exe_ok) {
960 Bool anyFound = discard_syms_in_range(a, len);
961 if (anyFound)
962 cfsi_cache__invalidate();
963 }
sewardjeadcd862006-04-04 15:12:44 +0000964}
965
sewardj731f9cf2011-09-21 08:43:08 +0000966
967/* This is a MacOSX 10.7 32-bit only special. See comments on the
968 declaration of struct _DebugInfoFSM for details. */
969void VG_(di_notify_vm_protect)( Addr a, SizeT len, UInt prot )
970{
971 Bool do_nothing = True;
sewardjae284e52012-08-02 18:25:04 +0000972# if defined(VGP_x86_darwin) && (DARWIN_VERS == DARWIN_10_7 || DARWIN_VERS == DARWIN_10_8)
sewardj731f9cf2011-09-21 08:43:08 +0000973 do_nothing = False;
974# endif
975 if (do_nothing /* wrong platform */)
976 return;
977
978 Bool r_ok = toBool(prot & VKI_PROT_READ);
979 Bool w_ok = toBool(prot & VKI_PROT_WRITE);
980 Bool x_ok = toBool(prot & VKI_PROT_EXEC);
981 if (! (r_ok && !w_ok && x_ok))
982 return; /* not an upgrade to r-x */
983
984 /* Find a DebugInfo containing a FSM that has [a, +len) previously
985 observed as a r-- mapping, plus some other rw- mapping. If such
986 is found, conclude we're in an accept state and read debuginfo
987 accordingly. */
988 DebugInfo* di;
sewardj6b5625b2012-07-13 11:24:05 +0000989 struct _DebugInfoMapping *map = NULL;
990 Word i;
sewardj731f9cf2011-09-21 08:43:08 +0000991 for (di = debugInfo_list; di; di = di->next) {
992 vg_assert(di->fsm.filename);
993 if (di->have_dinfo)
994 continue; /* already have debuginfo for this object */
995 if (!di->fsm.have_ro_map)
996 continue; /* need to have a r-- mapping for this object */
997 if (di->fsm.have_rx_map)
998 continue; /* rx- mapping already exists */
999 if (!di->fsm.have_rw_map)
1000 continue; /* need to have a rw- mapping */
sewardj6b5625b2012-07-13 11:24:05 +00001001 /* Try to find a mapping matching the memory area. */
1002 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1003 map = (struct _DebugInfoMapping*)VG_(indexXA)(di->fsm.maps, i);
1004 if (map->ro && map->avma == a && map->size == len)
1005 break;
1006 map = NULL;
1007 }
1008 if (!map)
1009 continue; /* this isn't an upgrade of an r-- mapping */
sewardj731f9cf2011-09-21 08:43:08 +00001010 /* looks like we're in luck! */
1011 break;
1012 }
1013 if (di == NULL)
1014 return; /* didn't find anything */
1015
sewardj6b5625b2012-07-13 11:24:05 +00001016 /* Do the upgrade. Simply update the flags of the mapping
1017 and pretend we never saw the RO map at all. */
sewardj731f9cf2011-09-21 08:43:08 +00001018 vg_assert(di->fsm.have_ro_map);
sewardj6b5625b2012-07-13 11:24:05 +00001019 map->rx = True;
1020 map->ro = False;
sewardj731f9cf2011-09-21 08:43:08 +00001021 di->fsm.have_rx_map = True;
sewardj731f9cf2011-09-21 08:43:08 +00001022 di->fsm.have_ro_map = False;
sewardj6b5625b2012-07-13 11:24:05 +00001023 /* See if there are any more ro mappings */
1024 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1025 map = (struct _DebugInfoMapping*)VG_(indexXA)(di->fsm.maps, i);
1026 if (map->ro) {
1027 di->fsm.have_ro_map = True;
1028 break;
1029 }
1030 }
sewardj731f9cf2011-09-21 08:43:08 +00001031
sewardj6b5625b2012-07-13 11:24:05 +00001032 /* Check if we're now in an accept state and read debuginfo. Finally. */
1033 if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) {
1034 ULong di_handle __attribute__((unused))
1035 = di_notify_ACHIEVE_ACCEPT_STATE( di );
1036 /* di_handle is ignored. That's not a problem per se -- it just
1037 means nobody will ever be able to refer to this debuginfo by
1038 handle since nobody will know what the handle value is. */
1039 }
sewardj731f9cf2011-09-21 08:43:08 +00001040}
1041
1042
sewardjc8259b82009-04-22 22:42:10 +00001043/*--------- PDB (windows debug info) reading --------- */
1044
1045/* this should really return ULong, as per VG_(di_notify_mmap). */
1046void VG_(di_notify_pdb_debuginfo)( Int fd_obj, Addr avma_obj,
sewardj54c45db2012-07-13 12:58:55 +00001047 SizeT total_size, PtrdiffT bias_obj )
sewardjc8259b82009-04-22 22:42:10 +00001048{
sewardj13ac96d2010-02-12 12:12:39 +00001049 Int i, r, sz_exename;
sewardjc8259b82009-04-22 22:42:10 +00001050 ULong obj_mtime, pdb_mtime;
florian54fe2022012-10-27 23:07:42 +00001051 HChar exename[VKI_PATH_MAX];
florian1636d332012-11-15 04:27:04 +00001052 HChar* pdbname = NULL;
1053 HChar* dot;
sewardjc8259b82009-04-22 22:42:10 +00001054 SysRes sres;
1055 Int fd_pdbimage;
1056 SizeT n_pdbimage;
1057 struct vg_stat stat_buf;
1058
1059 if (VG_(clo_verbosity) > 0) {
sewardj738856f2009-07-15 14:48:32 +00001060 VG_(message)(Vg_UserMsg, "\n");
sewardjc8259b82009-04-22 22:42:10 +00001061 VG_(message)(Vg_UserMsg,
sewardjcd458d22010-12-06 11:11:29 +00001062 "LOAD_PDB_DEBUGINFO: clreq: fd=%d, avma=%#lx, total_size=%lu, "
sewardj54c45db2012-07-13 12:58:55 +00001063 "bias=%#lx\n",
1064 fd_obj, avma_obj, total_size, bias_obj
sewardjc8259b82009-04-22 22:42:10 +00001065 );
1066 }
1067
1068 /* 'fd' refers to the .exe/.dll we're dealing with. Get its modification
1069 time into obj_mtime. */
1070 r = VG_(fstat)(fd_obj, &stat_buf);
1071 if (r == -1)
1072 goto out; /* stat failed ?! */
1073 vg_assert(r == 0);
njn9c20ece2009-05-20 02:02:30 +00001074 obj_mtime = stat_buf.mtime;
sewardjc8259b82009-04-22 22:42:10 +00001075
1076 /* and get its name into exename[]. */
1077 vg_assert(VKI_PATH_MAX > 100); /* to ensure /proc/self/fd/%d is safe */
1078 VG_(memset)(exename, 0, sizeof(exename));
1079 VG_(sprintf)(exename, "/proc/self/fd/%d", fd_obj);
1080 /* convert exename from a symlink to real name .. overwrites the
1081 old contents of the buffer. Ick. */
1082 sz_exename = VG_(readlink)(exename, exename, sizeof(exename)-2 );
1083 if (sz_exename == -1)
1084 goto out; /* readlink failed ?! */
1085 vg_assert(sz_exename >= 0 && sz_exename < sizeof(exename));
1086 vg_assert(exename[sizeof(exename)-1] == 0);
1087
1088 if (VG_(clo_verbosity) > 0) {
sewardj738856f2009-07-15 14:48:32 +00001089 VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: objname: %s\n", exename);
sewardjc8259b82009-04-22 22:42:10 +00001090 }
1091
sewardj13ac96d2010-02-12 12:12:39 +00001092 /* Try to get the PDB file name from the executable. */
1093 pdbname = ML_(find_name_of_pdb_file)(exename);
1094 if (pdbname) {
1095 vg_assert(VG_(strlen)(pdbname) >= 5); /* 5 = strlen("X.pdb") */
1096 /* So we successfully extracted a name from the PE file. But it's
1097 likely to be of the form
1098 e:\foo\bar\xyzzy\wibble.pdb
1099 and we need to change it into something we can actually open
1100 in Wine-world, which basically means turning it into
1101 $HOME/.wine/drive_e/foo/bar/xyzzy/wibble.pdb
1102 We also take into account $WINEPREFIX, if it is set.
1103 For the moment, if the name isn't fully qualified, just forget it
1104 (we'd have to root around to find where the pdb actually is)
1105 */
1106 /* Change all the backslashes to forward slashes */
1107 for (i = 0; pdbname[i]; i++) {
1108 if (pdbname[i] == '\\')
1109 pdbname[i] = '/';
1110 }
1111 Bool is_quald
1112 = ('a' <= VG_(tolower)(pdbname[0]) && VG_(tolower)(pdbname[0]) <= 'z')
1113 && pdbname[1] == ':'
1114 && pdbname[2] == '/';
1115 HChar* home = VG_(getenv)("HOME");
1116 HChar* wpfx = VG_(getenv)("WINEPREFIX");
1117 if (is_quald && wpfx) {
1118 /* Change e:/foo/bar/xyzzy/wibble.pdb
1119 to $WINEPREFIX/drive_e/foo/bar/xyzzy/wibble.pdb
1120 */
1121 Int mashedSzB = VG_(strlen)(pdbname) + VG_(strlen)(wpfx) + 50/*misc*/;
1122 HChar* mashed = ML_(dinfo_zalloc)("di.debuginfo.dnpdi.1", mashedSzB);
bart98500e22011-10-28 15:05:50 +00001123 VG_(snprintf)(mashed, mashedSzB, "%s/drive_%c%s",
1124 wpfx, pdbname[0], &pdbname[2]);
sewardj13ac96d2010-02-12 12:12:39 +00001125 vg_assert(mashed[mashedSzB-1] == 0);
1126 ML_(dinfo_free)(pdbname);
1127 pdbname = mashed;
1128 }
1129 else if (is_quald && home && !wpfx) {
1130 /* Change e:/foo/bar/xyzzy/wibble.pdb
1131 to $HOME/.wine/drive_e/foo/bar/xyzzy/wibble.pdb
1132 */
1133 Int mashedSzB = VG_(strlen)(pdbname) + VG_(strlen)(home) + 50/*misc*/;
1134 HChar* mashed = ML_(dinfo_zalloc)("di.debuginfo.dnpdi.2", mashedSzB);
bart98500e22011-10-28 15:05:50 +00001135 VG_(snprintf)(mashed, mashedSzB, "%s/.wine/drive_%c%s",
1136 home, pdbname[0], &pdbname[2]);
sewardj13ac96d2010-02-12 12:12:39 +00001137 vg_assert(mashed[mashedSzB-1] == 0);
1138 ML_(dinfo_free)(pdbname);
1139 pdbname = mashed;
1140 } else {
1141 /* It's not a fully qualified path, or neither $HOME nor $WINE
1142 are set (strange). Give up. */
1143 ML_(dinfo_free)(pdbname);
1144 pdbname = NULL;
1145 }
1146 }
sewardjc8259b82009-04-22 22:42:10 +00001147
sewardj13ac96d2010-02-12 12:12:39 +00001148 /* Try s/exe/pdb/ if we don't have a valid pdbname. */
1149 if (!pdbname) {
1150 /* Try to find a matching PDB file from which to read debuginfo.
1151 Windows PE files have symbol tables and line number information,
1152 but MSVC doesn't seem to use them. */
1153 /* Why +5 ? Because in the worst case, we could find a dot as the
1154 last character of pdbname, and we'd then put "pdb" right after
1155 it, hence extending it a bit. */
1156 pdbname = ML_(dinfo_zalloc)("di.debuginfo.lpd1", sz_exename+5);
1157 VG_(strcpy)(pdbname, exename);
1158 vg_assert(pdbname[sz_exename+5-1] == 0);
1159 dot = VG_(strrchr)(pdbname, '.');
1160 if (!dot)
1161 goto out; /* there's no dot in the exe's name ?! */
1162 if (dot[1] == 0)
1163 goto out; /* hmm, path ends in "." */
sewardjc8259b82009-04-22 22:42:10 +00001164
sewardj13ac96d2010-02-12 12:12:39 +00001165 if ('A' <= dot[1] && dot[1] <= 'Z')
1166 VG_(strcpy)(dot, ".PDB");
1167 else
1168 VG_(strcpy)(dot, ".pdb");
1169
1170 vg_assert(pdbname[sz_exename+5-1] == 0);
1171 }
sewardjc8259b82009-04-22 22:42:10 +00001172
1173 /* See if we can find it, and check it's in-dateness. */
1174 sres = VG_(stat)(pdbname, &stat_buf);
njncda2f0f2009-05-18 02:12:08 +00001175 if (sr_isError(sres)) {
sewardj738856f2009-07-15 14:48:32 +00001176 VG_(message)(Vg_UserMsg, "Warning: Missing or un-stat-able %s\n",
sewardjc8259b82009-04-22 22:42:10 +00001177 pdbname);
1178 if (VG_(clo_verbosity) > 0)
sewardj738856f2009-07-15 14:48:32 +00001179 VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: missing: %s\n", pdbname);
sewardjc8259b82009-04-22 22:42:10 +00001180 goto out;
1181 }
njn9c20ece2009-05-20 02:02:30 +00001182 pdb_mtime = stat_buf.mtime;
sewardj7138ef02010-01-29 22:37:02 +00001183
sewardjced85062010-02-10 13:37:37 +00001184 if (obj_mtime > pdb_mtime + 60ULL) {
sewardj7138ef02010-01-29 22:37:02 +00001185 /* PDB file is older than PE file. Really, the PDB should be
1186 newer than the PE, but that doesn't always seem to be the
1187 case. Allow the PDB to be up to one minute older.
1188 Otherwise, it's probably out of date, in which case ignore it
1189 or we will either (a) print wrong stack traces or more likely
1190 (b) crash.
1191 */
sewardj738856f2009-07-15 14:48:32 +00001192 VG_(message)(Vg_UserMsg,
sewardjced85062010-02-10 13:37:37 +00001193 "Warning: %s (mtime = %llu)\n"
1194 " is older than %s (mtime = %llu)\n",
1195 pdbname, pdb_mtime, exename, obj_mtime);
sewardjc8259b82009-04-22 22:42:10 +00001196 }
1197
1198 sres = VG_(open)(pdbname, VKI_O_RDONLY, 0);
njncda2f0f2009-05-18 02:12:08 +00001199 if (sr_isError(sres)) {
sewardj738856f2009-07-15 14:48:32 +00001200 VG_(message)(Vg_UserMsg, "Warning: Can't open %s\n", pdbname);
sewardjc8259b82009-04-22 22:42:10 +00001201 goto out;
1202 }
1203
sewardjcd458d22010-12-06 11:11:29 +00001204 /* Looks promising; go on to try and read stuff from it. But don't
1205 mmap the file. Instead mmap free space and read the file into
1206 it. This is because files on CIFS filesystems that are mounted
1207 '-o directio' can't be mmap'd, and that mount option is needed
1208 to make CIFS work reliably. (See
1209 http://www.nabble.com/Corrupted-data-on-write-to-
1210 Windows-2003-Server-t2782623.html)
1211 This is slower, but at least it works reliably. */
njncda2f0f2009-05-18 02:12:08 +00001212 fd_pdbimage = sr_Res(sres);
njn9c20ece2009-05-20 02:02:30 +00001213 n_pdbimage = stat_buf.size;
sewardjcd458d22010-12-06 11:11:29 +00001214 if (n_pdbimage == 0 || n_pdbimage > 0x7FFFFFFF) {
1215 // 0x7FFFFFFF: why? Because the VG_(read) just below only
1216 // can deal with a signed int as the size of data to read,
1217 // so we can't reliably check for read failure for files
1218 // greater than that size. Hence just skip them; we're
1219 // unlikely to encounter a PDB that large anyway.
1220 VG_(close)(fd_pdbimage);
1221 goto out;
1222 }
1223 sres = VG_(am_mmap_anon_float_valgrind)( n_pdbimage );
njncda2f0f2009-05-18 02:12:08 +00001224 if (sr_isError(sres)) {
sewardjc8259b82009-04-22 22:42:10 +00001225 VG_(close)(fd_pdbimage);
1226 goto out;
1227 }
1228
sewardjcd458d22010-12-06 11:11:29 +00001229 void* pdbimage = (void*)sr_Res(sres);
1230 r = VG_(read)( fd_pdbimage, pdbimage, (Int)n_pdbimage );
1231 if (r < 0 || r != (Int)n_pdbimage) {
1232 VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage );
1233 VG_(close)(fd_pdbimage);
1234 goto out;
1235 }
1236
sewardjc8259b82009-04-22 22:42:10 +00001237 if (VG_(clo_verbosity) > 0)
sewardj738856f2009-07-15 14:48:32 +00001238 VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: pdbname: %s\n", pdbname);
sewardjc8259b82009-04-22 22:42:10 +00001239
1240 /* play safe; always invalidate the CFI cache. I don't know if
1241 this is necessary, but anyway .. */
1242 cfsi_cache__invalidate();
1243 /* dump old info for this range, if any */
1244 discard_syms_in_range( avma_obj, total_size );
1245
sewardj0f4126c2011-09-20 16:10:59 +00001246 { DebugInfo* di = find_or_create_DebugInfo_for(exename);
sewardjc8259b82009-04-22 22:42:10 +00001247
1248 /* this di must be new, since we just nuked any old stuff in the range */
sewardja5acac32011-09-20 21:59:50 +00001249 vg_assert(di && !di->fsm.have_rx_map && !di->fsm.have_rw_map);
sewardjc8259b82009-04-22 22:42:10 +00001250 vg_assert(!di->have_dinfo);
1251
1252 /* don't set up any of the di-> fields; let
1253 ML_(read_pdb_debug_info) do it. */
sewardj54c45db2012-07-13 12:58:55 +00001254 ML_(read_pdb_debug_info)( di, avma_obj, bias_obj,
sewardjc8259b82009-04-22 22:42:10 +00001255 pdbimage, n_pdbimage, pdbname, pdb_mtime );
1256 // JRS fixme: take notice of return value from read_pdb_debug_info,
1257 // and handle failure
1258 vg_assert(di->have_dinfo); // fails if PDB read failed
1259 VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage );
1260 VG_(close)(fd_pdbimage);
sewardjcd458d22010-12-06 11:11:29 +00001261
1262 if (VG_(clo_verbosity) > 0) {
1263 VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: done: "
1264 "%lu syms, %lu src locs, %lu fpo recs\n",
1265 di->symtab_used, di->loctab_used, di->fpo_size);
1266 }
sewardjc8259b82009-04-22 22:42:10 +00001267 }
1268
1269 out:
1270 if (pdbname) ML_(dinfo_free)(pdbname);
1271}
1272
njn8b68b642009-06-24 00:37:09 +00001273#endif /* defined(VGO_linux) || defined(VGO_darwin) */
sewardj4ee4f982006-10-17 01:37:10 +00001274
1275
sewardjeadcd862006-04-04 15:12:44 +00001276/*------------------------------------------------------------*/
1277/*--- ---*/
1278/*--- TOP LEVEL: QUERYING EXISTING DEBUG INFO ---*/
1279/*--- ---*/
1280/*------------------------------------------------------------*/
1281
sewardj9c606bd2008-09-18 18:12:50 +00001282void VG_(di_discard_ALL_debuginfo)( void )
1283{
1284 DebugInfo *di, *di2;
1285 di = debugInfo_list;
1286 while (di) {
1287 di2 = di->next;
1288 VG_(printf)("XXX rm %p\n", di);
1289 free_DebugInfo( di );
1290 di = di2;
1291 }
1292}
1293
1294
sewardj6b5625b2012-07-13 11:24:05 +00001295struct _DebugInfoMapping* ML_(find_rx_mapping) ( struct _DebugInfo* di,
1296 Addr lo, Addr hi )
1297{
1298 Word i;
1299 vg_assert(lo <= hi);
1300
1301 /* Optimization: Try to use the last matched rx mapping first */
1302 if ( di->last_rx_map
1303 && lo >= di->last_rx_map->avma
1304 && hi < di->last_rx_map->avma + di->last_rx_map->size)
1305 return di->last_rx_map;
1306
1307 for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
1308 struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
1309 if ( map->rx && map->size > 0
1310 && lo >= map->avma && hi < map->avma + map->size) {
1311 di->last_rx_map = map;
1312 return map;
1313 }
1314 }
1315
1316 return NULL;
1317}
1318
1319
sewardjeadcd862006-04-04 15:12:44 +00001320/*------------------------------------------------------------*/
1321/*--- Use of symbol table & location info to create ---*/
1322/*--- plausible-looking stack dumps. ---*/
1323/*------------------------------------------------------------*/
1324
1325/* Search all symtabs that we know about to locate ptr. If found, set
sewardjb8b79ad2008-03-03 01:35:41 +00001326 *pdi to the relevant DebugInfo, and *symno to the symtab entry
1327 *number within that. If not found, *psi is set to NULL.
1328 If findText==True, only text symbols are searched for.
1329 If findText==False, only data symbols are searched for.
1330*/
1331static void search_all_symtabs ( Addr ptr, /*OUT*/DebugInfo** pdi,
sewardjf98e1c02008-10-25 16:22:41 +00001332 /*OUT*/Word* symno,
sewardjb8b79ad2008-03-03 01:35:41 +00001333 Bool match_anywhere_in_sym,
1334 Bool findText )
sewardjeadcd862006-04-04 15:12:44 +00001335{
sewardjf98e1c02008-10-25 16:22:41 +00001336 Word sno;
sewardjb8b79ad2008-03-03 01:35:41 +00001337 DebugInfo* di;
1338 Bool inRange;
sewardjeadcd862006-04-04 15:12:44 +00001339
sewardjb8b79ad2008-03-03 01:35:41 +00001340 for (di = debugInfo_list; di != NULL; di = di->next) {
1341
1342 if (findText) {
sewardj51c9d372010-04-12 20:56:56 +00001343 /* Consider any symbol in the r-x mapped area to be text.
1344 See Comment_Regarding_Text_Range_Checks in storage.c for
1345 details. */
sewardja5acac32011-09-20 21:59:50 +00001346 inRange = di->fsm.have_rx_map
sewardj6b5625b2012-07-13 11:24:05 +00001347 && (ML_(find_rx_mapping)(di, ptr, ptr) != NULL);
sewardjb8b79ad2008-03-03 01:35:41 +00001348 } else {
1349 inRange = (di->data_present
1350 && di->data_size > 0
1351 && di->data_avma <= ptr
1352 && ptr < di->data_avma + di->data_size)
1353 ||
1354 (di->sdata_present
1355 && di->sdata_size > 0
1356 && di->sdata_avma <= ptr
1357 && ptr < di->sdata_avma + di->sdata_size)
1358 ||
1359 (di->bss_present
1360 && di->bss_size > 0
1361 && di->bss_avma <= ptr
sewardj5706ca92009-01-22 21:18:15 +00001362 && ptr < di->bss_avma + di->bss_size)
1363 ||
1364 (di->sbss_present
1365 && di->sbss_size > 0
1366 && di->sbss_avma <= ptr
1367 && ptr < di->sbss_avma + di->sbss_size)
1368 ||
1369 (di->rodata_present
1370 && di->rodata_size > 0
1371 && di->rodata_avma <= ptr
1372 && ptr < di->rodata_avma + di->rodata_size);
sewardjeadcd862006-04-04 15:12:44 +00001373 }
sewardjb8b79ad2008-03-03 01:35:41 +00001374
1375 if (!inRange) continue;
1376
1377 sno = ML_(search_one_symtab) (
1378 di, ptr, match_anywhere_in_sym, findText );
1379 if (sno == -1) goto not_found;
1380 *symno = sno;
1381 *pdi = di;
1382 return;
1383
sewardjeadcd862006-04-04 15:12:44 +00001384 }
1385 not_found:
sewardjb8b79ad2008-03-03 01:35:41 +00001386 *pdi = NULL;
sewardjeadcd862006-04-04 15:12:44 +00001387}
1388
1389
1390/* Search all loctabs that we know about to locate ptr. If found, set
sewardjb8b79ad2008-03-03 01:35:41 +00001391 *pdi to the relevant DebugInfo, and *locno to the loctab entry
1392 *number within that. If not found, *pdi is set to NULL. */
1393static void search_all_loctabs ( Addr ptr, /*OUT*/DebugInfo** pdi,
sewardjf98e1c02008-10-25 16:22:41 +00001394 /*OUT*/Word* locno )
sewardjeadcd862006-04-04 15:12:44 +00001395{
sewardjf98e1c02008-10-25 16:22:41 +00001396 Word lno;
sewardjb8b79ad2008-03-03 01:35:41 +00001397 DebugInfo* di;
1398 for (di = debugInfo_list; di != NULL; di = di->next) {
1399 if (di->text_present
sewardj5706ca92009-01-22 21:18:15 +00001400 && di->text_size > 0
sewardjb8b79ad2008-03-03 01:35:41 +00001401 && di->text_avma <= ptr
1402 && ptr < di->text_avma + di->text_size) {
1403 lno = ML_(search_one_loctab) ( di, ptr );
sewardjeadcd862006-04-04 15:12:44 +00001404 if (lno == -1) goto not_found;
1405 *locno = lno;
sewardjb8b79ad2008-03-03 01:35:41 +00001406 *pdi = di;
sewardjeadcd862006-04-04 15:12:44 +00001407 return;
1408 }
1409 }
1410 not_found:
sewardjb8b79ad2008-03-03 01:35:41 +00001411 *pdi = NULL;
sewardjeadcd862006-04-04 15:12:44 +00001412}
1413
1414
1415/* The whole point of this whole big deal: map a code address to a
1416 plausible symbol name. Returns False if no idea; otherwise True.
njn6b7611b2009-02-11 06:06:10 +00001417 Caller supplies buf and nbuf. If do_cxx_demangling is False, don't do
1418 C++ demangling, regardless of VG_(clo_demangle) -- probably because the
1419 call has come from VG_(get_fnname_raw)(). findText
sewardjb8b79ad2008-03-03 01:35:41 +00001420 indicates whether we're looking for a text symbol or a data symbol
1421 -- caller must choose one kind or the other. */
sewardjeadcd862006-04-04 15:12:44 +00001422static
njn6b7611b2009-02-11 06:06:10 +00001423Bool get_sym_name ( Bool do_cxx_demangling, Bool do_z_demangling,
1424 Bool do_below_main_renaming,
florian1636d332012-11-15 04:27:04 +00001425 Addr a, HChar* buf, Int nbuf,
sewardjb8b79ad2008-03-03 01:35:41 +00001426 Bool match_anywhere_in_sym, Bool show_offset,
njnc4431bf2009-01-15 21:29:24 +00001427 Bool findText, /*OUT*/PtrdiffT* offsetP )
sewardjeadcd862006-04-04 15:12:44 +00001428{
sewardjb8b79ad2008-03-03 01:35:41 +00001429 DebugInfo* di;
sewardjf98e1c02008-10-25 16:22:41 +00001430 Word sno;
njnc4431bf2009-01-15 21:29:24 +00001431 PtrdiffT offset;
sewardjeadcd862006-04-04 15:12:44 +00001432
sewardjb8b79ad2008-03-03 01:35:41 +00001433 search_all_symtabs ( a, &di, &sno, match_anywhere_in_sym, findText );
1434 if (di == NULL)
sewardjeadcd862006-04-04 15:12:44 +00001435 return False;
njn68824432009-02-10 06:48:00 +00001436
sewardja5cace02011-08-15 09:42:34 +00001437 vg_assert(di->symtab[sno].pri_name);
njn6b7611b2009-02-11 06:06:10 +00001438 VG_(demangle) ( do_cxx_demangling, do_z_demangling,
sewardja5cace02011-08-15 09:42:34 +00001439 di->symtab[sno].pri_name, buf, nbuf );
njn6b7611b2009-02-11 06:06:10 +00001440
1441 /* Do the below-main hack */
1442 // To reduce the endless nuisance of multiple different names
1443 // for "the frame below main()" screwing up the testsuite, change all
1444 // known incarnations of said into a single name, "(below main)", if
1445 // --show-below-main=yes.
1446 if ( do_below_main_renaming && ! VG_(clo_show_below_main) &&
1447 Vg_FnNameBelowMain == VG_(get_fnname_kind)(buf) )
1448 {
1449 VG_(strncpy_safely)(buf, "(below main)", nbuf);
sewardjeadcd862006-04-04 15:12:44 +00001450 }
sewardjb8b79ad2008-03-03 01:35:41 +00001451 offset = a - di->symtab[sno].addr;
njnc4431bf2009-01-15 21:29:24 +00001452 if (offsetP) *offsetP = offset;
sewardjb8b79ad2008-03-03 01:35:41 +00001453
sewardjeadcd862006-04-04 15:12:44 +00001454 if (show_offset && offset != 0) {
florian1636d332012-11-15 04:27:04 +00001455 HChar buf2[12];
1456 HChar* symend = buf + VG_(strlen)(buf);
1457 HChar* end = buf + nbuf;
sewardjeadcd862006-04-04 15:12:44 +00001458 Int len;
1459
njnc4431bf2009-01-15 21:29:24 +00001460 len = VG_(sprintf)(buf2, "%c%ld",
sewardjeadcd862006-04-04 15:12:44 +00001461 offset < 0 ? '-' : '+',
1462 offset < 0 ? -offset : offset);
1463 vg_assert(len < (Int)sizeof(buf2));
1464
1465 if (len < (end - symend)) {
florian1636d332012-11-15 04:27:04 +00001466 HChar *cp = buf2;
sewardjeadcd862006-04-04 15:12:44 +00001467 VG_(memcpy)(symend, cp, len+1);
1468 }
1469 }
1470
njn6b7611b2009-02-11 06:06:10 +00001471 buf[nbuf-1] = 0; /* paranoia */
1472
sewardjeadcd862006-04-04 15:12:44 +00001473 return True;
1474}
1475
1476/* ppc64-linux only: find the TOC pointer (R2 value) that should be in
1477 force at the entry point address of the function containing
1478 guest_code_addr. Returns 0 if not known. */
1479Addr VG_(get_tocptr) ( Addr guest_code_addr )
1480{
sewardjb8b79ad2008-03-03 01:35:41 +00001481 DebugInfo* si;
sewardjf98e1c02008-10-25 16:22:41 +00001482 Word sno;
sewardjeadcd862006-04-04 15:12:44 +00001483 search_all_symtabs ( guest_code_addr,
sewardjb8b79ad2008-03-03 01:35:41 +00001484 &si, &sno,
1485 True/*match_anywhere_in_fun*/,
1486 True/*consider text symbols only*/ );
sewardjeadcd862006-04-04 15:12:44 +00001487 if (si == NULL)
1488 return 0;
1489 else
1490 return si->symtab[sno].tocptr;
1491}
1492
1493/* This is available to tools... always demangle C++ names,
1494 match anywhere in function, but don't show offsets. */
florian1636d332012-11-15 04:27:04 +00001495Bool VG_(get_fnname) ( Addr a, HChar* buf, Int nbuf )
sewardjeadcd862006-04-04 15:12:44 +00001496{
njn6b7611b2009-02-11 06:06:10 +00001497 return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True,
1498 /*below-main-renaming*/True,
1499 a, buf, nbuf,
sewardjb8b79ad2008-03-03 01:35:41 +00001500 /*match_anywhere_in_fun*/True,
1501 /*show offset?*/False,
1502 /*text syms only*/True,
1503 /*offsetP*/NULL );
sewardjeadcd862006-04-04 15:12:44 +00001504}
1505
1506/* This is available to tools... always demangle C++ names,
1507 match anywhere in function, and show offset if nonzero. */
florian1636d332012-11-15 04:27:04 +00001508Bool VG_(get_fnname_w_offset) ( Addr a, HChar* buf, Int nbuf )
sewardjeadcd862006-04-04 15:12:44 +00001509{
njn6b7611b2009-02-11 06:06:10 +00001510 return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True,
1511 /*below-main-renaming*/True,
1512 a, buf, nbuf,
sewardjb8b79ad2008-03-03 01:35:41 +00001513 /*match_anywhere_in_fun*/True,
1514 /*show offset?*/True,
1515 /*text syms only*/True,
1516 /*offsetP*/NULL );
sewardjeadcd862006-04-04 15:12:44 +00001517}
1518
1519/* This is available to tools... always demangle C++ names,
1520 only succeed if 'a' matches first instruction of function,
1521 and don't show offsets. */
florian1636d332012-11-15 04:27:04 +00001522Bool VG_(get_fnname_if_entry) ( Addr a, HChar* buf, Int nbuf )
sewardjeadcd862006-04-04 15:12:44 +00001523{
njn6b7611b2009-02-11 06:06:10 +00001524 return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True,
1525 /*below-main-renaming*/True,
1526 a, buf, nbuf,
sewardjb8b79ad2008-03-03 01:35:41 +00001527 /*match_anywhere_in_fun*/False,
1528 /*show offset?*/False,
1529 /*text syms only*/True,
1530 /*offsetP*/NULL );
sewardjeadcd862006-04-04 15:12:44 +00001531}
1532
njn6b7611b2009-02-11 06:06:10 +00001533/* This is only available to core... don't C++-demangle, don't Z-demangle,
1534 don't rename below-main, match anywhere in function, and don't show
1535 offsets. */
florian1636d332012-11-15 04:27:04 +00001536Bool VG_(get_fnname_raw) ( Addr a, HChar* buf, Int nbuf )
sewardjeadcd862006-04-04 15:12:44 +00001537{
njn6b7611b2009-02-11 06:06:10 +00001538 return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False,
1539 /*below-main-renaming*/False,
1540 a, buf, nbuf,
sewardjb8b79ad2008-03-03 01:35:41 +00001541 /*match_anywhere_in_fun*/True,
1542 /*show offset?*/False,
1543 /*text syms only*/True,
1544 /*offsetP*/NULL );
sewardjeadcd862006-04-04 15:12:44 +00001545}
1546
1547/* This is only available to core... don't demangle C++ names, but do
njn6b7611b2009-02-11 06:06:10 +00001548 do Z-demangling and below-main-renaming, match anywhere in function, and
1549 don't show offsets. */
florian1636d332012-11-15 04:27:04 +00001550Bool VG_(get_fnname_no_cxx_demangle) ( Addr a, HChar* buf, Int nbuf )
sewardjeadcd862006-04-04 15:12:44 +00001551{
njn6b7611b2009-02-11 06:06:10 +00001552 return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/True,
1553 /*below-main-renaming*/True,
1554 a, buf, nbuf,
1555 /*match_anywhere_in_fun*/True,
1556 /*show offset?*/False,
1557 /*text syms only*/True,
1558 /*offsetP*/NULL );
sewardjeadcd862006-04-04 15:12:44 +00001559}
1560
sewardj5db15402012-06-07 09:13:21 +00001561/* mips-linux only: find the offset of current address. This is needed for
1562 stack unwinding for MIPS.
1563*/
1564Bool VG_(get_inst_offset_in_function)( Addr a,
1565 /*OUT*/PtrdiffT* offset )
1566{
florian1636d332012-11-15 04:27:04 +00001567 HChar fnname[64];
sewardj5db15402012-06-07 09:13:21 +00001568 return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False,
1569 /*below-main-renaming*/False,
1570 a, fnname, 64,
1571 /*match_anywhere_in_sym*/True,
1572 /*show offset?*/True,
1573 /*data syms only please*/True,
1574 offset );
1575}
1576
florian1636d332012-11-15 04:27:04 +00001577Vg_FnNameKind VG_(get_fnname_kind) ( HChar* name )
njn68824432009-02-10 06:48:00 +00001578{
1579 if (VG_STREQ("main", name)) {
1580 return Vg_FnNameMain;
1581
1582 } else if (
sewardj3026f712010-01-01 18:46:41 +00001583# if defined(VGO_linux)
njn68824432009-02-10 06:48:00 +00001584 VG_STREQ("__libc_start_main", name) || // glibc glibness
1585 VG_STREQ("generic_start_main", name) || // Yellow Dog doggedness
sewardj3026f712010-01-01 18:46:41 +00001586# elif defined(VGO_darwin)
njnf76d27a2009-05-28 01:53:07 +00001587 // See readmacho.c for an explanation of this.
1588 VG_STREQ("start_according_to_valgrind", name) || // Darwin, darling
sewardj3026f712010-01-01 18:46:41 +00001589# else
1590# error "Unknown OS"
1591# endif
njn68824432009-02-10 06:48:00 +00001592 0) {
1593 return Vg_FnNameBelowMain;
1594
1595 } else {
1596 return Vg_FnNameNormal;
1597 }
1598}
1599
1600Vg_FnNameKind VG_(get_fnname_kind_from_IP) ( Addr ip )
1601{
1602 // We don't need a big buffer; all the special names are small.
1603 #define BUFLEN 50
florian1636d332012-11-15 04:27:04 +00001604 HChar buf[50];
njn68824432009-02-10 06:48:00 +00001605
1606 // We don't demangle, because it's faster not to, and the special names
1607 // we're looking for won't be demangled.
njn6b7611b2009-02-11 06:06:10 +00001608 if (VG_(get_fnname_raw) ( ip, buf, BUFLEN )) {
njn68824432009-02-10 06:48:00 +00001609 buf[BUFLEN-1] = '\0'; // paranoia
1610 return VG_(get_fnname_kind)(buf);
1611 } else {
1612 return Vg_FnNameNormal; // Don't know the name, treat it as normal.
1613 }
1614}
1615
sewardjb8b79ad2008-03-03 01:35:41 +00001616/* Looks up data_addr in the collection of data symbols, and if found
1617 puts its name (or as much as will fit) into dname[0 .. n_dname-1],
1618 which is guaranteed to be zero terminated. Also data_addr's offset
1619 from the symbol start is put into *offset. */
1620Bool VG_(get_datasym_and_offset)( Addr data_addr,
florian1636d332012-11-15 04:27:04 +00001621 /*OUT*/HChar* dname, Int n_dname,
njnc4431bf2009-01-15 21:29:24 +00001622 /*OUT*/PtrdiffT* offset )
sewardjb8b79ad2008-03-03 01:35:41 +00001623{
1624 Bool ok;
1625 vg_assert(n_dname > 1);
njn6b7611b2009-02-11 06:06:10 +00001626 ok = get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False,
1627 /*below-main-renaming*/False,
1628 data_addr, dname, n_dname,
sewardjb8b79ad2008-03-03 01:35:41 +00001629 /*match_anywhere_in_sym*/True,
1630 /*show offset?*/False,
1631 /*data syms only please*/False,
1632 offset );
1633 if (!ok)
1634 return False;
1635 dname[n_dname-1] = 0;
1636 return True;
1637}
1638
1639/* Map a code address to the name of a shared object file or the
1640 executable. Returns False if no idea; otherwise True. Doesn't
1641 require debug info. Caller supplies buf and nbuf. */
florian1636d332012-11-15 04:27:04 +00001642Bool VG_(get_objname) ( Addr a, HChar* buf, Int nbuf )
sewardjeadcd862006-04-04 15:12:44 +00001643{
sewardjb8b79ad2008-03-03 01:35:41 +00001644 DebugInfo* di;
tomf32ec7f2008-01-08 17:44:04 +00001645 const NSegment *seg;
1646 HChar* filename;
sewardj4ee4f982006-10-17 01:37:10 +00001647 vg_assert(nbuf > 0);
sewardj7cf4e6b2008-05-01 20:24:26 +00001648 /* Look in the debugInfo_list to find the name. In most cases we
1649 expect this to produce a result. */
sewardjb8b79ad2008-03-03 01:35:41 +00001650 for (di = debugInfo_list; di != NULL; di = di->next) {
1651 if (di->text_present
sewardj5706ca92009-01-22 21:18:15 +00001652 && di->text_size > 0
sewardjb8b79ad2008-03-03 01:35:41 +00001653 && di->text_avma <= a
1654 && a < di->text_avma + di->text_size) {
sewardja5acac32011-09-20 21:59:50 +00001655 VG_(strncpy_safely)(buf, di->fsm.filename, nbuf);
sewardj4ee4f982006-10-17 01:37:10 +00001656 buf[nbuf-1] = 0;
sewardjeadcd862006-04-04 15:12:44 +00001657 return True;
1658 }
1659 }
sewardj7cf4e6b2008-05-01 20:24:26 +00001660 /* Last-ditch fallback position: if we don't find the address in
1661 the debugInfo_list, ask the address space manager whether it
1662 knows the name of the file associated with this mapping. This
1663 allows us to print the names of exe/dll files in the stack trace
1664 when running programs under wine. */
1665 if ( (seg = VG_(am_find_nsegment(a))) != NULL
1666 && (filename = VG_(am_get_filename)(seg)) != NULL ) {
tomf32ec7f2008-01-08 17:44:04 +00001667 VG_(strncpy_safely)(buf, filename, nbuf);
1668 return True;
1669 }
sewardjeadcd862006-04-04 15:12:44 +00001670 return False;
1671}
1672
sewardjb8b79ad2008-03-03 01:35:41 +00001673/* Map a code address to its DebugInfo. Returns NULL if not found. Doesn't
sewardjeadcd862006-04-04 15:12:44 +00001674 require debug info. */
sewardje3f1e592009-07-31 09:41:29 +00001675DebugInfo* VG_(find_DebugInfo) ( Addr a )
sewardjeadcd862006-04-04 15:12:44 +00001676{
sewardje3f1e592009-07-31 09:41:29 +00001677 static UWord n_search = 0;
sewardjb8b79ad2008-03-03 01:35:41 +00001678 DebugInfo* di;
sewardje3f1e592009-07-31 09:41:29 +00001679 n_search++;
sewardjb8b79ad2008-03-03 01:35:41 +00001680 for (di = debugInfo_list; di != NULL; di = di->next) {
1681 if (di->text_present
sewardj5706ca92009-01-22 21:18:15 +00001682 && di->text_size > 0
sewardjb8b79ad2008-03-03 01:35:41 +00001683 && di->text_avma <= a
1684 && a < di->text_avma + di->text_size) {
sewardje3f1e592009-07-31 09:41:29 +00001685 if (0 == (n_search & 0xF))
1686 move_DebugInfo_one_step_forward( di );
sewardjb8b79ad2008-03-03 01:35:41 +00001687 return di;
sewardjeadcd862006-04-04 15:12:44 +00001688 }
1689 }
1690 return NULL;
1691}
1692
1693/* Map a code address to a filename. Returns True if successful. */
florian1636d332012-11-15 04:27:04 +00001694Bool VG_(get_filename)( Addr a, HChar* filename, Int n_filename )
sewardjeadcd862006-04-04 15:12:44 +00001695{
sewardjb8b79ad2008-03-03 01:35:41 +00001696 DebugInfo* si;
sewardjf98e1c02008-10-25 16:22:41 +00001697 Word locno;
sewardjeadcd862006-04-04 15:12:44 +00001698 search_all_loctabs ( a, &si, &locno );
1699 if (si == NULL)
1700 return False;
1701 VG_(strncpy_safely)(filename, si->loctab[locno].filename, n_filename);
1702 return True;
1703}
1704
1705/* Map a code address to a line number. Returns True if successful. */
1706Bool VG_(get_linenum)( Addr a, UInt* lineno )
1707{
sewardjb8b79ad2008-03-03 01:35:41 +00001708 DebugInfo* si;
sewardjf98e1c02008-10-25 16:22:41 +00001709 Word locno;
sewardjeadcd862006-04-04 15:12:44 +00001710 search_all_loctabs ( a, &si, &locno );
1711 if (si == NULL)
1712 return False;
1713 *lineno = si->loctab[locno].lineno;
1714
1715 return True;
1716}
1717
1718/* Map a code address to a filename/line number/dir name info.
1719 See prototype for detailed description of behaviour.
1720*/
1721Bool VG_(get_filename_linenum) ( Addr a,
florian1636d332012-11-15 04:27:04 +00001722 /*OUT*/HChar* filename, Int n_filename,
1723 /*OUT*/HChar* dirname, Int n_dirname,
sewardjeadcd862006-04-04 15:12:44 +00001724 /*OUT*/Bool* dirname_available,
1725 /*OUT*/UInt* lineno )
1726{
sewardjb8b79ad2008-03-03 01:35:41 +00001727 DebugInfo* si;
sewardjf98e1c02008-10-25 16:22:41 +00001728 Word locno;
sewardjeadcd862006-04-04 15:12:44 +00001729
1730 vg_assert( (dirname == NULL && dirname_available == NULL)
1731 ||
1732 (dirname != NULL && dirname_available != NULL) );
1733
1734 search_all_loctabs ( a, &si, &locno );
njnc1b1d422007-04-19 23:35:42 +00001735 if (si == NULL) {
njndb5c6572007-04-20 02:15:28 +00001736 if (dirname_available) {
1737 *dirname_available = False;
1738 *dirname = 0;
1739 }
sewardjeadcd862006-04-04 15:12:44 +00001740 return False;
njnc1b1d422007-04-19 23:35:42 +00001741 }
1742
sewardjeadcd862006-04-04 15:12:44 +00001743 VG_(strncpy_safely)(filename, si->loctab[locno].filename, n_filename);
1744 *lineno = si->loctab[locno].lineno;
1745
1746 if (dirname) {
1747 /* caller wants directory info too .. */
1748 vg_assert(n_dirname > 0);
1749 if (si->loctab[locno].dirname) {
1750 /* .. and we have some */
1751 *dirname_available = True;
1752 VG_(strncpy_safely)(dirname, si->loctab[locno].dirname,
1753 n_dirname);
1754 } else {
1755 /* .. but we don't have any */
1756 *dirname_available = False;
1757 *dirname = 0;
1758 }
1759 }
1760
1761 return True;
1762}
1763
1764
sewardj4ee4f982006-10-17 01:37:10 +00001765/* Map a function name to its entry point and toc pointer. Is done by
1766 sequential search of all symbol tables, so is very slow. To
1767 mitigate the worst performance effects, you may specify a soname
1768 pattern, and only objects matching that pattern are searched.
1769 Therefore specify "*" to search all the objects. On TOC-afflicted
1770 platforms, a symbol is deemed to be found only if it has a nonzero
1771 TOC pointer. */
florian6bd9dc12012-11-23 16:17:43 +00001772Bool VG_(lookup_symbol_SLOW)(const HChar* sopatt, HChar* name,
sewardjb8b79ad2008-03-03 01:35:41 +00001773 Addr* pEnt, Addr* pToc)
sewardj4ee4f982006-10-17 01:37:10 +00001774{
1775 Bool require_pToc = False;
1776 Int i;
sewardjb8b79ad2008-03-03 01:35:41 +00001777 DebugInfo* si;
sewardj4ee4f982006-10-17 01:37:10 +00001778 Bool debug = False;
1779# if defined(VG_PLAT_USES_PPCTOC)
1780 require_pToc = True;
1781# endif
sewardjb8b79ad2008-03-03 01:35:41 +00001782 for (si = debugInfo_list; si; si = si->next) {
sewardj4ee4f982006-10-17 01:37:10 +00001783 if (debug)
1784 VG_(printf)("lookup_symbol_SLOW: considering %s\n", si->soname);
1785 if (!VG_(string_match)(sopatt, si->soname)) {
1786 if (debug)
1787 VG_(printf)(" ... skip\n");
1788 continue;
1789 }
1790 for (i = 0; i < si->symtab_used; i++) {
florian1636d332012-11-15 04:27:04 +00001791 HChar* pri_name = si->symtab[i].pri_name;
sewardja5cace02011-08-15 09:42:34 +00001792 tl_assert(pri_name);
1793 if (0==VG_(strcmp)(name, pri_name)
sewardj4ee4f982006-10-17 01:37:10 +00001794 && (require_pToc ? si->symtab[i].tocptr : True)) {
1795 *pEnt = si->symtab[i].addr;
1796 *pToc = si->symtab[i].tocptr;
1797 return True;
1798 }
florian1636d332012-11-15 04:27:04 +00001799 HChar** sec_names = si->symtab[i].sec_names;
sewardja5cace02011-08-15 09:42:34 +00001800 if (sec_names) {
1801 tl_assert(sec_names[0]);
1802 while (*sec_names) {
1803 if (0==VG_(strcmp)(name, *sec_names)
1804 && (require_pToc ? si->symtab[i].tocptr : True)) {
1805 *pEnt = si->symtab[i].addr;
1806 *pToc = si->symtab[i].tocptr;
1807 return True;
1808 }
1809 sec_names++;
1810 }
1811 }
sewardj4ee4f982006-10-17 01:37:10 +00001812 }
1813 }
1814 return False;
1815}
1816
1817
sewardje872fec2007-01-10 15:42:15 +00001818/* VG_(describe_IP): print into buf info on code address, function
1819 name and filename. */
1820
1821/* Copy str into buf starting at n, but not going past buf[n_buf-1]
1822 and always ensuring that buf is zero-terminated. */
sewardjeadcd862006-04-04 15:12:44 +00001823
florian1636d332012-11-15 04:27:04 +00001824static Int putStr ( Int n, Int n_buf, HChar* buf, const HChar* str )
sewardjeadcd862006-04-04 15:12:44 +00001825{
sewardje872fec2007-01-10 15:42:15 +00001826 vg_assert(n_buf > 0);
1827 vg_assert(n >= 0 && n < n_buf);
sewardjeadcd862006-04-04 15:12:44 +00001828 for (; n < n_buf-1 && *str != 0; n++,str++)
1829 buf[n] = *str;
sewardje872fec2007-01-10 15:42:15 +00001830 vg_assert(n >= 0 && n < n_buf);
sewardjeadcd862006-04-04 15:12:44 +00001831 buf[n] = '\0';
1832 return n;
1833}
sewardje872fec2007-01-10 15:42:15 +00001834
1835/* Same as putStr, but escaping chars for XML output, and
1836 also not adding more than count chars to n_buf. */
1837
florian1636d332012-11-15 04:27:04 +00001838static Int putStrEsc ( Int n, Int n_buf, Int count, HChar* buf, HChar* str )
sewardjeadcd862006-04-04 15:12:44 +00001839{
florian1636d332012-11-15 04:27:04 +00001840 HChar alt[2];
sewardje872fec2007-01-10 15:42:15 +00001841 vg_assert(n_buf > 0);
1842 vg_assert(count >= 0 && count < n_buf);
1843 vg_assert(n >= 0 && n < n_buf);
sewardjeadcd862006-04-04 15:12:44 +00001844 for (; *str != 0; str++) {
sewardje872fec2007-01-10 15:42:15 +00001845 vg_assert(count >= 0);
1846 if (count <= 0)
1847 goto done;
sewardjeadcd862006-04-04 15:12:44 +00001848 switch (*str) {
sewardje872fec2007-01-10 15:42:15 +00001849 case '&':
1850 if (count < 5) goto done;
1851 n = putStr( n, n_buf, buf, "&amp;");
1852 count -= 5;
1853 break;
1854 case '<':
1855 if (count < 4) goto done;
1856 n = putStr( n, n_buf, buf, "&lt;");
1857 count -= 4;
1858 break;
1859 case '>':
1860 if (count < 4) goto done;
1861 n = putStr( n, n_buf, buf, "&gt;");
1862 count -= 4;
1863 break;
1864 default:
1865 if (count < 1) goto done;
1866 alt[0] = *str;
1867 alt[1] = 0;
1868 n = putStr( n, n_buf, buf, alt );
1869 count -= 1;
1870 break;
sewardjeadcd862006-04-04 15:12:44 +00001871 }
1872 }
sewardje872fec2007-01-10 15:42:15 +00001873 done:
1874 vg_assert(count >= 0); /* should not go -ve in loop */
1875 vg_assert(n >= 0 && n < n_buf);
sewardjeadcd862006-04-04 15:12:44 +00001876 return n;
1877}
1878
florian1636d332012-11-15 04:27:04 +00001879HChar* VG_(describe_IP)(Addr eip, HChar* buf, Int n_buf)
sewardjeadcd862006-04-04 15:12:44 +00001880{
1881# define APPEND(_str) \
sewardje872fec2007-01-10 15:42:15 +00001882 n = putStr(n, n_buf, buf, _str)
1883# define APPEND_ESC(_count,_str) \
1884 n = putStrEsc(n, n_buf, (_count), buf, (_str))
sewardjeadcd862006-04-04 15:12:44 +00001885# define BUF_LEN 4096
1886
1887 UInt lineno;
florian1636d332012-11-15 04:27:04 +00001888 HChar ibuf[50];
sewardjeadcd862006-04-04 15:12:44 +00001889 Int n = 0;
sewardj14cdbf82010-10-12 00:44:05 +00001890
florian1636d332012-11-15 04:27:04 +00001891 static HChar buf_fn[BUF_LEN];
1892 static HChar buf_obj[BUF_LEN];
1893 static HChar buf_srcloc[BUF_LEN];
1894 static HChar buf_dirname[BUF_LEN];
sewardj14cdbf82010-10-12 00:44:05 +00001895 buf_fn[0] = buf_obj[0] = buf_srcloc[0] = buf_dirname[0] = 0;
1896
sewardjeadcd862006-04-04 15:12:44 +00001897 Bool know_dirinfo = False;
sewardj4ee4f982006-10-17 01:37:10 +00001898 Bool know_fnname = VG_(clo_sym_offsets)
1899 ? VG_(get_fnname_w_offset) (eip, buf_fn, BUF_LEN)
1900 : VG_(get_fnname) (eip, buf_fn, BUF_LEN);
sewardjeadcd862006-04-04 15:12:44 +00001901 Bool know_objname = VG_(get_objname)(eip, buf_obj, BUF_LEN);
1902 Bool know_srcloc = VG_(get_filename_linenum)(
1903 eip,
1904 buf_srcloc, BUF_LEN,
1905 buf_dirname, BUF_LEN, &know_dirinfo,
1906 &lineno
1907 );
sewardj14cdbf82010-10-12 00:44:05 +00001908 buf_fn [ sizeof(buf_fn)-1 ] = 0;
1909 buf_obj [ sizeof(buf_obj)-1 ] = 0;
1910 buf_srcloc [ sizeof(buf_srcloc)-1 ] = 0;
1911 buf_dirname[ sizeof(buf_dirname)-1 ] = 0;
1912
sewardjeadcd862006-04-04 15:12:44 +00001913 if (VG_(clo_xml)) {
1914
1915 Bool human_readable = True;
florian6bd9dc12012-11-23 16:17:43 +00001916 const HChar* maybe_newline = human_readable ? "\n " : "";
1917 const HChar* maybe_newline2 = human_readable ? "\n " : "";
sewardjeadcd862006-04-04 15:12:44 +00001918
sewardje872fec2007-01-10 15:42:15 +00001919 /* Print in XML format, dumping in as much info as we know.
1920 Ensure all tags are balanced even if the individual strings
1921 are too long. Allocate 1/10 of BUF_LEN to the object name,
1922 6/10s to the function name, 1/10 to the directory name and
1923 1/10 to the file name, leaving 1/10 for all the fixed-length
1924 stuff. */
sewardjeadcd862006-04-04 15:12:44 +00001925 APPEND("<frame>");
sewardja44b15f2007-02-16 14:10:24 +00001926 VG_(sprintf)(ibuf,"<ip>0x%llX</ip>", (ULong)eip);
sewardjeadcd862006-04-04 15:12:44 +00001927 APPEND(maybe_newline);
1928 APPEND(ibuf);
1929 if (know_objname) {
1930 APPEND(maybe_newline);
1931 APPEND("<obj>");
sewardje872fec2007-01-10 15:42:15 +00001932 APPEND_ESC(1*BUF_LEN/10, buf_obj);
sewardjeadcd862006-04-04 15:12:44 +00001933 APPEND("</obj>");
1934 }
1935 if (know_fnname) {
1936 APPEND(maybe_newline);
1937 APPEND("<fn>");
sewardje872fec2007-01-10 15:42:15 +00001938 APPEND_ESC(6*BUF_LEN/10, buf_fn);
sewardjeadcd862006-04-04 15:12:44 +00001939 APPEND("</fn>");
1940 }
1941 if (know_srcloc) {
1942 if (know_dirinfo) {
1943 APPEND(maybe_newline);
1944 APPEND("<dir>");
sewardje872fec2007-01-10 15:42:15 +00001945 APPEND_ESC(1*BUF_LEN/10, buf_dirname);
sewardjeadcd862006-04-04 15:12:44 +00001946 APPEND("</dir>");
1947 }
1948 APPEND(maybe_newline);
1949 APPEND("<file>");
sewardje872fec2007-01-10 15:42:15 +00001950 APPEND_ESC(1*BUF_LEN/10, buf_srcloc);
sewardjeadcd862006-04-04 15:12:44 +00001951 APPEND("</file>");
1952 APPEND(maybe_newline);
1953 APPEND("<line>");
1954 VG_(sprintf)(ibuf,"%d",lineno);
1955 APPEND(ibuf);
1956 APPEND("</line>");
1957 }
1958 APPEND(maybe_newline2);
1959 APPEND("</frame>");
1960
1961 } else {
1962
1963 /* Print for humans to read */
njn5e40aba2009-03-16 22:11:31 +00001964 //
1965 // Possible forms:
1966 //
1967 // 0x80483BF: really (a.c:20)
1968 // 0x80483BF: really (in /foo/a.out)
1969 // 0x80483BF: really (in ???)
1970 // 0x80483BF: ??? (in /foo/a.out)
1971 // 0x80483BF: ??? (a.c:20)
1972 // 0x80483BF: ???
1973 //
sewardja44b15f2007-02-16 14:10:24 +00001974 VG_(sprintf)(ibuf,"0x%llX: ", (ULong)eip);
sewardjeadcd862006-04-04 15:12:44 +00001975 APPEND(ibuf);
njn5e40aba2009-03-16 22:11:31 +00001976 if (know_fnname) {
sewardjeadcd862006-04-04 15:12:44 +00001977 APPEND(buf_fn);
sewardjeadcd862006-04-04 15:12:44 +00001978 } else {
1979 APPEND("???");
1980 }
1981 if (know_srcloc) {
1982 APPEND(" (");
sewardj14cdbf82010-10-12 00:44:05 +00001983 // Get the directory name, if any, possibly pruned, into dirname.
florian1636d332012-11-15 04:27:04 +00001984 HChar* dirname = NULL;
sewardj14cdbf82010-10-12 00:44:05 +00001985 if (VG_(clo_n_fullpath_after) > 0) {
1986 Int i;
1987 dirname = buf_dirname;
1988 // Remove leading prefixes from the dirname.
1989 // If user supplied --fullpath-after=foo, this will remove
1990 // a leading string which matches '.*foo' (not greedy).
1991 for (i = 0; i < VG_(clo_n_fullpath_after); i++) {
florian1636d332012-11-15 04:27:04 +00001992 const HChar* prefix = VG_(clo_fullpath_after)[i];
1993 HChar* str = VG_(strstr)(dirname, prefix);
sewardj14cdbf82010-10-12 00:44:05 +00001994 if (str) {
1995 dirname = str + VG_(strlen)(prefix);
1996 break;
1997 }
1998 }
1999 /* remove leading "./" */
2000 if (dirname[0] == '.' && dirname[1] == '/')
2001 dirname += 2;
2002 }
2003 // do we have any interesting directory name to show? If so
2004 // add it in.
2005 if (dirname && dirname[0] != 0) {
2006 APPEND(dirname);
2007 APPEND("/");
bart5dd01902010-08-31 15:18:32 +00002008 }
sewardjeadcd862006-04-04 15:12:44 +00002009 APPEND(buf_srcloc);
2010 APPEND(":");
2011 VG_(sprintf)(ibuf,"%d",lineno);
2012 APPEND(ibuf);
2013 APPEND(")");
njn5e40aba2009-03-16 22:11:31 +00002014 } else if (know_objname) {
2015 APPEND(" (in ");
2016 APPEND(buf_obj);
2017 APPEND(")");
2018 } else if (know_fnname) {
2019 // Nb: do this in two steps because "??)" is a trigraph!
2020 APPEND(" (in ???");
2021 APPEND(")");
sewardjeadcd862006-04-04 15:12:44 +00002022 }
2023
2024 }
2025 return buf;
2026
2027# undef APPEND
2028# undef APPEND_ESC
2029# undef BUF_LEN
2030}
2031
sewardj72427fa2007-02-27 16:52:23 +00002032
sewardjb8b79ad2008-03-03 01:35:41 +00002033/*--------------------------------------------------------------*/
2034/*--- ---*/
2035/*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/
2036/*--- DWARF3 .eh_frame INFO ---*/
2037/*--- ---*/
2038/*--------------------------------------------------------------*/
sewardj72427fa2007-02-27 16:52:23 +00002039
2040/* Gather up all the constant pieces of info needed to evaluate
2041 a CfiExpr into one convenient struct. */
2042typedef
2043 struct {
sewardj3026f712010-01-01 18:46:41 +00002044 D3UnwindRegs* uregs;
2045 Addr min_accessible;
2046 Addr max_accessible;
sewardj72427fa2007-02-27 16:52:23 +00002047 }
2048 CfiExprEvalContext;
2049
2050/* Evaluate the CfiExpr rooted at ix in exprs given the context eec.
2051 *ok is set to False on failure, but not to True on success. The
2052 caller must set it to True before calling. */
sewardjf7183e32010-03-14 17:19:02 +00002053__attribute__((noinline))
2054static
sewardj72427fa2007-02-27 16:52:23 +00002055UWord evalCfiExpr ( XArray* exprs, Int ix,
2056 CfiExprEvalContext* eec, Bool* ok )
2057{
tom40628fa2012-09-21 09:12:30 +00002058 UWord w, wL, wR;
sewardj19dc88f2007-02-28 01:46:30 +00002059 Addr a;
sewardj3026f712010-01-01 18:46:41 +00002060 CfiExpr* e;
2061 vg_assert(sizeof(Addr) == sizeof(UWord));
2062 e = VG_(indexXA)( exprs, ix );
sewardj72427fa2007-02-27 16:52:23 +00002063 switch (e->tag) {
tom40628fa2012-09-21 09:12:30 +00002064 case Cex_Unop:
2065 w = evalCfiExpr( exprs, e->Cex.Unop.ix, eec, ok );
2066 if (!(*ok)) return 0;
2067 switch (e->Cex.Unop.op) {
2068 case Cunop_Abs: return (Word) w < 0 ? - w : w;
2069 case Cunop_Neg: return - (Word) w;
2070 case Cunop_Not: return ~ w;
2071 default: goto unhandled;
2072 }
2073 /*NOTREACHED*/
sewardj72427fa2007-02-27 16:52:23 +00002074 case Cex_Binop:
2075 wL = evalCfiExpr( exprs, e->Cex.Binop.ixL, eec, ok );
2076 if (!(*ok)) return 0;
2077 wR = evalCfiExpr( exprs, e->Cex.Binop.ixR, eec, ok );
2078 if (!(*ok)) return 0;
2079 switch (e->Cex.Binop.op) {
tomf6716dd2012-09-21 09:04:27 +00002080 case Cbinop_Add: return wL + wR;
2081 case Cbinop_Sub: return wL - wR;
2082 case Cbinop_And: return wL & wR;
2083 case Cbinop_Mul: return wL * wR;
2084 case Cbinop_Shl: return wL << wR;
2085 case Cbinop_Shr: return wL >> wR;
2086 case Cbinop_Eq: return wL == wR ? 1 : 0;
2087 case Cbinop_Ge: return (Word) wL >= (Word) wR ? 1 : 0;
2088 case Cbinop_Gt: return (Word) wL > (Word) wR ? 1 : 0;
2089 case Cbinop_Le: return (Word) wL <= (Word) wR ? 1 : 0;
2090 case Cbinop_Lt: return (Word) wL < (Word) wR ? 1 : 0;
2091 case Cbinop_Ne: return wL != wR ? 1 : 0;
sewardj72427fa2007-02-27 16:52:23 +00002092 default: goto unhandled;
2093 }
2094 /*NOTREACHED*/
2095 case Cex_CfiReg:
2096 switch (e->Cex.CfiReg.reg) {
sewardj3026f712010-01-01 18:46:41 +00002097# if defined(VGA_x86) || defined(VGA_amd64)
2098 case Creg_IA_IP: return eec->uregs->xip;
2099 case Creg_IA_SP: return eec->uregs->xsp;
2100 case Creg_IA_BP: return eec->uregs->xbp;
2101# elif defined(VGA_arm)
sewardj3026f712010-01-01 18:46:41 +00002102 case Creg_ARM_R15: return eec->uregs->r15;
2103 case Creg_ARM_R14: return eec->uregs->r14;
sewardjfa5ce562010-09-23 22:05:59 +00002104 case Creg_ARM_R13: return eec->uregs->r13;
2105 case Creg_ARM_R12: return eec->uregs->r12;
sewardjb5b87402011-03-07 16:05:35 +00002106# elif defined(VGA_s390x)
2107 case Creg_IA_IP: return eec->uregs->ia;
2108 case Creg_IA_SP: return eec->uregs->sp;
2109 case Creg_IA_BP: return eec->uregs->fp;
2110 case Creg_S390_R14: return eec->uregs->lr;
petarj4df0bfc2013-02-27 23:17:33 +00002111# elif defined(VGA_mips32) || defined(VGA_mips64)
sewardj5db15402012-06-07 09:13:21 +00002112 case Creg_IA_IP: return eec->uregs->pc;
2113 case Creg_IA_SP: return eec->uregs->sp;
2114 case Creg_IA_BP: return eec->uregs->fp;
2115 case Creg_MIPS_RA: return eec->uregs->ra;
sewardj3026f712010-01-01 18:46:41 +00002116# elif defined(VGA_ppc32) || defined(VGA_ppc64)
sewardjf0c12502014-01-12 12:54:00 +00002117# elif defined(VGP_arm64_linux)
sewardj821283b2014-01-13 00:21:09 +00002118 case Creg_ARM64_X30: return eec->uregs->x30;
sewardj3026f712010-01-01 18:46:41 +00002119# else
2120# error "Unsupported arch"
2121# endif
sewardj72427fa2007-02-27 16:52:23 +00002122 default: goto unhandled;
2123 }
2124 /*NOTREACHED*/
2125 case Cex_Const:
2126 return e->Cex.Const.con;
sewardj19dc88f2007-02-28 01:46:30 +00002127 case Cex_Deref:
2128 a = evalCfiExpr( exprs, e->Cex.Deref.ixAddr, eec, ok );
2129 if (!(*ok)) return 0;
2130 if (a < eec->min_accessible
sewardj720e6b72011-10-20 08:09:39 +00002131 || a > eec->max_accessible - sizeof(UWord) + 1) {
sewardj19dc88f2007-02-28 01:46:30 +00002132 *ok = False;
2133 return 0;
2134 }
2135 /* let's hope it doesn't trap! */
tom86781fa2011-10-05 08:48:07 +00002136 return ML_(read_UWord)((void *)a);
sewardj72427fa2007-02-27 16:52:23 +00002137 default:
2138 goto unhandled;
2139 }
2140 /*NOTREACHED*/
2141 unhandled:
2142 VG_(printf)("\n\nevalCfiExpr: unhandled\n");
2143 ML_(ppCfiExpr)( exprs, ix );
2144 VG_(printf)("\n");
2145 vg_assert(0);
2146 /*NOTREACHED*/
2147 return 0;
2148}
2149
2150
sewardjf98e1c02008-10-25 16:22:41 +00002151/* Search all the DebugInfos in the entire system, to find the DiCfSI
2152 that pertains to 'ip'.
2153
2154 If found, set *diP to the DebugInfo in which it resides, and
2155 *ixP to the index in that DebugInfo's cfsi array.
2156
2157 If not found, set *diP to (DebugInfo*)1 and *ixP to zero.
2158*/
2159__attribute__((noinline))
2160static void find_DiCfSI ( /*OUT*/DebugInfo** diP,
2161 /*OUT*/Word* ixP,
2162 Addr ip )
2163{
2164 DebugInfo* di;
2165 Word i = -1;
2166
2167 static UWord n_search = 0;
2168 static UWord n_steps = 0;
2169 n_search++;
2170
2171 if (0) VG_(printf)("search for %#lx\n", ip);
2172
2173 for (di = debugInfo_list; di != NULL; di = di->next) {
2174 Word j;
2175 n_steps++;
2176
2177 /* Use the per-DebugInfo summary address ranges to skip
2178 inapplicable DebugInfos quickly. */
2179 if (di->cfsi_used == 0)
2180 continue;
2181 if (ip < di->cfsi_minavma || ip > di->cfsi_maxavma)
2182 continue;
2183
2184 /* It might be in this DebugInfo. Search it. */
2185 j = ML_(search_one_cfitab)( di, ip );
2186 vg_assert(j >= -1 && j < (Word)di->cfsi_used);
2187
2188 if (j != -1) {
2189 i = j;
2190 break; /* found it */
2191 }
2192 }
2193
2194 if (i == -1) {
2195
2196 /* we didn't find it. */
2197 *diP = (DebugInfo*)1;
2198 *ixP = 0;
2199
2200 } else {
2201
2202 /* found it. */
2203 /* ensure that di is 4-aligned (at least), so it can't possibly
2204 be equal to (DebugInfo*)1. */
2205 vg_assert(di && VG_IS_4_ALIGNED(di));
2206 vg_assert(i >= 0 && i < di->cfsi_used);
2207 *diP = di;
2208 *ixP = i;
2209
2210 /* Start of performance-enhancing hack: once every 64 (chosen
2211 hackily after profiling) successful searches, move the found
2212 DebugInfo one step closer to the start of the list. This
2213 makes future searches cheaper. For starting konqueror on
2214 amd64, this in fact reduces the total amount of searching
2215 done by the above find-the-right-DebugInfo loop by more than
2216 a factor of 20. */
2217 if ((n_search & 0xF) == 0) {
2218 /* Move di one step closer to the start of the list. */
2219 move_DebugInfo_one_step_forward( di );
2220 }
2221 /* End of performance-enhancing hack. */
2222
2223 if (0 && ((n_search & 0x7FFFF) == 0))
2224 VG_(printf)("find_DiCfSI: %lu searches, "
2225 "%lu DebugInfos looked at\n",
2226 n_search, n_steps);
2227
2228 }
2229
2230}
2231
2232
2233/* Now follows a mechanism for caching queries to find_DiCfSI, since
2234 they are extremely frequent on amd64-linux, during stack unwinding.
2235
2236 Each cache entry binds an ip value to a (di, ix) pair. Possible
2237 values:
2238
2239 di is non-null, ix >= 0 ==> cache slot in use, "di->cfsi[ix]"
2240 di is (DebugInfo*)1 ==> cache slot in use, no associated di
2241 di is NULL ==> cache slot not in use
2242
2243 Hence simply zeroing out the entire cache invalidates all
2244 entries.
2245
2246 Why not map ip values directly to DiCfSI*'s? Because this would
2247 cause problems if/when the cfsi array is moved due to resizing.
2248 Instead we cache .cfsi array index value, which should be invariant
2249 across resizing. (That said, I don't think the current
2250 implementation will resize whilst during queries, since the DiCfSI
2251 records are added all at once, when the debuginfo for an object is
2252 read, and is not changed ever thereafter. */
2253
philippe50863bb2013-01-17 23:57:35 +00002254// Prime number, giving about 3K cache on 32 bits, 6K cache on 64 bits.
2255#define N_CFSI_CACHE 509
sewardjf98e1c02008-10-25 16:22:41 +00002256
2257typedef
2258 struct { Addr ip; DebugInfo* di; Word ix; }
2259 CFSICacheEnt;
2260
2261static CFSICacheEnt cfsi_cache[N_CFSI_CACHE];
2262
2263static void cfsi_cache__invalidate ( void ) {
2264 VG_(memset)(&cfsi_cache, 0, sizeof(cfsi_cache));
philippe20ede3a2013-01-30 23:18:11 +00002265 CF_info_generation++;
sewardjf98e1c02008-10-25 16:22:41 +00002266}
2267
philippe20ede3a2013-01-30 23:18:11 +00002268UInt VG_(CF_info_generation) (void)
2269{
2270 return CF_info_generation;
2271}
sewardjf98e1c02008-10-25 16:22:41 +00002272
sewardjf7183e32010-03-14 17:19:02 +00002273static inline CFSICacheEnt* cfsi_cache__find ( Addr ip )
tom3c9cf342009-11-12 13:28:34 +00002274{
2275 UWord hash = ip % N_CFSI_CACHE;
2276 CFSICacheEnt* ce = &cfsi_cache[hash];
2277 static UWord n_q = 0, n_m = 0;
2278
2279 n_q++;
2280 if (0 && 0 == (n_q & 0x1FFFFF))
2281 VG_(printf)("QQQ %lu %lu\n", n_q, n_m);
2282
2283 if (LIKELY(ce->ip == ip) && LIKELY(ce->di != NULL)) {
2284 /* found an entry in the cache .. */
2285 } else {
2286 /* not found in cache. Search and update. */
2287 n_m++;
2288 ce->ip = ip;
2289 find_DiCfSI( &ce->di, &ce->ix, ip );
2290 }
2291
2292 if (UNLIKELY(ce->di == (DebugInfo*)1)) {
2293 /* no DiCfSI for this address */
2294 return NULL;
2295 } else {
2296 /* found a DiCfSI for this address */
2297 return ce;
2298 }
2299}
2300
2301
sewardjf7183e32010-03-14 17:19:02 +00002302inline
sewardj3026f712010-01-01 18:46:41 +00002303static Addr compute_cfa ( D3UnwindRegs* uregs,
tom3c9cf342009-11-12 13:28:34 +00002304 Addr min_accessible, Addr max_accessible,
2305 DebugInfo* di, DiCfSI* cfsi )
2306{
2307 CfiExprEvalContext eec;
2308 Addr cfa;
2309 Bool ok;
2310
2311 /* Compute the CFA. */
2312 cfa = 0;
2313 switch (cfsi->cfa_how) {
sewardj3026f712010-01-01 18:46:41 +00002314# if defined(VGA_x86) || defined(VGA_amd64)
2315 case CFIC_IA_SPREL:
2316 cfa = cfsi->cfa_off + uregs->xsp;
tom3c9cf342009-11-12 13:28:34 +00002317 break;
sewardj3026f712010-01-01 18:46:41 +00002318 case CFIC_IA_BPREL:
2319 cfa = cfsi->cfa_off + uregs->xbp;
tom3c9cf342009-11-12 13:28:34 +00002320 break;
sewardj3026f712010-01-01 18:46:41 +00002321# elif defined(VGA_arm)
2322 case CFIC_ARM_R13REL:
2323 cfa = cfsi->cfa_off + uregs->r13;
2324 break;
2325 case CFIC_ARM_R12REL:
2326 cfa = cfsi->cfa_off + uregs->r12;
2327 break;
2328 case CFIC_ARM_R11REL:
2329 cfa = cfsi->cfa_off + uregs->r11;
2330 break;
sewardjfa5ce562010-09-23 22:05:59 +00002331 case CFIC_ARM_R7REL:
2332 cfa = cfsi->cfa_off + uregs->r7;
2333 break;
sewardjb5b87402011-03-07 16:05:35 +00002334# elif defined(VGA_s390x)
2335 case CFIC_IA_SPREL:
2336 cfa = cfsi->cfa_off + uregs->sp;
2337 break;
2338 case CFIR_MEMCFAREL:
2339 {
2340 Addr a = uregs->sp + cfsi->cfa_off;
2341 if (a < min_accessible || a > max_accessible-sizeof(Addr))
2342 break;
tom86781fa2011-10-05 08:48:07 +00002343 cfa = ML_(read_Addr)((void *)a);
sewardjb5b87402011-03-07 16:05:35 +00002344 break;
2345 }
2346 case CFIR_SAME:
2347 cfa = uregs->fp;
2348 break;
2349 case CFIC_IA_BPREL:
2350 cfa = cfsi->cfa_off + uregs->fp;
2351 break;
petarj4df0bfc2013-02-27 23:17:33 +00002352# elif defined(VGA_mips32) || defined(VGA_mips64)
sewardj5db15402012-06-07 09:13:21 +00002353 case CFIC_IA_SPREL:
2354 cfa = cfsi->cfa_off + uregs->sp;
2355 break;
2356 case CFIR_SAME:
2357 cfa = uregs->fp;
2358 break;
2359 case CFIC_IA_BPREL:
2360 cfa = cfsi->cfa_off + uregs->fp;
2361 break;
sewardj3026f712010-01-01 18:46:41 +00002362# elif defined(VGA_ppc32) || defined(VGA_ppc64)
sewardjf0c12502014-01-12 12:54:00 +00002363# elif defined(VGP_arm64_linux)
sewardj821283b2014-01-13 00:21:09 +00002364 case CFIC_ARM64_SPREL:
2365 cfa = cfsi->cfa_off + uregs->sp;
2366 break;
2367 case CFIC_ARM64_X29REL:
2368 cfa = cfsi->cfa_off + uregs->x29;
2369 break;
sewardj3026f712010-01-01 18:46:41 +00002370# else
2371# error "Unsupported arch"
2372# endif
2373 case CFIC_EXPR: /* available on all archs */
tom3c9cf342009-11-12 13:28:34 +00002374 if (0) {
2375 VG_(printf)("CFIC_EXPR: ");
2376 ML_(ppCfiExpr)(di->cfsi_exprs, cfsi->cfa_off);
2377 VG_(printf)("\n");
2378 }
sewardj3026f712010-01-01 18:46:41 +00002379 eec.uregs = uregs;
tom3c9cf342009-11-12 13:28:34 +00002380 eec.min_accessible = min_accessible;
2381 eec.max_accessible = max_accessible;
2382 ok = True;
2383 cfa = evalCfiExpr(di->cfsi_exprs, cfsi->cfa_off, &eec, &ok );
2384 if (!ok) return 0;
2385 break;
2386 default:
2387 vg_assert(0);
2388 }
2389 return cfa;
2390}
2391
2392
2393/* Get the call frame address (CFA) given an IP/SP/FP triple. */
sewardj3026f712010-01-01 18:46:41 +00002394/* NOTE: This function may rearrange the order of entries in the
2395 DebugInfo list. */
tom3c9cf342009-11-12 13:28:34 +00002396Addr ML_(get_CFA) ( Addr ip, Addr sp, Addr fp,
2397 Addr min_accessible, Addr max_accessible )
2398{
2399 CFSICacheEnt* ce;
2400 DebugInfo* di;
sewardjd2be8cc2011-03-28 20:33:52 +00002401 DiCfSI* cfsi __attribute__((unused));
tom3c9cf342009-11-12 13:28:34 +00002402
2403 ce = cfsi_cache__find(ip);
2404
2405 if (UNLIKELY(ce == NULL))
2406 return 0; /* no info. Nothing we can do. */
2407
2408 di = ce->di;
2409 cfsi = &di->cfsi[ ce->ix ];
2410
sewardj3026f712010-01-01 18:46:41 +00002411 /* Temporary impedance-matching kludge so that this keeps working
2412 on x86-linux and amd64-linux. */
2413# if defined(VGA_x86) || defined(VGA_amd64)
2414 { D3UnwindRegs uregs;
2415 uregs.xip = ip;
2416 uregs.xsp = sp;
2417 uregs.xbp = fp;
2418 return compute_cfa(&uregs,
2419 min_accessible, max_accessible, di, cfsi);
2420 }
sewardjb5b87402011-03-07 16:05:35 +00002421#elif defined(VGA_s390x)
2422 { D3UnwindRegs uregs;
2423 uregs.ia = ip;
2424 uregs.sp = sp;
2425 uregs.fp = fp;
2426 return compute_cfa(&uregs,
2427 min_accessible, max_accessible, di, cfsi);
2428 }
dejanjf03d0b72014-04-14 11:54:36 +00002429#elif defined(VGA_mips32) || defined(VGA_mips64)
dejanjfe0b4332014-04-04 10:02:03 +00002430 { D3UnwindRegs uregs;
2431 uregs.pc = ip;
2432 uregs.sp = sp;
2433 uregs.fp = fp;
2434 return compute_cfa(&uregs,
2435 min_accessible, max_accessible, di, cfsi);
2436 }
sewardjb5b87402011-03-07 16:05:35 +00002437
sewardj3026f712010-01-01 18:46:41 +00002438# else
2439 return 0; /* indicates failure */
2440# endif
tom3c9cf342009-11-12 13:28:34 +00002441}
2442
2443
sewardj3026f712010-01-01 18:46:41 +00002444/* The main function for DWARF2/3 CFI-based stack unwinding. Given a
2445 set of registers in UREGS, modify it to hold the register values
2446 for the previous frame, if possible. Returns True if successful.
2447 If not successful, *UREGS is not changed.
2448
2449 For x86 and amd64, the unwound registers are: {E,R}IP,
2450 {E,R}SP, {E,R}BP.
2451
sewardjfa5ce562010-09-23 22:05:59 +00002452 For arm, the unwound registers are: R7 R11 R12 R13 R14 R15.
sewardj821283b2014-01-13 00:21:09 +00002453
2454 For arm64, the unwound registers are: X29(FP) X30(LR) SP PC.
sewardj3026f712010-01-01 18:46:41 +00002455*/
2456Bool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere,
sewardjeadcd862006-04-04 15:12:44 +00002457 Addr min_accessible,
2458 Addr max_accessible )
2459{
tom3c9cf342009-11-12 13:28:34 +00002460 DebugInfo* di;
2461 DiCfSI* cfsi = NULL;
sewardj3026f712010-01-01 18:46:41 +00002462 Addr cfa, ipHere = 0;
tom3c9cf342009-11-12 13:28:34 +00002463 CFSICacheEnt* ce;
sewardjd2be8cc2011-03-28 20:33:52 +00002464 CfiExprEvalContext eec __attribute__((unused));
sewardj3026f712010-01-01 18:46:41 +00002465 D3UnwindRegs uregsPrev;
sewardj72427fa2007-02-27 16:52:23 +00002466
sewardj3026f712010-01-01 18:46:41 +00002467# if defined(VGA_x86) || defined(VGA_amd64)
2468 ipHere = uregsHere->xip;
2469# elif defined(VGA_arm)
2470 ipHere = uregsHere->r15;
sewardjb5b87402011-03-07 16:05:35 +00002471# elif defined(VGA_s390x)
2472 ipHere = uregsHere->ia;
petarj4df0bfc2013-02-27 23:17:33 +00002473# elif defined(VGA_mips32) || defined(VGA_mips64)
sewardj5db15402012-06-07 09:13:21 +00002474 ipHere = uregsHere->pc;
sewardj3026f712010-01-01 18:46:41 +00002475# elif defined(VGA_ppc32) || defined(VGA_ppc64)
sewardjf0c12502014-01-12 12:54:00 +00002476# elif defined(VGP_arm64_linux)
sewardj821283b2014-01-13 00:21:09 +00002477 ipHere = uregsHere->pc;
sewardj3026f712010-01-01 18:46:41 +00002478# else
2479# error "Unknown arch"
2480# endif
2481 ce = cfsi_cache__find(ipHere);
sewardjeadcd862006-04-04 15:12:44 +00002482
tom3c9cf342009-11-12 13:28:34 +00002483 if (UNLIKELY(ce == NULL))
sewardjf98e1c02008-10-25 16:22:41 +00002484 return False; /* no info. Nothing we can do. */
sewardjeadcd862006-04-04 15:12:44 +00002485
tom3c9cf342009-11-12 13:28:34 +00002486 di = ce->di;
2487 cfsi = &di->cfsi[ ce->ix ];
2488
sewardjeadcd862006-04-04 15:12:44 +00002489 if (0) {
2490 VG_(printf)("found cfisi: ");
sewardjf98e1c02008-10-25 16:22:41 +00002491 ML_(ppDiCfSI)(di->cfsi_exprs, cfsi);
sewardjeadcd862006-04-04 15:12:44 +00002492 }
2493
sewardjf7183e32010-03-14 17:19:02 +00002494 VG_(bzero_inline)(&uregsPrev, sizeof(uregsPrev));
sewardjeadcd862006-04-04 15:12:44 +00002495
sewardj72427fa2007-02-27 16:52:23 +00002496 /* First compute the CFA. */
sewardj3026f712010-01-01 18:46:41 +00002497 cfa = compute_cfa(uregsHere,
2498 min_accessible, max_accessible, di, cfsi);
tom3c9cf342009-11-12 13:28:34 +00002499 if (UNLIKELY(cfa == 0))
2500 return False;
sewardj72427fa2007-02-27 16:52:23 +00002501
2502 /* Now we know the CFA, use it to roll back the registers we're
2503 interested in. */
sewardjeadcd862006-04-04 15:12:44 +00002504
2505# define COMPUTE(_prev, _here, _how, _off) \
2506 do { \
2507 switch (_how) { \
2508 case CFIR_UNKNOWN: \
2509 return False; \
2510 case CFIR_SAME: \
2511 _prev = _here; break; \
2512 case CFIR_MEMCFAREL: { \
2513 Addr a = cfa + (Word)_off; \
2514 if (a < min_accessible \
sewardj9c606bd2008-09-18 18:12:50 +00002515 || a > max_accessible-sizeof(Addr)) \
sewardjeadcd862006-04-04 15:12:44 +00002516 return False; \
tom86781fa2011-10-05 08:48:07 +00002517 _prev = ML_(read_Addr)((void *)a); \
sewardjeadcd862006-04-04 15:12:44 +00002518 break; \
2519 } \
2520 case CFIR_CFAREL: \
2521 _prev = cfa + (Word)_off; \
2522 break; \
sewardj72427fa2007-02-27 16:52:23 +00002523 case CFIR_EXPR: \
2524 if (0) \
sewardjf98e1c02008-10-25 16:22:41 +00002525 ML_(ppCfiExpr)(di->cfsi_exprs,_off); \
sewardj3026f712010-01-01 18:46:41 +00002526 eec.uregs = uregsHere; \
sewardj72427fa2007-02-27 16:52:23 +00002527 eec.min_accessible = min_accessible; \
2528 eec.max_accessible = max_accessible; \
sewardjd2be8cc2011-03-28 20:33:52 +00002529 Bool ok = True; \
sewardjf98e1c02008-10-25 16:22:41 +00002530 _prev = evalCfiExpr(di->cfsi_exprs, _off, &eec, &ok ); \
sewardj72427fa2007-02-27 16:52:23 +00002531 if (!ok) return False; \
2532 break; \
2533 default: \
2534 vg_assert(0); \
sewardjeadcd862006-04-04 15:12:44 +00002535 } \
2536 } while (0)
2537
sewardj3026f712010-01-01 18:46:41 +00002538# if defined(VGA_x86) || defined(VGA_amd64)
2539 COMPUTE(uregsPrev.xip, uregsHere->xip, cfsi->ra_how, cfsi->ra_off);
sewardj9365e3f2010-01-01 19:55:17 +00002540 COMPUTE(uregsPrev.xsp, uregsHere->xsp, cfsi->sp_how, cfsi->sp_off);
2541 COMPUTE(uregsPrev.xbp, uregsHere->xbp, cfsi->bp_how, cfsi->bp_off);
sewardj3026f712010-01-01 18:46:41 +00002542# elif defined(VGA_arm)
2543 COMPUTE(uregsPrev.r15, uregsHere->r15, cfsi->ra_how, cfsi->ra_off);
2544 COMPUTE(uregsPrev.r14, uregsHere->r14, cfsi->r14_how, cfsi->r14_off);
2545 COMPUTE(uregsPrev.r13, uregsHere->r13, cfsi->r13_how, cfsi->r13_off);
2546 COMPUTE(uregsPrev.r12, uregsHere->r12, cfsi->r12_how, cfsi->r12_off);
2547 COMPUTE(uregsPrev.r11, uregsHere->r11, cfsi->r11_how, cfsi->r11_off);
sewardjfa5ce562010-09-23 22:05:59 +00002548 COMPUTE(uregsPrev.r7, uregsHere->r7, cfsi->r7_how, cfsi->r7_off);
sewardjb5b87402011-03-07 16:05:35 +00002549# elif defined(VGA_s390x)
2550 COMPUTE(uregsPrev.ia, uregsHere->ia, cfsi->ra_how, cfsi->ra_off);
2551 COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi->sp_how, cfsi->sp_off);
2552 COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi->fp_how, cfsi->fp_off);
petarj4df0bfc2013-02-27 23:17:33 +00002553# elif defined(VGA_mips32) || defined(VGA_mips64)
sewardj5db15402012-06-07 09:13:21 +00002554 COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi->ra_how, cfsi->ra_off);
2555 COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi->sp_how, cfsi->sp_off);
2556 COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi->fp_how, cfsi->fp_off);
sewardj3026f712010-01-01 18:46:41 +00002557# elif defined(VGA_ppc32) || defined(VGA_ppc64)
sewardjf0c12502014-01-12 12:54:00 +00002558# elif defined(VGP_arm64_linux)
sewardj821283b2014-01-13 00:21:09 +00002559 COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi->ra_how, cfsi->ra_off);
2560 COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi->sp_how, cfsi->sp_off);
2561 COMPUTE(uregsPrev.x30, uregsHere->x30, cfsi->x30_how, cfsi->x30_off);
2562 COMPUTE(uregsPrev.x29, uregsHere->x29, cfsi->x29_how, cfsi->x29_off);
sewardj3026f712010-01-01 18:46:41 +00002563# else
2564# error "Unknown arch"
2565# endif
sewardjeadcd862006-04-04 15:12:44 +00002566
2567# undef COMPUTE
2568
sewardj3026f712010-01-01 18:46:41 +00002569 *uregsHere = uregsPrev;
sewardjeadcd862006-04-04 15:12:44 +00002570 return True;
2571}
2572
2573
sewardjb8b79ad2008-03-03 01:35:41 +00002574/*--------------------------------------------------------------*/
2575/*--- ---*/
sewardjc8259b82009-04-22 22:42:10 +00002576/*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/
2577/*--- MSVC FPO INFO ---*/
2578/*--- ---*/
2579/*--------------------------------------------------------------*/
2580
2581Bool VG_(use_FPO_info) ( /*MOD*/Addr* ipP,
2582 /*MOD*/Addr* spP,
2583 /*MOD*/Addr* fpP,
2584 Addr min_accessible,
2585 Addr max_accessible )
2586{
2587 Word i;
2588 DebugInfo* di;
2589 FPO_DATA* fpo = NULL;
2590 Addr spHere;
2591
2592 static UWord n_search = 0;
2593 static UWord n_steps = 0;
2594 n_search++;
2595
2596 if (0) VG_(printf)("search FPO for %#lx\n", *ipP);
2597
2598 for (di = debugInfo_list; di != NULL; di = di->next) {
2599 n_steps++;
2600
2601 /* Use the per-DebugInfo summary address ranges to skip
2602 inapplicable DebugInfos quickly. */
2603 if (di->fpo == NULL)
2604 continue;
2605 if (*ipP < di->fpo_minavma || *ipP > di->fpo_maxavma)
2606 continue;
2607
2608 i = ML_(search_one_fpotab)( di, *ipP );
2609 if (i != -1) {
2610 Word j;
2611 if (0) {
2612 /* debug printing only */
2613 VG_(printf)("look for %#lx size %ld i %ld\n",
2614 *ipP, di->fpo_size, i);
2615 for (j = 0; j < di->fpo_size; j++)
2616 VG_(printf)("[%02ld] %#x %d\n",
2617 j, di->fpo[j].ulOffStart, di->fpo[j].cbProcSize);
2618 }
2619 vg_assert(i >= 0 && i < di->fpo_size);
2620 fpo = &di->fpo[i];
2621 break;
2622 }
2623 }
2624
2625 if (fpo == NULL)
2626 return False;
2627
2628 if (0 && ((n_search & 0x7FFFF) == 0))
2629 VG_(printf)("VG_(use_FPO_info): %lu searches, "
2630 "%lu DebugInfos looked at\n",
2631 n_search, n_steps);
2632
2633
2634 /* Start of performance-enhancing hack: once every 64 (chosen
2635 hackily after profiling) successful searches, move the found
2636 DebugInfo one step closer to the start of the list. This makes
2637 future searches cheaper. For starting konqueror on amd64, this
2638 in fact reduces the total amount of searching done by the above
2639 find-the-right-DebugInfo loop by more than a factor of 20. */
2640 if ((n_search & 0x3F) == 0) {
2641 /* Move si one step closer to the start of the list. */
2642 //move_DebugInfo_one_step_forward( di );
2643 }
2644 /* End of performance-enhancing hack. */
2645
2646 if (0) {
2647 VG_(printf)("found fpo: ");
2648 //ML_(ppFPO)(fpo);
2649 }
2650
2651 /*
2652 Stack layout is:
2653 %esp->
2654 4*.cbRegs {%edi, %esi, %ebp, %ebx}
2655 4*.cdwLocals
2656 return_pc
2657 4*.cdwParams
2658 prior_%esp->
2659
2660 Typical code looks like:
2661 sub $4*.cdwLocals,%esp
2662 Alternative to above for >=4KB (and sometimes for smaller):
2663 mov $size,%eax
2664 call __chkstk # WinNT performs page-by-page probe!
2665 __chkstk is much like alloc(), except that on return
2666 %eax= 5+ &CALL. Thus it could be used as part of
2667 Position Independent Code to locate the Global Offset Table.
2668 push %ebx
2669 push %ebp
2670 push %esi
2671 Other once-only instructions often scheduled >here<.
2672 push %edi
2673
2674 If the pc is within the first .cbProlog bytes of the function,
2675 then you must disassemble to see how many registers have been pushed,
2676 because instructions in the prolog may be scheduled for performance.
2677 The order of PUSH is always %ebx, %ebp, %esi, %edi, with trailing
2678 registers not pushed when .cbRegs < 4. This seems somewhat strange
2679 because %ebp is the register whose usage you want to minimize,
2680 yet it is in the first half of the PUSH list.
2681
2682 I don't know what happens when the compiler constructs an outgoing CALL.
2683 %esp could move if outgoing parameters are PUSHed, and this affects
2684 traceback for errors during the PUSHes. */
2685
2686 spHere = *spP;
2687
tom86781fa2011-10-05 08:48:07 +00002688 *ipP = ML_(read_Addr)((void *)(spHere + 4*(fpo->cbRegs + fpo->cdwLocals)));
2689 *spP = spHere + 4*(fpo->cbRegs + fpo->cdwLocals + 1
2690 + fpo->cdwParams);
2691 *fpP = ML_(read_Addr)((void *)(spHere + 4*2));
sewardjc8259b82009-04-22 22:42:10 +00002692 return True;
2693}
2694
2695
2696/*--------------------------------------------------------------*/
2697/*--- ---*/
sewardjb8b79ad2008-03-03 01:35:41 +00002698/*--- TOP LEVEL: GENERATE DESCRIPTION OF DATA ADDRESSES ---*/
2699/*--- FROM DWARF3 DEBUG INFO ---*/
2700/*--- ---*/
2701/*--------------------------------------------------------------*/
sewardjeadcd862006-04-04 15:12:44 +00002702
sewardj588adef2009-08-15 22:41:51 +00002703/* Try to make p2XA(dst, fmt, args..) turn into
bartb3af9cf2011-10-06 19:08:37 +00002704 VG_(xaprintf)(dst, fmt, args) without having to resort to
sewardj588adef2009-08-15 22:41:51 +00002705 vararg macros. As usual with everything to do with varargs, it's
2706 an ugly hack.
sewardj738856f2009-07-15 14:48:32 +00002707
sewardj588adef2009-08-15 22:41:51 +00002708 //#define p2XA(dstxa, format, args...)
bartb3af9cf2011-10-06 19:08:37 +00002709 // VG_(xaprintf)(dstxa, format, ##args)
sewardj738856f2009-07-15 14:48:32 +00002710*/
bartb3af9cf2011-10-06 19:08:37 +00002711#define p2XA VG_(xaprintf)
sewardj738856f2009-07-15 14:48:32 +00002712
sewardj588adef2009-08-15 22:41:51 +00002713/* Add a zero-terminating byte to DST, which must be an XArray* of
2714 HChar. */
sewardj738856f2009-07-15 14:48:32 +00002715static void zterm_XA ( XArray* dst )
2716{
2717 HChar zero = 0;
2718 (void) VG_(addBytesToXA)( dst, &zero, 1 );
2719}
2720
2721
sewardjb8b79ad2008-03-03 01:35:41 +00002722/* Evaluate the location expression/list for var, to see whether or
2723 not data_addr falls within the variable. If so also return the
2724 offset of data_addr from the start of the variable. Note that
2725 regs, which supplies ip,sp,fp values, will be NULL for global
2726 variables, and non-NULL for local variables. */
njnc4431bf2009-01-15 21:29:24 +00002727static Bool data_address_is_in_var ( /*OUT*/PtrdiffT* offset,
sewardj9c606bd2008-09-18 18:12:50 +00002728 XArray* /* TyEnt */ tyents,
sewardjb8b79ad2008-03-03 01:35:41 +00002729 DiVariable* var,
2730 RegSummary* regs,
2731 Addr data_addr,
tom588658b2009-01-22 13:40:12 +00002732 const DebugInfo* di )
sewardjeadcd862006-04-04 15:12:44 +00002733{
sewardj50fde232008-10-20 16:08:55 +00002734 MaybeULong mul;
sewardjb8b79ad2008-03-03 01:35:41 +00002735 SizeT var_szB;
2736 GXResult res;
2737 Bool show = False;
sewardj9c606bd2008-09-18 18:12:50 +00002738
sewardjb8b79ad2008-03-03 01:35:41 +00002739 vg_assert(var->name);
sewardjb8b79ad2008-03-03 01:35:41 +00002740 vg_assert(var->gexpr);
2741
2742 /* Figure out how big the variable is. */
sewardj50fde232008-10-20 16:08:55 +00002743 mul = ML_(sizeOfType)(tyents, var->typeR);
2744 /* If this var has a type whose size is unknown, zero, or
2745 impossibly large, it should never have been added. ML_(addVar)
2746 should have rejected it. */
2747 vg_assert(mul.b == True);
2748 vg_assert(mul.ul > 0);
2749 if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
2750 /* After this point, we assume we can truncate mul.ul to a host word
2751 safely (without loss of info). */
sewardjb8b79ad2008-03-03 01:35:41 +00002752
sewardj50fde232008-10-20 16:08:55 +00002753 var_szB = (SizeT)mul.ul; /* NB: truncate to host word */
sewardjb8b79ad2008-03-03 01:35:41 +00002754
2755 if (show) {
barta0b6b2c2008-07-07 06:49:24 +00002756 VG_(printf)("VVVV: data_address_%#lx_is_in_var: %s :: ",
sewardjb8b79ad2008-03-03 01:35:41 +00002757 data_addr, var->name );
sewardj9c606bd2008-09-18 18:12:50 +00002758 ML_(pp_TyEnt_C_ishly)( tyents, var->typeR );
sewardjb8b79ad2008-03-03 01:35:41 +00002759 VG_(printf)("\n");
2760 }
2761
2762 /* ignore zero-sized vars; they can never match anything. */
2763 if (var_szB == 0) {
2764 if (show)
2765 VG_(printf)("VVVV: -> Fail (variable is zero sized)\n");
2766 return False;
2767 }
2768
tom588658b2009-01-22 13:40:12 +00002769 res = ML_(evaluate_GX)( var->gexpr, var->fbGX, regs, di );
sewardjb8b79ad2008-03-03 01:35:41 +00002770
2771 if (show) {
2772 VG_(printf)("VVVV: -> ");
2773 ML_(pp_GXResult)( res );
2774 VG_(printf)("\n");
2775 }
2776
tom3c9cf342009-11-12 13:28:34 +00002777 if (res.kind == GXR_Addr
sewardjb8b79ad2008-03-03 01:35:41 +00002778 && res.word <= data_addr
2779 && data_addr < res.word + var_szB) {
2780 *offset = data_addr - res.word;
2781 return True;
2782 } else {
2783 return False;
2784 }
sewardjeadcd862006-04-04 15:12:44 +00002785}
2786
sewardjb8b79ad2008-03-03 01:35:41 +00002787
sewardj738856f2009-07-15 14:48:32 +00002788/* Format the acquired information into DN(AME)1 and DN(AME)2, which
2789 are XArray*s of HChar, that have been initialised by the caller.
2790 Resulting strings will be zero terminated. Information is
2791 formatted in an understandable way. Not so easy. If frameNo is
2792 -1, this is assumed to be a global variable; else a local
2793 variable. */
2794static void format_message ( /*MOD*/XArray* /* of HChar */ dn1,
2795 /*MOD*/XArray* /* of HChar */ dn2,
sewardjb8b79ad2008-03-03 01:35:41 +00002796 Addr data_addr,
2797 DiVariable* var,
njnc4431bf2009-01-15 21:29:24 +00002798 PtrdiffT var_offset,
2799 PtrdiffT residual_offset,
sewardjb8b79ad2008-03-03 01:35:41 +00002800 XArray* /*UChar*/ described,
2801 Int frameNo,
2802 ThreadId tid )
sewardjeadcd862006-04-04 15:12:44 +00002803{
sewardj738856f2009-07-15 14:48:32 +00002804 Bool have_descr, have_srcloc;
2805 Bool xml = VG_(clo_xml);
florian1636d332012-11-15 04:27:04 +00002806 const HChar* vo_plural = var_offset == 1 ? "" : "s";
2807 const HChar* ro_plural = residual_offset == 1 ? "" : "s";
2808 const HChar* basetag = "auxwhat"; /* a constant */
2809 HChar tagL[32], tagR[32], xagL[32], xagR[32];
sewardjb8b79ad2008-03-03 01:35:41 +00002810
sewardjd7adca72011-05-04 09:06:17 +00002811 if (frameNo < -1) {
2812 vg_assert(0); /* Not allowed */
2813 }
2814 else if (frameNo == -1) {
2815 vg_assert(tid == VG_INVALID_THREADID);
2816 }
2817 else /* (frameNo >= 0) */ {
2818 vg_assert(tid != VG_INVALID_THREADID);
2819 }
2820
sewardj738856f2009-07-15 14:48:32 +00002821 vg_assert(dn1 && dn2);
sewardjb8b79ad2008-03-03 01:35:41 +00002822 vg_assert(described);
2823 vg_assert(var && var->name);
2824 have_descr = VG_(sizeXA)(described) > 0
2825 && *(UChar*)VG_(indexXA)(described,0) != '\0';
2826 have_srcloc = var->fileName && var->lineNo > 0;
2827
sewardj738856f2009-07-15 14:48:32 +00002828 tagL[0] = tagR[0] = xagL[0] = xagR[0] = 0;
2829 if (xml) {
2830 VG_(sprintf)(tagL, "<%s>", basetag); // <auxwhat>
2831 VG_(sprintf)(tagR, "</%s>", basetag); // </auxwhat>
2832 VG_(sprintf)(xagL, "<x%s>", basetag); // <xauxwhat>
2833 VG_(sprintf)(xagR, "</x%s>", basetag); // </xauxwhat>
2834 }
2835
2836# define TAGL(_xa) p2XA(_xa, "%s", tagL)
2837# define TAGR(_xa) p2XA(_xa, "%s", tagR)
2838# define XAGL(_xa) p2XA(_xa, "%s", xagL)
2839# define XAGR(_xa) p2XA(_xa, "%s", xagR)
2840# define TXTL(_xa) p2XA(_xa, "%s", "<text>")
2841# define TXTR(_xa) p2XA(_xa, "%s", "</text>")
sewardjb8b79ad2008-03-03 01:35:41 +00002842
2843 /* ------ local cases ------ */
2844
2845 if ( frameNo >= 0 && (!have_srcloc) && (!have_descr) ) {
2846 /* no srcloc, no description:
2847 Location 0x7fefff6cf is 543 bytes inside local var "a",
2848 in frame #1 of thread 1
2849 */
sewardj738856f2009-07-15 14:48:32 +00002850 if (xml) {
2851 TAGL( dn1 );
2852 p2XA( dn1,
bartb3af9cf2011-10-06 19:08:37 +00002853 "Location 0x%lx is %lu byte%s inside local var \"%pS\",",
sewardj738856f2009-07-15 14:48:32 +00002854 data_addr, var_offset, vo_plural, var->name );
2855 TAGR( dn1 );
2856 TAGL( dn2 );
2857 p2XA( dn2,
2858 "in frame #%d of thread %d", frameNo, (Int)tid );
2859 TAGR( dn2 );
2860 } else {
2861 p2XA( dn1,
2862 "Location 0x%lx is %lu byte%s inside local var \"%s\",",
2863 data_addr, var_offset, vo_plural, var->name );
2864 p2XA( dn2,
2865 "in frame #%d of thread %d", frameNo, (Int)tid );
2866 }
sewardjb8b79ad2008-03-03 01:35:41 +00002867 }
2868 else
2869 if ( frameNo >= 0 && have_srcloc && (!have_descr) ) {
2870 /* no description:
2871 Location 0x7fefff6cf is 543 bytes inside local var "a"
2872 declared at dsyms7.c:17, in frame #1 of thread 1
2873 */
sewardj738856f2009-07-15 14:48:32 +00002874 if (xml) {
2875 TAGL( dn1 );
2876 p2XA( dn1,
bartb3af9cf2011-10-06 19:08:37 +00002877 "Location 0x%lx is %lu byte%s inside local var \"%pS\"",
sewardj738856f2009-07-15 14:48:32 +00002878 data_addr, var_offset, vo_plural, var->name );
2879 TAGR( dn1 );
2880 XAGL( dn2 );
2881 TXTL( dn2 );
2882 p2XA( dn2,
bartb3af9cf2011-10-06 19:08:37 +00002883 "declared at %pS:%d, in frame #%d of thread %d",
sewardj738856f2009-07-15 14:48:32 +00002884 var->fileName, var->lineNo, frameNo, (Int)tid );
2885 TXTR( dn2 );
2886 // FIXME: also do <dir>
2887 p2XA( dn2,
bartb3af9cf2011-10-06 19:08:37 +00002888 " <file>%pS</file> <line>%d</line> ",
sewardj738856f2009-07-15 14:48:32 +00002889 var->fileName, var->lineNo );
2890 XAGR( dn2 );
2891 } else {
2892 p2XA( dn1,
2893 "Location 0x%lx is %lu byte%s inside local var \"%s\"",
2894 data_addr, var_offset, vo_plural, var->name );
2895 p2XA( dn2,
2896 "declared at %s:%d, in frame #%d of thread %d",
2897 var->fileName, var->lineNo, frameNo, (Int)tid );
2898 }
sewardjb8b79ad2008-03-03 01:35:41 +00002899 }
2900 else
2901 if ( frameNo >= 0 && (!have_srcloc) && have_descr ) {
2902 /* no srcloc:
2903 Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2
2904 in frame #1 of thread 1
2905 */
sewardj738856f2009-07-15 14:48:32 +00002906 if (xml) {
2907 TAGL( dn1 );
2908 p2XA( dn1,
bartb3af9cf2011-10-06 19:08:37 +00002909 "Location 0x%lx is %lu byte%s inside %pS%pS",
sewardj738856f2009-07-15 14:48:32 +00002910 data_addr, residual_offset, ro_plural, var->name,
2911 (HChar*)(VG_(indexXA)(described,0)) );
2912 TAGR( dn1 );
2913 TAGL( dn2 );
2914 p2XA( dn2,
2915 "in frame #%d of thread %d", frameNo, (Int)tid );
2916 TAGR( dn2 );
2917 } else {
2918 p2XA( dn1,
2919 "Location 0x%lx is %lu byte%s inside %s%s",
2920 data_addr, residual_offset, ro_plural, var->name,
2921 (HChar*)(VG_(indexXA)(described,0)) );
2922 p2XA( dn2,
2923 "in frame #%d of thread %d", frameNo, (Int)tid );
2924 }
sewardjb8b79ad2008-03-03 01:35:41 +00002925 }
2926 else
2927 if ( frameNo >= 0 && have_srcloc && have_descr ) {
sewardj738856f2009-07-15 14:48:32 +00002928 /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
2929 declared at dsyms7.c:17, in frame #1 of thread 1 */
2930 if (xml) {
2931 TAGL( dn1 );
2932 p2XA( dn1,
bartb3af9cf2011-10-06 19:08:37 +00002933 "Location 0x%lx is %lu byte%s inside %pS%pS,",
sewardj738856f2009-07-15 14:48:32 +00002934 data_addr, residual_offset, ro_plural, var->name,
2935 (HChar*)(VG_(indexXA)(described,0)) );
2936 TAGR( dn1 );
2937 XAGL( dn2 );
2938 TXTL( dn2 );
2939 p2XA( dn2,
bartb3af9cf2011-10-06 19:08:37 +00002940 "declared at %pS:%d, in frame #%d of thread %d",
sewardj738856f2009-07-15 14:48:32 +00002941 var->fileName, var->lineNo, frameNo, (Int)tid );
2942 TXTR( dn2 );
2943 // FIXME: also do <dir>
2944 p2XA( dn2,
bartb3af9cf2011-10-06 19:08:37 +00002945 " <file>%pS</file> <line>%d</line> ",
sewardj738856f2009-07-15 14:48:32 +00002946 var->fileName, var->lineNo );
2947 XAGR( dn2 );
2948 } else {
2949 p2XA( dn1,
2950 "Location 0x%lx is %lu byte%s inside %s%s,",
2951 data_addr, residual_offset, ro_plural, var->name,
2952 (HChar*)(VG_(indexXA)(described,0)) );
2953 p2XA( dn2,
2954 "declared at %s:%d, in frame #%d of thread %d",
2955 var->fileName, var->lineNo, frameNo, (Int)tid );
2956 }
sewardjb8b79ad2008-03-03 01:35:41 +00002957 }
2958 else
2959 /* ------ global cases ------ */
2960 if ( frameNo >= -1 && (!have_srcloc) && (!have_descr) ) {
2961 /* no srcloc, no description:
2962 Location 0x7fefff6cf is 543 bytes inside global var "a"
2963 */
sewardj738856f2009-07-15 14:48:32 +00002964 if (xml) {
2965 TAGL( dn1 );
2966 p2XA( dn1,
bartb3af9cf2011-10-06 19:08:37 +00002967 "Location 0x%lx is %lu byte%s inside global var \"%pS\"",
sewardj738856f2009-07-15 14:48:32 +00002968 data_addr, var_offset, vo_plural, var->name );
2969 TAGR( dn1 );
2970 } else {
2971 p2XA( dn1,
2972 "Location 0x%lx is %lu byte%s inside global var \"%s\"",
2973 data_addr, var_offset, vo_plural, var->name );
2974 }
sewardjb8b79ad2008-03-03 01:35:41 +00002975 }
2976 else
2977 if ( frameNo >= -1 && have_srcloc && (!have_descr) ) {
2978 /* no description:
2979 Location 0x7fefff6cf is 543 bytes inside global var "a"
2980 declared at dsyms7.c:17
2981 */
sewardj738856f2009-07-15 14:48:32 +00002982 if (xml) {
2983 TAGL( dn1 );
2984 p2XA( dn1,
bartb3af9cf2011-10-06 19:08:37 +00002985 "Location 0x%lx is %lu byte%s inside global var \"%pS\"",
sewardj738856f2009-07-15 14:48:32 +00002986 data_addr, var_offset, vo_plural, var->name );
2987 TAGR( dn1 );
2988 XAGL( dn2 );
2989 TXTL( dn2 );
2990 p2XA( dn2,
bartb3af9cf2011-10-06 19:08:37 +00002991 "declared at %pS:%d",
sewardj738856f2009-07-15 14:48:32 +00002992 var->fileName, var->lineNo);
2993 TXTR( dn2 );
2994 // FIXME: also do <dir>
2995 p2XA( dn2,
bartb3af9cf2011-10-06 19:08:37 +00002996 " <file>%pS</file> <line>%d</line> ",
sewardj738856f2009-07-15 14:48:32 +00002997 var->fileName, var->lineNo );
2998 XAGR( dn2 );
2999 } else {
3000 p2XA( dn1,
3001 "Location 0x%lx is %lu byte%s inside global var \"%s\"",
3002 data_addr, var_offset, vo_plural, var->name );
3003 p2XA( dn2,
3004 "declared at %s:%d",
3005 var->fileName, var->lineNo);
3006 }
sewardjb8b79ad2008-03-03 01:35:41 +00003007 }
3008 else
3009 if ( frameNo >= -1 && (!have_srcloc) && have_descr ) {
3010 /* no srcloc:
3011 Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
3012 a global variable
3013 */
sewardj738856f2009-07-15 14:48:32 +00003014 if (xml) {
3015 TAGL( dn1 );
3016 p2XA( dn1,
bartb3af9cf2011-10-06 19:08:37 +00003017 "Location 0x%lx is %lu byte%s inside %pS%pS,",
sewardj738856f2009-07-15 14:48:32 +00003018 data_addr, residual_offset, ro_plural, var->name,
3019 (HChar*)(VG_(indexXA)(described,0)) );
3020 TAGR( dn1 );
3021 TAGL( dn2 );
3022 p2XA( dn2,
3023 "a global variable");
3024 TAGR( dn2 );
3025 } else {
3026 p2XA( dn1,
3027 "Location 0x%lx is %lu byte%s inside %s%s,",
3028 data_addr, residual_offset, ro_plural, var->name,
3029 (char*)(VG_(indexXA)(described,0)) );
3030 p2XA( dn2,
3031 "a global variable");
3032 }
sewardjb8b79ad2008-03-03 01:35:41 +00003033 }
3034 else
3035 if ( frameNo >= -1 && have_srcloc && have_descr ) {
sewardj738856f2009-07-15 14:48:32 +00003036 /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2,
3037 a global variable declared at dsyms7.c:17 */
3038 if (xml) {
3039 TAGL( dn1 );
3040 p2XA( dn1,
bartb3af9cf2011-10-06 19:08:37 +00003041 "Location 0x%lx is %lu byte%s inside %pS%pS,",
sewardj738856f2009-07-15 14:48:32 +00003042 data_addr, residual_offset, ro_plural, var->name,
3043 (HChar*)(VG_(indexXA)(described,0)) );
3044 TAGR( dn1 );
3045 XAGL( dn2 );
3046 TXTL( dn2 );
3047 p2XA( dn2,
bartb3af9cf2011-10-06 19:08:37 +00003048 "a global variable declared at %pS:%d",
sewardj738856f2009-07-15 14:48:32 +00003049 var->fileName, var->lineNo);
3050 TXTR( dn2 );
3051 // FIXME: also do <dir>
3052 p2XA( dn2,
bartb3af9cf2011-10-06 19:08:37 +00003053 " <file>%pS</file> <line>%d</line> ",
sewardj738856f2009-07-15 14:48:32 +00003054 var->fileName, var->lineNo );
3055 XAGR( dn2 );
3056 } else {
3057 p2XA( dn1,
3058 "Location 0x%lx is %lu byte%s inside %s%s,",
3059 data_addr, residual_offset, ro_plural, var->name,
3060 (HChar*)(VG_(indexXA)(described,0)) );
3061 p2XA( dn2,
3062 "a global variable declared at %s:%d",
3063 var->fileName, var->lineNo);
3064 }
sewardjb8b79ad2008-03-03 01:35:41 +00003065 }
3066 else
3067 vg_assert(0);
3068
sewardj738856f2009-07-15 14:48:32 +00003069 /* Zero terminate both strings */
3070 zterm_XA( dn1 );
3071 zterm_XA( dn2 );
3072
3073# undef TAGL
3074# undef TAGR
3075# undef XAGL
3076# undef XAGR
3077# undef TXTL
3078# undef TXTR
sewardjeadcd862006-04-04 15:12:44 +00003079}
3080
sewardj738856f2009-07-15 14:48:32 +00003081
sewardjb8b79ad2008-03-03 01:35:41 +00003082/* Determine if data_addr is a local variable in the frame
sewardj738856f2009-07-15 14:48:32 +00003083 characterised by (ip,sp,fp), and if so write its description at the
3084 ends of DNAME{1,2}, which are XArray*s of HChar, that have been
3085 initialised by the caller, zero terminate both, and return True.
3086 If it's not a local variable in said frame, return False. */
sewardjb8b79ad2008-03-03 01:35:41 +00003087static
sewardj738856f2009-07-15 14:48:32 +00003088Bool consider_vars_in_frame ( /*MOD*/XArray* /* of HChar */ dname1,
3089 /*MOD*/XArray* /* of HChar */ dname2,
sewardjb8b79ad2008-03-03 01:35:41 +00003090 Addr data_addr,
3091 Addr ip, Addr sp, Addr fp,
3092 /* shown to user: */
3093 ThreadId tid, Int frameNo )
sewardjeadcd862006-04-04 15:12:44 +00003094{
sewardjb8b79ad2008-03-03 01:35:41 +00003095 Word i;
3096 DebugInfo* di;
3097 RegSummary regs;
3098 Bool debug = False;
sewardjeadcd862006-04-04 15:12:44 +00003099
sewardjb8b79ad2008-03-03 01:35:41 +00003100 static UInt n_search = 0;
3101 static UInt n_steps = 0;
3102 n_search++;
3103 if (debug)
barta0b6b2c2008-07-07 06:49:24 +00003104 VG_(printf)("QQQQ: cvif: ip,sp,fp %#lx,%#lx,%#lx\n", ip,sp,fp);
sewardjb8b79ad2008-03-03 01:35:41 +00003105 /* first, find the DebugInfo that pertains to 'ip'. */
3106 for (di = debugInfo_list; di; di = di->next) {
3107 n_steps++;
3108 /* text segment missing? unlikely, but handle it .. */
3109 if (!di->text_present || di->text_size == 0)
3110 continue;
3111 /* Ok. So does this text mapping bracket the ip? */
3112 if (di->text_avma <= ip && ip < di->text_avma + di->text_size)
3113 break;
3114 }
3115
3116 /* Didn't find it. Strange -- means ip is a code address outside
3117 of any mapped text segment. Unlikely but not impossible -- app
3118 could be generating code to run. */
3119 if (!di)
3120 return False;
sewardjeadcd862006-04-04 15:12:44 +00003121
sewardjb8b79ad2008-03-03 01:35:41 +00003122 if (0 && ((n_search & 0x1) == 0))
3123 VG_(printf)("consider_vars_in_frame: %u searches, "
3124 "%u DebugInfos looked at\n",
3125 n_search, n_steps);
3126 /* Start of performance-enhancing hack: once every ??? (chosen
3127 hackily after profiling) successful searches, move the found
3128 DebugInfo one step closer to the start of the list. This makes
3129 future searches cheaper. */
3130 if ((n_search & 0xFFFF) == 0) {
3131 /* Move si one step closer to the start of the list. */
3132 move_DebugInfo_one_step_forward( di );
3133 }
3134 /* End of performance-enhancing hack. */
sewardjeadcd862006-04-04 15:12:44 +00003135
sewardjb8b79ad2008-03-03 01:35:41 +00003136 /* any var info at all? */
3137 if (!di->varinfo)
3138 return False;
sewardjeadcd862006-04-04 15:12:44 +00003139
sewardjb8b79ad2008-03-03 01:35:41 +00003140 /* Work through the scopes from most deeply nested outwards,
3141 looking for code address ranges that bracket 'ip'. The
3142 variables on each such address range found are in scope right
3143 now. Don't descend to level zero as that is the global
3144 scope. */
3145 regs.ip = ip;
3146 regs.sp = sp;
3147 regs.fp = fp;
sewardjeadcd862006-04-04 15:12:44 +00003148
sewardjb8b79ad2008-03-03 01:35:41 +00003149 /* "for each scope, working outwards ..." */
3150 for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) {
3151 XArray* vars;
3152 Word j;
3153 DiAddrRange* arange;
3154 OSet* this_scope
3155 = *(OSet**)VG_(indexXA)( di->varinfo, i );
3156 if (debug)
3157 VG_(printf)("QQQQ: considering scope %ld\n", (Word)i);
3158 if (!this_scope)
3159 continue;
3160 /* Find the set of variables in this scope that
3161 bracket the program counter. */
3162 arange = VG_(OSetGen_LookupWithCmp)(
3163 this_scope, &ip,
3164 ML_(cmp_for_DiAddrRange_range)
3165 );
3166 if (!arange)
3167 continue;
3168 /* stay sane */
3169 vg_assert(arange->aMin <= arange->aMax);
3170 /* It must bracket the ip we asked for, else
3171 ML_(cmp_for_DiAddrRange_range) is somehow broken. */
3172 vg_assert(arange->aMin <= ip && ip <= arange->aMax);
3173 /* It must have an attached XArray of DiVariables. */
3174 vars = arange->vars;
3175 vg_assert(vars);
3176 /* But it mustn't cover the entire address range. We only
3177 expect that to happen for the global scope (level 0), which
3178 we're not looking at here. Except, it may cover the entire
3179 address range, but in that case the vars array must be
3180 empty. */
3181 vg_assert(! (arange->aMin == (Addr)0
3182 && arange->aMax == ~(Addr)0
3183 && VG_(sizeXA)(vars) > 0) );
3184 for (j = 0; j < VG_(sizeXA)( vars ); j++) {
3185 DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j );
njnc4431bf2009-01-15 21:29:24 +00003186 PtrdiffT offset;
sewardjb8b79ad2008-03-03 01:35:41 +00003187 if (debug)
barta0b6b2c2008-07-07 06:49:24 +00003188 VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n",
sewardjb8b79ad2008-03-03 01:35:41 +00003189 var->name,arange->aMin,arange->aMax,ip);
sewardj9c606bd2008-09-18 18:12:50 +00003190 if (data_address_is_in_var( &offset, di->admin_tyents,
3191 var, &regs,
tom588658b2009-01-22 13:40:12 +00003192 data_addr, di )) {
njnc4431bf2009-01-15 21:29:24 +00003193 PtrdiffT residual_offset = 0;
sewardjb8b79ad2008-03-03 01:35:41 +00003194 XArray* described = ML_(describe_type)( &residual_offset,
sewardj9c606bd2008-09-18 18:12:50 +00003195 di->admin_tyents,
3196 var->typeR, offset );
sewardj738856f2009-07-15 14:48:32 +00003197 format_message( dname1, dname2,
sewardjb8b79ad2008-03-03 01:35:41 +00003198 data_addr, var, offset, residual_offset,
3199 described, frameNo, tid );
3200 VG_(deleteXA)( described );
3201 return True;
3202 }
sewardjab3698a2007-12-02 22:03:43 +00003203 }
sewardjeadcd862006-04-04 15:12:44 +00003204 }
3205
sewardjb8b79ad2008-03-03 01:35:41 +00003206 return False;
sewardjeadcd862006-04-04 15:12:44 +00003207}
3208
sewardj738856f2009-07-15 14:48:32 +00003209/* Try to form some description of DATA_ADDR by looking at the DWARF3
philippe25963372013-01-16 22:07:02 +00003210 debug info we have. This considers all global variables, and 8
sewardj738856f2009-07-15 14:48:32 +00003211 frames in the stacks of all threads. Result is written at the ends
3212 of DNAME{1,2}V, which are XArray*s of HChar, that have been
3213 initialised by the caller, and True is returned. If no description
3214 is created, False is returned. Regardless of the return value,
3215 DNAME{1,2}V are guaranteed to be zero terminated after the call.
3216
3217 Note that after the call, DNAME{1,2} may have more than one
3218 trailing zero, so callers should establish the useful text length
3219 using VG_(strlen) on the contents, rather than VG_(sizeXA) on the
3220 XArray itself.
3221*/
3222Bool VG_(get_data_description)(
3223 /*MOD*/ void* /* really, XArray* of HChar */ dname1v,
3224 /*MOD*/ void* /* really, XArray* of HChar */ dname2v,
3225 Addr data_addr
3226 )
sewardjbbec7722007-11-25 14:08:53 +00003227{
sewardjb8b79ad2008-03-03 01:35:41 +00003228# define N_FRAMES 8
3229 Addr ips[N_FRAMES], sps[N_FRAMES], fps[N_FRAMES];
3230 UInt n_frames;
3231
3232 Addr stack_min, stack_max;
3233 ThreadId tid;
3234 Bool found;
3235 DebugInfo* di;
3236 Word j;
3237
sewardj738856f2009-07-15 14:48:32 +00003238 XArray* dname1 = (XArray*)dname1v;
3239 XArray* dname2 = (XArray*)dname2v;
sewardjb8b79ad2008-03-03 01:35:41 +00003240
barta0b6b2c2008-07-07 06:49:24 +00003241 if (0) VG_(printf)("get_data_description: dataaddr %#lx\n", data_addr);
sewardjb8b79ad2008-03-03 01:35:41 +00003242 /* First, see if data_addr is (or is part of) a global variable.
3243 Loop over the DebugInfos we have. Check data_addr against the
3244 outermost scope of all of them, as that should be a global
3245 scope. */
3246 for (di = debugInfo_list; di != NULL; di = di->next) {
3247 OSet* global_scope;
sewardj9c606bd2008-09-18 18:12:50 +00003248 Word gs_size;
sewardjb8b79ad2008-03-03 01:35:41 +00003249 Addr zero;
3250 DiAddrRange* global_arange;
3251 Word i;
3252 XArray* vars;
3253
3254 /* text segment missing? unlikely, but handle it .. */
3255 if (!di->text_present || di->text_size == 0)
3256 continue;
3257 /* any var info at all? */
3258 if (!di->varinfo)
3259 continue;
3260 /* perhaps this object didn't contribute any vars at all? */
3261 if (VG_(sizeXA)( di->varinfo ) == 0)
3262 continue;
3263 global_scope = *(OSet**)VG_(indexXA)( di->varinfo, 0 );
3264 vg_assert(global_scope);
3265 gs_size = VG_(OSetGen_Size)( global_scope );
3266 /* The global scope might be completely empty if this
3267 compilation unit declared locals but nothing global. */
3268 if (gs_size == 0)
3269 continue;
3270 /* But if it isn't empty, then it must contain exactly one
3271 element, which covers the entire address range. */
3272 vg_assert(gs_size == 1);
3273 /* Fish out the global scope and check it is as expected. */
3274 zero = 0;
3275 global_arange
3276 = VG_(OSetGen_Lookup)( global_scope, &zero );
3277 /* The global range from (Addr)0 to ~(Addr)0 must exist */
3278 vg_assert(global_arange);
3279 vg_assert(global_arange->aMin == (Addr)0
3280 && global_arange->aMax == ~(Addr)0);
3281 /* Any vars in this range? */
3282 if (!global_arange->vars)
3283 continue;
3284 /* Ok, there are some vars in the global scope of this
3285 DebugInfo. Wade through them and see if the data addresses
3286 of any of them bracket data_addr. */
3287 vars = global_arange->vars;
3288 for (i = 0; i < VG_(sizeXA)( vars ); i++) {
njnc4431bf2009-01-15 21:29:24 +00003289 PtrdiffT offset;
sewardjb8b79ad2008-03-03 01:35:41 +00003290 DiVariable* var = (DiVariable*)VG_(indexXA)( vars, i );
3291 vg_assert(var->name);
3292 /* Note we use a NULL RegSummary* here. It can't make any
3293 sense for a global variable to have a location expression
3294 which depends on a SP/FP/IP value. So don't supply any.
3295 This means, if the evaluation of the location
3296 expression/list requires a register, we have to let it
3297 fail. */
sewardj9c606bd2008-09-18 18:12:50 +00003298 if (data_address_is_in_var( &offset, di->admin_tyents, var,
sewardjb8b79ad2008-03-03 01:35:41 +00003299 NULL/* RegSummary* */,
tom588658b2009-01-22 13:40:12 +00003300 data_addr, di )) {
njnc4431bf2009-01-15 21:29:24 +00003301 PtrdiffT residual_offset = 0;
sewardjb8b79ad2008-03-03 01:35:41 +00003302 XArray* described = ML_(describe_type)( &residual_offset,
sewardj9c606bd2008-09-18 18:12:50 +00003303 di->admin_tyents,
3304 var->typeR, offset );
sewardj738856f2009-07-15 14:48:32 +00003305 format_message( dname1, dname2,
sewardjb8b79ad2008-03-03 01:35:41 +00003306 data_addr, var, offset, residual_offset,
sewardjd7adca72011-05-04 09:06:17 +00003307 described, -1/*frameNo*/,
3308 VG_INVALID_THREADID );
sewardjb8b79ad2008-03-03 01:35:41 +00003309 VG_(deleteXA)( described );
sewardj738856f2009-07-15 14:48:32 +00003310 zterm_XA( dname1 );
3311 zterm_XA( dname2 );
sewardjb8b79ad2008-03-03 01:35:41 +00003312 return True;
3313 }
3314 }
sewardjbbec7722007-11-25 14:08:53 +00003315 }
sewardjb8b79ad2008-03-03 01:35:41 +00003316
3317 /* Ok, well it's not a global variable. So now let's snoop around
3318 in the stacks of all the threads. First try to figure out which
3319 thread's stack data_addr is in. */
3320
sewardjb8b79ad2008-03-03 01:35:41 +00003321 /* Perhaps it's on a thread's stack? */
3322 found = False;
3323 VG_(thread_stack_reset_iter)(&tid);
3324 while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) {
3325 if (stack_min >= stack_max)
3326 continue; /* ignore obviously stupid cases */
3327 if (stack_min - VG_STACK_REDZONE_SZB <= data_addr
3328 && data_addr <= stack_max) {
3329 found = True;
3330 break;
3331 }
3332 }
3333 if (!found) {
sewardj738856f2009-07-15 14:48:32 +00003334 zterm_XA( dname1 );
3335 zterm_XA( dname2 );
sewardjb8b79ad2008-03-03 01:35:41 +00003336 return False;
3337 }
3338
3339 /* We conclude data_addr is in thread tid's stack. Unwind the
3340 stack to get a bunch of (ip,sp,fp) triples describing the
3341 frames, and for each frame, consider the local variables. */
3342 n_frames = VG_(get_StackTrace)( tid, ips, N_FRAMES,
3343 sps, fps, 0/*first_ip_delta*/ );
sewardjb1ae15d2008-12-12 13:23:03 +00003344
sewardjb8b79ad2008-03-03 01:35:41 +00003345 vg_assert(n_frames >= 0 && n_frames <= N_FRAMES);
3346 for (j = 0; j < n_frames; j++) {
sewardj738856f2009-07-15 14:48:32 +00003347 if (consider_vars_in_frame( dname1, dname2,
sewardjb8b79ad2008-03-03 01:35:41 +00003348 data_addr,
sewardjb1ae15d2008-12-12 13:23:03 +00003349 ips[j],
sewardjb8b79ad2008-03-03 01:35:41 +00003350 sps[j], fps[j], tid, j )) {
sewardj738856f2009-07-15 14:48:32 +00003351 zterm_XA( dname1 );
3352 zterm_XA( dname2 );
sewardjb8b79ad2008-03-03 01:35:41 +00003353 return True;
3354 }
3355 /* Now, it appears that gcc sometimes appears to produce
3356 location lists whose ranges don't actually cover the call
3357 instruction, even though the address of the variable in
3358 question is passed as a parameter in the call. AFAICS this
3359 is simply a bug in gcc - how can the variable be claimed not
3360 exist in memory (on the stack) for the duration of a call in
3361 which its address is passed? But anyway, in the particular
3362 case I investigated (memcheck/tests/varinfo6.c, call to croak
3363 on line 2999, local var budget declared at line 3115
3364 appearing not to exist across the call to mainSort on line
3365 3143, "gcc.orig (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2)" on
3366 amd64), the variable's location list does claim it exists
3367 starting at the first byte of the first instruction after the
3368 call instruction. So, call consider_vars_in_frame a second
sewardjb1ae15d2008-12-12 13:23:03 +00003369 time, but this time add 1 to the IP. GDB handles this
3370 example with no difficulty, which leads me to believe that
3371 either (1) I misunderstood something, or (2) GDB has an
3372 equivalent kludge. */
3373 if (j > 0 /* this is a non-innermost frame */
sewardj738856f2009-07-15 14:48:32 +00003374 && consider_vars_in_frame( dname1, dname2,
sewardjb1ae15d2008-12-12 13:23:03 +00003375 data_addr,
3376 ips[j] + 1,
3377 sps[j], fps[j], tid, j )) {
sewardj738856f2009-07-15 14:48:32 +00003378 zterm_XA( dname1 );
3379 zterm_XA( dname2 );
sewardjb8b79ad2008-03-03 01:35:41 +00003380 return True;
3381 }
3382 }
3383
3384 /* We didn't find anything useful. */
sewardj738856f2009-07-15 14:48:32 +00003385 zterm_XA( dname1 );
3386 zterm_XA( dname2 );
sewardjb8b79ad2008-03-03 01:35:41 +00003387 return False;
3388# undef N_FRAMES
sewardjbbec7722007-11-25 14:08:53 +00003389}
3390
sewardjb8b79ad2008-03-03 01:35:41 +00003391
sewardj9c606bd2008-09-18 18:12:50 +00003392//////////////////////////////////////////////////////////////////
3393// //
3394// Support for other kinds of queries to the Dwarf3 var info //
3395// //
3396//////////////////////////////////////////////////////////////////
3397
3398/* Figure out if the variable 'var' has a location that is linearly
3399 dependent on a stack pointer value, or a frame pointer value, and
3400 if it is, add a description of it to 'blocks'. Otherwise ignore
3401 it. If 'arrays_only' is True, also ignore it unless it has an
3402 array type. */
3403
3404static
3405void analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks,
3406 XArray* /* TyEnt */ tyents,
tom588658b2009-01-22 13:40:12 +00003407 Addr ip, const DebugInfo* di, DiVariable* var,
sewardj9c606bd2008-09-18 18:12:50 +00003408 Bool arrays_only )
3409{
3410 GXResult res_sp_6k, res_sp_7k, res_fp_6k, res_fp_7k;
3411 RegSummary regs;
sewardj50fde232008-10-20 16:08:55 +00003412 MaybeULong mul;
sewardj9c606bd2008-09-18 18:12:50 +00003413 Bool isVec;
3414 TyEnt* ty;
3415
3416 Bool debug = False;
3417 if (0&&debug)
3418 VG_(printf)("adeps: var %s\n", var->name );
3419
3420 /* Figure out how big the variable is. */
sewardj50fde232008-10-20 16:08:55 +00003421 mul = ML_(sizeOfType)(tyents, var->typeR);
3422 /* If this var has a type whose size is unknown, zero, or
3423 impossibly large, it should never have been added. ML_(addVar)
3424 should have rejected it. */
3425 vg_assert(mul.b == True);
3426 vg_assert(mul.ul > 0);
3427 if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
3428 /* After this point, we assume we can truncate mul.ul to a host word
3429 safely (without loss of info). */
sewardj9c606bd2008-09-18 18:12:50 +00003430
3431 /* skip if non-array and we're only interested in arrays */
3432 ty = ML_(TyEnts__index_by_cuOff)( tyents, NULL, var->typeR );
3433 vg_assert(ty);
3434 vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty));
3435 if (ty->tag == Te_UNKNOWN)
3436 return; /* perhaps we should complain in this case? */
3437 isVec = ty->tag == Te_TyArray;
3438 if (arrays_only && !isVec)
3439 return;
3440
3441 if (0) {ML_(pp_TyEnt_C_ishly)(tyents, var->typeR);
3442 VG_(printf)(" %s\n", var->name);}
3443
3444 /* Do some test evaluations of the variable's location expression,
3445 in order to guess whether it is sp-relative, fp-relative, or
3446 none. A crude hack, which can be interpreted roughly as finding
3447 the first derivative of the location expression w.r.t. the
3448 supplied frame and stack pointer values. */
3449 regs.fp = 0;
3450 regs.ip = ip;
3451 regs.sp = 6 * 1024;
tom588658b2009-01-22 13:40:12 +00003452 res_sp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
sewardj9c606bd2008-09-18 18:12:50 +00003453
3454 regs.fp = 0;
3455 regs.ip = ip;
3456 regs.sp = 7 * 1024;
tom588658b2009-01-22 13:40:12 +00003457 res_sp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
sewardj9c606bd2008-09-18 18:12:50 +00003458
3459 regs.fp = 6 * 1024;
3460 regs.ip = ip;
3461 regs.sp = 0;
tom588658b2009-01-22 13:40:12 +00003462 res_fp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
sewardj9c606bd2008-09-18 18:12:50 +00003463
3464 regs.fp = 7 * 1024;
3465 regs.ip = ip;
3466 regs.sp = 0;
tom588658b2009-01-22 13:40:12 +00003467 res_fp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
sewardj9c606bd2008-09-18 18:12:50 +00003468
3469 vg_assert(res_sp_6k.kind == res_sp_7k.kind);
3470 vg_assert(res_sp_6k.kind == res_fp_6k.kind);
3471 vg_assert(res_sp_6k.kind == res_fp_7k.kind);
3472
tom3c9cf342009-11-12 13:28:34 +00003473 if (res_sp_6k.kind == GXR_Addr) {
sewardj9c606bd2008-09-18 18:12:50 +00003474 StackBlock block;
3475 GXResult res;
3476 UWord sp_delta = res_sp_7k.word - res_sp_6k.word;
3477 UWord fp_delta = res_fp_7k.word - res_fp_6k.word;
3478 tl_assert(sp_delta == 0 || sp_delta == 1024);
3479 tl_assert(fp_delta == 0 || fp_delta == 1024);
3480
3481 if (sp_delta == 0 && fp_delta == 0) {
3482 /* depends neither on sp nor fp, so it can't be a stack
3483 local. Ignore it. */
3484 }
3485 else
3486 if (sp_delta == 1024 && fp_delta == 0) {
3487 regs.sp = regs.fp = 0;
3488 regs.ip = ip;
tom588658b2009-01-22 13:40:12 +00003489 res = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
tom3c9cf342009-11-12 13:28:34 +00003490 tl_assert(res.kind == GXR_Addr);
sewardj9c606bd2008-09-18 18:12:50 +00003491 if (debug)
3492 VG_(printf)(" %5ld .. %5ld (sp) %s\n",
sewardj50fde232008-10-20 16:08:55 +00003493 res.word, res.word + ((UWord)mul.ul) - 1, var->name);
sewardj9c606bd2008-09-18 18:12:50 +00003494 block.base = res.word;
sewardj50fde232008-10-20 16:08:55 +00003495 block.szB = (SizeT)mul.ul;
sewardj9c606bd2008-09-18 18:12:50 +00003496 block.spRel = True;
3497 block.isVec = isVec;
3498 VG_(memset)( &block.name[0], 0, sizeof(block.name) );
3499 if (var->name)
3500 VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 );
3501 block.name[ sizeof(block.name)-1 ] = 0;
3502 VG_(addToXA)( blocks, &block );
3503 }
3504 else
3505 if (sp_delta == 0 && fp_delta == 1024) {
3506 regs.sp = regs.fp = 0;
3507 regs.ip = ip;
tom588658b2009-01-22 13:40:12 +00003508 res = ML_(evaluate_GX)( var->gexpr, var->fbGX, &regs, di );
tom3c9cf342009-11-12 13:28:34 +00003509 tl_assert(res.kind == GXR_Addr);
sewardj9c606bd2008-09-18 18:12:50 +00003510 if (debug)
3511 VG_(printf)(" %5ld .. %5ld (FP) %s\n",
sewardj50fde232008-10-20 16:08:55 +00003512 res.word, res.word + ((UWord)mul.ul) - 1, var->name);
sewardj9c606bd2008-09-18 18:12:50 +00003513 block.base = res.word;
sewardj50fde232008-10-20 16:08:55 +00003514 block.szB = (SizeT)mul.ul;
sewardj9c606bd2008-09-18 18:12:50 +00003515 block.spRel = False;
3516 block.isVec = isVec;
3517 VG_(memset)( &block.name[0], 0, sizeof(block.name) );
3518 if (var->name)
3519 VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 );
3520 block.name[ sizeof(block.name)-1 ] = 0;
3521 VG_(addToXA)( blocks, &block );
3522 }
3523 else {
3524 vg_assert(0);
3525 }
3526 }
3527}
3528
3529
3530/* Get an XArray of StackBlock which describe the stack (auto) blocks
3531 for this ip. The caller is expected to free the XArray at some
3532 point. If 'arrays_only' is True, only array-typed blocks are
3533 returned; otherwise blocks of all types are returned. */
3534
3535void* /* really, XArray* of StackBlock */
3536 VG_(di_get_stack_blocks_at_ip)( Addr ip, Bool arrays_only )
3537{
3538 /* This is a derivation of consider_vars_in_frame() above. */
3539 Word i;
3540 DebugInfo* di;
sewardj9c606bd2008-09-18 18:12:50 +00003541 Bool debug = False;
3542
3543 XArray* res = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dgsbai.1",
3544 ML_(dinfo_free),
3545 sizeof(StackBlock) );
3546
3547 static UInt n_search = 0;
3548 static UInt n_steps = 0;
3549 n_search++;
3550 if (debug)
3551 VG_(printf)("QQQQ: dgsbai: ip %#lx\n", ip);
3552 /* first, find the DebugInfo that pertains to 'ip'. */
3553 for (di = debugInfo_list; di; di = di->next) {
3554 n_steps++;
3555 /* text segment missing? unlikely, but handle it .. */
3556 if (!di->text_present || di->text_size == 0)
3557 continue;
3558 /* Ok. So does this text mapping bracket the ip? */
3559 if (di->text_avma <= ip && ip < di->text_avma + di->text_size)
3560 break;
3561 }
3562
3563 /* Didn't find it. Strange -- means ip is a code address outside
3564 of any mapped text segment. Unlikely but not impossible -- app
3565 could be generating code to run. */
3566 if (!di)
3567 return res; /* currently empty */
3568
3569 if (0 && ((n_search & 0x1) == 0))
3570 VG_(printf)("VG_(di_get_stack_blocks_at_ip): %u searches, "
3571 "%u DebugInfos looked at\n",
3572 n_search, n_steps);
3573 /* Start of performance-enhancing hack: once every ??? (chosen
3574 hackily after profiling) successful searches, move the found
3575 DebugInfo one step closer to the start of the list. This makes
3576 future searches cheaper. */
3577 if ((n_search & 0xFFFF) == 0) {
3578 /* Move si one step closer to the start of the list. */
3579 move_DebugInfo_one_step_forward( di );
3580 }
3581 /* End of performance-enhancing hack. */
3582
3583 /* any var info at all? */
3584 if (!di->varinfo)
3585 return res; /* currently empty */
3586
3587 /* Work through the scopes from most deeply nested outwards,
3588 looking for code address ranges that bracket 'ip'. The
3589 variables on each such address range found are in scope right
3590 now. Don't descend to level zero as that is the global
3591 scope. */
sewardj9c606bd2008-09-18 18:12:50 +00003592
3593 /* "for each scope, working outwards ..." */
3594 for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) {
3595 XArray* vars;
3596 Word j;
3597 DiAddrRange* arange;
3598 OSet* this_scope
3599 = *(OSet**)VG_(indexXA)( di->varinfo, i );
3600 if (debug)
3601 VG_(printf)("QQQQ: considering scope %ld\n", (Word)i);
3602 if (!this_scope)
3603 continue;
3604 /* Find the set of variables in this scope that
3605 bracket the program counter. */
3606 arange = VG_(OSetGen_LookupWithCmp)(
3607 this_scope, &ip,
3608 ML_(cmp_for_DiAddrRange_range)
3609 );
3610 if (!arange)
3611 continue;
3612 /* stay sane */
3613 vg_assert(arange->aMin <= arange->aMax);
3614 /* It must bracket the ip we asked for, else
3615 ML_(cmp_for_DiAddrRange_range) is somehow broken. */
3616 vg_assert(arange->aMin <= ip && ip <= arange->aMax);
3617 /* It must have an attached XArray of DiVariables. */
3618 vars = arange->vars;
3619 vg_assert(vars);
3620 /* But it mustn't cover the entire address range. We only
3621 expect that to happen for the global scope (level 0), which
3622 we're not looking at here. Except, it may cover the entire
3623 address range, but in that case the vars array must be
3624 empty. */
3625 vg_assert(! (arange->aMin == (Addr)0
3626 && arange->aMax == ~(Addr)0
3627 && VG_(sizeXA)(vars) > 0) );
3628 for (j = 0; j < VG_(sizeXA)( vars ); j++) {
3629 DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j );
3630 if (debug)
3631 VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n",
3632 var->name,arange->aMin,arange->aMax,ip);
3633 analyse_deps( res, di->admin_tyents, ip,
tom588658b2009-01-22 13:40:12 +00003634 di, var, arrays_only );
sewardj9c606bd2008-09-18 18:12:50 +00003635 }
3636 }
3637
3638 return res;
3639}
3640
3641
3642/* Get an array of GlobalBlock which describe the global blocks owned
3643 by the shared object characterised by the given di_handle. Asserts
3644 if the handle is invalid. The caller is responsible for freeing
3645 the array at some point. If 'arrays_only' is True, only
3646 array-typed blocks are returned; otherwise blocks of all types are
3647 returned. */
3648
3649void* /* really, XArray* of GlobalBlock */
3650 VG_(di_get_global_blocks_from_dihandle) ( ULong di_handle,
3651 Bool arrays_only )
3652{
3653 /* This is a derivation of consider_vars_in_frame() above. */
3654
3655 DebugInfo* di;
3656 XArray* gvars; /* XArray* of GlobalBlock */
3657 Word nScopes, scopeIx;
3658
3659 /* The first thing to do is find the DebugInfo that
3660 pertains to 'di_handle'. */
3661 tl_assert(di_handle > 0);
3662 for (di = debugInfo_list; di; di = di->next) {
3663 if (di->handle == di_handle)
3664 break;
3665 }
3666
3667 /* If this fails, we were unable to find any DebugInfo with the
3668 given handle. This is considered an error on the part of the
3669 caller. */
3670 tl_assert(di != NULL);
3671
3672 /* we'll put the collected variables in here. */
3673 gvars = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dggbfd.1",
3674 ML_(dinfo_free), sizeof(GlobalBlock) );
3675 tl_assert(gvars);
3676
3677 /* any var info at all? */
3678 if (!di->varinfo)
3679 return gvars;
3680
3681 /* we'll iterate over all the variables we can find, even if
3682 it seems senseless to visit stack-allocated variables */
3683 /* Iterate over all scopes */
3684 nScopes = VG_(sizeXA)( di->varinfo );
3685 for (scopeIx = 0; scopeIx < nScopes; scopeIx++) {
3686
3687 /* Iterate over each (code) address range at the current scope */
3688 DiAddrRange* range;
3689 OSet* /* of DiAddrInfo */ scope
3690 = *(OSet**)VG_(indexXA)( di->varinfo, scopeIx );
3691 tl_assert(scope);
3692 VG_(OSetGen_ResetIter)(scope);
3693 while ( (range = VG_(OSetGen_Next)(scope)) ) {
3694
3695 /* Iterate over each variable in the current address range */
3696 Word nVars, varIx;
3697 tl_assert(range->vars);
3698 nVars = VG_(sizeXA)( range->vars );
3699 for (varIx = 0; varIx < nVars; varIx++) {
3700
3701 Bool isVec;
3702 GXResult res;
sewardj50fde232008-10-20 16:08:55 +00003703 MaybeULong mul;
sewardj9c606bd2008-09-18 18:12:50 +00003704 GlobalBlock gb;
3705 TyEnt* ty;
3706 DiVariable* var = VG_(indexXA)( range->vars, varIx );
3707 tl_assert(var->name);
3708 if (0) VG_(printf)("at depth %ld var %s ", scopeIx, var->name );
3709
3710 /* Now figure out if this variable has a constant address
3711 (that is, independent of FP, SP, phase of moon, etc),
3712 and if so, what the address is. Any variable with a
3713 constant address is deemed to be a global so we collect
3714 it. */
3715 if (0) { VG_(printf)("EVAL: "); ML_(pp_GX)(var->gexpr);
3716 VG_(printf)("\n"); }
tom588658b2009-01-22 13:40:12 +00003717 res = ML_(evaluate_trivial_GX)( var->gexpr, di );
sewardj9c606bd2008-09-18 18:12:50 +00003718
3719 /* Not a constant address => not interesting */
tom3c9cf342009-11-12 13:28:34 +00003720 if (res.kind != GXR_Addr) {
sewardj9c606bd2008-09-18 18:12:50 +00003721 if (0) VG_(printf)("FAIL\n");
3722 continue;
3723 }
3724
3725 /* Ok, it's a constant address. See if we want to collect
3726 it. */
3727 if (0) VG_(printf)("%#lx\n", res.word);
3728
3729 /* Figure out how big the variable is. */
sewardj50fde232008-10-20 16:08:55 +00003730 mul = ML_(sizeOfType)(di->admin_tyents, var->typeR);
sewardj9c606bd2008-09-18 18:12:50 +00003731
sewardj50fde232008-10-20 16:08:55 +00003732 /* If this var has a type whose size is unknown, zero, or
3733 impossibly large, it should never have been added.
3734 ML_(addVar) should have rejected it. */
3735 vg_assert(mul.b == True);
3736 vg_assert(mul.ul > 0);
3737 if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32));
3738 /* After this point, we assume we can truncate mul.ul to a
3739 host word safely (without loss of info). */
sewardj9c606bd2008-09-18 18:12:50 +00003740
3741 /* skip if non-array and we're only interested in
3742 arrays */
3743 ty = ML_(TyEnts__index_by_cuOff)( di->admin_tyents, NULL,
3744 var->typeR );
3745 vg_assert(ty);
3746 vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty));
3747 if (ty->tag == Te_UNKNOWN)
3748 continue; /* perhaps we should complain in this case? */
3749
3750 isVec = ty->tag == Te_TyArray;
3751 if (arrays_only && !isVec) continue;
3752
3753 /* Ok, so collect it! */
3754 tl_assert(var->name);
3755 tl_assert(di->soname);
3756 if (0) VG_(printf)("XXXX %s %s %d\n", var->name,
3757 var->fileName?(HChar*)var->fileName
3758 :"??",var->lineNo);
3759 VG_(memset)(&gb, 0, sizeof(gb));
3760 gb.addr = res.word;
sewardj50fde232008-10-20 16:08:55 +00003761 gb.szB = (SizeT)mul.ul;
sewardj9c606bd2008-09-18 18:12:50 +00003762 gb.isVec = isVec;
3763 VG_(strncpy)(&gb.name[0], var->name, sizeof(gb.name)-1);
3764 VG_(strncpy)(&gb.soname[0], di->soname, sizeof(gb.soname)-1);
3765 tl_assert(gb.name[ sizeof(gb.name)-1 ] == 0);
3766 tl_assert(gb.soname[ sizeof(gb.soname)-1 ] == 0);
3767
3768 VG_(addToXA)( gvars, &gb );
3769
3770 } /* for (varIx = 0; varIx < nVars; varIx++) */
3771
3772 } /* while ( (range = VG_(OSetGen_Next)(scope)) ) */
3773
3774 } /* for (scopeIx = 0; scopeIx < nScopes; scopeIx++) */
3775
3776 return gvars;
3777}
3778
3779
sewardjb8b79ad2008-03-03 01:35:41 +00003780/*------------------------------------------------------------*/
3781/*--- DebugInfo accessor functions ---*/
3782/*------------------------------------------------------------*/
3783
sewardje3f1e592009-07-31 09:41:29 +00003784const DebugInfo* VG_(next_DebugInfo)(const DebugInfo* di)
sewardjb8b79ad2008-03-03 01:35:41 +00003785{
3786 if (di == NULL)
3787 return debugInfo_list;
3788 return di->next;
3789}
3790
sewardje3f1e592009-07-31 09:41:29 +00003791Addr VG_(DebugInfo_get_text_avma)(const DebugInfo* di)
sewardjb8b79ad2008-03-03 01:35:41 +00003792{
3793 return di->text_present ? di->text_avma : 0;
3794}
3795
sewardje3f1e592009-07-31 09:41:29 +00003796SizeT VG_(DebugInfo_get_text_size)(const DebugInfo* di)
sewardjb8b79ad2008-03-03 01:35:41 +00003797{
3798 return di->text_present ? di->text_size : 0;
3799}
3800
bart38980222013-08-24 17:52:26 +00003801Addr VG_(DebugInfo_get_bss_avma)(const DebugInfo* di)
3802{
3803 return di->bss_present ? di->bss_avma : 0;
3804}
3805
3806SizeT VG_(DebugInfo_get_bss_size)(const DebugInfo* di)
3807{
3808 return di->bss_present ? di->bss_size : 0;
3809}
3810
sewardje3f1e592009-07-31 09:41:29 +00003811Addr VG_(DebugInfo_get_plt_avma)(const DebugInfo* di)
bart092b6262008-05-25 16:37:22 +00003812{
3813 return di->plt_present ? di->plt_avma : 0;
3814}
3815
sewardje3f1e592009-07-31 09:41:29 +00003816SizeT VG_(DebugInfo_get_plt_size)(const DebugInfo* di)
bart092b6262008-05-25 16:37:22 +00003817{
3818 return di->plt_present ? di->plt_size : 0;
3819}
3820
sewardje3f1e592009-07-31 09:41:29 +00003821Addr VG_(DebugInfo_get_gotplt_avma)(const DebugInfo* di)
bart092b6262008-05-25 16:37:22 +00003822{
3823 return di->gotplt_present ? di->gotplt_avma : 0;
3824}
3825
sewardje3f1e592009-07-31 09:41:29 +00003826SizeT VG_(DebugInfo_get_gotplt_size)(const DebugInfo* di)
bart092b6262008-05-25 16:37:22 +00003827{
3828 return di->gotplt_present ? di->gotplt_size : 0;
3829}
3830
bart68347832012-09-06 14:08:26 +00003831Addr VG_(DebugInfo_get_got_avma)(const DebugInfo* di)
3832{
3833 return di->got_present ? di->got_avma : 0;
3834}
3835
3836SizeT VG_(DebugInfo_get_got_size)(const DebugInfo* di)
3837{
3838 return di->got_present ? di->got_size : 0;
3839}
3840
florian1636d332012-11-15 04:27:04 +00003841const HChar* VG_(DebugInfo_get_soname)(const DebugInfo* di)
sewardjb8b79ad2008-03-03 01:35:41 +00003842{
3843 return di->soname;
3844}
3845
florian1636d332012-11-15 04:27:04 +00003846const HChar* VG_(DebugInfo_get_filename)(const DebugInfo* di)
sewardjb8b79ad2008-03-03 01:35:41 +00003847{
sewardja5acac32011-09-20 21:59:50 +00003848 return di->fsm.filename;
sewardjb8b79ad2008-03-03 01:35:41 +00003849}
3850
sewardje3f1e592009-07-31 09:41:29 +00003851PtrdiffT VG_(DebugInfo_get_text_bias)(const DebugInfo* di)
sewardjb8b79ad2008-03-03 01:35:41 +00003852{
3853 return di->text_present ? di->text_bias : 0;
3854}
3855
sewardje3f1e592009-07-31 09:41:29 +00003856Int VG_(DebugInfo_syms_howmany) ( const DebugInfo *si )
sewardjeadcd862006-04-04 15:12:44 +00003857{
3858 return si->symtab_used;
3859}
3860
sewardje3f1e592009-07-31 09:41:29 +00003861void VG_(DebugInfo_syms_getidx) ( const DebugInfo *si,
3862 Int idx,
sewardja5cace02011-08-15 09:42:34 +00003863 /*OUT*/Addr* avma,
3864 /*OUT*/Addr* tocptr,
3865 /*OUT*/UInt* size,
florian19f91bb2012-11-10 22:29:54 +00003866 /*OUT*/HChar** pri_name,
3867 /*OUT*/HChar*** sec_names,
sewardja5cace02011-08-15 09:42:34 +00003868 /*OUT*/Bool* isText,
3869 /*OUT*/Bool* isIFunc )
sewardjeadcd862006-04-04 15:12:44 +00003870{
3871 vg_assert(idx >= 0 && idx < si->symtab_used);
sewardja5cace02011-08-15 09:42:34 +00003872 if (avma) *avma = si->symtab[idx].addr;
3873 if (tocptr) *tocptr = si->symtab[idx].tocptr;
3874 if (size) *size = si->symtab[idx].size;
3875 if (pri_name) *pri_name = si->symtab[idx].pri_name;
florian19f91bb2012-11-10 22:29:54 +00003876 if (sec_names) *sec_names = (HChar **)si->symtab[idx].sec_names; // FIXME
sewardja5cace02011-08-15 09:42:34 +00003877 if (isText) *isText = si->symtab[idx].isText;
3878 if (isIFunc) *isIFunc = si->symtab[idx].isIFunc;
sewardjb8b79ad2008-03-03 01:35:41 +00003879}
3880
3881
3882/*------------------------------------------------------------*/
3883/*--- SectKind query functions ---*/
3884/*------------------------------------------------------------*/
3885
3886/* Convert a VgSectKind to a string, which must be copied if you want
3887 to change it. */
3888const HChar* VG_(pp_SectKind)( VgSectKind kind )
3889{
3890 switch (kind) {
3891 case Vg_SectUnknown: return "Unknown";
3892 case Vg_SectText: return "Text";
3893 case Vg_SectData: return "Data";
3894 case Vg_SectBSS: return "BSS";
3895 case Vg_SectGOT: return "GOT";
3896 case Vg_SectPLT: return "PLT";
3897 case Vg_SectOPD: return "OPD";
sewardj5706ca92009-01-22 21:18:15 +00003898 case Vg_SectGOTPLT: return "GOTPLT";
sewardjb8b79ad2008-03-03 01:35:41 +00003899 default: vg_assert(0);
3900 }
3901}
3902
3903/* Given an address 'a', make a guess of which section of which object
3904 it comes from. If name is non-NULL, then the last n_name-1
3905 characters of the object's name is put in name[0 .. n_name-2], and
3906 name[n_name-1] is set to zero (guaranteed zero terminated). */
3907
florian1636d332012-11-15 04:27:04 +00003908VgSectKind VG_(DebugInfo_sect_kind)( /*OUT*/HChar* name, SizeT n_name,
sewardje3f1e592009-07-31 09:41:29 +00003909 Addr a)
sewardjb8b79ad2008-03-03 01:35:41 +00003910{
3911 DebugInfo* di;
3912 VgSectKind res = Vg_SectUnknown;
3913
3914 for (di = debugInfo_list; di != NULL; di = di->next) {
3915
3916 if (0)
3917 VG_(printf)(
sewardje3f1e592009-07-31 09:41:29 +00003918 "addr=%#lx di=%p %s got=%#lx,%ld plt=%#lx,%ld "
3919 "data=%#lx,%ld bss=%#lx,%ld\n",
sewardja5acac32011-09-20 21:59:50 +00003920 a, di, di->fsm.filename,
sewardjb8b79ad2008-03-03 01:35:41 +00003921 di->got_avma, di->got_size,
3922 di->plt_avma, di->plt_size,
3923 di->data_avma, di->data_size,
3924 di->bss_avma, di->bss_size);
3925
3926 if (di->text_present
3927 && di->text_size > 0
3928 && a >= di->text_avma && a < di->text_avma + di->text_size) {
3929 res = Vg_SectText;
3930 break;
3931 }
3932 if (di->data_present
3933 && di->data_size > 0
3934 && a >= di->data_avma && a < di->data_avma + di->data_size) {
3935 res = Vg_SectData;
3936 break;
3937 }
3938 if (di->sdata_present
3939 && di->sdata_size > 0
3940 && a >= di->sdata_avma && a < di->sdata_avma + di->sdata_size) {
3941 res = Vg_SectData;
3942 break;
3943 }
3944 if (di->bss_present
3945 && di->bss_size > 0
3946 && a >= di->bss_avma && a < di->bss_avma + di->bss_size) {
3947 res = Vg_SectBSS;
3948 break;
3949 }
sewardj5706ca92009-01-22 21:18:15 +00003950 if (di->sbss_present
3951 && di->sbss_size > 0
3952 && a >= di->sbss_avma && a < di->sbss_avma + di->sbss_size) {
3953 res = Vg_SectBSS;
3954 break;
3955 }
sewardjb8b79ad2008-03-03 01:35:41 +00003956 if (di->plt_present
3957 && di->plt_size > 0
3958 && a >= di->plt_avma && a < di->plt_avma + di->plt_size) {
3959 res = Vg_SectPLT;
3960 break;
3961 }
3962 if (di->got_present
3963 && di->got_size > 0
3964 && a >= di->got_avma && a < di->got_avma + di->got_size) {
3965 res = Vg_SectGOT;
3966 break;
3967 }
bart092b6262008-05-25 16:37:22 +00003968 if (di->gotplt_present
3969 && di->gotplt_size > 0
3970 && a >= di->gotplt_avma && a < di->gotplt_avma + di->gotplt_size) {
3971 res = Vg_SectGOTPLT;
3972 break;
3973 }
sewardjb8b79ad2008-03-03 01:35:41 +00003974 if (di->opd_present
3975 && di->opd_size > 0
3976 && a >= di->opd_avma && a < di->opd_avma + di->opd_size) {
3977 res = Vg_SectOPD;
3978 break;
3979 }
3980 /* we could also check for .eh_frame, if anyone really cares */
3981 }
3982
3983 vg_assert( (di == NULL && res == Vg_SectUnknown)
3984 || (di != NULL && res != Vg_SectUnknown) );
3985
3986 if (name) {
3987
3988 vg_assert(n_name >= 8);
3989
sewardja5acac32011-09-20 21:59:50 +00003990 if (di && di->fsm.filename) {
sewardjb8b79ad2008-03-03 01:35:41 +00003991 Int i, j;
sewardja5acac32011-09-20 21:59:50 +00003992 Int fnlen = VG_(strlen)(di->fsm.filename);
sewardjb8b79ad2008-03-03 01:35:41 +00003993 Int start_at = 1 + fnlen - n_name;
3994 if (start_at < 0) start_at = 0;
3995 vg_assert(start_at < fnlen);
3996 i = start_at; j = 0;
3997 while (True) {
bartd5dea1d2008-05-25 16:25:51 +00003998 vg_assert(j >= 0 && j < n_name);
sewardjb8b79ad2008-03-03 01:35:41 +00003999 vg_assert(i >= 0 && i <= fnlen);
sewardja5acac32011-09-20 21:59:50 +00004000 name[j] = di->fsm.filename[i];
4001 if (di->fsm.filename[i] == 0) break;
sewardjb8b79ad2008-03-03 01:35:41 +00004002 i++; j++;
4003 }
bartd5dea1d2008-05-25 16:25:51 +00004004 vg_assert(i == fnlen);
sewardjb8b79ad2008-03-03 01:35:41 +00004005 } else {
4006 VG_(snprintf)(name, n_name, "%s", "???");
4007 }
4008
4009 name[n_name-1] = 0;
4010 }
4011
4012 return res;
4013
sewardjeadcd862006-04-04 15:12:44 +00004014}
4015
sewardjeadcd862006-04-04 15:12:44 +00004016/*--------------------------------------------------------------------*/
4017/*--- end ---*/
4018/*--------------------------------------------------------------------*/