debuginfo.c revision 0ab84fe82d1e25c2e0544d08826df42caa44ded1
1eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 3eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Top level management of symbols and debugging information. ---*/ 4eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- debuginfo.c ---*/ 5eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 6eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 7eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* 8eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj This file is part of Valgrind, a dynamic binary instrumentation 9eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj framework. 10eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1103f8d3fc25f5a45c5826259d1b33b7f310117279sewardj Copyright (C) 2000-2012 Julian Seward 12eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj jseward@acm.org 13eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 14eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj This program is free software; you can redistribute it and/or 15eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj modify it under the terms of the GNU General Public License as 16eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj published by the Free Software Foundation; either version 2 of the 17eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj License, or (at your option) any later version. 18eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 19eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj This program is distributed in the hope that it will be useful, but 20eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj WITHOUT ANY WARRANTY; without even the implied warranty of 21eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj General Public License for more details. 23eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 24eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj You should have received a copy of the GNU General Public License 25eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj along with this program; if not, write to the Free Software 26eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 27eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 02111-1307, USA. 28eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 29eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj The GNU General Public License is contained in the file COPYING. 30eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 31eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 32eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_basics.h" 334cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj#include "pub_core_vki.h" 346c591e15c1d6402a2a755310f005f795b68e7e38sewardj#include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy 35eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_threadstate.h" 36b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_debuginfo.h" /* self */ 37eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_demangle.h" 38eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_libcbase.h" 39eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_libcassert.h" 40eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_libcprint.h" 41b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_libcfile.h" 4213ac96dea734b3933a73524b991ac64fb48a4d57sewardj#include "pub_core_libcproc.h" // VG_(getenv) 43d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj#include "pub_core_seqmatch.h" 44eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_options.h" 45b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_redir.h" // VG_(redir_notify_{new,delete}_SegInfo) 46eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_aspacemgr.h" 47b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_machine.h" // VG_PLAT_USES_PPCTOC 4872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj#include "pub_core_xarray.h" 49b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_oset.h" 506882443ef154bca367bc591287de641e43a9e108njn#include "pub_core_stacktrace.h" // VG_(get_StackTrace) XXX: circular dependency 51f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#include "pub_core_ume.h" 52b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 53b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_misc.h" /* dinfo_zalloc/free */ 54b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_d3basics.h" /* ML_(pp_GX) */ 55b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_tytypes.h" 56eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "priv_storage.h" 57eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "priv_readdwarf.h" 58eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "priv_readstabs.h" 594ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#if defined(VGO_linux) 604ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# include "priv_readelf.h" 61b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# include "priv_readdwarf3.h" 62c8259b85b701d25d72aabe9dc0a8154517f96913sewardj# include "priv_readpdb.h" 63f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(VGO_darwin) 64f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# include "priv_readmacho.h" 65f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# include "priv_readpdb.h" 664ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#endif 67eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 68c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 69c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/*------------------------------------------------------------*/ 70c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/*--- The _svma / _avma / _image / _bias naming scheme ---*/ 71c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/*------------------------------------------------------------*/ 72c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 73c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/* JRS 11 Jan 07: I find the different kinds of addresses involved in 74c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj debuginfo reading confusing. Recently I arrived at some 75c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj terminology which makes it clearer (to me, at least). There are 3 76c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj kinds of address used in the debuginfo reading process: 77c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 78c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj stated VMAs - the address where (eg) a .so says a symbol is, that 79c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj is, what it tells you if you consider the .so in 80c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj isolation 81c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 82c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj actual VMAs - the address where (eg) said symbol really wound up 83c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj after the .so was mapped into memory 84c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 85c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj image addresses - pointers into the copy of the .so (etc) 86c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj transiently mmaped aboard whilst we read its info 87c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 88c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj Additionally I use the term 'bias' to denote the difference 89c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj between stated and actual VMAs for a given entity. 90c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 91c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj This terminology is not used consistently, but a start has been 92c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj made. readelf.c and the call-frame info reader in readdwarf.c now 93c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj use it. Specifically, various variables and structure fields have 94f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj been annotated with _avma / _svma / _image / _bias. In places _img 95f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj is used instead of _image for the sake of brevity. 96c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj*/ 97c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 98c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 99eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 100f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- fwdses ---*/ 101f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*------------------------------------------------------------*/ 102f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 103f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic void cfsi_cache__invalidate ( void ); 104f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 105f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 106f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*------------------------------------------------------------*/ 107eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Root structure ---*/ 108eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 109eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 110b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* The root structure for the entire debug info system. It is a 111b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj linked list of DebugInfos. */ 112b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic DebugInfo* debugInfo_list = NULL; 113b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 114b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 115b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Find 'di' in the debugInfo_list and move it one step closer the the 116b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj front of the list, so as to make subsequent searches for it 117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj cheaper. When used in a controlled way, makes a major improvement 118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in some DebugInfo-search-intensive situations, most notably stack 119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj unwinding on amd64-linux. */ 120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void move_DebugInfo_one_step_forward ( DebugInfo* di ) 121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo *di0, *di1, *di2; 123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == debugInfo_list) 124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; /* already at head of list */ 125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di != NULL); 126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0 = debugInfo_list; 127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1 = NULL; 128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2 = NULL; 129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 == NULL || di0 == di) break; 131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2 = di1; 132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1 = di0; 133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0 = di0->next; 134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di0 == di); 136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 != NULL && di1 != NULL && di2 != NULL) { 137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* tmp; 138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* di0 points to di, di1 to its predecessor, and di2 to di1's 139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj predecessor. Swap di0 and di1, that is, move di0 one step 140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj closer to the start of the list. */ 141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di2->next == di1); 142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di1->next == di0); 143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj tmp = di0->next; 144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->next = di0; 145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0->next = di1; 146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1->next = tmp; 147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 != NULL && di1 != NULL && di2 == NULL) { 150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* it's second in the list. */ 151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(debugInfo_list == di1); 152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di1->next == di0); 153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1->next = di0->next; 154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0->next = di1; 155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debugInfo_list = di0; 156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 158eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 159eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 160eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 161eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Notification (acquire/discard) helpers ---*/ 162eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 163eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Gives out unique abstract handles for allocated DebugInfos. See 1659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj comment in priv_storage.h, declaration of struct _DebugInfo, for 1669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj details. */ 1679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic ULong handle_counter = 1; 1689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 169b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Allocate and zero out a new DebugInfo record. */ 170eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjstatic 1710f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardjDebugInfo* alloc_DebugInfo( const UChar* filename ) 172eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 173b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool traceme; 174b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 175eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 176f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj vg_assert(filename); 177f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj 1789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di = ML_(dinfo_zalloc)("di.debuginfo.aDI.1", sizeof(DebugInfo)); 179a5acac39bf3be7546222b1316faee5ee524be0d1sewardj di->handle = handle_counter++; 180a5acac39bf3be7546222b1316faee5ee524be0d1sewardj di->fsm.filename = ML_(dinfo_strdup)("di.debuginfo.aDI.2", filename); 1816b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.maps = VG_(newXA)( 1826b5625bb609b154766d2e138b61e15655f60b710sewardj ML_(dinfo_zalloc), "di.debuginfo.aDI.3", 1836b5625bb609b154766d2e138b61e15655f60b710sewardj ML_(dinfo_free), sizeof(struct _DebugInfoMapping)); 184eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 185452e89a9f847975609b3ad318943830f2cce841csewardj /* Everything else -- pointers, sizes, arrays -- is zeroed by 186452e89a9f847975609b3ad318943830f2cce841csewardj ML_(dinfo_zalloc). Now set up the debugging-output flags. */ 187f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj traceme 1880f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj = VG_(string_match)( VG_(clo_trace_symtab_patt), filename ); 189f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj if (traceme) { 190b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->trace_symtab = VG_(clo_trace_symtab); 191b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->trace_cfi = VG_(clo_trace_cfi); 192b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_syms = VG_(clo_debug_dump_syms); 193b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_line = VG_(clo_debug_dump_line); 194b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_frames = VG_(clo_debug_dump_frames); 195f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj } 196f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj 197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 198eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 199eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 200eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Free a DebugInfo, and also all the stuff hanging off it. */ 202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void free_DebugInfo ( DebugInfo* di ) 203eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 20459a2d18d0ddfa241850017252b0804d469187d79sewardj Word i, j, n; 205eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj struct strchunk *chunk, *next; 2069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ent; 20759a2d18d0ddfa241850017252b0804d469187d79sewardj GExpr* gexpr; 208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di != NULL); 2106b5625bb609b154766d2e138b61e15655f60b710sewardj if (di->fsm.maps) VG_(deleteXA)(di->fsm.maps); 211a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (di->fsm.filename) ML_(dinfo_free)(di->fsm.filename); 212f1e1aa691d7a2f0f2f933daf060bec5ae6938705philippe if (di->soname) ML_(dinfo_free)(di->soname); 213a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (di->loctab) ML_(dinfo_free)(di->loctab); 214a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (di->cfsi) ML_(dinfo_free)(di->cfsi); 215a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (di->cfsi_exprs) VG_(deleteXA)(di->cfsi_exprs); 216a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (di->fpo) ML_(dinfo_free)(di->fpo); 217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 218a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (di->symtab) { 219a5cace0c2a3e212931badbf6398a0cd98393121asewardj /* We have to visit all the entries so as to free up any 220a5cace0c2a3e212931badbf6398a0cd98393121asewardj sec_names arrays that might exist. */ 221a5cace0c2a3e212931badbf6398a0cd98393121asewardj n = di->symtab_used; 222a5cace0c2a3e212931badbf6398a0cd98393121asewardj for (i = 0; i < n; i++) { 223a5cace0c2a3e212931badbf6398a0cd98393121asewardj DiSym* sym = &di->symtab[i]; 224a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (sym->sec_names) 225a5cace0c2a3e212931badbf6398a0cd98393121asewardj ML_(dinfo_free)(sym->sec_names); 226a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 227a5cace0c2a3e212931badbf6398a0cd98393121asewardj /* and finally .. */ 228a5cace0c2a3e212931badbf6398a0cd98393121asewardj ML_(dinfo_free)(di->symtab); 229a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 230a5cace0c2a3e212931badbf6398a0cd98393121asewardj 231b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (chunk = di->strchunks; chunk != NULL; chunk = next) { 232eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj next = chunk->next; 233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(dinfo_free)(chunk); 234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Delete the two admin arrays. These lists exist primarily so 2379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj that we can visit each object exactly once when we need to 2389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj delete them. */ 2399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (di->admin_tyents) { 2409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n = VG_(sizeXA)(di->admin_tyents); 24159a2d18d0ddfa241850017252b0804d469187d79sewardj for (i = 0; i < n; i++) { 2429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ent = (TyEnt*)VG_(indexXA)(di->admin_tyents, i); 2439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Dump anything hanging off this ent */ 2449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(TyEnt__make_EMPTY)(ent); 24559a2d18d0ddfa241850017252b0804d469187d79sewardj } 2469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(deleteXA)(di->admin_tyents); 2479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->admin_tyents = NULL; 248eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 24959a2d18d0ddfa241850017252b0804d469187d79sewardj 25059a2d18d0ddfa241850017252b0804d469187d79sewardj if (di->admin_gexprs) { 25159a2d18d0ddfa241850017252b0804d469187d79sewardj n = VG_(sizeXA)(di->admin_gexprs); 25259a2d18d0ddfa241850017252b0804d469187d79sewardj for (i = 0; i < n; i++) { 25359a2d18d0ddfa241850017252b0804d469187d79sewardj gexpr = *(GExpr**)VG_(indexXA)(di->admin_gexprs, i); 25459a2d18d0ddfa241850017252b0804d469187d79sewardj ML_(dinfo_free)(gexpr); 25559a2d18d0ddfa241850017252b0804d469187d79sewardj } 25659a2d18d0ddfa241850017252b0804d469187d79sewardj VG_(deleteXA)(di->admin_gexprs); 25759a2d18d0ddfa241850017252b0804d469187d79sewardj di->admin_gexprs = NULL; 258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 260b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Dump the variable info. This is kinda complex: we must take 261b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj care not to free items which reside in either the admin lists 262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (as we have just freed them) or which reside in the DebugInfo's 263b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj string table. */ 264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->varinfo) { 265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = 0; i < VG_(sizeXA)(di->varinfo); i++) { 266b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* scope = *(OSet**)VG_(indexXA)(di->varinfo, i); 267b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!scope) continue; 268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* iterate over all entries in 'scope' */ 269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(OSetGen_ResetIter)(scope); 270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* arange = VG_(OSetGen_Next)(scope); 272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!arange) break; 273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* for each var in 'arange' */ 274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->vars); 275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < VG_(sizeXA)( arange->vars ); j++) { 276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)(arange->vars,j); 277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var); 278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Nothing to free in var: all the pointer fields refer 279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to stuff either on an admin list, or in 280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj .strchunks */ 281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)(arange->vars); 283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Don't free arange itself, as OSetGen_Destroy does 284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj that */ 285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(OSetGen_Destroy)(scope); 287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)(di->varinfo); 289b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(dinfo_free)(di); 292eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 293eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 294eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* 'si' is a member of debugInfo_list. Find it, remove it from the 296eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj list, notify m_redir that this has happened, and free all storage 297eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj reachable from it. 298eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void discard_DebugInfo ( DebugInfo* di ) 300eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3014ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj HChar* reason = "munmap"; 3024ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo** prev_next_ptr = &debugInfo_list; 304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* curr = debugInfo_list; 305eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 306eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj while (curr) { 307b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (curr == di) { 308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Found it; remove from list and free it. */ 30933e4e7eaab263cea956700f56f007ab26c39eab4sewardj if (curr->have_dinfo 31033e4e7eaab263cea956700f56f007ab26c39eab4sewardj && (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))) 311eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(message)(Vg_DebugMsg, 312738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Discarding syms at %#lx-%#lx in %s due to %s()\n", 313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_avma, 314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_avma + di->text_size, 315a5acac39bf3be7546222b1316faee5ee524be0d1sewardj curr->fsm.filename ? curr->fsm.filename 316a5acac39bf3be7546222b1316faee5ee524be0d1sewardj : (UChar*)"???", 3174ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj reason); 318eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(*prev_next_ptr == curr); 319eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *prev_next_ptr = curr->next; 32033e4e7eaab263cea956700f56f007ab26c39eab4sewardj if (curr->have_dinfo) 32133e4e7eaab263cea956700f56f007ab26c39eab4sewardj VG_(redir_notify_delete_DebugInfo)( curr ); 322b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj free_DebugInfo(curr); 323eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return; 324eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 325eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj prev_next_ptr = &curr->next; 326eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj curr = curr->next; 327eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 328eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Not found. */ 330eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 331eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 332eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Repeatedly scan debugInfo_list, looking for DebugInfos with text 334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj AVMAs intersecting [start,start+length), and call discard_DebugInfo 335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to get rid of them. This modifies the list, hence the multiple 336f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj iterations. Returns True iff any such DebugInfos were found. 337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/ 338f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic Bool discard_syms_in_range ( Addr start, SizeT length ) 339eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 340f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool anyFound = False; 341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool found; 342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* curr; 343eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 344eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj while (True) { 345eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj found = False; 346eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj curr = debugInfo_list; 348eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj while (True) { 349eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (curr == NULL) 350eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; 351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (curr->text_present 352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && curr->text_size > 0 353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && (start+length - 1 < curr->text_avma 354b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || curr->text_avma + curr->text_size - 1 < start)) { 355eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* no overlap */ 356eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 357eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj found = True; 358eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; 359eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 360eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj curr = curr->next; 361eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 362eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 363eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (!found) break; 364f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj anyFound = True; 365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_DebugInfo( curr ); 366eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 367f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 368f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return anyFound; 369eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 370eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 371eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Does [s1,+len1) overlap [s2,+len2) ? Note: does not handle 373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj wraparound at the end of the address space -- just asserts in that 374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case. */ 375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Bool ranges_overlap (Addr s1, SizeT len1, Addr s2, SizeT len2 ) 376eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr e1, e2; 378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (len1 == 0 || len2 == 0) 379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj e1 = s1 + len1 - 1; 381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj e2 = s2 + len2 - 1; 382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Assert that we don't have wraparound. If we do it would imply 383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj that file sections are getting mapped around the end of the 384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj address space, which sounds unlikely. */ 385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(s1 <= e1); 386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(s2 <= e2); 387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (e1 < s2 || e2 < s1) return False; 388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 390eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 391eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3926b5625bb609b154766d2e138b61e15655f60b710sewardj/* Do the basic mappings of the two DebugInfos overlap in any way? */ 393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Bool do_DebugInfos_overlap ( DebugInfo* di1, DebugInfo* di2 ) 394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 3956b5625bb609b154766d2e138b61e15655f60b710sewardj Word i, j; 396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di1); 397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di2); 3986b5625bb609b154766d2e138b61e15655f60b710sewardj for (i = 0; i < VG_(sizeXA)(di1->fsm.maps); i++) { 3996b5625bb609b154766d2e138b61e15655f60b710sewardj struct _DebugInfoMapping* map1 = VG_(indexXA)(di1->fsm.maps, i); 4006b5625bb609b154766d2e138b61e15655f60b710sewardj for (j = 0; j < VG_(sizeXA)(di2->fsm.maps); j++) { 4016b5625bb609b154766d2e138b61e15655f60b710sewardj struct _DebugInfoMapping* map2 = VG_(indexXA)(di2->fsm.maps, j); 4026b5625bb609b154766d2e138b61e15655f60b710sewardj if (ranges_overlap(map1->avma, map1->size, map2->avma, map2->size)) 4036b5625bb609b154766d2e138b61e15655f60b710sewardj return True; 4046b5625bb609b154766d2e138b61e15655f60b710sewardj } 4056b5625bb609b154766d2e138b61e15655f60b710sewardj } 406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 410b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 411b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Discard all elements of debugInfo_list whose .mark bit is set. 412b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/ 413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void discard_marked_DebugInfos ( void ) 414b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* curr; 416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj curr = debugInfo_list; 420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!curr) 422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (curr->mark) 424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj curr = curr->next; 426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!curr) break; 429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_DebugInfo( curr ); 430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Discard any elements of debugInfo_list which overlap with diRef. 4366b5625bb609b154766d2e138b61e15655f60b710sewardj Clearly diRef must have its mapping information set to something sane. */ 437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void discard_DebugInfos_which_overlap_with ( DebugInfo* diRef ) 438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Mark all the DebugInfos in debugInfo_list that need to be 441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj deleted. First, clear all the mark bits; then set them if they 442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj overlap with siRef. Since siRef itself is in this list we at 443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj least expect its own mark bit to be set. */ 444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di; di = di->next) { 445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->mark = do_DebugInfos_overlap( di, diRef ); 446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == diRef) { 447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->mark); 448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->mark = False; 449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 450eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_marked_DebugInfos(); 452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 454eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4550f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj/* Find the existing DebugInfo for |filename| or if not found, create 4560f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj one. In the latter case |filename| is strdup'd into VG_AR_DINFO, 4570f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj and the new DebugInfo is added to debugInfo_list. */ 4580f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardjstatic DebugInfo* find_or_create_DebugInfo_for ( UChar* filename ) 459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 460b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(filename); 462b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di; di = di->next) { 463a5acac39bf3be7546222b1316faee5ee524be0d1sewardj vg_assert(di->fsm.filename); 464a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (0==VG_(strcmp)(di->fsm.filename, filename)) 465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 467b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di) { 4680f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj di = alloc_DebugInfo(filename); 469b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di); 470b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->next = debugInfo_list; 471b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debugInfo_list = di; 472b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 473b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 474eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 475eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 476eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 477f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Debuginfo reading for 'di' has just been successfully completed. 478f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Check that the invariants stated in 479f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj "Comment_on_IMPORTANT_CFSI_REPRESENTATIONAL_INVARIANTS" in 480f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj priv_storage.h are observed. */ 481f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic void check_CFSI_related_invariants ( DebugInfo* di ) 482f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 483f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo* di2 = NULL; 4846b5625bb609b154766d2e138b61e15655f60b710sewardj Bool has_nonempty_rx = False; 4856b5625bb609b154766d2e138b61e15655f60b710sewardj Bool cfsi_fits = False; 4866b5625bb609b154766d2e138b61e15655f60b710sewardj Word i, j; 487f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di); 488f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* This fn isn't called until after debuginfo for this object has 489f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj been successfully read. And that shouldn't happen until we have 490f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj both a r-x and rw- mapping for the object. Hence: */ 491a5acac39bf3be7546222b1316faee5ee524be0d1sewardj vg_assert(di->fsm.have_rx_map); 492a5acac39bf3be7546222b1316faee5ee524be0d1sewardj vg_assert(di->fsm.have_rw_map); 4936b5625bb609b154766d2e138b61e15655f60b710sewardj for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { 4946b5625bb609b154766d2e138b61e15655f60b710sewardj struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i); 4956b5625bb609b154766d2e138b61e15655f60b710sewardj /* We are interested in r-x mappings only */ 4966b5625bb609b154766d2e138b61e15655f60b710sewardj if (!map->rx) 497f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj continue; 4986b5625bb609b154766d2e138b61e15655f60b710sewardj 4996b5625bb609b154766d2e138b61e15655f60b710sewardj /* degenerate case: r-x section is empty */ 5006b5625bb609b154766d2e138b61e15655f60b710sewardj if (map->size == 0) 501f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj continue; 5026b5625bb609b154766d2e138b61e15655f60b710sewardj has_nonempty_rx = True; 5036b5625bb609b154766d2e138b61e15655f60b710sewardj 5046b5625bb609b154766d2e138b61e15655f60b710sewardj /* normal case: r-x section is nonempty */ 5056b5625bb609b154766d2e138b61e15655f60b710sewardj /* invariant (0) */ 5066b5625bb609b154766d2e138b61e15655f60b710sewardj vg_assert(map->size > 0); 5076b5625bb609b154766d2e138b61e15655f60b710sewardj 5086b5625bb609b154766d2e138b61e15655f60b710sewardj /* invariant (1) */ 5096b5625bb609b154766d2e138b61e15655f60b710sewardj for (di2 = debugInfo_list; di2; di2 = di2->next) { 5106b5625bb609b154766d2e138b61e15655f60b710sewardj if (di2 == di) 5116b5625bb609b154766d2e138b61e15655f60b710sewardj continue; 5126b5625bb609b154766d2e138b61e15655f60b710sewardj for (j = 0; j < VG_(sizeXA)(di2->fsm.maps); j++) { 5136b5625bb609b154766d2e138b61e15655f60b710sewardj struct _DebugInfoMapping* map2 = VG_(indexXA)(di2->fsm.maps, j); 5146b5625bb609b154766d2e138b61e15655f60b710sewardj if (!map2->rx || map2->size == 0) 5156b5625bb609b154766d2e138b61e15655f60b710sewardj continue; 5166b5625bb609b154766d2e138b61e15655f60b710sewardj vg_assert(!ranges_overlap(map->avma, map->size, 5176b5625bb609b154766d2e138b61e15655f60b710sewardj map2->avma, map2->size)); 5186b5625bb609b154766d2e138b61e15655f60b710sewardj } 5196b5625bb609b154766d2e138b61e15655f60b710sewardj } 5206b5625bb609b154766d2e138b61e15655f60b710sewardj di2 = NULL; 5216b5625bb609b154766d2e138b61e15655f60b710sewardj 5226b5625bb609b154766d2e138b61e15655f60b710sewardj /* invariant (2) */ 5236b5625bb609b154766d2e138b61e15655f60b710sewardj if (di->cfsi) { 5246b5625bb609b154766d2e138b61e15655f60b710sewardj vg_assert(di->cfsi_minavma <= di->cfsi_maxavma); /* duh! */ 5256b5625bb609b154766d2e138b61e15655f60b710sewardj /* Assume the csfi fits completely into one individual mapping 5266b5625bb609b154766d2e138b61e15655f60b710sewardj for now. This might need to be improved/reworked later. */ 5276b5625bb609b154766d2e138b61e15655f60b710sewardj if (di->cfsi_minavma >= map->avma && 5286b5625bb609b154766d2e138b61e15655f60b710sewardj di->cfsi_maxavma < map->avma + map->size) 5296b5625bb609b154766d2e138b61e15655f60b710sewardj cfsi_fits = True; 5306b5625bb609b154766d2e138b61e15655f60b710sewardj } 531f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 5326b5625bb609b154766d2e138b61e15655f60b710sewardj 5336b5625bb609b154766d2e138b61e15655f60b710sewardj /* degenerate case: all r-x sections are empty */ 5346b5625bb609b154766d2e138b61e15655f60b710sewardj if (!has_nonempty_rx) { 5356b5625bb609b154766d2e138b61e15655f60b710sewardj vg_assert(di->cfsi == NULL); 5366b5625bb609b154766d2e138b61e15655f60b710sewardj return; 537f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 5386b5625bb609b154766d2e138b61e15655f60b710sewardj 5396b5625bb609b154766d2e138b61e15655f60b710sewardj /* invariant (2) - cont. */ 5406b5625bb609b154766d2e138b61e15655f60b710sewardj if (di->cfsi) 5416b5625bb609b154766d2e138b61e15655f60b710sewardj vg_assert(cfsi_fits); 5426b5625bb609b154766d2e138b61e15655f60b710sewardj 543f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* invariants (3) and (4) */ 544f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di->cfsi) { 545f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_used > 0); 546f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_size > 0); 547f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (i = 0; i < di->cfsi_used; i++) { 548f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DiCfSI* cfsi = &di->cfsi[i]; 549f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsi->len > 0); 550f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsi->base >= di->cfsi_minavma); 551f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsi->base + cfsi->len - 1 <= di->cfsi_maxavma); 552f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (i > 0) { 553f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DiCfSI* cfsip = &di->cfsi[i-1]; 554f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsip->base + cfsip->len <= cfsi->base); 555f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 556f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 557f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 558f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_used == 0); 559f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_size == 0); 560f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 561f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 562f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 563f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 564f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--------------------------------------------------------------*/ 565f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- ---*/ 566f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- TOP LEVEL: INITIALISE THE DEBUGINFO SYSTEM ---*/ 567f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- ---*/ 568f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--------------------------------------------------------------*/ 569f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 570f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjvoid VG_(di_initialise) ( void ) 571f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 572f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* There's actually very little to do here, since everything 573f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj centers around the DebugInfos in debugInfo_list, they are 574f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj created and destroyed on demand, and each one is treated more or 575f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj less independently. */ 576f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(debugInfo_list == NULL); 577f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 578f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* flush the CFI fast query cache. */ 579f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi_cache__invalidate(); 580f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 581f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 582f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 5834ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--------------------------------------------------------------*/ 5844ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- ---*/ 5854ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- TOP LEVEL: NOTIFICATION (ACQUIRE/DISCARD INFO) (LINUX) ---*/ 5864ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- ---*/ 5874ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--------------------------------------------------------------*/ 5884ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 589f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VGO_linux) || defined(VGO_darwin) 590eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 591eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* The debug info system is driven by notifications that a text 592731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj segment has been mapped in, or unmapped, or when sections change 593731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj permission. It's all a bit kludgey and basically means watching 594731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj syscalls, trying to second-guess when the system's dynamic linker 595731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj is done with mapping in a new object for execution. This is all 596731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj tracked using the DebugInfoFSM struct for the object. Anyway, once 597731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj we finally decide we've got to an accept state, this section then 598731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj will acquire whatever info is available for the corresponding 599731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj object. This section contains the notification handlers, which 600731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj update the FSM and determine when an accept state has been reached. 601731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj*/ 602731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 603731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj/* When the sequence of observations causes a DebugInfoFSM to move 604731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj into the accept state, call here to actually get the debuginfo read 605731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj in. Returns a ULong whose purpose is described in comments 606731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj preceding VG_(di_notify_mmap) just below. 607731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj*/ 608731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardjstatic ULong di_notify_ACHIEVE_ACCEPT_STATE ( struct _DebugInfo* di ) 609731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj{ 610731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj ULong di_handle; 611731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj Bool ok; 612731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 613731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj vg_assert(di->fsm.filename); 614731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n"); 615731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("------ start ELF OBJECT " 616731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj "------------------------------\n"); 617731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("------ name = %s\n", di->fsm.filename); 618731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n"); 619731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 620731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* We're going to read symbols and debug info for the avma 6216b5625bb609b154766d2e138b61e15655f60b710sewardj ranges specified in the _DebugInfoFsm mapping array. First 6226b5625bb609b154766d2e138b61e15655f60b710sewardj get rid of any other DebugInfos which overlap any of those 6236b5625bb609b154766d2e138b61e15655f60b710sewardj ranges (to avoid total confusion). */ 624731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj discard_DebugInfos_which_overlap_with( di ); 625731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 626731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* .. and acquire new info. */ 627731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# if defined(VGO_linux) 628731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj ok = ML_(read_elf_debug_info)( di ); 629731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# elif defined(VGO_darwin) 630731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj ok = ML_(read_macho_debug_info)( di ); 631731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# else 632731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# error "unknown OS" 633731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# endif 634731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 635731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (ok) { 636731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 637731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n------ Canonicalising the " 638731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj "acquired info ------\n"); 639731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* invalidate the CFI unwind cache. */ 640731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj cfsi_cache__invalidate(); 641731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* prepare read data for use */ 642731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj ML_(canonicaliseTables)( di ); 643731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* notify m_redir about it */ 644731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n------ Notifying m_redir ------\n"); 645731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj VG_(redir_notify_new_DebugInfo)( di ); 646731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Note that we succeeded */ 647731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj di->have_dinfo = True; 648731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj tl_assert(di->handle > 0); 649731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj di_handle = di->handle; 650731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Check invariants listed in 651731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj Comment_on_IMPORTANT_REPRESENTATIONAL_INVARIANTS in 652731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj priv_storage.h. */ 653731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj check_CFSI_related_invariants(di); 654731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 655731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj } else { 656731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n------ ELF reading failed ------\n"); 657731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Something went wrong (eg. bad ELF file). Should we delete 658731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj this DebugInfo? No - it contains info on the rw/rx 659731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj mappings, at least. */ 660731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj di_handle = 0; 661731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj vg_assert(di->have_dinfo == False); 662731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj } 663731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 664731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n"); 665731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("------ name = %s\n", di->fsm.filename); 666731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("------ end ELF OBJECT " 667731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj "------------------------------\n"); 668731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n"); 669731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 670731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return di_handle; 671731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj} 672731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 673eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 674eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Notify the debuginfo system about a new mapping. This is the way 675eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj new debug information gets loaded. If allow_SkFileV is True, it 676eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj will try load debug info if the mapping at 'a' belongs to Valgrind; 677eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj whereas normally (False) it will not do that. This allows us to 678eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj carefully control when the thing will read symbols from the 6799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Valgrind executable itself. 6809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 6815f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj If use_fd is not -1, that is used instead of the filename; this 6825f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj avoids perturbing fcntl locks, which are released by simply 6835f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj re-opening and closing the same file (even via different fd!). 6845f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj 6859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj If a call to VG_(di_notify_mmap) causes debug info to be read, then 6869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj the returned ULong is an abstract handle which can later be used to 6879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj refer to the debuginfo read as a result of this specific mapping, 6889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj in later queries to m_debuginfo. In this case the handle value 6899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj will be one or above. If the returned value is zero, no debug info 6909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj was read. */ 691eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 6925f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardjULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd ) 693eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 6944ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj NSegment const * seg; 695b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj HChar* filename; 696731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj Bool is_rx_map, is_rw_map, is_ro_map; 697b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 6985f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj Int actual_fd, oflags; 6995f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj SysRes preadres; 700b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj HChar buf1k[1024]; 701b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool debug = False; 702ec61b6509566cf36ab3968d69226cecf177cb0fesewardj SysRes statres; 703ec61b6509566cf36ab3968d69226cecf177cb0fesewardj struct vg_stat statbuf; 704b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 7055f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj vg_assert(use_fd >= -1); 7065f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj 707b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* In short, figure out if this mapping is of interest to us, and 708b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if so, try to guess what ld.so is doing and when/if we should 709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj read debug info. */ 710b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg = VG_(am_find_nsegment)(a); 711b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(seg); 712eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 713b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 714a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("di_notify_mmap-1: %#lx-%#lx %c%c%c\n", 715b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->start, seg->end, 716b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->hasR ? 'r' : '-', 717b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->hasW ? 'w' : '-',seg->hasX ? 'x' : '-' ); 718eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* guaranteed by aspacemgr-linux.c, sane_NSegment() */ 720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(seg->end > seg->start); 721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 722b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ignore non-file mappings */ 723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( ! (seg->kind == SkFileC 724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || (seg->kind == SkFileV && allow_SkFileV)) ) 7259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 726b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 727b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* If the file doesn't have a name, we're hosed. Give up. */ 728b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj filename = VG_(am_get_filename)( (NSegment*)seg ); 729b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!filename) 7309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 731b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 7320ab84fe82d1e25c2e0544d08826df42caa44ded1bart /* 7330ab84fe82d1e25c2e0544d08826df42caa44ded1bart * Cannot read from these magic files: 7340ab84fe82d1e25c2e0544d08826df42caa44ded1bart * --20208-- WARNING: Serious error when reading debug info 7350ab84fe82d1e25c2e0544d08826df42caa44ded1bart * --20208-- When reading debug info from /proc/xen/privcmd: 7360ab84fe82d1e25c2e0544d08826df42caa44ded1bart * --20208-- can't read file to inspect ELF header 7370ab84fe82d1e25c2e0544d08826df42caa44ded1bart */ 7380ab84fe82d1e25c2e0544d08826df42caa44ded1bart if (VG_(strncmp)(filename, "/proc/xen/", 10) == 0) 7390ab84fe82d1e25c2e0544d08826df42caa44ded1bart return 0; 7400ab84fe82d1e25c2e0544d08826df42caa44ded1bart 741b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 742b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("di_notify_mmap-2: %s\n", filename); 743b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 744ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* Only try to read debug information from regular files. */ 74515728ab41ea41bf731dcc74ac68354550ced2189bart statres = VG_(stat)(filename, &statbuf); 746ec61b6509566cf36ab3968d69226cecf177cb0fesewardj 747ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* stat dereferences symlinks, so we don't expect it to succeed and 748ec61b6509566cf36ab3968d69226cecf177cb0fesewardj yet produce something that is a symlink. */ 7499c20ece00e07304f66da5f43b87ec45bc9c04550njn vg_assert(sr_isError(statres) || ! VKI_S_ISLNK(statbuf.mode)); 750ec61b6509566cf36ab3968d69226cecf177cb0fesewardj 751ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* Don't let the stat call fail silently. Filter out some known 752ec61b6509566cf36ab3968d69226cecf177cb0fesewardj sources of noise before complaining, though. */ 753cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(statres)) { 754ec61b6509566cf36ab3968d69226cecf177cb0fesewardj DebugInfo fake_di; 755ec61b6509566cf36ab3968d69226cecf177cb0fesewardj Bool quiet = VG_(strstr)(filename, "/var/run/nscd/") != NULL; 756e025eca1d49cdfe5a8cb58ab495763434280333asewardj if (!quiet && VG_(clo_verbosity) > 1) { 757ec61b6509566cf36ab3968d69226cecf177cb0fesewardj VG_(memset)(&fake_di, 0, sizeof(fake_di)); 758a5acac39bf3be7546222b1316faee5ee524be0d1sewardj fake_di.fsm.filename = filename; 759ec61b6509566cf36ab3968d69226cecf177cb0fesewardj ML_(symerr)(&fake_di, True, "failed to stat64/stat this file"); 760ec61b6509566cf36ab3968d69226cecf177cb0fesewardj } 7619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 7622ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj } 7632ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj 764ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* Finally, the point of all this stattery: if it's not a regular file, 765ec61b6509566cf36ab3968d69226cecf177cb0fesewardj don't try to read debug info from it. */ 7669c20ece00e07304f66da5f43b87ec45bc9c04550njn if (! VKI_S_ISREG(statbuf.mode)) 7679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 768ec61b6509566cf36ab3968d69226cecf177cb0fesewardj 769ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* no uses of statbuf below here. */ 77015728ab41ea41bf731dcc74ac68354550ced2189bart 771b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Now we have to guess if this is a text-like mapping, a data-like 772b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj mapping, neither or both. The rules are: 773b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 774b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj text if: x86-linux r and x 775b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj other-linux r and x and not w 776b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 777b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data if: x86-linux r and w 778b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj other-linux r and w and not x 779b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 780b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Background: On x86-linux, objects are typically mapped twice: 781eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 782eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1b8fb000-1b8ff000 r-xp 00000000 08:02 4471477 vgpreload_memcheck.so 783eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1b8ff000-1b900000 rw-p 00004000 08:02 4471477 vgpreload_memcheck.so 784eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 785eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj whereas ppc32-linux mysteriously does this: 786eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 787eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118a6000-118ad000 r-xp 00000000 08:05 14209428 vgpreload_memcheck.so 788eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118ad000-118b6000 ---p 00007000 08:05 14209428 vgpreload_memcheck.so 789eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118b6000-118bd000 rwxp 00000000 08:05 14209428 vgpreload_memcheck.so 790eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 791eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj The third mapping should not be considered to have executable 792eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj code in. Therefore a test which works for both is: r and x and 793eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj NOT w. Reading symbols from the rwx segment -- which overlaps 794eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj the r-x segment in the file -- causes the redirection mechanism 795eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj to redirect to addresses in that third segment, which is wrong 796eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj and causes crashes. 797eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 798eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj JRS 28 Dec 05: unfortunately icc 8.1 on x86 has been seen to 799eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj produce executables with a single rwx segment rather than a 800eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj (r-x,rw-) pair. That means the rules have to be modified thusly: 801eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 802eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj x86-linux: consider if r and x 803b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj all others: consider if r and x and not w 804f56d255d644ec9a1bfa970d50a0489a816a4e736sewardj 805f56d255d644ec9a1bfa970d50a0489a816a4e736sewardj 2009 Aug 16: apply similar kludge to ppc32-linux. 806f56d255d644ec9a1bfa970d50a0489a816a4e736sewardj See http://bugs.kde.org/show_bug.cgi?id=190820 807b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 808b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj There are two modes on s390x: with and without the noexec kernel 809b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj parameter. Together with some older kernels, this leads to several 810b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj variants: 811b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj executable: r and x 812b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj data: r and w and x 813b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj or 814b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj executable: r and x 815b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj data: r and w 816eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj */ 817b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = False; 818b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = False; 819731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj is_ro_map = False; 820731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 8215db15403e889d4db339b342bc2a824ef0bfaa654sewardj# if defined(VGA_x86) || defined(VGA_ppc32) || defined(VGA_mips32) 822b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = seg->hasR && seg->hasX; 823b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = seg->hasR && seg->hasW; 8243026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_amd64) || defined(VGA_ppc64) || defined(VGA_arm) 825b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = seg->hasR && seg->hasX && !seg->hasW; 826b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = seg->hasR && seg->hasW && !seg->hasX; 827b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGP_s390x_linux) 828b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj is_rx_map = seg->hasR && seg->hasX && !seg->hasW; 829b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj is_rw_map = seg->hasR && seg->hasW; 830eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# else 831b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# error "Unknown platform" 832eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# endif 833eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 834731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# if defined(VGP_x86_darwin) && DARWIN_VERS == DARWIN_10_7 835731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj is_ro_map = seg->hasR && !seg->hasW && !seg->hasX; 836731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# endif 837731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 838b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 839b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("di_notify_mmap-3: is_rx_map %d, is_rw_map %d\n", 840b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (Int)is_rx_map, (Int)is_rw_map); 841eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 842731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Ignore mappings with permissions we can't possibly be interested in. */ 843731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (!(is_rx_map || is_rw_map || is_ro_map)) 8449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 845eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 8465a5eec0923d55afc94165721d25125d5fc8f24d8sewardj /* Peer at the first few bytes of the file, to see if it is an ELF */ 8475a5eec0923d55afc94165721d25125d5fc8f24d8sewardj /* object file. Ignore the file if we do not have read permission. */ 8485a5eec0923d55afc94165721d25125d5fc8f24d8sewardj VG_(memset)(buf1k, 0, sizeof(buf1k)); 849cec083d9a254e92623ed44e9dca080d224693c82sewardj oflags = VKI_O_RDONLY; 850cec083d9a254e92623ed44e9dca080d224693c82sewardj# if defined(VKI_O_LARGEFILE) 851cec083d9a254e92623ed44e9dca080d224693c82sewardj oflags |= VKI_O_LARGEFILE; 852cec083d9a254e92623ed44e9dca080d224693c82sewardj# endif 8535f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj 8545f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (use_fd == -1) { 8555f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj SysRes fd = VG_(open)( filename, oflags, 0 ); 8565f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (sr_isError(fd)) { 8575f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (sr_Err(fd) != VKI_EACCES) { 8585f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj DebugInfo fake_di; 8595f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj VG_(memset)(&fake_di, 0, sizeof(fake_di)); 8605f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj fake_di.fsm.filename = filename; 8615f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj ML_(symerr)(&fake_di, True, 8625f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj "can't open file to inspect ELF header"); 8635f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj } 8645f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj return 0; 8655a5eec0923d55afc94165721d25125d5fc8f24d8sewardj } 8665f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj actual_fd = sr_Res(fd); 8675f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj } else { 8685f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj actual_fd = use_fd; 8695a5eec0923d55afc94165721d25125d5fc8f24d8sewardj } 8705a5eec0923d55afc94165721d25125d5fc8f24d8sewardj 8715f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj preadres = VG_(pread)( actual_fd, buf1k, sizeof(buf1k), 0 ); 8725f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (use_fd == -1) { 8735f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj VG_(close)( actual_fd ); 8745f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj } 8755f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj 8765f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (sr_isError(preadres)) { 8775a5eec0923d55afc94165721d25125d5fc8f24d8sewardj DebugInfo fake_di; 8785a5eec0923d55afc94165721d25125d5fc8f24d8sewardj VG_(memset)(&fake_di, 0, sizeof(fake_di)); 879a5acac39bf3be7546222b1316faee5ee524be0d1sewardj fake_di.fsm.filename = filename; 8805a5eec0923d55afc94165721d25125d5fc8f24d8sewardj ML_(symerr)(&fake_di, True, "can't read file to inspect ELF header"); 8815a5eec0923d55afc94165721d25125d5fc8f24d8sewardj return 0; 8825a5eec0923d55afc94165721d25125d5fc8f24d8sewardj } 8835f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (sr_Res(preadres) == 0) 8845f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj return 0; 8855f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj vg_assert(sr_Res(preadres) > 0 && sr_Res(preadres) <= sizeof(buf1k) ); 8865a5eec0923d55afc94165721d25125d5fc8f24d8sewardj 8878b68b64759254d514d98328c496cbd88cde4c9a5njn /* We're only interested in mappings of object files. */ 8886e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# if defined(VGO_linux) 889f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj if (!ML_(is_elf_object_file)( buf1k, (SizeT)sr_Res(preadres), False )) 8905a5eec0923d55afc94165721d25125d5fc8f24d8sewardj return 0; 8916e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# elif defined(VGO_darwin) 8925f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (!ML_(is_macho_object_file)( buf1k, (SizeT)sr_Res(preadres) )) 893f76d27a697a7b0bf3b84490baf60623fc96a23afnjn return 0; 8946e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# else 8956e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# error "unknown OS" 8966e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# endif 8975a5eec0923d55afc94165721d25125d5fc8f24d8sewardj 898b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* See if we have a DebugInfo for this filename. If not, 899b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj create one. */ 9000f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj di = find_or_create_DebugInfo_for( filename ); 901b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di); 902b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 9036b5625bb609b154766d2e138b61e15655f60b710sewardj /* Note the details about the mapping. */ 9046b5625bb609b154766d2e138b61e15655f60b710sewardj struct _DebugInfoMapping map; 9056b5625bb609b154766d2e138b61e15655f60b710sewardj map.avma = a; 9066b5625bb609b154766d2e138b61e15655f60b710sewardj map.size = seg->end + 1 - seg->start; 9076b5625bb609b154766d2e138b61e15655f60b710sewardj map.foff = seg->offset; 9086b5625bb609b154766d2e138b61e15655f60b710sewardj map.rx = is_rx_map; 9096b5625bb609b154766d2e138b61e15655f60b710sewardj map.rw = is_rw_map; 9106b5625bb609b154766d2e138b61e15655f60b710sewardj map.ro = is_ro_map; 9116b5625bb609b154766d2e138b61e15655f60b710sewardj VG_(addToXA)(di->fsm.maps, &map); 9126b5625bb609b154766d2e138b61e15655f60b710sewardj 9136b5625bb609b154766d2e138b61e15655f60b710sewardj /* Update flags about what kind of mappings we've already seen. */ 9146b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.have_rx_map |= is_rx_map; 9156b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.have_rw_map |= is_rw_map; 9166b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.have_ro_map |= is_ro_map; 917b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 918731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* So, finally, are we in an accept state? */ 919731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) { 920731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Ok, so, finally, we found what we need, and we haven't 921731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj already read debuginfo for this object. So let's do so now. 922731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj Yee-ha! */ 923731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return di_notify_ACHIEVE_ACCEPT_STATE ( di ); 9249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } else { 925731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* If we don't have an rx and rw mapping, or if we already have 926731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj debuginfo for this mapping for whatever reason, go no 927731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj further. */ 928731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return 0; 9299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 930eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 931eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 932eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 933eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Unmap is simpler - throw away any SegInfos intersecting 934eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj [a, a+len). */ 935eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjvoid VG_(di_notify_munmap)( Addr a, SizeT len ) 936eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 937f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool anyFound; 938a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart if (0) VG_(printf)("DISCARD %#lx %#lx\n", a, a+len); 939f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj anyFound = discard_syms_in_range(a, len); 940f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (anyFound) 941f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi_cache__invalidate(); 942eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 943eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 944eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 945eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Uh, this doesn't do anything at all. IIRC glibc (or ld.so, I don't 946eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj remember) does a bunch of mprotects on itself, and if we follow 947eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj through here, it causes the debug info for that object to get 948eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj discarded. */ 949eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjvoid VG_(di_notify_mprotect)( Addr a, SizeT len, UInt prot ) 950eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 951eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool exe_ok = toBool(prot & VKI_PROT_EXEC); 952f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# if defined(VGA_x86) 953eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj exe_ok = exe_ok || toBool(prot & VKI_PROT_READ); 954eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# endif 955f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && !exe_ok) { 956f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool anyFound = discard_syms_in_range(a, len); 957f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (anyFound) 958f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi_cache__invalidate(); 959f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 960eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 961eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 962731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 963731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj/* This is a MacOSX 10.7 32-bit only special. See comments on the 964731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj declaration of struct _DebugInfoFSM for details. */ 965731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardjvoid VG_(di_notify_vm_protect)( Addr a, SizeT len, UInt prot ) 966731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj{ 967731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj Bool do_nothing = True; 968ae284e5cc0830afcdec7b436564ea9f18bbedff8sewardj# if defined(VGP_x86_darwin) && (DARWIN_VERS == DARWIN_10_7 || DARWIN_VERS == DARWIN_10_8) 969731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj do_nothing = False; 970731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# endif 971731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (do_nothing /* wrong platform */) 972731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return; 973731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 974731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj Bool r_ok = toBool(prot & VKI_PROT_READ); 975731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj Bool w_ok = toBool(prot & VKI_PROT_WRITE); 976731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj Bool x_ok = toBool(prot & VKI_PROT_EXEC); 977731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (! (r_ok && !w_ok && x_ok)) 978731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return; /* not an upgrade to r-x */ 979731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 980731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Find a DebugInfo containing a FSM that has [a, +len) previously 981731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj observed as a r-- mapping, plus some other rw- mapping. If such 982731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj is found, conclude we're in an accept state and read debuginfo 983731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj accordingly. */ 984731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj DebugInfo* di; 9856b5625bb609b154766d2e138b61e15655f60b710sewardj struct _DebugInfoMapping *map = NULL; 9866b5625bb609b154766d2e138b61e15655f60b710sewardj Word i; 987731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj for (di = debugInfo_list; di; di = di->next) { 988731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj vg_assert(di->fsm.filename); 989731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (di->have_dinfo) 990731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj continue; /* already have debuginfo for this object */ 991731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (!di->fsm.have_ro_map) 992731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj continue; /* need to have a r-- mapping for this object */ 993731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (di->fsm.have_rx_map) 994731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj continue; /* rx- mapping already exists */ 995731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (!di->fsm.have_rw_map) 996731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj continue; /* need to have a rw- mapping */ 9976b5625bb609b154766d2e138b61e15655f60b710sewardj /* Try to find a mapping matching the memory area. */ 9986b5625bb609b154766d2e138b61e15655f60b710sewardj for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { 9996b5625bb609b154766d2e138b61e15655f60b710sewardj map = (struct _DebugInfoMapping*)VG_(indexXA)(di->fsm.maps, i); 10006b5625bb609b154766d2e138b61e15655f60b710sewardj if (map->ro && map->avma == a && map->size == len) 10016b5625bb609b154766d2e138b61e15655f60b710sewardj break; 10026b5625bb609b154766d2e138b61e15655f60b710sewardj map = NULL; 10036b5625bb609b154766d2e138b61e15655f60b710sewardj } 10046b5625bb609b154766d2e138b61e15655f60b710sewardj if (!map) 10056b5625bb609b154766d2e138b61e15655f60b710sewardj continue; /* this isn't an upgrade of an r-- mapping */ 1006731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* looks like we're in luck! */ 1007731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj break; 1008731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj } 1009731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (di == NULL) 1010731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return; /* didn't find anything */ 1011731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 10126b5625bb609b154766d2e138b61e15655f60b710sewardj /* Do the upgrade. Simply update the flags of the mapping 10136b5625bb609b154766d2e138b61e15655f60b710sewardj and pretend we never saw the RO map at all. */ 1014731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj vg_assert(di->fsm.have_ro_map); 10156b5625bb609b154766d2e138b61e15655f60b710sewardj map->rx = True; 10166b5625bb609b154766d2e138b61e15655f60b710sewardj map->ro = False; 1017731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj di->fsm.have_rx_map = True; 1018731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj di->fsm.have_ro_map = False; 10196b5625bb609b154766d2e138b61e15655f60b710sewardj /* See if there are any more ro mappings */ 10206b5625bb609b154766d2e138b61e15655f60b710sewardj for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { 10216b5625bb609b154766d2e138b61e15655f60b710sewardj map = (struct _DebugInfoMapping*)VG_(indexXA)(di->fsm.maps, i); 10226b5625bb609b154766d2e138b61e15655f60b710sewardj if (map->ro) { 10236b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.have_ro_map = True; 10246b5625bb609b154766d2e138b61e15655f60b710sewardj break; 10256b5625bb609b154766d2e138b61e15655f60b710sewardj } 10266b5625bb609b154766d2e138b61e15655f60b710sewardj } 10276b5625bb609b154766d2e138b61e15655f60b710sewardj 10286b5625bb609b154766d2e138b61e15655f60b710sewardj /* Check if we're now in an accept state and read debuginfo. Finally. */ 10296b5625bb609b154766d2e138b61e15655f60b710sewardj if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) { 10306b5625bb609b154766d2e138b61e15655f60b710sewardj ULong di_handle __attribute__((unused)) 10316b5625bb609b154766d2e138b61e15655f60b710sewardj = di_notify_ACHIEVE_ACCEPT_STATE( di ); 10326b5625bb609b154766d2e138b61e15655f60b710sewardj /* di_handle is ignored. That's not a problem per se -- it just 10336b5625bb609b154766d2e138b61e15655f60b710sewardj means nobody will ever be able to refer to this debuginfo by 10346b5625bb609b154766d2e138b61e15655f60b710sewardj handle since nobody will know what the handle value is. */ 10356b5625bb609b154766d2e138b61e15655f60b710sewardj } 1036731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj} 1037731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 1038731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 1039c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--------- PDB (windows debug info) reading --------- */ 1040c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1041c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/* this should really return ULong, as per VG_(di_notify_mmap). */ 1042c8259b85b701d25d72aabe9dc0a8154517f96913sewardjvoid VG_(di_notify_pdb_debuginfo)( Int fd_obj, Addr avma_obj, 104354c45db2f978055aeca91aaccb05aac825523e6csewardj SizeT total_size, PtrdiffT bias_obj ) 1044c8259b85b701d25d72aabe9dc0a8154517f96913sewardj{ 104513ac96dea734b3933a73524b991ac64fb48a4d57sewardj Int i, r, sz_exename; 1046c8259b85b701d25d72aabe9dc0a8154517f96913sewardj ULong obj_mtime, pdb_mtime; 1047c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Char exename[VKI_PATH_MAX]; 1048c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Char* pdbname = NULL; 1049c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Char* dot; 1050c8259b85b701d25d72aabe9dc0a8154517f96913sewardj SysRes sres; 1051c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Int fd_pdbimage; 1052c8259b85b701d25d72aabe9dc0a8154517f96913sewardj SizeT n_pdbimage; 1053c8259b85b701d25d72aabe9dc0a8154517f96913sewardj struct vg_stat stat_buf; 1054c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1055c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) { 1056738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "\n"); 1057c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(message)(Vg_UserMsg, 1058cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj "LOAD_PDB_DEBUGINFO: clreq: fd=%d, avma=%#lx, total_size=%lu, " 105954c45db2f978055aeca91aaccb05aac825523e6csewardj "bias=%#lx\n", 106054c45db2f978055aeca91aaccb05aac825523e6csewardj fd_obj, avma_obj, total_size, bias_obj 1061c8259b85b701d25d72aabe9dc0a8154517f96913sewardj ); 1062c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1063c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1064c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* 'fd' refers to the .exe/.dll we're dealing with. Get its modification 1065c8259b85b701d25d72aabe9dc0a8154517f96913sewardj time into obj_mtime. */ 1066c8259b85b701d25d72aabe9dc0a8154517f96913sewardj r = VG_(fstat)(fd_obj, &stat_buf); 1067c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (r == -1) 1068c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; /* stat failed ?! */ 1069c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(r == 0); 10709c20ece00e07304f66da5f43b87ec45bc9c04550njn obj_mtime = stat_buf.mtime; 1071c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1072c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* and get its name into exename[]. */ 1073c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(VKI_PATH_MAX > 100); /* to ensure /proc/self/fd/%d is safe */ 1074c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(memset)(exename, 0, sizeof(exename)); 1075c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(sprintf)(exename, "/proc/self/fd/%d", fd_obj); 1076c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* convert exename from a symlink to real name .. overwrites the 1077c8259b85b701d25d72aabe9dc0a8154517f96913sewardj old contents of the buffer. Ick. */ 1078c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sz_exename = VG_(readlink)(exename, exename, sizeof(exename)-2 ); 1079c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (sz_exename == -1) 1080c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; /* readlink failed ?! */ 1081c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(sz_exename >= 0 && sz_exename < sizeof(exename)); 1082c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(exename[sizeof(exename)-1] == 0); 1083c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1084c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) { 1085738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: objname: %s\n", exename); 1086c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1087c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 108813ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Try to get the PDB file name from the executable. */ 108913ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = ML_(find_name_of_pdb_file)(exename); 109013ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (pdbname) { 109113ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(VG_(strlen)(pdbname) >= 5); /* 5 = strlen("X.pdb") */ 109213ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* So we successfully extracted a name from the PE file. But it's 109313ac96dea734b3933a73524b991ac64fb48a4d57sewardj likely to be of the form 109413ac96dea734b3933a73524b991ac64fb48a4d57sewardj e:\foo\bar\xyzzy\wibble.pdb 109513ac96dea734b3933a73524b991ac64fb48a4d57sewardj and we need to change it into something we can actually open 109613ac96dea734b3933a73524b991ac64fb48a4d57sewardj in Wine-world, which basically means turning it into 109713ac96dea734b3933a73524b991ac64fb48a4d57sewardj $HOME/.wine/drive_e/foo/bar/xyzzy/wibble.pdb 109813ac96dea734b3933a73524b991ac64fb48a4d57sewardj We also take into account $WINEPREFIX, if it is set. 109913ac96dea734b3933a73524b991ac64fb48a4d57sewardj For the moment, if the name isn't fully qualified, just forget it 110013ac96dea734b3933a73524b991ac64fb48a4d57sewardj (we'd have to root around to find where the pdb actually is) 110113ac96dea734b3933a73524b991ac64fb48a4d57sewardj */ 110213ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Change all the backslashes to forward slashes */ 110313ac96dea734b3933a73524b991ac64fb48a4d57sewardj for (i = 0; pdbname[i]; i++) { 110413ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (pdbname[i] == '\\') 110513ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname[i] = '/'; 110613ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 110713ac96dea734b3933a73524b991ac64fb48a4d57sewardj Bool is_quald 110813ac96dea734b3933a73524b991ac64fb48a4d57sewardj = ('a' <= VG_(tolower)(pdbname[0]) && VG_(tolower)(pdbname[0]) <= 'z') 110913ac96dea734b3933a73524b991ac64fb48a4d57sewardj && pdbname[1] == ':' 111013ac96dea734b3933a73524b991ac64fb48a4d57sewardj && pdbname[2] == '/'; 111113ac96dea734b3933a73524b991ac64fb48a4d57sewardj HChar* home = VG_(getenv)("HOME"); 111213ac96dea734b3933a73524b991ac64fb48a4d57sewardj HChar* wpfx = VG_(getenv)("WINEPREFIX"); 111313ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (is_quald && wpfx) { 111413ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Change e:/foo/bar/xyzzy/wibble.pdb 111513ac96dea734b3933a73524b991ac64fb48a4d57sewardj to $WINEPREFIX/drive_e/foo/bar/xyzzy/wibble.pdb 111613ac96dea734b3933a73524b991ac64fb48a4d57sewardj */ 111713ac96dea734b3933a73524b991ac64fb48a4d57sewardj Int mashedSzB = VG_(strlen)(pdbname) + VG_(strlen)(wpfx) + 50/*misc*/; 111813ac96dea734b3933a73524b991ac64fb48a4d57sewardj HChar* mashed = ML_(dinfo_zalloc)("di.debuginfo.dnpdi.1", mashedSzB); 111998500e2ee5f63f9c0af57835f7620d30848115f4bart VG_(snprintf)(mashed, mashedSzB, "%s/drive_%c%s", 112098500e2ee5f63f9c0af57835f7620d30848115f4bart wpfx, pdbname[0], &pdbname[2]); 112113ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(mashed[mashedSzB-1] == 0); 112213ac96dea734b3933a73524b991ac64fb48a4d57sewardj ML_(dinfo_free)(pdbname); 112313ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = mashed; 112413ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 112513ac96dea734b3933a73524b991ac64fb48a4d57sewardj else if (is_quald && home && !wpfx) { 112613ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Change e:/foo/bar/xyzzy/wibble.pdb 112713ac96dea734b3933a73524b991ac64fb48a4d57sewardj to $HOME/.wine/drive_e/foo/bar/xyzzy/wibble.pdb 112813ac96dea734b3933a73524b991ac64fb48a4d57sewardj */ 112913ac96dea734b3933a73524b991ac64fb48a4d57sewardj Int mashedSzB = VG_(strlen)(pdbname) + VG_(strlen)(home) + 50/*misc*/; 113013ac96dea734b3933a73524b991ac64fb48a4d57sewardj HChar* mashed = ML_(dinfo_zalloc)("di.debuginfo.dnpdi.2", mashedSzB); 113198500e2ee5f63f9c0af57835f7620d30848115f4bart VG_(snprintf)(mashed, mashedSzB, "%s/.wine/drive_%c%s", 113298500e2ee5f63f9c0af57835f7620d30848115f4bart home, pdbname[0], &pdbname[2]); 113313ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(mashed[mashedSzB-1] == 0); 113413ac96dea734b3933a73524b991ac64fb48a4d57sewardj ML_(dinfo_free)(pdbname); 113513ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = mashed; 113613ac96dea734b3933a73524b991ac64fb48a4d57sewardj } else { 113713ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* It's not a fully qualified path, or neither $HOME nor $WINE 113813ac96dea734b3933a73524b991ac64fb48a4d57sewardj are set (strange). Give up. */ 113913ac96dea734b3933a73524b991ac64fb48a4d57sewardj ML_(dinfo_free)(pdbname); 114013ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = NULL; 114113ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 114213ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 1143c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 114413ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Try s/exe/pdb/ if we don't have a valid pdbname. */ 114513ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (!pdbname) { 114613ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Try to find a matching PDB file from which to read debuginfo. 114713ac96dea734b3933a73524b991ac64fb48a4d57sewardj Windows PE files have symbol tables and line number information, 114813ac96dea734b3933a73524b991ac64fb48a4d57sewardj but MSVC doesn't seem to use them. */ 114913ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Why +5 ? Because in the worst case, we could find a dot as the 115013ac96dea734b3933a73524b991ac64fb48a4d57sewardj last character of pdbname, and we'd then put "pdb" right after 115113ac96dea734b3933a73524b991ac64fb48a4d57sewardj it, hence extending it a bit. */ 115213ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = ML_(dinfo_zalloc)("di.debuginfo.lpd1", sz_exename+5); 115313ac96dea734b3933a73524b991ac64fb48a4d57sewardj VG_(strcpy)(pdbname, exename); 115413ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(pdbname[sz_exename+5-1] == 0); 115513ac96dea734b3933a73524b991ac64fb48a4d57sewardj dot = VG_(strrchr)(pdbname, '.'); 115613ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (!dot) 115713ac96dea734b3933a73524b991ac64fb48a4d57sewardj goto out; /* there's no dot in the exe's name ?! */ 115813ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (dot[1] == 0) 115913ac96dea734b3933a73524b991ac64fb48a4d57sewardj goto out; /* hmm, path ends in "." */ 116013ac96dea734b3933a73524b991ac64fb48a4d57sewardj 116113ac96dea734b3933a73524b991ac64fb48a4d57sewardj if ('A' <= dot[1] && dot[1] <= 'Z') 116213ac96dea734b3933a73524b991ac64fb48a4d57sewardj VG_(strcpy)(dot, ".PDB"); 116313ac96dea734b3933a73524b991ac64fb48a4d57sewardj else 116413ac96dea734b3933a73524b991ac64fb48a4d57sewardj VG_(strcpy)(dot, ".pdb"); 116513ac96dea734b3933a73524b991ac64fb48a4d57sewardj 116613ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(pdbname[sz_exename+5-1] == 0); 116713ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 1168c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1169c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* See if we can find it, and check it's in-dateness. */ 1170c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sres = VG_(stat)(pdbname, &stat_buf); 1171cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) { 1172738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "Warning: Missing or un-stat-able %s\n", 1173c8259b85b701d25d72aabe9dc0a8154517f96913sewardj pdbname); 1174c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) 1175738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: missing: %s\n", pdbname); 1176c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; 1177c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 11789c20ece00e07304f66da5f43b87ec45bc9c04550njn pdb_mtime = stat_buf.mtime; 11797138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj 1180ced85060ebfd32f26de8e6a6f11567c9ac2b096asewardj if (obj_mtime > pdb_mtime + 60ULL) { 11817138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj /* PDB file is older than PE file. Really, the PDB should be 11827138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj newer than the PE, but that doesn't always seem to be the 11837138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj case. Allow the PDB to be up to one minute older. 11847138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj Otherwise, it's probably out of date, in which case ignore it 11857138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj or we will either (a) print wrong stack traces or more likely 11867138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj (b) crash. 11877138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj */ 1188738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, 1189ced85060ebfd32f26de8e6a6f11567c9ac2b096asewardj "Warning: %s (mtime = %llu)\n" 1190ced85060ebfd32f26de8e6a6f11567c9ac2b096asewardj " is older than %s (mtime = %llu)\n", 1191ced85060ebfd32f26de8e6a6f11567c9ac2b096asewardj pdbname, pdb_mtime, exename, obj_mtime); 1192c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1193c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1194c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sres = VG_(open)(pdbname, VKI_O_RDONLY, 0); 1195cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) { 1196738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "Warning: Can't open %s\n", pdbname); 1197c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; 1198c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1199c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1200cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj /* Looks promising; go on to try and read stuff from it. But don't 1201cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj mmap the file. Instead mmap free space and read the file into 1202cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj it. This is because files on CIFS filesystems that are mounted 1203cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj '-o directio' can't be mmap'd, and that mount option is needed 1204cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj to make CIFS work reliably. (See 1205cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj http://www.nabble.com/Corrupted-data-on-write-to- 1206cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj Windows-2003-Server-t2782623.html) 1207cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj This is slower, but at least it works reliably. */ 1208cda2f0fbda4c4b2644babc830244be8aed95de1dnjn fd_pdbimage = sr_Res(sres); 12099c20ece00e07304f66da5f43b87ec45bc9c04550njn n_pdbimage = stat_buf.size; 1210cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj if (n_pdbimage == 0 || n_pdbimage > 0x7FFFFFFF) { 1211cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // 0x7FFFFFFF: why? Because the VG_(read) just below only 1212cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // can deal with a signed int as the size of data to read, 1213cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // so we can't reliably check for read failure for files 1214cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // greater than that size. Hence just skip them; we're 1215cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // unlikely to encounter a PDB that large anyway. 1216cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj VG_(close)(fd_pdbimage); 1217cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj goto out; 1218cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj } 1219cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj sres = VG_(am_mmap_anon_float_valgrind)( n_pdbimage ); 1220cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) { 1221c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(close)(fd_pdbimage); 1222c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; 1223c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1224c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1225cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj void* pdbimage = (void*)sr_Res(sres); 1226cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj r = VG_(read)( fd_pdbimage, pdbimage, (Int)n_pdbimage ); 1227cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj if (r < 0 || r != (Int)n_pdbimage) { 1228cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage ); 1229cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj VG_(close)(fd_pdbimage); 1230cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj goto out; 1231cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj } 1232cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj 1233c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) 1234738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: pdbname: %s\n", pdbname); 1235c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1236c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* play safe; always invalidate the CFI cache. I don't know if 1237c8259b85b701d25d72aabe9dc0a8154517f96913sewardj this is necessary, but anyway .. */ 1238c8259b85b701d25d72aabe9dc0a8154517f96913sewardj cfsi_cache__invalidate(); 1239c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* dump old info for this range, if any */ 1240c8259b85b701d25d72aabe9dc0a8154517f96913sewardj discard_syms_in_range( avma_obj, total_size ); 1241c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 12420f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj { DebugInfo* di = find_or_create_DebugInfo_for(exename); 1243c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1244c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* this di must be new, since we just nuked any old stuff in the range */ 1245a5acac39bf3be7546222b1316faee5ee524be0d1sewardj vg_assert(di && !di->fsm.have_rx_map && !di->fsm.have_rw_map); 1246c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(!di->have_dinfo); 1247c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1248c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* don't set up any of the di-> fields; let 1249c8259b85b701d25d72aabe9dc0a8154517f96913sewardj ML_(read_pdb_debug_info) do it. */ 125054c45db2f978055aeca91aaccb05aac825523e6csewardj ML_(read_pdb_debug_info)( di, avma_obj, bias_obj, 1251c8259b85b701d25d72aabe9dc0a8154517f96913sewardj pdbimage, n_pdbimage, pdbname, pdb_mtime ); 1252c8259b85b701d25d72aabe9dc0a8154517f96913sewardj // JRS fixme: take notice of return value from read_pdb_debug_info, 1253c8259b85b701d25d72aabe9dc0a8154517f96913sewardj // and handle failure 1254c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(di->have_dinfo); // fails if PDB read failed 1255c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage ); 1256c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(close)(fd_pdbimage); 1257cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj 1258cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj if (VG_(clo_verbosity) > 0) { 1259cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: done: " 1260cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj "%lu syms, %lu src locs, %lu fpo recs\n", 1261cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj di->symtab_used, di->loctab_used, di->fpo_size); 1262cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj } 1263c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1264c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1265c8259b85b701d25d72aabe9dc0a8154517f96913sewardj out: 1266c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (pdbname) ML_(dinfo_free)(pdbname); 1267c8259b85b701d25d72aabe9dc0a8154517f96913sewardj} 1268c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 12698b68b64759254d514d98328c496cbd88cde4c9a5njn#endif /* defined(VGO_linux) || defined(VGO_darwin) */ 12704ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 12714ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 1272eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1273eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- ---*/ 1274eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- TOP LEVEL: QUERYING EXISTING DEBUG INFO ---*/ 1275eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- ---*/ 1276eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1277eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 12789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid VG_(di_discard_ALL_debuginfo)( void ) 12799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 12809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo *di, *di2; 12819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di = debugInfo_list; 12829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj while (di) { 12839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di2 = di->next; 12849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("XXX rm %p\n", di); 12859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj free_DebugInfo( di ); 12869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di = di2; 12879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 12889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 12899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 12909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 12916b5625bb609b154766d2e138b61e15655f60b710sewardjstruct _DebugInfoMapping* ML_(find_rx_mapping) ( struct _DebugInfo* di, 12926b5625bb609b154766d2e138b61e15655f60b710sewardj Addr lo, Addr hi ) 12936b5625bb609b154766d2e138b61e15655f60b710sewardj{ 12946b5625bb609b154766d2e138b61e15655f60b710sewardj Word i; 12956b5625bb609b154766d2e138b61e15655f60b710sewardj vg_assert(lo <= hi); 12966b5625bb609b154766d2e138b61e15655f60b710sewardj 12976b5625bb609b154766d2e138b61e15655f60b710sewardj /* Optimization: Try to use the last matched rx mapping first */ 12986b5625bb609b154766d2e138b61e15655f60b710sewardj if ( di->last_rx_map 12996b5625bb609b154766d2e138b61e15655f60b710sewardj && lo >= di->last_rx_map->avma 13006b5625bb609b154766d2e138b61e15655f60b710sewardj && hi < di->last_rx_map->avma + di->last_rx_map->size) 13016b5625bb609b154766d2e138b61e15655f60b710sewardj return di->last_rx_map; 13026b5625bb609b154766d2e138b61e15655f60b710sewardj 13036b5625bb609b154766d2e138b61e15655f60b710sewardj for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { 13046b5625bb609b154766d2e138b61e15655f60b710sewardj struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i); 13056b5625bb609b154766d2e138b61e15655f60b710sewardj if ( map->rx && map->size > 0 13066b5625bb609b154766d2e138b61e15655f60b710sewardj && lo >= map->avma && hi < map->avma + map->size) { 13076b5625bb609b154766d2e138b61e15655f60b710sewardj di->last_rx_map = map; 13086b5625bb609b154766d2e138b61e15655f60b710sewardj return map; 13096b5625bb609b154766d2e138b61e15655f60b710sewardj } 13106b5625bb609b154766d2e138b61e15655f60b710sewardj } 13116b5625bb609b154766d2e138b61e15655f60b710sewardj 13126b5625bb609b154766d2e138b61e15655f60b710sewardj return NULL; 13136b5625bb609b154766d2e138b61e15655f60b710sewardj} 13146b5625bb609b154766d2e138b61e15655f60b710sewardj 13156b5625bb609b154766d2e138b61e15655f60b710sewardj 1316eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1317eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Use of symbol table & location info to create ---*/ 1318eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- plausible-looking stack dumps. ---*/ 1319eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1320eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1321eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Search all symtabs that we know about to locate ptr. If found, set 1322b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi to the relevant DebugInfo, and *symno to the symtab entry 1323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *number within that. If not found, *psi is set to NULL. 1324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj If findText==True, only text symbols are searched for. 1325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj If findText==False, only data symbols are searched for. 1326b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/ 1327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void search_all_symtabs ( Addr ptr, /*OUT*/DebugInfo** pdi, 1328f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*OUT*/Word* symno, 1329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool match_anywhere_in_sym, 1330b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool findText ) 1331eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1332f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool inRange; 1335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (findText) { 133951c9d3750448a4f2c95d22879e2f9f4bbd22bcfesewardj /* Consider any symbol in the r-x mapped area to be text. 134051c9d3750448a4f2c95d22879e2f9f4bbd22bcfesewardj See Comment_Regarding_Text_Range_Checks in storage.c for 134151c9d3750448a4f2c95d22879e2f9f4bbd22bcfesewardj details. */ 1342a5acac39bf3be7546222b1316faee5ee524be0d1sewardj inRange = di->fsm.have_rx_map 13436b5625bb609b154766d2e138b61e15655f60b710sewardj && (ML_(find_rx_mapping)(di, ptr, ptr) != NULL); 1344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 1345b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj inRange = (di->data_present 1346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_size > 0 1347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_avma <= ptr 1348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->data_avma + di->data_size) 1349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || 1350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (di->sdata_present 1351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_size > 0 1352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_avma <= ptr 1353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->sdata_avma + di->sdata_size) 1354b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || 1355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (di->bss_present 1356b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_size > 0 1357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_avma <= ptr 13585706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && ptr < di->bss_avma + di->bss_size) 13595706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj || 13605706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj (di->sbss_present 13615706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->sbss_size > 0 13625706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->sbss_avma <= ptr 13635706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && ptr < di->sbss_avma + di->sbss_size) 13645706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj || 13655706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj (di->rodata_present 13665706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->rodata_size > 0 13675706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->rodata_avma <= ptr 13685706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && ptr < di->rodata_avma + di->rodata_size); 1369eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!inRange) continue; 1372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sno = ML_(search_one_symtab) ( 1374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di, ptr, match_anywhere_in_sym, findText ); 1375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (sno == -1) goto not_found; 1376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *symno = sno; 1377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = di; 1378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; 1379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1380eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1381eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj not_found: 1382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = NULL; 1383eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1384eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1385eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1386eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Search all loctabs that we know about to locate ptr. If found, set 1387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi to the relevant DebugInfo, and *locno to the loctab entry 1388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *number within that. If not found, *pdi is set to NULL. */ 1389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void search_all_loctabs ( Addr ptr, /*OUT*/DebugInfo** pdi, 1390f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*OUT*/Word* locno ) 1391eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1392f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word lno; 1393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 13965706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->text_size > 0 1397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= ptr 1398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->text_avma + di->text_size) { 1399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj lno = ML_(search_one_loctab) ( di, ptr ); 1400eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (lno == -1) goto not_found; 1401eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *locno = lno; 1402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = di; 1403eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return; 1404eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1405eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1406eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj not_found: 1407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = NULL; 1408eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1409eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1410eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1411eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* The whole point of this whole big deal: map a code address to a 1412eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj plausible symbol name. Returns False if no idea; otherwise True. 14136b7611bf42a0fbb62e047d8c43b008205bd21e75njn Caller supplies buf and nbuf. If do_cxx_demangling is False, don't do 14146b7611bf42a0fbb62e047d8c43b008205bd21e75njn C++ demangling, regardless of VG_(clo_demangle) -- probably because the 14156b7611bf42a0fbb62e047d8c43b008205bd21e75njn call has come from VG_(get_fnname_raw)(). findText 1416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj indicates whether we're looking for a text symbol or a data symbol 1417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj -- caller must choose one kind or the other. */ 1418eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjstatic 14196b7611bf42a0fbb62e047d8c43b008205bd21e75njnBool get_sym_name ( Bool do_cxx_demangling, Bool do_z_demangling, 14206b7611bf42a0fbb62e047d8c43b008205bd21e75njn Bool do_below_main_renaming, 14216b7611bf42a0fbb62e047d8c43b008205bd21e75njn Addr a, Char* buf, Int nbuf, 1422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool match_anywhere_in_sym, Bool show_offset, 1423c4431bfe04c7490ea2d74939d222d87f13f30960njn Bool findText, /*OUT*/PtrdiffT* offsetP ) 1424eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1426f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1427c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT offset; 1428eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj search_all_symtabs ( a, &di, &sno, match_anywhere_in_sym, findText ); 1430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == NULL) 1431eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 14326882443ef154bca367bc591287de641e43a9e108njn 1433a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(di->symtab[sno].pri_name); 14346b7611bf42a0fbb62e047d8c43b008205bd21e75njn VG_(demangle) ( do_cxx_demangling, do_z_demangling, 1435a5cace0c2a3e212931badbf6398a0cd98393121asewardj di->symtab[sno].pri_name, buf, nbuf ); 14366b7611bf42a0fbb62e047d8c43b008205bd21e75njn 14376b7611bf42a0fbb62e047d8c43b008205bd21e75njn /* Do the below-main hack */ 14386b7611bf42a0fbb62e047d8c43b008205bd21e75njn // To reduce the endless nuisance of multiple different names 14396b7611bf42a0fbb62e047d8c43b008205bd21e75njn // for "the frame below main()" screwing up the testsuite, change all 14406b7611bf42a0fbb62e047d8c43b008205bd21e75njn // known incarnations of said into a single name, "(below main)", if 14416b7611bf42a0fbb62e047d8c43b008205bd21e75njn // --show-below-main=yes. 14426b7611bf42a0fbb62e047d8c43b008205bd21e75njn if ( do_below_main_renaming && ! VG_(clo_show_below_main) && 14436b7611bf42a0fbb62e047d8c43b008205bd21e75njn Vg_FnNameBelowMain == VG_(get_fnname_kind)(buf) ) 14446b7611bf42a0fbb62e047d8c43b008205bd21e75njn { 14456b7611bf42a0fbb62e047d8c43b008205bd21e75njn VG_(strncpy_safely)(buf, "(below main)", nbuf); 1446eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset = a - di->symtab[sno].addr; 1448c4431bfe04c7490ea2d74939d222d87f13f30960njn if (offsetP) *offsetP = offset; 1449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1450eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (show_offset && offset != 0) { 1451eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char buf2[12]; 1452eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char* symend = buf + VG_(strlen)(buf); 1453eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char* end = buf + nbuf; 1454eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Int len; 1455eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1456c4431bfe04c7490ea2d74939d222d87f13f30960njn len = VG_(sprintf)(buf2, "%c%ld", 1457eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj offset < 0 ? '-' : '+', 1458eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj offset < 0 ? -offset : offset); 1459eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(len < (Int)sizeof(buf2)); 1460eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1461eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (len < (end - symend)) { 1462eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char *cp = buf2; 1463eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(memcpy)(symend, cp, len+1); 1464eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1465eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1466eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 14676b7611bf42a0fbb62e047d8c43b008205bd21e75njn buf[nbuf-1] = 0; /* paranoia */ 14686b7611bf42a0fbb62e047d8c43b008205bd21e75njn 1469eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1470eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1471eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1472eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* ppc64-linux only: find the TOC pointer (R2 value) that should be in 1473eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj force at the entry point address of the function containing 1474eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj guest_code_addr. Returns 0 if not known. */ 1475eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjAddr VG_(get_tocptr) ( Addr guest_code_addr ) 1476eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1477b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1478f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1479eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_symtabs ( guest_code_addr, 1480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj &si, &sno, 1481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj True/*match_anywhere_in_fun*/, 1482b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj True/*consider text symbols only*/ ); 1483eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 1484eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return 0; 1485eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj else 1486eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return si->symtab[sno].tocptr; 1487eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1488eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1489eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 1490eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj match anywhere in function, but don't show offsets. */ 1491eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_fnname) ( Addr a, Char* buf, Int nbuf ) 1492eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 14936b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, 14946b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 14956b7611bf42a0fbb62e047d8c43b008205bd21e75njn a, buf, nbuf, 1496b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1497b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1498b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1499b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1500eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1501eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1502eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 1503eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj match anywhere in function, and show offset if nonzero. */ 1504eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_fnname_w_offset) ( Addr a, Char* buf, Int nbuf ) 1505eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 15066b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, 15076b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 15086b7611bf42a0fbb62e047d8c43b008205bd21e75njn a, buf, nbuf, 1509b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1510b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/True, 1511b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1512b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1513eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1514eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1515eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 1516eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj only succeed if 'a' matches first instruction of function, 1517eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj and don't show offsets. */ 1518eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_fnname_if_entry) ( Addr a, Char* buf, Int nbuf ) 1519eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 15206b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, 15216b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 15226b7611bf42a0fbb62e047d8c43b008205bd21e75njn a, buf, nbuf, 1523b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/False, 1524b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1525b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1526b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1527eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1528eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 15296b7611bf42a0fbb62e047d8c43b008205bd21e75njn/* This is only available to core... don't C++-demangle, don't Z-demangle, 15306b7611bf42a0fbb62e047d8c43b008205bd21e75njn don't rename below-main, match anywhere in function, and don't show 15316b7611bf42a0fbb62e047d8c43b008205bd21e75njn offsets. */ 15326b7611bf42a0fbb62e047d8c43b008205bd21e75njnBool VG_(get_fnname_raw) ( Addr a, Char* buf, Int nbuf ) 1533eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 15346b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, 15356b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/False, 15366b7611bf42a0fbb62e047d8c43b008205bd21e75njn a, buf, nbuf, 1537b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1539b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1540b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1541eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1542eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1543eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is only available to core... don't demangle C++ names, but do 15446b7611bf42a0fbb62e047d8c43b008205bd21e75njn do Z-demangling and below-main-renaming, match anywhere in function, and 15456b7611bf42a0fbb62e047d8c43b008205bd21e75njn don't show offsets. */ 15466b7611bf42a0fbb62e047d8c43b008205bd21e75njnBool VG_(get_fnname_no_cxx_demangle) ( Addr a, Char* buf, Int nbuf ) 1547eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 15486b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/True, 15496b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 15506b7611bf42a0fbb62e047d8c43b008205bd21e75njn a, buf, nbuf, 15516b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*match_anywhere_in_fun*/True, 15526b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*show offset?*/False, 15536b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*text syms only*/True, 15546b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*offsetP*/NULL ); 1555eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1556eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 15575db15403e889d4db339b342bc2a824ef0bfaa654sewardj/* mips-linux only: find the offset of current address. This is needed for 15585db15403e889d4db339b342bc2a824ef0bfaa654sewardj stack unwinding for MIPS. 15595db15403e889d4db339b342bc2a824ef0bfaa654sewardj*/ 15605db15403e889d4db339b342bc2a824ef0bfaa654sewardjBool VG_(get_inst_offset_in_function)( Addr a, 15615db15403e889d4db339b342bc2a824ef0bfaa654sewardj /*OUT*/PtrdiffT* offset ) 15625db15403e889d4db339b342bc2a824ef0bfaa654sewardj{ 15635db15403e889d4db339b342bc2a824ef0bfaa654sewardj Char fnname[64]; 15645db15403e889d4db339b342bc2a824ef0bfaa654sewardj return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, 15655db15403e889d4db339b342bc2a824ef0bfaa654sewardj /*below-main-renaming*/False, 15665db15403e889d4db339b342bc2a824ef0bfaa654sewardj a, fnname, 64, 15675db15403e889d4db339b342bc2a824ef0bfaa654sewardj /*match_anywhere_in_sym*/True, 15685db15403e889d4db339b342bc2a824ef0bfaa654sewardj /*show offset?*/True, 15695db15403e889d4db339b342bc2a824ef0bfaa654sewardj /*data syms only please*/True, 15705db15403e889d4db339b342bc2a824ef0bfaa654sewardj offset ); 15715db15403e889d4db339b342bc2a824ef0bfaa654sewardj} 15725db15403e889d4db339b342bc2a824ef0bfaa654sewardj 15736882443ef154bca367bc591287de641e43a9e108njnVg_FnNameKind VG_(get_fnname_kind) ( Char* name ) 15746882443ef154bca367bc591287de641e43a9e108njn{ 15756882443ef154bca367bc591287de641e43a9e108njn if (VG_STREQ("main", name)) { 15766882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameMain; 15776882443ef154bca367bc591287de641e43a9e108njn 15786882443ef154bca367bc591287de641e43a9e108njn } else if ( 15793026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGO_linux) 15806882443ef154bca367bc591287de641e43a9e108njn VG_STREQ("__libc_start_main", name) || // glibc glibness 15816882443ef154bca367bc591287de641e43a9e108njn VG_STREQ("generic_start_main", name) || // Yellow Dog doggedness 15823026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGO_darwin) 1583f76d27a697a7b0bf3b84490baf60623fc96a23afnjn // See readmacho.c for an explanation of this. 1584f76d27a697a7b0bf3b84490baf60623fc96a23afnjn VG_STREQ("start_according_to_valgrind", name) || // Darwin, darling 15853026f71684a930286186aa10fef266c304672e8fsewardj# else 15863026f71684a930286186aa10fef266c304672e8fsewardj# error "Unknown OS" 15873026f71684a930286186aa10fef266c304672e8fsewardj# endif 15886882443ef154bca367bc591287de641e43a9e108njn 0) { 15896882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameBelowMain; 15906882443ef154bca367bc591287de641e43a9e108njn 15916882443ef154bca367bc591287de641e43a9e108njn } else { 15926882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameNormal; 15936882443ef154bca367bc591287de641e43a9e108njn } 15946882443ef154bca367bc591287de641e43a9e108njn} 15956882443ef154bca367bc591287de641e43a9e108njn 15966882443ef154bca367bc591287de641e43a9e108njnVg_FnNameKind VG_(get_fnname_kind_from_IP) ( Addr ip ) 15976882443ef154bca367bc591287de641e43a9e108njn{ 15986882443ef154bca367bc591287de641e43a9e108njn // We don't need a big buffer; all the special names are small. 15996882443ef154bca367bc591287de641e43a9e108njn #define BUFLEN 50 16006882443ef154bca367bc591287de641e43a9e108njn Char buf[50]; 16016882443ef154bca367bc591287de641e43a9e108njn 16026882443ef154bca367bc591287de641e43a9e108njn // We don't demangle, because it's faster not to, and the special names 16036882443ef154bca367bc591287de641e43a9e108njn // we're looking for won't be demangled. 16046b7611bf42a0fbb62e047d8c43b008205bd21e75njn if (VG_(get_fnname_raw) ( ip, buf, BUFLEN )) { 16056882443ef154bca367bc591287de641e43a9e108njn buf[BUFLEN-1] = '\0'; // paranoia 16066882443ef154bca367bc591287de641e43a9e108njn return VG_(get_fnname_kind)(buf); 16076882443ef154bca367bc591287de641e43a9e108njn } else { 16086882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameNormal; // Don't know the name, treat it as normal. 16096882443ef154bca367bc591287de641e43a9e108njn } 16106882443ef154bca367bc591287de641e43a9e108njn} 16116882443ef154bca367bc591287de641e43a9e108njn 1612b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Looks up data_addr in the collection of data symbols, and if found 1613b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj puts its name (or as much as will fit) into dname[0 .. n_dname-1], 1614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which is guaranteed to be zero terminated. Also data_addr's offset 1615b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj from the symbol start is put into *offset. */ 1616b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool VG_(get_datasym_and_offset)( Addr data_addr, 1617b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/Char* dname, Int n_dname, 1618c4431bfe04c7490ea2d74939d222d87f13f30960njn /*OUT*/PtrdiffT* offset ) 1619b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 1620b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool ok; 1621b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_dname > 1); 16226b7611bf42a0fbb62e047d8c43b008205bd21e75njn ok = get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, 16236b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/False, 16246b7611bf42a0fbb62e047d8c43b008205bd21e75njn data_addr, dname, n_dname, 1625b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_sym*/True, 1626b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*data syms only please*/False, 1628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset ); 1629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!ok) 1630b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 1631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname[n_dname-1] = 0; 1632b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 1633b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 1634b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1635b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Map a code address to the name of a shared object file or the 1636b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj executable. Returns False if no idea; otherwise True. Doesn't 1637b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj require debug info. Caller supplies buf and nbuf. */ 1638eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_objname) ( Addr a, Char* buf, Int nbuf ) 1639eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1640b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1641f32ec7f0de8a651bc16a1b2e448c0106d8669889tom const NSegment *seg; 1642f32ec7f0de8a651bc16a1b2e448c0106d8669889tom HChar* filename; 16434ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj vg_assert(nbuf > 0); 16447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Look in the debugInfo_list to find the name. In most cases we 16457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj expect this to produce a result. */ 1646b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1647b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 16485706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->text_size > 0 1649b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= a 1650b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a < di->text_avma + di->text_size) { 1651a5acac39bf3be7546222b1316faee5ee524be0d1sewardj VG_(strncpy_safely)(buf, di->fsm.filename, nbuf); 16524ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj buf[nbuf-1] = 0; 1653eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1654eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1655eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 16567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Last-ditch fallback position: if we don't find the address in 16577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj the debugInfo_list, ask the address space manager whether it 16587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj knows the name of the file associated with this mapping. This 16597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj allows us to print the names of exe/dll files in the stack trace 16607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj when running programs under wine. */ 16617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if ( (seg = VG_(am_find_nsegment(a))) != NULL 16627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj && (filename = VG_(am_get_filename)(seg)) != NULL ) { 1663f32ec7f0de8a651bc16a1b2e448c0106d8669889tom VG_(strncpy_safely)(buf, filename, nbuf); 1664f32ec7f0de8a651bc16a1b2e448c0106d8669889tom return True; 1665f32ec7f0de8a651bc16a1b2e448c0106d8669889tom } 1666eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1667eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1668eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Map a code address to its DebugInfo. Returns NULL if not found. Doesn't 1670eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj require debug info. */ 1671e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjDebugInfo* VG_(find_DebugInfo) ( Addr a ) 1672eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1673e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj static UWord n_search = 0; 1674b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1675e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj n_search++; 1676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1677b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 16785706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->text_size > 0 1679b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= a 1680b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a < di->text_avma + di->text_size) { 1681e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj if (0 == (n_search & 0xF)) 1682e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj move_DebugInfo_one_step_forward( di ); 1683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 1684eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1685eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1686eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return NULL; 1687eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1688eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1689eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a filename. Returns True if successful. */ 1690eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_filename)( Addr a, Char* filename, Int n_filename ) 1691eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1692b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1693f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 1694eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 1695eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 1696eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1697eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(strncpy_safely)(filename, si->loctab[locno].filename, n_filename); 1698eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1699eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1700eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1701eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a line number. Returns True if successful. */ 1702eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_linenum)( Addr a, UInt* lineno ) 1703eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1704b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1705f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 1706eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 1707eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 1708eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1709eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *lineno = si->loctab[locno].lineno; 1710eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1711eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1712eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1713eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1714eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a filename/line number/dir name info. 1715eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj See prototype for detailed description of behaviour. 1716eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 1717eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_filename_linenum) ( Addr a, 1718eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/Char* filename, Int n_filename, 1719eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/Char* dirname, Int n_dirname, 1720eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/Bool* dirname_available, 1721eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/UInt* lineno ) 1722eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1724f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 1725eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1726eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert( (dirname == NULL && dirname_available == NULL) 1727eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj || 1728eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj (dirname != NULL && dirname_available != NULL) ); 1729eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1730eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 1731c1b1d421216369aec58867ce1c5b99cfb1703c36njn if (si == NULL) { 1732db5c6571454c1f647a4c67593805a8e401cd14c5njn if (dirname_available) { 1733db5c6571454c1f647a4c67593805a8e401cd14c5njn *dirname_available = False; 1734db5c6571454c1f647a4c67593805a8e401cd14c5njn *dirname = 0; 1735db5c6571454c1f647a4c67593805a8e401cd14c5njn } 1736eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1737c1b1d421216369aec58867ce1c5b99cfb1703c36njn } 1738c1b1d421216369aec58867ce1c5b99cfb1703c36njn 1739eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(strncpy_safely)(filename, si->loctab[locno].filename, n_filename); 1740eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *lineno = si->loctab[locno].lineno; 1741eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1742eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (dirname) { 1743eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* caller wants directory info too .. */ 1744eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(n_dirname > 0); 1745eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si->loctab[locno].dirname) { 1746eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* .. and we have some */ 1747eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *dirname_available = True; 1748eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(strncpy_safely)(dirname, si->loctab[locno].dirname, 1749eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_dirname); 1750eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 1751eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* .. but we don't have any */ 1752eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *dirname_available = False; 1753eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *dirname = 0; 1754eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1755eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1756eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1757eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1758eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1759eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1760eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 17614ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/* Map a function name to its entry point and toc pointer. Is done by 17624ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj sequential search of all symbol tables, so is very slow. To 17634ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj mitigate the worst performance effects, you may specify a soname 17644ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj pattern, and only objects matching that pattern are searched. 17654ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Therefore specify "*" to search all the objects. On TOC-afflicted 17664ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj platforms, a symbol is deemed to be found only if it has a nonzero 17674ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj TOC pointer. */ 1768b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool VG_(lookup_symbol_SLOW)(UChar* sopatt, UChar* name, 1769b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr* pEnt, Addr* pToc) 17704ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj{ 17714ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool require_pToc = False; 17724ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Int i; 1773b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 17744ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool debug = False; 17754ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# if defined(VG_PLAT_USES_PPCTOC) 17764ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj require_pToc = True; 17774ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# endif 1778b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (si = debugInfo_list; si; si = si->next) { 17794ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (debug) 17804ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(printf)("lookup_symbol_SLOW: considering %s\n", si->soname); 17814ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (!VG_(string_match)(sopatt, si->soname)) { 17824ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (debug) 17834ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(printf)(" ... skip\n"); 17844ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj continue; 17854ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 17864ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj for (i = 0; i < si->symtab_used; i++) { 1787a5cace0c2a3e212931badbf6398a0cd98393121asewardj UChar* pri_name = si->symtab[i].pri_name; 1788a5cace0c2a3e212931badbf6398a0cd98393121asewardj tl_assert(pri_name); 1789a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (0==VG_(strcmp)(name, pri_name) 17904ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj && (require_pToc ? si->symtab[i].tocptr : True)) { 17914ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj *pEnt = si->symtab[i].addr; 17924ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj *pToc = si->symtab[i].tocptr; 17934ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj return True; 17944ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 1795a5cace0c2a3e212931badbf6398a0cd98393121asewardj UChar** sec_names = si->symtab[i].sec_names; 1796a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (sec_names) { 1797a5cace0c2a3e212931badbf6398a0cd98393121asewardj tl_assert(sec_names[0]); 1798a5cace0c2a3e212931badbf6398a0cd98393121asewardj while (*sec_names) { 1799a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (0==VG_(strcmp)(name, *sec_names) 1800a5cace0c2a3e212931badbf6398a0cd98393121asewardj && (require_pToc ? si->symtab[i].tocptr : True)) { 1801a5cace0c2a3e212931badbf6398a0cd98393121asewardj *pEnt = si->symtab[i].addr; 1802a5cace0c2a3e212931badbf6398a0cd98393121asewardj *pToc = si->symtab[i].tocptr; 1803a5cace0c2a3e212931badbf6398a0cd98393121asewardj return True; 1804a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 1805a5cace0c2a3e212931badbf6398a0cd98393121asewardj sec_names++; 1806a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 1807a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 18084ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 18094ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 18104ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj return False; 18114ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj} 18124ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 18134ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 1814e872fec0c1c3b478a399fdba42ac65764b53f470sewardj/* VG_(describe_IP): print into buf info on code address, function 1815e872fec0c1c3b478a399fdba42ac65764b53f470sewardj name and filename. */ 1816e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 1817e872fec0c1c3b478a399fdba42ac65764b53f470sewardj/* Copy str into buf starting at n, but not going past buf[n_buf-1] 1818e872fec0c1c3b478a399fdba42ac65764b53f470sewardj and always ensuring that buf is zero-terminated. */ 1819eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1820eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjstatic Int putStr ( Int n, Int n_buf, Char* buf, Char* str ) 1821eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1822e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n_buf > 0); 1823e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 1824eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj for (; n < n_buf-1 && *str != 0; n++,str++) 1825eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf[n] = *str; 1826e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 1827eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf[n] = '\0'; 1828eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return n; 1829eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1830e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 1831e872fec0c1c3b478a399fdba42ac65764b53f470sewardj/* Same as putStr, but escaping chars for XML output, and 1832e872fec0c1c3b478a399fdba42ac65764b53f470sewardj also not adding more than count chars to n_buf. */ 1833e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 1834e872fec0c1c3b478a399fdba42ac65764b53f470sewardjstatic Int putStrEsc ( Int n, Int n_buf, Int count, Char* buf, Char* str ) 1835eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1836eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char alt[2]; 1837e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n_buf > 0); 1838e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(count >= 0 && count < n_buf); 1839e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 1840eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj for (; *str != 0; str++) { 1841e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(count >= 0); 1842e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count <= 0) 1843e872fec0c1c3b478a399fdba42ac65764b53f470sewardj goto done; 1844eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj switch (*str) { 1845e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '&': 1846e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 5) goto done; 1847e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, "&"); 1848e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 5; 1849e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 1850e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '<': 1851e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 4) goto done; 1852e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, "<"); 1853e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 4; 1854e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 1855e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '>': 1856e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 4) goto done; 1857e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, ">"); 1858e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 4; 1859e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 1860e872fec0c1c3b478a399fdba42ac65764b53f470sewardj default: 1861e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 1) goto done; 1862e872fec0c1c3b478a399fdba42ac65764b53f470sewardj alt[0] = *str; 1863e872fec0c1c3b478a399fdba42ac65764b53f470sewardj alt[1] = 0; 1864e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, alt ); 1865e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 1; 1866e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 1867eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1868eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1869e872fec0c1c3b478a399fdba42ac65764b53f470sewardj done: 1870e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(count >= 0); /* should not go -ve in loop */ 1871e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 1872eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return n; 1873eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1874eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1875eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjChar* VG_(describe_IP)(Addr eip, Char* buf, Int n_buf) 1876eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1877eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define APPEND(_str) \ 1878e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr(n, n_buf, buf, _str) 1879e872fec0c1c3b478a399fdba42ac65764b53f470sewardj# define APPEND_ESC(_count,_str) \ 1880e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStrEsc(n, n_buf, (_count), buf, (_str)) 1881eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define BUF_LEN 4096 1882eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1883eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj UInt lineno; 1884eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj UChar ibuf[50]; 1885eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Int n = 0; 188614cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj 1887eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static UChar buf_fn[BUF_LEN]; 1888eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static UChar buf_obj[BUF_LEN]; 1889eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static UChar buf_srcloc[BUF_LEN]; 1890eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static UChar buf_dirname[BUF_LEN]; 189114cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj buf_fn[0] = buf_obj[0] = buf_srcloc[0] = buf_dirname[0] = 0; 189214cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj 1893eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool know_dirinfo = False; 18944ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool know_fnname = VG_(clo_sym_offsets) 18954ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj ? VG_(get_fnname_w_offset) (eip, buf_fn, BUF_LEN) 18964ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj : VG_(get_fnname) (eip, buf_fn, BUF_LEN); 1897eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool know_objname = VG_(get_objname)(eip, buf_obj, BUF_LEN); 1898eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool know_srcloc = VG_(get_filename_linenum)( 1899eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj eip, 1900eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf_srcloc, BUF_LEN, 1901eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf_dirname, BUF_LEN, &know_dirinfo, 1902eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj &lineno 1903eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj ); 190414cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj buf_fn [ sizeof(buf_fn)-1 ] = 0; 190514cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj buf_obj [ sizeof(buf_obj)-1 ] = 0; 190614cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj buf_srcloc [ sizeof(buf_srcloc)-1 ] = 0; 190714cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj buf_dirname[ sizeof(buf_dirname)-1 ] = 0; 190814cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj 1909eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (VG_(clo_xml)) { 1910eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1911eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool human_readable = True; 1912eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj HChar* maybe_newline = human_readable ? "\n " : ""; 1913eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj HChar* maybe_newline2 = human_readable ? "\n " : ""; 1914eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1915e872fec0c1c3b478a399fdba42ac65764b53f470sewardj /* Print in XML format, dumping in as much info as we know. 1916e872fec0c1c3b478a399fdba42ac65764b53f470sewardj Ensure all tags are balanced even if the individual strings 1917e872fec0c1c3b478a399fdba42ac65764b53f470sewardj are too long. Allocate 1/10 of BUF_LEN to the object name, 1918e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 6/10s to the function name, 1/10 to the directory name and 1919e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 1/10 to the file name, leaving 1/10 for all the fixed-length 1920e872fec0c1c3b478a399fdba42ac65764b53f470sewardj stuff. */ 1921eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<frame>"); 1922a44b15f527bbebfe824a2e68e4bd6ab1e153b486sewardj VG_(sprintf)(ibuf,"<ip>0x%llX</ip>", (ULong)eip); 1923eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1924eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 1925eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_objname) { 1926eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1927eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<obj>"); 1928e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(1*BUF_LEN/10, buf_obj); 1929eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</obj>"); 1930eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1931eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_fnname) { 1932eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1933eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<fn>"); 1934e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(6*BUF_LEN/10, buf_fn); 1935eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</fn>"); 1936eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1937eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_srcloc) { 1938eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_dirinfo) { 1939eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1940eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<dir>"); 1941e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(1*BUF_LEN/10, buf_dirname); 1942eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</dir>"); 1943eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1944eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1945eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<file>"); 1946e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(1*BUF_LEN/10, buf_srcloc); 1947eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</file>"); 1948eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1949eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<line>"); 1950eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(sprintf)(ibuf,"%d",lineno); 1951eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 1952eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</line>"); 1953eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1954eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline2); 1955eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</frame>"); 1956eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1957eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 1958eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1959eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Print for humans to read */ 19605e40abad4504416c59f0b29c1cfc8087201213a9njn // 19615e40abad4504416c59f0b29c1cfc8087201213a9njn // Possible forms: 19625e40abad4504416c59f0b29c1cfc8087201213a9njn // 19635e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: really (a.c:20) 19645e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: really (in /foo/a.out) 19655e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: really (in ???) 19665e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: ??? (in /foo/a.out) 19675e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: ??? (a.c:20) 19685e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: ??? 19695e40abad4504416c59f0b29c1cfc8087201213a9njn // 1970a44b15f527bbebfe824a2e68e4bd6ab1e153b486sewardj VG_(sprintf)(ibuf,"0x%llX: ", (ULong)eip); 1971eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 19725e40abad4504416c59f0b29c1cfc8087201213a9njn if (know_fnname) { 1973eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(buf_fn); 1974eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 1975eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("???"); 1976eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1977eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_srcloc) { 1978eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(" ("); 197914cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // Get the directory name, if any, possibly pruned, into dirname. 198014cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj UChar* dirname = NULL; 198114cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj if (VG_(clo_n_fullpath_after) > 0) { 198214cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj Int i; 198314cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj dirname = buf_dirname; 198414cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // Remove leading prefixes from the dirname. 198514cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // If user supplied --fullpath-after=foo, this will remove 198614cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // a leading string which matches '.*foo' (not greedy). 198714cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj for (i = 0; i < VG_(clo_n_fullpath_after); i++) { 198814cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj UChar* prefix = VG_(clo_fullpath_after)[i]; 198914cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj UChar* str = VG_(strstr)(dirname, prefix); 199014cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj if (str) { 199114cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj dirname = str + VG_(strlen)(prefix); 199214cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj break; 199314cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj } 199414cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj } 199514cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj /* remove leading "./" */ 199614cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj if (dirname[0] == '.' && dirname[1] == '/') 199714cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj dirname += 2; 199814cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj } 199914cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // do we have any interesting directory name to show? If so 200014cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // add it in. 200114cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj if (dirname && dirname[0] != 0) { 200214cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj APPEND(dirname); 200314cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj APPEND("/"); 20045dd0190bc0ea66f8ffa7218c66f5a2e1c7b51b30bart } 2005eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(buf_srcloc); 2006eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(":"); 2007eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(sprintf)(ibuf,"%d",lineno); 2008eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 2009eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(")"); 20105e40abad4504416c59f0b29c1cfc8087201213a9njn } else if (know_objname) { 20115e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(" (in "); 20125e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(buf_obj); 20135e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(")"); 20145e40abad4504416c59f0b29c1cfc8087201213a9njn } else if (know_fnname) { 20155e40abad4504416c59f0b29c1cfc8087201213a9njn // Nb: do this in two steps because "??)" is a trigraph! 20165e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(" (in ???"); 20175e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(")"); 2018eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2019eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2020eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2021eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return buf; 2022eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2023eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef APPEND 2024eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef APPEND_ESC 2025eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef BUF_LEN 2026eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2027eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 202872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 2029b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 2030b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 2031b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/ 2032b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- DWARF3 .eh_frame INFO ---*/ 2033b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 2034b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 203572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 203672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/* Gather up all the constant pieces of info needed to evaluate 203772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj a CfiExpr into one convenient struct. */ 203872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjtypedef 203972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj struct { 20403026f71684a930286186aa10fef266c304672e8fsewardj D3UnwindRegs* uregs; 20413026f71684a930286186aa10fef266c304672e8fsewardj Addr min_accessible; 20423026f71684a930286186aa10fef266c304672e8fsewardj Addr max_accessible; 204372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 204472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExprEvalContext; 204572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 204672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/* Evaluate the CfiExpr rooted at ix in exprs given the context eec. 204772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj *ok is set to False on failure, but not to True on success. The 204872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj caller must set it to True before calling. */ 2049f7183e38d6215e98043ed014cb947cf5262bdc4asewardj__attribute__((noinline)) 2050f7183e38d6215e98043ed014cb947cf5262bdc4asewardjstatic 205172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjUWord evalCfiExpr ( XArray* exprs, Int ix, 205272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExprEvalContext* eec, Bool* ok ) 205372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj{ 205472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj UWord wL, wR; 205519dc88f90d0e19a1463797dd99f6792a42f961d3sewardj Addr a; 20563026f71684a930286186aa10fef266c304672e8fsewardj CfiExpr* e; 20573026f71684a930286186aa10fef266c304672e8fsewardj vg_assert(sizeof(Addr) == sizeof(UWord)); 20583026f71684a930286186aa10fef266c304672e8fsewardj e = VG_(indexXA)( exprs, ix ); 205972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->tag) { 206072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_Binop: 206172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj wL = evalCfiExpr( exprs, e->Cex.Binop.ixL, eec, ok ); 206272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!(*ok)) return 0; 206372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj wR = evalCfiExpr( exprs, e->Cex.Binop.ixR, eec, ok ); 206472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!(*ok)) return 0; 206572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->Cex.Binop.op) { 206672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cop_Add: return wL + wR; 206772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cop_Sub: return wL - wR; 206819dc88f90d0e19a1463797dd99f6792a42f961d3sewardj case Cop_And: return wL & wR; 20697888e2204fff6e7429236b4227ed16594e7743b9sewardj case Cop_Mul: return wL * wR; 20700b98239b3e0abd430dbc913454d63c7e3d8c8b12tom case Cop_Shl: return wL << wR; 20710b98239b3e0abd430dbc913454d63c7e3d8c8b12tom case Cop_Shr: return wL >> wR; 20720b98239b3e0abd430dbc913454d63c7e3d8c8b12tom case Cop_Eq: return wL == wR ? 1 : 0; 2073130f6f5a47a1557a454b24db6e08431da6c8b9c1tom case Cop_Ge: return (Word) wL >= (Word) wR ? 1 : 0; 2074130f6f5a47a1557a454b24db6e08431da6c8b9c1tom case Cop_Gt: return (Word) wL > (Word) wR ? 1 : 0; 2075130f6f5a47a1557a454b24db6e08431da6c8b9c1tom case Cop_Le: return (Word) wL <= (Word) wR ? 1 : 0; 2076130f6f5a47a1557a454b24db6e08431da6c8b9c1tom case Cop_Lt: return (Word) wL < (Word) wR ? 1 : 0; 20770b98239b3e0abd430dbc913454d63c7e3d8c8b12tom case Cop_Ne: return wL != wR ? 1 : 0; 207872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: goto unhandled; 207972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 208072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 208172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_CfiReg: 208272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->Cex.CfiReg.reg) { 20833026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 20843026f71684a930286186aa10fef266c304672e8fsewardj case Creg_IA_IP: return eec->uregs->xip; 20853026f71684a930286186aa10fef266c304672e8fsewardj case Creg_IA_SP: return eec->uregs->xsp; 20863026f71684a930286186aa10fef266c304672e8fsewardj case Creg_IA_BP: return eec->uregs->xbp; 20873026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_arm) 20883026f71684a930286186aa10fef266c304672e8fsewardj case Creg_ARM_R15: return eec->uregs->r15; 20893026f71684a930286186aa10fef266c304672e8fsewardj case Creg_ARM_R14: return eec->uregs->r14; 2090fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj case Creg_ARM_R13: return eec->uregs->r13; 2091fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj case Creg_ARM_R12: return eec->uregs->r12; 2092b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGA_s390x) 2093b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Creg_IA_IP: return eec->uregs->ia; 2094b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Creg_IA_SP: return eec->uregs->sp; 2095b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Creg_IA_BP: return eec->uregs->fp; 2096b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Creg_S390_R14: return eec->uregs->lr; 20975db15403e889d4db339b342bc2a824ef0bfaa654sewardj# elif defined(VGA_mips32) 20985db15403e889d4db339b342bc2a824ef0bfaa654sewardj case Creg_IA_IP: return eec->uregs->pc; 20995db15403e889d4db339b342bc2a824ef0bfaa654sewardj case Creg_IA_SP: return eec->uregs->sp; 21005db15403e889d4db339b342bc2a824ef0bfaa654sewardj case Creg_IA_BP: return eec->uregs->fp; 21015db15403e889d4db339b342bc2a824ef0bfaa654sewardj case Creg_MIPS_RA: return eec->uregs->ra; 21023026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_ppc32) || defined(VGA_ppc64) 21033026f71684a930286186aa10fef266c304672e8fsewardj# else 21043026f71684a930286186aa10fef266c304672e8fsewardj# error "Unsupported arch" 21053026f71684a930286186aa10fef266c304672e8fsewardj# endif 210672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: goto unhandled; 210772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 210872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 210972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_Const: 211072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj return e->Cex.Const.con; 211119dc88f90d0e19a1463797dd99f6792a42f961d3sewardj case Cex_Deref: 211219dc88f90d0e19a1463797dd99f6792a42f961d3sewardj a = evalCfiExpr( exprs, e->Cex.Deref.ixAddr, eec, ok ); 211319dc88f90d0e19a1463797dd99f6792a42f961d3sewardj if (!(*ok)) return 0; 211419dc88f90d0e19a1463797dd99f6792a42f961d3sewardj if (a < eec->min_accessible 2115720e6b71b171885281afab634ce4d667c1f262bcsewardj || a > eec->max_accessible - sizeof(UWord) + 1) { 211619dc88f90d0e19a1463797dd99f6792a42f961d3sewardj *ok = False; 211719dc88f90d0e19a1463797dd99f6792a42f961d3sewardj return 0; 211819dc88f90d0e19a1463797dd99f6792a42f961d3sewardj } 211919dc88f90d0e19a1463797dd99f6792a42f961d3sewardj /* let's hope it doesn't trap! */ 212086781fabbfc019b752f9605e487cfce77b2a592atom return ML_(read_UWord)((void *)a); 212172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: 212272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj goto unhandled; 212372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 212472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 212572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj unhandled: 212672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("\n\nevalCfiExpr: unhandled\n"); 212772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj ML_(ppCfiExpr)( exprs, ix ); 212872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("\n"); 212972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); 213072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 213172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj return 0; 213272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj} 213372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 213472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 2135f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Search all the DebugInfos in the entire system, to find the DiCfSI 2136f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj that pertains to 'ip'. 2137eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2138f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj If found, set *diP to the DebugInfo in which it resides, and 2139f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *ixP to the index in that DebugInfo's cfsi array. 214072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 2141f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj If not found, set *diP to (DebugInfo*)1 and *ixP to zero. 2142f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj*/ 2143f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj__attribute__((noinline)) 2144f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic void find_DiCfSI ( /*OUT*/DebugInfo** diP, 2145f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*OUT*/Word* ixP, 2146f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Addr ip ) 2147f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 2148f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo* di; 2149f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word i = -1; 2150f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2151f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj static UWord n_search = 0; 2152f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj static UWord n_steps = 0; 2153eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_search++; 2154eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2155f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0) VG_(printf)("search for %#lx\n", ip); 2156eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2157f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (di = debugInfo_list; di != NULL; di = di->next) { 2158f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word j; 2159eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_steps++; 2160eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Use the per-DebugInfo summary address ranges to skip 2162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj inapplicable DebugInfos quickly. */ 2163f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di->cfsi_used == 0) 2164eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj continue; 2165f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (ip < di->cfsi_minavma || ip > di->cfsi_maxavma) 2166eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj continue; 2167eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2168f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* It might be in this DebugInfo. Search it. */ 2169f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj j = ML_(search_one_cfitab)( di, ip ); 2170f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(j >= -1 && j < (Word)di->cfsi_used); 2171f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2172f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (j != -1) { 2173f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj i = j; 2174f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj break; /* found it */ 2175eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2176eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2177eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2178f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (i == -1) { 2179f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2180f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* we didn't find it. */ 2181f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *diP = (DebugInfo*)1; 2182f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *ixP = 0; 2183f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2184f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 2185f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2186f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* found it. */ 2187f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* ensure that di is 4-aligned (at least), so it can't possibly 2188f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj be equal to (DebugInfo*)1. */ 2189f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di && VG_IS_4_ALIGNED(di)); 2190f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(i >= 0 && i < di->cfsi_used); 2191f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *diP = di; 2192f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *ixP = i; 2193f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2194f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Start of performance-enhancing hack: once every 64 (chosen 2195f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj hackily after profiling) successful searches, move the found 2196f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo one step closer to the start of the list. This 2197f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj makes future searches cheaper. For starting konqueror on 2198f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj amd64, this in fact reduces the total amount of searching 2199f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj done by the above find-the-right-DebugInfo loop by more than 2200f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj a factor of 20. */ 2201f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if ((n_search & 0xF) == 0) { 2202f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Move di one step closer to the start of the list. */ 2203f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj move_DebugInfo_one_step_forward( di ); 2204f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 2205f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* End of performance-enhancing hack. */ 2206f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2207f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && ((n_search & 0x7FFFF) == 0)) 2208f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(printf)("find_DiCfSI: %lu searches, " 2209f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj "%lu DebugInfos looked at\n", 2210f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj n_search, n_steps); 2211f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2212f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 2213f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2214f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 2215f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2216f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2217f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Now follows a mechanism for caching queries to find_DiCfSI, since 2218f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj they are extremely frequent on amd64-linux, during stack unwinding. 2219f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2220f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Each cache entry binds an ip value to a (di, ix) pair. Possible 2221f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj values: 2222f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2223f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj di is non-null, ix >= 0 ==> cache slot in use, "di->cfsi[ix]" 2224f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj di is (DebugInfo*)1 ==> cache slot in use, no associated di 2225f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj di is NULL ==> cache slot not in use 2226f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2227f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Hence simply zeroing out the entire cache invalidates all 2228f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj entries. 2229f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2230f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Why not map ip values directly to DiCfSI*'s? Because this would 2231f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cause problems if/when the cfsi array is moved due to resizing. 2232f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Instead we cache .cfsi array index value, which should be invariant 2233f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj across resizing. (That said, I don't think the current 2234f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj implementation will resize whilst during queries, since the DiCfSI 2235f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj records are added all at once, when the debuginfo for an object is 2236f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj read, and is not changed ever thereafter. */ 2237eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2238f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#define N_CFSI_CACHE 511 2239f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2240f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjtypedef 2241f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj struct { Addr ip; DebugInfo* di; Word ix; } 2242f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj CFSICacheEnt; 2243f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2244f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic CFSICacheEnt cfsi_cache[N_CFSI_CACHE]; 2245f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2246f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic void cfsi_cache__invalidate ( void ) { 2247f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(memset)(&cfsi_cache, 0, sizeof(cfsi_cache)); 2248f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 2249f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2250f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2251f7183e38d6215e98043ed014cb947cf5262bdc4asewardjstatic inline CFSICacheEnt* cfsi_cache__find ( Addr ip ) 2252f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 22533c9cf3442185b5891e15450d6e3058aeff6796fetom UWord hash = ip % N_CFSI_CACHE; 22543c9cf3442185b5891e15450d6e3058aeff6796fetom CFSICacheEnt* ce = &cfsi_cache[hash]; 22553c9cf3442185b5891e15450d6e3058aeff6796fetom static UWord n_q = 0, n_m = 0; 2256f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2257f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj n_q++; 2258f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && 0 == (n_q & 0x1FFFFF)) 2259f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(printf)("QQQ %lu %lu\n", n_q, n_m); 2260f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 22613c9cf3442185b5891e15450d6e3058aeff6796fetom if (LIKELY(ce->ip == ip) && LIKELY(ce->di != NULL)) { 22623c9cf3442185b5891e15450d6e3058aeff6796fetom /* found an entry in the cache .. */ 22633c9cf3442185b5891e15450d6e3058aeff6796fetom } else { 22643c9cf3442185b5891e15450d6e3058aeff6796fetom /* not found in cache. Search and update. */ 22653c9cf3442185b5891e15450d6e3058aeff6796fetom n_m++; 22663c9cf3442185b5891e15450d6e3058aeff6796fetom ce->ip = ip; 22673c9cf3442185b5891e15450d6e3058aeff6796fetom find_DiCfSI( &ce->di, &ce->ix, ip ); 22683c9cf3442185b5891e15450d6e3058aeff6796fetom } 2269eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 22703c9cf3442185b5891e15450d6e3058aeff6796fetom if (UNLIKELY(ce->di == (DebugInfo*)1)) { 22713c9cf3442185b5891e15450d6e3058aeff6796fetom /* no DiCfSI for this address */ 22723c9cf3442185b5891e15450d6e3058aeff6796fetom return NULL; 22733c9cf3442185b5891e15450d6e3058aeff6796fetom } else { 22743c9cf3442185b5891e15450d6e3058aeff6796fetom /* found a DiCfSI for this address */ 22753c9cf3442185b5891e15450d6e3058aeff6796fetom return ce; 2276eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 22773c9cf3442185b5891e15450d6e3058aeff6796fetom} 2278eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2279eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2280f7183e38d6215e98043ed014cb947cf5262bdc4asewardjinline 22813026f71684a930286186aa10fef266c304672e8fsewardjstatic Addr compute_cfa ( D3UnwindRegs* uregs, 22823c9cf3442185b5891e15450d6e3058aeff6796fetom Addr min_accessible, Addr max_accessible, 22833c9cf3442185b5891e15450d6e3058aeff6796fetom DebugInfo* di, DiCfSI* cfsi ) 22843c9cf3442185b5891e15450d6e3058aeff6796fetom{ 22853c9cf3442185b5891e15450d6e3058aeff6796fetom CfiExprEvalContext eec; 22863c9cf3442185b5891e15450d6e3058aeff6796fetom Addr cfa; 22873c9cf3442185b5891e15450d6e3058aeff6796fetom Bool ok; 2288eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 22893c9cf3442185b5891e15450d6e3058aeff6796fetom /* Compute the CFA. */ 229072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj cfa = 0; 229172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (cfsi->cfa_how) { 22923026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 22933026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_IA_SPREL: 22943026f71684a930286186aa10fef266c304672e8fsewardj cfa = cfsi->cfa_off + uregs->xsp; 22953026f71684a930286186aa10fef266c304672e8fsewardj break; 22963026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_IA_BPREL: 22973026f71684a930286186aa10fef266c304672e8fsewardj cfa = cfsi->cfa_off + uregs->xbp; 229872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 22993026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_arm) 23003026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_ARM_R13REL: 23013026f71684a930286186aa10fef266c304672e8fsewardj cfa = cfsi->cfa_off + uregs->r13; 230272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 23033026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_ARM_R12REL: 23043026f71684a930286186aa10fef266c304672e8fsewardj cfa = cfsi->cfa_off + uregs->r12; 23053026f71684a930286186aa10fef266c304672e8fsewardj break; 23063026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_ARM_R11REL: 23073026f71684a930286186aa10fef266c304672e8fsewardj cfa = cfsi->cfa_off + uregs->r11; 23083026f71684a930286186aa10fef266c304672e8fsewardj break; 2309fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj case CFIC_ARM_R7REL: 2310fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj cfa = cfsi->cfa_off + uregs->r7; 2311fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj break; 2312b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGA_s390x) 2313b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case CFIC_IA_SPREL: 2314b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj cfa = cfsi->cfa_off + uregs->sp; 2315b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 2316b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case CFIR_MEMCFAREL: 2317b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj { 2318b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj Addr a = uregs->sp + cfsi->cfa_off; 2319b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj if (a < min_accessible || a > max_accessible-sizeof(Addr)) 2320b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 232186781fabbfc019b752f9605e487cfce77b2a592atom cfa = ML_(read_Addr)((void *)a); 2322b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 2323b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj } 2324b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case CFIR_SAME: 2325b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj cfa = uregs->fp; 2326b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 2327b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case CFIC_IA_BPREL: 2328b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj cfa = cfsi->cfa_off + uregs->fp; 2329b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 23305db15403e889d4db339b342bc2a824ef0bfaa654sewardj# elif defined(VGA_mips32) 23315db15403e889d4db339b342bc2a824ef0bfaa654sewardj case CFIC_IA_SPREL: 23325db15403e889d4db339b342bc2a824ef0bfaa654sewardj cfa = cfsi->cfa_off + uregs->sp; 23335db15403e889d4db339b342bc2a824ef0bfaa654sewardj break; 23345db15403e889d4db339b342bc2a824ef0bfaa654sewardj case CFIR_SAME: 23355db15403e889d4db339b342bc2a824ef0bfaa654sewardj cfa = uregs->fp; 23365db15403e889d4db339b342bc2a824ef0bfaa654sewardj break; 23375db15403e889d4db339b342bc2a824ef0bfaa654sewardj case CFIC_IA_BPREL: 23385db15403e889d4db339b342bc2a824ef0bfaa654sewardj cfa = cfsi->cfa_off + uregs->fp; 23395db15403e889d4db339b342bc2a824ef0bfaa654sewardj break; 23403026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_ppc32) || defined(VGA_ppc64) 23413026f71684a930286186aa10fef266c304672e8fsewardj# else 23423026f71684a930286186aa10fef266c304672e8fsewardj# error "Unsupported arch" 23433026f71684a930286186aa10fef266c304672e8fsewardj# endif 23443026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_EXPR: /* available on all archs */ 23457888e2204fff6e7429236b4227ed16594e7743b9sewardj if (0) { 23467888e2204fff6e7429236b4227ed16594e7743b9sewardj VG_(printf)("CFIC_EXPR: "); 2347f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj ML_(ppCfiExpr)(di->cfsi_exprs, cfsi->cfa_off); 23487888e2204fff6e7429236b4227ed16594e7743b9sewardj VG_(printf)("\n"); 23497888e2204fff6e7429236b4227ed16594e7743b9sewardj } 23503026f71684a930286186aa10fef266c304672e8fsewardj eec.uregs = uregs; 23517888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.min_accessible = min_accessible; 23527888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.max_accessible = max_accessible; 23537888e2204fff6e7429236b4227ed16594e7743b9sewardj ok = True; 2354f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfa = evalCfiExpr(di->cfsi_exprs, cfsi->cfa_off, &eec, &ok ); 23553c9cf3442185b5891e15450d6e3058aeff6796fetom if (!ok) return 0; 235672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 235772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: 235872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); 235972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 23603c9cf3442185b5891e15450d6e3058aeff6796fetom return cfa; 23613c9cf3442185b5891e15450d6e3058aeff6796fetom} 23623c9cf3442185b5891e15450d6e3058aeff6796fetom 23633c9cf3442185b5891e15450d6e3058aeff6796fetom 23643c9cf3442185b5891e15450d6e3058aeff6796fetom/* Get the call frame address (CFA) given an IP/SP/FP triple. */ 23653026f71684a930286186aa10fef266c304672e8fsewardj/* NOTE: This function may rearrange the order of entries in the 23663026f71684a930286186aa10fef266c304672e8fsewardj DebugInfo list. */ 23673c9cf3442185b5891e15450d6e3058aeff6796fetomAddr ML_(get_CFA) ( Addr ip, Addr sp, Addr fp, 23683c9cf3442185b5891e15450d6e3058aeff6796fetom Addr min_accessible, Addr max_accessible ) 23693c9cf3442185b5891e15450d6e3058aeff6796fetom{ 23703c9cf3442185b5891e15450d6e3058aeff6796fetom CFSICacheEnt* ce; 23713c9cf3442185b5891e15450d6e3058aeff6796fetom DebugInfo* di; 2372d2be8cc17fed04cbd701e9a2cc1cf365ff45cc44sewardj DiCfSI* cfsi __attribute__((unused)); 23733c9cf3442185b5891e15450d6e3058aeff6796fetom 23743c9cf3442185b5891e15450d6e3058aeff6796fetom ce = cfsi_cache__find(ip); 23753c9cf3442185b5891e15450d6e3058aeff6796fetom 23763c9cf3442185b5891e15450d6e3058aeff6796fetom if (UNLIKELY(ce == NULL)) 23773c9cf3442185b5891e15450d6e3058aeff6796fetom return 0; /* no info. Nothing we can do. */ 23783c9cf3442185b5891e15450d6e3058aeff6796fetom 23793c9cf3442185b5891e15450d6e3058aeff6796fetom di = ce->di; 23803c9cf3442185b5891e15450d6e3058aeff6796fetom cfsi = &di->cfsi[ ce->ix ]; 23813c9cf3442185b5891e15450d6e3058aeff6796fetom 23823026f71684a930286186aa10fef266c304672e8fsewardj /* Temporary impedance-matching kludge so that this keeps working 23833026f71684a930286186aa10fef266c304672e8fsewardj on x86-linux and amd64-linux. */ 23843026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 23853026f71684a930286186aa10fef266c304672e8fsewardj { D3UnwindRegs uregs; 23863026f71684a930286186aa10fef266c304672e8fsewardj uregs.xip = ip; 23873026f71684a930286186aa10fef266c304672e8fsewardj uregs.xsp = sp; 23883026f71684a930286186aa10fef266c304672e8fsewardj uregs.xbp = fp; 23893026f71684a930286186aa10fef266c304672e8fsewardj return compute_cfa(&uregs, 23903026f71684a930286186aa10fef266c304672e8fsewardj min_accessible, max_accessible, di, cfsi); 23913026f71684a930286186aa10fef266c304672e8fsewardj } 2392b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#elif defined(VGA_s390x) 2393b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj { D3UnwindRegs uregs; 2394b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj uregs.ia = ip; 2395b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj uregs.sp = sp; 2396b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj uregs.fp = fp; 2397b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj return compute_cfa(&uregs, 2398b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj min_accessible, max_accessible, di, cfsi); 2399b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj } 2400b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 24013026f71684a930286186aa10fef266c304672e8fsewardj# else 24023026f71684a930286186aa10fef266c304672e8fsewardj return 0; /* indicates failure */ 24033026f71684a930286186aa10fef266c304672e8fsewardj# endif 24043c9cf3442185b5891e15450d6e3058aeff6796fetom} 24053c9cf3442185b5891e15450d6e3058aeff6796fetom 24063c9cf3442185b5891e15450d6e3058aeff6796fetom 24073026f71684a930286186aa10fef266c304672e8fsewardj/* The main function for DWARF2/3 CFI-based stack unwinding. Given a 24083026f71684a930286186aa10fef266c304672e8fsewardj set of registers in UREGS, modify it to hold the register values 24093026f71684a930286186aa10fef266c304672e8fsewardj for the previous frame, if possible. Returns True if successful. 24103026f71684a930286186aa10fef266c304672e8fsewardj If not successful, *UREGS is not changed. 24113026f71684a930286186aa10fef266c304672e8fsewardj 24123026f71684a930286186aa10fef266c304672e8fsewardj For x86 and amd64, the unwound registers are: {E,R}IP, 24133026f71684a930286186aa10fef266c304672e8fsewardj {E,R}SP, {E,R}BP. 24143026f71684a930286186aa10fef266c304672e8fsewardj 2415fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj For arm, the unwound registers are: R7 R11 R12 R13 R14 R15. 24163026f71684a930286186aa10fef266c304672e8fsewardj*/ 24173026f71684a930286186aa10fef266c304672e8fsewardjBool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere, 24183c9cf3442185b5891e15450d6e3058aeff6796fetom Addr min_accessible, 24193c9cf3442185b5891e15450d6e3058aeff6796fetom Addr max_accessible ) 24203c9cf3442185b5891e15450d6e3058aeff6796fetom{ 24213c9cf3442185b5891e15450d6e3058aeff6796fetom DebugInfo* di; 24223c9cf3442185b5891e15450d6e3058aeff6796fetom DiCfSI* cfsi = NULL; 24233026f71684a930286186aa10fef266c304672e8fsewardj Addr cfa, ipHere = 0; 24243c9cf3442185b5891e15450d6e3058aeff6796fetom CFSICacheEnt* ce; 2425d2be8cc17fed04cbd701e9a2cc1cf365ff45cc44sewardj CfiExprEvalContext eec __attribute__((unused)); 24263026f71684a930286186aa10fef266c304672e8fsewardj D3UnwindRegs uregsPrev; 24273c9cf3442185b5891e15450d6e3058aeff6796fetom 24283026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 24293026f71684a930286186aa10fef266c304672e8fsewardj ipHere = uregsHere->xip; 24303026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_arm) 24313026f71684a930286186aa10fef266c304672e8fsewardj ipHere = uregsHere->r15; 2432b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGA_s390x) 2433b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj ipHere = uregsHere->ia; 24345db15403e889d4db339b342bc2a824ef0bfaa654sewardj# elif defined(VGA_mips32) 24355db15403e889d4db339b342bc2a824ef0bfaa654sewardj ipHere = uregsHere->pc; 24363026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_ppc32) || defined(VGA_ppc64) 24373026f71684a930286186aa10fef266c304672e8fsewardj# else 24383026f71684a930286186aa10fef266c304672e8fsewardj# error "Unknown arch" 24393026f71684a930286186aa10fef266c304672e8fsewardj# endif 24403026f71684a930286186aa10fef266c304672e8fsewardj ce = cfsi_cache__find(ipHere); 24413c9cf3442185b5891e15450d6e3058aeff6796fetom 24423c9cf3442185b5891e15450d6e3058aeff6796fetom if (UNLIKELY(ce == NULL)) 24433c9cf3442185b5891e15450d6e3058aeff6796fetom return False; /* no info. Nothing we can do. */ 24443c9cf3442185b5891e15450d6e3058aeff6796fetom 24453c9cf3442185b5891e15450d6e3058aeff6796fetom di = ce->di; 24463c9cf3442185b5891e15450d6e3058aeff6796fetom cfsi = &di->cfsi[ ce->ix ]; 24473c9cf3442185b5891e15450d6e3058aeff6796fetom 24483c9cf3442185b5891e15450d6e3058aeff6796fetom if (0) { 24493c9cf3442185b5891e15450d6e3058aeff6796fetom VG_(printf)("found cfisi: "); 24503c9cf3442185b5891e15450d6e3058aeff6796fetom ML_(ppDiCfSI)(di->cfsi_exprs, cfsi); 24513c9cf3442185b5891e15450d6e3058aeff6796fetom } 24523c9cf3442185b5891e15450d6e3058aeff6796fetom 2453f7183e38d6215e98043ed014cb947cf5262bdc4asewardj VG_(bzero_inline)(&uregsPrev, sizeof(uregsPrev)); 24543c9cf3442185b5891e15450d6e3058aeff6796fetom 24553c9cf3442185b5891e15450d6e3058aeff6796fetom /* First compute the CFA. */ 24563026f71684a930286186aa10fef266c304672e8fsewardj cfa = compute_cfa(uregsHere, 24573026f71684a930286186aa10fef266c304672e8fsewardj min_accessible, max_accessible, di, cfsi); 24583c9cf3442185b5891e15450d6e3058aeff6796fetom if (UNLIKELY(cfa == 0)) 24593c9cf3442185b5891e15450d6e3058aeff6796fetom return False; 246072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 246172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /* Now we know the CFA, use it to roll back the registers we're 246272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj interested in. */ 2463eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2464eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define COMPUTE(_prev, _here, _how, _off) \ 2465eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj do { \ 2466eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj switch (_how) { \ 2467eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_UNKNOWN: \ 2468eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; \ 2469eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_SAME: \ 2470eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj _prev = _here; break; \ 2471eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_MEMCFAREL: { \ 2472eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Addr a = cfa + (Word)_off; \ 2473eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (a < min_accessible \ 24749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj || a > max_accessible-sizeof(Addr)) \ 2475eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; \ 247686781fabbfc019b752f9605e487cfce77b2a592atom _prev = ML_(read_Addr)((void *)a); \ 2477eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; \ 2478eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } \ 2479eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_CFAREL: \ 2480eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj _prev = cfa + (Word)_off; \ 2481eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; \ 248272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case CFIR_EXPR: \ 248372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (0) \ 2484f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj ML_(ppCfiExpr)(di->cfsi_exprs,_off); \ 24853026f71684a930286186aa10fef266c304672e8fsewardj eec.uregs = uregsHere; \ 248672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.min_accessible = min_accessible; \ 248772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.max_accessible = max_accessible; \ 2488d2be8cc17fed04cbd701e9a2cc1cf365ff45cc44sewardj Bool ok = True; \ 2489f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj _prev = evalCfiExpr(di->cfsi_exprs, _off, &eec, &ok ); \ 249072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!ok) return False; \ 249172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; \ 249272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: \ 249372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); \ 2494eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } \ 2495eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } while (0) 2496eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 24973026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 24983026f71684a930286186aa10fef266c304672e8fsewardj COMPUTE(uregsPrev.xip, uregsHere->xip, cfsi->ra_how, cfsi->ra_off); 24999365e3f48bc3efe2486bf4bc04111a2d89db5520sewardj COMPUTE(uregsPrev.xsp, uregsHere->xsp, cfsi->sp_how, cfsi->sp_off); 25009365e3f48bc3efe2486bf4bc04111a2d89db5520sewardj COMPUTE(uregsPrev.xbp, uregsHere->xbp, cfsi->bp_how, cfsi->bp_off); 25013026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_arm) 25023026f71684a930286186aa10fef266c304672e8fsewardj COMPUTE(uregsPrev.r15, uregsHere->r15, cfsi->ra_how, cfsi->ra_off); 25033026f71684a930286186aa10fef266c304672e8fsewardj COMPUTE(uregsPrev.r14, uregsHere->r14, cfsi->r14_how, cfsi->r14_off); 25043026f71684a930286186aa10fef266c304672e8fsewardj COMPUTE(uregsPrev.r13, uregsHere->r13, cfsi->r13_how, cfsi->r13_off); 25053026f71684a930286186aa10fef266c304672e8fsewardj COMPUTE(uregsPrev.r12, uregsHere->r12, cfsi->r12_how, cfsi->r12_off); 25063026f71684a930286186aa10fef266c304672e8fsewardj COMPUTE(uregsPrev.r11, uregsHere->r11, cfsi->r11_how, cfsi->r11_off); 2507fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj COMPUTE(uregsPrev.r7, uregsHere->r7, cfsi->r7_how, cfsi->r7_off); 2508b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGA_s390x) 2509b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj COMPUTE(uregsPrev.ia, uregsHere->ia, cfsi->ra_how, cfsi->ra_off); 2510b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi->sp_how, cfsi->sp_off); 2511b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi->fp_how, cfsi->fp_off); 25125db15403e889d4db339b342bc2a824ef0bfaa654sewardj# elif defined(VGA_mips32) 25135db15403e889d4db339b342bc2a824ef0bfaa654sewardj COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi->ra_how, cfsi->ra_off); 25145db15403e889d4db339b342bc2a824ef0bfaa654sewardj COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi->sp_how, cfsi->sp_off); 25155db15403e889d4db339b342bc2a824ef0bfaa654sewardj COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi->fp_how, cfsi->fp_off); 25163026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_ppc32) || defined(VGA_ppc64) 25173026f71684a930286186aa10fef266c304672e8fsewardj# else 25183026f71684a930286186aa10fef266c304672e8fsewardj# error "Unknown arch" 25193026f71684a930286186aa10fef266c304672e8fsewardj# endif 2520eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2521eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef COMPUTE 2522eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 25233026f71684a930286186aa10fef266c304672e8fsewardj *uregsHere = uregsPrev; 2524eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 2525eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2526eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2527eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2528b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 2529b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 2530c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/ 2531c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- MSVC FPO INFO ---*/ 2532c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- ---*/ 2533c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--------------------------------------------------------------*/ 2534c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2535c8259b85b701d25d72aabe9dc0a8154517f96913sewardjBool VG_(use_FPO_info) ( /*MOD*/Addr* ipP, 2536c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /*MOD*/Addr* spP, 2537c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /*MOD*/Addr* fpP, 2538c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Addr min_accessible, 2539c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Addr max_accessible ) 2540c8259b85b701d25d72aabe9dc0a8154517f96913sewardj{ 2541c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Word i; 2542c8259b85b701d25d72aabe9dc0a8154517f96913sewardj DebugInfo* di; 2543c8259b85b701d25d72aabe9dc0a8154517f96913sewardj FPO_DATA* fpo = NULL; 2544c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Addr spHere; 2545c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2546c8259b85b701d25d72aabe9dc0a8154517f96913sewardj static UWord n_search = 0; 2547c8259b85b701d25d72aabe9dc0a8154517f96913sewardj static UWord n_steps = 0; 2548c8259b85b701d25d72aabe9dc0a8154517f96913sewardj n_search++; 2549c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2550c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0) VG_(printf)("search FPO for %#lx\n", *ipP); 2551c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2552c8259b85b701d25d72aabe9dc0a8154517f96913sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 2553c8259b85b701d25d72aabe9dc0a8154517f96913sewardj n_steps++; 2554c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2555c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Use the per-DebugInfo summary address ranges to skip 2556c8259b85b701d25d72aabe9dc0a8154517f96913sewardj inapplicable DebugInfos quickly. */ 2557c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (di->fpo == NULL) 2558c8259b85b701d25d72aabe9dc0a8154517f96913sewardj continue; 2559c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (*ipP < di->fpo_minavma || *ipP > di->fpo_maxavma) 2560c8259b85b701d25d72aabe9dc0a8154517f96913sewardj continue; 2561c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2562c8259b85b701d25d72aabe9dc0a8154517f96913sewardj i = ML_(search_one_fpotab)( di, *ipP ); 2563c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (i != -1) { 2564c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Word j; 2565c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0) { 2566c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* debug printing only */ 2567c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("look for %#lx size %ld i %ld\n", 2568c8259b85b701d25d72aabe9dc0a8154517f96913sewardj *ipP, di->fpo_size, i); 2569c8259b85b701d25d72aabe9dc0a8154517f96913sewardj for (j = 0; j < di->fpo_size; j++) 2570c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("[%02ld] %#x %d\n", 2571c8259b85b701d25d72aabe9dc0a8154517f96913sewardj j, di->fpo[j].ulOffStart, di->fpo[j].cbProcSize); 2572c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2573c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(i >= 0 && i < di->fpo_size); 2574c8259b85b701d25d72aabe9dc0a8154517f96913sewardj fpo = &di->fpo[i]; 2575c8259b85b701d25d72aabe9dc0a8154517f96913sewardj break; 2576c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2577c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2578c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2579c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (fpo == NULL) 2580c8259b85b701d25d72aabe9dc0a8154517f96913sewardj return False; 2581c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2582c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0 && ((n_search & 0x7FFFF) == 0)) 2583c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("VG_(use_FPO_info): %lu searches, " 2584c8259b85b701d25d72aabe9dc0a8154517f96913sewardj "%lu DebugInfos looked at\n", 2585c8259b85b701d25d72aabe9dc0a8154517f96913sewardj n_search, n_steps); 2586c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2587c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2588c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Start of performance-enhancing hack: once every 64 (chosen 2589c8259b85b701d25d72aabe9dc0a8154517f96913sewardj hackily after profiling) successful searches, move the found 2590c8259b85b701d25d72aabe9dc0a8154517f96913sewardj DebugInfo one step closer to the start of the list. This makes 2591c8259b85b701d25d72aabe9dc0a8154517f96913sewardj future searches cheaper. For starting konqueror on amd64, this 2592c8259b85b701d25d72aabe9dc0a8154517f96913sewardj in fact reduces the total amount of searching done by the above 2593c8259b85b701d25d72aabe9dc0a8154517f96913sewardj find-the-right-DebugInfo loop by more than a factor of 20. */ 2594c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if ((n_search & 0x3F) == 0) { 2595c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Move si one step closer to the start of the list. */ 2596c8259b85b701d25d72aabe9dc0a8154517f96913sewardj //move_DebugInfo_one_step_forward( di ); 2597c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2598c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* End of performance-enhancing hack. */ 2599c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2600c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0) { 2601c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("found fpo: "); 2602c8259b85b701d25d72aabe9dc0a8154517f96913sewardj //ML_(ppFPO)(fpo); 2603c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2604c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2605c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* 2606c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Stack layout is: 2607c8259b85b701d25d72aabe9dc0a8154517f96913sewardj %esp-> 2608c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 4*.cbRegs {%edi, %esi, %ebp, %ebx} 2609c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 4*.cdwLocals 2610c8259b85b701d25d72aabe9dc0a8154517f96913sewardj return_pc 2611c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 4*.cdwParams 2612c8259b85b701d25d72aabe9dc0a8154517f96913sewardj prior_%esp-> 2613c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2614c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Typical code looks like: 2615c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sub $4*.cdwLocals,%esp 2616c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Alternative to above for >=4KB (and sometimes for smaller): 2617c8259b85b701d25d72aabe9dc0a8154517f96913sewardj mov $size,%eax 2618c8259b85b701d25d72aabe9dc0a8154517f96913sewardj call __chkstk # WinNT performs page-by-page probe! 2619c8259b85b701d25d72aabe9dc0a8154517f96913sewardj __chkstk is much like alloc(), except that on return 2620c8259b85b701d25d72aabe9dc0a8154517f96913sewardj %eax= 5+ &CALL. Thus it could be used as part of 2621c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Position Independent Code to locate the Global Offset Table. 2622c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %ebx 2623c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %ebp 2624c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %esi 2625c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Other once-only instructions often scheduled >here<. 2626c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %edi 2627c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2628c8259b85b701d25d72aabe9dc0a8154517f96913sewardj If the pc is within the first .cbProlog bytes of the function, 2629c8259b85b701d25d72aabe9dc0a8154517f96913sewardj then you must disassemble to see how many registers have been pushed, 2630c8259b85b701d25d72aabe9dc0a8154517f96913sewardj because instructions in the prolog may be scheduled for performance. 2631c8259b85b701d25d72aabe9dc0a8154517f96913sewardj The order of PUSH is always %ebx, %ebp, %esi, %edi, with trailing 2632c8259b85b701d25d72aabe9dc0a8154517f96913sewardj registers not pushed when .cbRegs < 4. This seems somewhat strange 2633c8259b85b701d25d72aabe9dc0a8154517f96913sewardj because %ebp is the register whose usage you want to minimize, 2634c8259b85b701d25d72aabe9dc0a8154517f96913sewardj yet it is in the first half of the PUSH list. 2635c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2636c8259b85b701d25d72aabe9dc0a8154517f96913sewardj I don't know what happens when the compiler constructs an outgoing CALL. 2637c8259b85b701d25d72aabe9dc0a8154517f96913sewardj %esp could move if outgoing parameters are PUSHed, and this affects 2638c8259b85b701d25d72aabe9dc0a8154517f96913sewardj traceback for errors during the PUSHes. */ 2639c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2640c8259b85b701d25d72aabe9dc0a8154517f96913sewardj spHere = *spP; 2641c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 264286781fabbfc019b752f9605e487cfce77b2a592atom *ipP = ML_(read_Addr)((void *)(spHere + 4*(fpo->cbRegs + fpo->cdwLocals))); 264386781fabbfc019b752f9605e487cfce77b2a592atom *spP = spHere + 4*(fpo->cbRegs + fpo->cdwLocals + 1 264486781fabbfc019b752f9605e487cfce77b2a592atom + fpo->cdwParams); 264586781fabbfc019b752f9605e487cfce77b2a592atom *fpP = ML_(read_Addr)((void *)(spHere + 4*2)); 2646c8259b85b701d25d72aabe9dc0a8154517f96913sewardj return True; 2647c8259b85b701d25d72aabe9dc0a8154517f96913sewardj} 2648c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2649c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2650c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--------------------------------------------------------------*/ 2651c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- ---*/ 2652b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- TOP LEVEL: GENERATE DESCRIPTION OF DATA ADDRESSES ---*/ 2653b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- FROM DWARF3 DEBUG INFO ---*/ 2654b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 2655b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 2656b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2657588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj/* Try to make p2XA(dst, fmt, args..) turn into 2658b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart VG_(xaprintf)(dst, fmt, args) without having to resort to 2659588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj vararg macros. As usual with everything to do with varargs, it's 2660588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj an ugly hack. 2661738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 2662588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj //#define p2XA(dstxa, format, args...) 2663b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart // VG_(xaprintf)(dstxa, format, ##args) 2664738856f99eea33d86ce91dcb1d6cd5b151e307casewardj*/ 2665b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart#define p2XA VG_(xaprintf) 2666738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 2667588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj/* Add a zero-terminating byte to DST, which must be an XArray* of 2668588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj HChar. */ 2669738856f99eea33d86ce91dcb1d6cd5b151e307casewardjstatic void zterm_XA ( XArray* dst ) 2670738856f99eea33d86ce91dcb1d6cd5b151e307casewardj{ 2671738856f99eea33d86ce91dcb1d6cd5b151e307casewardj HChar zero = 0; 2672738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (void) VG_(addBytesToXA)( dst, &zero, 1 ); 2673738856f99eea33d86ce91dcb1d6cd5b151e307casewardj} 2674738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 2675738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 2676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Evaluate the location expression/list for var, to see whether or 2677b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj not data_addr falls within the variable. If so also return the 2678b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset of data_addr from the start of the variable. Note that 2679b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs, which supplies ip,sp,fp values, will be NULL for global 2680b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj variables, and non-NULL for local variables. */ 2681c4431bfe04c7490ea2d74939d222d87f13f30960njnstatic Bool data_address_is_in_var ( /*OUT*/PtrdiffT* offset, 26829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* /* TyEnt */ tyents, 2683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var, 2684b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj RegSummary* regs, 2685b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 2686588658b13b5ad77672f323d48fe9da0ca60b0bcbtom const DebugInfo* di ) 2687b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 268850fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 2689b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj SizeT var_szB; 2690b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj GXResult res; 2691b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool show = False; 26929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 2693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->name); 2694b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->gexpr); 2695b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2696b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Figure out how big the variable is. */ 269750fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(tyents, var->typeR); 269850fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 269950fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. ML_(addVar) 270050fde23467d92281b32dd537d0d9a590263628c3sewardj should have rejected it. */ 270150fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 270250fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 270350fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 270450fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a host word 270550fde23467d92281b32dd537d0d9a590263628c3sewardj safely (without loss of info). */ 270650fde23467d92281b32dd537d0d9a590263628c3sewardj 270750fde23467d92281b32dd537d0d9a590263628c3sewardj var_szB = (SizeT)mul.ul; /* NB: truncate to host word */ 2708b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) { 2710a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("VVVV: data_address_%#lx_is_in_var: %s :: ", 2711b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var->name ); 27129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(pp_TyEnt_C_ishly)( tyents, var->typeR ); 2713b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("\n"); 2714b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2715b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2716b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ignore zero-sized vars; they can never match anything. */ 2717b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (var_szB == 0) { 2718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) 2719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("VVVV: -> Fail (variable is zero sized)\n"); 2720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 2721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2722b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2723588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_GX)( var->gexpr, var->fbGX, regs, di ); 2724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) { 2726b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("VVVV: -> "); 2727b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(pp_GXResult)( res ); 2728b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("\n"); 2729b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2730eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 27313c9cf3442185b5891e15450d6e3058aeff6796fetom if (res.kind == GXR_Addr 2732b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && res.word <= data_addr 2733b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && data_addr < res.word + var_szB) { 2734b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *offset = data_addr - res.word; 2735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 2736b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 2737b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 2738b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2739b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 2740b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2741b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2742738856f99eea33d86ce91dcb1d6cd5b151e307casewardj/* Format the acquired information into DN(AME)1 and DN(AME)2, which 2743738856f99eea33d86ce91dcb1d6cd5b151e307casewardj are XArray*s of HChar, that have been initialised by the caller. 2744738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Resulting strings will be zero terminated. Information is 2745738856f99eea33d86ce91dcb1d6cd5b151e307casewardj formatted in an understandable way. Not so easy. If frameNo is 2746738856f99eea33d86ce91dcb1d6cd5b151e307casewardj -1, this is assumed to be a global variable; else a local 2747738856f99eea33d86ce91dcb1d6cd5b151e307casewardj variable. */ 2748738856f99eea33d86ce91dcb1d6cd5b151e307casewardjstatic void format_message ( /*MOD*/XArray* /* of HChar */ dn1, 2749738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /*MOD*/XArray* /* of HChar */ dn2, 2750b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 2751b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var, 2752c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT var_offset, 2753c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT residual_offset, 2754b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* /*UChar*/ described, 2755b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int frameNo, 2756b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid ) 2757eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2758738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Bool have_descr, have_srcloc; 2759738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Bool xml = VG_(clo_xml); 2760b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj UChar* vo_plural = var_offset == 1 ? "" : "s"; 2761b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj UChar* ro_plural = residual_offset == 1 ? "" : "s"; 2762738856f99eea33d86ce91dcb1d6cd5b151e307casewardj UChar* basetag = "auxwhat"; /* a constant */ 2763738856f99eea33d86ce91dcb1d6cd5b151e307casewardj UChar tagL[32], tagR[32], xagL[32], xagR[32]; 2764b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2765d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj if (frameNo < -1) { 2766d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj vg_assert(0); /* Not allowed */ 2767d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj } 2768d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj else if (frameNo == -1) { 2769d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj vg_assert(tid == VG_INVALID_THREADID); 2770d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj } 2771d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj else /* (frameNo >= 0) */ { 2772d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj vg_assert(tid != VG_INVALID_THREADID); 2773d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj } 2774d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj 2775738856f99eea33d86ce91dcb1d6cd5b151e307casewardj vg_assert(dn1 && dn2); 2776b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(described); 2777b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var && var->name); 2778b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj have_descr = VG_(sizeXA)(described) > 0 2779b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && *(UChar*)VG_(indexXA)(described,0) != '\0'; 2780b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj have_srcloc = var->fileName && var->lineNo > 0; 2781b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2782738856f99eea33d86ce91dcb1d6cd5b151e307casewardj tagL[0] = tagR[0] = xagL[0] = xagR[0] = 0; 2783738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 2784738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(tagL, "<%s>", basetag); // <auxwhat> 2785738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(tagR, "</%s>", basetag); // </auxwhat> 2786738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(xagL, "<x%s>", basetag); // <xauxwhat> 2787738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(xagR, "</x%s>", basetag); // </xauxwhat> 2788738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 2789738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 2790738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TAGL(_xa) p2XA(_xa, "%s", tagL) 2791738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TAGR(_xa) p2XA(_xa, "%s", tagR) 2792738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define XAGL(_xa) p2XA(_xa, "%s", xagL) 2793738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define XAGR(_xa) p2XA(_xa, "%s", xagR) 2794738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TXTL(_xa) p2XA(_xa, "%s", "<text>") 2795738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TXTR(_xa) p2XA(_xa, "%s", "</text>") 2796b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2797b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ------ local cases ------ */ 2798b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2799b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && (!have_srcloc) && (!have_descr) ) { 2800b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc, no description: 2801b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside local var "a", 2802b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in frame #1 of thread 1 2803b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2804738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 2805738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 2806738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2807b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside local var \"%pS\",", 2808738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 2809738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 2810738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn2 ); 2811738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2812738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "in frame #%d of thread %d", frameNo, (Int)tid ); 2813738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn2 ); 2814738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 2815738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2816738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside local var \"%s\",", 2817738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 2818738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2819738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "in frame #%d of thread %d", frameNo, (Int)tid ); 2820738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 2821b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2822b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2823b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && have_srcloc && (!have_descr) ) { 2824b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no description: 2825b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside local var "a" 2826b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj declared at dsyms7.c:17, in frame #1 of thread 1 2827b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2828738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 2829738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 2830738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2831b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside local var \"%pS\"", 2832738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 2833738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 2834738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 2835738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 2836738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2837b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "declared at %pS:%d, in frame #%d of thread %d", 2838738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo, frameNo, (Int)tid ); 2839738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 2840738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 2841738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2842b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart " <file>%pS</file> <line>%d</line> ", 2843738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo ); 2844738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 2845738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 2846738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2847738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside local var \"%s\"", 2848738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 2849738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2850738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "declared at %s:%d, in frame #%d of thread %d", 2851738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo, frameNo, (Int)tid ); 2852738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 2853b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2854b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2855b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && (!have_srcloc) && have_descr ) { 2856b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc: 2857b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2 2858b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in frame #1 of thread 1 2859b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2860738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 2861738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 2862738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2863b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside %pS%pS", 2864738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 2865738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 2866738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 2867738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn2 ); 2868738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2869738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "in frame #%d of thread %d", frameNo, (Int)tid ); 2870738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn2 ); 2871738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 2872738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2873738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %s%s", 2874738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 2875738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 2876738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2877738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "in frame #%d of thread %d", frameNo, (Int)tid ); 2878738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 2879b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2880b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2881b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && have_srcloc && have_descr ) { 2882738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 2883738856f99eea33d86ce91dcb1d6cd5b151e307casewardj declared at dsyms7.c:17, in frame #1 of thread 1 */ 2884738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 2885738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 2886738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2887b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside %pS%pS,", 2888738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 2889738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 2890738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 2891738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 2892738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 2893738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2894b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "declared at %pS:%d, in frame #%d of thread %d", 2895738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo, frameNo, (Int)tid ); 2896738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 2897738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 2898738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2899b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart " <file>%pS</file> <line>%d</line> ", 2900738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo ); 2901738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 2902738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 2903738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2904738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %s%s,", 2905738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 2906738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 2907738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2908738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "declared at %s:%d, in frame #%d of thread %d", 2909738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo, frameNo, (Int)tid ); 2910738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 2911b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2912b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2913b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ------ global cases ------ */ 2914b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && (!have_srcloc) && (!have_descr) ) { 2915b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc, no description: 2916b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside global var "a" 2917b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2918738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 2919738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 2920738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2921b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside global var \"%pS\"", 2922738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 2923738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 2924738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 2925738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2926738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside global var \"%s\"", 2927738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 2928738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 2929b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2930b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2931b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && have_srcloc && (!have_descr) ) { 2932b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no description: 2933b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside global var "a" 2934b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj declared at dsyms7.c:17 2935b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2936738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 2937738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 2938738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2939b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside global var \"%pS\"", 2940738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 2941738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 2942738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 2943738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 2944738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2945b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "declared at %pS:%d", 2946738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo); 2947738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 2948738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 2949738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2950b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart " <file>%pS</file> <line>%d</line> ", 2951738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo ); 2952738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 2953738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 2954738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2955738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside global var \"%s\"", 2956738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 2957738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2958738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "declared at %s:%d", 2959738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo); 2960738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 2961b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2962b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2963b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && (!have_srcloc) && have_descr ) { 2964b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc: 2965b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 2966b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj a global variable 2967b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2968738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 2969738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 2970738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2971b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside %pS%pS,", 2972738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 2973738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 2974738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 2975738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn2 ); 2976738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2977738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "a global variable"); 2978738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn2 ); 2979738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 2980738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2981738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %s%s,", 2982738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 2983738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (char*)(VG_(indexXA)(described,0)) ); 2984738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2985738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "a global variable"); 2986738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 2987b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2988b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2989b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && have_srcloc && have_descr ) { 2990738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 2991738856f99eea33d86ce91dcb1d6cd5b151e307casewardj a global variable declared at dsyms7.c:17 */ 2992738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 2993738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 2994738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2995b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside %pS%pS,", 2996738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 2997738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 2998738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 2999738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 3000738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 3001738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3002b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "a global variable declared at %pS:%d", 3003738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo); 3004738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 3005738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 3006738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3007b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart " <file>%pS</file> <line>%d</line> ", 3008738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo ); 3009738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 3010738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3011738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3012738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %s%s,", 3013738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3014738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3015738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3016738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "a global variable declared at %s:%d", 3017738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo); 3018738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3019b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3020b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3021b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(0); 3022b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3023738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /* Zero terminate both strings */ 3024738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dn1 ); 3025738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dn2 ); 3026738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3027738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TAGL 3028738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TAGR 3029738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef XAGL 3030738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef XAGR 3031738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TXTL 3032738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TXTR 3033eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3034eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3035738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3036b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Determine if data_addr is a local variable in the frame 3037738856f99eea33d86ce91dcb1d6cd5b151e307casewardj characterised by (ip,sp,fp), and if so write its description at the 3038738856f99eea33d86ce91dcb1d6cd5b151e307casewardj ends of DNAME{1,2}, which are XArray*s of HChar, that have been 3039738856f99eea33d86ce91dcb1d6cd5b151e307casewardj initialised by the caller, zero terminate both, and return True. 3040738856f99eea33d86ce91dcb1d6cd5b151e307casewardj If it's not a local variable in said frame, return False. */ 3041b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic 3042738856f99eea33d86ce91dcb1d6cd5b151e307casewardjBool consider_vars_in_frame ( /*MOD*/XArray* /* of HChar */ dname1, 3043738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /*MOD*/XArray* /* of HChar */ dname2, 3044b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 3045b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr ip, Addr sp, Addr fp, 3046b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* shown to user: */ 3047b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid, Int frameNo ) 3048eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3049b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word i; 3050b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 3051b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj RegSummary regs; 3052b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool debug = False; 3053b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3054b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj static UInt n_search = 0; 3055b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj static UInt n_steps = 0; 3056b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_search++; 3057b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 3058a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("QQQQ: cvif: ip,sp,fp %#lx,%#lx,%#lx\n", ip,sp,fp); 3059b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* first, find the DebugInfo that pertains to 'ip'. */ 3060b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di; di = di->next) { 3061b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_steps++; 3062b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* text segment missing? unlikely, but handle it .. */ 3063b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->text_present || di->text_size == 0) 3064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3065b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok. So does this text mapping bracket the ip? */ 3066b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_avma <= ip && ip < di->text_avma + di->text_size) 3067b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3068b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3069b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3070b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Didn't find it. Strange -- means ip is a code address outside 3071b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj of any mapped text segment. Unlikely but not impossible -- app 3072b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj could be generating code to run. */ 3073b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di) 3074b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3075b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3076b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0 && ((n_search & 0x1) == 0)) 3077b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("consider_vars_in_frame: %u searches, " 3078b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "%u DebugInfos looked at\n", 3079b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_search, n_steps); 3080b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Start of performance-enhancing hack: once every ??? (chosen 3081b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj hackily after profiling) successful searches, move the found 3082b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo one step closer to the start of the list. This makes 3083b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj future searches cheaper. */ 3084b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ((n_search & 0xFFFF) == 0) { 3085b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Move si one step closer to the start of the list. */ 3086b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj move_DebugInfo_one_step_forward( di ); 3087b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3088b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* End of performance-enhancing hack. */ 3089b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3090b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* any var info at all? */ 3091b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->varinfo) 3092b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3093b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3094b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Work through the scopes from most deeply nested outwards, 3095b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj looking for code address ranges that bracket 'ip'. The 3096b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj variables on each such address range found are in scope right 3097b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj now. Don't descend to level zero as that is the global 3098b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj scope. */ 3099b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.ip = ip; 3100b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.sp = sp; 3101b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.fp = fp; 3102b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3103b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* "for each scope, working outwards ..." */ 3104b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) { 3105b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* vars; 3106b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word j; 3107b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* arange; 3108b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* this_scope 3109b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj = *(OSet**)VG_(indexXA)( di->varinfo, i ); 3110b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 3111b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("QQQQ: considering scope %ld\n", (Word)i); 3112b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!this_scope) 3113b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3114b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Find the set of variables in this scope that 3115b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj bracket the program counter. */ 3116b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj arange = VG_(OSetGen_LookupWithCmp)( 3117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj this_scope, &ip, 3118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(cmp_for_DiAddrRange_range) 3119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ); 3120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!arange) 3121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* stay sane */ 3123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->aMin <= arange->aMax); 3124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* It must bracket the ip we asked for, else 3125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(cmp_for_DiAddrRange_range) is somehow broken. */ 3126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->aMin <= ip && ip <= arange->aMax); 3127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* It must have an attached XArray of DiVariables. */ 3128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vars = arange->vars; 3129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(vars); 3130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* But it mustn't cover the entire address range. We only 3131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj expect that to happen for the global scope (level 0), which 3132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj we're not looking at here. Except, it may cover the entire 3133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj address range, but in that case the vars array must be 3134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj empty. */ 3135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(! (arange->aMin == (Addr)0 3136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && arange->aMax == ~(Addr)0 3137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && VG_(sizeXA)(vars) > 0) ); 3138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < VG_(sizeXA)( vars ); j++) { 3139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j ); 3140c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT offset; 3141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 3142a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n", 3143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var->name,arange->aMin,arange->aMax,ip); 31449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (data_address_is_in_var( &offset, di->admin_tyents, 31459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var, ®s, 3146588658b13b5ad77672f323d48fe9da0ca60b0bcbtom data_addr, di )) { 3147c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT residual_offset = 0; 3148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* described = ML_(describe_type)( &residual_offset, 31499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->admin_tyents, 31509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR, offset ); 3151738856f99eea33d86ce91dcb1d6cd5b151e307casewardj format_message( dname1, dname2, 3152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var, offset, residual_offset, 3153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj described, frameNo, tid ); 3154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)( described ); 3155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3161eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3162eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3163738856f99eea33d86ce91dcb1d6cd5b151e307casewardj/* Try to form some description of DATA_ADDR by looking at the DWARF3 3164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debug info we have. This considers all global variables, and all 3165738856f99eea33d86ce91dcb1d6cd5b151e307casewardj frames in the stacks of all threads. Result is written at the ends 3166738856f99eea33d86ce91dcb1d6cd5b151e307casewardj of DNAME{1,2}V, which are XArray*s of HChar, that have been 3167738856f99eea33d86ce91dcb1d6cd5b151e307casewardj initialised by the caller, and True is returned. If no description 3168738856f99eea33d86ce91dcb1d6cd5b151e307casewardj is created, False is returned. Regardless of the return value, 3169738856f99eea33d86ce91dcb1d6cd5b151e307casewardj DNAME{1,2}V are guaranteed to be zero terminated after the call. 3170738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3171738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Note that after the call, DNAME{1,2} may have more than one 3172738856f99eea33d86ce91dcb1d6cd5b151e307casewardj trailing zero, so callers should establish the useful text length 3173738856f99eea33d86ce91dcb1d6cd5b151e307casewardj using VG_(strlen) on the contents, rather than VG_(sizeXA) on the 3174738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XArray itself. 3175738856f99eea33d86ce91dcb1d6cd5b151e307casewardj*/ 3176738856f99eea33d86ce91dcb1d6cd5b151e307casewardjBool VG_(get_data_description)( 3177738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /*MOD*/ void* /* really, XArray* of HChar */ dname1v, 3178738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /*MOD*/ void* /* really, XArray* of HChar */ dname2v, 3179738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Addr data_addr 3180738856f99eea33d86ce91dcb1d6cd5b151e307casewardj ) 3181eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# define N_FRAMES 8 3183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr ips[N_FRAMES], sps[N_FRAMES], fps[N_FRAMES]; 3184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj UInt n_frames; 3185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr stack_min, stack_max; 3187b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid; 3188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool found; 3189b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 3190b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word j; 3191b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3192738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XArray* dname1 = (XArray*)dname1v; 3193738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XArray* dname2 = (XArray*)dname2v; 3194b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3195a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart if (0) VG_(printf)("get_data_description: dataaddr %#lx\n", data_addr); 3196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* First, see if data_addr is (or is part of) a global variable. 3197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Loop over the DebugInfos we have. Check data_addr against the 3198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj outermost scope of all of them, as that should be a global 3199b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj scope. */ 3200b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 3201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* global_scope; 32029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word gs_size; 3203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr zero; 3204b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* global_arange; 3205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word i; 3206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* vars; 3207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* text segment missing? unlikely, but handle it .. */ 3209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->text_present || di->text_size == 0) 3210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* any var info at all? */ 3212b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->varinfo) 3213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* perhaps this object didn't contribute any vars at all? */ 3215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (VG_(sizeXA)( di->varinfo ) == 0) 3216b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj global_scope = *(OSet**)VG_(indexXA)( di->varinfo, 0 ); 3218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_scope); 3219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj gs_size = VG_(OSetGen_Size)( global_scope ); 3220b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* The global scope might be completely empty if this 3221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj compilation unit declared locals but nothing global. */ 3222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (gs_size == 0) 3223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* But if it isn't empty, then it must contain exactly one 3225b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj element, which covers the entire address range. */ 3226b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(gs_size == 1); 3227b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Fish out the global scope and check it is as expected. */ 3228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj zero = 0; 3229b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj global_arange 3230b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj = VG_(OSetGen_Lookup)( global_scope, &zero ); 3231b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* The global range from (Addr)0 to ~(Addr)0 must exist */ 3232b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_arange); 3233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_arange->aMin == (Addr)0 3234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && global_arange->aMax == ~(Addr)0); 3235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Any vars in this range? */ 3236b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!global_arange->vars) 3237b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3238b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok, there are some vars in the global scope of this 3239b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo. Wade through them and see if the data addresses 3240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj of any of them bracket data_addr. */ 3241b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vars = global_arange->vars; 3242b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = 0; i < VG_(sizeXA)( vars ); i++) { 3243c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT offset; 3244b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, i ); 3245b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->name); 3246b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Note we use a NULL RegSummary* here. It can't make any 3247b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sense for a global variable to have a location expression 3248b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which depends on a SP/FP/IP value. So don't supply any. 3249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj This means, if the evaluation of the location 3250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj expression/list requires a register, we have to let it 3251b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj fail. */ 32529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (data_address_is_in_var( &offset, di->admin_tyents, var, 3253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj NULL/* RegSummary* */, 3254588658b13b5ad77672f323d48fe9da0ca60b0bcbtom data_addr, di )) { 3255c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT residual_offset = 0; 3256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* described = ML_(describe_type)( &residual_offset, 32579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->admin_tyents, 32589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR, offset ); 3259738856f99eea33d86ce91dcb1d6cd5b151e307casewardj format_message( dname1, dname2, 3260b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var, offset, residual_offset, 3261d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj described, -1/*frameNo*/, 3262d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj VG_INVALID_THREADID ); 3263b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)( described ); 3264738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3265738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3266b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3267b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok, well it's not a global variable. So now let's snoop around 3272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in the stacks of all the threads. First try to figure out which 3273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj thread's stack data_addr is in. */ 3274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* --- KLUDGE --- Try examining the top frame of all thread stacks. 3276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj This finds variables which are not stack allocated but are not 3277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj globally visible either; specifically it appears to pick up 3278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj variables which are visible only within a compilation unit. 3279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj These will have the address range of the compilation unit and 3280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj tend to live at Scope level 1. */ 3281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(thread_stack_reset_iter)(&tid); 3282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) { 3283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (stack_min >= stack_max) 3284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; /* ignore obviously stupid cases */ 3285738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (consider_vars_in_frame( dname1, dname2, 3286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, 3287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(get_IP)(tid), 3288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(get_SP)(tid), 3289b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(get_FP)(tid), tid, 0 )) { 3290738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3291738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3292b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3293b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* --- end KLUDGE --- */ 3296b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3297b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Perhaps it's on a thread's stack? */ 3298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj found = False; 3299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(thread_stack_reset_iter)(&tid); 3300b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) { 3301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (stack_min >= stack_max) 3302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; /* ignore obviously stupid cases */ 3303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (stack_min - VG_STACK_REDZONE_SZB <= data_addr 3304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && data_addr <= stack_max) { 3305b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj found = True; 3306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3307b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!found) { 3310738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3311738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3312b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We conclude data_addr is in thread tid's stack. Unwind the 3316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj stack to get a bunch of (ip,sp,fp) triples describing the 3317b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj frames, and for each frame, consider the local variables. */ 3318b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_frames = VG_(get_StackTrace)( tid, ips, N_FRAMES, 3319b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sps, fps, 0/*first_ip_delta*/ ); 3320b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj 3321b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* As a result of KLUDGE above, starting the loop at j = 0 3322b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj duplicates examination of the top frame and so isn't necessary. 3323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Oh well. */ 3324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_frames >= 0 && n_frames <= N_FRAMES); 3325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < n_frames; j++) { 3326738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (consider_vars_in_frame( dname1, dname2, 3327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, 3328b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj ips[j], 3329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sps[j], fps[j], tid, j )) { 3330738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3331738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Now, it appears that gcc sometimes appears to produce 3335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj location lists whose ranges don't actually cover the call 3336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj instruction, even though the address of the variable in 3337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj question is passed as a parameter in the call. AFAICS this 3338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is simply a bug in gcc - how can the variable be claimed not 3339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj exist in memory (on the stack) for the duration of a call in 3340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which its address is passed? But anyway, in the particular 3341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case I investigated (memcheck/tests/varinfo6.c, call to croak 3342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj on line 2999, local var budget declared at line 3115 3343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj appearing not to exist across the call to mainSort on line 3344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3143, "gcc.orig (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2)" on 3345b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj amd64), the variable's location list does claim it exists 3346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj starting at the first byte of the first instruction after the 3347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj call instruction. So, call consider_vars_in_frame a second 3348b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj time, but this time add 1 to the IP. GDB handles this 3349b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj example with no difficulty, which leads me to believe that 3350b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj either (1) I misunderstood something, or (2) GDB has an 3351b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj equivalent kludge. */ 3352b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj if (j > 0 /* this is a non-innermost frame */ 3353738856f99eea33d86ce91dcb1d6cd5b151e307casewardj && consider_vars_in_frame( dname1, dname2, 3354b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj data_addr, 3355b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj ips[j] + 1, 3356b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj sps[j], fps[j], tid, j )) { 3357738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3358738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3359b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3360b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3361b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3362b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3363b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We didn't find anything useful. */ 3364738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3365738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# undef N_FRAMES 3368eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3369eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 33719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj////////////////////////////////////////////////////////////////// 33729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// // 33739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// Support for other kinds of queries to the Dwarf3 var info // 33749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// // 33759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj////////////////////////////////////////////////////////////////// 33769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 33779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Figure out if the variable 'var' has a location that is linearly 33789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj dependent on a stack pointer value, or a frame pointer value, and 33799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if it is, add a description of it to 'blocks'. Otherwise ignore 33809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. If 'arrays_only' is True, also ignore it unless it has an 33819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj array type. */ 33829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 33839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic 33849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks, 33859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* /* TyEnt */ tyents, 3386588658b13b5ad77672f323d48fe9da0ca60b0bcbtom Addr ip, const DebugInfo* di, DiVariable* var, 33879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool arrays_only ) 33889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 33899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res_sp_6k, res_sp_7k, res_fp_6k, res_fp_7k; 33909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj RegSummary regs; 339150fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 33929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool isVec; 33939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ty; 33949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 33959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool debug = False; 33969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0&&debug) 33979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("adeps: var %s\n", var->name ); 33989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 33999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Figure out how big the variable is. */ 340050fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(tyents, var->typeR); 340150fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 340250fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. ML_(addVar) 340350fde23467d92281b32dd537d0d9a590263628c3sewardj should have rejected it. */ 340450fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 340550fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 340650fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 340750fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a host word 340850fde23467d92281b32dd537d0d9a590263628c3sewardj safely (without loss of info). */ 34099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 34109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* skip if non-array and we're only interested in arrays */ 34119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ty = ML_(TyEnts__index_by_cuOff)( tyents, NULL, var->typeR ); 34129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty); 34139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty)); 34149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (ty->tag == Te_UNKNOWN) 34159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return; /* perhaps we should complain in this case? */ 34169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj isVec = ty->tag == Te_TyArray; 34179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (arrays_only && !isVec) 34189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return; 34199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 34209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) {ML_(pp_TyEnt_C_ishly)(tyents, var->typeR); 34219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)(" %s\n", var->name);} 34229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 34239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Do some test evaluations of the variable's location expression, 34249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj in order to guess whether it is sp-relative, fp-relative, or 34259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj none. A crude hack, which can be interpreted roughly as finding 34269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj the first derivative of the location expression w.r.t. the 34279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj supplied frame and stack pointer values. */ 34289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 0; 34299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 34309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 6 * 1024; 3431588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_sp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 34329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 34339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 0; 34349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 34359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 7 * 1024; 3436588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_sp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 34379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 34389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 6 * 1024; 34399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 34409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 0; 3441588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_fp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 34429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 34439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 7 * 1024; 34449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 34459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 0; 3446588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_fp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 34479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 34489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_sp_7k.kind); 34499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_fp_6k.kind); 34509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_fp_7k.kind); 34519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 34523c9cf3442185b5891e15450d6e3058aeff6796fetom if (res_sp_6k.kind == GXR_Addr) { 34539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj StackBlock block; 34549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res; 34559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj UWord sp_delta = res_sp_7k.word - res_sp_6k.word; 34569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj UWord fp_delta = res_fp_7k.word - res_fp_6k.word; 34579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(sp_delta == 0 || sp_delta == 1024); 34589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(fp_delta == 0 || fp_delta == 1024); 34599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 34609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 0 && fp_delta == 0) { 34619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* depends neither on sp nor fp, so it can't be a stack 34629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj local. Ignore it. */ 34639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 34649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else 34659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 1024 && fp_delta == 0) { 34669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = regs.fp = 0; 34679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 3468588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 34693c9cf3442185b5891e15450d6e3058aeff6796fetom tl_assert(res.kind == GXR_Addr); 34709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 34719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)(" %5ld .. %5ld (sp) %s\n", 347250fde23467d92281b32dd537d0d9a590263628c3sewardj res.word, res.word + ((UWord)mul.ul) - 1, var->name); 34739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.base = res.word; 347450fde23467d92281b32dd537d0d9a590263628c3sewardj block.szB = (SizeT)mul.ul; 34759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.spRel = True; 34769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.isVec = isVec; 34779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)( &block.name[0], 0, sizeof(block.name) ); 34789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (var->name) 34799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 ); 34809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.name[ sizeof(block.name)-1 ] = 0; 34819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( blocks, &block ); 34829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 34839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else 34849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 0 && fp_delta == 1024) { 34859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = regs.fp = 0; 34869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 3487588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 34883c9cf3442185b5891e15450d6e3058aeff6796fetom tl_assert(res.kind == GXR_Addr); 34899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 34909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)(" %5ld .. %5ld (FP) %s\n", 349150fde23467d92281b32dd537d0d9a590263628c3sewardj res.word, res.word + ((UWord)mul.ul) - 1, var->name); 34929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.base = res.word; 349350fde23467d92281b32dd537d0d9a590263628c3sewardj block.szB = (SizeT)mul.ul; 34949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.spRel = False; 34959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.isVec = isVec; 34969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)( &block.name[0], 0, sizeof(block.name) ); 34979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (var->name) 34989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 ); 34999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.name[ sizeof(block.name)-1 ] = 0; 35009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( blocks, &block ); 35019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 35029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else { 35039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(0); 35049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 35059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 35069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 35079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 35089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 35099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Get an XArray of StackBlock which describe the stack (auto) blocks 35109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for this ip. The caller is expected to free the XArray at some 35119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj point. If 'arrays_only' is True, only array-typed blocks are 35129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj returned; otherwise blocks of all types are returned. */ 35139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 35149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid* /* really, XArray* of StackBlock */ 35159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(di_get_stack_blocks_at_ip)( Addr ip, Bool arrays_only ) 35169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 35179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* This is a derivation of consider_vars_in_frame() above. */ 35189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word i; 35199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo* di; 35209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool debug = False; 35219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 35229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* res = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dgsbai.1", 35239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(dinfo_free), 35249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj sizeof(StackBlock) ); 35259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 35269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj static UInt n_search = 0; 35279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj static UInt n_steps = 0; 35289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_search++; 35299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 35309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: dgsbai: ip %#lx\n", ip); 35319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* first, find the DebugInfo that pertains to 'ip'. */ 35329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (di = debugInfo_list; di; di = di->next) { 35339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_steps++; 35349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* text segment missing? unlikely, but handle it .. */ 35359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->text_present || di->text_size == 0) 35369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 35379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok. So does this text mapping bracket the ip? */ 35389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (di->text_avma <= ip && ip < di->text_avma + di->text_size) 35399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj break; 35409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 35419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 35429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Didn't find it. Strange -- means ip is a code address outside 35439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj of any mapped text segment. Unlikely but not impossible -- app 35449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj could be generating code to run. */ 35459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di) 35469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; /* currently empty */ 35479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 35489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0 && ((n_search & 0x1) == 0)) 35499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("VG_(di_get_stack_blocks_at_ip): %u searches, " 35509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj "%u DebugInfos looked at\n", 35519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_search, n_steps); 35529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Start of performance-enhancing hack: once every ??? (chosen 35539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj hackily after profiling) successful searches, move the found 35549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo one step closer to the start of the list. This makes 35559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj future searches cheaper. */ 35569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if ((n_search & 0xFFFF) == 0) { 35579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Move si one step closer to the start of the list. */ 35589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj move_DebugInfo_one_step_forward( di ); 35599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 35609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* End of performance-enhancing hack. */ 35619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 35629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* any var info at all? */ 35639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->varinfo) 35649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; /* currently empty */ 35659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 35669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Work through the scopes from most deeply nested outwards, 35679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj looking for code address ranges that bracket 'ip'. The 35689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj variables on each such address range found are in scope right 35699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj now. Don't descend to level zero as that is the global 35709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj scope. */ 35719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 35729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* "for each scope, working outwards ..." */ 35739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) { 35749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* vars; 35759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word j; 35769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiAddrRange* arange; 35779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj OSet* this_scope 35789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj = *(OSet**)VG_(indexXA)( di->varinfo, i ); 35799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 35809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: considering scope %ld\n", (Word)i); 35819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!this_scope) 35829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 35839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Find the set of variables in this scope that 35849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj bracket the program counter. */ 35859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj arange = VG_(OSetGen_LookupWithCmp)( 35869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj this_scope, &ip, 35879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(cmp_for_DiAddrRange_range) 35889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ); 35899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!arange) 35909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 35919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* stay sane */ 35929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(arange->aMin <= arange->aMax); 35939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* It must bracket the ip we asked for, else 35949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(cmp_for_DiAddrRange_range) is somehow broken. */ 35959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(arange->aMin <= ip && ip <= arange->aMax); 35969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* It must have an attached XArray of DiVariables. */ 35979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vars = arange->vars; 35989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(vars); 35999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* But it mustn't cover the entire address range. We only 36009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj expect that to happen for the global scope (level 0), which 36019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj we're not looking at here. Except, it may cover the entire 36029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj address range, but in that case the vars array must be 36039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj empty. */ 36049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(! (arange->aMin == (Addr)0 36059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj && arange->aMax == ~(Addr)0 36069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj && VG_(sizeXA)(vars) > 0) ); 36079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (j = 0; j < VG_(sizeXA)( vars ); j++) { 36089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j ); 36099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 36109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n", 36119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->name,arange->aMin,arange->aMax,ip); 36129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj analyse_deps( res, di->admin_tyents, ip, 3613588658b13b5ad77672f323d48fe9da0ca60b0bcbtom di, var, arrays_only ); 36149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 36159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 36169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 36179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; 36189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 36199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 36209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 36219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Get an array of GlobalBlock which describe the global blocks owned 36229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj by the shared object characterised by the given di_handle. Asserts 36239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if the handle is invalid. The caller is responsible for freeing 36249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj the array at some point. If 'arrays_only' is True, only 36259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj array-typed blocks are returned; otherwise blocks of all types are 36269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj returned. */ 36279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 36289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid* /* really, XArray* of GlobalBlock */ 36299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(di_get_global_blocks_from_dihandle) ( ULong di_handle, 36309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool arrays_only ) 36319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 36329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* This is a derivation of consider_vars_in_frame() above. */ 36339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 36349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo* di; 36359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* gvars; /* XArray* of GlobalBlock */ 36369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word nScopes, scopeIx; 36379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 36389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* The first thing to do is find the DebugInfo that 36399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj pertains to 'di_handle'. */ 36409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(di_handle > 0); 36419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (di = debugInfo_list; di; di = di->next) { 36429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (di->handle == di_handle) 36439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj break; 36449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 36459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 36469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* If this fails, we were unable to find any DebugInfo with the 36479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj given handle. This is considered an error on the part of the 36489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj caller. */ 36499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(di != NULL); 36509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 36519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* we'll put the collected variables in here. */ 36529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gvars = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dggbfd.1", 36539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(dinfo_free), sizeof(GlobalBlock) ); 36549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(gvars); 36559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 36569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* any var info at all? */ 36579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->varinfo) 36589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return gvars; 36599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 36609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* we'll iterate over all the variables we can find, even if 36619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it seems senseless to visit stack-allocated variables */ 36629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over all scopes */ 36639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj nScopes = VG_(sizeXA)( di->varinfo ); 36649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (scopeIx = 0; scopeIx < nScopes; scopeIx++) { 36659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 36669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over each (code) address range at the current scope */ 36679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiAddrRange* range; 36689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj OSet* /* of DiAddrInfo */ scope 36699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj = *(OSet**)VG_(indexXA)( di->varinfo, scopeIx ); 36709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(scope); 36719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(OSetGen_ResetIter)(scope); 36729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj while ( (range = VG_(OSetGen_Next)(scope)) ) { 36739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 36749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over each variable in the current address range */ 36759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word nVars, varIx; 36769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(range->vars); 36779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj nVars = VG_(sizeXA)( range->vars ); 36789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (varIx = 0; varIx < nVars; varIx++) { 36799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 36809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool isVec; 36819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res; 368250fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 36839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GlobalBlock gb; 36849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ty; 36859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiVariable* var = VG_(indexXA)( range->vars, varIx ); 36869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(var->name); 36879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("at depth %ld var %s ", scopeIx, var->name ); 36889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 36899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Now figure out if this variable has a constant address 36909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj (that is, independent of FP, SP, phase of moon, etc), 36919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj and if so, what the address is. Any variable with a 36929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj constant address is deemed to be a global so we collect 36939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. */ 36949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) { VG_(printf)("EVAL: "); ML_(pp_GX)(var->gexpr); 36959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("\n"); } 3696588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_trivial_GX)( var->gexpr, di ); 36979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 36989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Not a constant address => not interesting */ 36993c9cf3442185b5891e15450d6e3058aeff6796fetom if (res.kind != GXR_Addr) { 37009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("FAIL\n"); 37019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 37029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 37039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok, it's a constant address. See if we want to collect 37059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. */ 37069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("%#lx\n", res.word); 37079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Figure out how big the variable is. */ 370950fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(di->admin_tyents, var->typeR); 37109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 371150fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 371250fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. 371350fde23467d92281b32dd537d0d9a590263628c3sewardj ML_(addVar) should have rejected it. */ 371450fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 371550fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 371650fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 371750fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a 371850fde23467d92281b32dd537d0d9a590263628c3sewardj host word safely (without loss of info). */ 37199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* skip if non-array and we're only interested in 37219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj arrays */ 37229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ty = ML_(TyEnts__index_by_cuOff)( di->admin_tyents, NULL, 37239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR ); 37249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty); 37259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty)); 37269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (ty->tag == Te_UNKNOWN) 37279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; /* perhaps we should complain in this case? */ 37289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj isVec = ty->tag == Te_TyArray; 37309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (arrays_only && !isVec) continue; 37319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok, so collect it! */ 37339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(var->name); 37349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(di->soname); 37359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("XXXX %s %s %d\n", var->name, 37369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->fileName?(HChar*)var->fileName 37379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj :"??",var->lineNo); 37389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)(&gb, 0, sizeof(gb)); 37399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gb.addr = res.word; 374050fde23467d92281b32dd537d0d9a590263628c3sewardj gb.szB = (SizeT)mul.ul; 37419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gb.isVec = isVec; 37429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)(&gb.name[0], var->name, sizeof(gb.name)-1); 37439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)(&gb.soname[0], di->soname, sizeof(gb.soname)-1); 37449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(gb.name[ sizeof(gb.name)-1 ] == 0); 37459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(gb.soname[ sizeof(gb.soname)-1 ] == 0); 37469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( gvars, &gb ); 37489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* for (varIx = 0; varIx < nVars; varIx++) */ 37509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* while ( (range = VG_(OSetGen_Next)(scope)) ) */ 37529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* for (scopeIx = 0; scopeIx < nScopes; scopeIx++) */ 37549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return gvars; 37569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 37579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 3759b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 3760b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- DebugInfo accessor functions ---*/ 3761b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 3762b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3763e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjconst DebugInfo* VG_(next_DebugInfo)(const DebugInfo* di) 3764eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3765b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == NULL) 3766b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return debugInfo_list; 3767b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->next; 3768eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3769eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3770e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjAddr VG_(DebugInfo_get_text_avma)(const DebugInfo* di) 3771eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3772b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_avma : 0; 3773eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3774eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3775e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjSizeT VG_(DebugInfo_get_text_size)(const DebugInfo* di) 3776eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3777b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_size : 0; 3778eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3779eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3780e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjAddr VG_(DebugInfo_get_plt_avma)(const DebugInfo* di) 3781092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 3782092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->plt_present ? di->plt_avma : 0; 3783092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 3784092b6268cc4a38ae9ee41d1e3355937536ddc579bart 3785e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjSizeT VG_(DebugInfo_get_plt_size)(const DebugInfo* di) 3786092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 3787092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->plt_present ? di->plt_size : 0; 3788092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 3789092b6268cc4a38ae9ee41d1e3355937536ddc579bart 3790e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjAddr VG_(DebugInfo_get_gotplt_avma)(const DebugInfo* di) 3791092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 3792092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->gotplt_present ? di->gotplt_avma : 0; 3793092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 3794092b6268cc4a38ae9ee41d1e3355937536ddc579bart 3795e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjSizeT VG_(DebugInfo_get_gotplt_size)(const DebugInfo* di) 3796092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 3797092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->gotplt_present ? di->gotplt_size : 0; 3798092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 3799092b6268cc4a38ae9ee41d1e3355937536ddc579bart 380068347837b3d82e48f85daff33ec7ba528891e4e7bartAddr VG_(DebugInfo_get_got_avma)(const DebugInfo* di) 380168347837b3d82e48f85daff33ec7ba528891e4e7bart{ 380268347837b3d82e48f85daff33ec7ba528891e4e7bart return di->got_present ? di->got_avma : 0; 380368347837b3d82e48f85daff33ec7ba528891e4e7bart} 380468347837b3d82e48f85daff33ec7ba528891e4e7bart 380568347837b3d82e48f85daff33ec7ba528891e4e7bartSizeT VG_(DebugInfo_get_got_size)(const DebugInfo* di) 380668347837b3d82e48f85daff33ec7ba528891e4e7bart{ 380768347837b3d82e48f85daff33ec7ba528891e4e7bart return di->got_present ? di->got_size : 0; 380868347837b3d82e48f85daff33ec7ba528891e4e7bart} 380968347837b3d82e48f85daff33ec7ba528891e4e7bart 3810e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjconst UChar* VG_(DebugInfo_get_soname)(const DebugInfo* di) 3811eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3812b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->soname; 3813b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 3814eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3815e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjconst UChar* VG_(DebugInfo_get_filename)(const DebugInfo* di) 3816b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 3817a5acac39bf3be7546222b1316faee5ee524be0d1sewardj return di->fsm.filename; 3818eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3819eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3820e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjPtrdiffT VG_(DebugInfo_get_text_bias)(const DebugInfo* di) 3821bbec7728efefaa650970dd1f0282b77040287133sewardj{ 3822b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_bias : 0; 3823bbec7728efefaa650970dd1f0282b77040287133sewardj} 3824bbec7728efefaa650970dd1f0282b77040287133sewardj 3825e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjInt VG_(DebugInfo_syms_howmany) ( const DebugInfo *si ) 3826eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3827eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return si->symtab_used; 3828eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3829eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3830e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjvoid VG_(DebugInfo_syms_getidx) ( const DebugInfo *si, 3831e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj Int idx, 3832a5cace0c2a3e212931badbf6398a0cd98393121asewardj /*OUT*/Addr* avma, 3833a5cace0c2a3e212931badbf6398a0cd98393121asewardj /*OUT*/Addr* tocptr, 3834a5cace0c2a3e212931badbf6398a0cd98393121asewardj /*OUT*/UInt* size, 3835a5cace0c2a3e212931badbf6398a0cd98393121asewardj /*OUT*/UChar** pri_name, 3836a5cace0c2a3e212931badbf6398a0cd98393121asewardj /*OUT*/UChar*** sec_names, 3837a5cace0c2a3e212931badbf6398a0cd98393121asewardj /*OUT*/Bool* isText, 3838a5cace0c2a3e212931badbf6398a0cd98393121asewardj /*OUT*/Bool* isIFunc ) 3839eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3840eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(idx >= 0 && idx < si->symtab_used); 3841a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (avma) *avma = si->symtab[idx].addr; 3842a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (tocptr) *tocptr = si->symtab[idx].tocptr; 3843a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (size) *size = si->symtab[idx].size; 3844a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (pri_name) *pri_name = si->symtab[idx].pri_name; 3845a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (sec_names) *sec_names = si->symtab[idx].sec_names; 3846a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (isText) *isText = si->symtab[idx].isText; 3847a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (isIFunc) *isIFunc = si->symtab[idx].isIFunc; 3848b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 3849b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3850b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3851b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 3852b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- SectKind query functions ---*/ 3853b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 3854b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3855b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Convert a VgSectKind to a string, which must be copied if you want 3856b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to change it. */ 3857b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjconst HChar* VG_(pp_SectKind)( VgSectKind kind ) 3858b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 3859b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj switch (kind) { 3860b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectUnknown: return "Unknown"; 3861b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectText: return "Text"; 3862b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectData: return "Data"; 3863b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectBSS: return "BSS"; 3864b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectGOT: return "GOT"; 3865b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectPLT: return "PLT"; 3866b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectOPD: return "OPD"; 38675706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj case Vg_SectGOTPLT: return "GOTPLT"; 3868b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj default: vg_assert(0); 3869b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3870b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 3871b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3872b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Given an address 'a', make a guess of which section of which object 3873b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj it comes from. If name is non-NULL, then the last n_name-1 3874b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj characters of the object's name is put in name[0 .. n_name-2], and 3875b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj name[n_name-1] is set to zero (guaranteed zero terminated). */ 3876b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3877e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjVgSectKind VG_(DebugInfo_sect_kind)( /*OUT*/UChar* name, SizeT n_name, 3878e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj Addr a) 3879b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 3880b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 3881b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VgSectKind res = Vg_SectUnknown; 3882b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3883b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 3884b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3885b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0) 3886b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)( 3887e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj "addr=%#lx di=%p %s got=%#lx,%ld plt=%#lx,%ld " 3888e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj "data=%#lx,%ld bss=%#lx,%ld\n", 3889a5acac39bf3be7546222b1316faee5ee524be0d1sewardj a, di, di->fsm.filename, 3890b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->got_avma, di->got_size, 3891b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->plt_avma, di->plt_size, 3892b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_avma, di->data_size, 3893b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->bss_avma, di->bss_size); 3894b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3895b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 3896b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_size > 0 3897b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->text_avma && a < di->text_avma + di->text_size) { 3898b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectText; 3899b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3900b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3901b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->data_present 3902b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_size > 0 3903b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->data_avma && a < di->data_avma + di->data_size) { 3904b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectData; 3905b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3906b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3907b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->sdata_present 3908b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_size > 0 3909b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->sdata_avma && a < di->sdata_avma + di->sdata_size) { 3910b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectData; 3911b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3912b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3913b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->bss_present 3914b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_size > 0 3915b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->bss_avma && a < di->bss_avma + di->bss_size) { 3916b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectBSS; 3917b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3918b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 39195706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj if (di->sbss_present 39205706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->sbss_size > 0 39215706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && a >= di->sbss_avma && a < di->sbss_avma + di->sbss_size) { 39225706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj res = Vg_SectBSS; 39235706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj break; 39245706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj } 3925b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->plt_present 3926b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->plt_size > 0 3927b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->plt_avma && a < di->plt_avma + di->plt_size) { 3928b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectPLT; 3929b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3930b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3931b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->got_present 3932b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->got_size > 0 3933b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->got_avma && a < di->got_avma + di->got_size) { 3934b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectGOT; 3935b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3936b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3937092b6268cc4a38ae9ee41d1e3355937536ddc579bart if (di->gotplt_present 3938092b6268cc4a38ae9ee41d1e3355937536ddc579bart && di->gotplt_size > 0 3939092b6268cc4a38ae9ee41d1e3355937536ddc579bart && a >= di->gotplt_avma && a < di->gotplt_avma + di->gotplt_size) { 3940092b6268cc4a38ae9ee41d1e3355937536ddc579bart res = Vg_SectGOTPLT; 3941092b6268cc4a38ae9ee41d1e3355937536ddc579bart break; 3942092b6268cc4a38ae9ee41d1e3355937536ddc579bart } 3943b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->opd_present 3944b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->opd_size > 0 3945b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->opd_avma && a < di->opd_avma + di->opd_size) { 3946b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectOPD; 3947b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3948b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3949b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* we could also check for .eh_frame, if anyone really cares */ 3950b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3951b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3952b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert( (di == NULL && res == Vg_SectUnknown) 3953b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || (di != NULL && res != Vg_SectUnknown) ); 3954b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3955b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (name) { 3956b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3957b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_name >= 8); 3958b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3959a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (di && di->fsm.filename) { 3960b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int i, j; 3961a5acac39bf3be7546222b1316faee5ee524be0d1sewardj Int fnlen = VG_(strlen)(di->fsm.filename); 3962b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int start_at = 1 + fnlen - n_name; 3963b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (start_at < 0) start_at = 0; 3964b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(start_at < fnlen); 3965b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj i = start_at; j = 0; 3966b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 3967d5dea1dabc523d3f96bafd52ae9586abd8797416bart vg_assert(j >= 0 && j < n_name); 3968b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(i >= 0 && i <= fnlen); 3969a5acac39bf3be7546222b1316faee5ee524be0d1sewardj name[j] = di->fsm.filename[i]; 3970a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (di->fsm.filename[i] == 0) break; 3971b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj i++; j++; 3972b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3973d5dea1dabc523d3f96bafd52ae9586abd8797416bart vg_assert(i == fnlen); 3974b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 3975b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)(name, n_name, "%s", "???"); 3976b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3977b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3978b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj name[n_name-1] = 0; 3979b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3980b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3981b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return res; 3982b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3983eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3984eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3985eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 3986eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- end ---*/ 3987eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 3988