debuginfo.c revision 2ac79d3f62c0a2d44896a6d7d74a4500f364bbe0
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/*------------------------------------------------------------*/ 102eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Root structure ---*/ 103eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 104eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 105b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* The root structure for the entire debug info system. It is a 106b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj linked list of DebugInfos. */ 107b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic DebugInfo* debugInfo_list = NULL; 108b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 109b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 110b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Find 'di' in the debugInfo_list and move it one step closer the the 111b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj front of the list, so as to make subsequent searches for it 112b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj cheaper. When used in a controlled way, makes a major improvement 113b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in some DebugInfo-search-intensive situations, most notably stack 114b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj unwinding on amd64-linux. */ 115b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void move_DebugInfo_one_step_forward ( DebugInfo* di ) 116b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo *di0, *di1, *di2; 118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == debugInfo_list) 119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; /* already at head of list */ 120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di != NULL); 121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0 = debugInfo_list; 122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1 = NULL; 123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2 = NULL; 124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 == NULL || di0 == di) break; 126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2 = di1; 127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1 = di0; 128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0 = di0->next; 129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di0 == di); 131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 != NULL && di1 != NULL && di2 != NULL) { 132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* tmp; 133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* di0 points to di, di1 to its predecessor, and di2 to di1's 134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj predecessor. Swap di0 and di1, that is, move di0 one step 135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj closer to the start of the list. */ 136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di2->next == di1); 137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di1->next == di0); 138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj tmp = di0->next; 139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->next = di0; 140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0->next = di1; 141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1->next = tmp; 142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 != NULL && di1 != NULL && di2 == NULL) { 145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* it's second in the list. */ 146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(debugInfo_list == di1); 147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di1->next == di0); 148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1->next = di0->next; 149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0->next = di1; 150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debugInfo_list = di0; 151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 153eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 154eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 155eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 156eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Notification (acquire/discard) helpers ---*/ 157eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 158eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Allocate and zero out a new DebugInfo record. */ 160eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjstatic 161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjDebugInfo* alloc_DebugInfo( const UChar* filename, 162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj const UChar* memname ) 163eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool traceme; 165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 166eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 167f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj vg_assert(filename); 168f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj 169b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di = ML_(dinfo_zalloc)(sizeof(DebugInfo)); 170b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->filename = ML_(dinfo_strdup)(filename); 171b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->memname = memname ? ML_(dinfo_strdup)(memname) 172b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj : NULL; 173eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 174f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj /* Everything else -- pointers, sizes, arrays -- is zeroed by calloc. 175f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj Now set up the debugging-output flags. */ 176f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj traceme 177f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj = VG_(string_match)( VG_(clo_trace_symtab_patt), filename ) 178f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj || (memname && VG_(string_match)( VG_(clo_trace_symtab_patt), 179f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj memname )); 180f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj if (traceme) { 181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->trace_symtab = VG_(clo_trace_symtab); 182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->trace_cfi = VG_(clo_trace_cfi); 183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_syms = VG_(clo_debug_dump_syms); 184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_line = VG_(clo_debug_dump_line); 185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_frames = VG_(clo_debug_dump_frames); 186f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj } 187f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj 188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 189eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 190eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 191eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 192b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Free a DebugInfo, and also all the stuff hanging off it. */ 193b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void free_DebugInfo ( DebugInfo* di ) 194eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 195b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word i, j; 196eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj struct strchunk *chunk, *next; 197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj TyAdmin *admin1, *admin2; 198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj GExpr *gexpr1, *gexpr2; 199b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 200b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di != NULL); 201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->filename) ML_(dinfo_free)(di->filename); 202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->symtab) ML_(dinfo_free)(di->symtab); 203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->loctab) ML_(dinfo_free)(di->loctab); 204b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->cfsi) ML_(dinfo_free)(di->cfsi); 205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->cfsi_exprs) VG_(deleteXA)(di->cfsi_exprs); 206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (chunk = di->strchunks; chunk != NULL; chunk = next) { 208eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj next = chunk->next; 209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(dinfo_free)(chunk); 210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 212b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Delete the two admin lists. These lists exist purely so that we 213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj can visit each object exactly once when we need to delete 214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj them. */ 215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (admin1 = di->admin_tyadmins; admin1; admin1 = admin2) { 216b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj admin2 = admin1->next; 217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(delete_TyAdmin_and_payload)(admin1); 218eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (gexpr1 = di->admin_gexprs; gexpr1; gexpr1 = gexpr2) { 220b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj gexpr2 = gexpr1->next; 221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(dinfo_free)(gexpr1); 222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Dump the variable info. This is kinda complex: we must take 225b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj care not to free items which reside in either the admin lists 226b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (as we have just freed them) or which reside in the DebugInfo's 227b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj string table. */ 228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->varinfo) { 229b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = 0; i < VG_(sizeXA)(di->varinfo); i++) { 230b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* scope = *(OSet**)VG_(indexXA)(di->varinfo, i); 231b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!scope) continue; 232b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* iterate over all entries in 'scope' */ 233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(OSetGen_ResetIter)(scope); 234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* arange = VG_(OSetGen_Next)(scope); 236b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!arange) break; 237b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* for each var in 'arange' */ 238b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->vars); 239b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < VG_(sizeXA)( arange->vars ); j++) { 240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)(arange->vars,j); 241b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var); 242b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Nothing to free in var: all the pointer fields refer 243b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to stuff either on an admin list, or in 244b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj .strchunks */ 245b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 246b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)(arange->vars); 247b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Don't free arange itself, as OSetGen_Destroy does 248b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj that */ 249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(OSetGen_Destroy)(scope); 251b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 252b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)(di->varinfo); 253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(dinfo_free)(di); 256eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 257eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 258eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* 'si' is a member of debugInfo_list. Find it, remove it from the 260eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj list, notify m_redir that this has happened, and free all storage 261eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj reachable from it. 262eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 263b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void discard_DebugInfo ( DebugInfo* di ) 264eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2654ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# if defined(VGP_ppc32_aix5) 2664ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj HChar* reason = "__unload"; 2674ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# elif defined(VGP_ppc64_aix5) 2684ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj HChar* reason = "kunload64"; 2694ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# else 2704ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj HChar* reason = "munmap"; 2714ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# endif 2724ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo** prev_next_ptr = &debugInfo_list; 274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* curr = debugInfo_list; 275eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 276eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj while (curr) { 277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (curr == di) { 278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Found it; remove from list and free it. */ 27933e4e7eaab263cea956700f56f007ab26c39eab4sewardj if (curr->have_dinfo 28033e4e7eaab263cea956700f56f007ab26c39eab4sewardj && (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))) 281eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(message)(Vg_DebugMsg, 2824ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj "Discarding syms at %p-%p in %s due to %s()", 283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_avma, 284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_avma + di->text_size, 2854ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj curr->filename ? curr->filename : (UChar*)"???", 2864ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj reason); 287eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(*prev_next_ptr == curr); 288eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *prev_next_ptr = curr->next; 28933e4e7eaab263cea956700f56f007ab26c39eab4sewardj if (curr->have_dinfo) 29033e4e7eaab263cea956700f56f007ab26c39eab4sewardj VG_(redir_notify_delete_DebugInfo)( curr ); 291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj free_DebugInfo(curr); 292eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return; 293eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 294eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj prev_next_ptr = &curr->next; 295eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj curr = curr->next; 296eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 297eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Not found. */ 299eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 300eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 301eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Repeatedly scan debugInfo_list, looking for DebugInfos with text 303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj AVMAs intersecting [start,start+length), and call discard_DebugInfo 304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to get rid of them. This modifies the list, hence the multiple 305b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj iterations. 306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/ 307eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjstatic void discard_syms_in_range ( Addr start, SizeT length ) 308eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool found; 310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* curr; 311eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 312eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj while (True) { 313eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj found = False; 314eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj curr = debugInfo_list; 316eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj while (True) { 317eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (curr == NULL) 318eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; 319b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (curr->text_present 320b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && curr->text_size > 0 321b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && (start+length - 1 < curr->text_avma 322b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || curr->text_avma + curr->text_size - 1 < start)) { 323eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* no overlap */ 324eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 325eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj found = True; 326eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; 327eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 328eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj curr = curr->next; 329eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 330eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 331eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (!found) break; 332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_DebugInfo( curr ); 333eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 334eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 335eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 336eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Does [s1,+len1) overlap [s2,+len2) ? Note: does not handle 338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj wraparound at the end of the address space -- just asserts in that 339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case. */ 340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Bool ranges_overlap (Addr s1, SizeT len1, Addr s2, SizeT len2 ) 341eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr e1, e2; 343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (len1 == 0 || len2 == 0) 344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 345b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj e1 = s1 + len1 - 1; 346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj e2 = s2 + len2 - 1; 347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Assert that we don't have wraparound. If we do it would imply 348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj that file sections are getting mapped around the end of the 349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj address space, which sounds unlikely. */ 350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(s1 <= e1); 351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(s2 <= e2); 352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (e1 < s2 || e2 < s1) return False; 353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 354b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 355eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 356eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Do the basic rx_ and rw_ mappings of the two DebugInfos overlap in 358b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj any way? */ 359b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Bool do_DebugInfos_overlap ( DebugInfo* di1, DebugInfo* di2 ) 360b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 361b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di1); 362b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di2); 363eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 364b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di1->have_rx_map && di2->have_rx_map 365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ranges_overlap(di1->rx_map_avma, di1->rx_map_size, 366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->rx_map_avma, di2->rx_map_size)) 367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 368eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di1->have_rx_map && di2->have_rw_map 370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ranges_overlap(di1->rx_map_avma, di1->rx_map_size, 371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->rw_map_avma, di2->rw_map_size)) 372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di1->have_rw_map && di2->have_rx_map 375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ranges_overlap(di1->rw_map_avma, di1->rw_map_size, 376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->rx_map_avma, di2->rx_map_size)) 377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di1->have_rw_map && di2->have_rw_map 380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ranges_overlap(di1->rw_map_avma, di1->rw_map_size, 381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->rw_map_avma, di2->rw_map_size)) 382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Discard all elements of debugInfo_list whose .mark bit is set. 389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/ 390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void discard_marked_DebugInfos ( void ) 391b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 392b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* curr; 393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj curr = debugInfo_list; 397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!curr) 399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (curr->mark) 401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj curr = curr->next; 403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!curr) break; 406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_DebugInfo( curr ); 407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 410b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 411b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 412b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Discard any elements of debugInfo_list which overlap with diRef. 413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Clearly diRef must have its rx_ and rw_ mapping information set to 414b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj something sane. */ 415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#if defined(VGO_aix5) 416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((unused)) 417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif 418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void discard_DebugInfos_which_overlap_with ( DebugInfo* diRef ) 419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Mark all the DebugInfos in debugInfo_list that need to be 422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj deleted. First, clear all the mark bits; then set them if they 423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj overlap with siRef. Since siRef itself is in this list we at 424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj least expect its own mark bit to be set. */ 425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di; di = di->next) { 426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->mark = do_DebugInfos_overlap( di, diRef ); 427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == diRef) { 428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->mark); 429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->mark = False; 430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 431eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_marked_DebugInfos(); 433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 435eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Find the existing DebugInfo for (memname,filename) or if not found, 437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj create one. In the latter case memname and filename are strdup'd 438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj into VG_AR_DINFO, and the new DebugInfo is added to 439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debugInfo_list. */ 440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic 441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjDebugInfo* find_or_create_DebugInfo_for ( UChar* filename, UChar* memname ) 442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(filename); 445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di; di = di->next) { 446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->filename); 447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0==VG_(strcmp)(di->filename, filename) 448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ( (memname && di->memname) 449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ? 0==VG_(strcmp)(memname, di->memname) 450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj : True )) 451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di) { 454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di = alloc_DebugInfo(filename, memname); 455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di); 456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->next = debugInfo_list; 457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debugInfo_list = di; 458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 460eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 461eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 462eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4634ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--------------------------------------------------------------*/ 4644ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- ---*/ 4654ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- TOP LEVEL: NOTIFICATION (ACQUIRE/DISCARD INFO) (LINUX) ---*/ 4664ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- ---*/ 4674ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--------------------------------------------------------------*/ 4684ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 4694ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#if defined(VGO_linux) 470eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 471eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* The debug info system is driven by notifications that a text 472eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj segment has been mapped in, or unmapped. When that happens it 473eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj tries to acquire/discard whatever info is available for the 474eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj corresponding object. This section contains the notification 475eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj handlers. */ 476eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 477eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Notify the debuginfo system about a new mapping. This is the way 478eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj new debug information gets loaded. If allow_SkFileV is True, it 479eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj will try load debug info if the mapping at 'a' belongs to Valgrind; 480eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj whereas normally (False) it will not do that. This allows us to 481eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj carefully control when the thing will read symbols from the 482eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Valgrind executable itself. */ 483eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 484eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjvoid VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV ) 485eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4864ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj NSegment const * seg; 487b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj HChar* filename; 488b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool ok, is_rx_map, is_rw_map; 489b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 490b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj SysRes fd; 491b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int nread; 492b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj HChar buf1k[1024]; 493b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool debug = False; 494b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 495b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* In short, figure out if this mapping is of interest to us, and 496b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if so, try to guess what ld.so is doing and when/if we should 497b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj read debug info. */ 498b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg = VG_(am_find_nsegment)(a); 499b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(seg); 500eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 501b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 502b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("di_notify_mmap-1: %p-%p %c%c%c\n", 503b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->start, seg->end, 504b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->hasR ? 'r' : '-', 505b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->hasW ? 'w' : '-',seg->hasX ? 'x' : '-' ); 506eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 507b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* guaranteed by aspacemgr-linux.c, sane_NSegment() */ 508b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(seg->end > seg->start); 509b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 510b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ignore non-file mappings */ 511b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( ! (seg->kind == SkFileC 512b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || (seg->kind == SkFileV && allow_SkFileV)) ) 513b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; 514b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 515b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* If the file doesn't have a name, we're hosed. Give up. */ 516b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj filename = VG_(am_get_filename)( (NSegment*)seg ); 517b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!filename) 518b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; 519b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 520b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 521b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("di_notify_mmap-2: %s\n", filename); 522b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 5232ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj /* XXXX begin KLUDGE */ 5242ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj /* Skip filenames in /dev/. Don't even bother to try opening them. 5252ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj Why? 5262ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj 5272ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj Suppose the client opens and then mmaps the file specified by 5282ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj 'filename' and puts some kind of lock on it, so nobody else can 5292ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj open it. If we now try to open it to peer at the ELF header, 5302ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj the system can hang, because the VG_(open) call blocks. 5312ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj Precisely this happed when running Amarok, which opened and then 5322ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj mmap'd /dev/snd/pcmC0D0c. 5332ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj 5342ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj A clean(er) solution is to open the file with VKI_O_NONBLOCK, so 5352ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj that if it is locked, we simply fail immediately and don't hang 5362ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj the whole system. But "man 2 open" gives only a sketchy 5372ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj description of the resulting file semantics. So for the 5382ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj meantime, just skip files in /dev/ as (1) they are likely to be 5392ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj subject to wierd-ass locking stuff, and (2) they won't contain 5402ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj useful debug info anyway. 5412ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj 5422ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj But that's a kludge; in principle the same problem could occur 5432ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj with *any* file. 5442ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj */ 5452ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj if (0 == VG_(strncmp)(filename, "/dev/", 5)) { 5462ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj if (debug) 5472ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj VG_(printf)("di_notify_mmap-2: skipping %s\n", filename); 5482ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj return; 5492ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj } 5502ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj /* XXXX end KLUDGE */ 5512ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj 552b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Peer at the first few bytes of the file, to see if it is an ELF 553b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj object file. */ 554b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(memset)(buf1k, 0, sizeof(buf1k)); 555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj fd = VG_(open)( filename, VKI_O_RDONLY, 0 ); 556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (fd.isError) { 557b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo fake_di; 558b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(memset)(&fake_di, 0, sizeof(fake_di)); 559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj fake_di.filename = filename; 560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(symerr)(&fake_di, True, "can't open file to inspect ELF header"); 561b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; 562b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 563b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj nread = VG_(read)( fd.res, buf1k, sizeof(buf1k) ); 564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(close)( fd.res ); 565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (nread <= 0) { 567b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(symerr)(NULL, True, "can't read file to inspect ELF header"); 568b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; 569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 570b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(nread > 0 && nread <= sizeof(buf1k) ); 571b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 572b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We're only interested in mappings of ELF object files. */ 573b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!ML_(is_elf_object_file)( buf1k, (SizeT)nread )) 574b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; 575b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 576b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Now we have to guess if this is a text-like mapping, a data-like 577b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj mapping, neither or both. The rules are: 578b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 579b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj text if: x86-linux r and x 580b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj other-linux r and x and not w 581b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 582b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data if: x86-linux r and w 583b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj other-linux r and w and not x 584b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 585b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Background: On x86-linux, objects are typically mapped twice: 586eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 587eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1b8fb000-1b8ff000 r-xp 00000000 08:02 4471477 vgpreload_memcheck.so 588eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1b8ff000-1b900000 rw-p 00004000 08:02 4471477 vgpreload_memcheck.so 589eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 590eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj whereas ppc32-linux mysteriously does this: 591eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 592eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118a6000-118ad000 r-xp 00000000 08:05 14209428 vgpreload_memcheck.so 593eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118ad000-118b6000 ---p 00007000 08:05 14209428 vgpreload_memcheck.so 594eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118b6000-118bd000 rwxp 00000000 08:05 14209428 vgpreload_memcheck.so 595eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 596eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj The third mapping should not be considered to have executable 597eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj code in. Therefore a test which works for both is: r and x and 598eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj NOT w. Reading symbols from the rwx segment -- which overlaps 599eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj the r-x segment in the file -- causes the redirection mechanism 600eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj to redirect to addresses in that third segment, which is wrong 601eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj and causes crashes. 602eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 603eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj JRS 28 Dec 05: unfortunately icc 8.1 on x86 has been seen to 604eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj produce executables with a single rwx segment rather than a 605eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj (r-x,rw-) pair. That means the rules have to be modified thusly: 606eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 607eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj x86-linux: consider if r and x 608b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj all others: consider if r and x and not w 609eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj */ 610b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = False; 611b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = False; 612eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# if defined(VGP_x86_linux) 613b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = seg->hasR && seg->hasX; 614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = seg->hasR && seg->hasW; 615b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# elif defined(VGP_amd64_linux) \ 616b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) 617b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = seg->hasR && seg->hasX && !seg->hasW; 618b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = seg->hasR && seg->hasW && !seg->hasX; 619eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# else 620b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# error "Unknown platform" 621eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# endif 622eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 623b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 624b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("di_notify_mmap-3: is_rx_map %d, is_rw_map %d\n", 625b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (Int)is_rx_map, (Int)is_rw_map); 626eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* If it is neither text-ish nor data-ish, we're not interested. */ 628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!(is_rx_map || is_rw_map)) 629eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return; 630eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* See if we have a DebugInfo for this filename. If not, 632b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj create one. */ 633b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di = find_or_create_DebugInfo_for( filename, NULL/*membername*/ ); 634b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di); 635b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 636b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (is_rx_map) { 637b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We have a text-like mapping. Note the details. */ 638b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->have_rx_map) { 639b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->have_rx_map = True; 640b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rx_map_avma = a; 641b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rx_map_size = seg->end + 1 - seg->start; 642b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rx_map_foff = seg->offset; 643b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 644b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* FIXME: complain about a second text-like mapping */ 645b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 646b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 647eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 648b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (is_rw_map) { 649b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We have a data-like mapping. Note the details. */ 650b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->have_rw_map) { 651b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->have_rw_map = True; 652b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rw_map_avma = a; 653b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rw_map_size = seg->end + 1 - seg->start; 654b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rw_map_foff = seg->offset; 655b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 656b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* FIXME: complain about a second data-like mapping */ 657b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 658eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 659eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 660b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->have_rx_map && di->have_rw_map && !di->have_dinfo) { 661b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 662b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->filename); 663b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj TRACE_SYMTAB("\n"); 664b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj TRACE_SYMTAB("------ start ELF OBJECT " 665b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "------------------------------\n"); 666b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj TRACE_SYMTAB("------ name = %s\n", di->filename); 667b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj TRACE_SYMTAB("\n"); 668b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We're going to read symbols and debug info for the avma 670b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ranges [rx_map_avma, +rx_map_size) and [rw_map_avma, 671b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj +rw_map_size). First get rid of any other DebugInfos which 672b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj overlap either of those ranges (to avoid total confusion). */ 673b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_DebugInfos_which_overlap_with( di ); 674b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 675b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* .. and acquire new info. */ 676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ok = ML_(read_elf_debug_info)( di ); 677b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 678b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (ok) { 679b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj TRACE_SYMTAB("\n------ Canonicalising the " 680b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "acquired info ------\n"); 681b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* prepare read data for use */ 682b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(canonicaliseTables)( di ); 683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* notify m_redir about it */ 684b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj TRACE_SYMTAB("\n------ Notifying m_redir ------\n"); 685b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(redir_notify_new_DebugInfo)( di ); 686b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Note that we succeeded */ 687b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->have_dinfo = True; 688b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 689b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj TRACE_SYMTAB("\n------ ELF reading failed ------\n"); 690b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Something went wrong (eg. bad ELF file). Should we delete 691b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj this DebugInfo? No - it contains info on the rw/rx 692b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj mappings, at least. */ 693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 694eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 695b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj TRACE_SYMTAB("\n"); 696b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj TRACE_SYMTAB("------ name = %s\n", di->filename); 697b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj TRACE_SYMTAB("------ end ELF OBJECT " 698b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "------------------------------\n"); 699b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj TRACE_SYMTAB("\n"); 700eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 701b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 702eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 703eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 704eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 705eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Unmap is simpler - throw away any SegInfos intersecting 706eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj [a, a+len). */ 707eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjvoid VG_(di_notify_munmap)( Addr a, SizeT len ) 708eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0) VG_(printf)("DISCARD %p %p\n", a, a+len); 710eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj discard_syms_in_range(a, len); 711eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 712eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 713eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 714eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Uh, this doesn't do anything at all. IIRC glibc (or ld.so, I don't 715eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj remember) does a bunch of mprotects on itself, and if we follow 716eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj through here, it causes the debug info for that object to get 717eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj discarded. */ 718eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjvoid VG_(di_notify_mprotect)( Addr a, SizeT len, UInt prot ) 719eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 720eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool exe_ok = toBool(prot & VKI_PROT_EXEC); 721eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# if defined(VGP_x86_linux) 722eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj exe_ok = exe_ok || toBool(prot & VKI_PROT_READ); 723eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# endif 724eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (0 && !exe_ok) 725eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj discard_syms_in_range(a, len); 726eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 727eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 7284ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#endif /* defined(VGO_linux) */ 7294ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 7304ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 7314ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*-------------------------------------------------------------*/ 7324ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- ---*/ 7334ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- TOP LEVEL: NOTIFICATION (ACQUIRE/DISCARD INFO) (AIX5) ---*/ 7344ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- ---*/ 7354ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*-------------------------------------------------------------*/ 7364ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 7374ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#if defined(VGO_aix5) 7384ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 7394ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/* The supplied parameters describe a code segment and its associated 7404ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj data segment, that have recently been mapped in -- so we need to 7414ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj read debug info for it -- or conversely, have recently been dumped, 7424ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj in which case the relevant debug info has to be unloaded. */ 7434ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 7444ee4f98c6dd3dd9517954efc628753bf46811d2dsewardjvoid VG_(di_aix5_notify_segchange)( 7454ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Addr code_start, 7464ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Word code_len, 7474ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Addr data_start, 7484ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Word data_len, 7494ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj UChar* file_name, 7504ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj UChar* mem_name, 7514ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool is_mainexe, 7524ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool acquire ) 7534ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj{ 7544ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (acquire) { 7554ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 756b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool ok; 757b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 758b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di = find_or_create_DebugInfo_for( file_name, mem_name ); 759b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di); 760b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 761b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (code_len > 0) { 762b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_present = True; 763b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_svma = 0; /* don't know yet */ 764b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_bias = 0; /* don't know yet */ 765b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_avma = code_start; 766b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_size = code_len; 767b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 768b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (data_len > 0) { 769b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_present = True; 770b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_svma = 0; /* don't know yet */ 771b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_bias = 0; /* don't know yet */ 772b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_avma = data_start; 773b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_size = data_len; 774b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 775b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 776b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* These need to be filled in in order to keep various 777b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj assertions in storage.c happy. In particular see 778b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Comment_Regarding_Text_Range_Checks" in that file. */ 779b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->have_rx_map = True; 780b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rx_map_avma = code_start; 781b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rx_map_size = code_len; 782b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->have_rw_map = True; 783b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rw_map_avma = data_start; 784b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rw_map_size = data_len; 785b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 786b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ok = ML_(read_xcoff_debug_info) ( di, is_mainexe ); 787b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 788b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (ok) { 789b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* prepare read data for use */ 790b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(canonicaliseTables)( di ); 791b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* notify m_redir about it */ 792b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(redir_notify_new_DebugInfo)( di ); 793b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Note that we succeeded */ 794b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->have_dinfo = True; 795b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 796b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Something went wrong (eg. bad XCOFF file). */ 797b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_DebugInfo( di ); 798b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di = NULL; 799b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 8004ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 8014ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } else { 8024ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 803b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Dump all the debugInfos whose text segments intersect 804f7cdfe298805a91a35b8e0495d9034cbf21003f5sewardj code_start/code_len. */ 805b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (code_len > 0) 806b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_syms_in_range( code_start, code_len ); 8074ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 8084ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 8094ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj} 8104ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 8114ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 8124ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#endif /* defined(VGO_aix5) */ 8134ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 814eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 815eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 816eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- ---*/ 817eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- TOP LEVEL: QUERYING EXISTING DEBUG INFO ---*/ 818eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- ---*/ 819eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 820eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 821eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 822eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Use of symbol table & location info to create ---*/ 823eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- plausible-looking stack dumps. ---*/ 824eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 825eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 826eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Search all symtabs that we know about to locate ptr. If found, set 827b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi to the relevant DebugInfo, and *symno to the symtab entry 828b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *number within that. If not found, *psi is set to NULL. 829b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj If findText==True, only text symbols are searched for. 830b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj If findText==False, only data symbols are searched for. 831b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/ 832b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void search_all_symtabs ( Addr ptr, /*OUT*/DebugInfo** pdi, 833eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/Int* symno, 834b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool match_anywhere_in_sym, 835b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool findText ) 836eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 837b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int sno; 838b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 839b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool inRange; 840b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 841b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 842b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 843b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (findText) { 844b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj inRange = di->text_present 845b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_size > 0 846b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= ptr 847b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->text_avma + di->text_size; 848b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 849b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj inRange = (di->data_present 850b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_size > 0 851b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_avma <= ptr 852b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->data_avma + di->data_size) 853b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || 854b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (di->sdata_present 855b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_size > 0 856b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_avma <= ptr 857b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->sdata_avma + di->sdata_size) 858b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || 859b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (di->bss_present 860b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_size > 0 861b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_avma <= ptr 862b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->bss_avma + di->bss_size); 863eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 864b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 865b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!inRange) continue; 866b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 867b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sno = ML_(search_one_symtab) ( 868b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di, ptr, match_anywhere_in_sym, findText ); 869b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (sno == -1) goto not_found; 870b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *symno = sno; 871b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = di; 872b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; 873b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 874eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 875eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj not_found: 876b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = NULL; 877eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 878eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 879eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 880eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Search all loctabs that we know about to locate ptr. If found, set 881b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi to the relevant DebugInfo, and *locno to the loctab entry 882b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *number within that. If not found, *pdi is set to NULL. */ 883b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void search_all_loctabs ( Addr ptr, /*OUT*/DebugInfo** pdi, 884eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/Int* locno ) 885eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 886b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int lno; 887b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 888b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 889b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 890b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= ptr 891b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->text_avma + di->text_size) { 892b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj lno = ML_(search_one_loctab) ( di, ptr ); 893eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (lno == -1) goto not_found; 894eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *locno = lno; 895b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = di; 896eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return; 897eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 898eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 899eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj not_found: 900b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = NULL; 901eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 902eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 903eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 904eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* The whole point of this whole big deal: map a code address to a 905eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj plausible symbol name. Returns False if no idea; otherwise True. 906eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Caller supplies buf and nbuf. If demangle is False, don't do 907eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj demangling, regardless of VG_(clo_demangle) -- probably because the 908b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj call has come from VG_(get_fnname_nodemangle)(). findText 909b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj indicates whether we're looking for a text symbol or a data symbol 910b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj -- caller must choose one kind or the other. */ 911eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjstatic 912b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool get_sym_name ( Bool demangle, Addr a, Char* buf, Int nbuf, 913b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool match_anywhere_in_sym, Bool show_offset, 914b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool findText, /*OUT*/OffT* offsetP ) 915eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 916b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 917b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int sno; 918b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int offset; 919eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 920b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj search_all_symtabs ( a, &di, &sno, match_anywhere_in_sym, findText ); 921b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == NULL) 922eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 923eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (demangle) { 924eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(demangle) ( True/*do C++ demangle*/, 925b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->symtab[sno].name, buf, nbuf ); 926eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 927b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(strncpy_safely) ( buf, di->symtab[sno].name, nbuf ); 928eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 929eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 930b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset = a - di->symtab[sno].addr; 931b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (offsetP) *offsetP = (OffT)offset; 932b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 933eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (show_offset && offset != 0) { 934eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char buf2[12]; 935eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char* symend = buf + VG_(strlen)(buf); 936eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char* end = buf + nbuf; 937eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Int len; 938eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 939eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj len = VG_(sprintf)(buf2, "%c%d", 940eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj offset < 0 ? '-' : '+', 941eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj offset < 0 ? -offset : offset); 942eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(len < (Int)sizeof(buf2)); 943eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 944eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (len < (end - symend)) { 945eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char *cp = buf2; 946eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(memcpy)(symend, cp, len+1); 947eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 948eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 949eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 950eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 951eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 952eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 953eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* ppc64-linux only: find the TOC pointer (R2 value) that should be in 954eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj force at the entry point address of the function containing 955eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj guest_code_addr. Returns 0 if not known. */ 956eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjAddr VG_(get_tocptr) ( Addr guest_code_addr ) 957eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 958b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 959b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int sno; 960eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_symtabs ( guest_code_addr, 961b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj &si, &sno, 962b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj True/*match_anywhere_in_fun*/, 963b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj True/*consider text symbols only*/ ); 964eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 965eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return 0; 966eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj else 967eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return si->symtab[sno].tocptr; 968eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 969eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 970eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 971eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj match anywhere in function, but don't show offsets. */ 972eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_fnname) ( Addr a, Char* buf, Int nbuf ) 973eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 974b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return get_sym_name ( /*demangle*/True, a, buf, nbuf, 975b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 976b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 977b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 978b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 979eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 980eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 981eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 982eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj match anywhere in function, and show offset if nonzero. */ 983eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_fnname_w_offset) ( Addr a, Char* buf, Int nbuf ) 984eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 985b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return get_sym_name ( /*demangle*/True, a, buf, nbuf, 986b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 987b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/True, 988b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 989b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 990eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 991eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 992eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 993eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj only succeed if 'a' matches first instruction of function, 994eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj and don't show offsets. */ 995eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_fnname_if_entry) ( Addr a, Char* buf, Int nbuf ) 996eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 997b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return get_sym_name ( /*demangle*/True, a, buf, nbuf, 998b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/False, 999b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1000b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1001b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1002eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1003eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1004eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is only available to core... don't demangle C++ names, 1005eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj match anywhere in function, and don't show offsets. */ 1006eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_fnname_nodemangle) ( Addr a, Char* buf, Int nbuf ) 1007eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1008b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return get_sym_name ( /*demangle*/False, a, buf, nbuf, 1009b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1010b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1011b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1012b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1013eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1014eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1015eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is only available to core... don't demangle C++ names, but do 1016eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj do Z-demangling, match anywhere in function, and don't show 1017eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj offsets. */ 1018eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_fnname_Z_demangle_only) ( Addr a, Char* buf, Int nbuf ) 1019eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1020eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define N_TMPBUF 4096 /* arbitrary, 4096 == ERRTXT_LEN */ 1021eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char tmpbuf[N_TMPBUF]; 1022eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool ok; 1023eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(nbuf > 0); 1024b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ok = get_sym_name ( /*demangle*/False, a, tmpbuf, N_TMPBUF, 1025b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1026b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1027b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1028b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1029eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj tmpbuf[N_TMPBUF-1] = 0; /* paranoia */ 1030eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (!ok) 1031eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1032eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1033eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* We have something, at least. Try to Z-demangle it. */ 1034eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(demangle)( False/*don't do C++ demangling*/, tmpbuf, buf, nbuf); 1035eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1036eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf[nbuf-1] = 0; /* paranoia */ 1037eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1038eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef N_TMPBUF 1039eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1040eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1041b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Looks up data_addr in the collection of data symbols, and if found 1042b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj puts its name (or as much as will fit) into dname[0 .. n_dname-1], 1043b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which is guaranteed to be zero terminated. Also data_addr's offset 1044b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj from the symbol start is put into *offset. */ 1045b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool VG_(get_datasym_and_offset)( Addr data_addr, 1046b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/Char* dname, Int n_dname, 1047b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/OffT* offset ) 1048b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 1049b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool ok; 1050b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_dname > 1); 1051b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ok = get_sym_name ( /*demangle*/False, data_addr, dname, n_dname, 1052b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_sym*/True, 1053b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1054b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*data syms only please*/False, 1055b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset ); 1056b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!ok) 1057b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 1058b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname[n_dname-1] = 0; 1059b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 1060b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 1061b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1062b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Map a code address to the name of a shared object file or the 1063b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj executable. Returns False if no idea; otherwise True. Doesn't 1064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj require debug info. Caller supplies buf and nbuf. */ 1065eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_objname) ( Addr a, Char* buf, Int nbuf ) 1066eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 10674ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Int used; 1068b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1069f32ec7f0de8a651bc16a1b2e448c0106d8669889tom const NSegment *seg; 1070f32ec7f0de8a651bc16a1b2e448c0106d8669889tom HChar* filename; 10714ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj vg_assert(nbuf > 0); 1072b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1073b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 1074b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= a 1075b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a < di->text_avma + di->text_size) { 1076b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(strncpy_safely)(buf, di->filename, nbuf); 1077b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->memname) { 10784ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj used = VG_(strlen)(buf); 10794ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (used < nbuf) 10804ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(strncpy_safely)(&buf[used], "(", nbuf-used); 10814ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj used = VG_(strlen)(buf); 10824ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (used < nbuf) 1083b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(strncpy_safely)(&buf[used], di->memname, nbuf-used); 10844ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj used = VG_(strlen)(buf); 10854ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (used < nbuf) 10864ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(strncpy_safely)(&buf[used], ")", nbuf-used); 10874ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 10884ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj buf[nbuf-1] = 0; 1089eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1090eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1091eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1092f32ec7f0de8a651bc16a1b2e448c0106d8669889tom if ((seg = VG_(am_find_nsegment(a))) != NULL && 1093f32ec7f0de8a651bc16a1b2e448c0106d8669889tom (filename = VG_(am_get_filename)(seg)) != NULL) 1094f32ec7f0de8a651bc16a1b2e448c0106d8669889tom { 1095f32ec7f0de8a651bc16a1b2e448c0106d8669889tom VG_(strncpy_safely)(buf, filename, nbuf); 1096f32ec7f0de8a651bc16a1b2e448c0106d8669889tom return True; 1097f32ec7f0de8a651bc16a1b2e448c0106d8669889tom } 1098eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1099eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1100eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1101b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Map a code address to its DebugInfo. Returns NULL if not found. Doesn't 1102eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj require debug info. */ 1103b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjDebugInfo* VG_(find_seginfo) ( Addr a ) 1104eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1105b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1106b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1107b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 1108b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= a 1109b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a < di->text_avma + di->text_size) { 1110b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 1111eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1112eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1113eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return NULL; 1114eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1115eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1116eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a filename. Returns True if successful. */ 1117eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_filename)( Addr a, Char* filename, Int n_filename ) 1118eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1120eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Int locno; 1121eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 1122eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 1123eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1124eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(strncpy_safely)(filename, si->loctab[locno].filename, n_filename); 1125eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1126eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1127eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1128eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a line number. Returns True if successful. */ 1129eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_linenum)( Addr a, UInt* lineno ) 1130eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1132eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Int locno; 1133eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 1134eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 1135eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1136eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *lineno = si->loctab[locno].lineno; 1137eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1138eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1139eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1140eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1141eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a filename/line number/dir name info. 1142eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj See prototype for detailed description of behaviour. 1143eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 1144eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_filename_linenum) ( Addr a, 1145eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/Char* filename, Int n_filename, 1146eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/Char* dirname, Int n_dirname, 1147eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/Bool* dirname_available, 1148eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/UInt* lineno ) 1149eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1151eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Int locno; 1152eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1153eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert( (dirname == NULL && dirname_available == NULL) 1154eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj || 1155eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj (dirname != NULL && dirname_available != NULL) ); 1156eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1157eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 1158c1b1d421216369aec58867ce1c5b99cfb1703c36njn if (si == NULL) { 1159db5c6571454c1f647a4c67593805a8e401cd14c5njn if (dirname_available) { 1160db5c6571454c1f647a4c67593805a8e401cd14c5njn *dirname_available = False; 1161db5c6571454c1f647a4c67593805a8e401cd14c5njn *dirname = 0; 1162db5c6571454c1f647a4c67593805a8e401cd14c5njn } 1163eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1164c1b1d421216369aec58867ce1c5b99cfb1703c36njn } 1165c1b1d421216369aec58867ce1c5b99cfb1703c36njn 1166eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(strncpy_safely)(filename, si->loctab[locno].filename, n_filename); 1167eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *lineno = si->loctab[locno].lineno; 1168eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1169eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (dirname) { 1170eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* caller wants directory info too .. */ 1171eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(n_dirname > 0); 1172eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si->loctab[locno].dirname) { 1173eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* .. and we have some */ 1174eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *dirname_available = True; 1175eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(strncpy_safely)(dirname, si->loctab[locno].dirname, 1176eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_dirname); 1177eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 1178eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* .. but we don't have any */ 1179eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *dirname_available = False; 1180eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *dirname = 0; 1181eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1182eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1183eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1184eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1185eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1186eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1187eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 11884ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/* Map a function name to its entry point and toc pointer. Is done by 11894ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj sequential search of all symbol tables, so is very slow. To 11904ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj mitigate the worst performance effects, you may specify a soname 11914ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj pattern, and only objects matching that pattern are searched. 11924ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Therefore specify "*" to search all the objects. On TOC-afflicted 11934ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj platforms, a symbol is deemed to be found only if it has a nonzero 11944ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj TOC pointer. */ 1195b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool VG_(lookup_symbol_SLOW)(UChar* sopatt, UChar* name, 1196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr* pEnt, Addr* pToc) 11974ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj{ 11984ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool require_pToc = False; 11994ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Int i; 1200b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 12014ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool debug = False; 12024ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# if defined(VG_PLAT_USES_PPCTOC) 12034ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj require_pToc = True; 12044ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# endif 1205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (si = debugInfo_list; si; si = si->next) { 12064ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (debug) 12074ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(printf)("lookup_symbol_SLOW: considering %s\n", si->soname); 12084ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (!VG_(string_match)(sopatt, si->soname)) { 12094ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (debug) 12104ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(printf)(" ... skip\n"); 12114ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj continue; 12124ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 12134ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj for (i = 0; i < si->symtab_used; i++) { 12144ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (0==VG_(strcmp)(name, si->symtab[i].name) 12154ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj && (require_pToc ? si->symtab[i].tocptr : True)) { 12164ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj *pEnt = si->symtab[i].addr; 12174ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj *pToc = si->symtab[i].tocptr; 12184ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj return True; 12194ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 12204ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 12214ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 12224ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj return False; 12234ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj} 12244ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 12254ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 1226e872fec0c1c3b478a399fdba42ac65764b53f470sewardj/* VG_(describe_IP): print into buf info on code address, function 1227e872fec0c1c3b478a399fdba42ac65764b53f470sewardj name and filename. */ 1228e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 1229e872fec0c1c3b478a399fdba42ac65764b53f470sewardj/* Copy str into buf starting at n, but not going past buf[n_buf-1] 1230e872fec0c1c3b478a399fdba42ac65764b53f470sewardj and always ensuring that buf is zero-terminated. */ 1231eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1232eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjstatic Int putStr ( Int n, Int n_buf, Char* buf, Char* str ) 1233eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1234e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n_buf > 0); 1235e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 1236eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj for (; n < n_buf-1 && *str != 0; n++,str++) 1237eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf[n] = *str; 1238e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 1239eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf[n] = '\0'; 1240eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return n; 1241eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1242e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 1243e872fec0c1c3b478a399fdba42ac65764b53f470sewardj/* Same as putStr, but escaping chars for XML output, and 1244e872fec0c1c3b478a399fdba42ac65764b53f470sewardj also not adding more than count chars to n_buf. */ 1245e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 1246e872fec0c1c3b478a399fdba42ac65764b53f470sewardjstatic Int putStrEsc ( Int n, Int n_buf, Int count, Char* buf, Char* str ) 1247eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1248eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char alt[2]; 1249e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n_buf > 0); 1250e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(count >= 0 && count < n_buf); 1251e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 1252eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj for (; *str != 0; str++) { 1253e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(count >= 0); 1254e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count <= 0) 1255e872fec0c1c3b478a399fdba42ac65764b53f470sewardj goto done; 1256eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj switch (*str) { 1257e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '&': 1258e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 5) goto done; 1259e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, "&"); 1260e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 5; 1261e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 1262e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '<': 1263e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 4) goto done; 1264e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, "<"); 1265e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 4; 1266e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 1267e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '>': 1268e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 4) goto done; 1269e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, ">"); 1270e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 4; 1271e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 1272e872fec0c1c3b478a399fdba42ac65764b53f470sewardj default: 1273e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 1) goto done; 1274e872fec0c1c3b478a399fdba42ac65764b53f470sewardj alt[0] = *str; 1275e872fec0c1c3b478a399fdba42ac65764b53f470sewardj alt[1] = 0; 1276e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, alt ); 1277e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 1; 1278e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 1279eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1280eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1281e872fec0c1c3b478a399fdba42ac65764b53f470sewardj done: 1282e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(count >= 0); /* should not go -ve in loop */ 1283e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 1284eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return n; 1285eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1286eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1287eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjChar* VG_(describe_IP)(Addr eip, Char* buf, Int n_buf) 1288eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1289eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define APPEND(_str) \ 1290e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr(n, n_buf, buf, _str) 1291e872fec0c1c3b478a399fdba42ac65764b53f470sewardj# define APPEND_ESC(_count,_str) \ 1292e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStrEsc(n, n_buf, (_count), buf, (_str)) 1293eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define BUF_LEN 4096 1294eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1295eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj UInt lineno; 1296eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj UChar ibuf[50]; 1297eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Int n = 0; 1298eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static UChar buf_fn[BUF_LEN]; 1299eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static UChar buf_obj[BUF_LEN]; 1300eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static UChar buf_srcloc[BUF_LEN]; 1301eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static UChar buf_dirname[BUF_LEN]; 1302eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool know_dirinfo = False; 13034ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool know_fnname = VG_(clo_sym_offsets) 13044ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj ? VG_(get_fnname_w_offset) (eip, buf_fn, BUF_LEN) 13054ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj : VG_(get_fnname) (eip, buf_fn, BUF_LEN); 1306eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool know_objname = VG_(get_objname)(eip, buf_obj, BUF_LEN); 1307eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool know_srcloc = VG_(get_filename_linenum)( 1308eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj eip, 1309eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf_srcloc, BUF_LEN, 1310eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf_dirname, BUF_LEN, &know_dirinfo, 1311eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj &lineno 1312eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj ); 1313eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (VG_(clo_xml)) { 1314eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1315eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool human_readable = True; 1316eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj HChar* maybe_newline = human_readable ? "\n " : ""; 1317eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj HChar* maybe_newline2 = human_readable ? "\n " : ""; 1318eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1319e872fec0c1c3b478a399fdba42ac65764b53f470sewardj /* Print in XML format, dumping in as much info as we know. 1320e872fec0c1c3b478a399fdba42ac65764b53f470sewardj Ensure all tags are balanced even if the individual strings 1321e872fec0c1c3b478a399fdba42ac65764b53f470sewardj are too long. Allocate 1/10 of BUF_LEN to the object name, 1322e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 6/10s to the function name, 1/10 to the directory name and 1323e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 1/10 to the file name, leaving 1/10 for all the fixed-length 1324e872fec0c1c3b478a399fdba42ac65764b53f470sewardj stuff. */ 1325eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<frame>"); 1326a44b15f527bbebfe824a2e68e4bd6ab1e153b486sewardj VG_(sprintf)(ibuf,"<ip>0x%llX</ip>", (ULong)eip); 1327eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1328eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 1329eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_objname) { 1330eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1331eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<obj>"); 1332e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(1*BUF_LEN/10, buf_obj); 1333eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</obj>"); 1334eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1335eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_fnname) { 1336eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1337eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<fn>"); 1338e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(6*BUF_LEN/10, buf_fn); 1339eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</fn>"); 1340eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1341eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_srcloc) { 1342eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_dirinfo) { 1343eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1344eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<dir>"); 1345e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(1*BUF_LEN/10, buf_dirname); 1346eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</dir>"); 1347eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1348eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1349eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<file>"); 1350e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(1*BUF_LEN/10, buf_srcloc); 1351eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</file>"); 1352eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1353eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<line>"); 1354eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(sprintf)(ibuf,"%d",lineno); 1355eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 1356eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</line>"); 1357eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1358eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline2); 1359eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</frame>"); 1360eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1361eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 1362eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1363eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Print for humans to read */ 1364a44b15f527bbebfe824a2e68e4bd6ab1e153b486sewardj VG_(sprintf)(ibuf,"0x%llX: ", (ULong)eip); 1365eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 1366eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_fnname) { 1367eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(buf_fn); 1368eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (!know_srcloc && know_objname) { 1369eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(" (in "); 1370eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(buf_obj); 1371eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(")"); 1372eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1373eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else if (know_objname && !know_srcloc) { 1374eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("(within "); 1375eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(buf_obj); 1376eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(")"); 1377eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 1378eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("???"); 1379eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1380eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_srcloc) { 1381eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(" ("); 1382eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(buf_srcloc); 1383eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(":"); 1384eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(sprintf)(ibuf,"%d",lineno); 1385eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 1386eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(")"); 1387eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1388eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1389eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1390eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return buf; 1391eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1392eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef APPEND 1393eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef APPEND_ESC 1394eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef BUF_LEN 1395eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1396eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 139772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 1398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 1399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 1400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/ 1401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- DWARF3 .eh_frame INFO ---*/ 1402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 1403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 140472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 140572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/* Gather up all the constant pieces of info needed to evaluate 140672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj a CfiExpr into one convenient struct. */ 140772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjtypedef 140872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj struct { 140972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj Addr ipHere; 141072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj Addr spHere; 141172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj Addr fpHere; 141272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj Addr min_accessible; 141372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj Addr max_accessible; 141472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 141572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExprEvalContext; 141672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 141772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/* Evaluate the CfiExpr rooted at ix in exprs given the context eec. 141872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj *ok is set to False on failure, but not to True on success. The 141972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj caller must set it to True before calling. */ 142072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjstatic 142172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjUWord evalCfiExpr ( XArray* exprs, Int ix, 142272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExprEvalContext* eec, Bool* ok ) 142372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj{ 142472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj UWord wL, wR; 142519dc88f90d0e19a1463797dd99f6792a42f961d3sewardj Addr a; 142672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExpr* e = VG_(indexXA)( exprs, ix ); 142772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->tag) { 142872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_Binop: 142972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj wL = evalCfiExpr( exprs, e->Cex.Binop.ixL, eec, ok ); 143072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!(*ok)) return 0; 143172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj wR = evalCfiExpr( exprs, e->Cex.Binop.ixR, eec, ok ); 143272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!(*ok)) return 0; 143372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->Cex.Binop.op) { 143472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cop_Add: return wL + wR; 143572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cop_Sub: return wL - wR; 143619dc88f90d0e19a1463797dd99f6792a42f961d3sewardj case Cop_And: return wL & wR; 14377888e2204fff6e7429236b4227ed16594e7743b9sewardj case Cop_Mul: return wL * wR; 143872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: goto unhandled; 143972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 144072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 144172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_CfiReg: 144272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->Cex.CfiReg.reg) { 144372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Creg_IP: return (Addr)eec->ipHere; 144472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Creg_SP: return (Addr)eec->spHere; 144572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Creg_FP: return (Addr)eec->fpHere; 144672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: goto unhandled; 144772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 144872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 144972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_Const: 145072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj return e->Cex.Const.con; 145119dc88f90d0e19a1463797dd99f6792a42f961d3sewardj case Cex_Deref: 145219dc88f90d0e19a1463797dd99f6792a42f961d3sewardj a = evalCfiExpr( exprs, e->Cex.Deref.ixAddr, eec, ok ); 145319dc88f90d0e19a1463797dd99f6792a42f961d3sewardj if (!(*ok)) return 0; 145419dc88f90d0e19a1463797dd99f6792a42f961d3sewardj if (a < eec->min_accessible 145519dc88f90d0e19a1463797dd99f6792a42f961d3sewardj || (a + sizeof(UWord) - 1) > eec->max_accessible) { 145619dc88f90d0e19a1463797dd99f6792a42f961d3sewardj *ok = False; 145719dc88f90d0e19a1463797dd99f6792a42f961d3sewardj return 0; 145819dc88f90d0e19a1463797dd99f6792a42f961d3sewardj } 145919dc88f90d0e19a1463797dd99f6792a42f961d3sewardj /* let's hope it doesn't trap! */ 146019dc88f90d0e19a1463797dd99f6792a42f961d3sewardj return * ((UWord*)a); 146172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: 146272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj goto unhandled; 146372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 146472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 146572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj unhandled: 146672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("\n\nevalCfiExpr: unhandled\n"); 146772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj ML_(ppCfiExpr)( exprs, ix ); 146872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("\n"); 146972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); 147072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 147172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj return 0; 147272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj} 147372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 147472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 147572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/* The main function for DWARF2/3 CFI-based stack unwinding. 147672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj Given an IP/SP/FP triple, produce the IP/SP/FP values for the 147772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj previous frame, if possible. */ 1478eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Returns True if OK. If not OK, *{ip,sp,fp}P are not changed. */ 1479eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* NOTE: this function may rearrange the order of entries in the 1480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo list. */ 1481eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(use_CF_info) ( /*MOD*/Addr* ipP, 1482eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*MOD*/Addr* spP, 1483eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*MOD*/Addr* fpP, 1484eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Addr min_accessible, 1485eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Addr max_accessible ) 1486eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 148772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj Bool ok; 1488eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Int i; 1489b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1490eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj DiCfSI* cfsi = NULL; 1491eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Addr cfa, ipHere, spHere, fpHere, ipPrev, spPrev, fpPrev; 1492eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 149372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExprEvalContext eec; 149472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 1495eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static UInt n_search = 0; 1496eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static UInt n_steps = 0; 1497eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_search++; 1498eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1499eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (0) VG_(printf)("search for %p\n", *ipP); 1500eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1501b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (si = debugInfo_list; si != NULL; si = si->next) { 1502eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_steps++; 1503eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1504b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Use the per-DebugInfo summary address ranges to skip 1505b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj inapplicable DebugInfos quickly. */ 1506eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si->cfsi_used == 0) 1507eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj continue; 1508b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (*ipP < si->cfsi_minavma || *ipP > si->cfsi_maxavma) 1509eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj continue; 1510eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1511eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj i = ML_(search_one_cfitab)( si, *ipP ); 1512eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (i != -1) { 1513eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(i >= 0 && i < si->cfsi_used); 1514eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj cfsi = &si->cfsi[i]; 1515eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; 1516eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1517eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1518eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1519eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (cfsi == NULL) 1520eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1521eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1522b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0 && ((n_search & 0x7FFFF) == 0)) 1523b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("VG_(use_CF_info): %u searches, " 1524b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "%u DebugInfos looked at\n", 1525b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_search, n_steps); 1526eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1527b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Start of performance-enhancing hack: once every 64 (chosen 152872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj hackily after profiling) successful searches, move the found 1529b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo one step closer to the start of the list. This makes 1530eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj future searches cheaper. For starting konqueror on amd64, this 1531eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj in fact reduces the total amount of searching done by the above 1532b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj find-the-right-DebugInfo loop by more than a factor of 20. */ 1533b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ((n_search & 0x3F) == 0) { 1534eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Move si one step closer to the start of the list. */ 1535b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj move_DebugInfo_one_step_forward( si ); 1536eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1537eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* End of performance-enhancing hack. */ 1538eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1539eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (0) { 1540eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(printf)("found cfisi: "); 154172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj ML_(ppDiCfSI)(si->cfsi_exprs, cfsi); 1542eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1543eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1544eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj ipPrev = spPrev = fpPrev = 0; 1545eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1546eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj ipHere = *ipP; 1547eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj spHere = *spP; 1548eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj fpHere = *fpP; 1549eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 155072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /* First compute the CFA. */ 155172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj cfa = 0; 155272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (cfsi->cfa_how) { 155372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case CFIC_SPREL: 155472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj cfa = cfsi->cfa_off + spHere; 155572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 155672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case CFIC_FPREL: 155772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj cfa = cfsi->cfa_off + fpHere; 155872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 155972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case CFIC_EXPR: 15607888e2204fff6e7429236b4227ed16594e7743b9sewardj if (0) { 15617888e2204fff6e7429236b4227ed16594e7743b9sewardj VG_(printf)("CFIC_EXPR: "); 15627888e2204fff6e7429236b4227ed16594e7743b9sewardj ML_(ppCfiExpr)(si->cfsi_exprs, cfsi->cfa_off); 15637888e2204fff6e7429236b4227ed16594e7743b9sewardj VG_(printf)("\n"); 15647888e2204fff6e7429236b4227ed16594e7743b9sewardj } 15657888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.ipHere = ipHere; 15667888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.spHere = spHere; 15677888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.fpHere = fpHere; 15687888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.min_accessible = min_accessible; 15697888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.max_accessible = max_accessible; 15707888e2204fff6e7429236b4227ed16594e7743b9sewardj ok = True; 15717888e2204fff6e7429236b4227ed16594e7743b9sewardj cfa = evalCfiExpr(si->cfsi_exprs, cfsi->cfa_off, &eec, &ok ); 15727888e2204fff6e7429236b4227ed16594e7743b9sewardj if (!ok) return False; 157372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 157472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: 157572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); 157672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 157772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 157872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /* Now we know the CFA, use it to roll back the registers we're 157972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj interested in. */ 1580eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1581eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define COMPUTE(_prev, _here, _how, _off) \ 1582eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj do { \ 1583eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj switch (_how) { \ 1584eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_UNKNOWN: \ 1585eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; \ 1586eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_SAME: \ 1587eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj _prev = _here; break; \ 1588eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_MEMCFAREL: { \ 1589eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Addr a = cfa + (Word)_off; \ 1590eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (a < min_accessible \ 1591eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj || a+sizeof(Addr) > max_accessible) \ 1592eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; \ 1593eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj _prev = *(Addr*)a; \ 1594eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; \ 1595eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } \ 1596eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_CFAREL: \ 1597eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj _prev = cfa + (Word)_off; \ 1598eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; \ 159972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case CFIR_EXPR: \ 160072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (0) \ 160172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj ML_(ppCfiExpr)(si->cfsi_exprs,_off); \ 160272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.ipHere = ipHere; \ 160372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.spHere = spHere; \ 160472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.fpHere = fpHere; \ 160572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.min_accessible = min_accessible; \ 160672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.max_accessible = max_accessible; \ 160772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj ok = True; \ 160872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj _prev = evalCfiExpr(si->cfsi_exprs, _off, &eec, &ok ); \ 160972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!ok) return False; \ 161072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; \ 161172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: \ 161272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); \ 1613eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } \ 1614eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } while (0) 1615eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1616eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj COMPUTE(ipPrev, ipHere, cfsi->ra_how, cfsi->ra_off); 1617eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj COMPUTE(spPrev, spHere, cfsi->sp_how, cfsi->sp_off); 1618eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj COMPUTE(fpPrev, fpHere, cfsi->fp_how, cfsi->fp_off); 1619eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1620eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef COMPUTE 1621eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1622eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *ipP = ipPrev; 1623eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *spP = spPrev; 1624eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *fpP = fpPrev; 1625eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1626eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1627eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1628eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 1630b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 1631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- TOP LEVEL: GENERATE DESCRIPTION OF DATA ADDRESSES ---*/ 1632b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- FROM DWARF3 DEBUG INFO ---*/ 1633b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 1634b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 1635b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1636b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Evaluate the location expression/list for var, to see whether or 1637b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj not data_addr falls within the variable. If so also return the 1638b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset of data_addr from the start of the variable. Note that 1639b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs, which supplies ip,sp,fp values, will be NULL for global 1640b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj variables, and non-NULL for local variables. */ 1641b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Bool data_address_is_in_var ( /*OUT*/UWord* offset, 1642b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var, 1643b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj RegSummary* regs, 1644b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 1645b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_bias ) 1646b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 1647b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj MaybeUWord muw; 1648b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj SizeT var_szB; 1649b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj GXResult res; 1650b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool show = False; 1651b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->name); 1652b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->type); 1653b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->gexpr); 1654b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1655b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Figure out how big the variable is. */ 1656b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj muw = ML_(sizeOfType)(var->type); 1657b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* if this var has a type whose size is unknown, it should never 1658b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj have been added. ML_(addVar) should have rejected it. */ 1659b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(muw.b == True); 1660b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1661b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var_szB = muw.w; 1662b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1663b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) { 1664b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("VVVV: data_address_%p_is_in_var: %s :: ", 1665b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var->name ); 1666b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(pp_Type_C_ishly)( var->type ); 1667b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("\n"); 1668b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1670b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ignore zero-sized vars; they can never match anything. */ 1671b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (var_szB == 0) { 1672b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) 1673b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("VVVV: -> Fail (variable is zero sized)\n"); 1674b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 1675b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1677b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = ML_(evaluate_GX)( var->gexpr, var->fbGX, regs, data_bias ); 1678b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1679b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) { 1680b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("VVVV: -> "); 1681b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(pp_GXResult)( res ); 1682b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("\n"); 1683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1684eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1685b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (res.kind == GXR_Value 1686b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && res.word <= data_addr 1687b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && data_addr < res.word + var_szB) { 1688b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *offset = data_addr - res.word; 1689b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 1690b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 1691b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 1692b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 1694b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1695b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1696b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Format the acquired information into dname1[0 .. n_dname-1] and 1697b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2[0 .. n_dname-1] in an understandable way. Not so easy. 1698b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj If frameNo is -1, this is assumed to be a global variable; else 1699b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj a local variable. */ 1700b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void format_message ( /*OUT*/Char* dname1, 1701b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/Char* dname2, 1702b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int n_dname, 1703b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 1704b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var, 1705b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OffT var_offset, 1706b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OffT residual_offset, 1707b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* /*UChar*/ described, 1708b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int frameNo, 1709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid ) 1710eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1711b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool have_descr, have_srcloc; 1712b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj UChar* vo_plural = var_offset == 1 ? "" : "s"; 1713b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj UChar* ro_plural = residual_offset == 1 ? "" : "s"; 1714b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1715b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(frameNo >= -1); 1716b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(dname1 && dname2 && n_dname > 1); 1717b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(described); 1718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var && var->name); 1719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj have_descr = VG_(sizeXA)(described) > 0 1720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && *(UChar*)VG_(indexXA)(described,0) != '\0'; 1721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj have_srcloc = var->fileName && var->lineNo > 0; 1722b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[0] = dname2[0] = '\0'; 1724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ------ local cases ------ */ 1726b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1727b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && (!have_srcloc) && (!have_descr) ) { 1728b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc, no description: 1729b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside local var "a", 1730b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in frame #1 of thread 1 1731b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 1732b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 1733b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 1734b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside local var \"%s\",", 1735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var_offset, vo_plural, var->name ); 1736b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 1737b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2, n_dname, 1738b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "in frame #%d of thread %d", frameNo, (Int)tid); 1739b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1740b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 1741b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && have_srcloc && (!have_descr) ) { 1742b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no description: 1743b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside local var "a" 1744b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj declared at dsyms7.c:17, in frame #1 of thread 1 1745b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 1746b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 1747b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 1748b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside local var \"%s\"", 1749b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var_offset, vo_plural, var->name ); 1750b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 1751b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2, n_dname, 1752b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "declared at %s:%d, in frame #%d of thread %d", 1753b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var->fileName, var->lineNo, frameNo, (Int)tid); 1754b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1755b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 1756b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && (!have_srcloc) && have_descr ) { 1757b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc: 1758b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2 1759b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in frame #1 of thread 1 1760b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 1761b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 1762b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 1763b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside %s%s", 1764b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, residual_offset, ro_plural, var->name, 1765b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(indexXA)(described,0) ); 1766b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 1767b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2, n_dname, 1768b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "in frame #%d of thread %d", frameNo, (Int)tid); 1769b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1770b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 1771b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && have_srcloc && have_descr ) { 1772b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 1773b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj declared at dsyms7.c:17, in frame #1 of thread 1 */ 1774b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 1775b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 1776b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside %s%s,", 1777b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, residual_offset, ro_plural, var->name, 1778b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(indexXA)(described,0) ); 1779b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 1780b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2, n_dname, 1781b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "declared at %s:%d, in frame #%d of thread %d", 1782b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var->fileName, var->lineNo, frameNo, (Int)tid); 1783b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1784b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 1785b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ------ global cases ------ */ 1786b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && (!have_srcloc) && (!have_descr) ) { 1787b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc, no description: 1788b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside global var "a" 1789b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 1790b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 1791b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 1792b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside global var \"%s\"", 1793b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var_offset, vo_plural, var->name ); 1794b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1795b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 1796b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && have_srcloc && (!have_descr) ) { 1797b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no description: 1798b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside global var "a" 1799b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj declared at dsyms7.c:17 1800b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 1801b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 1802b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 1803b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside global var \"%s\"", 1804b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var_offset, vo_plural, var->name ); 1805b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 1806b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2, n_dname, 1807b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "declared at %s:%d", 1808b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var->fileName, var->lineNo); 1809b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1810b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 1811b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && (!have_srcloc) && have_descr ) { 1812b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc: 1813b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 1814b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj a global variable 1815b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 1816b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 1817b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 1818b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside %s%s,", 1819b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, residual_offset, ro_plural, var->name, 1820b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(indexXA)(described,0) ); 1821b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 1822b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2, n_dname, 1823b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "a global variable"); 1824b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1825b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 1826b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && have_srcloc && have_descr ) { 1827b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 1828b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj a global variable declared at dsyms7.c:17 */ 1829b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 1830b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 1831b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside %s%s,", 1832b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, residual_offset, ro_plural, var->name, 1833b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(indexXA)(described,0) ); 1834b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 1835b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2, n_dname, 1836b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "a global variable declared at %s:%d", 1837b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var->fileName, var->lineNo); 1838b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1839b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 1840b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(0); 1841b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1842b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 1843eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1844eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1845b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1846b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Determine if data_addr is a local variable in the frame 1847b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj characterised by (ip,sp,fp), and if so write its description into 1848b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname{1,2}[0..n_dname-1], and return True. If not, return 1849b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj False. */ 1850b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic 1851b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool consider_vars_in_frame ( /*OUT*/Char* dname1, 1852b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/Char* dname2, 1853b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int n_dname, 1854b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 1855b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr ip, Addr sp, Addr fp, 1856b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* shown to user: */ 1857b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid, Int frameNo ) 1858eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1859b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word i; 1860b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1861b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj RegSummary regs; 1862b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool debug = False; 1863b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1864b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj static UInt n_search = 0; 1865b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj static UInt n_steps = 0; 1866b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_search++; 1867b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 1868b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("QQQQ: cvif: ip,sp,fp %p,%p,%p\n", ip,sp,fp); 1869b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* first, find the DebugInfo that pertains to 'ip'. */ 1870b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di; di = di->next) { 1871b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_steps++; 1872b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* text segment missing? unlikely, but handle it .. */ 1873b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->text_present || di->text_size == 0) 1874b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 1875b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok. So does this text mapping bracket the ip? */ 1876b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_avma <= ip && ip < di->text_avma + di->text_size) 1877b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 1878b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1879b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1880b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Didn't find it. Strange -- means ip is a code address outside 1881b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj of any mapped text segment. Unlikely but not impossible -- app 1882b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj could be generating code to run. */ 1883b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di) 1884b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 1885b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1886b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0 && ((n_search & 0x1) == 0)) 1887b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("consider_vars_in_frame: %u searches, " 1888b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "%u DebugInfos looked at\n", 1889b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_search, n_steps); 1890b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Start of performance-enhancing hack: once every ??? (chosen 1891b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj hackily after profiling) successful searches, move the found 1892b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo one step closer to the start of the list. This makes 1893b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj future searches cheaper. */ 1894b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ((n_search & 0xFFFF) == 0) { 1895b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Move si one step closer to the start of the list. */ 1896b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj move_DebugInfo_one_step_forward( di ); 1897b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1898b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* End of performance-enhancing hack. */ 1899b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1900b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* any var info at all? */ 1901b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->varinfo) 1902b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 1903b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1904b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Work through the scopes from most deeply nested outwards, 1905b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj looking for code address ranges that bracket 'ip'. The 1906b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj variables on each such address range found are in scope right 1907b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj now. Don't descend to level zero as that is the global 1908b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj scope. */ 1909b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.ip = ip; 1910b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.sp = sp; 1911b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.fp = fp; 1912b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1913b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* "for each scope, working outwards ..." */ 1914b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) { 1915b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* vars; 1916b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word j; 1917b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* arange; 1918b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* this_scope 1919b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj = *(OSet**)VG_(indexXA)( di->varinfo, i ); 1920b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 1921b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("QQQQ: considering scope %ld\n", (Word)i); 1922b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!this_scope) 1923b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 1924b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Find the set of variables in this scope that 1925b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj bracket the program counter. */ 1926b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj arange = VG_(OSetGen_LookupWithCmp)( 1927b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj this_scope, &ip, 1928b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(cmp_for_DiAddrRange_range) 1929b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ); 1930b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!arange) 1931b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 1932b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* stay sane */ 1933b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->aMin <= arange->aMax); 1934b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* It must bracket the ip we asked for, else 1935b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(cmp_for_DiAddrRange_range) is somehow broken. */ 1936b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->aMin <= ip && ip <= arange->aMax); 1937b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* It must have an attached XArray of DiVariables. */ 1938b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vars = arange->vars; 1939b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(vars); 1940b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* But it mustn't cover the entire address range. We only 1941b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj expect that to happen for the global scope (level 0), which 1942b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj we're not looking at here. Except, it may cover the entire 1943b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj address range, but in that case the vars array must be 1944b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj empty. */ 1945b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(! (arange->aMin == (Addr)0 1946b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && arange->aMax == ~(Addr)0 1947b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && VG_(sizeXA)(vars) > 0) ); 1948b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < VG_(sizeXA)( vars ); j++) { 1949b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j ); 1950b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj SizeT offset; 1951b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 1952b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("QQQQ: var:name=%s %p-%p %p\n", 1953b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var->name,arange->aMin,arange->aMax,ip); 1954b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (data_address_is_in_var( &offset, var, ®s, data_addr, 1955b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_bias )) { 1956b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OffT residual_offset = 0; 1957b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* described = ML_(describe_type)( &residual_offset, 1958b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var->type, offset ); 1959b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj format_message( dname1, dname2, n_dname, 1960b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var, offset, residual_offset, 1961b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj described, frameNo, tid ); 1962b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)( described ); 1963b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 1964b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1965b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1966b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1967b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1968b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 1969eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1970eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1971b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Try to form some description of data_addr by looking at the DWARF3 1972b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debug info we have. This considers all global variables, and all 1973b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj frames in the stacks of all threads. Result (or as much as will 1974b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj fit) is put into into dname{1,2}[0 .. n_dname-1] and is guaranteed 1975b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to be zero terminated. */ 1976b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool VG_(get_data_description)( /*OUT*/Char* dname1, 1977b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/Char* dname2, 1978b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int n_dname, 1979b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr ) 1980eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1981b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# define N_FRAMES 8 1982b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr ips[N_FRAMES], sps[N_FRAMES], fps[N_FRAMES]; 1983b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj UInt n_frames; 1984b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1985b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr stack_min, stack_max; 1986b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid; 1987b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool found; 1988b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1989b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word j; 1990b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1991b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_dname > 1); 1992b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 1993b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1994b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0) VG_(printf)("get_data_description: dataaddr %p\n", data_addr); 1995b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* First, see if data_addr is (or is part of) a global variable. 1996b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Loop over the DebugInfos we have. Check data_addr against the 1997b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj outermost scope of all of them, as that should be a global 1998b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj scope. */ 1999b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 2000b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* global_scope; 2001b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int gs_size; 2002b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr zero; 2003b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* global_arange; 2004b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word i; 2005b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* vars; 2006b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2007b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* text segment missing? unlikely, but handle it .. */ 2008b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->text_present || di->text_size == 0) 2009b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2010b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* any var info at all? */ 2011b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->varinfo) 2012b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2013b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* perhaps this object didn't contribute any vars at all? */ 2014b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (VG_(sizeXA)( di->varinfo ) == 0) 2015b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2016b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj global_scope = *(OSet**)VG_(indexXA)( di->varinfo, 0 ); 2017b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_scope); 2018b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj gs_size = VG_(OSetGen_Size)( global_scope ); 2019b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* The global scope might be completely empty if this 2020b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj compilation unit declared locals but nothing global. */ 2021b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (gs_size == 0) 2022b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2023b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* But if it isn't empty, then it must contain exactly one 2024b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj element, which covers the entire address range. */ 2025b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(gs_size == 1); 2026b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Fish out the global scope and check it is as expected. */ 2027b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj zero = 0; 2028b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj global_arange 2029b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj = VG_(OSetGen_Lookup)( global_scope, &zero ); 2030b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* The global range from (Addr)0 to ~(Addr)0 must exist */ 2031b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_arange); 2032b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_arange->aMin == (Addr)0 2033b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && global_arange->aMax == ~(Addr)0); 2034b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Any vars in this range? */ 2035b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!global_arange->vars) 2036b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2037b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok, there are some vars in the global scope of this 2038b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo. Wade through them and see if the data addresses 2039b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj of any of them bracket data_addr. */ 2040b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vars = global_arange->vars; 2041b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = 0; i < VG_(sizeXA)( vars ); i++) { 2042b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj SizeT offset; 2043b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, i ); 2044b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->name); 2045b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Note we use a NULL RegSummary* here. It can't make any 2046b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sense for a global variable to have a location expression 2047b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which depends on a SP/FP/IP value. So don't supply any. 2048b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj This means, if the evaluation of the location 2049b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj expression/list requires a register, we have to let it 2050b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj fail. */ 2051b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (data_address_is_in_var( &offset, var, 2052b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj NULL/* RegSummary* */, 2053b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, di->data_bias )) { 2054b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OffT residual_offset = 0; 2055b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* described = ML_(describe_type)( &residual_offset, 2056b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var->type, offset ); 2057b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj format_message( dname1, dname2, n_dname, 2058b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var, offset, residual_offset, 2059b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj described, -1/*frameNo*/, tid ); 2060b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)( described ); 2061b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 2062b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 2063b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2065b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2066b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2067b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok, well it's not a global variable. So now let's snoop around 2068b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in the stacks of all the threads. First try to figure out which 2069b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj thread's stack data_addr is in. */ 2070b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2071b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* --- KLUDGE --- Try examining the top frame of all thread stacks. 2072b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj This finds variables which are not stack allocated but are not 2073b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj globally visible either; specifically it appears to pick up 2074b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj variables which are visible only within a compilation unit. 2075b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj These will have the address range of the compilation unit and 2076b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj tend to live at Scope level 1. */ 2077b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(thread_stack_reset_iter)(&tid); 2078b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) { 2079b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (stack_min >= stack_max) 2080b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; /* ignore obviously stupid cases */ 2081b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (consider_vars_in_frame( dname1, dname2, n_dname, 2082b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, 2083b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(get_IP)(tid), 2084b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(get_SP)(tid), 2085b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(get_FP)(tid), tid, 0 )) { 2086b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 2087b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 2088b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2089b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2090b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* --- end KLUDGE --- */ 2091b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2092b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Perhaps it's on a thread's stack? */ 2093b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj found = False; 2094b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(thread_stack_reset_iter)(&tid); 2095b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) { 2096b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (stack_min >= stack_max) 2097b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; /* ignore obviously stupid cases */ 2098b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (stack_min - VG_STACK_REDZONE_SZB <= data_addr 2099b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && data_addr <= stack_max) { 2100b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj found = True; 2101b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 2102b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2103b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2104b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!found) { 2105b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 2106b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 2107b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2108b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2109b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We conclude data_addr is in thread tid's stack. Unwind the 2110b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj stack to get a bunch of (ip,sp,fp) triples describing the 2111b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj frames, and for each frame, consider the local variables. */ 2112b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_frames = VG_(get_StackTrace)( tid, ips, N_FRAMES, 2113b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sps, fps, 0/*first_ip_delta*/ ); 2114b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Re ip_delta in the next loop: There's a subtlety in the meaning 2115b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj of the IP values in a stack obtained from VG_(get_StackTrace). 2116b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj The innermost value really is simply the thread's program 2117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj counter at the time the snapshot was taken. However, all the 2118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj other values are actually return addresses, and so point just 2119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj after the call instructions. Hence they notionally reflect not 2120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj what the program counters were at the time those calls were 2121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj made, but what they will be when those calls return. This can 2122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj be of significance should an address range happen to end at the 2123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj end of a call instruction -- we may ignore the range when in 2124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj fact it should be considered. Hence, back up the IPs by 1 for 2125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj all non-innermost IPs. Note that VG_(get_StackTrace_wrk) itself 2126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj has to use the same trick in order to use CFI data to unwind the 2127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj stack (as documented therein in comments). */ 2128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* As a result of KLUDGE above, starting the loop at j = 0 2129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj duplicates examination of the top frame and so isn't necessary. 2130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Oh well. */ 2131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_frames >= 0 && n_frames <= N_FRAMES); 2132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < n_frames; j++) { 2133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word ip_delta = j == 0 ? 0 : 1; 2134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (consider_vars_in_frame( dname1, dname2, n_dname, 2135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, 2136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ips[j] - ip_delta, 2137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sps[j], fps[j], tid, j )) { 2138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 2139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 2140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Now, it appears that gcc sometimes appears to produce 2142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj location lists whose ranges don't actually cover the call 2143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj instruction, even though the address of the variable in 2144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj question is passed as a parameter in the call. AFAICS this 2145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is simply a bug in gcc - how can the variable be claimed not 2146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj exist in memory (on the stack) for the duration of a call in 2147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which its address is passed? But anyway, in the particular 2148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case I investigated (memcheck/tests/varinfo6.c, call to croak 2149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj on line 2999, local var budget declared at line 3115 2150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj appearing not to exist across the call to mainSort on line 2151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3143, "gcc.orig (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2)" on 2152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj amd64), the variable's location list does claim it exists 2153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj starting at the first byte of the first instruction after the 2154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj call instruction. So, call consider_vars_in_frame a second 2155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj time, but this time don't subtract 1 from the IP. GDB 2156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj handles this example with no difficulty, which leads me to 2157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj believe that either (1) I misunderstood something, or (2) GDB 2158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj has an equivalent kludge. */ 2159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (consider_vars_in_frame( dname1, dname2, n_dname, 2160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, 2161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ips[j], 2162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sps[j], fps[j], tid, j )) { 2163b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 2164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 2165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2166b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2167b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2168b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We didn't find anything useful. */ 2169b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 2170b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 2171b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# undef N_FRAMES 2172eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2173eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2174b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 2176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- DebugInfo accessor functions ---*/ 2177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 2178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjconst DebugInfo* VG_(next_seginfo)(const DebugInfo* di) 2180eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == NULL) 2182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return debugInfo_list; 2183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->next; 2184eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2185eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjAddr VG_(seginfo_get_text_avma)(const DebugInfo* di) 2187eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_avma : 0; 2189eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2190eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2191b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjSizeT VG_(seginfo_get_text_size)(const DebugInfo* di) 2192eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2193b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_size : 0; 2194eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2195eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjconst UChar* VG_(seginfo_soname)(const DebugInfo* di) 2197eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->soname; 2199b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 2200eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjconst UChar* VG_(seginfo_filename)(const DebugInfo* di) 2202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 2203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->filename; 2204eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2205eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjULong VG_(seginfo_get_text_bias)(const DebugInfo* di) 2207bbec7728efefaa650970dd1f0282b77040287133sewardj{ 2208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_bias : 0; 2209bbec7728efefaa650970dd1f0282b77040287133sewardj} 2210bbec7728efefaa650970dd1f0282b77040287133sewardj 2211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjInt VG_(seginfo_syms_howmany) ( const DebugInfo *si ) 2212eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2213eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return si->symtab_used; 2214eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2215eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2216b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid VG_(seginfo_syms_getidx) ( const DebugInfo *si, 2217eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Int idx, 2218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/Addr* avma, 22194ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj /*OUT*/Addr* tocptr, 2220eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/UInt* size, 2221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/HChar** name, 2222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/Bool* isText ) 2223eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2224eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(idx >= 0 && idx < si->symtab_used); 2225b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (avma) *avma = si->symtab[idx].addr; 22264ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (tocptr) *tocptr = si->symtab[idx].tocptr; 22274ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (size) *size = si->symtab[idx].size; 22284ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (name) *name = (HChar*)si->symtab[idx].name; 2229b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (isText) *isText = si->symtab[idx].isText; 2230b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 2231b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2232b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 2234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- SectKind query functions ---*/ 2235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 2236b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2237b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Convert a VgSectKind to a string, which must be copied if you want 2238b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to change it. */ 2239b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjconst HChar* VG_(pp_SectKind)( VgSectKind kind ) 2240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 2241b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj switch (kind) { 2242b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectUnknown: return "Unknown"; 2243b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectText: return "Text"; 2244b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectData: return "Data"; 2245b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectBSS: return "BSS"; 2246b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectGOT: return "GOT"; 2247b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectPLT: return "PLT"; 2248b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectOPD: return "OPD"; 2249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj default: vg_assert(0); 2250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2251b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 2252b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Given an address 'a', make a guess of which section of which object 2254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj it comes from. If name is non-NULL, then the last n_name-1 2255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj characters of the object's name is put in name[0 .. n_name-2], and 2256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj name[n_name-1] is set to zero (guaranteed zero terminated). */ 2257b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjVgSectKind VG_(seginfo_sect_kind)( /*OUT*/UChar* name, SizeT n_name, 2259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr a) 2260b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 2261b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 2262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VgSectKind res = Vg_SectUnknown; 2263b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 2265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2266b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0) 2267b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)( 2268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "addr=%p di=%p %s got=%p,%ld plt=%p,%ld data=%p,%ld bss=%p,%ld\n", 2269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj a, di, di->filename, 2270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->got_avma, di->got_size, 2271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->plt_avma, di->plt_size, 2272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_avma, di->data_size, 2273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->bss_avma, di->bss_size); 2274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 2276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_size > 0 2277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->text_avma && a < di->text_avma + di->text_size) { 2278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectText; 2279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 2280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->data_present 2282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_size > 0 2283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->data_avma && a < di->data_avma + di->data_size) { 2284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectData; 2285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 2286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->sdata_present 2288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_size > 0 2289b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->sdata_avma && a < di->sdata_avma + di->sdata_size) { 2290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectData; 2291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 2292b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2293b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->bss_present 2294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_size > 0 2295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->bss_avma && a < di->bss_avma + di->bss_size) { 2296b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectBSS; 2297b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 2298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->plt_present 2300b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->plt_size > 0 2301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->plt_avma && a < di->plt_avma + di->plt_size) { 2302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectPLT; 2303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 2304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2305b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->got_present 2306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->got_size > 0 2307b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->got_avma && a < di->got_avma + di->got_size) { 2308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectGOT; 2309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 2310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2311b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->opd_present 2312b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->opd_size > 0 2313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->opd_avma && a < di->opd_avma + di->opd_size) { 2314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectOPD; 2315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 2316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2317b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* we could also check for .eh_frame, if anyone really cares */ 2318b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2319b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2320b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert( (di == NULL && res == Vg_SectUnknown) 2321b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || (di != NULL && res != Vg_SectUnknown) ); 2322b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (name) { 2324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_name >= 8); 2326b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di && di->filename) { 2328b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int i, j; 2329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int fnlen = VG_(strlen)(di->filename); 2330b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int start_at = 1 + fnlen - n_name; 2331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (start_at < 0) start_at = 0; 2332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(start_at < fnlen); 2333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj i = start_at; j = 0; 2334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 2335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(j >= 0 && j+1 < n_name); 2336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(i >= 0 && i <= fnlen); 2337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj name[j] = di->filename[i]; 2338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj name[j+1] = 0; 2339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->filename[i] == 0) break; 2340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj i++; j++; 2341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 2343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)(name, n_name, "%s", "???"); 2344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2345b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj name[n_name-1] = 0; 2347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return res; 2350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2351eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2352eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2353eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2354eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 2355eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- end ---*/ 2356eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 2357