debuginfo.c revision f76d27a697a7b0bf3b84490baf60623fc96a23af
1eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 3eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Top level management of symbols and debugging information. ---*/ 4eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- debuginfo.c ---*/ 5eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 6eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 7eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* 8eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj This file is part of Valgrind, a dynamic binary instrumentation 9eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj framework. 10eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 119f207460d70d38c46c9e81996a3dcdf90961c6dbnjn Copyright (C) 2000-2009 Julian Seward 12eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj jseward@acm.org 13eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 14eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj This program is free software; you can redistribute it and/or 15eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj modify it under the terms of the GNU General Public License as 16eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj published by the Free Software Foundation; either version 2 of the 17eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj License, or (at your option) any later version. 18eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 19eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj This program is distributed in the hope that it will be useful, but 20eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj WITHOUT ANY WARRANTY; without even the implied warranty of 21eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj General Public License for more details. 23eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 24eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj You should have received a copy of the GNU General Public License 25eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj along with this program; if not, write to the Free Software 26eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 27eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 02111-1307, USA. 28eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 29eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj The GNU General Public License is contained in the file COPYING. 30eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 31eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* 32eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 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" 46d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj#include "pub_core_seqmatch.h" 47eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_options.h" 48b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_redir.h" // VG_(redir_notify_{new,delete}_SegInfo) 49eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_aspacemgr.h" 50b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_machine.h" // VG_PLAT_USES_PPCTOC 5172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj#include "pub_core_xarray.h" 52b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_oset.h" 536882443ef154bca367bc591287de641e43a9e108njn#include "pub_core_stacktrace.h" // VG_(get_StackTrace) XXX: circular dependency 54f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#include "pub_core_ume.h" 55b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 56b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_misc.h" /* dinfo_zalloc/free */ 57b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_d3basics.h" /* ML_(pp_GX) */ 58b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_tytypes.h" 59eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "priv_storage.h" 60eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "priv_readdwarf.h" 61eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "priv_readstabs.h" 624ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#if defined(VGO_linux) 634ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# include "priv_readelf.h" 64b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# include "priv_readdwarf3.h" 65c8259b85b701d25d72aabe9dc0a8154517f96913sewardj# include "priv_readpdb.h" 664ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#elif defined(VGO_aix5) 674ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# include "pub_core_debuglog.h" 684ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# include "pub_core_libcproc.h" 694ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# include "pub_core_libcfile.h" 704ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# include "priv_readxcoff.h" 71f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(VGO_darwin) 72f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# include "priv_readmacho.h" 73f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# include "priv_readpdb.h" 744ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#endif 75eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 76c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 77c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/*------------------------------------------------------------*/ 78c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/*--- The _svma / _avma / _image / _bias naming scheme ---*/ 79c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/*------------------------------------------------------------*/ 80c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 81c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/* JRS 11 Jan 07: I find the different kinds of addresses involved in 82c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj debuginfo reading confusing. Recently I arrived at some 83c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj terminology which makes it clearer (to me, at least). There are 3 84c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj kinds of address used in the debuginfo reading process: 85c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 86c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj stated VMAs - the address where (eg) a .so says a symbol is, that 87c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj is, what it tells you if you consider the .so in 88c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj isolation 89c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 90c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj actual VMAs - the address where (eg) said symbol really wound up 91c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj after the .so was mapped into memory 92c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 93c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj image addresses - pointers into the copy of the .so (etc) 94c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj transiently mmaped aboard whilst we read its info 95c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 96c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj Additionally I use the term 'bias' to denote the difference 97c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj between stated and actual VMAs for a given entity. 98c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 99c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj This terminology is not used consistently, but a start has been 100c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj made. readelf.c and the call-frame info reader in readdwarf.c now 101c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj use it. Specifically, various variables and structure fields have 102f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj been annotated with _avma / _svma / _image / _bias. In places _img 103f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj is used instead of _image for the sake of brevity. 104c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj*/ 105c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 106c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 107eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 108f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- fwdses ---*/ 109f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*------------------------------------------------------------*/ 110f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 111f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic void cfsi_cache__invalidate ( void ); 112f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 113f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 114f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*------------------------------------------------------------*/ 115eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Root structure ---*/ 116eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 117eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* The root structure for the entire debug info system. It is a 119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj linked list of DebugInfos. */ 120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic DebugInfo* debugInfo_list = NULL; 121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Find 'di' in the debugInfo_list and move it one step closer the the 124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj front of the list, so as to make subsequent searches for it 125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj cheaper. When used in a controlled way, makes a major improvement 126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in some DebugInfo-search-intensive situations, most notably stack 127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj unwinding on amd64-linux. */ 128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void move_DebugInfo_one_step_forward ( DebugInfo* di ) 129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo *di0, *di1, *di2; 131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == debugInfo_list) 132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; /* already at head of list */ 133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di != NULL); 134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0 = debugInfo_list; 135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1 = NULL; 136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2 = NULL; 137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 == NULL || di0 == di) break; 139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2 = di1; 140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1 = di0; 141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0 = di0->next; 142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di0 == di); 144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 != NULL && di1 != NULL && di2 != NULL) { 145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* tmp; 146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* di0 points to di, di1 to its predecessor, and di2 to di1's 147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj predecessor. Swap di0 and di1, that is, move di0 one step 148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj closer to the start of the list. */ 149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di2->next == di1); 150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di1->next == di0); 151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj tmp = di0->next; 152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->next = di0; 153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0->next = di1; 154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1->next = tmp; 155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 != NULL && di1 != NULL && di2 == NULL) { 158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* it's second in the list. */ 159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(debugInfo_list == di1); 160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di1->next == di0); 161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1->next = di0->next; 162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0->next = di1; 163b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debugInfo_list = di0; 164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 166eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 167eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 168eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 169eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Notification (acquire/discard) helpers ---*/ 170eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 171eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Gives out unique abstract handles for allocated DebugInfos. See 1739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj comment in priv_storage.h, declaration of struct _DebugInfo, for 1749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj details. */ 1759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic ULong handle_counter = 1; 1769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Allocate and zero out a new DebugInfo record. */ 178eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjstatic 179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjDebugInfo* alloc_DebugInfo( const UChar* filename, 180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj const UChar* memname ) 181eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool traceme; 183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 184eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 185f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj vg_assert(filename); 186f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj 1879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di = ML_(dinfo_zalloc)("di.debuginfo.aDI.1", sizeof(DebugInfo)); 1889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->handle = handle_counter++; 1899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->filename = ML_(dinfo_strdup)("di.debuginfo.aDI.2", filename); 1909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->memname = memname ? ML_(dinfo_strdup)("di.debuginfo.aDI.3", memname) 191b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj : NULL; 192eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 193f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj /* Everything else -- pointers, sizes, arrays -- is zeroed by calloc. 194f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj Now set up the debugging-output flags. */ 195f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj traceme 196f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj = VG_(string_match)( VG_(clo_trace_symtab_patt), filename ) 197f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj || (memname && VG_(string_match)( VG_(clo_trace_symtab_patt), 198f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj memname )); 199f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj if (traceme) { 200b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->trace_symtab = VG_(clo_trace_symtab); 201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->trace_cfi = VG_(clo_trace_cfi); 202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_syms = VG_(clo_debug_dump_syms); 203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_line = VG_(clo_debug_dump_line); 204b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_frames = VG_(clo_debug_dump_frames); 205f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj } 206f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj 207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 208eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 209eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 210eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Free a DebugInfo, and also all the stuff hanging off it. */ 212b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void free_DebugInfo ( DebugInfo* di ) 213eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 21459a2d18d0ddfa241850017252b0804d469187d79sewardj Word i, j, n; 215eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj struct strchunk *chunk, *next; 2169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ent; 21759a2d18d0ddfa241850017252b0804d469187d79sewardj GExpr* gexpr; 218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di != NULL); 220b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->filename) ML_(dinfo_free)(di->filename); 221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->symtab) ML_(dinfo_free)(di->symtab); 222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->loctab) ML_(dinfo_free)(di->loctab); 223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->cfsi) ML_(dinfo_free)(di->cfsi); 224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->cfsi_exprs) VG_(deleteXA)(di->cfsi_exprs); 225c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (di->fpo) ML_(dinfo_free)(di->fpo); 226b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 227b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (chunk = di->strchunks; chunk != NULL; chunk = next) { 228eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj next = chunk->next; 229b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(dinfo_free)(chunk); 230b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 231b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Delete the two admin arrays. These lists exist primarily so 2339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj that we can visit each object exactly once when we need to 2349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj delete them. */ 2359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (di->admin_tyents) { 2369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n = VG_(sizeXA)(di->admin_tyents); 23759a2d18d0ddfa241850017252b0804d469187d79sewardj for (i = 0; i < n; i++) { 2389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ent = (TyEnt*)VG_(indexXA)(di->admin_tyents, i); 2399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Dump anything hanging off this ent */ 2409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(TyEnt__make_EMPTY)(ent); 24159a2d18d0ddfa241850017252b0804d469187d79sewardj } 2429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(deleteXA)(di->admin_tyents); 2439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->admin_tyents = NULL; 244eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 24559a2d18d0ddfa241850017252b0804d469187d79sewardj 24659a2d18d0ddfa241850017252b0804d469187d79sewardj if (di->admin_gexprs) { 24759a2d18d0ddfa241850017252b0804d469187d79sewardj n = VG_(sizeXA)(di->admin_gexprs); 24859a2d18d0ddfa241850017252b0804d469187d79sewardj for (i = 0; i < n; i++) { 24959a2d18d0ddfa241850017252b0804d469187d79sewardj gexpr = *(GExpr**)VG_(indexXA)(di->admin_gexprs, i); 25059a2d18d0ddfa241850017252b0804d469187d79sewardj ML_(dinfo_free)(gexpr); 25159a2d18d0ddfa241850017252b0804d469187d79sewardj } 25259a2d18d0ddfa241850017252b0804d469187d79sewardj VG_(deleteXA)(di->admin_gexprs); 25359a2d18d0ddfa241850017252b0804d469187d79sewardj di->admin_gexprs = NULL; 254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Dump the variable info. This is kinda complex: we must take 257b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj care not to free items which reside in either the admin lists 258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (as we have just freed them) or which reside in the DebugInfo's 259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj string table. */ 260b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->varinfo) { 261b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = 0; i < VG_(sizeXA)(di->varinfo); i++) { 262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* scope = *(OSet**)VG_(indexXA)(di->varinfo, i); 263b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!scope) continue; 264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* iterate over all entries in 'scope' */ 265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(OSetGen_ResetIter)(scope); 266b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 267b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* arange = VG_(OSetGen_Next)(scope); 268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!arange) break; 269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* for each var in 'arange' */ 270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->vars); 271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < VG_(sizeXA)( arange->vars ); j++) { 272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)(arange->vars,j); 273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var); 274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Nothing to free in var: all the pointer fields refer 275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to stuff either on an admin list, or in 276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj .strchunks */ 277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)(arange->vars); 279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Don't free arange itself, as OSetGen_Destroy does 280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj that */ 281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(OSetGen_Destroy)(scope); 283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)(di->varinfo); 285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(dinfo_free)(di); 288eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 289eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 290eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* 'si' is a member of debugInfo_list. Find it, remove it from the 292eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj list, notify m_redir that this has happened, and free all storage 293eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj reachable from it. 294eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void discard_DebugInfo ( DebugInfo* di ) 296eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2974ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# if defined(VGP_ppc32_aix5) 2984ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj HChar* reason = "__unload"; 2994ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# elif defined(VGP_ppc64_aix5) 3004ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj HChar* reason = "kunload64"; 3014ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# else 3024ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj HChar* reason = "munmap"; 3034ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# endif 3044ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 305b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo** prev_next_ptr = &debugInfo_list; 306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* curr = debugInfo_list; 307eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 308eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj while (curr) { 309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (curr == di) { 310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Found it; remove from list and free it. */ 31133e4e7eaab263cea956700f56f007ab26c39eab4sewardj if (curr->have_dinfo 31233e4e7eaab263cea956700f56f007ab26c39eab4sewardj && (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))) 313eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(message)(Vg_DebugMsg, 314a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart "Discarding syms at %#lx-%#lx in %s due to %s()", 315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_avma, 316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_avma + di->text_size, 3174ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj curr->filename ? curr->filename : (UChar*)"???", 3184ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj reason); 319eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(*prev_next_ptr == curr); 320eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *prev_next_ptr = curr->next; 32133e4e7eaab263cea956700f56f007ab26c39eab4sewardj if (curr->have_dinfo) 32233e4e7eaab263cea956700f56f007ab26c39eab4sewardj VG_(redir_notify_delete_DebugInfo)( curr ); 323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj free_DebugInfo(curr); 324eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return; 325eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 326eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj prev_next_ptr = &curr->next; 327eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj curr = curr->next; 328eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 329eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 330b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Not found. */ 331eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 332eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 333eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Repeatedly scan debugInfo_list, looking for DebugInfos with text 335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj AVMAs intersecting [start,start+length), and call discard_DebugInfo 336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to get rid of them. This modifies the list, hence the multiple 337f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj iterations. Returns True iff any such DebugInfos were found. 338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/ 339f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic Bool discard_syms_in_range ( Addr start, SizeT length ) 340eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 341f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool anyFound = False; 342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool found; 343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* curr; 344eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 345eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj while (True) { 346eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj found = False; 347eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj curr = debugInfo_list; 349eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj while (True) { 350eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (curr == NULL) 351eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; 352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (curr->text_present 353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && curr->text_size > 0 354b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && (start+length - 1 < curr->text_avma 355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || curr->text_avma + curr->text_size - 1 < start)) { 356eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* no overlap */ 357eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 358eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj found = True; 359eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; 360eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 361eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj curr = curr->next; 362eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 363eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 364eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (!found) break; 365f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj anyFound = True; 366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_DebugInfo( curr ); 367eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 368f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 369f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return anyFound; 370eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 371eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 372eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Does [s1,+len1) overlap [s2,+len2) ? Note: does not handle 374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj wraparound at the end of the address space -- just asserts in that 375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case. */ 376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Bool ranges_overlap (Addr s1, SizeT len1, Addr s2, SizeT len2 ) 377eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr e1, e2; 379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (len1 == 0 || len2 == 0) 380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj e1 = s1 + len1 - 1; 382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj e2 = s2 + len2 - 1; 383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Assert that we don't have wraparound. If we do it would imply 384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj that file sections are getting mapped around the end of the 385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj address space, which sounds unlikely. */ 386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(s1 <= e1); 387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(s2 <= e2); 388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (e1 < s2 || e2 < s1) return False; 389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 391eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 392eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Do the basic rx_ and rw_ mappings of the two DebugInfos overlap in 394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj any way? */ 395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Bool do_DebugInfos_overlap ( DebugInfo* di1, DebugInfo* di2 ) 396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di1); 398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di2); 399eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di1->have_rx_map && di2->have_rx_map 401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ranges_overlap(di1->rx_map_avma, di1->rx_map_size, 402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->rx_map_avma, di2->rx_map_size)) 403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 404eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di1->have_rx_map && di2->have_rw_map 406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ranges_overlap(di1->rx_map_avma, di1->rx_map_size, 407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->rw_map_avma, di2->rw_map_size)) 408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 410b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di1->have_rw_map && di2->have_rx_map 411b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ranges_overlap(di1->rw_map_avma, di1->rw_map_size, 412b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->rx_map_avma, di2->rx_map_size)) 413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 414b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di1->have_rw_map && di2->have_rw_map 416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ranges_overlap(di1->rw_map_avma, di1->rw_map_size, 417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->rw_map_avma, di2->rw_map_size)) 418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Discard all elements of debugInfo_list whose .mark bit is set. 425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/ 426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void discard_marked_DebugInfos ( void ) 427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* curr; 429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj curr = debugInfo_list; 433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!curr) 435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (curr->mark) 437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj curr = curr->next; 439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!curr) break; 442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_DebugInfo( curr ); 443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Discard any elements of debugInfo_list which overlap with diRef. 449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Clearly diRef must have its rx_ and rw_ mapping information set to 450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj something sane. */ 451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#if defined(VGO_aix5) 452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((unused)) 453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif 454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void discard_DebugInfos_which_overlap_with ( DebugInfo* diRef ) 455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Mark all the DebugInfos in debugInfo_list that need to be 458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj deleted. First, clear all the mark bits; then set them if they 459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj overlap with siRef. Since siRef itself is in this list we at 460b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj least expect its own mark bit to be set. */ 461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di; di = di->next) { 462b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->mark = do_DebugInfos_overlap( di, diRef ); 463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == diRef) { 464b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->mark); 465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->mark = False; 466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 467eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 468b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_marked_DebugInfos(); 469b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 470b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 471eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 472b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Find the existing DebugInfo for (memname,filename) or if not found, 473b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj create one. In the latter case memname and filename are strdup'd 474b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj into VG_AR_DINFO, and the new DebugInfo is added to 475b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debugInfo_list. */ 476b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic 477b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjDebugInfo* find_or_create_DebugInfo_for ( UChar* filename, UChar* memname ) 478b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 479b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(filename); 481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di; di = di->next) { 482b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->filename); 483b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0==VG_(strcmp)(di->filename, filename) 484b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ( (memname && di->memname) 485b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ? 0==VG_(strcmp)(memname, di->memname) 486b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj : True )) 487b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 488b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 489b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di) { 490b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di = alloc_DebugInfo(filename, memname); 491b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di); 492b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->next = debugInfo_list; 493b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debugInfo_list = di; 494b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 495b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 496eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 497eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 498eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 499f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Debuginfo reading for 'di' has just been successfully completed. 500f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Check that the invariants stated in 501f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj "Comment_on_IMPORTANT_CFSI_REPRESENTATIONAL_INVARIANTS" in 502f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj priv_storage.h are observed. */ 503f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic void check_CFSI_related_invariants ( DebugInfo* di ) 504f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 505f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo* di2 = NULL; 506f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di); 507f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* This fn isn't called until after debuginfo for this object has 508f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj been successfully read. And that shouldn't happen until we have 509f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj both a r-x and rw- mapping for the object. Hence: */ 510f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->have_rx_map); 511f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->have_rw_map); 512f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* degenerate case: r-x section is empty */ 513f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di->rx_map_size == 0) { 514f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi == NULL); 515f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return; 516f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 517f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* normal case: r-x section is nonempty */ 518f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* invariant (0) */ 519f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->rx_map_size > 0); 520f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* invariant (1) */ 521f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (di2 = debugInfo_list; di2; di2 = di2->next) { 522f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di2 == di) 523f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj continue; 524f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di2->rx_map_size == 0) 525f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj continue; 526f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->rx_map_avma + di->rx_map_size <= di2->rx_map_avma 527f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj || di2->rx_map_avma + di2->rx_map_size <= di->rx_map_avma); 528f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 529f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj di2 = NULL; 530f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* invariant (2) */ 531f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di->cfsi) { 532f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_minavma <= di->cfsi_maxavma); /* duh! */ 533f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_minavma >= di->rx_map_avma); 534f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_maxavma < di->rx_map_avma + di->rx_map_size); 535f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 536f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* invariants (3) and (4) */ 537f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di->cfsi) { 538f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word i; 539f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_used > 0); 540f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_size > 0); 541f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (i = 0; i < di->cfsi_used; i++) { 542f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DiCfSI* cfsi = &di->cfsi[i]; 543f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsi->len > 0); 544f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsi->base >= di->cfsi_minavma); 545f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsi->base + cfsi->len - 1 <= di->cfsi_maxavma); 546f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (i > 0) { 547f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DiCfSI* cfsip = &di->cfsi[i-1]; 548f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsip->base + cfsip->len <= cfsi->base); 549f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 550f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 551f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 552f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_used == 0); 553f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_size == 0); 554f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 555f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 556f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 557f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 558f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--------------------------------------------------------------*/ 559f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- ---*/ 560f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- TOP LEVEL: INITIALISE THE DEBUGINFO SYSTEM ---*/ 561f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- ---*/ 562f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--------------------------------------------------------------*/ 563f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 564f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjvoid VG_(di_initialise) ( void ) 565f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 566f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* There's actually very little to do here, since everything 567f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj centers around the DebugInfos in debugInfo_list, they are 568f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj created and destroyed on demand, and each one is treated more or 569f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj less independently. */ 570f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(debugInfo_list == NULL); 571f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 572f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* flush the CFI fast query cache. */ 573f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi_cache__invalidate(); 574f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 575f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 576f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 5774ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--------------------------------------------------------------*/ 5784ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- ---*/ 5794ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- TOP LEVEL: NOTIFICATION (ACQUIRE/DISCARD INFO) (LINUX) ---*/ 5804ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- ---*/ 5814ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--------------------------------------------------------------*/ 5824ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 583f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VGO_linux) || defined(VGO_darwin) 584eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 585eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* The debug info system is driven by notifications that a text 586eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj segment has been mapped in, or unmapped. When that happens it 587eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj tries to acquire/discard whatever info is available for the 588eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj corresponding object. This section contains the notification 589eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj handlers. */ 590eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 591eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Notify the debuginfo system about a new mapping. This is the way 592eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj new debug information gets loaded. If allow_SkFileV is True, it 593eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj will try load debug info if the mapping at 'a' belongs to Valgrind; 594eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj whereas normally (False) it will not do that. This allows us to 595eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj carefully control when the thing will read symbols from the 5969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Valgrind executable itself. 5979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 5989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj If a call to VG_(di_notify_mmap) causes debug info to be read, then 5999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj the returned ULong is an abstract handle which can later be used to 6009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj refer to the debuginfo read as a result of this specific mapping, 6019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj in later queries to m_debuginfo. In this case the handle value 6029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj will be one or above. If the returned value is zero, no debug info 6039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj was read. */ 604eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 6059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV ) 606eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 6074ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj NSegment const * seg; 608b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj HChar* filename; 609b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool ok, is_rx_map, is_rw_map; 610b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 6119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ULong di_handle; 612b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj SysRes fd; 613b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int nread; 614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj HChar buf1k[1024]; 615b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool debug = False; 616ec61b6509566cf36ab3968d69226cecf177cb0fesewardj SysRes statres; 617ec61b6509566cf36ab3968d69226cecf177cb0fesewardj struct vg_stat statbuf; 618b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 619b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* In short, figure out if this mapping is of interest to us, and 620b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if so, try to guess what ld.so is doing and when/if we should 621b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj read debug info. */ 622b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg = VG_(am_find_nsegment)(a); 623b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(seg); 624eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 625b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 626a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("di_notify_mmap-1: %#lx-%#lx %c%c%c\n", 627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->start, seg->end, 628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->hasR ? 'r' : '-', 629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->hasW ? 'w' : '-',seg->hasX ? 'x' : '-' ); 630eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* guaranteed by aspacemgr-linux.c, sane_NSegment() */ 632b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(seg->end > seg->start); 633b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 634b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ignore non-file mappings */ 635b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( ! (seg->kind == SkFileC 636b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || (seg->kind == SkFileV && allow_SkFileV)) ) 6379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 638b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 639b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* If the file doesn't have a name, we're hosed. Give up. */ 640b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj filename = VG_(am_get_filename)( (NSegment*)seg ); 641b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!filename) 6429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 643b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 644b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 645b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("di_notify_mmap-2: %s\n", filename); 646b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 647ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* Only try to read debug information from regular files. */ 64815728ab41ea41bf731dcc74ac68354550ced2189bart statres = VG_(stat)(filename, &statbuf); 649ec61b6509566cf36ab3968d69226cecf177cb0fesewardj 650ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* stat dereferences symlinks, so we don't expect it to succeed and 651ec61b6509566cf36ab3968d69226cecf177cb0fesewardj yet produce something that is a symlink. */ 6529c20ece00e07304f66da5f43b87ec45bc9c04550njn vg_assert(sr_isError(statres) || ! VKI_S_ISLNK(statbuf.mode)); 653ec61b6509566cf36ab3968d69226cecf177cb0fesewardj 654ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* Don't let the stat call fail silently. Filter out some known 655ec61b6509566cf36ab3968d69226cecf177cb0fesewardj sources of noise before complaining, though. */ 656cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(statres)) { 657ec61b6509566cf36ab3968d69226cecf177cb0fesewardj DebugInfo fake_di; 658ec61b6509566cf36ab3968d69226cecf177cb0fesewardj Bool quiet = VG_(strstr)(filename, "/var/run/nscd/") != NULL; 659e025eca1d49cdfe5a8cb58ab495763434280333asewardj if (!quiet && VG_(clo_verbosity) > 1) { 660ec61b6509566cf36ab3968d69226cecf177cb0fesewardj VG_(memset)(&fake_di, 0, sizeof(fake_di)); 661ec61b6509566cf36ab3968d69226cecf177cb0fesewardj fake_di.filename = filename; 662ec61b6509566cf36ab3968d69226cecf177cb0fesewardj ML_(symerr)(&fake_di, True, "failed to stat64/stat this file"); 663ec61b6509566cf36ab3968d69226cecf177cb0fesewardj } 6649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 6652ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj } 6662ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj 667ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* Finally, the point of all this stattery: if it's not a regular file, 668ec61b6509566cf36ab3968d69226cecf177cb0fesewardj don't try to read debug info from it. */ 6699c20ece00e07304f66da5f43b87ec45bc9c04550njn if (! VKI_S_ISREG(statbuf.mode)) 6709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 671ec61b6509566cf36ab3968d69226cecf177cb0fesewardj 672ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* no uses of statbuf below here. */ 67315728ab41ea41bf731dcc74ac68354550ced2189bart 674b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Now we have to guess if this is a text-like mapping, a data-like 675b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj mapping, neither or both. The rules are: 676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 677b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj text if: x86-linux r and x 678b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj other-linux r and x and not w 679b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 680b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data if: x86-linux r and w 681b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj other-linux r and w and not x 682b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Background: On x86-linux, objects are typically mapped twice: 684eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 685eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1b8fb000-1b8ff000 r-xp 00000000 08:02 4471477 vgpreload_memcheck.so 686eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1b8ff000-1b900000 rw-p 00004000 08:02 4471477 vgpreload_memcheck.so 687eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 688eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj whereas ppc32-linux mysteriously does this: 689eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 690eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118a6000-118ad000 r-xp 00000000 08:05 14209428 vgpreload_memcheck.so 691eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118ad000-118b6000 ---p 00007000 08:05 14209428 vgpreload_memcheck.so 692eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118b6000-118bd000 rwxp 00000000 08:05 14209428 vgpreload_memcheck.so 693eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 694eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj The third mapping should not be considered to have executable 695eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj code in. Therefore a test which works for both is: r and x and 696eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj NOT w. Reading symbols from the rwx segment -- which overlaps 697eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj the r-x segment in the file -- causes the redirection mechanism 698eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj to redirect to addresses in that third segment, which is wrong 699eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj and causes crashes. 700eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 701eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj JRS 28 Dec 05: unfortunately icc 8.1 on x86 has been seen to 702eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj produce executables with a single rwx segment rather than a 703eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj (r-x,rw-) pair. That means the rules have to be modified thusly: 704eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 705eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj x86-linux: consider if r and x 706b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj all others: consider if r and x and not w 707eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj */ 708b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = False; 709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = False; 710f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# if defined(VGA_x86) 711b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = seg->hasR && seg->hasX; 712b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = seg->hasR && seg->hasW; 713f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# elif defined(VGA_amd64) || defined(VGA_ppc32) || defined(VGA_ppc64) 714b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = seg->hasR && seg->hasX && !seg->hasW; 715b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = seg->hasR && seg->hasW && !seg->hasX; 716eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# else 717b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# error "Unknown platform" 718eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# endif 719eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("di_notify_mmap-3: is_rx_map %d, is_rw_map %d\n", 722b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (Int)is_rx_map, (Int)is_rw_map); 723eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* If it is neither text-ish nor data-ish, we're not interested. */ 725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!(is_rx_map || is_rw_map)) 7269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 727eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 7285a5eec0923d55afc94165721d25125d5fc8f24d8sewardj /* Peer at the first few bytes of the file, to see if it is an ELF */ 7295a5eec0923d55afc94165721d25125d5fc8f24d8sewardj /* object file. Ignore the file if we do not have read permission. */ 7305a5eec0923d55afc94165721d25125d5fc8f24d8sewardj VG_(memset)(buf1k, 0, sizeof(buf1k)); 7315a5eec0923d55afc94165721d25125d5fc8f24d8sewardj fd = VG_(open)( filename, VKI_O_RDONLY, 0 ); 732cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(fd)) { 733cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_Err(fd) != VKI_EACCES) { 7345a5eec0923d55afc94165721d25125d5fc8f24d8sewardj DebugInfo fake_di; 7355a5eec0923d55afc94165721d25125d5fc8f24d8sewardj VG_(memset)(&fake_di, 0, sizeof(fake_di)); 7365a5eec0923d55afc94165721d25125d5fc8f24d8sewardj fake_di.filename = filename; 7375a5eec0923d55afc94165721d25125d5fc8f24d8sewardj ML_(symerr)(&fake_di, True, "can't open file to inspect ELF header"); 7385a5eec0923d55afc94165721d25125d5fc8f24d8sewardj } 7395a5eec0923d55afc94165721d25125d5fc8f24d8sewardj return 0; 7405a5eec0923d55afc94165721d25125d5fc8f24d8sewardj } 741cda2f0fbda4c4b2644babc830244be8aed95de1dnjn nread = VG_(read)( sr_Res(fd), buf1k, sizeof(buf1k) ); 742cda2f0fbda4c4b2644babc830244be8aed95de1dnjn VG_(close)( sr_Res(fd) ); 7435a5eec0923d55afc94165721d25125d5fc8f24d8sewardj 7445a5eec0923d55afc94165721d25125d5fc8f24d8sewardj if (nread == 0) 7455a5eec0923d55afc94165721d25125d5fc8f24d8sewardj return 0; 7465a5eec0923d55afc94165721d25125d5fc8f24d8sewardj if (nread < 0) { 7475a5eec0923d55afc94165721d25125d5fc8f24d8sewardj DebugInfo fake_di; 7485a5eec0923d55afc94165721d25125d5fc8f24d8sewardj VG_(memset)(&fake_di, 0, sizeof(fake_di)); 7495a5eec0923d55afc94165721d25125d5fc8f24d8sewardj fake_di.filename = filename; 7505a5eec0923d55afc94165721d25125d5fc8f24d8sewardj ML_(symerr)(&fake_di, True, "can't read file to inspect ELF header"); 7515a5eec0923d55afc94165721d25125d5fc8f24d8sewardj return 0; 7525a5eec0923d55afc94165721d25125d5fc8f24d8sewardj } 7535a5eec0923d55afc94165721d25125d5fc8f24d8sewardj vg_assert(nread > 0 && nread <= sizeof(buf1k) ); 7545a5eec0923d55afc94165721d25125d5fc8f24d8sewardj 7555a5eec0923d55afc94165721d25125d5fc8f24d8sewardj /* We're only interested in mappings of ELF object files. */ 756f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(HAVE_ELF) 7575a5eec0923d55afc94165721d25125d5fc8f24d8sewardj if (!ML_(is_elf_object_file)( buf1k, (SizeT)nread )) 7585a5eec0923d55afc94165721d25125d5fc8f24d8sewardj return 0; 759f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(HAVE_MACHO) 760f76d27a697a7b0bf3b84490baf60623fc96a23afnjn if (!ML_(is_macho_object_file)( buf1k, (SizeT)nread )) 761f76d27a697a7b0bf3b84490baf60623fc96a23afnjn return 0; 762f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#else 763f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# error "unknown executable type" 764f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 7655a5eec0923d55afc94165721d25125d5fc8f24d8sewardj 766b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* See if we have a DebugInfo for this filename. If not, 767b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj create one. */ 768b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di = find_or_create_DebugInfo_for( filename, NULL/*membername*/ ); 769b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di); 770b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 771b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (is_rx_map) { 772b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We have a text-like mapping. Note the details. */ 773b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->have_rx_map) { 774b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->have_rx_map = True; 775b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rx_map_avma = a; 776b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rx_map_size = seg->end + 1 - seg->start; 777b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rx_map_foff = seg->offset; 778b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 779b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* FIXME: complain about a second text-like mapping */ 780b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 781b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 782eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 783b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (is_rw_map) { 784b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We have a data-like mapping. Note the details. */ 785b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->have_rw_map) { 786b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->have_rw_map = True; 787b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rw_map_avma = a; 788b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rw_map_size = seg->end + 1 - seg->start; 789b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rw_map_foff = seg->offset; 790b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 791b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* FIXME: complain about a second data-like mapping */ 792b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 793eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 794eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 7959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* If we don't have an rx and rw mapping, or if we already have 7969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj debuginfo for this mapping for whatever reason, go no 7979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj further. */ 7989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if ( ! (di->have_rx_map && di->have_rw_map && !di->have_dinfo) ) 7999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 800b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 8019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok, so, finally, let's try to read the debuginfo. */ 8029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(di->filename); 8039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("\n"); 8049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("------ start ELF OBJECT " 8059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj "------------------------------\n"); 8069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("------ name = %s\n", di->filename); 8079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("\n"); 8089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 8099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* We're going to read symbols and debug info for the avma 8109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ranges [rx_map_avma, +rx_map_size) and [rw_map_avma, 8119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj +rw_map_size). First get rid of any other DebugInfos which 8129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj overlap either of those ranges (to avoid total confusion). */ 8139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj discard_DebugInfos_which_overlap_with( di ); 8149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 8159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* .. and acquire new info. */ 816f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(HAVE_ELF) 8179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ok = ML_(read_elf_debug_info)( di ); 818f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(HAVE_MACHO) 819f76d27a697a7b0bf3b84490baf60623fc96a23afnjn ok = ML_(read_macho_debug_info)( di ); 820f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#else 821f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# error "unknown executable type" 822f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 8239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 8249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (ok) { 8259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 8269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("\n------ Canonicalising the " 8279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj "acquired info ------\n"); 828f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* invalidate the CFI unwind cache. */ 829f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi_cache__invalidate(); 8309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* prepare read data for use */ 8319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(canonicaliseTables)( di ); 8329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* notify m_redir about it */ 8339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("\n------ Notifying m_redir ------\n"); 8349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(redir_notify_new_DebugInfo)( di ); 8359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Note that we succeeded */ 8369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->have_dinfo = True; 8379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(di->handle > 0); 8389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di_handle = di->handle; 839f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Check invariants listed in 840f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Comment_on_IMPORTANT_REPRESENTATIONAL_INVARIANTS in 841f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj priv_storage.h. */ 842f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj check_CFSI_related_invariants(di); 843b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 8449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } else { 8459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("\n------ ELF reading failed ------\n"); 8469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Something went wrong (eg. bad ELF file). Should we delete 8479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj this DebugInfo? No - it contains info on the rw/rx 8489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj mappings, at least. */ 8499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di_handle = 0; 850f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->have_dinfo == False); 8519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 852eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 8539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("\n"); 8549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("------ name = %s\n", di->filename); 8559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("------ end ELF OBJECT " 8569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj "------------------------------\n"); 8579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TRACE_SYMTAB("\n"); 858eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 8599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return di_handle; 860eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 861eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 862eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 863eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Unmap is simpler - throw away any SegInfos intersecting 864eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj [a, a+len). */ 865eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjvoid VG_(di_notify_munmap)( Addr a, SizeT len ) 866eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 867f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool anyFound; 868a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart if (0) VG_(printf)("DISCARD %#lx %#lx\n", a, a+len); 869f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj anyFound = discard_syms_in_range(a, len); 870f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (anyFound) 871f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi_cache__invalidate(); 872eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 873eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 874eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 875eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Uh, this doesn't do anything at all. IIRC glibc (or ld.so, I don't 876eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj remember) does a bunch of mprotects on itself, and if we follow 877eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj through here, it causes the debug info for that object to get 878eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj discarded. */ 879eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjvoid VG_(di_notify_mprotect)( Addr a, SizeT len, UInt prot ) 880eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 881eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool exe_ok = toBool(prot & VKI_PROT_EXEC); 882f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# if defined(VGA_x86) 883eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj exe_ok = exe_ok || toBool(prot & VKI_PROT_READ); 884eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# endif 885f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && !exe_ok) { 886f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool anyFound = discard_syms_in_range(a, len); 887f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (anyFound) 888f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi_cache__invalidate(); 889f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 890eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 891eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 892c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--------- PDB (windows debug info) reading --------- */ 893c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 894c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/* this should really return ULong, as per VG_(di_notify_mmap). */ 895c8259b85b701d25d72aabe9dc0a8154517f96913sewardjvoid VG_(di_notify_pdb_debuginfo)( Int fd_obj, Addr avma_obj, 896c8259b85b701d25d72aabe9dc0a8154517f96913sewardj SizeT total_size, 897c8259b85b701d25d72aabe9dc0a8154517f96913sewardj PtrdiffT unknown_purpose__reloc ) 898c8259b85b701d25d72aabe9dc0a8154517f96913sewardj{ 899c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Int r, sz_exename; 900c8259b85b701d25d72aabe9dc0a8154517f96913sewardj ULong obj_mtime, pdb_mtime; 901c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Char exename[VKI_PATH_MAX]; 902c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Char* pdbname = NULL; 903c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Char* dot; 904c8259b85b701d25d72aabe9dc0a8154517f96913sewardj SysRes sres; 905c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Int fd_pdbimage; 906c8259b85b701d25d72aabe9dc0a8154517f96913sewardj SizeT n_pdbimage; 907c8259b85b701d25d72aabe9dc0a8154517f96913sewardj struct vg_stat stat_buf; 908c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 909c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) { 910c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(message)(Vg_UserMsg, ""); 911c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(message)(Vg_UserMsg, 912c8259b85b701d25d72aabe9dc0a8154517f96913sewardj "LOAD_PDB_DEBUGINFO(fd=%d, avma=%#lx, total_size=%lu, " 913c8259b85b701d25d72aabe9dc0a8154517f96913sewardj "uu_reloc=%#lx)", 914c8259b85b701d25d72aabe9dc0a8154517f96913sewardj fd_obj, avma_obj, total_size, unknown_purpose__reloc 915c8259b85b701d25d72aabe9dc0a8154517f96913sewardj ); 916c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 917c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 918c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* 'fd' refers to the .exe/.dll we're dealing with. Get its modification 919c8259b85b701d25d72aabe9dc0a8154517f96913sewardj time into obj_mtime. */ 920c8259b85b701d25d72aabe9dc0a8154517f96913sewardj r = VG_(fstat)(fd_obj, &stat_buf); 921c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (r == -1) 922c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; /* stat failed ?! */ 923c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(r == 0); 9249c20ece00e07304f66da5f43b87ec45bc9c04550njn obj_mtime = stat_buf.mtime; 925c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 926c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* and get its name into exename[]. */ 927c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(VKI_PATH_MAX > 100); /* to ensure /proc/self/fd/%d is safe */ 928c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(memset)(exename, 0, sizeof(exename)); 929c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(sprintf)(exename, "/proc/self/fd/%d", fd_obj); 930c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* convert exename from a symlink to real name .. overwrites the 931c8259b85b701d25d72aabe9dc0a8154517f96913sewardj old contents of the buffer. Ick. */ 932c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sz_exename = VG_(readlink)(exename, exename, sizeof(exename)-2 ); 933c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (sz_exename == -1) 934c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; /* readlink failed ?! */ 935c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(sz_exename >= 0 && sz_exename < sizeof(exename)); 936c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(exename[sizeof(exename)-1] == 0); 937c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 938c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) { 939c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: objname: %s", exename); 940c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 941c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 942c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Try to find a matching PDB file from which to read debuginfo. 943c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Windows PE files have symbol tables and line number information, 944c8259b85b701d25d72aabe9dc0a8154517f96913sewardj but MSVC doesn't seem to use them. */ 945c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Why +5 ? Because in the worst case, we could find a dot as the 946c8259b85b701d25d72aabe9dc0a8154517f96913sewardj last character of pdbname, and we'd then put "pdb" right after 947c8259b85b701d25d72aabe9dc0a8154517f96913sewardj it, hence extending it a bit. */ 948c8259b85b701d25d72aabe9dc0a8154517f96913sewardj pdbname = ML_(dinfo_zalloc)("di.debuginfo.lpd1", sz_exename+5); 949c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(strcpy)(pdbname, exename); 950c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(pdbname[sz_exename+5-1] == 0); 951c8259b85b701d25d72aabe9dc0a8154517f96913sewardj dot = VG_(strrchr)(pdbname, '.'); 952c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (!dot) 953c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; /* there's no dot in the exe's name ?! */ 954c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (dot[1] == 0) 955c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; /* hmm, path ends in "." */ 956c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 957c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if ('A' <= dot[1] && dot[1] <= 'Z') 958c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(strcpy)(dot, ".PDB"); 959c8259b85b701d25d72aabe9dc0a8154517f96913sewardj else 960c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(strcpy)(dot, ".pdb"); 961c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 962c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(pdbname[sz_exename+5-1] == 0); 963c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 964c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* See if we can find it, and check it's in-dateness. */ 965c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sres = VG_(stat)(pdbname, &stat_buf); 966cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) { 967c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(message)(Vg_UserMsg, "Warning: Missing or un-stat-able %s", 968c8259b85b701d25d72aabe9dc0a8154517f96913sewardj pdbname); 969c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) 970c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: missing: %s", pdbname); 971c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; 972c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 9739c20ece00e07304f66da5f43b87ec45bc9c04550njn pdb_mtime = stat_buf.mtime; 974c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (pdb_mtime < obj_mtime ) { 975c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* PDB file is older than PE file - ignore it or we will either 976c8259b85b701d25d72aabe9dc0a8154517f96913sewardj (a) print wrong stack traces or more likely (b) crash. */ 977c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(message)(Vg_UserMsg, "Warning: Ignoring %s since it is older than %s", 978c8259b85b701d25d72aabe9dc0a8154517f96913sewardj pdbname, exename); 979c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; 980c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 981c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 982c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sres = VG_(open)(pdbname, VKI_O_RDONLY, 0); 983cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) { 984c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(message)(Vg_UserMsg, "Warning: Can't open %s", pdbname); 985c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; 986c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 987c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 988c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Looks promising; go on to try and read stuff from it. */ 989cda2f0fbda4c4b2644babc830244be8aed95de1dnjn fd_pdbimage = sr_Res(sres); 9909c20ece00e07304f66da5f43b87ec45bc9c04550njn n_pdbimage = stat_buf.size; 991c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sres = VG_(am_mmap_file_float_valgrind)( n_pdbimage, VKI_PROT_READ, 992c8259b85b701d25d72aabe9dc0a8154517f96913sewardj fd_pdbimage, 0 ); 993cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) { 994c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(close)(fd_pdbimage); 995c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; 996c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 997c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 998c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) 999c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: pdbname: %s", pdbname); 1000c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1001c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* play safe; always invalidate the CFI cache. I don't know if 1002c8259b85b701d25d72aabe9dc0a8154517f96913sewardj this is necessary, but anyway .. */ 1003c8259b85b701d25d72aabe9dc0a8154517f96913sewardj cfsi_cache__invalidate(); 1004c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* dump old info for this range, if any */ 1005c8259b85b701d25d72aabe9dc0a8154517f96913sewardj discard_syms_in_range( avma_obj, total_size ); 1006c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1007cda2f0fbda4c4b2644babc830244be8aed95de1dnjn { void* pdbimage = (void*)sr_Res(sres); 1008c8259b85b701d25d72aabe9dc0a8154517f96913sewardj DebugInfo* di = find_or_create_DebugInfo_for(exename, NULL/*membername*/ ); 1009c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1010c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* this di must be new, since we just nuked any old stuff in the range */ 1011c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(di && !di->have_rx_map && !di->have_rw_map); 1012c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(!di->have_dinfo); 1013c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1014c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* don't set up any of the di-> fields; let 1015c8259b85b701d25d72aabe9dc0a8154517f96913sewardj ML_(read_pdb_debug_info) do it. */ 1016c8259b85b701d25d72aabe9dc0a8154517f96913sewardj ML_(read_pdb_debug_info)( di, avma_obj, unknown_purpose__reloc, 1017c8259b85b701d25d72aabe9dc0a8154517f96913sewardj pdbimage, n_pdbimage, pdbname, pdb_mtime ); 1018c8259b85b701d25d72aabe9dc0a8154517f96913sewardj // JRS fixme: take notice of return value from read_pdb_debug_info, 1019c8259b85b701d25d72aabe9dc0a8154517f96913sewardj // and handle failure 1020c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(di->have_dinfo); // fails if PDB read failed 1021c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage ); 1022c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(close)(fd_pdbimage); 1023c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1024c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1025c8259b85b701d25d72aabe9dc0a8154517f96913sewardj out: 1026c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (pdbname) ML_(dinfo_free)(pdbname); 1027c8259b85b701d25d72aabe9dc0a8154517f96913sewardj} 1028c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 10294ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#endif /* defined(VGO_linux) */ 10304ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 10314ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 10324ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*-------------------------------------------------------------*/ 10334ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- ---*/ 10344ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- TOP LEVEL: NOTIFICATION (ACQUIRE/DISCARD INFO) (AIX5) ---*/ 10354ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- ---*/ 10364ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*-------------------------------------------------------------*/ 10374ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 10384ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#if defined(VGO_aix5) 10394ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 10404ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/* The supplied parameters describe a code segment and its associated 10414ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj data segment, that have recently been mapped in -- so we need to 10424ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj read debug info for it -- or conversely, have recently been dumped, 10434ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj in which case the relevant debug info has to be unloaded. */ 10444ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 10459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjULong VG_(di_aix5_notify_segchange)( 10464ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Addr code_start, 10474ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Word code_len, 10484ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Addr data_start, 10494ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Word data_len, 10504ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj UChar* file_name, 10514ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj UChar* mem_name, 10524ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool is_mainexe, 10534ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool acquire ) 10544ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj{ 10559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ULong hdl = 0; 10569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 1057f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* play safe; always invalidate the CFI cache. Not 1058f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj that it should be used on AIX, but still .. */ 1059f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi_cache__invalidate(); 1060f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 10614ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (acquire) { 10624ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 1063b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool ok; 1064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1065b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di = find_or_create_DebugInfo_for( file_name, mem_name ); 1066b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di); 1067b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1068b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (code_len > 0) { 1069b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_present = True; 1070b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_svma = 0; /* don't know yet */ 1071b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_bias = 0; /* don't know yet */ 1072b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_avma = code_start; 1073b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_size = code_len; 1074b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1075b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (data_len > 0) { 1076b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_present = True; 1077b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_svma = 0; /* don't know yet */ 1078b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_bias = 0; /* don't know yet */ 1079b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_avma = data_start; 1080b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_size = data_len; 1081b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 1082b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1083b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* These need to be filled in in order to keep various 1084b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj assertions in storage.c happy. In particular see 1085b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Comment_Regarding_Text_Range_Checks" in that file. */ 1086b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->have_rx_map = True; 1087b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rx_map_avma = code_start; 1088b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rx_map_size = code_len; 1089b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->have_rw_map = True; 1090b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rw_map_avma = data_start; 1091b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->rw_map_size = data_len; 1092b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1093b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ok = ML_(read_xcoff_debug_info) ( di, is_mainexe ); 1094b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1095b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (ok) { 1096b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* prepare read data for use */ 1097b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(canonicaliseTables)( di ); 1098b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* notify m_redir about it */ 1099b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(redir_notify_new_DebugInfo)( di ); 1100b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Note that we succeeded */ 1101b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->have_dinfo = True; 11029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj hdl = di->handle; 11039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(hdl > 0); 1104f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Check invariants listed in 1105f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Comment_on_IMPORTANT_REPRESENTATIONAL_INVARIANTS in 1106f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj priv_storage.h. */ 1107f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj check_CFSI_related_invariants(di); 1108b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 1109b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Something went wrong (eg. bad XCOFF file). */ 1110b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_DebugInfo( di ); 1111b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di = NULL; 1112b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 11134ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 11144ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } else { 11154ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 1116b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Dump all the debugInfos whose text segments intersect 1117f7cdfe298805a91a35b8e0495d9034cbf21003f5sewardj code_start/code_len. */ 1118f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* CFI cache is always invalidated at start of this routine. 1119f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Hence it's safe to ignore the return value of 1120f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj discard_syms_in_range. */ 1121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (code_len > 0) 1122f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj (void)discard_syms_in_range( code_start, code_len ); 11234ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 11244ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 11259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 11269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return hdl; 11274ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj} 11284ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 11294ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 11304ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#endif /* defined(VGO_aix5) */ 11314ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 1132eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1133eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1134eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- ---*/ 1135eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- TOP LEVEL: QUERYING EXISTING DEBUG INFO ---*/ 1136eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- ---*/ 1137eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1138eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 11399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid VG_(di_discard_ALL_debuginfo)( void ) 11409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 11419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo *di, *di2; 11429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di = debugInfo_list; 11439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj while (di) { 11449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di2 = di->next; 11459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("XXX rm %p\n", di); 11469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj free_DebugInfo( di ); 11479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di = di2; 11489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 11499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 11509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 11519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 1152eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1153eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Use of symbol table & location info to create ---*/ 1154eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- plausible-looking stack dumps. ---*/ 1155eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1156eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1157eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Search all symtabs that we know about to locate ptr. If found, set 1158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi to the relevant DebugInfo, and *symno to the symtab entry 1159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *number within that. If not found, *psi is set to NULL. 1160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj If findText==True, only text symbols are searched for. 1161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj If findText==False, only data symbols are searched for. 1162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/ 1163b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void search_all_symtabs ( Addr ptr, /*OUT*/DebugInfo** pdi, 1164f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*OUT*/Word* symno, 1165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool match_anywhere_in_sym, 1166b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool findText ) 1167eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1168f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1169b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1170b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool inRange; 1171b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1172b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1173b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1174b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (findText) { 1175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj inRange = di->text_present 1176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_size > 0 1177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= ptr 1178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->text_avma + di->text_size; 1179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 1180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj inRange = (di->data_present 1181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_size > 0 1182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_avma <= ptr 1183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->data_avma + di->data_size) 1184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || 1185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (di->sdata_present 1186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_size > 0 1187b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_avma <= ptr 1188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->sdata_avma + di->sdata_size) 1189b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || 1190b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (di->bss_present 1191b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_size > 0 1192b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_avma <= ptr 11935706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && ptr < di->bss_avma + di->bss_size) 11945706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj || 11955706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj (di->sbss_present 11965706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->sbss_size > 0 11975706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->sbss_avma <= ptr 11985706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && ptr < di->sbss_avma + di->sbss_size) 11995706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj || 12005706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj (di->rodata_present 12015706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->rodata_size > 0 12025706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->rodata_avma <= ptr 12035706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && ptr < di->rodata_avma + di->rodata_size); 1204eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!inRange) continue; 1207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sno = ML_(search_one_symtab) ( 1209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di, ptr, match_anywhere_in_sym, findText ); 1210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (sno == -1) goto not_found; 1211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *symno = sno; 1212b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = di; 1213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; 1214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1215eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1216eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj not_found: 1217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = NULL; 1218eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1219eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1220eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1221eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Search all loctabs that we know about to locate ptr. If found, set 1222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi to the relevant DebugInfo, and *locno to the loctab entry 1223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *number within that. If not found, *pdi is set to NULL. */ 1224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void search_all_loctabs ( Addr ptr, /*OUT*/DebugInfo** pdi, 1225f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*OUT*/Word* locno ) 1226eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1227f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word lno; 1228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1229b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1230b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 12315706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->text_size > 0 1232b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= ptr 1233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->text_avma + di->text_size) { 1234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj lno = ML_(search_one_loctab) ( di, ptr ); 1235eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (lno == -1) goto not_found; 1236eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *locno = lno; 1237b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = di; 1238eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return; 1239eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1240eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1241eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj not_found: 1242b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = NULL; 1243eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1244eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1245eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1246eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* The whole point of this whole big deal: map a code address to a 1247eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj plausible symbol name. Returns False if no idea; otherwise True. 12486b7611bf42a0fbb62e047d8c43b008205bd21e75njn Caller supplies buf and nbuf. If do_cxx_demangling is False, don't do 12496b7611bf42a0fbb62e047d8c43b008205bd21e75njn C++ demangling, regardless of VG_(clo_demangle) -- probably because the 12506b7611bf42a0fbb62e047d8c43b008205bd21e75njn call has come from VG_(get_fnname_raw)(). findText 1251b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj indicates whether we're looking for a text symbol or a data symbol 1252b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj -- caller must choose one kind or the other. */ 1253eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjstatic 12546b7611bf42a0fbb62e047d8c43b008205bd21e75njnBool get_sym_name ( Bool do_cxx_demangling, Bool do_z_demangling, 12556b7611bf42a0fbb62e047d8c43b008205bd21e75njn Bool do_below_main_renaming, 12566b7611bf42a0fbb62e047d8c43b008205bd21e75njn Addr a, Char* buf, Int nbuf, 1257b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool match_anywhere_in_sym, Bool show_offset, 1258c4431bfe04c7490ea2d74939d222d87f13f30960njn Bool findText, /*OUT*/PtrdiffT* offsetP ) 1259eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1260b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1261f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1262c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT offset; 1263eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj search_all_symtabs ( a, &di, &sno, match_anywhere_in_sym, findText ); 1265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == NULL) 1266eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 12676882443ef154bca367bc591287de641e43a9e108njn 12686b7611bf42a0fbb62e047d8c43b008205bd21e75njn VG_(demangle) ( do_cxx_demangling, do_z_demangling, 12696b7611bf42a0fbb62e047d8c43b008205bd21e75njn di->symtab[sno].name, buf, nbuf ); 12706b7611bf42a0fbb62e047d8c43b008205bd21e75njn 12716b7611bf42a0fbb62e047d8c43b008205bd21e75njn /* Do the below-main hack */ 12726b7611bf42a0fbb62e047d8c43b008205bd21e75njn // To reduce the endless nuisance of multiple different names 12736b7611bf42a0fbb62e047d8c43b008205bd21e75njn // for "the frame below main()" screwing up the testsuite, change all 12746b7611bf42a0fbb62e047d8c43b008205bd21e75njn // known incarnations of said into a single name, "(below main)", if 12756b7611bf42a0fbb62e047d8c43b008205bd21e75njn // --show-below-main=yes. 12766b7611bf42a0fbb62e047d8c43b008205bd21e75njn if ( do_below_main_renaming && ! VG_(clo_show_below_main) && 12776b7611bf42a0fbb62e047d8c43b008205bd21e75njn Vg_FnNameBelowMain == VG_(get_fnname_kind)(buf) ) 12786b7611bf42a0fbb62e047d8c43b008205bd21e75njn { 12796b7611bf42a0fbb62e047d8c43b008205bd21e75njn VG_(strncpy_safely)(buf, "(below main)", nbuf); 1280eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset = a - di->symtab[sno].addr; 1282c4431bfe04c7490ea2d74939d222d87f13f30960njn if (offsetP) *offsetP = offset; 1283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1284eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (show_offset && offset != 0) { 1285eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char buf2[12]; 1286eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char* symend = buf + VG_(strlen)(buf); 1287eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char* end = buf + nbuf; 1288eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Int len; 1289eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1290c4431bfe04c7490ea2d74939d222d87f13f30960njn len = VG_(sprintf)(buf2, "%c%ld", 1291eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj offset < 0 ? '-' : '+', 1292eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj offset < 0 ? -offset : offset); 1293eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(len < (Int)sizeof(buf2)); 1294eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1295eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (len < (end - symend)) { 1296eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char *cp = buf2; 1297eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(memcpy)(symend, cp, len+1); 1298eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1299eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1300eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 13016b7611bf42a0fbb62e047d8c43b008205bd21e75njn buf[nbuf-1] = 0; /* paranoia */ 13026b7611bf42a0fbb62e047d8c43b008205bd21e75njn 1303eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1304eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1305eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1306eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* ppc64-linux only: find the TOC pointer (R2 value) that should be in 1307eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj force at the entry point address of the function containing 1308eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj guest_code_addr. Returns 0 if not known. */ 1309eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjAddr VG_(get_tocptr) ( Addr guest_code_addr ) 1310eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1311b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1312f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1313eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_symtabs ( guest_code_addr, 1314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj &si, &sno, 1315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj True/*match_anywhere_in_fun*/, 1316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj True/*consider text symbols only*/ ); 1317eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 1318eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return 0; 1319eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj else 1320eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return si->symtab[sno].tocptr; 1321eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1322eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1323eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 1324eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj match anywhere in function, but don't show offsets. */ 1325eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_fnname) ( Addr a, Char* buf, Int nbuf ) 1326eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 13276b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, 13286b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 13296b7611bf42a0fbb62e047d8c43b008205bd21e75njn a, buf, nbuf, 1330b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1334eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1335eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1336eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 1337eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj match anywhere in function, and show offset if nonzero. */ 1338eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_fnname_w_offset) ( Addr a, Char* buf, Int nbuf ) 1339eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 13406b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, 13416b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 13426b7611bf42a0fbb62e047d8c43b008205bd21e75njn a, buf, nbuf, 1343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/True, 1345b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1347eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1348eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1349eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 1350eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj only succeed if 'a' matches first instruction of function, 1351eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj and don't show offsets. */ 1352eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_fnname_if_entry) ( Addr a, Char* buf, Int nbuf ) 1353eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 13546b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, 13556b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 13566b7611bf42a0fbb62e047d8c43b008205bd21e75njn a, buf, nbuf, 1357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/False, 1358b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1359b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1360b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1361eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1362eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 13636b7611bf42a0fbb62e047d8c43b008205bd21e75njn/* This is only available to core... don't C++-demangle, don't Z-demangle, 13646b7611bf42a0fbb62e047d8c43b008205bd21e75njn don't rename below-main, match anywhere in function, and don't show 13656b7611bf42a0fbb62e047d8c43b008205bd21e75njn offsets. */ 13666b7611bf42a0fbb62e047d8c43b008205bd21e75njnBool VG_(get_fnname_raw) ( Addr a, Char* buf, Int nbuf ) 1367eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 13686b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, 13696b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/False, 13706b7611bf42a0fbb62e047d8c43b008205bd21e75njn a, buf, nbuf, 1371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1375eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1376eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1377eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is only available to core... don't demangle C++ names, but do 13786b7611bf42a0fbb62e047d8c43b008205bd21e75njn do Z-demangling and below-main-renaming, match anywhere in function, and 13796b7611bf42a0fbb62e047d8c43b008205bd21e75njn don't show offsets. */ 13806b7611bf42a0fbb62e047d8c43b008205bd21e75njnBool VG_(get_fnname_no_cxx_demangle) ( Addr a, Char* buf, Int nbuf ) 1381eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 13826b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/True, 13836b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 13846b7611bf42a0fbb62e047d8c43b008205bd21e75njn a, buf, nbuf, 13856b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*match_anywhere_in_fun*/True, 13866b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*show offset?*/False, 13876b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*text syms only*/True, 13886b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*offsetP*/NULL ); 1389eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1390eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 13916882443ef154bca367bc591287de641e43a9e108njnVg_FnNameKind VG_(get_fnname_kind) ( Char* name ) 13926882443ef154bca367bc591287de641e43a9e108njn{ 13936882443ef154bca367bc591287de641e43a9e108njn if (VG_STREQ("main", name)) { 13946882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameMain; 13956882443ef154bca367bc591287de641e43a9e108njn 13966882443ef154bca367bc591287de641e43a9e108njn } else if ( 13976882443ef154bca367bc591287de641e43a9e108njn#if defined(VGO_linux) 13986882443ef154bca367bc591287de641e43a9e108njn VG_STREQ("__libc_start_main", name) || // glibc glibness 13996882443ef154bca367bc591287de641e43a9e108njn VG_STREQ("generic_start_main", name) || // Yellow Dog doggedness 14006882443ef154bca367bc591287de641e43a9e108njn#elif defined(VGO_aix5) 14016882443ef154bca367bc591287de641e43a9e108njn VG_STREQ("__start", name) || // AIX aches 1402f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(VGO_darwin) 1403f76d27a697a7b0bf3b84490baf60623fc96a23afnjn // See readmacho.c for an explanation of this. 1404f76d27a697a7b0bf3b84490baf60623fc96a23afnjn VG_STREQ("start_according_to_valgrind", name) || // Darwin, darling 14056882443ef154bca367bc591287de641e43a9e108njn#else 14066882443ef154bca367bc591287de641e43a9e108njn# error Unknown OS 14076882443ef154bca367bc591287de641e43a9e108njn#endif 14086882443ef154bca367bc591287de641e43a9e108njn 0) { 14096882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameBelowMain; 14106882443ef154bca367bc591287de641e43a9e108njn 14116882443ef154bca367bc591287de641e43a9e108njn } else { 14126882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameNormal; 14136882443ef154bca367bc591287de641e43a9e108njn } 14146882443ef154bca367bc591287de641e43a9e108njn} 14156882443ef154bca367bc591287de641e43a9e108njn 14166882443ef154bca367bc591287de641e43a9e108njnVg_FnNameKind VG_(get_fnname_kind_from_IP) ( Addr ip ) 14176882443ef154bca367bc591287de641e43a9e108njn{ 14186882443ef154bca367bc591287de641e43a9e108njn // We don't need a big buffer; all the special names are small. 14196882443ef154bca367bc591287de641e43a9e108njn #define BUFLEN 50 14206882443ef154bca367bc591287de641e43a9e108njn Char buf[50]; 14216882443ef154bca367bc591287de641e43a9e108njn 14226882443ef154bca367bc591287de641e43a9e108njn // We don't demangle, because it's faster not to, and the special names 14236882443ef154bca367bc591287de641e43a9e108njn // we're looking for won't be demangled. 14246b7611bf42a0fbb62e047d8c43b008205bd21e75njn if (VG_(get_fnname_raw) ( ip, buf, BUFLEN )) { 14256882443ef154bca367bc591287de641e43a9e108njn buf[BUFLEN-1] = '\0'; // paranoia 14266882443ef154bca367bc591287de641e43a9e108njn return VG_(get_fnname_kind)(buf); 14276882443ef154bca367bc591287de641e43a9e108njn } else { 14286882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameNormal; // Don't know the name, treat it as normal. 14296882443ef154bca367bc591287de641e43a9e108njn } 14306882443ef154bca367bc591287de641e43a9e108njn} 14316882443ef154bca367bc591287de641e43a9e108njn 1432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Looks up data_addr in the collection of data symbols, and if found 1433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj puts its name (or as much as will fit) into dname[0 .. n_dname-1], 1434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which is guaranteed to be zero terminated. Also data_addr's offset 1435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj from the symbol start is put into *offset. */ 1436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool VG_(get_datasym_and_offset)( Addr data_addr, 1437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/Char* dname, Int n_dname, 1438c4431bfe04c7490ea2d74939d222d87f13f30960njn /*OUT*/PtrdiffT* offset ) 1439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 1440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool ok; 1441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_dname > 1); 14426b7611bf42a0fbb62e047d8c43b008205bd21e75njn ok = get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, 14436b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/False, 14446b7611bf42a0fbb62e047d8c43b008205bd21e75njn data_addr, dname, n_dname, 1445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_sym*/True, 1446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*data syms only please*/False, 1448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset ); 1449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!ok) 1450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 1451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname[n_dname-1] = 0; 1452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 1453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 1454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Map a code address to the name of a shared object file or the 1456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj executable. Returns False if no idea; otherwise True. Doesn't 1457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj require debug info. Caller supplies buf and nbuf. */ 1458eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_objname) ( Addr a, Char* buf, Int nbuf ) 1459eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 14604ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Int used; 1461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1462f32ec7f0de8a651bc16a1b2e448c0106d8669889tom const NSegment *seg; 1463f32ec7f0de8a651bc16a1b2e448c0106d8669889tom HChar* filename; 14644ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj vg_assert(nbuf > 0); 14657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Look in the debugInfo_list to find the name. In most cases we 14667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj expect this to produce a result. */ 1467b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1468b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 14695706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->text_size > 0 1470b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= a 1471b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a < di->text_avma + di->text_size) { 1472b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(strncpy_safely)(buf, di->filename, nbuf); 1473b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->memname) { 14744ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj used = VG_(strlen)(buf); 14754ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (used < nbuf) 14764ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(strncpy_safely)(&buf[used], "(", nbuf-used); 14774ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj used = VG_(strlen)(buf); 14784ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (used < nbuf) 1479b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(strncpy_safely)(&buf[used], di->memname, nbuf-used); 14804ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj used = VG_(strlen)(buf); 14814ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (used < nbuf) 14824ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(strncpy_safely)(&buf[used], ")", nbuf-used); 14834ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 14844ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj buf[nbuf-1] = 0; 1485eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1486eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1487eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 14887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Last-ditch fallback position: if we don't find the address in 14897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj the debugInfo_list, ask the address space manager whether it 14907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj knows the name of the file associated with this mapping. This 14917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj allows us to print the names of exe/dll files in the stack trace 14927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj when running programs under wine. */ 14937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if ( (seg = VG_(am_find_nsegment(a))) != NULL 14947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj && (filename = VG_(am_get_filename)(seg)) != NULL ) { 1495f32ec7f0de8a651bc16a1b2e448c0106d8669889tom VG_(strncpy_safely)(buf, filename, nbuf); 1496f32ec7f0de8a651bc16a1b2e448c0106d8669889tom return True; 1497f32ec7f0de8a651bc16a1b2e448c0106d8669889tom } 1498eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1499eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1500eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1501b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Map a code address to its DebugInfo. Returns NULL if not found. Doesn't 1502eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj require debug info. */ 1503b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjDebugInfo* VG_(find_seginfo) ( Addr a ) 1504eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1505b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1506b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1507b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 15085706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->text_size > 0 1509b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= a 1510b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a < di->text_avma + di->text_size) { 1511b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 1512eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1513eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1514eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return NULL; 1515eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1516eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1517eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a filename. Returns True if successful. */ 1518eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_filename)( Addr a, Char* filename, Int n_filename ) 1519eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1520b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1521f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 1522eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 1523eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 1524eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1525eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(strncpy_safely)(filename, si->loctab[locno].filename, n_filename); 1526eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1527eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1528eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1529eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a line number. Returns True if successful. */ 1530eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_linenum)( Addr a, UInt* lineno ) 1531eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1532b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1533f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 1534eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 1535eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 1536eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1537eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *lineno = si->loctab[locno].lineno; 1538eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1539eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1540eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1541eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1542eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a filename/line number/dir name info. 1543eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj See prototype for detailed description of behaviour. 1544eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 1545eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_filename_linenum) ( Addr a, 1546eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/Char* filename, Int n_filename, 1547eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/Char* dirname, Int n_dirname, 1548eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/Bool* dirname_available, 1549eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/UInt* lineno ) 1550eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1551b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1552f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 1553eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1554eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert( (dirname == NULL && dirname_available == NULL) 1555eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj || 1556eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj (dirname != NULL && dirname_available != NULL) ); 1557eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1558eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 1559c1b1d421216369aec58867ce1c5b99cfb1703c36njn if (si == NULL) { 1560db5c6571454c1f647a4c67593805a8e401cd14c5njn if (dirname_available) { 1561db5c6571454c1f647a4c67593805a8e401cd14c5njn *dirname_available = False; 1562db5c6571454c1f647a4c67593805a8e401cd14c5njn *dirname = 0; 1563db5c6571454c1f647a4c67593805a8e401cd14c5njn } 1564eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1565c1b1d421216369aec58867ce1c5b99cfb1703c36njn } 1566c1b1d421216369aec58867ce1c5b99cfb1703c36njn 1567eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(strncpy_safely)(filename, si->loctab[locno].filename, n_filename); 1568eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *lineno = si->loctab[locno].lineno; 1569eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1570eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (dirname) { 1571eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* caller wants directory info too .. */ 1572eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(n_dirname > 0); 1573eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si->loctab[locno].dirname) { 1574eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* .. and we have some */ 1575eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *dirname_available = True; 1576eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(strncpy_safely)(dirname, si->loctab[locno].dirname, 1577eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_dirname); 1578eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 1579eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* .. but we don't have any */ 1580eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *dirname_available = False; 1581eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *dirname = 0; 1582eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1583eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1584eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1585eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1586eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1587eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1588eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 15894ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/* Map a function name to its entry point and toc pointer. Is done by 15904ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj sequential search of all symbol tables, so is very slow. To 15914ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj mitigate the worst performance effects, you may specify a soname 15924ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj pattern, and only objects matching that pattern are searched. 15934ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Therefore specify "*" to search all the objects. On TOC-afflicted 15944ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj platforms, a symbol is deemed to be found only if it has a nonzero 15954ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj TOC pointer. */ 1596b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool VG_(lookup_symbol_SLOW)(UChar* sopatt, UChar* name, 1597b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr* pEnt, Addr* pToc) 15984ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj{ 15994ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool require_pToc = False; 16004ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Int i; 1601b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 16024ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool debug = False; 16034ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# if defined(VG_PLAT_USES_PPCTOC) 16044ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj require_pToc = True; 16054ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# endif 1606b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (si = debugInfo_list; si; si = si->next) { 16074ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (debug) 16084ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(printf)("lookup_symbol_SLOW: considering %s\n", si->soname); 16094ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (!VG_(string_match)(sopatt, si->soname)) { 16104ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (debug) 16114ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(printf)(" ... skip\n"); 16124ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj continue; 16134ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 16144ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj for (i = 0; i < si->symtab_used; i++) { 16154ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (0==VG_(strcmp)(name, si->symtab[i].name) 16164ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj && (require_pToc ? si->symtab[i].tocptr : True)) { 16174ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj *pEnt = si->symtab[i].addr; 16184ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj *pToc = si->symtab[i].tocptr; 16194ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj return True; 16204ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 16214ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 16224ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 16234ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj return False; 16244ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj} 16254ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 16264ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 1627e872fec0c1c3b478a399fdba42ac65764b53f470sewardj/* VG_(describe_IP): print into buf info on code address, function 1628e872fec0c1c3b478a399fdba42ac65764b53f470sewardj name and filename. */ 1629e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 1630e872fec0c1c3b478a399fdba42ac65764b53f470sewardj/* Copy str into buf starting at n, but not going past buf[n_buf-1] 1631e872fec0c1c3b478a399fdba42ac65764b53f470sewardj and always ensuring that buf is zero-terminated. */ 1632eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1633eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjstatic Int putStr ( Int n, Int n_buf, Char* buf, Char* str ) 1634eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1635e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n_buf > 0); 1636e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 1637eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj for (; n < n_buf-1 && *str != 0; n++,str++) 1638eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf[n] = *str; 1639e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 1640eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf[n] = '\0'; 1641eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return n; 1642eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1643e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 1644e872fec0c1c3b478a399fdba42ac65764b53f470sewardj/* Same as putStr, but escaping chars for XML output, and 1645e872fec0c1c3b478a399fdba42ac65764b53f470sewardj also not adding more than count chars to n_buf. */ 1646e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 1647e872fec0c1c3b478a399fdba42ac65764b53f470sewardjstatic Int putStrEsc ( Int n, Int n_buf, Int count, Char* buf, Char* str ) 1648eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1649eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Char alt[2]; 1650e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n_buf > 0); 1651e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(count >= 0 && count < n_buf); 1652e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 1653eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj for (; *str != 0; str++) { 1654e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(count >= 0); 1655e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count <= 0) 1656e872fec0c1c3b478a399fdba42ac65764b53f470sewardj goto done; 1657eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj switch (*str) { 1658e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '&': 1659e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 5) goto done; 1660e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, "&"); 1661e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 5; 1662e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 1663e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '<': 1664e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 4) goto done; 1665e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, "<"); 1666e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 4; 1667e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 1668e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '>': 1669e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 4) goto done; 1670e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, ">"); 1671e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 4; 1672e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 1673e872fec0c1c3b478a399fdba42ac65764b53f470sewardj default: 1674e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 1) goto done; 1675e872fec0c1c3b478a399fdba42ac65764b53f470sewardj alt[0] = *str; 1676e872fec0c1c3b478a399fdba42ac65764b53f470sewardj alt[1] = 0; 1677e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, alt ); 1678e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 1; 1679e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 1680eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1681eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1682e872fec0c1c3b478a399fdba42ac65764b53f470sewardj done: 1683e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(count >= 0); /* should not go -ve in loop */ 1684e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 1685eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return n; 1686eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1687eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1688eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjChar* VG_(describe_IP)(Addr eip, Char* buf, Int n_buf) 1689eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1690eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define APPEND(_str) \ 1691e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr(n, n_buf, buf, _str) 1692e872fec0c1c3b478a399fdba42ac65764b53f470sewardj# define APPEND_ESC(_count,_str) \ 1693e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStrEsc(n, n_buf, (_count), buf, (_str)) 1694eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define BUF_LEN 4096 1695eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1696eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj UInt lineno; 1697eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj UChar ibuf[50]; 1698eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Int n = 0; 1699eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static UChar buf_fn[BUF_LEN]; 1700eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static UChar buf_obj[BUF_LEN]; 1701eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static UChar buf_srcloc[BUF_LEN]; 1702eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj static UChar buf_dirname[BUF_LEN]; 1703eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool know_dirinfo = False; 17044ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool know_fnname = VG_(clo_sym_offsets) 17054ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj ? VG_(get_fnname_w_offset) (eip, buf_fn, BUF_LEN) 17064ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj : VG_(get_fnname) (eip, buf_fn, BUF_LEN); 1707eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool know_objname = VG_(get_objname)(eip, buf_obj, BUF_LEN); 1708eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool know_srcloc = VG_(get_filename_linenum)( 1709eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj eip, 1710eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf_srcloc, BUF_LEN, 1711eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf_dirname, BUF_LEN, &know_dirinfo, 1712eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj &lineno 1713eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj ); 1714eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (VG_(clo_xml)) { 1715eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1716eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool human_readable = True; 1717eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj HChar* maybe_newline = human_readable ? "\n " : ""; 1718eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj HChar* maybe_newline2 = human_readable ? "\n " : ""; 1719eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1720e872fec0c1c3b478a399fdba42ac65764b53f470sewardj /* Print in XML format, dumping in as much info as we know. 1721e872fec0c1c3b478a399fdba42ac65764b53f470sewardj Ensure all tags are balanced even if the individual strings 1722e872fec0c1c3b478a399fdba42ac65764b53f470sewardj are too long. Allocate 1/10 of BUF_LEN to the object name, 1723e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 6/10s to the function name, 1/10 to the directory name and 1724e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 1/10 to the file name, leaving 1/10 for all the fixed-length 1725e872fec0c1c3b478a399fdba42ac65764b53f470sewardj stuff. */ 1726eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<frame>"); 1727a44b15f527bbebfe824a2e68e4bd6ab1e153b486sewardj VG_(sprintf)(ibuf,"<ip>0x%llX</ip>", (ULong)eip); 1728eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1729eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 1730eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_objname) { 1731eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1732eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<obj>"); 1733e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(1*BUF_LEN/10, buf_obj); 1734eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</obj>"); 1735eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1736eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_fnname) { 1737eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1738eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<fn>"); 1739e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(6*BUF_LEN/10, buf_fn); 1740eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</fn>"); 1741eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1742eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_srcloc) { 1743eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_dirinfo) { 1744eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1745eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<dir>"); 1746e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(1*BUF_LEN/10, buf_dirname); 1747eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</dir>"); 1748eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1749eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1750eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<file>"); 1751e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(1*BUF_LEN/10, buf_srcloc); 1752eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</file>"); 1753eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 1754eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<line>"); 1755eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(sprintf)(ibuf,"%d",lineno); 1756eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 1757eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</line>"); 1758eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1759eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline2); 1760eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</frame>"); 1761eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1762eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 1763eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1764eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Print for humans to read */ 17655e40abad4504416c59f0b29c1cfc8087201213a9njn // 17665e40abad4504416c59f0b29c1cfc8087201213a9njn // Possible forms: 17675e40abad4504416c59f0b29c1cfc8087201213a9njn // 17685e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: really (a.c:20) 17695e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: really (in /foo/a.out) 17705e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: really (in ???) 17715e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: ??? (in /foo/a.out) 17725e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: ??? (a.c:20) 17735e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: ??? 17745e40abad4504416c59f0b29c1cfc8087201213a9njn // 1775a44b15f527bbebfe824a2e68e4bd6ab1e153b486sewardj VG_(sprintf)(ibuf,"0x%llX: ", (ULong)eip); 1776eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 17775e40abad4504416c59f0b29c1cfc8087201213a9njn if (know_fnname) { 1778eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(buf_fn); 1779eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 1780eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("???"); 1781eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1782eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_srcloc) { 1783eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(" ("); 1784eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(buf_srcloc); 1785eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(":"); 1786eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(sprintf)(ibuf,"%d",lineno); 1787eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 1788eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(")"); 17895e40abad4504416c59f0b29c1cfc8087201213a9njn } else if (know_objname) { 17905e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(" (in "); 17915e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(buf_obj); 17925e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(")"); 17935e40abad4504416c59f0b29c1cfc8087201213a9njn } else if (know_fnname) { 17945e40abad4504416c59f0b29c1cfc8087201213a9njn // Nb: do this in two steps because "??)" is a trigraph! 17955e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(" (in ???"); 17965e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(")"); 1797eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1798eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1799eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1800eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return buf; 1801eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1802eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef APPEND 1803eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef APPEND_ESC 1804eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef BUF_LEN 1805eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1806eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 180772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 1808b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 1809b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 1810b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/ 1811b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- DWARF3 .eh_frame INFO ---*/ 1812b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 1813b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 181472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 181572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/* Gather up all the constant pieces of info needed to evaluate 181672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj a CfiExpr into one convenient struct. */ 181772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjtypedef 181872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj struct { 181972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj Addr ipHere; 182072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj Addr spHere; 182172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj Addr fpHere; 182272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj Addr min_accessible; 182372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj Addr max_accessible; 182472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 182572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExprEvalContext; 182672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 182772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/* Evaluate the CfiExpr rooted at ix in exprs given the context eec. 182872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj *ok is set to False on failure, but not to True on success. The 182972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj caller must set it to True before calling. */ 183072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjstatic 183172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjUWord evalCfiExpr ( XArray* exprs, Int ix, 183272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExprEvalContext* eec, Bool* ok ) 183372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj{ 183472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj UWord wL, wR; 183519dc88f90d0e19a1463797dd99f6792a42f961d3sewardj Addr a; 183672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExpr* e = VG_(indexXA)( exprs, ix ); 183772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->tag) { 183872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_Binop: 183972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj wL = evalCfiExpr( exprs, e->Cex.Binop.ixL, eec, ok ); 184072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!(*ok)) return 0; 184172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj wR = evalCfiExpr( exprs, e->Cex.Binop.ixR, eec, ok ); 184272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!(*ok)) return 0; 184372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->Cex.Binop.op) { 184472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cop_Add: return wL + wR; 184572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cop_Sub: return wL - wR; 184619dc88f90d0e19a1463797dd99f6792a42f961d3sewardj case Cop_And: return wL & wR; 18477888e2204fff6e7429236b4227ed16594e7743b9sewardj case Cop_Mul: return wL * wR; 184872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: goto unhandled; 184972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 185072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 185172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_CfiReg: 185272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->Cex.CfiReg.reg) { 185372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Creg_IP: return (Addr)eec->ipHere; 185472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Creg_SP: return (Addr)eec->spHere; 185572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Creg_FP: return (Addr)eec->fpHere; 185672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: goto unhandled; 185772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 185872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 185972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_Const: 186072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj return e->Cex.Const.con; 186119dc88f90d0e19a1463797dd99f6792a42f961d3sewardj case Cex_Deref: 186219dc88f90d0e19a1463797dd99f6792a42f961d3sewardj a = evalCfiExpr( exprs, e->Cex.Deref.ixAddr, eec, ok ); 186319dc88f90d0e19a1463797dd99f6792a42f961d3sewardj if (!(*ok)) return 0; 186419dc88f90d0e19a1463797dd99f6792a42f961d3sewardj if (a < eec->min_accessible 186519dc88f90d0e19a1463797dd99f6792a42f961d3sewardj || (a + sizeof(UWord) - 1) > eec->max_accessible) { 186619dc88f90d0e19a1463797dd99f6792a42f961d3sewardj *ok = False; 186719dc88f90d0e19a1463797dd99f6792a42f961d3sewardj return 0; 186819dc88f90d0e19a1463797dd99f6792a42f961d3sewardj } 186919dc88f90d0e19a1463797dd99f6792a42f961d3sewardj /* let's hope it doesn't trap! */ 187019dc88f90d0e19a1463797dd99f6792a42f961d3sewardj return * ((UWord*)a); 187172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: 187272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj goto unhandled; 187372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 187472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 187572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj unhandled: 187672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("\n\nevalCfiExpr: unhandled\n"); 187772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj ML_(ppCfiExpr)( exprs, ix ); 187872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("\n"); 187972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); 188072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 188172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj return 0; 188272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj} 188372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 188472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 1885f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Search all the DebugInfos in the entire system, to find the DiCfSI 1886f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj that pertains to 'ip'. 1887eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1888f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj If found, set *diP to the DebugInfo in which it resides, and 1889f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *ixP to the index in that DebugInfo's cfsi array. 189072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 1891f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj If not found, set *diP to (DebugInfo*)1 and *ixP to zero. 1892f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj*/ 1893f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj__attribute__((noinline)) 1894f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic void find_DiCfSI ( /*OUT*/DebugInfo** diP, 1895f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*OUT*/Word* ixP, 1896f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Addr ip ) 1897f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 1898f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo* di; 1899f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word i = -1; 1900f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1901f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj static UWord n_search = 0; 1902f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj static UWord n_steps = 0; 1903eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_search++; 1904eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1905f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0) VG_(printf)("search for %#lx\n", ip); 1906eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1907f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1908f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word j; 1909eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_steps++; 1910eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1911b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Use the per-DebugInfo summary address ranges to skip 1912b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj inapplicable DebugInfos quickly. */ 1913f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di->cfsi_used == 0) 1914eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj continue; 1915f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (ip < di->cfsi_minavma || ip > di->cfsi_maxavma) 1916eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj continue; 1917eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1918f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* It might be in this DebugInfo. Search it. */ 1919f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj j = ML_(search_one_cfitab)( di, ip ); 1920f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(j >= -1 && j < (Word)di->cfsi_used); 1921f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1922f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (j != -1) { 1923f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj i = j; 1924f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj break; /* found it */ 1925eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1926eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1927eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1928f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (i == -1) { 1929f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1930f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* we didn't find it. */ 1931f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *diP = (DebugInfo*)1; 1932f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *ixP = 0; 1933f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1934f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 1935f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1936f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* found it. */ 1937f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* ensure that di is 4-aligned (at least), so it can't possibly 1938f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj be equal to (DebugInfo*)1. */ 1939f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di && VG_IS_4_ALIGNED(di)); 1940f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(i >= 0 && i < di->cfsi_used); 1941f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *diP = di; 1942f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *ixP = i; 1943f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1944f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Start of performance-enhancing hack: once every 64 (chosen 1945f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj hackily after profiling) successful searches, move the found 1946f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo one step closer to the start of the list. This 1947f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj makes future searches cheaper. For starting konqueror on 1948f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj amd64, this in fact reduces the total amount of searching 1949f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj done by the above find-the-right-DebugInfo loop by more than 1950f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj a factor of 20. */ 1951f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if ((n_search & 0xF) == 0) { 1952f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Move di one step closer to the start of the list. */ 1953f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj move_DebugInfo_one_step_forward( di ); 1954f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 1955f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* End of performance-enhancing hack. */ 1956f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1957f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && ((n_search & 0x7FFFF) == 0)) 1958f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(printf)("find_DiCfSI: %lu searches, " 1959f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj "%lu DebugInfos looked at\n", 1960f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj n_search, n_steps); 1961f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1962f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 1963f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1964f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 1965f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1966f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1967f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Now follows a mechanism for caching queries to find_DiCfSI, since 1968f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj they are extremely frequent on amd64-linux, during stack unwinding. 1969f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1970f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Each cache entry binds an ip value to a (di, ix) pair. Possible 1971f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj values: 1972f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1973f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj di is non-null, ix >= 0 ==> cache slot in use, "di->cfsi[ix]" 1974f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj di is (DebugInfo*)1 ==> cache slot in use, no associated di 1975f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj di is NULL ==> cache slot not in use 1976f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1977f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Hence simply zeroing out the entire cache invalidates all 1978f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj entries. 1979f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1980f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Why not map ip values directly to DiCfSI*'s? Because this would 1981f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cause problems if/when the cfsi array is moved due to resizing. 1982f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Instead we cache .cfsi array index value, which should be invariant 1983f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj across resizing. (That said, I don't think the current 1984f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj implementation will resize whilst during queries, since the DiCfSI 1985f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj records are added all at once, when the debuginfo for an object is 1986f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj read, and is not changed ever thereafter. */ 1987eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1988f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#define N_CFSI_CACHE 511 1989f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1990f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjtypedef 1991f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj struct { Addr ip; DebugInfo* di; Word ix; } 1992f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj CFSICacheEnt; 1993f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1994f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic CFSICacheEnt cfsi_cache[N_CFSI_CACHE]; 1995f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1996f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic void cfsi_cache__invalidate ( void ) { 1997f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(memset)(&cfsi_cache, 0, sizeof(cfsi_cache)); 1998f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 1999f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2000f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2001f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* The main function for DWARF2/3 CFI-based stack unwinding. 2002f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Given an IP/SP/FP triple, produce the IP/SP/FP values for the 2003f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj previous frame, if possible. */ 2004f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Returns True if OK. If not OK, *{ip,sp,fp}P are not changed. */ 2005f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* NOTE: this function may rearrange the order of entries in the 2006f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo list. */ 2007f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjBool VG_(use_CF_info) ( /*MOD*/Addr* ipP, 2008f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*MOD*/Addr* spP, 2009f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*MOD*/Addr* fpP, 2010f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Addr min_accessible, 2011f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Addr max_accessible ) 2012f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 2013f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool ok; 2014f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo* di; 2015f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DiCfSI* cfsi = NULL; 2016f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Addr cfa, ipHere, spHere, fpHere, ipPrev, spPrev, fpPrev; 2017f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2018f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj CfiExprEvalContext eec; 2019f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2020f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj static UWord n_q = 0, n_m = 0; 2021f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj n_q++; 2022f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && 0 == (n_q & 0x1FFFFF)) 2023f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(printf)("QQQ %lu %lu\n", n_q, n_m); 2024f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2025f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj { UWord hash = (*ipP) % N_CFSI_CACHE; 2026f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj CFSICacheEnt* ce = &cfsi_cache[hash]; 2027f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2028f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (LIKELY(ce->ip == *ipP) && LIKELY(ce->di != NULL)) { 2029f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* found an entry in the cache .. */ 2030f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 2031f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* not found in cache. Search and update. */ 2032f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj n_m++; 2033f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj ce->ip = *ipP; 2034f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj find_DiCfSI( &ce->di, &ce->ix, *ipP ); 2035f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 2036f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2037f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (UNLIKELY(ce->di == (DebugInfo*)1)) { 2038f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* no DiCfSI for this address */ 2039f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi = NULL; 2040f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj di = NULL; 2041f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 2042f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* found a DiCfSI for this address */ 2043f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj di = ce->di; 2044f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfsi = &di->cfsi[ ce->ix ]; 2045f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 2046eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2047f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2048f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (UNLIKELY(cfsi == NULL)) 2049f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return False; /* no info. Nothing we can do. */ 2050eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2051eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (0) { 2052eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(printf)("found cfisi: "); 2053f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj ML_(ppDiCfSI)(di->cfsi_exprs, cfsi); 2054eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2055eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2056eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj ipPrev = spPrev = fpPrev = 0; 2057eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2058eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj ipHere = *ipP; 2059eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj spHere = *spP; 2060eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj fpHere = *fpP; 2061eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 206272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /* First compute the CFA. */ 206372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj cfa = 0; 206472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (cfsi->cfa_how) { 206572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case CFIC_SPREL: 206672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj cfa = cfsi->cfa_off + spHere; 206772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 206872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case CFIC_FPREL: 206972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj cfa = cfsi->cfa_off + fpHere; 207072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 207172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case CFIC_EXPR: 20727888e2204fff6e7429236b4227ed16594e7743b9sewardj if (0) { 20737888e2204fff6e7429236b4227ed16594e7743b9sewardj VG_(printf)("CFIC_EXPR: "); 2074f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj ML_(ppCfiExpr)(di->cfsi_exprs, cfsi->cfa_off); 20757888e2204fff6e7429236b4227ed16594e7743b9sewardj VG_(printf)("\n"); 20767888e2204fff6e7429236b4227ed16594e7743b9sewardj } 20777888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.ipHere = ipHere; 20787888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.spHere = spHere; 20797888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.fpHere = fpHere; 20807888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.min_accessible = min_accessible; 20817888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.max_accessible = max_accessible; 20827888e2204fff6e7429236b4227ed16594e7743b9sewardj ok = True; 2083f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj cfa = evalCfiExpr(di->cfsi_exprs, cfsi->cfa_off, &eec, &ok ); 20847888e2204fff6e7429236b4227ed16594e7743b9sewardj if (!ok) return False; 208572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 208672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: 208772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); 208872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 208972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 209072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /* Now we know the CFA, use it to roll back the registers we're 209172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj interested in. */ 2092eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2093eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define COMPUTE(_prev, _here, _how, _off) \ 2094eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj do { \ 2095eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj switch (_how) { \ 2096eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_UNKNOWN: \ 2097eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; \ 2098eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_SAME: \ 2099eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj _prev = _here; break; \ 2100eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_MEMCFAREL: { \ 2101eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Addr a = cfa + (Word)_off; \ 2102eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (a < min_accessible \ 21039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj || a > max_accessible-sizeof(Addr)) \ 2104eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; \ 2105eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj _prev = *(Addr*)a; \ 2106eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; \ 2107eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } \ 2108eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_CFAREL: \ 2109eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj _prev = cfa + (Word)_off; \ 2110eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; \ 211172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case CFIR_EXPR: \ 211272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (0) \ 2113f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj ML_(ppCfiExpr)(di->cfsi_exprs,_off); \ 211472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.ipHere = ipHere; \ 211572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.spHere = spHere; \ 211672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.fpHere = fpHere; \ 211772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.min_accessible = min_accessible; \ 211872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.max_accessible = max_accessible; \ 211972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj ok = True; \ 2120f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj _prev = evalCfiExpr(di->cfsi_exprs, _off, &eec, &ok ); \ 212172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!ok) return False; \ 212272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; \ 212372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: \ 212472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); \ 2125eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } \ 2126eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } while (0) 2127eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2128eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj COMPUTE(ipPrev, ipHere, cfsi->ra_how, cfsi->ra_off); 2129eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj COMPUTE(spPrev, spHere, cfsi->sp_how, cfsi->sp_off); 2130eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj COMPUTE(fpPrev, fpHere, cfsi->fp_how, cfsi->fp_off); 2131eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2132eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef COMPUTE 2133eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2134eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *ipP = ipPrev; 2135eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *spP = spPrev; 2136eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *fpP = fpPrev; 2137eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 2138eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2139eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2140eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 2142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 2143c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/ 2144c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- MSVC FPO INFO ---*/ 2145c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- ---*/ 2146c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--------------------------------------------------------------*/ 2147c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2148c8259b85b701d25d72aabe9dc0a8154517f96913sewardjBool VG_(use_FPO_info) ( /*MOD*/Addr* ipP, 2149c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /*MOD*/Addr* spP, 2150c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /*MOD*/Addr* fpP, 2151c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Addr min_accessible, 2152c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Addr max_accessible ) 2153c8259b85b701d25d72aabe9dc0a8154517f96913sewardj{ 2154c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Word i; 2155c8259b85b701d25d72aabe9dc0a8154517f96913sewardj DebugInfo* di; 2156c8259b85b701d25d72aabe9dc0a8154517f96913sewardj FPO_DATA* fpo = NULL; 2157c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Addr spHere; 2158c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2159c8259b85b701d25d72aabe9dc0a8154517f96913sewardj static UWord n_search = 0; 2160c8259b85b701d25d72aabe9dc0a8154517f96913sewardj static UWord n_steps = 0; 2161c8259b85b701d25d72aabe9dc0a8154517f96913sewardj n_search++; 2162c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2163c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0) VG_(printf)("search FPO for %#lx\n", *ipP); 2164c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2165c8259b85b701d25d72aabe9dc0a8154517f96913sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 2166c8259b85b701d25d72aabe9dc0a8154517f96913sewardj n_steps++; 2167c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2168c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Use the per-DebugInfo summary address ranges to skip 2169c8259b85b701d25d72aabe9dc0a8154517f96913sewardj inapplicable DebugInfos quickly. */ 2170c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (di->fpo == NULL) 2171c8259b85b701d25d72aabe9dc0a8154517f96913sewardj continue; 2172c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (*ipP < di->fpo_minavma || *ipP > di->fpo_maxavma) 2173c8259b85b701d25d72aabe9dc0a8154517f96913sewardj continue; 2174c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2175c8259b85b701d25d72aabe9dc0a8154517f96913sewardj i = ML_(search_one_fpotab)( di, *ipP ); 2176c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (i != -1) { 2177c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Word j; 2178c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0) { 2179c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* debug printing only */ 2180c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("look for %#lx size %ld i %ld\n", 2181c8259b85b701d25d72aabe9dc0a8154517f96913sewardj *ipP, di->fpo_size, i); 2182c8259b85b701d25d72aabe9dc0a8154517f96913sewardj for (j = 0; j < di->fpo_size; j++) 2183c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("[%02ld] %#x %d\n", 2184c8259b85b701d25d72aabe9dc0a8154517f96913sewardj j, di->fpo[j].ulOffStart, di->fpo[j].cbProcSize); 2185c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2186c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(i >= 0 && i < di->fpo_size); 2187c8259b85b701d25d72aabe9dc0a8154517f96913sewardj fpo = &di->fpo[i]; 2188c8259b85b701d25d72aabe9dc0a8154517f96913sewardj break; 2189c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2190c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2191c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2192c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (fpo == NULL) 2193c8259b85b701d25d72aabe9dc0a8154517f96913sewardj return False; 2194c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2195c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0 && ((n_search & 0x7FFFF) == 0)) 2196c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("VG_(use_FPO_info): %lu searches, " 2197c8259b85b701d25d72aabe9dc0a8154517f96913sewardj "%lu DebugInfos looked at\n", 2198c8259b85b701d25d72aabe9dc0a8154517f96913sewardj n_search, n_steps); 2199c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2200c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2201c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Start of performance-enhancing hack: once every 64 (chosen 2202c8259b85b701d25d72aabe9dc0a8154517f96913sewardj hackily after profiling) successful searches, move the found 2203c8259b85b701d25d72aabe9dc0a8154517f96913sewardj DebugInfo one step closer to the start of the list. This makes 2204c8259b85b701d25d72aabe9dc0a8154517f96913sewardj future searches cheaper. For starting konqueror on amd64, this 2205c8259b85b701d25d72aabe9dc0a8154517f96913sewardj in fact reduces the total amount of searching done by the above 2206c8259b85b701d25d72aabe9dc0a8154517f96913sewardj find-the-right-DebugInfo loop by more than a factor of 20. */ 2207c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if ((n_search & 0x3F) == 0) { 2208c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Move si one step closer to the start of the list. */ 2209c8259b85b701d25d72aabe9dc0a8154517f96913sewardj //move_DebugInfo_one_step_forward( di ); 2210c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2211c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* End of performance-enhancing hack. */ 2212c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2213c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0) { 2214c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("found fpo: "); 2215c8259b85b701d25d72aabe9dc0a8154517f96913sewardj //ML_(ppFPO)(fpo); 2216c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2217c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2218c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* 2219c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Stack layout is: 2220c8259b85b701d25d72aabe9dc0a8154517f96913sewardj %esp-> 2221c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 4*.cbRegs {%edi, %esi, %ebp, %ebx} 2222c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 4*.cdwLocals 2223c8259b85b701d25d72aabe9dc0a8154517f96913sewardj return_pc 2224c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 4*.cdwParams 2225c8259b85b701d25d72aabe9dc0a8154517f96913sewardj prior_%esp-> 2226c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2227c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Typical code looks like: 2228c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sub $4*.cdwLocals,%esp 2229c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Alternative to above for >=4KB (and sometimes for smaller): 2230c8259b85b701d25d72aabe9dc0a8154517f96913sewardj mov $size,%eax 2231c8259b85b701d25d72aabe9dc0a8154517f96913sewardj call __chkstk # WinNT performs page-by-page probe! 2232c8259b85b701d25d72aabe9dc0a8154517f96913sewardj __chkstk is much like alloc(), except that on return 2233c8259b85b701d25d72aabe9dc0a8154517f96913sewardj %eax= 5+ &CALL. Thus it could be used as part of 2234c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Position Independent Code to locate the Global Offset Table. 2235c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %ebx 2236c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %ebp 2237c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %esi 2238c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Other once-only instructions often scheduled >here<. 2239c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %edi 2240c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2241c8259b85b701d25d72aabe9dc0a8154517f96913sewardj If the pc is within the first .cbProlog bytes of the function, 2242c8259b85b701d25d72aabe9dc0a8154517f96913sewardj then you must disassemble to see how many registers have been pushed, 2243c8259b85b701d25d72aabe9dc0a8154517f96913sewardj because instructions in the prolog may be scheduled for performance. 2244c8259b85b701d25d72aabe9dc0a8154517f96913sewardj The order of PUSH is always %ebx, %ebp, %esi, %edi, with trailing 2245c8259b85b701d25d72aabe9dc0a8154517f96913sewardj registers not pushed when .cbRegs < 4. This seems somewhat strange 2246c8259b85b701d25d72aabe9dc0a8154517f96913sewardj because %ebp is the register whose usage you want to minimize, 2247c8259b85b701d25d72aabe9dc0a8154517f96913sewardj yet it is in the first half of the PUSH list. 2248c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2249c8259b85b701d25d72aabe9dc0a8154517f96913sewardj I don't know what happens when the compiler constructs an outgoing CALL. 2250c8259b85b701d25d72aabe9dc0a8154517f96913sewardj %esp could move if outgoing parameters are PUSHed, and this affects 2251c8259b85b701d25d72aabe9dc0a8154517f96913sewardj traceback for errors during the PUSHes. */ 2252c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2253c8259b85b701d25d72aabe9dc0a8154517f96913sewardj spHere = *spP; 2254c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2255c8259b85b701d25d72aabe9dc0a8154517f96913sewardj *ipP = *(Addr *)(spHere + 4*(fpo->cbRegs + fpo->cdwLocals)); 2256c8259b85b701d25d72aabe9dc0a8154517f96913sewardj *spP = spHere + 4*(fpo->cbRegs + fpo->cdwLocals + 1 + fpo->cdwParams); 2257c8259b85b701d25d72aabe9dc0a8154517f96913sewardj *fpP = *(Addr *)(spHere + 4*2); 2258c8259b85b701d25d72aabe9dc0a8154517f96913sewardj return True; 2259c8259b85b701d25d72aabe9dc0a8154517f96913sewardj} 2260c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2261c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2262c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--------------------------------------------------------------*/ 2263c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- ---*/ 2264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- TOP LEVEL: GENERATE DESCRIPTION OF DATA ADDRESSES ---*/ 2265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- FROM DWARF3 DEBUG INFO ---*/ 2266b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 2267b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 2268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Evaluate the location expression/list for var, to see whether or 2270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj not data_addr falls within the variable. If so also return the 2271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset of data_addr from the start of the variable. Note that 2272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs, which supplies ip,sp,fp values, will be NULL for global 2273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj variables, and non-NULL for local variables. */ 2274c4431bfe04c7490ea2d74939d222d87f13f30960njnstatic Bool data_address_is_in_var ( /*OUT*/PtrdiffT* offset, 22759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* /* TyEnt */ tyents, 2276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var, 2277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj RegSummary* regs, 2278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 2279588658b13b5ad77672f323d48fe9da0ca60b0bcbtom const DebugInfo* di ) 2280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 228150fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 2282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj SizeT var_szB; 2283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj GXResult res; 2284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool show = False; 22859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 2286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->name); 2287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->gexpr); 2288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2289b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Figure out how big the variable is. */ 229050fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(tyents, var->typeR); 229150fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 229250fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. ML_(addVar) 229350fde23467d92281b32dd537d0d9a590263628c3sewardj should have rejected it. */ 229450fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 229550fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 229650fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 229750fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a host word 229850fde23467d92281b32dd537d0d9a590263628c3sewardj safely (without loss of info). */ 229950fde23467d92281b32dd537d0d9a590263628c3sewardj 230050fde23467d92281b32dd537d0d9a590263628c3sewardj var_szB = (SizeT)mul.ul; /* NB: truncate to host word */ 2301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) { 2303a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("VVVV: data_address_%#lx_is_in_var: %s :: ", 2304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var->name ); 23059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(pp_TyEnt_C_ishly)( tyents, var->typeR ); 2306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("\n"); 2307b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ignore zero-sized vars; they can never match anything. */ 2310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (var_szB == 0) { 2311b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) 2312b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("VVVV: -> Fail (variable is zero sized)\n"); 2313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 2314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2316588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_GX)( var->gexpr, var->fbGX, regs, di ); 2317b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2318b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) { 2319b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("VVVV: -> "); 2320b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(pp_GXResult)( res ); 2321b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("\n"); 2322b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2323eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (res.kind == GXR_Value 2325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && res.word <= data_addr 2326b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && data_addr < res.word + var_szB) { 2327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *offset = data_addr - res.word; 2328b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 2329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 2330b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 2331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 2333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Format the acquired information into dname1[0 .. n_dname-1] and 2336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2[0 .. n_dname-1] in an understandable way. Not so easy. 2337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj If frameNo is -1, this is assumed to be a global variable; else 2338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj a local variable. */ 2339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void format_message ( /*OUT*/Char* dname1, 2340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/Char* dname2, 2341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int n_dname, 2342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 2343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var, 2344c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT var_offset, 2345c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT residual_offset, 2346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* /*UChar*/ described, 2347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int frameNo, 2348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid ) 2349eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool have_descr, have_srcloc; 2351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj UChar* vo_plural = var_offset == 1 ? "" : "s"; 2352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj UChar* ro_plural = residual_offset == 1 ? "" : "s"; 2353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2354b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(frameNo >= -1); 2355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(dname1 && dname2 && n_dname > 1); 2356b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(described); 2357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var && var->name); 2358b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj have_descr = VG_(sizeXA)(described) > 0 2359b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && *(UChar*)VG_(indexXA)(described,0) != '\0'; 2360b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj have_srcloc = var->fileName && var->lineNo > 0; 2361b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2362b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[0] = dname2[0] = '\0'; 2363b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2364b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ------ local cases ------ */ 2365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && (!have_srcloc) && (!have_descr) ) { 2367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc, no description: 2368b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside local var "a", 2369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in frame #1 of thread 1 2370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 2373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside local var \"%s\",", 2374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var_offset, vo_plural, var->name ); 2375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2, n_dname, 2377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "in frame #%d of thread %d", frameNo, (Int)tid); 2378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && have_srcloc && (!have_descr) ) { 2381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no description: 2382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside local var "a" 2383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj declared at dsyms7.c:17, in frame #1 of thread 1 2384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 2387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside local var \"%s\"", 2388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var_offset, vo_plural, var->name ); 2389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2, n_dname, 2391b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "declared at %s:%d, in frame #%d of thread %d", 2392b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var->fileName, var->lineNo, frameNo, (Int)tid); 2393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && (!have_srcloc) && have_descr ) { 2396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc: 2397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2 2398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in frame #1 of thread 1 2399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 2402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside %s%s", 2403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, residual_offset, ro_plural, var->name, 2404a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart (char*)(VG_(indexXA)(described,0)) ); 2405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2, n_dname, 2407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "in frame #%d of thread %d", frameNo, (Int)tid); 2408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2410b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && have_srcloc && have_descr ) { 2411b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 2412b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj declared at dsyms7.c:17, in frame #1 of thread 1 */ 2413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2414b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 2415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside %s%s,", 2416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, residual_offset, ro_plural, var->name, 2417a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart (char*)(VG_(indexXA)(described,0)) ); 2418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2, n_dname, 2420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "declared at %s:%d, in frame #%d of thread %d", 2421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var->fileName, var->lineNo, frameNo, (Int)tid); 2422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ------ global cases ------ */ 2425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && (!have_srcloc) && (!have_descr) ) { 2426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc, no description: 2427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside global var "a" 2428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 2431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside global var \"%s\"", 2432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var_offset, vo_plural, var->name ); 2433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && have_srcloc && (!have_descr) ) { 2436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no description: 2437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside global var "a" 2438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj declared at dsyms7.c:17 2439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 2442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside global var \"%s\"", 2443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var_offset, vo_plural, var->name ); 2444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2, n_dname, 2446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "declared at %s:%d", 2447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var->fileName, var->lineNo); 2448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && (!have_srcloc) && have_descr ) { 2451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc: 2452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 2453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj a global variable 2454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 2455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 2457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside %s%s,", 2458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, residual_offset, ro_plural, var->name, 2459a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart (char*)(VG_(indexXA)(described,0)) ); 2460b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2, n_dname, 2462b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "a global variable"); 2463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2464b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && have_srcloc && have_descr ) { 2466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 2467b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj a global variable declared at dsyms7.c:17 */ 2468b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2469b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1, n_dname, 2470b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "Location 0x%lx is %lu byte%s inside %s%s,", 2471b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, residual_offset, ro_plural, var->name, 2472a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart (char*)(VG_(indexXA)(described,0)) ); 2473b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)( 2474b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname2, n_dname, 2475b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "a global variable declared at %s:%d", 2476b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var->fileName, var->lineNo); 2477b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2478b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 2479b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(0); 2480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 2482eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2483eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2484b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Determine if data_addr is a local variable in the frame 2485b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj characterised by (ip,sp,fp), and if so write its description into 2486b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname{1,2}[0..n_dname-1], and return True. If not, return 2487b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj False. */ 2488b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic 2489b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool consider_vars_in_frame ( /*OUT*/Char* dname1, 2490b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/Char* dname2, 2491b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int n_dname, 2492b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 2493b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr ip, Addr sp, Addr fp, 2494b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* shown to user: */ 2495b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid, Int frameNo ) 2496eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2497b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word i; 2498b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 2499b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj RegSummary regs; 2500b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool debug = False; 2501b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2502b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj static UInt n_search = 0; 2503b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj static UInt n_steps = 0; 2504b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_search++; 2505b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 2506a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("QQQQ: cvif: ip,sp,fp %#lx,%#lx,%#lx\n", ip,sp,fp); 2507b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* first, find the DebugInfo that pertains to 'ip'. */ 2508b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di; di = di->next) { 2509b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_steps++; 2510b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* text segment missing? unlikely, but handle it .. */ 2511b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->text_present || di->text_size == 0) 2512b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2513b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok. So does this text mapping bracket the ip? */ 2514b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_avma <= ip && ip < di->text_avma + di->text_size) 2515b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 2516b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2517b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2518b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Didn't find it. Strange -- means ip is a code address outside 2519b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj of any mapped text segment. Unlikely but not impossible -- app 2520b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj could be generating code to run. */ 2521b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di) 2522b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 2523b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2524b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0 && ((n_search & 0x1) == 0)) 2525b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("consider_vars_in_frame: %u searches, " 2526b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "%u DebugInfos looked at\n", 2527b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_search, n_steps); 2528b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Start of performance-enhancing hack: once every ??? (chosen 2529b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj hackily after profiling) successful searches, move the found 2530b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo one step closer to the start of the list. This makes 2531b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj future searches cheaper. */ 2532b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ((n_search & 0xFFFF) == 0) { 2533b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Move si one step closer to the start of the list. */ 2534b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj move_DebugInfo_one_step_forward( di ); 2535b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2536b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* End of performance-enhancing hack. */ 2537b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* any var info at all? */ 2539b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->varinfo) 2540b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 2541b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2542b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Work through the scopes from most deeply nested outwards, 2543b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj looking for code address ranges that bracket 'ip'. The 2544b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj variables on each such address range found are in scope right 2545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj now. Don't descend to level zero as that is the global 2546b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj scope. */ 2547b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.ip = ip; 2548b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.sp = sp; 2549b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.fp = fp; 2550b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2551b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* "for each scope, working outwards ..." */ 2552b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) { 2553b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* vars; 2554b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word j; 2555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* arange; 2556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* this_scope 2557b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj = *(OSet**)VG_(indexXA)( di->varinfo, i ); 2558b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 2559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("QQQQ: considering scope %ld\n", (Word)i); 2560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!this_scope) 2561b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2562b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Find the set of variables in this scope that 2563b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj bracket the program counter. */ 2564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj arange = VG_(OSetGen_LookupWithCmp)( 2565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj this_scope, &ip, 2566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(cmp_for_DiAddrRange_range) 2567b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ); 2568b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!arange) 2569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2570b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* stay sane */ 2571b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->aMin <= arange->aMax); 2572b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* It must bracket the ip we asked for, else 2573b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(cmp_for_DiAddrRange_range) is somehow broken. */ 2574b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->aMin <= ip && ip <= arange->aMax); 2575b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* It must have an attached XArray of DiVariables. */ 2576b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vars = arange->vars; 2577b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(vars); 2578b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* But it mustn't cover the entire address range. We only 2579b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj expect that to happen for the global scope (level 0), which 2580b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj we're not looking at here. Except, it may cover the entire 2581b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj address range, but in that case the vars array must be 2582b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj empty. */ 2583b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(! (arange->aMin == (Addr)0 2584b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && arange->aMax == ~(Addr)0 2585b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && VG_(sizeXA)(vars) > 0) ); 2586b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < VG_(sizeXA)( vars ); j++) { 2587b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j ); 2588c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT offset; 2589b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 2590a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n", 2591b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var->name,arange->aMin,arange->aMax,ip); 25929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (data_address_is_in_var( &offset, di->admin_tyents, 25939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var, ®s, 2594588658b13b5ad77672f323d48fe9da0ca60b0bcbtom data_addr, di )) { 2595c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT residual_offset = 0; 2596b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* described = ML_(describe_type)( &residual_offset, 25979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->admin_tyents, 25989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR, offset ); 2599b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj format_message( dname1, dname2, n_dname, 2600b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var, offset, residual_offset, 2601b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj described, frameNo, tid ); 2602b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)( described ); 2603b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 2604b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2605b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2606b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2607b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2608b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 2609eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2610eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2611b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Try to form some description of data_addr by looking at the DWARF3 2612b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debug info we have. This considers all global variables, and all 2613b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj frames in the stacks of all threads. Result (or as much as will 2614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj fit) is put into into dname{1,2}[0 .. n_dname-1] and is guaranteed 2615b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to be zero terminated. */ 2616b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool VG_(get_data_description)( /*OUT*/Char* dname1, 2617b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/Char* dname2, 2618b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int n_dname, 2619b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr ) 2620eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2621b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# define N_FRAMES 8 2622b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr ips[N_FRAMES], sps[N_FRAMES], fps[N_FRAMES]; 2623b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj UInt n_frames; 2624b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2625b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr stack_min, stack_max; 2626b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid; 2627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool found; 2628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 2629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word j; 2630b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_dname > 1); 2632b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 2633b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2634a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart if (0) VG_(printf)("get_data_description: dataaddr %#lx\n", data_addr); 2635b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* First, see if data_addr is (or is part of) a global variable. 2636b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Loop over the DebugInfos we have. Check data_addr against the 2637b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj outermost scope of all of them, as that should be a global 2638b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj scope. */ 2639b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 2640b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* global_scope; 26419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word gs_size; 2642b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr zero; 2643b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* global_arange; 2644b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word i; 2645b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* vars; 2646b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2647b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* text segment missing? unlikely, but handle it .. */ 2648b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->text_present || di->text_size == 0) 2649b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2650b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* any var info at all? */ 2651b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->varinfo) 2652b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2653b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* perhaps this object didn't contribute any vars at all? */ 2654b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (VG_(sizeXA)( di->varinfo ) == 0) 2655b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2656b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj global_scope = *(OSet**)VG_(indexXA)( di->varinfo, 0 ); 2657b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_scope); 2658b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj gs_size = VG_(OSetGen_Size)( global_scope ); 2659b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* The global scope might be completely empty if this 2660b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj compilation unit declared locals but nothing global. */ 2661b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (gs_size == 0) 2662b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2663b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* But if it isn't empty, then it must contain exactly one 2664b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj element, which covers the entire address range. */ 2665b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(gs_size == 1); 2666b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Fish out the global scope and check it is as expected. */ 2667b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj zero = 0; 2668b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj global_arange 2669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj = VG_(OSetGen_Lookup)( global_scope, &zero ); 2670b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* The global range from (Addr)0 to ~(Addr)0 must exist */ 2671b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_arange); 2672b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_arange->aMin == (Addr)0 2673b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && global_arange->aMax == ~(Addr)0); 2674b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Any vars in this range? */ 2675b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!global_arange->vars) 2676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 2677b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok, there are some vars in the global scope of this 2678b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo. Wade through them and see if the data addresses 2679b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj of any of them bracket data_addr. */ 2680b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vars = global_arange->vars; 2681b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = 0; i < VG_(sizeXA)( vars ); i++) { 2682c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT offset; 2683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, i ); 2684b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->name); 2685b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Note we use a NULL RegSummary* here. It can't make any 2686b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sense for a global variable to have a location expression 2687b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which depends on a SP/FP/IP value. So don't supply any. 2688b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj This means, if the evaluation of the location 2689b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj expression/list requires a register, we have to let it 2690b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj fail. */ 26919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (data_address_is_in_var( &offset, di->admin_tyents, var, 2692b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj NULL/* RegSummary* */, 2693588658b13b5ad77672f323d48fe9da0ca60b0bcbtom data_addr, di )) { 2694c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT residual_offset = 0; 2695b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* described = ML_(describe_type)( &residual_offset, 26969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->admin_tyents, 26979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR, offset ); 2698b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj format_message( dname1, dname2, n_dname, 2699b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var, offset, residual_offset, 2700b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj described, -1/*frameNo*/, tid ); 2701b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)( described ); 2702b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 2703b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 2704b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2705b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2706b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2707b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2708b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok, well it's not a global variable. So now let's snoop around 2709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in the stacks of all the threads. First try to figure out which 2710b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj thread's stack data_addr is in. */ 2711b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2712b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* --- KLUDGE --- Try examining the top frame of all thread stacks. 2713b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj This finds variables which are not stack allocated but are not 2714b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj globally visible either; specifically it appears to pick up 2715b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj variables which are visible only within a compilation unit. 2716b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj These will have the address range of the compilation unit and 2717b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj tend to live at Scope level 1. */ 2718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(thread_stack_reset_iter)(&tid); 2719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) { 2720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (stack_min >= stack_max) 2721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; /* ignore obviously stupid cases */ 2722b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (consider_vars_in_frame( dname1, dname2, n_dname, 2723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, 2724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(get_IP)(tid), 2725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(get_SP)(tid), 2726b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(get_FP)(tid), tid, 0 )) { 2727b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 2728b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 2729b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2730b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2731b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* --- end KLUDGE --- */ 2732b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2733b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Perhaps it's on a thread's stack? */ 2734b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj found = False; 2735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(thread_stack_reset_iter)(&tid); 2736b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) { 2737b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (stack_min >= stack_max) 2738b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; /* ignore obviously stupid cases */ 2739b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (stack_min - VG_STACK_REDZONE_SZB <= data_addr 2740b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && data_addr <= stack_max) { 2741b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj found = True; 2742b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 2743b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2744b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2745b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!found) { 2746b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 2747b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 2748b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2749b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2750b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We conclude data_addr is in thread tid's stack. Unwind the 2751b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj stack to get a bunch of (ip,sp,fp) triples describing the 2752b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj frames, and for each frame, consider the local variables. */ 2753b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_frames = VG_(get_StackTrace)( tid, ips, N_FRAMES, 2754b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sps, fps, 0/*first_ip_delta*/ ); 2755b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj 2756b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* As a result of KLUDGE above, starting the loop at j = 0 2757b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj duplicates examination of the top frame and so isn't necessary. 2758b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Oh well. */ 2759b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_frames >= 0 && n_frames <= N_FRAMES); 2760b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < n_frames; j++) { 2761b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (consider_vars_in_frame( dname1, dname2, n_dname, 2762b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, 2763b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj ips[j], 2764b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sps[j], fps[j], tid, j )) { 2765b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 2766b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 2767b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2768b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Now, it appears that gcc sometimes appears to produce 2769b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj location lists whose ranges don't actually cover the call 2770b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj instruction, even though the address of the variable in 2771b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj question is passed as a parameter in the call. AFAICS this 2772b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is simply a bug in gcc - how can the variable be claimed not 2773b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj exist in memory (on the stack) for the duration of a call in 2774b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which its address is passed? But anyway, in the particular 2775b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case I investigated (memcheck/tests/varinfo6.c, call to croak 2776b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj on line 2999, local var budget declared at line 3115 2777b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj appearing not to exist across the call to mainSort on line 2778b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3143, "gcc.orig (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2)" on 2779b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj amd64), the variable's location list does claim it exists 2780b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj starting at the first byte of the first instruction after the 2781b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj call instruction. So, call consider_vars_in_frame a second 2782b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj time, but this time add 1 to the IP. GDB handles this 2783b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj example with no difficulty, which leads me to believe that 2784b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj either (1) I misunderstood something, or (2) GDB has an 2785b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj equivalent kludge. */ 2786b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj if (j > 0 /* this is a non-innermost frame */ 2787b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj && consider_vars_in_frame( dname1, dname2, n_dname, 2788b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj data_addr, 2789b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj ips[j] + 1, 2790b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj sps[j], fps[j], tid, j )) { 2791b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 2792b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 2793b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2794b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 2795b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2796b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We didn't find anything useful. */ 2797b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname1[n_dname-1] = dname2[n_dname-1] = 0; 2798b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 2799b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# undef N_FRAMES 2800eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2801eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2802b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 28039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj////////////////////////////////////////////////////////////////// 28049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// // 28059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// Support for other kinds of queries to the Dwarf3 var info // 28069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// // 28079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj////////////////////////////////////////////////////////////////// 28089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Figure out if the variable 'var' has a location that is linearly 28109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj dependent on a stack pointer value, or a frame pointer value, and 28119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if it is, add a description of it to 'blocks'. Otherwise ignore 28129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. If 'arrays_only' is True, also ignore it unless it has an 28139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj array type. */ 28149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic 28169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks, 28179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* /* TyEnt */ tyents, 2818588658b13b5ad77672f323d48fe9da0ca60b0bcbtom Addr ip, const DebugInfo* di, DiVariable* var, 28199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool arrays_only ) 28209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 28219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res_sp_6k, res_sp_7k, res_fp_6k, res_fp_7k; 28229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj RegSummary regs; 282350fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 28249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool isVec; 28259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ty; 28269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool debug = False; 28289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0&&debug) 28299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("adeps: var %s\n", var->name ); 28309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Figure out how big the variable is. */ 283250fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(tyents, var->typeR); 283350fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 283450fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. ML_(addVar) 283550fde23467d92281b32dd537d0d9a590263628c3sewardj should have rejected it. */ 283650fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 283750fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 283850fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 283950fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a host word 284050fde23467d92281b32dd537d0d9a590263628c3sewardj safely (without loss of info). */ 28419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* skip if non-array and we're only interested in arrays */ 28439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ty = ML_(TyEnts__index_by_cuOff)( tyents, NULL, var->typeR ); 28449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty); 28459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty)); 28469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (ty->tag == Te_UNKNOWN) 28479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return; /* perhaps we should complain in this case? */ 28489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj isVec = ty->tag == Te_TyArray; 28499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (arrays_only && !isVec) 28509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return; 28519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) {ML_(pp_TyEnt_C_ishly)(tyents, var->typeR); 28539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)(" %s\n", var->name);} 28549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Do some test evaluations of the variable's location expression, 28569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj in order to guess whether it is sp-relative, fp-relative, or 28579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj none. A crude hack, which can be interpreted roughly as finding 28589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj the first derivative of the location expression w.r.t. the 28599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj supplied frame and stack pointer values. */ 28609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 0; 28619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 28629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 6 * 1024; 2863588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_sp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 28649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 0; 28669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 28679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 7 * 1024; 2868588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_sp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 28699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 6 * 1024; 28719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 28729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 0; 2873588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_fp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 28749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 7 * 1024; 28769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 28779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 0; 2878588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_fp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 28799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_sp_7k.kind); 28819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_fp_6k.kind); 28829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_fp_7k.kind); 28839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (res_sp_6k.kind == GXR_Value) { 28859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj StackBlock block; 28869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res; 28879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj UWord sp_delta = res_sp_7k.word - res_sp_6k.word; 28889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj UWord fp_delta = res_fp_7k.word - res_fp_6k.word; 28899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(sp_delta == 0 || sp_delta == 1024); 28909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(fp_delta == 0 || fp_delta == 1024); 28919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 28929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 0 && fp_delta == 0) { 28939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* depends neither on sp nor fp, so it can't be a stack 28949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj local. Ignore it. */ 28959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 28969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else 28979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 1024 && fp_delta == 0) { 28989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = regs.fp = 0; 28999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 2900588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 29019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(res.kind == GXR_Value); 29029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 29039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)(" %5ld .. %5ld (sp) %s\n", 290450fde23467d92281b32dd537d0d9a590263628c3sewardj res.word, res.word + ((UWord)mul.ul) - 1, var->name); 29059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.base = res.word; 290650fde23467d92281b32dd537d0d9a590263628c3sewardj block.szB = (SizeT)mul.ul; 29079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.spRel = True; 29089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.isVec = isVec; 29099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)( &block.name[0], 0, sizeof(block.name) ); 29109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (var->name) 29119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 ); 29129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.name[ sizeof(block.name)-1 ] = 0; 29139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( blocks, &block ); 29149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 29159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else 29169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 0 && fp_delta == 1024) { 29179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = regs.fp = 0; 29189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 2919588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 29209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(res.kind == GXR_Value); 29219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 29229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)(" %5ld .. %5ld (FP) %s\n", 292350fde23467d92281b32dd537d0d9a590263628c3sewardj res.word, res.word + ((UWord)mul.ul) - 1, var->name); 29249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.base = res.word; 292550fde23467d92281b32dd537d0d9a590263628c3sewardj block.szB = (SizeT)mul.ul; 29269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.spRel = False; 29279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.isVec = isVec; 29289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)( &block.name[0], 0, sizeof(block.name) ); 29299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (var->name) 29309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 ); 29319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.name[ sizeof(block.name)-1 ] = 0; 29329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( blocks, &block ); 29339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 29349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else { 29359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(0); 29369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 29379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 29389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 29399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 29409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 29419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Get an XArray of StackBlock which describe the stack (auto) blocks 29429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for this ip. The caller is expected to free the XArray at some 29439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj point. If 'arrays_only' is True, only array-typed blocks are 29449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj returned; otherwise blocks of all types are returned. */ 29459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 29469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid* /* really, XArray* of StackBlock */ 29479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(di_get_stack_blocks_at_ip)( Addr ip, Bool arrays_only ) 29489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 29499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* This is a derivation of consider_vars_in_frame() above. */ 29509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word i; 29519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo* di; 29529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj RegSummary regs; 29539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool debug = False; 29549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 29559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* res = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dgsbai.1", 29569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(dinfo_free), 29579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj sizeof(StackBlock) ); 29589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 29599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj static UInt n_search = 0; 29609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj static UInt n_steps = 0; 29619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_search++; 29629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 29639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: dgsbai: ip %#lx\n", ip); 29649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* first, find the DebugInfo that pertains to 'ip'. */ 29659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (di = debugInfo_list; di; di = di->next) { 29669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_steps++; 29679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* text segment missing? unlikely, but handle it .. */ 29689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->text_present || di->text_size == 0) 29699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 29709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok. So does this text mapping bracket the ip? */ 29719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (di->text_avma <= ip && ip < di->text_avma + di->text_size) 29729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj break; 29739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 29749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 29759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Didn't find it. Strange -- means ip is a code address outside 29769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj of any mapped text segment. Unlikely but not impossible -- app 29779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj could be generating code to run. */ 29789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di) 29799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; /* currently empty */ 29809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 29819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0 && ((n_search & 0x1) == 0)) 29829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("VG_(di_get_stack_blocks_at_ip): %u searches, " 29839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj "%u DebugInfos looked at\n", 29849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_search, n_steps); 29859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Start of performance-enhancing hack: once every ??? (chosen 29869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj hackily after profiling) successful searches, move the found 29879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo one step closer to the start of the list. This makes 29889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj future searches cheaper. */ 29899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if ((n_search & 0xFFFF) == 0) { 29909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Move si one step closer to the start of the list. */ 29919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj move_DebugInfo_one_step_forward( di ); 29929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 29939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* End of performance-enhancing hack. */ 29949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 29959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* any var info at all? */ 29969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->varinfo) 29979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; /* currently empty */ 29989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 29999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Work through the scopes from most deeply nested outwards, 30009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj looking for code address ranges that bracket 'ip'. The 30019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj variables on each such address range found are in scope right 30029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj now. Don't descend to level zero as that is the global 30039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj scope. */ 30049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 30059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 0; 30069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 0; 30079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 30089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* "for each scope, working outwards ..." */ 30099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) { 30109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* vars; 30119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word j; 30129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiAddrRange* arange; 30139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj OSet* this_scope 30149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj = *(OSet**)VG_(indexXA)( di->varinfo, i ); 30159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 30169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: considering scope %ld\n", (Word)i); 30179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!this_scope) 30189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 30199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Find the set of variables in this scope that 30209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj bracket the program counter. */ 30219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj arange = VG_(OSetGen_LookupWithCmp)( 30229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj this_scope, &ip, 30239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(cmp_for_DiAddrRange_range) 30249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ); 30259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!arange) 30269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 30279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* stay sane */ 30289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(arange->aMin <= arange->aMax); 30299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* It must bracket the ip we asked for, else 30309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(cmp_for_DiAddrRange_range) is somehow broken. */ 30319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(arange->aMin <= ip && ip <= arange->aMax); 30329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* It must have an attached XArray of DiVariables. */ 30339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vars = arange->vars; 30349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(vars); 30359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* But it mustn't cover the entire address range. We only 30369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj expect that to happen for the global scope (level 0), which 30379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj we're not looking at here. Except, it may cover the entire 30389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj address range, but in that case the vars array must be 30399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj empty. */ 30409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(! (arange->aMin == (Addr)0 30419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj && arange->aMax == ~(Addr)0 30429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj && VG_(sizeXA)(vars) > 0) ); 30439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (j = 0; j < VG_(sizeXA)( vars ); j++) { 30449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j ); 30459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 30469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n", 30479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->name,arange->aMin,arange->aMax,ip); 30489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj analyse_deps( res, di->admin_tyents, ip, 3049588658b13b5ad77672f323d48fe9da0ca60b0bcbtom di, var, arrays_only ); 30509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 30519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 30529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 30539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; 30549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 30559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 30569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 30579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Get an array of GlobalBlock which describe the global blocks owned 30589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj by the shared object characterised by the given di_handle. Asserts 30599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if the handle is invalid. The caller is responsible for freeing 30609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj the array at some point. If 'arrays_only' is True, only 30619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj array-typed blocks are returned; otherwise blocks of all types are 30629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj returned. */ 30639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 30649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid* /* really, XArray* of GlobalBlock */ 30659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(di_get_global_blocks_from_dihandle) ( ULong di_handle, 30669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool arrays_only ) 30679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 30689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* This is a derivation of consider_vars_in_frame() above. */ 30699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 30709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo* di; 30719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* gvars; /* XArray* of GlobalBlock */ 30729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word nScopes, scopeIx; 30739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 30749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* The first thing to do is find the DebugInfo that 30759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj pertains to 'di_handle'. */ 30769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(di_handle > 0); 30779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (di = debugInfo_list; di; di = di->next) { 30789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (di->handle == di_handle) 30799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj break; 30809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 30819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 30829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* If this fails, we were unable to find any DebugInfo with the 30839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj given handle. This is considered an error on the part of the 30849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj caller. */ 30859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(di != NULL); 30869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 30879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* we'll put the collected variables in here. */ 30889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gvars = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dggbfd.1", 30899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(dinfo_free), sizeof(GlobalBlock) ); 30909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(gvars); 30919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 30929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* any var info at all? */ 30939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->varinfo) 30949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return gvars; 30959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 30969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* we'll iterate over all the variables we can find, even if 30979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it seems senseless to visit stack-allocated variables */ 30989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over all scopes */ 30999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj nScopes = VG_(sizeXA)( di->varinfo ); 31009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (scopeIx = 0; scopeIx < nScopes; scopeIx++) { 31019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over each (code) address range at the current scope */ 31039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiAddrRange* range; 31049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj OSet* /* of DiAddrInfo */ scope 31059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj = *(OSet**)VG_(indexXA)( di->varinfo, scopeIx ); 31069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(scope); 31079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(OSetGen_ResetIter)(scope); 31089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj while ( (range = VG_(OSetGen_Next)(scope)) ) { 31099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over each variable in the current address range */ 31119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word nVars, varIx; 31129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(range->vars); 31139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj nVars = VG_(sizeXA)( range->vars ); 31149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (varIx = 0; varIx < nVars; varIx++) { 31159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool isVec; 31179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res; 311850fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 31199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GlobalBlock gb; 31209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ty; 31219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiVariable* var = VG_(indexXA)( range->vars, varIx ); 31229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(var->name); 31239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("at depth %ld var %s ", scopeIx, var->name ); 31249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Now figure out if this variable has a constant address 31269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj (that is, independent of FP, SP, phase of moon, etc), 31279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj and if so, what the address is. Any variable with a 31289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj constant address is deemed to be a global so we collect 31299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. */ 31309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) { VG_(printf)("EVAL: "); ML_(pp_GX)(var->gexpr); 31319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("\n"); } 3132588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_trivial_GX)( var->gexpr, di ); 31339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Not a constant address => not interesting */ 31359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (res.kind != GXR_Value) { 31369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("FAIL\n"); 31379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 31389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 31399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok, it's a constant address. See if we want to collect 31419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. */ 31429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("%#lx\n", res.word); 31439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Figure out how big the variable is. */ 314550fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(di->admin_tyents, var->typeR); 31469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 314750fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 314850fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. 314950fde23467d92281b32dd537d0d9a590263628c3sewardj ML_(addVar) should have rejected it. */ 315050fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 315150fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 315250fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 315350fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a 315450fde23467d92281b32dd537d0d9a590263628c3sewardj host word safely (without loss of info). */ 31559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* skip if non-array and we're only interested in 31579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj arrays */ 31589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ty = ML_(TyEnts__index_by_cuOff)( di->admin_tyents, NULL, 31599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR ); 31609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty); 31619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty)); 31629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (ty->tag == Te_UNKNOWN) 31639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; /* perhaps we should complain in this case? */ 31649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj isVec = ty->tag == Te_TyArray; 31669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (arrays_only && !isVec) continue; 31679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok, so collect it! */ 31699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(var->name); 31709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(di->soname); 31719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("XXXX %s %s %d\n", var->name, 31729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->fileName?(HChar*)var->fileName 31739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj :"??",var->lineNo); 31749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)(&gb, 0, sizeof(gb)); 31759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gb.addr = res.word; 317650fde23467d92281b32dd537d0d9a590263628c3sewardj gb.szB = (SizeT)mul.ul; 31779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gb.isVec = isVec; 31789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)(&gb.name[0], var->name, sizeof(gb.name)-1); 31799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)(&gb.soname[0], di->soname, sizeof(gb.soname)-1); 31809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(gb.name[ sizeof(gb.name)-1 ] == 0); 31819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(gb.soname[ sizeof(gb.soname)-1 ] == 0); 31829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( gvars, &gb ); 31849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* for (varIx = 0; varIx < nVars; varIx++) */ 31869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* while ( (range = VG_(OSetGen_Next)(scope)) ) */ 31889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* for (scopeIx = 0; scopeIx < nScopes; scopeIx++) */ 31909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return gvars; 31929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 31939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 31949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 3195b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 3196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- DebugInfo accessor functions ---*/ 3197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 3198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3199b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjconst DebugInfo* VG_(next_seginfo)(const DebugInfo* di) 3200eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == NULL) 3202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return debugInfo_list; 3203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->next; 3204eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3205eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjAddr VG_(seginfo_get_text_avma)(const DebugInfo* di) 3207eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_avma : 0; 3209eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3210eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjSizeT VG_(seginfo_get_text_size)(const DebugInfo* di) 3212eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_size : 0; 3214eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3215eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3216092b6268cc4a38ae9ee41d1e3355937536ddc579bartAddr VG_(seginfo_get_plt_avma)(const DebugInfo* di) 3217092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 3218092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->plt_present ? di->plt_avma : 0; 3219092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 3220092b6268cc4a38ae9ee41d1e3355937536ddc579bart 3221092b6268cc4a38ae9ee41d1e3355937536ddc579bartSizeT VG_(seginfo_get_plt_size)(const DebugInfo* di) 3222092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 3223092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->plt_present ? di->plt_size : 0; 3224092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 3225092b6268cc4a38ae9ee41d1e3355937536ddc579bart 3226092b6268cc4a38ae9ee41d1e3355937536ddc579bartAddr VG_(seginfo_get_gotplt_avma)(const DebugInfo* di) 3227092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 3228092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->gotplt_present ? di->gotplt_avma : 0; 3229092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 3230092b6268cc4a38ae9ee41d1e3355937536ddc579bart 3231092b6268cc4a38ae9ee41d1e3355937536ddc579bartSizeT VG_(seginfo_get_gotplt_size)(const DebugInfo* di) 3232092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 3233092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->gotplt_present ? di->gotplt_size : 0; 3234092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 3235092b6268cc4a38ae9ee41d1e3355937536ddc579bart 3236b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjconst UChar* VG_(seginfo_soname)(const DebugInfo* di) 3237eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3238b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->soname; 3239b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 3240eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3241b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjconst UChar* VG_(seginfo_filename)(const DebugInfo* di) 3242b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 3243b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->filename; 3244eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3245eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3246c4431bfe04c7490ea2d74939d222d87f13f30960njnPtrdiffT VG_(seginfo_get_text_bias)(const DebugInfo* di) 3247bbec7728efefaa650970dd1f0282b77040287133sewardj{ 3248b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_bias : 0; 3249bbec7728efefaa650970dd1f0282b77040287133sewardj} 3250bbec7728efefaa650970dd1f0282b77040287133sewardj 3251b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjInt VG_(seginfo_syms_howmany) ( const DebugInfo *si ) 3252eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3253eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return si->symtab_used; 3254eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3255eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid VG_(seginfo_syms_getidx) ( const DebugInfo *si, 3257eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Int idx, 3258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/Addr* avma, 32594ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj /*OUT*/Addr* tocptr, 3260eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/UInt* size, 3261b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/HChar** name, 3262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*OUT*/Bool* isText ) 3263eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3264eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(idx >= 0 && idx < si->symtab_used); 3265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (avma) *avma = si->symtab[idx].addr; 32664ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (tocptr) *tocptr = si->symtab[idx].tocptr; 32674ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (size) *size = si->symtab[idx].size; 32684ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (name) *name = (HChar*)si->symtab[idx].name; 3269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (isText) *isText = si->symtab[idx].isText; 3270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 3271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 3274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- SectKind query functions ---*/ 3275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 3276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Convert a VgSectKind to a string, which must be copied if you want 3278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to change it. */ 3279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjconst HChar* VG_(pp_SectKind)( VgSectKind kind ) 3280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 3281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj switch (kind) { 3282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectUnknown: return "Unknown"; 3283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectText: return "Text"; 3284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectData: return "Data"; 3285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectBSS: return "BSS"; 3286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectGOT: return "GOT"; 3287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectPLT: return "PLT"; 3288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectOPD: return "OPD"; 32895706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj case Vg_SectGOTPLT: return "GOTPLT"; 3290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj default: vg_assert(0); 3291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3292b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 3293b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Given an address 'a', make a guess of which section of which object 3295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj it comes from. If name is non-NULL, then the last n_name-1 3296b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj characters of the object's name is put in name[0 .. n_name-2], and 3297b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj name[n_name-1] is set to zero (guaranteed zero terminated). */ 3298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjVgSectKind VG_(seginfo_sect_kind)( /*OUT*/UChar* name, SizeT n_name, 3300b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr a) 3301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 3302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 3303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VgSectKind res = Vg_SectUnknown; 3304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3305b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 3306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3307b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0) 3308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)( 3309a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart "addr=%#lx di=%p %s got=%#lx,%ld plt=%#lx,%ld data=%#lx,%ld bss=%#lx,%ld\n", 3310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj a, di, di->filename, 3311b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->got_avma, di->got_size, 3312b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->plt_avma, di->plt_size, 3313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_avma, di->data_size, 3314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->bss_avma, di->bss_size); 3315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 3317b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_size > 0 3318b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->text_avma && a < di->text_avma + di->text_size) { 3319b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectText; 3320b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3321b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3322b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->data_present 3323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_size > 0 3324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->data_avma && a < di->data_avma + di->data_size) { 3325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectData; 3326b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3328b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->sdata_present 3329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_size > 0 3330b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->sdata_avma && a < di->sdata_avma + di->sdata_size) { 3331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectData; 3332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->bss_present 3335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_size > 0 3336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->bss_avma && a < di->bss_avma + di->bss_size) { 3337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectBSS; 3338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 33405706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj if (di->sbss_present 33415706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->sbss_size > 0 33425706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && a >= di->sbss_avma && a < di->sbss_avma + di->sbss_size) { 33435706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj res = Vg_SectBSS; 33445706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj break; 33455706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj } 3346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->plt_present 3347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->plt_size > 0 3348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->plt_avma && a < di->plt_avma + di->plt_size) { 3349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectPLT; 3350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->got_present 3353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->got_size > 0 3354b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->got_avma && a < di->got_avma + di->got_size) { 3355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectGOT; 3356b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3358092b6268cc4a38ae9ee41d1e3355937536ddc579bart if (di->gotplt_present 3359092b6268cc4a38ae9ee41d1e3355937536ddc579bart && di->gotplt_size > 0 3360092b6268cc4a38ae9ee41d1e3355937536ddc579bart && a >= di->gotplt_avma && a < di->gotplt_avma + di->gotplt_size) { 3361092b6268cc4a38ae9ee41d1e3355937536ddc579bart res = Vg_SectGOTPLT; 3362092b6268cc4a38ae9ee41d1e3355937536ddc579bart break; 3363092b6268cc4a38ae9ee41d1e3355937536ddc579bart } 3364b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->opd_present 3365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->opd_size > 0 3366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->opd_avma && a < di->opd_avma + di->opd_size) { 3367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectOPD; 3368b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* we could also check for .eh_frame, if anyone really cares */ 3371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert( (di == NULL && res == Vg_SectUnknown) 3374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || (di != NULL && res != Vg_SectUnknown) ); 3375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (name) { 3377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_name >= 8); 3379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di && di->filename) { 3381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int i, j; 3382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int fnlen = VG_(strlen)(di->filename); 3383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int start_at = 1 + fnlen - n_name; 3384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (start_at < 0) start_at = 0; 3385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(start_at < fnlen); 3386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj i = start_at; j = 0; 3387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 3388d5dea1dabc523d3f96bafd52ae9586abd8797416bart vg_assert(j >= 0 && j < n_name); 3389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(i >= 0 && i <= fnlen); 3390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj name[j] = di->filename[i]; 3391b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->filename[i] == 0) break; 3392b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj i++; j++; 3393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3394d5dea1dabc523d3f96bafd52ae9586abd8797416bart vg_assert(i == fnlen); 3395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 3396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)(name, n_name, "%s", "???"); 3397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj name[n_name-1] = 0; 3400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return res; 3403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3404eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3405eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3406eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 3407eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- end ---*/ 3408eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 3409