1770a8d23e40b980b5745e59ecb8e4037d81af357florian/* -*- mode: C; c-basic-offset: 3; -*- */ 2582d58245637ab05272d89fb94b12fd0f18fa0f8carll 3eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 4eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Top level management of symbols and debugging information. ---*/ 5eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- debuginfo.c ---*/ 6eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 7eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 8eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* 9eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj This file is part of Valgrind, a dynamic binary instrumentation 10eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj framework. 11eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 12b3a1e4bffbdbbf38304f216af405009868f43628sewardj Copyright (C) 2000-2015 Julian Seward 13eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj jseward@acm.org 14eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 15eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj This program is free software; you can redistribute it and/or 16eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj modify it under the terms of the GNU General Public License as 17eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj published by the Free Software Foundation; either version 2 of the 18eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj License, or (at your option) any later version. 19eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 20eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj This program is distributed in the hope that it will be useful, but 21eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj WITHOUT ANY WARRANTY; without even the implied warranty of 22eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj General Public License for more details. 24eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 25eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj You should have received a copy of the GNU General Public License 26eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj along with this program; if not, write to the Free Software 27eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 28eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 02111-1307, USA. 29eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 30eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj The GNU General Public License is contained in the file COPYING. 31eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 32eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 33eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "pub_core_basics.h" 344cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj#include "pub_core_vki.h" 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" 598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#if defined(VGO_linux) || defined(VGO_solaris) 604ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# include "priv_readelf.h" 61b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# include "priv_readdwarf3.h" 62c8259b85b701d25d72aabe9dc0a8154517f96913sewardj# include "priv_readpdb.h" 63f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(VGO_darwin) 64f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# include "priv_readmacho.h" 65f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# include "priv_readpdb.h" 664ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#endif 67eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 68c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 696f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj/* Set this to 1 to enable debug printing for the 706f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj should-we-load-debuginfo-now? finite state machine. */ 716f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj#define DEBUG_FSM 0 726f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj 736f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj 74c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/*------------------------------------------------------------*/ 75c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/*--- The _svma / _avma / _image / _bias naming scheme ---*/ 76c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/*------------------------------------------------------------*/ 77c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 78c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/* JRS 11 Jan 07: I find the different kinds of addresses involved in 79c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj debuginfo reading confusing. Recently I arrived at some 80c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj terminology which makes it clearer (to me, at least). There are 3 81c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj kinds of address used in the debuginfo reading process: 82c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 83c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj stated VMAs - the address where (eg) a .so says a symbol is, that 84c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj is, what it tells you if you consider the .so in 85c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj isolation 86c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 87c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj actual VMAs - the address where (eg) said symbol really wound up 88c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj after the .so was mapped into memory 89c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 90c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj image addresses - pointers into the copy of the .so (etc) 91c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj transiently mmaped aboard whilst we read its info 92c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 93c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj Additionally I use the term 'bias' to denote the difference 94c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj between stated and actual VMAs for a given entity. 95c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 96c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj This terminology is not used consistently, but a start has been 97c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj made. readelf.c and the call-frame info reader in readdwarf.c now 98c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj use it. Specifically, various variables and structure fields have 99f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj been annotated with _avma / _svma / _image / _bias. In places _img 100f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj is used instead of _image for the sake of brevity. 101c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj*/ 102c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 103c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj 104eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 105f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- fwdses ---*/ 106f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*------------------------------------------------------------*/ 107f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 108f7bbd7982397fb73477bdc21bf236cf9100cee44philippestatic UInt debuginfo_generation = 0; 1095c3dba227192de63d86f65ec7d9597c132818c37philippestatic void cfsi_m_cache__invalidate ( void ); 110f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 111f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 112f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*------------------------------------------------------------*/ 113eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Root structure ---*/ 114eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 115eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 116b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* The root structure for the entire debug info system. It is a 117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj linked list of DebugInfos. */ 118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic DebugInfo* debugInfo_list = NULL; 119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 121ad4e979f408239dabbaae955d8ffcb84a51a5c85florian/* Find 'di' in the debugInfo_list and move it one step closer to the 122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj front of the list, so as to make subsequent searches for it 123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj cheaper. When used in a controlled way, makes a major improvement 124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in some DebugInfo-search-intensive situations, most notably stack 125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj unwinding on amd64-linux. */ 126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void move_DebugInfo_one_step_forward ( DebugInfo* di ) 127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo *di0, *di1, *di2; 129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == debugInfo_list) 130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; /* already at head of list */ 131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di != NULL); 132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0 = debugInfo_list; 133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1 = NULL; 134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2 = NULL; 135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while (True) { 136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 == NULL || di0 == di) break; 137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2 = di1; 138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1 = di0; 139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0 = di0->next; 140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di0 == di); 142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 != NULL && di1 != NULL && di2 != NULL) { 143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* tmp; 144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* di0 points to di, di1 to its predecessor, and di2 to di1's 145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj predecessor. Swap di0 and di1, that is, move di0 one step 146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj closer to the start of the list. */ 147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di2->next == di1); 148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di1->next == di0); 149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj tmp = di0->next; 150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di2->next = di0; 151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0->next = di1; 152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1->next = tmp; 153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di0 != NULL && di1 != NULL && di2 == NULL) { 156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* it's second in the list. */ 157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(debugInfo_list == di1); 158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di1->next == di0); 159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di1->next = di0->next; 160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di0->next = di1; 161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj debugInfo_list = di0; 162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 163b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 164eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 165eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 166eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 167eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Notification (acquire/discard) helpers ---*/ 168eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 169eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Gives out unique abstract handles for allocated DebugInfos. See 1719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj comment in priv_storage.h, declaration of struct _DebugInfo, for 1729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj details. */ 1739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic ULong handle_counter = 1; 1749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Allocate and zero out a new DebugInfo record. */ 176eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjstatic 1771636d33c13958b9c0e7d3059cdd5005746418eb2florianDebugInfo* alloc_DebugInfo( const HChar* filename ) 178eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool traceme; 180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 181eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 182f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj vg_assert(filename); 183f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj 1849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di = ML_(dinfo_zalloc)("di.debuginfo.aDI.1", sizeof(DebugInfo)); 185a5acac39bf3be7546222b1316faee5ee524be0d1sewardj di->handle = handle_counter++; 186a5acac39bf3be7546222b1316faee5ee524be0d1sewardj di->fsm.filename = ML_(dinfo_strdup)("di.debuginfo.aDI.2", filename); 1876b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.maps = VG_(newXA)( 1886b5625bb609b154766d2e138b61e15655f60b710sewardj ML_(dinfo_zalloc), "di.debuginfo.aDI.3", 189518850bf0da07ed3e2244e307268ae0fd80e93a8florian ML_(dinfo_free), sizeof(DebugInfoMapping)); 190eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 191452e89a9f847975609b3ad318943830f2cce841csewardj /* Everything else -- pointers, sizes, arrays -- is zeroed by 192452e89a9f847975609b3ad318943830f2cce841csewardj ML_(dinfo_zalloc). Now set up the debugging-output flags. */ 193f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj traceme 1940f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj = VG_(string_match)( VG_(clo_trace_symtab_patt), filename ); 195f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj if (traceme) { 196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->trace_symtab = VG_(clo_trace_symtab); 197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->trace_cfi = VG_(clo_trace_cfi); 198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_syms = VG_(clo_debug_dump_syms); 199b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_line = VG_(clo_debug_dump_line); 200b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->ddump_frames = VG_(clo_debug_dump_frames); 201f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj } 202f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj 203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 204eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 205eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 206eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Free a DebugInfo, and also all the stuff hanging off it. */ 208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void free_DebugInfo ( DebugInfo* di ) 209eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 21059a2d18d0ddfa241850017252b0804d469187d79sewardj Word i, j, n; 2119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ent; 21259a2d18d0ddfa241850017252b0804d469187d79sewardj GExpr* gexpr; 213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di != NULL); 2156b5625bb609b154766d2e138b61e15655f60b710sewardj if (di->fsm.maps) VG_(deleteXA)(di->fsm.maps); 216a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (di->fsm.filename) ML_(dinfo_free)(di->fsm.filename); 217c5af2ae7cec426721577d4a249d4a7b7c0eeb65emjw if (di->fsm.dbgname) ML_(dinfo_free)(di->fsm.dbgname); 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? */ 404518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic Bool do_DebugInfos_overlap ( const DebugInfo* di1, const 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++) { 410518850bf0da07ed3e2244e307268ae0fd80e93a8florian const DebugInfoMapping* map1 = VG_(indexXA)(di1->fsm.maps, i); 4116b5625bb609b154766d2e138b61e15655f60b710sewardj for (j = 0; j < VG_(sizeXA)(di2->fsm.maps); j++) { 412518850bf0da07ed3e2244e307268ae0fd80e93a8florian const 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. */ 469518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic DebugInfo* find_or_create_DebugInfo_for ( const 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. */ 492518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic void check_CFSI_related_invariants ( const 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++) { 505518850bf0da07ed3e2244e307268ae0fd80e93a8florian const 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++) { 524518850bf0da07ed3e2244e307268ae0fd80e93a8florian const 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 6008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) 601eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 602d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj/* Helper (indirect) for di_notify_ACHIEVE_ACCEPT_STATE */ 603518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic Bool overlaps_DebugInfoMappings ( const DebugInfoMapping* map1, 604518850bf0da07ed3e2244e307268ae0fd80e93a8florian const DebugInfoMapping* map2 ) 605d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj{ 606d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj vg_assert(map1 && map2 && map1 != map2); 607d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj vg_assert(map1->size != 0 && map2->size != 0); 608d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj if (map1->avma + map1->size <= map2->avma) return False; 609d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj if (map2->avma + map2->size <= map1->avma) return False; 610d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj return True; 611d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj} 612d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj 613d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj 614d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj/* Helper (indirect) for di_notify_ACHIEVE_ACCEPT_STATE */ 615d6845c6e889dd75928e5cdbe5a8ba654881783acsewardjstatic void show_DebugInfoMappings 616518850bf0da07ed3e2244e307268ae0fd80e93a8florian ( const DebugInfo* di, 617518850bf0da07ed3e2244e307268ae0fd80e93a8florian /*MOD*/XArray* maps /* XArray<DebugInfoMapping> */ ) 618d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj{ 619d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj Word i, n; 620d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj vg_assert(maps); 621d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj n = VG_(sizeXA)(maps); 622d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj for (i = 0; i < n; i++) { 623518850bf0da07ed3e2244e307268ae0fd80e93a8florian const DebugInfoMapping* map = VG_(indexXA)(maps, i); 624c6e5d76e9eea8625f385ff844545c688c91938daflorian TRACE_SYMTAB(" [%ld] avma 0x%-16lx size %-8lu " 625e7f48e650ebc8871b185af5efdd986f526d2f460sewardj "foff %-8lld %s %s %s\n", 626e7f48e650ebc8871b185af5efdd986f526d2f460sewardj i, map->avma, map->size, (Long)map->foff, 627d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj map->rx ? "rx" : "--", 628d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj map->rw ? "rw" : "--", 629d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj map->ro ? "ro" : "--"); 630d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj } 631d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj} 632d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj 633d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj 634d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj/* Helper for di_notify_ACHIEVE_ACCEPT_STATE. This removes overlaps 635d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj in |maps|, in a fairly weak way, by truncating overlapping ends. 636d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj This may need to be strengthened in future. Currently it performs 637d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj a post-fixup check, so as least we can be sure that if this 638d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj function returns (rather than asserts) that |maps| is overlap 639d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj free. */ 640d6845c6e889dd75928e5cdbe5a8ba654881783acsewardjstatic void truncate_DebugInfoMapping_overlaps 641518850bf0da07ed3e2244e307268ae0fd80e93a8florian ( const DebugInfo* di, 642518850bf0da07ed3e2244e307268ae0fd80e93a8florian /*MOD*/XArray* maps /* XArray<DebugInfoMapping> */ ) 643d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj{ 644d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj TRACE_SYMTAB("Un-de-overlapped _DebugInfoMappings:\n"); 645d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj show_DebugInfoMappings(di, maps); 646d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj TRACE_SYMTAB("\n"); 647d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj 648d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj Word i, j, n; 649518850bf0da07ed3e2244e307268ae0fd80e93a8florian DebugInfoMapping *map_i, *map_j; 650d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj 651d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj n = VG_(sizeXA)(maps); 652d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj for (i = 0; i < n; i++) { 653d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj 654518850bf0da07ed3e2244e307268ae0fd80e93a8florian map_i = VG_(indexXA)(maps, i); 655d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj if (map_i->size == 0) 656d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj continue; // Hmm, mutancy. Shouldn't happen. 657d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj 658d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj for (j = i+1; j < n; j++) { 659d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj 660518850bf0da07ed3e2244e307268ae0fd80e93a8florian map_j = VG_(indexXA)(maps, j); 661d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj if (map_j->size == 0) 662d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj continue; // Hmm, mutancy. Shouldn't happen. 663d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj 664d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj /* map_j was observed later than map_i, since the entries are 665d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj in the XArray in the order in which they were observed. 666d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj If map_j starts inside map_i, trim map_i's end so it does 667d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj not overlap map_j. This reflects the reality that when 668d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj two mmaped areas overlap, the later mmap silently 669d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj overwrites the earlier mmap's mapping. */ 670d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj if (map_j->avma >= map_i->avma 671d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj && map_j->avma < map_i->avma + map_i->size) { 672d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj SizeT map_i_newsize = map_j->avma - map_i->avma; 673d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj vg_assert(map_i_newsize < map_i->size); 674d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj map_i->size = map_i_newsize; 675d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj } 676d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj 677d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj } 678d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj } 679d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj 680518850bf0da07ed3e2244e307268ae0fd80e93a8florian TRACE_SYMTAB("De-overlapped DebugInfoMappings:\n"); 681d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj show_DebugInfoMappings(di, maps); 682d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj TRACE_SYMTAB("\n"); 683d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj TRACE_SYMTAB("Checking that there are no remaining overlaps.\n"); 684d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj 685d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj for (i = 0; i < n; i++) { 686518850bf0da07ed3e2244e307268ae0fd80e93a8florian map_i = VG_(indexXA)(maps, i); 687d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj if (map_i->size == 0) 688d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj continue; 689d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj for (j = i+1; j < n; j++) { 690518850bf0da07ed3e2244e307268ae0fd80e93a8florian map_j = VG_(indexXA)(maps, j); 691d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj if (map_j->size == 0) 692d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj continue; 693d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj Bool overlap 694d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj = overlaps_DebugInfoMappings( map_i, map_j ); 695d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj /* If the following assert ever fails, it means the de-overlapping 696d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj scheme above is too weak, and needs improvement. */ 697d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj vg_assert(!overlap); 698d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj } 699d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj } 700d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj 701d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj TRACE_SYMTAB("Check successful.\n"); 702d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj} 703d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj 704d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj 705eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* The debug info system is driven by notifications that a text 706731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj segment has been mapped in, or unmapped, or when sections change 707731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj permission. It's all a bit kludgey and basically means watching 708731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj syscalls, trying to second-guess when the system's dynamic linker 709731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj is done with mapping in a new object for execution. This is all 710731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj tracked using the DebugInfoFSM struct for the object. Anyway, once 711731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj we finally decide we've got to an accept state, this section then 712731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj will acquire whatever info is available for the corresponding 713731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj object. This section contains the notification handlers, which 714731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj update the FSM and determine when an accept state has been reached. 715731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj*/ 716731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 717731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj/* When the sequence of observations causes a DebugInfoFSM to move 718731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj into the accept state, call here to actually get the debuginfo read 719731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj in. Returns a ULong whose purpose is described in comments 720731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj preceding VG_(di_notify_mmap) just below. 721731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj*/ 722731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardjstatic ULong di_notify_ACHIEVE_ACCEPT_STATE ( struct _DebugInfo* di ) 723731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj{ 724731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj ULong di_handle; 725731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj Bool ok; 726731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 727731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj vg_assert(di->fsm.filename); 728731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n"); 729731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("------ start ELF OBJECT " 730d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj "-------------------------" 731731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj "------------------------------\n"); 732731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("------ name = %s\n", di->fsm.filename); 733731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n"); 734731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 735731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* We're going to read symbols and debug info for the avma 7366b5625bb609b154766d2e138b61e15655f60b710sewardj ranges specified in the _DebugInfoFsm mapping array. First 7376b5625bb609b154766d2e138b61e15655f60b710sewardj get rid of any other DebugInfos which overlap any of those 7386b5625bb609b154766d2e138b61e15655f60b710sewardj ranges (to avoid total confusion). */ 739731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj discard_DebugInfos_which_overlap_with( di ); 740731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 741d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj /* The DebugInfoMappings that now exist in the FSM may involve 742d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj overlaps. This confuses ML_(read_elf_debug_info), and may cause 743d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj it to compute wrong biases. So de-overlap them now. 744d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj See http://bugzilla.mozilla.org/show_bug.cgi?id=788974 */ 745d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj truncate_DebugInfoMapping_overlaps( di, di->fsm.maps ); 746d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj 747d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj /* And acquire new info. */ 7488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# if defined(VGO_linux) || defined(VGO_solaris) 749731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj ok = ML_(read_elf_debug_info)( di ); 750731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# elif defined(VGO_darwin) 751731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj ok = ML_(read_macho_debug_info)( di ); 752731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# else 753731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# error "unknown OS" 754731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# endif 755731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 756731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (ok) { 757731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 758731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n------ Canonicalising the " 759731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj "acquired info ------\n"); 760731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* invalidate the CFI unwind cache. */ 7615c3dba227192de63d86f65ec7d9597c132818c37philippe cfsi_m_cache__invalidate(); 762731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* prepare read data for use */ 763731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj ML_(canonicaliseTables)( di ); 7645c3dba227192de63d86f65ec7d9597c132818c37philippe /* Check invariants listed in 7655c3dba227192de63d86f65ec7d9597c132818c37philippe Comment_on_IMPORTANT_REPRESENTATIONAL_INVARIANTS in 7665c3dba227192de63d86f65ec7d9597c132818c37philippe priv_storage.h. */ 7675c3dba227192de63d86f65ec7d9597c132818c37philippe check_CFSI_related_invariants(di); 7685c3dba227192de63d86f65ec7d9597c132818c37philippe ML_(finish_CFSI_arrays)(di); 769731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* notify m_redir about it */ 770731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n------ Notifying m_redir ------\n"); 771731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj VG_(redir_notify_new_DebugInfo)( di ); 772731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Note that we succeeded */ 773731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj di->have_dinfo = True; 774e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(di->handle > 0); 775731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj di_handle = di->handle; 776731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 777731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj } else { 778731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n------ ELF reading failed ------\n"); 779731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Something went wrong (eg. bad ELF file). Should we delete 780731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj this DebugInfo? No - it contains info on the rw/rx 781731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj mappings, at least. */ 782731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj di_handle = 0; 783731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj vg_assert(di->have_dinfo == False); 784731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj } 785731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 786731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n"); 787731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("------ name = %s\n", di->fsm.filename); 788731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("------ end ELF OBJECT " 789d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj "-------------------------" 790731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj "------------------------------\n"); 791731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj TRACE_SYMTAB("\n"); 792731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 793731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return di_handle; 794731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj} 795731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 796eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 797eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Notify the debuginfo system about a new mapping. This is the way 798eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj new debug information gets loaded. If allow_SkFileV is True, it 799eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj will try load debug info if the mapping at 'a' belongs to Valgrind; 800eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj whereas normally (False) it will not do that. This allows us to 801eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj carefully control when the thing will read symbols from the 8029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Valgrind executable itself. 8039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 8045f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj If use_fd is not -1, that is used instead of the filename; this 8055f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj avoids perturbing fcntl locks, which are released by simply 8065f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj re-opening and closing the same file (even via different fd!). 8075f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj 8089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj If a call to VG_(di_notify_mmap) causes debug info to be read, then 8099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj the returned ULong is an abstract handle which can later be used to 8109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj refer to the debuginfo read as a result of this specific mapping, 8119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj in later queries to m_debuginfo. In this case the handle value 8129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj will be one or above. If the returned value is zero, no debug info 8139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj was read. */ 814eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 8155f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardjULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd ) 816eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 8174ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj NSegment const * seg; 818d3166c4cf9d2545242da71d8baeaaf203b02a09dflorian const HChar* filename; 819731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj Bool is_rx_map, is_rw_map, is_ro_map; 820b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 8215f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj Int actual_fd, oflags; 8225f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj SysRes preadres; 823b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj HChar buf1k[1024]; 8246f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj Bool debug = (DEBUG_FSM != 0); 825ec61b6509566cf36ab3968d69226cecf177cb0fesewardj SysRes statres; 826ec61b6509566cf36ab3968d69226cecf177cb0fesewardj struct vg_stat statbuf; 827b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 8285f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj vg_assert(use_fd >= -1); 8295f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj 830b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* In short, figure out if this mapping is of interest to us, and 831b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if so, try to guess what ld.so is doing and when/if we should 832b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj read debug info. */ 833b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg = VG_(am_find_nsegment)(a); 834b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(seg); 835eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 8366f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) { 8376f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_mmap-0:\n"); 838a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("di_notify_mmap-1: %#lx-%#lx %c%c%c\n", 839b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->start, seg->end, 840b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->hasR ? 'r' : '-', 841b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj seg->hasW ? 'w' : '-',seg->hasX ? 'x' : '-' ); 8426f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj } 843eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 844b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* guaranteed by aspacemgr-linux.c, sane_NSegment() */ 845b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(seg->end > seg->start); 846b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 847b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ignore non-file mappings */ 848b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( ! (seg->kind == SkFileC 849b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || (seg->kind == SkFileV && allow_SkFileV)) ) 8509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 851b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 852b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* If the file doesn't have a name, we're hosed. Give up. */ 8533e7986312a0ffc7646b0552d4c4ea3744a870e73florian filename = VG_(am_get_filename)( seg ); 854b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!filename) 8559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 856b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 8570ab84fe82d1e25c2e0544d08826df42caa44ded1bart /* 8580ab84fe82d1e25c2e0544d08826df42caa44ded1bart * Cannot read from these magic files: 8590ab84fe82d1e25c2e0544d08826df42caa44ded1bart * --20208-- WARNING: Serious error when reading debug info 8600ab84fe82d1e25c2e0544d08826df42caa44ded1bart * --20208-- When reading debug info from /proc/xen/privcmd: 8610ab84fe82d1e25c2e0544d08826df42caa44ded1bart * --20208-- can't read file to inspect ELF header 8620ab84fe82d1e25c2e0544d08826df42caa44ded1bart */ 8630ab84fe82d1e25c2e0544d08826df42caa44ded1bart if (VG_(strncmp)(filename, "/proc/xen/", 10) == 0) 8640ab84fe82d1e25c2e0544d08826df42caa44ded1bart return 0; 8650ab84fe82d1e25c2e0544d08826df42caa44ded1bart 866b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 867b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("di_notify_mmap-2: %s\n", filename); 868b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 869ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* Only try to read debug information from regular files. */ 87015728ab41ea41bf731dcc74ac68354550ced2189bart statres = VG_(stat)(filename, &statbuf); 871ec61b6509566cf36ab3968d69226cecf177cb0fesewardj 872ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* stat dereferences symlinks, so we don't expect it to succeed and 873ec61b6509566cf36ab3968d69226cecf177cb0fesewardj yet produce something that is a symlink. */ 8749c20ece00e07304f66da5f43b87ec45bc9c04550njn vg_assert(sr_isError(statres) || ! VKI_S_ISLNK(statbuf.mode)); 875ec61b6509566cf36ab3968d69226cecf177cb0fesewardj 876ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* Don't let the stat call fail silently. Filter out some known 877ec61b6509566cf36ab3968d69226cecf177cb0fesewardj sources of noise before complaining, though. */ 878cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(statres)) { 879ec61b6509566cf36ab3968d69226cecf177cb0fesewardj DebugInfo fake_di; 880ec61b6509566cf36ab3968d69226cecf177cb0fesewardj Bool quiet = VG_(strstr)(filename, "/var/run/nscd/") != NULL; 881e025eca1d49cdfe5a8cb58ab495763434280333asewardj if (!quiet && VG_(clo_verbosity) > 1) { 882ec61b6509566cf36ab3968d69226cecf177cb0fesewardj VG_(memset)(&fake_di, 0, sizeof(fake_di)); 883d3166c4cf9d2545242da71d8baeaaf203b02a09dflorian fake_di.fsm.filename = ML_(dinfo_strdup)("di.debuginfo.nmm", filename); 884ec61b6509566cf36ab3968d69226cecf177cb0fesewardj ML_(symerr)(&fake_di, True, "failed to stat64/stat this file"); 885ec61b6509566cf36ab3968d69226cecf177cb0fesewardj } 8869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 8872ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj } 8882ac79d3f62c0a2d44896a6d7d74a4500f364bbe0sewardj 889ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* Finally, the point of all this stattery: if it's not a regular file, 890ec61b6509566cf36ab3968d69226cecf177cb0fesewardj don't try to read debug info from it. */ 8919c20ece00e07304f66da5f43b87ec45bc9c04550njn if (! VKI_S_ISREG(statbuf.mode)) 8929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 893ec61b6509566cf36ab3968d69226cecf177cb0fesewardj 894ec61b6509566cf36ab3968d69226cecf177cb0fesewardj /* no uses of statbuf below here. */ 89515728ab41ea41bf731dcc74ac68354550ced2189bart 896b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Now we have to guess if this is a text-like mapping, a data-like 897b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj mapping, neither or both. The rules are: 898b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 899b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj text if: x86-linux r and x 900b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj other-linux r and x and not w 901b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 902b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data if: x86-linux r and w 903b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj other-linux r and w and not x 904b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 905b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Background: On x86-linux, objects are typically mapped twice: 906eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 907eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1b8fb000-1b8ff000 r-xp 00000000 08:02 4471477 vgpreload_memcheck.so 908eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1b8ff000-1b900000 rw-p 00004000 08:02 4471477 vgpreload_memcheck.so 909eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 910eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj whereas ppc32-linux mysteriously does this: 911eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 912eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118a6000-118ad000 r-xp 00000000 08:05 14209428 vgpreload_memcheck.so 913eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118ad000-118b6000 ---p 00007000 08:05 14209428 vgpreload_memcheck.so 914eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 118b6000-118bd000 rwxp 00000000 08:05 14209428 vgpreload_memcheck.so 915eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 916eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj The third mapping should not be considered to have executable 917eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj code in. Therefore a test which works for both is: r and x and 918eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj NOT w. Reading symbols from the rwx segment -- which overlaps 919eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj the r-x segment in the file -- causes the redirection mechanism 920eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj to redirect to addresses in that third segment, which is wrong 921eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj and causes crashes. 922eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 923eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj JRS 28 Dec 05: unfortunately icc 8.1 on x86 has been seen to 924eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj produce executables with a single rwx segment rather than a 925eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj (r-x,rw-) pair. That means the rules have to be modified thusly: 926eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 927eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj x86-linux: consider if r and x 928b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj all others: consider if r and x and not w 929f56d255d644ec9a1bfa970d50a0489a816a4e736sewardj 930f56d255d644ec9a1bfa970d50a0489a816a4e736sewardj 2009 Aug 16: apply similar kludge to ppc32-linux. 931f56d255d644ec9a1bfa970d50a0489a816a4e736sewardj See http://bugs.kde.org/show_bug.cgi?id=190820 932b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 933b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj There are two modes on s390x: with and without the noexec kernel 934b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj parameter. Together with some older kernels, this leads to several 935b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj variants: 936b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj executable: r and x 937b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj data: r and w and x 938b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj or 939b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj executable: r and x 940b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj data: r and w 941eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj */ 942b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = False; 943b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = False; 944731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj is_ro_map = False; 945731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 9464df0bfc0614379192c780c944415dc420d9cfe8epetarj# if defined(VGA_x86) || defined(VGA_ppc32) || defined(VGA_mips32) \ 9474df0bfc0614379192c780c944415dc420d9cfe8epetarj || defined(VGA_mips64) 948b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = seg->hasR && seg->hasX; 949b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = seg->hasR && seg->hasW; 950cae0cc22b83ffb260ee8379e92099c5a701944cbcarll# elif defined(VGA_amd64) || defined(VGA_ppc64be) || defined(VGA_ppc64le) \ 951cae0cc22b83ffb260ee8379e92099c5a701944cbcarll || defined(VGA_arm) || defined(VGA_arm64) 952b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rx_map = seg->hasR && seg->hasX && !seg->hasW; 953b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is_rw_map = seg->hasR && seg->hasW && !seg->hasX; 954b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGP_s390x_linux) 955b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj is_rx_map = seg->hasR && seg->hasX && !seg->hasW; 956b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj is_rw_map = seg->hasR && seg->hasW; 957112711afefcfcd43680c7c4aa8d38ef180e8811esewardj# elif defined(VGA_tilegx) 958112711afefcfcd43680c7c4aa8d38ef180e8811esewardj is_rx_map = seg->hasR && seg->hasX; // && !seg->hasW; 959112711afefcfcd43680c7c4aa8d38ef180e8811esewardj is_rw_map = seg->hasR && seg->hasW; // && !seg->hasX; 960eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# else 961b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# error "Unknown platform" 962eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# endif 963eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 964588cd4ebce3305d0cf91896c1f6322ef9775d6c1sewardj# if defined(VGP_x86_darwin) && DARWIN_VERS >= DARWIN_10_7 965731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj is_ro_map = seg->hasR && !seg->hasW && !seg->hasX; 966731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# endif 967731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 9688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# if defined(VGO_solaris) 9698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj is_rx_map = seg->hasR && seg->hasX && !seg->hasW; 9708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj is_rw_map = seg->hasR && seg->hasW; 9718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# endif 9728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 973b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 9746f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_mmap-3: " 9756f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj "is_rx_map %d, is_rw_map %d, is_ro_map %d\n", 9766f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj (Int)is_rx_map, (Int)is_rw_map, (Int)is_ro_map); 977eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 978731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Ignore mappings with permissions we can't possibly be interested in. */ 979731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (!(is_rx_map || is_rw_map || is_ro_map)) 9809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 981eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 9825a5eec0923d55afc94165721d25125d5fc8f24d8sewardj /* Peer at the first few bytes of the file, to see if it is an ELF */ 9835a5eec0923d55afc94165721d25125d5fc8f24d8sewardj /* object file. Ignore the file if we do not have read permission. */ 9845a5eec0923d55afc94165721d25125d5fc8f24d8sewardj VG_(memset)(buf1k, 0, sizeof(buf1k)); 985cec083d9a254e92623ed44e9dca080d224693c82sewardj oflags = VKI_O_RDONLY; 986cec083d9a254e92623ed44e9dca080d224693c82sewardj# if defined(VKI_O_LARGEFILE) 987cec083d9a254e92623ed44e9dca080d224693c82sewardj oflags |= VKI_O_LARGEFILE; 988cec083d9a254e92623ed44e9dca080d224693c82sewardj# endif 9895f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj 9905f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (use_fd == -1) { 9915f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj SysRes fd = VG_(open)( filename, oflags, 0 ); 9925f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (sr_isError(fd)) { 9935f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (sr_Err(fd) != VKI_EACCES) { 9945f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj DebugInfo fake_di; 9955f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj VG_(memset)(&fake_di, 0, sizeof(fake_di)); 996d3166c4cf9d2545242da71d8baeaaf203b02a09dflorian fake_di.fsm.filename = ML_(dinfo_strdup)("di.debuginfo.nmm", 997d3166c4cf9d2545242da71d8baeaaf203b02a09dflorian filename); 9985f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj ML_(symerr)(&fake_di, True, 9995f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj "can't open file to inspect ELF header"); 10005f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj } 10015f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj return 0; 10025a5eec0923d55afc94165721d25125d5fc8f24d8sewardj } 10035f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj actual_fd = sr_Res(fd); 10045f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj } else { 10055f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj actual_fd = use_fd; 10065a5eec0923d55afc94165721d25125d5fc8f24d8sewardj } 10075a5eec0923d55afc94165721d25125d5fc8f24d8sewardj 10085f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj preadres = VG_(pread)( actual_fd, buf1k, sizeof(buf1k), 0 ); 10095f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (use_fd == -1) { 10105f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj VG_(close)( actual_fd ); 10115f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj } 10125f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj 10135f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (sr_isError(preadres)) { 10145a5eec0923d55afc94165721d25125d5fc8f24d8sewardj DebugInfo fake_di; 10155a5eec0923d55afc94165721d25125d5fc8f24d8sewardj VG_(memset)(&fake_di, 0, sizeof(fake_di)); 1016d3166c4cf9d2545242da71d8baeaaf203b02a09dflorian fake_di.fsm.filename = ML_(dinfo_strdup)("di.debuginfo.nmm", filename); 10175a5eec0923d55afc94165721d25125d5fc8f24d8sewardj ML_(symerr)(&fake_di, True, "can't read file to inspect ELF header"); 10185a5eec0923d55afc94165721d25125d5fc8f24d8sewardj return 0; 10195a5eec0923d55afc94165721d25125d5fc8f24d8sewardj } 10205f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (sr_Res(preadres) == 0) 10215f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj return 0; 10225f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj vg_assert(sr_Res(preadres) > 0 && sr_Res(preadres) <= sizeof(buf1k) ); 10235a5eec0923d55afc94165721d25125d5fc8f24d8sewardj 10248b68b64759254d514d98328c496cbd88cde4c9a5njn /* We're only interested in mappings of object files. */ 10258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# if defined(VGO_linux) || defined(VGO_solaris) 1026f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj if (!ML_(is_elf_object_file)( buf1k, (SizeT)sr_Res(preadres), False )) 10275a5eec0923d55afc94165721d25125d5fc8f24d8sewardj return 0; 10286e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# elif defined(VGO_darwin) 10295f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (!ML_(is_macho_object_file)( buf1k, (SizeT)sr_Res(preadres) )) 1030f76d27a697a7b0bf3b84490baf60623fc96a23afnjn return 0; 10316e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# else 10326e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# error "unknown OS" 10336e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# endif 10345a5eec0923d55afc94165721d25125d5fc8f24d8sewardj 1035b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* See if we have a DebugInfo for this filename. If not, 1036b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj create one. */ 10370f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj di = find_or_create_DebugInfo_for( filename ); 1038b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di); 1039b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 10406f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 10416f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_mmap-4: " 10426f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj "noting details in DebugInfo* at %p\n", di); 10436f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj 10446b5625bb609b154766d2e138b61e15655f60b710sewardj /* Note the details about the mapping. */ 1045518850bf0da07ed3e2244e307268ae0fd80e93a8florian DebugInfoMapping map; 10468291e31aca3156bef501b4de33a54a23fc404f11mjw map.avma = seg->start; 10476b5625bb609b154766d2e138b61e15655f60b710sewardj map.size = seg->end + 1 - seg->start; 10486b5625bb609b154766d2e138b61e15655f60b710sewardj map.foff = seg->offset; 10496b5625bb609b154766d2e138b61e15655f60b710sewardj map.rx = is_rx_map; 10506b5625bb609b154766d2e138b61e15655f60b710sewardj map.rw = is_rw_map; 10516b5625bb609b154766d2e138b61e15655f60b710sewardj map.ro = is_ro_map; 10526b5625bb609b154766d2e138b61e15655f60b710sewardj VG_(addToXA)(di->fsm.maps, &map); 10536b5625bb609b154766d2e138b61e15655f60b710sewardj 10546b5625bb609b154766d2e138b61e15655f60b710sewardj /* Update flags about what kind of mappings we've already seen. */ 10556b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.have_rx_map |= is_rx_map; 10566b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.have_rw_map |= is_rw_map; 10576b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.have_ro_map |= is_ro_map; 1058b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1059731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* So, finally, are we in an accept state? */ 1060731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) { 1061731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Ok, so, finally, we found what we need, and we haven't 1062731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj already read debuginfo for this object. So let's do so now. 1063731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj Yee-ha! */ 10646f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 10656f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_mmap-5: " 10666f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj "achieved accept state for %s\n", filename); 1067731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return di_notify_ACHIEVE_ACCEPT_STATE ( di ); 10689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } else { 1069731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* If we don't have an rx and rw mapping, or if we already have 1070731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj debuginfo for this mapping for whatever reason, go no 1071731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj further. */ 1072731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return 0; 10739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 1074eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1075eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1076eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1077eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Unmap is simpler - throw away any SegInfos intersecting 1078eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj [a, a+len). */ 1079eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjvoid VG_(di_notify_munmap)( Addr a, SizeT len ) 1080eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1081f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool anyFound; 1082a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart if (0) VG_(printf)("DISCARD %#lx %#lx\n", a, a+len); 1083f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj anyFound = discard_syms_in_range(a, len); 1084f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (anyFound) 10855c3dba227192de63d86f65ec7d9597c132818c37philippe cfsi_m_cache__invalidate(); 1086eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1087eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1088eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1089eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Uh, this doesn't do anything at all. IIRC glibc (or ld.so, I don't 1090eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj remember) does a bunch of mprotects on itself, and if we follow 1091eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj through here, it causes the debug info for that object to get 1092eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj discarded. */ 1093eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjvoid VG_(di_notify_mprotect)( Addr a, SizeT len, UInt prot ) 1094eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1095eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool exe_ok = toBool(prot & VKI_PROT_EXEC); 1096f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# if defined(VGA_x86) 1097eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj exe_ok = exe_ok || toBool(prot & VKI_PROT_READ); 1098eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# endif 1099f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && !exe_ok) { 1100f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool anyFound = discard_syms_in_range(a, len); 1101f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (anyFound) 11025c3dba227192de63d86f65ec7d9597c132818c37philippe cfsi_m_cache__invalidate(); 1103f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 1104eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1105eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1106731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 1107588cd4ebce3305d0cf91896c1f6322ef9775d6c1sewardj/* This is a MacOSX >= 10.7 32-bit only special. See comments on the 1108731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj declaration of struct _DebugInfoFSM for details. */ 1109731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardjvoid VG_(di_notify_vm_protect)( Addr a, SizeT len, UInt prot ) 1110731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj{ 11116f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj Bool debug = (DEBUG_FSM != 0); 11126f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj 11136f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj Bool r_ok = toBool(prot & VKI_PROT_READ); 11146f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj Bool w_ok = toBool(prot & VKI_PROT_WRITE); 11156f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj Bool x_ok = toBool(prot & VKI_PROT_EXEC); 11166f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) { 11176f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-0:\n"); 11186f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-1: %#lx-%#lx %c%c%c\n", 11196f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj a, a + len - 1, 11206f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj r_ok ? 'r' : '-', w_ok ? 'w' : '-', x_ok ? 'x' : '-' ); 11216f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj } 11226f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj 1123731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj Bool do_nothing = True; 1124ec66ad5f33a4d904b1f728935ec6ee29b58a55ecsewardj# if defined(VGP_x86_darwin) && (DARWIN_VERS >= DARWIN_10_7) 1125731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj do_nothing = False; 1126731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# endif 11276f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (do_nothing /* wrong platform */) { 11286f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 11296f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-2: wrong platform, " 11306f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj "doing nothing.\n"); 1131731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return; 11326f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj } 1133731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 1134731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (! (r_ok && !w_ok && x_ok)) 1135731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return; /* not an upgrade to r-x */ 1136731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 1137731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Find a DebugInfo containing a FSM that has [a, +len) previously 1138731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj observed as a r-- mapping, plus some other rw- mapping. If such 1139731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj is found, conclude we're in an accept state and read debuginfo 1140731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj accordingly. */ 11416f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 11426f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-3: looking for existing DebugInfo*\n"); 1143731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj DebugInfo* di; 1144518850bf0da07ed3e2244e307268ae0fd80e93a8florian DebugInfoMapping *map = NULL; 11456b5625bb609b154766d2e138b61e15655f60b710sewardj Word i; 1146731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj for (di = debugInfo_list; di; di = di->next) { 1147731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj vg_assert(di->fsm.filename); 1148731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (di->have_dinfo) 1149731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj continue; /* already have debuginfo for this object */ 1150731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (!di->fsm.have_ro_map) 1151731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj continue; /* need to have a r-- mapping for this object */ 1152731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (di->fsm.have_rx_map) 1153731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj continue; /* rx- mapping already exists */ 1154731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (!di->fsm.have_rw_map) 1155731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj continue; /* need to have a rw- mapping */ 11566b5625bb609b154766d2e138b61e15655f60b710sewardj /* Try to find a mapping matching the memory area. */ 11576b5625bb609b154766d2e138b61e15655f60b710sewardj for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { 1158518850bf0da07ed3e2244e307268ae0fd80e93a8florian map = VG_(indexXA)(di->fsm.maps, i); 11596b5625bb609b154766d2e138b61e15655f60b710sewardj if (map->ro && map->avma == a && map->size == len) 11606b5625bb609b154766d2e138b61e15655f60b710sewardj break; 11616b5625bb609b154766d2e138b61e15655f60b710sewardj map = NULL; 11626b5625bb609b154766d2e138b61e15655f60b710sewardj } 11636b5625bb609b154766d2e138b61e15655f60b710sewardj if (!map) 11646b5625bb609b154766d2e138b61e15655f60b710sewardj continue; /* this isn't an upgrade of an r-- mapping */ 1165731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* looks like we're in luck! */ 1166731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj break; 1167731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj } 1168731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (di == NULL) 1169731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return; /* didn't find anything */ 1170731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 11716f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 11726f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-4: found existing DebugInfo* at %p\n", 11736f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj di); 11746f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj 11756b5625bb609b154766d2e138b61e15655f60b710sewardj /* Do the upgrade. Simply update the flags of the mapping 11766b5625bb609b154766d2e138b61e15655f60b710sewardj and pretend we never saw the RO map at all. */ 1177731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj vg_assert(di->fsm.have_ro_map); 11786b5625bb609b154766d2e138b61e15655f60b710sewardj map->rx = True; 11796b5625bb609b154766d2e138b61e15655f60b710sewardj map->ro = False; 1180731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj di->fsm.have_rx_map = True; 1181731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj di->fsm.have_ro_map = False; 11826b5625bb609b154766d2e138b61e15655f60b710sewardj /* See if there are any more ro mappings */ 11836b5625bb609b154766d2e138b61e15655f60b710sewardj for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { 1184518850bf0da07ed3e2244e307268ae0fd80e93a8florian map = VG_(indexXA)(di->fsm.maps, i); 11856b5625bb609b154766d2e138b61e15655f60b710sewardj if (map->ro) { 11866b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.have_ro_map = True; 11876b5625bb609b154766d2e138b61e15655f60b710sewardj break; 11886b5625bb609b154766d2e138b61e15655f60b710sewardj } 11896b5625bb609b154766d2e138b61e15655f60b710sewardj } 11906b5625bb609b154766d2e138b61e15655f60b710sewardj 11916b5625bb609b154766d2e138b61e15655f60b710sewardj /* Check if we're now in an accept state and read debuginfo. Finally. */ 11926b5625bb609b154766d2e138b61e15655f60b710sewardj if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) { 11936f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 11946f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-5: " 11956f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj "achieved accept state for %s\n", di->fsm.filename); 11966b5625bb609b154766d2e138b61e15655f60b710sewardj ULong di_handle __attribute__((unused)) 11976b5625bb609b154766d2e138b61e15655f60b710sewardj = di_notify_ACHIEVE_ACCEPT_STATE( di ); 11986b5625bb609b154766d2e138b61e15655f60b710sewardj /* di_handle is ignored. That's not a problem per se -- it just 11996b5625bb609b154766d2e138b61e15655f60b710sewardj means nobody will ever be able to refer to this debuginfo by 12006b5625bb609b154766d2e138b61e15655f60b710sewardj handle since nobody will know what the handle value is. */ 12016b5625bb609b154766d2e138b61e15655f60b710sewardj } 1202731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj} 1203731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 1204731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 1205c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--------- PDB (windows debug info) reading --------- */ 1206c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1207c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/* this should really return ULong, as per VG_(di_notify_mmap). */ 1208c8259b85b701d25d72aabe9dc0a8154517f96913sewardjvoid VG_(di_notify_pdb_debuginfo)( Int fd_obj, Addr avma_obj, 120954c45db2f978055aeca91aaccb05aac825523e6csewardj SizeT total_size, PtrdiffT bias_obj ) 1210c8259b85b701d25d72aabe9dc0a8154517f96913sewardj{ 121113ac96dea734b3933a73524b991ac64fb48a4d57sewardj Int i, r, sz_exename; 1212c8259b85b701d25d72aabe9dc0a8154517f96913sewardj ULong obj_mtime, pdb_mtime; 12131636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar* pdbname = NULL; 12141636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar* dot; 1215c8259b85b701d25d72aabe9dc0a8154517f96913sewardj SysRes sres; 1216c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Int fd_pdbimage; 1217c8259b85b701d25d72aabe9dc0a8154517f96913sewardj SizeT n_pdbimage; 1218c8259b85b701d25d72aabe9dc0a8154517f96913sewardj struct vg_stat stat_buf; 1219c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1220c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) { 1221738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "\n"); 1222c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(message)(Vg_UserMsg, 1223cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj "LOAD_PDB_DEBUGINFO: clreq: fd=%d, avma=%#lx, total_size=%lu, " 122454c45db2f978055aeca91aaccb05aac825523e6csewardj "bias=%#lx\n", 1225c6e5d76e9eea8625f385ff844545c688c91938daflorian fd_obj, avma_obj, total_size, (UWord)bias_obj 1226c8259b85b701d25d72aabe9dc0a8154517f96913sewardj ); 1227c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1228c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1229c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* 'fd' refers to the .exe/.dll we're dealing with. Get its modification 1230c8259b85b701d25d72aabe9dc0a8154517f96913sewardj time into obj_mtime. */ 1231c8259b85b701d25d72aabe9dc0a8154517f96913sewardj r = VG_(fstat)(fd_obj, &stat_buf); 1232c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (r == -1) 1233a175ffb9ffa4fd250611582a611333d11c835de2florian return; /* stat failed ?! */ 1234c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(r == 0); 12359c20ece00e07304f66da5f43b87ec45bc9c04550njn obj_mtime = stat_buf.mtime; 1236c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1237a175ffb9ffa4fd250611582a611333d11c835de2florian /* and get its name into exename. */ 12383130eab8c67d0c720cb1a86906cc057daa9700ccflorian const HChar *exe; 1239a175ffb9ffa4fd250611582a611333d11c835de2florian if (! VG_(resolve_filename)(fd_obj, &exe)) 1240a175ffb9ffa4fd250611582a611333d11c835de2florian return; /* failed */ 1241a175ffb9ffa4fd250611582a611333d11c835de2florian sz_exename = VG_(strlen)(exe); 1242a175ffb9ffa4fd250611582a611333d11c835de2florian HChar exename[sz_exename + 1]; 1243a175ffb9ffa4fd250611582a611333d11c835de2florian VG_(strcpy)(exename, exe); // make a copy on the stack 1244c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1245c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) { 1246738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: objname: %s\n", exename); 1247c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1248c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 124913ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Try to get the PDB file name from the executable. */ 125013ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = ML_(find_name_of_pdb_file)(exename); 125113ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (pdbname) { 125213ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(VG_(strlen)(pdbname) >= 5); /* 5 = strlen("X.pdb") */ 125313ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* So we successfully extracted a name from the PE file. But it's 125413ac96dea734b3933a73524b991ac64fb48a4d57sewardj likely to be of the form 125513ac96dea734b3933a73524b991ac64fb48a4d57sewardj e:\foo\bar\xyzzy\wibble.pdb 125613ac96dea734b3933a73524b991ac64fb48a4d57sewardj and we need to change it into something we can actually open 125713ac96dea734b3933a73524b991ac64fb48a4d57sewardj in Wine-world, which basically means turning it into 125813ac96dea734b3933a73524b991ac64fb48a4d57sewardj $HOME/.wine/drive_e/foo/bar/xyzzy/wibble.pdb 125913ac96dea734b3933a73524b991ac64fb48a4d57sewardj We also take into account $WINEPREFIX, if it is set. 126013ac96dea734b3933a73524b991ac64fb48a4d57sewardj For the moment, if the name isn't fully qualified, just forget it 126113ac96dea734b3933a73524b991ac64fb48a4d57sewardj (we'd have to root around to find where the pdb actually is) 126213ac96dea734b3933a73524b991ac64fb48a4d57sewardj */ 126313ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Change all the backslashes to forward slashes */ 126413ac96dea734b3933a73524b991ac64fb48a4d57sewardj for (i = 0; pdbname[i]; i++) { 126513ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (pdbname[i] == '\\') 126613ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname[i] = '/'; 126713ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 126813ac96dea734b3933a73524b991ac64fb48a4d57sewardj Bool is_quald 126913ac96dea734b3933a73524b991ac64fb48a4d57sewardj = ('a' <= VG_(tolower)(pdbname[0]) && VG_(tolower)(pdbname[0]) <= 'z') 127013ac96dea734b3933a73524b991ac64fb48a4d57sewardj && pdbname[1] == ':' 127113ac96dea734b3933a73524b991ac64fb48a4d57sewardj && pdbname[2] == '/'; 127213ac96dea734b3933a73524b991ac64fb48a4d57sewardj HChar* home = VG_(getenv)("HOME"); 127313ac96dea734b3933a73524b991ac64fb48a4d57sewardj HChar* wpfx = VG_(getenv)("WINEPREFIX"); 127413ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (is_quald && wpfx) { 127513ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Change e:/foo/bar/xyzzy/wibble.pdb 127613ac96dea734b3933a73524b991ac64fb48a4d57sewardj to $WINEPREFIX/drive_e/foo/bar/xyzzy/wibble.pdb 127713ac96dea734b3933a73524b991ac64fb48a4d57sewardj */ 127813ac96dea734b3933a73524b991ac64fb48a4d57sewardj Int mashedSzB = VG_(strlen)(pdbname) + VG_(strlen)(wpfx) + 50/*misc*/; 127913ac96dea734b3933a73524b991ac64fb48a4d57sewardj HChar* mashed = ML_(dinfo_zalloc)("di.debuginfo.dnpdi.1", mashedSzB); 128098500e2ee5f63f9c0af57835f7620d30848115f4bart VG_(snprintf)(mashed, mashedSzB, "%s/drive_%c%s", 128198500e2ee5f63f9c0af57835f7620d30848115f4bart wpfx, pdbname[0], &pdbname[2]); 128213ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(mashed[mashedSzB-1] == 0); 128313ac96dea734b3933a73524b991ac64fb48a4d57sewardj ML_(dinfo_free)(pdbname); 128413ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = mashed; 128513ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 128613ac96dea734b3933a73524b991ac64fb48a4d57sewardj else if (is_quald && home && !wpfx) { 128713ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Change e:/foo/bar/xyzzy/wibble.pdb 128813ac96dea734b3933a73524b991ac64fb48a4d57sewardj to $HOME/.wine/drive_e/foo/bar/xyzzy/wibble.pdb 128913ac96dea734b3933a73524b991ac64fb48a4d57sewardj */ 129013ac96dea734b3933a73524b991ac64fb48a4d57sewardj Int mashedSzB = VG_(strlen)(pdbname) + VG_(strlen)(home) + 50/*misc*/; 129113ac96dea734b3933a73524b991ac64fb48a4d57sewardj HChar* mashed = ML_(dinfo_zalloc)("di.debuginfo.dnpdi.2", mashedSzB); 129298500e2ee5f63f9c0af57835f7620d30848115f4bart VG_(snprintf)(mashed, mashedSzB, "%s/.wine/drive_%c%s", 129398500e2ee5f63f9c0af57835f7620d30848115f4bart home, pdbname[0], &pdbname[2]); 129413ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(mashed[mashedSzB-1] == 0); 129513ac96dea734b3933a73524b991ac64fb48a4d57sewardj ML_(dinfo_free)(pdbname); 129613ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = mashed; 129713ac96dea734b3933a73524b991ac64fb48a4d57sewardj } else { 129813ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* It's not a fully qualified path, or neither $HOME nor $WINE 129913ac96dea734b3933a73524b991ac64fb48a4d57sewardj are set (strange). Give up. */ 130013ac96dea734b3933a73524b991ac64fb48a4d57sewardj ML_(dinfo_free)(pdbname); 130113ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = NULL; 130213ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 130313ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 1304c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 130513ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Try s/exe/pdb/ if we don't have a valid pdbname. */ 130613ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (!pdbname) { 130713ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Try to find a matching PDB file from which to read debuginfo. 130813ac96dea734b3933a73524b991ac64fb48a4d57sewardj Windows PE files have symbol tables and line number information, 130913ac96dea734b3933a73524b991ac64fb48a4d57sewardj but MSVC doesn't seem to use them. */ 131013ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Why +5 ? Because in the worst case, we could find a dot as the 131113ac96dea734b3933a73524b991ac64fb48a4d57sewardj last character of pdbname, and we'd then put "pdb" right after 131213ac96dea734b3933a73524b991ac64fb48a4d57sewardj it, hence extending it a bit. */ 131313ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = ML_(dinfo_zalloc)("di.debuginfo.lpd1", sz_exename+5); 131413ac96dea734b3933a73524b991ac64fb48a4d57sewardj VG_(strcpy)(pdbname, exename); 131513ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(pdbname[sz_exename+5-1] == 0); 131613ac96dea734b3933a73524b991ac64fb48a4d57sewardj dot = VG_(strrchr)(pdbname, '.'); 131713ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (!dot) 131813ac96dea734b3933a73524b991ac64fb48a4d57sewardj goto out; /* there's no dot in the exe's name ?! */ 131913ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (dot[1] == 0) 132013ac96dea734b3933a73524b991ac64fb48a4d57sewardj goto out; /* hmm, path ends in "." */ 132113ac96dea734b3933a73524b991ac64fb48a4d57sewardj 132213ac96dea734b3933a73524b991ac64fb48a4d57sewardj if ('A' <= dot[1] && dot[1] <= 'Z') 132313ac96dea734b3933a73524b991ac64fb48a4d57sewardj VG_(strcpy)(dot, ".PDB"); 132413ac96dea734b3933a73524b991ac64fb48a4d57sewardj else 132513ac96dea734b3933a73524b991ac64fb48a4d57sewardj VG_(strcpy)(dot, ".pdb"); 132613ac96dea734b3933a73524b991ac64fb48a4d57sewardj 132713ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(pdbname[sz_exename+5-1] == 0); 132813ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 1329c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1330c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* See if we can find it, and check it's in-dateness. */ 1331c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sres = VG_(stat)(pdbname, &stat_buf); 1332cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) { 1333738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "Warning: Missing or un-stat-able %s\n", 1334c8259b85b701d25d72aabe9dc0a8154517f96913sewardj pdbname); 1335c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) 1336738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: missing: %s\n", pdbname); 1337c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; 1338c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 13399c20ece00e07304f66da5f43b87ec45bc9c04550njn pdb_mtime = stat_buf.mtime; 13407138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj 1341ced85060ebfd32f26de8e6a6f11567c9ac2b096asewardj if (obj_mtime > pdb_mtime + 60ULL) { 13427138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj /* PDB file is older than PE file. Really, the PDB should be 13437138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj newer than the PE, but that doesn't always seem to be the 13447138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj case. Allow the PDB to be up to one minute older. 13457138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj Otherwise, it's probably out of date, in which case ignore it 13467138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj or we will either (a) print wrong stack traces or more likely 13477138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj (b) crash. 13487138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj */ 1349738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, 1350ced85060ebfd32f26de8e6a6f11567c9ac2b096asewardj "Warning: %s (mtime = %llu)\n" 1351ced85060ebfd32f26de8e6a6f11567c9ac2b096asewardj " is older than %s (mtime = %llu)\n", 1352ced85060ebfd32f26de8e6a6f11567c9ac2b096asewardj pdbname, pdb_mtime, exename, obj_mtime); 1353c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1354c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1355c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sres = VG_(open)(pdbname, VKI_O_RDONLY, 0); 1356cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) { 1357738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "Warning: Can't open %s\n", pdbname); 1358c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; 1359c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1360c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1361cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj /* Looks promising; go on to try and read stuff from it. But don't 1362cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj mmap the file. Instead mmap free space and read the file into 1363cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj it. This is because files on CIFS filesystems that are mounted 1364cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj '-o directio' can't be mmap'd, and that mount option is needed 1365cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj to make CIFS work reliably. (See 1366cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj http://www.nabble.com/Corrupted-data-on-write-to- 1367cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj Windows-2003-Server-t2782623.html) 1368cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj This is slower, but at least it works reliably. */ 1369cda2f0fbda4c4b2644babc830244be8aed95de1dnjn fd_pdbimage = sr_Res(sres); 13709c20ece00e07304f66da5f43b87ec45bc9c04550njn n_pdbimage = stat_buf.size; 1371cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj if (n_pdbimage == 0 || n_pdbimage > 0x7FFFFFFF) { 1372cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // 0x7FFFFFFF: why? Because the VG_(read) just below only 1373cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // can deal with a signed int as the size of data to read, 1374cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // so we can't reliably check for read failure for files 1375cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // greater than that size. Hence just skip them; we're 1376cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // unlikely to encounter a PDB that large anyway. 1377cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj VG_(close)(fd_pdbimage); 1378cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj goto out; 1379cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj } 1380cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj sres = VG_(am_mmap_anon_float_valgrind)( n_pdbimage ); 1381cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) { 1382c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(close)(fd_pdbimage); 1383c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; 1384c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1385c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1386cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj void* pdbimage = (void*)sr_Res(sres); 1387cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj r = VG_(read)( fd_pdbimage, pdbimage, (Int)n_pdbimage ); 1388cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj if (r < 0 || r != (Int)n_pdbimage) { 1389cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage ); 1390cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj VG_(close)(fd_pdbimage); 1391cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj goto out; 1392cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj } 1393cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj 1394c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) 1395738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: pdbname: %s\n", pdbname); 1396c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1397c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* play safe; always invalidate the CFI cache. I don't know if 1398c8259b85b701d25d72aabe9dc0a8154517f96913sewardj this is necessary, but anyway .. */ 13995c3dba227192de63d86f65ec7d9597c132818c37philippe cfsi_m_cache__invalidate(); 1400c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* dump old info for this range, if any */ 1401c8259b85b701d25d72aabe9dc0a8154517f96913sewardj discard_syms_in_range( avma_obj, total_size ); 1402c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 14030f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj { DebugInfo* di = find_or_create_DebugInfo_for(exename); 1404c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1405c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* this di must be new, since we just nuked any old stuff in the range */ 1406a5acac39bf3be7546222b1316faee5ee524be0d1sewardj vg_assert(di && !di->fsm.have_rx_map && !di->fsm.have_rw_map); 1407c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(!di->have_dinfo); 1408c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1409c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* don't set up any of the di-> fields; let 1410c8259b85b701d25d72aabe9dc0a8154517f96913sewardj ML_(read_pdb_debug_info) do it. */ 141154c45db2f978055aeca91aaccb05aac825523e6csewardj ML_(read_pdb_debug_info)( di, avma_obj, bias_obj, 1412c8259b85b701d25d72aabe9dc0a8154517f96913sewardj pdbimage, n_pdbimage, pdbname, pdb_mtime ); 1413c8259b85b701d25d72aabe9dc0a8154517f96913sewardj // JRS fixme: take notice of return value from read_pdb_debug_info, 1414c8259b85b701d25d72aabe9dc0a8154517f96913sewardj // and handle failure 1415c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(di->have_dinfo); // fails if PDB read failed 1416c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage ); 1417c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(close)(fd_pdbimage); 1418cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj 1419cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj if (VG_(clo_verbosity) > 0) { 1420cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: done: " 1421a663c8e5b4767efbd870c857076251460992e3edsewardj "%lu syms, %lu src locs, %lu fpo recs\n", 1422a663c8e5b4767efbd870c857076251460992e3edsewardj di->symtab_used, di->loctab_used, di->fpo_size); 1423cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj } 1424c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1425c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1426c8259b85b701d25d72aabe9dc0a8154517f96913sewardj out: 1427c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (pdbname) ML_(dinfo_free)(pdbname); 1428c8259b85b701d25d72aabe9dc0a8154517f96913sewardj} 1429c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 14308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#endif /* defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) */ 14314ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 14324ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 1433eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1434eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- ---*/ 1435eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- TOP LEVEL: QUERYING EXISTING DEBUG INFO ---*/ 1436eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- ---*/ 1437eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1438eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 14399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid VG_(di_discard_ALL_debuginfo)( void ) 14409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 14419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo *di, *di2; 14429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di = debugInfo_list; 14439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj while (di) { 14449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di2 = di->next; 14459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("XXX rm %p\n", di); 14469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj free_DebugInfo( di ); 14479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di = di2; 14489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 14499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 14509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 14519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 1452518850bf0da07ed3e2244e307268ae0fd80e93a8florianDebugInfoMapping* ML_(find_rx_mapping) ( DebugInfo* di, Addr lo, Addr hi ) 14536b5625bb609b154766d2e138b61e15655f60b710sewardj{ 14546b5625bb609b154766d2e138b61e15655f60b710sewardj Word i; 14556b5625bb609b154766d2e138b61e15655f60b710sewardj vg_assert(lo <= hi); 14566b5625bb609b154766d2e138b61e15655f60b710sewardj 14576b5625bb609b154766d2e138b61e15655f60b710sewardj /* Optimization: Try to use the last matched rx mapping first */ 14586b5625bb609b154766d2e138b61e15655f60b710sewardj if ( di->last_rx_map 14596b5625bb609b154766d2e138b61e15655f60b710sewardj && lo >= di->last_rx_map->avma 14606b5625bb609b154766d2e138b61e15655f60b710sewardj && hi < di->last_rx_map->avma + di->last_rx_map->size) 14616b5625bb609b154766d2e138b61e15655f60b710sewardj return di->last_rx_map; 14626b5625bb609b154766d2e138b61e15655f60b710sewardj 14636b5625bb609b154766d2e138b61e15655f60b710sewardj for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { 1464518850bf0da07ed3e2244e307268ae0fd80e93a8florian DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i); 14656b5625bb609b154766d2e138b61e15655f60b710sewardj if ( map->rx && map->size > 0 14666b5625bb609b154766d2e138b61e15655f60b710sewardj && lo >= map->avma && hi < map->avma + map->size) { 14676b5625bb609b154766d2e138b61e15655f60b710sewardj di->last_rx_map = map; 14686b5625bb609b154766d2e138b61e15655f60b710sewardj return map; 14696b5625bb609b154766d2e138b61e15655f60b710sewardj } 14706b5625bb609b154766d2e138b61e15655f60b710sewardj } 14716b5625bb609b154766d2e138b61e15655f60b710sewardj 14726b5625bb609b154766d2e138b61e15655f60b710sewardj return NULL; 14736b5625bb609b154766d2e138b61e15655f60b710sewardj} 14746b5625bb609b154766d2e138b61e15655f60b710sewardj 1475a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/*------------------------------------------------------------*/ 1476a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/*--- Types and functions for inlined IP cursor ---*/ 1477a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/*------------------------------------------------------------*/ 1478a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestruct _InlIPCursor { 1479a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Addr eip; // Cursor used to describe calls at eip. 1480a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe DebugInfo* di; // DebugInfo describing inlined calls at eip 1481a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1482a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word inltab_lopos; // The inlined fn calls covering eip are in 1483a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word inltab_hipos; // di->inltab[inltab_lopos..inltab_hipos]. 1484a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // Note that not all inlined fn calls in this range 1485a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // are necessarily covering eip. 1486a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1487a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Int curlevel; // Current level to describe. 1488a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // 0 means to describe eip itself. 1489a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word cur_inltab; // inltab pos for call inlined at current level. 1490a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word next_inltab; // inltab pos for call inlined at next (towards main) 1491a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // level. 1492a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe}; 1493a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1494518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic Bool is_top(const InlIPCursor *iipc) 1495a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1496a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return !iipc || iipc->cur_inltab == -1; 1497a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1498a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1499518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic Bool is_bottom(const InlIPCursor *iipc) 1500a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1501a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return !iipc || iipc->next_inltab == -1; 1502a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1503a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1504a0a73939b0398b6608fd6dbde49820ce6530d12cphilippeBool VG_(next_IIPC)(InlIPCursor *iipc) 1505a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1506a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word i; 1507a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe DiInlLoc *hinl = NULL; 1508a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word hinl_pos = -1; 1509a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe DebugInfo *di; 1510a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1511a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (iipc == NULL) 1512a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return False; 1513a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1514a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (iipc->curlevel <= 0) { 1515a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe iipc->curlevel--; 1516a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return False; 1517a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1518a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1519a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe di = iipc->di; 1520a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe for (i = iipc->inltab_lopos; i <= iipc->inltab_hipos; i++) { 1521a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di->inltab[i].addr_lo <= iipc->eip 1522a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe && iipc->eip < di->inltab[i].addr_hi 1523a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe && di->inltab[i].level < iipc->curlevel 1524a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe && (!hinl || hinl->level < di->inltab[i].level)) { 1525a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe hinl = &di->inltab[i]; 1526a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe hinl_pos = i; 1527a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1528a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1529a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1530a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe iipc->cur_inltab = iipc->next_inltab; 1531a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe iipc->next_inltab = hinl_pos; 1532a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (iipc->next_inltab < 0) 1533a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe iipc->curlevel = 0; // no inlined call anymore, describe eip itself 1534a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe else 1535a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe iipc->curlevel = di->inltab[iipc->next_inltab].level; 1536a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1537a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return True; 1538a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1539a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1540a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/* Forward */ 1541a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic void search_all_loctabs ( Addr ptr, /*OUT*/DebugInfo** pdi, 1542a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*OUT*/Word* locno ); 1543a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1544a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/* Returns the position after which eip would be inserted in inltab. 1545a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe (-1 if eip should be inserted before position 0). 1546a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe This is the highest position with an addr_lo <= eip. 1547a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe As inltab is sorted on addr_lo, dichotomic search can be done 1548a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe (note that inltab might have duplicates addr_lo). */ 1549a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic Word inltab_insert_pos (DebugInfo *di, Addr eip) 1550a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1551a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word mid, 1552a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe lo = 0, 1553a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe hi = di->inltab_used-1; 1554a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe while (lo <= hi) { 1555a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe mid = (lo + hi) / 2; 1556a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (eip < di->inltab[mid].addr_lo) { hi = mid-1; continue; } 1557a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (eip > di->inltab[mid].addr_lo) { lo = mid+1; continue; } 1558a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe lo = mid; break; 1559a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1560a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1561a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe while (lo <= di->inltab_used-1 && di->inltab[lo].addr_lo <= eip) 1562a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe lo++; 1563a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe#if 0 1564a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe for (mid = 0; mid <= di->inltab_used-1; mid++) 1565a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (eip < di->inltab[mid].addr_lo) 1566a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe break; 1567a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (lo - 1 == mid - 1); 1568a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe#endif 1569a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return lo - 1; 1570a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1571a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1572a0a73939b0398b6608fd6dbde49820ce6530d12cphilippeInlIPCursor* VG_(new_IIPC)(Addr eip) 1573a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1574a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe DebugInfo* di; 1575a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word locno; 1576a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word i; 1577a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe InlIPCursor *ret; 1578a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Bool avail; 1579a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1580a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (!VG_(clo_read_inline_info)) 1581a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return NULL; // No way we can find inlined calls. 1582a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1583a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* Search the DebugInfo for eip */ 1584a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe search_all_loctabs ( eip, &di, &locno ); 1585a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di == NULL || di->inltab_used == 0) 1586a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return NULL; // No di (with inltab) containing eip. 1587a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1588a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* Search the entry in di->inltab with the highest addr_lo that 1589a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe contains eip. */ 1590a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* We start from the highest pos in inltab after which eip would 1591a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe be inserted. */ 1592a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe for (i = inltab_insert_pos (di, eip); i >= 0; i--) { 1593a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di->inltab[i].addr_lo <= eip && eip < di->inltab[i].addr_hi) { 1594a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe break; 1595a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1596a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* Stop the backward scan when reaching an addr_lo which 1597a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe cannot anymore contain eip : we know that all ranges before 1598a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe i also cannot contain eip. */ 1599a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di->inltab[i].addr_lo < eip - di->maxinl_codesz) 1600a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return NULL; 1601a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1602a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1603a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (i < 0) 1604a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return NULL; // No entry containing eip. 1605a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1606a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* We have found the highest entry containing eip. 1607a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Build a cursor. */ 1608a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret = ML_(dinfo_zalloc) ("dinfo.new_IIPC", sizeof(*ret)); 1609a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->eip = eip; 1610a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->di = di; 1611a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->inltab_hipos = i; 1612a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe for (i = ret->inltab_hipos - 1; i >= 0; i--) { 1613a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1614a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di->inltab[i].addr_lo < eip - di->maxinl_codesz) 1615a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe break; /* Similar stop backward scan logic as above. */ 1616a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1617a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->inltab_lopos = i + 1; 1618a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->curlevel = MAX_LEVEL; 1619a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->cur_inltab = -1; 1620a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->next_inltab = -1; 1621a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1622a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* MAX_LEVEL is higher than any stored level. We can use 1623a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe VG_(next_IIPC) to get to the 'real' first highest call level. */ 1624a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe avail = VG_(next_IIPC) (ret); 1625a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (avail); 1626a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1627a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return ret; 1628a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1629a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1630a0a73939b0398b6608fd6dbde49820ce6530d12cphilippevoid VG_(delete_IIPC)(InlIPCursor *iipc) 1631a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1632a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (iipc) 1633a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ML_(dinfo_free)( iipc ); 1634a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1635a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 16366b5625bb609b154766d2e138b61e15655f60b710sewardj 1637eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1638eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Use of symbol table & location info to create ---*/ 1639eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- plausible-looking stack dumps. ---*/ 1640eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1641eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1642eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Search all symtabs that we know about to locate ptr. If found, set 1643b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi to the relevant DebugInfo, and *symno to the symtab entry 1644b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *number within that. If not found, *psi is set to NULL. 1645b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj If findText==True, only text symbols are searched for. 1646b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj If findText==False, only data symbols are searched for. 1647b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/ 1648b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void search_all_symtabs ( Addr ptr, /*OUT*/DebugInfo** pdi, 1649f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*OUT*/Word* symno, 1650b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool match_anywhere_in_sym, 1651b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool findText ) 1652eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1653f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1654b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1655b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool inRange; 1656b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1657b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1658b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1659b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (findText) { 166051c9d3750448a4f2c95d22879e2f9f4bbd22bcfesewardj /* Consider any symbol in the r-x mapped area to be text. 166151c9d3750448a4f2c95d22879e2f9f4bbd22bcfesewardj See Comment_Regarding_Text_Range_Checks in storage.c for 166251c9d3750448a4f2c95d22879e2f9f4bbd22bcfesewardj details. */ 1663a5acac39bf3be7546222b1316faee5ee524be0d1sewardj inRange = di->fsm.have_rx_map 16646b5625bb609b154766d2e138b61e15655f60b710sewardj && (ML_(find_rx_mapping)(di, ptr, ptr) != NULL); 1665b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 1666b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj inRange = (di->data_present 1667b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_size > 0 1668b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_avma <= ptr 1669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->data_avma + di->data_size) 1670b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || 1671b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (di->sdata_present 1672b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_size > 0 1673b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_avma <= ptr 1674b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->sdata_avma + di->sdata_size) 1675b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || 1676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (di->bss_present 1677b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_size > 0 1678b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_avma <= ptr 16795706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && ptr < di->bss_avma + di->bss_size) 16805706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj || 16815706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj (di->sbss_present 16825706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->sbss_size > 0 16835706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->sbss_avma <= ptr 16845706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && ptr < di->sbss_avma + di->sbss_size) 16855706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj || 16865706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj (di->rodata_present 16875706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->rodata_size > 0 16885706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->rodata_avma <= ptr 16895706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && ptr < di->rodata_avma + di->rodata_size); 1690eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1691b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1692b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!inRange) continue; 1693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1694b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sno = ML_(search_one_symtab) ( 1695b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di, ptr, match_anywhere_in_sym, findText ); 1696b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (sno == -1) goto not_found; 1697b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *symno = sno; 1698b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = di; 1699b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; 1700b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1701eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1702eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj not_found: 1703b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = NULL; 1704eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1705eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1706eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1707eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Search all loctabs that we know about to locate ptr. If found, set 1708b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi to the relevant DebugInfo, and *locno to the loctab entry 1709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *number within that. If not found, *pdi is set to NULL. */ 1710b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void search_all_loctabs ( Addr ptr, /*OUT*/DebugInfo** pdi, 1711f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*OUT*/Word* locno ) 1712eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1713f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word lno; 1714b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1715b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1716b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 17175706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->text_size > 0 1718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= ptr 1719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->text_avma + di->text_size) { 1720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj lno = ML_(search_one_loctab) ( di, ptr ); 1721eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (lno == -1) goto not_found; 1722eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *locno = lno; 1723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = di; 1724eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return; 1725eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1726eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1727eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj not_found: 1728b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = NULL; 1729eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1730eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1731eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1732eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* The whole point of this whole big deal: map a code address to a 1733eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj plausible symbol name. Returns False if no idea; otherwise True. 1734dc4ff1a019a3e54d3e5517514b7e683cb2071829florian Caller supplies buf. If do_cxx_demangling is False, don't do 17356b7611bf42a0fbb62e047d8c43b008205bd21e75njn C++ demangling, regardless of VG_(clo_demangle) -- probably because the 17366b7611bf42a0fbb62e047d8c43b008205bd21e75njn call has come from VG_(get_fnname_raw)(). findText 1737b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj indicates whether we're looking for a text symbol or a data symbol 173846cc04521acf2827eb33310fadc119bf2dc039e4florian -- caller must choose one kind or the other. 173946cc04521acf2827eb33310fadc119bf2dc039e4florian Note: the string returned in *BUF is persistent as long as 174046cc04521acf2827eb33310fadc119bf2dc039e4florian (1) the DebugInfo it belongs to is not discarded 174146cc04521acf2827eb33310fadc119bf2dc039e4florian (2) the segment containing the address is not merged with another segment 174246cc04521acf2827eb33310fadc119bf2dc039e4florian (3) the demangler is not invoked again 174346cc04521acf2827eb33310fadc119bf2dc039e4florian In other words: if in doubt, save it away. 174446cc04521acf2827eb33310fadc119bf2dc039e4florian Also, the returned string is owned by "somebody else". Callers must 174546cc04521acf2827eb33310fadc119bf2dc039e4florian not free it or modify it. */ 1746eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjstatic 17476b7611bf42a0fbb62e047d8c43b008205bd21e75njnBool get_sym_name ( Bool do_cxx_demangling, Bool do_z_demangling, 17486b7611bf42a0fbb62e047d8c43b008205bd21e75njn Bool do_below_main_renaming, 174946cc04521acf2827eb33310fadc119bf2dc039e4florian Addr a, const HChar** buf, 1750b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool match_anywhere_in_sym, Bool show_offset, 1751c4431bfe04c7490ea2d74939d222d87f13f30960njn Bool findText, /*OUT*/PtrdiffT* offsetP ) 1752eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1753b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1754f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1755c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT offset; 1756eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1757b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj search_all_symtabs ( a, &di, &sno, match_anywhere_in_sym, findText ); 175846cc04521acf2827eb33310fadc119bf2dc039e4florian if (di == NULL) { 175946cc04521acf2827eb33310fadc119bf2dc039e4florian *buf = ""; 1760eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 176146cc04521acf2827eb33310fadc119bf2dc039e4florian } 17626882443ef154bca367bc591287de641e43a9e108njn 1763a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(di->symtab[sno].pri_name); 17646b7611bf42a0fbb62e047d8c43b008205bd21e75njn VG_(demangle) ( do_cxx_demangling, do_z_demangling, 176546cc04521acf2827eb33310fadc119bf2dc039e4florian di->symtab[sno].pri_name, buf ); 17666b7611bf42a0fbb62e047d8c43b008205bd21e75njn 17676b7611bf42a0fbb62e047d8c43b008205bd21e75njn /* Do the below-main hack */ 17686b7611bf42a0fbb62e047d8c43b008205bd21e75njn // To reduce the endless nuisance of multiple different names 17696b7611bf42a0fbb62e047d8c43b008205bd21e75njn // for "the frame below main()" screwing up the testsuite, change all 17706b7611bf42a0fbb62e047d8c43b008205bd21e75njn // known incarnations of said into a single name, "(below main)", if 17716b7611bf42a0fbb62e047d8c43b008205bd21e75njn // --show-below-main=yes. 17726b7611bf42a0fbb62e047d8c43b008205bd21e75njn if ( do_below_main_renaming && ! VG_(clo_show_below_main) && 177346cc04521acf2827eb33310fadc119bf2dc039e4florian Vg_FnNameBelowMain == VG_(get_fnname_kind)(*buf) ) 17746b7611bf42a0fbb62e047d8c43b008205bd21e75njn { 177546cc04521acf2827eb33310fadc119bf2dc039e4florian *buf = "(below main)"; 1776eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 17774cace66777ca9ee73ea156210c04e9d4cc178395philippe offset = a - di->symtab[sno].avmas.main; 1778c4431bfe04c7490ea2d74939d222d87f13f30960njn if (offsetP) *offsetP = offset; 1779b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1780eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (show_offset && offset != 0) { 178146cc04521acf2827eb33310fadc119bf2dc039e4florian static HChar *bufwo; // buf with offset 178246cc04521acf2827eb33310fadc119bf2dc039e4florian static SizeT bufwo_szB; 178346cc04521acf2827eb33310fadc119bf2dc039e4florian SizeT need, len; 178446cc04521acf2827eb33310fadc119bf2dc039e4florian 178546cc04521acf2827eb33310fadc119bf2dc039e4florian len = VG_(strlen)(*buf); 178646cc04521acf2827eb33310fadc119bf2dc039e4florian need = len + 1 + 19 + 1; 178746cc04521acf2827eb33310fadc119bf2dc039e4florian if (need > bufwo_szB) { 178846cc04521acf2827eb33310fadc119bf2dc039e4florian bufwo = ML_(dinfo_realloc)("get_sym_size", bufwo, need); 178946cc04521acf2827eb33310fadc119bf2dc039e4florian bufwo_szB = need; 1790eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1791eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 179246cc04521acf2827eb33310fadc119bf2dc039e4florian VG_(strcpy)(bufwo, *buf); 179346cc04521acf2827eb33310fadc119bf2dc039e4florian VG_(sprintf)(bufwo + len, "%c%ld", 179446cc04521acf2827eb33310fadc119bf2dc039e4florian offset < 0 ? '-' : '+', 179546cc04521acf2827eb33310fadc119bf2dc039e4florian offset < 0 ? -offset : offset); 179646cc04521acf2827eb33310fadc119bf2dc039e4florian *buf = bufwo; 179746cc04521acf2827eb33310fadc119bf2dc039e4florian } 17986b7611bf42a0fbb62e047d8c43b008205bd21e75njn 1799eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1800eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1801eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1802cae0cc22b83ffb260ee8379e92099c5a701944cbcarll/* ppc64be-linux only: find the TOC pointer (R2 value) that should be in 1803eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj force at the entry point address of the function containing 1804eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj guest_code_addr. Returns 0 if not known. */ 1805eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjAddr VG_(get_tocptr) ( Addr guest_code_addr ) 1806eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 18074cace66777ca9ee73ea156210c04e9d4cc178395philippe#if defined(VGA_ppc64be) || defined(VGA_ppc64le) 1808b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1809f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1810eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_symtabs ( guest_code_addr, 1811b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj &si, &sno, 1812b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj True/*match_anywhere_in_fun*/, 1813b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj True/*consider text symbols only*/ ); 1814eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 1815eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return 0; 1816eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj else 18174cace66777ca9ee73ea156210c04e9d4cc178395philippe return GET_TOCPTR_AVMA(si->symtab[sno].avmas); 18184cace66777ca9ee73ea156210c04e9d4cc178395philippe#else 18194cace66777ca9ee73ea156210c04e9d4cc178395philippe return 0; 18204cace66777ca9ee73ea156210c04e9d4cc178395philippe#endif 1821eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1822eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1823eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 182446cc04521acf2827eb33310fadc119bf2dc039e4florian match anywhere in function, but don't show offsets. 182546cc04521acf2827eb33310fadc119bf2dc039e4florian NOTE: See important comment about the persistence and memory ownership 182646cc04521acf2827eb33310fadc119bf2dc039e4florian of the return string at function get_sym_name */ 182746cc04521acf2827eb33310fadc119bf2dc039e4florianBool VG_(get_fnname) ( Addr a, const HChar** buf ) 1828eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 18296b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, 18306b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 183146cc04521acf2827eb33310fadc119bf2dc039e4florian a, buf, 1832b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1833b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1834b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1835b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1836eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1837eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1838eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 183946cc04521acf2827eb33310fadc119bf2dc039e4florian match anywhere in function, and show offset if nonzero. 184046cc04521acf2827eb33310fadc119bf2dc039e4florian NOTE: See important comment about the persistence and memory ownership 184146cc04521acf2827eb33310fadc119bf2dc039e4florian of the return string at function get_sym_name */ 184246cc04521acf2827eb33310fadc119bf2dc039e4florianBool VG_(get_fnname_w_offset) ( Addr a, const HChar** buf ) 1843eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 18446b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, 18456b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 184646cc04521acf2827eb33310fadc119bf2dc039e4florian a, buf, 1847b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1848b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/True, 1849b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1850b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1851eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1852eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1853eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 1854eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj only succeed if 'a' matches first instruction of function, 185546cc04521acf2827eb33310fadc119bf2dc039e4florian and don't show offsets. 185646cc04521acf2827eb33310fadc119bf2dc039e4florian NOTE: See important comment about the persistence and memory ownership 185746cc04521acf2827eb33310fadc119bf2dc039e4florian of the return string at function get_sym_name */ 185846cc04521acf2827eb33310fadc119bf2dc039e4florianBool VG_(get_fnname_if_entry) ( Addr a, const HChar** buf ) 1859eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1860dc4ff1a019a3e54d3e5517514b7e683cb2071829florian const HChar *tmp; 1861dc4ff1a019a3e54d3e5517514b7e683cb2071829florian Bool res; 1862dc4ff1a019a3e54d3e5517514b7e683cb2071829florian 1863dc4ff1a019a3e54d3e5517514b7e683cb2071829florian res = get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, 18646b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 1865dc4ff1a019a3e54d3e5517514b7e683cb2071829florian a, &tmp, 1866b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/False, 1867b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1868b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1869b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1870dc4ff1a019a3e54d3e5517514b7e683cb2071829florian if (res) 1871dc4ff1a019a3e54d3e5517514b7e683cb2071829florian *buf = tmp; 1872dc4ff1a019a3e54d3e5517514b7e683cb2071829florian return res; 1873eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1874eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 18756b7611bf42a0fbb62e047d8c43b008205bd21e75njn/* This is only available to core... don't C++-demangle, don't Z-demangle, 18766b7611bf42a0fbb62e047d8c43b008205bd21e75njn don't rename below-main, match anywhere in function, and don't show 187746cc04521acf2827eb33310fadc119bf2dc039e4florian offsets. 187846cc04521acf2827eb33310fadc119bf2dc039e4florian NOTE: See important comment about the persistence and memory ownership 187946cc04521acf2827eb33310fadc119bf2dc039e4florian of the return string at function get_sym_name */ 188046cc04521acf2827eb33310fadc119bf2dc039e4florianBool VG_(get_fnname_raw) ( Addr a, const HChar** buf ) 1881eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 18826b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, 18836b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/False, 188446cc04521acf2827eb33310fadc119bf2dc039e4florian a, buf, 1885b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1886b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1887b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1888b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1889eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1890eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1891eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is only available to core... don't demangle C++ names, but do 18926b7611bf42a0fbb62e047d8c43b008205bd21e75njn do Z-demangling and below-main-renaming, match anywhere in function, and 189346cc04521acf2827eb33310fadc119bf2dc039e4florian don't show offsets. 189446cc04521acf2827eb33310fadc119bf2dc039e4florian NOTE: See important comment about the persistence and memory ownership 189546cc04521acf2827eb33310fadc119bf2dc039e4florian of the return string at function get_sym_name */ 189646cc04521acf2827eb33310fadc119bf2dc039e4florianBool VG_(get_fnname_no_cxx_demangle) ( Addr a, const HChar** buf, 189746cc04521acf2827eb33310fadc119bf2dc039e4florian const InlIPCursor* iipc ) 1898eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1899a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (is_bottom(iipc)) { 1900a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // At the bottom (towards main), we describe the fn at eip. 1901a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/True, 1902a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*below-main-renaming*/True, 190346cc04521acf2827eb33310fadc119bf2dc039e4florian a, buf, 1904a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*match_anywhere_in_fun*/True, 1905a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*show offset?*/False, 1906a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*text syms only*/True, 1907a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*offsetP*/NULL ); 1908a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } else { 1909a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe const DiInlLoc *next_inl = iipc && iipc->next_inltab >= 0 1910a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ? & iipc->di->inltab[iipc->next_inltab] 1911a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe : NULL; 1912a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (next_inl); 1913a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // The function we are in is called by next_inl. 191446cc04521acf2827eb33310fadc119bf2dc039e4florian *buf = next_inl->inlinedfn; 1915a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return True; 1916a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1917eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1918eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 19195db15403e889d4db339b342bc2a824ef0bfaa654sewardj/* mips-linux only: find the offset of current address. This is needed for 19205db15403e889d4db339b342bc2a824ef0bfaa654sewardj stack unwinding for MIPS. 19215db15403e889d4db339b342bc2a824ef0bfaa654sewardj*/ 19225db15403e889d4db339b342bc2a824ef0bfaa654sewardjBool VG_(get_inst_offset_in_function)( Addr a, 19235db15403e889d4db339b342bc2a824ef0bfaa654sewardj /*OUT*/PtrdiffT* offset ) 19245db15403e889d4db339b342bc2a824ef0bfaa654sewardj{ 192546cc04521acf2827eb33310fadc119bf2dc039e4florian const HChar *fnname; 19265db15403e889d4db339b342bc2a824ef0bfaa654sewardj return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, 19275db15403e889d4db339b342bc2a824ef0bfaa654sewardj /*below-main-renaming*/False, 192846cc04521acf2827eb33310fadc119bf2dc039e4florian a, &fnname, 19295db15403e889d4db339b342bc2a824ef0bfaa654sewardj /*match_anywhere_in_sym*/True, 193081208182df4e8b9c8642affd6754996777ee7556florian /*show offset?*/False, 19314afac5b6f637d1cea82e62b3a280fa4e81101c05petarj /*text syms only*/True, 19325db15403e889d4db339b342bc2a824ef0bfaa654sewardj offset ); 19335db15403e889d4db339b342bc2a824ef0bfaa654sewardj} 19345db15403e889d4db339b342bc2a824ef0bfaa654sewardj 193546cc04521acf2827eb33310fadc119bf2dc039e4florianVg_FnNameKind VG_(get_fnname_kind) ( const HChar* name ) 19366882443ef154bca367bc591287de641e43a9e108njn{ 19376882443ef154bca367bc591287de641e43a9e108njn if (VG_STREQ("main", name)) { 19386882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameMain; 19396882443ef154bca367bc591287de641e43a9e108njn 19406882443ef154bca367bc591287de641e43a9e108njn } else if ( 19413026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGO_linux) 19426882443ef154bca367bc591287de641e43a9e108njn VG_STREQ("__libc_start_main", name) || // glibc glibness 19436882443ef154bca367bc591287de641e43a9e108njn VG_STREQ("generic_start_main", name) || // Yellow Dog doggedness 19443026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGO_darwin) 1945f76d27a697a7b0bf3b84490baf60623fc96a23afnjn // See readmacho.c for an explanation of this. 1946f76d27a697a7b0bf3b84490baf60623fc96a23afnjn VG_STREQ("start_according_to_valgrind", name) || // Darwin, darling 19478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# elif defined(VGO_solaris) 19488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_STREQ("_start", name) || // main() is called directly from _start 19493026f71684a930286186aa10fef266c304672e8fsewardj# else 19503026f71684a930286186aa10fef266c304672e8fsewardj# error "Unknown OS" 19513026f71684a930286186aa10fef266c304672e8fsewardj# endif 19526882443ef154bca367bc591287de641e43a9e108njn 0) { 19536882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameBelowMain; 19546882443ef154bca367bc591287de641e43a9e108njn 19556882443ef154bca367bc591287de641e43a9e108njn } else { 19566882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameNormal; 19576882443ef154bca367bc591287de641e43a9e108njn } 19586882443ef154bca367bc591287de641e43a9e108njn} 19596882443ef154bca367bc591287de641e43a9e108njn 19606882443ef154bca367bc591287de641e43a9e108njnVg_FnNameKind VG_(get_fnname_kind_from_IP) ( Addr ip ) 19616882443ef154bca367bc591287de641e43a9e108njn{ 196246cc04521acf2827eb33310fadc119bf2dc039e4florian const HChar *buf; 19636882443ef154bca367bc591287de641e43a9e108njn 19646882443ef154bca367bc591287de641e43a9e108njn // We don't demangle, because it's faster not to, and the special names 19657d995792542cf8e7f5a81248589445adfffeae30florian // we're looking for won't be mangled. 196646cc04521acf2827eb33310fadc119bf2dc039e4florian if (VG_(get_fnname_raw) ( ip, &buf )) { 196746cc04521acf2827eb33310fadc119bf2dc039e4florian 19686882443ef154bca367bc591287de641e43a9e108njn return VG_(get_fnname_kind)(buf); 19696882443ef154bca367bc591287de641e43a9e108njn } else { 19706882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameNormal; // Don't know the name, treat it as normal. 19716882443ef154bca367bc591287de641e43a9e108njn } 19726882443ef154bca367bc591287de641e43a9e108njn} 19736882443ef154bca367bc591287de641e43a9e108njn 1974b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Looks up data_addr in the collection of data symbols, and if found 197546cc04521acf2827eb33310fadc119bf2dc039e4florian puts a pointer to its name into dname. The name is zero terminated. 197646cc04521acf2827eb33310fadc119bf2dc039e4florian Also data_addr's offset from the symbol start is put into *offset. 197746cc04521acf2827eb33310fadc119bf2dc039e4florian NOTE: See important comment about the persistence and memory ownership 197846cc04521acf2827eb33310fadc119bf2dc039e4florian of the return string at function get_sym_name */ 1979b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool VG_(get_datasym_and_offset)( Addr data_addr, 198046cc04521acf2827eb33310fadc119bf2dc039e4florian /*OUT*/const HChar** dname, 1981c4431bfe04c7490ea2d74939d222d87f13f30960njn /*OUT*/PtrdiffT* offset ) 1982b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 198346cc04521acf2827eb33310fadc119bf2dc039e4florian return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, 19846b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/False, 198546cc04521acf2827eb33310fadc119bf2dc039e4florian data_addr, dname, 1986b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_sym*/True, 1987b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1988b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*data syms only please*/False, 1989b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset ); 1990b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 1991b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1992b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Map a code address to the name of a shared object file or the 199346cc04521acf2827eb33310fadc119bf2dc039e4florian executable. Returns False if no idea; otherwise True. 199446cc04521acf2827eb33310fadc119bf2dc039e4florian Note: the string returned in *BUF is persistent as long as 199546cc04521acf2827eb33310fadc119bf2dc039e4florian (1) the DebugInfo it belongs to is not discarded 199646cc04521acf2827eb33310fadc119bf2dc039e4florian (2) the segment containing the address is not merged with another segment 199746cc04521acf2827eb33310fadc119bf2dc039e4florian*/ 199846cc04521acf2827eb33310fadc119bf2dc039e4florianBool VG_(get_objname) ( Addr a, const HChar** buf ) 1999eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2000b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 2001f32ec7f0de8a651bc16a1b2e448c0106d8669889tom const NSegment *seg; 20023297124fa2116737066ac3cd709f18fdd5405163florian const HChar* filename; 200346cc04521acf2827eb33310fadc119bf2dc039e4florian 20047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Look in the debugInfo_list to find the name. In most cases we 20057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj expect this to produce a result. */ 2006b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 2007b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 20085706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->text_size > 0 2009b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= a 2010b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a < di->text_avma + di->text_size) { 201146cc04521acf2827eb33310fadc119bf2dc039e4florian *buf = di->fsm.filename; 2012eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 2013eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2014eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 20157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Last-ditch fallback position: if we don't find the address in 20167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj the debugInfo_list, ask the address space manager whether it 20177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj knows the name of the file associated with this mapping. This 20187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj allows us to print the names of exe/dll files in the stack trace 20197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj when running programs under wine. */ 20207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if ( (seg = VG_(am_find_nsegment(a))) != NULL 20217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj && (filename = VG_(am_get_filename)(seg)) != NULL ) { 202246cc04521acf2827eb33310fadc119bf2dc039e4florian *buf = filename; 2023f32ec7f0de8a651bc16a1b2e448c0106d8669889tom return True; 2024f32ec7f0de8a651bc16a1b2e448c0106d8669889tom } 2025eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 2026eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2027eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2028b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Map a code address to its DebugInfo. Returns NULL if not found. Doesn't 2029eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj require debug info. */ 2030e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjDebugInfo* VG_(find_DebugInfo) ( Addr a ) 2031eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2032e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj static UWord n_search = 0; 2033b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 2034e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj n_search++; 2035b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 2036b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 20375706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->text_size > 0 2038b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= a 2039b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a < di->text_avma + di->text_size) { 2040e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj if (0 == (n_search & 0xF)) 2041e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj move_DebugInfo_one_step_forward( di ); 2042b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 2043eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2044eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2045eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return NULL; 2046eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2047eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 204810ef725f1e8e9f1615c483555348eb75b69c4713florian/* Map a code address to a filename. Returns True if successful. The 204910ef725f1e8e9f1615c483555348eb75b69c4713florian returned string is persistent as long as the DebugInfo to which it 205010ef725f1e8e9f1615c483555348eb75b69c4713florian belongs is not discarded. */ 205110ef725f1e8e9f1615c483555348eb75b69c4713florianBool VG_(get_filename)( Addr a, const HChar** filename ) 2052eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2053b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 2054f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 205559e1f3c79e870a978d24add86db6d8c5450c8b63philippe UInt fndn_ix; 205659e1f3c79e870a978d24add86db6d8c5450c8b63philippe 2057eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 2058eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 2059eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 206059e1f3c79e870a978d24add86db6d8c5450c8b63philippe fndn_ix = ML_(fndn_ix) (si, locno); 206110ef725f1e8e9f1615c483555348eb75b69c4713florian *filename = ML_(fndn_ix2filename) (si, fndn_ix); 2062eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 2063eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2064eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2065eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a line number. Returns True if successful. */ 2066eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_linenum)( Addr a, UInt* lineno ) 2067eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2068b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 2069f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 2070eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 2071eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 2072eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 2073eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *lineno = si->loctab[locno].lineno; 2074eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2075eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 2076eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2077eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2078eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a filename/line number/dir name info. 2079eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj See prototype for detailed description of behaviour. 2080eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 2081eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_filename_linenum) ( Addr a, 208210ef725f1e8e9f1615c483555348eb75b69c4713florian /*OUT*/const HChar** filename, 208310ef725f1e8e9f1615c483555348eb75b69c4713florian /*OUT*/const HChar** dirname, 2084eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/UInt* lineno ) 2085eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2086b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 2087f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 208859e1f3c79e870a978d24add86db6d8c5450c8b63philippe UInt fndn_ix; 2089eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2090eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 2091c1b1d421216369aec58867ce1c5b99cfb1703c36njn if (si == NULL) { 2092f4384f47ee6b6234dba548a775585c37af712edfflorian if (dirname) { 209310ef725f1e8e9f1615c483555348eb75b69c4713florian *dirname = ""; 2094db5c6571454c1f647a4c67593805a8e401cd14c5njn } 209510ef725f1e8e9f1615c483555348eb75b69c4713florian *filename = ""; // this used to be not initialised.... 2096eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 2097c1b1d421216369aec58867ce1c5b99cfb1703c36njn } 2098c1b1d421216369aec58867ce1c5b99cfb1703c36njn 209959e1f3c79e870a978d24add86db6d8c5450c8b63philippe fndn_ix = ML_(fndn_ix)(si, locno); 210010ef725f1e8e9f1615c483555348eb75b69c4713florian *filename = ML_(fndn_ix2filename) (si, fndn_ix); 2101eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *lineno = si->loctab[locno].lineno; 2102eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2103eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (dirname) { 2104eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* caller wants directory info too .. */ 210510ef725f1e8e9f1615c483555348eb75b69c4713florian *dirname = ML_(fndn_ix2dirname) (si, fndn_ix); 2106eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2107eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2108eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 2109eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2110eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2111eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 21124ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/* Map a function name to its entry point and toc pointer. Is done by 21134ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj sequential search of all symbol tables, so is very slow. To 21144ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj mitigate the worst performance effects, you may specify a soname 21154ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj pattern, and only objects matching that pattern are searched. 21164ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Therefore specify "*" to search all the objects. On TOC-afflicted 21174ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj platforms, a symbol is deemed to be found only if it has a nonzero 21184ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj TOC pointer. */ 2119518850bf0da07ed3e2244e307268ae0fd80e93a8florianBool VG_(lookup_symbol_SLOW)(const HChar* sopatt, const HChar* name, 2120518850bf0da07ed3e2244e307268ae0fd80e93a8florian SymAVMAs* avmas) 21214ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj{ 21224ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool require_pToc = False; 21234ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Int i; 2124518850bf0da07ed3e2244e307268ae0fd80e93a8florian const DebugInfo* si; 21254ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool debug = False; 21264ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# if defined(VG_PLAT_USES_PPCTOC) 21274ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj require_pToc = True; 21284ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# endif 2129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (si = debugInfo_list; si; si = si->next) { 21304ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (debug) 21314ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(printf)("lookup_symbol_SLOW: considering %s\n", si->soname); 21324ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (!VG_(string_match)(sopatt, si->soname)) { 21334ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (debug) 21344ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(printf)(" ... skip\n"); 21354ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj continue; 21364ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 21374ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj for (i = 0; i < si->symtab_used; i++) { 21381ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian const HChar* pri_name = si->symtab[i].pri_name; 2139e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(pri_name); 2140a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (0==VG_(strcmp)(name, pri_name) 21414cace66777ca9ee73ea156210c04e9d4cc178395philippe && (require_pToc ? GET_TOCPTR_AVMA(si->symtab[i].avmas) : True)) { 21424cace66777ca9ee73ea156210c04e9d4cc178395philippe *avmas = si->symtab[i].avmas; 21434ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj return True; 21444ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 21451ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian const HChar** sec_names = si->symtab[i].sec_names; 2146a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (sec_names) { 2147e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(sec_names[0]); 2148a5cace0c2a3e212931badbf6398a0cd98393121asewardj while (*sec_names) { 2149a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (0==VG_(strcmp)(name, *sec_names) 21504cace66777ca9ee73ea156210c04e9d4cc178395philippe && (require_pToc 21514cace66777ca9ee73ea156210c04e9d4cc178395philippe ? GET_TOCPTR_AVMA(si->symtab[i].avmas) : True)) { 21524cace66777ca9ee73ea156210c04e9d4cc178395philippe *avmas = si->symtab[i].avmas; 2153a5cace0c2a3e212931badbf6398a0cd98393121asewardj return True; 2154a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 2155a5cace0c2a3e212931badbf6398a0cd98393121asewardj sec_names++; 2156a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 2157a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 21584ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 21594ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 21604ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj return False; 21614ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj} 21624ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 21634ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 2164770a8d23e40b980b5745e59ecb8e4037d81af357florian/* VG_(describe_IP): return info on code address, function name and 2165770a8d23e40b980b5745e59ecb8e4037d81af357florian filename. The returned string is allocated in a static buffer and will 2166770a8d23e40b980b5745e59ecb8e4037d81af357florian be overwritten in the next invocation. */ 2167eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2168770a8d23e40b980b5745e59ecb8e4037d81af357florian/* Copy str into *buf starting at n, ensuring that buf is zero-terminated. 2169770a8d23e40b980b5745e59ecb8e4037d81af357florian Return the index of the terminating null character. */ 2170770a8d23e40b980b5745e59ecb8e4037d81af357florianstatic SizeT 2171770a8d23e40b980b5745e59ecb8e4037d81af357florianputStr( SizeT n, HChar** buf, SizeT *bufsiz, const HChar* str ) 2172eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2173770a8d23e40b980b5745e59ecb8e4037d81af357florian SizeT slen = VG_(strlen)(str); 2174770a8d23e40b980b5745e59ecb8e4037d81af357florian SizeT need = n + slen + 1; 2175e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 2176770a8d23e40b980b5745e59ecb8e4037d81af357florian if (need > *bufsiz) { 2177770a8d23e40b980b5745e59ecb8e4037d81af357florian if (need < 256) need = 256; 2178770a8d23e40b980b5745e59ecb8e4037d81af357florian *bufsiz = need; 2179770a8d23e40b980b5745e59ecb8e4037d81af357florian *buf = ML_(dinfo_realloc)("putStr", *buf, *bufsiz); 2180770a8d23e40b980b5745e59ecb8e4037d81af357florian } 2181e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 2182770a8d23e40b980b5745e59ecb8e4037d81af357florian VG_(strcpy)(*buf + n, str); 2183770a8d23e40b980b5745e59ecb8e4037d81af357florian 2184770a8d23e40b980b5745e59ecb8e4037d81af357florian return n + slen; 2185770a8d23e40b980b5745e59ecb8e4037d81af357florian} 2186770a8d23e40b980b5745e59ecb8e4037d81af357florian 2187770a8d23e40b980b5745e59ecb8e4037d81af357florian/* Same as putStr, but escaping chars for XML output. */ 2188770a8d23e40b980b5745e59ecb8e4037d81af357florianstatic SizeT 2189770a8d23e40b980b5745e59ecb8e4037d81af357florianputStrEsc( SizeT n, HChar** buf, SizeT *bufsiz, const HChar* str ) 2190eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 21911636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar alt[2]; 2192770a8d23e40b980b5745e59ecb8e4037d81af357florian 2193eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj for (; *str != 0; str++) { 2194eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj switch (*str) { 2195e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '&': 2196770a8d23e40b980b5745e59ecb8e4037d81af357florian n = putStr( n, buf, bufsiz, "&"); 2197e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 2198e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '<': 2199770a8d23e40b980b5745e59ecb8e4037d81af357florian n = putStr( n, buf, bufsiz, "<"); 2200e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 2201e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '>': 2202770a8d23e40b980b5745e59ecb8e4037d81af357florian n = putStr( n, buf, bufsiz, ">"); 2203e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 2204e872fec0c1c3b478a399fdba42ac65764b53f470sewardj default: 2205e872fec0c1c3b478a399fdba42ac65764b53f470sewardj alt[0] = *str; 2206e872fec0c1c3b478a399fdba42ac65764b53f470sewardj alt[1] = 0; 2207770a8d23e40b980b5745e59ecb8e4037d81af357florian n = putStr( n, buf, bufsiz, alt ); 2208e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 2209eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2210eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2211eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return n; 2212eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2213eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2214770a8d23e40b980b5745e59ecb8e4037d81af357florianconst HChar* VG_(describe_IP)(Addr eip, const InlIPCursor *iipc) 2215eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2216770a8d23e40b980b5745e59ecb8e4037d81af357florian static HChar *buf = NULL; 2217770a8d23e40b980b5745e59ecb8e4037d81af357florian static SizeT bufsiz = 0; 2218eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define APPEND(_str) \ 2219770a8d23e40b980b5745e59ecb8e4037d81af357florian n = putStr(n, &buf, &bufsiz, _str) 2220770a8d23e40b980b5745e59ecb8e4037d81af357florian# define APPEND_ESC(_str) \ 2221770a8d23e40b980b5745e59ecb8e4037d81af357florian n = putStrEsc(n, &buf, &bufsiz, _str) 2222eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2223eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj UInt lineno; 2224770a8d23e40b980b5745e59ecb8e4037d81af357florian HChar ibuf[50]; // large enough 2225770a8d23e40b980b5745e59ecb8e4037d81af357florian SizeT n = 0; 222614cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj 2227a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (!iipc || iipc->eip == eip); 2228a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2229770a8d23e40b980b5745e59ecb8e4037d81af357florian const HChar *buf_fn; 2230770a8d23e40b980b5745e59ecb8e4037d81af357florian const HChar *buf_obj; 2231770a8d23e40b980b5745e59ecb8e4037d81af357florian const HChar *buf_srcloc; 2232770a8d23e40b980b5745e59ecb8e4037d81af357florian const HChar *buf_dirname; 223314cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj 223425148a6f2d895ee7005a69395427a4c9753f089dflorian Bool know_dirinfo; 2235a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Bool know_fnname; 2236a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Bool know_objname; 2237a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Bool know_srcloc; 2238a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2239a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (is_bottom(iipc)) { 2240a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // At the bottom (towards main), we describe the fn at eip. 2241a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe know_fnname = VG_(clo_sym_offsets) 224246cc04521acf2827eb33310fadc119bf2dc039e4florian ? VG_(get_fnname_w_offset) (eip, &buf_fn) 224346cc04521acf2827eb33310fadc119bf2dc039e4florian : VG_(get_fnname) (eip, &buf_fn); 2244a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } else { 2245a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe const DiInlLoc *next_inl = iipc && iipc->next_inltab >= 0 2246a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ? & iipc->di->inltab[iipc->next_inltab] 2247a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe : NULL; 2248a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (next_inl); 2249a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // The function we are in is called by next_inl. 2250770a8d23e40b980b5745e59ecb8e4037d81af357florian buf_fn = next_inl->inlinedfn; 2251a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe know_fnname = True; 2252a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2253a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // INLINED???? 2254a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // ??? Can we compute an offset for an inlined fn call ? 2255a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // ??? Offset from what ? The beginning of the inl info ? 2256a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // ??? But that is not necessarily the beginning of the fn 2257a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // ??? as e.g. an inlined fn call can be in several ranges. 2258a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // ??? Currently never showing an offset. 2259a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 2260a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 226146cc04521acf2827eb33310fadc119bf2dc039e4florian know_objname = VG_(get_objname)(eip, &buf_obj); 2262a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2263a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (is_top(iipc)) { 2264a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // The source for the highest level is in the loctab entry. 2265a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe know_srcloc = VG_(get_filename_linenum)( 2266a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe eip, 226710ef725f1e8e9f1615c483555348eb75b69c4713florian &buf_srcloc, 2268f4384f47ee6b6234dba548a775585c37af712edfflorian &buf_dirname, 2269a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe &lineno 2270a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ); 2271f4384f47ee6b6234dba548a775585c37af712edfflorian know_dirinfo = buf_dirname[0] != '\0'; 2272a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } else { 2273a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe const DiInlLoc *cur_inl = iipc && iipc->cur_inltab >= 0 2274a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ? & iipc->di->inltab[iipc->cur_inltab] 2275a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe : NULL; 2276a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (cur_inl); 2277a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 227859e1f3c79e870a978d24add86db6d8c5450c8b63philippe know_dirinfo = False; 227925148a6f2d895ee7005a69395427a4c9753f089dflorian buf_dirname = ""; 2280666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe // The fndn_ix and lineno for the caller of the inlined fn is in cur_inl. 2281666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe if (cur_inl->fndn_ix == 0) { 228210ef725f1e8e9f1615c483555348eb75b69c4713florian buf_srcloc = "???"; 2283666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe } else { 2284666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe FnDn *fndn = VG_(indexEltNumber) (iipc->di->fndnpool, 2285666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe cur_inl->fndn_ix); 2286666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe if (fndn->dirname) { 228710ef725f1e8e9f1615c483555348eb75b69c4713florian buf_dirname = fndn->dirname; 2288666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe know_dirinfo = True; 2289666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe } 229010ef725f1e8e9f1615c483555348eb75b69c4713florian buf_srcloc = fndn->filename; 2291666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe } 2292666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe lineno = cur_inl->lineno; 2293a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe know_srcloc = True; 2294a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 2295a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2296eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (VG_(clo_xml)) { 2297eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2298eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool human_readable = True; 22996bd9dc18c043927c1196caba20a327238a179c42florian const HChar* maybe_newline = human_readable ? "\n " : ""; 23006bd9dc18c043927c1196caba20a327238a179c42florian const HChar* maybe_newline2 = human_readable ? "\n " : ""; 2301eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2302e872fec0c1c3b478a399fdba42ac65764b53f470sewardj /* Print in XML format, dumping in as much info as we know. 2303770a8d23e40b980b5745e59ecb8e4037d81af357florian Ensure all tags are balanced. */ 2304eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<frame>"); 2305c6e5d76e9eea8625f385ff844545c688c91938daflorian VG_(sprintf)(ibuf,"<ip>0x%lX</ip>", eip); 2306eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2307eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 2308eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_objname) { 2309eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2310eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<obj>"); 2311770a8d23e40b980b5745e59ecb8e4037d81af357florian APPEND_ESC(buf_obj); 2312eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</obj>"); 2313eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2314eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_fnname) { 2315eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2316eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<fn>"); 2317770a8d23e40b980b5745e59ecb8e4037d81af357florian APPEND_ESC(buf_fn); 2318eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</fn>"); 2319eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2320eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_srcloc) { 2321eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_dirinfo) { 2322eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2323eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<dir>"); 2324770a8d23e40b980b5745e59ecb8e4037d81af357florian APPEND_ESC(buf_dirname); 2325eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</dir>"); 2326eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2327eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2328eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<file>"); 2329770a8d23e40b980b5745e59ecb8e4037d81af357florian APPEND_ESC(buf_srcloc); 2330eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</file>"); 2331eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2332eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<line>"); 2333c6e5d76e9eea8625f385ff844545c688c91938daflorian VG_(sprintf)(ibuf,"%u",lineno); 2334eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 2335eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</line>"); 2336eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2337eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline2); 2338eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</frame>"); 2339eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2340eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 2341eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2342eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Print for humans to read */ 23435e40abad4504416c59f0b29c1cfc8087201213a9njn // 23445e40abad4504416c59f0b29c1cfc8087201213a9njn // Possible forms: 23455e40abad4504416c59f0b29c1cfc8087201213a9njn // 23465e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: really (a.c:20) 23475e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: really (in /foo/a.out) 23485e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: really (in ???) 23495e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: ??? (in /foo/a.out) 23505e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: ??? (a.c:20) 23515e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: ??? 23525e40abad4504416c59f0b29c1cfc8087201213a9njn // 2353c6e5d76e9eea8625f385ff844545c688c91938daflorian VG_(sprintf)(ibuf,"0x%lX: ", eip); 2354eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 23555e40abad4504416c59f0b29c1cfc8087201213a9njn if (know_fnname) { 2356eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(buf_fn); 2357eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 2358eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("???"); 2359eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2360eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_srcloc) { 2361eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(" ("); 236214cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // Get the directory name, if any, possibly pruned, into dirname. 236310ef725f1e8e9f1615c483555348eb75b69c4713florian const HChar* dirname = NULL; 236425148a6f2d895ee7005a69395427a4c9753f089dflorian if (know_dirinfo && VG_(sizeXA)(VG_(clo_fullpath_after)) > 0) { 236514cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj Int i; 236614cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj dirname = buf_dirname; 236714cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // Remove leading prefixes from the dirname. 236814cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // If user supplied --fullpath-after=foo, this will remove 236914cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // a leading string which matches '.*foo' (not greedy). 23707931627282eede4440f3f329b657c3ec68371e8aflorian for (i = 0; i < VG_(sizeXA)(VG_(clo_fullpath_after)); i++) { 23717931627282eede4440f3f329b657c3ec68371e8aflorian const HChar* prefix = 23727931627282eede4440f3f329b657c3ec68371e8aflorian *(HChar**) VG_(indexXA)( VG_(clo_fullpath_after), i ); 23731636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar* str = VG_(strstr)(dirname, prefix); 237414cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj if (str) { 237514cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj dirname = str + VG_(strlen)(prefix); 237614cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj break; 237714cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj } 237814cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj } 237914cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj /* remove leading "./" */ 238014cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj if (dirname[0] == '.' && dirname[1] == '/') 238114cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj dirname += 2; 238214cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj } 238314cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // do we have any interesting directory name to show? If so 238414cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // add it in. 238514cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj if (dirname && dirname[0] != 0) { 238614cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj APPEND(dirname); 238714cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj APPEND("/"); 23885dd0190bc0ea66f8ffa7218c66f5a2e1c7b51b30bart } 2389eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(buf_srcloc); 2390eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(":"); 2391c6e5d76e9eea8625f385ff844545c688c91938daflorian VG_(sprintf)(ibuf,"%u",lineno); 2392eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 2393eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(")"); 23945e40abad4504416c59f0b29c1cfc8087201213a9njn } else if (know_objname) { 23955e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(" (in "); 23965e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(buf_obj); 23975e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(")"); 23985e40abad4504416c59f0b29c1cfc8087201213a9njn } else if (know_fnname) { 23995e40abad4504416c59f0b29c1cfc8087201213a9njn // Nb: do this in two steps because "??)" is a trigraph! 24005e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(" (in ???"); 24015e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(")"); 2402eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2403eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2404eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2405eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return buf; 2406eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2407eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef APPEND 2408eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef APPEND_ESC 2409eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2410eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 241172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 2412b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 2413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 2414b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/ 2415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- DWARF3 .eh_frame INFO ---*/ 2416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 2417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 241872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 241972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/* Gather up all the constant pieces of info needed to evaluate 242072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj a CfiExpr into one convenient struct. */ 242172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjtypedef 242272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj struct { 24233297124fa2116737066ac3cd709f18fdd5405163florian const D3UnwindRegs* uregs; 24243026f71684a930286186aa10fef266c304672e8fsewardj Addr min_accessible; 24253026f71684a930286186aa10fef266c304672e8fsewardj Addr max_accessible; 242672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 242772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExprEvalContext; 242872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 242972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/* Evaluate the CfiExpr rooted at ix in exprs given the context eec. 243072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj *ok is set to False on failure, but not to True on success. The 243172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj caller must set it to True before calling. */ 2432f7183e38d6215e98043ed014cb947cf5262bdc4asewardj__attribute__((noinline)) 2433f7183e38d6215e98043ed014cb947cf5262bdc4asewardjstatic 24343297124fa2116737066ac3cd709f18fdd5405163florianUWord evalCfiExpr ( const XArray* exprs, Int ix, 24353297124fa2116737066ac3cd709f18fdd5405163florian const CfiExprEvalContext* eec, Bool* ok ) 243672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj{ 243740628facff2285b0fce592381c6e26fdcd2a1252tom UWord w, wL, wR; 243819dc88f90d0e19a1463797dd99f6792a42f961d3sewardj Addr a; 24393297124fa2116737066ac3cd709f18fdd5405163florian const CfiExpr* e; 24403026f71684a930286186aa10fef266c304672e8fsewardj vg_assert(sizeof(Addr) == sizeof(UWord)); 24413026f71684a930286186aa10fef266c304672e8fsewardj e = VG_(indexXA)( exprs, ix ); 244272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->tag) { 244340628facff2285b0fce592381c6e26fdcd2a1252tom case Cex_Unop: 244440628facff2285b0fce592381c6e26fdcd2a1252tom w = evalCfiExpr( exprs, e->Cex.Unop.ix, eec, ok ); 244540628facff2285b0fce592381c6e26fdcd2a1252tom if (!(*ok)) return 0; 244640628facff2285b0fce592381c6e26fdcd2a1252tom switch (e->Cex.Unop.op) { 244740628facff2285b0fce592381c6e26fdcd2a1252tom case Cunop_Abs: return (Word) w < 0 ? - w : w; 244840628facff2285b0fce592381c6e26fdcd2a1252tom case Cunop_Neg: return - (Word) w; 244940628facff2285b0fce592381c6e26fdcd2a1252tom case Cunop_Not: return ~ w; 245040628facff2285b0fce592381c6e26fdcd2a1252tom default: goto unhandled; 245140628facff2285b0fce592381c6e26fdcd2a1252tom } 245240628facff2285b0fce592381c6e26fdcd2a1252tom /*NOTREACHED*/ 245372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_Binop: 245472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj wL = evalCfiExpr( exprs, e->Cex.Binop.ixL, eec, ok ); 245572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!(*ok)) return 0; 245672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj wR = evalCfiExpr( exprs, e->Cex.Binop.ixR, eec, ok ); 245772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!(*ok)) return 0; 245872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->Cex.Binop.op) { 2459f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Add: return wL + wR; 2460f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Sub: return wL - wR; 2461f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_And: return wL & wR; 2462f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Mul: return wL * wR; 2463f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Shl: return wL << wR; 2464f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Shr: return wL >> wR; 2465f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Eq: return wL == wR ? 1 : 0; 2466f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Ge: return (Word) wL >= (Word) wR ? 1 : 0; 2467f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Gt: return (Word) wL > (Word) wR ? 1 : 0; 2468f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Le: return (Word) wL <= (Word) wR ? 1 : 0; 2469f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Lt: return (Word) wL < (Word) wR ? 1 : 0; 2470f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Ne: return wL != wR ? 1 : 0; 247172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: goto unhandled; 247272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 247372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 247472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_CfiReg: 247572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->Cex.CfiReg.reg) { 24763026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 24773026f71684a930286186aa10fef266c304672e8fsewardj case Creg_IA_IP: return eec->uregs->xip; 24783026f71684a930286186aa10fef266c304672e8fsewardj case Creg_IA_SP: return eec->uregs->xsp; 24793026f71684a930286186aa10fef266c304672e8fsewardj case Creg_IA_BP: return eec->uregs->xbp; 24803026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_arm) 24813026f71684a930286186aa10fef266c304672e8fsewardj case Creg_ARM_R15: return eec->uregs->r15; 24823026f71684a930286186aa10fef266c304672e8fsewardj case Creg_ARM_R14: return eec->uregs->r14; 2483fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj case Creg_ARM_R13: return eec->uregs->r13; 2484fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj case Creg_ARM_R12: return eec->uregs->r12; 2485ade2eddf567a868bafad9110ed92acf7373a972bsewardj case Creg_ARM_R7: return eec->uregs->r7; 2486b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGA_s390x) 2487b6ba6d288e6000a8f95fba1dea671e0b53e26043florian case Creg_S390_IA: return eec->uregs->ia; 2488b6ba6d288e6000a8f95fba1dea671e0b53e26043florian case Creg_S390_SP: return eec->uregs->sp; 2489b6ba6d288e6000a8f95fba1dea671e0b53e26043florian case Creg_S390_FP: return eec->uregs->fp; 2490b6ba6d288e6000a8f95fba1dea671e0b53e26043florian case Creg_S390_LR: return eec->uregs->lr; 24914df0bfc0614379192c780c944415dc420d9cfe8epetarj# elif defined(VGA_mips32) || defined(VGA_mips64) 24925db15403e889d4db339b342bc2a824ef0bfaa654sewardj case Creg_IA_IP: return eec->uregs->pc; 24935db15403e889d4db339b342bc2a824ef0bfaa654sewardj case Creg_IA_SP: return eec->uregs->sp; 24945db15403e889d4db339b342bc2a824ef0bfaa654sewardj case Creg_IA_BP: return eec->uregs->fp; 24955db15403e889d4db339b342bc2a824ef0bfaa654sewardj case Creg_MIPS_RA: return eec->uregs->ra; 2496cae0cc22b83ffb260ee8379e92099c5a701944cbcarll# elif defined(VGA_ppc32) || defined(VGA_ppc64be) \ 2497cae0cc22b83ffb260ee8379e92099c5a701944cbcarll || defined(VGA_ppc64le) 2498f0c1250e324f6684757c6a15545366447ef1d64fsewardj# elif defined(VGP_arm64_linux) 2499821283b2110420321fd3f60afcc799b287788c68sewardj case Creg_ARM64_X30: return eec->uregs->x30; 2500112711afefcfcd43680c7c4aa8d38ef180e8811esewardj# elif defined(VGA_tilegx) 2501112711afefcfcd43680c7c4aa8d38ef180e8811esewardj case Creg_TILEGX_IP: return eec->uregs->pc; 2502112711afefcfcd43680c7c4aa8d38ef180e8811esewardj case Creg_TILEGX_SP: return eec->uregs->sp; 2503112711afefcfcd43680c7c4aa8d38ef180e8811esewardj case Creg_TILEGX_BP: return eec->uregs->fp; 2504112711afefcfcd43680c7c4aa8d38ef180e8811esewardj case Creg_TILEGX_LR: return eec->uregs->lr; 25053026f71684a930286186aa10fef266c304672e8fsewardj# else 25063026f71684a930286186aa10fef266c304672e8fsewardj# error "Unsupported arch" 25073026f71684a930286186aa10fef266c304672e8fsewardj# endif 250872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: goto unhandled; 250972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 251072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 251172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_Const: 251272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj return e->Cex.Const.con; 251319dc88f90d0e19a1463797dd99f6792a42f961d3sewardj case Cex_Deref: 251419dc88f90d0e19a1463797dd99f6792a42f961d3sewardj a = evalCfiExpr( exprs, e->Cex.Deref.ixAddr, eec, ok ); 251519dc88f90d0e19a1463797dd99f6792a42f961d3sewardj if (!(*ok)) return 0; 251619dc88f90d0e19a1463797dd99f6792a42f961d3sewardj if (a < eec->min_accessible 2517720e6b71b171885281afab634ce4d667c1f262bcsewardj || a > eec->max_accessible - sizeof(UWord) + 1) { 251819dc88f90d0e19a1463797dd99f6792a42f961d3sewardj *ok = False; 251919dc88f90d0e19a1463797dd99f6792a42f961d3sewardj return 0; 252019dc88f90d0e19a1463797dd99f6792a42f961d3sewardj } 252119dc88f90d0e19a1463797dd99f6792a42f961d3sewardj /* let's hope it doesn't trap! */ 252286781fabbfc019b752f9605e487cfce77b2a592atom return ML_(read_UWord)((void *)a); 252372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: 252472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj goto unhandled; 252572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 252672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 252772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj unhandled: 252872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("\n\nevalCfiExpr: unhandled\n"); 252972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj ML_(ppCfiExpr)( exprs, ix ); 253072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("\n"); 253172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); 253272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 253372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj return 0; 253472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj} 253572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 253672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 25375c3dba227192de63d86f65ec7d9597c132818c37philippe/* Search all the DebugInfos in the entire system, to find the DiCfSI_m 2538f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj that pertains to 'ip'. 2539eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2540f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj If found, set *diP to the DebugInfo in which it resides, and 25415c3dba227192de63d86f65ec7d9597c132818c37philippe *cfsi_mP to the cfsi_m pointer in that DebugInfo's cfsi_m_pool. 254272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 25435c3dba227192de63d86f65ec7d9597c132818c37philippe If not found, set *diP to (DebugInfo*)1 and *cfsi_mP to zero. 2544f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj*/ 2545f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj__attribute__((noinline)) 2546f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic void find_DiCfSI ( /*OUT*/DebugInfo** diP, 25475c3dba227192de63d86f65ec7d9597c132818c37philippe /*OUT*/DiCfSI_m** cfsi_mP, 2548f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Addr ip ) 2549f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 2550f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo* di; 2551f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word i = -1; 2552f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2553f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj static UWord n_search = 0; 2554f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj static UWord n_steps = 0; 2555eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_search++; 2556eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2557f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0) VG_(printf)("search for %#lx\n", ip); 2558eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2559f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (di = debugInfo_list; di != NULL; di = di->next) { 2560f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word j; 2561eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_steps++; 2562eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2563b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Use the per-DebugInfo summary address ranges to skip 2564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj inapplicable DebugInfos quickly. */ 2565f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di->cfsi_used == 0) 2566eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj continue; 2567f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (ip < di->cfsi_minavma || ip > di->cfsi_maxavma) 2568eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj continue; 2569eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2570f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* It might be in this DebugInfo. Search it. */ 2571f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj j = ML_(search_one_cfitab)( di, ip ); 2572f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(j >= -1 && j < (Word)di->cfsi_used); 2573f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2574f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (j != -1) { 2575f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj i = j; 2576f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj break; /* found it */ 2577eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2578eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2579eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2580f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (i == -1) { 2581f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2582f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* we didn't find it. */ 2583f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *diP = (DebugInfo*)1; 25845c3dba227192de63d86f65ec7d9597c132818c37philippe *cfsi_mP = 0; 2585f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2586f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 2587f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 25885c3dba227192de63d86f65ec7d9597c132818c37philippe /* found a di corresponding to ip. */ 2589f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* ensure that di is 4-aligned (at least), so it can't possibly 2590f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj be equal to (DebugInfo*)1. */ 2591f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di && VG_IS_4_ALIGNED(di)); 25925c3dba227192de63d86f65ec7d9597c132818c37philippe *cfsi_mP = ML_(get_cfsi_m) (di, i); 25935c3dba227192de63d86f65ec7d9597c132818c37philippe if (*cfsi_mP == NULL) { 25945c3dba227192de63d86f65ec7d9597c132818c37philippe // This is a cfsi hole. Report no cfi information found. 25955c3dba227192de63d86f65ec7d9597c132818c37philippe *diP = (DebugInfo*)1; 25965c3dba227192de63d86f65ec7d9597c132818c37philippe // But we will still perform the hack below. 25975c3dba227192de63d86f65ec7d9597c132818c37philippe } else { 25985c3dba227192de63d86f65ec7d9597c132818c37philippe *diP = di; 25995c3dba227192de63d86f65ec7d9597c132818c37philippe } 2600f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2601f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Start of performance-enhancing hack: once every 64 (chosen 2602f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj hackily after profiling) successful searches, move the found 2603f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo one step closer to the start of the list. This 2604f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj makes future searches cheaper. For starting konqueror on 2605f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj amd64, this in fact reduces the total amount of searching 2606f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj done by the above find-the-right-DebugInfo loop by more than 2607f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj a factor of 20. */ 2608f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if ((n_search & 0xF) == 0) { 2609f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Move di one step closer to the start of the list. */ 2610f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj move_DebugInfo_one_step_forward( di ); 2611f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 2612f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* End of performance-enhancing hack. */ 2613f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2614f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && ((n_search & 0x7FFFF) == 0)) 2615f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(printf)("find_DiCfSI: %lu searches, " 2616f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj "%lu DebugInfos looked at\n", 2617f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj n_search, n_steps); 2618f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2619f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 2620f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2621f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 2622f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2623f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2624f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Now follows a mechanism for caching queries to find_DiCfSI, since 2625f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj they are extremely frequent on amd64-linux, during stack unwinding. 2626f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 26275c3dba227192de63d86f65ec7d9597c132818c37philippe Each cache entry binds an ip value to a (di, cfsi_m*) pair. Possible 2628f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj values: 2629f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 26305c3dba227192de63d86f65ec7d9597c132818c37philippe di is non-null, cfsi_m* >= 0 ==> cache slot in use, "cfsi_m*" 26315c3dba227192de63d86f65ec7d9597c132818c37philippe di is (DebugInfo*)1 ==> cache slot in use, no associated di 26325c3dba227192de63d86f65ec7d9597c132818c37philippe di is NULL ==> cache slot not in use 2633f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2634f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Hence simply zeroing out the entire cache invalidates all 2635f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj entries. 2636f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 26375c3dba227192de63d86f65ec7d9597c132818c37philippe We can map an ip value directly to a (di, cfsi_m*) pair as 26385c3dba227192de63d86f65ec7d9597c132818c37philippe once a DebugInfo is read, adding new DiCfSI_m* is not possible 26395c3dba227192de63d86f65ec7d9597c132818c37philippe anymore, as the cfsi_m_pool is frozen once the reading is terminated. 26405c3dba227192de63d86f65ec7d9597c132818c37philippe Also, the cache is invalidated when new debuginfo is read due to 26415c3dba227192de63d86f65ec7d9597c132818c37philippe an mmap or some debuginfo is discarded due to an munmap. */ 2642eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 26435c3dba227192de63d86f65ec7d9597c132818c37philippe// Prime number, giving about 6Kbytes cache on 32 bits, 26445c3dba227192de63d86f65ec7d9597c132818c37philippe// 12Kbytes cache on 64 bits. 26455c3dba227192de63d86f65ec7d9597c132818c37philippe#define N_CFSI_M_CACHE 509 2646f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2647f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjtypedef 26485c3dba227192de63d86f65ec7d9597c132818c37philippe struct { Addr ip; DebugInfo* di; DiCfSI_m* cfsi_m; } 26495c3dba227192de63d86f65ec7d9597c132818c37philippe CFSI_m_CacheEnt; 2650f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 26515c3dba227192de63d86f65ec7d9597c132818c37philippestatic CFSI_m_CacheEnt cfsi_m_cache[N_CFSI_M_CACHE]; 2652f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 26535c3dba227192de63d86f65ec7d9597c132818c37philippestatic void cfsi_m_cache__invalidate ( void ) { 26545c3dba227192de63d86f65ec7d9597c132818c37philippe VG_(memset)(&cfsi_m_cache, 0, sizeof(cfsi_m_cache)); 2655f7bbd7982397fb73477bdc21bf236cf9100cee44philippe debuginfo_generation++; 2656f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 2657f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2658f7bbd7982397fb73477bdc21bf236cf9100cee44philippeUInt VG_(debuginfo_generation) (void) 265920ede3a4f086d4a4b1e0969b1098dcb244ffb6b4philippe{ 2660f7bbd7982397fb73477bdc21bf236cf9100cee44philippe return debuginfo_generation; 266120ede3a4f086d4a4b1e0969b1098dcb244ffb6b4philippe} 2662f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 26635c3dba227192de63d86f65ec7d9597c132818c37philippestatic inline CFSI_m_CacheEnt* cfsi_m_cache__find ( Addr ip ) 2664f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 26655c3dba227192de63d86f65ec7d9597c132818c37philippe UWord hash = ip % N_CFSI_M_CACHE; 26665c3dba227192de63d86f65ec7d9597c132818c37philippe CFSI_m_CacheEnt* ce = &cfsi_m_cache[hash]; 26673c9cf3442185b5891e15450d6e3058aeff6796fetom static UWord n_q = 0, n_m = 0; 2668f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2669f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj n_q++; 2670f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && 0 == (n_q & 0x1FFFFF)) 2671f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(printf)("QQQ %lu %lu\n", n_q, n_m); 2672f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 26733c9cf3442185b5891e15450d6e3058aeff6796fetom if (LIKELY(ce->ip == ip) && LIKELY(ce->di != NULL)) { 26743c9cf3442185b5891e15450d6e3058aeff6796fetom /* found an entry in the cache .. */ 26753c9cf3442185b5891e15450d6e3058aeff6796fetom } else { 26763c9cf3442185b5891e15450d6e3058aeff6796fetom /* not found in cache. Search and update. */ 26773c9cf3442185b5891e15450d6e3058aeff6796fetom n_m++; 26783c9cf3442185b5891e15450d6e3058aeff6796fetom ce->ip = ip; 26795c3dba227192de63d86f65ec7d9597c132818c37philippe find_DiCfSI( &ce->di, &ce->cfsi_m, ip ); 26803c9cf3442185b5891e15450d6e3058aeff6796fetom } 2681eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 26823c9cf3442185b5891e15450d6e3058aeff6796fetom if (UNLIKELY(ce->di == (DebugInfo*)1)) { 26833c9cf3442185b5891e15450d6e3058aeff6796fetom /* no DiCfSI for this address */ 26843c9cf3442185b5891e15450d6e3058aeff6796fetom return NULL; 26853c9cf3442185b5891e15450d6e3058aeff6796fetom } else { 26863c9cf3442185b5891e15450d6e3058aeff6796fetom /* found a DiCfSI for this address */ 26873c9cf3442185b5891e15450d6e3058aeff6796fetom return ce; 2688eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 26893c9cf3442185b5891e15450d6e3058aeff6796fetom} 2690eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2691eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2692f7183e38d6215e98043ed014cb947cf5262bdc4asewardjinline 26933297124fa2116737066ac3cd709f18fdd5405163florianstatic Addr compute_cfa ( const D3UnwindRegs* uregs, 26943c9cf3442185b5891e15450d6e3058aeff6796fetom Addr min_accessible, Addr max_accessible, 26953297124fa2116737066ac3cd709f18fdd5405163florian const DebugInfo* di, const DiCfSI_m* cfsi_m ) 26963c9cf3442185b5891e15450d6e3058aeff6796fetom{ 26973c9cf3442185b5891e15450d6e3058aeff6796fetom CfiExprEvalContext eec; 26983c9cf3442185b5891e15450d6e3058aeff6796fetom Addr cfa; 26993c9cf3442185b5891e15450d6e3058aeff6796fetom Bool ok; 2700eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 27013c9cf3442185b5891e15450d6e3058aeff6796fetom /* Compute the CFA. */ 270272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj cfa = 0; 27035c3dba227192de63d86f65ec7d9597c132818c37philippe switch (cfsi_m->cfa_how) { 27043026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 27053026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_IA_SPREL: 27065c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->xsp; 27073026f71684a930286186aa10fef266c304672e8fsewardj break; 27083026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_IA_BPREL: 27095c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->xbp; 271072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 27113026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_arm) 27123026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_ARM_R13REL: 27135c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->r13; 271472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 27153026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_ARM_R12REL: 27165c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->r12; 27173026f71684a930286186aa10fef266c304672e8fsewardj break; 27183026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_ARM_R11REL: 27195c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->r11; 27203026f71684a930286186aa10fef266c304672e8fsewardj break; 2721fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj case CFIC_ARM_R7REL: 27225c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->r7; 2723fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj break; 2724b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGA_s390x) 2725b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case CFIC_IA_SPREL: 27265c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->sp; 2727b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 2728b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case CFIR_MEMCFAREL: 2729b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj { 27305c3dba227192de63d86f65ec7d9597c132818c37philippe Addr a = uregs->sp + cfsi_m->cfa_off; 2731b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj if (a < min_accessible || a > max_accessible-sizeof(Addr)) 2732b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 273386781fabbfc019b752f9605e487cfce77b2a592atom cfa = ML_(read_Addr)((void *)a); 2734b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 2735b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj } 2736b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case CFIR_SAME: 2737b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj cfa = uregs->fp; 2738b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 2739b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case CFIC_IA_BPREL: 27405c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->fp; 2741b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 27424df0bfc0614379192c780c944415dc420d9cfe8epetarj# elif defined(VGA_mips32) || defined(VGA_mips64) 27435db15403e889d4db339b342bc2a824ef0bfaa654sewardj case CFIC_IA_SPREL: 27445c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->sp; 27455db15403e889d4db339b342bc2a824ef0bfaa654sewardj break; 27465db15403e889d4db339b342bc2a824ef0bfaa654sewardj case CFIR_SAME: 27475db15403e889d4db339b342bc2a824ef0bfaa654sewardj cfa = uregs->fp; 27485db15403e889d4db339b342bc2a824ef0bfaa654sewardj break; 27495db15403e889d4db339b342bc2a824ef0bfaa654sewardj case CFIC_IA_BPREL: 27505c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->fp; 27515db15403e889d4db339b342bc2a824ef0bfaa654sewardj break; 2752cae0cc22b83ffb260ee8379e92099c5a701944cbcarll# elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le) 2753f0c1250e324f6684757c6a15545366447ef1d64fsewardj# elif defined(VGP_arm64_linux) 2754821283b2110420321fd3f60afcc799b287788c68sewardj case CFIC_ARM64_SPREL: 27555c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->sp; 2756821283b2110420321fd3f60afcc799b287788c68sewardj break; 2757821283b2110420321fd3f60afcc799b287788c68sewardj case CFIC_ARM64_X29REL: 27585c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->x29; 2759821283b2110420321fd3f60afcc799b287788c68sewardj break; 2760112711afefcfcd43680c7c4aa8d38ef180e8811esewardj# elif defined(VGA_tilegx) 2761112711afefcfcd43680c7c4aa8d38ef180e8811esewardj case CFIC_IA_SPREL: 2762112711afefcfcd43680c7c4aa8d38ef180e8811esewardj cfa = cfsi_m->cfa_off + uregs->sp; 2763112711afefcfcd43680c7c4aa8d38ef180e8811esewardj break; 2764112711afefcfcd43680c7c4aa8d38ef180e8811esewardj case CFIR_SAME: 2765112711afefcfcd43680c7c4aa8d38ef180e8811esewardj cfa = uregs->fp; 2766112711afefcfcd43680c7c4aa8d38ef180e8811esewardj break; 2767112711afefcfcd43680c7c4aa8d38ef180e8811esewardj case CFIC_IA_BPREL: 2768112711afefcfcd43680c7c4aa8d38ef180e8811esewardj cfa = cfsi_m->cfa_off + uregs->fp; 2769112711afefcfcd43680c7c4aa8d38ef180e8811esewardj break; 27703026f71684a930286186aa10fef266c304672e8fsewardj# else 27713026f71684a930286186aa10fef266c304672e8fsewardj# error "Unsupported arch" 27723026f71684a930286186aa10fef266c304672e8fsewardj# endif 27733026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_EXPR: /* available on all archs */ 27747888e2204fff6e7429236b4227ed16594e7743b9sewardj if (0) { 27757888e2204fff6e7429236b4227ed16594e7743b9sewardj VG_(printf)("CFIC_EXPR: "); 27765c3dba227192de63d86f65ec7d9597c132818c37philippe ML_(ppCfiExpr)(di->cfsi_exprs, cfsi_m->cfa_off); 27777888e2204fff6e7429236b4227ed16594e7743b9sewardj VG_(printf)("\n"); 27787888e2204fff6e7429236b4227ed16594e7743b9sewardj } 27793026f71684a930286186aa10fef266c304672e8fsewardj eec.uregs = uregs; 27807888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.min_accessible = min_accessible; 27817888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.max_accessible = max_accessible; 27827888e2204fff6e7429236b4227ed16594e7743b9sewardj ok = True; 27835c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = evalCfiExpr(di->cfsi_exprs, cfsi_m->cfa_off, &eec, &ok ); 27843c9cf3442185b5891e15450d6e3058aeff6796fetom if (!ok) return 0; 278572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 278672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: 278772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); 278872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 27893c9cf3442185b5891e15450d6e3058aeff6796fetom return cfa; 27903c9cf3442185b5891e15450d6e3058aeff6796fetom} 27913c9cf3442185b5891e15450d6e3058aeff6796fetom 27923c9cf3442185b5891e15450d6e3058aeff6796fetom 27933c9cf3442185b5891e15450d6e3058aeff6796fetom/* Get the call frame address (CFA) given an IP/SP/FP triple. */ 27943026f71684a930286186aa10fef266c304672e8fsewardj/* NOTE: This function may rearrange the order of entries in the 27953026f71684a930286186aa10fef266c304672e8fsewardj DebugInfo list. */ 27963c9cf3442185b5891e15450d6e3058aeff6796fetomAddr ML_(get_CFA) ( Addr ip, Addr sp, Addr fp, 27973c9cf3442185b5891e15450d6e3058aeff6796fetom Addr min_accessible, Addr max_accessible ) 27983c9cf3442185b5891e15450d6e3058aeff6796fetom{ 27995c3dba227192de63d86f65ec7d9597c132818c37philippe CFSI_m_CacheEnt* ce; 28003c9cf3442185b5891e15450d6e3058aeff6796fetom 28015c3dba227192de63d86f65ec7d9597c132818c37philippe ce = cfsi_m_cache__find(ip); 28023c9cf3442185b5891e15450d6e3058aeff6796fetom 28033c9cf3442185b5891e15450d6e3058aeff6796fetom if (UNLIKELY(ce == NULL)) 28043c9cf3442185b5891e15450d6e3058aeff6796fetom return 0; /* no info. Nothing we can do. */ 28053c9cf3442185b5891e15450d6e3058aeff6796fetom 28063026f71684a930286186aa10fef266c304672e8fsewardj /* Temporary impedance-matching kludge so that this keeps working 28073026f71684a930286186aa10fef266c304672e8fsewardj on x86-linux and amd64-linux. */ 28083026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 28093026f71684a930286186aa10fef266c304672e8fsewardj { D3UnwindRegs uregs; 28103026f71684a930286186aa10fef266c304672e8fsewardj uregs.xip = ip; 28113026f71684a930286186aa10fef266c304672e8fsewardj uregs.xsp = sp; 28123026f71684a930286186aa10fef266c304672e8fsewardj uregs.xbp = fp; 28133026f71684a930286186aa10fef266c304672e8fsewardj return compute_cfa(&uregs, 281405c459ea63c50a072cf1eb0868590e9c0b362f30philippe min_accessible, max_accessible, ce->di, ce->cfsi_m); 28153026f71684a930286186aa10fef266c304672e8fsewardj } 2816b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#elif defined(VGA_s390x) 2817b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj { D3UnwindRegs uregs; 2818b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj uregs.ia = ip; 2819b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj uregs.sp = sp; 2820b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj uregs.fp = fp; 2821b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj return compute_cfa(&uregs, 282205c459ea63c50a072cf1eb0868590e9c0b362f30philippe min_accessible, max_accessible, ce->di, ce->cfsi_m); 2823b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj } 2824112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#elif defined(VGA_mips32) || defined(VGA_mips64) || defined(VGA_tilegx) 2825fe0b43315c344cfd07981a0826bc34614a220169dejanj { D3UnwindRegs uregs; 2826fe0b43315c344cfd07981a0826bc34614a220169dejanj uregs.pc = ip; 2827fe0b43315c344cfd07981a0826bc34614a220169dejanj uregs.sp = sp; 2828fe0b43315c344cfd07981a0826bc34614a220169dejanj uregs.fp = fp; 2829fe0b43315c344cfd07981a0826bc34614a220169dejanj return compute_cfa(&uregs, 283005c459ea63c50a072cf1eb0868590e9c0b362f30philippe min_accessible, max_accessible, ce->di, ce->cfsi_m); 2831fe0b43315c344cfd07981a0826bc34614a220169dejanj } 2832b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 28333026f71684a930286186aa10fef266c304672e8fsewardj# else 28343026f71684a930286186aa10fef266c304672e8fsewardj return 0; /* indicates failure */ 28353026f71684a930286186aa10fef266c304672e8fsewardj# endif 28363c9cf3442185b5891e15450d6e3058aeff6796fetom} 28373c9cf3442185b5891e15450d6e3058aeff6796fetom 283897bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippevoid VG_(ppUnwindInfo) (Addr from, Addr to) 283997bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe{ 284097bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe DebugInfo* di; 284197bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe CFSI_m_CacheEnt* ce; 284297bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe Addr ce_from; 284397bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe CFSI_m_CacheEnt* next_ce; 284497bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe 284597bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe 284697bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe ce = cfsi_m_cache__find(from); 284797bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe ce_from = from; 284897bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe while (from <= to) { 284997bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe from++; 285097bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe next_ce = cfsi_m_cache__find(from); 285197bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe if ((ce == NULL && next_ce != NULL) 285297bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe || (ce != NULL && next_ce == NULL) 285397bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe || (ce != NULL && next_ce != NULL && ce->cfsi_m != next_ce->cfsi_m) 285497bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe || from > to) { 285597bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe if (ce == NULL) { 285697bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe VG_(printf)("[%#lx .. %#lx]: no CFI info\n", ce_from, from-1); 285797bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe } else { 285897bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe di = ce->di; 285997bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe ML_(ppDiCfSI)(di->cfsi_exprs, 286097bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe ce_from, from - ce_from, 286197bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe ce->cfsi_m); 286297bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe } 286397bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe ce = next_ce; 286497bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe ce_from = from; 286597bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe } 286697bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe } 286797bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe} 286897bfa1905b957b46e8426db4a8aed9b4ee7f476ephilippe 28693c9cf3442185b5891e15450d6e3058aeff6796fetom 28703026f71684a930286186aa10fef266c304672e8fsewardj/* The main function for DWARF2/3 CFI-based stack unwinding. Given a 28713026f71684a930286186aa10fef266c304672e8fsewardj set of registers in UREGS, modify it to hold the register values 28723026f71684a930286186aa10fef266c304672e8fsewardj for the previous frame, if possible. Returns True if successful. 28733026f71684a930286186aa10fef266c304672e8fsewardj If not successful, *UREGS is not changed. 28743026f71684a930286186aa10fef266c304672e8fsewardj 28753026f71684a930286186aa10fef266c304672e8fsewardj For x86 and amd64, the unwound registers are: {E,R}IP, 28763026f71684a930286186aa10fef266c304672e8fsewardj {E,R}SP, {E,R}BP. 28773026f71684a930286186aa10fef266c304672e8fsewardj 2878fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj For arm, the unwound registers are: R7 R11 R12 R13 R14 R15. 2879821283b2110420321fd3f60afcc799b287788c68sewardj 2880821283b2110420321fd3f60afcc799b287788c68sewardj For arm64, the unwound registers are: X29(FP) X30(LR) SP PC. 28813026f71684a930286186aa10fef266c304672e8fsewardj*/ 28823026f71684a930286186aa10fef266c304672e8fsewardjBool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere, 28833c9cf3442185b5891e15450d6e3058aeff6796fetom Addr min_accessible, 28843c9cf3442185b5891e15450d6e3058aeff6796fetom Addr max_accessible ) 28853c9cf3442185b5891e15450d6e3058aeff6796fetom{ 28863c9cf3442185b5891e15450d6e3058aeff6796fetom DebugInfo* di; 28875c3dba227192de63d86f65ec7d9597c132818c37philippe DiCfSI_m* cfsi_m = NULL; 28883026f71684a930286186aa10fef266c304672e8fsewardj Addr cfa, ipHere = 0; 28895c3dba227192de63d86f65ec7d9597c132818c37philippe CFSI_m_CacheEnt* ce; 2890d2be8cc17fed04cbd701e9a2cc1cf365ff45cc44sewardj CfiExprEvalContext eec __attribute__((unused)); 28913026f71684a930286186aa10fef266c304672e8fsewardj D3UnwindRegs uregsPrev; 28923c9cf3442185b5891e15450d6e3058aeff6796fetom 28933026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 28943026f71684a930286186aa10fef266c304672e8fsewardj ipHere = uregsHere->xip; 28953026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_arm) 28963026f71684a930286186aa10fef266c304672e8fsewardj ipHere = uregsHere->r15; 2897b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGA_s390x) 2898b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj ipHere = uregsHere->ia; 28994df0bfc0614379192c780c944415dc420d9cfe8epetarj# elif defined(VGA_mips32) || defined(VGA_mips64) 29005db15403e889d4db339b342bc2a824ef0bfaa654sewardj ipHere = uregsHere->pc; 2901cae0cc22b83ffb260ee8379e92099c5a701944cbcarll# elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le) 2902f0c1250e324f6684757c6a15545366447ef1d64fsewardj# elif defined(VGP_arm64_linux) 2903821283b2110420321fd3f60afcc799b287788c68sewardj ipHere = uregsHere->pc; 2904112711afefcfcd43680c7c4aa8d38ef180e8811esewardj# elif defined(VGA_tilegx) 2905112711afefcfcd43680c7c4aa8d38ef180e8811esewardj ipHere = uregsHere->pc; 29063026f71684a930286186aa10fef266c304672e8fsewardj# else 29073026f71684a930286186aa10fef266c304672e8fsewardj# error "Unknown arch" 29083026f71684a930286186aa10fef266c304672e8fsewardj# endif 29095c3dba227192de63d86f65ec7d9597c132818c37philippe ce = cfsi_m_cache__find(ipHere); 29103c9cf3442185b5891e15450d6e3058aeff6796fetom 29113c9cf3442185b5891e15450d6e3058aeff6796fetom if (UNLIKELY(ce == NULL)) 29123c9cf3442185b5891e15450d6e3058aeff6796fetom return False; /* no info. Nothing we can do. */ 29133c9cf3442185b5891e15450d6e3058aeff6796fetom 29143c9cf3442185b5891e15450d6e3058aeff6796fetom di = ce->di; 29155c3dba227192de63d86f65ec7d9597c132818c37philippe cfsi_m = ce->cfsi_m; 29163c9cf3442185b5891e15450d6e3058aeff6796fetom 29173c9cf3442185b5891e15450d6e3058aeff6796fetom if (0) { 29185c3dba227192de63d86f65ec7d9597c132818c37philippe VG_(printf)("found cfsi_m (but printing fake base/len): "); 29195c3dba227192de63d86f65ec7d9597c132818c37philippe ML_(ppDiCfSI)(di->cfsi_exprs, 0, 0, cfsi_m); 29203c9cf3442185b5891e15450d6e3058aeff6796fetom } 29213c9cf3442185b5891e15450d6e3058aeff6796fetom 2922f7183e38d6215e98043ed014cb947cf5262bdc4asewardj VG_(bzero_inline)(&uregsPrev, sizeof(uregsPrev)); 29233c9cf3442185b5891e15450d6e3058aeff6796fetom 29243c9cf3442185b5891e15450d6e3058aeff6796fetom /* First compute the CFA. */ 29253026f71684a930286186aa10fef266c304672e8fsewardj cfa = compute_cfa(uregsHere, 29265c3dba227192de63d86f65ec7d9597c132818c37philippe min_accessible, max_accessible, di, cfsi_m); 29273c9cf3442185b5891e15450d6e3058aeff6796fetom if (UNLIKELY(cfa == 0)) 29283c9cf3442185b5891e15450d6e3058aeff6796fetom return False; 292972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 293072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /* Now we know the CFA, use it to roll back the registers we're 293172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj interested in. */ 2932eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2933eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define COMPUTE(_prev, _here, _how, _off) \ 2934eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj do { \ 2935eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj switch (_how) { \ 2936eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_UNKNOWN: \ 2937eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; \ 2938eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_SAME: \ 2939eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj _prev = _here; break; \ 2940eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_MEMCFAREL: { \ 2941eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Addr a = cfa + (Word)_off; \ 2942eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (a < min_accessible \ 29439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj || a > max_accessible-sizeof(Addr)) \ 2944eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; \ 294586781fabbfc019b752f9605e487cfce77b2a592atom _prev = ML_(read_Addr)((void *)a); \ 2946eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; \ 2947eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } \ 2948eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_CFAREL: \ 2949eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj _prev = cfa + (Word)_off; \ 2950eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; \ 295172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case CFIR_EXPR: \ 295272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (0) \ 2953f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj ML_(ppCfiExpr)(di->cfsi_exprs,_off); \ 29543026f71684a930286186aa10fef266c304672e8fsewardj eec.uregs = uregsHere; \ 295572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.min_accessible = min_accessible; \ 295672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.max_accessible = max_accessible; \ 2957d2be8cc17fed04cbd701e9a2cc1cf365ff45cc44sewardj Bool ok = True; \ 2958f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj _prev = evalCfiExpr(di->cfsi_exprs, _off, &eec, &ok ); \ 295972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!ok) return False; \ 296072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; \ 296172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: \ 296272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); \ 2963eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } \ 2964eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } while (0) 2965eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 29663026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 29675c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.xip, uregsHere->xip, cfsi_m->ra_how, cfsi_m->ra_off); 29685c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.xsp, uregsHere->xsp, cfsi_m->sp_how, cfsi_m->sp_off); 29695c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.xbp, uregsHere->xbp, cfsi_m->bp_how, cfsi_m->bp_off); 29703026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_arm) 29715c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r15, uregsHere->r15, cfsi_m->ra_how, cfsi_m->ra_off); 29725c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r14, uregsHere->r14, cfsi_m->r14_how, cfsi_m->r14_off); 29735c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r13, uregsHere->r13, cfsi_m->r13_how, cfsi_m->r13_off); 29745c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r12, uregsHere->r12, cfsi_m->r12_how, cfsi_m->r12_off); 29755c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r11, uregsHere->r11, cfsi_m->r11_how, cfsi_m->r11_off); 29765c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r7, uregsHere->r7, cfsi_m->r7_how, cfsi_m->r7_off); 2977b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGA_s390x) 29785c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.ia, uregsHere->ia, cfsi_m->ra_how, cfsi_m->ra_off); 29795c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off); 29805c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi_m->fp_how, cfsi_m->fp_off); 29814df0bfc0614379192c780c944415dc420d9cfe8epetarj# elif defined(VGA_mips32) || defined(VGA_mips64) 29825c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi_m->ra_how, cfsi_m->ra_off); 29835c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off); 29845c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi_m->fp_how, cfsi_m->fp_off); 2985cae0cc22b83ffb260ee8379e92099c5a701944cbcarll# elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le) 2986f0c1250e324f6684757c6a15545366447ef1d64fsewardj# elif defined(VGP_arm64_linux) 29875c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi_m->ra_how, cfsi_m->ra_off); 29885c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off); 29895c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.x30, uregsHere->x30, cfsi_m->x30_how, cfsi_m->x30_off); 29905c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.x29, uregsHere->x29, cfsi_m->x29_how, cfsi_m->x29_off); 2991112711afefcfcd43680c7c4aa8d38ef180e8811esewardj# elif defined(VGA_tilegx) 2992112711afefcfcd43680c7c4aa8d38ef180e8811esewardj COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi_m->ra_how, cfsi_m->ra_off); 2993112711afefcfcd43680c7c4aa8d38ef180e8811esewardj COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off); 2994112711afefcfcd43680c7c4aa8d38ef180e8811esewardj COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi_m->fp_how, cfsi_m->fp_off); 29953026f71684a930286186aa10fef266c304672e8fsewardj# else 29963026f71684a930286186aa10fef266c304672e8fsewardj# error "Unknown arch" 29973026f71684a930286186aa10fef266c304672e8fsewardj# endif 2998eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2999eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef COMPUTE 3000eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 30013026f71684a930286186aa10fef266c304672e8fsewardj *uregsHere = uregsPrev; 3002eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 3003eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3004eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3005eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3006b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 3007b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 3008c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/ 3009c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- MSVC FPO INFO ---*/ 3010c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- ---*/ 3011c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--------------------------------------------------------------*/ 3012c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3013c8259b85b701d25d72aabe9dc0a8154517f96913sewardjBool VG_(use_FPO_info) ( /*MOD*/Addr* ipP, 3014c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /*MOD*/Addr* spP, 3015c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /*MOD*/Addr* fpP, 3016c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Addr min_accessible, 3017c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Addr max_accessible ) 3018c8259b85b701d25d72aabe9dc0a8154517f96913sewardj{ 3019c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Word i; 30203297124fa2116737066ac3cd709f18fdd5405163florian const DebugInfo* di; 3021c8259b85b701d25d72aabe9dc0a8154517f96913sewardj FPO_DATA* fpo = NULL; 3022c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Addr spHere; 3023c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3024c8259b85b701d25d72aabe9dc0a8154517f96913sewardj static UWord n_search = 0; 3025c8259b85b701d25d72aabe9dc0a8154517f96913sewardj static UWord n_steps = 0; 3026c8259b85b701d25d72aabe9dc0a8154517f96913sewardj n_search++; 3027c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3028c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0) VG_(printf)("search FPO for %#lx\n", *ipP); 3029c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3030c8259b85b701d25d72aabe9dc0a8154517f96913sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 3031c8259b85b701d25d72aabe9dc0a8154517f96913sewardj n_steps++; 3032c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3033c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Use the per-DebugInfo summary address ranges to skip 3034c8259b85b701d25d72aabe9dc0a8154517f96913sewardj inapplicable DebugInfos quickly. */ 3035c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (di->fpo == NULL) 3036c8259b85b701d25d72aabe9dc0a8154517f96913sewardj continue; 3037c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (*ipP < di->fpo_minavma || *ipP > di->fpo_maxavma) 3038c8259b85b701d25d72aabe9dc0a8154517f96913sewardj continue; 3039c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3040c8259b85b701d25d72aabe9dc0a8154517f96913sewardj i = ML_(search_one_fpotab)( di, *ipP ); 3041c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (i != -1) { 3042c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Word j; 3043c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0) { 3044c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* debug printing only */ 3045c6e5d76e9eea8625f385ff844545c688c91938daflorian VG_(printf)("look for %#lx size %lu i %ld\n", 3046c8259b85b701d25d72aabe9dc0a8154517f96913sewardj *ipP, di->fpo_size, i); 3047c8259b85b701d25d72aabe9dc0a8154517f96913sewardj for (j = 0; j < di->fpo_size; j++) 3048c6e5d76e9eea8625f385ff844545c688c91938daflorian VG_(printf)("[%02ld] %#x %u\n", 3049c8259b85b701d25d72aabe9dc0a8154517f96913sewardj j, di->fpo[j].ulOffStart, di->fpo[j].cbProcSize); 3050c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 3051c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(i >= 0 && i < di->fpo_size); 3052c8259b85b701d25d72aabe9dc0a8154517f96913sewardj fpo = &di->fpo[i]; 3053c8259b85b701d25d72aabe9dc0a8154517f96913sewardj break; 3054c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 3055c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 3056c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3057c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (fpo == NULL) 3058c8259b85b701d25d72aabe9dc0a8154517f96913sewardj return False; 3059c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3060c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0 && ((n_search & 0x7FFFF) == 0)) 3061c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("VG_(use_FPO_info): %lu searches, " 3062c8259b85b701d25d72aabe9dc0a8154517f96913sewardj "%lu DebugInfos looked at\n", 3063c8259b85b701d25d72aabe9dc0a8154517f96913sewardj n_search, n_steps); 3064c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3065c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3066c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Start of performance-enhancing hack: once every 64 (chosen 3067c8259b85b701d25d72aabe9dc0a8154517f96913sewardj hackily after profiling) successful searches, move the found 3068c8259b85b701d25d72aabe9dc0a8154517f96913sewardj DebugInfo one step closer to the start of the list. This makes 3069c8259b85b701d25d72aabe9dc0a8154517f96913sewardj future searches cheaper. For starting konqueror on amd64, this 3070c8259b85b701d25d72aabe9dc0a8154517f96913sewardj in fact reduces the total amount of searching done by the above 3071c8259b85b701d25d72aabe9dc0a8154517f96913sewardj find-the-right-DebugInfo loop by more than a factor of 20. */ 3072c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if ((n_search & 0x3F) == 0) { 3073c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Move si one step closer to the start of the list. */ 3074c8259b85b701d25d72aabe9dc0a8154517f96913sewardj //move_DebugInfo_one_step_forward( di ); 3075c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 3076c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* End of performance-enhancing hack. */ 3077c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3078c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0) { 3079c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("found fpo: "); 3080c8259b85b701d25d72aabe9dc0a8154517f96913sewardj //ML_(ppFPO)(fpo); 3081c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 3082c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3083c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* 3084c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Stack layout is: 3085c8259b85b701d25d72aabe9dc0a8154517f96913sewardj %esp-> 3086c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 4*.cbRegs {%edi, %esi, %ebp, %ebx} 3087c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 4*.cdwLocals 3088c8259b85b701d25d72aabe9dc0a8154517f96913sewardj return_pc 3089c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 4*.cdwParams 3090c8259b85b701d25d72aabe9dc0a8154517f96913sewardj prior_%esp-> 3091c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3092c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Typical code looks like: 3093c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sub $4*.cdwLocals,%esp 3094c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Alternative to above for >=4KB (and sometimes for smaller): 3095c8259b85b701d25d72aabe9dc0a8154517f96913sewardj mov $size,%eax 3096c8259b85b701d25d72aabe9dc0a8154517f96913sewardj call __chkstk # WinNT performs page-by-page probe! 3097c8259b85b701d25d72aabe9dc0a8154517f96913sewardj __chkstk is much like alloc(), except that on return 3098c8259b85b701d25d72aabe9dc0a8154517f96913sewardj %eax= 5+ &CALL. Thus it could be used as part of 3099c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Position Independent Code to locate the Global Offset Table. 3100c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %ebx 3101c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %ebp 3102c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %esi 3103c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Other once-only instructions often scheduled >here<. 3104c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %edi 3105c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3106c8259b85b701d25d72aabe9dc0a8154517f96913sewardj If the pc is within the first .cbProlog bytes of the function, 3107c8259b85b701d25d72aabe9dc0a8154517f96913sewardj then you must disassemble to see how many registers have been pushed, 3108c8259b85b701d25d72aabe9dc0a8154517f96913sewardj because instructions in the prolog may be scheduled for performance. 3109c8259b85b701d25d72aabe9dc0a8154517f96913sewardj The order of PUSH is always %ebx, %ebp, %esi, %edi, with trailing 3110c8259b85b701d25d72aabe9dc0a8154517f96913sewardj registers not pushed when .cbRegs < 4. This seems somewhat strange 3111c8259b85b701d25d72aabe9dc0a8154517f96913sewardj because %ebp is the register whose usage you want to minimize, 3112c8259b85b701d25d72aabe9dc0a8154517f96913sewardj yet it is in the first half of the PUSH list. 3113c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3114c8259b85b701d25d72aabe9dc0a8154517f96913sewardj I don't know what happens when the compiler constructs an outgoing CALL. 3115c8259b85b701d25d72aabe9dc0a8154517f96913sewardj %esp could move if outgoing parameters are PUSHed, and this affects 3116c8259b85b701d25d72aabe9dc0a8154517f96913sewardj traceback for errors during the PUSHes. */ 3117c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3118c8259b85b701d25d72aabe9dc0a8154517f96913sewardj spHere = *spP; 3119c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 312086781fabbfc019b752f9605e487cfce77b2a592atom *ipP = ML_(read_Addr)((void *)(spHere + 4*(fpo->cbRegs + fpo->cdwLocals))); 312186781fabbfc019b752f9605e487cfce77b2a592atom *spP = spHere + 4*(fpo->cbRegs + fpo->cdwLocals + 1 312286781fabbfc019b752f9605e487cfce77b2a592atom + fpo->cdwParams); 312386781fabbfc019b752f9605e487cfce77b2a592atom *fpP = ML_(read_Addr)((void *)(spHere + 4*2)); 3124c8259b85b701d25d72aabe9dc0a8154517f96913sewardj return True; 3125c8259b85b701d25d72aabe9dc0a8154517f96913sewardj} 3126c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3127f7bbd7982397fb73477bdc21bf236cf9100cee44philippeBool VG_(FPO_info_present)(void) 3128f7bbd7982397fb73477bdc21bf236cf9100cee44philippe{ 3129f7bbd7982397fb73477bdc21bf236cf9100cee44philippe const DebugInfo* di; 3130f7bbd7982397fb73477bdc21bf236cf9100cee44philippe for (di = debugInfo_list; di != NULL; di = di->next) { 3131f7bbd7982397fb73477bdc21bf236cf9100cee44philippe if (di->fpo != NULL) 3132f7bbd7982397fb73477bdc21bf236cf9100cee44philippe return True; 3133f7bbd7982397fb73477bdc21bf236cf9100cee44philippe } 3134f7bbd7982397fb73477bdc21bf236cf9100cee44philippe return False; 3135f7bbd7982397fb73477bdc21bf236cf9100cee44philippe} 3136f7bbd7982397fb73477bdc21bf236cf9100cee44philippe 3137c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3138c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--------------------------------------------------------------*/ 3139c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- ---*/ 3140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- TOP LEVEL: GENERATE DESCRIPTION OF DATA ADDRESSES ---*/ 3141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- FROM DWARF3 DEBUG INFO ---*/ 3142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 3143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 3144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3145588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj/* Try to make p2XA(dst, fmt, args..) turn into 3146b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart VG_(xaprintf)(dst, fmt, args) without having to resort to 3147588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj vararg macros. As usual with everything to do with varargs, it's 3148588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj an ugly hack. 3149738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3150588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj //#define p2XA(dstxa, format, args...) 3151b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart // VG_(xaprintf)(dstxa, format, ##args) 3152738856f99eea33d86ce91dcb1d6cd5b151e307casewardj*/ 3153b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart#define p2XA VG_(xaprintf) 3154738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3155588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj/* Add a zero-terminating byte to DST, which must be an XArray* of 3156588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj HChar. */ 3157738856f99eea33d86ce91dcb1d6cd5b151e307casewardjstatic void zterm_XA ( XArray* dst ) 3158738856f99eea33d86ce91dcb1d6cd5b151e307casewardj{ 3159738856f99eea33d86ce91dcb1d6cd5b151e307casewardj HChar zero = 0; 3160738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (void) VG_(addBytesToXA)( dst, &zero, 1 ); 3161738856f99eea33d86ce91dcb1d6cd5b151e307casewardj} 3162738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3163738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Evaluate the location expression/list for var, to see whether or 3165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj not data_addr falls within the variable. If so also return the 3166b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset of data_addr from the start of the variable. Note that 3167b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs, which supplies ip,sp,fp values, will be NULL for global 3168b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj variables, and non-NULL for local variables. */ 3169c4431bfe04c7490ea2d74939d222d87f13f30960njnstatic Bool data_address_is_in_var ( /*OUT*/PtrdiffT* offset, 31703297124fa2116737066ac3cd709f18fdd5405163florian const XArray* /* TyEnt */ tyents, 31713297124fa2116737066ac3cd709f18fdd5405163florian const DiVariable* var, 31723297124fa2116737066ac3cd709f18fdd5405163florian const RegSummary* regs, 31733297124fa2116737066ac3cd709f18fdd5405163florian Addr data_addr, 3174588658b13b5ad77672f323d48fe9da0ca60b0bcbtom const DebugInfo* di ) 3175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 317650fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 3177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj SizeT var_szB; 3178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj GXResult res; 3179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool show = False; 31809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 3181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->name); 3182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->gexpr); 3183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Figure out how big the variable is. */ 318550fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(tyents, var->typeR); 318650fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 318750fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. ML_(addVar) 318850fde23467d92281b32dd537d0d9a590263628c3sewardj should have rejected it. */ 318950fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 319050fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 319150fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 319250fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a host word 319350fde23467d92281b32dd537d0d9a590263628c3sewardj safely (without loss of info). */ 319450fde23467d92281b32dd537d0d9a590263628c3sewardj 319550fde23467d92281b32dd537d0d9a590263628c3sewardj var_szB = (SizeT)mul.ul; /* NB: truncate to host word */ 3196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) { 3198a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("VVVV: data_address_%#lx_is_in_var: %s :: ", 3199b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var->name ); 32009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(pp_TyEnt_C_ishly)( tyents, var->typeR ); 3201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("\n"); 3202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3204b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ignore zero-sized vars; they can never match anything. */ 3205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (var_szB == 0) { 3206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) 3207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("VVVV: -> Fail (variable is zero sized)\n"); 3208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3211588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_GX)( var->gexpr, var->fbGX, regs, di ); 3212b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) { 3214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("VVVV: -> "); 3215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(pp_GXResult)( res ); 3216b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("\n"); 3217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3218eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 32193c9cf3442185b5891e15450d6e3058aeff6796fetom if (res.kind == GXR_Addr 3220b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && res.word <= data_addr 3221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && data_addr < res.word + var_szB) { 3222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *offset = data_addr - res.word; 3223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 3225b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3226b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3227b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 3228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3229b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3230738856f99eea33d86ce91dcb1d6cd5b151e307casewardj/* Format the acquired information into DN(AME)1 and DN(AME)2, which 3231738856f99eea33d86ce91dcb1d6cd5b151e307casewardj are XArray*s of HChar, that have been initialised by the caller. 3232738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Resulting strings will be zero terminated. Information is 3233738856f99eea33d86ce91dcb1d6cd5b151e307casewardj formatted in an understandable way. Not so easy. If frameNo is 3234738856f99eea33d86ce91dcb1d6cd5b151e307casewardj -1, this is assumed to be a global variable; else a local 3235738856f99eea33d86ce91dcb1d6cd5b151e307casewardj variable. */ 3236738856f99eea33d86ce91dcb1d6cd5b151e307casewardjstatic void format_message ( /*MOD*/XArray* /* of HChar */ dn1, 3237738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /*MOD*/XArray* /* of HChar */ dn2, 3238b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 3239518850bf0da07ed3e2244e307268ae0fd80e93a8florian const DebugInfo* di, 3240518850bf0da07ed3e2244e307268ae0fd80e93a8florian const DiVariable* var, 3241c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT var_offset, 3242c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT residual_offset, 3243518850bf0da07ed3e2244e307268ae0fd80e93a8florian const XArray* /*HChar*/ described, 3244b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int frameNo, 3245b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid ) 3246eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3247738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Bool have_descr, have_srcloc; 3248738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Bool xml = VG_(clo_xml); 32491636d33c13958b9c0e7d3059cdd5005746418eb2florian const HChar* vo_plural = var_offset == 1 ? "" : "s"; 32501636d33c13958b9c0e7d3059cdd5005746418eb2florian const HChar* ro_plural = residual_offset == 1 ? "" : "s"; 32511636d33c13958b9c0e7d3059cdd5005746418eb2florian const HChar* basetag = "auxwhat"; /* a constant */ 32521636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar tagL[32], tagR[32], xagL[32], xagR[32]; 3253666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe const HChar *fileName = ML_(fndn_ix2filename)(di, var->fndn_ix); 3254666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe // fileName will be "???" if var->fndn_ix == 0. 3255666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe // fileName will only be used if have_descr is True. 3256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3257d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj if (frameNo < -1) { 3258d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj vg_assert(0); /* Not allowed */ 3259d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj } 3260d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj else if (frameNo == -1) { 3261d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj vg_assert(tid == VG_INVALID_THREADID); 3262d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj } 3263d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj else /* (frameNo >= 0) */ { 3264d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj vg_assert(tid != VG_INVALID_THREADID); 3265d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj } 3266d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj 3267738856f99eea33d86ce91dcb1d6cd5b151e307casewardj vg_assert(dn1 && dn2); 3268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(described); 3269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var && var->name); 3270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj have_descr = VG_(sizeXA)(described) > 0 3271d6b9fcc80e248211dc9cf888a768a49fa1091522florian && *(HChar*)VG_(indexXA)(described,0) != '\0'; 3272666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe have_srcloc = var->fndn_ix > 0 && var->lineNo > 0; 3273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3274738856f99eea33d86ce91dcb1d6cd5b151e307casewardj tagL[0] = tagR[0] = xagL[0] = xagR[0] = 0; 3275738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3276738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(tagL, "<%s>", basetag); // <auxwhat> 3277738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(tagR, "</%s>", basetag); // </auxwhat> 3278738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(xagL, "<x%s>", basetag); // <xauxwhat> 3279738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(xagR, "</x%s>", basetag); // </xauxwhat> 3280738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3281738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3282738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TAGL(_xa) p2XA(_xa, "%s", tagL) 3283738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TAGR(_xa) p2XA(_xa, "%s", tagR) 3284738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define XAGL(_xa) p2XA(_xa, "%s", xagL) 3285738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define XAGR(_xa) p2XA(_xa, "%s", xagR) 3286738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TXTL(_xa) p2XA(_xa, "%s", "<text>") 3287738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TXTR(_xa) p2XA(_xa, "%s", "</text>") 3288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3289b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ------ local cases ------ */ 3290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && (!have_srcloc) && (!have_descr) ) { 3292b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc, no description: 3293b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside local var "a", 3294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in frame #1 of thread 1 3295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3296738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3297738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3298738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3299c6e5d76e9eea8625f385ff844545c688c91938daflorian "Location 0x%lx is %ld byte%s inside local var \"%pS\",", 3300738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3301738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3302738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn2 ); 3303738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3304c6e5d76e9eea8625f385ff844545c688c91938daflorian "in frame #%d of thread %u", frameNo, tid ); 3305738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn2 ); 3306738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3307738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3308c6e5d76e9eea8625f385ff844545c688c91938daflorian "Location 0x%lx is %ld byte%s inside local var \"%s\",", 3309738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3310738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3311c6e5d76e9eea8625f385ff844545c688c91938daflorian "in frame #%d of thread %u", frameNo, tid ); 3312738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && have_srcloc && (!have_descr) ) { 3316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no description: 3317b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside local var "a" 3318b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj declared at dsyms7.c:17, in frame #1 of thread 1 3319b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3320738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3321738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3322738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3323c6e5d76e9eea8625f385ff844545c688c91938daflorian "Location 0x%lx is %ld byte%s inside local var \"%pS\"", 3324738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3325738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3326738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 3327738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 3328738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3329c6e5d76e9eea8625f385ff844545c688c91938daflorian "declared at %pS:%d, in frame #%d of thread %u", 3330c6e5d76e9eea8625f385ff844545c688c91938daflorian fileName, var->lineNo, frameNo, tid ); 3331738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 3332738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 3333738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3334b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart " <file>%pS</file> <line>%d</line> ", 3335666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo ); 3336738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 3337738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3338738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3339c6e5d76e9eea8625f385ff844545c688c91938daflorian "Location 0x%lx is %ld byte%s inside local var \"%s\"", 3340738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3341738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3342c6e5d76e9eea8625f385ff844545c688c91938daflorian "declared at %s:%d, in frame #%d of thread %u", 3343c6e5d76e9eea8625f385ff844545c688c91938daflorian fileName, var->lineNo, frameNo, tid ); 3344738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3345b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && (!have_srcloc) && have_descr ) { 3348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc: 3349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2 3350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in frame #1 of thread 1 3351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3352738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3353738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3354738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3355c6e5d76e9eea8625f385ff844545c688c91938daflorian "Location 0x%lx is %ld byte%s inside %pS%pS", 3356738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3357738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3358738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3359738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn2 ); 3360738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3361c6e5d76e9eea8625f385ff844545c688c91938daflorian "in frame #%d of thread %u", frameNo, tid ); 3362738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn2 ); 3363738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3364738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3365c6e5d76e9eea8625f385ff844545c688c91938daflorian "Location 0x%lx is %ld byte%s inside %s%s", 3366738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3367738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3368738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3369c6e5d76e9eea8625f385ff844545c688c91938daflorian "in frame #%d of thread %u", frameNo, tid ); 3370738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && have_srcloc && have_descr ) { 3374738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 3375738856f99eea33d86ce91dcb1d6cd5b151e307casewardj declared at dsyms7.c:17, in frame #1 of thread 1 */ 3376738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3377738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3378738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3379c6e5d76e9eea8625f385ff844545c688c91938daflorian "Location 0x%lx is %ld byte%s inside %pS%pS,", 3380738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3381738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3382738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3383738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 3384738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 3385738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3386c6e5d76e9eea8625f385ff844545c688c91938daflorian "declared at %pS:%d, in frame #%d of thread %u", 3387c6e5d76e9eea8625f385ff844545c688c91938daflorian fileName, var->lineNo, frameNo, tid ); 3388738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 3389738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 3390738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3391b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart " <file>%pS</file> <line>%d</line> ", 3392666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo ); 3393738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 3394738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3395738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3396c6e5d76e9eea8625f385ff844545c688c91938daflorian "Location 0x%lx is %ld byte%s inside %s%s,", 3397738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3398738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3399738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3400c6e5d76e9eea8625f385ff844545c688c91938daflorian "declared at %s:%d, in frame #%d of thread %u", 3401c6e5d76e9eea8625f385ff844545c688c91938daflorian fileName, var->lineNo, frameNo, tid ); 3402738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ------ global cases ------ */ 3406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && (!have_srcloc) && (!have_descr) ) { 3407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc, no description: 3408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside global var "a" 3409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3410738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3411738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3412738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3413c6e5d76e9eea8625f385ff844545c688c91938daflorian "Location 0x%lx is %ld byte%s inside global var \"%pS\"", 3414738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3415738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3416738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3417738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3418c6e5d76e9eea8625f385ff844545c688c91938daflorian "Location 0x%lx is %ld byte%s inside global var \"%s\"", 3419738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3420738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && have_srcloc && (!have_descr) ) { 3424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no description: 3425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside global var "a" 3426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj declared at dsyms7.c:17 3427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3428738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3429738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3430738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3431c6e5d76e9eea8625f385ff844545c688c91938daflorian "Location 0x%lx is %ld byte%s inside global var \"%pS\"", 3432738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3433738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3434738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 3435738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 3436738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3437b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "declared at %pS:%d", 3438666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo); 3439738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 3440738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 3441738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3442b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart " <file>%pS</file> <line>%d</line> ", 3443666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo ); 3444738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 3445738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3446738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3447c6e5d76e9eea8625f385ff844545c688c91938daflorian "Location 0x%lx is %ld byte%s inside global var \"%s\"", 3448738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3449738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3450738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "declared at %s:%d", 3451666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo); 3452738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && (!have_srcloc) && have_descr ) { 3456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc: 3457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 3458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj a global variable 3459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3460738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3461738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3462738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3463c6e5d76e9eea8625f385ff844545c688c91938daflorian "Location 0x%lx is %ld byte%s inside %pS%pS,", 3464738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3465738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3466738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3467738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn2 ); 3468738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3469738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "a global variable"); 3470738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn2 ); 3471738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3472738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3473c6e5d76e9eea8625f385ff844545c688c91938daflorian "Location 0x%lx is %ld byte%s inside %s%s,", 3474738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3475c6e5d76e9eea8625f385ff844545c688c91938daflorian (HChar*)(VG_(indexXA)(described,0)) ); 3476738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3477738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "a global variable"); 3478738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3479b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && have_srcloc && have_descr ) { 3482738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 3483738856f99eea33d86ce91dcb1d6cd5b151e307casewardj a global variable declared at dsyms7.c:17 */ 3484738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3485738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3486738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3487c6e5d76e9eea8625f385ff844545c688c91938daflorian "Location 0x%lx is %ld byte%s inside %pS%pS,", 3488738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3489738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3490738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3491738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 3492738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 3493738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3494b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "a global variable declared at %pS:%d", 3495666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo); 3496738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 3497738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 3498738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3499b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart " <file>%pS</file> <line>%d</line> ", 3500666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo ); 3501738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 3502738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3503738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3504c6e5d76e9eea8625f385ff844545c688c91938daflorian "Location 0x%lx is %ld byte%s inside %s%s,", 3505738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3506738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3507738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3508738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "a global variable declared at %s:%d", 3509666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo); 3510738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3511b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3512b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3513b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(0); 3514b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3515738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /* Zero terminate both strings */ 3516738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dn1 ); 3517738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dn2 ); 3518738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3519738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TAGL 3520738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TAGR 3521738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef XAGL 3522738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef XAGR 3523738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TXTL 3524738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TXTR 3525eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3526eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3527738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3528b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Determine if data_addr is a local variable in the frame 3529738856f99eea33d86ce91dcb1d6cd5b151e307casewardj characterised by (ip,sp,fp), and if so write its description at the 3530738856f99eea33d86ce91dcb1d6cd5b151e307casewardj ends of DNAME{1,2}, which are XArray*s of HChar, that have been 3531738856f99eea33d86ce91dcb1d6cd5b151e307casewardj initialised by the caller, zero terminate both, and return True. 3532738856f99eea33d86ce91dcb1d6cd5b151e307casewardj If it's not a local variable in said frame, return False. */ 3533b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic 3534738856f99eea33d86ce91dcb1d6cd5b151e307casewardjBool consider_vars_in_frame ( /*MOD*/XArray* /* of HChar */ dname1, 3535738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /*MOD*/XArray* /* of HChar */ dname2, 3536b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 3537b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr ip, Addr sp, Addr fp, 3538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* shown to user: */ 3539b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid, Int frameNo ) 3540eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3541b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word i; 3542b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 3543b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj RegSummary regs; 3544b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool debug = False; 3545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3546b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj static UInt n_search = 0; 3547b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj static UInt n_steps = 0; 3548b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_search++; 3549b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 3550a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("QQQQ: cvif: ip,sp,fp %#lx,%#lx,%#lx\n", ip,sp,fp); 3551b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* first, find the DebugInfo that pertains to 'ip'. */ 3552b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di; di = di->next) { 3553b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_steps++; 3554b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* text segment missing? unlikely, but handle it .. */ 3555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->text_present || di->text_size == 0) 3556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3557b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok. So does this text mapping bracket the ip? */ 3558b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_avma <= ip && ip < di->text_avma + di->text_size) 3559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3561b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3562b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Didn't find it. Strange -- means ip is a code address outside 3563b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj of any mapped text segment. Unlikely but not impossible -- app 3564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj could be generating code to run. */ 3565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di) 3566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3567b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3568b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0 && ((n_search & 0x1) == 0)) 3569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("consider_vars_in_frame: %u searches, " 3570b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "%u DebugInfos looked at\n", 3571b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_search, n_steps); 3572b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Start of performance-enhancing hack: once every ??? (chosen 3573b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj hackily after profiling) successful searches, move the found 3574b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo one step closer to the start of the list. This makes 3575b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj future searches cheaper. */ 3576b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ((n_search & 0xFFFF) == 0) { 3577b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Move si one step closer to the start of the list. */ 3578b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj move_DebugInfo_one_step_forward( di ); 3579b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3580b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* End of performance-enhancing hack. */ 3581b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3582b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* any var info at all? */ 3583b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->varinfo) 3584b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3585b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3586b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Work through the scopes from most deeply nested outwards, 3587b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj looking for code address ranges that bracket 'ip'. The 3588b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj variables on each such address range found are in scope right 3589b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj now. Don't descend to level zero as that is the global 3590b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj scope. */ 3591b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.ip = ip; 3592b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.sp = sp; 3593b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.fp = fp; 3594b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3595b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* "for each scope, working outwards ..." */ 3596b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) { 3597b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* vars; 3598b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word j; 3599b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* arange; 3600b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* this_scope 3601b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj = *(OSet**)VG_(indexXA)( di->varinfo, i ); 3602b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 3603b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("QQQQ: considering scope %ld\n", (Word)i); 3604b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!this_scope) 3605b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3606b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Find the set of variables in this scope that 3607b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj bracket the program counter. */ 3608b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj arange = VG_(OSetGen_LookupWithCmp)( 3609b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj this_scope, &ip, 3610b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(cmp_for_DiAddrRange_range) 3611b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ); 3612b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!arange) 3613b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* stay sane */ 3615b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->aMin <= arange->aMax); 3616b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* It must bracket the ip we asked for, else 3617b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(cmp_for_DiAddrRange_range) is somehow broken. */ 3618b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->aMin <= ip && ip <= arange->aMax); 3619b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* It must have an attached XArray of DiVariables. */ 3620b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vars = arange->vars; 3621b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(vars); 3622b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* But it mustn't cover the entire address range. We only 3623b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj expect that to happen for the global scope (level 0), which 3624b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj we're not looking at here. Except, it may cover the entire 3625b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj address range, but in that case the vars array must be 3626b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj empty. */ 3627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(! (arange->aMin == (Addr)0 3628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && arange->aMax == ~(Addr)0 3629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && VG_(sizeXA)(vars) > 0) ); 3630b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < VG_(sizeXA)( vars ); j++) { 3631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j ); 3632c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT offset; 3633b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 3634a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n", 3635b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var->name,arange->aMin,arange->aMax,ip); 36369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (data_address_is_in_var( &offset, di->admin_tyents, 36379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var, ®s, 3638588658b13b5ad77672f323d48fe9da0ca60b0bcbtom data_addr, di )) { 3639c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT residual_offset = 0; 3640b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* described = ML_(describe_type)( &residual_offset, 36419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->admin_tyents, 36429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR, offset ); 3643738856f99eea33d86ce91dcb1d6cd5b151e307casewardj format_message( dname1, dname2, 3644666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe data_addr, di, var, offset, residual_offset, 3645b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj described, frameNo, tid ); 3646b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)( described ); 3647b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3648b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3649b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3650b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3651b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3652b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3653eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3654eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3655738856f99eea33d86ce91dcb1d6cd5b151e307casewardj/* Try to form some description of DATA_ADDR by looking at the DWARF3 365625963376a3669e7f77395d6f884bdf1f6a928966philippe debug info we have. This considers all global variables, and 8 3657738856f99eea33d86ce91dcb1d6cd5b151e307casewardj frames in the stacks of all threads. Result is written at the ends 3658738856f99eea33d86ce91dcb1d6cd5b151e307casewardj of DNAME{1,2}V, which are XArray*s of HChar, that have been 3659738856f99eea33d86ce91dcb1d6cd5b151e307casewardj initialised by the caller, and True is returned. If no description 3660738856f99eea33d86ce91dcb1d6cd5b151e307casewardj is created, False is returned. Regardless of the return value, 3661738856f99eea33d86ce91dcb1d6cd5b151e307casewardj DNAME{1,2}V are guaranteed to be zero terminated after the call. 3662738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3663738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Note that after the call, DNAME{1,2} may have more than one 3664738856f99eea33d86ce91dcb1d6cd5b151e307casewardj trailing zero, so callers should establish the useful text length 3665738856f99eea33d86ce91dcb1d6cd5b151e307casewardj using VG_(strlen) on the contents, rather than VG_(sizeXA) on the 3666738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XArray itself. 3667738856f99eea33d86ce91dcb1d6cd5b151e307casewardj*/ 3668738856f99eea33d86ce91dcb1d6cd5b151e307casewardjBool VG_(get_data_description)( 366909a8b1491c62d8e70575eb85da4875d9a07fd20eflorian /*MOD*/ XArray* /* of HChar */ dname1, 367009a8b1491c62d8e70575eb85da4875d9a07fd20eflorian /*MOD*/ XArray* /* of HChar */ dname2, 3671738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Addr data_addr 3672738856f99eea33d86ce91dcb1d6cd5b151e307casewardj ) 3673eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3674b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# define N_FRAMES 8 3675b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr ips[N_FRAMES], sps[N_FRAMES], fps[N_FRAMES]; 3676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj UInt n_frames; 3677b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3678b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr stack_min, stack_max; 3679b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid; 3680b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool found; 3681b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 3682b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word j; 3683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3684a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart if (0) VG_(printf)("get_data_description: dataaddr %#lx\n", data_addr); 3685b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* First, see if data_addr is (or is part of) a global variable. 3686b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Loop over the DebugInfos we have. Check data_addr against the 3687b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj outermost scope of all of them, as that should be a global 3688b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj scope. */ 3689b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 3690b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* global_scope; 36919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word gs_size; 3692b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr zero; 3693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* global_arange; 3694b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word i; 3695b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* vars; 3696b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3697b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* text segment missing? unlikely, but handle it .. */ 3698b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->text_present || di->text_size == 0) 3699b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3700b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* any var info at all? */ 3701b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->varinfo) 3702b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3703b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* perhaps this object didn't contribute any vars at all? */ 3704b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (VG_(sizeXA)( di->varinfo ) == 0) 3705b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3706b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj global_scope = *(OSet**)VG_(indexXA)( di->varinfo, 0 ); 3707b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_scope); 3708b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj gs_size = VG_(OSetGen_Size)( global_scope ); 3709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* The global scope might be completely empty if this 3710b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj compilation unit declared locals but nothing global. */ 3711b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (gs_size == 0) 3712b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3713b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* But if it isn't empty, then it must contain exactly one 3714b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj element, which covers the entire address range. */ 3715b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(gs_size == 1); 3716b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Fish out the global scope and check it is as expected. */ 3717b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj zero = 0; 3718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj global_arange 3719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj = VG_(OSetGen_Lookup)( global_scope, &zero ); 3720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* The global range from (Addr)0 to ~(Addr)0 must exist */ 3721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_arange); 3722b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_arange->aMin == (Addr)0 3723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && global_arange->aMax == ~(Addr)0); 3724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Any vars in this range? */ 3725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!global_arange->vars) 3726b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3727b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok, there are some vars in the global scope of this 3728b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo. Wade through them and see if the data addresses 3729b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj of any of them bracket data_addr. */ 3730b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vars = global_arange->vars; 3731b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = 0; i < VG_(sizeXA)( vars ); i++) { 3732c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT offset; 3733b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, i ); 3734b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->name); 3735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Note we use a NULL RegSummary* here. It can't make any 3736b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sense for a global variable to have a location expression 3737b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which depends on a SP/FP/IP value. So don't supply any. 3738b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj This means, if the evaluation of the location 3739b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj expression/list requires a register, we have to let it 3740b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj fail. */ 37419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (data_address_is_in_var( &offset, di->admin_tyents, var, 3742b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj NULL/* RegSummary* */, 3743588658b13b5ad77672f323d48fe9da0ca60b0bcbtom data_addr, di )) { 3744c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT residual_offset = 0; 3745b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* described = ML_(describe_type)( &residual_offset, 37469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->admin_tyents, 37479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR, offset ); 3748738856f99eea33d86ce91dcb1d6cd5b151e307casewardj format_message( dname1, dname2, 3749666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe data_addr, di, var, offset, residual_offset, 3750d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj described, -1/*frameNo*/, 3751d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj VG_INVALID_THREADID ); 3752b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)( described ); 3753738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3754738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3755b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3756b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3757b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3758b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3759b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3760b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok, well it's not a global variable. So now let's snoop around 3761b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in the stacks of all the threads. First try to figure out which 3762b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj thread's stack data_addr is in. */ 3763b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3764b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Perhaps it's on a thread's stack? */ 3765b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj found = False; 3766b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(thread_stack_reset_iter)(&tid); 3767b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) { 3768b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (stack_min >= stack_max) 3769b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; /* ignore obviously stupid cases */ 3770b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (stack_min - VG_STACK_REDZONE_SZB <= data_addr 3771b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && data_addr <= stack_max) { 3772b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj found = True; 3773b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3774b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3775b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3776b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!found) { 3777738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3778738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3779b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3780b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3781b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3782b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We conclude data_addr is in thread tid's stack. Unwind the 3783b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj stack to get a bunch of (ip,sp,fp) triples describing the 3784b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj frames, and for each frame, consider the local variables. */ 3785b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_frames = VG_(get_StackTrace)( tid, ips, N_FRAMES, 3786b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sps, fps, 0/*first_ip_delta*/ ); 3787b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj 3788b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_frames >= 0 && n_frames <= N_FRAMES); 3789b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < n_frames; j++) { 3790738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (consider_vars_in_frame( dname1, dname2, 3791b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, 3792b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj ips[j], 3793b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sps[j], fps[j], tid, j )) { 3794738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3795738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3796b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3797b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3798b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Now, it appears that gcc sometimes appears to produce 3799b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj location lists whose ranges don't actually cover the call 3800b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj instruction, even though the address of the variable in 3801b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj question is passed as a parameter in the call. AFAICS this 3802b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is simply a bug in gcc - how can the variable be claimed not 3803b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj exist in memory (on the stack) for the duration of a call in 3804b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which its address is passed? But anyway, in the particular 3805b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case I investigated (memcheck/tests/varinfo6.c, call to croak 3806b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj on line 2999, local var budget declared at line 3115 3807b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj appearing not to exist across the call to mainSort on line 3808b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3143, "gcc.orig (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2)" on 3809b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj amd64), the variable's location list does claim it exists 3810b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj starting at the first byte of the first instruction after the 3811b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj call instruction. So, call consider_vars_in_frame a second 3812b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj time, but this time add 1 to the IP. GDB handles this 3813b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj example with no difficulty, which leads me to believe that 3814b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj either (1) I misunderstood something, or (2) GDB has an 3815b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj equivalent kludge. */ 3816b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj if (j > 0 /* this is a non-innermost frame */ 3817738856f99eea33d86ce91dcb1d6cd5b151e307casewardj && consider_vars_in_frame( dname1, dname2, 3818b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj data_addr, 3819b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj ips[j] + 1, 3820b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj sps[j], fps[j], tid, j )) { 3821738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3822738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3823b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3824b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3825b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3826b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3827b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We didn't find anything useful. */ 3828738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3829738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3830b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3831b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# undef N_FRAMES 3832eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3833eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3834b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 38359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj////////////////////////////////////////////////////////////////// 38369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// // 38379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// Support for other kinds of queries to the Dwarf3 var info // 38389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// // 38399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj////////////////////////////////////////////////////////////////// 38409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Figure out if the variable 'var' has a location that is linearly 38429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj dependent on a stack pointer value, or a frame pointer value, and 38439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if it is, add a description of it to 'blocks'. Otherwise ignore 38449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. If 'arrays_only' is True, also ignore it unless it has an 38459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj array type. */ 38469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic 38489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks, 38493297124fa2116737066ac3cd709f18fdd5405163florian const XArray* /* TyEnt */ tyents, 38503297124fa2116737066ac3cd709f18fdd5405163florian Addr ip, const DebugInfo* di, const DiVariable* var, 38519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool arrays_only ) 38529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 38539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res_sp_6k, res_sp_7k, res_fp_6k, res_fp_7k; 38549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj RegSummary regs; 385550fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 38569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool isVec; 38579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ty; 38589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool debug = False; 38609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0&&debug) 38619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("adeps: var %s\n", var->name ); 38629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Figure out how big the variable is. */ 386450fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(tyents, var->typeR); 386550fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 386650fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. ML_(addVar) 386750fde23467d92281b32dd537d0d9a590263628c3sewardj should have rejected it. */ 386850fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 386950fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 387050fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 387150fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a host word 387250fde23467d92281b32dd537d0d9a590263628c3sewardj safely (without loss of info). */ 38739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* skip if non-array and we're only interested in arrays */ 38759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ty = ML_(TyEnts__index_by_cuOff)( tyents, NULL, var->typeR ); 38769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty); 38779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty)); 38789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (ty->tag == Te_UNKNOWN) 38799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return; /* perhaps we should complain in this case? */ 38809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj isVec = ty->tag == Te_TyArray; 38819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (arrays_only && !isVec) 38829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return; 38839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) {ML_(pp_TyEnt_C_ishly)(tyents, var->typeR); 38859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)(" %s\n", var->name);} 38869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Do some test evaluations of the variable's location expression, 38889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj in order to guess whether it is sp-relative, fp-relative, or 38899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj none. A crude hack, which can be interpreted roughly as finding 38909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj the first derivative of the location expression w.r.t. the 38919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj supplied frame and stack pointer values. */ 38929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 0; 38939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 38949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 6 * 1024; 3895588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_sp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 38969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 0; 38989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 38999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 7 * 1024; 3900588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_sp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 39019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 6 * 1024; 39039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 39049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 0; 3905588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_fp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 39069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 7 * 1024; 39089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 39099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 0; 3910588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_fp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 39119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_sp_7k.kind); 39139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_fp_6k.kind); 39149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_fp_7k.kind); 39159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39163c9cf3442185b5891e15450d6e3058aeff6796fetom if (res_sp_6k.kind == GXR_Addr) { 39179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj StackBlock block; 39189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res; 39199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj UWord sp_delta = res_sp_7k.word - res_sp_6k.word; 39209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj UWord fp_delta = res_fp_7k.word - res_fp_6k.word; 3921e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(sp_delta == 0 || sp_delta == 1024); 3922e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(fp_delta == 0 || fp_delta == 1024); 39239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 0 && fp_delta == 0) { 39259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* depends neither on sp nor fp, so it can't be a stack 39269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj local. Ignore it. */ 39279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 39289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else 39299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 1024 && fp_delta == 0) { 39309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = regs.fp = 0; 39319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 3932588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 3933e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(res.kind == GXR_Addr); 39349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 3935c6e5d76e9eea8625f385ff844545c688c91938daflorian VG_(printf)(" %5lu .. %5llu (sp) %s\n", 3936c6e5d76e9eea8625f385ff844545c688c91938daflorian res.word, res.word + mul.ul - 1, var->name); 39379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.base = res.word; 393850fde23467d92281b32dd537d0d9a590263628c3sewardj block.szB = (SizeT)mul.ul; 39399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.spRel = True; 39409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.isVec = isVec; 39419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)( &block.name[0], 0, sizeof(block.name) ); 39429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (var->name) 39439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 ); 39449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.name[ sizeof(block.name)-1 ] = 0; 39459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( blocks, &block ); 39469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 39479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else 39489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 0 && fp_delta == 1024) { 39499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = regs.fp = 0; 39509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 3951588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 3952e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(res.kind == GXR_Addr); 39539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 3954c6e5d76e9eea8625f385ff844545c688c91938daflorian VG_(printf)(" %5lu .. %5llu (FP) %s\n", 3955c6e5d76e9eea8625f385ff844545c688c91938daflorian res.word, res.word + mul.ul - 1, var->name); 39569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.base = res.word; 395750fde23467d92281b32dd537d0d9a590263628c3sewardj block.szB = (SizeT)mul.ul; 39589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.spRel = False; 39599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.isVec = isVec; 39609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)( &block.name[0], 0, sizeof(block.name) ); 39619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (var->name) 39629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 ); 39639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.name[ sizeof(block.name)-1 ] = 0; 39649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( blocks, &block ); 39659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 39669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else { 39679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(0); 39689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 39699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 39709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 39719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Get an XArray of StackBlock which describe the stack (auto) blocks 39749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for this ip. The caller is expected to free the XArray at some 39759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj point. If 'arrays_only' is True, only array-typed blocks are 39769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj returned; otherwise blocks of all types are returned. */ 39779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 397809a8b1491c62d8e70575eb85da4875d9a07fd20eflorianXArray* /* of StackBlock */ 397909a8b1491c62d8e70575eb85da4875d9a07fd20eflorianVG_(di_get_stack_blocks_at_ip)( Addr ip, Bool arrays_only ) 39809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 39819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* This is a derivation of consider_vars_in_frame() above. */ 39829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word i; 39839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo* di; 39849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool debug = False; 39859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* res = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dgsbai.1", 39879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(dinfo_free), 39889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj sizeof(StackBlock) ); 39899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj static UInt n_search = 0; 39919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj static UInt n_steps = 0; 39929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_search++; 39939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 39949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: dgsbai: ip %#lx\n", ip); 39959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* first, find the DebugInfo that pertains to 'ip'. */ 39969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (di = debugInfo_list; di; di = di->next) { 39979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_steps++; 39989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* text segment missing? unlikely, but handle it .. */ 39999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->text_present || di->text_size == 0) 40009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 40019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok. So does this text mapping bracket the ip? */ 40029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (di->text_avma <= ip && ip < di->text_avma + di->text_size) 40039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj break; 40049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 40059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Didn't find it. Strange -- means ip is a code address outside 40079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj of any mapped text segment. Unlikely but not impossible -- app 40089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj could be generating code to run. */ 40099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di) 40109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; /* currently empty */ 40119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0 && ((n_search & 0x1) == 0)) 40139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("VG_(di_get_stack_blocks_at_ip): %u searches, " 40149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj "%u DebugInfos looked at\n", 40159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_search, n_steps); 40169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Start of performance-enhancing hack: once every ??? (chosen 40179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj hackily after profiling) successful searches, move the found 40189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo one step closer to the start of the list. This makes 40199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj future searches cheaper. */ 40209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if ((n_search & 0xFFFF) == 0) { 40219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Move si one step closer to the start of the list. */ 40229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj move_DebugInfo_one_step_forward( di ); 40239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 40249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* End of performance-enhancing hack. */ 40259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* any var info at all? */ 40279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->varinfo) 40289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; /* currently empty */ 40299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Work through the scopes from most deeply nested outwards, 40319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj looking for code address ranges that bracket 'ip'. The 40329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj variables on each such address range found are in scope right 40339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj now. Don't descend to level zero as that is the global 40349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj scope. */ 40359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* "for each scope, working outwards ..." */ 40379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) { 40389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* vars; 40399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word j; 40409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiAddrRange* arange; 40419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj OSet* this_scope 40429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj = *(OSet**)VG_(indexXA)( di->varinfo, i ); 40439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 40449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: considering scope %ld\n", (Word)i); 40459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!this_scope) 40469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 40479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Find the set of variables in this scope that 40489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj bracket the program counter. */ 40499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj arange = VG_(OSetGen_LookupWithCmp)( 40509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj this_scope, &ip, 40519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(cmp_for_DiAddrRange_range) 40529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ); 40539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!arange) 40549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 40559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* stay sane */ 40569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(arange->aMin <= arange->aMax); 40579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* It must bracket the ip we asked for, else 40589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(cmp_for_DiAddrRange_range) is somehow broken. */ 40599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(arange->aMin <= ip && ip <= arange->aMax); 40609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* It must have an attached XArray of DiVariables. */ 40619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vars = arange->vars; 40629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(vars); 40639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* But it mustn't cover the entire address range. We only 40649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj expect that to happen for the global scope (level 0), which 40659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj we're not looking at here. Except, it may cover the entire 40669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj address range, but in that case the vars array must be 40679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj empty. */ 40689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(! (arange->aMin == (Addr)0 40699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj && arange->aMax == ~(Addr)0 40709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj && VG_(sizeXA)(vars) > 0) ); 40719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (j = 0; j < VG_(sizeXA)( vars ); j++) { 40729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j ); 40739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 40749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n", 40759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->name,arange->aMin,arange->aMax,ip); 40769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj analyse_deps( res, di->admin_tyents, ip, 4077588658b13b5ad77672f323d48fe9da0ca60b0bcbtom di, var, arrays_only ); 40789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 40799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 40809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; 40829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 40839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Get an array of GlobalBlock which describe the global blocks owned 40869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj by the shared object characterised by the given di_handle. Asserts 40879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if the handle is invalid. The caller is responsible for freeing 40889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj the array at some point. If 'arrays_only' is True, only 40899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj array-typed blocks are returned; otherwise blocks of all types are 40909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj returned. */ 40919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 409209a8b1491c62d8e70575eb85da4875d9a07fd20eflorianXArray* /* of GlobalBlock */ 409309a8b1491c62d8e70575eb85da4875d9a07fd20eflorianVG_(di_get_global_blocks_from_dihandle) ( ULong di_handle, Bool arrays_only ) 40949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 40959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* This is a derivation of consider_vars_in_frame() above. */ 40969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo* di; 40989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* gvars; /* XArray* of GlobalBlock */ 40999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word nScopes, scopeIx; 41009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* The first thing to do is find the DebugInfo that 41029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj pertains to 'di_handle'. */ 4103e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(di_handle > 0); 41049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (di = debugInfo_list; di; di = di->next) { 41059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (di->handle == di_handle) 41069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj break; 41079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 41089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* If this fails, we were unable to find any DebugInfo with the 41109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj given handle. This is considered an error on the part of the 41119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj caller. */ 4112e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(di != NULL); 41139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* we'll put the collected variables in here. */ 41159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gvars = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dggbfd.1", 41169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(dinfo_free), sizeof(GlobalBlock) ); 41179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* any var info at all? */ 41199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->varinfo) 41209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return gvars; 41219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* we'll iterate over all the variables we can find, even if 41239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it seems senseless to visit stack-allocated variables */ 41249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over all scopes */ 41259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj nScopes = VG_(sizeXA)( di->varinfo ); 41269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (scopeIx = 0; scopeIx < nScopes; scopeIx++) { 41279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over each (code) address range at the current scope */ 41299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiAddrRange* range; 41309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj OSet* /* of DiAddrInfo */ scope 41319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj = *(OSet**)VG_(indexXA)( di->varinfo, scopeIx ); 4132e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(scope); 41339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(OSetGen_ResetIter)(scope); 41349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj while ( (range = VG_(OSetGen_Next)(scope)) ) { 41359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over each variable in the current address range */ 41379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word nVars, varIx; 4138e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(range->vars); 41399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj nVars = VG_(sizeXA)( range->vars ); 41409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (varIx = 0; varIx < nVars; varIx++) { 41419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool isVec; 41439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res; 414450fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 41459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GlobalBlock gb; 41469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ty; 41479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiVariable* var = VG_(indexXA)( range->vars, varIx ); 4148e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(var->name); 41499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("at depth %ld var %s ", scopeIx, var->name ); 41509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Now figure out if this variable has a constant address 41529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj (that is, independent of FP, SP, phase of moon, etc), 41539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj and if so, what the address is. Any variable with a 41549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj constant address is deemed to be a global so we collect 41559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. */ 41569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) { VG_(printf)("EVAL: "); ML_(pp_GX)(var->gexpr); 41579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("\n"); } 4158588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_trivial_GX)( var->gexpr, di ); 41599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Not a constant address => not interesting */ 41613c9cf3442185b5891e15450d6e3058aeff6796fetom if (res.kind != GXR_Addr) { 41629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("FAIL\n"); 41639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 41649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 41659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok, it's a constant address. See if we want to collect 41679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. */ 41689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("%#lx\n", res.word); 41699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Figure out how big the variable is. */ 417150fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(di->admin_tyents, var->typeR); 41729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 417350fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 417450fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. 417550fde23467d92281b32dd537d0d9a590263628c3sewardj ML_(addVar) should have rejected it. */ 417650fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 417750fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 417850fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 417950fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a 418050fde23467d92281b32dd537d0d9a590263628c3sewardj host word safely (without loss of info). */ 41819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* skip if non-array and we're only interested in 41839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj arrays */ 41849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ty = ML_(TyEnts__index_by_cuOff)( di->admin_tyents, NULL, 41859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR ); 41869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty); 41879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty)); 41889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (ty->tag == Te_UNKNOWN) 41899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; /* perhaps we should complain in this case? */ 41909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj isVec = ty->tag == Te_TyArray; 41929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (arrays_only && !isVec) continue; 41939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok, so collect it! */ 4195e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(var->name); 4196e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(di->soname); 41979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("XXXX %s %s %d\n", var->name, 4198666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe ML_(fndn_ix2filename)(di, var->fndn_ix), 4199666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe var->lineNo); 42009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)(&gb, 0, sizeof(gb)); 42019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gb.addr = res.word; 420250fde23467d92281b32dd537d0d9a590263628c3sewardj gb.szB = (SizeT)mul.ul; 42039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gb.isVec = isVec; 42049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)(&gb.name[0], var->name, sizeof(gb.name)-1); 42059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)(&gb.soname[0], di->soname, sizeof(gb.soname)-1); 4206e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(gb.name[ sizeof(gb.name)-1 ] == 0); 4207e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(gb.soname[ sizeof(gb.soname)-1 ] == 0); 42089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 42099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( gvars, &gb ); 42109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 42119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* for (varIx = 0; varIx < nVars; varIx++) */ 42129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 42139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* while ( (range = VG_(OSetGen_Next)(scope)) ) */ 42149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 42159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* for (scopeIx = 0; scopeIx < nScopes; scopeIx++) */ 42169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 42179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return gvars; 42189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 42199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 42209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 4221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 4222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- DebugInfo accessor functions ---*/ 4223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 4224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4225e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjconst DebugInfo* VG_(next_DebugInfo)(const DebugInfo* di) 4226eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4227b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == NULL) 4228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return debugInfo_list; 4229b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->next; 4230eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4231eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4232e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjAddr VG_(DebugInfo_get_text_avma)(const DebugInfo* di) 4233eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_avma : 0; 4235eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4236eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4237e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjSizeT VG_(DebugInfo_get_text_size)(const DebugInfo* di) 4238eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4239b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_size : 0; 4240eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4241eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 42423898022a7d74a227d6a35102faaedd420ed3a1c1bartAddr VG_(DebugInfo_get_bss_avma)(const DebugInfo* di) 42433898022a7d74a227d6a35102faaedd420ed3a1c1bart{ 42443898022a7d74a227d6a35102faaedd420ed3a1c1bart return di->bss_present ? di->bss_avma : 0; 42453898022a7d74a227d6a35102faaedd420ed3a1c1bart} 42463898022a7d74a227d6a35102faaedd420ed3a1c1bart 42473898022a7d74a227d6a35102faaedd420ed3a1c1bartSizeT VG_(DebugInfo_get_bss_size)(const DebugInfo* di) 42483898022a7d74a227d6a35102faaedd420ed3a1c1bart{ 42493898022a7d74a227d6a35102faaedd420ed3a1c1bart return di->bss_present ? di->bss_size : 0; 42503898022a7d74a227d6a35102faaedd420ed3a1c1bart} 42513898022a7d74a227d6a35102faaedd420ed3a1c1bart 4252e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjAddr VG_(DebugInfo_get_plt_avma)(const DebugInfo* di) 4253092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 4254092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->plt_present ? di->plt_avma : 0; 4255092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 4256092b6268cc4a38ae9ee41d1e3355937536ddc579bart 4257e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjSizeT VG_(DebugInfo_get_plt_size)(const DebugInfo* di) 4258092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 4259092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->plt_present ? di->plt_size : 0; 4260092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 4261092b6268cc4a38ae9ee41d1e3355937536ddc579bart 4262e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjAddr VG_(DebugInfo_get_gotplt_avma)(const DebugInfo* di) 4263092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 4264092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->gotplt_present ? di->gotplt_avma : 0; 4265092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 4266092b6268cc4a38ae9ee41d1e3355937536ddc579bart 4267e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjSizeT VG_(DebugInfo_get_gotplt_size)(const DebugInfo* di) 4268092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 4269092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->gotplt_present ? di->gotplt_size : 0; 4270092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 4271092b6268cc4a38ae9ee41d1e3355937536ddc579bart 427268347837b3d82e48f85daff33ec7ba528891e4e7bartAddr VG_(DebugInfo_get_got_avma)(const DebugInfo* di) 427368347837b3d82e48f85daff33ec7ba528891e4e7bart{ 427468347837b3d82e48f85daff33ec7ba528891e4e7bart return di->got_present ? di->got_avma : 0; 427568347837b3d82e48f85daff33ec7ba528891e4e7bart} 427668347837b3d82e48f85daff33ec7ba528891e4e7bart 427768347837b3d82e48f85daff33ec7ba528891e4e7bartSizeT VG_(DebugInfo_get_got_size)(const DebugInfo* di) 427868347837b3d82e48f85daff33ec7ba528891e4e7bart{ 427968347837b3d82e48f85daff33ec7ba528891e4e7bart return di->got_present ? di->got_size : 0; 428068347837b3d82e48f85daff33ec7ba528891e4e7bart} 428168347837b3d82e48f85daff33ec7ba528891e4e7bart 42821636d33c13958b9c0e7d3059cdd5005746418eb2florianconst HChar* VG_(DebugInfo_get_soname)(const DebugInfo* di) 4283eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->soname; 4285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 4286eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 42871636d33c13958b9c0e7d3059cdd5005746418eb2florianconst HChar* VG_(DebugInfo_get_filename)(const DebugInfo* di) 4288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 4289a5acac39bf3be7546222b1316faee5ee524be0d1sewardj return di->fsm.filename; 4290eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4291eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4292e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjPtrdiffT VG_(DebugInfo_get_text_bias)(const DebugInfo* di) 4293bbec7728efefaa650970dd1f0282b77040287133sewardj{ 4294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_bias : 0; 4295bbec7728efefaa650970dd1f0282b77040287133sewardj} 4296bbec7728efefaa650970dd1f0282b77040287133sewardj 4297e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjInt VG_(DebugInfo_syms_howmany) ( const DebugInfo *si ) 4298eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4299eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return si->symtab_used; 4300eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4301eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4302e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjvoid VG_(DebugInfo_syms_getidx) ( const DebugInfo *si, 4303e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj Int idx, 43044cace66777ca9ee73ea156210c04e9d4cc178395philippe /*OUT*/SymAVMAs* avmas, 43054cace66777ca9ee73ea156210c04e9d4cc178395philippe /*OUT*/UInt* size, 43061ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian /*OUT*/const HChar** pri_name, 43071ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian /*OUT*/const HChar*** sec_names, 43084cace66777ca9ee73ea156210c04e9d4cc178395philippe /*OUT*/Bool* isText, 43094cace66777ca9ee73ea156210c04e9d4cc178395philippe /*OUT*/Bool* isIFunc ) 4310eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4311eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(idx >= 0 && idx < si->symtab_used); 43124cace66777ca9ee73ea156210c04e9d4cc178395philippe if (avmas) *avmas = si->symtab[idx].avmas; 4313a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (size) *size = si->symtab[idx].size; 4314a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (pri_name) *pri_name = si->symtab[idx].pri_name; 43151ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian if (sec_names) *sec_names = si->symtab[idx].sec_names; 4316a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (isText) *isText = si->symtab[idx].isText; 4317a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (isIFunc) *isIFunc = si->symtab[idx].isIFunc; 4318b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 4319b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4320b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4321b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 4322b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- SectKind query functions ---*/ 4323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 4324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Convert a VgSectKind to a string, which must be copied if you want 4326b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to change it. */ 4327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjconst HChar* VG_(pp_SectKind)( VgSectKind kind ) 4328b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 4329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj switch (kind) { 4330b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectUnknown: return "Unknown"; 4331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectText: return "Text"; 4332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectData: return "Data"; 4333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectBSS: return "BSS"; 4334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectGOT: return "GOT"; 4335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectPLT: return "PLT"; 4336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectOPD: return "OPD"; 43375706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj case Vg_SectGOTPLT: return "GOTPLT"; 4338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj default: vg_assert(0); 4339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 4341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Given an address 'a', make a guess of which section of which object 4343e08950b4ce5a3f5d75a7279548f975cd6207dc74florian it comes from. If name is non-NULL, then the object's name is put 4344e08950b4ce5a3f5d75a7279548f975cd6207dc74florian in *name. The returned name, if any, should be saved away, if there is 4345e08950b4ce5a3f5d75a7279548f975cd6207dc74florian a chance that a debug-info will be discarded and the name is being 4346e08950b4ce5a3f5d75a7279548f975cd6207dc74florian used later on. */ 4347e08950b4ce5a3f5d75a7279548f975cd6207dc74florianVgSectKind VG_(DebugInfo_sect_kind)( /*OUT*/const HChar** name, Addr a) 4348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 4349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 4350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VgSectKind res = Vg_SectUnknown; 4351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 4353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4354b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0) 4355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)( 4356c6e5d76e9eea8625f385ff844545c688c91938daflorian "addr=%#lx di=%p %s got=%#lx,%lu plt=%#lx,%lu " 4357c6e5d76e9eea8625f385ff844545c688c91938daflorian "data=%#lx,%lu bss=%#lx,%lu\n", 4358a5acac39bf3be7546222b1316faee5ee524be0d1sewardj a, di, di->fsm.filename, 4359b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->got_avma, di->got_size, 4360b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->plt_avma, di->plt_size, 4361b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_avma, di->data_size, 4362b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->bss_avma, di->bss_size); 4363b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4364b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 4365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_size > 0 4366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->text_avma && a < di->text_avma + di->text_size) { 4367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectText; 4368b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->data_present 4371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_size > 0 4372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->data_avma && a < di->data_avma + di->data_size) { 4373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectData; 4374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->sdata_present 4377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_size > 0 4378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->sdata_avma && a < di->sdata_avma + di->sdata_size) { 4379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectData; 4380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->bss_present 4383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_size > 0 4384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->bss_avma && a < di->bss_avma + di->bss_size) { 4385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectBSS; 4386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 43885706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj if (di->sbss_present 43895706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->sbss_size > 0 43905706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && a >= di->sbss_avma && a < di->sbss_avma + di->sbss_size) { 43915706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj res = Vg_SectBSS; 43925706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj break; 43935706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj } 4394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->plt_present 4395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->plt_size > 0 4396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->plt_avma && a < di->plt_avma + di->plt_size) { 4397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectPLT; 4398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->got_present 4401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->got_size > 0 4402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->got_avma && a < di->got_avma + di->got_size) { 4403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectGOT; 4404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4406092b6268cc4a38ae9ee41d1e3355937536ddc579bart if (di->gotplt_present 4407092b6268cc4a38ae9ee41d1e3355937536ddc579bart && di->gotplt_size > 0 4408092b6268cc4a38ae9ee41d1e3355937536ddc579bart && a >= di->gotplt_avma && a < di->gotplt_avma + di->gotplt_size) { 4409092b6268cc4a38ae9ee41d1e3355937536ddc579bart res = Vg_SectGOTPLT; 4410092b6268cc4a38ae9ee41d1e3355937536ddc579bart break; 4411092b6268cc4a38ae9ee41d1e3355937536ddc579bart } 4412b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->opd_present 4413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->opd_size > 0 4414b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->opd_avma && a < di->opd_avma + di->opd_size) { 4415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectOPD; 4416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* we could also check for .eh_frame, if anyone really cares */ 4419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert( (di == NULL && res == Vg_SectUnknown) 4422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || (di != NULL && res != Vg_SectUnknown) ); 4423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (name) { 4425a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (di && di->fsm.filename) { 4426e08950b4ce5a3f5d75a7279548f975cd6207dc74florian *name = di->fsm.filename; 4427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 4428e08950b4ce5a3f5d75a7279548f975cd6207dc74florian *name = "???"; 4429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return res; 4433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4434eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4435eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4436eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 4437eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- end ---*/ 4438eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 4439