debuginfo.c revision 588adeffafa8102adcfa7a1c035ae272b35cf86d
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 119f207460d70d38c46c9e81996a3dcdf90961c6dbnjn Copyright (C) 2000-2009 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" 34eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_threadstate.h" 35b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_debuginfo.h" /* self */ 36eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_demangle.h" 37eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_libcbase.h" 38eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_libcassert.h" 39eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_libcprint.h" 40b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_libcfile.h" 41d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj#include "pub_core_seqmatch.h" 42eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_options.h" 43b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_redir.h" // VG_(redir_notify_{new,delete}_SegInfo) 44eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_aspacemgr.h" 45b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_machine.h" // VG_PLAT_USES_PPCTOC 4672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj#include "pub_core_xarray.h" 47b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_oset.h" 486882443ef154bca367bc591287de641e43a9e108njn#include "pub_core_stacktrace.h" // VG_(get_StackTrace) XXX: circular dependency 49f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#include "pub_core_ume.h" 50b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 51b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_misc.h" /* dinfo_zalloc/free */ 52b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_d3basics.h" /* ML_(pp_GX) */ 53b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_tytypes.h" 54eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "priv_storage.h" 55eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "priv_readdwarf.h" 56eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "priv_readstabs.h" 574ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#if defined(VGO_linux) 584ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# include "priv_readelf.h" 59b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# include "priv_readdwarf3.h" 60c8259b85b701d25d72aabe9dc0a8154517f96913sewardj# include "priv_readpdb.h" 614ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#elif defined(VGO_aix5) 624ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# include "pub_core_debuglog.h" 634ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# include "pub_core_libcproc.h" 644ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# include "pub_core_libcfile.h" 654ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# include "priv_readxcoff.h" 66f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(VGO_darwin) 67f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# include "priv_readmacho.h" 68f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# include "priv_readpdb.h" 694ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#endif 70eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 71c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 72c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/*------------------------------------------------------------*/ 73c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/*--- The _svma / _avma / _image / _bias naming scheme ---*/ 74c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/*------------------------------------------------------------*/ 75c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 76c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/* JRS 11 Jan 07: I find the different kinds of addresses involved in 77c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj debuginfo reading confusing. Recently I arrived at some 78c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj terminology which makes it clearer (to me, at least). There are 3 79c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj kinds of address used in the debuginfo reading process: 80c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 81c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj stated VMAs - the address where (eg) a .so says a symbol is, that 82c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj is, what it tells you if you consider the .so in 83c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj isolation 84c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 85c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj actual VMAs - the address where (eg) said symbol really wound up 86c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj after the .so was mapped into memory 87c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 88c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj image addresses - pointers into the copy of the .so (etc) 89c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj transiently mmaped aboard whilst we read its info 90c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 91c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj Additionally I use the term 'bias' to denote the difference 92c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj between stated and actual VMAs for a given entity. 93c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 94c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj This terminology is not used consistently, but a start has been 95c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj made. readelf.c and the call-frame info reader in readdwarf.c now 96c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj use it. Specifically, various variables and structure fields have 97f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj been annotated with _avma / _svma / _image / _bias. In places _img 98f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj is used instead of _image for the sake of brevity. 99c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj*/ 100c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 101c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 102eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 103f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- fwdses ---*/ 104f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*------------------------------------------------------------*/ 105f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 106f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic void cfsi_cache__invalidate ( void ); 107f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 108f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 109f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*------------------------------------------------------------*/ 110eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Root structure ---*/ 111eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 112eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 113b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* The root structure for the entire debug info system. It is a 114b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj linked list of DebugInfos. */ 115b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic DebugInfo* debugInfo_list = NULL; 116b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Find 'di' in the debugInfo_list and move it one step closer the the 119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj front of the list, so as to make subsequent searches for it 120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj cheaper. When used in a controlled way, makes a major improvement 121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in some DebugInfo-search-intensive situations, most notably stack 122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj unwinding on amd64-linux. */ 123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void move_DebugInfo_one_step_forward ( DebugInfo* di ) 124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo *di0, *di1, *di2; 126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == debugInfo_list) 127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; /* already at head of list */ 128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di != NULL); 129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0 = debugInfo_list; 130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1 = NULL; 131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2 = NULL; 132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 == NULL || di0 == di) break; 134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2 = di1; 135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1 = di0; 136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0 = di0->next; 137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di0 == di); 139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 != NULL && di1 != NULL && di2 != NULL) { 140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* tmp; 141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* di0 points to di, di1 to its predecessor, and di2 to di1's 142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj predecessor. Swap di0 and di1, that is, move di0 one step 143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj closer to the start of the list. */ 144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di2->next == di1); 145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di1->next == di0); 146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj tmp = di0->next; 147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->next = di0; 148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0->next = di1; 149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1->next = tmp; 150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 != NULL && di1 != NULL && di2 == NULL) { 153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* it's second in the list. */ 154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(debugInfo_list == di1); 155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di1->next == di0); 156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1->next = di0->next; 157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0->next = di1; 158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debugInfo_list = di0; 159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 161eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 162eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 163eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 164eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Notification (acquire/discard) helpers ---*/ 165eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 166eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Gives out unique abstract handles for allocated DebugInfos. See 1689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj comment in priv_storage.h, declaration of struct _DebugInfo, for 1699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj details. */ 1709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic ULong handle_counter = 1; 1719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 172b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Allocate and zero out a new DebugInfo record. */ 173eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjstatic 174b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjDebugInfo* alloc_DebugInfo( const UChar* filename, 175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj const UChar* memname ) 176eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool traceme; 178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 179eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 180f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj vg_assert(filename); 181f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj 1829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di = ML_(dinfo_zalloc)("di.debuginfo.aDI.1", sizeof(DebugInfo)); 1839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->handle = handle_counter++; 1849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->filename = ML_(dinfo_strdup)("di.debuginfo.aDI.2", filename); 1859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->memname = memname ? ML_(dinfo_strdup)("di.debuginfo.aDI.3", memname) 186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj : NULL; 187eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 188f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj /* Everything else -- pointers, sizes, arrays -- is zeroed by calloc. 189f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj Now set up the debugging-output flags. */ 190f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj traceme 191f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj = VG_(string_match)( VG_(clo_trace_symtab_patt), filename ) 192f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj || (memname && VG_(string_match)( VG_(clo_trace_symtab_patt), 193f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj memname )); 194f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj if (traceme) { 195b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->trace_symtab = VG_(clo_trace_symtab); 196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->trace_cfi = VG_(clo_trace_cfi); 197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_syms = VG_(clo_debug_dump_syms); 198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_line = VG_(clo_debug_dump_line); 199b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_frames = VG_(clo_debug_dump_frames); 200f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj } 201f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj 202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 203eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 204eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 205eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Free a DebugInfo, and also all the stuff hanging off it. */ 207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void free_DebugInfo ( DebugInfo* di ) 208eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 20959a2d18d0ddfa241850017252b0804d469187d79sewardj Word i, j, n; 210eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj struct strchunk *chunk, *next; 2119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ent; 21259a2d18d0ddfa241850017252b0804d469187d79sewardj GExpr* gexpr; 213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di != NULL); 215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->filename) ML_(dinfo_free)(di->filename); 216b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->symtab) ML_(dinfo_free)(di->symtab); 217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->loctab) ML_(dinfo_free)(di->loctab); 218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->cfsi) ML_(dinfo_free)(di->cfsi); 219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->cfsi_exprs) VG_(deleteXA)(di->cfsi_exprs); 220c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (di->fpo) ML_(dinfo_free)(di->fpo); 221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (chunk = di->strchunks; chunk != NULL; chunk = next) { 223eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj next = chunk->next; 224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(dinfo_free)(chunk); 225b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 226b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Delete the two admin arrays. These lists exist primarily so 2289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj that we can visit each object exactly once when we need to 2299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj delete them. */ 2309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (di->admin_tyents) { 2319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n = VG_(sizeXA)(di->admin_tyents); 23259a2d18d0ddfa241850017252b0804d469187d79sewardj for (i = 0; i < n; i++) { 2339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ent = (TyEnt*)VG_(indexXA)(di->admin_tyents, i); 2349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Dump anything hanging off this ent */ 2359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(TyEnt__make_EMPTY)(ent); 23659a2d18d0ddfa241850017252b0804d469187d79sewardj } 2379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(deleteXA)(di->admin_tyents); 2389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->admin_tyents = NULL; 239eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 24059a2d18d0ddfa241850017252b0804d469187d79sewardj 24159a2d18d0ddfa241850017252b0804d469187d79sewardj if (di->admin_gexprs) { 24259a2d18d0ddfa241850017252b0804d469187d79sewardj n = VG_(sizeXA)(di->admin_gexprs); 24359a2d18d0ddfa241850017252b0804d469187d79sewardj for (i = 0; i < n; i++) { 24459a2d18d0ddfa241850017252b0804d469187d79sewardj gexpr = *(GExpr**)VG_(indexXA)(di->admin_gexprs, i); 24559a2d18d0ddfa241850017252b0804d469187d79sewardj ML_(dinfo_free)(gexpr); 24659a2d18d0ddfa241850017252b0804d469187d79sewardj } 24759a2d18d0ddfa241850017252b0804d469187d79sewardj VG_(deleteXA)(di->admin_gexprs); 24859a2d18d0ddfa241850017252b0804d469187d79sewardj di->admin_gexprs = NULL; 249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 251b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Dump the variable info. This is kinda complex: we must take 252b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj care not to free items which reside in either the admin lists 253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (as we have just freed them) or which reside in the DebugInfo's 254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj string table. */ 255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->varinfo) { 256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = 0; i < VG_(sizeXA)(di->varinfo); i++) { 257b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* scope = *(OSet**)VG_(indexXA)(di->varinfo, i); 258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!scope) continue; 259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* iterate over all entries in 'scope' */ 260b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(OSetGen_ResetIter)(scope); 261b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* arange = VG_(OSetGen_Next)(scope); 263b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!arange) break; 264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* for each var in 'arange' */ 265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->vars); 266b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < VG_(sizeXA)( arange->vars ); j++) { 267b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)(arange->vars,j); 268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var); 269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Nothing to free in var: all the pointer fields refer 270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to stuff either on an admin list, or in 271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj .strchunks */ 272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)(arange->vars); 274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Don't free arange itself, as OSetGen_Destroy does 275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj that */ 276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(OSetGen_Destroy)(scope); 278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)(di->varinfo); 280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(dinfo_free)(di); 283eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 284eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 285eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* 'si' is a member of debugInfo_list. Find it, remove it from the 287eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj list, notify m_redir that this has happened, and free all storage 288eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj reachable from it. 289eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void discard_DebugInfo ( DebugInfo* di ) 291eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2924ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# if defined(VGP_ppc32_aix5) 2934ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj HChar* reason = "__unload"; 2944ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# elif defined(VGP_ppc64_aix5) 2954ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj HChar* reason = "kunload64"; 2964ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# else 2974ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj HChar* reason = "munmap"; 2984ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# endif 2994ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 300b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo** prev_next_ptr = &debugInfo_list; 301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* curr = debugInfo_list; 302eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 303eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj while (curr) { 304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (curr == di) { 305b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Found it; remove from list and free it. */ 30633e4e7eaab263cea956700f56f007ab26c39eab4sewardj if (curr->have_dinfo 30733e4e7eaab263cea956700f56f007ab26c39eab4sewardj && (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))) 308eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(message)(Vg_DebugMsg, 309738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Discarding syms at %#lx-%#lx in %s due to %s()\n", 310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_avma, 311b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_avma + di->text_size, 3124ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj curr->filename ? curr->filename : (UChar*)"???", 3134ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj reason); 314eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(*prev_next_ptr == curr); 315eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *prev_next_ptr = curr->next; 31633e4e7eaab263cea956700f56f007ab26c39eab4sewardj if (curr->have_dinfo) 31733e4e7eaab263cea956700f56f007ab26c39eab4sewardj VG_(redir_notify_delete_DebugInfo)( curr ); 318b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj free_DebugInfo(curr); 319eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return; 320eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 321eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj prev_next_ptr = &curr->next; 322eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj curr = curr->next; 323eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 324eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Not found. */ 326eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 327eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 328eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Repeatedly scan debugInfo_list, looking for DebugInfos with text 330b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj AVMAs intersecting [start,start+length), and call discard_DebugInfo 331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to get rid of them. This modifies the list, hence the multiple 332f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj iterations. Returns True iff any such DebugInfos were found. 333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/ 334f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic Bool discard_syms_in_range ( Addr start, SizeT length ) 335eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 336f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool anyFound = False; 337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool found; 338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* curr; 339eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 340eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj while (True) { 341eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj found = False; 342eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj curr = debugInfo_list; 344eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj while (True) { 345eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (curr == NULL) 346eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; 347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (curr->text_present 348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && curr->text_size > 0 349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && (start+length - 1 < curr->text_avma 350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || curr->text_avma + curr->text_size - 1 < start)) { 351eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* no overlap */ 352eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 353eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj found = True; 354eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; 355eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 356eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj curr = curr->next; 357eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 358eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 359eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (!found) break; 360f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj anyFound = True; 361b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_DebugInfo( curr ); 362eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 363f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 364f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return anyFound; 365eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 366eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 367eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 368b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Does [s1,+len1) overlap [s2,+len2) ? Note: does not handle 369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj wraparound at the end of the address space -- just asserts in that 370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case. */ 371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Bool ranges_overlap (Addr s1, SizeT len1, Addr s2, SizeT len2 ) 372eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr e1, e2; 374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (len1 == 0 || len2 == 0) 375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj e1 = s1 + len1 - 1; 377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj e2 = s2 + len2 - 1; 378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Assert that we don't have wraparound. If we do it would imply 379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj that file sections are getting mapped around the end of the 380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj address space, which sounds unlikely. */ 381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(s1 <= e1); 382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(s2 <= e2); 383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (e1 < s2 || e2 < s1) return False; 384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 386eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 387eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Do the basic rx_ and rw_ mappings of the two DebugInfos overlap in 389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj any way? */ 390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Bool do_DebugInfos_overlap ( DebugInfo* di1, DebugInfo* di2 ) 391b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 392b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di1); 393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di2); 394eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di1->have_rx_map && di2->have_rx_map 396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ranges_overlap(di1->rx_map_avma, di1->rx_map_size, 397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->rx_map_avma, di2->rx_map_size)) 398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 399eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di1->have_rx_map && di2->have_rw_map 401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ranges_overlap(di1->rx_map_avma, di1->rx_map_size, 402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->rw_map_avma, di2->rw_map_size)) 403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di1->have_rw_map && di2->have_rx_map 406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ranges_overlap(di1->rw_map_avma, di1->rw_map_size, 407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->rx_map_avma, di2->rx_map_size)) 408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 410b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di1->have_rw_map && di2->have_rw_map 411b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ranges_overlap(di1->rw_map_avma, di1->rw_map_size, 412b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->rw_map_avma, di2->rw_map_size)) 413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 414b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Discard all elements of debugInfo_list whose .mark bit is set. 420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/ 421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void discard_marked_DebugInfos ( void ) 422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* curr; 424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj curr = debugInfo_list; 428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!curr) 430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (curr->mark) 432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj curr = curr->next; 434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!curr) break; 437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_DebugInfo( curr ); 438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Discard any elements of debugInfo_list which overlap with diRef. 444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Clearly diRef must have its rx_ and rw_ mapping information set to 445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj something sane. */ 446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#if defined(VGO_aix5) 447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((unused)) 448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif 449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void discard_DebugInfos_which_overlap_with ( DebugInfo* diRef ) 450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Mark all the DebugInfos in debugInfo_list that need to be 453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj deleted. First, clear all the mark bits; then set them if they 454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj overlap with siRef. Since siRef itself is in this list we at 455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj least expect its own mark bit to be set. */ 456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di; di = di->next) { 457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->mark = do_DebugInfos_overlap( di, diRef ); 458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == diRef) { 459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->mark); 460b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->mark = False; 461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 462eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_marked_DebugInfos(); 464b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 466eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 467b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Find the existing DebugInfo for (memname,filename) or if not found, 468b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj create one. In the latter case memname and filename are strdup'd 469b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj into VG_AR_DINFO, and the new DebugInfo is added to 470b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debugInfo_list. */ 471b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic 472b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjDebugInfo* find_or_create_DebugInfo_for ( UChar* filename, UChar* memname ) 473b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 474b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 475b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(filename); 476b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di; di = di->next) { 477b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->filename); 478b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0==VG_(strcmp)(di->filename, filename) 479b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ( (memname && di->memname) 480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ? 0==VG_(strcmp)(memname, di->memname) 481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj : True )) 482b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 483b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 484b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di) { 485b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di = alloc_DebugInfo(filename, memname); 486b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di); 487b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->next = debugInfo_list; 488b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debugInfo_list = di; 489b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 490b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 491eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 492eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 493eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 494f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Debuginfo reading for 'di' has just been successfully completed. 495f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Check that the invariants stated in 496f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj "Comment_on_IMPORTANT_CFSI_REPRESENTATIONAL_INVARIANTS" in 497f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj priv_storage.h are observed. */ 498f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic void check_CFSI_related_invariants ( DebugInfo* di ) 499f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 500f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo* di2 = NULL; 501f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di); 502f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* This fn isn't called until after debuginfo for this object has 503f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj been successfully read. And that shouldn't happen until we have 504f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj both a r-x and rw- mapping for the object. Hence: */ 505f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->have_rx_map); 506f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->have_rw_map); 507f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* degenerate case: r-x section is empty */ 508f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di->rx_map_size == 0) { 509f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi == NULL); 510f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return; 511f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 512f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* normal case: r-x section is nonempty */ 513f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* invariant (0) */ 514f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->rx_map_size > 0); 515f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* invariant (1) */ 516f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (di2 = debugInfo_list; di2; di2 = di2->next) { 517f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di2 == di) 518f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj continue; 519f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di2->rx_map_size == 0) 520f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj continue; 521f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->rx_map_avma + di->rx_map_size <= di2->rx_map_avma 522f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj || di2->rx_map_avma + di2->rx_map_size <= di->rx_map_avma); 523f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 524f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj di2 = NULL; 525f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* invariant (2) */ 526f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di->cfsi) { 527f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_minavma <= di->cfsi_maxavma); /* duh! */ 528f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_minavma >= di->rx_map_avma); 529f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_maxavma < di->rx_map_avma + di->rx_map_size); 530f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 531f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* invariants (3) and (4) */ 532f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di->cfsi) { 533f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word i; 534f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_used > 0); 535f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_size > 0); 536f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (i = 0; i < di->cfsi_used; i++) { 537f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DiCfSI* cfsi = &di->cfsi[i]; 538f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsi->len > 0); 539f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsi->base >= di->cfsi_minavma); 540f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsi->base + cfsi->len - 1 <= di->cfsi_maxavma); 541f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (i > 0) { 542f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DiCfSI* cfsip = &di->cfsi[i-1]; 543f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsip->base + cfsip->len <= cfsi->base); 544f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 545f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 546f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 547f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_used == 0); 548f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_size == 0); 549f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 550f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 551f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 552f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 553f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--------------------------------------------------------------*/ 554f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- ---*/ 555f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- TOP LEVEL: INITIALISE THE DEBUGINFO SYSTEM ---*/ 556f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- ---*/ 557f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--------------------------------------------------------------*/ 558f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 559f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjvoid VG_(di_initialise) ( void ) 560f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 561f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* There's actually very little to do here, since everything 562f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj centers around the DebugInfos in debugInfo_list, they are 563f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj created and destroyed on demand, and each one is treated more or 564f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj less independently. */ 565f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(debugInfo_list == NULL); 566f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 567f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* flush the CFI fast query cache. */ 568f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi_cache__invalidate(); 569f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 570f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 571f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 5724ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--------------------------------------------------------------*/ 5734ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- ---*/ 5744ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- TOP LEVEL: NOTIFICATION (ACQUIRE/DISCARD INFO) (LINUX) ---*/ 5754ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- ---*/ 5764ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--------------------------------------------------------------*/ 5774ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 578f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VGO_linux) || defined(VGO_darwin) 579eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 580eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* The debug info system is driven by notifications that a text 581eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj segment has been mapped in, or unmapped. When that happens it 582eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj tries to acquire/discard whatever info is available for the 583eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj corresponding object. This section contains the notification 584eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj handlers. */ 585eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 586eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Notify the debuginfo system about a new mapping. This is the way 587eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj new debug information gets loaded. If allow_SkFileV is True, it 588eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj will try load debug info if the mapping at 'a' belongs to Valgrind; 589eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj whereas normally (False) it will not do that. This allows us to 590eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj carefully control when the thing will read symbols from the 5919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Valgrind executable itself. 5929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 5939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj If a call to VG_(di_notify_mmap) causes debug info to be read, then 5949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj the returned ULong is an abstract handle which can later be used to 5959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj refer to the debuginfo read as a result of this specific mapping, 5969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj in later queries to m_debuginfo. In this case the handle value 5979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj will be one or above. If the returned value is zero, no debug info 5989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj was read. */ 599eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 6009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV ) 601eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 6024ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj NSegment const * seg; 603b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj HChar* filename; 604b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool ok, is_rx_map, is_rw_map; 605b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 6069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ULong di_handle; 607b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj SysRes fd; 608b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int nread; 609b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj HChar buf1k[1024]; 610b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool debug = False; 611ec61b6509566cf36ab3968d69226cecf177cb0fesewardj SysRes statres; 612ec61b6509566cf36ab3968d69226cecf177cb0fesewardj struct vg_stat statbuf; 613b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* In short, figure out if this mapping is of interest to us, and 615b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if so, try to guess what ld.so is doing and when/if we should 616b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj read debug info. */ 617b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg = VG_(am_find_nsegment)(a); 618b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(seg); 619eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 620b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 621a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("di_notify_mmap-1: %#lx-%#lx %c%c%c\n", 622b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->start, seg->end, 623b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->hasR ? 'r' : '-', 624b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->hasW ? 'w' : '-',seg->hasX ? 'x' : '-' ); 625eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 626b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* guaranteed by aspacemgr-linux.c, sane_NSegment() */ 627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(seg->end > seg->start); 628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ignore non-file mappings */ 630b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( ! (seg->kind == SkFileC 631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || (seg->kind == SkFileV && allow_SkFileV)) ) 6329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 633b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 634b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* If the file doesn't have a name, we're hosed. Give up. */ 635b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj filename = VG_(am_get_filename)( (NSegment*)seg ); 636b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!filename) 6379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 638b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 639b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 640b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("di_notify_mmap-2: %s\n", filename); 641b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 642ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* Only try to read debug information from regular files. */ 64315728ab41ea41bf731dcc74ac68354550ced2189bart statres = VG_(stat)(filename, &statbuf); 644ec61b6509566cf36ab3968d69226cecf177cb0fesewardj 645ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* stat dereferences symlinks, so we don't expect it to succeed and 646ec61b6509566cf36ab3968d69226cecf177cb0fesewardj yet produce something that is a symlink. */ 6479c20ece00e07304f66da5f43b87ec45bc9c04550njn vg_assert(sr_isError(statres) || ! VKI_S_ISLNK(statbuf.mode)); 648ec61b6509566cf36ab3968d69226cecf177cb0fesewardj 649ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* Don't let the stat call fail silently. Filter out some known 650ec61b6509566cf36ab3968d69226cecf177cb0fesewardj sources of noise before complaining, though. */ 651cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(statres)) { 652ec61b6509566cf36ab3968d69226cecf177cb0fesewardj DebugInfo fake_di; 653ec61b6509566cf36ab3968d69226cecf177cb0fesewardj Bool quiet = VG_(strstr)(filename, "/var/run/nscd/") != NULL; 654e025eca1d49cdfe5a8cb58ab495763434280333asewardj if (!quiet && VG_(clo_verbosity) > 1) { 655ec61b6509566cf36ab3968d69226cecf177cb0fesewardj VG_(memset)(&fake_di, 0, sizeof(fake_di)); 656ec61b6509566cf36ab3968d69226cecf177cb0fesewardj fake_di.filename = filename; 657ec61b6509566cf36ab3968d69226cecf177cb0fesewardj ML_(symerr)(&fake_di, True, "failed to stat64/stat this file"); 658ec61b6509566cf36ab3968d69226cecf177cb0fesewardj } 6599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 6602ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj } 6612ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj 662ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* Finally, the point of all this stattery: if it's not a regular file, 663ec61b6509566cf36ab3968d69226cecf177cb0fesewardj don't try to read debug info from it. */ 6649c20ece00e07304f66da5f43b87ec45bc9c04550njn if (! VKI_S_ISREG(statbuf.mode)) 6659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 666ec61b6509566cf36ab3968d69226cecf177cb0fesewardj 667ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* no uses of statbuf below here. */ 66815728ab41ea41bf731dcc74ac68354550ced2189bart 669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Now we have to guess if this is a text-like mapping, a data-like 670b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj mapping, neither or both. The rules are: 671b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 672b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj text if: x86-linux r and x 673b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj other-linux r and x and not w 674b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 675b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data if: x86-linux r and w 676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj other-linux r and w and not x 677b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 678b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Background: On x86-linux, objects are typically mapped twice: 679eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 680eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1b8fb000-1b8ff000 r-xp 00000000 08:02 4471477 vgpreload_memcheck.so 681eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1b8ff000-1b900000 rw-p 00004000 08:02 4471477 vgpreload_memcheck.so 682eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 683eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj whereas ppc32-linux mysteriously does this: 684eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 685eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118a6000-118ad000 r-xp 00000000 08:05 14209428 vgpreload_memcheck.so 686eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118ad000-118b6000 ---p 00007000 08:05 14209428 vgpreload_memcheck.so 687eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118b6000-118bd000 rwxp 00000000 08:05 14209428 vgpreload_memcheck.so 688eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 689eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj The third mapping should not be considered to have executable 690eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj code in. Therefore a test which works for both is: r and x and 691eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj NOT w. Reading symbols from the rwx segment -- which overlaps 692eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj the r-x segment in the file -- causes the redirection mechanism 693eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj to redirect to addresses in that third segment, which is wrong 694eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj and causes crashes. 695eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 696eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj JRS 28 Dec 05: unfortunately icc 8.1 on x86 has been seen to 697eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj produce executables with a single rwx segment rather than a 698eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj (r-x,rw-) pair. That means the rules have to be modified thusly: 699eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 700eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj x86-linux: consider if r and x 701b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj all others: consider if r and x and not w 702eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj */ 703b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = False; 704b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = False; 705f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# if defined(VGA_x86) 706b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = seg->hasR && seg->hasX; 707b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = seg->hasR && seg->hasW; 708f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# elif defined(VGA_amd64) || defined(VGA_ppc32) || defined(VGA_ppc64) 709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = seg->hasR && seg->hasX && !seg->hasW; 710b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = seg->hasR && seg->hasW && !seg->hasX; 711eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# else 712b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# error "Unknown platform" 713eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# endif 714eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 715b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 716b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("di_notify_mmap-3: is_rx_map %d, is_rw_map %d\n", 717b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (Int)is_rx_map, (Int)is_rw_map); 718eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* If it is neither text-ish nor data-ish, we're not interested. */ 720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!(is_rx_map || is_rw_map)) 7219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 722eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 7235a5eec0923d55afc94165721d25125d5fc8f24d8sewardj /* Peer at the first few bytes of the file, to see if it is an ELF */ 7245a5eec0923d55afc94165721d25125d5fc8f24d8sewardj /* object file. Ignore the file if we do not have read permission. */ 7255a5eec0923d55afc94165721d25125d5fc8f24d8sewardj VG_(memset)(buf1k, 0, sizeof(buf1k)); 7265a5eec0923d55afc94165721d25125d5fc8f24d8sewardj fd = VG_(open)( filename, VKI_O_RDONLY, 0 ); 727cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(fd)) { 728cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_Err(fd) != VKI_EACCES) { 7295a5eec0923d55afc94165721d25125d5fc8f24d8sewardj DebugInfo fake_di; 7305a5eec0923d55afc94165721d25125d5fc8f24d8sewardj VG_(memset)(&fake_di, 0, sizeof(fake_di)); 7315a5eec0923d55afc94165721d25125d5fc8f24d8sewardj fake_di.filename = filename; 7325a5eec0923d55afc94165721d25125d5fc8f24d8sewardj ML_(symerr)(&fake_di, True, "can't open file to inspect ELF header"); 7335a5eec0923d55afc94165721d25125d5fc8f24d8sewardj } 7345a5eec0923d55afc94165721d25125d5fc8f24d8sewardj return 0; 7355a5eec0923d55afc94165721d25125d5fc8f24d8sewardj } 736cda2f0fbda4c4b2644babc830244be8aed95de1dnjn nread = VG_(read)( sr_Res(fd), buf1k, sizeof(buf1k) ); 737cda2f0fbda4c4b2644babc830244be8aed95de1dnjn VG_(close)( sr_Res(fd) ); 7385a5eec0923d55afc94165721d25125d5fc8f24d8sewardj 7395a5eec0923d55afc94165721d25125d5fc8f24d8sewardj if (nread == 0) 7405a5eec0923d55afc94165721d25125d5fc8f24d8sewardj return 0; 7415a5eec0923d55afc94165721d25125d5fc8f24d8sewardj if (nread < 0) { 7425a5eec0923d55afc94165721d25125d5fc8f24d8sewardj DebugInfo fake_di; 7435a5eec0923d55afc94165721d25125d5fc8f24d8sewardj VG_(memset)(&fake_di, 0, sizeof(fake_di)); 7445a5eec0923d55afc94165721d25125d5fc8f24d8sewardj fake_di.filename = filename; 7455a5eec0923d55afc94165721d25125d5fc8f24d8sewardj ML_(symerr)(&fake_di, True, "can't read file to inspect ELF header"); 7465a5eec0923d55afc94165721d25125d5fc8f24d8sewardj return 0; 7475a5eec0923d55afc94165721d25125d5fc8f24d8sewardj } 7485a5eec0923d55afc94165721d25125d5fc8f24d8sewardj vg_assert(nread > 0 && nread <= sizeof(buf1k) ); 7495a5eec0923d55afc94165721d25125d5fc8f24d8sewardj 7508b68b64759254d514d98328c496cbd88cde4c9a5njn /* We're only interested in mappings of object files. */ 7518b68b64759254d514d98328c496cbd88cde4c9a5njn // Nb: AIX5 doesn't use this file and so isn't represented here. 7528b68b64759254d514d98328c496cbd88cde4c9a5njn#if defined(VGO_linux) 7535a5eec0923d55afc94165721d25125d5fc8f24d8sewardj if (!ML_(is_elf_object_file)( buf1k, (SizeT)nread )) 7545a5eec0923d55afc94165721d25125d5fc8f24d8sewardj return 0; 7558b68b64759254d514d98328c496cbd88cde4c9a5njn#elif defined(VGO_darwin) 756f76d27a697a7b0bf3b84490baf60623fc96a23afnjn if (!ML_(is_macho_object_file)( buf1k, (SizeT)nread )) 757f76d27a697a7b0bf3b84490baf60623fc96a23afnjn return 0; 758f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#else 7598b68b64759254d514d98328c496cbd88cde4c9a5njn# error "unknown OS" 760f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 7615a5eec0923d55afc94165721d25125d5fc8f24d8sewardj 762b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* See if we have a DebugInfo for this filename. If not, 763b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj create one. */ 764b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di = find_or_create_DebugInfo_for( filename, NULL/*membername*/ ); 765b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di); 766b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 767b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (is_rx_map) { 768b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We have a text-like mapping. Note the details. */ 769b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->have_rx_map) { 770b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->have_rx_map = True; 771b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rx_map_avma = a; 772b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rx_map_size = seg->end + 1 - seg->start; 773b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rx_map_foff = seg->offset; 774b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 775b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* FIXME: complain about a second text-like mapping */ 776b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 777b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 778eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 779b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (is_rw_map) { 780b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We have a data-like mapping. Note the details. */ 781b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->have_rw_map) { 782b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->have_rw_map = True; 783b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rw_map_avma = a; 784b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rw_map_size = seg->end + 1 - seg->start; 785b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rw_map_foff = seg->offset; 786b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 787b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* FIXME: complain about a second data-like mapping */ 788b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 789eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 790eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 7919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* If we don't have an rx and rw mapping, or if we already have 7929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj debuginfo for this mapping for whatever reason, go no 7939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj further. */ 7949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if ( ! (di->have_rx_map && di->have_rw_map && !di->have_dinfo) ) 7959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 796b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 7979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok, so, finally, let's try to read the debuginfo. */ 7989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(di->filename); 7999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("\n"); 8009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("------ start ELF OBJECT " 8019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj "------------------------------\n"); 8029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("------ name = %s\n", di->filename); 8039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("\n"); 8049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 8059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* We're going to read symbols and debug info for the avma 8069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ranges [rx_map_avma, +rx_map_size) and [rw_map_avma, 8079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj +rw_map_size). First get rid of any other DebugInfos which 8089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj overlap either of those ranges (to avoid total confusion). */ 8099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj discard_DebugInfos_which_overlap_with( di ); 8109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 8119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* .. and acquire new info. */ 8128b68b64759254d514d98328c496cbd88cde4c9a5njn // Nb: AIX5 doesn't use this file and so isn't represented here. 8138b68b64759254d514d98328c496cbd88cde4c9a5njn#if defined(VGO_linux) 8149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ok = ML_(read_elf_debug_info)( di ); 8158b68b64759254d514d98328c496cbd88cde4c9a5njn#elif defined(VGO_darwin) 816f76d27a697a7b0bf3b84490baf60623fc96a23afnjn ok = ML_(read_macho_debug_info)( di ); 817f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#else 8188b68b64759254d514d98328c496cbd88cde4c9a5njn# error "unknown OS" 819f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 8209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 8219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (ok) { 8229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 8239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("\n------ Canonicalising the " 8249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj "acquired info ------\n"); 825f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* invalidate the CFI unwind cache. */ 826f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi_cache__invalidate(); 8279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* prepare read data for use */ 8289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(canonicaliseTables)( di ); 8299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* notify m_redir about it */ 8309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("\n------ Notifying m_redir ------\n"); 8319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(redir_notify_new_DebugInfo)( di ); 8329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Note that we succeeded */ 8339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->have_dinfo = True; 8349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(di->handle > 0); 8359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di_handle = di->handle; 836f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Check invariants listed in 837f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Comment_on_IMPORTANT_REPRESENTATIONAL_INVARIANTS in 838f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj priv_storage.h. */ 839f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj check_CFSI_related_invariants(di); 840b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 8419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } else { 8429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("\n------ ELF reading failed ------\n"); 8439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Something went wrong (eg. bad ELF file). Should we delete 8449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj this DebugInfo? No - it contains info on the rw/rx 8459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj mappings, at least. */ 8469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di_handle = 0; 847f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->have_dinfo == False); 8489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 849eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 8509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("\n"); 8519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("------ name = %s\n", di->filename); 8529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("------ end ELF OBJECT " 8539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj "------------------------------\n"); 8549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("\n"); 855eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 8569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return di_handle; 857eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 858eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 859eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 860eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Unmap is simpler - throw away any SegInfos intersecting 861eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj [a, a+len). */ 862eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjvoid VG_(di_notify_munmap)( Addr a, SizeT len ) 863eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 864f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool anyFound; 865a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart if (0) VG_(printf)("DISCARD %#lx %#lx\n", a, a+len); 866f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj anyFound = discard_syms_in_range(a, len); 867f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (anyFound) 868f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi_cache__invalidate(); 869eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 870eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 871eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 872eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Uh, this doesn't do anything at all. IIRC glibc (or ld.so, I don't 873eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj remember) does a bunch of mprotects on itself, and if we follow 874eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj through here, it causes the debug info for that object to get 875eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj discarded. */ 876eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjvoid VG_(di_notify_mprotect)( Addr a, SizeT len, UInt prot ) 877eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 878eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool exe_ok = toBool(prot & VKI_PROT_EXEC); 879f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# if defined(VGA_x86) 880eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj exe_ok = exe_ok || toBool(prot & VKI_PROT_READ); 881eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# endif 882f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && !exe_ok) { 883f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool anyFound = discard_syms_in_range(a, len); 884f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (anyFound) 885f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi_cache__invalidate(); 886f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 887eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 888eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 889c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--------- PDB (windows debug info) reading --------- */ 890c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 891c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/* this should really return ULong, as per VG_(di_notify_mmap). */ 892c8259b85b701d25d72aabe9dc0a8154517f96913sewardjvoid VG_(di_notify_pdb_debuginfo)( Int fd_obj, Addr avma_obj, 893c8259b85b701d25d72aabe9dc0a8154517f96913sewardj SizeT total_size, 894c8259b85b701d25d72aabe9dc0a8154517f96913sewardj PtrdiffT unknown_purpose__reloc ) 895c8259b85b701d25d72aabe9dc0a8154517f96913sewardj{ 896c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Int r, sz_exename; 897c8259b85b701d25d72aabe9dc0a8154517f96913sewardj ULong obj_mtime, pdb_mtime; 898c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Char exename[VKI_PATH_MAX]; 899c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Char* pdbname = NULL; 900c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Char* dot; 901c8259b85b701d25d72aabe9dc0a8154517f96913sewardj SysRes sres; 902c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Int fd_pdbimage; 903c8259b85b701d25d72aabe9dc0a8154517f96913sewardj SizeT n_pdbimage; 904c8259b85b701d25d72aabe9dc0a8154517f96913sewardj struct vg_stat stat_buf; 905c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 906c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) { 907738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "\n"); 908c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(message)(Vg_UserMsg, 909c8259b85b701d25d72aabe9dc0a8154517f96913sewardj "LOAD_PDB_DEBUGINFO(fd=%d, avma=%#lx, total_size=%lu, " 910738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "uu_reloc=%#lx)\n", 911c8259b85b701d25d72aabe9dc0a8154517f96913sewardj fd_obj, avma_obj, total_size, unknown_purpose__reloc 912c8259b85b701d25d72aabe9dc0a8154517f96913sewardj ); 913c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 914c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 915c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* 'fd' refers to the .exe/.dll we're dealing with. Get its modification 916c8259b85b701d25d72aabe9dc0a8154517f96913sewardj time into obj_mtime. */ 917c8259b85b701d25d72aabe9dc0a8154517f96913sewardj r = VG_(fstat)(fd_obj, &stat_buf); 918c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (r == -1) 919c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; /* stat failed ?! */ 920c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(r == 0); 9219c20ece00e07304f66da5f43b87ec45bc9c04550njn obj_mtime = stat_buf.mtime; 922c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 923c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* and get its name into exename[]. */ 924c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(VKI_PATH_MAX > 100); /* to ensure /proc/self/fd/%d is safe */ 925c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(memset)(exename, 0, sizeof(exename)); 926c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(sprintf)(exename, "/proc/self/fd/%d", fd_obj); 927c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* convert exename from a symlink to real name .. overwrites the 928c8259b85b701d25d72aabe9dc0a8154517f96913sewardj old contents of the buffer. Ick. */ 929c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sz_exename = VG_(readlink)(exename, exename, sizeof(exename)-2 ); 930c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (sz_exename == -1) 931c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; /* readlink failed ?! */ 932c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(sz_exename >= 0 && sz_exename < sizeof(exename)); 933c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(exename[sizeof(exename)-1] == 0); 934c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 935c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) { 936738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: objname: %s\n", exename); 937c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 938c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 939c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Try to find a matching PDB file from which to read debuginfo. 940c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Windows PE files have symbol tables and line number information, 941c8259b85b701d25d72aabe9dc0a8154517f96913sewardj but MSVC doesn't seem to use them. */ 942c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Why +5 ? Because in the worst case, we could find a dot as the 943c8259b85b701d25d72aabe9dc0a8154517f96913sewardj last character of pdbname, and we'd then put "pdb" right after 944c8259b85b701d25d72aabe9dc0a8154517f96913sewardj it, hence extending it a bit. */ 945c8259b85b701d25d72aabe9dc0a8154517f96913sewardj pdbname = ML_(dinfo_zalloc)("di.debuginfo.lpd1", sz_exename+5); 946c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(strcpy)(pdbname, exename); 947c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(pdbname[sz_exename+5-1] == 0); 948c8259b85b701d25d72aabe9dc0a8154517f96913sewardj dot = VG_(strrchr)(pdbname, '.'); 949c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (!dot) 950c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; /* there's no dot in the exe's name ?! */ 951c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (dot[1] == 0) 952c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; /* hmm, path ends in "." */ 953c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 954c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if ('A' <= dot[1] && dot[1] <= 'Z') 955c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(strcpy)(dot, ".PDB"); 956c8259b85b701d25d72aabe9dc0a8154517f96913sewardj else 957c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(strcpy)(dot, ".pdb"); 958c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 959c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(pdbname[sz_exename+5-1] == 0); 960c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 961c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* See if we can find it, and check it's in-dateness. */ 962c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sres = VG_(stat)(pdbname, &stat_buf); 963cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) { 964738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "Warning: Missing or un-stat-able %s\n", 965c8259b85b701d25d72aabe9dc0a8154517f96913sewardj pdbname); 966c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) 967738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: missing: %s\n", pdbname); 968c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; 969c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 9709c20ece00e07304f66da5f43b87ec45bc9c04550njn pdb_mtime = stat_buf.mtime; 971c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (pdb_mtime < obj_mtime ) { 972c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* PDB file is older than PE file - ignore it or we will either 973c8259b85b701d25d72aabe9dc0a8154517f96913sewardj (a) print wrong stack traces or more likely (b) crash. */ 974738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, 975738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Warning: Ignoring %s since it is older than %s\n", 976738856f99eea33d86ce91dcb1d6cd5b151e307casewardj pdbname, exename); 977c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; 978c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 979c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 980c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sres = VG_(open)(pdbname, VKI_O_RDONLY, 0); 981cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) { 982738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "Warning: Can't open %s\n", pdbname); 983c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; 984c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 985c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 986c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Looks promising; go on to try and read stuff from it. */ 987cda2f0fbda4c4b2644babc830244be8aed95de1dnjn fd_pdbimage = sr_Res(sres); 9889c20ece00e07304f66da5f43b87ec45bc9c04550njn n_pdbimage = stat_buf.size; 989c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sres = VG_(am_mmap_file_float_valgrind)( n_pdbimage, VKI_PROT_READ, 990c8259b85b701d25d72aabe9dc0a8154517f96913sewardj fd_pdbimage, 0 ); 991cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) { 992c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(close)(fd_pdbimage); 993c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; 994c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 995c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 996c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) 997738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: pdbname: %s\n", pdbname); 998c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 999c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* play safe; always invalidate the CFI cache. I don't know if 1000c8259b85b701d25d72aabe9dc0a8154517f96913sewardj this is necessary, but anyway .. */ 1001c8259b85b701d25d72aabe9dc0a8154517f96913sewardj cfsi_cache__invalidate(); 1002c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* dump old info for this range, if any */ 1003c8259b85b701d25d72aabe9dc0a8154517f96913sewardj discard_syms_in_range( avma_obj, total_size ); 1004c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1005cda2f0fbda4c4b2644babc830244be8aed95de1dnjn { void* pdbimage = (void*)sr_Res(sres); 1006c8259b85b701d25d72aabe9dc0a8154517f96913sewardj DebugInfo* di = find_or_create_DebugInfo_for(exename, NULL/*membername*/ ); 1007c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1008c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* this di must be new, since we just nuked any old stuff in the range */ 1009c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(di && !di->have_rx_map && !di->have_rw_map); 1010c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(!di->have_dinfo); 1011c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1012c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* don't set up any of the di-> fields; let 1013c8259b85b701d25d72aabe9dc0a8154517f96913sewardj ML_(read_pdb_debug_info) do it. */ 1014c8259b85b701d25d72aabe9dc0a8154517f96913sewardj ML_(read_pdb_debug_info)( di, avma_obj, unknown_purpose__reloc, 1015c8259b85b701d25d72aabe9dc0a8154517f96913sewardj pdbimage, n_pdbimage, pdbname, pdb_mtime ); 1016c8259b85b701d25d72aabe9dc0a8154517f96913sewardj // JRS fixme: take notice of return value from read_pdb_debug_info, 1017c8259b85b701d25d72aabe9dc0a8154517f96913sewardj // and handle failure 1018c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(di->have_dinfo); // fails if PDB read failed 1019c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage ); 1020c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(close)(fd_pdbimage); 1021c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1022c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1023c8259b85b701d25d72aabe9dc0a8154517f96913sewardj out: 1024c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (pdbname) ML_(dinfo_free)(pdbname); 1025c8259b85b701d25d72aabe9dc0a8154517f96913sewardj} 1026c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 10278b68b64759254d514d98328c496cbd88cde4c9a5njn#endif /* defined(VGO_linux) || defined(VGO_darwin) */ 10284ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 10294ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 10304ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*-------------------------------------------------------------*/ 10314ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- ---*/ 10324ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- TOP LEVEL: NOTIFICATION (ACQUIRE/DISCARD INFO) (AIX5) ---*/ 10334ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- ---*/ 10344ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*-------------------------------------------------------------*/ 10354ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 10364ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#if defined(VGO_aix5) 10374ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 10384ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/* The supplied parameters describe a code segment and its associated 10394ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj data segment, that have recently been mapped in -- so we need to 10404ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj read debug info for it -- or conversely, have recently been dumped, 10414ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj in which case the relevant debug info has to be unloaded. */ 10424ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 10439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjULong VG_(di_aix5_notify_segchange)( 10444ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Addr code_start, 10454ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Word code_len, 10464ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Addr data_start, 10474ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Word data_len, 10484ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj UChar* file_name, 10494ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj UChar* mem_name, 10504ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool is_mainexe, 10514ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool acquire ) 10524ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj{ 10539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ULong hdl = 0; 10549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 1055f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* play safe; always invalidate the CFI cache. Not 1056f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj that it should be used on AIX, but still .. */ 1057f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi_cache__invalidate(); 1058f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 10594ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (acquire) { 10604ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 1061b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool ok; 1062b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1063b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di = find_or_create_DebugInfo_for( file_name, mem_name ); 1064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di); 1065b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1066b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (code_len > 0) { 1067b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_present = True; 1068b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_svma = 0; /* don't know yet */ 1069b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_bias = 0; /* don't know yet */ 1070b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_avma = code_start; 1071b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_size = code_len; 1072b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1073b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (data_len > 0) { 1074b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_present = True; 1075b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_svma = 0; /* don't know yet */ 1076b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_bias = 0; /* don't know yet */ 1077b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_avma = data_start; 1078b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_size = data_len; 1079b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1080b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1081b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* These need to be filled in in order to keep various 1082b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj assertions in storage.c happy. In particular see 1083b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Comment_Regarding_Text_Range_Checks" in that file. */ 1084b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->have_rx_map = True; 1085b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rx_map_avma = code_start; 1086b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rx_map_size = code_len; 1087b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->have_rw_map = True; 1088b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rw_map_avma = data_start; 1089b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rw_map_size = data_len; 1090b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1091b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ok = ML_(read_xcoff_debug_info) ( di, is_mainexe ); 1092b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1093b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (ok) { 1094b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* prepare read data for use */ 1095b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(canonicaliseTables)( di ); 1096b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* notify m_redir about it */ 1097b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(redir_notify_new_DebugInfo)( di ); 1098b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Note that we succeeded */ 1099b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->have_dinfo = True; 11009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj hdl = di->handle; 11019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(hdl > 0); 1102f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Check invariants listed in 1103f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Comment_on_IMPORTANT_REPRESENTATIONAL_INVARIANTS in 1104f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj priv_storage.h. */ 1105f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj check_CFSI_related_invariants(di); 1106b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 1107b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Something went wrong (eg. bad XCOFF file). */ 1108b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_DebugInfo( di ); 1109b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di = NULL; 1110b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 11114ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 11124ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } else { 11134ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 1114b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Dump all the debugInfos whose text segments intersect 1115f7cdfe298805a91a35b8e0495d9034cbf21003f5sewardj code_start/code_len. */ 1116f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* CFI cache is always invalidated at start of this routine. 1117f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Hence it's safe to ignore the return value of 1118f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj discard_syms_in_range. */ 1119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (code_len > 0) 1120f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj (void)discard_syms_in_range( code_start, code_len ); 11214ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 11224ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 11239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 11249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return hdl; 11254ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj} 11264ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 11274ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 11284ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#endif /* defined(VGO_aix5) */ 11294ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 1130eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1131eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1132eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- ---*/ 1133eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- TOP LEVEL: QUERYING EXISTING DEBUG INFO ---*/ 1134eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- ---*/ 1135eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1136eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 11379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid VG_(di_discard_ALL_debuginfo)( void ) 11389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 11399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo *di, *di2; 11409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di = debugInfo_list; 11419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj while (di) { 11429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di2 = di->next; 11439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("XXX rm %p\n", di); 11449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj free_DebugInfo( di ); 11459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di = di2; 11469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 11479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 11489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 11499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 1150eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1151eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Use of symbol table & location info to create ---*/ 1152eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- plausible-looking stack dumps. ---*/ 1153eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1154eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1155eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Search all symtabs that we know about to locate ptr. If found, set 1156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi to the relevant DebugInfo, and *symno to the symtab entry 1157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *number within that. If not found, *psi is set to NULL. 1158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj If findText==True, only text symbols are searched for. 1159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj If findText==False, only data symbols are searched for. 1160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/ 1161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void search_all_symtabs ( Addr ptr, /*OUT*/DebugInfo** pdi, 1162f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*OUT*/Word* symno, 1163b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool match_anywhere_in_sym, 1164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool findText ) 1165eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1166f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1167b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1168b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool inRange; 1169b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1170b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1171b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1172b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (findText) { 1173b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj inRange = di->text_present 1174b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_size > 0 1175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= ptr 1176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->text_avma + di->text_size; 1177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 1178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj inRange = (di->data_present 1179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_size > 0 1180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_avma <= ptr 1181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->data_avma + di->data_size) 1182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || 1183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (di->sdata_present 1184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_size > 0 1185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_avma <= ptr 1186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->sdata_avma + di->sdata_size) 1187b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || 1188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (di->bss_present 1189b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_size > 0 1190b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_avma <= ptr 11915706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && ptr < di->bss_avma + di->bss_size) 11925706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj || 11935706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj (di->sbss_present 11945706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->sbss_size > 0 11955706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->sbss_avma <= ptr 11965706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && ptr < di->sbss_avma + di->sbss_size) 11975706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj || 11985706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj (di->rodata_present 11995706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->rodata_size > 0 12005706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->rodata_avma <= ptr 12015706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && ptr < di->rodata_avma + di->rodata_size); 1202eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1204b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!inRange) continue; 1205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sno = ML_(search_one_symtab) ( 1207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di, ptr, match_anywhere_in_sym, findText ); 1208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (sno == -1) goto not_found; 1209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *symno = sno; 1210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = di; 1211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; 1212b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1213eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1214eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj not_found: 1215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = NULL; 1216eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1217eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1218eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1219eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Search all loctabs that we know about to locate ptr. If found, set 1220b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi to the relevant DebugInfo, and *locno to the loctab entry 1221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *number within that. If not found, *pdi is set to NULL. */ 1222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void search_all_loctabs ( Addr ptr, /*OUT*/DebugInfo** pdi, 1223f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*OUT*/Word* locno ) 1224eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1225f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word lno; 1226b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1227b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 12295706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->text_size > 0 1230b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= ptr 1231b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->text_avma + di->text_size) { 1232b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj lno = ML_(search_one_loctab) ( di, ptr ); 1233eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (lno == -1) goto not_found; 1234eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *locno = lno; 1235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = di; 1236eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return; 1237eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1238eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1239eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj not_found: 1240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = NULL; 1241eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1242eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1243eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1244eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* The whole point of this whole big deal: map a code address to a 1245eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj plausible symbol name. Returns False if no idea; otherwise True. 12466b7611bf42a0fbb62e047d8c43b008205bd21e75njn Caller supplies buf and nbuf. If do_cxx_demangling is False, don't do 12476b7611bf42a0fbb62e047d8c43b008205bd21e75njn C++ demangling, regardless of VG_(clo_demangle) -- probably because the 12486b7611bf42a0fbb62e047d8c43b008205bd21e75njn call has come from VG_(get_fnname_raw)(). findText 1249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj indicates whether we're looking for a text symbol or a data symbol 1250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj -- caller must choose one kind or the other. */ 1251eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjstatic 12526b7611bf42a0fbb62e047d8c43b008205bd21e75njnBool get_sym_name ( Bool do_cxx_demangling, Bool do_z_demangling, 12536b7611bf42a0fbb62e047d8c43b008205bd21e75njn Bool do_below_main_renaming, 12546b7611bf42a0fbb62e047d8c43b008205bd21e75njn Addr a, Char* buf, Int nbuf, 1255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool match_anywhere_in_sym, Bool show_offset, 1256c4431bfe04c7490ea2d74939d222d87f13f30960njn Bool findText, /*OUT*/PtrdiffT* offsetP ) 1257eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1259f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1260c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT offset; 1261eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj search_all_symtabs ( a, &di, &sno, match_anywhere_in_sym, findText ); 1263b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == NULL) 1264eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 12656882443ef154bca367bc591287de641e43a9e108njn 12666b7611bf42a0fbb62e047d8c43b008205bd21e75njn VG_(demangle) ( do_cxx_demangling, do_z_demangling, 12676b7611bf42a0fbb62e047d8c43b008205bd21e75njn di->symtab[sno].name, buf, nbuf ); 12686b7611bf42a0fbb62e047d8c43b008205bd21e75njn 12696b7611bf42a0fbb62e047d8c43b008205bd21e75njn /* Do the below-main hack */ 12706b7611bf42a0fbb62e047d8c43b008205bd21e75njn // To reduce the endless nuisance of multiple different names 12716b7611bf42a0fbb62e047d8c43b008205bd21e75njn // for "the frame below main()" screwing up the testsuite, change all 12726b7611bf42a0fbb62e047d8c43b008205bd21e75njn // known incarnations of said into a single name, "(below main)", if 12736b7611bf42a0fbb62e047d8c43b008205bd21e75njn // --show-below-main=yes. 12746b7611bf42a0fbb62e047d8c43b008205bd21e75njn if ( do_below_main_renaming && ! VG_(clo_show_below_main) && 12756b7611bf42a0fbb62e047d8c43b008205bd21e75njn Vg_FnNameBelowMain == VG_(get_fnname_kind)(buf) ) 12766b7611bf42a0fbb62e047d8c43b008205bd21e75njn { 12776b7611bf42a0fbb62e047d8c43b008205bd21e75njn VG_(strncpy_safely)(buf, "(below main)", nbuf); 1278eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset = a - di->symtab[sno].addr; 1280c4431bfe04c7490ea2d74939d222d87f13f30960njn if (offsetP) *offsetP = offset; 1281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1282eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (show_offset && offset != 0) { 1283eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char buf2[12]; 1284eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char* symend = buf + VG_(strlen)(buf); 1285eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char* end = buf + nbuf; 1286eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Int len; 1287eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1288c4431bfe04c7490ea2d74939d222d87f13f30960njn len = VG_(sprintf)(buf2, "%c%ld", 1289eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj offset < 0 ? '-' : '+', 1290eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj offset < 0 ? -offset : offset); 1291eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(len < (Int)sizeof(buf2)); 1292eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1293eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (len < (end - symend)) { 1294eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char *cp = buf2; 1295eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(memcpy)(symend, cp, len+1); 1296eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1297eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1298eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 12996b7611bf42a0fbb62e047d8c43b008205bd21e75njn buf[nbuf-1] = 0; /* paranoia */ 13006b7611bf42a0fbb62e047d8c43b008205bd21e75njn 1301eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1302eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1303eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1304eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* ppc64-linux only: find the TOC pointer (R2 value) that should be in 1305eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj force at the entry point address of the function containing 1306eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj guest_code_addr. Returns 0 if not known. */ 1307eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjAddr VG_(get_tocptr) ( Addr guest_code_addr ) 1308eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1310f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1311eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_symtabs ( guest_code_addr, 1312b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj &si, &sno, 1313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj True/*match_anywhere_in_fun*/, 1314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj True/*consider text symbols only*/ ); 1315eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 1316eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return 0; 1317eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj else 1318eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return si->symtab[sno].tocptr; 1319eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1320eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1321eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 1322eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj match anywhere in function, but don't show offsets. */ 1323eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_fnname) ( Addr a, Char* buf, Int nbuf ) 1324eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 13256b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, 13266b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 13276b7611bf42a0fbb62e047d8c43b008205bd21e75njn a, buf, nbuf, 1328b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1330b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1332eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1333eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1334eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 1335eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj match anywhere in function, and show offset if nonzero. */ 1336eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_fnname_w_offset) ( Addr a, Char* buf, Int nbuf ) 1337eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 13386b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, 13396b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 13406b7611bf42a0fbb62e047d8c43b008205bd21e75njn a, buf, nbuf, 1341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/True, 1343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1345eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1346eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1347eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 1348eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj only succeed if 'a' matches first instruction of function, 1349eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj and don't show offsets. */ 1350eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_fnname_if_entry) ( Addr a, Char* buf, Int nbuf ) 1351eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 13526b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, 13536b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 13546b7611bf42a0fbb62e047d8c43b008205bd21e75njn a, buf, nbuf, 1355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/False, 1356b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1358b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1359eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1360eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 13616b7611bf42a0fbb62e047d8c43b008205bd21e75njn/* This is only available to core... don't C++-demangle, don't Z-demangle, 13626b7611bf42a0fbb62e047d8c43b008205bd21e75njn don't rename below-main, match anywhere in function, and don't show 13636b7611bf42a0fbb62e047d8c43b008205bd21e75njn offsets. */ 13646b7611bf42a0fbb62e047d8c43b008205bd21e75njnBool VG_(get_fnname_raw) ( Addr a, Char* buf, Int nbuf ) 1365eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 13666b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, 13676b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/False, 13686b7611bf42a0fbb62e047d8c43b008205bd21e75njn a, buf, nbuf, 1369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1373eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1374eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1375eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is only available to core... don't demangle C++ names, but do 13766b7611bf42a0fbb62e047d8c43b008205bd21e75njn do Z-demangling and below-main-renaming, match anywhere in function, and 13776b7611bf42a0fbb62e047d8c43b008205bd21e75njn don't show offsets. */ 13786b7611bf42a0fbb62e047d8c43b008205bd21e75njnBool VG_(get_fnname_no_cxx_demangle) ( Addr a, Char* buf, Int nbuf ) 1379eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 13806b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/True, 13816b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 13826b7611bf42a0fbb62e047d8c43b008205bd21e75njn a, buf, nbuf, 13836b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*match_anywhere_in_fun*/True, 13846b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*show offset?*/False, 13856b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*text syms only*/True, 13866b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*offsetP*/NULL ); 1387eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1388eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 13896882443ef154bca367bc591287de641e43a9e108njnVg_FnNameKind VG_(get_fnname_kind) ( Char* name ) 13906882443ef154bca367bc591287de641e43a9e108njn{ 13916882443ef154bca367bc591287de641e43a9e108njn if (VG_STREQ("main", name)) { 13926882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameMain; 13936882443ef154bca367bc591287de641e43a9e108njn 13946882443ef154bca367bc591287de641e43a9e108njn } else if ( 13956882443ef154bca367bc591287de641e43a9e108njn#if defined(VGO_linux) 13966882443ef154bca367bc591287de641e43a9e108njn VG_STREQ("__libc_start_main", name) || // glibc glibness 13976882443ef154bca367bc591287de641e43a9e108njn VG_STREQ("generic_start_main", name) || // Yellow Dog doggedness 13986882443ef154bca367bc591287de641e43a9e108njn#elif defined(VGO_aix5) 13996882443ef154bca367bc591287de641e43a9e108njn VG_STREQ("__start", name) || // AIX aches 1400f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(VGO_darwin) 1401f76d27a697a7b0bf3b84490baf60623fc96a23afnjn // See readmacho.c for an explanation of this. 1402f76d27a697a7b0bf3b84490baf60623fc96a23afnjn VG_STREQ("start_according_to_valgrind", name) || // Darwin, darling 14036882443ef154bca367bc591287de641e43a9e108njn#else 14046882443ef154bca367bc591287de641e43a9e108njn# error Unknown OS 14056882443ef154bca367bc591287de641e43a9e108njn#endif 14066882443ef154bca367bc591287de641e43a9e108njn 0) { 14076882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameBelowMain; 14086882443ef154bca367bc591287de641e43a9e108njn 14096882443ef154bca367bc591287de641e43a9e108njn } else { 14106882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameNormal; 14116882443ef154bca367bc591287de641e43a9e108njn } 14126882443ef154bca367bc591287de641e43a9e108njn} 14136882443ef154bca367bc591287de641e43a9e108njn 14146882443ef154bca367bc591287de641e43a9e108njnVg_FnNameKind VG_(get_fnname_kind_from_IP) ( Addr ip ) 14156882443ef154bca367bc591287de641e43a9e108njn{ 14166882443ef154bca367bc591287de641e43a9e108njn // We don't need a big buffer; all the special names are small. 14176882443ef154bca367bc591287de641e43a9e108njn #define BUFLEN 50 14186882443ef154bca367bc591287de641e43a9e108njn Char buf[50]; 14196882443ef154bca367bc591287de641e43a9e108njn 14206882443ef154bca367bc591287de641e43a9e108njn // We don't demangle, because it's faster not to, and the special names 14216882443ef154bca367bc591287de641e43a9e108njn // we're looking for won't be demangled. 14226b7611bf42a0fbb62e047d8c43b008205bd21e75njn if (VG_(get_fnname_raw) ( ip, buf, BUFLEN )) { 14236882443ef154bca367bc591287de641e43a9e108njn buf[BUFLEN-1] = '\0'; // paranoia 14246882443ef154bca367bc591287de641e43a9e108njn return VG_(get_fnname_kind)(buf); 14256882443ef154bca367bc591287de641e43a9e108njn } else { 14266882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameNormal; // Don't know the name, treat it as normal. 14276882443ef154bca367bc591287de641e43a9e108njn } 14286882443ef154bca367bc591287de641e43a9e108njn} 14296882443ef154bca367bc591287de641e43a9e108njn 1430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Looks up data_addr in the collection of data symbols, and if found 1431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj puts its name (or as much as will fit) into dname[0 .. n_dname-1], 1432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which is guaranteed to be zero terminated. Also data_addr's offset 1433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj from the symbol start is put into *offset. */ 1434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool VG_(get_datasym_and_offset)( Addr data_addr, 1435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/Char* dname, Int n_dname, 1436c4431bfe04c7490ea2d74939d222d87f13f30960njn /*OUT*/PtrdiffT* offset ) 1437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 1438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool ok; 1439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_dname > 1); 14406b7611bf42a0fbb62e047d8c43b008205bd21e75njn ok = get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, 14416b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/False, 14426b7611bf42a0fbb62e047d8c43b008205bd21e75njn data_addr, dname, n_dname, 1443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_sym*/True, 1444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*data syms only please*/False, 1446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset ); 1447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!ok) 1448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 1449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname[n_dname-1] = 0; 1450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 1451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 1452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Map a code address to the name of a shared object file or the 1454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj executable. Returns False if no idea; otherwise True. Doesn't 1455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj require debug info. Caller supplies buf and nbuf. */ 1456eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_objname) ( Addr a, Char* buf, Int nbuf ) 1457eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 14584ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Int used; 1459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1460f32ec7f0de8a651bc16a1b2e448c0106d8669889tom const NSegment *seg; 1461f32ec7f0de8a651bc16a1b2e448c0106d8669889tom HChar* filename; 14624ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj vg_assert(nbuf > 0); 14637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Look in the debugInfo_list to find the name. In most cases we 14647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj expect this to produce a result. */ 1465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 14675706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->text_size > 0 1468b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= a 1469b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a < di->text_avma + di->text_size) { 1470b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(strncpy_safely)(buf, di->filename, nbuf); 1471b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->memname) { 14724ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj used = VG_(strlen)(buf); 14734ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (used < nbuf) 14744ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(strncpy_safely)(&buf[used], "(", nbuf-used); 14754ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj used = VG_(strlen)(buf); 14764ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (used < nbuf) 1477b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(strncpy_safely)(&buf[used], di->memname, nbuf-used); 14784ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj used = VG_(strlen)(buf); 14794ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (used < nbuf) 14804ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(strncpy_safely)(&buf[used], ")", nbuf-used); 14814ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 14824ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj buf[nbuf-1] = 0; 1483eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1484eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1485eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 14867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Last-ditch fallback position: if we don't find the address in 14877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj the debugInfo_list, ask the address space manager whether it 14887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj knows the name of the file associated with this mapping. This 14897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj allows us to print the names of exe/dll files in the stack trace 14907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj when running programs under wine. */ 14917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if ( (seg = VG_(am_find_nsegment(a))) != NULL 14927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj && (filename = VG_(am_get_filename)(seg)) != NULL ) { 1493f32ec7f0de8a651bc16a1b2e448c0106d8669889tom VG_(strncpy_safely)(buf, filename, nbuf); 1494f32ec7f0de8a651bc16a1b2e448c0106d8669889tom return True; 1495f32ec7f0de8a651bc16a1b2e448c0106d8669889tom } 1496eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1497eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1498eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1499b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Map a code address to its DebugInfo. Returns NULL if not found. Doesn't 1500eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj require debug info. */ 1501e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjDebugInfo* VG_(find_DebugInfo) ( Addr a ) 1502eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1503e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj static UWord n_search = 0; 1504b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1505e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj n_search++; 1506b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1507b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 15085706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->text_size > 0 1509b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= a 1510b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a < di->text_avma + di->text_size) { 1511e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj if (0 == (n_search & 0xF)) 1512e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj move_DebugInfo_one_step_forward( di ); 1513b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 1514eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1515eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1516eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return NULL; 1517eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1518eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1519eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a filename. Returns True if successful. */ 1520eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_filename)( Addr a, Char* filename, Int n_filename ) 1521eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1522b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1523f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 1524eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 1525eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 1526eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1527eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(strncpy_safely)(filename, si->loctab[locno].filename, n_filename); 1528eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1529eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1530eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1531eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a line number. Returns True if successful. */ 1532eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_linenum)( Addr a, UInt* lineno ) 1533eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1534b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1535f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 1536eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 1537eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 1538eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1539eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *lineno = si->loctab[locno].lineno; 1540eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1541eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1542eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1543eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1544eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a filename/line number/dir name info. 1545eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj See prototype for detailed description of behaviour. 1546eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 1547eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_filename_linenum) ( Addr a, 1548eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/Char* filename, Int n_filename, 1549eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/Char* dirname, Int n_dirname, 1550eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/Bool* dirname_available, 1551eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/UInt* lineno ) 1552eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1553b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1554f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 1555eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1556eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert( (dirname == NULL && dirname_available == NULL) 1557eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj || 1558eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj (dirname != NULL && dirname_available != NULL) ); 1559eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1560eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 1561c1b1d421216369aec58867ce1c5b99cfb1703c36njn if (si == NULL) { 1562db5c6571454c1f647a4c67593805a8e401cd14c5njn if (dirname_available) { 1563db5c6571454c1f647a4c67593805a8e401cd14c5njn *dirname_available = False; 1564db5c6571454c1f647a4c67593805a8e401cd14c5njn *dirname = 0; 1565db5c6571454c1f647a4c67593805a8e401cd14c5njn } 1566eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1567c1b1d421216369aec58867ce1c5b99cfb1703c36njn } 1568c1b1d421216369aec58867ce1c5b99cfb1703c36njn 1569eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(strncpy_safely)(filename, si->loctab[locno].filename, n_filename); 1570eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *lineno = si->loctab[locno].lineno; 1571eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1572eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (dirname) { 1573eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* caller wants directory info too .. */ 1574eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(n_dirname > 0); 1575eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si->loctab[locno].dirname) { 1576eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* .. and we have some */ 1577eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *dirname_available = True; 1578eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(strncpy_safely)(dirname, si->loctab[locno].dirname, 1579eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_dirname); 1580eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 1581eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* .. but we don't have any */ 1582eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *dirname_available = False; 1583eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *dirname = 0; 1584eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1585eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1586eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1587eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1588eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1589eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1590eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 15914ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/* Map a function name to its entry point and toc pointer. Is done by 15924ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj sequential search of all symbol tables, so is very slow. To 15934ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj mitigate the worst performance effects, you may specify a soname 15944ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj pattern, and only objects matching that pattern are searched. 15954ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Therefore specify "*" to search all the objects. On TOC-afflicted 15964ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj platforms, a symbol is deemed to be found only if it has a nonzero 15974ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj TOC pointer. */ 1598b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool VG_(lookup_symbol_SLOW)(UChar* sopatt, UChar* name, 1599b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr* pEnt, Addr* pToc) 16004ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj{ 16014ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool require_pToc = False; 16024ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Int i; 1603b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 16044ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool debug = False; 16054ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# if defined(VG_PLAT_USES_PPCTOC) 16064ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj require_pToc = True; 16074ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# endif 1608b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (si = debugInfo_list; si; si = si->next) { 16094ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (debug) 16104ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(printf)("lookup_symbol_SLOW: considering %s\n", si->soname); 16114ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (!VG_(string_match)(sopatt, si->soname)) { 16124ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (debug) 16134ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(printf)(" ... skip\n"); 16144ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj continue; 16154ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 16164ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj for (i = 0; i < si->symtab_used; i++) { 16174ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (0==VG_(strcmp)(name, si->symtab[i].name) 16184ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj && (require_pToc ? si->symtab[i].tocptr : True)) { 16194ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj *pEnt = si->symtab[i].addr; 16204ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj *pToc = si->symtab[i].tocptr; 16214ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj return True; 16224ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 16234ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 16244ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 16254ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj return False; 16264ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj} 16274ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 16284ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 1629e872fec0c1c3b478a399fdba42ac65764b53f470sewardj/* VG_(describe_IP): print into buf info on code address, function 1630e872fec0c1c3b478a399fdba42ac65764b53f470sewardj name and filename. */ 1631e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 1632e872fec0c1c3b478a399fdba42ac65764b53f470sewardj/* Copy str into buf starting at n, but not going past buf[n_buf-1] 1633e872fec0c1c3b478a399fdba42ac65764b53f470sewardj and always ensuring that buf is zero-terminated. */ 1634eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1635eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjstatic Int putStr ( Int n, Int n_buf, Char* buf, Char* str ) 1636eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1637e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n_buf > 0); 1638e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 1639eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj for (; n < n_buf-1 && *str != 0; n++,str++) 1640eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf[n] = *str; 1641e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 1642eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf[n] = '\0'; 1643eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return n; 1644eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1645e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 1646e872fec0c1c3b478a399fdba42ac65764b53f470sewardj/* Same as putStr, but escaping chars for XML output, and 1647e872fec0c1c3b478a399fdba42ac65764b53f470sewardj also not adding more than count chars to n_buf. */ 1648e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 1649e872fec0c1c3b478a399fdba42ac65764b53f470sewardjstatic Int putStrEsc ( Int n, Int n_buf, Int count, Char* buf, Char* str ) 1650eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1651eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char alt[2]; 1652e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n_buf > 0); 1653e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(count >= 0 && count < n_buf); 1654e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 1655eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj for (; *str != 0; str++) { 1656e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(count >= 0); 1657e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count <= 0) 1658e872fec0c1c3b478a399fdba42ac65764b53f470sewardj goto done; 1659eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj switch (*str) { 1660e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '&': 1661e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 5) goto done; 1662e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, "&"); 1663e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 5; 1664e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 1665e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '<': 1666e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 4) goto done; 1667e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, "<"); 1668e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 4; 1669e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 1670e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '>': 1671e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 4) goto done; 1672e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, ">"); 1673e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 4; 1674e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 1675e872fec0c1c3b478a399fdba42ac65764b53f470sewardj default: 1676e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 1) goto done; 1677e872fec0c1c3b478a399fdba42ac65764b53f470sewardj alt[0] = *str; 1678e872fec0c1c3b478a399fdba42ac65764b53f470sewardj alt[1] = 0; 1679e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, alt ); 1680e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 1; 1681e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 1682eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1683eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1684e872fec0c1c3b478a399fdba42ac65764b53f470sewardj done: 1685e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(count >= 0); /* should not go -ve in loop */ 1686e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 1687eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return n; 1688eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1689eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1690eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjChar* VG_(describe_IP)(Addr eip, Char* buf, Int n_buf) 1691eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1692eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define APPEND(_str) \ 1693e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr(n, n_buf, buf, _str) 1694e872fec0c1c3b478a399fdba42ac65764b53f470sewardj# define APPEND_ESC(_count,_str) \ 1695e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStrEsc(n, n_buf, (_count), buf, (_str)) 1696eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define BUF_LEN 4096 1697eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1698eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj UInt lineno; 1699eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj UChar ibuf[50]; 1700eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Int n = 0; 1701eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static UChar buf_fn[BUF_LEN]; 1702eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static UChar buf_obj[BUF_LEN]; 1703eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static UChar buf_srcloc[BUF_LEN]; 1704eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static UChar buf_dirname[BUF_LEN]; 1705eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool know_dirinfo = False; 17064ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool know_fnname = VG_(clo_sym_offsets) 17074ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj ? VG_(get_fnname_w_offset) (eip, buf_fn, BUF_LEN) 17084ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj : VG_(get_fnname) (eip, buf_fn, BUF_LEN); 1709eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool know_objname = VG_(get_objname)(eip, buf_obj, BUF_LEN); 1710eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool know_srcloc = VG_(get_filename_linenum)( 1711eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj eip, 1712eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf_srcloc, BUF_LEN, 1713eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf_dirname, BUF_LEN, &know_dirinfo, 1714eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj &lineno 1715eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj ); 1716eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (VG_(clo_xml)) { 1717eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1718eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool human_readable = True; 1719eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj HChar* maybe_newline = human_readable ? "\n " : ""; 1720eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj HChar* maybe_newline2 = human_readable ? "\n " : ""; 1721eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1722e872fec0c1c3b478a399fdba42ac65764b53f470sewardj /* Print in XML format, dumping in as much info as we know. 1723e872fec0c1c3b478a399fdba42ac65764b53f470sewardj Ensure all tags are balanced even if the individual strings 1724e872fec0c1c3b478a399fdba42ac65764b53f470sewardj are too long. Allocate 1/10 of BUF_LEN to the object name, 1725e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 6/10s to the function name, 1/10 to the directory name and 1726e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 1/10 to the file name, leaving 1/10 for all the fixed-length 1727e872fec0c1c3b478a399fdba42ac65764b53f470sewardj stuff. */ 1728eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<frame>"); 1729a44b15f527bbebfe824a2e68e4bd6ab1e153b486sewardj VG_(sprintf)(ibuf,"<ip>0x%llX</ip>", (ULong)eip); 1730eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1731eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 1732eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_objname) { 1733eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1734eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<obj>"); 1735e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(1*BUF_LEN/10, buf_obj); 1736eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</obj>"); 1737eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1738eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_fnname) { 1739eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1740eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<fn>"); 1741e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(6*BUF_LEN/10, buf_fn); 1742eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</fn>"); 1743eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1744eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_srcloc) { 1745eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_dirinfo) { 1746eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1747eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<dir>"); 1748e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(1*BUF_LEN/10, buf_dirname); 1749eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</dir>"); 1750eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1751eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1752eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<file>"); 1753e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(1*BUF_LEN/10, buf_srcloc); 1754eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</file>"); 1755eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1756eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<line>"); 1757eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(sprintf)(ibuf,"%d",lineno); 1758eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 1759eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</line>"); 1760eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1761eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline2); 1762eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</frame>"); 1763eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1764eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 1765eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1766eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Print for humans to read */ 17675e40abad4504416c59f0b29c1cfc8087201213a9njn // 17685e40abad4504416c59f0b29c1cfc8087201213a9njn // Possible forms: 17695e40abad4504416c59f0b29c1cfc8087201213a9njn // 17705e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: really (a.c:20) 17715e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: really (in /foo/a.out) 17725e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: really (in ???) 17735e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: ??? (in /foo/a.out) 17745e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: ??? (a.c:20) 17755e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: ??? 17765e40abad4504416c59f0b29c1cfc8087201213a9njn // 1777a44b15f527bbebfe824a2e68e4bd6ab1e153b486sewardj VG_(sprintf)(ibuf,"0x%llX: ", (ULong)eip); 1778eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 17795e40abad4504416c59f0b29c1cfc8087201213a9njn if (know_fnname) { 1780eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(buf_fn); 1781eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 1782eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("???"); 1783eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1784eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_srcloc) { 1785eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(" ("); 1786eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(buf_srcloc); 1787eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(":"); 1788eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(sprintf)(ibuf,"%d",lineno); 1789eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 1790eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(")"); 17915e40abad4504416c59f0b29c1cfc8087201213a9njn } else if (know_objname) { 17925e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(" (in "); 17935e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(buf_obj); 17945e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(")"); 17955e40abad4504416c59f0b29c1cfc8087201213a9njn } else if (know_fnname) { 17965e40abad4504416c59f0b29c1cfc8087201213a9njn // Nb: do this in two steps because "??)" is a trigraph! 17975e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(" (in ???"); 17985e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(")"); 1799eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1800eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1801eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1802eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return buf; 1803eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1804eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef APPEND 1805eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef APPEND_ESC 1806eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef BUF_LEN 1807eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1808eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 180972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 1810b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 1811b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 1812b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/ 1813b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- DWARF3 .eh_frame INFO ---*/ 1814b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 1815b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 181672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 181772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/* Gather up all the constant pieces of info needed to evaluate 181872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj a CfiExpr into one convenient struct. */ 181972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjtypedef 182072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj struct { 182172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj Addr ipHere; 182272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj Addr spHere; 182372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj Addr fpHere; 182472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj Addr min_accessible; 182572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj Addr max_accessible; 182672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 182772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExprEvalContext; 182872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 182972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/* Evaluate the CfiExpr rooted at ix in exprs given the context eec. 183072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj *ok is set to False on failure, but not to True on success. The 183172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj caller must set it to True before calling. */ 183272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjstatic 183372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjUWord evalCfiExpr ( XArray* exprs, Int ix, 183472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExprEvalContext* eec, Bool* ok ) 183572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj{ 183672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj UWord wL, wR; 183719dc88f90d0e19a1463797dd99f6792a42f961d3sewardj Addr a; 183872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExpr* e = VG_(indexXA)( exprs, ix ); 183972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->tag) { 184072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_Binop: 184172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj wL = evalCfiExpr( exprs, e->Cex.Binop.ixL, eec, ok ); 184272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!(*ok)) return 0; 184372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj wR = evalCfiExpr( exprs, e->Cex.Binop.ixR, eec, ok ); 184472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!(*ok)) return 0; 184572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->Cex.Binop.op) { 184672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cop_Add: return wL + wR; 184772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cop_Sub: return wL - wR; 184819dc88f90d0e19a1463797dd99f6792a42f961d3sewardj case Cop_And: return wL & wR; 18497888e2204fff6e7429236b4227ed16594e7743b9sewardj case Cop_Mul: return wL * wR; 185072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: goto unhandled; 185172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 185272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 185372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_CfiReg: 185472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->Cex.CfiReg.reg) { 185572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Creg_IP: return (Addr)eec->ipHere; 185672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Creg_SP: return (Addr)eec->spHere; 185772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Creg_FP: return (Addr)eec->fpHere; 185872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: goto unhandled; 185972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 186072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 186172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_Const: 186272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj return e->Cex.Const.con; 186319dc88f90d0e19a1463797dd99f6792a42f961d3sewardj case Cex_Deref: 186419dc88f90d0e19a1463797dd99f6792a42f961d3sewardj a = evalCfiExpr( exprs, e->Cex.Deref.ixAddr, eec, ok ); 186519dc88f90d0e19a1463797dd99f6792a42f961d3sewardj if (!(*ok)) return 0; 186619dc88f90d0e19a1463797dd99f6792a42f961d3sewardj if (a < eec->min_accessible 186719dc88f90d0e19a1463797dd99f6792a42f961d3sewardj || (a + sizeof(UWord) - 1) > eec->max_accessible) { 186819dc88f90d0e19a1463797dd99f6792a42f961d3sewardj *ok = False; 186919dc88f90d0e19a1463797dd99f6792a42f961d3sewardj return 0; 187019dc88f90d0e19a1463797dd99f6792a42f961d3sewardj } 187119dc88f90d0e19a1463797dd99f6792a42f961d3sewardj /* let's hope it doesn't trap! */ 187219dc88f90d0e19a1463797dd99f6792a42f961d3sewardj return * ((UWord*)a); 187372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: 187472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj goto unhandled; 187572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 187672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 187772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj unhandled: 187872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("\n\nevalCfiExpr: unhandled\n"); 187972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj ML_(ppCfiExpr)( exprs, ix ); 188072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("\n"); 188172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); 188272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 188372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj return 0; 188472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj} 188572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 188672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 1887f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Search all the DebugInfos in the entire system, to find the DiCfSI 1888f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj that pertains to 'ip'. 1889eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1890f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj If found, set *diP to the DebugInfo in which it resides, and 1891f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *ixP to the index in that DebugInfo's cfsi array. 189272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 1893f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj If not found, set *diP to (DebugInfo*)1 and *ixP to zero. 1894f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj*/ 1895f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj__attribute__((noinline)) 1896f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic void find_DiCfSI ( /*OUT*/DebugInfo** diP, 1897f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*OUT*/Word* ixP, 1898f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Addr ip ) 1899f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 1900f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo* di; 1901f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word i = -1; 1902f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1903f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj static UWord n_search = 0; 1904f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj static UWord n_steps = 0; 1905eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_search++; 1906eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1907f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0) VG_(printf)("search for %#lx\n", ip); 1908eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1909f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1910f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word j; 1911eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_steps++; 1912eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1913b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Use the per-DebugInfo summary address ranges to skip 1914b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj inapplicable DebugInfos quickly. */ 1915f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di->cfsi_used == 0) 1916eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj continue; 1917f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (ip < di->cfsi_minavma || ip > di->cfsi_maxavma) 1918eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj continue; 1919eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1920f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* It might be in this DebugInfo. Search it. */ 1921f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj j = ML_(search_one_cfitab)( di, ip ); 1922f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(j >= -1 && j < (Word)di->cfsi_used); 1923f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1924f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (j != -1) { 1925f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj i = j; 1926f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj break; /* found it */ 1927eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1928eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1929eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1930f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (i == -1) { 1931f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1932f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* we didn't find it. */ 1933f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *diP = (DebugInfo*)1; 1934f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *ixP = 0; 1935f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1936f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 1937f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1938f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* found it. */ 1939f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* ensure that di is 4-aligned (at least), so it can't possibly 1940f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj be equal to (DebugInfo*)1. */ 1941f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di && VG_IS_4_ALIGNED(di)); 1942f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(i >= 0 && i < di->cfsi_used); 1943f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *diP = di; 1944f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *ixP = i; 1945f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1946f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Start of performance-enhancing hack: once every 64 (chosen 1947f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj hackily after profiling) successful searches, move the found 1948f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo one step closer to the start of the list. This 1949f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj makes future searches cheaper. For starting konqueror on 1950f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj amd64, this in fact reduces the total amount of searching 1951f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj done by the above find-the-right-DebugInfo loop by more than 1952f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj a factor of 20. */ 1953f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if ((n_search & 0xF) == 0) { 1954f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Move di one step closer to the start of the list. */ 1955f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj move_DebugInfo_one_step_forward( di ); 1956f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 1957f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* End of performance-enhancing hack. */ 1958f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1959f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && ((n_search & 0x7FFFF) == 0)) 1960f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(printf)("find_DiCfSI: %lu searches, " 1961f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj "%lu DebugInfos looked at\n", 1962f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj n_search, n_steps); 1963f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1964f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 1965f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1966f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 1967f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1968f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1969f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Now follows a mechanism for caching queries to find_DiCfSI, since 1970f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj they are extremely frequent on amd64-linux, during stack unwinding. 1971f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1972f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Each cache entry binds an ip value to a (di, ix) pair. Possible 1973f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj values: 1974f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1975f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj di is non-null, ix >= 0 ==> cache slot in use, "di->cfsi[ix]" 1976f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj di is (DebugInfo*)1 ==> cache slot in use, no associated di 1977f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj di is NULL ==> cache slot not in use 1978f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1979f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Hence simply zeroing out the entire cache invalidates all 1980f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj entries. 1981f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1982f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Why not map ip values directly to DiCfSI*'s? Because this would 1983f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cause problems if/when the cfsi array is moved due to resizing. 1984f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Instead we cache .cfsi array index value, which should be invariant 1985f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj across resizing. (That said, I don't think the current 1986f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj implementation will resize whilst during queries, since the DiCfSI 1987f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj records are added all at once, when the debuginfo for an object is 1988f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj read, and is not changed ever thereafter. */ 1989eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1990f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#define N_CFSI_CACHE 511 1991f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1992f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjtypedef 1993f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj struct { Addr ip; DebugInfo* di; Word ix; } 1994f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj CFSICacheEnt; 1995f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1996f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic CFSICacheEnt cfsi_cache[N_CFSI_CACHE]; 1997f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1998f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic void cfsi_cache__invalidate ( void ) { 1999f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(memset)(&cfsi_cache, 0, sizeof(cfsi_cache)); 2000f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 2001f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2002f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2003f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* The main function for DWARF2/3 CFI-based stack unwinding. 2004f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Given an IP/SP/FP triple, produce the IP/SP/FP values for the 2005f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj previous frame, if possible. */ 2006f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Returns True if OK. If not OK, *{ip,sp,fp}P are not changed. */ 2007f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* NOTE: this function may rearrange the order of entries in the 2008f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo list. */ 2009f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjBool VG_(use_CF_info) ( /*MOD*/Addr* ipP, 2010f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*MOD*/Addr* spP, 2011f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*MOD*/Addr* fpP, 2012f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Addr min_accessible, 2013f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Addr max_accessible ) 2014f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 2015f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool ok; 2016f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo* di; 2017f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DiCfSI* cfsi = NULL; 2018f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Addr cfa, ipHere, spHere, fpHere, ipPrev, spPrev, fpPrev; 2019f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2020f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj CfiExprEvalContext eec; 2021f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2022f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj static UWord n_q = 0, n_m = 0; 2023f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj n_q++; 2024f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && 0 == (n_q & 0x1FFFFF)) 2025f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(printf)("QQQ %lu %lu\n", n_q, n_m); 2026f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2027f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj { UWord hash = (*ipP) % N_CFSI_CACHE; 2028f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj CFSICacheEnt* ce = &cfsi_cache[hash]; 2029f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2030f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (LIKELY(ce->ip == *ipP) && LIKELY(ce->di != NULL)) { 2031f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* found an entry in the cache .. */ 2032f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 2033f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* not found in cache. Search and update. */ 2034f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj n_m++; 2035f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj ce->ip = *ipP; 2036f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj find_DiCfSI( &ce->di, &ce->ix, *ipP ); 2037f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 2038f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2039f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (UNLIKELY(ce->di == (DebugInfo*)1)) { 2040f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* no DiCfSI for this address */ 2041f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi = NULL; 2042f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj di = NULL; 2043f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 2044f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* found a DiCfSI for this address */ 2045f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj di = ce->di; 2046f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi = &di->cfsi[ ce->ix ]; 2047f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 2048eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2049f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2050f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (UNLIKELY(cfsi == NULL)) 2051f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return False; /* no info. Nothing we can do. */ 2052eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2053eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (0) { 2054eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(printf)("found cfisi: "); 2055f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj ML_(ppDiCfSI)(di->cfsi_exprs, cfsi); 2056eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2057eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2058eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj ipPrev = spPrev = fpPrev = 0; 2059eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2060eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj ipHere = *ipP; 2061eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj spHere = *spP; 2062eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj fpHere = *fpP; 2063eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 206472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /* First compute the CFA. */ 206572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj cfa = 0; 206672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (cfsi->cfa_how) { 206772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case CFIC_SPREL: 206872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj cfa = cfsi->cfa_off + spHere; 206972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 207072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case CFIC_FPREL: 207172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj cfa = cfsi->cfa_off + fpHere; 207272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 207372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case CFIC_EXPR: 20747888e2204fff6e7429236b4227ed16594e7743b9sewardj if (0) { 20757888e2204fff6e7429236b4227ed16594e7743b9sewardj VG_(printf)("CFIC_EXPR: "); 2076f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj ML_(ppCfiExpr)(di->cfsi_exprs, cfsi->cfa_off); 20777888e2204fff6e7429236b4227ed16594e7743b9sewardj VG_(printf)("\n"); 20787888e2204fff6e7429236b4227ed16594e7743b9sewardj } 20797888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.ipHere = ipHere; 20807888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.spHere = spHere; 20817888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.fpHere = fpHere; 20827888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.min_accessible = min_accessible; 20837888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.max_accessible = max_accessible; 20847888e2204fff6e7429236b4227ed16594e7743b9sewardj ok = True; 2085f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfa = evalCfiExpr(di->cfsi_exprs, cfsi->cfa_off, &eec, &ok ); 20867888e2204fff6e7429236b4227ed16594e7743b9sewardj if (!ok) return False; 208772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 208872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: 208972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); 209072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 209172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 209272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /* Now we know the CFA, use it to roll back the registers we're 209372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj interested in. */ 2094eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2095eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define COMPUTE(_prev, _here, _how, _off) \ 2096eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj do { \ 2097eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj switch (_how) { \ 2098eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_UNKNOWN: \ 2099eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; \ 2100eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_SAME: \ 2101eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj _prev = _here; break; \ 2102eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_MEMCFAREL: { \ 2103eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Addr a = cfa + (Word)_off; \ 2104eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (a < min_accessible \ 21059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj || a > max_accessible-sizeof(Addr)) \ 2106eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; \ 2107eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj _prev = *(Addr*)a; \ 2108eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; \ 2109eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } \ 2110eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_CFAREL: \ 2111eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj _prev = cfa + (Word)_off; \ 2112eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; \ 211372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case CFIR_EXPR: \ 211472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (0) \ 2115f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj ML_(ppCfiExpr)(di->cfsi_exprs,_off); \ 211672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.ipHere = ipHere; \ 211772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.spHere = spHere; \ 211872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.fpHere = fpHere; \ 211972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.min_accessible = min_accessible; \ 212072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.max_accessible = max_accessible; \ 212172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj ok = True; \ 2122f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj _prev = evalCfiExpr(di->cfsi_exprs, _off, &eec, &ok ); \ 212372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!ok) return False; \ 212472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; \ 212572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: \ 212672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); \ 2127eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } \ 2128eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } while (0) 2129eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2130eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj COMPUTE(ipPrev, ipHere, cfsi->ra_how, cfsi->ra_off); 2131eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj COMPUTE(spPrev, spHere, cfsi->sp_how, cfsi->sp_off); 2132eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj COMPUTE(fpPrev, fpHere, cfsi->fp_how, cfsi->fp_off); 2133eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2134eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef COMPUTE 2135eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2136eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *ipP = ipPrev; 2137eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *spP = spPrev; 2138eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *fpP = fpPrev; 2139eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 2140eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2141eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2142eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 2144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 2145c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/ 2146c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- MSVC FPO INFO ---*/ 2147c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- ---*/ 2148c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--------------------------------------------------------------*/ 2149c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2150c8259b85b701d25d72aabe9dc0a8154517f96913sewardjBool VG_(use_FPO_info) ( /*MOD*/Addr* ipP, 2151c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /*MOD*/Addr* spP, 2152c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /*MOD*/Addr* fpP, 2153c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Addr min_accessible, 2154c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Addr max_accessible ) 2155c8259b85b701d25d72aabe9dc0a8154517f96913sewardj{ 2156c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Word i; 2157c8259b85b701d25d72aabe9dc0a8154517f96913sewardj DebugInfo* di; 2158c8259b85b701d25d72aabe9dc0a8154517f96913sewardj FPO_DATA* fpo = NULL; 2159c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Addr spHere; 2160c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2161c8259b85b701d25d72aabe9dc0a8154517f96913sewardj static UWord n_search = 0; 2162c8259b85b701d25d72aabe9dc0a8154517f96913sewardj static UWord n_steps = 0; 2163c8259b85b701d25d72aabe9dc0a8154517f96913sewardj n_search++; 2164c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2165c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0) VG_(printf)("search FPO for %#lx\n", *ipP); 2166c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2167c8259b85b701d25d72aabe9dc0a8154517f96913sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 2168c8259b85b701d25d72aabe9dc0a8154517f96913sewardj n_steps++; 2169c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2170c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Use the per-DebugInfo summary address ranges to skip 2171c8259b85b701d25d72aabe9dc0a8154517f96913sewardj inapplicable DebugInfos quickly. */ 2172c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (di->fpo == NULL) 2173c8259b85b701d25d72aabe9dc0a8154517f96913sewardj continue; 2174c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (*ipP < di->fpo_minavma || *ipP > di->fpo_maxavma) 2175c8259b85b701d25d72aabe9dc0a8154517f96913sewardj continue; 2176c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2177c8259b85b701d25d72aabe9dc0a8154517f96913sewardj i = ML_(search_one_fpotab)( di, *ipP ); 2178c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (i != -1) { 2179c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Word j; 2180c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0) { 2181c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* debug printing only */ 2182c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("look for %#lx size %ld i %ld\n", 2183c8259b85b701d25d72aabe9dc0a8154517f96913sewardj *ipP, di->fpo_size, i); 2184c8259b85b701d25d72aabe9dc0a8154517f96913sewardj for (j = 0; j < di->fpo_size; j++) 2185c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("[%02ld] %#x %d\n", 2186c8259b85b701d25d72aabe9dc0a8154517f96913sewardj j, di->fpo[j].ulOffStart, di->fpo[j].cbProcSize); 2187c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2188c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(i >= 0 && i < di->fpo_size); 2189c8259b85b701d25d72aabe9dc0a8154517f96913sewardj fpo = &di->fpo[i]; 2190c8259b85b701d25d72aabe9dc0a8154517f96913sewardj break; 2191c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2192c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2193c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2194c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (fpo == NULL) 2195c8259b85b701d25d72aabe9dc0a8154517f96913sewardj return False; 2196c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2197c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0 && ((n_search & 0x7FFFF) == 0)) 2198c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("VG_(use_FPO_info): %lu searches, " 2199c8259b85b701d25d72aabe9dc0a8154517f96913sewardj "%lu DebugInfos looked at\n", 2200c8259b85b701d25d72aabe9dc0a8154517f96913sewardj n_search, n_steps); 2201c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2202c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2203c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Start of performance-enhancing hack: once every 64 (chosen 2204c8259b85b701d25d72aabe9dc0a8154517f96913sewardj hackily after profiling) successful searches, move the found 2205c8259b85b701d25d72aabe9dc0a8154517f96913sewardj DebugInfo one step closer to the start of the list. This makes 2206c8259b85b701d25d72aabe9dc0a8154517f96913sewardj future searches cheaper. For starting konqueror on amd64, this 2207c8259b85b701d25d72aabe9dc0a8154517f96913sewardj in fact reduces the total amount of searching done by the above 2208c8259b85b701d25d72aabe9dc0a8154517f96913sewardj find-the-right-DebugInfo loop by more than a factor of 20. */ 2209c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if ((n_search & 0x3F) == 0) { 2210c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Move si one step closer to the start of the list. */ 2211c8259b85b701d25d72aabe9dc0a8154517f96913sewardj //move_DebugInfo_one_step_forward( di ); 2212c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2213c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* End of performance-enhancing hack. */ 2214c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2215c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0) { 2216c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("found fpo: "); 2217c8259b85b701d25d72aabe9dc0a8154517f96913sewardj //ML_(ppFPO)(fpo); 2218c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2219c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2220c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* 2221c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Stack layout is: 2222c8259b85b701d25d72aabe9dc0a8154517f96913sewardj %esp-> 2223c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 4*.cbRegs {%edi, %esi, %ebp, %ebx} 2224c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 4*.cdwLocals 2225c8259b85b701d25d72aabe9dc0a8154517f96913sewardj return_pc 2226c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 4*.cdwParams 2227c8259b85b701d25d72aabe9dc0a8154517f96913sewardj prior_%esp-> 2228c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2229c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Typical code looks like: 2230c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sub $4*.cdwLocals,%esp 2231c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Alternative to above for >=4KB (and sometimes for smaller): 2232c8259b85b701d25d72aabe9dc0a8154517f96913sewardj mov $size,%eax 2233c8259b85b701d25d72aabe9dc0a8154517f96913sewardj call __chkstk # WinNT performs page-by-page probe! 2234c8259b85b701d25d72aabe9dc0a8154517f96913sewardj __chkstk is much like alloc(), except that on return 2235c8259b85b701d25d72aabe9dc0a8154517f96913sewardj %eax= 5+ &CALL. Thus it could be used as part of 2236c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Position Independent Code to locate the Global Offset Table. 2237c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %ebx 2238c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %ebp 2239c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %esi 2240c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Other once-only instructions often scheduled >here<. 2241c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %edi 2242c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2243c8259b85b701d25d72aabe9dc0a8154517f96913sewardj If the pc is within the first .cbProlog bytes of the function, 2244c8259b85b701d25d72aabe9dc0a8154517f96913sewardj then you must disassemble to see how many registers have been pushed, 2245c8259b85b701d25d72aabe9dc0a8154517f96913sewardj because instructions in the prolog may be scheduled for performance. 2246c8259b85b701d25d72aabe9dc0a8154517f96913sewardj The order of PUSH is always %ebx, %ebp, %esi, %edi, with trailing 2247c8259b85b701d25d72aabe9dc0a8154517f96913sewardj registers not pushed when .cbRegs < 4. This seems somewhat strange 2248c8259b85b701d25d72aabe9dc0a8154517f96913sewardj because %ebp is the register whose usage you want to minimize, 2249c8259b85b701d25d72aabe9dc0a8154517f96913sewardj yet it is in the first half of the PUSH list. 2250c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2251c8259b85b701d25d72aabe9dc0a8154517f96913sewardj I don't know what happens when the compiler constructs an outgoing CALL. 2252c8259b85b701d25d72aabe9dc0a8154517f96913sewardj %esp could move if outgoing parameters are PUSHed, and this affects 2253c8259b85b701d25d72aabe9dc0a8154517f96913sewardj traceback for errors during the PUSHes. */ 2254c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2255c8259b85b701d25d72aabe9dc0a8154517f96913sewardj spHere = *spP; 2256c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2257c8259b85b701d25d72aabe9dc0a8154517f96913sewardj *ipP = *(Addr *)(spHere + 4*(fpo->cbRegs + fpo->cdwLocals)); 2258738856f99eea33d86ce91dcb1d6cd5b151e307casewardj *spP = spHere + 4*(fpo->cbRegs + fpo->cdwLocals + 1 2259738856f99eea33d86ce91dcb1d6cd5b151e307casewardj + fpo->cdwParams); 2260c8259b85b701d25d72aabe9dc0a8154517f96913sewardj *fpP = *(Addr *)(spHere + 4*2); 2261c8259b85b701d25d72aabe9dc0a8154517f96913sewardj return True; 2262c8259b85b701d25d72aabe9dc0a8154517f96913sewardj} 2263c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2264c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2265c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--------------------------------------------------------------*/ 2266c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- ---*/ 2267b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- TOP LEVEL: GENERATE DESCRIPTION OF DATA ADDRESSES ---*/ 2268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- FROM DWARF3 DEBUG INFO ---*/ 2269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 2270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 2271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2272588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj/* Try to make p2XA(dst, fmt, args..) turn into 2273588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj VG_(xaprintf_no_f_c)(dst, fmt, args) without having to resort to 2274588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj vararg macros. As usual with everything to do with varargs, it's 2275588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj an ugly hack. 2276738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 2277588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj //#define p2XA(dstxa, format, args...) 2278588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj // VG_(xaprintf_no_f_c)(dstxa, format, ##args) 2279738856f99eea33d86ce91dcb1d6cd5b151e307casewardj*/ 2280588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj#define p2XA VG_(xaprintf_no_f_c) 2281738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 2282588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj/* Add a zero-terminating byte to DST, which must be an XArray* of 2283588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj HChar. */ 2284738856f99eea33d86ce91dcb1d6cd5b151e307casewardjstatic void zterm_XA ( XArray* dst ) 2285738856f99eea33d86ce91dcb1d6cd5b151e307casewardj{ 2286738856f99eea33d86ce91dcb1d6cd5b151e307casewardj HChar zero = 0; 2287738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (void) VG_(addBytesToXA)( dst, &zero, 1 ); 2288738856f99eea33d86ce91dcb1d6cd5b151e307casewardj} 2289738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 2290738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 2291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Evaluate the location expression/list for var, to see whether or 2292b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj not data_addr falls within the variable. If so also return the 2293b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset of data_addr from the start of the variable. Note that 2294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs, which supplies ip,sp,fp values, will be NULL for global 2295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj variables, and non-NULL for local variables. */ 2296c4431bfe04c7490ea2d74939d222d87f13f30960njnstatic Bool data_address_is_in_var ( /*OUT*/PtrdiffT* offset, 22979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* /* TyEnt */ tyents, 2298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var, 2299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj RegSummary* regs, 2300b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 2301588658b13b5ad77672f323d48fe9da0ca60b0bcbtom const DebugInfo* di ) 2302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 230350fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 2304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj SizeT var_szB; 2305b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj GXResult res; 2306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool show = False; 23079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 2308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->name); 2309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->gexpr); 2310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2311b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Figure out how big the variable is. */ 231250fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(tyents, var->typeR); 231350fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 231450fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. ML_(addVar) 231550fde23467d92281b32dd537d0d9a590263628c3sewardj should have rejected it. */ 231650fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 231750fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 231850fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 231950fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a host word 232050fde23467d92281b32dd537d0d9a590263628c3sewardj safely (without loss of info). */ 232150fde23467d92281b32dd537d0d9a590263628c3sewardj 232250fde23467d92281b32dd537d0d9a590263628c3sewardj var_szB = (SizeT)mul.ul; /* NB: truncate to host word */ 2323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) { 2325a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("VVVV: data_address_%#lx_is_in_var: %s :: ", 2326b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var->name ); 23279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(pp_TyEnt_C_ishly)( tyents, var->typeR ); 2328b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("\n"); 2329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2330b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ignore zero-sized vars; they can never match anything. */ 2332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (var_szB == 0) { 2333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) 2334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("VVVV: -> Fail (variable is zero sized)\n"); 2335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 2336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2338588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_GX)( var->gexpr, var->fbGX, regs, di ); 2339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) { 2341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("VVVV: -> "); 2342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(pp_GXResult)( res ); 2343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("\n"); 2344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2345eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (res.kind == GXR_Value 2347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && res.word <= data_addr 2348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && data_addr < res.word + var_szB) { 2349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *offset = data_addr - res.word; 2350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 2351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 2352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 2353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2354b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 2355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2356b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2357738856f99eea33d86ce91dcb1d6cd5b151e307casewardj/* Format the acquired information into DN(AME)1 and DN(AME)2, which 2358738856f99eea33d86ce91dcb1d6cd5b151e307casewardj are XArray*s of HChar, that have been initialised by the caller. 2359738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Resulting strings will be zero terminated. Information is 2360738856f99eea33d86ce91dcb1d6cd5b151e307casewardj formatted in an understandable way. Not so easy. If frameNo is 2361738856f99eea33d86ce91dcb1d6cd5b151e307casewardj -1, this is assumed to be a global variable; else a local 2362738856f99eea33d86ce91dcb1d6cd5b151e307casewardj variable. */ 2363738856f99eea33d86ce91dcb1d6cd5b151e307casewardjstatic void format_message ( /*MOD*/XArray* /* of HChar */ dn1, 2364738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /*MOD*/XArray* /* of HChar */ dn2, 2365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 2366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var, 2367c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT var_offset, 2368c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT residual_offset, 2369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* /*UChar*/ described, 2370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int frameNo, 2371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid ) 2372eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2373738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Bool have_descr, have_srcloc; 2374738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Bool xml = VG_(clo_xml); 2375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj UChar* vo_plural = var_offset == 1 ? "" : "s"; 2376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj UChar* ro_plural = residual_offset == 1 ? "" : "s"; 2377738856f99eea33d86ce91dcb1d6cd5b151e307casewardj UChar* basetag = "auxwhat"; /* a constant */ 2378738856f99eea33d86ce91dcb1d6cd5b151e307casewardj UChar tagL[32], tagR[32], xagL[32], xagR[32]; 2379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(frameNo >= -1); 2381738856f99eea33d86ce91dcb1d6cd5b151e307casewardj vg_assert(dn1 && dn2); 2382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(described); 2383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var && var->name); 2384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj have_descr = VG_(sizeXA)(described) > 0 2385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && *(UChar*)VG_(indexXA)(described,0) != '\0'; 2386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj have_srcloc = var->fileName && var->lineNo > 0; 2387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2388738856f99eea33d86ce91dcb1d6cd5b151e307casewardj tagL[0] = tagR[0] = xagL[0] = xagR[0] = 0; 2389738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 2390738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(tagL, "<%s>", basetag); // <auxwhat> 2391738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(tagR, "</%s>", basetag); // </auxwhat> 2392738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(xagL, "<x%s>", basetag); // <xauxwhat> 2393738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(xagR, "</x%s>", basetag); // </xauxwhat> 2394738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 2395738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 2396738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TAGL(_xa) p2XA(_xa, "%s", tagL) 2397738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TAGR(_xa) p2XA(_xa, "%s", tagR) 2398738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define XAGL(_xa) p2XA(_xa, "%s", xagL) 2399738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define XAGR(_xa) p2XA(_xa, "%s", xagR) 2400738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TXTL(_xa) p2XA(_xa, "%s", "<text>") 2401738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TXTR(_xa) p2XA(_xa, "%s", "</text>") 2402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ------ local cases ------ */ 2404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && (!have_srcloc) && (!have_descr) ) { 2406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc, no description: 2407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside local var "a", 2408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in frame #1 of thread 1 2409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2410738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 2411738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 2412738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2413738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside local var \"%t\",", 2414738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 2415738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 2416738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn2 ); 2417738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2418738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "in frame #%d of thread %d", frameNo, (Int)tid ); 2419738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn2 ); 2420738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 2421738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2422738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside local var \"%s\",", 2423738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 2424738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2425738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "in frame #%d of thread %d", frameNo, (Int)tid ); 2426738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 2427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && have_srcloc && (!have_descr) ) { 2430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no description: 2431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside local var "a" 2432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj declared at dsyms7.c:17, in frame #1 of thread 1 2433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2434738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 2435738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 2436738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2437738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside local var \"%t\"", 2438738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 2439738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 2440738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 2441738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 2442738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2443738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "declared at %t:%d, in frame #%d of thread %d", 2444738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo, frameNo, (Int)tid ); 2445738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 2446738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 2447738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2448738856f99eea33d86ce91dcb1d6cd5b151e307casewardj " <file>%t</file> <line>%d</line> ", 2449738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo ); 2450738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 2451738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 2452738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2453738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside local var \"%s\"", 2454738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 2455738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2456738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "declared at %s:%d, in frame #%d of thread %d", 2457738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo, frameNo, (Int)tid ); 2458738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 2459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2460b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && (!have_srcloc) && have_descr ) { 2462b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc: 2463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2 2464b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in frame #1 of thread 1 2465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2466738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 2467738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 2468738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2469738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %t%t", 2470738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 2471738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 2472738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 2473738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn2 ); 2474738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2475738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "in frame #%d of thread %d", frameNo, (Int)tid ); 2476738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn2 ); 2477738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 2478738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2479738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %s%s", 2480738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 2481738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 2482738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2483738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "in frame #%d of thread %d", frameNo, (Int)tid ); 2484738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 2485b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2486b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2487b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && have_srcloc && have_descr ) { 2488738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 2489738856f99eea33d86ce91dcb1d6cd5b151e307casewardj declared at dsyms7.c:17, in frame #1 of thread 1 */ 2490738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 2491738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 2492738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2493738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %t%t,", 2494738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 2495738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 2496738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 2497738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 2498738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 2499738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2500738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "declared at %t:%d, in frame #%d of thread %d", 2501738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo, frameNo, (Int)tid ); 2502738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 2503738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 2504738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2505738856f99eea33d86ce91dcb1d6cd5b151e307casewardj " <file>%t</file> <line>%d</line> ", 2506738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo ); 2507738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 2508738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 2509738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2510738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %s%s,", 2511738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 2512738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 2513738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2514738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "declared at %s:%d, in frame #%d of thread %d", 2515738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo, frameNo, (Int)tid ); 2516738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 2517b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2518b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2519b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ------ global cases ------ */ 2520b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && (!have_srcloc) && (!have_descr) ) { 2521b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc, no description: 2522b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside global var "a" 2523b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2524738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 2525738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 2526738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2527738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside global var \"%t\"", 2528738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 2529738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 2530738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 2531738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2532738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside global var \"%s\"", 2533738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 2534738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 2535b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2536b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2537b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && have_srcloc && (!have_descr) ) { 2538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no description: 2539b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside global var "a" 2540b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj declared at dsyms7.c:17 2541b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2542738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 2543738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 2544738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2545738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside global var \"%t\"", 2546738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 2547738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 2548738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 2549738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 2550738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2551738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "declared at %t:%d", 2552738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo); 2553738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 2554738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 2555738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2556738856f99eea33d86ce91dcb1d6cd5b151e307casewardj " <file>%t</file> <line>%d</line> ", 2557738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo ); 2558738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 2559738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 2560738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2561738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside global var \"%s\"", 2562738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 2563738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2564738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "declared at %s:%d", 2565738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo); 2566738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 2567b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2568b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && (!have_srcloc) && have_descr ) { 2570b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc: 2571b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 2572b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj a global variable 2573b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2574738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 2575738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 2576738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2577738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %t%t,", 2578738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 2579738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 2580738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 2581738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn2 ); 2582738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2583738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "a global variable"); 2584738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn2 ); 2585738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 2586738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2587738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %s%s,", 2588738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 2589738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (char*)(VG_(indexXA)(described,0)) ); 2590738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2591738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "a global variable"); 2592738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 2593b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2594b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2595b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && have_srcloc && have_descr ) { 2596738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 2597738856f99eea33d86ce91dcb1d6cd5b151e307casewardj a global variable declared at dsyms7.c:17 */ 2598738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 2599738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 2600738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2601738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %t%t,", 2602738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 2603738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 2604738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 2605738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 2606738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 2607738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2608738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "a global variable declared at %t:%d", 2609738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo); 2610738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 2611738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 2612738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2613738856f99eea33d86ce91dcb1d6cd5b151e307casewardj " <file>%t</file> <line>%d</line> ", 2614738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo ); 2615738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 2616738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 2617738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 2618738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %s%s,", 2619738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 2620738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 2621738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 2622738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "a global variable declared at %s:%d", 2623738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo); 2624738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 2625b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2626b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(0); 2628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2629738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /* Zero terminate both strings */ 2630738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dn1 ); 2631738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dn2 ); 2632738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 2633738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TAGL 2634738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TAGR 2635738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef XAGL 2636738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef XAGR 2637738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TXTL 2638738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TXTR 2639eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2640eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2641738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 2642b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Determine if data_addr is a local variable in the frame 2643738856f99eea33d86ce91dcb1d6cd5b151e307casewardj characterised by (ip,sp,fp), and if so write its description at the 2644738856f99eea33d86ce91dcb1d6cd5b151e307casewardj ends of DNAME{1,2}, which are XArray*s of HChar, that have been 2645738856f99eea33d86ce91dcb1d6cd5b151e307casewardj initialised by the caller, zero terminate both, and return True. 2646738856f99eea33d86ce91dcb1d6cd5b151e307casewardj If it's not a local variable in said frame, return False. */ 2647b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic 2648738856f99eea33d86ce91dcb1d6cd5b151e307casewardjBool consider_vars_in_frame ( /*MOD*/XArray* /* of HChar */ dname1, 2649738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /*MOD*/XArray* /* of HChar */ dname2, 2650b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 2651b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr ip, Addr sp, Addr fp, 2652b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* shown to user: */ 2653b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid, Int frameNo ) 2654eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2655b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word i; 2656b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 2657b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj RegSummary regs; 2658b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool debug = False; 2659b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2660b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj static UInt n_search = 0; 2661b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj static UInt n_steps = 0; 2662b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_search++; 2663b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 2664a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("QQQQ: cvif: ip,sp,fp %#lx,%#lx,%#lx\n", ip,sp,fp); 2665b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* first, find the DebugInfo that pertains to 'ip'. */ 2666b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di; di = di->next) { 2667b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_steps++; 2668b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* text segment missing? unlikely, but handle it .. */ 2669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->text_present || di->text_size == 0) 2670b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2671b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok. So does this text mapping bracket the ip? */ 2672b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_avma <= ip && ip < di->text_avma + di->text_size) 2673b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 2674b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2675b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Didn't find it. Strange -- means ip is a code address outside 2677b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj of any mapped text segment. Unlikely but not impossible -- app 2678b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj could be generating code to run. */ 2679b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di) 2680b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 2681b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2682b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0 && ((n_search & 0x1) == 0)) 2683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("consider_vars_in_frame: %u searches, " 2684b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "%u DebugInfos looked at\n", 2685b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_search, n_steps); 2686b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Start of performance-enhancing hack: once every ??? (chosen 2687b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj hackily after profiling) successful searches, move the found 2688b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo one step closer to the start of the list. This makes 2689b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj future searches cheaper. */ 2690b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ((n_search & 0xFFFF) == 0) { 2691b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Move si one step closer to the start of the list. */ 2692b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj move_DebugInfo_one_step_forward( di ); 2693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2694b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* End of performance-enhancing hack. */ 2695b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2696b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* any var info at all? */ 2697b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->varinfo) 2698b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 2699b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2700b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Work through the scopes from most deeply nested outwards, 2701b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj looking for code address ranges that bracket 'ip'. The 2702b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj variables on each such address range found are in scope right 2703b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj now. Don't descend to level zero as that is the global 2704b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj scope. */ 2705b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.ip = ip; 2706b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.sp = sp; 2707b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.fp = fp; 2708b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* "for each scope, working outwards ..." */ 2710b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) { 2711b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* vars; 2712b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word j; 2713b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* arange; 2714b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* this_scope 2715b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj = *(OSet**)VG_(indexXA)( di->varinfo, i ); 2716b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 2717b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("QQQQ: considering scope %ld\n", (Word)i); 2718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!this_scope) 2719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Find the set of variables in this scope that 2721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj bracket the program counter. */ 2722b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj arange = VG_(OSetGen_LookupWithCmp)( 2723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj this_scope, &ip, 2724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(cmp_for_DiAddrRange_range) 2725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ); 2726b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!arange) 2727b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2728b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* stay sane */ 2729b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->aMin <= arange->aMax); 2730b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* It must bracket the ip we asked for, else 2731b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(cmp_for_DiAddrRange_range) is somehow broken. */ 2732b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->aMin <= ip && ip <= arange->aMax); 2733b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* It must have an attached XArray of DiVariables. */ 2734b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vars = arange->vars; 2735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(vars); 2736b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* But it mustn't cover the entire address range. We only 2737b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj expect that to happen for the global scope (level 0), which 2738b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj we're not looking at here. Except, it may cover the entire 2739b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj address range, but in that case the vars array must be 2740b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj empty. */ 2741b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(! (arange->aMin == (Addr)0 2742b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && arange->aMax == ~(Addr)0 2743b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && VG_(sizeXA)(vars) > 0) ); 2744b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < VG_(sizeXA)( vars ); j++) { 2745b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j ); 2746c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT offset; 2747b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 2748a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n", 2749b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var->name,arange->aMin,arange->aMax,ip); 27509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (data_address_is_in_var( &offset, di->admin_tyents, 27519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var, ®s, 2752588658b13b5ad77672f323d48fe9da0ca60b0bcbtom data_addr, di )) { 2753c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT residual_offset = 0; 2754b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* described = ML_(describe_type)( &residual_offset, 27559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->admin_tyents, 27569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR, offset ); 2757738856f99eea33d86ce91dcb1d6cd5b151e307casewardj format_message( dname1, dname2, 2758b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var, offset, residual_offset, 2759b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj described, frameNo, tid ); 2760b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)( described ); 2761b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 2762b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2763b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2764b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2765b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2766b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 2767eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2768eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2769738856f99eea33d86ce91dcb1d6cd5b151e307casewardj/* Try to form some description of DATA_ADDR by looking at the DWARF3 2770b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debug info we have. This considers all global variables, and all 2771738856f99eea33d86ce91dcb1d6cd5b151e307casewardj frames in the stacks of all threads. Result is written at the ends 2772738856f99eea33d86ce91dcb1d6cd5b151e307casewardj of DNAME{1,2}V, which are XArray*s of HChar, that have been 2773738856f99eea33d86ce91dcb1d6cd5b151e307casewardj initialised by the caller, and True is returned. If no description 2774738856f99eea33d86ce91dcb1d6cd5b151e307casewardj is created, False is returned. Regardless of the return value, 2775738856f99eea33d86ce91dcb1d6cd5b151e307casewardj DNAME{1,2}V are guaranteed to be zero terminated after the call. 2776738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 2777738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Note that after the call, DNAME{1,2} may have more than one 2778738856f99eea33d86ce91dcb1d6cd5b151e307casewardj trailing zero, so callers should establish the useful text length 2779738856f99eea33d86ce91dcb1d6cd5b151e307casewardj using VG_(strlen) on the contents, rather than VG_(sizeXA) on the 2780738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XArray itself. 2781738856f99eea33d86ce91dcb1d6cd5b151e307casewardj*/ 2782738856f99eea33d86ce91dcb1d6cd5b151e307casewardjBool VG_(get_data_description)( 2783738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /*MOD*/ void* /* really, XArray* of HChar */ dname1v, 2784738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /*MOD*/ void* /* really, XArray* of HChar */ dname2v, 2785738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Addr data_addr 2786738856f99eea33d86ce91dcb1d6cd5b151e307casewardj ) 2787eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2788b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# define N_FRAMES 8 2789b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr ips[N_FRAMES], sps[N_FRAMES], fps[N_FRAMES]; 2790b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj UInt n_frames; 2791b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2792b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr stack_min, stack_max; 2793b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid; 2794b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool found; 2795b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 2796b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word j; 2797b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2798738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XArray* dname1 = (XArray*)dname1v; 2799738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XArray* dname2 = (XArray*)dname2v; 2800b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2801a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart if (0) VG_(printf)("get_data_description: dataaddr %#lx\n", data_addr); 2802b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* First, see if data_addr is (or is part of) a global variable. 2803b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Loop over the DebugInfos we have. Check data_addr against the 2804b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj outermost scope of all of them, as that should be a global 2805b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj scope. */ 2806b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 2807b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* global_scope; 28089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word gs_size; 2809b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr zero; 2810b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* global_arange; 2811b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word i; 2812b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* vars; 2813b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2814b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* text segment missing? unlikely, but handle it .. */ 2815b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->text_present || di->text_size == 0) 2816b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2817b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* any var info at all? */ 2818b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->varinfo) 2819b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2820b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* perhaps this object didn't contribute any vars at all? */ 2821b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (VG_(sizeXA)( di->varinfo ) == 0) 2822b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2823b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj global_scope = *(OSet**)VG_(indexXA)( di->varinfo, 0 ); 2824b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_scope); 2825b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj gs_size = VG_(OSetGen_Size)( global_scope ); 2826b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* The global scope might be completely empty if this 2827b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj compilation unit declared locals but nothing global. */ 2828b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (gs_size == 0) 2829b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2830b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* But if it isn't empty, then it must contain exactly one 2831b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj element, which covers the entire address range. */ 2832b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(gs_size == 1); 2833b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Fish out the global scope and check it is as expected. */ 2834b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj zero = 0; 2835b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj global_arange 2836b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj = VG_(OSetGen_Lookup)( global_scope, &zero ); 2837b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* The global range from (Addr)0 to ~(Addr)0 must exist */ 2838b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_arange); 2839b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_arange->aMin == (Addr)0 2840b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && global_arange->aMax == ~(Addr)0); 2841b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Any vars in this range? */ 2842b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!global_arange->vars) 2843b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2844b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok, there are some vars in the global scope of this 2845b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo. Wade through them and see if the data addresses 2846b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj of any of them bracket data_addr. */ 2847b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vars = global_arange->vars; 2848b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = 0; i < VG_(sizeXA)( vars ); i++) { 2849c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT offset; 2850b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, i ); 2851b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->name); 2852b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Note we use a NULL RegSummary* here. It can't make any 2853b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sense for a global variable to have a location expression 2854b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which depends on a SP/FP/IP value. So don't supply any. 2855b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj This means, if the evaluation of the location 2856b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj expression/list requires a register, we have to let it 2857b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj fail. */ 28589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (data_address_is_in_var( &offset, di->admin_tyents, var, 2859b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj NULL/* RegSummary* */, 2860588658b13b5ad77672f323d48fe9da0ca60b0bcbtom data_addr, di )) { 2861c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT residual_offset = 0; 2862b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* described = ML_(describe_type)( &residual_offset, 28639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->admin_tyents, 28649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR, offset ); 2865738856f99eea33d86ce91dcb1d6cd5b151e307casewardj format_message( dname1, dname2, 2866b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var, offset, residual_offset, 2867b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj described, -1/*frameNo*/, tid ); 2868b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)( described ); 2869738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 2870738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 2871b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 2872b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2873b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2874b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2875b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2876b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok, well it's not a global variable. So now let's snoop around 2877b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in the stacks of all the threads. First try to figure out which 2878b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj thread's stack data_addr is in. */ 2879b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2880b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* --- KLUDGE --- Try examining the top frame of all thread stacks. 2881b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj This finds variables which are not stack allocated but are not 2882b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj globally visible either; specifically it appears to pick up 2883b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj variables which are visible only within a compilation unit. 2884b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj These will have the address range of the compilation unit and 2885b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj tend to live at Scope level 1. */ 2886b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(thread_stack_reset_iter)(&tid); 2887b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) { 2888b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (stack_min >= stack_max) 2889b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; /* ignore obviously stupid cases */ 2890738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (consider_vars_in_frame( dname1, dname2, 2891b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, 2892b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(get_IP)(tid), 2893b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(get_SP)(tid), 2894b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(get_FP)(tid), tid, 0 )) { 2895738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 2896738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 2897b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 2898b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2899b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2900b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* --- end KLUDGE --- */ 2901b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2902b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Perhaps it's on a thread's stack? */ 2903b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj found = False; 2904b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(thread_stack_reset_iter)(&tid); 2905b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) { 2906b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (stack_min >= stack_max) 2907b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; /* ignore obviously stupid cases */ 2908b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (stack_min - VG_STACK_REDZONE_SZB <= data_addr 2909b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && data_addr <= stack_max) { 2910b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj found = True; 2911b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 2912b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2913b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2914b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!found) { 2915738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 2916738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 2917b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 2918b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2919b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2920b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We conclude data_addr is in thread tid's stack. Unwind the 2921b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj stack to get a bunch of (ip,sp,fp) triples describing the 2922b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj frames, and for each frame, consider the local variables. */ 2923b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_frames = VG_(get_StackTrace)( tid, ips, N_FRAMES, 2924b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sps, fps, 0/*first_ip_delta*/ ); 2925b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj 2926b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* As a result of KLUDGE above, starting the loop at j = 0 2927b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj duplicates examination of the top frame and so isn't necessary. 2928b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Oh well. */ 2929b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_frames >= 0 && n_frames <= N_FRAMES); 2930b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < n_frames; j++) { 2931738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (consider_vars_in_frame( dname1, dname2, 2932b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, 2933b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj ips[j], 2934b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sps[j], fps[j], tid, j )) { 2935738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 2936738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 2937b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 2938b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2939b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Now, it appears that gcc sometimes appears to produce 2940b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj location lists whose ranges don't actually cover the call 2941b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj instruction, even though the address of the variable in 2942b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj question is passed as a parameter in the call. AFAICS this 2943b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is simply a bug in gcc - how can the variable be claimed not 2944b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj exist in memory (on the stack) for the duration of a call in 2945b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which its address is passed? But anyway, in the particular 2946b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case I investigated (memcheck/tests/varinfo6.c, call to croak 2947b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj on line 2999, local var budget declared at line 3115 2948b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj appearing not to exist across the call to mainSort on line 2949b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3143, "gcc.orig (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2)" on 2950b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj amd64), the variable's location list does claim it exists 2951b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj starting at the first byte of the first instruction after the 2952b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj call instruction. So, call consider_vars_in_frame a second 2953b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj time, but this time add 1 to the IP. GDB handles this 2954b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj example with no difficulty, which leads me to believe that 2955b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj either (1) I misunderstood something, or (2) GDB has an 2956b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj equivalent kludge. */ 2957b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj if (j > 0 /* this is a non-innermost frame */ 2958738856f99eea33d86ce91dcb1d6cd5b151e307casewardj && consider_vars_in_frame( dname1, dname2, 2959b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj data_addr, 2960b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj ips[j] + 1, 2961b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj sps[j], fps[j], tid, j )) { 2962738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 2963738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 2964b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 2965b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2966b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2967b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2968b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We didn't find anything useful. */ 2969738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 2970738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 2971b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 2972b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# undef N_FRAMES 2973eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2974eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2975b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 29769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj////////////////////////////////////////////////////////////////// 29779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// // 29789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// Support for other kinds of queries to the Dwarf3 var info // 29799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// // 29809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj////////////////////////////////////////////////////////////////// 29819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 29829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Figure out if the variable 'var' has a location that is linearly 29839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj dependent on a stack pointer value, or a frame pointer value, and 29849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if it is, add a description of it to 'blocks'. Otherwise ignore 29859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. If 'arrays_only' is True, also ignore it unless it has an 29869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj array type. */ 29879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 29889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic 29899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks, 29909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* /* TyEnt */ tyents, 2991588658b13b5ad77672f323d48fe9da0ca60b0bcbtom Addr ip, const DebugInfo* di, DiVariable* var, 29929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool arrays_only ) 29939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 29949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res_sp_6k, res_sp_7k, res_fp_6k, res_fp_7k; 29959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj RegSummary regs; 299650fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 29979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool isVec; 29989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ty; 29999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 30009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool debug = False; 30019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0&&debug) 30029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("adeps: var %s\n", var->name ); 30039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 30049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Figure out how big the variable is. */ 300550fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(tyents, var->typeR); 300650fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 300750fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. ML_(addVar) 300850fde23467d92281b32dd537d0d9a590263628c3sewardj should have rejected it. */ 300950fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 301050fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 301150fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 301250fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a host word 301350fde23467d92281b32dd537d0d9a590263628c3sewardj safely (without loss of info). */ 30149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 30159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* skip if non-array and we're only interested in arrays */ 30169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ty = ML_(TyEnts__index_by_cuOff)( tyents, NULL, var->typeR ); 30179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty); 30189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty)); 30199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (ty->tag == Te_UNKNOWN) 30209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return; /* perhaps we should complain in this case? */ 30219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj isVec = ty->tag == Te_TyArray; 30229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (arrays_only && !isVec) 30239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return; 30249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 30259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) {ML_(pp_TyEnt_C_ishly)(tyents, var->typeR); 30269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)(" %s\n", var->name);} 30279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 30289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Do some test evaluations of the variable's location expression, 30299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj in order to guess whether it is sp-relative, fp-relative, or 30309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj none. A crude hack, which can be interpreted roughly as finding 30319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj the first derivative of the location expression w.r.t. the 30329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj supplied frame and stack pointer values. */ 30339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 0; 30349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 30359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 6 * 1024; 3036588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_sp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 30379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 30389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 0; 30399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 30409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 7 * 1024; 3041588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_sp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 30429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 30439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 6 * 1024; 30449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 30459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 0; 3046588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_fp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 30479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 30489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 7 * 1024; 30499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 30509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 0; 3051588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_fp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 30529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 30539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_sp_7k.kind); 30549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_fp_6k.kind); 30559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_fp_7k.kind); 30569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 30579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (res_sp_6k.kind == GXR_Value) { 30589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj StackBlock block; 30599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res; 30609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj UWord sp_delta = res_sp_7k.word - res_sp_6k.word; 30619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj UWord fp_delta = res_fp_7k.word - res_fp_6k.word; 30629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(sp_delta == 0 || sp_delta == 1024); 30639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(fp_delta == 0 || fp_delta == 1024); 30649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 30659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 0 && fp_delta == 0) { 30669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* depends neither on sp nor fp, so it can't be a stack 30679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj local. Ignore it. */ 30689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 30699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else 30709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 1024 && fp_delta == 0) { 30719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = regs.fp = 0; 30729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 3073588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 30749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(res.kind == GXR_Value); 30759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 30769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)(" %5ld .. %5ld (sp) %s\n", 307750fde23467d92281b32dd537d0d9a590263628c3sewardj res.word, res.word + ((UWord)mul.ul) - 1, var->name); 30789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.base = res.word; 307950fde23467d92281b32dd537d0d9a590263628c3sewardj block.szB = (SizeT)mul.ul; 30809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.spRel = True; 30819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.isVec = isVec; 30829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)( &block.name[0], 0, sizeof(block.name) ); 30839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (var->name) 30849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 ); 30859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.name[ sizeof(block.name)-1 ] = 0; 30869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( blocks, &block ); 30879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 30889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else 30899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 0 && fp_delta == 1024) { 30909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = regs.fp = 0; 30919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 3092588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 30939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(res.kind == GXR_Value); 30949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 30959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)(" %5ld .. %5ld (FP) %s\n", 309650fde23467d92281b32dd537d0d9a590263628c3sewardj res.word, res.word + ((UWord)mul.ul) - 1, var->name); 30979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.base = res.word; 309850fde23467d92281b32dd537d0d9a590263628c3sewardj block.szB = (SizeT)mul.ul; 30999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.spRel = False; 31009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.isVec = isVec; 31019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)( &block.name[0], 0, sizeof(block.name) ); 31029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (var->name) 31039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 ); 31049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.name[ sizeof(block.name)-1 ] = 0; 31059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( blocks, &block ); 31069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 31079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else { 31089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(0); 31099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 31109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 31119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 31129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Get an XArray of StackBlock which describe the stack (auto) blocks 31159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for this ip. The caller is expected to free the XArray at some 31169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj point. If 'arrays_only' is True, only array-typed blocks are 31179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj returned; otherwise blocks of all types are returned. */ 31189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid* /* really, XArray* of StackBlock */ 31209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(di_get_stack_blocks_at_ip)( Addr ip, Bool arrays_only ) 31219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 31229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* This is a derivation of consider_vars_in_frame() above. */ 31239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word i; 31249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo* di; 31259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj RegSummary regs; 31269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool debug = False; 31279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* res = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dgsbai.1", 31299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(dinfo_free), 31309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj sizeof(StackBlock) ); 31319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj static UInt n_search = 0; 31339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj static UInt n_steps = 0; 31349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_search++; 31359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 31369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: dgsbai: ip %#lx\n", ip); 31379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* first, find the DebugInfo that pertains to 'ip'. */ 31389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (di = debugInfo_list; di; di = di->next) { 31399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_steps++; 31409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* text segment missing? unlikely, but handle it .. */ 31419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->text_present || di->text_size == 0) 31429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 31439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok. So does this text mapping bracket the ip? */ 31449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (di->text_avma <= ip && ip < di->text_avma + di->text_size) 31459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj break; 31469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 31479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Didn't find it. Strange -- means ip is a code address outside 31499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj of any mapped text segment. Unlikely but not impossible -- app 31509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj could be generating code to run. */ 31519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di) 31529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; /* currently empty */ 31539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0 && ((n_search & 0x1) == 0)) 31559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("VG_(di_get_stack_blocks_at_ip): %u searches, " 31569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj "%u DebugInfos looked at\n", 31579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_search, n_steps); 31589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Start of performance-enhancing hack: once every ??? (chosen 31599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj hackily after profiling) successful searches, move the found 31609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo one step closer to the start of the list. This makes 31619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj future searches cheaper. */ 31629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if ((n_search & 0xFFFF) == 0) { 31639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Move si one step closer to the start of the list. */ 31649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj move_DebugInfo_one_step_forward( di ); 31659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 31669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* End of performance-enhancing hack. */ 31679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* any var info at all? */ 31699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->varinfo) 31709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; /* currently empty */ 31719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Work through the scopes from most deeply nested outwards, 31739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj looking for code address ranges that bracket 'ip'. The 31749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj variables on each such address range found are in scope right 31759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj now. Don't descend to level zero as that is the global 31769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj scope. */ 31779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 31789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 0; 31799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 0; 31809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* "for each scope, working outwards ..." */ 31829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) { 31839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* vars; 31849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word j; 31859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiAddrRange* arange; 31869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj OSet* this_scope 31879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj = *(OSet**)VG_(indexXA)( di->varinfo, i ); 31889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 31899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: considering scope %ld\n", (Word)i); 31909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!this_scope) 31919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 31929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Find the set of variables in this scope that 31939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj bracket the program counter. */ 31949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj arange = VG_(OSetGen_LookupWithCmp)( 31959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj this_scope, &ip, 31969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(cmp_for_DiAddrRange_range) 31979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ); 31989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!arange) 31999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 32009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* stay sane */ 32019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(arange->aMin <= arange->aMax); 32029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* It must bracket the ip we asked for, else 32039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(cmp_for_DiAddrRange_range) is somehow broken. */ 32049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(arange->aMin <= ip && ip <= arange->aMax); 32059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* It must have an attached XArray of DiVariables. */ 32069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vars = arange->vars; 32079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(vars); 32089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* But it mustn't cover the entire address range. We only 32099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj expect that to happen for the global scope (level 0), which 32109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj we're not looking at here. Except, it may cover the entire 32119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj address range, but in that case the vars array must be 32129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj empty. */ 32139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(! (arange->aMin == (Addr)0 32149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj && arange->aMax == ~(Addr)0 32159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj && VG_(sizeXA)(vars) > 0) ); 32169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (j = 0; j < VG_(sizeXA)( vars ); j++) { 32179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j ); 32189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 32199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n", 32209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->name,arange->aMin,arange->aMax,ip); 32219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj analyse_deps( res, di->admin_tyents, ip, 3222588658b13b5ad77672f323d48fe9da0ca60b0bcbtom di, var, arrays_only ); 32239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 32249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 32259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 32269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; 32279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 32289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 32299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 32309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Get an array of GlobalBlock which describe the global blocks owned 32319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj by the shared object characterised by the given di_handle. Asserts 32329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if the handle is invalid. The caller is responsible for freeing 32339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj the array at some point. If 'arrays_only' is True, only 32349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj array-typed blocks are returned; otherwise blocks of all types are 32359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj returned. */ 32369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 32379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid* /* really, XArray* of GlobalBlock */ 32389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(di_get_global_blocks_from_dihandle) ( ULong di_handle, 32399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool arrays_only ) 32409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 32419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* This is a derivation of consider_vars_in_frame() above. */ 32429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 32439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo* di; 32449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* gvars; /* XArray* of GlobalBlock */ 32459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word nScopes, scopeIx; 32469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 32479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* The first thing to do is find the DebugInfo that 32489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj pertains to 'di_handle'. */ 32499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(di_handle > 0); 32509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (di = debugInfo_list; di; di = di->next) { 32519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (di->handle == di_handle) 32529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj break; 32539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 32549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 32559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* If this fails, we were unable to find any DebugInfo with the 32569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj given handle. This is considered an error on the part of the 32579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj caller. */ 32589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(di != NULL); 32599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 32609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* we'll put the collected variables in here. */ 32619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gvars = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dggbfd.1", 32629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(dinfo_free), sizeof(GlobalBlock) ); 32639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(gvars); 32649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 32659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* any var info at all? */ 32669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->varinfo) 32679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return gvars; 32689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 32699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* we'll iterate over all the variables we can find, even if 32709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it seems senseless to visit stack-allocated variables */ 32719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over all scopes */ 32729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj nScopes = VG_(sizeXA)( di->varinfo ); 32739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (scopeIx = 0; scopeIx < nScopes; scopeIx++) { 32749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 32759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over each (code) address range at the current scope */ 32769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiAddrRange* range; 32779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj OSet* /* of DiAddrInfo */ scope 32789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj = *(OSet**)VG_(indexXA)( di->varinfo, scopeIx ); 32799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(scope); 32809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(OSetGen_ResetIter)(scope); 32819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj while ( (range = VG_(OSetGen_Next)(scope)) ) { 32829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 32839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over each variable in the current address range */ 32849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word nVars, varIx; 32859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(range->vars); 32869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj nVars = VG_(sizeXA)( range->vars ); 32879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (varIx = 0; varIx < nVars; varIx++) { 32889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 32899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool isVec; 32909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res; 329150fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 32929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GlobalBlock gb; 32939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ty; 32949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiVariable* var = VG_(indexXA)( range->vars, varIx ); 32959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(var->name); 32969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("at depth %ld var %s ", scopeIx, var->name ); 32979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 32989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Now figure out if this variable has a constant address 32999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj (that is, independent of FP, SP, phase of moon, etc), 33009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj and if so, what the address is. Any variable with a 33019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj constant address is deemed to be a global so we collect 33029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. */ 33039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) { VG_(printf)("EVAL: "); ML_(pp_GX)(var->gexpr); 33049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("\n"); } 3305588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_trivial_GX)( var->gexpr, di ); 33069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 33079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Not a constant address => not interesting */ 33089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (res.kind != GXR_Value) { 33099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("FAIL\n"); 33109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 33119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 33129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 33139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok, it's a constant address. See if we want to collect 33149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. */ 33159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("%#lx\n", res.word); 33169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 33179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Figure out how big the variable is. */ 331850fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(di->admin_tyents, var->typeR); 33199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 332050fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 332150fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. 332250fde23467d92281b32dd537d0d9a590263628c3sewardj ML_(addVar) should have rejected it. */ 332350fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 332450fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 332550fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 332650fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a 332750fde23467d92281b32dd537d0d9a590263628c3sewardj host word safely (without loss of info). */ 33289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 33299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* skip if non-array and we're only interested in 33309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj arrays */ 33319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ty = ML_(TyEnts__index_by_cuOff)( di->admin_tyents, NULL, 33329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR ); 33339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty); 33349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty)); 33359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (ty->tag == Te_UNKNOWN) 33369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; /* perhaps we should complain in this case? */ 33379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 33389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj isVec = ty->tag == Te_TyArray; 33399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (arrays_only && !isVec) continue; 33409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 33419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok, so collect it! */ 33429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(var->name); 33439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(di->soname); 33449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("XXXX %s %s %d\n", var->name, 33459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->fileName?(HChar*)var->fileName 33469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj :"??",var->lineNo); 33479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)(&gb, 0, sizeof(gb)); 33489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gb.addr = res.word; 334950fde23467d92281b32dd537d0d9a590263628c3sewardj gb.szB = (SizeT)mul.ul; 33509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gb.isVec = isVec; 33519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)(&gb.name[0], var->name, sizeof(gb.name)-1); 33529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)(&gb.soname[0], di->soname, sizeof(gb.soname)-1); 33539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(gb.name[ sizeof(gb.name)-1 ] == 0); 33549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(gb.soname[ sizeof(gb.soname)-1 ] == 0); 33559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 33569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( gvars, &gb ); 33579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 33589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* for (varIx = 0; varIx < nVars; varIx++) */ 33599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 33609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* while ( (range = VG_(OSetGen_Next)(scope)) ) */ 33619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 33629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* for (scopeIx = 0; scopeIx < nScopes; scopeIx++) */ 33639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 33649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return gvars; 33659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 33669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 33679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 3368b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 3369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- DebugInfo accessor functions ---*/ 3370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 3371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3372e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjconst DebugInfo* VG_(next_DebugInfo)(const DebugInfo* di) 3373eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == NULL) 3375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return debugInfo_list; 3376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->next; 3377eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3378eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3379e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjAddr VG_(DebugInfo_get_text_avma)(const DebugInfo* di) 3380eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_avma : 0; 3382eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3383eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3384e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjSizeT VG_(DebugInfo_get_text_size)(const DebugInfo* di) 3385eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_size : 0; 3387eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3388eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3389e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjAddr VG_(DebugInfo_get_plt_avma)(const DebugInfo* di) 3390092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 3391092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->plt_present ? di->plt_avma : 0; 3392092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 3393092b6268cc4a38ae9ee41d1e3355937536ddc579bart 3394e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjSizeT VG_(DebugInfo_get_plt_size)(const DebugInfo* di) 3395092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 3396092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->plt_present ? di->plt_size : 0; 3397092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 3398092b6268cc4a38ae9ee41d1e3355937536ddc579bart 3399e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjAddr VG_(DebugInfo_get_gotplt_avma)(const DebugInfo* di) 3400092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 3401092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->gotplt_present ? di->gotplt_avma : 0; 3402092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 3403092b6268cc4a38ae9ee41d1e3355937536ddc579bart 3404e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjSizeT VG_(DebugInfo_get_gotplt_size)(const DebugInfo* di) 3405092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 3406092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->gotplt_present ? di->gotplt_size : 0; 3407092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 3408092b6268cc4a38ae9ee41d1e3355937536ddc579bart 3409e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjconst UChar* VG_(DebugInfo_get_soname)(const DebugInfo* di) 3410eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3411b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->soname; 3412b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 3413eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3414e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjconst UChar* VG_(DebugInfo_get_filename)(const DebugInfo* di) 3415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 3416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->filename; 3417eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3418eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3419e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjPtrdiffT VG_(DebugInfo_get_text_bias)(const DebugInfo* di) 3420bbec7728efefaa650970dd1f0282b77040287133sewardj{ 3421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_bias : 0; 3422bbec7728efefaa650970dd1f0282b77040287133sewardj} 3423bbec7728efefaa650970dd1f0282b77040287133sewardj 3424e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjInt VG_(DebugInfo_syms_howmany) ( const DebugInfo *si ) 3425eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3426eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return si->symtab_used; 3427eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3428eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3429e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjvoid VG_(DebugInfo_syms_getidx) ( const DebugInfo *si, 3430e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj Int idx, 3431e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj /*OUT*/Addr* avma, 3432e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj /*OUT*/Addr* tocptr, 3433e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj /*OUT*/UInt* size, 3434e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj /*OUT*/HChar** name, 3435e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj /*OUT*/Bool* isText ) 3436eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3437eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(idx >= 0 && idx < si->symtab_used); 3438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (avma) *avma = si->symtab[idx].addr; 34394ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (tocptr) *tocptr = si->symtab[idx].tocptr; 34404ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (size) *size = si->symtab[idx].size; 34414ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (name) *name = (HChar*)si->symtab[idx].name; 3442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (isText) *isText = si->symtab[idx].isText; 3443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 3444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 3447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- SectKind query functions ---*/ 3448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 3449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Convert a VgSectKind to a string, which must be copied if you want 3451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to change it. */ 3452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjconst HChar* VG_(pp_SectKind)( VgSectKind kind ) 3453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 3454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj switch (kind) { 3455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectUnknown: return "Unknown"; 3456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectText: return "Text"; 3457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectData: return "Data"; 3458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectBSS: return "BSS"; 3459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectGOT: return "GOT"; 3460b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectPLT: return "PLT"; 3461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectOPD: return "OPD"; 34625706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj case Vg_SectGOTPLT: return "GOTPLT"; 3463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj default: vg_assert(0); 3464b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 3466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3467b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Given an address 'a', make a guess of which section of which object 3468b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj it comes from. If name is non-NULL, then the last n_name-1 3469b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj characters of the object's name is put in name[0 .. n_name-2], and 3470b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj name[n_name-1] is set to zero (guaranteed zero terminated). */ 3471b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3472e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjVgSectKind VG_(DebugInfo_sect_kind)( /*OUT*/UChar* name, SizeT n_name, 3473e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj Addr a) 3474b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 3475b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 3476b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VgSectKind res = Vg_SectUnknown; 3477b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3478b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 3479b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0) 3481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)( 3482e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj "addr=%#lx di=%p %s got=%#lx,%ld plt=%#lx,%ld " 3483e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj "data=%#lx,%ld bss=%#lx,%ld\n", 3484b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj a, di, di->filename, 3485b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->got_avma, di->got_size, 3486b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->plt_avma, di->plt_size, 3487b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_avma, di->data_size, 3488b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->bss_avma, di->bss_size); 3489b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3490b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 3491b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_size > 0 3492b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->text_avma && a < di->text_avma + di->text_size) { 3493b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectText; 3494b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3495b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3496b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->data_present 3497b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_size > 0 3498b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->data_avma && a < di->data_avma + di->data_size) { 3499b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectData; 3500b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3501b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3502b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->sdata_present 3503b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_size > 0 3504b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->sdata_avma && a < di->sdata_avma + di->sdata_size) { 3505b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectData; 3506b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3507b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3508b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->bss_present 3509b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_size > 0 3510b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->bss_avma && a < di->bss_avma + di->bss_size) { 3511b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectBSS; 3512b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3513b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 35145706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj if (di->sbss_present 35155706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->sbss_size > 0 35165706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && a >= di->sbss_avma && a < di->sbss_avma + di->sbss_size) { 35175706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj res = Vg_SectBSS; 35185706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj break; 35195706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj } 3520b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->plt_present 3521b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->plt_size > 0 3522b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->plt_avma && a < di->plt_avma + di->plt_size) { 3523b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectPLT; 3524b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3525b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3526b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->got_present 3527b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->got_size > 0 3528b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->got_avma && a < di->got_avma + di->got_size) { 3529b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectGOT; 3530b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3531b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3532092b6268cc4a38ae9ee41d1e3355937536ddc579bart if (di->gotplt_present 3533092b6268cc4a38ae9ee41d1e3355937536ddc579bart && di->gotplt_size > 0 3534092b6268cc4a38ae9ee41d1e3355937536ddc579bart && a >= di->gotplt_avma && a < di->gotplt_avma + di->gotplt_size) { 3535092b6268cc4a38ae9ee41d1e3355937536ddc579bart res = Vg_SectGOTPLT; 3536092b6268cc4a38ae9ee41d1e3355937536ddc579bart break; 3537092b6268cc4a38ae9ee41d1e3355937536ddc579bart } 3538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->opd_present 3539b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->opd_size > 0 3540b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->opd_avma && a < di->opd_avma + di->opd_size) { 3541b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectOPD; 3542b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3543b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3544b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* we could also check for .eh_frame, if anyone really cares */ 3545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3546b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3547b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert( (di == NULL && res == Vg_SectUnknown) 3548b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || (di != NULL && res != Vg_SectUnknown) ); 3549b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3550b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (name) { 3551b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3552b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_name >= 8); 3553b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3554b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di && di->filename) { 3555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int i, j; 3556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int fnlen = VG_(strlen)(di->filename); 3557b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int start_at = 1 + fnlen - n_name; 3558b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (start_at < 0) start_at = 0; 3559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(start_at < fnlen); 3560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj i = start_at; j = 0; 3561b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 3562d5dea1dabc523d3f96bafd52ae9586abd8797416bart vg_assert(j >= 0 && j < n_name); 3563b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(i >= 0 && i <= fnlen); 3564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj name[j] = di->filename[i]; 3565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->filename[i] == 0) break; 3566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj i++; j++; 3567b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3568d5dea1dabc523d3f96bafd52ae9586abd8797416bart vg_assert(i == fnlen); 3569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 3570b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)(name, n_name, "%s", "???"); 3571b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3572b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3573b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj name[n_name-1] = 0; 3574b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3575b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3576b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return res; 3577b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3578eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3579eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3580eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 3581eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- end ---*/ 3582eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 3583