debuginfo.c revision f98e1c03ce4bea1fb092cdea5571c41f29f6df9b
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 114d474d086188fd1f29fa97dbd84d8ea2e589a9b8sewardj Copyright (C) 2000-2008 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 Stabs reader greatly improved by Nick Nethercote, Apr 02. 33eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj This module was also extensively hacked on by Jeremy Fitzhardinge 34eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj and Tom Hughes. 35eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 36eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 37eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_basics.h" 384cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj#include "pub_core_vki.h" 39eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_threadstate.h" 40b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_debuginfo.h" /* self */ 41eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_demangle.h" 42eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_libcbase.h" 43eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_libcassert.h" 44eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_libcprint.h" 45b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_libcfile.h" 46eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_options.h" 47b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_redir.h" // VG_(redir_notify_{new,delete}_SegInfo) 48eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_aspacemgr.h" 49b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_machine.h" // VG_PLAT_USES_PPCTOC 5072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj#include "pub_core_xarray.h" 51b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_oset.h" 52b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_stacktrace.h" // VG_(get_StackTrace) 53b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 54b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_misc.h" /* dinfo_zalloc/free */ 55b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_d3basics.h" /* ML_(pp_GX) */ 56b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_tytypes.h" 57eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "priv_storage.h" 58eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "priv_readdwarf.h" 59eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "priv_readstabs.h" 604ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#if defined(VGO_linux) 614ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# include "priv_readelf.h" 62b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# include "priv_readdwarf3.h" 634ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#elif defined(VGO_aix5) 644ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# include "pub_core_debuglog.h" 654ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# include "pub_core_libcproc.h" 664ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# include "pub_core_libcfile.h" 674ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# include "priv_readxcoff.h" 684ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#endif 69eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 70c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 71c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/*------------------------------------------------------------*/ 72c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/*--- The _svma / _avma / _image / _bias naming scheme ---*/ 73c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/*------------------------------------------------------------*/ 74c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 75c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/* JRS 11 Jan 07: I find the different kinds of addresses involved in 76c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj debuginfo reading confusing. Recently I arrived at some 77c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj terminology which makes it clearer (to me, at least). There are 3 78c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj kinds of address used in the debuginfo reading process: 79c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 80c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj stated VMAs - the address where (eg) a .so says a symbol is, that 81c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj is, what it tells you if you consider the .so in 82c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj isolation 83c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 84c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj actual VMAs - the address where (eg) said symbol really wound up 85c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj after the .so was mapped into memory 86c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 87c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj image addresses - pointers into the copy of the .so (etc) 88c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj transiently mmaped aboard whilst we read its info 89c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 90c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj Additionally I use the term 'bias' to denote the difference 91c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj between stated and actual VMAs for a given entity. 92c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 93c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj This terminology is not used consistently, but a start has been 94c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj made. readelf.c and the call-frame info reader in readdwarf.c now 95c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj use it. Specifically, various variables and structure fields have 96f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj been annotated with _avma / _svma / _image / _bias. In places _img 97f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj is used instead of _image for the sake of brevity. 98c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj*/ 99c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 100c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 101eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 102f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- fwdses ---*/ 103f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*------------------------------------------------------------*/ 104f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 105f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic void cfsi_cache__invalidate ( void ); 106f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 107f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 108f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*------------------------------------------------------------*/ 109eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Root structure ---*/ 110eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 111eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 112b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* The root structure for the entire debug info system. It is a 113b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj linked list of DebugInfos. */ 114b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic DebugInfo* debugInfo_list = NULL; 115b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 116b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Find 'di' in the debugInfo_list and move it one step closer the the 118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj front of the list, so as to make subsequent searches for it 119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj cheaper. When used in a controlled way, makes a major improvement 120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in some DebugInfo-search-intensive situations, most notably stack 121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj unwinding on amd64-linux. */ 122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void move_DebugInfo_one_step_forward ( DebugInfo* di ) 123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo *di0, *di1, *di2; 125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == debugInfo_list) 126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; /* already at head of list */ 127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di != NULL); 128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0 = debugInfo_list; 129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1 = NULL; 130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2 = NULL; 131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 == NULL || di0 == di) break; 133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2 = di1; 134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1 = di0; 135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0 = di0->next; 136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di0 == di); 138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 != NULL && di1 != NULL && di2 != NULL) { 139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* tmp; 140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* di0 points to di, di1 to its predecessor, and di2 to di1's 141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj predecessor. Swap di0 and di1, that is, move di0 one step 142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj closer to the start of the list. */ 143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di2->next == di1); 144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di1->next == di0); 145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj tmp = di0->next; 146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->next = di0; 147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0->next = di1; 148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1->next = tmp; 149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 != NULL && di1 != NULL && di2 == NULL) { 152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* it's second in the list. */ 153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(debugInfo_list == di1); 154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di1->next == di0); 155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1->next = di0->next; 156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0->next = di1; 157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debugInfo_list = di0; 158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 160eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 161eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 162eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 163eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Notification (acquire/discard) helpers ---*/ 164eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 165eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Gives out unique abstract handles for allocated DebugInfos. See 1679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj comment in priv_storage.h, declaration of struct _DebugInfo, for 1689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj details. */ 1699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic ULong handle_counter = 1; 1709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 171b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Allocate and zero out a new DebugInfo record. */ 172eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjstatic 173b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjDebugInfo* alloc_DebugInfo( const UChar* filename, 174b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj const UChar* memname ) 175eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool traceme; 177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 178eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 179f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj vg_assert(filename); 180f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj 1819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di = ML_(dinfo_zalloc)("di.debuginfo.aDI.1", sizeof(DebugInfo)); 1829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->handle = handle_counter++; 1839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->filename = ML_(dinfo_strdup)("di.debuginfo.aDI.2", filename); 1849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->memname = memname ? ML_(dinfo_strdup)("di.debuginfo.aDI.3", memname) 185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj : NULL; 186eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 187f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj /* Everything else -- pointers, sizes, arrays -- is zeroed by calloc. 188f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj Now set up the debugging-output flags. */ 189f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj traceme 190f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj = VG_(string_match)( VG_(clo_trace_symtab_patt), filename ) 191f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj || (memname && VG_(string_match)( VG_(clo_trace_symtab_patt), 192f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj memname )); 193f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj if (traceme) { 194b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->trace_symtab = VG_(clo_trace_symtab); 195b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->trace_cfi = VG_(clo_trace_cfi); 196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_syms = VG_(clo_debug_dump_syms); 197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_line = VG_(clo_debug_dump_line); 198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_frames = VG_(clo_debug_dump_frames); 199f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj } 200f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj 201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 202eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 203eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 204eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Free a DebugInfo, and also all the stuff hanging off it. */ 206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void free_DebugInfo ( DebugInfo* di ) 207eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 20859a2d18d0ddfa241850017252b0804d469187d79sewardj Word i, j, n; 209eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj struct strchunk *chunk, *next; 2109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ent; 21159a2d18d0ddfa241850017252b0804d469187d79sewardj GExpr* gexpr; 212b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di != NULL); 214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->filename) ML_(dinfo_free)(di->filename); 215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->symtab) ML_(dinfo_free)(di->symtab); 216b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->loctab) ML_(dinfo_free)(di->loctab); 217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->cfsi) ML_(dinfo_free)(di->cfsi); 218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->cfsi_exprs) VG_(deleteXA)(di->cfsi_exprs); 219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 220b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (chunk = di->strchunks; chunk != NULL; chunk = next) { 221eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj next = chunk->next; 222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(dinfo_free)(chunk); 223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Delete the two admin arrays. These lists exist primarily so 2269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj that we can visit each object exactly once when we need to 2279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj delete them. */ 2289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (di->admin_tyents) { 2299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n = VG_(sizeXA)(di->admin_tyents); 23059a2d18d0ddfa241850017252b0804d469187d79sewardj for (i = 0; i < n; i++) { 2319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ent = (TyEnt*)VG_(indexXA)(di->admin_tyents, i); 2329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Dump anything hanging off this ent */ 2339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(TyEnt__make_EMPTY)(ent); 23459a2d18d0ddfa241850017252b0804d469187d79sewardj } 2359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(deleteXA)(di->admin_tyents); 2369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->admin_tyents = NULL; 237eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 23859a2d18d0ddfa241850017252b0804d469187d79sewardj 23959a2d18d0ddfa241850017252b0804d469187d79sewardj if (di->admin_gexprs) { 24059a2d18d0ddfa241850017252b0804d469187d79sewardj n = VG_(sizeXA)(di->admin_gexprs); 24159a2d18d0ddfa241850017252b0804d469187d79sewardj for (i = 0; i < n; i++) { 24259a2d18d0ddfa241850017252b0804d469187d79sewardj gexpr = *(GExpr**)VG_(indexXA)(di->admin_gexprs, i); 24359a2d18d0ddfa241850017252b0804d469187d79sewardj ML_(dinfo_free)(gexpr); 24459a2d18d0ddfa241850017252b0804d469187d79sewardj } 24559a2d18d0ddfa241850017252b0804d469187d79sewardj VG_(deleteXA)(di->admin_gexprs); 24659a2d18d0ddfa241850017252b0804d469187d79sewardj di->admin_gexprs = NULL; 247b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 248b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Dump the variable info. This is kinda complex: we must take 250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj care not to free items which reside in either the admin lists 251b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (as we have just freed them) or which reside in the DebugInfo's 252b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj string table. */ 253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->varinfo) { 254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = 0; i < VG_(sizeXA)(di->varinfo); i++) { 255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* scope = *(OSet**)VG_(indexXA)(di->varinfo, i); 256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!scope) continue; 257b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* iterate over all entries in 'scope' */ 258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(OSetGen_ResetIter)(scope); 259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 260b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* arange = VG_(OSetGen_Next)(scope); 261b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!arange) break; 262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* for each var in 'arange' */ 263b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->vars); 264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < VG_(sizeXA)( arange->vars ); j++) { 265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)(arange->vars,j); 266b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var); 267b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Nothing to free in var: all the pointer fields refer 268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to stuff either on an admin list, or in 269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj .strchunks */ 270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)(arange->vars); 272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Don't free arange itself, as OSetGen_Destroy does 273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj that */ 274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(OSetGen_Destroy)(scope); 276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)(di->varinfo); 278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(dinfo_free)(di); 281eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 282eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 283eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* 'si' is a member of debugInfo_list. Find it, remove it from the 285eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj list, notify m_redir that this has happened, and free all storage 286eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj reachable from it. 287eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void discard_DebugInfo ( DebugInfo* di ) 289eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2904ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# if defined(VGP_ppc32_aix5) 2914ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj HChar* reason = "__unload"; 2924ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# elif defined(VGP_ppc64_aix5) 2934ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj HChar* reason = "kunload64"; 2944ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# else 2954ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj HChar* reason = "munmap"; 2964ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# endif 2974ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo** prev_next_ptr = &debugInfo_list; 299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* curr = debugInfo_list; 300eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 301eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj while (curr) { 302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (curr == di) { 303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Found it; remove from list and free it. */ 30433e4e7eaab263cea956700f56f007ab26c39eab4sewardj if (curr->have_dinfo 30533e4e7eaab263cea956700f56f007ab26c39eab4sewardj && (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))) 306eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(message)(Vg_DebugMsg, 307a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart "Discarding syms at %#lx-%#lx in %s due to %s()", 308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_avma, 309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_avma + di->text_size, 3104ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj curr->filename ? curr->filename : (UChar*)"???", 3114ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj reason); 312eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(*prev_next_ptr == curr); 313eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *prev_next_ptr = curr->next; 31433e4e7eaab263cea956700f56f007ab26c39eab4sewardj if (curr->have_dinfo) 31533e4e7eaab263cea956700f56f007ab26c39eab4sewardj VG_(redir_notify_delete_DebugInfo)( curr ); 316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj free_DebugInfo(curr); 317eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return; 318eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 319eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj prev_next_ptr = &curr->next; 320eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj curr = curr->next; 321eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 322eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Not found. */ 324eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 325eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 326eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Repeatedly scan debugInfo_list, looking for DebugInfos with text 328b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj AVMAs intersecting [start,start+length), and call discard_DebugInfo 329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to get rid of them. This modifies the list, hence the multiple 330f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj iterations. Returns True iff any such DebugInfos were found. 331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/ 332f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic Bool discard_syms_in_range ( Addr start, SizeT length ) 333eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 334f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool anyFound = False; 335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool found; 336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* curr; 337eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 338eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj while (True) { 339eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj found = False; 340eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj curr = debugInfo_list; 342eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj while (True) { 343eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (curr == NULL) 344eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; 345b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (curr->text_present 346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && curr->text_size > 0 347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && (start+length - 1 < curr->text_avma 348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || curr->text_avma + curr->text_size - 1 < start)) { 349eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* no overlap */ 350eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 351eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj found = True; 352eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; 353eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 354eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj curr = curr->next; 355eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 356eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 357eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (!found) break; 358f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj anyFound = True; 359b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_DebugInfo( curr ); 360eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 361f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 362f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return anyFound; 363eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 364eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 365eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Does [s1,+len1) overlap [s2,+len2) ? Note: does not handle 367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj wraparound at the end of the address space -- just asserts in that 368b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case. */ 369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Bool ranges_overlap (Addr s1, SizeT len1, Addr s2, SizeT len2 ) 370eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr e1, e2; 372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (len1 == 0 || len2 == 0) 373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj e1 = s1 + len1 - 1; 375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj e2 = s2 + len2 - 1; 376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Assert that we don't have wraparound. If we do it would imply 377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj that file sections are getting mapped around the end of the 378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj address space, which sounds unlikely. */ 379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(s1 <= e1); 380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(s2 <= e2); 381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (e1 < s2 || e2 < s1) return False; 382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 384eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 385eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Do the basic rx_ and rw_ mappings of the two DebugInfos overlap in 387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj any way? */ 388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Bool do_DebugInfos_overlap ( DebugInfo* di1, DebugInfo* di2 ) 389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di1); 391b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di2); 392eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di1->have_rx_map && di2->have_rx_map 394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ranges_overlap(di1->rx_map_avma, di1->rx_map_size, 395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->rx_map_avma, di2->rx_map_size)) 396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 397eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di1->have_rx_map && di2->have_rw_map 399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ranges_overlap(di1->rx_map_avma, di1->rx_map_size, 400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->rw_map_avma, di2->rw_map_size)) 401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di1->have_rw_map && di2->have_rx_map 404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ranges_overlap(di1->rw_map_avma, di1->rw_map_size, 405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->rx_map_avma, di2->rx_map_size)) 406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di1->have_rw_map && di2->have_rw_map 409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ranges_overlap(di1->rw_map_avma, di1->rw_map_size, 410b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->rw_map_avma, di2->rw_map_size)) 411b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 412b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 414b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Discard all elements of debugInfo_list whose .mark bit is set. 418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/ 419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void discard_marked_DebugInfos ( void ) 420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* curr; 422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj curr = debugInfo_list; 426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!curr) 428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (curr->mark) 430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj curr = curr->next; 432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!curr) break; 435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_DebugInfo( curr ); 436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Discard any elements of debugInfo_list which overlap with diRef. 442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Clearly diRef must have its rx_ and rw_ mapping information set to 443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj something sane. */ 444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#if defined(VGO_aix5) 445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((unused)) 446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif 447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void discard_DebugInfos_which_overlap_with ( DebugInfo* diRef ) 448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Mark all the DebugInfos in debugInfo_list that need to be 451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj deleted. First, clear all the mark bits; then set them if they 452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj overlap with siRef. Since siRef itself is in this list we at 453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj least expect its own mark bit to be set. */ 454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di; di = di->next) { 455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->mark = do_DebugInfos_overlap( di, diRef ); 456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == diRef) { 457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->mark); 458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->mark = False; 459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 460eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_marked_DebugInfos(); 462b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 464eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Find the existing DebugInfo for (memname,filename) or if not found, 466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj create one. In the latter case memname and filename are strdup'd 467b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj into VG_AR_DINFO, and the new DebugInfo is added to 468b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debugInfo_list. */ 469b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic 470b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjDebugInfo* find_or_create_DebugInfo_for ( UChar* filename, UChar* memname ) 471b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 472b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 473b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(filename); 474b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di; di = di->next) { 475b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->filename); 476b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0==VG_(strcmp)(di->filename, filename) 477b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ( (memname && di->memname) 478b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ? 0==VG_(strcmp)(memname, di->memname) 479b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj : True )) 480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 482b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di) { 483b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di = alloc_DebugInfo(filename, memname); 484b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di); 485b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->next = debugInfo_list; 486b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debugInfo_list = di; 487b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 488b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 489eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 490eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 491eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 492f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Debuginfo reading for 'di' has just been successfully completed. 493f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Check that the invariants stated in 494f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj "Comment_on_IMPORTANT_CFSI_REPRESENTATIONAL_INVARIANTS" in 495f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj priv_storage.h are observed. */ 496f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic void check_CFSI_related_invariants ( DebugInfo* di ) 497f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 498f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo* di2 = NULL; 499f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di); 500f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* This fn isn't called until after debuginfo for this object has 501f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj been successfully read. And that shouldn't happen until we have 502f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj both a r-x and rw- mapping for the object. Hence: */ 503f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->have_rx_map); 504f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->have_rw_map); 505f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* degenerate case: r-x section is empty */ 506f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di->rx_map_size == 0) { 507f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi == NULL); 508f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return; 509f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 510f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* normal case: r-x section is nonempty */ 511f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* invariant (0) */ 512f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->rx_map_size > 0); 513f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* invariant (1) */ 514f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (di2 = debugInfo_list; di2; di2 = di2->next) { 515f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di2 == di) 516f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj continue; 517f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di2->rx_map_size == 0) 518f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj continue; 519f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->rx_map_avma + di->rx_map_size <= di2->rx_map_avma 520f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj || di2->rx_map_avma + di2->rx_map_size <= di->rx_map_avma); 521f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 522f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj di2 = NULL; 523f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* invariant (2) */ 524f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di->cfsi) { 525f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_minavma <= di->cfsi_maxavma); /* duh! */ 526f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_minavma >= di->rx_map_avma); 527f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_maxavma < di->rx_map_avma + di->rx_map_size); 528f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 529f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* invariants (3) and (4) */ 530f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di->cfsi) { 531f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word i; 532f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_used > 0); 533f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_size > 0); 534f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (i = 0; i < di->cfsi_used; i++) { 535f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DiCfSI* cfsi = &di->cfsi[i]; 536f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsi->len > 0); 537f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsi->base >= di->cfsi_minavma); 538f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsi->base + cfsi->len - 1 <= di->cfsi_maxavma); 539f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (i > 0) { 540f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DiCfSI* cfsip = &di->cfsi[i-1]; 541f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsip->base + cfsip->len <= cfsi->base); 542f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 543f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 544f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 545f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_used == 0); 546f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_size == 0); 547f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 548f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 549f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 550f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 551f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--------------------------------------------------------------*/ 552f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- ---*/ 553f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- TOP LEVEL: INITIALISE THE DEBUGINFO SYSTEM ---*/ 554f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- ---*/ 555f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--------------------------------------------------------------*/ 556f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 557f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjvoid VG_(di_initialise) ( void ) 558f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 559f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* There's actually very little to do here, since everything 560f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj centers around the DebugInfos in debugInfo_list, they are 561f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj created and destroyed on demand, and each one is treated more or 562f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj less independently. */ 563f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(debugInfo_list == NULL); 564f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 565f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* flush the CFI fast query cache. */ 566f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi_cache__invalidate(); 567f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 568f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 569f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 5704ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--------------------------------------------------------------*/ 5714ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- ---*/ 5724ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- TOP LEVEL: NOTIFICATION (ACQUIRE/DISCARD INFO) (LINUX) ---*/ 5734ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- ---*/ 5744ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--------------------------------------------------------------*/ 5754ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 5764ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#if defined(VGO_linux) 577eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 578eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* The debug info system is driven by notifications that a text 579eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj segment has been mapped in, or unmapped. When that happens it 580eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj tries to acquire/discard whatever info is available for the 581eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj corresponding object. This section contains the notification 582eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj handlers. */ 583eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 584eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Notify the debuginfo system about a new mapping. This is the way 585eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj new debug information gets loaded. If allow_SkFileV is True, it 586eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj will try load debug info if the mapping at 'a' belongs to Valgrind; 587eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj whereas normally (False) it will not do that. This allows us to 588eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj carefully control when the thing will read symbols from the 5899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Valgrind executable itself. 5909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 5919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj If a call to VG_(di_notify_mmap) causes debug info to be read, then 5929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj the returned ULong is an abstract handle which can later be used to 5939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj refer to the debuginfo read as a result of this specific mapping, 5949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj in later queries to m_debuginfo. In this case the handle value 5959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj will be one or above. If the returned value is zero, no debug info 5969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj was read. */ 597eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 5989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV ) 599eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 6004ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj NSegment const * seg; 601b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj HChar* filename; 602b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool ok, is_rx_map, is_rw_map; 603b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 6049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ULong di_handle; 605b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj SysRes fd; 606b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int nread; 607b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj HChar buf1k[1024]; 608b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool debug = False; 609ec61b6509566cf36ab3968d69226cecf177cb0fesewardj SysRes statres; 610ec61b6509566cf36ab3968d69226cecf177cb0fesewardj struct vg_stat statbuf; 611b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 612b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* In short, figure out if this mapping is of interest to us, and 613b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if so, try to guess what ld.so is doing and when/if we should 614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj read debug info. */ 615b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg = VG_(am_find_nsegment)(a); 616b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(seg); 617eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 618b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 619a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("di_notify_mmap-1: %#lx-%#lx %c%c%c\n", 620b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->start, seg->end, 621b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->hasR ? 'r' : '-', 622b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->hasW ? 'w' : '-',seg->hasX ? 'x' : '-' ); 623eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 624b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* guaranteed by aspacemgr-linux.c, sane_NSegment() */ 625b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(seg->end > seg->start); 626b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ignore non-file mappings */ 628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( ! (seg->kind == SkFileC 629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || (seg->kind == SkFileV && allow_SkFileV)) ) 6309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 632b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* If the file doesn't have a name, we're hosed. Give up. */ 633b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj filename = VG_(am_get_filename)( (NSegment*)seg ); 634b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!filename) 6359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 636b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 637b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 638b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("di_notify_mmap-2: %s\n", filename); 639b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 640ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* Only try to read debug information from regular files. */ 64115728ab41ea41bf731dcc74ac68354550ced2189bart statres = VG_(stat)(filename, &statbuf); 642ec61b6509566cf36ab3968d69226cecf177cb0fesewardj 643ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* stat dereferences symlinks, so we don't expect it to succeed and 644ec61b6509566cf36ab3968d69226cecf177cb0fesewardj yet produce something that is a symlink. */ 64515728ab41ea41bf731dcc74ac68354550ced2189bart vg_assert(statres.isError || ! VKI_S_ISLNK(statbuf.st_mode)); 646ec61b6509566cf36ab3968d69226cecf177cb0fesewardj 647ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* Don't let the stat call fail silently. Filter out some known 648ec61b6509566cf36ab3968d69226cecf177cb0fesewardj sources of noise before complaining, though. */ 649ec61b6509566cf36ab3968d69226cecf177cb0fesewardj if (statres.isError) { 650ec61b6509566cf36ab3968d69226cecf177cb0fesewardj DebugInfo fake_di; 651ec61b6509566cf36ab3968d69226cecf177cb0fesewardj Bool quiet = VG_(strstr)(filename, "/var/run/nscd/") != NULL; 652e025eca1d49cdfe5a8cb58ab495763434280333asewardj if (!quiet && VG_(clo_verbosity) > 1) { 653ec61b6509566cf36ab3968d69226cecf177cb0fesewardj VG_(memset)(&fake_di, 0, sizeof(fake_di)); 654ec61b6509566cf36ab3968d69226cecf177cb0fesewardj fake_di.filename = filename; 655ec61b6509566cf36ab3968d69226cecf177cb0fesewardj ML_(symerr)(&fake_di, True, "failed to stat64/stat this file"); 656ec61b6509566cf36ab3968d69226cecf177cb0fesewardj } 6579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 6582ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj } 6592ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj 660ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* Finally, the point of all this stattery: if it's not a regular file, 661ec61b6509566cf36ab3968d69226cecf177cb0fesewardj don't try to read debug info from it. */ 662ec61b6509566cf36ab3968d69226cecf177cb0fesewardj if (! VKI_S_ISREG(statbuf.st_mode)) 6639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 664ec61b6509566cf36ab3968d69226cecf177cb0fesewardj 665ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* no uses of statbuf below here. */ 66615728ab41ea41bf731dcc74ac68354550ced2189bart 66715728ab41ea41bf731dcc74ac68354550ced2189bart /* Peer at the first few bytes of the file, to see if it is an ELF */ 66815728ab41ea41bf731dcc74ac68354550ced2189bart /* object file. Ignore the file if we do not have read permission. */ 669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(memset)(buf1k, 0, sizeof(buf1k)); 670b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj fd = VG_(open)( filename, VKI_O_RDONLY, 0 ); 671b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (fd.isError) { 67215728ab41ea41bf731dcc74ac68354550ced2189bart if (fd.err != VKI_EACCES) 67315728ab41ea41bf731dcc74ac68354550ced2189bart { 674d5dea1dabc523d3f96bafd52ae9586abd8797416bart DebugInfo fake_di; 67515728ab41ea41bf731dcc74ac68354550ced2189bart VG_(memset)(&fake_di, 0, sizeof(fake_di)); 67615728ab41ea41bf731dcc74ac68354550ced2189bart fake_di.filename = filename; 67715728ab41ea41bf731dcc74ac68354550ced2189bart ML_(symerr)(&fake_di, True, "can't open file to inspect ELF header"); 67815728ab41ea41bf731dcc74ac68354550ced2189bart } 6799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 680b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 681b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj nread = VG_(read)( fd.res, buf1k, sizeof(buf1k) ); 682b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(close)( fd.res ); 683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 684d5dea1dabc523d3f96bafd52ae9586abd8797416bart if (nread == 0) 6859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 686d5dea1dabc523d3f96bafd52ae9586abd8797416bart if (nread < 0) { 687d5dea1dabc523d3f96bafd52ae9586abd8797416bart DebugInfo fake_di; 688d5dea1dabc523d3f96bafd52ae9586abd8797416bart VG_(memset)(&fake_di, 0, sizeof(fake_di)); 689d5dea1dabc523d3f96bafd52ae9586abd8797416bart fake_di.filename = filename; 690d5dea1dabc523d3f96bafd52ae9586abd8797416bart ML_(symerr)(&fake_di, True, "can't read file to inspect ELF header"); 6919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 692b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(nread > 0 && nread <= sizeof(buf1k) ); 694b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 695b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We're only interested in mappings of ELF object files. */ 696b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!ML_(is_elf_object_file)( buf1k, (SizeT)nread )) 6979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 698b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 699b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Now we have to guess if this is a text-like mapping, a data-like 700b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj mapping, neither or both. The rules are: 701b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 702b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj text if: x86-linux r and x 703b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj other-linux r and x and not w 704b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 705b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data if: x86-linux r and w 706b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj other-linux r and w and not x 707b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 708b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Background: On x86-linux, objects are typically mapped twice: 709eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 710eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1b8fb000-1b8ff000 r-xp 00000000 08:02 4471477 vgpreload_memcheck.so 711eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1b8ff000-1b900000 rw-p 00004000 08:02 4471477 vgpreload_memcheck.so 712eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 713eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj whereas ppc32-linux mysteriously does this: 714eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 715eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118a6000-118ad000 r-xp 00000000 08:05 14209428 vgpreload_memcheck.so 716eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118ad000-118b6000 ---p 00007000 08:05 14209428 vgpreload_memcheck.so 717eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118b6000-118bd000 rwxp 00000000 08:05 14209428 vgpreload_memcheck.so 718eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 719eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj The third mapping should not be considered to have executable 720eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj code in. Therefore a test which works for both is: r and x and 721eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj NOT w. Reading symbols from the rwx segment -- which overlaps 722eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj the r-x segment in the file -- causes the redirection mechanism 723eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj to redirect to addresses in that third segment, which is wrong 724eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj and causes crashes. 725eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 726eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj JRS 28 Dec 05: unfortunately icc 8.1 on x86 has been seen to 727eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj produce executables with a single rwx segment rather than a 728eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj (r-x,rw-) pair. That means the rules have to be modified thusly: 729eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 730eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj x86-linux: consider if r and x 731b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj all others: consider if r and x and not w 732eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj */ 733b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = False; 734b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = False; 735eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# if defined(VGP_x86_linux) 736b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = seg->hasR && seg->hasX; 737b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = seg->hasR && seg->hasW; 738b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# elif defined(VGP_amd64_linux) \ 739b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) 740b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = seg->hasR && seg->hasX && !seg->hasW; 741b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = seg->hasR && seg->hasW && !seg->hasX; 742eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# else 743b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# error "Unknown platform" 744eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# endif 745eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 746b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 747b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("di_notify_mmap-3: is_rx_map %d, is_rw_map %d\n", 748b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (Int)is_rx_map, (Int)is_rw_map); 749eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 750b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* If it is neither text-ish nor data-ish, we're not interested. */ 751b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!(is_rx_map || is_rw_map)) 7529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 753eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 754b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* See if we have a DebugInfo for this filename. If not, 755b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj create one. */ 756b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di = find_or_create_DebugInfo_for( filename, NULL/*membername*/ ); 757b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di); 758b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 759b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (is_rx_map) { 760b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We have a text-like mapping. Note the details. */ 761b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->have_rx_map) { 762b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->have_rx_map = True; 763b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rx_map_avma = a; 764b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rx_map_size = seg->end + 1 - seg->start; 765b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rx_map_foff = seg->offset; 766b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 767b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* FIXME: complain about a second text-like mapping */ 768b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 769b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 770eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 771b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (is_rw_map) { 772b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We have a data-like mapping. Note the details. */ 773b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->have_rw_map) { 774b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->have_rw_map = True; 775b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rw_map_avma = a; 776b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rw_map_size = seg->end + 1 - seg->start; 777b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rw_map_foff = seg->offset; 778b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 779b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* FIXME: complain about a second data-like mapping */ 780b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 781eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 782eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 7839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* If we don't have an rx and rw mapping, or if we already have 7849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj debuginfo for this mapping for whatever reason, go no 7859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj further. */ 7869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if ( ! (di->have_rx_map && di->have_rw_map && !di->have_dinfo) ) 7879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 788b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 7899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok, so, finally, let's try to read the debuginfo. */ 7909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(di->filename); 7919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("\n"); 7929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("------ start ELF OBJECT " 7939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj "------------------------------\n"); 7949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("------ name = %s\n", di->filename); 7959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("\n"); 7969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 7979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* We're going to read symbols and debug info for the avma 7989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ranges [rx_map_avma, +rx_map_size) and [rw_map_avma, 7999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj +rw_map_size). First get rid of any other DebugInfos which 8009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj overlap either of those ranges (to avoid total confusion). */ 8019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj discard_DebugInfos_which_overlap_with( di ); 8029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 8039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* .. and acquire new info. */ 8049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ok = ML_(read_elf_debug_info)( di ); 8059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 8069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (ok) { 8079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 8089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("\n------ Canonicalising the " 8099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj "acquired info ------\n"); 810f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* invalidate the CFI unwind cache. */ 811f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi_cache__invalidate(); 8129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* prepare read data for use */ 8139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(canonicaliseTables)( di ); 8149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* notify m_redir about it */ 8159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("\n------ Notifying m_redir ------\n"); 8169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(redir_notify_new_DebugInfo)( di ); 8179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Note that we succeeded */ 8189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->have_dinfo = True; 8199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(di->handle > 0); 8209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di_handle = di->handle; 821f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Check invariants listed in 822f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Comment_on_IMPORTANT_REPRESENTATIONAL_INVARIANTS in 823f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj priv_storage.h. */ 824f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj check_CFSI_related_invariants(di); 825b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 8269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } else { 8279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("\n------ ELF reading failed ------\n"); 8289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Something went wrong (eg. bad ELF file). Should we delete 8299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj this DebugInfo? No - it contains info on the rw/rx 8309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj mappings, at least. */ 8319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di_handle = 0; 832f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->have_dinfo == False); 8339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 834eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 8359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("\n"); 8369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("------ name = %s\n", di->filename); 8379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("------ end ELF OBJECT " 8389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj "------------------------------\n"); 8399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("\n"); 840eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 8419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return di_handle; 842eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 843eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 844eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 845eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Unmap is simpler - throw away any SegInfos intersecting 846eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj [a, a+len). */ 847eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjvoid VG_(di_notify_munmap)( Addr a, SizeT len ) 848eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 849f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool anyFound; 850a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart if (0) VG_(printf)("DISCARD %#lx %#lx\n", a, a+len); 851f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj anyFound = discard_syms_in_range(a, len); 852f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (anyFound) 853f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi_cache__invalidate(); 854eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 855eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 856eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 857eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Uh, this doesn't do anything at all. IIRC glibc (or ld.so, I don't 858eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj remember) does a bunch of mprotects on itself, and if we follow 859eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj through here, it causes the debug info for that object to get 860eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj discarded. */ 861eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjvoid VG_(di_notify_mprotect)( Addr a, SizeT len, UInt prot ) 862eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 863eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool exe_ok = toBool(prot & VKI_PROT_EXEC); 864eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# if defined(VGP_x86_linux) 865eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj exe_ok = exe_ok || toBool(prot & VKI_PROT_READ); 866eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# endif 867f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && !exe_ok) { 868f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool anyFound = discard_syms_in_range(a, len); 869f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (anyFound) 870f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi_cache__invalidate(); 871f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 872eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 873eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 8744ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#endif /* defined(VGO_linux) */ 8754ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 8764ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 8774ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*-------------------------------------------------------------*/ 8784ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- ---*/ 8794ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- TOP LEVEL: NOTIFICATION (ACQUIRE/DISCARD INFO) (AIX5) ---*/ 8804ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- ---*/ 8814ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*-------------------------------------------------------------*/ 8824ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 8834ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#if defined(VGO_aix5) 8844ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 8854ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/* The supplied parameters describe a code segment and its associated 8864ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj data segment, that have recently been mapped in -- so we need to 8874ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj read debug info for it -- or conversely, have recently been dumped, 8884ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj in which case the relevant debug info has to be unloaded. */ 8894ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 8909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjULong VG_(di_aix5_notify_segchange)( 8914ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Addr code_start, 8924ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Word code_len, 8934ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Addr data_start, 8944ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Word data_len, 8954ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj UChar* file_name, 8964ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj UChar* mem_name, 8974ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool is_mainexe, 8984ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool acquire ) 8994ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj{ 9009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ULong hdl = 0; 9019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 902f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* play safe; always invalidate the CFI cache. Not 903f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj that it should be used on AIX, but still .. */ 904f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi_cache__invalidate(); 905f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 9064ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (acquire) { 9074ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 908b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool ok; 909b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 910b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di = find_or_create_DebugInfo_for( file_name, mem_name ); 911b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di); 912b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 913b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (code_len > 0) { 914b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_present = True; 915b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_svma = 0; /* don't know yet */ 916b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_bias = 0; /* don't know yet */ 917b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_avma = code_start; 918b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_size = code_len; 919b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 920b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (data_len > 0) { 921b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_present = True; 922b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_svma = 0; /* don't know yet */ 923b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_bias = 0; /* don't know yet */ 924b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_avma = data_start; 925b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_size = data_len; 926b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 927b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 928b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* These need to be filled in in order to keep various 929b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj assertions in storage.c happy. In particular see 930b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Comment_Regarding_Text_Range_Checks" in that file. */ 931b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->have_rx_map = True; 932b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rx_map_avma = code_start; 933b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rx_map_size = code_len; 934b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->have_rw_map = True; 935b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rw_map_avma = data_start; 936b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rw_map_size = data_len; 937b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 938b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ok = ML_(read_xcoff_debug_info) ( di, is_mainexe ); 939b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 940b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (ok) { 941b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* prepare read data for use */ 942b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(canonicaliseTables)( di ); 943b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* notify m_redir about it */ 944b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(redir_notify_new_DebugInfo)( di ); 945b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Note that we succeeded */ 946b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->have_dinfo = True; 9479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj hdl = di->handle; 9489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(hdl > 0); 949f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Check invariants listed in 950f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Comment_on_IMPORTANT_REPRESENTATIONAL_INVARIANTS in 951f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj priv_storage.h. */ 952f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj check_CFSI_related_invariants(di); 953b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 954b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Something went wrong (eg. bad XCOFF file). */ 955b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_DebugInfo( di ); 956b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di = NULL; 957b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 9584ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 9594ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } else { 9604ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 961b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Dump all the debugInfos whose text segments intersect 962f7cdfe298805a91a35b8e0495d9034cbf21003f5sewardj code_start/code_len. */ 963f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* CFI cache is always invalidated at start of this routine. 964f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Hence it's safe to ignore the return value of 965f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj discard_syms_in_range. */ 966b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (code_len > 0) 967f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj (void)discard_syms_in_range( code_start, code_len ); 9684ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 9694ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 9709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 9719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return hdl; 9724ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj} 9734ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 9744ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 9754ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#endif /* defined(VGO_aix5) */ 9764ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 977eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 978eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 979eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- ---*/ 980eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- TOP LEVEL: QUERYING EXISTING DEBUG INFO ---*/ 981eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- ---*/ 982eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 983eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 9849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid VG_(di_discard_ALL_debuginfo)( void ) 9859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 9869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo *di, *di2; 9879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di = debugInfo_list; 9889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj while (di) { 9899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di2 = di->next; 9909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("XXX rm %p\n", di); 9919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj free_DebugInfo( di ); 9929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di = di2; 9939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 9949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 9959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 9969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 997eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 998eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Use of symbol table & location info to create ---*/ 999eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- plausible-looking stack dumps. ---*/ 1000eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1001eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1002eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Search all symtabs that we know about to locate ptr. If found, set 1003b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi to the relevant DebugInfo, and *symno to the symtab entry 1004b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *number within that. If not found, *psi is set to NULL. 1005b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj If findText==True, only text symbols are searched for. 1006b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj If findText==False, only data symbols are searched for. 1007b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/ 1008b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void search_all_symtabs ( Addr ptr, /*OUT*/DebugInfo** pdi, 1009f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*OUT*/Word* symno, 1010b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool match_anywhere_in_sym, 1011b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool findText ) 1012eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1013f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1014b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1015b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool inRange; 1016b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1017b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1018b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1019b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (findText) { 1020b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj inRange = di->text_present 1021b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_size > 0 1022b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= ptr 1023b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->text_avma + di->text_size; 1024b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 1025b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj inRange = (di->data_present 1026b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_size > 0 1027b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_avma <= ptr 1028b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->data_avma + di->data_size) 1029b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || 1030b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (di->sdata_present 1031b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_size > 0 1032b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_avma <= ptr 1033b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->sdata_avma + di->sdata_size) 1034b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || 1035b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (di->bss_present 1036b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_size > 0 1037b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_avma <= ptr 1038b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->bss_avma + di->bss_size); 1039eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1040b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1041b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!inRange) continue; 1042b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1043b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sno = ML_(search_one_symtab) ( 1044b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di, ptr, match_anywhere_in_sym, findText ); 1045b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (sno == -1) goto not_found; 1046b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *symno = sno; 1047b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = di; 1048b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; 1049b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1050eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1051eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj not_found: 1052b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = NULL; 1053eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1054eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1055eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1056eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Search all loctabs that we know about to locate ptr. If found, set 1057b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi to the relevant DebugInfo, and *locno to the loctab entry 1058b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *number within that. If not found, *pdi is set to NULL. */ 1059b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void search_all_loctabs ( Addr ptr, /*OUT*/DebugInfo** pdi, 1060f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*OUT*/Word* locno ) 1061eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1062f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word lno; 1063b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1065b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 1066b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= ptr 1067b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->text_avma + di->text_size) { 1068b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj lno = ML_(search_one_loctab) ( di, ptr ); 1069eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (lno == -1) goto not_found; 1070eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *locno = lno; 1071b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = di; 1072eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return; 1073eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1074eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1075eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj not_found: 1076b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = NULL; 1077eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1078eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1079eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1080eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* The whole point of this whole big deal: map a code address to a 1081eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj plausible symbol name. Returns False if no idea; otherwise True. 1082eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Caller supplies buf and nbuf. If demangle is False, don't do 1083eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj demangling, regardless of VG_(clo_demangle) -- probably because the 1084b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj call has come from VG_(get_fnname_nodemangle)(). findText 1085b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj indicates whether we're looking for a text symbol or a data symbol 1086b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj -- caller must choose one kind or the other. */ 1087eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjstatic 1088b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool get_sym_name ( Bool demangle, Addr a, Char* buf, Int nbuf, 1089b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool match_anywhere_in_sym, Bool show_offset, 1090b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool findText, /*OUT*/OffT* offsetP ) 1091eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1092b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1093f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1094b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int offset; 1095eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1096b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj search_all_symtabs ( a, &di, &sno, match_anywhere_in_sym, findText ); 1097b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == NULL) 1098eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1099eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (demangle) { 1100eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(demangle) ( True/*do C++ demangle*/, 1101b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->symtab[sno].name, buf, nbuf ); 1102eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 1103b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(strncpy_safely) ( buf, di->symtab[sno].name, nbuf ); 1104eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1105eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1106b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset = a - di->symtab[sno].addr; 1107b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (offsetP) *offsetP = (OffT)offset; 1108b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1109eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (show_offset && offset != 0) { 1110eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char buf2[12]; 1111eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char* symend = buf + VG_(strlen)(buf); 1112eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char* end = buf + nbuf; 1113eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Int len; 1114eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1115eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj len = VG_(sprintf)(buf2, "%c%d", 1116eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj offset < 0 ? '-' : '+', 1117eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj offset < 0 ? -offset : offset); 1118eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(len < (Int)sizeof(buf2)); 1119eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1120eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (len < (end - symend)) { 1121eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char *cp = buf2; 1122eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(memcpy)(symend, cp, len+1); 1123eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1124eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1125eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1126eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1127eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1128eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1129eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* ppc64-linux only: find the TOC pointer (R2 value) that should be in 1130eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj force at the entry point address of the function containing 1131eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj guest_code_addr. Returns 0 if not known. */ 1132eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjAddr VG_(get_tocptr) ( Addr guest_code_addr ) 1133eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1135f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1136eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_symtabs ( guest_code_addr, 1137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj &si, &sno, 1138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj True/*match_anywhere_in_fun*/, 1139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj True/*consider text symbols only*/ ); 1140eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 1141eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return 0; 1142eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj else 1143eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return si->symtab[sno].tocptr; 1144eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1145eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1146eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 1147eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj match anywhere in function, but don't show offsets. */ 1148eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_fnname) ( Addr a, Char* buf, Int nbuf ) 1149eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return get_sym_name ( /*demangle*/True, a, buf, nbuf, 1151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1155eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1156eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1157eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 1158eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj match anywhere in function, and show offset if nonzero. */ 1159eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_fnname_w_offset) ( Addr a, Char* buf, Int nbuf ) 1160eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return get_sym_name ( /*demangle*/True, a, buf, nbuf, 1162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1163b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/True, 1164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1166eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1167eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1168eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 1169eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj only succeed if 'a' matches first instruction of function, 1170eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj and don't show offsets. */ 1171eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_fnname_if_entry) ( Addr a, Char* buf, Int nbuf ) 1172eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1173b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return get_sym_name ( /*demangle*/True, a, buf, nbuf, 1174b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/False, 1175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1178eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1179eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1180eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is only available to core... don't demangle C++ names, 1181eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj match anywhere in function, and don't show offsets. */ 1182eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_fnname_nodemangle) ( Addr a, Char* buf, Int nbuf ) 1183eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return get_sym_name ( /*demangle*/False, a, buf, nbuf, 1185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1187b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1189eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1190eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1191eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is only available to core... don't demangle C++ names, but do 1192eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj do Z-demangling, match anywhere in function, and don't show 1193eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj offsets. */ 1194eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_fnname_Z_demangle_only) ( Addr a, Char* buf, Int nbuf ) 1195eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1196eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define N_TMPBUF 4096 /* arbitrary, 4096 == ERRTXT_LEN */ 1197eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char tmpbuf[N_TMPBUF]; 1198eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool ok; 1199eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(nbuf > 0); 1200b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ok = get_sym_name ( /*demangle*/False, a, tmpbuf, N_TMPBUF, 1201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1204b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1205eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj tmpbuf[N_TMPBUF-1] = 0; /* paranoia */ 1206eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (!ok) 1207eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1208eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1209eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* We have something, at least. Try to Z-demangle it. */ 1210eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(demangle)( False/*don't do C++ demangling*/, tmpbuf, buf, nbuf); 1211eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1212eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf[nbuf-1] = 0; /* paranoia */ 1213eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1214eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef N_TMPBUF 1215eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1216eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Looks up data_addr in the collection of data symbols, and if found 1218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj puts its name (or as much as will fit) into dname[0 .. n_dname-1], 1219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which is guaranteed to be zero terminated. Also data_addr's offset 1220b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj from the symbol start is put into *offset. */ 1221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool VG_(get_datasym_and_offset)( Addr data_addr, 1222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/Char* dname, Int n_dname, 1223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/OffT* offset ) 1224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 1225b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool ok; 1226b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_dname > 1); 1227b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ok = get_sym_name ( /*demangle*/False, data_addr, dname, n_dname, 1228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_sym*/True, 1229b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1230b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*data syms only please*/False, 1231b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset ); 1232b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!ok) 1233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 1234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname[n_dname-1] = 0; 1235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 1236b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 1237b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1238b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Map a code address to the name of a shared object file or the 1239b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj executable. Returns False if no idea; otherwise True. Doesn't 1240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj require debug info. Caller supplies buf and nbuf. */ 1241eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_objname) ( Addr a, Char* buf, Int nbuf ) 1242eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 12434ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Int used; 1244b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1245f32ec7f0de8a651bc16a1b2e448c0106d8669889tom const NSegment *seg; 1246f32ec7f0de8a651bc16a1b2e448c0106d8669889tom HChar* filename; 12474ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj vg_assert(nbuf > 0); 12487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Look in the debugInfo_list to find the name. In most cases we 12497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj expect this to produce a result. */ 1250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1251b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 1252b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= a 1253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a < di->text_avma + di->text_size) { 1254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(strncpy_safely)(buf, di->filename, nbuf); 1255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->memname) { 12564ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj used = VG_(strlen)(buf); 12574ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (used < nbuf) 12584ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(strncpy_safely)(&buf[used], "(", nbuf-used); 12594ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj used = VG_(strlen)(buf); 12604ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (used < nbuf) 1261b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(strncpy_safely)(&buf[used], di->memname, nbuf-used); 12624ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj used = VG_(strlen)(buf); 12634ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (used < nbuf) 12644ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(strncpy_safely)(&buf[used], ")", nbuf-used); 12654ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 12664ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj buf[nbuf-1] = 0; 1267eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1268eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1269eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 12707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Last-ditch fallback position: if we don't find the address in 12717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj the debugInfo_list, ask the address space manager whether it 12727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj knows the name of the file associated with this mapping. This 12737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj allows us to print the names of exe/dll files in the stack trace 12747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj when running programs under wine. */ 12757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if ( (seg = VG_(am_find_nsegment(a))) != NULL 12767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj && (filename = VG_(am_get_filename)(seg)) != NULL ) { 1277f32ec7f0de8a651bc16a1b2e448c0106d8669889tom VG_(strncpy_safely)(buf, filename, nbuf); 1278f32ec7f0de8a651bc16a1b2e448c0106d8669889tom return True; 1279f32ec7f0de8a651bc16a1b2e448c0106d8669889tom } 1280eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1281eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1282eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Map a code address to its DebugInfo. Returns NULL if not found. Doesn't 1284eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj require debug info. */ 1285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjDebugInfo* VG_(find_seginfo) ( Addr a ) 1286eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1289b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 1290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= a 1291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a < di->text_avma + di->text_size) { 1292b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 1293eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1294eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1295eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return NULL; 1296eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1297eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1298eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a filename. Returns True if successful. */ 1299eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_filename)( Addr a, Char* filename, Int n_filename ) 1300eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1302f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 1303eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 1304eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 1305eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1306eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(strncpy_safely)(filename, si->loctab[locno].filename, n_filename); 1307eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1308eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1309eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1310eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a line number. Returns True if successful. */ 1311eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_linenum)( Addr a, UInt* lineno ) 1312eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1314f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 1315eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 1316eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 1317eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1318eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *lineno = si->loctab[locno].lineno; 1319eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1320eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1321eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1322eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1323eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a filename/line number/dir name info. 1324eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj See prototype for detailed description of behaviour. 1325eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 1326eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_filename_linenum) ( Addr a, 1327eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/Char* filename, Int n_filename, 1328eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/Char* dirname, Int n_dirname, 1329eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/Bool* dirname_available, 1330eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/UInt* lineno ) 1331eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1333f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 1334eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1335eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert( (dirname == NULL && dirname_available == NULL) 1336eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj || 1337eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj (dirname != NULL && dirname_available != NULL) ); 1338eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1339eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 1340c1b1d421216369aec58867ce1c5b99cfb1703c36njn if (si == NULL) { 1341db5c6571454c1f647a4c67593805a8e401cd14c5njn if (dirname_available) { 1342db5c6571454c1f647a4c67593805a8e401cd14c5njn *dirname_available = False; 1343db5c6571454c1f647a4c67593805a8e401cd14c5njn *dirname = 0; 1344db5c6571454c1f647a4c67593805a8e401cd14c5njn } 1345eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1346c1b1d421216369aec58867ce1c5b99cfb1703c36njn } 1347c1b1d421216369aec58867ce1c5b99cfb1703c36njn 1348eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(strncpy_safely)(filename, si->loctab[locno].filename, n_filename); 1349eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *lineno = si->loctab[locno].lineno; 1350eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1351eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (dirname) { 1352eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* caller wants directory info too .. */ 1353eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(n_dirname > 0); 1354eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si->loctab[locno].dirname) { 1355eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* .. and we have some */ 1356eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *dirname_available = True; 1357eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(strncpy_safely)(dirname, si->loctab[locno].dirname, 1358eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_dirname); 1359eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 1360eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* .. but we don't have any */ 1361eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *dirname_available = False; 1362eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *dirname = 0; 1363eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1364eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1365eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1366eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1367eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1368eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1369eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 13704ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/* Map a function name to its entry point and toc pointer. Is done by 13714ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj sequential search of all symbol tables, so is very slow. To 13724ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj mitigate the worst performance effects, you may specify a soname 13734ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj pattern, and only objects matching that pattern are searched. 13744ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Therefore specify "*" to search all the objects. On TOC-afflicted 13754ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj platforms, a symbol is deemed to be found only if it has a nonzero 13764ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj TOC pointer. */ 1377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool VG_(lookup_symbol_SLOW)(UChar* sopatt, UChar* name, 1378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr* pEnt, Addr* pToc) 13794ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj{ 13804ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool require_pToc = False; 13814ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Int i; 1382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 13834ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool debug = False; 13844ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# if defined(VG_PLAT_USES_PPCTOC) 13854ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj require_pToc = True; 13864ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# endif 1387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (si = debugInfo_list; si; si = si->next) { 13884ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (debug) 13894ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(printf)("lookup_symbol_SLOW: considering %s\n", si->soname); 13904ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (!VG_(string_match)(sopatt, si->soname)) { 13914ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (debug) 13924ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(printf)(" ... skip\n"); 13934ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj continue; 13944ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 13954ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj for (i = 0; i < si->symtab_used; i++) { 13964ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (0==VG_(strcmp)(name, si->symtab[i].name) 13974ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj && (require_pToc ? si->symtab[i].tocptr : True)) { 13984ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj *pEnt = si->symtab[i].addr; 13994ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj *pToc = si->symtab[i].tocptr; 14004ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj return True; 14014ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 14024ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 14034ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 14044ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj return False; 14054ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj} 14064ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 14074ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 1408e872fec0c1c3b478a399fdba42ac65764b53f470sewardj/* VG_(describe_IP): print into buf info on code address, function 1409e872fec0c1c3b478a399fdba42ac65764b53f470sewardj name and filename. */ 1410e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 1411e872fec0c1c3b478a399fdba42ac65764b53f470sewardj/* Copy str into buf starting at n, but not going past buf[n_buf-1] 1412e872fec0c1c3b478a399fdba42ac65764b53f470sewardj and always ensuring that buf is zero-terminated. */ 1413eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1414eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjstatic Int putStr ( Int n, Int n_buf, Char* buf, Char* str ) 1415eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1416e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n_buf > 0); 1417e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 1418eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj for (; n < n_buf-1 && *str != 0; n++,str++) 1419eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf[n] = *str; 1420e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 1421eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf[n] = '\0'; 1422eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return n; 1423eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1424e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 1425e872fec0c1c3b478a399fdba42ac65764b53f470sewardj/* Same as putStr, but escaping chars for XML output, and 1426e872fec0c1c3b478a399fdba42ac65764b53f470sewardj also not adding more than count chars to n_buf. */ 1427e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 1428e872fec0c1c3b478a399fdba42ac65764b53f470sewardjstatic Int putStrEsc ( Int n, Int n_buf, Int count, Char* buf, Char* str ) 1429eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1430eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char alt[2]; 1431e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n_buf > 0); 1432e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(count >= 0 && count < n_buf); 1433e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 1434eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj for (; *str != 0; str++) { 1435e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(count >= 0); 1436e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count <= 0) 1437e872fec0c1c3b478a399fdba42ac65764b53f470sewardj goto done; 1438eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj switch (*str) { 1439e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '&': 1440e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 5) goto done; 1441e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, "&"); 1442e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 5; 1443e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 1444e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '<': 1445e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 4) goto done; 1446e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, "<"); 1447e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 4; 1448e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 1449e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '>': 1450e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 4) goto done; 1451e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, ">"); 1452e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 4; 1453e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 1454e872fec0c1c3b478a399fdba42ac65764b53f470sewardj default: 1455e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 1) goto done; 1456e872fec0c1c3b478a399fdba42ac65764b53f470sewardj alt[0] = *str; 1457e872fec0c1c3b478a399fdba42ac65764b53f470sewardj alt[1] = 0; 1458e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, alt ); 1459e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 1; 1460e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 1461eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1462eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1463e872fec0c1c3b478a399fdba42ac65764b53f470sewardj done: 1464e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(count >= 0); /* should not go -ve in loop */ 1465e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 1466eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return n; 1467eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1468eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1469eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjChar* VG_(describe_IP)(Addr eip, Char* buf, Int n_buf) 1470eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1471eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define APPEND(_str) \ 1472e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr(n, n_buf, buf, _str) 1473e872fec0c1c3b478a399fdba42ac65764b53f470sewardj# define APPEND_ESC(_count,_str) \ 1474e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStrEsc(n, n_buf, (_count), buf, (_str)) 1475eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define BUF_LEN 4096 1476eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1477eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj UInt lineno; 1478eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj UChar ibuf[50]; 1479eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Int n = 0; 1480eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static UChar buf_fn[BUF_LEN]; 1481eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static UChar buf_obj[BUF_LEN]; 1482eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static UChar buf_srcloc[BUF_LEN]; 1483eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static UChar buf_dirname[BUF_LEN]; 1484eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool know_dirinfo = False; 14854ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool know_fnname = VG_(clo_sym_offsets) 14864ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj ? VG_(get_fnname_w_offset) (eip, buf_fn, BUF_LEN) 14874ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj : VG_(get_fnname) (eip, buf_fn, BUF_LEN); 1488eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool know_objname = VG_(get_objname)(eip, buf_obj, BUF_LEN); 1489eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool know_srcloc = VG_(get_filename_linenum)( 1490eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj eip, 1491eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf_srcloc, BUF_LEN, 1492eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf_dirname, BUF_LEN, &know_dirinfo, 1493eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj &lineno 1494eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj ); 1495eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (VG_(clo_xml)) { 1496eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1497eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool human_readable = True; 1498eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj HChar* maybe_newline = human_readable ? "\n " : ""; 1499eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj HChar* maybe_newline2 = human_readable ? "\n " : ""; 1500eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1501e872fec0c1c3b478a399fdba42ac65764b53f470sewardj /* Print in XML format, dumping in as much info as we know. 1502e872fec0c1c3b478a399fdba42ac65764b53f470sewardj Ensure all tags are balanced even if the individual strings 1503e872fec0c1c3b478a399fdba42ac65764b53f470sewardj are too long. Allocate 1/10 of BUF_LEN to the object name, 1504e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 6/10s to the function name, 1/10 to the directory name and 1505e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 1/10 to the file name, leaving 1/10 for all the fixed-length 1506e872fec0c1c3b478a399fdba42ac65764b53f470sewardj stuff. */ 1507eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<frame>"); 1508a44b15f527bbebfe824a2e68e4bd6ab1e153b486sewardj VG_(sprintf)(ibuf,"<ip>0x%llX</ip>", (ULong)eip); 1509eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1510eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 1511eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_objname) { 1512eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1513eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<obj>"); 1514e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(1*BUF_LEN/10, buf_obj); 1515eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</obj>"); 1516eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1517eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_fnname) { 1518eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1519eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<fn>"); 1520e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(6*BUF_LEN/10, buf_fn); 1521eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</fn>"); 1522eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1523eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_srcloc) { 1524eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_dirinfo) { 1525eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1526eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<dir>"); 1527e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(1*BUF_LEN/10, buf_dirname); 1528eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</dir>"); 1529eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1530eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1531eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<file>"); 1532e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(1*BUF_LEN/10, buf_srcloc); 1533eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</file>"); 1534eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1535eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<line>"); 1536eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(sprintf)(ibuf,"%d",lineno); 1537eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 1538eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</line>"); 1539eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1540eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline2); 1541eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</frame>"); 1542eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1543eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 1544eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1545eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Print for humans to read */ 1546a44b15f527bbebfe824a2e68e4bd6ab1e153b486sewardj VG_(sprintf)(ibuf,"0x%llX: ", (ULong)eip); 1547eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 1548eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_fnname) { 1549eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(buf_fn); 1550eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (!know_srcloc && know_objname) { 1551eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(" (in "); 1552eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(buf_obj); 1553eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(")"); 1554eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1555eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else if (know_objname && !know_srcloc) { 1556eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("(within "); 1557eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(buf_obj); 1558eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(")"); 1559eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 1560eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("???"); 1561eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1562eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_srcloc) { 1563eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(" ("); 1564eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(buf_srcloc); 1565eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(":"); 1566eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(sprintf)(ibuf,"%d",lineno); 1567eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 1568eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(")"); 1569eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1570eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1571eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1572eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return buf; 1573eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1574eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef APPEND 1575eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef APPEND_ESC 1576eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef BUF_LEN 1577eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1578eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 157972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 1580b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 1581b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 1582b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/ 1583b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- DWARF3 .eh_frame INFO ---*/ 1584b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 1585b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 158672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 158772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/* Gather up all the constant pieces of info needed to evaluate 158872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj a CfiExpr into one convenient struct. */ 158972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjtypedef 159072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj struct { 159172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj Addr ipHere; 159272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj Addr spHere; 159372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj Addr fpHere; 159472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj Addr min_accessible; 159572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj Addr max_accessible; 159672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 159772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExprEvalContext; 159872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 159972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/* Evaluate the CfiExpr rooted at ix in exprs given the context eec. 160072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj *ok is set to False on failure, but not to True on success. The 160172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj caller must set it to True before calling. */ 160272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjstatic 160372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjUWord evalCfiExpr ( XArray* exprs, Int ix, 160472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExprEvalContext* eec, Bool* ok ) 160572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj{ 160672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj UWord wL, wR; 160719dc88f90d0e19a1463797dd99f6792a42f961d3sewardj Addr a; 160872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExpr* e = VG_(indexXA)( exprs, ix ); 160972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->tag) { 161072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_Binop: 161172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj wL = evalCfiExpr( exprs, e->Cex.Binop.ixL, eec, ok ); 161272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!(*ok)) return 0; 161372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj wR = evalCfiExpr( exprs, e->Cex.Binop.ixR, eec, ok ); 161472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!(*ok)) return 0; 161572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->Cex.Binop.op) { 161672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cop_Add: return wL + wR; 161772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cop_Sub: return wL - wR; 161819dc88f90d0e19a1463797dd99f6792a42f961d3sewardj case Cop_And: return wL & wR; 16197888e2204fff6e7429236b4227ed16594e7743b9sewardj case Cop_Mul: return wL * wR; 162072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: goto unhandled; 162172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 162272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 162372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_CfiReg: 162472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->Cex.CfiReg.reg) { 162572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Creg_IP: return (Addr)eec->ipHere; 162672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Creg_SP: return (Addr)eec->spHere; 162772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Creg_FP: return (Addr)eec->fpHere; 162872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: goto unhandled; 162972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 163072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 163172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_Const: 163272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj return e->Cex.Const.con; 163319dc88f90d0e19a1463797dd99f6792a42f961d3sewardj case Cex_Deref: 163419dc88f90d0e19a1463797dd99f6792a42f961d3sewardj a = evalCfiExpr( exprs, e->Cex.Deref.ixAddr, eec, ok ); 163519dc88f90d0e19a1463797dd99f6792a42f961d3sewardj if (!(*ok)) return 0; 163619dc88f90d0e19a1463797dd99f6792a42f961d3sewardj if (a < eec->min_accessible 163719dc88f90d0e19a1463797dd99f6792a42f961d3sewardj || (a + sizeof(UWord) - 1) > eec->max_accessible) { 163819dc88f90d0e19a1463797dd99f6792a42f961d3sewardj *ok = False; 163919dc88f90d0e19a1463797dd99f6792a42f961d3sewardj return 0; 164019dc88f90d0e19a1463797dd99f6792a42f961d3sewardj } 164119dc88f90d0e19a1463797dd99f6792a42f961d3sewardj /* let's hope it doesn't trap! */ 164219dc88f90d0e19a1463797dd99f6792a42f961d3sewardj return * ((UWord*)a); 164372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: 164472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj goto unhandled; 164572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 164672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 164772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj unhandled: 164872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("\n\nevalCfiExpr: unhandled\n"); 164972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj ML_(ppCfiExpr)( exprs, ix ); 165072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("\n"); 165172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); 165272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 165372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj return 0; 165472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj} 165572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 165672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 1657f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Search all the DebugInfos in the entire system, to find the DiCfSI 1658f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj that pertains to 'ip'. 1659eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1660f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj If found, set *diP to the DebugInfo in which it resides, and 1661f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *ixP to the index in that DebugInfo's cfsi array. 166272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 1663f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj If not found, set *diP to (DebugInfo*)1 and *ixP to zero. 1664f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj*/ 1665f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj__attribute__((noinline)) 1666f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic void find_DiCfSI ( /*OUT*/DebugInfo** diP, 1667f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*OUT*/Word* ixP, 1668f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Addr ip ) 1669f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 1670f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo* di; 1671f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word i = -1; 1672f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1673f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj static UWord n_search = 0; 1674f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj static UWord n_steps = 0; 1675eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_search++; 1676eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1677f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0) VG_(printf)("search for %#lx\n", ip); 1678eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1679f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1680f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word j; 1681eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_steps++; 1682eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Use the per-DebugInfo summary address ranges to skip 1684b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj inapplicable DebugInfos quickly. */ 1685f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di->cfsi_used == 0) 1686eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj continue; 1687f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (ip < di->cfsi_minavma || ip > di->cfsi_maxavma) 1688eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj continue; 1689eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1690f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* It might be in this DebugInfo. Search it. */ 1691f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj j = ML_(search_one_cfitab)( di, ip ); 1692f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(j >= -1 && j < (Word)di->cfsi_used); 1693f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1694f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (j != -1) { 1695f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj i = j; 1696f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj break; /* found it */ 1697eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1698eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1699eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1700f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (i == -1) { 1701f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1702f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* we didn't find it. */ 1703f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *diP = (DebugInfo*)1; 1704f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *ixP = 0; 1705f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1706f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 1707f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1708f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* found it. */ 1709f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* ensure that di is 4-aligned (at least), so it can't possibly 1710f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj be equal to (DebugInfo*)1. */ 1711f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di && VG_IS_4_ALIGNED(di)); 1712f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(i >= 0 && i < di->cfsi_used); 1713f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *diP = di; 1714f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *ixP = i; 1715f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1716f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Start of performance-enhancing hack: once every 64 (chosen 1717f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj hackily after profiling) successful searches, move the found 1718f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo one step closer to the start of the list. This 1719f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj makes future searches cheaper. For starting konqueror on 1720f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj amd64, this in fact reduces the total amount of searching 1721f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj done by the above find-the-right-DebugInfo loop by more than 1722f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj a factor of 20. */ 1723f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if ((n_search & 0xF) == 0) { 1724f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Move di one step closer to the start of the list. */ 1725f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj move_DebugInfo_one_step_forward( di ); 1726f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 1727f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* End of performance-enhancing hack. */ 1728f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1729f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && ((n_search & 0x7FFFF) == 0)) 1730f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(printf)("find_DiCfSI: %lu searches, " 1731f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj "%lu DebugInfos looked at\n", 1732f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj n_search, n_steps); 1733f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1734f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 1735f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1736f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 1737f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1738f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1739f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Now follows a mechanism for caching queries to find_DiCfSI, since 1740f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj they are extremely frequent on amd64-linux, during stack unwinding. 1741f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1742f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Each cache entry binds an ip value to a (di, ix) pair. Possible 1743f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj values: 1744f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1745f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj di is non-null, ix >= 0 ==> cache slot in use, "di->cfsi[ix]" 1746f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj di is (DebugInfo*)1 ==> cache slot in use, no associated di 1747f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj di is NULL ==> cache slot not in use 1748f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1749f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Hence simply zeroing out the entire cache invalidates all 1750f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj entries. 1751f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1752f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Why not map ip values directly to DiCfSI*'s? Because this would 1753f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cause problems if/when the cfsi array is moved due to resizing. 1754f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Instead we cache .cfsi array index value, which should be invariant 1755f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj across resizing. (That said, I don't think the current 1756f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj implementation will resize whilst during queries, since the DiCfSI 1757f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj records are added all at once, when the debuginfo for an object is 1758f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj read, and is not changed ever thereafter. */ 1759eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1760f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#define N_CFSI_CACHE 511 1761f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1762f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjtypedef 1763f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj struct { Addr ip; DebugInfo* di; Word ix; } 1764f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj CFSICacheEnt; 1765f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1766f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic CFSICacheEnt cfsi_cache[N_CFSI_CACHE]; 1767f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1768f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic void cfsi_cache__invalidate ( void ) { 1769f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(memset)(&cfsi_cache, 0, sizeof(cfsi_cache)); 1770f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 1771f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1772f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1773f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* The main function for DWARF2/3 CFI-based stack unwinding. 1774f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Given an IP/SP/FP triple, produce the IP/SP/FP values for the 1775f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj previous frame, if possible. */ 1776f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Returns True if OK. If not OK, *{ip,sp,fp}P are not changed. */ 1777f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* NOTE: this function may rearrange the order of entries in the 1778f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo list. */ 1779f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjBool VG_(use_CF_info) ( /*MOD*/Addr* ipP, 1780f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*MOD*/Addr* spP, 1781f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*MOD*/Addr* fpP, 1782f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Addr min_accessible, 1783f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Addr max_accessible ) 1784f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 1785f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool ok; 1786f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo* di; 1787f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DiCfSI* cfsi = NULL; 1788f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Addr cfa, ipHere, spHere, fpHere, ipPrev, spPrev, fpPrev; 1789f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1790f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj CfiExprEvalContext eec; 1791f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1792f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj static UWord n_q = 0, n_m = 0; 1793f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj n_q++; 1794f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && 0 == (n_q & 0x1FFFFF)) 1795f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(printf)("QQQ %lu %lu\n", n_q, n_m); 1796f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1797f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj { UWord hash = (*ipP) % N_CFSI_CACHE; 1798f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj CFSICacheEnt* ce = &cfsi_cache[hash]; 1799f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1800f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (LIKELY(ce->ip == *ipP) && LIKELY(ce->di != NULL)) { 1801f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* found an entry in the cache .. */ 1802f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 1803f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* not found in cache. Search and update. */ 1804f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj n_m++; 1805f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj ce->ip = *ipP; 1806f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj find_DiCfSI( &ce->di, &ce->ix, *ipP ); 1807f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 1808f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1809f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (UNLIKELY(ce->di == (DebugInfo*)1)) { 1810f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* no DiCfSI for this address */ 1811f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi = NULL; 1812f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj di = NULL; 1813f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 1814f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* found a DiCfSI for this address */ 1815f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj di = ce->di; 1816f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi = &di->cfsi[ ce->ix ]; 1817f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 1818eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1819f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1820f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (UNLIKELY(cfsi == NULL)) 1821f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return False; /* no info. Nothing we can do. */ 1822eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1823eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (0) { 1824eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(printf)("found cfisi: "); 1825f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj ML_(ppDiCfSI)(di->cfsi_exprs, cfsi); 1826eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1827eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1828eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj ipPrev = spPrev = fpPrev = 0; 1829eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1830eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj ipHere = *ipP; 1831eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj spHere = *spP; 1832eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj fpHere = *fpP; 1833eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 183472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /* First compute the CFA. */ 183572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj cfa = 0; 183672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (cfsi->cfa_how) { 183772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case CFIC_SPREL: 183872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj cfa = cfsi->cfa_off + spHere; 183972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 184072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case CFIC_FPREL: 184172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj cfa = cfsi->cfa_off + fpHere; 184272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 184372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case CFIC_EXPR: 18447888e2204fff6e7429236b4227ed16594e7743b9sewardj if (0) { 18457888e2204fff6e7429236b4227ed16594e7743b9sewardj VG_(printf)("CFIC_EXPR: "); 1846f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj ML_(ppCfiExpr)(di->cfsi_exprs, cfsi->cfa_off); 18477888e2204fff6e7429236b4227ed16594e7743b9sewardj VG_(printf)("\n"); 18487888e2204fff6e7429236b4227ed16594e7743b9sewardj } 18497888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.ipHere = ipHere; 18507888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.spHere = spHere; 18517888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.fpHere = fpHere; 18527888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.min_accessible = min_accessible; 18537888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.max_accessible = max_accessible; 18547888e2204fff6e7429236b4227ed16594e7743b9sewardj ok = True; 1855f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfa = evalCfiExpr(di->cfsi_exprs, cfsi->cfa_off, &eec, &ok ); 18567888e2204fff6e7429236b4227ed16594e7743b9sewardj if (!ok) return False; 185772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 185872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: 185972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); 186072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 186172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 186272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /* Now we know the CFA, use it to roll back the registers we're 186372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj interested in. */ 1864eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1865eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define COMPUTE(_prev, _here, _how, _off) \ 1866eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj do { \ 1867eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj switch (_how) { \ 1868eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_UNKNOWN: \ 1869eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; \ 1870eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_SAME: \ 1871eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj _prev = _here; break; \ 1872eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_MEMCFAREL: { \ 1873eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Addr a = cfa + (Word)_off; \ 1874eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (a < min_accessible \ 18759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj || a > max_accessible-sizeof(Addr)) \ 1876eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; \ 1877eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj _prev = *(Addr*)a; \ 1878eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; \ 1879eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } \ 1880eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_CFAREL: \ 1881eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj _prev = cfa + (Word)_off; \ 1882eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; \ 188372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case CFIR_EXPR: \ 188472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (0) \ 1885f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj ML_(ppCfiExpr)(di->cfsi_exprs,_off); \ 188672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.ipHere = ipHere; \ 188772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.spHere = spHere; \ 188872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.fpHere = fpHere; \ 188972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.min_accessible = min_accessible; \ 189072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.max_accessible = max_accessible; \ 189172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj ok = True; \ 1892f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj _prev = evalCfiExpr(di->cfsi_exprs, _off, &eec, &ok ); \ 189372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!ok) return False; \ 189472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; \ 189572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: \ 189672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); \ 1897eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } \ 1898eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } while (0) 1899eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1900eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj COMPUTE(ipPrev, ipHere, cfsi->ra_how, cfsi->ra_off); 1901eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj COMPUTE(spPrev, spHere, cfsi->sp_how, cfsi->sp_off); 1902eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj COMPUTE(fpPrev, fpHere, cfsi->fp_how, cfsi->fp_off); 1903eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1904eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef COMPUTE 1905eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1906eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *ipP = ipPrev; 1907eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *spP = spPrev; 1908eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *fpP = fpPrev; 1909eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1910eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1911eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1912eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1913b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 1914b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 1915b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- TOP LEVEL: GENERATE DESCRIPTION OF DATA ADDRESSES ---*/ 1916b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- FROM DWARF3 DEBUG INFO ---*/ 1917b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 1918b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 1919b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1920b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Evaluate the location expression/list for var, to see whether or 1921b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj not data_addr falls within the variable. If so also return the 1922b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset of data_addr from the start of the variable. Note that 1923b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs, which supplies ip,sp,fp values, will be NULL for global 1924b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj variables, and non-NULL for local variables. */ 1925b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Bool data_address_is_in_var ( /*OUT*/UWord* offset, 19269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* /* TyEnt */ tyents, 1927b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var, 1928b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj RegSummary* regs, 1929b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 1930b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_bias ) 1931b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 193250fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 1933b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj SizeT var_szB; 1934b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj GXResult res; 1935b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool show = False; 19369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 1937b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->name); 1938b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->gexpr); 1939b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1940b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Figure out how big the variable is. */ 194150fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(tyents, var->typeR); 194250fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 194350fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. ML_(addVar) 194450fde23467d92281b32dd537d0d9a590263628c3sewardj should have rejected it. */ 194550fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 194650fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 194750fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 194850fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a host word 194950fde23467d92281b32dd537d0d9a590263628c3sewardj safely (without loss of info). */ 195050fde23467d92281b32dd537d0d9a590263628c3sewardj 195150fde23467d92281b32dd537d0d9a590263628c3sewardj var_szB = (SizeT)mul.ul; /* NB: truncate to host word */ 1952b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1953b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) { 1954a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("VVVV: data_address_%#lx_is_in_var: %s :: ", 1955b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var->name ); 19569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(pp_TyEnt_C_ishly)( tyents, var->typeR ); 1957b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("\n"); 1958b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1959b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1960b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ignore zero-sized vars; they can never match anything. */ 1961b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (var_szB == 0) { 1962b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) 1963b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("VVVV: -> Fail (variable is zero sized)\n"); 1964b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 1965b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1966b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1967b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = ML_(evaluate_GX)( var->gexpr, var->fbGX, regs, data_bias ); 1968b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1969b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) { 1970b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("VVVV: -> "); 1971b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(pp_GXResult)( res ); 1972b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("\n"); 1973b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1974eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1975b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (res.kind == GXR_Value 1976b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && res.word <= data_addr 1977b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && data_addr < res.word + var_szB) { 1978b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *offset = data_addr - res.word; 1979b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 1980b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 1981b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 1982b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1983b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 1984b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1985b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1986b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Format the acquired information into dname1[0 .. n_dname-1] and 1987b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2[0 .. n_dname-1] in an understandable way. Not so easy. 1988b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj If frameNo is -1, this is assumed to be a global variable; else 1989b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj a local variable. */ 1990b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void format_message ( /*OUT*/Char* dname1, 1991b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/Char* dname2, 1992b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int n_dname, 1993b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 1994b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var, 1995b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OffT var_offset, 1996b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OffT residual_offset, 1997b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* /*UChar*/ described, 1998b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int frameNo, 1999b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid ) 2000eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2001b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool have_descr, have_srcloc; 2002b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj UChar* vo_plural = var_offset == 1 ? "" : "s"; 2003b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj UChar* ro_plural = residual_offset == 1 ? "" : "s"; 2004b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2005b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(frameNo >= -1); 2006b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(dname1 && dname2 && n_dname > 1); 2007b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(described); 2008b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var && var->name); 2009b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj have_descr = VG_(sizeXA)(described) > 0 2010b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && *(UChar*)VG_(indexXA)(described,0) != '\0'; 2011b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj have_srcloc = var->fileName && var->lineNo > 0; 2012b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2013b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[0] = dname2[0] = '\0'; 2014b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2015b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ------ local cases ------ */ 2016b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2017b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && (!have_srcloc) && (!have_descr) ) { 2018b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc, no description: 2019b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside local var "a", 2020b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in frame #1 of thread 1 2021b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2022b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2023b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 2024b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside local var \"%s\",", 2025b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var_offset, vo_plural, var->name ); 2026b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2027b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2, n_dname, 2028b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "in frame #%d of thread %d", frameNo, (Int)tid); 2029b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2030b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2031b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && have_srcloc && (!have_descr) ) { 2032b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no description: 2033b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside local var "a" 2034b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj declared at dsyms7.c:17, in frame #1 of thread 1 2035b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2036b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2037b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 2038b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside local var \"%s\"", 2039b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var_offset, vo_plural, var->name ); 2040b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2041b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2, n_dname, 2042b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "declared at %s:%d, in frame #%d of thread %d", 2043b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var->fileName, var->lineNo, frameNo, (Int)tid); 2044b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2045b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2046b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && (!have_srcloc) && have_descr ) { 2047b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc: 2048b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2 2049b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in frame #1 of thread 1 2050b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2051b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2052b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 2053b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside %s%s", 2054b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, residual_offset, ro_plural, var->name, 2055a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart (char*)(VG_(indexXA)(described,0)) ); 2056b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2057b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2, n_dname, 2058b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "in frame #%d of thread %d", frameNo, (Int)tid); 2059b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2060b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2061b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && have_srcloc && have_descr ) { 2062b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 2063b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj declared at dsyms7.c:17, in frame #1 of thread 1 */ 2064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2065b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 2066b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside %s%s,", 2067b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, residual_offset, ro_plural, var->name, 2068a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart (char*)(VG_(indexXA)(described,0)) ); 2069b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2070b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2, n_dname, 2071b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "declared at %s:%d, in frame #%d of thread %d", 2072b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var->fileName, var->lineNo, frameNo, (Int)tid); 2073b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2074b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2075b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ------ global cases ------ */ 2076b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && (!have_srcloc) && (!have_descr) ) { 2077b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc, no description: 2078b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside global var "a" 2079b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2080b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2081b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 2082b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside global var \"%s\"", 2083b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var_offset, vo_plural, var->name ); 2084b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2085b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2086b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && have_srcloc && (!have_descr) ) { 2087b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no description: 2088b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside global var "a" 2089b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj declared at dsyms7.c:17 2090b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2091b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2092b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 2093b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside global var \"%s\"", 2094b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var_offset, vo_plural, var->name ); 2095b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2096b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2, n_dname, 2097b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "declared at %s:%d", 2098b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var->fileName, var->lineNo); 2099b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2100b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2101b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && (!have_srcloc) && have_descr ) { 2102b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc: 2103b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 2104b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj a global variable 2105b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2106b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2107b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 2108b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside %s%s,", 2109b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, residual_offset, ro_plural, var->name, 2110a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart (char*)(VG_(indexXA)(described,0)) ); 2111b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2112b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2, n_dname, 2113b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "a global variable"); 2114b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2115b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2116b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && have_srcloc && have_descr ) { 2117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 2118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj a global variable declared at dsyms7.c:17 */ 2119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 2121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside %s%s,", 2122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, residual_offset, ro_plural, var->name, 2123a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart (char*)(VG_(indexXA)(described,0)) ); 2124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2, n_dname, 2126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "a global variable declared at %s:%d", 2127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var->fileName, var->lineNo); 2128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(0); 2131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 2133eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2134eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Determine if data_addr is a local variable in the frame 2136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj characterised by (ip,sp,fp), and if so write its description into 2137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname{1,2}[0..n_dname-1], and return True. If not, return 2138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj False. */ 2139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic 2140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool consider_vars_in_frame ( /*OUT*/Char* dname1, 2141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/Char* dname2, 2142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int n_dname, 2143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 2144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr ip, Addr sp, Addr fp, 2145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* shown to user: */ 2146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid, Int frameNo ) 2147eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word i; 2149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 2150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj RegSummary regs; 2151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool debug = False; 2152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj static UInt n_search = 0; 2154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj static UInt n_steps = 0; 2155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_search++; 2156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 2157a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("QQQQ: cvif: ip,sp,fp %#lx,%#lx,%#lx\n", ip,sp,fp); 2158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* first, find the DebugInfo that pertains to 'ip'. */ 2159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di; di = di->next) { 2160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_steps++; 2161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* text segment missing? unlikely, but handle it .. */ 2162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->text_present || di->text_size == 0) 2163b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok. So does this text mapping bracket the ip? */ 2165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_avma <= ip && ip < di->text_avma + di->text_size) 2166b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 2167b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2168b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2169b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Didn't find it. Strange -- means ip is a code address outside 2170b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj of any mapped text segment. Unlikely but not impossible -- app 2171b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj could be generating code to run. */ 2172b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di) 2173b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 2174b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0 && ((n_search & 0x1) == 0)) 2176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("consider_vars_in_frame: %u searches, " 2177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "%u DebugInfos looked at\n", 2178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_search, n_steps); 2179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Start of performance-enhancing hack: once every ??? (chosen 2180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj hackily after profiling) successful searches, move the found 2181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo one step closer to the start of the list. This makes 2182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj future searches cheaper. */ 2183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ((n_search & 0xFFFF) == 0) { 2184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Move si one step closer to the start of the list. */ 2185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj move_DebugInfo_one_step_forward( di ); 2186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2187b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* End of performance-enhancing hack. */ 2188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2189b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* any var info at all? */ 2190b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->varinfo) 2191b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 2192b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2193b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Work through the scopes from most deeply nested outwards, 2194b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj looking for code address ranges that bracket 'ip'. The 2195b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj variables on each such address range found are in scope right 2196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj now. Don't descend to level zero as that is the global 2197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj scope. */ 2198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.ip = ip; 2199b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.sp = sp; 2200b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.fp = fp; 2201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* "for each scope, working outwards ..." */ 2203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) { 2204b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* vars; 2205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word j; 2206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* arange; 2207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* this_scope 2208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj = *(OSet**)VG_(indexXA)( di->varinfo, i ); 2209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 2210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("QQQQ: considering scope %ld\n", (Word)i); 2211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!this_scope) 2212b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Find the set of variables in this scope that 2214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj bracket the program counter. */ 2215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj arange = VG_(OSetGen_LookupWithCmp)( 2216b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj this_scope, &ip, 2217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(cmp_for_DiAddrRange_range) 2218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ); 2219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!arange) 2220b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* stay sane */ 2222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->aMin <= arange->aMax); 2223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* It must bracket the ip we asked for, else 2224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(cmp_for_DiAddrRange_range) is somehow broken. */ 2225b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->aMin <= ip && ip <= arange->aMax); 2226b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* It must have an attached XArray of DiVariables. */ 2227b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vars = arange->vars; 2228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(vars); 2229b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* But it mustn't cover the entire address range. We only 2230b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj expect that to happen for the global scope (level 0), which 2231b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj we're not looking at here. Except, it may cover the entire 2232b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj address range, but in that case the vars array must be 2233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj empty. */ 2234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(! (arange->aMin == (Addr)0 2235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && arange->aMax == ~(Addr)0 2236b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && VG_(sizeXA)(vars) > 0) ); 2237b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < VG_(sizeXA)( vars ); j++) { 2238b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j ); 2239b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj SizeT offset; 2240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 2241a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n", 2242b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var->name,arange->aMin,arange->aMax,ip); 22439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (data_address_is_in_var( &offset, di->admin_tyents, 22449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var, ®s, 22459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj data_addr, di->data_bias )) { 2246b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OffT residual_offset = 0; 2247b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* described = ML_(describe_type)( &residual_offset, 22489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->admin_tyents, 22499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR, offset ); 2250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj format_message( dname1, dname2, n_dname, 2251b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var, offset, residual_offset, 2252b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj described, frameNo, tid ); 2253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)( described ); 2254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 2255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2257b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 2260eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2261eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Try to form some description of data_addr by looking at the DWARF3 2263b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debug info we have. This considers all global variables, and all 2264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj frames in the stacks of all threads. Result (or as much as will 2265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj fit) is put into into dname{1,2}[0 .. n_dname-1] and is guaranteed 2266b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to be zero terminated. */ 2267b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool VG_(get_data_description)( /*OUT*/Char* dname1, 2268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/Char* dname2, 2269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int n_dname, 2270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr ) 2271eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# define N_FRAMES 8 2273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr ips[N_FRAMES], sps[N_FRAMES], fps[N_FRAMES]; 2274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj UInt n_frames; 2275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr stack_min, stack_max; 2277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid; 2278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool found; 2279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 2280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word j; 2281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_dname > 1); 2283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 2284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2285a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart if (0) VG_(printf)("get_data_description: dataaddr %#lx\n", data_addr); 2286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* First, see if data_addr is (or is part of) a global variable. 2287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Loop over the DebugInfos we have. Check data_addr against the 2288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj outermost scope of all of them, as that should be a global 2289b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj scope. */ 2290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 2291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* global_scope; 22929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word gs_size; 2293b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr zero; 2294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* global_arange; 2295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word i; 2296b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* vars; 2297b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* text segment missing? unlikely, but handle it .. */ 2299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->text_present || di->text_size == 0) 2300b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* any var info at all? */ 2302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->varinfo) 2303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* perhaps this object didn't contribute any vars at all? */ 2305b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (VG_(sizeXA)( di->varinfo ) == 0) 2306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2307b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj global_scope = *(OSet**)VG_(indexXA)( di->varinfo, 0 ); 2308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_scope); 2309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj gs_size = VG_(OSetGen_Size)( global_scope ); 2310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* The global scope might be completely empty if this 2311b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj compilation unit declared locals but nothing global. */ 2312b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (gs_size == 0) 2313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* But if it isn't empty, then it must contain exactly one 2315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj element, which covers the entire address range. */ 2316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(gs_size == 1); 2317b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Fish out the global scope and check it is as expected. */ 2318b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj zero = 0; 2319b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj global_arange 2320b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj = VG_(OSetGen_Lookup)( global_scope, &zero ); 2321b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* The global range from (Addr)0 to ~(Addr)0 must exist */ 2322b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_arange); 2323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_arange->aMin == (Addr)0 2324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && global_arange->aMax == ~(Addr)0); 2325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Any vars in this range? */ 2326b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!global_arange->vars) 2327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2328b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok, there are some vars in the global scope of this 2329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo. Wade through them and see if the data addresses 2330b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj of any of them bracket data_addr. */ 2331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vars = global_arange->vars; 2332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = 0; i < VG_(sizeXA)( vars ); i++) { 2333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj SizeT offset; 2334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, i ); 2335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->name); 2336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Note we use a NULL RegSummary* here. It can't make any 2337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sense for a global variable to have a location expression 2338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which depends on a SP/FP/IP value. So don't supply any. 2339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj This means, if the evaluation of the location 2340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj expression/list requires a register, we have to let it 2341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj fail. */ 23429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (data_address_is_in_var( &offset, di->admin_tyents, var, 2343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj NULL/* RegSummary* */, 2344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, di->data_bias )) { 2345b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OffT residual_offset = 0; 2346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* described = ML_(describe_type)( &residual_offset, 23479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->admin_tyents, 23489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR, offset ); 2349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj format_message( dname1, dname2, n_dname, 2350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var, offset, residual_offset, 2351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj described, -1/*frameNo*/, tid ); 2352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)( described ); 2353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 2354b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 2355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2356b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2358b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2359b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok, well it's not a global variable. So now let's snoop around 2360b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in the stacks of all the threads. First try to figure out which 2361b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj thread's stack data_addr is in. */ 2362b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2363b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* --- KLUDGE --- Try examining the top frame of all thread stacks. 2364b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj This finds variables which are not stack allocated but are not 2365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj globally visible either; specifically it appears to pick up 2366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj variables which are visible only within a compilation unit. 2367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj These will have the address range of the compilation unit and 2368b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj tend to live at Scope level 1. */ 2369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(thread_stack_reset_iter)(&tid); 2370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) { 2371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (stack_min >= stack_max) 2372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; /* ignore obviously stupid cases */ 2373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (consider_vars_in_frame( dname1, dname2, n_dname, 2374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, 2375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(get_IP)(tid), 2376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(get_SP)(tid), 2377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(get_FP)(tid), tid, 0 )) { 2378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 2379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 2380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* --- end KLUDGE --- */ 2383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Perhaps it's on a thread's stack? */ 2385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj found = False; 2386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(thread_stack_reset_iter)(&tid); 2387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) { 2388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (stack_min >= stack_max) 2389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; /* ignore obviously stupid cases */ 2390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (stack_min - VG_STACK_REDZONE_SZB <= data_addr 2391b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && data_addr <= stack_max) { 2392b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj found = True; 2393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 2394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!found) { 2397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 2398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 2399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We conclude data_addr is in thread tid's stack. Unwind the 2402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj stack to get a bunch of (ip,sp,fp) triples describing the 2403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj frames, and for each frame, consider the local variables. */ 2404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_frames = VG_(get_StackTrace)( tid, ips, N_FRAMES, 2405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sps, fps, 0/*first_ip_delta*/ ); 2406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Re ip_delta in the next loop: There's a subtlety in the meaning 2407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj of the IP values in a stack obtained from VG_(get_StackTrace). 2408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj The innermost value really is simply the thread's program 2409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj counter at the time the snapshot was taken. However, all the 2410b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj other values are actually return addresses, and so point just 2411b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj after the call instructions. Hence they notionally reflect not 2412b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj what the program counters were at the time those calls were 2413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj made, but what they will be when those calls return. This can 2414b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj be of significance should an address range happen to end at the 2415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj end of a call instruction -- we may ignore the range when in 2416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj fact it should be considered. Hence, back up the IPs by 1 for 2417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj all non-innermost IPs. Note that VG_(get_StackTrace_wrk) itself 2418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj has to use the same trick in order to use CFI data to unwind the 2419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj stack (as documented therein in comments). */ 2420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* As a result of KLUDGE above, starting the loop at j = 0 2421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj duplicates examination of the top frame and so isn't necessary. 2422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Oh well. */ 2423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_frames >= 0 && n_frames <= N_FRAMES); 2424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < n_frames; j++) { 2425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word ip_delta = j == 0 ? 0 : 1; 2426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (consider_vars_in_frame( dname1, dname2, n_dname, 2427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, 2428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ips[j] - ip_delta, 2429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sps[j], fps[j], tid, j )) { 2430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 2431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 2432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Now, it appears that gcc sometimes appears to produce 2434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj location lists whose ranges don't actually cover the call 2435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj instruction, even though the address of the variable in 2436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj question is passed as a parameter in the call. AFAICS this 2437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is simply a bug in gcc - how can the variable be claimed not 2438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj exist in memory (on the stack) for the duration of a call in 2439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which its address is passed? But anyway, in the particular 2440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case I investigated (memcheck/tests/varinfo6.c, call to croak 2441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj on line 2999, local var budget declared at line 3115 2442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj appearing not to exist across the call to mainSort on line 2443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3143, "gcc.orig (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2)" on 2444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj amd64), the variable's location list does claim it exists 2445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj starting at the first byte of the first instruction after the 2446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj call instruction. So, call consider_vars_in_frame a second 2447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj time, but this time don't subtract 1 from the IP. GDB 2448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj handles this example with no difficulty, which leads me to 2449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj believe that either (1) I misunderstood something, or (2) GDB 2450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj has an equivalent kludge. */ 2451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (consider_vars_in_frame( dname1, dname2, n_dname, 2452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, 2453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ips[j], 2454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sps[j], fps[j], tid, j )) { 2455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 2456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 2457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2460b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We didn't find anything useful. */ 2461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 2462b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 2463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# undef N_FRAMES 2464eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2465eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 24679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj////////////////////////////////////////////////////////////////// 24689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// // 24699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// Support for other kinds of queries to the Dwarf3 var info // 24709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// // 24719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj////////////////////////////////////////////////////////////////// 24729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 24739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Figure out if the variable 'var' has a location that is linearly 24749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj dependent on a stack pointer value, or a frame pointer value, and 24759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if it is, add a description of it to 'blocks'. Otherwise ignore 24769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. If 'arrays_only' is True, also ignore it unless it has an 24779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj array type. */ 24789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 24799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic 24809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks, 24819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* /* TyEnt */ tyents, 24829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Addr ip, Addr data_bias, DiVariable* var, 24839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool arrays_only ) 24849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 24859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res_sp_6k, res_sp_7k, res_fp_6k, res_fp_7k; 24869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj RegSummary regs; 248750fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 24889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool isVec; 24899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ty; 24909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 24919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool debug = False; 24929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0&&debug) 24939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("adeps: var %s\n", var->name ); 24949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 24959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Figure out how big the variable is. */ 249650fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(tyents, var->typeR); 249750fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 249850fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. ML_(addVar) 249950fde23467d92281b32dd537d0d9a590263628c3sewardj should have rejected it. */ 250050fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 250150fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 250250fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 250350fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a host word 250450fde23467d92281b32dd537d0d9a590263628c3sewardj safely (without loss of info). */ 25059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 25069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* skip if non-array and we're only interested in arrays */ 25079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ty = ML_(TyEnts__index_by_cuOff)( tyents, NULL, var->typeR ); 25089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty); 25099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty)); 25109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (ty->tag == Te_UNKNOWN) 25119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return; /* perhaps we should complain in this case? */ 25129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj isVec = ty->tag == Te_TyArray; 25139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (arrays_only && !isVec) 25149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return; 25159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 25169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) {ML_(pp_TyEnt_C_ishly)(tyents, var->typeR); 25179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)(" %s\n", var->name);} 25189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 25199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Do some test evaluations of the variable's location expression, 25209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj in order to guess whether it is sp-relative, fp-relative, or 25219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj none. A crude hack, which can be interpreted roughly as finding 25229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj the first derivative of the location expression w.r.t. the 25239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj supplied frame and stack pointer values. */ 25249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 0; 25259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 25269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 6 * 1024; 25279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj res_sp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, data_bias ); 25289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 25299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 0; 25309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 25319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 7 * 1024; 25329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj res_sp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, data_bias ); 25339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 25349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 6 * 1024; 25359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 25369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 0; 25379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj res_fp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, data_bias ); 25389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 25399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 7 * 1024; 25409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 25419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 0; 25429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj res_fp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, data_bias ); 25439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 25449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_sp_7k.kind); 25459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_fp_6k.kind); 25469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_fp_7k.kind); 25479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 25489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (res_sp_6k.kind == GXR_Value) { 25499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj StackBlock block; 25509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res; 25519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj UWord sp_delta = res_sp_7k.word - res_sp_6k.word; 25529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj UWord fp_delta = res_fp_7k.word - res_fp_6k.word; 25539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(sp_delta == 0 || sp_delta == 1024); 25549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(fp_delta == 0 || fp_delta == 1024); 25559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 25569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 0 && fp_delta == 0) { 25579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* depends neither on sp nor fp, so it can't be a stack 25589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj local. Ignore it. */ 25599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 25609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else 25619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 1024 && fp_delta == 0) { 25629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = regs.fp = 0; 25639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 25649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, data_bias ); 25659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(res.kind == GXR_Value); 25669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 25679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)(" %5ld .. %5ld (sp) %s\n", 256850fde23467d92281b32dd537d0d9a590263628c3sewardj res.word, res.word + ((UWord)mul.ul) - 1, var->name); 25699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.base = res.word; 257050fde23467d92281b32dd537d0d9a590263628c3sewardj block.szB = (SizeT)mul.ul; 25719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.spRel = True; 25729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.isVec = isVec; 25739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)( &block.name[0], 0, sizeof(block.name) ); 25749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (var->name) 25759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 ); 25769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.name[ sizeof(block.name)-1 ] = 0; 25779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( blocks, &block ); 25789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 25799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else 25809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 0 && fp_delta == 1024) { 25819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = regs.fp = 0; 25829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 25839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, data_bias ); 25849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(res.kind == GXR_Value); 25859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 25869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)(" %5ld .. %5ld (FP) %s\n", 258750fde23467d92281b32dd537d0d9a590263628c3sewardj res.word, res.word + ((UWord)mul.ul) - 1, var->name); 25889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.base = res.word; 258950fde23467d92281b32dd537d0d9a590263628c3sewardj block.szB = (SizeT)mul.ul; 25909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.spRel = False; 25919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.isVec = isVec; 25929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)( &block.name[0], 0, sizeof(block.name) ); 25939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (var->name) 25949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 ); 25959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.name[ sizeof(block.name)-1 ] = 0; 25969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( blocks, &block ); 25979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 25989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else { 25999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(0); 26009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 26019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 26029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 26039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 26049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 26059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Get an XArray of StackBlock which describe the stack (auto) blocks 26069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for this ip. The caller is expected to free the XArray at some 26079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj point. If 'arrays_only' is True, only array-typed blocks are 26089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj returned; otherwise blocks of all types are returned. */ 26099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 26109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid* /* really, XArray* of StackBlock */ 26119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(di_get_stack_blocks_at_ip)( Addr ip, Bool arrays_only ) 26129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 26139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* This is a derivation of consider_vars_in_frame() above. */ 26149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word i; 26159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo* di; 26169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj RegSummary regs; 26179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool debug = False; 26189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 26199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* res = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dgsbai.1", 26209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(dinfo_free), 26219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj sizeof(StackBlock) ); 26229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 26239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj static UInt n_search = 0; 26249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj static UInt n_steps = 0; 26259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_search++; 26269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 26279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: dgsbai: ip %#lx\n", ip); 26289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* first, find the DebugInfo that pertains to 'ip'. */ 26299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (di = debugInfo_list; di; di = di->next) { 26309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_steps++; 26319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* text segment missing? unlikely, but handle it .. */ 26329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->text_present || di->text_size == 0) 26339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 26349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok. So does this text mapping bracket the ip? */ 26359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (di->text_avma <= ip && ip < di->text_avma + di->text_size) 26369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj break; 26379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 26389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 26399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Didn't find it. Strange -- means ip is a code address outside 26409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj of any mapped text segment. Unlikely but not impossible -- app 26419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj could be generating code to run. */ 26429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di) 26439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; /* currently empty */ 26449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 26459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0 && ((n_search & 0x1) == 0)) 26469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("VG_(di_get_stack_blocks_at_ip): %u searches, " 26479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj "%u DebugInfos looked at\n", 26489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_search, n_steps); 26499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Start of performance-enhancing hack: once every ??? (chosen 26509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj hackily after profiling) successful searches, move the found 26519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo one step closer to the start of the list. This makes 26529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj future searches cheaper. */ 26539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if ((n_search & 0xFFFF) == 0) { 26549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Move si one step closer to the start of the list. */ 26559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj move_DebugInfo_one_step_forward( di ); 26569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 26579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* End of performance-enhancing hack. */ 26589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 26599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* any var info at all? */ 26609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->varinfo) 26619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; /* currently empty */ 26629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 26639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Work through the scopes from most deeply nested outwards, 26649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj looking for code address ranges that bracket 'ip'. The 26659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj variables on each such address range found are in scope right 26669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj now. Don't descend to level zero as that is the global 26679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj scope. */ 26689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 26699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 0; 26709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 0; 26719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 26729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* "for each scope, working outwards ..." */ 26739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) { 26749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* vars; 26759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word j; 26769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiAddrRange* arange; 26779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj OSet* this_scope 26789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj = *(OSet**)VG_(indexXA)( di->varinfo, i ); 26799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 26809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: considering scope %ld\n", (Word)i); 26819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!this_scope) 26829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 26839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Find the set of variables in this scope that 26849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj bracket the program counter. */ 26859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj arange = VG_(OSetGen_LookupWithCmp)( 26869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj this_scope, &ip, 26879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(cmp_for_DiAddrRange_range) 26889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ); 26899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!arange) 26909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 26919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* stay sane */ 26929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(arange->aMin <= arange->aMax); 26939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* It must bracket the ip we asked for, else 26949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(cmp_for_DiAddrRange_range) is somehow broken. */ 26959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(arange->aMin <= ip && ip <= arange->aMax); 26969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* It must have an attached XArray of DiVariables. */ 26979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vars = arange->vars; 26989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(vars); 26999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* But it mustn't cover the entire address range. We only 27009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj expect that to happen for the global scope (level 0), which 27019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj we're not looking at here. Except, it may cover the entire 27029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj address range, but in that case the vars array must be 27039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj empty. */ 27049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(! (arange->aMin == (Addr)0 27059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj && arange->aMax == ~(Addr)0 27069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj && VG_(sizeXA)(vars) > 0) ); 27079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (j = 0; j < VG_(sizeXA)( vars ); j++) { 27089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j ); 27099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 27109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n", 27119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->name,arange->aMin,arange->aMax,ip); 27129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj analyse_deps( res, di->admin_tyents, ip, 27139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->data_bias, var, arrays_only ); 27149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 27159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 27169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 27179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; 27189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 27199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 27209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 27219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Get an array of GlobalBlock which describe the global blocks owned 27229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj by the shared object characterised by the given di_handle. Asserts 27239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if the handle is invalid. The caller is responsible for freeing 27249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj the array at some point. If 'arrays_only' is True, only 27259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj array-typed blocks are returned; otherwise blocks of all types are 27269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj returned. */ 27279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 27289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid* /* really, XArray* of GlobalBlock */ 27299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(di_get_global_blocks_from_dihandle) ( ULong di_handle, 27309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool arrays_only ) 27319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 27329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* This is a derivation of consider_vars_in_frame() above. */ 27339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 27349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo* di; 27359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* gvars; /* XArray* of GlobalBlock */ 27369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word nScopes, scopeIx; 27379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 27389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* The first thing to do is find the DebugInfo that 27399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj pertains to 'di_handle'. */ 27409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(di_handle > 0); 27419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (di = debugInfo_list; di; di = di->next) { 27429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (di->handle == di_handle) 27439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj break; 27449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 27459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 27469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* If this fails, we were unable to find any DebugInfo with the 27479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj given handle. This is considered an error on the part of the 27489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj caller. */ 27499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(di != NULL); 27509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 27519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* we'll put the collected variables in here. */ 27529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gvars = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dggbfd.1", 27539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(dinfo_free), sizeof(GlobalBlock) ); 27549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(gvars); 27559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 27569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* any var info at all? */ 27579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->varinfo) 27589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return gvars; 27599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 27609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* we'll iterate over all the variables we can find, even if 27619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it seems senseless to visit stack-allocated variables */ 27629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over all scopes */ 27639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj nScopes = VG_(sizeXA)( di->varinfo ); 27649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (scopeIx = 0; scopeIx < nScopes; scopeIx++) { 27659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 27669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over each (code) address range at the current scope */ 27679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiAddrRange* range; 27689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj OSet* /* of DiAddrInfo */ scope 27699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj = *(OSet**)VG_(indexXA)( di->varinfo, scopeIx ); 27709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(scope); 27719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(OSetGen_ResetIter)(scope); 27729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj while ( (range = VG_(OSetGen_Next)(scope)) ) { 27739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 27749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over each variable in the current address range */ 27759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word nVars, varIx; 27769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(range->vars); 27779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj nVars = VG_(sizeXA)( range->vars ); 27789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (varIx = 0; varIx < nVars; varIx++) { 27799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 27809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool isVec; 27819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res; 278250fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 27839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GlobalBlock gb; 27849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ty; 27859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiVariable* var = VG_(indexXA)( range->vars, varIx ); 27869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(var->name); 27879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("at depth %ld var %s ", scopeIx, var->name ); 27889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 27899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Now figure out if this variable has a constant address 27909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj (that is, independent of FP, SP, phase of moon, etc), 27919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj and if so, what the address is. Any variable with a 27929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj constant address is deemed to be a global so we collect 27939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. */ 27949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) { VG_(printf)("EVAL: "); ML_(pp_GX)(var->gexpr); 27959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("\n"); } 27969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj res = ML_(evaluate_trivial_GX)( var->gexpr, di->data_bias ); 27979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 27989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Not a constant address => not interesting */ 27999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (res.kind != GXR_Value) { 28009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("FAIL\n"); 28019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 28029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 28039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok, it's a constant address. See if we want to collect 28059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. */ 28069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("%#lx\n", res.word); 28079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Figure out how big the variable is. */ 280950fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(di->admin_tyents, var->typeR); 28109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 281150fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 281250fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. 281350fde23467d92281b32dd537d0d9a590263628c3sewardj ML_(addVar) should have rejected it. */ 281450fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 281550fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 281650fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 281750fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a 281850fde23467d92281b32dd537d0d9a590263628c3sewardj host word safely (without loss of info). */ 28199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* skip if non-array and we're only interested in 28219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj arrays */ 28229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ty = ML_(TyEnts__index_by_cuOff)( di->admin_tyents, NULL, 28239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR ); 28249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty); 28259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty)); 28269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (ty->tag == Te_UNKNOWN) 28279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; /* perhaps we should complain in this case? */ 28289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj isVec = ty->tag == Te_TyArray; 28309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (arrays_only && !isVec) continue; 28319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok, so collect it! */ 28339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(var->name); 28349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(di->soname); 28359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("XXXX %s %s %d\n", var->name, 28369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->fileName?(HChar*)var->fileName 28379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj :"??",var->lineNo); 28389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)(&gb, 0, sizeof(gb)); 28399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gb.addr = res.word; 284050fde23467d92281b32dd537d0d9a590263628c3sewardj gb.szB = (SizeT)mul.ul; 28419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gb.isVec = isVec; 28429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)(&gb.name[0], var->name, sizeof(gb.name)-1); 28439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)(&gb.soname[0], di->soname, sizeof(gb.soname)-1); 28449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(gb.name[ sizeof(gb.name)-1 ] == 0); 28459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(gb.soname[ sizeof(gb.soname)-1 ] == 0); 28469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( gvars, &gb ); 28489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* for (varIx = 0; varIx < nVars; varIx++) */ 28509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* while ( (range = VG_(OSetGen_Next)(scope)) ) */ 28529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* for (scopeIx = 0; scopeIx < nScopes; scopeIx++) */ 28549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return gvars; 28569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 28579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 2860b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 2861b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- DebugInfo accessor functions ---*/ 2862b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 2863b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2864b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjconst DebugInfo* VG_(next_seginfo)(const DebugInfo* di) 2865eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2866b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == NULL) 2867b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return debugInfo_list; 2868b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->next; 2869eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2870eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2871b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjAddr VG_(seginfo_get_text_avma)(const DebugInfo* di) 2872eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2873b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_avma : 0; 2874eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2875eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2876b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjSizeT VG_(seginfo_get_text_size)(const DebugInfo* di) 2877eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2878b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_size : 0; 2879eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2880eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2881092b6268cc4a38ae9ee41d1e3355937536ddc579bartAddr VG_(seginfo_get_plt_avma)(const DebugInfo* di) 2882092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 2883092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->plt_present ? di->plt_avma : 0; 2884092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 2885092b6268cc4a38ae9ee41d1e3355937536ddc579bart 2886092b6268cc4a38ae9ee41d1e3355937536ddc579bartSizeT VG_(seginfo_get_plt_size)(const DebugInfo* di) 2887092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 2888092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->plt_present ? di->plt_size : 0; 2889092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 2890092b6268cc4a38ae9ee41d1e3355937536ddc579bart 2891092b6268cc4a38ae9ee41d1e3355937536ddc579bartAddr VG_(seginfo_get_gotplt_avma)(const DebugInfo* di) 2892092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 2893092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->gotplt_present ? di->gotplt_avma : 0; 2894092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 2895092b6268cc4a38ae9ee41d1e3355937536ddc579bart 2896092b6268cc4a38ae9ee41d1e3355937536ddc579bartSizeT VG_(seginfo_get_gotplt_size)(const DebugInfo* di) 2897092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 2898092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->gotplt_present ? di->gotplt_size : 0; 2899092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 2900092b6268cc4a38ae9ee41d1e3355937536ddc579bart 2901b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjconst UChar* VG_(seginfo_soname)(const DebugInfo* di) 2902eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2903b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->soname; 2904b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 2905eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2906b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjconst UChar* VG_(seginfo_filename)(const DebugInfo* di) 2907b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 2908b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->filename; 2909eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2910eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2911b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjULong VG_(seginfo_get_text_bias)(const DebugInfo* di) 2912bbec7728efefaa650970dd1f0282b77040287133sewardj{ 2913b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_bias : 0; 2914bbec7728efefaa650970dd1f0282b77040287133sewardj} 2915bbec7728efefaa650970dd1f0282b77040287133sewardj 2916b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjInt VG_(seginfo_syms_howmany) ( const DebugInfo *si ) 2917eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2918eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return si->symtab_used; 2919eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2920eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2921b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid VG_(seginfo_syms_getidx) ( const DebugInfo *si, 2922eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Int idx, 2923b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/Addr* avma, 29244ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj /*OUT*/Addr* tocptr, 2925eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/UInt* size, 2926b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/HChar** name, 2927b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/Bool* isText ) 2928eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2929eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(idx >= 0 && idx < si->symtab_used); 2930b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (avma) *avma = si->symtab[idx].addr; 29314ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (tocptr) *tocptr = si->symtab[idx].tocptr; 29324ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (size) *size = si->symtab[idx].size; 29334ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (name) *name = (HChar*)si->symtab[idx].name; 2934b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (isText) *isText = si->symtab[idx].isText; 2935b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 2936b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2937b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2938b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 2939b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- SectKind query functions ---*/ 2940b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 2941b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2942b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Convert a VgSectKind to a string, which must be copied if you want 2943b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to change it. */ 2944b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjconst HChar* VG_(pp_SectKind)( VgSectKind kind ) 2945b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 2946b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj switch (kind) { 2947b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectUnknown: return "Unknown"; 2948b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectText: return "Text"; 2949b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectData: return "Data"; 2950b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectBSS: return "BSS"; 2951b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectGOT: return "GOT"; 2952b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectPLT: return "PLT"; 2953b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectOPD: return "OPD"; 2954b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj default: vg_assert(0); 2955b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2956b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 2957b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2958b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Given an address 'a', make a guess of which section of which object 2959b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj it comes from. If name is non-NULL, then the last n_name-1 2960b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj characters of the object's name is put in name[0 .. n_name-2], and 2961b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj name[n_name-1] is set to zero (guaranteed zero terminated). */ 2962b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2963b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjVgSectKind VG_(seginfo_sect_kind)( /*OUT*/UChar* name, SizeT n_name, 2964b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr a) 2965b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 2966b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 2967b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VgSectKind res = Vg_SectUnknown; 2968b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2969b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 2970b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2971b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0) 2972b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)( 2973a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart "addr=%#lx di=%p %s got=%#lx,%ld plt=%#lx,%ld data=%#lx,%ld bss=%#lx,%ld\n", 2974b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj a, di, di->filename, 2975b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->got_avma, di->got_size, 2976b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->plt_avma, di->plt_size, 2977b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_avma, di->data_size, 2978b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->bss_avma, di->bss_size); 2979b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2980b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 2981b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_size > 0 2982b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->text_avma && a < di->text_avma + di->text_size) { 2983b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectText; 2984b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 2985b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2986b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->data_present 2987b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_size > 0 2988b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->data_avma && a < di->data_avma + di->data_size) { 2989b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectData; 2990b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 2991b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2992b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->sdata_present 2993b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_size > 0 2994b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->sdata_avma && a < di->sdata_avma + di->sdata_size) { 2995b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectData; 2996b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 2997b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2998b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->bss_present 2999b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_size > 0 3000b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->bss_avma && a < di->bss_avma + di->bss_size) { 3001b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectBSS; 3002b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3003b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3004b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->plt_present 3005b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->plt_size > 0 3006b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->plt_avma && a < di->plt_avma + di->plt_size) { 3007b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectPLT; 3008b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3009b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3010b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->got_present 3011b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->got_size > 0 3012b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->got_avma && a < di->got_avma + di->got_size) { 3013b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectGOT; 3014b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3015b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3016092b6268cc4a38ae9ee41d1e3355937536ddc579bart if (di->gotplt_present 3017092b6268cc4a38ae9ee41d1e3355937536ddc579bart && di->gotplt_size > 0 3018092b6268cc4a38ae9ee41d1e3355937536ddc579bart && a >= di->gotplt_avma && a < di->gotplt_avma + di->gotplt_size) { 3019092b6268cc4a38ae9ee41d1e3355937536ddc579bart res = Vg_SectGOTPLT; 3020092b6268cc4a38ae9ee41d1e3355937536ddc579bart break; 3021092b6268cc4a38ae9ee41d1e3355937536ddc579bart } 3022b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->opd_present 3023b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->opd_size > 0 3024b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->opd_avma && a < di->opd_avma + di->opd_size) { 3025b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectOPD; 3026b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3027b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3028b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* we could also check for .eh_frame, if anyone really cares */ 3029b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3030b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3031b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert( (di == NULL && res == Vg_SectUnknown) 3032b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || (di != NULL && res != Vg_SectUnknown) ); 3033b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3034b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (name) { 3035b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3036b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_name >= 8); 3037b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3038b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di && di->filename) { 3039b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int i, j; 3040b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int fnlen = VG_(strlen)(di->filename); 3041b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int start_at = 1 + fnlen - n_name; 3042b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (start_at < 0) start_at = 0; 3043b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(start_at < fnlen); 3044b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj i = start_at; j = 0; 3045b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 3046d5dea1dabc523d3f96bafd52ae9586abd8797416bart vg_assert(j >= 0 && j < n_name); 3047b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(i >= 0 && i <= fnlen); 3048b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj name[j] = di->filename[i]; 3049b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->filename[i] == 0) break; 3050b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj i++; j++; 3051b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3052d5dea1dabc523d3f96bafd52ae9586abd8797416bart vg_assert(i == fnlen); 3053b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 3054b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)(name, n_name, "%s", "???"); 3055b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3056b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3057b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj name[n_name-1] = 0; 3058b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3059b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3060b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return res; 3061b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3062eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3063eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3064eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3065eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 3066eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- end ---*/ 3067eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 3068