debuginfo.c revision ade2eddf567a868bafad9110ed92acf7373a972b
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 110f157ddb404bcde7815a1c5bf2d7e41c114f3d73sewardj Copyright (C) 2000-2013 Julian Seward 12eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj jseward@acm.org 13eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 14eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj This program is free software; you can redistribute it and/or 15eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj modify it under the terms of the GNU General Public License as 16eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj published by the Free Software Foundation; either version 2 of the 17eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj License, or (at your option) any later version. 18eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 19eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj This program is distributed in the hope that it will be useful, but 20eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj WITHOUT ANY WARRANTY; without even the implied warranty of 21eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj General Public License for more details. 23eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 24eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj You should have received a copy of the GNU General Public License 25eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj along with this program; if not, write to the Free Software 26eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 27eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 02111-1307, USA. 28eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 29eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj The GNU General Public License is contained in the file COPYING. 30eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 31eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 32eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_basics.h" 334cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj#include "pub_core_vki.h" 346c591e15c1d6402a2a755310f005f795b68e7e38sewardj#include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy 35eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_threadstate.h" 36b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_debuginfo.h" /* self */ 37eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_demangle.h" 38eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_libcbase.h" 39eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_libcassert.h" 40eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_libcprint.h" 41b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_libcfile.h" 4213ac96dea734b3933a73524b991ac64fb48a4d57sewardj#include "pub_core_libcproc.h" // VG_(getenv) 43d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj#include "pub_core_seqmatch.h" 44eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_options.h" 45b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_redir.h" // VG_(redir_notify_{new,delete}_SegInfo) 46eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_aspacemgr.h" 47b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_machine.h" // VG_PLAT_USES_PPCTOC 4872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj#include "pub_core_xarray.h" 49b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_oset.h" 506882443ef154bca367bc591287de641e43a9e108njn#include "pub_core_stacktrace.h" // VG_(get_StackTrace) XXX: circular dependency 51f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#include "pub_core_ume.h" 52b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 53b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_misc.h" /* dinfo_zalloc/free */ 545d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj#include "priv_image.h" 55b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_d3basics.h" /* ML_(pp_GX) */ 56b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_tytypes.h" 57eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "priv_storage.h" 58eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "priv_readdwarf.h" 59eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "priv_readstabs.h" 604ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#if defined(VGO_linux) 614ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# include "priv_readelf.h" 62b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# include "priv_readdwarf3.h" 63c8259b85b701d25d72aabe9dc0a8154517f96913sewardj# include "priv_readpdb.h" 64f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(VGO_darwin) 65f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# include "priv_readmacho.h" 66f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# include "priv_readpdb.h" 674ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#endif 68eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 69c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 706f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj/* Set this to 1 to enable debug printing for the 716f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj should-we-load-debuginfo-now? finite state machine. */ 726f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj#define DEBUG_FSM 0 736f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj 746f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj 75c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/*------------------------------------------------------------*/ 76c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/*--- The _svma / _avma / _image / _bias naming scheme ---*/ 77c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/*------------------------------------------------------------*/ 78c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 79c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/* JRS 11 Jan 07: I find the different kinds of addresses involved in 80c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj debuginfo reading confusing. Recently I arrived at some 81c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj terminology which makes it clearer (to me, at least). There are 3 82c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj kinds of address used in the debuginfo reading process: 83c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 84c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj stated VMAs - the address where (eg) a .so says a symbol is, that 85c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj is, what it tells you if you consider the .so in 86c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj isolation 87c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 88c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj actual VMAs - the address where (eg) said symbol really wound up 89c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj after the .so was mapped into memory 90c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 91c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj image addresses - pointers into the copy of the .so (etc) 92c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj transiently mmaped aboard whilst we read its info 93c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 94c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj Additionally I use the term 'bias' to denote the difference 95c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj between stated and actual VMAs for a given entity. 96c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 97c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj This terminology is not used consistently, but a start has been 98c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj made. readelf.c and the call-frame info reader in readdwarf.c now 99c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj use it. Specifically, various variables and structure fields have 100f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj been annotated with _avma / _svma / _image / _bias. In places _img 101f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj is used instead of _image for the sake of brevity. 102c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj*/ 103c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 104c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 105eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 106f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- fwdses ---*/ 107f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*------------------------------------------------------------*/ 108f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 10920ede3a4f086d4a4b1e0969b1098dcb244ffb6b4philippestatic UInt CF_info_generation = 0; 1105c3dba227192de63d86f65ec7d9597c132818c37philippestatic void cfsi_m_cache__invalidate ( void ); 111f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 112f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 113f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*------------------------------------------------------------*/ 114eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Root structure ---*/ 115eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 116eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* The root structure for the entire debug info system. It is a 118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj linked list of DebugInfos. */ 119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic DebugInfo* debugInfo_list = NULL; 120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Find 'di' in the debugInfo_list and move it one step closer the the 123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj front of the list, so as to make subsequent searches for it 124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj cheaper. When used in a controlled way, makes a major improvement 125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in some DebugInfo-search-intensive situations, most notably stack 126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj unwinding on amd64-linux. */ 127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void move_DebugInfo_one_step_forward ( DebugInfo* di ) 128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo *di0, *di1, *di2; 130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == debugInfo_list) 131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; /* already at head of list */ 132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di != NULL); 133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0 = debugInfo_list; 134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1 = NULL; 135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2 = NULL; 136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 == NULL || di0 == di) break; 138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2 = di1; 139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1 = di0; 140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0 = di0->next; 141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di0 == di); 143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 != NULL && di1 != NULL && di2 != NULL) { 144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* tmp; 145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* di0 points to di, di1 to its predecessor, and di2 to di1's 146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj predecessor. Swap di0 and di1, that is, move di0 one step 147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj closer to the start of the list. */ 148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di2->next == di1); 149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di1->next == di0); 150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj tmp = di0->next; 151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->next = di0; 152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0->next = di1; 153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1->next = tmp; 154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 != NULL && di1 != NULL && di2 == NULL) { 157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* it's second in the list. */ 158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(debugInfo_list == di1); 159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di1->next == di0); 160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1->next = di0->next; 161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0->next = di1; 162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debugInfo_list = di0; 163b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 165eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 166eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 167eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 168eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Notification (acquire/discard) helpers ---*/ 169eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 170eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Gives out unique abstract handles for allocated DebugInfos. See 1729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj comment in priv_storage.h, declaration of struct _DebugInfo, for 1739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj details. */ 1749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic ULong handle_counter = 1; 1759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Allocate and zero out a new DebugInfo record. */ 177eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjstatic 1781636d33c13958b9c0e7d3059cdd5005746418eb2florianDebugInfo* alloc_DebugInfo( const HChar* filename ) 179eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool traceme; 181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 182eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 183f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj vg_assert(filename); 184f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj 1859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di = ML_(dinfo_zalloc)("di.debuginfo.aDI.1", sizeof(DebugInfo)); 186a5acac39bf3be7546222b1316faee5ee524be0d1sewardj di->handle = handle_counter++; 187a5acac39bf3be7546222b1316faee5ee524be0d1sewardj di->fsm.filename = ML_(dinfo_strdup)("di.debuginfo.aDI.2", filename); 1886b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.maps = VG_(newXA)( 1896b5625bb609b154766d2e138b61e15655f60b710sewardj ML_(dinfo_zalloc), "di.debuginfo.aDI.3", 1906b5625bb609b154766d2e138b61e15655f60b710sewardj ML_(dinfo_free), sizeof(struct _DebugInfoMapping)); 191eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 192452e89a9f847975609b3ad318943830f2cce841csewardj /* Everything else -- pointers, sizes, arrays -- is zeroed by 193452e89a9f847975609b3ad318943830f2cce841csewardj ML_(dinfo_zalloc). Now set up the debugging-output flags. */ 194f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj traceme 1950f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj = VG_(string_match)( VG_(clo_trace_symtab_patt), filename ); 196f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj if (traceme) { 197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->trace_symtab = VG_(clo_trace_symtab); 198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->trace_cfi = VG_(clo_trace_cfi); 199b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_syms = VG_(clo_debug_dump_syms); 200b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_line = VG_(clo_debug_dump_line); 201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_frames = VG_(clo_debug_dump_frames); 202f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj } 203f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj 204b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 205eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 206eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 207eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Free a DebugInfo, and also all the stuff hanging off it. */ 209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void free_DebugInfo ( DebugInfo* di ) 210eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 21159a2d18d0ddfa241850017252b0804d469187d79sewardj Word i, j, n; 2129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ent; 21359a2d18d0ddfa241850017252b0804d469187d79sewardj GExpr* gexpr; 214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di != NULL); 2166b5625bb609b154766d2e138b61e15655f60b710sewardj if (di->fsm.maps) VG_(deleteXA)(di->fsm.maps); 217a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (di->fsm.filename) ML_(dinfo_free)(di->fsm.filename); 218f1e1aa691d7a2f0f2f933daf060bec5ae6938705philippe if (di->soname) ML_(dinfo_free)(di->soname); 219a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (di->loctab) ML_(dinfo_free)(di->loctab); 22059e1f3c79e870a978d24add86db6d8c5450c8b63philippe if (di->loctab_fndn_ix) ML_(dinfo_free)(di->loctab_fndn_ix); 221a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di->inltab) ML_(dinfo_free)(di->inltab); 2225c3dba227192de63d86f65ec7d9597c132818c37philippe if (di->cfsi_base) ML_(dinfo_free)(di->cfsi_base); 2235c3dba227192de63d86f65ec7d9597c132818c37philippe if (di->cfsi_m_ix) ML_(dinfo_free)(di->cfsi_m_ix); 2245c3dba227192de63d86f65ec7d9597c132818c37philippe if (di->cfsi_rd) ML_(dinfo_free)(di->cfsi_rd); 2255c3dba227192de63d86f65ec7d9597c132818c37philippe if (di->cfsi_m_pool) VG_(deleteDedupPA)(di->cfsi_m_pool); 226a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (di->cfsi_exprs) VG_(deleteXA)(di->cfsi_exprs); 227a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (di->fpo) ML_(dinfo_free)(di->fpo); 228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 229a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (di->symtab) { 230a5cace0c2a3e212931badbf6398a0cd98393121asewardj /* We have to visit all the entries so as to free up any 231a5cace0c2a3e212931badbf6398a0cd98393121asewardj sec_names arrays that might exist. */ 232a5cace0c2a3e212931badbf6398a0cd98393121asewardj n = di->symtab_used; 233a5cace0c2a3e212931badbf6398a0cd98393121asewardj for (i = 0; i < n; i++) { 234a5cace0c2a3e212931badbf6398a0cd98393121asewardj DiSym* sym = &di->symtab[i]; 235a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (sym->sec_names) 236a5cace0c2a3e212931badbf6398a0cd98393121asewardj ML_(dinfo_free)(sym->sec_names); 237a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 238a5cace0c2a3e212931badbf6398a0cd98393121asewardj /* and finally .. */ 239a5cace0c2a3e212931badbf6398a0cd98393121asewardj ML_(dinfo_free)(di->symtab); 240a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 241a5cace0c2a3e212931badbf6398a0cd98393121asewardj 2422352e9843d8a616b9d829aef929d218aea9b4ae0philippe if (di->strpool) 2432352e9843d8a616b9d829aef929d218aea9b4ae0philippe VG_(deleteDedupPA) (di->strpool); 24459e1f3c79e870a978d24add86db6d8c5450c8b63philippe if (di->fndnpool) 24559e1f3c79e870a978d24add86db6d8c5450c8b63philippe VG_(deleteDedupPA) (di->fndnpool); 246b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Delete the two admin arrays. These lists exist primarily so 2489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj that we can visit each object exactly once when we need to 2499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj delete them. */ 2509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (di->admin_tyents) { 2519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n = VG_(sizeXA)(di->admin_tyents); 25259a2d18d0ddfa241850017252b0804d469187d79sewardj for (i = 0; i < n; i++) { 2539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ent = (TyEnt*)VG_(indexXA)(di->admin_tyents, i); 2549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Dump anything hanging off this ent */ 2559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(TyEnt__make_EMPTY)(ent); 25659a2d18d0ddfa241850017252b0804d469187d79sewardj } 2579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(deleteXA)(di->admin_tyents); 2589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->admin_tyents = NULL; 259eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 26059a2d18d0ddfa241850017252b0804d469187d79sewardj 26159a2d18d0ddfa241850017252b0804d469187d79sewardj if (di->admin_gexprs) { 26259a2d18d0ddfa241850017252b0804d469187d79sewardj n = VG_(sizeXA)(di->admin_gexprs); 26359a2d18d0ddfa241850017252b0804d469187d79sewardj for (i = 0; i < n; i++) { 26459a2d18d0ddfa241850017252b0804d469187d79sewardj gexpr = *(GExpr**)VG_(indexXA)(di->admin_gexprs, i); 26559a2d18d0ddfa241850017252b0804d469187d79sewardj ML_(dinfo_free)(gexpr); 26659a2d18d0ddfa241850017252b0804d469187d79sewardj } 26759a2d18d0ddfa241850017252b0804d469187d79sewardj VG_(deleteXA)(di->admin_gexprs); 26859a2d18d0ddfa241850017252b0804d469187d79sewardj di->admin_gexprs = NULL; 269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Dump the variable info. This is kinda complex: we must take 272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj care not to free items which reside in either the admin lists 273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (as we have just freed them) or which reside in the DebugInfo's 274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj string table. */ 275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->varinfo) { 276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = 0; i < VG_(sizeXA)(di->varinfo); i++) { 277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* scope = *(OSet**)VG_(indexXA)(di->varinfo, i); 278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!scope) continue; 279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* iterate over all entries in 'scope' */ 280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(OSetGen_ResetIter)(scope); 281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* arange = VG_(OSetGen_Next)(scope); 283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!arange) break; 284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* for each var in 'arange' */ 285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->vars); 286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < VG_(sizeXA)( arange->vars ); j++) { 287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)(arange->vars,j); 288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var); 289b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Nothing to free in var: all the pointer fields refer 290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to stuff either on an admin list, or in 2917293d2530f8c60c1060f9f003e214cc341d35266philippe .strpool */ 292b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 293b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)(arange->vars); 294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Don't free arange itself, as OSetGen_Destroy does 295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj that */ 296b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 297b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(OSetGen_Destroy)(scope); 298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)(di->varinfo); 300b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(dinfo_free)(di); 303eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 304eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 305eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* 'si' is a member of debugInfo_list. Find it, remove it from the 307eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj list, notify m_redir that this has happened, and free all storage 308eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj reachable from it. 309eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void discard_DebugInfo ( DebugInfo* di ) 311eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3126bd9dc18c043927c1196caba20a327238a179c42florian const HChar* reason = "munmap"; 3134ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo** prev_next_ptr = &debugInfo_list; 315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* curr = debugInfo_list; 316eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 317eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj while (curr) { 318b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (curr == di) { 319b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Found it; remove from list and free it. */ 32033e4e7eaab263cea956700f56f007ab26c39eab4sewardj if (curr->have_dinfo 32133e4e7eaab263cea956700f56f007ab26c39eab4sewardj && (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))) 322eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(message)(Vg_DebugMsg, 323738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Discarding syms at %#lx-%#lx in %s due to %s()\n", 324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_avma, 325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->text_avma + di->text_size, 326a5acac39bf3be7546222b1316faee5ee524be0d1sewardj curr->fsm.filename ? curr->fsm.filename 3271636d33c13958b9c0e7d3059cdd5005746418eb2florian : "???", 3284ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj reason); 329eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(*prev_next_ptr == curr); 330eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *prev_next_ptr = curr->next; 33133e4e7eaab263cea956700f56f007ab26c39eab4sewardj if (curr->have_dinfo) 33233e4e7eaab263cea956700f56f007ab26c39eab4sewardj VG_(redir_notify_delete_DebugInfo)( curr ); 333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj free_DebugInfo(curr); 334eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return; 335eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 336eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj prev_next_ptr = &curr->next; 337eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj curr = curr->next; 338eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 339eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Not found. */ 341eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 342eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 343eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Repeatedly scan debugInfo_list, looking for DebugInfos with text 345b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj AVMAs intersecting [start,start+length), and call discard_DebugInfo 346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to get rid of them. This modifies the list, hence the multiple 347f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj iterations. Returns True iff any such DebugInfos were found. 348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/ 349f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic Bool discard_syms_in_range ( Addr start, SizeT length ) 350eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 351f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool anyFound = False; 352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool found; 353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* curr; 354eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 355eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj while (True) { 356eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj found = False; 357eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 358b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj curr = debugInfo_list; 359eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj while (True) { 360eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (curr == NULL) 361eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; 362b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (curr->text_present 363b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && curr->text_size > 0 364b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && (start+length - 1 < curr->text_avma 365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || curr->text_avma + curr->text_size - 1 < start)) { 366eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* no overlap */ 367eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 368eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj found = True; 369eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; 370eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 371eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj curr = curr->next; 372eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 373eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 374eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (!found) break; 375f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj anyFound = True; 376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_DebugInfo( curr ); 377eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 378f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 379f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return anyFound; 380eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 381eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 382eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Does [s1,+len1) overlap [s2,+len2) ? Note: does not handle 384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj wraparound at the end of the address space -- just asserts in that 385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case. */ 386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Bool ranges_overlap (Addr s1, SizeT len1, Addr s2, SizeT len2 ) 387eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr e1, e2; 389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (len1 == 0 || len2 == 0) 390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 391b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj e1 = s1 + len1 - 1; 392b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj e2 = s2 + len2 - 1; 393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Assert that we don't have wraparound. If we do it would imply 394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj that file sections are getting mapped around the end of the 395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj address space, which sounds unlikely. */ 396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(s1 <= e1); 397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(s2 <= e2); 398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (e1 < s2 || e2 < s1) return False; 399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 401eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 402eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4036b5625bb609b154766d2e138b61e15655f60b710sewardj/* Do the basic mappings of the two DebugInfos overlap in any way? */ 404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Bool do_DebugInfos_overlap ( DebugInfo* di1, DebugInfo* di2 ) 405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 4066b5625bb609b154766d2e138b61e15655f60b710sewardj Word i, j; 407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di1); 408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di2); 4096b5625bb609b154766d2e138b61e15655f60b710sewardj for (i = 0; i < VG_(sizeXA)(di1->fsm.maps); i++) { 4106b5625bb609b154766d2e138b61e15655f60b710sewardj struct _DebugInfoMapping* map1 = VG_(indexXA)(di1->fsm.maps, i); 4116b5625bb609b154766d2e138b61e15655f60b710sewardj for (j = 0; j < VG_(sizeXA)(di2->fsm.maps); j++) { 4126b5625bb609b154766d2e138b61e15655f60b710sewardj struct _DebugInfoMapping* map2 = VG_(indexXA)(di2->fsm.maps, j); 4136b5625bb609b154766d2e138b61e15655f60b710sewardj if (ranges_overlap(map1->avma, map1->size, map2->avma, map2->size)) 4146b5625bb609b154766d2e138b61e15655f60b710sewardj return True; 4156b5625bb609b154766d2e138b61e15655f60b710sewardj } 4166b5625bb609b154766d2e138b61e15655f60b710sewardj } 417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Discard all elements of debugInfo_list whose .mark bit is set. 423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/ 424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void discard_marked_DebugInfos ( void ) 425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* curr; 427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj curr = debugInfo_list; 431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!curr) 433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (curr->mark) 435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj curr = curr->next; 437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!curr) break; 440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_DebugInfo( curr ); 441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Discard any elements of debugInfo_list which overlap with diRef. 4476b5625bb609b154766d2e138b61e15655f60b710sewardj Clearly diRef must have its mapping information set to something sane. */ 448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void discard_DebugInfos_which_overlap_with ( DebugInfo* diRef ) 449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Mark all the DebugInfos in debugInfo_list that need to be 452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj deleted. First, clear all the mark bits; then set them if they 453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj overlap with siRef. Since siRef itself is in this list we at 454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj least expect its own mark bit to be set. */ 455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di; di = di->next) { 456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->mark = do_DebugInfos_overlap( di, diRef ); 457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == diRef) { 458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di->mark); 459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->mark = False; 460b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 461eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 462b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj discard_marked_DebugInfos(); 463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 464b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 465eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4660f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj/* Find the existing DebugInfo for |filename| or if not found, create 4670f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj one. In the latter case |filename| is strdup'd into VG_AR_DINFO, 4680f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj and the new DebugInfo is added to debugInfo_list. */ 4691636d33c13958b9c0e7d3059cdd5005746418eb2florianstatic DebugInfo* find_or_create_DebugInfo_for ( HChar* filename ) 470b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 471b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 472b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(filename); 473b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di; di = di->next) { 474a5acac39bf3be7546222b1316faee5ee524be0d1sewardj vg_assert(di->fsm.filename); 475a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (0==VG_(strcmp)(di->fsm.filename, filename)) 476b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 477b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 478b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di) { 4790f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj di = alloc_DebugInfo(filename); 480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di); 481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->next = debugInfo_list; 482b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debugInfo_list = di; 483b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 484b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 485eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 486eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 487eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 488f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Debuginfo reading for 'di' has just been successfully completed. 489f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Check that the invariants stated in 490f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj "Comment_on_IMPORTANT_CFSI_REPRESENTATIONAL_INVARIANTS" in 491f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj priv_storage.h are observed. */ 492f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic void check_CFSI_related_invariants ( DebugInfo* di ) 493f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 494f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo* di2 = NULL; 4956b5625bb609b154766d2e138b61e15655f60b710sewardj Bool has_nonempty_rx = False; 4966b5625bb609b154766d2e138b61e15655f60b710sewardj Bool cfsi_fits = False; 4976b5625bb609b154766d2e138b61e15655f60b710sewardj Word i, j; 498f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di); 499f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* This fn isn't called until after debuginfo for this object has 500f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj been successfully read. And that shouldn't happen until we have 501f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj both a r-x and rw- mapping for the object. Hence: */ 502a5acac39bf3be7546222b1316faee5ee524be0d1sewardj vg_assert(di->fsm.have_rx_map); 503a5acac39bf3be7546222b1316faee5ee524be0d1sewardj vg_assert(di->fsm.have_rw_map); 5046b5625bb609b154766d2e138b61e15655f60b710sewardj for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { 5056b5625bb609b154766d2e138b61e15655f60b710sewardj struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i); 5066b5625bb609b154766d2e138b61e15655f60b710sewardj /* We are interested in r-x mappings only */ 5076b5625bb609b154766d2e138b61e15655f60b710sewardj if (!map->rx) 508f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj continue; 5096b5625bb609b154766d2e138b61e15655f60b710sewardj 5106b5625bb609b154766d2e138b61e15655f60b710sewardj /* degenerate case: r-x section is empty */ 5116b5625bb609b154766d2e138b61e15655f60b710sewardj if (map->size == 0) 512f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj continue; 5136b5625bb609b154766d2e138b61e15655f60b710sewardj has_nonempty_rx = True; 5146b5625bb609b154766d2e138b61e15655f60b710sewardj 5156b5625bb609b154766d2e138b61e15655f60b710sewardj /* normal case: r-x section is nonempty */ 5166b5625bb609b154766d2e138b61e15655f60b710sewardj /* invariant (0) */ 5176b5625bb609b154766d2e138b61e15655f60b710sewardj vg_assert(map->size > 0); 5186b5625bb609b154766d2e138b61e15655f60b710sewardj 5196b5625bb609b154766d2e138b61e15655f60b710sewardj /* invariant (1) */ 5206b5625bb609b154766d2e138b61e15655f60b710sewardj for (di2 = debugInfo_list; di2; di2 = di2->next) { 5216b5625bb609b154766d2e138b61e15655f60b710sewardj if (di2 == di) 5226b5625bb609b154766d2e138b61e15655f60b710sewardj continue; 5236b5625bb609b154766d2e138b61e15655f60b710sewardj for (j = 0; j < VG_(sizeXA)(di2->fsm.maps); j++) { 5246b5625bb609b154766d2e138b61e15655f60b710sewardj struct _DebugInfoMapping* map2 = VG_(indexXA)(di2->fsm.maps, j); 5256b5625bb609b154766d2e138b61e15655f60b710sewardj if (!map2->rx || map2->size == 0) 5266b5625bb609b154766d2e138b61e15655f60b710sewardj continue; 5276b5625bb609b154766d2e138b61e15655f60b710sewardj vg_assert(!ranges_overlap(map->avma, map->size, 5286b5625bb609b154766d2e138b61e15655f60b710sewardj map2->avma, map2->size)); 5296b5625bb609b154766d2e138b61e15655f60b710sewardj } 5306b5625bb609b154766d2e138b61e15655f60b710sewardj } 5316b5625bb609b154766d2e138b61e15655f60b710sewardj di2 = NULL; 5326b5625bb609b154766d2e138b61e15655f60b710sewardj 5336b5625bb609b154766d2e138b61e15655f60b710sewardj /* invariant (2) */ 5345c3dba227192de63d86f65ec7d9597c132818c37philippe if (di->cfsi_rd) { 5356b5625bb609b154766d2e138b61e15655f60b710sewardj vg_assert(di->cfsi_minavma <= di->cfsi_maxavma); /* duh! */ 5366b5625bb609b154766d2e138b61e15655f60b710sewardj /* Assume the csfi fits completely into one individual mapping 5376b5625bb609b154766d2e138b61e15655f60b710sewardj for now. This might need to be improved/reworked later. */ 5386b5625bb609b154766d2e138b61e15655f60b710sewardj if (di->cfsi_minavma >= map->avma && 5396b5625bb609b154766d2e138b61e15655f60b710sewardj di->cfsi_maxavma < map->avma + map->size) 5406b5625bb609b154766d2e138b61e15655f60b710sewardj cfsi_fits = True; 5416b5625bb609b154766d2e138b61e15655f60b710sewardj } 542f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 5436b5625bb609b154766d2e138b61e15655f60b710sewardj 5446b5625bb609b154766d2e138b61e15655f60b710sewardj /* degenerate case: all r-x sections are empty */ 5456b5625bb609b154766d2e138b61e15655f60b710sewardj if (!has_nonempty_rx) { 5465c3dba227192de63d86f65ec7d9597c132818c37philippe vg_assert(di->cfsi_rd == NULL); 5476b5625bb609b154766d2e138b61e15655f60b710sewardj return; 548f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 5496b5625bb609b154766d2e138b61e15655f60b710sewardj 5506b5625bb609b154766d2e138b61e15655f60b710sewardj /* invariant (2) - cont. */ 5515c3dba227192de63d86f65ec7d9597c132818c37philippe if (di->cfsi_rd) 5526b5625bb609b154766d2e138b61e15655f60b710sewardj vg_assert(cfsi_fits); 5536b5625bb609b154766d2e138b61e15655f60b710sewardj 554f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* invariants (3) and (4) */ 5555c3dba227192de63d86f65ec7d9597c132818c37philippe if (di->cfsi_rd) { 556f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_used > 0); 557f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_size > 0); 558f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (i = 0; i < di->cfsi_used; i++) { 5595c3dba227192de63d86f65ec7d9597c132818c37philippe DiCfSI* cfsi = &di->cfsi_rd[i]; 560f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsi->len > 0); 561f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsi->base >= di->cfsi_minavma); 562f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsi->base + cfsi->len - 1 <= di->cfsi_maxavma); 563f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (i > 0) { 5645c3dba227192de63d86f65ec7d9597c132818c37philippe DiCfSI* cfsip = &di->cfsi_rd[i-1]; 565f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(cfsip->base + cfsip->len <= cfsi->base); 566f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 567f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 568f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 569f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_used == 0); 570f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di->cfsi_size == 0); 571f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 572f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 573f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 574f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 575f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--------------------------------------------------------------*/ 576f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- ---*/ 577f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- TOP LEVEL: INITIALISE THE DEBUGINFO SYSTEM ---*/ 578f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- ---*/ 579f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--------------------------------------------------------------*/ 580f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 581f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjvoid VG_(di_initialise) ( void ) 582f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 583f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* There's actually very little to do here, since everything 584f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj centers around the DebugInfos in debugInfo_list, they are 585f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj created and destroyed on demand, and each one is treated more or 586f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj less independently. */ 587f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(debugInfo_list == NULL); 588f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 589f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* flush the CFI fast query cache. */ 5905c3dba227192de63d86f65ec7d9597c132818c37philippe cfsi_m_cache__invalidate(); 591f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 592f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 593f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 5944ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--------------------------------------------------------------*/ 5954ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- ---*/ 5964ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- TOP LEVEL: NOTIFICATION (ACQUIRE/DISCARD INFO) (LINUX) ---*/ 5974ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--- ---*/ 5984ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/*--------------------------------------------------------------*/ 5994ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 600f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VGO_linux) || defined(VGO_darwin) 601eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 602eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* The debug info system is driven by notifications that a text 603731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj segment has been mapped in, or unmapped, or when sections change 604731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj permission. It's all a bit kludgey and basically means watching 605731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj syscalls, trying to second-guess when the system's dynamic linker 606731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj is done with mapping in a new object for execution. This is all 607731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj tracked using the DebugInfoFSM struct for the object. Anyway, once 608731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj we finally decide we've got to an accept state, this section then 609731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj will acquire whatever info is available for the corresponding 610731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj object. This section contains the notification handlers, which 611731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj update the FSM and determine when an accept state has been reached. 612731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj*/ 613731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 614731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj/* When the sequence of observations causes a DebugInfoFSM to move 615731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj into the accept state, call here to actually get the debuginfo read 616731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj in. Returns a ULong whose purpose is described in comments 617731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj preceding VG_(di_notify_mmap) just below. 618731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj*/ 619731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardjstatic ULong di_notify_ACHIEVE_ACCEPT_STATE ( struct _DebugInfo* di ) 620731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj{ 621731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj ULong di_handle; 622731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj Bool ok; 623731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 624731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj vg_assert(di->fsm.filename); 625731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n"); 626731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("------ start ELF OBJECT " 627731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj "------------------------------\n"); 628731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("------ name = %s\n", di->fsm.filename); 629731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n"); 630731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 631731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* We're going to read symbols and debug info for the avma 6326b5625bb609b154766d2e138b61e15655f60b710sewardj ranges specified in the _DebugInfoFsm mapping array. First 6336b5625bb609b154766d2e138b61e15655f60b710sewardj get rid of any other DebugInfos which overlap any of those 6346b5625bb609b154766d2e138b61e15655f60b710sewardj ranges (to avoid total confusion). */ 635731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj discard_DebugInfos_which_overlap_with( di ); 636731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 637731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* .. and acquire new info. */ 638731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# if defined(VGO_linux) 639731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj ok = ML_(read_elf_debug_info)( di ); 640731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# elif defined(VGO_darwin) 641731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj ok = ML_(read_macho_debug_info)( di ); 642731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# else 643731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# error "unknown OS" 644731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# endif 645731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 646731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (ok) { 647731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 648731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n------ Canonicalising the " 649731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj "acquired info ------\n"); 650731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* invalidate the CFI unwind cache. */ 6515c3dba227192de63d86f65ec7d9597c132818c37philippe cfsi_m_cache__invalidate(); 652731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* prepare read data for use */ 653731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj ML_(canonicaliseTables)( di ); 6545c3dba227192de63d86f65ec7d9597c132818c37philippe /* Check invariants listed in 6555c3dba227192de63d86f65ec7d9597c132818c37philippe Comment_on_IMPORTANT_REPRESENTATIONAL_INVARIANTS in 6565c3dba227192de63d86f65ec7d9597c132818c37philippe priv_storage.h. */ 6575c3dba227192de63d86f65ec7d9597c132818c37philippe check_CFSI_related_invariants(di); 6585c3dba227192de63d86f65ec7d9597c132818c37philippe ML_(finish_CFSI_arrays)(di); 659731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* notify m_redir about it */ 660731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n------ Notifying m_redir ------\n"); 661731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj VG_(redir_notify_new_DebugInfo)( di ); 662731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Note that we succeeded */ 663731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj di->have_dinfo = True; 664731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj tl_assert(di->handle > 0); 665731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj di_handle = di->handle; 666731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 667731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj } else { 668731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n------ ELF reading failed ------\n"); 669731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Something went wrong (eg. bad ELF file). Should we delete 670731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj this DebugInfo? No - it contains info on the rw/rx 671731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj mappings, at least. */ 672731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj di_handle = 0; 673731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj vg_assert(di->have_dinfo == False); 674731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj } 675731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 676731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n"); 677731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("------ name = %s\n", di->fsm.filename); 678731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("------ end ELF OBJECT " 679731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj "------------------------------\n"); 680731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n"); 681731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 682731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return di_handle; 683731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj} 684731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 685eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 686eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Notify the debuginfo system about a new mapping. This is the way 687eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj new debug information gets loaded. If allow_SkFileV is True, it 688eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj will try load debug info if the mapping at 'a' belongs to Valgrind; 689eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj whereas normally (False) it will not do that. This allows us to 690eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj carefully control when the thing will read symbols from the 6919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Valgrind executable itself. 6929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 6935f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj If use_fd is not -1, that is used instead of the filename; this 6945f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj avoids perturbing fcntl locks, which are released by simply 6955f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj re-opening and closing the same file (even via different fd!). 6965f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj 6979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj If a call to VG_(di_notify_mmap) causes debug info to be read, then 6989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj the returned ULong is an abstract handle which can later be used to 6999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj refer to the debuginfo read as a result of this specific mapping, 7009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj in later queries to m_debuginfo. In this case the handle value 7019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj will be one or above. If the returned value is zero, no debug info 7029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj was read. */ 703eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 7045f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardjULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd ) 705eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 7064ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj NSegment const * seg; 707b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj HChar* filename; 708731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj Bool is_rx_map, is_rw_map, is_ro_map; 709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 7105f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj Int actual_fd, oflags; 7115f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj SysRes preadres; 712b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj HChar buf1k[1024]; 7136f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj Bool debug = (DEBUG_FSM != 0); 714ec61b6509566cf36ab3968d69226cecf177cb0fesewardj SysRes statres; 715ec61b6509566cf36ab3968d69226cecf177cb0fesewardj struct vg_stat statbuf; 716b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 7175f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj vg_assert(use_fd >= -1); 7185f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj 719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* In short, figure out if this mapping is of interest to us, and 720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if so, try to guess what ld.so is doing and when/if we should 721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj read debug info. */ 722b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg = VG_(am_find_nsegment)(a); 723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(seg); 724eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 7256f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) { 7266f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_mmap-0:\n"); 727a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("di_notify_mmap-1: %#lx-%#lx %c%c%c\n", 728b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->start, seg->end, 729b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->hasR ? 'r' : '-', 730b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->hasW ? 'w' : '-',seg->hasX ? 'x' : '-' ); 7316f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj } 732eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 733b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* guaranteed by aspacemgr-linux.c, sane_NSegment() */ 734b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(seg->end > seg->start); 735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 736b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ignore non-file mappings */ 737b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( ! (seg->kind == SkFileC 738b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || (seg->kind == SkFileV && allow_SkFileV)) ) 7399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 740b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 741b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* If the file doesn't have a name, we're hosed. Give up. */ 7423e7986312a0ffc7646b0552d4c4ea3744a870e73florian filename = VG_(am_get_filename)( seg ); 743b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!filename) 7449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 745b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 7460ab84fe82d1e25c2e0544d08826df42caa44ded1bart /* 7470ab84fe82d1e25c2e0544d08826df42caa44ded1bart * Cannot read from these magic files: 7480ab84fe82d1e25c2e0544d08826df42caa44ded1bart * --20208-- WARNING: Serious error when reading debug info 7490ab84fe82d1e25c2e0544d08826df42caa44ded1bart * --20208-- When reading debug info from /proc/xen/privcmd: 7500ab84fe82d1e25c2e0544d08826df42caa44ded1bart * --20208-- can't read file to inspect ELF header 7510ab84fe82d1e25c2e0544d08826df42caa44ded1bart */ 7520ab84fe82d1e25c2e0544d08826df42caa44ded1bart if (VG_(strncmp)(filename, "/proc/xen/", 10) == 0) 7530ab84fe82d1e25c2e0544d08826df42caa44ded1bart return 0; 7540ab84fe82d1e25c2e0544d08826df42caa44ded1bart 755b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 756b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("di_notify_mmap-2: %s\n", filename); 757b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 758ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* Only try to read debug information from regular files. */ 75915728ab41ea41bf731dcc74ac68354550ced2189bart statres = VG_(stat)(filename, &statbuf); 760ec61b6509566cf36ab3968d69226cecf177cb0fesewardj 761ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* stat dereferences symlinks, so we don't expect it to succeed and 762ec61b6509566cf36ab3968d69226cecf177cb0fesewardj yet produce something that is a symlink. */ 7639c20ece00e07304f66da5f43b87ec45bc9c04550njn vg_assert(sr_isError(statres) || ! VKI_S_ISLNK(statbuf.mode)); 764ec61b6509566cf36ab3968d69226cecf177cb0fesewardj 765ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* Don't let the stat call fail silently. Filter out some known 766ec61b6509566cf36ab3968d69226cecf177cb0fesewardj sources of noise before complaining, though. */ 767cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(statres)) { 768ec61b6509566cf36ab3968d69226cecf177cb0fesewardj DebugInfo fake_di; 769ec61b6509566cf36ab3968d69226cecf177cb0fesewardj Bool quiet = VG_(strstr)(filename, "/var/run/nscd/") != NULL; 770e025eca1d49cdfe5a8cb58ab495763434280333asewardj if (!quiet && VG_(clo_verbosity) > 1) { 771ec61b6509566cf36ab3968d69226cecf177cb0fesewardj VG_(memset)(&fake_di, 0, sizeof(fake_di)); 772a5acac39bf3be7546222b1316faee5ee524be0d1sewardj fake_di.fsm.filename = filename; 773ec61b6509566cf36ab3968d69226cecf177cb0fesewardj ML_(symerr)(&fake_di, True, "failed to stat64/stat this file"); 774ec61b6509566cf36ab3968d69226cecf177cb0fesewardj } 7759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 7762ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj } 7772ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj 778ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* Finally, the point of all this stattery: if it's not a regular file, 779ec61b6509566cf36ab3968d69226cecf177cb0fesewardj don't try to read debug info from it. */ 7809c20ece00e07304f66da5f43b87ec45bc9c04550njn if (! VKI_S_ISREG(statbuf.mode)) 7819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 782ec61b6509566cf36ab3968d69226cecf177cb0fesewardj 783ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* no uses of statbuf below here. */ 78415728ab41ea41bf731dcc74ac68354550ced2189bart 785b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Now we have to guess if this is a text-like mapping, a data-like 786b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj mapping, neither or both. The rules are: 787b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 788b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj text if: x86-linux r and x 789b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj other-linux r and x and not w 790b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 791b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data if: x86-linux r and w 792b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj other-linux r and w and not x 793b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 794b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Background: On x86-linux, objects are typically mapped twice: 795eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 796eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1b8fb000-1b8ff000 r-xp 00000000 08:02 4471477 vgpreload_memcheck.so 797eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1b8ff000-1b900000 rw-p 00004000 08:02 4471477 vgpreload_memcheck.so 798eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 799eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj whereas ppc32-linux mysteriously does this: 800eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 801eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118a6000-118ad000 r-xp 00000000 08:05 14209428 vgpreload_memcheck.so 802eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118ad000-118b6000 ---p 00007000 08:05 14209428 vgpreload_memcheck.so 803eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118b6000-118bd000 rwxp 00000000 08:05 14209428 vgpreload_memcheck.so 804eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 805eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj The third mapping should not be considered to have executable 806eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj code in. Therefore a test which works for both is: r and x and 807eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj NOT w. Reading symbols from the rwx segment -- which overlaps 808eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj the r-x segment in the file -- causes the redirection mechanism 809eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj to redirect to addresses in that third segment, which is wrong 810eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj and causes crashes. 811eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 812eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj JRS 28 Dec 05: unfortunately icc 8.1 on x86 has been seen to 813eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj produce executables with a single rwx segment rather than a 814eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj (r-x,rw-) pair. That means the rules have to be modified thusly: 815eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 816eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj x86-linux: consider if r and x 817b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj all others: consider if r and x and not w 818f56d255d644ec9a1bfa970d50a0489a816a4e736sewardj 819f56d255d644ec9a1bfa970d50a0489a816a4e736sewardj 2009 Aug 16: apply similar kludge to ppc32-linux. 820f56d255d644ec9a1bfa970d50a0489a816a4e736sewardj See http://bugs.kde.org/show_bug.cgi?id=190820 821b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 822b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj There are two modes on s390x: with and without the noexec kernel 823b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj parameter. Together with some older kernels, this leads to several 824b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj variants: 825b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj executable: r and x 826b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj data: r and w and x 827b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj or 828b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj executable: r and x 829b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj data: r and w 830eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj */ 831b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = False; 832b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = False; 833731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj is_ro_map = False; 834731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 8354df0bfc0614379192c780c944415dc420d9cfe8epetarj# if defined(VGA_x86) || defined(VGA_ppc32) || defined(VGA_mips32) \ 8364df0bfc0614379192c780c944415dc420d9cfe8epetarj || defined(VGA_mips64) 837b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = seg->hasR && seg->hasX; 838b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = seg->hasR && seg->hasW; 839f0c1250e324f6684757c6a15545366447ef1d64fsewardj# elif defined(VGA_amd64) || defined(VGA_ppc64) || defined(VGA_arm) \ 840f0c1250e324f6684757c6a15545366447ef1d64fsewardj || defined(VGA_arm64) 841b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = seg->hasR && seg->hasX && !seg->hasW; 842b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = seg->hasR && seg->hasW && !seg->hasX; 843b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGP_s390x_linux) 844b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj is_rx_map = seg->hasR && seg->hasX && !seg->hasW; 845b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj is_rw_map = seg->hasR && seg->hasW; 846eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# else 847b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# error "Unknown platform" 848eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# endif 849eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 850588cd4ebce3305d0cf91896c1f6322ef9775d6c1sewardj# if defined(VGP_x86_darwin) && DARWIN_VERS >= DARWIN_10_7 851731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj is_ro_map = seg->hasR && !seg->hasW && !seg->hasX; 852731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# endif 853731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 854b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 8556f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_mmap-3: " 8566f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj "is_rx_map %d, is_rw_map %d, is_ro_map %d\n", 8576f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj (Int)is_rx_map, (Int)is_rw_map, (Int)is_ro_map); 858eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 859731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Ignore mappings with permissions we can't possibly be interested in. */ 860731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (!(is_rx_map || is_rw_map || is_ro_map)) 8619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 862eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 8635a5eec0923d55afc94165721d25125d5fc8f24d8sewardj /* Peer at the first few bytes of the file, to see if it is an ELF */ 8645a5eec0923d55afc94165721d25125d5fc8f24d8sewardj /* object file. Ignore the file if we do not have read permission. */ 8655a5eec0923d55afc94165721d25125d5fc8f24d8sewardj VG_(memset)(buf1k, 0, sizeof(buf1k)); 866cec083d9a254e92623ed44e9dca080d224693c82sewardj oflags = VKI_O_RDONLY; 867cec083d9a254e92623ed44e9dca080d224693c82sewardj# if defined(VKI_O_LARGEFILE) 868cec083d9a254e92623ed44e9dca080d224693c82sewardj oflags |= VKI_O_LARGEFILE; 869cec083d9a254e92623ed44e9dca080d224693c82sewardj# endif 8705f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj 8715f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (use_fd == -1) { 8725f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj SysRes fd = VG_(open)( filename, oflags, 0 ); 8735f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (sr_isError(fd)) { 8745f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (sr_Err(fd) != VKI_EACCES) { 8755f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj DebugInfo fake_di; 8765f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj VG_(memset)(&fake_di, 0, sizeof(fake_di)); 8775f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj fake_di.fsm.filename = filename; 8785f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj ML_(symerr)(&fake_di, True, 8795f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj "can't open file to inspect ELF header"); 8805f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj } 8815f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj return 0; 8825a5eec0923d55afc94165721d25125d5fc8f24d8sewardj } 8835f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj actual_fd = sr_Res(fd); 8845f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj } else { 8855f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj actual_fd = use_fd; 8865a5eec0923d55afc94165721d25125d5fc8f24d8sewardj } 8875a5eec0923d55afc94165721d25125d5fc8f24d8sewardj 8885f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj preadres = VG_(pread)( actual_fd, buf1k, sizeof(buf1k), 0 ); 8895f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (use_fd == -1) { 8905f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj VG_(close)( actual_fd ); 8915f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj } 8925f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj 8935f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (sr_isError(preadres)) { 8945a5eec0923d55afc94165721d25125d5fc8f24d8sewardj DebugInfo fake_di; 8955a5eec0923d55afc94165721d25125d5fc8f24d8sewardj VG_(memset)(&fake_di, 0, sizeof(fake_di)); 896a5acac39bf3be7546222b1316faee5ee524be0d1sewardj fake_di.fsm.filename = filename; 8975a5eec0923d55afc94165721d25125d5fc8f24d8sewardj ML_(symerr)(&fake_di, True, "can't read file to inspect ELF header"); 8985a5eec0923d55afc94165721d25125d5fc8f24d8sewardj return 0; 8995a5eec0923d55afc94165721d25125d5fc8f24d8sewardj } 9005f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (sr_Res(preadres) == 0) 9015f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj return 0; 9025f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj vg_assert(sr_Res(preadres) > 0 && sr_Res(preadres) <= sizeof(buf1k) ); 9035a5eec0923d55afc94165721d25125d5fc8f24d8sewardj 9048b68b64759254d514d98328c496cbd88cde4c9a5njn /* We're only interested in mappings of object files. */ 9056e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# if defined(VGO_linux) 906f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj if (!ML_(is_elf_object_file)( buf1k, (SizeT)sr_Res(preadres), False )) 9075a5eec0923d55afc94165721d25125d5fc8f24d8sewardj return 0; 9086e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# elif defined(VGO_darwin) 9095f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (!ML_(is_macho_object_file)( buf1k, (SizeT)sr_Res(preadres) )) 910f76d27a697a7b0bf3b84490baf60623fc96a23afnjn return 0; 9116e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# else 9126e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# error "unknown OS" 9136e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# endif 9145a5eec0923d55afc94165721d25125d5fc8f24d8sewardj 915b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* See if we have a DebugInfo for this filename. If not, 916b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj create one. */ 9170f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj di = find_or_create_DebugInfo_for( filename ); 918b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di); 919b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 9206f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 9216f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_mmap-4: " 9226f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj "noting details in DebugInfo* at %p\n", di); 9236f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj 9246b5625bb609b154766d2e138b61e15655f60b710sewardj /* Note the details about the mapping. */ 9256b5625bb609b154766d2e138b61e15655f60b710sewardj struct _DebugInfoMapping map; 9266b5625bb609b154766d2e138b61e15655f60b710sewardj map.avma = a; 9276b5625bb609b154766d2e138b61e15655f60b710sewardj map.size = seg->end + 1 - seg->start; 9286b5625bb609b154766d2e138b61e15655f60b710sewardj map.foff = seg->offset; 9296b5625bb609b154766d2e138b61e15655f60b710sewardj map.rx = is_rx_map; 9306b5625bb609b154766d2e138b61e15655f60b710sewardj map.rw = is_rw_map; 9316b5625bb609b154766d2e138b61e15655f60b710sewardj map.ro = is_ro_map; 9326b5625bb609b154766d2e138b61e15655f60b710sewardj VG_(addToXA)(di->fsm.maps, &map); 9336b5625bb609b154766d2e138b61e15655f60b710sewardj 9346b5625bb609b154766d2e138b61e15655f60b710sewardj /* Update flags about what kind of mappings we've already seen. */ 9356b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.have_rx_map |= is_rx_map; 9366b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.have_rw_map |= is_rw_map; 9376b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.have_ro_map |= is_ro_map; 938b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 939731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* So, finally, are we in an accept state? */ 940731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) { 941731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Ok, so, finally, we found what we need, and we haven't 942731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj already read debuginfo for this object. So let's do so now. 943731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj Yee-ha! */ 9446f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 9456f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_mmap-5: " 9466f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj "achieved accept state for %s\n", filename); 947731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return di_notify_ACHIEVE_ACCEPT_STATE ( di ); 9489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } else { 949731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* If we don't have an rx and rw mapping, or if we already have 950731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj debuginfo for this mapping for whatever reason, go no 951731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj further. */ 952731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return 0; 9539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 954eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 955eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 956eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 957eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Unmap is simpler - throw away any SegInfos intersecting 958eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj [a, a+len). */ 959eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjvoid VG_(di_notify_munmap)( Addr a, SizeT len ) 960eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 961f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool anyFound; 962a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart if (0) VG_(printf)("DISCARD %#lx %#lx\n", a, a+len); 963f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj anyFound = discard_syms_in_range(a, len); 964f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (anyFound) 9655c3dba227192de63d86f65ec7d9597c132818c37philippe cfsi_m_cache__invalidate(); 966eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 967eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 968eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 969eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Uh, this doesn't do anything at all. IIRC glibc (or ld.so, I don't 970eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj remember) does a bunch of mprotects on itself, and if we follow 971eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj through here, it causes the debug info for that object to get 972eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj discarded. */ 973eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjvoid VG_(di_notify_mprotect)( Addr a, SizeT len, UInt prot ) 974eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 975eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool exe_ok = toBool(prot & VKI_PROT_EXEC); 976f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# if defined(VGA_x86) 977eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj exe_ok = exe_ok || toBool(prot & VKI_PROT_READ); 978eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# endif 979f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && !exe_ok) { 980f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool anyFound = discard_syms_in_range(a, len); 981f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (anyFound) 9825c3dba227192de63d86f65ec7d9597c132818c37philippe cfsi_m_cache__invalidate(); 983f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 984eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 985eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 986731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 987588cd4ebce3305d0cf91896c1f6322ef9775d6c1sewardj/* This is a MacOSX >= 10.7 32-bit only special. See comments on the 988731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj declaration of struct _DebugInfoFSM for details. */ 989731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardjvoid VG_(di_notify_vm_protect)( Addr a, SizeT len, UInt prot ) 990731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj{ 9916f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj Bool debug = (DEBUG_FSM != 0); 9926f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj 9936f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj Bool r_ok = toBool(prot & VKI_PROT_READ); 9946f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj Bool w_ok = toBool(prot & VKI_PROT_WRITE); 9956f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj Bool x_ok = toBool(prot & VKI_PROT_EXEC); 9966f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) { 9976f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-0:\n"); 9986f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-1: %#lx-%#lx %c%c%c\n", 9996f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj a, a + len - 1, 10006f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj r_ok ? 'r' : '-', w_ok ? 'w' : '-', x_ok ? 'x' : '-' ); 10016f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj } 10026f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj 1003731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj Bool do_nothing = True; 1004ec66ad5f33a4d904b1f728935ec6ee29b58a55ecsewardj# if defined(VGP_x86_darwin) && (DARWIN_VERS >= DARWIN_10_7) 1005731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj do_nothing = False; 1006731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# endif 10076f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (do_nothing /* wrong platform */) { 10086f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 10096f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-2: wrong platform, " 10106f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj "doing nothing.\n"); 1011731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return; 10126f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj } 1013731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 1014731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (! (r_ok && !w_ok && x_ok)) 1015731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return; /* not an upgrade to r-x */ 1016731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 1017731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Find a DebugInfo containing a FSM that has [a, +len) previously 1018731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj observed as a r-- mapping, plus some other rw- mapping. If such 1019731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj is found, conclude we're in an accept state and read debuginfo 1020731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj accordingly. */ 10216f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 10226f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-3: looking for existing DebugInfo*\n"); 1023731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj DebugInfo* di; 10246b5625bb609b154766d2e138b61e15655f60b710sewardj struct _DebugInfoMapping *map = NULL; 10256b5625bb609b154766d2e138b61e15655f60b710sewardj Word i; 1026731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj for (di = debugInfo_list; di; di = di->next) { 1027731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj vg_assert(di->fsm.filename); 1028731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (di->have_dinfo) 1029731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj continue; /* already have debuginfo for this object */ 1030731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (!di->fsm.have_ro_map) 1031731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj continue; /* need to have a r-- mapping for this object */ 1032731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (di->fsm.have_rx_map) 1033731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj continue; /* rx- mapping already exists */ 1034731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (!di->fsm.have_rw_map) 1035731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj continue; /* need to have a rw- mapping */ 10366b5625bb609b154766d2e138b61e15655f60b710sewardj /* Try to find a mapping matching the memory area. */ 10376b5625bb609b154766d2e138b61e15655f60b710sewardj for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { 10386b5625bb609b154766d2e138b61e15655f60b710sewardj map = (struct _DebugInfoMapping*)VG_(indexXA)(di->fsm.maps, i); 10396b5625bb609b154766d2e138b61e15655f60b710sewardj if (map->ro && map->avma == a && map->size == len) 10406b5625bb609b154766d2e138b61e15655f60b710sewardj break; 10416b5625bb609b154766d2e138b61e15655f60b710sewardj map = NULL; 10426b5625bb609b154766d2e138b61e15655f60b710sewardj } 10436b5625bb609b154766d2e138b61e15655f60b710sewardj if (!map) 10446b5625bb609b154766d2e138b61e15655f60b710sewardj continue; /* this isn't an upgrade of an r-- mapping */ 1045731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* looks like we're in luck! */ 1046731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj break; 1047731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj } 1048731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (di == NULL) 1049731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return; /* didn't find anything */ 1050731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 10516f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 10526f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-4: found existing DebugInfo* at %p\n", 10536f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj di); 10546f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj 10556b5625bb609b154766d2e138b61e15655f60b710sewardj /* Do the upgrade. Simply update the flags of the mapping 10566b5625bb609b154766d2e138b61e15655f60b710sewardj and pretend we never saw the RO map at all. */ 1057731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj vg_assert(di->fsm.have_ro_map); 10586b5625bb609b154766d2e138b61e15655f60b710sewardj map->rx = True; 10596b5625bb609b154766d2e138b61e15655f60b710sewardj map->ro = False; 1060731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj di->fsm.have_rx_map = True; 1061731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj di->fsm.have_ro_map = False; 10626b5625bb609b154766d2e138b61e15655f60b710sewardj /* See if there are any more ro mappings */ 10636b5625bb609b154766d2e138b61e15655f60b710sewardj for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { 10646b5625bb609b154766d2e138b61e15655f60b710sewardj map = (struct _DebugInfoMapping*)VG_(indexXA)(di->fsm.maps, i); 10656b5625bb609b154766d2e138b61e15655f60b710sewardj if (map->ro) { 10666b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.have_ro_map = True; 10676b5625bb609b154766d2e138b61e15655f60b710sewardj break; 10686b5625bb609b154766d2e138b61e15655f60b710sewardj } 10696b5625bb609b154766d2e138b61e15655f60b710sewardj } 10706b5625bb609b154766d2e138b61e15655f60b710sewardj 10716b5625bb609b154766d2e138b61e15655f60b710sewardj /* Check if we're now in an accept state and read debuginfo. Finally. */ 10726b5625bb609b154766d2e138b61e15655f60b710sewardj if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) { 10736f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 10746f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-5: " 10756f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj "achieved accept state for %s\n", di->fsm.filename); 10766b5625bb609b154766d2e138b61e15655f60b710sewardj ULong di_handle __attribute__((unused)) 10776b5625bb609b154766d2e138b61e15655f60b710sewardj = di_notify_ACHIEVE_ACCEPT_STATE( di ); 10786b5625bb609b154766d2e138b61e15655f60b710sewardj /* di_handle is ignored. That's not a problem per se -- it just 10796b5625bb609b154766d2e138b61e15655f60b710sewardj means nobody will ever be able to refer to this debuginfo by 10806b5625bb609b154766d2e138b61e15655f60b710sewardj handle since nobody will know what the handle value is. */ 10816b5625bb609b154766d2e138b61e15655f60b710sewardj } 1082731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj} 1083731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 1084731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 1085c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--------- PDB (windows debug info) reading --------- */ 1086c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1087c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/* this should really return ULong, as per VG_(di_notify_mmap). */ 1088c8259b85b701d25d72aabe9dc0a8154517f96913sewardjvoid VG_(di_notify_pdb_debuginfo)( Int fd_obj, Addr avma_obj, 108954c45db2f978055aeca91aaccb05aac825523e6csewardj SizeT total_size, PtrdiffT bias_obj ) 1090c8259b85b701d25d72aabe9dc0a8154517f96913sewardj{ 109113ac96dea734b3933a73524b991ac64fb48a4d57sewardj Int i, r, sz_exename; 1092c8259b85b701d25d72aabe9dc0a8154517f96913sewardj ULong obj_mtime, pdb_mtime; 109354fe2021b87b9e5edb8ec8070f47b86d5cafb8aaflorian HChar exename[VKI_PATH_MAX]; 10941636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar* pdbname = NULL; 10951636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar* dot; 1096c8259b85b701d25d72aabe9dc0a8154517f96913sewardj SysRes sres; 1097c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Int fd_pdbimage; 1098c8259b85b701d25d72aabe9dc0a8154517f96913sewardj SizeT n_pdbimage; 1099c8259b85b701d25d72aabe9dc0a8154517f96913sewardj struct vg_stat stat_buf; 1100c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1101c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) { 1102738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "\n"); 1103c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(message)(Vg_UserMsg, 1104cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj "LOAD_PDB_DEBUGINFO: clreq: fd=%d, avma=%#lx, total_size=%lu, " 110554c45db2f978055aeca91aaccb05aac825523e6csewardj "bias=%#lx\n", 110654c45db2f978055aeca91aaccb05aac825523e6csewardj fd_obj, avma_obj, total_size, bias_obj 1107c8259b85b701d25d72aabe9dc0a8154517f96913sewardj ); 1108c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1109c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1110c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* 'fd' refers to the .exe/.dll we're dealing with. Get its modification 1111c8259b85b701d25d72aabe9dc0a8154517f96913sewardj time into obj_mtime. */ 1112c8259b85b701d25d72aabe9dc0a8154517f96913sewardj r = VG_(fstat)(fd_obj, &stat_buf); 1113c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (r == -1) 1114c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; /* stat failed ?! */ 1115c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(r == 0); 11169c20ece00e07304f66da5f43b87ec45bc9c04550njn obj_mtime = stat_buf.mtime; 1117c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1118c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* and get its name into exename[]. */ 1119c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(VKI_PATH_MAX > 100); /* to ensure /proc/self/fd/%d is safe */ 1120c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(memset)(exename, 0, sizeof(exename)); 1121c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(sprintf)(exename, "/proc/self/fd/%d", fd_obj); 1122c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* convert exename from a symlink to real name .. overwrites the 1123c8259b85b701d25d72aabe9dc0a8154517f96913sewardj old contents of the buffer. Ick. */ 1124c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sz_exename = VG_(readlink)(exename, exename, sizeof(exename)-2 ); 1125c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (sz_exename == -1) 1126c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; /* readlink failed ?! */ 1127c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(sz_exename >= 0 && sz_exename < sizeof(exename)); 1128c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(exename[sizeof(exename)-1] == 0); 1129c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1130c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) { 1131738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: objname: %s\n", exename); 1132c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1133c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 113413ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Try to get the PDB file name from the executable. */ 113513ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = ML_(find_name_of_pdb_file)(exename); 113613ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (pdbname) { 113713ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(VG_(strlen)(pdbname) >= 5); /* 5 = strlen("X.pdb") */ 113813ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* So we successfully extracted a name from the PE file. But it's 113913ac96dea734b3933a73524b991ac64fb48a4d57sewardj likely to be of the form 114013ac96dea734b3933a73524b991ac64fb48a4d57sewardj e:\foo\bar\xyzzy\wibble.pdb 114113ac96dea734b3933a73524b991ac64fb48a4d57sewardj and we need to change it into something we can actually open 114213ac96dea734b3933a73524b991ac64fb48a4d57sewardj in Wine-world, which basically means turning it into 114313ac96dea734b3933a73524b991ac64fb48a4d57sewardj $HOME/.wine/drive_e/foo/bar/xyzzy/wibble.pdb 114413ac96dea734b3933a73524b991ac64fb48a4d57sewardj We also take into account $WINEPREFIX, if it is set. 114513ac96dea734b3933a73524b991ac64fb48a4d57sewardj For the moment, if the name isn't fully qualified, just forget it 114613ac96dea734b3933a73524b991ac64fb48a4d57sewardj (we'd have to root around to find where the pdb actually is) 114713ac96dea734b3933a73524b991ac64fb48a4d57sewardj */ 114813ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Change all the backslashes to forward slashes */ 114913ac96dea734b3933a73524b991ac64fb48a4d57sewardj for (i = 0; pdbname[i]; i++) { 115013ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (pdbname[i] == '\\') 115113ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname[i] = '/'; 115213ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 115313ac96dea734b3933a73524b991ac64fb48a4d57sewardj Bool is_quald 115413ac96dea734b3933a73524b991ac64fb48a4d57sewardj = ('a' <= VG_(tolower)(pdbname[0]) && VG_(tolower)(pdbname[0]) <= 'z') 115513ac96dea734b3933a73524b991ac64fb48a4d57sewardj && pdbname[1] == ':' 115613ac96dea734b3933a73524b991ac64fb48a4d57sewardj && pdbname[2] == '/'; 115713ac96dea734b3933a73524b991ac64fb48a4d57sewardj HChar* home = VG_(getenv)("HOME"); 115813ac96dea734b3933a73524b991ac64fb48a4d57sewardj HChar* wpfx = VG_(getenv)("WINEPREFIX"); 115913ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (is_quald && wpfx) { 116013ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Change e:/foo/bar/xyzzy/wibble.pdb 116113ac96dea734b3933a73524b991ac64fb48a4d57sewardj to $WINEPREFIX/drive_e/foo/bar/xyzzy/wibble.pdb 116213ac96dea734b3933a73524b991ac64fb48a4d57sewardj */ 116313ac96dea734b3933a73524b991ac64fb48a4d57sewardj Int mashedSzB = VG_(strlen)(pdbname) + VG_(strlen)(wpfx) + 50/*misc*/; 116413ac96dea734b3933a73524b991ac64fb48a4d57sewardj HChar* mashed = ML_(dinfo_zalloc)("di.debuginfo.dnpdi.1", mashedSzB); 116598500e2ee5f63f9c0af57835f7620d30848115f4bart VG_(snprintf)(mashed, mashedSzB, "%s/drive_%c%s", 116698500e2ee5f63f9c0af57835f7620d30848115f4bart wpfx, pdbname[0], &pdbname[2]); 116713ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(mashed[mashedSzB-1] == 0); 116813ac96dea734b3933a73524b991ac64fb48a4d57sewardj ML_(dinfo_free)(pdbname); 116913ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = mashed; 117013ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 117113ac96dea734b3933a73524b991ac64fb48a4d57sewardj else if (is_quald && home && !wpfx) { 117213ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Change e:/foo/bar/xyzzy/wibble.pdb 117313ac96dea734b3933a73524b991ac64fb48a4d57sewardj to $HOME/.wine/drive_e/foo/bar/xyzzy/wibble.pdb 117413ac96dea734b3933a73524b991ac64fb48a4d57sewardj */ 117513ac96dea734b3933a73524b991ac64fb48a4d57sewardj Int mashedSzB = VG_(strlen)(pdbname) + VG_(strlen)(home) + 50/*misc*/; 117613ac96dea734b3933a73524b991ac64fb48a4d57sewardj HChar* mashed = ML_(dinfo_zalloc)("di.debuginfo.dnpdi.2", mashedSzB); 117798500e2ee5f63f9c0af57835f7620d30848115f4bart VG_(snprintf)(mashed, mashedSzB, "%s/.wine/drive_%c%s", 117898500e2ee5f63f9c0af57835f7620d30848115f4bart home, pdbname[0], &pdbname[2]); 117913ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(mashed[mashedSzB-1] == 0); 118013ac96dea734b3933a73524b991ac64fb48a4d57sewardj ML_(dinfo_free)(pdbname); 118113ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = mashed; 118213ac96dea734b3933a73524b991ac64fb48a4d57sewardj } else { 118313ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* It's not a fully qualified path, or neither $HOME nor $WINE 118413ac96dea734b3933a73524b991ac64fb48a4d57sewardj are set (strange). Give up. */ 118513ac96dea734b3933a73524b991ac64fb48a4d57sewardj ML_(dinfo_free)(pdbname); 118613ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = NULL; 118713ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 118813ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 1189c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 119013ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Try s/exe/pdb/ if we don't have a valid pdbname. */ 119113ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (!pdbname) { 119213ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Try to find a matching PDB file from which to read debuginfo. 119313ac96dea734b3933a73524b991ac64fb48a4d57sewardj Windows PE files have symbol tables and line number information, 119413ac96dea734b3933a73524b991ac64fb48a4d57sewardj but MSVC doesn't seem to use them. */ 119513ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Why +5 ? Because in the worst case, we could find a dot as the 119613ac96dea734b3933a73524b991ac64fb48a4d57sewardj last character of pdbname, and we'd then put "pdb" right after 119713ac96dea734b3933a73524b991ac64fb48a4d57sewardj it, hence extending it a bit. */ 119813ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = ML_(dinfo_zalloc)("di.debuginfo.lpd1", sz_exename+5); 119913ac96dea734b3933a73524b991ac64fb48a4d57sewardj VG_(strcpy)(pdbname, exename); 120013ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(pdbname[sz_exename+5-1] == 0); 120113ac96dea734b3933a73524b991ac64fb48a4d57sewardj dot = VG_(strrchr)(pdbname, '.'); 120213ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (!dot) 120313ac96dea734b3933a73524b991ac64fb48a4d57sewardj goto out; /* there's no dot in the exe's name ?! */ 120413ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (dot[1] == 0) 120513ac96dea734b3933a73524b991ac64fb48a4d57sewardj goto out; /* hmm, path ends in "." */ 120613ac96dea734b3933a73524b991ac64fb48a4d57sewardj 120713ac96dea734b3933a73524b991ac64fb48a4d57sewardj if ('A' <= dot[1] && dot[1] <= 'Z') 120813ac96dea734b3933a73524b991ac64fb48a4d57sewardj VG_(strcpy)(dot, ".PDB"); 120913ac96dea734b3933a73524b991ac64fb48a4d57sewardj else 121013ac96dea734b3933a73524b991ac64fb48a4d57sewardj VG_(strcpy)(dot, ".pdb"); 121113ac96dea734b3933a73524b991ac64fb48a4d57sewardj 121213ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(pdbname[sz_exename+5-1] == 0); 121313ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 1214c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1215c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* See if we can find it, and check it's in-dateness. */ 1216c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sres = VG_(stat)(pdbname, &stat_buf); 1217cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) { 1218738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "Warning: Missing or un-stat-able %s\n", 1219c8259b85b701d25d72aabe9dc0a8154517f96913sewardj pdbname); 1220c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) 1221738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: missing: %s\n", pdbname); 1222c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; 1223c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 12249c20ece00e07304f66da5f43b87ec45bc9c04550njn pdb_mtime = stat_buf.mtime; 12257138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj 1226ced85060ebfd32f26de8e6a6f11567c9ac2b096asewardj if (obj_mtime > pdb_mtime + 60ULL) { 12277138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj /* PDB file is older than PE file. Really, the PDB should be 12287138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj newer than the PE, but that doesn't always seem to be the 12297138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj case. Allow the PDB to be up to one minute older. 12307138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj Otherwise, it's probably out of date, in which case ignore it 12317138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj or we will either (a) print wrong stack traces or more likely 12327138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj (b) crash. 12337138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj */ 1234738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, 1235ced85060ebfd32f26de8e6a6f11567c9ac2b096asewardj "Warning: %s (mtime = %llu)\n" 1236ced85060ebfd32f26de8e6a6f11567c9ac2b096asewardj " is older than %s (mtime = %llu)\n", 1237ced85060ebfd32f26de8e6a6f11567c9ac2b096asewardj pdbname, pdb_mtime, exename, obj_mtime); 1238c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1239c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1240c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sres = VG_(open)(pdbname, VKI_O_RDONLY, 0); 1241cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) { 1242738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "Warning: Can't open %s\n", pdbname); 1243c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; 1244c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1245c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1246cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj /* Looks promising; go on to try and read stuff from it. But don't 1247cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj mmap the file. Instead mmap free space and read the file into 1248cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj it. This is because files on CIFS filesystems that are mounted 1249cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj '-o directio' can't be mmap'd, and that mount option is needed 1250cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj to make CIFS work reliably. (See 1251cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj http://www.nabble.com/Corrupted-data-on-write-to- 1252cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj Windows-2003-Server-t2782623.html) 1253cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj This is slower, but at least it works reliably. */ 1254cda2f0fbda4c4b2644babc830244be8aed95de1dnjn fd_pdbimage = sr_Res(sres); 12559c20ece00e07304f66da5f43b87ec45bc9c04550njn n_pdbimage = stat_buf.size; 1256cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj if (n_pdbimage == 0 || n_pdbimage > 0x7FFFFFFF) { 1257cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // 0x7FFFFFFF: why? Because the VG_(read) just below only 1258cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // can deal with a signed int as the size of data to read, 1259cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // so we can't reliably check for read failure for files 1260cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // greater than that size. Hence just skip them; we're 1261cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // unlikely to encounter a PDB that large anyway. 1262cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj VG_(close)(fd_pdbimage); 1263cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj goto out; 1264cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj } 1265cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj sres = VG_(am_mmap_anon_float_valgrind)( n_pdbimage ); 1266cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) { 1267c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(close)(fd_pdbimage); 1268c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; 1269c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1270c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1271cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj void* pdbimage = (void*)sr_Res(sres); 1272cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj r = VG_(read)( fd_pdbimage, pdbimage, (Int)n_pdbimage ); 1273cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj if (r < 0 || r != (Int)n_pdbimage) { 1274cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage ); 1275cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj VG_(close)(fd_pdbimage); 1276cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj goto out; 1277cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj } 1278cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj 1279c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) 1280738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: pdbname: %s\n", pdbname); 1281c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1282c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* play safe; always invalidate the CFI cache. I don't know if 1283c8259b85b701d25d72aabe9dc0a8154517f96913sewardj this is necessary, but anyway .. */ 12845c3dba227192de63d86f65ec7d9597c132818c37philippe cfsi_m_cache__invalidate(); 1285c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* dump old info for this range, if any */ 1286c8259b85b701d25d72aabe9dc0a8154517f96913sewardj discard_syms_in_range( avma_obj, total_size ); 1287c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 12880f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj { DebugInfo* di = find_or_create_DebugInfo_for(exename); 1289c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1290c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* this di must be new, since we just nuked any old stuff in the range */ 1291a5acac39bf3be7546222b1316faee5ee524be0d1sewardj vg_assert(di && !di->fsm.have_rx_map && !di->fsm.have_rw_map); 1292c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(!di->have_dinfo); 1293c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1294c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* don't set up any of the di-> fields; let 1295c8259b85b701d25d72aabe9dc0a8154517f96913sewardj ML_(read_pdb_debug_info) do it. */ 129654c45db2f978055aeca91aaccb05aac825523e6csewardj ML_(read_pdb_debug_info)( di, avma_obj, bias_obj, 1297c8259b85b701d25d72aabe9dc0a8154517f96913sewardj pdbimage, n_pdbimage, pdbname, pdb_mtime ); 1298c8259b85b701d25d72aabe9dc0a8154517f96913sewardj // JRS fixme: take notice of return value from read_pdb_debug_info, 1299c8259b85b701d25d72aabe9dc0a8154517f96913sewardj // and handle failure 1300c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(di->have_dinfo); // fails if PDB read failed 1301c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage ); 1302c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(close)(fd_pdbimage); 1303cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj 1304cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj if (VG_(clo_verbosity) > 0) { 1305cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: done: " 1306a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe "%lu syms, %lu src locs, " 1307a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe "%lu src locs, %lu fpo recs\n", 1308a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe di->symtab_used, di->loctab_used, 1309a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe di->inltab_used, di->fpo_size); 1310cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj } 1311c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1312c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1313c8259b85b701d25d72aabe9dc0a8154517f96913sewardj out: 1314c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (pdbname) ML_(dinfo_free)(pdbname); 1315c8259b85b701d25d72aabe9dc0a8154517f96913sewardj} 1316c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 13178b68b64759254d514d98328c496cbd88cde4c9a5njn#endif /* defined(VGO_linux) || defined(VGO_darwin) */ 13184ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 13194ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 1320eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1321eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- ---*/ 1322eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- TOP LEVEL: QUERYING EXISTING DEBUG INFO ---*/ 1323eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- ---*/ 1324eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1325eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 13269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid VG_(di_discard_ALL_debuginfo)( void ) 13279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 13289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo *di, *di2; 13299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di = debugInfo_list; 13309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj while (di) { 13319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di2 = di->next; 13329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("XXX rm %p\n", di); 13339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj free_DebugInfo( di ); 13349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di = di2; 13359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 13369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 13379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 13389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 13396b5625bb609b154766d2e138b61e15655f60b710sewardjstruct _DebugInfoMapping* ML_(find_rx_mapping) ( struct _DebugInfo* di, 13406b5625bb609b154766d2e138b61e15655f60b710sewardj Addr lo, Addr hi ) 13416b5625bb609b154766d2e138b61e15655f60b710sewardj{ 13426b5625bb609b154766d2e138b61e15655f60b710sewardj Word i; 13436b5625bb609b154766d2e138b61e15655f60b710sewardj vg_assert(lo <= hi); 13446b5625bb609b154766d2e138b61e15655f60b710sewardj 13456b5625bb609b154766d2e138b61e15655f60b710sewardj /* Optimization: Try to use the last matched rx mapping first */ 13466b5625bb609b154766d2e138b61e15655f60b710sewardj if ( di->last_rx_map 13476b5625bb609b154766d2e138b61e15655f60b710sewardj && lo >= di->last_rx_map->avma 13486b5625bb609b154766d2e138b61e15655f60b710sewardj && hi < di->last_rx_map->avma + di->last_rx_map->size) 13496b5625bb609b154766d2e138b61e15655f60b710sewardj return di->last_rx_map; 13506b5625bb609b154766d2e138b61e15655f60b710sewardj 13516b5625bb609b154766d2e138b61e15655f60b710sewardj for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { 13526b5625bb609b154766d2e138b61e15655f60b710sewardj struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i); 13536b5625bb609b154766d2e138b61e15655f60b710sewardj if ( map->rx && map->size > 0 13546b5625bb609b154766d2e138b61e15655f60b710sewardj && lo >= map->avma && hi < map->avma + map->size) { 13556b5625bb609b154766d2e138b61e15655f60b710sewardj di->last_rx_map = map; 13566b5625bb609b154766d2e138b61e15655f60b710sewardj return map; 13576b5625bb609b154766d2e138b61e15655f60b710sewardj } 13586b5625bb609b154766d2e138b61e15655f60b710sewardj } 13596b5625bb609b154766d2e138b61e15655f60b710sewardj 13606b5625bb609b154766d2e138b61e15655f60b710sewardj return NULL; 13616b5625bb609b154766d2e138b61e15655f60b710sewardj} 13626b5625bb609b154766d2e138b61e15655f60b710sewardj 1363a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/*------------------------------------------------------------*/ 1364a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/*--- Types and functions for inlined IP cursor ---*/ 1365a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/*------------------------------------------------------------*/ 1366a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestruct _InlIPCursor { 1367a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Addr eip; // Cursor used to describe calls at eip. 1368a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe DebugInfo* di; // DebugInfo describing inlined calls at eip 1369a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1370a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word inltab_lopos; // The inlined fn calls covering eip are in 1371a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word inltab_hipos; // di->inltab[inltab_lopos..inltab_hipos]. 1372a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // Note that not all inlined fn calls in this range 1373a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // are necessarily covering eip. 1374a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1375a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Int curlevel; // Current level to describe. 1376a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // 0 means to describe eip itself. 1377a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word cur_inltab; // inltab pos for call inlined at current level. 1378a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word next_inltab; // inltab pos for call inlined at next (towards main) 1379a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // level. 1380a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe}; 1381a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1382a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic Bool is_top(InlIPCursor *iipc) 1383a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1384a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return !iipc || iipc->cur_inltab == -1; 1385a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1386a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1387a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic Bool is_bottom(InlIPCursor *iipc) 1388a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1389a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return !iipc || iipc->next_inltab == -1; 1390a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1391a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1392a0a73939b0398b6608fd6dbde49820ce6530d12cphilippeBool VG_(next_IIPC)(InlIPCursor *iipc) 1393a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1394a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word i; 1395a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe DiInlLoc *hinl = NULL; 1396a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word hinl_pos = -1; 1397a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe DebugInfo *di; 1398a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1399a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (iipc == NULL) 1400a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return False; 1401a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1402a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (iipc->curlevel <= 0) { 1403a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe iipc->curlevel--; 1404a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return False; 1405a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1406a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1407a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe di = iipc->di; 1408a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe for (i = iipc->inltab_lopos; i <= iipc->inltab_hipos; i++) { 1409a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di->inltab[i].addr_lo <= iipc->eip 1410a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe && iipc->eip < di->inltab[i].addr_hi 1411a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe && di->inltab[i].level < iipc->curlevel 1412a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe && (!hinl || hinl->level < di->inltab[i].level)) { 1413a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe hinl = &di->inltab[i]; 1414a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe hinl_pos = i; 1415a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1416a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1417a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1418a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe iipc->cur_inltab = iipc->next_inltab; 1419a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe iipc->next_inltab = hinl_pos; 1420a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (iipc->next_inltab < 0) 1421a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe iipc->curlevel = 0; // no inlined call anymore, describe eip itself 1422a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe else 1423a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe iipc->curlevel = di->inltab[iipc->next_inltab].level; 1424a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1425a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return True; 1426a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1427a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1428a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/* Forward */ 1429a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic void search_all_loctabs ( Addr ptr, /*OUT*/DebugInfo** pdi, 1430a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*OUT*/Word* locno ); 1431a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1432a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/* Returns the position after which eip would be inserted in inltab. 1433a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe (-1 if eip should be inserted before position 0). 1434a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe This is the highest position with an addr_lo <= eip. 1435a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe As inltab is sorted on addr_lo, dichotomic search can be done 1436a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe (note that inltab might have duplicates addr_lo). */ 1437a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic Word inltab_insert_pos (DebugInfo *di, Addr eip) 1438a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1439a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word mid, 1440a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe lo = 0, 1441a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe hi = di->inltab_used-1; 1442a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe while (lo <= hi) { 1443a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe mid = (lo + hi) / 2; 1444a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (eip < di->inltab[mid].addr_lo) { hi = mid-1; continue; } 1445a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (eip > di->inltab[mid].addr_lo) { lo = mid+1; continue; } 1446a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe lo = mid; break; 1447a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1448a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1449a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe while (lo <= di->inltab_used-1 && di->inltab[lo].addr_lo <= eip) 1450a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe lo++; 1451a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe#if 0 1452a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe for (mid = 0; mid <= di->inltab_used-1; mid++) 1453a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (eip < di->inltab[mid].addr_lo) 1454a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe break; 1455a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (lo - 1 == mid - 1); 1456a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe#endif 1457a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return lo - 1; 1458a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1459a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1460a0a73939b0398b6608fd6dbde49820ce6530d12cphilippeInlIPCursor* VG_(new_IIPC)(Addr eip) 1461a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1462a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe DebugInfo* di; 1463a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word locno; 1464a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word i; 1465a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe InlIPCursor *ret; 1466a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Bool avail; 1467a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1468a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (!VG_(clo_read_inline_info)) 1469a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return NULL; // No way we can find inlined calls. 1470a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1471a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* Search the DebugInfo for eip */ 1472a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe search_all_loctabs ( eip, &di, &locno ); 1473a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di == NULL || di->inltab_used == 0) 1474a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return NULL; // No di (with inltab) containing eip. 1475a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1476a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* Search the entry in di->inltab with the highest addr_lo that 1477a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe contains eip. */ 1478a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* We start from the highest pos in inltab after which eip would 1479a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe be inserted. */ 1480a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe for (i = inltab_insert_pos (di, eip); i >= 0; i--) { 1481a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di->inltab[i].addr_lo <= eip && eip < di->inltab[i].addr_hi) { 1482a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe break; 1483a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1484a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* Stop the backward scan when reaching an addr_lo which 1485a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe cannot anymore contain eip : we know that all ranges before 1486a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe i also cannot contain eip. */ 1487a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di->inltab[i].addr_lo < eip - di->maxinl_codesz) 1488a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return NULL; 1489a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1490a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1491a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (i < 0) 1492a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return NULL; // No entry containing eip. 1493a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1494a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* We have found the highest entry containing eip. 1495a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Build a cursor. */ 1496a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret = ML_(dinfo_zalloc) ("dinfo.new_IIPC", sizeof(*ret)); 1497a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->eip = eip; 1498a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->di = di; 1499a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->inltab_hipos = i; 1500a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe for (i = ret->inltab_hipos - 1; i >= 0; i--) { 1501a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1502a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di->inltab[i].addr_lo < eip - di->maxinl_codesz) 1503a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe break; /* Similar stop backward scan logic as above. */ 1504a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1505a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->inltab_lopos = i + 1; 1506a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->curlevel = MAX_LEVEL; 1507a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->cur_inltab = -1; 1508a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->next_inltab = -1; 1509a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1510a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* MAX_LEVEL is higher than any stored level. We can use 1511a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe VG_(next_IIPC) to get to the 'real' first highest call level. */ 1512a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe avail = VG_(next_IIPC) (ret); 1513a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (avail); 1514a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1515a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return ret; 1516a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1517a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1518a0a73939b0398b6608fd6dbde49820ce6530d12cphilippevoid VG_(delete_IIPC)(InlIPCursor *iipc) 1519a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1520a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (iipc) 1521a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ML_(dinfo_free)( iipc ); 1522a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1523a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 15246b5625bb609b154766d2e138b61e15655f60b710sewardj 1525eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1526eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Use of symbol table & location info to create ---*/ 1527eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- plausible-looking stack dumps. ---*/ 1528eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1529eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1530eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Search all symtabs that we know about to locate ptr. If found, set 1531b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi to the relevant DebugInfo, and *symno to the symtab entry 1532b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *number within that. If not found, *psi is set to NULL. 1533b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj If findText==True, only text symbols are searched for. 1534b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj If findText==False, only data symbols are searched for. 1535b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/ 1536b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void search_all_symtabs ( Addr ptr, /*OUT*/DebugInfo** pdi, 1537f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*OUT*/Word* symno, 1538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool match_anywhere_in_sym, 1539b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool findText ) 1540eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1541f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1542b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1543b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool inRange; 1544b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1546b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1547b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (findText) { 154851c9d3750448a4f2c95d22879e2f9f4bbd22bcfesewardj /* Consider any symbol in the r-x mapped area to be text. 154951c9d3750448a4f2c95d22879e2f9f4bbd22bcfesewardj See Comment_Regarding_Text_Range_Checks in storage.c for 155051c9d3750448a4f2c95d22879e2f9f4bbd22bcfesewardj details. */ 1551a5acac39bf3be7546222b1316faee5ee524be0d1sewardj inRange = di->fsm.have_rx_map 15526b5625bb609b154766d2e138b61e15655f60b710sewardj && (ML_(find_rx_mapping)(di, ptr, ptr) != NULL); 1553b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 1554b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj inRange = (di->data_present 1555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_size > 0 1556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_avma <= ptr 1557b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->data_avma + di->data_size) 1558b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || 1559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (di->sdata_present 1560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_size > 0 1561b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_avma <= ptr 1562b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->sdata_avma + di->sdata_size) 1563b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || 1564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (di->bss_present 1565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_size > 0 1566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_avma <= ptr 15675706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && ptr < di->bss_avma + di->bss_size) 15685706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj || 15695706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj (di->sbss_present 15705706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->sbss_size > 0 15715706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->sbss_avma <= ptr 15725706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && ptr < di->sbss_avma + di->sbss_size) 15735706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj || 15745706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj (di->rodata_present 15755706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->rodata_size > 0 15765706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->rodata_avma <= ptr 15775706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && ptr < di->rodata_avma + di->rodata_size); 1578eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1579b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1580b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!inRange) continue; 1581b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1582b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sno = ML_(search_one_symtab) ( 1583b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di, ptr, match_anywhere_in_sym, findText ); 1584b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (sno == -1) goto not_found; 1585b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *symno = sno; 1586b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = di; 1587b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; 1588b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1589eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1590eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj not_found: 1591b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = NULL; 1592eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1593eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1594eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1595eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Search all loctabs that we know about to locate ptr. If found, set 1596b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi to the relevant DebugInfo, and *locno to the loctab entry 1597b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *number within that. If not found, *pdi is set to NULL. */ 1598b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void search_all_loctabs ( Addr ptr, /*OUT*/DebugInfo** pdi, 1599f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*OUT*/Word* locno ) 1600eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1601f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word lno; 1602b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1603b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1604b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 16055706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->text_size > 0 1606b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= ptr 1607b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->text_avma + di->text_size) { 1608b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj lno = ML_(search_one_loctab) ( di, ptr ); 1609eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (lno == -1) goto not_found; 1610eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *locno = lno; 1611b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = di; 1612eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return; 1613eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1614eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1615eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj not_found: 1616b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = NULL; 1617eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1618eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1619eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1620eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* The whole point of this whole big deal: map a code address to a 1621eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj plausible symbol name. Returns False if no idea; otherwise True. 16226b7611bf42a0fbb62e047d8c43b008205bd21e75njn Caller supplies buf and nbuf. If do_cxx_demangling is False, don't do 16236b7611bf42a0fbb62e047d8c43b008205bd21e75njn C++ demangling, regardless of VG_(clo_demangle) -- probably because the 16246b7611bf42a0fbb62e047d8c43b008205bd21e75njn call has come from VG_(get_fnname_raw)(). findText 1625b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj indicates whether we're looking for a text symbol or a data symbol 1626b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj -- caller must choose one kind or the other. */ 1627eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjstatic 16286b7611bf42a0fbb62e047d8c43b008205bd21e75njnBool get_sym_name ( Bool do_cxx_demangling, Bool do_z_demangling, 16296b7611bf42a0fbb62e047d8c43b008205bd21e75njn Bool do_below_main_renaming, 16301636d33c13958b9c0e7d3059cdd5005746418eb2florian Addr a, HChar* buf, Int nbuf, 1631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool match_anywhere_in_sym, Bool show_offset, 1632c4431bfe04c7490ea2d74939d222d87f13f30960njn Bool findText, /*OUT*/PtrdiffT* offsetP ) 1633eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1634b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1635f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1636c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT offset; 1637eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1638b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj search_all_symtabs ( a, &di, &sno, match_anywhere_in_sym, findText ); 1639b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == NULL) 1640eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 16416882443ef154bca367bc591287de641e43a9e108njn 1642a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(di->symtab[sno].pri_name); 16436b7611bf42a0fbb62e047d8c43b008205bd21e75njn VG_(demangle) ( do_cxx_demangling, do_z_demangling, 1644a5cace0c2a3e212931badbf6398a0cd98393121asewardj di->symtab[sno].pri_name, buf, nbuf ); 16456b7611bf42a0fbb62e047d8c43b008205bd21e75njn 16466b7611bf42a0fbb62e047d8c43b008205bd21e75njn /* Do the below-main hack */ 16476b7611bf42a0fbb62e047d8c43b008205bd21e75njn // To reduce the endless nuisance of multiple different names 16486b7611bf42a0fbb62e047d8c43b008205bd21e75njn // for "the frame below main()" screwing up the testsuite, change all 16496b7611bf42a0fbb62e047d8c43b008205bd21e75njn // known incarnations of said into a single name, "(below main)", if 16506b7611bf42a0fbb62e047d8c43b008205bd21e75njn // --show-below-main=yes. 16516b7611bf42a0fbb62e047d8c43b008205bd21e75njn if ( do_below_main_renaming && ! VG_(clo_show_below_main) && 16526b7611bf42a0fbb62e047d8c43b008205bd21e75njn Vg_FnNameBelowMain == VG_(get_fnname_kind)(buf) ) 16536b7611bf42a0fbb62e047d8c43b008205bd21e75njn { 16546b7611bf42a0fbb62e047d8c43b008205bd21e75njn VG_(strncpy_safely)(buf, "(below main)", nbuf); 1655eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1656b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset = a - di->symtab[sno].addr; 1657c4431bfe04c7490ea2d74939d222d87f13f30960njn if (offsetP) *offsetP = offset; 1658b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1659eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (show_offset && offset != 0) { 16601636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar buf2[12]; 16611636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar* symend = buf + VG_(strlen)(buf); 16621636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar* end = buf + nbuf; 1663eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Int len; 1664eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1665c4431bfe04c7490ea2d74939d222d87f13f30960njn len = VG_(sprintf)(buf2, "%c%ld", 1666eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj offset < 0 ? '-' : '+', 1667eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj offset < 0 ? -offset : offset); 1668eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(len < (Int)sizeof(buf2)); 1669eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1670eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (len < (end - symend)) { 16711636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar *cp = buf2; 1672eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(memcpy)(symend, cp, len+1); 1673eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1674eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1675eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 16766b7611bf42a0fbb62e047d8c43b008205bd21e75njn buf[nbuf-1] = 0; /* paranoia */ 16776b7611bf42a0fbb62e047d8c43b008205bd21e75njn 1678eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1679eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1680eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1681eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* ppc64-linux only: find the TOC pointer (R2 value) that should be in 1682eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj force at the entry point address of the function containing 1683eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj guest_code_addr. Returns 0 if not known. */ 1684eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjAddr VG_(get_tocptr) ( Addr guest_code_addr ) 1685eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1686b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1687f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1688eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_symtabs ( guest_code_addr, 1689b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj &si, &sno, 1690b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj True/*match_anywhere_in_fun*/, 1691b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj True/*consider text symbols only*/ ); 1692eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 1693eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return 0; 1694eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj else 1695eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return si->symtab[sno].tocptr; 1696eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1697eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1698eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 1699eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj match anywhere in function, but don't show offsets. */ 17001636d33c13958b9c0e7d3059cdd5005746418eb2florianBool VG_(get_fnname) ( Addr a, HChar* buf, Int nbuf ) 1701eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 17026b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, 17036b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 17046b7611bf42a0fbb62e047d8c43b008205bd21e75njn a, buf, nbuf, 1705b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1706b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1707b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1708b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1709eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1710eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1711eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 1712eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj match anywhere in function, and show offset if nonzero. */ 17131636d33c13958b9c0e7d3059cdd5005746418eb2florianBool VG_(get_fnname_w_offset) ( Addr a, HChar* buf, Int nbuf ) 1714eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 17156b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, 17166b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 17176b7611bf42a0fbb62e047d8c43b008205bd21e75njn a, buf, nbuf, 1718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/True, 1720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1722eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1723eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1724eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 1725eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj only succeed if 'a' matches first instruction of function, 1726eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj and don't show offsets. */ 17271636d33c13958b9c0e7d3059cdd5005746418eb2florianBool VG_(get_fnname_if_entry) ( Addr a, HChar* buf, Int nbuf ) 1728eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 17296b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, 17306b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 17316b7611bf42a0fbb62e047d8c43b008205bd21e75njn a, buf, nbuf, 1732b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/False, 1733b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1734b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1736eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1737eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 17386b7611bf42a0fbb62e047d8c43b008205bd21e75njn/* This is only available to core... don't C++-demangle, don't Z-demangle, 17396b7611bf42a0fbb62e047d8c43b008205bd21e75njn don't rename below-main, match anywhere in function, and don't show 17406b7611bf42a0fbb62e047d8c43b008205bd21e75njn offsets. */ 17411636d33c13958b9c0e7d3059cdd5005746418eb2florianBool VG_(get_fnname_raw) ( Addr a, HChar* buf, Int nbuf ) 1742eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 17436b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, 17446b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/False, 17456b7611bf42a0fbb62e047d8c43b008205bd21e75njn a, buf, nbuf, 1746b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1747b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1748b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1749b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1750eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1751eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1752eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is only available to core... don't demangle C++ names, but do 17536b7611bf42a0fbb62e047d8c43b008205bd21e75njn do Z-demangling and below-main-renaming, match anywhere in function, and 17546b7611bf42a0fbb62e047d8c43b008205bd21e75njn don't show offsets. */ 1755a0a73939b0398b6608fd6dbde49820ce6530d12cphilippeBool VG_(get_fnname_no_cxx_demangle) ( Addr a, HChar* buf, Int nbuf, 1756a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe InlIPCursor* iipc ) 1757eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1758a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (is_bottom(iipc)) { 1759a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // At the bottom (towards main), we describe the fn at eip. 1760a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/True, 1761a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*below-main-renaming*/True, 1762a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe a, buf, nbuf, 1763a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*match_anywhere_in_fun*/True, 1764a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*show offset?*/False, 1765a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*text syms only*/True, 1766a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*offsetP*/NULL ); 1767a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } else { 1768a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe const DiInlLoc *next_inl = iipc && iipc->next_inltab >= 0 1769a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ? & iipc->di->inltab[iipc->next_inltab] 1770a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe : NULL; 1771a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (next_inl); 1772a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // The function we are in is called by next_inl. 1773a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe VG_(snprintf)(buf, nbuf, "%s", next_inl->inlinedfn); 1774a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return True; 1775a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1776eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1777eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 17785db15403e889d4db339b342bc2a824ef0bfaa654sewardj/* mips-linux only: find the offset of current address. This is needed for 17795db15403e889d4db339b342bc2a824ef0bfaa654sewardj stack unwinding for MIPS. 17805db15403e889d4db339b342bc2a824ef0bfaa654sewardj*/ 17815db15403e889d4db339b342bc2a824ef0bfaa654sewardjBool VG_(get_inst_offset_in_function)( Addr a, 17825db15403e889d4db339b342bc2a824ef0bfaa654sewardj /*OUT*/PtrdiffT* offset ) 17835db15403e889d4db339b342bc2a824ef0bfaa654sewardj{ 17841636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar fnname[64]; 17855db15403e889d4db339b342bc2a824ef0bfaa654sewardj return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, 17865db15403e889d4db339b342bc2a824ef0bfaa654sewardj /*below-main-renaming*/False, 17875db15403e889d4db339b342bc2a824ef0bfaa654sewardj a, fnname, 64, 17885db15403e889d4db339b342bc2a824ef0bfaa654sewardj /*match_anywhere_in_sym*/True, 178981208182df4e8b9c8642affd6754996777ee7556florian /*show offset?*/False, 17904afac5b6f637d1cea82e62b3a280fa4e81101c05petarj /*text syms only*/True, 17915db15403e889d4db339b342bc2a824ef0bfaa654sewardj offset ); 17925db15403e889d4db339b342bc2a824ef0bfaa654sewardj} 17935db15403e889d4db339b342bc2a824ef0bfaa654sewardj 17941636d33c13958b9c0e7d3059cdd5005746418eb2florianVg_FnNameKind VG_(get_fnname_kind) ( HChar* name ) 17956882443ef154bca367bc591287de641e43a9e108njn{ 17966882443ef154bca367bc591287de641e43a9e108njn if (VG_STREQ("main", name)) { 17976882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameMain; 17986882443ef154bca367bc591287de641e43a9e108njn 17996882443ef154bca367bc591287de641e43a9e108njn } else if ( 18003026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGO_linux) 18016882443ef154bca367bc591287de641e43a9e108njn VG_STREQ("__libc_start_main", name) || // glibc glibness 18026882443ef154bca367bc591287de641e43a9e108njn VG_STREQ("generic_start_main", name) || // Yellow Dog doggedness 18033026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGO_darwin) 1804f76d27a697a7b0bf3b84490baf60623fc96a23afnjn // See readmacho.c for an explanation of this. 1805f76d27a697a7b0bf3b84490baf60623fc96a23afnjn VG_STREQ("start_according_to_valgrind", name) || // Darwin, darling 18063026f71684a930286186aa10fef266c304672e8fsewardj# else 18073026f71684a930286186aa10fef266c304672e8fsewardj# error "Unknown OS" 18083026f71684a930286186aa10fef266c304672e8fsewardj# endif 18096882443ef154bca367bc591287de641e43a9e108njn 0) { 18106882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameBelowMain; 18116882443ef154bca367bc591287de641e43a9e108njn 18126882443ef154bca367bc591287de641e43a9e108njn } else { 18136882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameNormal; 18146882443ef154bca367bc591287de641e43a9e108njn } 18156882443ef154bca367bc591287de641e43a9e108njn} 18166882443ef154bca367bc591287de641e43a9e108njn 18176882443ef154bca367bc591287de641e43a9e108njnVg_FnNameKind VG_(get_fnname_kind_from_IP) ( Addr ip ) 18186882443ef154bca367bc591287de641e43a9e108njn{ 18196882443ef154bca367bc591287de641e43a9e108njn // We don't need a big buffer; all the special names are small. 18206882443ef154bca367bc591287de641e43a9e108njn #define BUFLEN 50 18211636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar buf[50]; 18226882443ef154bca367bc591287de641e43a9e108njn 18236882443ef154bca367bc591287de641e43a9e108njn // We don't demangle, because it's faster not to, and the special names 18247d995792542cf8e7f5a81248589445adfffeae30florian // we're looking for won't be mangled. 18256b7611bf42a0fbb62e047d8c43b008205bd21e75njn if (VG_(get_fnname_raw) ( ip, buf, BUFLEN )) { 18266882443ef154bca367bc591287de641e43a9e108njn buf[BUFLEN-1] = '\0'; // paranoia 18276882443ef154bca367bc591287de641e43a9e108njn return VG_(get_fnname_kind)(buf); 18286882443ef154bca367bc591287de641e43a9e108njn } else { 18296882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameNormal; // Don't know the name, treat it as normal. 18306882443ef154bca367bc591287de641e43a9e108njn } 18316882443ef154bca367bc591287de641e43a9e108njn} 18326882443ef154bca367bc591287de641e43a9e108njn 1833b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Looks up data_addr in the collection of data symbols, and if found 1834b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj puts its name (or as much as will fit) into dname[0 .. n_dname-1], 1835b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which is guaranteed to be zero terminated. Also data_addr's offset 1836b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj from the symbol start is put into *offset. */ 1837b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool VG_(get_datasym_and_offset)( Addr data_addr, 18381636d33c13958b9c0e7d3059cdd5005746418eb2florian /*OUT*/HChar* dname, Int n_dname, 1839c4431bfe04c7490ea2d74939d222d87f13f30960njn /*OUT*/PtrdiffT* offset ) 1840b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 1841b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool ok; 1842b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_dname > 1); 18436b7611bf42a0fbb62e047d8c43b008205bd21e75njn ok = get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, 18446b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/False, 18456b7611bf42a0fbb62e047d8c43b008205bd21e75njn data_addr, dname, n_dname, 1846b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_sym*/True, 1847b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1848b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*data syms only please*/False, 1849b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset ); 1850b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!ok) 1851b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 1852b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj dname[n_dname-1] = 0; 1853b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 1854b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 1855b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1856b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Map a code address to the name of a shared object file or the 1857b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj executable. Returns False if no idea; otherwise True. Doesn't 1858b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj require debug info. Caller supplies buf and nbuf. */ 18591636d33c13958b9c0e7d3059cdd5005746418eb2florianBool VG_(get_objname) ( Addr a, HChar* buf, Int nbuf ) 1860eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1861b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1862f32ec7f0de8a651bc16a1b2e448c0106d8669889tom const NSegment *seg; 1863f32ec7f0de8a651bc16a1b2e448c0106d8669889tom HChar* filename; 18644ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj vg_assert(nbuf > 0); 18657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Look in the debugInfo_list to find the name. In most cases we 18667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj expect this to produce a result. */ 1867b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1868b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 18695706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->text_size > 0 1870b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= a 1871b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a < di->text_avma + di->text_size) { 1872a5acac39bf3be7546222b1316faee5ee524be0d1sewardj VG_(strncpy_safely)(buf, di->fsm.filename, nbuf); 18736625f7115ce012b84712770af22765c01f96ba44florian buf[nbuf-1] = 0; 1874eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1875eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1876eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 18777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Last-ditch fallback position: if we don't find the address in 18787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj the debugInfo_list, ask the address space manager whether it 18797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj knows the name of the file associated with this mapping. This 18807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj allows us to print the names of exe/dll files in the stack trace 18817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj when running programs under wine. */ 18827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if ( (seg = VG_(am_find_nsegment(a))) != NULL 18837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj && (filename = VG_(am_get_filename)(seg)) != NULL ) { 1884f32ec7f0de8a651bc16a1b2e448c0106d8669889tom VG_(strncpy_safely)(buf, filename, nbuf); 1885f32ec7f0de8a651bc16a1b2e448c0106d8669889tom return True; 1886f32ec7f0de8a651bc16a1b2e448c0106d8669889tom } 1887eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1888eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1889eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1890b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Map a code address to its DebugInfo. Returns NULL if not found. Doesn't 1891eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj require debug info. */ 1892e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjDebugInfo* VG_(find_DebugInfo) ( Addr a ) 1893eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1894e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj static UWord n_search = 0; 1895b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1896e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj n_search++; 1897b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1898b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 18995706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->text_size > 0 1900b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= a 1901b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a < di->text_avma + di->text_size) { 1902e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj if (0 == (n_search & 0xF)) 1903e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj move_DebugInfo_one_step_forward( di ); 1904b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 1905eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1906eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1907eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return NULL; 1908eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1909eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1910eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a filename. Returns True if successful. */ 19111636d33c13958b9c0e7d3059cdd5005746418eb2florianBool VG_(get_filename)( Addr a, HChar* filename, Int n_filename ) 1912eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1913b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1914f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 191559e1f3c79e870a978d24add86db6d8c5450c8b63philippe UInt fndn_ix; 191659e1f3c79e870a978d24add86db6d8c5450c8b63philippe FnDn* fndn; 191759e1f3c79e870a978d24add86db6d8c5450c8b63philippe 1918eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 1919eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 1920eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 192159e1f3c79e870a978d24add86db6d8c5450c8b63philippe fndn_ix = ML_(fndn_ix) (si, locno); 192259e1f3c79e870a978d24add86db6d8c5450c8b63philippe if (fndn_ix == 0) 192359e1f3c79e870a978d24add86db6d8c5450c8b63philippe VG_(strncpy_safely)(filename, "???", n_filename); 192459e1f3c79e870a978d24add86db6d8c5450c8b63philippe else { 192559e1f3c79e870a978d24add86db6d8c5450c8b63philippe fndn = VG_(indexEltNumber) (si->fndnpool, fndn_ix); 192659e1f3c79e870a978d24add86db6d8c5450c8b63philippe VG_(strncpy_safely)(filename, fndn->filename, n_filename); 192759e1f3c79e870a978d24add86db6d8c5450c8b63philippe } 1928eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1929eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1930eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1931eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a line number. Returns True if successful. */ 1932eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_linenum)( Addr a, UInt* lineno ) 1933eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1934b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1935f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 1936eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 1937eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 1938eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1939eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *lineno = si->loctab[locno].lineno; 1940eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1941eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1942eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1943eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1944eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a filename/line number/dir name info. 1945eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj See prototype for detailed description of behaviour. 1946eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 1947eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_filename_linenum) ( Addr a, 19481636d33c13958b9c0e7d3059cdd5005746418eb2florian /*OUT*/HChar* filename, Int n_filename, 19491636d33c13958b9c0e7d3059cdd5005746418eb2florian /*OUT*/HChar* dirname, Int n_dirname, 1950eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/Bool* dirname_available, 1951eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/UInt* lineno ) 1952eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1953b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1954f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 195559e1f3c79e870a978d24add86db6d8c5450c8b63philippe UInt fndn_ix; 195659e1f3c79e870a978d24add86db6d8c5450c8b63philippe FnDn* fndn = NULL; 1957eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1958eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert( (dirname == NULL && dirname_available == NULL) 1959eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj || 1960eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj (dirname != NULL && dirname_available != NULL) ); 1961eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1962eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 1963c1b1d421216369aec58867ce1c5b99cfb1703c36njn if (si == NULL) { 1964db5c6571454c1f647a4c67593805a8e401cd14c5njn if (dirname_available) { 1965db5c6571454c1f647a4c67593805a8e401cd14c5njn *dirname_available = False; 1966db5c6571454c1f647a4c67593805a8e401cd14c5njn *dirname = 0; 1967db5c6571454c1f647a4c67593805a8e401cd14c5njn } 1968eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 1969c1b1d421216369aec58867ce1c5b99cfb1703c36njn } 1970c1b1d421216369aec58867ce1c5b99cfb1703c36njn 197159e1f3c79e870a978d24add86db6d8c5450c8b63philippe fndn_ix = ML_(fndn_ix)(si, locno); 197259e1f3c79e870a978d24add86db6d8c5450c8b63philippe if (fndn_ix == 0) 197359e1f3c79e870a978d24add86db6d8c5450c8b63philippe VG_(strncpy_safely)(filename, "???", n_filename); 197459e1f3c79e870a978d24add86db6d8c5450c8b63philippe else { 197559e1f3c79e870a978d24add86db6d8c5450c8b63philippe fndn = VG_(indexEltNumber) (si->fndnpool, fndn_ix); 197659e1f3c79e870a978d24add86db6d8c5450c8b63philippe VG_(strncpy_safely)(filename, fndn->filename, n_filename); 197759e1f3c79e870a978d24add86db6d8c5450c8b63philippe } 1978eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *lineno = si->loctab[locno].lineno; 1979eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1980eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (dirname) { 1981eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* caller wants directory info too .. */ 1982eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(n_dirname > 0); 198359e1f3c79e870a978d24add86db6d8c5450c8b63philippe if (fndn_ix != 0 && fndn->dirname) { 1984eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* .. and we have some */ 1985eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *dirname_available = True; 198659e1f3c79e870a978d24add86db6d8c5450c8b63philippe VG_(strncpy_safely)(dirname, fndn->dirname, n_dirname); 1987eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 1988eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* .. but we don't have any */ 1989eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *dirname_available = False; 1990eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *dirname = 0; 1991eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1992eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1993eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1994eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1995eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1996eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1997eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 19984ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/* Map a function name to its entry point and toc pointer. Is done by 19994ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj sequential search of all symbol tables, so is very slow. To 20004ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj mitigate the worst performance effects, you may specify a soname 20014ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj pattern, and only objects matching that pattern are searched. 20024ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Therefore specify "*" to search all the objects. On TOC-afflicted 20034ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj platforms, a symbol is deemed to be found only if it has a nonzero 20044ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj TOC pointer. */ 20056bd9dc18c043927c1196caba20a327238a179c42florianBool VG_(lookup_symbol_SLOW)(const HChar* sopatt, HChar* name, 2006b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr* pEnt, Addr* pToc) 20074ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj{ 20084ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool require_pToc = False; 20094ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Int i; 2010b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 20114ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool debug = False; 20124ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# if defined(VG_PLAT_USES_PPCTOC) 20134ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj require_pToc = True; 20144ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# endif 2015b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (si = debugInfo_list; si; si = si->next) { 20164ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (debug) 20174ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(printf)("lookup_symbol_SLOW: considering %s\n", si->soname); 20184ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (!VG_(string_match)(sopatt, si->soname)) { 20194ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (debug) 20204ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(printf)(" ... skip\n"); 20214ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj continue; 20224ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 20234ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj for (i = 0; i < si->symtab_used; i++) { 20241636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar* pri_name = si->symtab[i].pri_name; 2025a5cace0c2a3e212931badbf6398a0cd98393121asewardj tl_assert(pri_name); 2026a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (0==VG_(strcmp)(name, pri_name) 20274ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj && (require_pToc ? si->symtab[i].tocptr : True)) { 20284ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj *pEnt = si->symtab[i].addr; 20294ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj *pToc = si->symtab[i].tocptr; 20304ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj return True; 20314ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 20321636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar** sec_names = si->symtab[i].sec_names; 2033a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (sec_names) { 2034a5cace0c2a3e212931badbf6398a0cd98393121asewardj tl_assert(sec_names[0]); 2035a5cace0c2a3e212931badbf6398a0cd98393121asewardj while (*sec_names) { 2036a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (0==VG_(strcmp)(name, *sec_names) 2037a5cace0c2a3e212931badbf6398a0cd98393121asewardj && (require_pToc ? si->symtab[i].tocptr : True)) { 2038a5cace0c2a3e212931badbf6398a0cd98393121asewardj *pEnt = si->symtab[i].addr; 2039a5cace0c2a3e212931badbf6398a0cd98393121asewardj *pToc = si->symtab[i].tocptr; 2040a5cace0c2a3e212931badbf6398a0cd98393121asewardj return True; 2041a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 2042a5cace0c2a3e212931badbf6398a0cd98393121asewardj sec_names++; 2043a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 2044a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 20454ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 20464ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 20474ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj return False; 20484ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj} 20494ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 20504ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 2051e872fec0c1c3b478a399fdba42ac65764b53f470sewardj/* VG_(describe_IP): print into buf info on code address, function 2052e872fec0c1c3b478a399fdba42ac65764b53f470sewardj name and filename. */ 2053e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 2054e872fec0c1c3b478a399fdba42ac65764b53f470sewardj/* Copy str into buf starting at n, but not going past buf[n_buf-1] 2055e872fec0c1c3b478a399fdba42ac65764b53f470sewardj and always ensuring that buf is zero-terminated. */ 2056eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 20571636d33c13958b9c0e7d3059cdd5005746418eb2florianstatic Int putStr ( Int n, Int n_buf, HChar* buf, const HChar* str ) 2058eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2059e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n_buf > 0); 2060e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 2061eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj for (; n < n_buf-1 && *str != 0; n++,str++) 2062eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf[n] = *str; 2063e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 2064eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj buf[n] = '\0'; 2065eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return n; 2066eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2067e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 2068e872fec0c1c3b478a399fdba42ac65764b53f470sewardj/* Same as putStr, but escaping chars for XML output, and 2069e872fec0c1c3b478a399fdba42ac65764b53f470sewardj also not adding more than count chars to n_buf. */ 2070e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 20711636d33c13958b9c0e7d3059cdd5005746418eb2florianstatic Int putStrEsc ( Int n, Int n_buf, Int count, HChar* buf, HChar* str ) 2072eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 20731636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar alt[2]; 2074e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n_buf > 0); 2075e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(count >= 0 && count < n_buf); 2076e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 2077eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj for (; *str != 0; str++) { 2078e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(count >= 0); 2079e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count <= 0) 2080e872fec0c1c3b478a399fdba42ac65764b53f470sewardj goto done; 2081eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj switch (*str) { 2082e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '&': 2083e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 5) goto done; 2084e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, "&"); 2085e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 5; 2086e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 2087e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '<': 2088e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 4) goto done; 2089e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, "<"); 2090e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 4; 2091e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 2092e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '>': 2093e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 4) goto done; 2094e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, ">"); 2095e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 4; 2096e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 2097e872fec0c1c3b478a399fdba42ac65764b53f470sewardj default: 2098e872fec0c1c3b478a399fdba42ac65764b53f470sewardj if (count < 1) goto done; 2099e872fec0c1c3b478a399fdba42ac65764b53f470sewardj alt[0] = *str; 2100e872fec0c1c3b478a399fdba42ac65764b53f470sewardj alt[1] = 0; 2101e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr( n, n_buf, buf, alt ); 2102e872fec0c1c3b478a399fdba42ac65764b53f470sewardj count -= 1; 2103e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 2104eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2105eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2106e872fec0c1c3b478a399fdba42ac65764b53f470sewardj done: 2107e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(count >= 0); /* should not go -ve in loop */ 2108e872fec0c1c3b478a399fdba42ac65764b53f470sewardj vg_assert(n >= 0 && n < n_buf); 2109eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return n; 2110eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2111eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2112a0a73939b0398b6608fd6dbde49820ce6530d12cphilippeHChar* VG_(describe_IP)(Addr eip, HChar* buf, Int n_buf, InlIPCursor *iipc) 2113eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2114eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define APPEND(_str) \ 2115e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStr(n, n_buf, buf, _str) 2116e872fec0c1c3b478a399fdba42ac65764b53f470sewardj# define APPEND_ESC(_count,_str) \ 2117e872fec0c1c3b478a399fdba42ac65764b53f470sewardj n = putStrEsc(n, n_buf, (_count), buf, (_str)) 2118eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define BUF_LEN 4096 2119eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2120eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj UInt lineno; 21211636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar ibuf[50]; 2122eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Int n = 0; 212314cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj 2124a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (!iipc || iipc->eip == eip); 2125a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 21261636d33c13958b9c0e7d3059cdd5005746418eb2florian static HChar buf_fn[BUF_LEN]; 21271636d33c13958b9c0e7d3059cdd5005746418eb2florian static HChar buf_obj[BUF_LEN]; 21281636d33c13958b9c0e7d3059cdd5005746418eb2florian static HChar buf_srcloc[BUF_LEN]; 21291636d33c13958b9c0e7d3059cdd5005746418eb2florian static HChar buf_dirname[BUF_LEN]; 213014cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj buf_fn[0] = buf_obj[0] = buf_srcloc[0] = buf_dirname[0] = 0; 213114cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj 2132eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool know_dirinfo = False; 2133a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Bool know_fnname; 2134a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Bool know_objname; 2135a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Bool know_srcloc; 2136a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2137a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (is_bottom(iipc)) { 2138a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // At the bottom (towards main), we describe the fn at eip. 2139a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe know_fnname = VG_(clo_sym_offsets) 2140a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ? VG_(get_fnname_w_offset) (eip, buf_fn, BUF_LEN) 2141a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe : VG_(get_fnname) (eip, buf_fn, BUF_LEN); 2142a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } else { 2143a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe const DiInlLoc *next_inl = iipc && iipc->next_inltab >= 0 2144a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ? & iipc->di->inltab[iipc->next_inltab] 2145a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe : NULL; 2146a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (next_inl); 2147a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // The function we are in is called by next_inl. 2148a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe VG_(snprintf)(buf_fn, BUF_LEN, "%s", next_inl->inlinedfn); 2149a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe know_fnname = True; 2150a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2151a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // INLINED???? 2152a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // ??? Can we compute an offset for an inlined fn call ? 2153a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // ??? Offset from what ? The beginning of the inl info ? 2154a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // ??? But that is not necessarily the beginning of the fn 2155a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // ??? as e.g. an inlined fn call can be in several ranges. 2156a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // ??? Currently never showing an offset. 2157a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 2158a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2159a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe know_objname = VG_(get_objname)(eip, buf_obj, BUF_LEN); 2160a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2161a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (is_top(iipc)) { 2162a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // The source for the highest level is in the loctab entry. 2163a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe know_srcloc = VG_(get_filename_linenum)( 2164a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe eip, 2165a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe buf_srcloc, BUF_LEN, 2166a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe buf_dirname, BUF_LEN, &know_dirinfo, 2167a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe &lineno 2168a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ); 2169a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } else { 2170a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe const DiInlLoc *cur_inl = iipc && iipc->cur_inltab >= 0 2171a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ? & iipc->di->inltab[iipc->cur_inltab] 2172a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe : NULL; 2173a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (cur_inl); 2174a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // The filename and lineno for the inlined fn caller is in cur_inl. 2175b152de19f5e0aac996676c262e7a772e16c692f5philippe VG_(snprintf) (buf_srcloc, BUF_LEN, "%s", cur_inl->filename); 2176a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe lineno = cur_inl->lineno; 2177a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 217859e1f3c79e870a978d24add86db6d8c5450c8b63philippe know_dirinfo = False; 2179a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe know_srcloc = True; 2180a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 2181a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2182a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 218314cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj buf_fn [ sizeof(buf_fn)-1 ] = 0; 218414cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj buf_obj [ sizeof(buf_obj)-1 ] = 0; 218514cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj buf_srcloc [ sizeof(buf_srcloc)-1 ] = 0; 218614cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj buf_dirname[ sizeof(buf_dirname)-1 ] = 0; 218714cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj 2188eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (VG_(clo_xml)) { 2189eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2190eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool human_readable = True; 21916bd9dc18c043927c1196caba20a327238a179c42florian const HChar* maybe_newline = human_readable ? "\n " : ""; 21926bd9dc18c043927c1196caba20a327238a179c42florian const HChar* maybe_newline2 = human_readable ? "\n " : ""; 2193eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2194e872fec0c1c3b478a399fdba42ac65764b53f470sewardj /* Print in XML format, dumping in as much info as we know. 2195e872fec0c1c3b478a399fdba42ac65764b53f470sewardj Ensure all tags are balanced even if the individual strings 2196e872fec0c1c3b478a399fdba42ac65764b53f470sewardj are too long. Allocate 1/10 of BUF_LEN to the object name, 2197e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 6/10s to the function name, 1/10 to the directory name and 2198e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 1/10 to the file name, leaving 1/10 for all the fixed-length 2199e872fec0c1c3b478a399fdba42ac65764b53f470sewardj stuff. */ 2200eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<frame>"); 2201a44b15f527bbebfe824a2e68e4bd6ab1e153b486sewardj VG_(sprintf)(ibuf,"<ip>0x%llX</ip>", (ULong)eip); 2202eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2203eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 2204eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_objname) { 2205eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2206eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<obj>"); 2207e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(1*BUF_LEN/10, buf_obj); 2208eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</obj>"); 2209eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2210eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_fnname) { 2211eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2212eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<fn>"); 2213e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(6*BUF_LEN/10, buf_fn); 2214eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</fn>"); 2215eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2216eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_srcloc) { 2217eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_dirinfo) { 2218eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2219eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<dir>"); 2220e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(1*BUF_LEN/10, buf_dirname); 2221eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</dir>"); 2222eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2223eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2224eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<file>"); 2225e872fec0c1c3b478a399fdba42ac65764b53f470sewardj APPEND_ESC(1*BUF_LEN/10, buf_srcloc); 2226eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</file>"); 2227eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2228eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<line>"); 2229eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(sprintf)(ibuf,"%d",lineno); 2230eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 2231eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</line>"); 2232eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2233eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline2); 2234eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</frame>"); 2235eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2236eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 2237eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2238eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Print for humans to read */ 22395e40abad4504416c59f0b29c1cfc8087201213a9njn // 22405e40abad4504416c59f0b29c1cfc8087201213a9njn // Possible forms: 22415e40abad4504416c59f0b29c1cfc8087201213a9njn // 22425e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: really (a.c:20) 22435e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: really (in /foo/a.out) 22445e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: really (in ???) 22455e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: ??? (in /foo/a.out) 22465e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: ??? (a.c:20) 22475e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: ??? 22485e40abad4504416c59f0b29c1cfc8087201213a9njn // 2249a44b15f527bbebfe824a2e68e4bd6ab1e153b486sewardj VG_(sprintf)(ibuf,"0x%llX: ", (ULong)eip); 2250eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 22515e40abad4504416c59f0b29c1cfc8087201213a9njn if (know_fnname) { 2252eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(buf_fn); 2253eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 2254eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("???"); 2255eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2256eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_srcloc) { 2257eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(" ("); 225814cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // Get the directory name, if any, possibly pruned, into dirname. 22591636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar* dirname = NULL; 226014cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj if (VG_(clo_n_fullpath_after) > 0) { 226114cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj Int i; 226214cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj dirname = buf_dirname; 226314cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // Remove leading prefixes from the dirname. 226414cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // If user supplied --fullpath-after=foo, this will remove 226514cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // a leading string which matches '.*foo' (not greedy). 226614cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj for (i = 0; i < VG_(clo_n_fullpath_after); i++) { 22671636d33c13958b9c0e7d3059cdd5005746418eb2florian const HChar* prefix = VG_(clo_fullpath_after)[i]; 22681636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar* str = VG_(strstr)(dirname, prefix); 226914cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj if (str) { 227014cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj dirname = str + VG_(strlen)(prefix); 227114cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj break; 227214cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj } 227314cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj } 227414cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj /* remove leading "./" */ 227514cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj if (dirname[0] == '.' && dirname[1] == '/') 227614cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj dirname += 2; 227714cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj } 227814cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // do we have any interesting directory name to show? If so 227914cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // add it in. 228014cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj if (dirname && dirname[0] != 0) { 228114cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj APPEND(dirname); 228214cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj APPEND("/"); 22835dd0190bc0ea66f8ffa7218c66f5a2e1c7b51b30bart } 2284eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(buf_srcloc); 2285eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(":"); 2286eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(sprintf)(ibuf,"%d",lineno); 2287eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 2288eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(")"); 22895e40abad4504416c59f0b29c1cfc8087201213a9njn } else if (know_objname) { 22905e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(" (in "); 22915e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(buf_obj); 22925e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(")"); 22935e40abad4504416c59f0b29c1cfc8087201213a9njn } else if (know_fnname) { 22945e40abad4504416c59f0b29c1cfc8087201213a9njn // Nb: do this in two steps because "??)" is a trigraph! 22955e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(" (in ???"); 22965e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(")"); 2297eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2298eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2299eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2300eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return buf; 2301eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2302eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef APPEND 2303eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef APPEND_ESC 2304eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef BUF_LEN 2305eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2306eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 230772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 2308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 2309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 2310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/ 2311b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- DWARF3 .eh_frame INFO ---*/ 2312b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 2313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 231472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 231572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/* Gather up all the constant pieces of info needed to evaluate 231672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj a CfiExpr into one convenient struct. */ 231772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjtypedef 231872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj struct { 23193026f71684a930286186aa10fef266c304672e8fsewardj D3UnwindRegs* uregs; 23203026f71684a930286186aa10fef266c304672e8fsewardj Addr min_accessible; 23213026f71684a930286186aa10fef266c304672e8fsewardj Addr max_accessible; 232272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 232372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExprEvalContext; 232472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 232572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/* Evaluate the CfiExpr rooted at ix in exprs given the context eec. 232672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj *ok is set to False on failure, but not to True on success. The 232772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj caller must set it to True before calling. */ 2328f7183e38d6215e98043ed014cb947cf5262bdc4asewardj__attribute__((noinline)) 2329f7183e38d6215e98043ed014cb947cf5262bdc4asewardjstatic 233072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjUWord evalCfiExpr ( XArray* exprs, Int ix, 233172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExprEvalContext* eec, Bool* ok ) 233272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj{ 233340628facff2285b0fce592381c6e26fdcd2a1252tom UWord w, wL, wR; 233419dc88f90d0e19a1463797dd99f6792a42f961d3sewardj Addr a; 23353026f71684a930286186aa10fef266c304672e8fsewardj CfiExpr* e; 23363026f71684a930286186aa10fef266c304672e8fsewardj vg_assert(sizeof(Addr) == sizeof(UWord)); 23373026f71684a930286186aa10fef266c304672e8fsewardj e = VG_(indexXA)( exprs, ix ); 233872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->tag) { 233940628facff2285b0fce592381c6e26fdcd2a1252tom case Cex_Unop: 234040628facff2285b0fce592381c6e26fdcd2a1252tom w = evalCfiExpr( exprs, e->Cex.Unop.ix, eec, ok ); 234140628facff2285b0fce592381c6e26fdcd2a1252tom if (!(*ok)) return 0; 234240628facff2285b0fce592381c6e26fdcd2a1252tom switch (e->Cex.Unop.op) { 234340628facff2285b0fce592381c6e26fdcd2a1252tom case Cunop_Abs: return (Word) w < 0 ? - w : w; 234440628facff2285b0fce592381c6e26fdcd2a1252tom case Cunop_Neg: return - (Word) w; 234540628facff2285b0fce592381c6e26fdcd2a1252tom case Cunop_Not: return ~ w; 234640628facff2285b0fce592381c6e26fdcd2a1252tom default: goto unhandled; 234740628facff2285b0fce592381c6e26fdcd2a1252tom } 234840628facff2285b0fce592381c6e26fdcd2a1252tom /*NOTREACHED*/ 234972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_Binop: 235072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj wL = evalCfiExpr( exprs, e->Cex.Binop.ixL, eec, ok ); 235172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!(*ok)) return 0; 235272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj wR = evalCfiExpr( exprs, e->Cex.Binop.ixR, eec, ok ); 235372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!(*ok)) return 0; 235472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->Cex.Binop.op) { 2355f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Add: return wL + wR; 2356f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Sub: return wL - wR; 2357f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_And: return wL & wR; 2358f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Mul: return wL * wR; 2359f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Shl: return wL << wR; 2360f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Shr: return wL >> wR; 2361f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Eq: return wL == wR ? 1 : 0; 2362f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Ge: return (Word) wL >= (Word) wR ? 1 : 0; 2363f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Gt: return (Word) wL > (Word) wR ? 1 : 0; 2364f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Le: return (Word) wL <= (Word) wR ? 1 : 0; 2365f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Lt: return (Word) wL < (Word) wR ? 1 : 0; 2366f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Ne: return wL != wR ? 1 : 0; 236772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: goto unhandled; 236872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 236972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 237072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_CfiReg: 237172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->Cex.CfiReg.reg) { 23723026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 23733026f71684a930286186aa10fef266c304672e8fsewardj case Creg_IA_IP: return eec->uregs->xip; 23743026f71684a930286186aa10fef266c304672e8fsewardj case Creg_IA_SP: return eec->uregs->xsp; 23753026f71684a930286186aa10fef266c304672e8fsewardj case Creg_IA_BP: return eec->uregs->xbp; 23763026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_arm) 23773026f71684a930286186aa10fef266c304672e8fsewardj case Creg_ARM_R15: return eec->uregs->r15; 23783026f71684a930286186aa10fef266c304672e8fsewardj case Creg_ARM_R14: return eec->uregs->r14; 2379fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj case Creg_ARM_R13: return eec->uregs->r13; 2380fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj case Creg_ARM_R12: return eec->uregs->r12; 2381ade2eddf567a868bafad9110ed92acf7373a972bsewardj case Creg_ARM_R7: return eec->uregs->r7; 2382b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGA_s390x) 2383b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Creg_IA_IP: return eec->uregs->ia; 2384b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Creg_IA_SP: return eec->uregs->sp; 2385b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Creg_IA_BP: return eec->uregs->fp; 2386b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case Creg_S390_R14: return eec->uregs->lr; 23874df0bfc0614379192c780c944415dc420d9cfe8epetarj# elif defined(VGA_mips32) || defined(VGA_mips64) 23885db15403e889d4db339b342bc2a824ef0bfaa654sewardj case Creg_IA_IP: return eec->uregs->pc; 23895db15403e889d4db339b342bc2a824ef0bfaa654sewardj case Creg_IA_SP: return eec->uregs->sp; 23905db15403e889d4db339b342bc2a824ef0bfaa654sewardj case Creg_IA_BP: return eec->uregs->fp; 23915db15403e889d4db339b342bc2a824ef0bfaa654sewardj case Creg_MIPS_RA: return eec->uregs->ra; 23923026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_ppc32) || defined(VGA_ppc64) 2393f0c1250e324f6684757c6a15545366447ef1d64fsewardj# elif defined(VGP_arm64_linux) 2394821283b2110420321fd3f60afcc799b287788c68sewardj case Creg_ARM64_X30: return eec->uregs->x30; 23953026f71684a930286186aa10fef266c304672e8fsewardj# else 23963026f71684a930286186aa10fef266c304672e8fsewardj# error "Unsupported arch" 23973026f71684a930286186aa10fef266c304672e8fsewardj# endif 239872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: goto unhandled; 239972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 240072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 240172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_Const: 240272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj return e->Cex.Const.con; 240319dc88f90d0e19a1463797dd99f6792a42f961d3sewardj case Cex_Deref: 240419dc88f90d0e19a1463797dd99f6792a42f961d3sewardj a = evalCfiExpr( exprs, e->Cex.Deref.ixAddr, eec, ok ); 240519dc88f90d0e19a1463797dd99f6792a42f961d3sewardj if (!(*ok)) return 0; 240619dc88f90d0e19a1463797dd99f6792a42f961d3sewardj if (a < eec->min_accessible 2407720e6b71b171885281afab634ce4d667c1f262bcsewardj || a > eec->max_accessible - sizeof(UWord) + 1) { 240819dc88f90d0e19a1463797dd99f6792a42f961d3sewardj *ok = False; 240919dc88f90d0e19a1463797dd99f6792a42f961d3sewardj return 0; 241019dc88f90d0e19a1463797dd99f6792a42f961d3sewardj } 241119dc88f90d0e19a1463797dd99f6792a42f961d3sewardj /* let's hope it doesn't trap! */ 241286781fabbfc019b752f9605e487cfce77b2a592atom return ML_(read_UWord)((void *)a); 241372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: 241472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj goto unhandled; 241572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 241672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 241772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj unhandled: 241872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("\n\nevalCfiExpr: unhandled\n"); 241972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj ML_(ppCfiExpr)( exprs, ix ); 242072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("\n"); 242172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); 242272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 242372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj return 0; 242472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj} 242572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 242672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 24275c3dba227192de63d86f65ec7d9597c132818c37philippe/* Search all the DebugInfos in the entire system, to find the DiCfSI_m 2428f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj that pertains to 'ip'. 2429eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2430f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj If found, set *diP to the DebugInfo in which it resides, and 24315c3dba227192de63d86f65ec7d9597c132818c37philippe *cfsi_mP to the cfsi_m pointer in that DebugInfo's cfsi_m_pool. 243272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 24335c3dba227192de63d86f65ec7d9597c132818c37philippe If not found, set *diP to (DebugInfo*)1 and *cfsi_mP to zero. 2434f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj*/ 2435f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj__attribute__((noinline)) 2436f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic void find_DiCfSI ( /*OUT*/DebugInfo** diP, 24375c3dba227192de63d86f65ec7d9597c132818c37philippe /*OUT*/DiCfSI_m** cfsi_mP, 2438f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Addr ip ) 2439f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 2440f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo* di; 2441f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word i = -1; 2442f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2443f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj static UWord n_search = 0; 2444f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj static UWord n_steps = 0; 2445eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_search++; 2446eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2447f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0) VG_(printf)("search for %#lx\n", ip); 2448eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2449f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (di = debugInfo_list; di != NULL; di = di->next) { 2450f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word j; 2451eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_steps++; 2452eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Use the per-DebugInfo summary address ranges to skip 2454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj inapplicable DebugInfos quickly. */ 2455f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di->cfsi_used == 0) 2456eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj continue; 2457f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (ip < di->cfsi_minavma || ip > di->cfsi_maxavma) 2458eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj continue; 2459eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2460f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* It might be in this DebugInfo. Search it. */ 2461f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj j = ML_(search_one_cfitab)( di, ip ); 2462f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(j >= -1 && j < (Word)di->cfsi_used); 2463f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2464f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (j != -1) { 2465f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj i = j; 2466f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj break; /* found it */ 2467eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2468eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2469eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2470f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (i == -1) { 2471f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2472f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* we didn't find it. */ 2473f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *diP = (DebugInfo*)1; 24745c3dba227192de63d86f65ec7d9597c132818c37philippe *cfsi_mP = 0; 2475f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2476f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 2477f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 24785c3dba227192de63d86f65ec7d9597c132818c37philippe /* found a di corresponding to ip. */ 2479f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* ensure that di is 4-aligned (at least), so it can't possibly 2480f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj be equal to (DebugInfo*)1. */ 2481f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di && VG_IS_4_ALIGNED(di)); 24825c3dba227192de63d86f65ec7d9597c132818c37philippe *cfsi_mP = ML_(get_cfsi_m) (di, i); 24835c3dba227192de63d86f65ec7d9597c132818c37philippe if (*cfsi_mP == NULL) { 24845c3dba227192de63d86f65ec7d9597c132818c37philippe // This is a cfsi hole. Report no cfi information found. 24855c3dba227192de63d86f65ec7d9597c132818c37philippe *diP = (DebugInfo*)1; 24865c3dba227192de63d86f65ec7d9597c132818c37philippe // But we will still perform the hack below. 24875c3dba227192de63d86f65ec7d9597c132818c37philippe } else { 24885c3dba227192de63d86f65ec7d9597c132818c37philippe *diP = di; 24895c3dba227192de63d86f65ec7d9597c132818c37philippe } 2490f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2491f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Start of performance-enhancing hack: once every 64 (chosen 2492f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj hackily after profiling) successful searches, move the found 2493f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo one step closer to the start of the list. This 2494f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj makes future searches cheaper. For starting konqueror on 2495f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj amd64, this in fact reduces the total amount of searching 2496f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj done by the above find-the-right-DebugInfo loop by more than 2497f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj a factor of 20. */ 2498f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if ((n_search & 0xF) == 0) { 2499f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Move di one step closer to the start of the list. */ 2500f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj move_DebugInfo_one_step_forward( di ); 2501f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 2502f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* End of performance-enhancing hack. */ 2503f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2504f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && ((n_search & 0x7FFFF) == 0)) 2505f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(printf)("find_DiCfSI: %lu searches, " 2506f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj "%lu DebugInfos looked at\n", 2507f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj n_search, n_steps); 2508f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2509f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 2510f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2511f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 2512f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2513f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2514f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Now follows a mechanism for caching queries to find_DiCfSI, since 2515f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj they are extremely frequent on amd64-linux, during stack unwinding. 2516f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 25175c3dba227192de63d86f65ec7d9597c132818c37philippe Each cache entry binds an ip value to a (di, cfsi_m*) pair. Possible 2518f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj values: 2519f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 25205c3dba227192de63d86f65ec7d9597c132818c37philippe di is non-null, cfsi_m* >= 0 ==> cache slot in use, "cfsi_m*" 25215c3dba227192de63d86f65ec7d9597c132818c37philippe di is (DebugInfo*)1 ==> cache slot in use, no associated di 25225c3dba227192de63d86f65ec7d9597c132818c37philippe di is NULL ==> cache slot not in use 2523f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2524f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Hence simply zeroing out the entire cache invalidates all 2525f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj entries. 2526f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 25275c3dba227192de63d86f65ec7d9597c132818c37philippe We can map an ip value directly to a (di, cfsi_m*) pair as 25285c3dba227192de63d86f65ec7d9597c132818c37philippe once a DebugInfo is read, adding new DiCfSI_m* is not possible 25295c3dba227192de63d86f65ec7d9597c132818c37philippe anymore, as the cfsi_m_pool is frozen once the reading is terminated. 25305c3dba227192de63d86f65ec7d9597c132818c37philippe Also, the cache is invalidated when new debuginfo is read due to 25315c3dba227192de63d86f65ec7d9597c132818c37philippe an mmap or some debuginfo is discarded due to an munmap. */ 2532eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 25335c3dba227192de63d86f65ec7d9597c132818c37philippe// Prime number, giving about 6Kbytes cache on 32 bits, 25345c3dba227192de63d86f65ec7d9597c132818c37philippe// 12Kbytes cache on 64 bits. 25355c3dba227192de63d86f65ec7d9597c132818c37philippe#define N_CFSI_M_CACHE 509 2536f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2537f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjtypedef 25385c3dba227192de63d86f65ec7d9597c132818c37philippe struct { Addr ip; DebugInfo* di; DiCfSI_m* cfsi_m; } 25395c3dba227192de63d86f65ec7d9597c132818c37philippe CFSI_m_CacheEnt; 2540f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 25415c3dba227192de63d86f65ec7d9597c132818c37philippestatic CFSI_m_CacheEnt cfsi_m_cache[N_CFSI_M_CACHE]; 2542f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 25435c3dba227192de63d86f65ec7d9597c132818c37philippestatic void cfsi_m_cache__invalidate ( void ) { 25445c3dba227192de63d86f65ec7d9597c132818c37philippe VG_(memset)(&cfsi_m_cache, 0, sizeof(cfsi_m_cache)); 254520ede3a4f086d4a4b1e0969b1098dcb244ffb6b4philippe CF_info_generation++; 2546f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 2547f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 254820ede3a4f086d4a4b1e0969b1098dcb244ffb6b4philippeUInt VG_(CF_info_generation) (void) 254920ede3a4f086d4a4b1e0969b1098dcb244ffb6b4philippe{ 255020ede3a4f086d4a4b1e0969b1098dcb244ffb6b4philippe return CF_info_generation; 255120ede3a4f086d4a4b1e0969b1098dcb244ffb6b4philippe} 2552f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 25535c3dba227192de63d86f65ec7d9597c132818c37philippestatic inline CFSI_m_CacheEnt* cfsi_m_cache__find ( Addr ip ) 2554f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 25555c3dba227192de63d86f65ec7d9597c132818c37philippe UWord hash = ip % N_CFSI_M_CACHE; 25565c3dba227192de63d86f65ec7d9597c132818c37philippe CFSI_m_CacheEnt* ce = &cfsi_m_cache[hash]; 25573c9cf3442185b5891e15450d6e3058aeff6796fetom static UWord n_q = 0, n_m = 0; 2558f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2559f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj n_q++; 2560f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && 0 == (n_q & 0x1FFFFF)) 2561f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(printf)("QQQ %lu %lu\n", n_q, n_m); 2562f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 25633c9cf3442185b5891e15450d6e3058aeff6796fetom if (LIKELY(ce->ip == ip) && LIKELY(ce->di != NULL)) { 25643c9cf3442185b5891e15450d6e3058aeff6796fetom /* found an entry in the cache .. */ 25653c9cf3442185b5891e15450d6e3058aeff6796fetom } else { 25663c9cf3442185b5891e15450d6e3058aeff6796fetom /* not found in cache. Search and update. */ 25673c9cf3442185b5891e15450d6e3058aeff6796fetom n_m++; 25683c9cf3442185b5891e15450d6e3058aeff6796fetom ce->ip = ip; 25695c3dba227192de63d86f65ec7d9597c132818c37philippe find_DiCfSI( &ce->di, &ce->cfsi_m, ip ); 25703c9cf3442185b5891e15450d6e3058aeff6796fetom } 2571eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 25723c9cf3442185b5891e15450d6e3058aeff6796fetom if (UNLIKELY(ce->di == (DebugInfo*)1)) { 25733c9cf3442185b5891e15450d6e3058aeff6796fetom /* no DiCfSI for this address */ 25743c9cf3442185b5891e15450d6e3058aeff6796fetom return NULL; 25753c9cf3442185b5891e15450d6e3058aeff6796fetom } else { 25763c9cf3442185b5891e15450d6e3058aeff6796fetom /* found a DiCfSI for this address */ 25773c9cf3442185b5891e15450d6e3058aeff6796fetom return ce; 2578eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 25793c9cf3442185b5891e15450d6e3058aeff6796fetom} 2580eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2581eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2582f7183e38d6215e98043ed014cb947cf5262bdc4asewardjinline 25833026f71684a930286186aa10fef266c304672e8fsewardjstatic Addr compute_cfa ( D3UnwindRegs* uregs, 25843c9cf3442185b5891e15450d6e3058aeff6796fetom Addr min_accessible, Addr max_accessible, 25855c3dba227192de63d86f65ec7d9597c132818c37philippe DebugInfo* di, DiCfSI_m* cfsi_m ) 25863c9cf3442185b5891e15450d6e3058aeff6796fetom{ 25873c9cf3442185b5891e15450d6e3058aeff6796fetom CfiExprEvalContext eec; 25883c9cf3442185b5891e15450d6e3058aeff6796fetom Addr cfa; 25893c9cf3442185b5891e15450d6e3058aeff6796fetom Bool ok; 2590eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 25913c9cf3442185b5891e15450d6e3058aeff6796fetom /* Compute the CFA. */ 259272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj cfa = 0; 25935c3dba227192de63d86f65ec7d9597c132818c37philippe switch (cfsi_m->cfa_how) { 25943026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 25953026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_IA_SPREL: 25965c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->xsp; 25973026f71684a930286186aa10fef266c304672e8fsewardj break; 25983026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_IA_BPREL: 25995c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->xbp; 260072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 26013026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_arm) 26023026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_ARM_R13REL: 26035c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->r13; 260472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 26053026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_ARM_R12REL: 26065c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->r12; 26073026f71684a930286186aa10fef266c304672e8fsewardj break; 26083026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_ARM_R11REL: 26095c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->r11; 26103026f71684a930286186aa10fef266c304672e8fsewardj break; 2611fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj case CFIC_ARM_R7REL: 26125c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->r7; 2613fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj break; 2614b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGA_s390x) 2615b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case CFIC_IA_SPREL: 26165c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->sp; 2617b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 2618b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case CFIR_MEMCFAREL: 2619b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj { 26205c3dba227192de63d86f65ec7d9597c132818c37philippe Addr a = uregs->sp + cfsi_m->cfa_off; 2621b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj if (a < min_accessible || a > max_accessible-sizeof(Addr)) 2622b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 262386781fabbfc019b752f9605e487cfce77b2a592atom cfa = ML_(read_Addr)((void *)a); 2624b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 2625b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj } 2626b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case CFIR_SAME: 2627b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj cfa = uregs->fp; 2628b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 2629b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case CFIC_IA_BPREL: 26305c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->fp; 2631b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 26324df0bfc0614379192c780c944415dc420d9cfe8epetarj# elif defined(VGA_mips32) || defined(VGA_mips64) 26335db15403e889d4db339b342bc2a824ef0bfaa654sewardj case CFIC_IA_SPREL: 26345c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->sp; 26355db15403e889d4db339b342bc2a824ef0bfaa654sewardj break; 26365db15403e889d4db339b342bc2a824ef0bfaa654sewardj case CFIR_SAME: 26375db15403e889d4db339b342bc2a824ef0bfaa654sewardj cfa = uregs->fp; 26385db15403e889d4db339b342bc2a824ef0bfaa654sewardj break; 26395db15403e889d4db339b342bc2a824ef0bfaa654sewardj case CFIC_IA_BPREL: 26405c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->fp; 26415db15403e889d4db339b342bc2a824ef0bfaa654sewardj break; 26423026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_ppc32) || defined(VGA_ppc64) 2643f0c1250e324f6684757c6a15545366447ef1d64fsewardj# elif defined(VGP_arm64_linux) 2644821283b2110420321fd3f60afcc799b287788c68sewardj case CFIC_ARM64_SPREL: 26455c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->sp; 2646821283b2110420321fd3f60afcc799b287788c68sewardj break; 2647821283b2110420321fd3f60afcc799b287788c68sewardj case CFIC_ARM64_X29REL: 26485c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->x29; 2649821283b2110420321fd3f60afcc799b287788c68sewardj break; 26503026f71684a930286186aa10fef266c304672e8fsewardj# else 26513026f71684a930286186aa10fef266c304672e8fsewardj# error "Unsupported arch" 26523026f71684a930286186aa10fef266c304672e8fsewardj# endif 26533026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_EXPR: /* available on all archs */ 26547888e2204fff6e7429236b4227ed16594e7743b9sewardj if (0) { 26557888e2204fff6e7429236b4227ed16594e7743b9sewardj VG_(printf)("CFIC_EXPR: "); 26565c3dba227192de63d86f65ec7d9597c132818c37philippe ML_(ppCfiExpr)(di->cfsi_exprs, cfsi_m->cfa_off); 26577888e2204fff6e7429236b4227ed16594e7743b9sewardj VG_(printf)("\n"); 26587888e2204fff6e7429236b4227ed16594e7743b9sewardj } 26593026f71684a930286186aa10fef266c304672e8fsewardj eec.uregs = uregs; 26607888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.min_accessible = min_accessible; 26617888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.max_accessible = max_accessible; 26627888e2204fff6e7429236b4227ed16594e7743b9sewardj ok = True; 26635c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = evalCfiExpr(di->cfsi_exprs, cfsi_m->cfa_off, &eec, &ok ); 26643c9cf3442185b5891e15450d6e3058aeff6796fetom if (!ok) return 0; 266572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 266672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: 266772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); 266872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 26693c9cf3442185b5891e15450d6e3058aeff6796fetom return cfa; 26703c9cf3442185b5891e15450d6e3058aeff6796fetom} 26713c9cf3442185b5891e15450d6e3058aeff6796fetom 26723c9cf3442185b5891e15450d6e3058aeff6796fetom 26733c9cf3442185b5891e15450d6e3058aeff6796fetom/* Get the call frame address (CFA) given an IP/SP/FP triple. */ 26743026f71684a930286186aa10fef266c304672e8fsewardj/* NOTE: This function may rearrange the order of entries in the 26753026f71684a930286186aa10fef266c304672e8fsewardj DebugInfo list. */ 26763c9cf3442185b5891e15450d6e3058aeff6796fetomAddr ML_(get_CFA) ( Addr ip, Addr sp, Addr fp, 26773c9cf3442185b5891e15450d6e3058aeff6796fetom Addr min_accessible, Addr max_accessible ) 26783c9cf3442185b5891e15450d6e3058aeff6796fetom{ 26795c3dba227192de63d86f65ec7d9597c132818c37philippe CFSI_m_CacheEnt* ce; 26803c9cf3442185b5891e15450d6e3058aeff6796fetom 26815c3dba227192de63d86f65ec7d9597c132818c37philippe ce = cfsi_m_cache__find(ip); 26823c9cf3442185b5891e15450d6e3058aeff6796fetom 26833c9cf3442185b5891e15450d6e3058aeff6796fetom if (UNLIKELY(ce == NULL)) 26843c9cf3442185b5891e15450d6e3058aeff6796fetom return 0; /* no info. Nothing we can do. */ 26853c9cf3442185b5891e15450d6e3058aeff6796fetom 26863026f71684a930286186aa10fef266c304672e8fsewardj /* Temporary impedance-matching kludge so that this keeps working 26873026f71684a930286186aa10fef266c304672e8fsewardj on x86-linux and amd64-linux. */ 26883026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 26893026f71684a930286186aa10fef266c304672e8fsewardj { D3UnwindRegs uregs; 26903026f71684a930286186aa10fef266c304672e8fsewardj uregs.xip = ip; 26913026f71684a930286186aa10fef266c304672e8fsewardj uregs.xsp = sp; 26923026f71684a930286186aa10fef266c304672e8fsewardj uregs.xbp = fp; 26933026f71684a930286186aa10fef266c304672e8fsewardj return compute_cfa(&uregs, 269405c459ea63c50a072cf1eb0868590e9c0b362f30philippe min_accessible, max_accessible, ce->di, ce->cfsi_m); 26953026f71684a930286186aa10fef266c304672e8fsewardj } 2696b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#elif defined(VGA_s390x) 2697b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj { D3UnwindRegs uregs; 2698b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj uregs.ia = ip; 2699b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj uregs.sp = sp; 2700b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj uregs.fp = fp; 2701b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj return compute_cfa(&uregs, 270205c459ea63c50a072cf1eb0868590e9c0b362f30philippe min_accessible, max_accessible, ce->di, ce->cfsi_m); 2703b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj } 2704f03d0b76228354fb63eb970a4e6c9fa1337d60a9dejanj#elif defined(VGA_mips32) || defined(VGA_mips64) 2705fe0b43315c344cfd07981a0826bc34614a220169dejanj { D3UnwindRegs uregs; 2706fe0b43315c344cfd07981a0826bc34614a220169dejanj uregs.pc = ip; 2707fe0b43315c344cfd07981a0826bc34614a220169dejanj uregs.sp = sp; 2708fe0b43315c344cfd07981a0826bc34614a220169dejanj uregs.fp = fp; 2709fe0b43315c344cfd07981a0826bc34614a220169dejanj return compute_cfa(&uregs, 271005c459ea63c50a072cf1eb0868590e9c0b362f30philippe min_accessible, max_accessible, ce->di, ce->cfsi_m); 2711fe0b43315c344cfd07981a0826bc34614a220169dejanj } 2712b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 27133026f71684a930286186aa10fef266c304672e8fsewardj# else 27143026f71684a930286186aa10fef266c304672e8fsewardj return 0; /* indicates failure */ 27153026f71684a930286186aa10fef266c304672e8fsewardj# endif 27163c9cf3442185b5891e15450d6e3058aeff6796fetom} 27173c9cf3442185b5891e15450d6e3058aeff6796fetom 27183c9cf3442185b5891e15450d6e3058aeff6796fetom 27193026f71684a930286186aa10fef266c304672e8fsewardj/* The main function for DWARF2/3 CFI-based stack unwinding. Given a 27203026f71684a930286186aa10fef266c304672e8fsewardj set of registers in UREGS, modify it to hold the register values 27213026f71684a930286186aa10fef266c304672e8fsewardj for the previous frame, if possible. Returns True if successful. 27223026f71684a930286186aa10fef266c304672e8fsewardj If not successful, *UREGS is not changed. 27233026f71684a930286186aa10fef266c304672e8fsewardj 27243026f71684a930286186aa10fef266c304672e8fsewardj For x86 and amd64, the unwound registers are: {E,R}IP, 27253026f71684a930286186aa10fef266c304672e8fsewardj {E,R}SP, {E,R}BP. 27263026f71684a930286186aa10fef266c304672e8fsewardj 2727fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj For arm, the unwound registers are: R7 R11 R12 R13 R14 R15. 2728821283b2110420321fd3f60afcc799b287788c68sewardj 2729821283b2110420321fd3f60afcc799b287788c68sewardj For arm64, the unwound registers are: X29(FP) X30(LR) SP PC. 27303026f71684a930286186aa10fef266c304672e8fsewardj*/ 27313026f71684a930286186aa10fef266c304672e8fsewardjBool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere, 27323c9cf3442185b5891e15450d6e3058aeff6796fetom Addr min_accessible, 27333c9cf3442185b5891e15450d6e3058aeff6796fetom Addr max_accessible ) 27343c9cf3442185b5891e15450d6e3058aeff6796fetom{ 27353c9cf3442185b5891e15450d6e3058aeff6796fetom DebugInfo* di; 27365c3dba227192de63d86f65ec7d9597c132818c37philippe DiCfSI_m* cfsi_m = NULL; 27373026f71684a930286186aa10fef266c304672e8fsewardj Addr cfa, ipHere = 0; 27385c3dba227192de63d86f65ec7d9597c132818c37philippe CFSI_m_CacheEnt* ce; 2739d2be8cc17fed04cbd701e9a2cc1cf365ff45cc44sewardj CfiExprEvalContext eec __attribute__((unused)); 27403026f71684a930286186aa10fef266c304672e8fsewardj D3UnwindRegs uregsPrev; 27413c9cf3442185b5891e15450d6e3058aeff6796fetom 27423026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 27433026f71684a930286186aa10fef266c304672e8fsewardj ipHere = uregsHere->xip; 27443026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_arm) 27453026f71684a930286186aa10fef266c304672e8fsewardj ipHere = uregsHere->r15; 2746b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGA_s390x) 2747b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj ipHere = uregsHere->ia; 27484df0bfc0614379192c780c944415dc420d9cfe8epetarj# elif defined(VGA_mips32) || defined(VGA_mips64) 27495db15403e889d4db339b342bc2a824ef0bfaa654sewardj ipHere = uregsHere->pc; 27503026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_ppc32) || defined(VGA_ppc64) 2751f0c1250e324f6684757c6a15545366447ef1d64fsewardj# elif defined(VGP_arm64_linux) 2752821283b2110420321fd3f60afcc799b287788c68sewardj ipHere = uregsHere->pc; 27533026f71684a930286186aa10fef266c304672e8fsewardj# else 27543026f71684a930286186aa10fef266c304672e8fsewardj# error "Unknown arch" 27553026f71684a930286186aa10fef266c304672e8fsewardj# endif 27565c3dba227192de63d86f65ec7d9597c132818c37philippe ce = cfsi_m_cache__find(ipHere); 27573c9cf3442185b5891e15450d6e3058aeff6796fetom 27583c9cf3442185b5891e15450d6e3058aeff6796fetom if (UNLIKELY(ce == NULL)) 27593c9cf3442185b5891e15450d6e3058aeff6796fetom return False; /* no info. Nothing we can do. */ 27603c9cf3442185b5891e15450d6e3058aeff6796fetom 27613c9cf3442185b5891e15450d6e3058aeff6796fetom di = ce->di; 27625c3dba227192de63d86f65ec7d9597c132818c37philippe cfsi_m = ce->cfsi_m; 27633c9cf3442185b5891e15450d6e3058aeff6796fetom 27643c9cf3442185b5891e15450d6e3058aeff6796fetom if (0) { 27655c3dba227192de63d86f65ec7d9597c132818c37philippe VG_(printf)("found cfsi_m (but printing fake base/len): "); 27665c3dba227192de63d86f65ec7d9597c132818c37philippe ML_(ppDiCfSI)(di->cfsi_exprs, 0, 0, cfsi_m); 27673c9cf3442185b5891e15450d6e3058aeff6796fetom } 27683c9cf3442185b5891e15450d6e3058aeff6796fetom 2769f7183e38d6215e98043ed014cb947cf5262bdc4asewardj VG_(bzero_inline)(&uregsPrev, sizeof(uregsPrev)); 27703c9cf3442185b5891e15450d6e3058aeff6796fetom 27713c9cf3442185b5891e15450d6e3058aeff6796fetom /* First compute the CFA. */ 27723026f71684a930286186aa10fef266c304672e8fsewardj cfa = compute_cfa(uregsHere, 27735c3dba227192de63d86f65ec7d9597c132818c37philippe min_accessible, max_accessible, di, cfsi_m); 27743c9cf3442185b5891e15450d6e3058aeff6796fetom if (UNLIKELY(cfa == 0)) 27753c9cf3442185b5891e15450d6e3058aeff6796fetom return False; 277672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 277772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /* Now we know the CFA, use it to roll back the registers we're 277872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj interested in. */ 2779eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2780eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define COMPUTE(_prev, _here, _how, _off) \ 2781eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj do { \ 2782eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj switch (_how) { \ 2783eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_UNKNOWN: \ 2784eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; \ 2785eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_SAME: \ 2786eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj _prev = _here; break; \ 2787eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_MEMCFAREL: { \ 2788eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Addr a = cfa + (Word)_off; \ 2789eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (a < min_accessible \ 27909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj || a > max_accessible-sizeof(Addr)) \ 2791eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; \ 279286781fabbfc019b752f9605e487cfce77b2a592atom _prev = ML_(read_Addr)((void *)a); \ 2793eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; \ 2794eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } \ 2795eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_CFAREL: \ 2796eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj _prev = cfa + (Word)_off; \ 2797eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; \ 279872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case CFIR_EXPR: \ 279972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (0) \ 2800f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj ML_(ppCfiExpr)(di->cfsi_exprs,_off); \ 28013026f71684a930286186aa10fef266c304672e8fsewardj eec.uregs = uregsHere; \ 280272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.min_accessible = min_accessible; \ 280372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.max_accessible = max_accessible; \ 2804d2be8cc17fed04cbd701e9a2cc1cf365ff45cc44sewardj Bool ok = True; \ 2805f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj _prev = evalCfiExpr(di->cfsi_exprs, _off, &eec, &ok ); \ 280672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!ok) return False; \ 280772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; \ 280872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: \ 280972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); \ 2810eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } \ 2811eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } while (0) 2812eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 28133026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 28145c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.xip, uregsHere->xip, cfsi_m->ra_how, cfsi_m->ra_off); 28155c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.xsp, uregsHere->xsp, cfsi_m->sp_how, cfsi_m->sp_off); 28165c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.xbp, uregsHere->xbp, cfsi_m->bp_how, cfsi_m->bp_off); 28173026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_arm) 28185c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r15, uregsHere->r15, cfsi_m->ra_how, cfsi_m->ra_off); 28195c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r14, uregsHere->r14, cfsi_m->r14_how, cfsi_m->r14_off); 28205c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r13, uregsHere->r13, cfsi_m->r13_how, cfsi_m->r13_off); 28215c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r12, uregsHere->r12, cfsi_m->r12_how, cfsi_m->r12_off); 28225c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r11, uregsHere->r11, cfsi_m->r11_how, cfsi_m->r11_off); 28235c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r7, uregsHere->r7, cfsi_m->r7_how, cfsi_m->r7_off); 2824b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGA_s390x) 28255c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.ia, uregsHere->ia, cfsi_m->ra_how, cfsi_m->ra_off); 28265c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off); 28275c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi_m->fp_how, cfsi_m->fp_off); 28284df0bfc0614379192c780c944415dc420d9cfe8epetarj# elif defined(VGA_mips32) || defined(VGA_mips64) 28295c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi_m->ra_how, cfsi_m->ra_off); 28305c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off); 28315c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi_m->fp_how, cfsi_m->fp_off); 28323026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_ppc32) || defined(VGA_ppc64) 2833f0c1250e324f6684757c6a15545366447ef1d64fsewardj# elif defined(VGP_arm64_linux) 28345c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi_m->ra_how, cfsi_m->ra_off); 28355c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off); 28365c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.x30, uregsHere->x30, cfsi_m->x30_how, cfsi_m->x30_off); 28375c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.x29, uregsHere->x29, cfsi_m->x29_how, cfsi_m->x29_off); 28383026f71684a930286186aa10fef266c304672e8fsewardj# else 28393026f71684a930286186aa10fef266c304672e8fsewardj# error "Unknown arch" 28403026f71684a930286186aa10fef266c304672e8fsewardj# endif 2841eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2842eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef COMPUTE 2843eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 28443026f71684a930286186aa10fef266c304672e8fsewardj *uregsHere = uregsPrev; 2845eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 2846eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2847eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2848eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2849b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 2850b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 2851c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/ 2852c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- MSVC FPO INFO ---*/ 2853c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- ---*/ 2854c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--------------------------------------------------------------*/ 2855c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2856c8259b85b701d25d72aabe9dc0a8154517f96913sewardjBool VG_(use_FPO_info) ( /*MOD*/Addr* ipP, 2857c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /*MOD*/Addr* spP, 2858c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /*MOD*/Addr* fpP, 2859c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Addr min_accessible, 2860c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Addr max_accessible ) 2861c8259b85b701d25d72aabe9dc0a8154517f96913sewardj{ 2862c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Word i; 2863c8259b85b701d25d72aabe9dc0a8154517f96913sewardj DebugInfo* di; 2864c8259b85b701d25d72aabe9dc0a8154517f96913sewardj FPO_DATA* fpo = NULL; 2865c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Addr spHere; 2866c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2867c8259b85b701d25d72aabe9dc0a8154517f96913sewardj static UWord n_search = 0; 2868c8259b85b701d25d72aabe9dc0a8154517f96913sewardj static UWord n_steps = 0; 2869c8259b85b701d25d72aabe9dc0a8154517f96913sewardj n_search++; 2870c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2871c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0) VG_(printf)("search FPO for %#lx\n", *ipP); 2872c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2873c8259b85b701d25d72aabe9dc0a8154517f96913sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 2874c8259b85b701d25d72aabe9dc0a8154517f96913sewardj n_steps++; 2875c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2876c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Use the per-DebugInfo summary address ranges to skip 2877c8259b85b701d25d72aabe9dc0a8154517f96913sewardj inapplicable DebugInfos quickly. */ 2878c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (di->fpo == NULL) 2879c8259b85b701d25d72aabe9dc0a8154517f96913sewardj continue; 2880c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (*ipP < di->fpo_minavma || *ipP > di->fpo_maxavma) 2881c8259b85b701d25d72aabe9dc0a8154517f96913sewardj continue; 2882c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2883c8259b85b701d25d72aabe9dc0a8154517f96913sewardj i = ML_(search_one_fpotab)( di, *ipP ); 2884c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (i != -1) { 2885c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Word j; 2886c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0) { 2887c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* debug printing only */ 2888c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("look for %#lx size %ld i %ld\n", 2889c8259b85b701d25d72aabe9dc0a8154517f96913sewardj *ipP, di->fpo_size, i); 2890c8259b85b701d25d72aabe9dc0a8154517f96913sewardj for (j = 0; j < di->fpo_size; j++) 2891c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("[%02ld] %#x %d\n", 2892c8259b85b701d25d72aabe9dc0a8154517f96913sewardj j, di->fpo[j].ulOffStart, di->fpo[j].cbProcSize); 2893c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2894c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(i >= 0 && i < di->fpo_size); 2895c8259b85b701d25d72aabe9dc0a8154517f96913sewardj fpo = &di->fpo[i]; 2896c8259b85b701d25d72aabe9dc0a8154517f96913sewardj break; 2897c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2898c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2899c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2900c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (fpo == NULL) 2901c8259b85b701d25d72aabe9dc0a8154517f96913sewardj return False; 2902c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2903c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0 && ((n_search & 0x7FFFF) == 0)) 2904c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("VG_(use_FPO_info): %lu searches, " 2905c8259b85b701d25d72aabe9dc0a8154517f96913sewardj "%lu DebugInfos looked at\n", 2906c8259b85b701d25d72aabe9dc0a8154517f96913sewardj n_search, n_steps); 2907c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2908c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2909c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Start of performance-enhancing hack: once every 64 (chosen 2910c8259b85b701d25d72aabe9dc0a8154517f96913sewardj hackily after profiling) successful searches, move the found 2911c8259b85b701d25d72aabe9dc0a8154517f96913sewardj DebugInfo one step closer to the start of the list. This makes 2912c8259b85b701d25d72aabe9dc0a8154517f96913sewardj future searches cheaper. For starting konqueror on amd64, this 2913c8259b85b701d25d72aabe9dc0a8154517f96913sewardj in fact reduces the total amount of searching done by the above 2914c8259b85b701d25d72aabe9dc0a8154517f96913sewardj find-the-right-DebugInfo loop by more than a factor of 20. */ 2915c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if ((n_search & 0x3F) == 0) { 2916c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Move si one step closer to the start of the list. */ 2917c8259b85b701d25d72aabe9dc0a8154517f96913sewardj //move_DebugInfo_one_step_forward( di ); 2918c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2919c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* End of performance-enhancing hack. */ 2920c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2921c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0) { 2922c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("found fpo: "); 2923c8259b85b701d25d72aabe9dc0a8154517f96913sewardj //ML_(ppFPO)(fpo); 2924c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 2925c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2926c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* 2927c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Stack layout is: 2928c8259b85b701d25d72aabe9dc0a8154517f96913sewardj %esp-> 2929c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 4*.cbRegs {%edi, %esi, %ebp, %ebx} 2930c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 4*.cdwLocals 2931c8259b85b701d25d72aabe9dc0a8154517f96913sewardj return_pc 2932c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 4*.cdwParams 2933c8259b85b701d25d72aabe9dc0a8154517f96913sewardj prior_%esp-> 2934c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2935c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Typical code looks like: 2936c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sub $4*.cdwLocals,%esp 2937c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Alternative to above for >=4KB (and sometimes for smaller): 2938c8259b85b701d25d72aabe9dc0a8154517f96913sewardj mov $size,%eax 2939c8259b85b701d25d72aabe9dc0a8154517f96913sewardj call __chkstk # WinNT performs page-by-page probe! 2940c8259b85b701d25d72aabe9dc0a8154517f96913sewardj __chkstk is much like alloc(), except that on return 2941c8259b85b701d25d72aabe9dc0a8154517f96913sewardj %eax= 5+ &CALL. Thus it could be used as part of 2942c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Position Independent Code to locate the Global Offset Table. 2943c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %ebx 2944c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %ebp 2945c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %esi 2946c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Other once-only instructions often scheduled >here<. 2947c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %edi 2948c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2949c8259b85b701d25d72aabe9dc0a8154517f96913sewardj If the pc is within the first .cbProlog bytes of the function, 2950c8259b85b701d25d72aabe9dc0a8154517f96913sewardj then you must disassemble to see how many registers have been pushed, 2951c8259b85b701d25d72aabe9dc0a8154517f96913sewardj because instructions in the prolog may be scheduled for performance. 2952c8259b85b701d25d72aabe9dc0a8154517f96913sewardj The order of PUSH is always %ebx, %ebp, %esi, %edi, with trailing 2953c8259b85b701d25d72aabe9dc0a8154517f96913sewardj registers not pushed when .cbRegs < 4. This seems somewhat strange 2954c8259b85b701d25d72aabe9dc0a8154517f96913sewardj because %ebp is the register whose usage you want to minimize, 2955c8259b85b701d25d72aabe9dc0a8154517f96913sewardj yet it is in the first half of the PUSH list. 2956c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2957c8259b85b701d25d72aabe9dc0a8154517f96913sewardj I don't know what happens when the compiler constructs an outgoing CALL. 2958c8259b85b701d25d72aabe9dc0a8154517f96913sewardj %esp could move if outgoing parameters are PUSHed, and this affects 2959c8259b85b701d25d72aabe9dc0a8154517f96913sewardj traceback for errors during the PUSHes. */ 2960c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2961c8259b85b701d25d72aabe9dc0a8154517f96913sewardj spHere = *spP; 2962c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 296386781fabbfc019b752f9605e487cfce77b2a592atom *ipP = ML_(read_Addr)((void *)(spHere + 4*(fpo->cbRegs + fpo->cdwLocals))); 296486781fabbfc019b752f9605e487cfce77b2a592atom *spP = spHere + 4*(fpo->cbRegs + fpo->cdwLocals + 1 296586781fabbfc019b752f9605e487cfce77b2a592atom + fpo->cdwParams); 296686781fabbfc019b752f9605e487cfce77b2a592atom *fpP = ML_(read_Addr)((void *)(spHere + 4*2)); 2967c8259b85b701d25d72aabe9dc0a8154517f96913sewardj return True; 2968c8259b85b701d25d72aabe9dc0a8154517f96913sewardj} 2969c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2970c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2971c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--------------------------------------------------------------*/ 2972c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- ---*/ 2973b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- TOP LEVEL: GENERATE DESCRIPTION OF DATA ADDRESSES ---*/ 2974b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- FROM DWARF3 DEBUG INFO ---*/ 2975b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 2976b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 2977b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 2978588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj/* Try to make p2XA(dst, fmt, args..) turn into 2979b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart VG_(xaprintf)(dst, fmt, args) without having to resort to 2980588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj vararg macros. As usual with everything to do with varargs, it's 2981588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj an ugly hack. 2982738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 2983588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj //#define p2XA(dstxa, format, args...) 2984b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart // VG_(xaprintf)(dstxa, format, ##args) 2985738856f99eea33d86ce91dcb1d6cd5b151e307casewardj*/ 2986b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart#define p2XA VG_(xaprintf) 2987738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 2988588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj/* Add a zero-terminating byte to DST, which must be an XArray* of 2989588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj HChar. */ 2990738856f99eea33d86ce91dcb1d6cd5b151e307casewardjstatic void zterm_XA ( XArray* dst ) 2991738856f99eea33d86ce91dcb1d6cd5b151e307casewardj{ 2992738856f99eea33d86ce91dcb1d6cd5b151e307casewardj HChar zero = 0; 2993738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (void) VG_(addBytesToXA)( dst, &zero, 1 ); 2994738856f99eea33d86ce91dcb1d6cd5b151e307casewardj} 2995738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 2996738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 2997b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Evaluate the location expression/list for var, to see whether or 2998b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj not data_addr falls within the variable. If so also return the 2999b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset of data_addr from the start of the variable. Note that 3000b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs, which supplies ip,sp,fp values, will be NULL for global 3001b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj variables, and non-NULL for local variables. */ 3002c4431bfe04c7490ea2d74939d222d87f13f30960njnstatic Bool data_address_is_in_var ( /*OUT*/PtrdiffT* offset, 30039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* /* TyEnt */ tyents, 3004b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var, 3005b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj RegSummary* regs, 3006b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 3007588658b13b5ad77672f323d48fe9da0ca60b0bcbtom const DebugInfo* di ) 3008b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 300950fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 3010b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj SizeT var_szB; 3011b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj GXResult res; 3012b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool show = False; 30139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 3014b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->name); 3015b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->gexpr); 3016b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3017b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Figure out how big the variable is. */ 301850fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(tyents, var->typeR); 301950fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 302050fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. ML_(addVar) 302150fde23467d92281b32dd537d0d9a590263628c3sewardj should have rejected it. */ 302250fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 302350fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 302450fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 302550fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a host word 302650fde23467d92281b32dd537d0d9a590263628c3sewardj safely (without loss of info). */ 302750fde23467d92281b32dd537d0d9a590263628c3sewardj 302850fde23467d92281b32dd537d0d9a590263628c3sewardj var_szB = (SizeT)mul.ul; /* NB: truncate to host word */ 3029b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3030b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) { 3031a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("VVVV: data_address_%#lx_is_in_var: %s :: ", 3032b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var->name ); 30339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(pp_TyEnt_C_ishly)( tyents, var->typeR ); 3034b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("\n"); 3035b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3036b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3037b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ignore zero-sized vars; they can never match anything. */ 3038b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (var_szB == 0) { 3039b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) 3040b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("VVVV: -> Fail (variable is zero sized)\n"); 3041b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3042b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3043b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3044588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_GX)( var->gexpr, var->fbGX, regs, di ); 3045b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3046b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) { 3047b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("VVVV: -> "); 3048b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(pp_GXResult)( res ); 3049b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("\n"); 3050b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3051eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 30523c9cf3442185b5891e15450d6e3058aeff6796fetom if (res.kind == GXR_Addr 3053b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && res.word <= data_addr 3054b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && data_addr < res.word + var_szB) { 3055b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *offset = data_addr - res.word; 3056b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3057b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 3058b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3059b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3060b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 3061b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3062b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3063738856f99eea33d86ce91dcb1d6cd5b151e307casewardj/* Format the acquired information into DN(AME)1 and DN(AME)2, which 3064738856f99eea33d86ce91dcb1d6cd5b151e307casewardj are XArray*s of HChar, that have been initialised by the caller. 3065738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Resulting strings will be zero terminated. Information is 3066738856f99eea33d86ce91dcb1d6cd5b151e307casewardj formatted in an understandable way. Not so easy. If frameNo is 3067738856f99eea33d86ce91dcb1d6cd5b151e307casewardj -1, this is assumed to be a global variable; else a local 3068738856f99eea33d86ce91dcb1d6cd5b151e307casewardj variable. */ 3069738856f99eea33d86ce91dcb1d6cd5b151e307casewardjstatic void format_message ( /*MOD*/XArray* /* of HChar */ dn1, 3070738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /*MOD*/XArray* /* of HChar */ dn2, 3071b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 3072b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var, 3073c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT var_offset, 3074c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT residual_offset, 3075b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* /*UChar*/ described, 3076b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int frameNo, 3077b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid ) 3078eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3079738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Bool have_descr, have_srcloc; 3080738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Bool xml = VG_(clo_xml); 30811636d33c13958b9c0e7d3059cdd5005746418eb2florian const HChar* vo_plural = var_offset == 1 ? "" : "s"; 30821636d33c13958b9c0e7d3059cdd5005746418eb2florian const HChar* ro_plural = residual_offset == 1 ? "" : "s"; 30831636d33c13958b9c0e7d3059cdd5005746418eb2florian const HChar* basetag = "auxwhat"; /* a constant */ 30841636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar tagL[32], tagR[32], xagL[32], xagR[32]; 3085b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3086d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj if (frameNo < -1) { 3087d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj vg_assert(0); /* Not allowed */ 3088d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj } 3089d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj else if (frameNo == -1) { 3090d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj vg_assert(tid == VG_INVALID_THREADID); 3091d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj } 3092d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj else /* (frameNo >= 0) */ { 3093d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj vg_assert(tid != VG_INVALID_THREADID); 3094d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj } 3095d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj 3096738856f99eea33d86ce91dcb1d6cd5b151e307casewardj vg_assert(dn1 && dn2); 3097b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(described); 3098b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var && var->name); 3099b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj have_descr = VG_(sizeXA)(described) > 0 3100b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && *(UChar*)VG_(indexXA)(described,0) != '\0'; 3101b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj have_srcloc = var->fileName && var->lineNo > 0; 3102b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3103738856f99eea33d86ce91dcb1d6cd5b151e307casewardj tagL[0] = tagR[0] = xagL[0] = xagR[0] = 0; 3104738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3105738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(tagL, "<%s>", basetag); // <auxwhat> 3106738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(tagR, "</%s>", basetag); // </auxwhat> 3107738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(xagL, "<x%s>", basetag); // <xauxwhat> 3108738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(xagR, "</x%s>", basetag); // </xauxwhat> 3109738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3110738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3111738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TAGL(_xa) p2XA(_xa, "%s", tagL) 3112738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TAGR(_xa) p2XA(_xa, "%s", tagR) 3113738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define XAGL(_xa) p2XA(_xa, "%s", xagL) 3114738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define XAGR(_xa) p2XA(_xa, "%s", xagR) 3115738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TXTL(_xa) p2XA(_xa, "%s", "<text>") 3116738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TXTR(_xa) p2XA(_xa, "%s", "</text>") 3117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ------ local cases ------ */ 3119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && (!have_srcloc) && (!have_descr) ) { 3121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc, no description: 3122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside local var "a", 3123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in frame #1 of thread 1 3124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3125738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3126738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3127738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3128b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside local var \"%pS\",", 3129738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3130738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3131738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn2 ); 3132738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3133738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "in frame #%d of thread %d", frameNo, (Int)tid ); 3134738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn2 ); 3135738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3136738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3137738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside local var \"%s\",", 3138738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3139738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3140738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "in frame #%d of thread %d", frameNo, (Int)tid ); 3141738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && have_srcloc && (!have_descr) ) { 3145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no description: 3146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside local var "a" 3147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj declared at dsyms7.c:17, in frame #1 of thread 1 3148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3149738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3150738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3151738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3152b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside local var \"%pS\"", 3153738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3154738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3155738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 3156738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 3157738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3158b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "declared at %pS:%d, in frame #%d of thread %d", 3159738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo, frameNo, (Int)tid ); 3160738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 3161738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 3162738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3163b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart " <file>%pS</file> <line>%d</line> ", 3164738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo ); 3165738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 3166738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3167738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3168738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside local var \"%s\"", 3169738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3170738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3171738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "declared at %s:%d, in frame #%d of thread %d", 3172738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo, frameNo, (Int)tid ); 3173738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3174b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && (!have_srcloc) && have_descr ) { 3177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc: 3178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2 3179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in frame #1 of thread 1 3180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3181738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3182738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3183738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3184b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside %pS%pS", 3185738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3186738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3187738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3188738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn2 ); 3189738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3190738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "in frame #%d of thread %d", frameNo, (Int)tid ); 3191738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn2 ); 3192738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3193738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3194738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %s%s", 3195738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3196738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3197738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3198738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "in frame #%d of thread %d", frameNo, (Int)tid ); 3199738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3200b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && have_srcloc && have_descr ) { 3203738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 3204738856f99eea33d86ce91dcb1d6cd5b151e307casewardj declared at dsyms7.c:17, in frame #1 of thread 1 */ 3205738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3206738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3207738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3208b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside %pS%pS,", 3209738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3210738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3211738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3212738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 3213738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 3214738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3215b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "declared at %pS:%d, in frame #%d of thread %d", 3216738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo, frameNo, (Int)tid ); 3217738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 3218738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 3219738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3220b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart " <file>%pS</file> <line>%d</line> ", 3221738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo ); 3222738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 3223738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3224738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3225738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %s%s,", 3226738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3227738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3228738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3229738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "declared at %s:%d, in frame #%d of thread %d", 3230738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo, frameNo, (Int)tid ); 3231738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3232b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ------ global cases ------ */ 3235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && (!have_srcloc) && (!have_descr) ) { 3236b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc, no description: 3237b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside global var "a" 3238b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3239738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3240738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3241738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3242b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside global var \"%pS\"", 3243738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3244738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3245738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3246738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3247738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside global var \"%s\"", 3248738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3249738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3251b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3252b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && have_srcloc && (!have_descr) ) { 3253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no description: 3254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside global var "a" 3255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj declared at dsyms7.c:17 3256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3257738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3258738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3259738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3260b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside global var \"%pS\"", 3261738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3262738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3263738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 3264738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 3265738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3266b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "declared at %pS:%d", 3267738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo); 3268738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 3269738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 3270738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3271b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart " <file>%pS</file> <line>%d</line> ", 3272738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo ); 3273738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 3274738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3275738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3276738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside global var \"%s\"", 3277738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3278738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3279738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "declared at %s:%d", 3280738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo); 3281738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && (!have_srcloc) && have_descr ) { 3285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc: 3286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 3287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj a global variable 3288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3289738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3290738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3291738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3292b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside %pS%pS,", 3293738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3294738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3295738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3296738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn2 ); 3297738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3298738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "a global variable"); 3299738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn2 ); 3300738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3301738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3302738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %s%s,", 3303738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3304738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (char*)(VG_(indexXA)(described,0)) ); 3305738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3306738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "a global variable"); 3307738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && have_srcloc && have_descr ) { 3311738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 3312738856f99eea33d86ce91dcb1d6cd5b151e307casewardj a global variable declared at dsyms7.c:17 */ 3313738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3314738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3315738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3316b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside %pS%pS,", 3317738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3318738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3319738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3320738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 3321738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 3322738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3323b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "a global variable declared at %pS:%d", 3324738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo); 3325738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 3326738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 3327738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3328b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart " <file>%pS</file> <line>%d</line> ", 3329738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo ); 3330738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 3331738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3332738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3333738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %s%s,", 3334738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3335738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3336738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3337738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "a global variable declared at %s:%d", 3338738856f99eea33d86ce91dcb1d6cd5b151e307casewardj var->fileName, var->lineNo); 3339738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(0); 3343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3344738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /* Zero terminate both strings */ 3345738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dn1 ); 3346738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dn2 ); 3347738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3348738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TAGL 3349738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TAGR 3350738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef XAGL 3351738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef XAGR 3352738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TXTL 3353738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TXTR 3354eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3355eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3356738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Determine if data_addr is a local variable in the frame 3358738856f99eea33d86ce91dcb1d6cd5b151e307casewardj characterised by (ip,sp,fp), and if so write its description at the 3359738856f99eea33d86ce91dcb1d6cd5b151e307casewardj ends of DNAME{1,2}, which are XArray*s of HChar, that have been 3360738856f99eea33d86ce91dcb1d6cd5b151e307casewardj initialised by the caller, zero terminate both, and return True. 3361738856f99eea33d86ce91dcb1d6cd5b151e307casewardj If it's not a local variable in said frame, return False. */ 3362b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic 3363738856f99eea33d86ce91dcb1d6cd5b151e307casewardjBool consider_vars_in_frame ( /*MOD*/XArray* /* of HChar */ dname1, 3364738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /*MOD*/XArray* /* of HChar */ dname2, 3365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 3366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr ip, Addr sp, Addr fp, 3367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* shown to user: */ 3368b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid, Int frameNo ) 3369eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word i; 3371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 3372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj RegSummary regs; 3373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool debug = False; 3374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj static UInt n_search = 0; 3376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj static UInt n_steps = 0; 3377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_search++; 3378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 3379a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("QQQQ: cvif: ip,sp,fp %#lx,%#lx,%#lx\n", ip,sp,fp); 3380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* first, find the DebugInfo that pertains to 'ip'. */ 3381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di; di = di->next) { 3382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_steps++; 3383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* text segment missing? unlikely, but handle it .. */ 3384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->text_present || di->text_size == 0) 3385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok. So does this text mapping bracket the ip? */ 3387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_avma <= ip && ip < di->text_avma + di->text_size) 3388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3391b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Didn't find it. Strange -- means ip is a code address outside 3392b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj of any mapped text segment. Unlikely but not impossible -- app 3393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj could be generating code to run. */ 3394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di) 3395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0 && ((n_search & 0x1) == 0)) 3398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("consider_vars_in_frame: %u searches, " 3399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "%u DebugInfos looked at\n", 3400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_search, n_steps); 3401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Start of performance-enhancing hack: once every ??? (chosen 3402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj hackily after profiling) successful searches, move the found 3403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo one step closer to the start of the list. This makes 3404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj future searches cheaper. */ 3405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ((n_search & 0xFFFF) == 0) { 3406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Move si one step closer to the start of the list. */ 3407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj move_DebugInfo_one_step_forward( di ); 3408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* End of performance-enhancing hack. */ 3410b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3411b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* any var info at all? */ 3412b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->varinfo) 3413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3414b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Work through the scopes from most deeply nested outwards, 3416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj looking for code address ranges that bracket 'ip'. The 3417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj variables on each such address range found are in scope right 3418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj now. Don't descend to level zero as that is the global 3419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj scope. */ 3420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.ip = ip; 3421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.sp = sp; 3422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.fp = fp; 3423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* "for each scope, working outwards ..." */ 3425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) { 3426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* vars; 3427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word j; 3428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* arange; 3429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* this_scope 3430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj = *(OSet**)VG_(indexXA)( di->varinfo, i ); 3431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 3432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("QQQQ: considering scope %ld\n", (Word)i); 3433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!this_scope) 3434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Find the set of variables in this scope that 3436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj bracket the program counter. */ 3437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj arange = VG_(OSetGen_LookupWithCmp)( 3438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj this_scope, &ip, 3439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(cmp_for_DiAddrRange_range) 3440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ); 3441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!arange) 3442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* stay sane */ 3444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->aMin <= arange->aMax); 3445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* It must bracket the ip we asked for, else 3446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(cmp_for_DiAddrRange_range) is somehow broken. */ 3447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->aMin <= ip && ip <= arange->aMax); 3448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* It must have an attached XArray of DiVariables. */ 3449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vars = arange->vars; 3450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(vars); 3451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* But it mustn't cover the entire address range. We only 3452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj expect that to happen for the global scope (level 0), which 3453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj we're not looking at here. Except, it may cover the entire 3454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj address range, but in that case the vars array must be 3455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj empty. */ 3456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(! (arange->aMin == (Addr)0 3457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && arange->aMax == ~(Addr)0 3458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && VG_(sizeXA)(vars) > 0) ); 3459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < VG_(sizeXA)( vars ); j++) { 3460b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j ); 3461c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT offset; 3462b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 3463a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n", 3464b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var->name,arange->aMin,arange->aMax,ip); 34659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (data_address_is_in_var( &offset, di->admin_tyents, 34669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var, ®s, 3467588658b13b5ad77672f323d48fe9da0ca60b0bcbtom data_addr, di )) { 3468c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT residual_offset = 0; 3469b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* described = ML_(describe_type)( &residual_offset, 34709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->admin_tyents, 34719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR, offset ); 3472738856f99eea33d86ce91dcb1d6cd5b151e307casewardj format_message( dname1, dname2, 3473b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var, offset, residual_offset, 3474b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj described, frameNo, tid ); 3475b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)( described ); 3476b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3477b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3478b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3479b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3482eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3483eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3484738856f99eea33d86ce91dcb1d6cd5b151e307casewardj/* Try to form some description of DATA_ADDR by looking at the DWARF3 348525963376a3669e7f77395d6f884bdf1f6a928966philippe debug info we have. This considers all global variables, and 8 3486738856f99eea33d86ce91dcb1d6cd5b151e307casewardj frames in the stacks of all threads. Result is written at the ends 3487738856f99eea33d86ce91dcb1d6cd5b151e307casewardj of DNAME{1,2}V, which are XArray*s of HChar, that have been 3488738856f99eea33d86ce91dcb1d6cd5b151e307casewardj initialised by the caller, and True is returned. If no description 3489738856f99eea33d86ce91dcb1d6cd5b151e307casewardj is created, False is returned. Regardless of the return value, 3490738856f99eea33d86ce91dcb1d6cd5b151e307casewardj DNAME{1,2}V are guaranteed to be zero terminated after the call. 3491738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3492738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Note that after the call, DNAME{1,2} may have more than one 3493738856f99eea33d86ce91dcb1d6cd5b151e307casewardj trailing zero, so callers should establish the useful text length 3494738856f99eea33d86ce91dcb1d6cd5b151e307casewardj using VG_(strlen) on the contents, rather than VG_(sizeXA) on the 3495738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XArray itself. 3496738856f99eea33d86ce91dcb1d6cd5b151e307casewardj*/ 3497738856f99eea33d86ce91dcb1d6cd5b151e307casewardjBool VG_(get_data_description)( 3498738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /*MOD*/ void* /* really, XArray* of HChar */ dname1v, 3499738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /*MOD*/ void* /* really, XArray* of HChar */ dname2v, 3500738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Addr data_addr 3501738856f99eea33d86ce91dcb1d6cd5b151e307casewardj ) 3502eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3503b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# define N_FRAMES 8 3504b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr ips[N_FRAMES], sps[N_FRAMES], fps[N_FRAMES]; 3505b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj UInt n_frames; 3506b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3507b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr stack_min, stack_max; 3508b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid; 3509b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool found; 3510b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 3511b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word j; 3512b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3513738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XArray* dname1 = (XArray*)dname1v; 3514738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XArray* dname2 = (XArray*)dname2v; 3515b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3516a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart if (0) VG_(printf)("get_data_description: dataaddr %#lx\n", data_addr); 3517b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* First, see if data_addr is (or is part of) a global variable. 3518b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Loop over the DebugInfos we have. Check data_addr against the 3519b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj outermost scope of all of them, as that should be a global 3520b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj scope. */ 3521b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 3522b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* global_scope; 35239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word gs_size; 3524b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr zero; 3525b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* global_arange; 3526b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word i; 3527b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* vars; 3528b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3529b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* text segment missing? unlikely, but handle it .. */ 3530b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->text_present || di->text_size == 0) 3531b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3532b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* any var info at all? */ 3533b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->varinfo) 3534b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3535b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* perhaps this object didn't contribute any vars at all? */ 3536b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (VG_(sizeXA)( di->varinfo ) == 0) 3537b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj global_scope = *(OSet**)VG_(indexXA)( di->varinfo, 0 ); 3539b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_scope); 3540b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj gs_size = VG_(OSetGen_Size)( global_scope ); 3541b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* The global scope might be completely empty if this 3542b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj compilation unit declared locals but nothing global. */ 3543b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (gs_size == 0) 3544b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* But if it isn't empty, then it must contain exactly one 3546b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj element, which covers the entire address range. */ 3547b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(gs_size == 1); 3548b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Fish out the global scope and check it is as expected. */ 3549b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj zero = 0; 3550b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj global_arange 3551b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj = VG_(OSetGen_Lookup)( global_scope, &zero ); 3552b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* The global range from (Addr)0 to ~(Addr)0 must exist */ 3553b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_arange); 3554b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_arange->aMin == (Addr)0 3555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && global_arange->aMax == ~(Addr)0); 3556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Any vars in this range? */ 3557b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!global_arange->vars) 3558b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok, there are some vars in the global scope of this 3560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo. Wade through them and see if the data addresses 3561b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj of any of them bracket data_addr. */ 3562b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vars = global_arange->vars; 3563b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = 0; i < VG_(sizeXA)( vars ); i++) { 3564c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT offset; 3565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, i ); 3566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->name); 3567b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Note we use a NULL RegSummary* here. It can't make any 3568b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sense for a global variable to have a location expression 3569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which depends on a SP/FP/IP value. So don't supply any. 3570b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj This means, if the evaluation of the location 3571b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj expression/list requires a register, we have to let it 3572b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj fail. */ 35739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (data_address_is_in_var( &offset, di->admin_tyents, var, 3574b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj NULL/* RegSummary* */, 3575588658b13b5ad77672f323d48fe9da0ca60b0bcbtom data_addr, di )) { 3576c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT residual_offset = 0; 3577b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* described = ML_(describe_type)( &residual_offset, 35789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->admin_tyents, 35799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR, offset ); 3580738856f99eea33d86ce91dcb1d6cd5b151e307casewardj format_message( dname1, dname2, 3581b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var, offset, residual_offset, 3582d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj described, -1/*frameNo*/, 3583d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj VG_INVALID_THREADID ); 3584b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)( described ); 3585738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3586738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3587b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3588b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3589b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3590b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3591b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3592b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok, well it's not a global variable. So now let's snoop around 3593b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in the stacks of all the threads. First try to figure out which 3594b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj thread's stack data_addr is in. */ 3595b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3596b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Perhaps it's on a thread's stack? */ 3597b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj found = False; 3598b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(thread_stack_reset_iter)(&tid); 3599b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) { 3600b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (stack_min >= stack_max) 3601b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; /* ignore obviously stupid cases */ 3602b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (stack_min - VG_STACK_REDZONE_SZB <= data_addr 3603b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && data_addr <= stack_max) { 3604b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj found = True; 3605b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3606b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3607b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3608b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!found) { 3609738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3610738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3611b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3612b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3613b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We conclude data_addr is in thread tid's stack. Unwind the 3615b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj stack to get a bunch of (ip,sp,fp) triples describing the 3616b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj frames, and for each frame, consider the local variables. */ 3617b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_frames = VG_(get_StackTrace)( tid, ips, N_FRAMES, 3618b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sps, fps, 0/*first_ip_delta*/ ); 3619b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj 3620b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_frames >= 0 && n_frames <= N_FRAMES); 3621b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < n_frames; j++) { 3622738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (consider_vars_in_frame( dname1, dname2, 3623b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, 3624b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj ips[j], 3625b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sps[j], fps[j], tid, j )) { 3626738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3627738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3630b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Now, it appears that gcc sometimes appears to produce 3631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj location lists whose ranges don't actually cover the call 3632b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj instruction, even though the address of the variable in 3633b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj question is passed as a parameter in the call. AFAICS this 3634b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is simply a bug in gcc - how can the variable be claimed not 3635b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj exist in memory (on the stack) for the duration of a call in 3636b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which its address is passed? But anyway, in the particular 3637b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case I investigated (memcheck/tests/varinfo6.c, call to croak 3638b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj on line 2999, local var budget declared at line 3115 3639b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj appearing not to exist across the call to mainSort on line 3640b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3143, "gcc.orig (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2)" on 3641b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj amd64), the variable's location list does claim it exists 3642b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj starting at the first byte of the first instruction after the 3643b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj call instruction. So, call consider_vars_in_frame a second 3644b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj time, but this time add 1 to the IP. GDB handles this 3645b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj example with no difficulty, which leads me to believe that 3646b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj either (1) I misunderstood something, or (2) GDB has an 3647b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj equivalent kludge. */ 3648b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj if (j > 0 /* this is a non-innermost frame */ 3649738856f99eea33d86ce91dcb1d6cd5b151e307casewardj && consider_vars_in_frame( dname1, dname2, 3650b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj data_addr, 3651b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj ips[j] + 1, 3652b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj sps[j], fps[j], tid, j )) { 3653738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3654738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3655b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3656b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3657b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3658b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3659b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We didn't find anything useful. */ 3660738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3661738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3662b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3663b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# undef N_FRAMES 3664eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3665eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3666b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 36679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj////////////////////////////////////////////////////////////////// 36689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// // 36699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// Support for other kinds of queries to the Dwarf3 var info // 36709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// // 36719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj////////////////////////////////////////////////////////////////// 36729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 36739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Figure out if the variable 'var' has a location that is linearly 36749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj dependent on a stack pointer value, or a frame pointer value, and 36759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if it is, add a description of it to 'blocks'. Otherwise ignore 36769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. If 'arrays_only' is True, also ignore it unless it has an 36779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj array type. */ 36789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 36799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic 36809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks, 36819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* /* TyEnt */ tyents, 3682588658b13b5ad77672f323d48fe9da0ca60b0bcbtom Addr ip, const DebugInfo* di, DiVariable* var, 36839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool arrays_only ) 36849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 36859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res_sp_6k, res_sp_7k, res_fp_6k, res_fp_7k; 36869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj RegSummary regs; 368750fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 36889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool isVec; 36899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ty; 36909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 36919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool debug = False; 36929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0&&debug) 36939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("adeps: var %s\n", var->name ); 36949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 36959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Figure out how big the variable is. */ 369650fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(tyents, var->typeR); 369750fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 369850fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. ML_(addVar) 369950fde23467d92281b32dd537d0d9a590263628c3sewardj should have rejected it. */ 370050fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 370150fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 370250fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 370350fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a host word 370450fde23467d92281b32dd537d0d9a590263628c3sewardj safely (without loss of info). */ 37059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* skip if non-array and we're only interested in arrays */ 37079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ty = ML_(TyEnts__index_by_cuOff)( tyents, NULL, var->typeR ); 37089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty); 37099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty)); 37109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (ty->tag == Te_UNKNOWN) 37119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return; /* perhaps we should complain in this case? */ 37129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj isVec = ty->tag == Te_TyArray; 37139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (arrays_only && !isVec) 37149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return; 37159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) {ML_(pp_TyEnt_C_ishly)(tyents, var->typeR); 37179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)(" %s\n", var->name);} 37189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Do some test evaluations of the variable's location expression, 37209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj in order to guess whether it is sp-relative, fp-relative, or 37219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj none. A crude hack, which can be interpreted roughly as finding 37229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj the first derivative of the location expression w.r.t. the 37239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj supplied frame and stack pointer values. */ 37249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 0; 37259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 37269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 6 * 1024; 3727588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_sp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 37289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 0; 37309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 37319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 7 * 1024; 3732588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_sp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 37339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 6 * 1024; 37359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 37369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 0; 3737588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_fp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 37389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 7 * 1024; 37409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 37419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 0; 3742588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_fp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 37439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_sp_7k.kind); 37459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_fp_6k.kind); 37469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_fp_7k.kind); 37479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37483c9cf3442185b5891e15450d6e3058aeff6796fetom if (res_sp_6k.kind == GXR_Addr) { 37499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj StackBlock block; 37509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res; 37519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj UWord sp_delta = res_sp_7k.word - res_sp_6k.word; 37529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj UWord fp_delta = res_fp_7k.word - res_fp_6k.word; 37539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(sp_delta == 0 || sp_delta == 1024); 37549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(fp_delta == 0 || fp_delta == 1024); 37559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 0 && fp_delta == 0) { 37579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* depends neither on sp nor fp, so it can't be a stack 37589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj local. Ignore it. */ 37599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 37609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else 37619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 1024 && fp_delta == 0) { 37629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = regs.fp = 0; 37639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 3764588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 37653c9cf3442185b5891e15450d6e3058aeff6796fetom tl_assert(res.kind == GXR_Addr); 37669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 37679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)(" %5ld .. %5ld (sp) %s\n", 376850fde23467d92281b32dd537d0d9a590263628c3sewardj res.word, res.word + ((UWord)mul.ul) - 1, var->name); 37699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.base = res.word; 377050fde23467d92281b32dd537d0d9a590263628c3sewardj block.szB = (SizeT)mul.ul; 37719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.spRel = True; 37729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.isVec = isVec; 37739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)( &block.name[0], 0, sizeof(block.name) ); 37749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (var->name) 37759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 ); 37769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.name[ sizeof(block.name)-1 ] = 0; 37779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( blocks, &block ); 37789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 37799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else 37809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 0 && fp_delta == 1024) { 37819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = regs.fp = 0; 37829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 3783588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 37843c9cf3442185b5891e15450d6e3058aeff6796fetom tl_assert(res.kind == GXR_Addr); 37859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 37869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)(" %5ld .. %5ld (FP) %s\n", 378750fde23467d92281b32dd537d0d9a590263628c3sewardj res.word, res.word + ((UWord)mul.ul) - 1, var->name); 37889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.base = res.word; 378950fde23467d92281b32dd537d0d9a590263628c3sewardj block.szB = (SizeT)mul.ul; 37909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.spRel = False; 37919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.isVec = isVec; 37929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)( &block.name[0], 0, sizeof(block.name) ); 37939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (var->name) 37949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 ); 37959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.name[ sizeof(block.name)-1 ] = 0; 37969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( blocks, &block ); 37979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 37989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else { 37999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(0); 38009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 38019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 38029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 38039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Get an XArray of StackBlock which describe the stack (auto) blocks 38069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for this ip. The caller is expected to free the XArray at some 38079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj point. If 'arrays_only' is True, only array-typed blocks are 38089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj returned; otherwise blocks of all types are returned. */ 38099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid* /* really, XArray* of StackBlock */ 38119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(di_get_stack_blocks_at_ip)( Addr ip, Bool arrays_only ) 38129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 38139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* This is a derivation of consider_vars_in_frame() above. */ 38149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word i; 38159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo* di; 38169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool debug = False; 38179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* res = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dgsbai.1", 38199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(dinfo_free), 38209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj sizeof(StackBlock) ); 38219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj static UInt n_search = 0; 38239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj static UInt n_steps = 0; 38249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_search++; 38259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 38269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: dgsbai: ip %#lx\n", ip); 38279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* first, find the DebugInfo that pertains to 'ip'. */ 38289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (di = debugInfo_list; di; di = di->next) { 38299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_steps++; 38309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* text segment missing? unlikely, but handle it .. */ 38319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->text_present || di->text_size == 0) 38329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 38339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok. So does this text mapping bracket the ip? */ 38349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (di->text_avma <= ip && ip < di->text_avma + di->text_size) 38359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj break; 38369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 38379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Didn't find it. Strange -- means ip is a code address outside 38399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj of any mapped text segment. Unlikely but not impossible -- app 38409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj could be generating code to run. */ 38419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di) 38429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; /* currently empty */ 38439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0 && ((n_search & 0x1) == 0)) 38459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("VG_(di_get_stack_blocks_at_ip): %u searches, " 38469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj "%u DebugInfos looked at\n", 38479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_search, n_steps); 38489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Start of performance-enhancing hack: once every ??? (chosen 38499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj hackily after profiling) successful searches, move the found 38509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo one step closer to the start of the list. This makes 38519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj future searches cheaper. */ 38529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if ((n_search & 0xFFFF) == 0) { 38539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Move si one step closer to the start of the list. */ 38549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj move_DebugInfo_one_step_forward( di ); 38559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 38569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* End of performance-enhancing hack. */ 38579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* any var info at all? */ 38599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->varinfo) 38609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; /* currently empty */ 38619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Work through the scopes from most deeply nested outwards, 38639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj looking for code address ranges that bracket 'ip'. The 38649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj variables on each such address range found are in scope right 38659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj now. Don't descend to level zero as that is the global 38669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj scope. */ 38679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* "for each scope, working outwards ..." */ 38699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) { 38709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* vars; 38719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word j; 38729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiAddrRange* arange; 38739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj OSet* this_scope 38749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj = *(OSet**)VG_(indexXA)( di->varinfo, i ); 38759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 38769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: considering scope %ld\n", (Word)i); 38779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!this_scope) 38789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 38799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Find the set of variables in this scope that 38809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj bracket the program counter. */ 38819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj arange = VG_(OSetGen_LookupWithCmp)( 38829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj this_scope, &ip, 38839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(cmp_for_DiAddrRange_range) 38849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ); 38859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!arange) 38869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 38879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* stay sane */ 38889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(arange->aMin <= arange->aMax); 38899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* It must bracket the ip we asked for, else 38909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(cmp_for_DiAddrRange_range) is somehow broken. */ 38919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(arange->aMin <= ip && ip <= arange->aMax); 38929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* It must have an attached XArray of DiVariables. */ 38939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vars = arange->vars; 38949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(vars); 38959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* But it mustn't cover the entire address range. We only 38969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj expect that to happen for the global scope (level 0), which 38979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj we're not looking at here. Except, it may cover the entire 38989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj address range, but in that case the vars array must be 38999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj empty. */ 39009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(! (arange->aMin == (Addr)0 39019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj && arange->aMax == ~(Addr)0 39029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj && VG_(sizeXA)(vars) > 0) ); 39039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (j = 0; j < VG_(sizeXA)( vars ); j++) { 39049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j ); 39059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 39069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n", 39079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->name,arange->aMin,arange->aMax,ip); 39089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj analyse_deps( res, di->admin_tyents, ip, 3909588658b13b5ad77672f323d48fe9da0ca60b0bcbtom di, var, arrays_only ); 39109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 39119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 39129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; 39149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 39159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Get an array of GlobalBlock which describe the global blocks owned 39189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj by the shared object characterised by the given di_handle. Asserts 39199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if the handle is invalid. The caller is responsible for freeing 39209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj the array at some point. If 'arrays_only' is True, only 39219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj array-typed blocks are returned; otherwise blocks of all types are 39229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj returned. */ 39239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid* /* really, XArray* of GlobalBlock */ 39259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(di_get_global_blocks_from_dihandle) ( ULong di_handle, 39269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool arrays_only ) 39279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 39289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* This is a derivation of consider_vars_in_frame() above. */ 39299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo* di; 39319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* gvars; /* XArray* of GlobalBlock */ 39329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word nScopes, scopeIx; 39339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* The first thing to do is find the DebugInfo that 39359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj pertains to 'di_handle'. */ 39369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(di_handle > 0); 39379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (di = debugInfo_list; di; di = di->next) { 39389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (di->handle == di_handle) 39399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj break; 39409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 39419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* If this fails, we were unable to find any DebugInfo with the 39439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj given handle. This is considered an error on the part of the 39449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj caller. */ 39459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(di != NULL); 39469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* we'll put the collected variables in here. */ 39489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gvars = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dggbfd.1", 39499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(dinfo_free), sizeof(GlobalBlock) ); 39509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(gvars); 39519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* any var info at all? */ 39539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->varinfo) 39549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return gvars; 39559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* we'll iterate over all the variables we can find, even if 39579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it seems senseless to visit stack-allocated variables */ 39589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over all scopes */ 39599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj nScopes = VG_(sizeXA)( di->varinfo ); 39609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (scopeIx = 0; scopeIx < nScopes; scopeIx++) { 39619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over each (code) address range at the current scope */ 39639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiAddrRange* range; 39649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj OSet* /* of DiAddrInfo */ scope 39659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj = *(OSet**)VG_(indexXA)( di->varinfo, scopeIx ); 39669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(scope); 39679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(OSetGen_ResetIter)(scope); 39689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj while ( (range = VG_(OSetGen_Next)(scope)) ) { 39699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over each variable in the current address range */ 39719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word nVars, varIx; 39729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(range->vars); 39739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj nVars = VG_(sizeXA)( range->vars ); 39749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (varIx = 0; varIx < nVars; varIx++) { 39759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool isVec; 39779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res; 397850fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 39799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GlobalBlock gb; 39809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ty; 39819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiVariable* var = VG_(indexXA)( range->vars, varIx ); 39829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(var->name); 39839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("at depth %ld var %s ", scopeIx, var->name ); 39849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Now figure out if this variable has a constant address 39869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj (that is, independent of FP, SP, phase of moon, etc), 39879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj and if so, what the address is. Any variable with a 39889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj constant address is deemed to be a global so we collect 39899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. */ 39909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) { VG_(printf)("EVAL: "); ML_(pp_GX)(var->gexpr); 39919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("\n"); } 3992588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_trivial_GX)( var->gexpr, di ); 39939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Not a constant address => not interesting */ 39953c9cf3442185b5891e15450d6e3058aeff6796fetom if (res.kind != GXR_Addr) { 39969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("FAIL\n"); 39979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 39989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 39999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok, it's a constant address. See if we want to collect 40019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. */ 40029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("%#lx\n", res.word); 40039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Figure out how big the variable is. */ 400550fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(di->admin_tyents, var->typeR); 40069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 400750fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 400850fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. 400950fde23467d92281b32dd537d0d9a590263628c3sewardj ML_(addVar) should have rejected it. */ 401050fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 401150fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 401250fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 401350fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a 401450fde23467d92281b32dd537d0d9a590263628c3sewardj host word safely (without loss of info). */ 40159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* skip if non-array and we're only interested in 40179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj arrays */ 40189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ty = ML_(TyEnts__index_by_cuOff)( di->admin_tyents, NULL, 40199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR ); 40209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty); 40219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty)); 40229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (ty->tag == Te_UNKNOWN) 40239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; /* perhaps we should complain in this case? */ 40249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj isVec = ty->tag == Te_TyArray; 40269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (arrays_only && !isVec) continue; 40279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok, so collect it! */ 40299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(var->name); 40309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(di->soname); 40319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("XXXX %s %s %d\n", var->name, 40329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->fileName?(HChar*)var->fileName 40339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj :"??",var->lineNo); 40349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)(&gb, 0, sizeof(gb)); 40359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gb.addr = res.word; 403650fde23467d92281b32dd537d0d9a590263628c3sewardj gb.szB = (SizeT)mul.ul; 40379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gb.isVec = isVec; 40389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)(&gb.name[0], var->name, sizeof(gb.name)-1); 40399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)(&gb.soname[0], di->soname, sizeof(gb.soname)-1); 40409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(gb.name[ sizeof(gb.name)-1 ] == 0); 40419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj tl_assert(gb.soname[ sizeof(gb.soname)-1 ] == 0); 40429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( gvars, &gb ); 40449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* for (varIx = 0; varIx < nVars; varIx++) */ 40469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* while ( (range = VG_(OSetGen_Next)(scope)) ) */ 40489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* for (scopeIx = 0; scopeIx < nScopes; scopeIx++) */ 40509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return gvars; 40529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 40539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 4055b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 4056b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- DebugInfo accessor functions ---*/ 4057b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 4058b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4059e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjconst DebugInfo* VG_(next_DebugInfo)(const DebugInfo* di) 4060eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4061b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == NULL) 4062b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return debugInfo_list; 4063b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->next; 4064eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4065eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4066e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjAddr VG_(DebugInfo_get_text_avma)(const DebugInfo* di) 4067eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4068b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_avma : 0; 4069eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4070eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4071e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjSizeT VG_(DebugInfo_get_text_size)(const DebugInfo* di) 4072eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4073b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_size : 0; 4074eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4075eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 40763898022a7d74a227d6a35102faaedd420ed3a1c1bartAddr VG_(DebugInfo_get_bss_avma)(const DebugInfo* di) 40773898022a7d74a227d6a35102faaedd420ed3a1c1bart{ 40783898022a7d74a227d6a35102faaedd420ed3a1c1bart return di->bss_present ? di->bss_avma : 0; 40793898022a7d74a227d6a35102faaedd420ed3a1c1bart} 40803898022a7d74a227d6a35102faaedd420ed3a1c1bart 40813898022a7d74a227d6a35102faaedd420ed3a1c1bartSizeT VG_(DebugInfo_get_bss_size)(const DebugInfo* di) 40823898022a7d74a227d6a35102faaedd420ed3a1c1bart{ 40833898022a7d74a227d6a35102faaedd420ed3a1c1bart return di->bss_present ? di->bss_size : 0; 40843898022a7d74a227d6a35102faaedd420ed3a1c1bart} 40853898022a7d74a227d6a35102faaedd420ed3a1c1bart 4086e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjAddr VG_(DebugInfo_get_plt_avma)(const DebugInfo* di) 4087092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 4088092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->plt_present ? di->plt_avma : 0; 4089092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 4090092b6268cc4a38ae9ee41d1e3355937536ddc579bart 4091e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjSizeT VG_(DebugInfo_get_plt_size)(const DebugInfo* di) 4092092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 4093092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->plt_present ? di->plt_size : 0; 4094092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 4095092b6268cc4a38ae9ee41d1e3355937536ddc579bart 4096e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjAddr VG_(DebugInfo_get_gotplt_avma)(const DebugInfo* di) 4097092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 4098092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->gotplt_present ? di->gotplt_avma : 0; 4099092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 4100092b6268cc4a38ae9ee41d1e3355937536ddc579bart 4101e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjSizeT VG_(DebugInfo_get_gotplt_size)(const DebugInfo* di) 4102092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 4103092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->gotplt_present ? di->gotplt_size : 0; 4104092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 4105092b6268cc4a38ae9ee41d1e3355937536ddc579bart 410668347837b3d82e48f85daff33ec7ba528891e4e7bartAddr VG_(DebugInfo_get_got_avma)(const DebugInfo* di) 410768347837b3d82e48f85daff33ec7ba528891e4e7bart{ 410868347837b3d82e48f85daff33ec7ba528891e4e7bart return di->got_present ? di->got_avma : 0; 410968347837b3d82e48f85daff33ec7ba528891e4e7bart} 411068347837b3d82e48f85daff33ec7ba528891e4e7bart 411168347837b3d82e48f85daff33ec7ba528891e4e7bartSizeT VG_(DebugInfo_get_got_size)(const DebugInfo* di) 411268347837b3d82e48f85daff33ec7ba528891e4e7bart{ 411368347837b3d82e48f85daff33ec7ba528891e4e7bart return di->got_present ? di->got_size : 0; 411468347837b3d82e48f85daff33ec7ba528891e4e7bart} 411568347837b3d82e48f85daff33ec7ba528891e4e7bart 41161636d33c13958b9c0e7d3059cdd5005746418eb2florianconst HChar* VG_(DebugInfo_get_soname)(const DebugInfo* di) 4117eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->soname; 4119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 4120eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 41211636d33c13958b9c0e7d3059cdd5005746418eb2florianconst HChar* VG_(DebugInfo_get_filename)(const DebugInfo* di) 4122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 4123a5acac39bf3be7546222b1316faee5ee524be0d1sewardj return di->fsm.filename; 4124eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4125eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4126e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjPtrdiffT VG_(DebugInfo_get_text_bias)(const DebugInfo* di) 4127bbec7728efefaa650970dd1f0282b77040287133sewardj{ 4128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_bias : 0; 4129bbec7728efefaa650970dd1f0282b77040287133sewardj} 4130bbec7728efefaa650970dd1f0282b77040287133sewardj 4131e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjInt VG_(DebugInfo_syms_howmany) ( const DebugInfo *si ) 4132eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4133eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return si->symtab_used; 4134eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4135eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4136e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjvoid VG_(DebugInfo_syms_getidx) ( const DebugInfo *si, 4137e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj Int idx, 4138a5cace0c2a3e212931badbf6398a0cd98393121asewardj /*OUT*/Addr* avma, 4139a5cace0c2a3e212931badbf6398a0cd98393121asewardj /*OUT*/Addr* tocptr, 4140a5cace0c2a3e212931badbf6398a0cd98393121asewardj /*OUT*/UInt* size, 414119f91bbaedb4caef8a60ce94b0f507193cc0bc10florian /*OUT*/HChar** pri_name, 414219f91bbaedb4caef8a60ce94b0f507193cc0bc10florian /*OUT*/HChar*** sec_names, 4143a5cace0c2a3e212931badbf6398a0cd98393121asewardj /*OUT*/Bool* isText, 4144a5cace0c2a3e212931badbf6398a0cd98393121asewardj /*OUT*/Bool* isIFunc ) 4145eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4146eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(idx >= 0 && idx < si->symtab_used); 4147a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (avma) *avma = si->symtab[idx].addr; 4148a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (tocptr) *tocptr = si->symtab[idx].tocptr; 4149a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (size) *size = si->symtab[idx].size; 4150a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (pri_name) *pri_name = si->symtab[idx].pri_name; 415119f91bbaedb4caef8a60ce94b0f507193cc0bc10florian if (sec_names) *sec_names = (HChar **)si->symtab[idx].sec_names; // FIXME 4152a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (isText) *isText = si->symtab[idx].isText; 4153a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (isIFunc) *isIFunc = si->symtab[idx].isIFunc; 4154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 4155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 4158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- SectKind query functions ---*/ 4159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 4160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Convert a VgSectKind to a string, which must be copied if you want 4162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to change it. */ 4163b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjconst HChar* VG_(pp_SectKind)( VgSectKind kind ) 4164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 4165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj switch (kind) { 4166b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectUnknown: return "Unknown"; 4167b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectText: return "Text"; 4168b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectData: return "Data"; 4169b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectBSS: return "BSS"; 4170b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectGOT: return "GOT"; 4171b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectPLT: return "PLT"; 4172b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectOPD: return "OPD"; 41735706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj case Vg_SectGOTPLT: return "GOTPLT"; 4174b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj default: vg_assert(0); 4175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 4177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Given an address 'a', make a guess of which section of which object 4179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj it comes from. If name is non-NULL, then the last n_name-1 4180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj characters of the object's name is put in name[0 .. n_name-2], and 4181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj name[n_name-1] is set to zero (guaranteed zero terminated). */ 4182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 41831636d33c13958b9c0e7d3059cdd5005746418eb2florianVgSectKind VG_(DebugInfo_sect_kind)( /*OUT*/HChar* name, SizeT n_name, 4184e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj Addr a) 4185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 4186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 4187b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VgSectKind res = Vg_SectUnknown; 4188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4189b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 4190b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4191b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0) 4192b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)( 4193e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj "addr=%#lx di=%p %s got=%#lx,%ld plt=%#lx,%ld " 4194e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj "data=%#lx,%ld bss=%#lx,%ld\n", 4195a5acac39bf3be7546222b1316faee5ee524be0d1sewardj a, di, di->fsm.filename, 4196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->got_avma, di->got_size, 4197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->plt_avma, di->plt_size, 4198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_avma, di->data_size, 4199b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->bss_avma, di->bss_size); 4200b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 4202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_size > 0 4203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->text_avma && a < di->text_avma + di->text_size) { 4204b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectText; 4205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->data_present 4208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_size > 0 4209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->data_avma && a < di->data_avma + di->data_size) { 4210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectData; 4211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4212b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->sdata_present 4214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_size > 0 4215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->sdata_avma && a < di->sdata_avma + di->sdata_size) { 4216b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectData; 4217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->bss_present 4220b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_size > 0 4221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->bss_avma && a < di->bss_avma + di->bss_size) { 4222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectBSS; 4223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 42255706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj if (di->sbss_present 42265706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->sbss_size > 0 42275706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && a >= di->sbss_avma && a < di->sbss_avma + di->sbss_size) { 42285706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj res = Vg_SectBSS; 42295706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj break; 42305706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj } 4231b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->plt_present 4232b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->plt_size > 0 4233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->plt_avma && a < di->plt_avma + di->plt_size) { 4234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectPLT; 4235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4236b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4237b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->got_present 4238b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->got_size > 0 4239b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->got_avma && a < di->got_avma + di->got_size) { 4240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectGOT; 4241b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4242b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4243092b6268cc4a38ae9ee41d1e3355937536ddc579bart if (di->gotplt_present 4244092b6268cc4a38ae9ee41d1e3355937536ddc579bart && di->gotplt_size > 0 4245092b6268cc4a38ae9ee41d1e3355937536ddc579bart && a >= di->gotplt_avma && a < di->gotplt_avma + di->gotplt_size) { 4246092b6268cc4a38ae9ee41d1e3355937536ddc579bart res = Vg_SectGOTPLT; 4247092b6268cc4a38ae9ee41d1e3355937536ddc579bart break; 4248092b6268cc4a38ae9ee41d1e3355937536ddc579bart } 4249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->opd_present 4250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->opd_size > 0 4251b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->opd_avma && a < di->opd_avma + di->opd_size) { 4252b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectOPD; 4253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* we could also check for .eh_frame, if anyone really cares */ 4256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4257b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert( (di == NULL && res == Vg_SectUnknown) 4259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || (di != NULL && res != Vg_SectUnknown) ); 4260b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4261b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (name) { 4262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4263b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_name >= 8); 4264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4265a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (di && di->fsm.filename) { 4266b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int i, j; 4267a5acac39bf3be7546222b1316faee5ee524be0d1sewardj Int fnlen = VG_(strlen)(di->fsm.filename); 4268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int start_at = 1 + fnlen - n_name; 4269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (start_at < 0) start_at = 0; 4270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(start_at < fnlen); 4271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj i = start_at; j = 0; 4272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 4273d5dea1dabc523d3f96bafd52ae9586abd8797416bart vg_assert(j >= 0 && j < n_name); 4274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(i >= 0 && i <= fnlen); 4275a5acac39bf3be7546222b1316faee5ee524be0d1sewardj name[j] = di->fsm.filename[i]; 4276a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (di->fsm.filename[i] == 0) break; 4277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj i++; j++; 4278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4279d5dea1dabc523d3f96bafd52ae9586abd8797416bart vg_assert(i == fnlen); 4280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 4281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(snprintf)(name, n_name, "%s", "???"); 4282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj name[n_name-1] = 0; 4285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return res; 4288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4289eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4290eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4291eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 4292eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- end ---*/ 4293eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 4294