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 120f157ddb404bcde7815a1c5bf2d7e41c114f3d73sewardj Copyright (C) 2000-2013 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" 594ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj#if defined(VGO_linux) 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 10820ede3a4f086d4a4b1e0969b1098dcb244ffb6b4philippestatic UInt CF_info_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 121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Find 'di' in the debugInfo_list and move it one step closer the 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 600f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VGO_linux) || defined(VGO_darwin) 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); 624d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj TRACE_SYMTAB(" [%ld] avma 0x%-16llx size %-8lu " 625d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj "foff %-8lld %s %s %s\n", 626d6845c6e889dd75928e5cdbe5a8ba654881783acsewardj i, (ULong)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. */ 748731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# if defined(VGO_linux) 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 968b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 9696f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_mmap-3: " 9706f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj "is_rx_map %d, is_rw_map %d, is_ro_map %d\n", 9716f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj (Int)is_rx_map, (Int)is_rw_map, (Int)is_ro_map); 972eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 973731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Ignore mappings with permissions we can't possibly be interested in. */ 974731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (!(is_rx_map || is_rw_map || is_ro_map)) 9759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return 0; 976eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 9775a5eec0923d55afc94165721d25125d5fc8f24d8sewardj /* Peer at the first few bytes of the file, to see if it is an ELF */ 9785a5eec0923d55afc94165721d25125d5fc8f24d8sewardj /* object file. Ignore the file if we do not have read permission. */ 9795a5eec0923d55afc94165721d25125d5fc8f24d8sewardj VG_(memset)(buf1k, 0, sizeof(buf1k)); 980cec083d9a254e92623ed44e9dca080d224693c82sewardj oflags = VKI_O_RDONLY; 981cec083d9a254e92623ed44e9dca080d224693c82sewardj# if defined(VKI_O_LARGEFILE) 982cec083d9a254e92623ed44e9dca080d224693c82sewardj oflags |= VKI_O_LARGEFILE; 983cec083d9a254e92623ed44e9dca080d224693c82sewardj# endif 9845f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj 9855f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (use_fd == -1) { 9865f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj SysRes fd = VG_(open)( filename, oflags, 0 ); 9875f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (sr_isError(fd)) { 9885f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (sr_Err(fd) != VKI_EACCES) { 9895f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj DebugInfo fake_di; 9905f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj VG_(memset)(&fake_di, 0, sizeof(fake_di)); 991d3166c4cf9d2545242da71d8baeaaf203b02a09dflorian fake_di.fsm.filename = ML_(dinfo_strdup)("di.debuginfo.nmm", 992d3166c4cf9d2545242da71d8baeaaf203b02a09dflorian filename); 9935f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj ML_(symerr)(&fake_di, True, 9945f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj "can't open file to inspect ELF header"); 9955f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj } 9965f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj return 0; 9975a5eec0923d55afc94165721d25125d5fc8f24d8sewardj } 9985f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj actual_fd = sr_Res(fd); 9995f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj } else { 10005f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj actual_fd = use_fd; 10015a5eec0923d55afc94165721d25125d5fc8f24d8sewardj } 10025a5eec0923d55afc94165721d25125d5fc8f24d8sewardj 10035f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj preadres = VG_(pread)( actual_fd, buf1k, sizeof(buf1k), 0 ); 10045f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (use_fd == -1) { 10055f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj VG_(close)( actual_fd ); 10065f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj } 10075f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj 10085f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (sr_isError(preadres)) { 10095a5eec0923d55afc94165721d25125d5fc8f24d8sewardj DebugInfo fake_di; 10105a5eec0923d55afc94165721d25125d5fc8f24d8sewardj VG_(memset)(&fake_di, 0, sizeof(fake_di)); 1011d3166c4cf9d2545242da71d8baeaaf203b02a09dflorian fake_di.fsm.filename = ML_(dinfo_strdup)("di.debuginfo.nmm", filename); 10125a5eec0923d55afc94165721d25125d5fc8f24d8sewardj ML_(symerr)(&fake_di, True, "can't read file to inspect ELF header"); 10135a5eec0923d55afc94165721d25125d5fc8f24d8sewardj return 0; 10145a5eec0923d55afc94165721d25125d5fc8f24d8sewardj } 10155f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (sr_Res(preadres) == 0) 10165f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj return 0; 10175f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj vg_assert(sr_Res(preadres) > 0 && sr_Res(preadres) <= sizeof(buf1k) ); 10185a5eec0923d55afc94165721d25125d5fc8f24d8sewardj 10198b68b64759254d514d98328c496cbd88cde4c9a5njn /* We're only interested in mappings of object files. */ 10206e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# if defined(VGO_linux) 1021f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj if (!ML_(is_elf_object_file)( buf1k, (SizeT)sr_Res(preadres), False )) 10225a5eec0923d55afc94165721d25125d5fc8f24d8sewardj return 0; 10236e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# elif defined(VGO_darwin) 10245f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj if (!ML_(is_macho_object_file)( buf1k, (SizeT)sr_Res(preadres) )) 1025f76d27a697a7b0bf3b84490baf60623fc96a23afnjn return 0; 10266e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# else 10276e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# error "unknown OS" 10286e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj# endif 10295a5eec0923d55afc94165721d25125d5fc8f24d8sewardj 1030b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* See if we have a DebugInfo for this filename. If not, 1031b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj create one. */ 10320f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj di = find_or_create_DebugInfo_for( filename ); 1033b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(di); 1034b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 10356f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 10366f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_mmap-4: " 10376f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj "noting details in DebugInfo* at %p\n", di); 10386f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj 10396b5625bb609b154766d2e138b61e15655f60b710sewardj /* Note the details about the mapping. */ 1040518850bf0da07ed3e2244e307268ae0fd80e93a8florian DebugInfoMapping map; 10416b5625bb609b154766d2e138b61e15655f60b710sewardj map.avma = a; 10426b5625bb609b154766d2e138b61e15655f60b710sewardj map.size = seg->end + 1 - seg->start; 10436b5625bb609b154766d2e138b61e15655f60b710sewardj map.foff = seg->offset; 10446b5625bb609b154766d2e138b61e15655f60b710sewardj map.rx = is_rx_map; 10456b5625bb609b154766d2e138b61e15655f60b710sewardj map.rw = is_rw_map; 10466b5625bb609b154766d2e138b61e15655f60b710sewardj map.ro = is_ro_map; 10476b5625bb609b154766d2e138b61e15655f60b710sewardj VG_(addToXA)(di->fsm.maps, &map); 10486b5625bb609b154766d2e138b61e15655f60b710sewardj 10496b5625bb609b154766d2e138b61e15655f60b710sewardj /* Update flags about what kind of mappings we've already seen. */ 10506b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.have_rx_map |= is_rx_map; 10516b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.have_rw_map |= is_rw_map; 10526b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.have_ro_map |= is_ro_map; 1053b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1054731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* So, finally, are we in an accept state? */ 1055731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) { 1056731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Ok, so, finally, we found what we need, and we haven't 1057731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj already read debuginfo for this object. So let's do so now. 1058731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj Yee-ha! */ 10596f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 10606f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_mmap-5: " 10616f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj "achieved accept state for %s\n", filename); 1062731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return di_notify_ACHIEVE_ACCEPT_STATE ( di ); 10639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } else { 1064731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* If we don't have an rx and rw mapping, or if we already have 1065731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj debuginfo for this mapping for whatever reason, go no 1066731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj further. */ 1067731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return 0; 10689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 1069eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1070eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1071eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1072eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Unmap is simpler - throw away any SegInfos intersecting 1073eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj [a, a+len). */ 1074eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjvoid VG_(di_notify_munmap)( Addr a, SizeT len ) 1075eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1076f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool anyFound; 1077a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart if (0) VG_(printf)("DISCARD %#lx %#lx\n", a, a+len); 1078f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj anyFound = discard_syms_in_range(a, len); 1079f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (anyFound) 10805c3dba227192de63d86f65ec7d9597c132818c37philippe cfsi_m_cache__invalidate(); 1081eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1082eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1083eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1084eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Uh, this doesn't do anything at all. IIRC glibc (or ld.so, I don't 1085eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj remember) does a bunch of mprotects on itself, and if we follow 1086eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj through here, it causes the debug info for that object to get 1087eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj discarded. */ 1088eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjvoid VG_(di_notify_mprotect)( Addr a, SizeT len, UInt prot ) 1089eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1090eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool exe_ok = toBool(prot & VKI_PROT_EXEC); 1091f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# if defined(VGA_x86) 1092eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj exe_ok = exe_ok || toBool(prot & VKI_PROT_READ); 1093eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# endif 1094f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && !exe_ok) { 1095f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Bool anyFound = discard_syms_in_range(a, len); 1096f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (anyFound) 10975c3dba227192de63d86f65ec7d9597c132818c37philippe cfsi_m_cache__invalidate(); 1098f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 1099eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1100eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1101731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 1102588cd4ebce3305d0cf91896c1f6322ef9775d6c1sewardj/* This is a MacOSX >= 10.7 32-bit only special. See comments on the 1103731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj declaration of struct _DebugInfoFSM for details. */ 1104731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardjvoid VG_(di_notify_vm_protect)( Addr a, SizeT len, UInt prot ) 1105731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj{ 11066f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj Bool debug = (DEBUG_FSM != 0); 11076f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj 11086f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj Bool r_ok = toBool(prot & VKI_PROT_READ); 11096f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj Bool w_ok = toBool(prot & VKI_PROT_WRITE); 11106f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj Bool x_ok = toBool(prot & VKI_PROT_EXEC); 11116f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) { 11126f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-0:\n"); 11136f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-1: %#lx-%#lx %c%c%c\n", 11146f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj a, a + len - 1, 11156f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj r_ok ? 'r' : '-', w_ok ? 'w' : '-', x_ok ? 'x' : '-' ); 11166f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj } 11176f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj 1118731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj Bool do_nothing = True; 1119ec66ad5f33a4d904b1f728935ec6ee29b58a55ecsewardj# if defined(VGP_x86_darwin) && (DARWIN_VERS >= DARWIN_10_7) 1120731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj do_nothing = False; 1121731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj# endif 11226f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (do_nothing /* wrong platform */) { 11236f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 11246f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-2: wrong platform, " 11256f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj "doing nothing.\n"); 1126731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return; 11276f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj } 1128731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 1129731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (! (r_ok && !w_ok && x_ok)) 1130731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return; /* not an upgrade to r-x */ 1131731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 1132731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* Find a DebugInfo containing a FSM that has [a, +len) previously 1133731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj observed as a r-- mapping, plus some other rw- mapping. If such 1134731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj is found, conclude we're in an accept state and read debuginfo 1135731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj accordingly. */ 11366f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 11376f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-3: looking for existing DebugInfo*\n"); 1138731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj DebugInfo* di; 1139518850bf0da07ed3e2244e307268ae0fd80e93a8florian DebugInfoMapping *map = NULL; 11406b5625bb609b154766d2e138b61e15655f60b710sewardj Word i; 1141731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj for (di = debugInfo_list; di; di = di->next) { 1142731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj vg_assert(di->fsm.filename); 1143731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (di->have_dinfo) 1144731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj continue; /* already have debuginfo for this object */ 1145731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (!di->fsm.have_ro_map) 1146731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj continue; /* need to have a r-- mapping for this object */ 1147731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (di->fsm.have_rx_map) 1148731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj continue; /* rx- mapping already exists */ 1149731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (!di->fsm.have_rw_map) 1150731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj continue; /* need to have a rw- mapping */ 11516b5625bb609b154766d2e138b61e15655f60b710sewardj /* Try to find a mapping matching the memory area. */ 11526b5625bb609b154766d2e138b61e15655f60b710sewardj for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { 1153518850bf0da07ed3e2244e307268ae0fd80e93a8florian map = VG_(indexXA)(di->fsm.maps, i); 11546b5625bb609b154766d2e138b61e15655f60b710sewardj if (map->ro && map->avma == a && map->size == len) 11556b5625bb609b154766d2e138b61e15655f60b710sewardj break; 11566b5625bb609b154766d2e138b61e15655f60b710sewardj map = NULL; 11576b5625bb609b154766d2e138b61e15655f60b710sewardj } 11586b5625bb609b154766d2e138b61e15655f60b710sewardj if (!map) 11596b5625bb609b154766d2e138b61e15655f60b710sewardj continue; /* this isn't an upgrade of an r-- mapping */ 1160731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj /* looks like we're in luck! */ 1161731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj break; 1162731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj } 1163731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj if (di == NULL) 1164731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj return; /* didn't find anything */ 1165731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 11666f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 11676f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-4: found existing DebugInfo* at %p\n", 11686f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj di); 11696f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj 11706b5625bb609b154766d2e138b61e15655f60b710sewardj /* Do the upgrade. Simply update the flags of the mapping 11716b5625bb609b154766d2e138b61e15655f60b710sewardj and pretend we never saw the RO map at all. */ 1172731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj vg_assert(di->fsm.have_ro_map); 11736b5625bb609b154766d2e138b61e15655f60b710sewardj map->rx = True; 11746b5625bb609b154766d2e138b61e15655f60b710sewardj map->ro = False; 1175731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj di->fsm.have_rx_map = True; 1176731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj di->fsm.have_ro_map = False; 11776b5625bb609b154766d2e138b61e15655f60b710sewardj /* See if there are any more ro mappings */ 11786b5625bb609b154766d2e138b61e15655f60b710sewardj for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { 1179518850bf0da07ed3e2244e307268ae0fd80e93a8florian map = VG_(indexXA)(di->fsm.maps, i); 11806b5625bb609b154766d2e138b61e15655f60b710sewardj if (map->ro) { 11816b5625bb609b154766d2e138b61e15655f60b710sewardj di->fsm.have_ro_map = True; 11826b5625bb609b154766d2e138b61e15655f60b710sewardj break; 11836b5625bb609b154766d2e138b61e15655f60b710sewardj } 11846b5625bb609b154766d2e138b61e15655f60b710sewardj } 11856b5625bb609b154766d2e138b61e15655f60b710sewardj 11866b5625bb609b154766d2e138b61e15655f60b710sewardj /* Check if we're now in an accept state and read debuginfo. Finally. */ 11876b5625bb609b154766d2e138b61e15655f60b710sewardj if (di->fsm.have_rx_map && di->fsm.have_rw_map && !di->have_dinfo) { 11886f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj if (debug) 11896f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj VG_(printf)("di_notify_vm_protect-5: " 11906f00ae96d4dcab1f35efe4cc875837089e6d8f72sewardj "achieved accept state for %s\n", di->fsm.filename); 11916b5625bb609b154766d2e138b61e15655f60b710sewardj ULong di_handle __attribute__((unused)) 11926b5625bb609b154766d2e138b61e15655f60b710sewardj = di_notify_ACHIEVE_ACCEPT_STATE( di ); 11936b5625bb609b154766d2e138b61e15655f60b710sewardj /* di_handle is ignored. That's not a problem per se -- it just 11946b5625bb609b154766d2e138b61e15655f60b710sewardj means nobody will ever be able to refer to this debuginfo by 11956b5625bb609b154766d2e138b61e15655f60b710sewardj handle since nobody will know what the handle value is. */ 11966b5625bb609b154766d2e138b61e15655f60b710sewardj } 1197731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj} 1198731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 1199731f9cf9fd4d507b44f1a0fdc2d3b8e8efae02e3sewardj 1200c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--------- PDB (windows debug info) reading --------- */ 1201c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1202c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/* this should really return ULong, as per VG_(di_notify_mmap). */ 1203c8259b85b701d25d72aabe9dc0a8154517f96913sewardjvoid VG_(di_notify_pdb_debuginfo)( Int fd_obj, Addr avma_obj, 120454c45db2f978055aeca91aaccb05aac825523e6csewardj SizeT total_size, PtrdiffT bias_obj ) 1205c8259b85b701d25d72aabe9dc0a8154517f96913sewardj{ 120613ac96dea734b3933a73524b991ac64fb48a4d57sewardj Int i, r, sz_exename; 1207c8259b85b701d25d72aabe9dc0a8154517f96913sewardj ULong obj_mtime, pdb_mtime; 12081636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar* pdbname = NULL; 12091636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar* dot; 1210c8259b85b701d25d72aabe9dc0a8154517f96913sewardj SysRes sres; 1211c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Int fd_pdbimage; 1212c8259b85b701d25d72aabe9dc0a8154517f96913sewardj SizeT n_pdbimage; 1213c8259b85b701d25d72aabe9dc0a8154517f96913sewardj struct vg_stat stat_buf; 1214c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1215c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) { 1216738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "\n"); 1217c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(message)(Vg_UserMsg, 1218cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj "LOAD_PDB_DEBUGINFO: clreq: fd=%d, avma=%#lx, total_size=%lu, " 121954c45db2f978055aeca91aaccb05aac825523e6csewardj "bias=%#lx\n", 122054c45db2f978055aeca91aaccb05aac825523e6csewardj fd_obj, avma_obj, total_size, bias_obj 1221c8259b85b701d25d72aabe9dc0a8154517f96913sewardj ); 1222c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1223c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1224c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* 'fd' refers to the .exe/.dll we're dealing with. Get its modification 1225c8259b85b701d25d72aabe9dc0a8154517f96913sewardj time into obj_mtime. */ 1226c8259b85b701d25d72aabe9dc0a8154517f96913sewardj r = VG_(fstat)(fd_obj, &stat_buf); 1227c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (r == -1) 1228a175ffb9ffa4fd250611582a611333d11c835de2florian return; /* stat failed ?! */ 1229c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(r == 0); 12309c20ece00e07304f66da5f43b87ec45bc9c04550njn obj_mtime = stat_buf.mtime; 1231c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1232a175ffb9ffa4fd250611582a611333d11c835de2florian /* and get its name into exename. */ 12333130eab8c67d0c720cb1a86906cc057daa9700ccflorian const HChar *exe; 1234a175ffb9ffa4fd250611582a611333d11c835de2florian if (! VG_(resolve_filename)(fd_obj, &exe)) 1235a175ffb9ffa4fd250611582a611333d11c835de2florian return; /* failed */ 1236a175ffb9ffa4fd250611582a611333d11c835de2florian sz_exename = VG_(strlen)(exe); 1237a175ffb9ffa4fd250611582a611333d11c835de2florian HChar exename[sz_exename + 1]; 1238a175ffb9ffa4fd250611582a611333d11c835de2florian VG_(strcpy)(exename, exe); // make a copy on the stack 1239c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1240c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) { 1241738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: objname: %s\n", exename); 1242c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1243c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 124413ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Try to get the PDB file name from the executable. */ 124513ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = ML_(find_name_of_pdb_file)(exename); 124613ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (pdbname) { 124713ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(VG_(strlen)(pdbname) >= 5); /* 5 = strlen("X.pdb") */ 124813ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* So we successfully extracted a name from the PE file. But it's 124913ac96dea734b3933a73524b991ac64fb48a4d57sewardj likely to be of the form 125013ac96dea734b3933a73524b991ac64fb48a4d57sewardj e:\foo\bar\xyzzy\wibble.pdb 125113ac96dea734b3933a73524b991ac64fb48a4d57sewardj and we need to change it into something we can actually open 125213ac96dea734b3933a73524b991ac64fb48a4d57sewardj in Wine-world, which basically means turning it into 125313ac96dea734b3933a73524b991ac64fb48a4d57sewardj $HOME/.wine/drive_e/foo/bar/xyzzy/wibble.pdb 125413ac96dea734b3933a73524b991ac64fb48a4d57sewardj We also take into account $WINEPREFIX, if it is set. 125513ac96dea734b3933a73524b991ac64fb48a4d57sewardj For the moment, if the name isn't fully qualified, just forget it 125613ac96dea734b3933a73524b991ac64fb48a4d57sewardj (we'd have to root around to find where the pdb actually is) 125713ac96dea734b3933a73524b991ac64fb48a4d57sewardj */ 125813ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Change all the backslashes to forward slashes */ 125913ac96dea734b3933a73524b991ac64fb48a4d57sewardj for (i = 0; pdbname[i]; i++) { 126013ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (pdbname[i] == '\\') 126113ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname[i] = '/'; 126213ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 126313ac96dea734b3933a73524b991ac64fb48a4d57sewardj Bool is_quald 126413ac96dea734b3933a73524b991ac64fb48a4d57sewardj = ('a' <= VG_(tolower)(pdbname[0]) && VG_(tolower)(pdbname[0]) <= 'z') 126513ac96dea734b3933a73524b991ac64fb48a4d57sewardj && pdbname[1] == ':' 126613ac96dea734b3933a73524b991ac64fb48a4d57sewardj && pdbname[2] == '/'; 126713ac96dea734b3933a73524b991ac64fb48a4d57sewardj HChar* home = VG_(getenv)("HOME"); 126813ac96dea734b3933a73524b991ac64fb48a4d57sewardj HChar* wpfx = VG_(getenv)("WINEPREFIX"); 126913ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (is_quald && wpfx) { 127013ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Change e:/foo/bar/xyzzy/wibble.pdb 127113ac96dea734b3933a73524b991ac64fb48a4d57sewardj to $WINEPREFIX/drive_e/foo/bar/xyzzy/wibble.pdb 127213ac96dea734b3933a73524b991ac64fb48a4d57sewardj */ 127313ac96dea734b3933a73524b991ac64fb48a4d57sewardj Int mashedSzB = VG_(strlen)(pdbname) + VG_(strlen)(wpfx) + 50/*misc*/; 127413ac96dea734b3933a73524b991ac64fb48a4d57sewardj HChar* mashed = ML_(dinfo_zalloc)("di.debuginfo.dnpdi.1", mashedSzB); 127598500e2ee5f63f9c0af57835f7620d30848115f4bart VG_(snprintf)(mashed, mashedSzB, "%s/drive_%c%s", 127698500e2ee5f63f9c0af57835f7620d30848115f4bart wpfx, pdbname[0], &pdbname[2]); 127713ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(mashed[mashedSzB-1] == 0); 127813ac96dea734b3933a73524b991ac64fb48a4d57sewardj ML_(dinfo_free)(pdbname); 127913ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = mashed; 128013ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 128113ac96dea734b3933a73524b991ac64fb48a4d57sewardj else if (is_quald && home && !wpfx) { 128213ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Change e:/foo/bar/xyzzy/wibble.pdb 128313ac96dea734b3933a73524b991ac64fb48a4d57sewardj to $HOME/.wine/drive_e/foo/bar/xyzzy/wibble.pdb 128413ac96dea734b3933a73524b991ac64fb48a4d57sewardj */ 128513ac96dea734b3933a73524b991ac64fb48a4d57sewardj Int mashedSzB = VG_(strlen)(pdbname) + VG_(strlen)(home) + 50/*misc*/; 128613ac96dea734b3933a73524b991ac64fb48a4d57sewardj HChar* mashed = ML_(dinfo_zalloc)("di.debuginfo.dnpdi.2", mashedSzB); 128798500e2ee5f63f9c0af57835f7620d30848115f4bart VG_(snprintf)(mashed, mashedSzB, "%s/.wine/drive_%c%s", 128898500e2ee5f63f9c0af57835f7620d30848115f4bart home, pdbname[0], &pdbname[2]); 128913ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(mashed[mashedSzB-1] == 0); 129013ac96dea734b3933a73524b991ac64fb48a4d57sewardj ML_(dinfo_free)(pdbname); 129113ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = mashed; 129213ac96dea734b3933a73524b991ac64fb48a4d57sewardj } else { 129313ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* It's not a fully qualified path, or neither $HOME nor $WINE 129413ac96dea734b3933a73524b991ac64fb48a4d57sewardj are set (strange). Give up. */ 129513ac96dea734b3933a73524b991ac64fb48a4d57sewardj ML_(dinfo_free)(pdbname); 129613ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = NULL; 129713ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 129813ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 1299c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 130013ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Try s/exe/pdb/ if we don't have a valid pdbname. */ 130113ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (!pdbname) { 130213ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Try to find a matching PDB file from which to read debuginfo. 130313ac96dea734b3933a73524b991ac64fb48a4d57sewardj Windows PE files have symbol tables and line number information, 130413ac96dea734b3933a73524b991ac64fb48a4d57sewardj but MSVC doesn't seem to use them. */ 130513ac96dea734b3933a73524b991ac64fb48a4d57sewardj /* Why +5 ? Because in the worst case, we could find a dot as the 130613ac96dea734b3933a73524b991ac64fb48a4d57sewardj last character of pdbname, and we'd then put "pdb" right after 130713ac96dea734b3933a73524b991ac64fb48a4d57sewardj it, hence extending it a bit. */ 130813ac96dea734b3933a73524b991ac64fb48a4d57sewardj pdbname = ML_(dinfo_zalloc)("di.debuginfo.lpd1", sz_exename+5); 130913ac96dea734b3933a73524b991ac64fb48a4d57sewardj VG_(strcpy)(pdbname, exename); 131013ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(pdbname[sz_exename+5-1] == 0); 131113ac96dea734b3933a73524b991ac64fb48a4d57sewardj dot = VG_(strrchr)(pdbname, '.'); 131213ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (!dot) 131313ac96dea734b3933a73524b991ac64fb48a4d57sewardj goto out; /* there's no dot in the exe's name ?! */ 131413ac96dea734b3933a73524b991ac64fb48a4d57sewardj if (dot[1] == 0) 131513ac96dea734b3933a73524b991ac64fb48a4d57sewardj goto out; /* hmm, path ends in "." */ 131613ac96dea734b3933a73524b991ac64fb48a4d57sewardj 131713ac96dea734b3933a73524b991ac64fb48a4d57sewardj if ('A' <= dot[1] && dot[1] <= 'Z') 131813ac96dea734b3933a73524b991ac64fb48a4d57sewardj VG_(strcpy)(dot, ".PDB"); 131913ac96dea734b3933a73524b991ac64fb48a4d57sewardj else 132013ac96dea734b3933a73524b991ac64fb48a4d57sewardj VG_(strcpy)(dot, ".pdb"); 132113ac96dea734b3933a73524b991ac64fb48a4d57sewardj 132213ac96dea734b3933a73524b991ac64fb48a4d57sewardj vg_assert(pdbname[sz_exename+5-1] == 0); 132313ac96dea734b3933a73524b991ac64fb48a4d57sewardj } 1324c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1325c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* See if we can find it, and check it's in-dateness. */ 1326c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sres = VG_(stat)(pdbname, &stat_buf); 1327cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) { 1328738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "Warning: Missing or un-stat-able %s\n", 1329c8259b85b701d25d72aabe9dc0a8154517f96913sewardj pdbname); 1330c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) 1331738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: missing: %s\n", pdbname); 1332c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; 1333c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 13349c20ece00e07304f66da5f43b87ec45bc9c04550njn pdb_mtime = stat_buf.mtime; 13357138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj 1336ced85060ebfd32f26de8e6a6f11567c9ac2b096asewardj if (obj_mtime > pdb_mtime + 60ULL) { 13377138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj /* PDB file is older than PE file. Really, the PDB should be 13387138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj newer than the PE, but that doesn't always seem to be the 13397138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj case. Allow the PDB to be up to one minute older. 13407138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj Otherwise, it's probably out of date, in which case ignore it 13417138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj or we will either (a) print wrong stack traces or more likely 13427138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj (b) crash. 13437138ef060dce6c67500c5cb16daa503b6ce71dc6sewardj */ 1344738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, 1345ced85060ebfd32f26de8e6a6f11567c9ac2b096asewardj "Warning: %s (mtime = %llu)\n" 1346ced85060ebfd32f26de8e6a6f11567c9ac2b096asewardj " is older than %s (mtime = %llu)\n", 1347ced85060ebfd32f26de8e6a6f11567c9ac2b096asewardj pdbname, pdb_mtime, exename, obj_mtime); 1348c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1349c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1350c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sres = VG_(open)(pdbname, VKI_O_RDONLY, 0); 1351cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) { 1352738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "Warning: Can't open %s\n", pdbname); 1353c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; 1354c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1355c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1356cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj /* Looks promising; go on to try and read stuff from it. But don't 1357cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj mmap the file. Instead mmap free space and read the file into 1358cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj it. This is because files on CIFS filesystems that are mounted 1359cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj '-o directio' can't be mmap'd, and that mount option is needed 1360cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj to make CIFS work reliably. (See 1361cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj http://www.nabble.com/Corrupted-data-on-write-to- 1362cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj Windows-2003-Server-t2782623.html) 1363cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj This is slower, but at least it works reliably. */ 1364cda2f0fbda4c4b2644babc830244be8aed95de1dnjn fd_pdbimage = sr_Res(sres); 13659c20ece00e07304f66da5f43b87ec45bc9c04550njn n_pdbimage = stat_buf.size; 1366cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj if (n_pdbimage == 0 || n_pdbimage > 0x7FFFFFFF) { 1367cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // 0x7FFFFFFF: why? Because the VG_(read) just below only 1368cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // can deal with a signed int as the size of data to read, 1369cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // so we can't reliably check for read failure for files 1370cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // greater than that size. Hence just skip them; we're 1371cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj // unlikely to encounter a PDB that large anyway. 1372cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj VG_(close)(fd_pdbimage); 1373cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj goto out; 1374cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj } 1375cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj sres = VG_(am_mmap_anon_float_valgrind)( n_pdbimage ); 1376cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) { 1377c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(close)(fd_pdbimage); 1378c8259b85b701d25d72aabe9dc0a8154517f96913sewardj goto out; 1379c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1380c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1381cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj void* pdbimage = (void*)sr_Res(sres); 1382cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj r = VG_(read)( fd_pdbimage, pdbimage, (Int)n_pdbimage ); 1383cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj if (r < 0 || r != (Int)n_pdbimage) { 1384cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage ); 1385cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj VG_(close)(fd_pdbimage); 1386cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj goto out; 1387cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj } 1388cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj 1389c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (VG_(clo_verbosity) > 0) 1390738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: pdbname: %s\n", pdbname); 1391c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1392c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* play safe; always invalidate the CFI cache. I don't know if 1393c8259b85b701d25d72aabe9dc0a8154517f96913sewardj this is necessary, but anyway .. */ 13945c3dba227192de63d86f65ec7d9597c132818c37philippe cfsi_m_cache__invalidate(); 1395c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* dump old info for this range, if any */ 1396c8259b85b701d25d72aabe9dc0a8154517f96913sewardj discard_syms_in_range( avma_obj, total_size ); 1397c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 13980f4126c9b5898dde89473d5993c98dd4d41ee8b7sewardj { DebugInfo* di = find_or_create_DebugInfo_for(exename); 1399c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1400c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* this di must be new, since we just nuked any old stuff in the range */ 1401a5acac39bf3be7546222b1316faee5ee524be0d1sewardj vg_assert(di && !di->fsm.have_rx_map && !di->fsm.have_rw_map); 1402c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(!di->have_dinfo); 1403c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1404c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* don't set up any of the di-> fields; let 1405c8259b85b701d25d72aabe9dc0a8154517f96913sewardj ML_(read_pdb_debug_info) do it. */ 140654c45db2f978055aeca91aaccb05aac825523e6csewardj ML_(read_pdb_debug_info)( di, avma_obj, bias_obj, 1407c8259b85b701d25d72aabe9dc0a8154517f96913sewardj pdbimage, n_pdbimage, pdbname, pdb_mtime ); 1408c8259b85b701d25d72aabe9dc0a8154517f96913sewardj // JRS fixme: take notice of return value from read_pdb_debug_info, 1409c8259b85b701d25d72aabe9dc0a8154517f96913sewardj // and handle failure 1410c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(di->have_dinfo); // fails if PDB read failed 1411c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(am_munmap_valgrind)( (Addr)pdbimage, n_pdbimage ); 1412c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(close)(fd_pdbimage); 1413cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj 1414cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj if (VG_(clo_verbosity) > 0) { 1415cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: done: " 1416a663c8e5b4767efbd870c857076251460992e3edsewardj "%lu syms, %lu src locs, %lu fpo recs\n", 1417a663c8e5b4767efbd870c857076251460992e3edsewardj di->symtab_used, di->loctab_used, di->fpo_size); 1418cd458d28a6a18ab7e1516ae0c05eeaaaa2512f47sewardj } 1419c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 1420c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 1421c8259b85b701d25d72aabe9dc0a8154517f96913sewardj out: 1422c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (pdbname) ML_(dinfo_free)(pdbname); 1423c8259b85b701d25d72aabe9dc0a8154517f96913sewardj} 1424c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 14258b68b64759254d514d98328c496cbd88cde4c9a5njn#endif /* defined(VGO_linux) || defined(VGO_darwin) */ 14264ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 14274ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 1428eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1429eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- ---*/ 1430eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- TOP LEVEL: QUERYING EXISTING DEBUG INFO ---*/ 1431eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- ---*/ 1432eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1433eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 14349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid VG_(di_discard_ALL_debuginfo)( void ) 14359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 14369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo *di, *di2; 14379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di = debugInfo_list; 14389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj while (di) { 14399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di2 = di->next; 14409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("XXX rm %p\n", di); 14419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj free_DebugInfo( di ); 14429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di = di2; 14439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 14449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 14459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 14469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 1447518850bf0da07ed3e2244e307268ae0fd80e93a8florianDebugInfoMapping* ML_(find_rx_mapping) ( DebugInfo* di, Addr lo, Addr hi ) 14486b5625bb609b154766d2e138b61e15655f60b710sewardj{ 14496b5625bb609b154766d2e138b61e15655f60b710sewardj Word i; 14506b5625bb609b154766d2e138b61e15655f60b710sewardj vg_assert(lo <= hi); 14516b5625bb609b154766d2e138b61e15655f60b710sewardj 14526b5625bb609b154766d2e138b61e15655f60b710sewardj /* Optimization: Try to use the last matched rx mapping first */ 14536b5625bb609b154766d2e138b61e15655f60b710sewardj if ( di->last_rx_map 14546b5625bb609b154766d2e138b61e15655f60b710sewardj && lo >= di->last_rx_map->avma 14556b5625bb609b154766d2e138b61e15655f60b710sewardj && hi < di->last_rx_map->avma + di->last_rx_map->size) 14566b5625bb609b154766d2e138b61e15655f60b710sewardj return di->last_rx_map; 14576b5625bb609b154766d2e138b61e15655f60b710sewardj 14586b5625bb609b154766d2e138b61e15655f60b710sewardj for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) { 1459518850bf0da07ed3e2244e307268ae0fd80e93a8florian DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i); 14606b5625bb609b154766d2e138b61e15655f60b710sewardj if ( map->rx && map->size > 0 14616b5625bb609b154766d2e138b61e15655f60b710sewardj && lo >= map->avma && hi < map->avma + map->size) { 14626b5625bb609b154766d2e138b61e15655f60b710sewardj di->last_rx_map = map; 14636b5625bb609b154766d2e138b61e15655f60b710sewardj return map; 14646b5625bb609b154766d2e138b61e15655f60b710sewardj } 14656b5625bb609b154766d2e138b61e15655f60b710sewardj } 14666b5625bb609b154766d2e138b61e15655f60b710sewardj 14676b5625bb609b154766d2e138b61e15655f60b710sewardj return NULL; 14686b5625bb609b154766d2e138b61e15655f60b710sewardj} 14696b5625bb609b154766d2e138b61e15655f60b710sewardj 1470a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/*------------------------------------------------------------*/ 1471a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/*--- Types and functions for inlined IP cursor ---*/ 1472a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/*------------------------------------------------------------*/ 1473a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestruct _InlIPCursor { 1474a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Addr eip; // Cursor used to describe calls at eip. 1475a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe DebugInfo* di; // DebugInfo describing inlined calls at eip 1476a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1477a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word inltab_lopos; // The inlined fn calls covering eip are in 1478a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word inltab_hipos; // di->inltab[inltab_lopos..inltab_hipos]. 1479a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // Note that not all inlined fn calls in this range 1480a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // are necessarily covering eip. 1481a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1482a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Int curlevel; // Current level to describe. 1483a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // 0 means to describe eip itself. 1484a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word cur_inltab; // inltab pos for call inlined at current level. 1485a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word next_inltab; // inltab pos for call inlined at next (towards main) 1486a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // level. 1487a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe}; 1488a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1489518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic Bool is_top(const InlIPCursor *iipc) 1490a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1491a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return !iipc || iipc->cur_inltab == -1; 1492a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1493a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1494518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic Bool is_bottom(const InlIPCursor *iipc) 1495a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1496a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return !iipc || iipc->next_inltab == -1; 1497a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1498a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1499a0a73939b0398b6608fd6dbde49820ce6530d12cphilippeBool VG_(next_IIPC)(InlIPCursor *iipc) 1500a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1501a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word i; 1502a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe DiInlLoc *hinl = NULL; 1503a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word hinl_pos = -1; 1504a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe DebugInfo *di; 1505a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1506a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (iipc == NULL) 1507a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return False; 1508a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1509a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (iipc->curlevel <= 0) { 1510a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe iipc->curlevel--; 1511a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return False; 1512a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1513a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1514a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe di = iipc->di; 1515a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe for (i = iipc->inltab_lopos; i <= iipc->inltab_hipos; i++) { 1516a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di->inltab[i].addr_lo <= iipc->eip 1517a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe && iipc->eip < di->inltab[i].addr_hi 1518a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe && di->inltab[i].level < iipc->curlevel 1519a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe && (!hinl || hinl->level < di->inltab[i].level)) { 1520a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe hinl = &di->inltab[i]; 1521a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe hinl_pos = i; 1522a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1523a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1524a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1525a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe iipc->cur_inltab = iipc->next_inltab; 1526a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe iipc->next_inltab = hinl_pos; 1527a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (iipc->next_inltab < 0) 1528a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe iipc->curlevel = 0; // no inlined call anymore, describe eip itself 1529a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe else 1530a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe iipc->curlevel = di->inltab[iipc->next_inltab].level; 1531a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1532a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return True; 1533a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1534a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1535a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/* Forward */ 1536a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic void search_all_loctabs ( Addr ptr, /*OUT*/DebugInfo** pdi, 1537a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*OUT*/Word* locno ); 1538a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1539a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/* Returns the position after which eip would be inserted in inltab. 1540a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe (-1 if eip should be inserted before position 0). 1541a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe This is the highest position with an addr_lo <= eip. 1542a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe As inltab is sorted on addr_lo, dichotomic search can be done 1543a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe (note that inltab might have duplicates addr_lo). */ 1544a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic Word inltab_insert_pos (DebugInfo *di, Addr eip) 1545a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1546a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word mid, 1547a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe lo = 0, 1548a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe hi = di->inltab_used-1; 1549a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe while (lo <= hi) { 1550a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe mid = (lo + hi) / 2; 1551a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (eip < di->inltab[mid].addr_lo) { hi = mid-1; continue; } 1552a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (eip > di->inltab[mid].addr_lo) { lo = mid+1; continue; } 1553a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe lo = mid; break; 1554a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1555a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1556a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe while (lo <= di->inltab_used-1 && di->inltab[lo].addr_lo <= eip) 1557a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe lo++; 1558a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe#if 0 1559a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe for (mid = 0; mid <= di->inltab_used-1; mid++) 1560a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (eip < di->inltab[mid].addr_lo) 1561a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe break; 1562a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (lo - 1 == mid - 1); 1563a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe#endif 1564a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return lo - 1; 1565a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1566a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1567a0a73939b0398b6608fd6dbde49820ce6530d12cphilippeInlIPCursor* VG_(new_IIPC)(Addr eip) 1568a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1569a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe DebugInfo* di; 1570a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word locno; 1571a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Word i; 1572a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe InlIPCursor *ret; 1573a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Bool avail; 1574a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1575a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (!VG_(clo_read_inline_info)) 1576a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return NULL; // No way we can find inlined calls. 1577a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1578a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* Search the DebugInfo for eip */ 1579a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe search_all_loctabs ( eip, &di, &locno ); 1580a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di == NULL || di->inltab_used == 0) 1581a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return NULL; // No di (with inltab) containing eip. 1582a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1583a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* Search the entry in di->inltab with the highest addr_lo that 1584a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe contains eip. */ 1585a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* We start from the highest pos in inltab after which eip would 1586a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe be inserted. */ 1587a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe for (i = inltab_insert_pos (di, eip); i >= 0; i--) { 1588a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di->inltab[i].addr_lo <= eip && eip < di->inltab[i].addr_hi) { 1589a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe break; 1590a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1591a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* Stop the backward scan when reaching an addr_lo which 1592a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe cannot anymore contain eip : we know that all ranges before 1593a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe i also cannot contain eip. */ 1594a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di->inltab[i].addr_lo < eip - di->maxinl_codesz) 1595a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return NULL; 1596a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1597a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1598a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (i < 0) 1599a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return NULL; // No entry containing eip. 1600a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1601a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* We have found the highest entry containing eip. 1602a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Build a cursor. */ 1603a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret = ML_(dinfo_zalloc) ("dinfo.new_IIPC", sizeof(*ret)); 1604a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->eip = eip; 1605a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->di = di; 1606a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->inltab_hipos = i; 1607a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe for (i = ret->inltab_hipos - 1; i >= 0; i--) { 1608a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1609a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (di->inltab[i].addr_lo < eip - di->maxinl_codesz) 1610a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe break; /* Similar stop backward scan logic as above. */ 1611a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1612a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->inltab_lopos = i + 1; 1613a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->curlevel = MAX_LEVEL; 1614a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->cur_inltab = -1; 1615a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ret->next_inltab = -1; 1616a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1617a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /* MAX_LEVEL is higher than any stored level. We can use 1618a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe VG_(next_IIPC) to get to the 'real' first highest call level. */ 1619a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe avail = VG_(next_IIPC) (ret); 1620a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (avail); 1621a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1622a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return ret; 1623a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1624a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 1625a0a73939b0398b6608fd6dbde49820ce6530d12cphilippevoid VG_(delete_IIPC)(InlIPCursor *iipc) 1626a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{ 1627a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (iipc) 1628a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ML_(dinfo_free)( iipc ); 1629a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe} 1630a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 16316b5625bb609b154766d2e138b61e15655f60b710sewardj 1632eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1633eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Use of symbol table & location info to create ---*/ 1634eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- plausible-looking stack dumps. ---*/ 1635eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/ 1636eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1637eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Search all symtabs that we know about to locate ptr. If found, set 1638b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi to the relevant DebugInfo, and *symno to the symtab entry 1639b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *number within that. If not found, *psi is set to NULL. 1640b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj If findText==True, only text symbols are searched for. 1641b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj If findText==False, only data symbols are searched for. 1642b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/ 1643b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void search_all_symtabs ( Addr ptr, /*OUT*/DebugInfo** pdi, 1644f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*OUT*/Word* symno, 1645b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool match_anywhere_in_sym, 1646b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool findText ) 1647eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1648f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1649b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1650b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool inRange; 1651b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1652b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1653b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1654b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (findText) { 165551c9d3750448a4f2c95d22879e2f9f4bbd22bcfesewardj /* Consider any symbol in the r-x mapped area to be text. 165651c9d3750448a4f2c95d22879e2f9f4bbd22bcfesewardj See Comment_Regarding_Text_Range_Checks in storage.c for 165751c9d3750448a4f2c95d22879e2f9f4bbd22bcfesewardj details. */ 1658a5acac39bf3be7546222b1316faee5ee524be0d1sewardj inRange = di->fsm.have_rx_map 16596b5625bb609b154766d2e138b61e15655f60b710sewardj && (ML_(find_rx_mapping)(di, ptr, ptr) != NULL); 1660b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 1661b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj inRange = (di->data_present 1662b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_size > 0 1663b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_avma <= ptr 1664b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->data_avma + di->data_size) 1665b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || 1666b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (di->sdata_present 1667b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_size > 0 1668b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_avma <= ptr 1669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->sdata_avma + di->sdata_size) 1670b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || 1671b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj (di->bss_present 1672b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_size > 0 1673b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_avma <= ptr 16745706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && ptr < di->bss_avma + di->bss_size) 16755706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj || 16765706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj (di->sbss_present 16775706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->sbss_size > 0 16785706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->sbss_avma <= ptr 16795706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && ptr < di->sbss_avma + di->sbss_size) 16805706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj || 16815706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj (di->rodata_present 16825706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->rodata_size > 0 16835706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->rodata_avma <= ptr 16845706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && ptr < di->rodata_avma + di->rodata_size); 1685eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1686b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1687b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!inRange) continue; 1688b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1689b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sno = ML_(search_one_symtab) ( 1690b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di, ptr, match_anywhere_in_sym, findText ); 1691b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (sno == -1) goto not_found; 1692b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *symno = sno; 1693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = di; 1694b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return; 1695b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1696eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1697eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj not_found: 1698b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = NULL; 1699eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1700eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1701eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1702eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Search all loctabs that we know about to locate ptr. If found, set 1703b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi to the relevant DebugInfo, and *locno to the loctab entry 1704b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *number within that. If not found, *pdi is set to NULL. */ 1705b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void search_all_loctabs ( Addr ptr, /*OUT*/DebugInfo** pdi, 1706f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*OUT*/Word* locno ) 1707eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1708f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word lno; 1709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1710b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 1711b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 17125706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->text_size > 0 1713b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= ptr 1714b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && ptr < di->text_avma + di->text_size) { 1715b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj lno = ML_(search_one_loctab) ( di, ptr ); 1716eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (lno == -1) goto not_found; 1717eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *locno = lno; 1718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = di; 1719eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return; 1720eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1721eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1722eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj not_found: 1723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *pdi = NULL; 1724eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1725eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1726eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1727eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* The whole point of this whole big deal: map a code address to a 1728eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj plausible symbol name. Returns False if no idea; otherwise True. 1729dc4ff1a019a3e54d3e5517514b7e683cb2071829florian Caller supplies buf. If do_cxx_demangling is False, don't do 17306b7611bf42a0fbb62e047d8c43b008205bd21e75njn C++ demangling, regardless of VG_(clo_demangle) -- probably because the 17316b7611bf42a0fbb62e047d8c43b008205bd21e75njn call has come from VG_(get_fnname_raw)(). findText 1732b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj indicates whether we're looking for a text symbol or a data symbol 173346cc04521acf2827eb33310fadc119bf2dc039e4florian -- caller must choose one kind or the other. 173446cc04521acf2827eb33310fadc119bf2dc039e4florian Note: the string returned in *BUF is persistent as long as 173546cc04521acf2827eb33310fadc119bf2dc039e4florian (1) the DebugInfo it belongs to is not discarded 173646cc04521acf2827eb33310fadc119bf2dc039e4florian (2) the segment containing the address is not merged with another segment 173746cc04521acf2827eb33310fadc119bf2dc039e4florian (3) the demangler is not invoked again 173846cc04521acf2827eb33310fadc119bf2dc039e4florian In other words: if in doubt, save it away. 173946cc04521acf2827eb33310fadc119bf2dc039e4florian Also, the returned string is owned by "somebody else". Callers must 174046cc04521acf2827eb33310fadc119bf2dc039e4florian not free it or modify it. */ 1741eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjstatic 17426b7611bf42a0fbb62e047d8c43b008205bd21e75njnBool get_sym_name ( Bool do_cxx_demangling, Bool do_z_demangling, 17436b7611bf42a0fbb62e047d8c43b008205bd21e75njn Bool do_below_main_renaming, 174446cc04521acf2827eb33310fadc119bf2dc039e4florian Addr a, const HChar** buf, 1745b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool match_anywhere_in_sym, Bool show_offset, 1746c4431bfe04c7490ea2d74939d222d87f13f30960njn Bool findText, /*OUT*/PtrdiffT* offsetP ) 1747eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1748b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1749f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1750c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT offset; 1751eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1752b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj search_all_symtabs ( a, &di, &sno, match_anywhere_in_sym, findText ); 175346cc04521acf2827eb33310fadc119bf2dc039e4florian if (di == NULL) { 175446cc04521acf2827eb33310fadc119bf2dc039e4florian *buf = ""; 1755eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 175646cc04521acf2827eb33310fadc119bf2dc039e4florian } 17576882443ef154bca367bc591287de641e43a9e108njn 1758a5cace0c2a3e212931badbf6398a0cd98393121asewardj vg_assert(di->symtab[sno].pri_name); 17596b7611bf42a0fbb62e047d8c43b008205bd21e75njn VG_(demangle) ( do_cxx_demangling, do_z_demangling, 176046cc04521acf2827eb33310fadc119bf2dc039e4florian di->symtab[sno].pri_name, buf ); 17616b7611bf42a0fbb62e047d8c43b008205bd21e75njn 17626b7611bf42a0fbb62e047d8c43b008205bd21e75njn /* Do the below-main hack */ 17636b7611bf42a0fbb62e047d8c43b008205bd21e75njn // To reduce the endless nuisance of multiple different names 17646b7611bf42a0fbb62e047d8c43b008205bd21e75njn // for "the frame below main()" screwing up the testsuite, change all 17656b7611bf42a0fbb62e047d8c43b008205bd21e75njn // known incarnations of said into a single name, "(below main)", if 17666b7611bf42a0fbb62e047d8c43b008205bd21e75njn // --show-below-main=yes. 17676b7611bf42a0fbb62e047d8c43b008205bd21e75njn if ( do_below_main_renaming && ! VG_(clo_show_below_main) && 176846cc04521acf2827eb33310fadc119bf2dc039e4florian Vg_FnNameBelowMain == VG_(get_fnname_kind)(*buf) ) 17696b7611bf42a0fbb62e047d8c43b008205bd21e75njn { 177046cc04521acf2827eb33310fadc119bf2dc039e4florian *buf = "(below main)"; 1771eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 17724cace66777ca9ee73ea156210c04e9d4cc178395philippe offset = a - di->symtab[sno].avmas.main; 1773c4431bfe04c7490ea2d74939d222d87f13f30960njn if (offsetP) *offsetP = offset; 1774b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1775eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (show_offset && offset != 0) { 177646cc04521acf2827eb33310fadc119bf2dc039e4florian static HChar *bufwo; // buf with offset 177746cc04521acf2827eb33310fadc119bf2dc039e4florian static SizeT bufwo_szB; 177846cc04521acf2827eb33310fadc119bf2dc039e4florian SizeT need, len; 177946cc04521acf2827eb33310fadc119bf2dc039e4florian 178046cc04521acf2827eb33310fadc119bf2dc039e4florian len = VG_(strlen)(*buf); 178146cc04521acf2827eb33310fadc119bf2dc039e4florian need = len + 1 + 19 + 1; 178246cc04521acf2827eb33310fadc119bf2dc039e4florian if (need > bufwo_szB) { 178346cc04521acf2827eb33310fadc119bf2dc039e4florian bufwo = ML_(dinfo_realloc)("get_sym_size", bufwo, need); 178446cc04521acf2827eb33310fadc119bf2dc039e4florian bufwo_szB = need; 1785eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 1786eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 178746cc04521acf2827eb33310fadc119bf2dc039e4florian VG_(strcpy)(bufwo, *buf); 178846cc04521acf2827eb33310fadc119bf2dc039e4florian VG_(sprintf)(bufwo + len, "%c%ld", 178946cc04521acf2827eb33310fadc119bf2dc039e4florian offset < 0 ? '-' : '+', 179046cc04521acf2827eb33310fadc119bf2dc039e4florian offset < 0 ? -offset : offset); 179146cc04521acf2827eb33310fadc119bf2dc039e4florian *buf = bufwo; 179246cc04521acf2827eb33310fadc119bf2dc039e4florian } 17936b7611bf42a0fbb62e047d8c43b008205bd21e75njn 1794eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 1795eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1796eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1797cae0cc22b83ffb260ee8379e92099c5a701944cbcarll/* ppc64be-linux only: find the TOC pointer (R2 value) that should be in 1798eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj force at the entry point address of the function containing 1799eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj guest_code_addr. Returns 0 if not known. */ 1800eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjAddr VG_(get_tocptr) ( Addr guest_code_addr ) 1801eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 18024cace66777ca9ee73ea156210c04e9d4cc178395philippe#if defined(VGA_ppc64be) || defined(VGA_ppc64le) 1803b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 1804f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word sno; 1805eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_symtabs ( guest_code_addr, 1806b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj &si, &sno, 1807b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj True/*match_anywhere_in_fun*/, 1808b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj True/*consider text symbols only*/ ); 1809eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 1810eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return 0; 1811eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj else 18124cace66777ca9ee73ea156210c04e9d4cc178395philippe return GET_TOCPTR_AVMA(si->symtab[sno].avmas); 18134cace66777ca9ee73ea156210c04e9d4cc178395philippe#else 18144cace66777ca9ee73ea156210c04e9d4cc178395philippe return 0; 18154cace66777ca9ee73ea156210c04e9d4cc178395philippe#endif 1816eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1817eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1818eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 181946cc04521acf2827eb33310fadc119bf2dc039e4florian match anywhere in function, but don't show offsets. 182046cc04521acf2827eb33310fadc119bf2dc039e4florian NOTE: See important comment about the persistence and memory ownership 182146cc04521acf2827eb33310fadc119bf2dc039e4florian of the return string at function get_sym_name */ 182246cc04521acf2827eb33310fadc119bf2dc039e4florianBool VG_(get_fnname) ( Addr a, const HChar** buf ) 1823eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 18246b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, 18256b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 182646cc04521acf2827eb33310fadc119bf2dc039e4florian a, buf, 1827b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1828b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1829b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1830b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1831eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1832eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1833eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 183446cc04521acf2827eb33310fadc119bf2dc039e4florian match anywhere in function, and show offset if nonzero. 183546cc04521acf2827eb33310fadc119bf2dc039e4florian NOTE: See important comment about the persistence and memory ownership 183646cc04521acf2827eb33310fadc119bf2dc039e4florian of the return string at function get_sym_name */ 183746cc04521acf2827eb33310fadc119bf2dc039e4florianBool VG_(get_fnname_w_offset) ( Addr a, const HChar** buf ) 1838eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 18396b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, 18406b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 184146cc04521acf2827eb33310fadc119bf2dc039e4florian a, buf, 1842b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1843b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/True, 1844b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1845b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1846eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1847eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1848eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is available to tools... always demangle C++ names, 1849eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj only succeed if 'a' matches first instruction of function, 185046cc04521acf2827eb33310fadc119bf2dc039e4florian and don't show offsets. 185146cc04521acf2827eb33310fadc119bf2dc039e4florian NOTE: See important comment about the persistence and memory ownership 185246cc04521acf2827eb33310fadc119bf2dc039e4florian of the return string at function get_sym_name */ 185346cc04521acf2827eb33310fadc119bf2dc039e4florianBool VG_(get_fnname_if_entry) ( Addr a, const HChar** buf ) 1854eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1855dc4ff1a019a3e54d3e5517514b7e683cb2071829florian const HChar *tmp; 1856dc4ff1a019a3e54d3e5517514b7e683cb2071829florian Bool res; 1857dc4ff1a019a3e54d3e5517514b7e683cb2071829florian 1858dc4ff1a019a3e54d3e5517514b7e683cb2071829florian res = get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, 18596b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/True, 1860dc4ff1a019a3e54d3e5517514b7e683cb2071829florian a, &tmp, 1861b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/False, 1862b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1863b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1864b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1865dc4ff1a019a3e54d3e5517514b7e683cb2071829florian if (res) 1866dc4ff1a019a3e54d3e5517514b7e683cb2071829florian *buf = tmp; 1867dc4ff1a019a3e54d3e5517514b7e683cb2071829florian return res; 1868eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1869eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 18706b7611bf42a0fbb62e047d8c43b008205bd21e75njn/* This is only available to core... don't C++-demangle, don't Z-demangle, 18716b7611bf42a0fbb62e047d8c43b008205bd21e75njn don't rename below-main, match anywhere in function, and don't show 187246cc04521acf2827eb33310fadc119bf2dc039e4florian offsets. 187346cc04521acf2827eb33310fadc119bf2dc039e4florian NOTE: See important comment about the persistence and memory ownership 187446cc04521acf2827eb33310fadc119bf2dc039e4florian of the return string at function get_sym_name */ 187546cc04521acf2827eb33310fadc119bf2dc039e4florianBool VG_(get_fnname_raw) ( Addr a, const HChar** buf ) 1876eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 18776b7611bf42a0fbb62e047d8c43b008205bd21e75njn return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, 18786b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/False, 187946cc04521acf2827eb33310fadc119bf2dc039e4florian a, buf, 1880b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_fun*/True, 1881b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1882b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*text syms only*/True, 1883b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*offsetP*/NULL ); 1884eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1885eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 1886eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* This is only available to core... don't demangle C++ names, but do 18876b7611bf42a0fbb62e047d8c43b008205bd21e75njn do Z-demangling and below-main-renaming, match anywhere in function, and 188846cc04521acf2827eb33310fadc119bf2dc039e4florian don't show offsets. 188946cc04521acf2827eb33310fadc119bf2dc039e4florian NOTE: See important comment about the persistence and memory ownership 189046cc04521acf2827eb33310fadc119bf2dc039e4florian of the return string at function get_sym_name */ 189146cc04521acf2827eb33310fadc119bf2dc039e4florianBool VG_(get_fnname_no_cxx_demangle) ( Addr a, const HChar** buf, 189246cc04521acf2827eb33310fadc119bf2dc039e4florian const InlIPCursor* iipc ) 1893eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1894a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (is_bottom(iipc)) { 1895a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // At the bottom (towards main), we describe the fn at eip. 1896a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/True, 1897a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*below-main-renaming*/True, 189846cc04521acf2827eb33310fadc119bf2dc039e4florian a, buf, 1899a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*match_anywhere_in_fun*/True, 1900a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*show offset?*/False, 1901a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*text syms only*/True, 1902a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe /*offsetP*/NULL ); 1903a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } else { 1904a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe const DiInlLoc *next_inl = iipc && iipc->next_inltab >= 0 1905a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ? & iipc->di->inltab[iipc->next_inltab] 1906a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe : NULL; 1907a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (next_inl); 1908a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // The function we are in is called by next_inl. 190946cc04521acf2827eb33310fadc119bf2dc039e4florian *buf = next_inl->inlinedfn; 1910a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe return True; 1911a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 1912eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 1913eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 19145db15403e889d4db339b342bc2a824ef0bfaa654sewardj/* mips-linux only: find the offset of current address. This is needed for 19155db15403e889d4db339b342bc2a824ef0bfaa654sewardj stack unwinding for MIPS. 19165db15403e889d4db339b342bc2a824ef0bfaa654sewardj*/ 19175db15403e889d4db339b342bc2a824ef0bfaa654sewardjBool VG_(get_inst_offset_in_function)( Addr a, 19185db15403e889d4db339b342bc2a824ef0bfaa654sewardj /*OUT*/PtrdiffT* offset ) 19195db15403e889d4db339b342bc2a824ef0bfaa654sewardj{ 192046cc04521acf2827eb33310fadc119bf2dc039e4florian const HChar *fnname; 19215db15403e889d4db339b342bc2a824ef0bfaa654sewardj return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, 19225db15403e889d4db339b342bc2a824ef0bfaa654sewardj /*below-main-renaming*/False, 192346cc04521acf2827eb33310fadc119bf2dc039e4florian a, &fnname, 19245db15403e889d4db339b342bc2a824ef0bfaa654sewardj /*match_anywhere_in_sym*/True, 192581208182df4e8b9c8642affd6754996777ee7556florian /*show offset?*/False, 19264afac5b6f637d1cea82e62b3a280fa4e81101c05petarj /*text syms only*/True, 19275db15403e889d4db339b342bc2a824ef0bfaa654sewardj offset ); 19285db15403e889d4db339b342bc2a824ef0bfaa654sewardj} 19295db15403e889d4db339b342bc2a824ef0bfaa654sewardj 193046cc04521acf2827eb33310fadc119bf2dc039e4florianVg_FnNameKind VG_(get_fnname_kind) ( const HChar* name ) 19316882443ef154bca367bc591287de641e43a9e108njn{ 19326882443ef154bca367bc591287de641e43a9e108njn if (VG_STREQ("main", name)) { 19336882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameMain; 19346882443ef154bca367bc591287de641e43a9e108njn 19356882443ef154bca367bc591287de641e43a9e108njn } else if ( 19363026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGO_linux) 19376882443ef154bca367bc591287de641e43a9e108njn VG_STREQ("__libc_start_main", name) || // glibc glibness 19386882443ef154bca367bc591287de641e43a9e108njn VG_STREQ("generic_start_main", name) || // Yellow Dog doggedness 19393026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGO_darwin) 1940f76d27a697a7b0bf3b84490baf60623fc96a23afnjn // See readmacho.c for an explanation of this. 1941f76d27a697a7b0bf3b84490baf60623fc96a23afnjn VG_STREQ("start_according_to_valgrind", name) || // Darwin, darling 19423026f71684a930286186aa10fef266c304672e8fsewardj# else 19433026f71684a930286186aa10fef266c304672e8fsewardj# error "Unknown OS" 19443026f71684a930286186aa10fef266c304672e8fsewardj# endif 19456882443ef154bca367bc591287de641e43a9e108njn 0) { 19466882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameBelowMain; 19476882443ef154bca367bc591287de641e43a9e108njn 19486882443ef154bca367bc591287de641e43a9e108njn } else { 19496882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameNormal; 19506882443ef154bca367bc591287de641e43a9e108njn } 19516882443ef154bca367bc591287de641e43a9e108njn} 19526882443ef154bca367bc591287de641e43a9e108njn 19536882443ef154bca367bc591287de641e43a9e108njnVg_FnNameKind VG_(get_fnname_kind_from_IP) ( Addr ip ) 19546882443ef154bca367bc591287de641e43a9e108njn{ 195546cc04521acf2827eb33310fadc119bf2dc039e4florian const HChar *buf; 19566882443ef154bca367bc591287de641e43a9e108njn 19576882443ef154bca367bc591287de641e43a9e108njn // We don't demangle, because it's faster not to, and the special names 19587d995792542cf8e7f5a81248589445adfffeae30florian // we're looking for won't be mangled. 195946cc04521acf2827eb33310fadc119bf2dc039e4florian if (VG_(get_fnname_raw) ( ip, &buf )) { 196046cc04521acf2827eb33310fadc119bf2dc039e4florian 19616882443ef154bca367bc591287de641e43a9e108njn return VG_(get_fnname_kind)(buf); 19626882443ef154bca367bc591287de641e43a9e108njn } else { 19636882443ef154bca367bc591287de641e43a9e108njn return Vg_FnNameNormal; // Don't know the name, treat it as normal. 19646882443ef154bca367bc591287de641e43a9e108njn } 19656882443ef154bca367bc591287de641e43a9e108njn} 19666882443ef154bca367bc591287de641e43a9e108njn 1967b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Looks up data_addr in the collection of data symbols, and if found 196846cc04521acf2827eb33310fadc119bf2dc039e4florian puts a pointer to its name into dname. The name is zero terminated. 196946cc04521acf2827eb33310fadc119bf2dc039e4florian Also data_addr's offset from the symbol start is put into *offset. 197046cc04521acf2827eb33310fadc119bf2dc039e4florian NOTE: See important comment about the persistence and memory ownership 197146cc04521acf2827eb33310fadc119bf2dc039e4florian of the return string at function get_sym_name */ 1972b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool VG_(get_datasym_and_offset)( Addr data_addr, 197346cc04521acf2827eb33310fadc119bf2dc039e4florian /*OUT*/const HChar** dname, 1974c4431bfe04c7490ea2d74939d222d87f13f30960njn /*OUT*/PtrdiffT* offset ) 1975b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 197646cc04521acf2827eb33310fadc119bf2dc039e4florian return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, 19776b7611bf42a0fbb62e047d8c43b008205bd21e75njn /*below-main-renaming*/False, 197846cc04521acf2827eb33310fadc119bf2dc039e4florian data_addr, dname, 1979b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*match_anywhere_in_sym*/True, 1980b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*show offset?*/False, 1981b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /*data syms only please*/False, 1982b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset ); 1983b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 1984b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 1985b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Map a code address to the name of a shared object file or the 198646cc04521acf2827eb33310fadc119bf2dc039e4florian executable. Returns False if no idea; otherwise True. 198746cc04521acf2827eb33310fadc119bf2dc039e4florian Note: the string returned in *BUF is persistent as long as 198846cc04521acf2827eb33310fadc119bf2dc039e4florian (1) the DebugInfo it belongs to is not discarded 198946cc04521acf2827eb33310fadc119bf2dc039e4florian (2) the segment containing the address is not merged with another segment 199046cc04521acf2827eb33310fadc119bf2dc039e4florian*/ 199146cc04521acf2827eb33310fadc119bf2dc039e4florianBool VG_(get_objname) ( Addr a, const HChar** buf ) 1992eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 1993b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 1994f32ec7f0de8a651bc16a1b2e448c0106d8669889tom const NSegment *seg; 19953297124fa2116737066ac3cd709f18fdd5405163florian const HChar* filename; 199646cc04521acf2827eb33310fadc119bf2dc039e4florian 19977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Look in the debugInfo_list to find the name. In most cases we 19987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj expect this to produce a result. */ 1999b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 2000b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 20015706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->text_size > 0 2002b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= a 2003b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a < di->text_avma + di->text_size) { 200446cc04521acf2827eb33310fadc119bf2dc039e4florian *buf = di->fsm.filename; 2005eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 2006eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2007eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 20087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Last-ditch fallback position: if we don't find the address in 20097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj the debugInfo_list, ask the address space manager whether it 20107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj knows the name of the file associated with this mapping. This 20117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj allows us to print the names of exe/dll files in the stack trace 20127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj when running programs under wine. */ 20137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj if ( (seg = VG_(am_find_nsegment(a))) != NULL 20147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj && (filename = VG_(am_get_filename)(seg)) != NULL ) { 201546cc04521acf2827eb33310fadc119bf2dc039e4florian *buf = filename; 2016f32ec7f0de8a651bc16a1b2e448c0106d8669889tom return True; 2017f32ec7f0de8a651bc16a1b2e448c0106d8669889tom } 2018eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 2019eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2020eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2021b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Map a code address to its DebugInfo. Returns NULL if not found. Doesn't 2022eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj require debug info. */ 2023e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjDebugInfo* VG_(find_DebugInfo) ( Addr a ) 2024eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2025e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj static UWord n_search = 0; 2026b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 2027e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj n_search++; 2028b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 2029b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 20305706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->text_size > 0 2031b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_avma <= a 2032b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a < di->text_avma + di->text_size) { 2033e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj if (0 == (n_search & 0xF)) 2034e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj move_DebugInfo_one_step_forward( di ); 2035b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di; 2036eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2037eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2038eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return NULL; 2039eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2040eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 204110ef725f1e8e9f1615c483555348eb75b69c4713florian/* Map a code address to a filename. Returns True if successful. The 204210ef725f1e8e9f1615c483555348eb75b69c4713florian returned string is persistent as long as the DebugInfo to which it 204310ef725f1e8e9f1615c483555348eb75b69c4713florian belongs is not discarded. */ 204410ef725f1e8e9f1615c483555348eb75b69c4713florianBool VG_(get_filename)( Addr a, const HChar** filename ) 2045eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2046b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 2047f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 204859e1f3c79e870a978d24add86db6d8c5450c8b63philippe UInt fndn_ix; 204959e1f3c79e870a978d24add86db6d8c5450c8b63philippe 2050eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 2051eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 2052eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 205359e1f3c79e870a978d24add86db6d8c5450c8b63philippe fndn_ix = ML_(fndn_ix) (si, locno); 205410ef725f1e8e9f1615c483555348eb75b69c4713florian *filename = ML_(fndn_ix2filename) (si, fndn_ix); 2055eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 2056eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2057eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2058eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a line number. Returns True if successful. */ 2059eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_linenum)( Addr a, UInt* lineno ) 2060eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2061b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 2062f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 2063eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 2064eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (si == NULL) 2065eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 2066eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *lineno = si->loctab[locno].lineno; 2067eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2068eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 2069eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2070eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2071eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/* Map a code address to a filename/line number/dir name info. 2072eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj See prototype for detailed description of behaviour. 2073eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj*/ 2074eadcd86d1b0f59efed44c162ef4378ccfb528290sewardjBool VG_(get_filename_linenum) ( Addr a, 207510ef725f1e8e9f1615c483555348eb75b69c4713florian /*OUT*/const HChar** filename, 207610ef725f1e8e9f1615c483555348eb75b69c4713florian /*OUT*/const HChar** dirname, 2077eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /*OUT*/UInt* lineno ) 2078eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2079b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* si; 2080f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word locno; 208159e1f3c79e870a978d24add86db6d8c5450c8b63philippe UInt fndn_ix; 2082eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2083eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj search_all_loctabs ( a, &si, &locno ); 2084c1b1d421216369aec58867ce1c5b99cfb1703c36njn if (si == NULL) { 2085f4384f47ee6b6234dba548a775585c37af712edfflorian if (dirname) { 208610ef725f1e8e9f1615c483555348eb75b69c4713florian *dirname = ""; 2087db5c6571454c1f647a4c67593805a8e401cd14c5njn } 208810ef725f1e8e9f1615c483555348eb75b69c4713florian *filename = ""; // this used to be not initialised.... 2089eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; 2090c1b1d421216369aec58867ce1c5b99cfb1703c36njn } 2091c1b1d421216369aec58867ce1c5b99cfb1703c36njn 209259e1f3c79e870a978d24add86db6d8c5450c8b63philippe fndn_ix = ML_(fndn_ix)(si, locno); 209310ef725f1e8e9f1615c483555348eb75b69c4713florian *filename = ML_(fndn_ix2filename) (si, fndn_ix); 2094eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj *lineno = si->loctab[locno].lineno; 2095eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2096eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (dirname) { 2097eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* caller wants directory info too .. */ 209810ef725f1e8e9f1615c483555348eb75b69c4713florian *dirname = ML_(fndn_ix2dirname) (si, fndn_ix); 2099eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2100eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2101eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 2102eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2103eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2104eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 21054ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj/* Map a function name to its entry point and toc pointer. Is done by 21064ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj sequential search of all symbol tables, so is very slow. To 21074ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj mitigate the worst performance effects, you may specify a soname 21084ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj pattern, and only objects matching that pattern are searched. 21094ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Therefore specify "*" to search all the objects. On TOC-afflicted 21104ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj platforms, a symbol is deemed to be found only if it has a nonzero 21114ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj TOC pointer. */ 2112518850bf0da07ed3e2244e307268ae0fd80e93a8florianBool VG_(lookup_symbol_SLOW)(const HChar* sopatt, const HChar* name, 2113518850bf0da07ed3e2244e307268ae0fd80e93a8florian SymAVMAs* avmas) 21144ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj{ 21154ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool require_pToc = False; 21164ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Int i; 2117518850bf0da07ed3e2244e307268ae0fd80e93a8florian const DebugInfo* si; 21184ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj Bool debug = False; 21194ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# if defined(VG_PLAT_USES_PPCTOC) 21204ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj require_pToc = True; 21214ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj# endif 2122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (si = debugInfo_list; si; si = si->next) { 21234ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (debug) 21244ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(printf)("lookup_symbol_SLOW: considering %s\n", si->soname); 21254ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (!VG_(string_match)(sopatt, si->soname)) { 21264ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj if (debug) 21274ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj VG_(printf)(" ... skip\n"); 21284ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj continue; 21294ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 21304ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj for (i = 0; i < si->symtab_used; i++) { 21311ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian const HChar* pri_name = si->symtab[i].pri_name; 2132e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(pri_name); 2133a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (0==VG_(strcmp)(name, pri_name) 21344cace66777ca9ee73ea156210c04e9d4cc178395philippe && (require_pToc ? GET_TOCPTR_AVMA(si->symtab[i].avmas) : True)) { 21354cace66777ca9ee73ea156210c04e9d4cc178395philippe *avmas = si->symtab[i].avmas; 21364ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj return True; 21374ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 21381ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian const HChar** sec_names = si->symtab[i].sec_names; 2139a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (sec_names) { 2140e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(sec_names[0]); 2141a5cace0c2a3e212931badbf6398a0cd98393121asewardj while (*sec_names) { 2142a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (0==VG_(strcmp)(name, *sec_names) 21434cace66777ca9ee73ea156210c04e9d4cc178395philippe && (require_pToc 21444cace66777ca9ee73ea156210c04e9d4cc178395philippe ? GET_TOCPTR_AVMA(si->symtab[i].avmas) : True)) { 21454cace66777ca9ee73ea156210c04e9d4cc178395philippe *avmas = si->symtab[i].avmas; 2146a5cace0c2a3e212931badbf6398a0cd98393121asewardj return True; 2147a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 2148a5cace0c2a3e212931badbf6398a0cd98393121asewardj sec_names++; 2149a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 2150a5cace0c2a3e212931badbf6398a0cd98393121asewardj } 21514ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 21524ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj } 21534ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj return False; 21544ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj} 21554ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 21564ee4f98c6dd3dd9517954efc628753bf46811d2dsewardj 2157770a8d23e40b980b5745e59ecb8e4037d81af357florian/* VG_(describe_IP): return info on code address, function name and 2158770a8d23e40b980b5745e59ecb8e4037d81af357florian filename. The returned string is allocated in a static buffer and will 2159770a8d23e40b980b5745e59ecb8e4037d81af357florian be overwritten in the next invocation. */ 2160eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2161770a8d23e40b980b5745e59ecb8e4037d81af357florian/* Copy str into *buf starting at n, ensuring that buf is zero-terminated. 2162770a8d23e40b980b5745e59ecb8e4037d81af357florian Return the index of the terminating null character. */ 2163770a8d23e40b980b5745e59ecb8e4037d81af357florianstatic SizeT 2164770a8d23e40b980b5745e59ecb8e4037d81af357florianputStr( SizeT n, HChar** buf, SizeT *bufsiz, const HChar* str ) 2165eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2166770a8d23e40b980b5745e59ecb8e4037d81af357florian SizeT slen = VG_(strlen)(str); 2167770a8d23e40b980b5745e59ecb8e4037d81af357florian SizeT need = n + slen + 1; 2168e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 2169770a8d23e40b980b5745e59ecb8e4037d81af357florian if (need > *bufsiz) { 2170770a8d23e40b980b5745e59ecb8e4037d81af357florian if (need < 256) need = 256; 2171770a8d23e40b980b5745e59ecb8e4037d81af357florian *bufsiz = need; 2172770a8d23e40b980b5745e59ecb8e4037d81af357florian *buf = ML_(dinfo_realloc)("putStr", *buf, *bufsiz); 2173770a8d23e40b980b5745e59ecb8e4037d81af357florian } 2174e872fec0c1c3b478a399fdba42ac65764b53f470sewardj 2175770a8d23e40b980b5745e59ecb8e4037d81af357florian VG_(strcpy)(*buf + n, str); 2176770a8d23e40b980b5745e59ecb8e4037d81af357florian 2177770a8d23e40b980b5745e59ecb8e4037d81af357florian return n + slen; 2178770a8d23e40b980b5745e59ecb8e4037d81af357florian} 2179770a8d23e40b980b5745e59ecb8e4037d81af357florian 2180770a8d23e40b980b5745e59ecb8e4037d81af357florian/* Same as putStr, but escaping chars for XML output. */ 2181770a8d23e40b980b5745e59ecb8e4037d81af357florianstatic SizeT 2182770a8d23e40b980b5745e59ecb8e4037d81af357florianputStrEsc( SizeT n, HChar** buf, SizeT *bufsiz, const HChar* str ) 2183eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 21841636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar alt[2]; 2185770a8d23e40b980b5745e59ecb8e4037d81af357florian 2186eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj for (; *str != 0; str++) { 2187eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj switch (*str) { 2188e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '&': 2189770a8d23e40b980b5745e59ecb8e4037d81af357florian n = putStr( n, buf, bufsiz, "&"); 2190e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 2191e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '<': 2192770a8d23e40b980b5745e59ecb8e4037d81af357florian n = putStr( n, buf, bufsiz, "<"); 2193e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 2194e872fec0c1c3b478a399fdba42ac65764b53f470sewardj case '>': 2195770a8d23e40b980b5745e59ecb8e4037d81af357florian n = putStr( n, buf, bufsiz, ">"); 2196e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 2197e872fec0c1c3b478a399fdba42ac65764b53f470sewardj default: 2198e872fec0c1c3b478a399fdba42ac65764b53f470sewardj alt[0] = *str; 2199e872fec0c1c3b478a399fdba42ac65764b53f470sewardj alt[1] = 0; 2200770a8d23e40b980b5745e59ecb8e4037d81af357florian n = putStr( n, buf, bufsiz, alt ); 2201e872fec0c1c3b478a399fdba42ac65764b53f470sewardj break; 2202eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2203eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2204eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return n; 2205eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2206eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2207770a8d23e40b980b5745e59ecb8e4037d81af357florianconst HChar* VG_(describe_IP)(Addr eip, const InlIPCursor *iipc) 2208eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 2209770a8d23e40b980b5745e59ecb8e4037d81af357florian static HChar *buf = NULL; 2210770a8d23e40b980b5745e59ecb8e4037d81af357florian static SizeT bufsiz = 0; 2211eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define APPEND(_str) \ 2212770a8d23e40b980b5745e59ecb8e4037d81af357florian n = putStr(n, &buf, &bufsiz, _str) 2213770a8d23e40b980b5745e59ecb8e4037d81af357florian# define APPEND_ESC(_str) \ 2214770a8d23e40b980b5745e59ecb8e4037d81af357florian n = putStrEsc(n, &buf, &bufsiz, _str) 2215eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2216eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj UInt lineno; 2217770a8d23e40b980b5745e59ecb8e4037d81af357florian HChar ibuf[50]; // large enough 2218770a8d23e40b980b5745e59ecb8e4037d81af357florian SizeT n = 0; 221914cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj 2220a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (!iipc || iipc->eip == eip); 2221a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2222770a8d23e40b980b5745e59ecb8e4037d81af357florian const HChar *buf_fn; 2223770a8d23e40b980b5745e59ecb8e4037d81af357florian const HChar *buf_obj; 2224770a8d23e40b980b5745e59ecb8e4037d81af357florian const HChar *buf_srcloc; 2225770a8d23e40b980b5745e59ecb8e4037d81af357florian const HChar *buf_dirname; 222614cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj 222725148a6f2d895ee7005a69395427a4c9753f089dflorian Bool know_dirinfo; 2228a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Bool know_fnname; 2229a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Bool know_objname; 2230a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe Bool know_srcloc; 2231a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2232a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (is_bottom(iipc)) { 2233a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // At the bottom (towards main), we describe the fn at eip. 2234a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe know_fnname = VG_(clo_sym_offsets) 223546cc04521acf2827eb33310fadc119bf2dc039e4florian ? VG_(get_fnname_w_offset) (eip, &buf_fn) 223646cc04521acf2827eb33310fadc119bf2dc039e4florian : VG_(get_fnname) (eip, &buf_fn); 2237a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } else { 2238a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe const DiInlLoc *next_inl = iipc && iipc->next_inltab >= 0 2239a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ? & iipc->di->inltab[iipc->next_inltab] 2240a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe : NULL; 2241a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (next_inl); 2242a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // The function we are in is called by next_inl. 2243770a8d23e40b980b5745e59ecb8e4037d81af357florian buf_fn = next_inl->inlinedfn; 2244a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe know_fnname = True; 2245a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2246a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // INLINED???? 2247a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // ??? Can we compute an offset for an inlined fn call ? 2248a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // ??? Offset from what ? The beginning of the inl info ? 2249a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // ??? But that is not necessarily the beginning of the fn 2250a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // ??? as e.g. an inlined fn call can be in several ranges. 2251a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // ??? Currently never showing an offset. 2252a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 2253a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 225446cc04521acf2827eb33310fadc119bf2dc039e4florian know_objname = VG_(get_objname)(eip, &buf_obj); 2255a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2256a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe if (is_top(iipc)) { 2257a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe // The source for the highest level is in the loctab entry. 2258a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe know_srcloc = VG_(get_filename_linenum)( 2259a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe eip, 226010ef725f1e8e9f1615c483555348eb75b69c4713florian &buf_srcloc, 2261f4384f47ee6b6234dba548a775585c37af712edfflorian &buf_dirname, 2262a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe &lineno 2263a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ); 2264f4384f47ee6b6234dba548a775585c37af712edfflorian know_dirinfo = buf_dirname[0] != '\0'; 2265a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } else { 2266a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe const DiInlLoc *cur_inl = iipc && iipc->cur_inltab >= 0 2267a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe ? & iipc->di->inltab[iipc->cur_inltab] 2268a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe : NULL; 2269a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe vg_assert (cur_inl); 2270a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 227159e1f3c79e870a978d24add86db6d8c5450c8b63philippe know_dirinfo = False; 227225148a6f2d895ee7005a69395427a4c9753f089dflorian buf_dirname = ""; 2273666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe // The fndn_ix and lineno for the caller of the inlined fn is in cur_inl. 2274666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe if (cur_inl->fndn_ix == 0) { 227510ef725f1e8e9f1615c483555348eb75b69c4713florian buf_srcloc = "???"; 2276666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe } else { 2277666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe FnDn *fndn = VG_(indexEltNumber) (iipc->di->fndnpool, 2278666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe cur_inl->fndn_ix); 2279666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe if (fndn->dirname) { 228010ef725f1e8e9f1615c483555348eb75b69c4713florian buf_dirname = fndn->dirname; 2281666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe know_dirinfo = True; 2282666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe } 228310ef725f1e8e9f1615c483555348eb75b69c4713florian buf_srcloc = fndn->filename; 2284666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe } 2285666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe lineno = cur_inl->lineno; 2286a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe know_srcloc = True; 2287a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe } 2288a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe 2289eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (VG_(clo_xml)) { 2290eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2291eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Bool human_readable = True; 22926bd9dc18c043927c1196caba20a327238a179c42florian const HChar* maybe_newline = human_readable ? "\n " : ""; 22936bd9dc18c043927c1196caba20a327238a179c42florian const HChar* maybe_newline2 = human_readable ? "\n " : ""; 2294eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2295e872fec0c1c3b478a399fdba42ac65764b53f470sewardj /* Print in XML format, dumping in as much info as we know. 2296770a8d23e40b980b5745e59ecb8e4037d81af357florian Ensure all tags are balanced. */ 2297eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<frame>"); 2298a44b15f527bbebfe824a2e68e4bd6ab1e153b486sewardj VG_(sprintf)(ibuf,"<ip>0x%llX</ip>", (ULong)eip); 2299eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2300eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 2301eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_objname) { 2302eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2303eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<obj>"); 2304770a8d23e40b980b5745e59ecb8e4037d81af357florian APPEND_ESC(buf_obj); 2305eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</obj>"); 2306eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2307eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_fnname) { 2308eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2309eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<fn>"); 2310770a8d23e40b980b5745e59ecb8e4037d81af357florian APPEND_ESC(buf_fn); 2311eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</fn>"); 2312eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2313eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_srcloc) { 2314eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_dirinfo) { 2315eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2316eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<dir>"); 2317770a8d23e40b980b5745e59ecb8e4037d81af357florian APPEND_ESC(buf_dirname); 2318eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</dir>"); 2319eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2320eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2321eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<file>"); 2322770a8d23e40b980b5745e59ecb8e4037d81af357florian APPEND_ESC(buf_srcloc); 2323eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</file>"); 2324eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline); 2325eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("<line>"); 2326eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(sprintf)(ibuf,"%d",lineno); 2327eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 2328eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</line>"); 2329eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2330eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(maybe_newline2); 2331eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("</frame>"); 2332eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2333eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 2334eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2335eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj /* Print for humans to read */ 23365e40abad4504416c59f0b29c1cfc8087201213a9njn // 23375e40abad4504416c59f0b29c1cfc8087201213a9njn // Possible forms: 23385e40abad4504416c59f0b29c1cfc8087201213a9njn // 23395e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: really (a.c:20) 23405e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: really (in /foo/a.out) 23415e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: really (in ???) 23425e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: ??? (in /foo/a.out) 23435e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: ??? (a.c:20) 23445e40abad4504416c59f0b29c1cfc8087201213a9njn // 0x80483BF: ??? 23455e40abad4504416c59f0b29c1cfc8087201213a9njn // 2346a44b15f527bbebfe824a2e68e4bd6ab1e153b486sewardj VG_(sprintf)(ibuf,"0x%llX: ", (ULong)eip); 2347eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 23485e40abad4504416c59f0b29c1cfc8087201213a9njn if (know_fnname) { 2349eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(buf_fn); 2350eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } else { 2351eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND("???"); 2352eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2353eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (know_srcloc) { 2354eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(" ("); 235514cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // Get the directory name, if any, possibly pruned, into dirname. 235610ef725f1e8e9f1615c483555348eb75b69c4713florian const HChar* dirname = NULL; 235725148a6f2d895ee7005a69395427a4c9753f089dflorian if (know_dirinfo && VG_(sizeXA)(VG_(clo_fullpath_after)) > 0) { 235814cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj Int i; 235914cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj dirname = buf_dirname; 236014cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // Remove leading prefixes from the dirname. 236114cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // If user supplied --fullpath-after=foo, this will remove 236214cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // a leading string which matches '.*foo' (not greedy). 23637931627282eede4440f3f329b657c3ec68371e8aflorian for (i = 0; i < VG_(sizeXA)(VG_(clo_fullpath_after)); i++) { 23647931627282eede4440f3f329b657c3ec68371e8aflorian const HChar* prefix = 23657931627282eede4440f3f329b657c3ec68371e8aflorian *(HChar**) VG_(indexXA)( VG_(clo_fullpath_after), i ); 23661636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar* str = VG_(strstr)(dirname, prefix); 236714cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj if (str) { 236814cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj dirname = str + VG_(strlen)(prefix); 236914cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj break; 237014cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj } 237114cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj } 237214cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj /* remove leading "./" */ 237314cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj if (dirname[0] == '.' && dirname[1] == '/') 237414cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj dirname += 2; 237514cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj } 237614cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // do we have any interesting directory name to show? If so 237714cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj // add it in. 237814cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj if (dirname && dirname[0] != 0) { 237914cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj APPEND(dirname); 238014cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardj APPEND("/"); 23815dd0190bc0ea66f8ffa7218c66f5a2e1c7b51b30bart } 2382eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(buf_srcloc); 2383eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(":"); 2384eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj VG_(sprintf)(ibuf,"%d",lineno); 2385eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(ibuf); 2386eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj APPEND(")"); 23875e40abad4504416c59f0b29c1cfc8087201213a9njn } else if (know_objname) { 23885e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(" (in "); 23895e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(buf_obj); 23905e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(")"); 23915e40abad4504416c59f0b29c1cfc8087201213a9njn } else if (know_fnname) { 23925e40abad4504416c59f0b29c1cfc8087201213a9njn // Nb: do this in two steps because "??)" is a trigraph! 23935e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(" (in ???"); 23945e40abad4504416c59f0b29c1cfc8087201213a9njn APPEND(")"); 2395eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2396eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2397eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2398eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return buf; 2399eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2400eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef APPEND 2401eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef APPEND_ESC 2402eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2403eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 240472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 2405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 2406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 2407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/ 2408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- DWARF3 .eh_frame INFO ---*/ 2409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 2410b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 241172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 241272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/* Gather up all the constant pieces of info needed to evaluate 241372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj a CfiExpr into one convenient struct. */ 241472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjtypedef 241572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj struct { 24163297124fa2116737066ac3cd709f18fdd5405163florian const D3UnwindRegs* uregs; 24173026f71684a930286186aa10fef266c304672e8fsewardj Addr min_accessible; 24183026f71684a930286186aa10fef266c304672e8fsewardj Addr max_accessible; 241972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 242072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj CfiExprEvalContext; 242172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 242272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/* Evaluate the CfiExpr rooted at ix in exprs given the context eec. 242372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj *ok is set to False on failure, but not to True on success. The 242472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj caller must set it to True before calling. */ 2425f7183e38d6215e98043ed014cb947cf5262bdc4asewardj__attribute__((noinline)) 2426f7183e38d6215e98043ed014cb947cf5262bdc4asewardjstatic 24273297124fa2116737066ac3cd709f18fdd5405163florianUWord evalCfiExpr ( const XArray* exprs, Int ix, 24283297124fa2116737066ac3cd709f18fdd5405163florian const CfiExprEvalContext* eec, Bool* ok ) 242972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj{ 243040628facff2285b0fce592381c6e26fdcd2a1252tom UWord w, wL, wR; 243119dc88f90d0e19a1463797dd99f6792a42f961d3sewardj Addr a; 24323297124fa2116737066ac3cd709f18fdd5405163florian const CfiExpr* e; 24333026f71684a930286186aa10fef266c304672e8fsewardj vg_assert(sizeof(Addr) == sizeof(UWord)); 24343026f71684a930286186aa10fef266c304672e8fsewardj e = VG_(indexXA)( exprs, ix ); 243572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->tag) { 243640628facff2285b0fce592381c6e26fdcd2a1252tom case Cex_Unop: 243740628facff2285b0fce592381c6e26fdcd2a1252tom w = evalCfiExpr( exprs, e->Cex.Unop.ix, eec, ok ); 243840628facff2285b0fce592381c6e26fdcd2a1252tom if (!(*ok)) return 0; 243940628facff2285b0fce592381c6e26fdcd2a1252tom switch (e->Cex.Unop.op) { 244040628facff2285b0fce592381c6e26fdcd2a1252tom case Cunop_Abs: return (Word) w < 0 ? - w : w; 244140628facff2285b0fce592381c6e26fdcd2a1252tom case Cunop_Neg: return - (Word) w; 244240628facff2285b0fce592381c6e26fdcd2a1252tom case Cunop_Not: return ~ w; 244340628facff2285b0fce592381c6e26fdcd2a1252tom default: goto unhandled; 244440628facff2285b0fce592381c6e26fdcd2a1252tom } 244540628facff2285b0fce592381c6e26fdcd2a1252tom /*NOTREACHED*/ 244672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_Binop: 244772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj wL = evalCfiExpr( exprs, e->Cex.Binop.ixL, eec, ok ); 244872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!(*ok)) return 0; 244972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj wR = evalCfiExpr( exprs, e->Cex.Binop.ixR, eec, ok ); 245072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!(*ok)) return 0; 245172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->Cex.Binop.op) { 2452f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Add: return wL + wR; 2453f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Sub: return wL - wR; 2454f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_And: return wL & wR; 2455f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Mul: return wL * wR; 2456f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Shl: return wL << wR; 2457f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Shr: return wL >> wR; 2458f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Eq: return wL == wR ? 1 : 0; 2459f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Ge: return (Word) wL >= (Word) wR ? 1 : 0; 2460f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Gt: return (Word) wL > (Word) wR ? 1 : 0; 2461f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Le: return (Word) wL <= (Word) wR ? 1 : 0; 2462f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Lt: return (Word) wL < (Word) wR ? 1 : 0; 2463f6716dd8f025c9ace67541f3360d7f4523496d8atom case Cbinop_Ne: return wL != wR ? 1 : 0; 246472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: goto unhandled; 246572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 246672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 246772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_CfiReg: 246872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj switch (e->Cex.CfiReg.reg) { 24693026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 24703026f71684a930286186aa10fef266c304672e8fsewardj case Creg_IA_IP: return eec->uregs->xip; 24713026f71684a930286186aa10fef266c304672e8fsewardj case Creg_IA_SP: return eec->uregs->xsp; 24723026f71684a930286186aa10fef266c304672e8fsewardj case Creg_IA_BP: return eec->uregs->xbp; 24733026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_arm) 24743026f71684a930286186aa10fef266c304672e8fsewardj case Creg_ARM_R15: return eec->uregs->r15; 24753026f71684a930286186aa10fef266c304672e8fsewardj case Creg_ARM_R14: return eec->uregs->r14; 2476fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj case Creg_ARM_R13: return eec->uregs->r13; 2477fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj case Creg_ARM_R12: return eec->uregs->r12; 2478ade2eddf567a868bafad9110ed92acf7373a972bsewardj case Creg_ARM_R7: return eec->uregs->r7; 2479b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGA_s390x) 2480b6ba6d288e6000a8f95fba1dea671e0b53e26043florian case Creg_S390_IA: return eec->uregs->ia; 2481b6ba6d288e6000a8f95fba1dea671e0b53e26043florian case Creg_S390_SP: return eec->uregs->sp; 2482b6ba6d288e6000a8f95fba1dea671e0b53e26043florian case Creg_S390_FP: return eec->uregs->fp; 2483b6ba6d288e6000a8f95fba1dea671e0b53e26043florian case Creg_S390_LR: return eec->uregs->lr; 24844df0bfc0614379192c780c944415dc420d9cfe8epetarj# elif defined(VGA_mips32) || defined(VGA_mips64) 24855db15403e889d4db339b342bc2a824ef0bfaa654sewardj case Creg_IA_IP: return eec->uregs->pc; 24865db15403e889d4db339b342bc2a824ef0bfaa654sewardj case Creg_IA_SP: return eec->uregs->sp; 24875db15403e889d4db339b342bc2a824ef0bfaa654sewardj case Creg_IA_BP: return eec->uregs->fp; 24885db15403e889d4db339b342bc2a824ef0bfaa654sewardj case Creg_MIPS_RA: return eec->uregs->ra; 2489cae0cc22b83ffb260ee8379e92099c5a701944cbcarll# elif defined(VGA_ppc32) || defined(VGA_ppc64be) \ 2490cae0cc22b83ffb260ee8379e92099c5a701944cbcarll || defined(VGA_ppc64le) 2491f0c1250e324f6684757c6a15545366447ef1d64fsewardj# elif defined(VGP_arm64_linux) 2492821283b2110420321fd3f60afcc799b287788c68sewardj case Creg_ARM64_X30: return eec->uregs->x30; 2493112711afefcfcd43680c7c4aa8d38ef180e8811esewardj# elif defined(VGA_tilegx) 2494112711afefcfcd43680c7c4aa8d38ef180e8811esewardj case Creg_TILEGX_IP: return eec->uregs->pc; 2495112711afefcfcd43680c7c4aa8d38ef180e8811esewardj case Creg_TILEGX_SP: return eec->uregs->sp; 2496112711afefcfcd43680c7c4aa8d38ef180e8811esewardj case Creg_TILEGX_BP: return eec->uregs->fp; 2497112711afefcfcd43680c7c4aa8d38ef180e8811esewardj case Creg_TILEGX_LR: return eec->uregs->lr; 24983026f71684a930286186aa10fef266c304672e8fsewardj# else 24993026f71684a930286186aa10fef266c304672e8fsewardj# error "Unsupported arch" 25003026f71684a930286186aa10fef266c304672e8fsewardj# endif 250172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: goto unhandled; 250272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 250372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 250472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case Cex_Const: 250572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj return e->Cex.Const.con; 250619dc88f90d0e19a1463797dd99f6792a42f961d3sewardj case Cex_Deref: 250719dc88f90d0e19a1463797dd99f6792a42f961d3sewardj a = evalCfiExpr( exprs, e->Cex.Deref.ixAddr, eec, ok ); 250819dc88f90d0e19a1463797dd99f6792a42f961d3sewardj if (!(*ok)) return 0; 250919dc88f90d0e19a1463797dd99f6792a42f961d3sewardj if (a < eec->min_accessible 2510720e6b71b171885281afab634ce4d667c1f262bcsewardj || a > eec->max_accessible - sizeof(UWord) + 1) { 251119dc88f90d0e19a1463797dd99f6792a42f961d3sewardj *ok = False; 251219dc88f90d0e19a1463797dd99f6792a42f961d3sewardj return 0; 251319dc88f90d0e19a1463797dd99f6792a42f961d3sewardj } 251419dc88f90d0e19a1463797dd99f6792a42f961d3sewardj /* let's hope it doesn't trap! */ 251586781fabbfc019b752f9605e487cfce77b2a592atom return ML_(read_UWord)((void *)a); 251672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: 251772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj goto unhandled; 251872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 251972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 252072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj unhandled: 252172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("\n\nevalCfiExpr: unhandled\n"); 252272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj ML_(ppCfiExpr)( exprs, ix ); 252372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj VG_(printf)("\n"); 252472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); 252572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /*NOTREACHED*/ 252672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj return 0; 252772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj} 252872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 252972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 25305c3dba227192de63d86f65ec7d9597c132818c37philippe/* Search all the DebugInfos in the entire system, to find the DiCfSI_m 2531f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj that pertains to 'ip'. 2532eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2533f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj If found, set *diP to the DebugInfo in which it resides, and 25345c3dba227192de63d86f65ec7d9597c132818c37philippe *cfsi_mP to the cfsi_m pointer in that DebugInfo's cfsi_m_pool. 253572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 25365c3dba227192de63d86f65ec7d9597c132818c37philippe If not found, set *diP to (DebugInfo*)1 and *cfsi_mP to zero. 2537f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj*/ 2538f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj__attribute__((noinline)) 2539f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic void find_DiCfSI ( /*OUT*/DebugInfo** diP, 25405c3dba227192de63d86f65ec7d9597c132818c37philippe /*OUT*/DiCfSI_m** cfsi_mP, 2541f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Addr ip ) 2542f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 2543f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo* di; 2544f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word i = -1; 2545f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2546f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj static UWord n_search = 0; 2547f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj static UWord n_steps = 0; 2548eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_search++; 2549eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2550f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0) VG_(printf)("search for %#lx\n", ip); 2551eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2552f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for (di = debugInfo_list; di != NULL; di = di->next) { 2553f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word j; 2554eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj n_steps++; 2555eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Use the per-DebugInfo summary address ranges to skip 2557b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj inapplicable DebugInfos quickly. */ 2558f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (di->cfsi_used == 0) 2559eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj continue; 2560f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (ip < di->cfsi_minavma || ip > di->cfsi_maxavma) 2561eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj continue; 2562eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2563f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* It might be in this DebugInfo. Search it. */ 2564f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj j = ML_(search_one_cfitab)( di, ip ); 2565f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(j >= -1 && j < (Word)di->cfsi_used); 2566f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2567f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (j != -1) { 2568f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj i = j; 2569f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj break; /* found it */ 2570eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2571eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 2572eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2573f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (i == -1) { 2574f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2575f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* we didn't find it. */ 2576f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *diP = (DebugInfo*)1; 25775c3dba227192de63d86f65ec7d9597c132818c37philippe *cfsi_mP = 0; 2578f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2579f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 2580f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 25815c3dba227192de63d86f65ec7d9597c132818c37philippe /* found a di corresponding to ip. */ 2582f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* ensure that di is 4-aligned (at least), so it can't possibly 2583f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj be equal to (DebugInfo*)1. */ 2584f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj vg_assert(di && VG_IS_4_ALIGNED(di)); 25855c3dba227192de63d86f65ec7d9597c132818c37philippe *cfsi_mP = ML_(get_cfsi_m) (di, i); 25865c3dba227192de63d86f65ec7d9597c132818c37philippe if (*cfsi_mP == NULL) { 25875c3dba227192de63d86f65ec7d9597c132818c37philippe // This is a cfsi hole. Report no cfi information found. 25885c3dba227192de63d86f65ec7d9597c132818c37philippe *diP = (DebugInfo*)1; 25895c3dba227192de63d86f65ec7d9597c132818c37philippe // But we will still perform the hack below. 25905c3dba227192de63d86f65ec7d9597c132818c37philippe } else { 25915c3dba227192de63d86f65ec7d9597c132818c37philippe *diP = di; 25925c3dba227192de63d86f65ec7d9597c132818c37philippe } 2593f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2594f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Start of performance-enhancing hack: once every 64 (chosen 2595f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj hackily after profiling) successful searches, move the found 2596f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj DebugInfo one step closer to the start of the list. This 2597f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj makes future searches cheaper. For starting konqueror on 2598f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj amd64, this in fact reduces the total amount of searching 2599f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj done by the above find-the-right-DebugInfo loop by more than 2600f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj a factor of 20. */ 2601f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if ((n_search & 0xF) == 0) { 2602f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Move di one step closer to the start of the list. */ 2603f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj move_DebugInfo_one_step_forward( di ); 2604f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 2605f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* End of performance-enhancing hack. */ 2606f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2607f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && ((n_search & 0x7FFFF) == 0)) 2608f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(printf)("find_DiCfSI: %lu searches, " 2609f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj "%lu DebugInfos looked at\n", 2610f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj n_search, n_steps); 2611f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2612f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 2613f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2614f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 2615f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2616f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2617f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Now follows a mechanism for caching queries to find_DiCfSI, since 2618f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj they are extremely frequent on amd64-linux, during stack unwinding. 2619f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 26205c3dba227192de63d86f65ec7d9597c132818c37philippe Each cache entry binds an ip value to a (di, cfsi_m*) pair. Possible 2621f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj values: 2622f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 26235c3dba227192de63d86f65ec7d9597c132818c37philippe di is non-null, cfsi_m* >= 0 ==> cache slot in use, "cfsi_m*" 26245c3dba227192de63d86f65ec7d9597c132818c37philippe di is (DebugInfo*)1 ==> cache slot in use, no associated di 26255c3dba227192de63d86f65ec7d9597c132818c37philippe di is NULL ==> cache slot not in use 2626f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2627f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Hence simply zeroing out the entire cache invalidates all 2628f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj entries. 2629f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 26305c3dba227192de63d86f65ec7d9597c132818c37philippe We can map an ip value directly to a (di, cfsi_m*) pair as 26315c3dba227192de63d86f65ec7d9597c132818c37philippe once a DebugInfo is read, adding new DiCfSI_m* is not possible 26325c3dba227192de63d86f65ec7d9597c132818c37philippe anymore, as the cfsi_m_pool is frozen once the reading is terminated. 26335c3dba227192de63d86f65ec7d9597c132818c37philippe Also, the cache is invalidated when new debuginfo is read due to 26345c3dba227192de63d86f65ec7d9597c132818c37philippe an mmap or some debuginfo is discarded due to an munmap. */ 2635eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 26365c3dba227192de63d86f65ec7d9597c132818c37philippe// Prime number, giving about 6Kbytes cache on 32 bits, 26375c3dba227192de63d86f65ec7d9597c132818c37philippe// 12Kbytes cache on 64 bits. 26385c3dba227192de63d86f65ec7d9597c132818c37philippe#define N_CFSI_M_CACHE 509 2639f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2640f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjtypedef 26415c3dba227192de63d86f65ec7d9597c132818c37philippe struct { Addr ip; DebugInfo* di; DiCfSI_m* cfsi_m; } 26425c3dba227192de63d86f65ec7d9597c132818c37philippe CFSI_m_CacheEnt; 2643f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 26445c3dba227192de63d86f65ec7d9597c132818c37philippestatic CFSI_m_CacheEnt cfsi_m_cache[N_CFSI_M_CACHE]; 2645f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 26465c3dba227192de63d86f65ec7d9597c132818c37philippestatic void cfsi_m_cache__invalidate ( void ) { 26475c3dba227192de63d86f65ec7d9597c132818c37philippe VG_(memset)(&cfsi_m_cache, 0, sizeof(cfsi_m_cache)); 264820ede3a4f086d4a4b1e0969b1098dcb244ffb6b4philippe CF_info_generation++; 2649f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 2650f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 265120ede3a4f086d4a4b1e0969b1098dcb244ffb6b4philippeUInt VG_(CF_info_generation) (void) 265220ede3a4f086d4a4b1e0969b1098dcb244ffb6b4philippe{ 265320ede3a4f086d4a4b1e0969b1098dcb244ffb6b4philippe return CF_info_generation; 265420ede3a4f086d4a4b1e0969b1098dcb244ffb6b4philippe} 2655f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 26565c3dba227192de63d86f65ec7d9597c132818c37philippestatic inline CFSI_m_CacheEnt* cfsi_m_cache__find ( Addr ip ) 2657f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 26585c3dba227192de63d86f65ec7d9597c132818c37philippe UWord hash = ip % N_CFSI_M_CACHE; 26595c3dba227192de63d86f65ec7d9597c132818c37philippe CFSI_m_CacheEnt* ce = &cfsi_m_cache[hash]; 26603c9cf3442185b5891e15450d6e3058aeff6796fetom static UWord n_q = 0, n_m = 0; 2661f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2662f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj n_q++; 2663f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 && 0 == (n_q & 0x1FFFFF)) 2664f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(printf)("QQQ %lu %lu\n", n_q, n_m); 2665f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 26663c9cf3442185b5891e15450d6e3058aeff6796fetom if (LIKELY(ce->ip == ip) && LIKELY(ce->di != NULL)) { 26673c9cf3442185b5891e15450d6e3058aeff6796fetom /* found an entry in the cache .. */ 26683c9cf3442185b5891e15450d6e3058aeff6796fetom } else { 26693c9cf3442185b5891e15450d6e3058aeff6796fetom /* not found in cache. Search and update. */ 26703c9cf3442185b5891e15450d6e3058aeff6796fetom n_m++; 26713c9cf3442185b5891e15450d6e3058aeff6796fetom ce->ip = ip; 26725c3dba227192de63d86f65ec7d9597c132818c37philippe find_DiCfSI( &ce->di, &ce->cfsi_m, ip ); 26733c9cf3442185b5891e15450d6e3058aeff6796fetom } 2674eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 26753c9cf3442185b5891e15450d6e3058aeff6796fetom if (UNLIKELY(ce->di == (DebugInfo*)1)) { 26763c9cf3442185b5891e15450d6e3058aeff6796fetom /* no DiCfSI for this address */ 26773c9cf3442185b5891e15450d6e3058aeff6796fetom return NULL; 26783c9cf3442185b5891e15450d6e3058aeff6796fetom } else { 26793c9cf3442185b5891e15450d6e3058aeff6796fetom /* found a DiCfSI for this address */ 26803c9cf3442185b5891e15450d6e3058aeff6796fetom return ce; 2681eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } 26823c9cf3442185b5891e15450d6e3058aeff6796fetom} 2683eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2684eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2685f7183e38d6215e98043ed014cb947cf5262bdc4asewardjinline 26863297124fa2116737066ac3cd709f18fdd5405163florianstatic Addr compute_cfa ( const D3UnwindRegs* uregs, 26873c9cf3442185b5891e15450d6e3058aeff6796fetom Addr min_accessible, Addr max_accessible, 26883297124fa2116737066ac3cd709f18fdd5405163florian const DebugInfo* di, const DiCfSI_m* cfsi_m ) 26893c9cf3442185b5891e15450d6e3058aeff6796fetom{ 26903c9cf3442185b5891e15450d6e3058aeff6796fetom CfiExprEvalContext eec; 26913c9cf3442185b5891e15450d6e3058aeff6796fetom Addr cfa; 26923c9cf3442185b5891e15450d6e3058aeff6796fetom Bool ok; 2693eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 26943c9cf3442185b5891e15450d6e3058aeff6796fetom /* Compute the CFA. */ 269572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj cfa = 0; 26965c3dba227192de63d86f65ec7d9597c132818c37philippe switch (cfsi_m->cfa_how) { 26973026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 26983026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_IA_SPREL: 26995c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->xsp; 27003026f71684a930286186aa10fef266c304672e8fsewardj break; 27013026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_IA_BPREL: 27025c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->xbp; 270372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 27043026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_arm) 27053026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_ARM_R13REL: 27065c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->r13; 270772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 27083026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_ARM_R12REL: 27095c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->r12; 27103026f71684a930286186aa10fef266c304672e8fsewardj break; 27113026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_ARM_R11REL: 27125c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->r11; 27133026f71684a930286186aa10fef266c304672e8fsewardj break; 2714fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj case CFIC_ARM_R7REL: 27155c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->r7; 2716fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj break; 2717b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGA_s390x) 2718b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case CFIC_IA_SPREL: 27195c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->sp; 2720b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 2721b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case CFIR_MEMCFAREL: 2722b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj { 27235c3dba227192de63d86f65ec7d9597c132818c37philippe Addr a = uregs->sp + cfsi_m->cfa_off; 2724b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj if (a < min_accessible || a > max_accessible-sizeof(Addr)) 2725b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 272686781fabbfc019b752f9605e487cfce77b2a592atom cfa = ML_(read_Addr)((void *)a); 2727b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 2728b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj } 2729b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case CFIR_SAME: 2730b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj cfa = uregs->fp; 2731b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 2732b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj case CFIC_IA_BPREL: 27335c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->fp; 2734b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj break; 27354df0bfc0614379192c780c944415dc420d9cfe8epetarj# elif defined(VGA_mips32) || defined(VGA_mips64) 27365db15403e889d4db339b342bc2a824ef0bfaa654sewardj case CFIC_IA_SPREL: 27375c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->sp; 27385db15403e889d4db339b342bc2a824ef0bfaa654sewardj break; 27395db15403e889d4db339b342bc2a824ef0bfaa654sewardj case CFIR_SAME: 27405db15403e889d4db339b342bc2a824ef0bfaa654sewardj cfa = uregs->fp; 27415db15403e889d4db339b342bc2a824ef0bfaa654sewardj break; 27425db15403e889d4db339b342bc2a824ef0bfaa654sewardj case CFIC_IA_BPREL: 27435c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->fp; 27445db15403e889d4db339b342bc2a824ef0bfaa654sewardj break; 2745cae0cc22b83ffb260ee8379e92099c5a701944cbcarll# elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le) 2746f0c1250e324f6684757c6a15545366447ef1d64fsewardj# elif defined(VGP_arm64_linux) 2747821283b2110420321fd3f60afcc799b287788c68sewardj case CFIC_ARM64_SPREL: 27485c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->sp; 2749821283b2110420321fd3f60afcc799b287788c68sewardj break; 2750821283b2110420321fd3f60afcc799b287788c68sewardj case CFIC_ARM64_X29REL: 27515c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = cfsi_m->cfa_off + uregs->x29; 2752821283b2110420321fd3f60afcc799b287788c68sewardj break; 2753112711afefcfcd43680c7c4aa8d38ef180e8811esewardj# elif defined(VGA_tilegx) 2754112711afefcfcd43680c7c4aa8d38ef180e8811esewardj case CFIC_IA_SPREL: 2755112711afefcfcd43680c7c4aa8d38ef180e8811esewardj cfa = cfsi_m->cfa_off + uregs->sp; 2756112711afefcfcd43680c7c4aa8d38ef180e8811esewardj break; 2757112711afefcfcd43680c7c4aa8d38ef180e8811esewardj case CFIR_SAME: 2758112711afefcfcd43680c7c4aa8d38ef180e8811esewardj cfa = uregs->fp; 2759112711afefcfcd43680c7c4aa8d38ef180e8811esewardj break; 2760112711afefcfcd43680c7c4aa8d38ef180e8811esewardj case CFIC_IA_BPREL: 2761112711afefcfcd43680c7c4aa8d38ef180e8811esewardj cfa = cfsi_m->cfa_off + uregs->fp; 2762112711afefcfcd43680c7c4aa8d38ef180e8811esewardj break; 27633026f71684a930286186aa10fef266c304672e8fsewardj# else 27643026f71684a930286186aa10fef266c304672e8fsewardj# error "Unsupported arch" 27653026f71684a930286186aa10fef266c304672e8fsewardj# endif 27663026f71684a930286186aa10fef266c304672e8fsewardj case CFIC_EXPR: /* available on all archs */ 27677888e2204fff6e7429236b4227ed16594e7743b9sewardj if (0) { 27687888e2204fff6e7429236b4227ed16594e7743b9sewardj VG_(printf)("CFIC_EXPR: "); 27695c3dba227192de63d86f65ec7d9597c132818c37philippe ML_(ppCfiExpr)(di->cfsi_exprs, cfsi_m->cfa_off); 27707888e2204fff6e7429236b4227ed16594e7743b9sewardj VG_(printf)("\n"); 27717888e2204fff6e7429236b4227ed16594e7743b9sewardj } 27723026f71684a930286186aa10fef266c304672e8fsewardj eec.uregs = uregs; 27737888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.min_accessible = min_accessible; 27747888e2204fff6e7429236b4227ed16594e7743b9sewardj eec.max_accessible = max_accessible; 27757888e2204fff6e7429236b4227ed16594e7743b9sewardj ok = True; 27765c3dba227192de63d86f65ec7d9597c132818c37philippe cfa = evalCfiExpr(di->cfsi_exprs, cfsi_m->cfa_off, &eec, &ok ); 27773c9cf3442185b5891e15450d6e3058aeff6796fetom if (!ok) return 0; 277872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; 277972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: 278072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); 278172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj } 27823c9cf3442185b5891e15450d6e3058aeff6796fetom return cfa; 27833c9cf3442185b5891e15450d6e3058aeff6796fetom} 27843c9cf3442185b5891e15450d6e3058aeff6796fetom 27853c9cf3442185b5891e15450d6e3058aeff6796fetom 27863c9cf3442185b5891e15450d6e3058aeff6796fetom/* Get the call frame address (CFA) given an IP/SP/FP triple. */ 27873026f71684a930286186aa10fef266c304672e8fsewardj/* NOTE: This function may rearrange the order of entries in the 27883026f71684a930286186aa10fef266c304672e8fsewardj DebugInfo list. */ 27893c9cf3442185b5891e15450d6e3058aeff6796fetomAddr ML_(get_CFA) ( Addr ip, Addr sp, Addr fp, 27903c9cf3442185b5891e15450d6e3058aeff6796fetom Addr min_accessible, Addr max_accessible ) 27913c9cf3442185b5891e15450d6e3058aeff6796fetom{ 27925c3dba227192de63d86f65ec7d9597c132818c37philippe CFSI_m_CacheEnt* ce; 27933c9cf3442185b5891e15450d6e3058aeff6796fetom 27945c3dba227192de63d86f65ec7d9597c132818c37philippe ce = cfsi_m_cache__find(ip); 27953c9cf3442185b5891e15450d6e3058aeff6796fetom 27963c9cf3442185b5891e15450d6e3058aeff6796fetom if (UNLIKELY(ce == NULL)) 27973c9cf3442185b5891e15450d6e3058aeff6796fetom return 0; /* no info. Nothing we can do. */ 27983c9cf3442185b5891e15450d6e3058aeff6796fetom 27993026f71684a930286186aa10fef266c304672e8fsewardj /* Temporary impedance-matching kludge so that this keeps working 28003026f71684a930286186aa10fef266c304672e8fsewardj on x86-linux and amd64-linux. */ 28013026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 28023026f71684a930286186aa10fef266c304672e8fsewardj { D3UnwindRegs uregs; 28033026f71684a930286186aa10fef266c304672e8fsewardj uregs.xip = ip; 28043026f71684a930286186aa10fef266c304672e8fsewardj uregs.xsp = sp; 28053026f71684a930286186aa10fef266c304672e8fsewardj uregs.xbp = fp; 28063026f71684a930286186aa10fef266c304672e8fsewardj return compute_cfa(&uregs, 280705c459ea63c50a072cf1eb0868590e9c0b362f30philippe min_accessible, max_accessible, ce->di, ce->cfsi_m); 28083026f71684a930286186aa10fef266c304672e8fsewardj } 2809b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#elif defined(VGA_s390x) 2810b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj { D3UnwindRegs uregs; 2811b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj uregs.ia = ip; 2812b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj uregs.sp = sp; 2813b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj uregs.fp = fp; 2814b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj return compute_cfa(&uregs, 281505c459ea63c50a072cf1eb0868590e9c0b362f30philippe min_accessible, max_accessible, ce->di, ce->cfsi_m); 2816b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj } 2817112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#elif defined(VGA_mips32) || defined(VGA_mips64) || defined(VGA_tilegx) 2818fe0b43315c344cfd07981a0826bc34614a220169dejanj { D3UnwindRegs uregs; 2819fe0b43315c344cfd07981a0826bc34614a220169dejanj uregs.pc = ip; 2820fe0b43315c344cfd07981a0826bc34614a220169dejanj uregs.sp = sp; 2821fe0b43315c344cfd07981a0826bc34614a220169dejanj uregs.fp = fp; 2822fe0b43315c344cfd07981a0826bc34614a220169dejanj return compute_cfa(&uregs, 282305c459ea63c50a072cf1eb0868590e9c0b362f30philippe min_accessible, max_accessible, ce->di, ce->cfsi_m); 2824fe0b43315c344cfd07981a0826bc34614a220169dejanj } 2825b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 28263026f71684a930286186aa10fef266c304672e8fsewardj# else 28273026f71684a930286186aa10fef266c304672e8fsewardj return 0; /* indicates failure */ 28283026f71684a930286186aa10fef266c304672e8fsewardj# endif 28293c9cf3442185b5891e15450d6e3058aeff6796fetom} 28303c9cf3442185b5891e15450d6e3058aeff6796fetom 28313c9cf3442185b5891e15450d6e3058aeff6796fetom 28323026f71684a930286186aa10fef266c304672e8fsewardj/* The main function for DWARF2/3 CFI-based stack unwinding. Given a 28333026f71684a930286186aa10fef266c304672e8fsewardj set of registers in UREGS, modify it to hold the register values 28343026f71684a930286186aa10fef266c304672e8fsewardj for the previous frame, if possible. Returns True if successful. 28353026f71684a930286186aa10fef266c304672e8fsewardj If not successful, *UREGS is not changed. 28363026f71684a930286186aa10fef266c304672e8fsewardj 28373026f71684a930286186aa10fef266c304672e8fsewardj For x86 and amd64, the unwound registers are: {E,R}IP, 28383026f71684a930286186aa10fef266c304672e8fsewardj {E,R}SP, {E,R}BP. 28393026f71684a930286186aa10fef266c304672e8fsewardj 2840fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj For arm, the unwound registers are: R7 R11 R12 R13 R14 R15. 2841821283b2110420321fd3f60afcc799b287788c68sewardj 2842821283b2110420321fd3f60afcc799b287788c68sewardj For arm64, the unwound registers are: X29(FP) X30(LR) SP PC. 28433026f71684a930286186aa10fef266c304672e8fsewardj*/ 28443026f71684a930286186aa10fef266c304672e8fsewardjBool VG_(use_CF_info) ( /*MOD*/D3UnwindRegs* uregsHere, 28453c9cf3442185b5891e15450d6e3058aeff6796fetom Addr min_accessible, 28463c9cf3442185b5891e15450d6e3058aeff6796fetom Addr max_accessible ) 28473c9cf3442185b5891e15450d6e3058aeff6796fetom{ 28483c9cf3442185b5891e15450d6e3058aeff6796fetom DebugInfo* di; 28495c3dba227192de63d86f65ec7d9597c132818c37philippe DiCfSI_m* cfsi_m = NULL; 28503026f71684a930286186aa10fef266c304672e8fsewardj Addr cfa, ipHere = 0; 28515c3dba227192de63d86f65ec7d9597c132818c37philippe CFSI_m_CacheEnt* ce; 2852d2be8cc17fed04cbd701e9a2cc1cf365ff45cc44sewardj CfiExprEvalContext eec __attribute__((unused)); 28533026f71684a930286186aa10fef266c304672e8fsewardj D3UnwindRegs uregsPrev; 28543c9cf3442185b5891e15450d6e3058aeff6796fetom 28553026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 28563026f71684a930286186aa10fef266c304672e8fsewardj ipHere = uregsHere->xip; 28573026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_arm) 28583026f71684a930286186aa10fef266c304672e8fsewardj ipHere = uregsHere->r15; 2859b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGA_s390x) 2860b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj ipHere = uregsHere->ia; 28614df0bfc0614379192c780c944415dc420d9cfe8epetarj# elif defined(VGA_mips32) || defined(VGA_mips64) 28625db15403e889d4db339b342bc2a824ef0bfaa654sewardj ipHere = uregsHere->pc; 2863cae0cc22b83ffb260ee8379e92099c5a701944cbcarll# elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le) 2864f0c1250e324f6684757c6a15545366447ef1d64fsewardj# elif defined(VGP_arm64_linux) 2865821283b2110420321fd3f60afcc799b287788c68sewardj ipHere = uregsHere->pc; 2866112711afefcfcd43680c7c4aa8d38ef180e8811esewardj# elif defined(VGA_tilegx) 2867112711afefcfcd43680c7c4aa8d38ef180e8811esewardj ipHere = uregsHere->pc; 28683026f71684a930286186aa10fef266c304672e8fsewardj# else 28693026f71684a930286186aa10fef266c304672e8fsewardj# error "Unknown arch" 28703026f71684a930286186aa10fef266c304672e8fsewardj# endif 28715c3dba227192de63d86f65ec7d9597c132818c37philippe ce = cfsi_m_cache__find(ipHere); 28723c9cf3442185b5891e15450d6e3058aeff6796fetom 28733c9cf3442185b5891e15450d6e3058aeff6796fetom if (UNLIKELY(ce == NULL)) 28743c9cf3442185b5891e15450d6e3058aeff6796fetom return False; /* no info. Nothing we can do. */ 28753c9cf3442185b5891e15450d6e3058aeff6796fetom 28763c9cf3442185b5891e15450d6e3058aeff6796fetom di = ce->di; 28775c3dba227192de63d86f65ec7d9597c132818c37philippe cfsi_m = ce->cfsi_m; 28783c9cf3442185b5891e15450d6e3058aeff6796fetom 28793c9cf3442185b5891e15450d6e3058aeff6796fetom if (0) { 28805c3dba227192de63d86f65ec7d9597c132818c37philippe VG_(printf)("found cfsi_m (but printing fake base/len): "); 28815c3dba227192de63d86f65ec7d9597c132818c37philippe ML_(ppDiCfSI)(di->cfsi_exprs, 0, 0, cfsi_m); 28823c9cf3442185b5891e15450d6e3058aeff6796fetom } 28833c9cf3442185b5891e15450d6e3058aeff6796fetom 2884f7183e38d6215e98043ed014cb947cf5262bdc4asewardj VG_(bzero_inline)(&uregsPrev, sizeof(uregsPrev)); 28853c9cf3442185b5891e15450d6e3058aeff6796fetom 28863c9cf3442185b5891e15450d6e3058aeff6796fetom /* First compute the CFA. */ 28873026f71684a930286186aa10fef266c304672e8fsewardj cfa = compute_cfa(uregsHere, 28885c3dba227192de63d86f65ec7d9597c132818c37philippe min_accessible, max_accessible, di, cfsi_m); 28893c9cf3442185b5891e15450d6e3058aeff6796fetom if (UNLIKELY(cfa == 0)) 28903c9cf3442185b5891e15450d6e3058aeff6796fetom return False; 289172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj 289272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj /* Now we know the CFA, use it to roll back the registers we're 289372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj interested in. */ 2894eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2895eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# define COMPUTE(_prev, _here, _how, _off) \ 2896eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj do { \ 2897eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj switch (_how) { \ 2898eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_UNKNOWN: \ 2899eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; \ 2900eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_SAME: \ 2901eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj _prev = _here; break; \ 2902eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_MEMCFAREL: { \ 2903eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj Addr a = cfa + (Word)_off; \ 2904eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj if (a < min_accessible \ 29059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj || a > max_accessible-sizeof(Addr)) \ 2906eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return False; \ 290786781fabbfc019b752f9605e487cfce77b2a592atom _prev = ML_(read_Addr)((void *)a); \ 2908eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; \ 2909eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } \ 2910eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj case CFIR_CFAREL: \ 2911eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj _prev = cfa + (Word)_off; \ 2912eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj break; \ 291372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj case CFIR_EXPR: \ 291472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (0) \ 2915f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj ML_(ppCfiExpr)(di->cfsi_exprs,_off); \ 29163026f71684a930286186aa10fef266c304672e8fsewardj eec.uregs = uregsHere; \ 291772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.min_accessible = min_accessible; \ 291872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj eec.max_accessible = max_accessible; \ 2919d2be8cc17fed04cbd701e9a2cc1cf365ff45cc44sewardj Bool ok = True; \ 2920f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj _prev = evalCfiExpr(di->cfsi_exprs, _off, &eec, &ok ); \ 292172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj if (!ok) return False; \ 292272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj break; \ 292372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj default: \ 292472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj vg_assert(0); \ 2925eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } \ 2926eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj } while (0) 2927eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 29283026f71684a930286186aa10fef266c304672e8fsewardj# if defined(VGA_x86) || defined(VGA_amd64) 29295c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.xip, uregsHere->xip, cfsi_m->ra_how, cfsi_m->ra_off); 29305c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.xsp, uregsHere->xsp, cfsi_m->sp_how, cfsi_m->sp_off); 29315c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.xbp, uregsHere->xbp, cfsi_m->bp_how, cfsi_m->bp_off); 29323026f71684a930286186aa10fef266c304672e8fsewardj# elif defined(VGA_arm) 29335c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r15, uregsHere->r15, cfsi_m->ra_how, cfsi_m->ra_off); 29345c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r14, uregsHere->r14, cfsi_m->r14_how, cfsi_m->r14_off); 29355c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r13, uregsHere->r13, cfsi_m->r13_how, cfsi_m->r13_off); 29365c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r12, uregsHere->r12, cfsi_m->r12_how, cfsi_m->r12_off); 29375c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r11, uregsHere->r11, cfsi_m->r11_how, cfsi_m->r11_off); 29385c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.r7, uregsHere->r7, cfsi_m->r7_how, cfsi_m->r7_off); 2939b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGA_s390x) 29405c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.ia, uregsHere->ia, cfsi_m->ra_how, cfsi_m->ra_off); 29415c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off); 29425c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi_m->fp_how, cfsi_m->fp_off); 29434df0bfc0614379192c780c944415dc420d9cfe8epetarj# elif defined(VGA_mips32) || defined(VGA_mips64) 29445c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi_m->ra_how, cfsi_m->ra_off); 29455c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off); 29465c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi_m->fp_how, cfsi_m->fp_off); 2947cae0cc22b83ffb260ee8379e92099c5a701944cbcarll# elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le) 2948f0c1250e324f6684757c6a15545366447ef1d64fsewardj# elif defined(VGP_arm64_linux) 29495c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi_m->ra_how, cfsi_m->ra_off); 29505c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off); 29515c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.x30, uregsHere->x30, cfsi_m->x30_how, cfsi_m->x30_off); 29525c3dba227192de63d86f65ec7d9597c132818c37philippe COMPUTE(uregsPrev.x29, uregsHere->x29, cfsi_m->x29_how, cfsi_m->x29_off); 2953112711afefcfcd43680c7c4aa8d38ef180e8811esewardj# elif defined(VGA_tilegx) 2954112711afefcfcd43680c7c4aa8d38ef180e8811esewardj COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi_m->ra_how, cfsi_m->ra_off); 2955112711afefcfcd43680c7c4aa8d38ef180e8811esewardj COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi_m->sp_how, cfsi_m->sp_off); 2956112711afefcfcd43680c7c4aa8d38ef180e8811esewardj COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi_m->fp_how, cfsi_m->fp_off); 29573026f71684a930286186aa10fef266c304672e8fsewardj# else 29583026f71684a930286186aa10fef266c304672e8fsewardj# error "Unknown arch" 29593026f71684a930286186aa10fef266c304672e8fsewardj# endif 2960eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2961eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj# undef COMPUTE 2962eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 29633026f71684a930286186aa10fef266c304672e8fsewardj *uregsHere = uregsPrev; 2964eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return True; 2965eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 2966eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2967eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 2968b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 2969b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 2970c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- TOP LEVEL: FOR UNWINDING THE STACK USING ---*/ 2971c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- MSVC FPO INFO ---*/ 2972c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- ---*/ 2973c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--------------------------------------------------------------*/ 2974c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2975c8259b85b701d25d72aabe9dc0a8154517f96913sewardjBool VG_(use_FPO_info) ( /*MOD*/Addr* ipP, 2976c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /*MOD*/Addr* spP, 2977c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /*MOD*/Addr* fpP, 2978c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Addr min_accessible, 2979c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Addr max_accessible ) 2980c8259b85b701d25d72aabe9dc0a8154517f96913sewardj{ 2981c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Word i; 29823297124fa2116737066ac3cd709f18fdd5405163florian const DebugInfo* di; 2983c8259b85b701d25d72aabe9dc0a8154517f96913sewardj FPO_DATA* fpo = NULL; 2984c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Addr spHere; 2985c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2986c8259b85b701d25d72aabe9dc0a8154517f96913sewardj static UWord n_search = 0; 2987c8259b85b701d25d72aabe9dc0a8154517f96913sewardj static UWord n_steps = 0; 2988c8259b85b701d25d72aabe9dc0a8154517f96913sewardj n_search++; 2989c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2990c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0) VG_(printf)("search FPO for %#lx\n", *ipP); 2991c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2992c8259b85b701d25d72aabe9dc0a8154517f96913sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 2993c8259b85b701d25d72aabe9dc0a8154517f96913sewardj n_steps++; 2994c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 2995c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Use the per-DebugInfo summary address ranges to skip 2996c8259b85b701d25d72aabe9dc0a8154517f96913sewardj inapplicable DebugInfos quickly. */ 2997c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (di->fpo == NULL) 2998c8259b85b701d25d72aabe9dc0a8154517f96913sewardj continue; 2999c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (*ipP < di->fpo_minavma || *ipP > di->fpo_maxavma) 3000c8259b85b701d25d72aabe9dc0a8154517f96913sewardj continue; 3001c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3002c8259b85b701d25d72aabe9dc0a8154517f96913sewardj i = ML_(search_one_fpotab)( di, *ipP ); 3003c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (i != -1) { 3004c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Word j; 3005c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0) { 3006c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* debug printing only */ 3007c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("look for %#lx size %ld i %ld\n", 3008c8259b85b701d25d72aabe9dc0a8154517f96913sewardj *ipP, di->fpo_size, i); 3009c8259b85b701d25d72aabe9dc0a8154517f96913sewardj for (j = 0; j < di->fpo_size; j++) 3010c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("[%02ld] %#x %d\n", 3011c8259b85b701d25d72aabe9dc0a8154517f96913sewardj j, di->fpo[j].ulOffStart, di->fpo[j].cbProcSize); 3012c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 3013c8259b85b701d25d72aabe9dc0a8154517f96913sewardj vg_assert(i >= 0 && i < di->fpo_size); 3014c8259b85b701d25d72aabe9dc0a8154517f96913sewardj fpo = &di->fpo[i]; 3015c8259b85b701d25d72aabe9dc0a8154517f96913sewardj break; 3016c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 3017c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 3018c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3019c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (fpo == NULL) 3020c8259b85b701d25d72aabe9dc0a8154517f96913sewardj return False; 3021c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3022c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0 && ((n_search & 0x7FFFF) == 0)) 3023c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("VG_(use_FPO_info): %lu searches, " 3024c8259b85b701d25d72aabe9dc0a8154517f96913sewardj "%lu DebugInfos looked at\n", 3025c8259b85b701d25d72aabe9dc0a8154517f96913sewardj n_search, n_steps); 3026c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3027c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3028c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Start of performance-enhancing hack: once every 64 (chosen 3029c8259b85b701d25d72aabe9dc0a8154517f96913sewardj hackily after profiling) successful searches, move the found 3030c8259b85b701d25d72aabe9dc0a8154517f96913sewardj DebugInfo one step closer to the start of the list. This makes 3031c8259b85b701d25d72aabe9dc0a8154517f96913sewardj future searches cheaper. For starting konqueror on amd64, this 3032c8259b85b701d25d72aabe9dc0a8154517f96913sewardj in fact reduces the total amount of searching done by the above 3033c8259b85b701d25d72aabe9dc0a8154517f96913sewardj find-the-right-DebugInfo loop by more than a factor of 20. */ 3034c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if ((n_search & 0x3F) == 0) { 3035c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* Move si one step closer to the start of the list. */ 3036c8259b85b701d25d72aabe9dc0a8154517f96913sewardj //move_DebugInfo_one_step_forward( di ); 3037c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 3038c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* End of performance-enhancing hack. */ 3039c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3040c8259b85b701d25d72aabe9dc0a8154517f96913sewardj if (0) { 3041c8259b85b701d25d72aabe9dc0a8154517f96913sewardj VG_(printf)("found fpo: "); 3042c8259b85b701d25d72aabe9dc0a8154517f96913sewardj //ML_(ppFPO)(fpo); 3043c8259b85b701d25d72aabe9dc0a8154517f96913sewardj } 3044c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3045c8259b85b701d25d72aabe9dc0a8154517f96913sewardj /* 3046c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Stack layout is: 3047c8259b85b701d25d72aabe9dc0a8154517f96913sewardj %esp-> 3048c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 4*.cbRegs {%edi, %esi, %ebp, %ebx} 3049c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 4*.cdwLocals 3050c8259b85b701d25d72aabe9dc0a8154517f96913sewardj return_pc 3051c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 4*.cdwParams 3052c8259b85b701d25d72aabe9dc0a8154517f96913sewardj prior_%esp-> 3053c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3054c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Typical code looks like: 3055c8259b85b701d25d72aabe9dc0a8154517f96913sewardj sub $4*.cdwLocals,%esp 3056c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Alternative to above for >=4KB (and sometimes for smaller): 3057c8259b85b701d25d72aabe9dc0a8154517f96913sewardj mov $size,%eax 3058c8259b85b701d25d72aabe9dc0a8154517f96913sewardj call __chkstk # WinNT performs page-by-page probe! 3059c8259b85b701d25d72aabe9dc0a8154517f96913sewardj __chkstk is much like alloc(), except that on return 3060c8259b85b701d25d72aabe9dc0a8154517f96913sewardj %eax= 5+ &CALL. Thus it could be used as part of 3061c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Position Independent Code to locate the Global Offset Table. 3062c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %ebx 3063c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %ebp 3064c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %esi 3065c8259b85b701d25d72aabe9dc0a8154517f96913sewardj Other once-only instructions often scheduled >here<. 3066c8259b85b701d25d72aabe9dc0a8154517f96913sewardj push %edi 3067c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3068c8259b85b701d25d72aabe9dc0a8154517f96913sewardj If the pc is within the first .cbProlog bytes of the function, 3069c8259b85b701d25d72aabe9dc0a8154517f96913sewardj then you must disassemble to see how many registers have been pushed, 3070c8259b85b701d25d72aabe9dc0a8154517f96913sewardj because instructions in the prolog may be scheduled for performance. 3071c8259b85b701d25d72aabe9dc0a8154517f96913sewardj The order of PUSH is always %ebx, %ebp, %esi, %edi, with trailing 3072c8259b85b701d25d72aabe9dc0a8154517f96913sewardj registers not pushed when .cbRegs < 4. This seems somewhat strange 3073c8259b85b701d25d72aabe9dc0a8154517f96913sewardj because %ebp is the register whose usage you want to minimize, 3074c8259b85b701d25d72aabe9dc0a8154517f96913sewardj yet it is in the first half of the PUSH list. 3075c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3076c8259b85b701d25d72aabe9dc0a8154517f96913sewardj I don't know what happens when the compiler constructs an outgoing CALL. 3077c8259b85b701d25d72aabe9dc0a8154517f96913sewardj %esp could move if outgoing parameters are PUSHed, and this affects 3078c8259b85b701d25d72aabe9dc0a8154517f96913sewardj traceback for errors during the PUSHes. */ 3079c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3080c8259b85b701d25d72aabe9dc0a8154517f96913sewardj spHere = *spP; 3081c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 308286781fabbfc019b752f9605e487cfce77b2a592atom *ipP = ML_(read_Addr)((void *)(spHere + 4*(fpo->cbRegs + fpo->cdwLocals))); 308386781fabbfc019b752f9605e487cfce77b2a592atom *spP = spHere + 4*(fpo->cbRegs + fpo->cdwLocals + 1 308486781fabbfc019b752f9605e487cfce77b2a592atom + fpo->cdwParams); 308586781fabbfc019b752f9605e487cfce77b2a592atom *fpP = ML_(read_Addr)((void *)(spHere + 4*2)); 3086c8259b85b701d25d72aabe9dc0a8154517f96913sewardj return True; 3087c8259b85b701d25d72aabe9dc0a8154517f96913sewardj} 3088c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3089c8259b85b701d25d72aabe9dc0a8154517f96913sewardj 3090c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--------------------------------------------------------------*/ 3091c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/*--- ---*/ 3092b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- TOP LEVEL: GENERATE DESCRIPTION OF DATA ADDRESSES ---*/ 3093b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- FROM DWARF3 DEBUG INFO ---*/ 3094b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- ---*/ 3095b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------*/ 3096b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3097588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj/* Try to make p2XA(dst, fmt, args..) turn into 3098b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart VG_(xaprintf)(dst, fmt, args) without having to resort to 3099588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj vararg macros. As usual with everything to do with varargs, it's 3100588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj an ugly hack. 3101738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3102588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj //#define p2XA(dstxa, format, args...) 3103b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart // VG_(xaprintf)(dstxa, format, ##args) 3104738856f99eea33d86ce91dcb1d6cd5b151e307casewardj*/ 3105b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart#define p2XA VG_(xaprintf) 3106738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3107588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj/* Add a zero-terminating byte to DST, which must be an XArray* of 3108588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj HChar. */ 3109738856f99eea33d86ce91dcb1d6cd5b151e307casewardjstatic void zterm_XA ( XArray* dst ) 3110738856f99eea33d86ce91dcb1d6cd5b151e307casewardj{ 3111738856f99eea33d86ce91dcb1d6cd5b151e307casewardj HChar zero = 0; 3112738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (void) VG_(addBytesToXA)( dst, &zero, 1 ); 3113738856f99eea33d86ce91dcb1d6cd5b151e307casewardj} 3114738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3115738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3116b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Evaluate the location expression/list for var, to see whether or 3117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj not data_addr falls within the variable. If so also return the 3118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj offset of data_addr from the start of the variable. Note that 3119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs, which supplies ip,sp,fp values, will be NULL for global 3120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj variables, and non-NULL for local variables. */ 3121c4431bfe04c7490ea2d74939d222d87f13f30960njnstatic Bool data_address_is_in_var ( /*OUT*/PtrdiffT* offset, 31223297124fa2116737066ac3cd709f18fdd5405163florian const XArray* /* TyEnt */ tyents, 31233297124fa2116737066ac3cd709f18fdd5405163florian const DiVariable* var, 31243297124fa2116737066ac3cd709f18fdd5405163florian const RegSummary* regs, 31253297124fa2116737066ac3cd709f18fdd5405163florian Addr data_addr, 3126588658b13b5ad77672f323d48fe9da0ca60b0bcbtom const DebugInfo* di ) 3127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 312850fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 3129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj SizeT var_szB; 3130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj GXResult res; 3131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool show = False; 31329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 3133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->name); 3134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->gexpr); 3135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Figure out how big the variable is. */ 313750fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(tyents, var->typeR); 313850fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 313950fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. ML_(addVar) 314050fde23467d92281b32dd537d0d9a590263628c3sewardj should have rejected it. */ 314150fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 314250fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 314350fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 314450fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a host word 314550fde23467d92281b32dd537d0d9a590263628c3sewardj safely (without loss of info). */ 314650fde23467d92281b32dd537d0d9a590263628c3sewardj 314750fde23467d92281b32dd537d0d9a590263628c3sewardj var_szB = (SizeT)mul.ul; /* NB: truncate to host word */ 3148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) { 3150a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("VVVV: data_address_%#lx_is_in_var: %s :: ", 3151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, var->name ); 31529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(pp_TyEnt_C_ishly)( tyents, var->typeR ); 3153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("\n"); 3154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ignore zero-sized vars; they can never match anything. */ 3157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (var_szB == 0) { 3158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) 3159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("VVVV: -> Fail (variable is zero sized)\n"); 3160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3163588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_GX)( var->gexpr, var->fbGX, regs, di ); 3164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (show) { 3166b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("VVVV: -> "); 3167b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(pp_GXResult)( res ); 3168b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("\n"); 3169b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3170eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 31713c9cf3442185b5891e15450d6e3058aeff6796fetom if (res.kind == GXR_Addr 3172b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && res.word <= data_addr 3173b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && data_addr < res.word + var_szB) { 3174b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *offset = data_addr - res.word; 3175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 3177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 3180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3182738856f99eea33d86ce91dcb1d6cd5b151e307casewardj/* Format the acquired information into DN(AME)1 and DN(AME)2, which 3183738856f99eea33d86ce91dcb1d6cd5b151e307casewardj are XArray*s of HChar, that have been initialised by the caller. 3184738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Resulting strings will be zero terminated. Information is 3185738856f99eea33d86ce91dcb1d6cd5b151e307casewardj formatted in an understandable way. Not so easy. If frameNo is 3186738856f99eea33d86ce91dcb1d6cd5b151e307casewardj -1, this is assumed to be a global variable; else a local 3187738856f99eea33d86ce91dcb1d6cd5b151e307casewardj variable. */ 3188738856f99eea33d86ce91dcb1d6cd5b151e307casewardjstatic void format_message ( /*MOD*/XArray* /* of HChar */ dn1, 3189738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /*MOD*/XArray* /* of HChar */ dn2, 3190b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 3191518850bf0da07ed3e2244e307268ae0fd80e93a8florian const DebugInfo* di, 3192518850bf0da07ed3e2244e307268ae0fd80e93a8florian const DiVariable* var, 3193c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT var_offset, 3194c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT residual_offset, 3195518850bf0da07ed3e2244e307268ae0fd80e93a8florian const XArray* /*HChar*/ described, 3196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Int frameNo, 3197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid ) 3198eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3199738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Bool have_descr, have_srcloc; 3200738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Bool xml = VG_(clo_xml); 32011636d33c13958b9c0e7d3059cdd5005746418eb2florian const HChar* vo_plural = var_offset == 1 ? "" : "s"; 32021636d33c13958b9c0e7d3059cdd5005746418eb2florian const HChar* ro_plural = residual_offset == 1 ? "" : "s"; 32031636d33c13958b9c0e7d3059cdd5005746418eb2florian const HChar* basetag = "auxwhat"; /* a constant */ 32041636d33c13958b9c0e7d3059cdd5005746418eb2florian HChar tagL[32], tagR[32], xagL[32], xagR[32]; 3205666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe const HChar *fileName = ML_(fndn_ix2filename)(di, var->fndn_ix); 3206666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe // fileName will be "???" if var->fndn_ix == 0. 3207666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe // fileName will only be used if have_descr is True. 3208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3209d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj if (frameNo < -1) { 3210d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj vg_assert(0); /* Not allowed */ 3211d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj } 3212d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj else if (frameNo == -1) { 3213d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj vg_assert(tid == VG_INVALID_THREADID); 3214d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj } 3215d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj else /* (frameNo >= 0) */ { 3216d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj vg_assert(tid != VG_INVALID_THREADID); 3217d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj } 3218d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj 3219738856f99eea33d86ce91dcb1d6cd5b151e307casewardj vg_assert(dn1 && dn2); 3220b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(described); 3221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var && var->name); 3222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj have_descr = VG_(sizeXA)(described) > 0 3223d6b9fcc80e248211dc9cf888a768a49fa1091522florian && *(HChar*)VG_(indexXA)(described,0) != '\0'; 3224666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe have_srcloc = var->fndn_ix > 0 && var->lineNo > 0; 3225b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3226738856f99eea33d86ce91dcb1d6cd5b151e307casewardj tagL[0] = tagR[0] = xagL[0] = xagR[0] = 0; 3227738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3228738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(tagL, "<%s>", basetag); // <auxwhat> 3229738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(tagR, "</%s>", basetag); // </auxwhat> 3230738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(xagL, "<x%s>", basetag); // <xauxwhat> 3231738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(sprintf)(xagR, "</x%s>", basetag); // </xauxwhat> 3232738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3233738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3234738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TAGL(_xa) p2XA(_xa, "%s", tagL) 3235738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TAGR(_xa) p2XA(_xa, "%s", tagR) 3236738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define XAGL(_xa) p2XA(_xa, "%s", xagL) 3237738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define XAGR(_xa) p2XA(_xa, "%s", xagR) 3238738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TXTL(_xa) p2XA(_xa, "%s", "<text>") 3239738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# define TXTR(_xa) p2XA(_xa, "%s", "</text>") 3240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3241b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ------ local cases ------ */ 3242b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3243b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && (!have_srcloc) && (!have_descr) ) { 3244b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc, no description: 3245b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside local var "a", 3246b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in frame #1 of thread 1 3247b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3248738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3249738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3250738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3251b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside local var \"%pS\",", 3252738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3253738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3254738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn2 ); 3255738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3256738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "in frame #%d of thread %d", frameNo, (Int)tid ); 3257738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn2 ); 3258738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3259738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3260738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside local var \"%s\",", 3261738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3262738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3263738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "in frame #%d of thread %d", frameNo, (Int)tid ); 3264738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3266b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3267b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && have_srcloc && (!have_descr) ) { 3268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no description: 3269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside local var "a" 3270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj declared at dsyms7.c:17, in frame #1 of thread 1 3271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3272738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3273738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3274738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3275b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside local var \"%pS\"", 3276738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3277738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3278738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 3279738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 3280738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3281b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "declared at %pS:%d, in frame #%d of thread %d", 3282666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo, frameNo, (Int)tid ); 3283738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 3284738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 3285738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3286b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart " <file>%pS</file> <line>%d</line> ", 3287666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo ); 3288738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 3289738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3290738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3291738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside local var \"%s\"", 3292738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3293738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3294738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "declared at %s:%d, in frame #%d of thread %d", 3295666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo, frameNo, (Int)tid ); 3296738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3297b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && (!have_srcloc) && have_descr ) { 3300b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc: 3301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2 3302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in frame #1 of thread 1 3303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3304738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3305738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3306738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3307b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside %pS%pS", 3308738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3309738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3310738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3311738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn2 ); 3312738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3313738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "in frame #%d of thread %d", frameNo, (Int)tid ); 3314738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn2 ); 3315738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3316738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3317738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %s%s", 3318738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3319738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3320738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3321738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "in frame #%d of thread %d", frameNo, (Int)tid ); 3322738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= 0 && have_srcloc && have_descr ) { 3326738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 3327738856f99eea33d86ce91dcb1d6cd5b151e307casewardj declared at dsyms7.c:17, in frame #1 of thread 1 */ 3328738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3329738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3330738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3331b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside %pS%pS,", 3332738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3333738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3334738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3335738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 3336738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 3337738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3338b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "declared at %pS:%d, in frame #%d of thread %d", 3339666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo, frameNo, (Int)tid ); 3340738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 3341738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 3342738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3343b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart " <file>%pS</file> <line>%d</line> ", 3344666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo ); 3345738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 3346738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3347738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3348738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %s%s,", 3349738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3350738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3351738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3352738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "declared at %s:%d, in frame #%d of thread %d", 3353666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo, frameNo, (Int)tid ); 3354738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3356b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* ------ global cases ------ */ 3358b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && (!have_srcloc) && (!have_descr) ) { 3359b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc, no description: 3360b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside global var "a" 3361b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3362738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3363738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3364738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3365b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside global var \"%pS\"", 3366738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3367738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3368738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3369738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3370738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside global var \"%s\"", 3371738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3372738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && have_srcloc && (!have_descr) ) { 3376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no description: 3377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 543 bytes inside global var "a" 3378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj declared at dsyms7.c:17 3379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3380738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3381738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3382738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3383b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside global var \"%pS\"", 3384738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3385738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3386738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 3387738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 3388738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3389b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "declared at %pS:%d", 3390666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo); 3391738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 3392738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 3393738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3394b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart " <file>%pS</file> <line>%d</line> ", 3395666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo ); 3396738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 3397738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3398738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3399738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside global var \"%s\"", 3400738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, var_offset, vo_plural, var->name ); 3401738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3402738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "declared at %s:%d", 3403666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo); 3404738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && (!have_srcloc) && have_descr ) { 3408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* no srcloc: 3409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 3410b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj a global variable 3411b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */ 3412738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3413738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3414738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3415b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside %pS%pS,", 3416738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3417738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3418738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3419738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn2 ); 3420738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3421738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "a global variable"); 3422738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn2 ); 3423738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3424738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3425738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %s%s,", 3426738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3427738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (char*)(VG_(indexXA)(described,0)) ); 3428738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3429738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "a global variable"); 3430738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ( frameNo >= -1 && have_srcloc && have_descr ) { 3434738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /* Location 0x7fefff6cf is 2 bytes inside a[3].xyzzy[21].c2, 3435738856f99eea33d86ce91dcb1d6cd5b151e307casewardj a global variable declared at dsyms7.c:17 */ 3436738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (xml) { 3437738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGL( dn1 ); 3438738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3439b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "Location 0x%lx is %lu byte%s inside %pS%pS,", 3440738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3441738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3442738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TAGR( dn1 ); 3443738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGL( dn2 ); 3444738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTL( dn2 ); 3445738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3446b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart "a global variable declared at %pS:%d", 3447666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo); 3448738856f99eea33d86ce91dcb1d6cd5b151e307casewardj TXTR( dn2 ); 3449738856f99eea33d86ce91dcb1d6cd5b151e307casewardj // FIXME: also do <dir> 3450738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3451b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart " <file>%pS</file> <line>%d</line> ", 3452666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo ); 3453738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XAGR( dn2 ); 3454738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } else { 3455738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn1, 3456738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Location 0x%lx is %lu byte%s inside %s%s,", 3457738856f99eea33d86ce91dcb1d6cd5b151e307casewardj data_addr, residual_offset, ro_plural, var->name, 3458738856f99eea33d86ce91dcb1d6cd5b151e307casewardj (HChar*)(VG_(indexXA)(described,0)) ); 3459738856f99eea33d86ce91dcb1d6cd5b151e307casewardj p2XA( dn2, 3460738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "a global variable declared at %s:%d", 3461666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe fileName, var->lineNo); 3462738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 3463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3464b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj else 3465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(0); 3466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3467738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /* Zero terminate both strings */ 3468738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dn1 ); 3469738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dn2 ); 3470738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3471738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TAGL 3472738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TAGR 3473738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef XAGL 3474738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef XAGR 3475738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TXTL 3476738856f99eea33d86ce91dcb1d6cd5b151e307casewardj# undef TXTR 3477eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3478eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3479738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Determine if data_addr is a local variable in the frame 3481738856f99eea33d86ce91dcb1d6cd5b151e307casewardj characterised by (ip,sp,fp), and if so write its description at the 3482738856f99eea33d86ce91dcb1d6cd5b151e307casewardj ends of DNAME{1,2}, which are XArray*s of HChar, that have been 3483738856f99eea33d86ce91dcb1d6cd5b151e307casewardj initialised by the caller, zero terminate both, and return True. 3484738856f99eea33d86ce91dcb1d6cd5b151e307casewardj If it's not a local variable in said frame, return False. */ 3485b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic 3486738856f99eea33d86ce91dcb1d6cd5b151e307casewardjBool consider_vars_in_frame ( /*MOD*/XArray* /* of HChar */ dname1, 3487738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /*MOD*/XArray* /* of HChar */ dname2, 3488b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr data_addr, 3489b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr ip, Addr sp, Addr fp, 3490b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* shown to user: */ 3491b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid, Int frameNo ) 3492eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3493b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word i; 3494b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 3495b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj RegSummary regs; 3496b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool debug = False; 3497b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3498b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj static UInt n_search = 0; 3499b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj static UInt n_steps = 0; 3500b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_search++; 3501b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 3502a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("QQQQ: cvif: ip,sp,fp %#lx,%#lx,%#lx\n", ip,sp,fp); 3503b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* first, find the DebugInfo that pertains to 'ip'. */ 3504b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di; di = di->next) { 3505b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_steps++; 3506b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* text segment missing? unlikely, but handle it .. */ 3507b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->text_present || di->text_size == 0) 3508b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3509b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok. So does this text mapping bracket the ip? */ 3510b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_avma <= ip && ip < di->text_avma + di->text_size) 3511b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3512b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3513b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3514b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Didn't find it. Strange -- means ip is a code address outside 3515b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj of any mapped text segment. Unlikely but not impossible -- app 3516b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj could be generating code to run. */ 3517b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di) 3518b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3519b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3520b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0 && ((n_search & 0x1) == 0)) 3521b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("consider_vars_in_frame: %u searches, " 3522b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj "%u DebugInfos looked at\n", 3523b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_search, n_steps); 3524b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Start of performance-enhancing hack: once every ??? (chosen 3525b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj hackily after profiling) successful searches, move the found 3526b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo one step closer to the start of the list. This makes 3527b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj future searches cheaper. */ 3528b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if ((n_search & 0xFFFF) == 0) { 3529b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Move si one step closer to the start of the list. */ 3530b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj move_DebugInfo_one_step_forward( di ); 3531b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3532b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* End of performance-enhancing hack. */ 3533b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3534b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* any var info at all? */ 3535b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->varinfo) 3536b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3537b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Work through the scopes from most deeply nested outwards, 3539b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj looking for code address ranges that bracket 'ip'. The 3540b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj variables on each such address range found are in scope right 3541b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj now. Don't descend to level zero as that is the global 3542b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj scope. */ 3543b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.ip = ip; 3544b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.sp = sp; 3545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj regs.fp = fp; 3546b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3547b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* "for each scope, working outwards ..." */ 3548b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) { 3549b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* vars; 3550b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word j; 3551b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* arange; 3552b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* this_scope 3553b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj = *(OSet**)VG_(indexXA)( di->varinfo, i ); 3554b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 3555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)("QQQQ: considering scope %ld\n", (Word)i); 3556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!this_scope) 3557b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3558b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Find the set of variables in this scope that 3559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj bracket the program counter. */ 3560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj arange = VG_(OSetGen_LookupWithCmp)( 3561b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj this_scope, &ip, 3562b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(cmp_for_DiAddrRange_range) 3563b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ); 3564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!arange) 3565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* stay sane */ 3567b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->aMin <= arange->aMax); 3568b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* It must bracket the ip we asked for, else 3569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ML_(cmp_for_DiAddrRange_range) is somehow broken. */ 3570b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(arange->aMin <= ip && ip <= arange->aMax); 3571b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* It must have an attached XArray of DiVariables. */ 3572b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vars = arange->vars; 3573b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(vars); 3574b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* But it mustn't cover the entire address range. We only 3575b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj expect that to happen for the global scope (level 0), which 3576b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj we're not looking at here. Except, it may cover the entire 3577b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj address range, but in that case the vars array must be 3578b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj empty. */ 3579b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(! (arange->aMin == (Addr)0 3580b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && arange->aMax == ~(Addr)0 3581b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && VG_(sizeXA)(vars) > 0) ); 3582b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < VG_(sizeXA)( vars ); j++) { 3583b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j ); 3584c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT offset; 3585b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (debug) 3586a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n", 3587b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj var->name,arange->aMin,arange->aMax,ip); 35889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (data_address_is_in_var( &offset, di->admin_tyents, 35899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var, ®s, 3590588658b13b5ad77672f323d48fe9da0ca60b0bcbtom data_addr, di )) { 3591c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT residual_offset = 0; 3592b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* described = ML_(describe_type)( &residual_offset, 35939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->admin_tyents, 35949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR, offset ); 3595738856f99eea33d86ce91dcb1d6cd5b151e307casewardj format_message( dname1, dname2, 3596666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe data_addr, di, var, offset, residual_offset, 3597b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj described, frameNo, tid ); 3598b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)( described ); 3599b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3600b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3601b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3602b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3603b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3604b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3605eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3606eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3607738856f99eea33d86ce91dcb1d6cd5b151e307casewardj/* Try to form some description of DATA_ADDR by looking at the DWARF3 360825963376a3669e7f77395d6f884bdf1f6a928966philippe debug info we have. This considers all global variables, and 8 3609738856f99eea33d86ce91dcb1d6cd5b151e307casewardj frames in the stacks of all threads. Result is written at the ends 3610738856f99eea33d86ce91dcb1d6cd5b151e307casewardj of DNAME{1,2}V, which are XArray*s of HChar, that have been 3611738856f99eea33d86ce91dcb1d6cd5b151e307casewardj initialised by the caller, and True is returned. If no description 3612738856f99eea33d86ce91dcb1d6cd5b151e307casewardj is created, False is returned. Regardless of the return value, 3613738856f99eea33d86ce91dcb1d6cd5b151e307casewardj DNAME{1,2}V are guaranteed to be zero terminated after the call. 3614738856f99eea33d86ce91dcb1d6cd5b151e307casewardj 3615738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Note that after the call, DNAME{1,2} may have more than one 3616738856f99eea33d86ce91dcb1d6cd5b151e307casewardj trailing zero, so callers should establish the useful text length 3617738856f99eea33d86ce91dcb1d6cd5b151e307casewardj using VG_(strlen) on the contents, rather than VG_(sizeXA) on the 3618738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XArray itself. 3619738856f99eea33d86ce91dcb1d6cd5b151e307casewardj*/ 3620738856f99eea33d86ce91dcb1d6cd5b151e307casewardjBool VG_(get_data_description)( 3621738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /*MOD*/ void* /* really, XArray* of HChar */ dname1v, 3622738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /*MOD*/ void* /* really, XArray* of HChar */ dname2v, 3623738856f99eea33d86ce91dcb1d6cd5b151e307casewardj Addr data_addr 3624738856f99eea33d86ce91dcb1d6cd5b151e307casewardj ) 3625eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 3626b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# define N_FRAMES 8 3627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr ips[N_FRAMES], sps[N_FRAMES], fps[N_FRAMES]; 3628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj UInt n_frames; 3629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3630b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr stack_min, stack_max; 3631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj ThreadId tid; 3632b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Bool found; 3633b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 3634b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word j; 3635b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3636738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XArray* dname1 = (XArray*)dname1v; 3637738856f99eea33d86ce91dcb1d6cd5b151e307casewardj XArray* dname2 = (XArray*)dname2v; 3638b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3639a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart if (0) VG_(printf)("get_data_description: dataaddr %#lx\n", data_addr); 3640b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* First, see if data_addr is (or is part of) a global variable. 3641b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Loop over the DebugInfos we have. Check data_addr against the 3642b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj outermost scope of all of them, as that should be a global 3643b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj scope. */ 3644b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 3645b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj OSet* global_scope; 36469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word gs_size; 3647b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Addr zero; 3648b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiAddrRange* global_arange; 3649b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj Word i; 3650b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* vars; 3651b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3652b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* text segment missing? unlikely, but handle it .. */ 3653b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->text_present || di->text_size == 0) 3654b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3655b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* any var info at all? */ 3656b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!di->varinfo) 3657b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3658b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* perhaps this object didn't contribute any vars at all? */ 3659b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (VG_(sizeXA)( di->varinfo ) == 0) 3660b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3661b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj global_scope = *(OSet**)VG_(indexXA)( di->varinfo, 0 ); 3662b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_scope); 3663b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj gs_size = VG_(OSetGen_Size)( global_scope ); 3664b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* The global scope might be completely empty if this 3665b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj compilation unit declared locals but nothing global. */ 3666b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (gs_size == 0) 3667b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3668b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* But if it isn't empty, then it must contain exactly one 3669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj element, which covers the entire address range. */ 3670b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(gs_size == 1); 3671b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Fish out the global scope and check it is as expected. */ 3672b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj zero = 0; 3673b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj global_arange 3674b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj = VG_(OSetGen_Lookup)( global_scope, &zero ); 3675b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* The global range from (Addr)0 to ~(Addr)0 must exist */ 3676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_arange); 3677b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(global_arange->aMin == (Addr)0 3678b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && global_arange->aMax == ~(Addr)0); 3679b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Any vars in this range? */ 3680b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!global_arange->vars) 3681b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; 3682b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok, there are some vars in the global scope of this 3683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo. Wade through them and see if the data addresses 3684b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj of any of them bracket data_addr. */ 3685b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vars = global_arange->vars; 3686b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (i = 0; i < VG_(sizeXA)( vars ); i++) { 3687c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT offset; 3688b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, i ); 3689b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(var->name); 3690b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Note we use a NULL RegSummary* here. It can't make any 3691b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sense for a global variable to have a location expression 3692b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which depends on a SP/FP/IP value. So don't supply any. 3693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj This means, if the evaluation of the location 3694b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj expression/list requires a register, we have to let it 3695b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj fail. */ 36969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (data_address_is_in_var( &offset, di->admin_tyents, var, 3697b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj NULL/* RegSummary* */, 3698588658b13b5ad77672f323d48fe9da0ca60b0bcbtom data_addr, di )) { 3699c4431bfe04c7490ea2d74939d222d87f13f30960njn PtrdiffT residual_offset = 0; 3700b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj XArray* described = ML_(describe_type)( &residual_offset, 37019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di->admin_tyents, 37029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR, offset ); 3703738856f99eea33d86ce91dcb1d6cd5b151e307casewardj format_message( dname1, dname2, 3704666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe data_addr, di, var, offset, residual_offset, 3705d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj described, -1/*frameNo*/, 3706d7adca740c8309a31c897c1ec6c3bbfe1c26489bsewardj VG_INVALID_THREADID ); 3707b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(deleteXA)( described ); 3708738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3709738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3710b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3711b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3712b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3713b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3714b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3715b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Ok, well it's not a global variable. So now let's snoop around 3716b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj in the stacks of all the threads. First try to figure out which 3717b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj thread's stack data_addr is in. */ 3718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Perhaps it's on a thread's stack? */ 3720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj found = False; 3721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(thread_stack_reset_iter)(&tid); 3722b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) { 3723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (stack_min >= stack_max) 3724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj continue; /* ignore obviously stupid cases */ 3725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (stack_min - VG_STACK_REDZONE_SZB <= data_addr 3726b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && data_addr <= stack_max) { 3727b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj found = True; 3728b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 3729b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3730b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3731b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (!found) { 3732738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3733738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3734b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3736b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3737b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We conclude data_addr is in thread tid's stack. Unwind the 3738b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj stack to get a bunch of (ip,sp,fp) triples describing the 3739b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj frames, and for each frame, consider the local variables. */ 3740b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj n_frames = VG_(get_StackTrace)( tid, ips, N_FRAMES, 3741b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sps, fps, 0/*first_ip_delta*/ ); 3742b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj 3743b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert(n_frames >= 0 && n_frames <= N_FRAMES); 3744b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (j = 0; j < n_frames; j++) { 3745738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (consider_vars_in_frame( dname1, dname2, 3746b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj data_addr, 3747b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj ips[j], 3748b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj sps[j], fps[j], tid, j )) { 3749738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3750738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3751b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3752b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3753b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* Now, it appears that gcc sometimes appears to produce 3754b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj location lists whose ranges don't actually cover the call 3755b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj instruction, even though the address of the variable in 3756b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj question is passed as a parameter in the call. AFAICS this 3757b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj is simply a bug in gcc - how can the variable be claimed not 3758b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj exist in memory (on the stack) for the duration of a call in 3759b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj which its address is passed? But anyway, in the particular 3760b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case I investigated (memcheck/tests/varinfo6.c, call to croak 3761b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj on line 2999, local var budget declared at line 3115 3762b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj appearing not to exist across the call to mainSort on line 3763b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3143, "gcc.orig (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2)" on 3764b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj amd64), the variable's location list does claim it exists 3765b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj starting at the first byte of the first instruction after the 3766b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj call instruction. So, call consider_vars_in_frame a second 3767b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj time, but this time add 1 to the IP. GDB handles this 3768b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj example with no difficulty, which leads me to believe that 3769b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj either (1) I misunderstood something, or (2) GDB has an 3770b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj equivalent kludge. */ 3771b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj if (j > 0 /* this is a non-innermost frame */ 3772738856f99eea33d86ce91dcb1d6cd5b151e307casewardj && consider_vars_in_frame( dname1, dname2, 3773b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj data_addr, 3774b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj ips[j] + 1, 3775b1ae15d5c3ca2fb57cf1545debd62fc653ad2abfsewardj sps[j], fps[j], tid, j )) { 3776738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3777738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3778b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return True; 3779b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3780b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 3781b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 3782b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* We didn't find anything useful. */ 3783738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname1 ); 3784738856f99eea33d86ce91dcb1d6cd5b151e307casewardj zterm_XA( dname2 ); 3785b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return False; 3786b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj# undef N_FRAMES 3787eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 3788eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 3789b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 37909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj////////////////////////////////////////////////////////////////// 37919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// // 37929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// Support for other kinds of queries to the Dwarf3 var info // 37939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj// // 37949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj////////////////////////////////////////////////////////////////// 37959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 37969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Figure out if the variable 'var' has a location that is linearly 37979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj dependent on a stack pointer value, or a frame pointer value, and 37989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if it is, add a description of it to 'blocks'. Otherwise ignore 37999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. If 'arrays_only' is True, also ignore it unless it has an 38009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj array type. */ 38019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic 38039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid analyse_deps ( /*MOD*/XArray* /* of FrameBlock */ blocks, 38043297124fa2116737066ac3cd709f18fdd5405163florian const XArray* /* TyEnt */ tyents, 38053297124fa2116737066ac3cd709f18fdd5405163florian Addr ip, const DebugInfo* di, const DiVariable* var, 38069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool arrays_only ) 38079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 38089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res_sp_6k, res_sp_7k, res_fp_6k, res_fp_7k; 38099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj RegSummary regs; 381050fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 38119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool isVec; 38129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ty; 38139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool debug = False; 38159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0&&debug) 38169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("adeps: var %s\n", var->name ); 38179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Figure out how big the variable is. */ 381950fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(tyents, var->typeR); 382050fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 382150fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. ML_(addVar) 382250fde23467d92281b32dd537d0d9a590263628c3sewardj should have rejected it. */ 382350fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 382450fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 382550fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 382650fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a host word 382750fde23467d92281b32dd537d0d9a590263628c3sewardj safely (without loss of info). */ 38289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* skip if non-array and we're only interested in arrays */ 38309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ty = ML_(TyEnts__index_by_cuOff)( tyents, NULL, var->typeR ); 38319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty); 38329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty)); 38339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (ty->tag == Te_UNKNOWN) 38349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return; /* perhaps we should complain in this case? */ 38359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj isVec = ty->tag == Te_TyArray; 38369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (arrays_only && !isVec) 38379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return; 38389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) {ML_(pp_TyEnt_C_ishly)(tyents, var->typeR); 38409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)(" %s\n", var->name);} 38419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Do some test evaluations of the variable's location expression, 38439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj in order to guess whether it is sp-relative, fp-relative, or 38449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj none. A crude hack, which can be interpreted roughly as finding 38459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj the first derivative of the location expression w.r.t. the 38469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj supplied frame and stack pointer values. */ 38479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 0; 38489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 38499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 6 * 1024; 3850588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_sp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 38519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 0; 38539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 38549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 7 * 1024; 3855588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_sp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 38569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 6 * 1024; 38589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 38599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 0; 3860588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_fp_6k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 38619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.fp = 7 * 1024; 38639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 38649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = 0; 3865588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res_fp_7k = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 38669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_sp_7k.kind); 38689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_fp_6k.kind); 38699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(res_sp_6k.kind == res_fp_7k.kind); 38709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38713c9cf3442185b5891e15450d6e3058aeff6796fetom if (res_sp_6k.kind == GXR_Addr) { 38729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj StackBlock block; 38739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res; 38749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj UWord sp_delta = res_sp_7k.word - res_sp_6k.word; 38759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj UWord fp_delta = res_fp_7k.word - res_fp_6k.word; 3876e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(sp_delta == 0 || sp_delta == 1024); 3877e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(fp_delta == 0 || fp_delta == 1024); 38789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 38799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 0 && fp_delta == 0) { 38809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* depends neither on sp nor fp, so it can't be a stack 38819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj local. Ignore it. */ 38829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 38839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else 38849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 1024 && fp_delta == 0) { 38859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = regs.fp = 0; 38869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 3887588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 3888e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(res.kind == GXR_Addr); 38899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 38909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)(" %5ld .. %5ld (sp) %s\n", 389150fde23467d92281b32dd537d0d9a590263628c3sewardj res.word, res.word + ((UWord)mul.ul) - 1, var->name); 38929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.base = res.word; 389350fde23467d92281b32dd537d0d9a590263628c3sewardj block.szB = (SizeT)mul.ul; 38949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.spRel = True; 38959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.isVec = isVec; 38969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)( &block.name[0], 0, sizeof(block.name) ); 38979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (var->name) 38989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 ); 38999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.name[ sizeof(block.name)-1 ] = 0; 39009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( blocks, &block ); 39019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 39029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else 39039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (sp_delta == 0 && fp_delta == 1024) { 39049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.sp = regs.fp = 0; 39059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj regs.ip = ip; 3906588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); 3907e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(res.kind == GXR_Addr); 39089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 39099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)(" %5ld .. %5ld (FP) %s\n", 391050fde23467d92281b32dd537d0d9a590263628c3sewardj res.word, res.word + ((UWord)mul.ul) - 1, var->name); 39119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.base = res.word; 391250fde23467d92281b32dd537d0d9a590263628c3sewardj block.szB = (SizeT)mul.ul; 39139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.spRel = False; 39149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.isVec = isVec; 39159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)( &block.name[0], 0, sizeof(block.name) ); 39169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (var->name) 39179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)( &block.name[0], var->name, sizeof(block.name)-1 ); 39189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj block.name[ sizeof(block.name)-1 ] = 0; 39199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( blocks, &block ); 39209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 39219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj else { 39229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(0); 39239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 39249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 39259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 39269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Get an XArray of StackBlock which describe the stack (auto) blocks 39299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for this ip. The caller is expected to free the XArray at some 39309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj point. If 'arrays_only' is True, only array-typed blocks are 39319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj returned; otherwise blocks of all types are returned. */ 39329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid* /* really, XArray* of StackBlock */ 39349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(di_get_stack_blocks_at_ip)( Addr ip, Bool arrays_only ) 39359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 39369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* This is a derivation of consider_vars_in_frame() above. */ 39379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word i; 39389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo* di; 39399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool debug = False; 39409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* res = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dgsbai.1", 39429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(dinfo_free), 39439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj sizeof(StackBlock) ); 39449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj static UInt n_search = 0; 39469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj static UInt n_steps = 0; 39479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_search++; 39489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 39499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: dgsbai: ip %#lx\n", ip); 39509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* first, find the DebugInfo that pertains to 'ip'. */ 39519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (di = debugInfo_list; di; di = di->next) { 39529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_steps++; 39539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* text segment missing? unlikely, but handle it .. */ 39549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->text_present || di->text_size == 0) 39559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 39569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok. So does this text mapping bracket the ip? */ 39579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (di->text_avma <= ip && ip < di->text_avma + di->text_size) 39589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj break; 39599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 39609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Didn't find it. Strange -- means ip is a code address outside 39629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj of any mapped text segment. Unlikely but not impossible -- app 39639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj could be generating code to run. */ 39649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di) 39659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; /* currently empty */ 39669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0 && ((n_search & 0x1) == 0)) 39689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("VG_(di_get_stack_blocks_at_ip): %u searches, " 39699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj "%u DebugInfos looked at\n", 39709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj n_search, n_steps); 39719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Start of performance-enhancing hack: once every ??? (chosen 39729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj hackily after profiling) successful searches, move the found 39739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo one step closer to the start of the list. This makes 39749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj future searches cheaper. */ 39759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if ((n_search & 0xFFFF) == 0) { 39769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Move si one step closer to the start of the list. */ 39779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj move_DebugInfo_one_step_forward( di ); 39789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 39799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* End of performance-enhancing hack. */ 39809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* any var info at all? */ 39829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->varinfo) 39839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; /* currently empty */ 39849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Work through the scopes from most deeply nested outwards, 39869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj looking for code address ranges that bracket 'ip'. The 39879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj variables on each such address range found are in scope right 39889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj now. Don't descend to level zero as that is the global 39899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj scope. */ 39909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 39919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* "for each scope, working outwards ..." */ 39929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (i = VG_(sizeXA)(di->varinfo) - 1; i >= 1; i--) { 39939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* vars; 39949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word j; 39959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiAddrRange* arange; 39969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj OSet* this_scope 39979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj = *(OSet**)VG_(indexXA)( di->varinfo, i ); 39989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 39999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: considering scope %ld\n", (Word)i); 40009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!this_scope) 40019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 40029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Find the set of variables in this scope that 40039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj bracket the program counter. */ 40049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj arange = VG_(OSetGen_LookupWithCmp)( 40059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj this_scope, &ip, 40069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(cmp_for_DiAddrRange_range) 40079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ); 40089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!arange) 40099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 40109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* stay sane */ 40119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(arange->aMin <= arange->aMax); 40129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* It must bracket the ip we asked for, else 40139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(cmp_for_DiAddrRange_range) is somehow broken. */ 40149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(arange->aMin <= ip && ip <= arange->aMax); 40159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* It must have an attached XArray of DiVariables. */ 40169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vars = arange->vars; 40179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(vars); 40189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* But it mustn't cover the entire address range. We only 40199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj expect that to happen for the global scope (level 0), which 40209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj we're not looking at here. Except, it may cover the entire 40219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj address range, but in that case the vars array must be 40229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj empty. */ 40239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(! (arange->aMin == (Addr)0 40249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj && arange->aMax == ~(Addr)0 40259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj && VG_(sizeXA)(vars) > 0) ); 40269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (j = 0; j < VG_(sizeXA)( vars ); j++) { 40279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiVariable* var = (DiVariable*)VG_(indexXA)( vars, j ); 40289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (debug) 40299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("QQQQ: var:name=%s %#lx-%#lx %#lx\n", 40309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->name,arange->aMin,arange->aMax,ip); 40319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj analyse_deps( res, di->admin_tyents, ip, 4032588658b13b5ad77672f323d48fe9da0ca60b0bcbtom di, var, arrays_only ); 40339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 40349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 40359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return res; 40379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 40389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Get an array of GlobalBlock which describe the global blocks owned 40419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj by the shared object characterised by the given di_handle. Asserts 40429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if the handle is invalid. The caller is responsible for freeing 40439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj the array at some point. If 'arrays_only' is True, only 40449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj array-typed blocks are returned; otherwise blocks of all types are 40459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj returned. */ 40469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid* /* really, XArray* of GlobalBlock */ 40489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(di_get_global_blocks_from_dihandle) ( ULong di_handle, 40499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool arrays_only ) 40509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{ 40519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* This is a derivation of consider_vars_in_frame() above. */ 40529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DebugInfo* di; 40549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj XArray* gvars; /* XArray* of GlobalBlock */ 40559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word nScopes, scopeIx; 40569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* The first thing to do is find the DebugInfo that 40589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj pertains to 'di_handle'. */ 4059e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(di_handle > 0); 40609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (di = debugInfo_list; di; di = di->next) { 40619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (di->handle == di_handle) 40629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj break; 40639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 40649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* If this fails, we were unable to find any DebugInfo with the 40669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj given handle. This is considered an error on the part of the 40679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj caller. */ 4068e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(di != NULL); 40699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* we'll put the collected variables in here. */ 40719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gvars = VG_(newXA)( ML_(dinfo_zalloc), "di.debuginfo.dggbfd.1", 40729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ML_(dinfo_free), sizeof(GlobalBlock) ); 40739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* any var info at all? */ 40759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (!di->varinfo) 40769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return gvars; 40779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* we'll iterate over all the variables we can find, even if 40799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it seems senseless to visit stack-allocated variables */ 40809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over all scopes */ 40819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj nScopes = VG_(sizeXA)( di->varinfo ); 40829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (scopeIx = 0; scopeIx < nScopes; scopeIx++) { 40839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over each (code) address range at the current scope */ 40859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiAddrRange* range; 40869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj OSet* /* of DiAddrInfo */ scope 40879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj = *(OSet**)VG_(indexXA)( di->varinfo, scopeIx ); 4088e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(scope); 40899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(OSetGen_ResetIter)(scope); 40909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj while ( (range = VG_(OSetGen_Next)(scope)) ) { 40919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Iterate over each variable in the current address range */ 40939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Word nVars, varIx; 4094e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(range->vars); 40959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj nVars = VG_(sizeXA)( range->vars ); 40969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj for (varIx = 0; varIx < nVars; varIx++) { 40979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 40989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj Bool isVec; 40999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GXResult res; 410050fde23467d92281b32dd537d0d9a590263628c3sewardj MaybeULong mul; 41019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj GlobalBlock gb; 41029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj TyEnt* ty; 41039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj DiVariable* var = VG_(indexXA)( range->vars, varIx ); 4104e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(var->name); 41059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("at depth %ld var %s ", scopeIx, var->name ); 41069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Now figure out if this variable has a constant address 41089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj (that is, independent of FP, SP, phase of moon, etc), 41099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj and if so, what the address is. Any variable with a 41109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj constant address is deemed to be a global so we collect 41119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. */ 41129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) { VG_(printf)("EVAL: "); ML_(pp_GX)(var->gexpr); 41139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(printf)("\n"); } 4114588658b13b5ad77672f323d48fe9da0ca60b0bcbtom res = ML_(evaluate_trivial_GX)( var->gexpr, di ); 41159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Not a constant address => not interesting */ 41173c9cf3442185b5891e15450d6e3058aeff6796fetom if (res.kind != GXR_Addr) { 41189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("FAIL\n"); 41199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; 41209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } 41219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok, it's a constant address. See if we want to collect 41239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj it. */ 41249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("%#lx\n", res.word); 41259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Figure out how big the variable is. */ 412750fde23467d92281b32dd537d0d9a590263628c3sewardj mul = ML_(sizeOfType)(di->admin_tyents, var->typeR); 41289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 412950fde23467d92281b32dd537d0d9a590263628c3sewardj /* If this var has a type whose size is unknown, zero, or 413050fde23467d92281b32dd537d0d9a590263628c3sewardj impossibly large, it should never have been added. 413150fde23467d92281b32dd537d0d9a590263628c3sewardj ML_(addVar) should have rejected it. */ 413250fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.b == True); 413350fde23467d92281b32dd537d0d9a590263628c3sewardj vg_assert(mul.ul > 0); 413450fde23467d92281b32dd537d0d9a590263628c3sewardj if (sizeof(void*) == 4) vg_assert(mul.ul < (1ULL << 32)); 413550fde23467d92281b32dd537d0d9a590263628c3sewardj /* After this point, we assume we can truncate mul.ul to a 413650fde23467d92281b32dd537d0d9a590263628c3sewardj host word safely (without loss of info). */ 41379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* skip if non-array and we're only interested in 41399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj arrays */ 41409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ty = ML_(TyEnts__index_by_cuOff)( di->admin_tyents, NULL, 41419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj var->typeR ); 41429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty); 41439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj vg_assert(ty->tag == Te_UNKNOWN || ML_(TyEnt__is_type)(ty)); 41449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (ty->tag == Te_UNKNOWN) 41459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj continue; /* perhaps we should complain in this case? */ 41469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj isVec = ty->tag == Te_TyArray; 41489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (arrays_only && !isVec) continue; 41499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj /* Ok, so collect it! */ 4151e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(var->name); 4152e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(di->soname); 41539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if (0) VG_(printf)("XXXX %s %s %d\n", var->name, 4154666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe ML_(fndn_ix2filename)(di, var->fndn_ix), 4155666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe var->lineNo); 41569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(memset)(&gb, 0, sizeof(gb)); 41579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gb.addr = res.word; 415850fde23467d92281b32dd537d0d9a590263628c3sewardj gb.szB = (SizeT)mul.ul; 41599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj gb.isVec = isVec; 41609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)(&gb.name[0], var->name, sizeof(gb.name)-1); 41619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(strncpy)(&gb.soname[0], di->soname, sizeof(gb.soname)-1); 4162e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(gb.name[ sizeof(gb.name)-1 ] == 0); 4163e2800c958044937e72eefa371c10ae47ac40e089florian vg_assert(gb.soname[ sizeof(gb.soname)-1 ] == 0); 41649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_(addToXA)( gvars, &gb ); 41669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* for (varIx = 0; varIx < nVars; varIx++) */ 41689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* while ( (range = VG_(OSetGen_Next)(scope)) ) */ 41709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj } /* for (scopeIx = 0; scopeIx < nScopes; scopeIx++) */ 41729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj return gvars; 41749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj} 41759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 41769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 4177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 4178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- DebugInfo accessor functions ---*/ 4179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 4180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4181e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjconst DebugInfo* VG_(next_DebugInfo)(const DebugInfo* di) 4182eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di == NULL) 4184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return debugInfo_list; 4185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->next; 4186eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4187eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4188e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjAddr VG_(DebugInfo_get_text_avma)(const DebugInfo* di) 4189eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4190b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_avma : 0; 4191eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4192eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4193e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjSizeT VG_(DebugInfo_get_text_size)(const DebugInfo* di) 4194eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4195b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_size : 0; 4196eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4197eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 41983898022a7d74a227d6a35102faaedd420ed3a1c1bartAddr VG_(DebugInfo_get_bss_avma)(const DebugInfo* di) 41993898022a7d74a227d6a35102faaedd420ed3a1c1bart{ 42003898022a7d74a227d6a35102faaedd420ed3a1c1bart return di->bss_present ? di->bss_avma : 0; 42013898022a7d74a227d6a35102faaedd420ed3a1c1bart} 42023898022a7d74a227d6a35102faaedd420ed3a1c1bart 42033898022a7d74a227d6a35102faaedd420ed3a1c1bartSizeT VG_(DebugInfo_get_bss_size)(const DebugInfo* di) 42043898022a7d74a227d6a35102faaedd420ed3a1c1bart{ 42053898022a7d74a227d6a35102faaedd420ed3a1c1bart return di->bss_present ? di->bss_size : 0; 42063898022a7d74a227d6a35102faaedd420ed3a1c1bart} 42073898022a7d74a227d6a35102faaedd420ed3a1c1bart 4208e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjAddr VG_(DebugInfo_get_plt_avma)(const DebugInfo* di) 4209092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 4210092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->plt_present ? di->plt_avma : 0; 4211092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 4212092b6268cc4a38ae9ee41d1e3355937536ddc579bart 4213e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjSizeT VG_(DebugInfo_get_plt_size)(const DebugInfo* di) 4214092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 4215092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->plt_present ? di->plt_size : 0; 4216092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 4217092b6268cc4a38ae9ee41d1e3355937536ddc579bart 4218e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjAddr VG_(DebugInfo_get_gotplt_avma)(const DebugInfo* di) 4219092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 4220092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->gotplt_present ? di->gotplt_avma : 0; 4221092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 4222092b6268cc4a38ae9ee41d1e3355937536ddc579bart 4223e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjSizeT VG_(DebugInfo_get_gotplt_size)(const DebugInfo* di) 4224092b6268cc4a38ae9ee41d1e3355937536ddc579bart{ 4225092b6268cc4a38ae9ee41d1e3355937536ddc579bart return di->gotplt_present ? di->gotplt_size : 0; 4226092b6268cc4a38ae9ee41d1e3355937536ddc579bart} 4227092b6268cc4a38ae9ee41d1e3355937536ddc579bart 422868347837b3d82e48f85daff33ec7ba528891e4e7bartAddr VG_(DebugInfo_get_got_avma)(const DebugInfo* di) 422968347837b3d82e48f85daff33ec7ba528891e4e7bart{ 423068347837b3d82e48f85daff33ec7ba528891e4e7bart return di->got_present ? di->got_avma : 0; 423168347837b3d82e48f85daff33ec7ba528891e4e7bart} 423268347837b3d82e48f85daff33ec7ba528891e4e7bart 423368347837b3d82e48f85daff33ec7ba528891e4e7bartSizeT VG_(DebugInfo_get_got_size)(const DebugInfo* di) 423468347837b3d82e48f85daff33ec7ba528891e4e7bart{ 423568347837b3d82e48f85daff33ec7ba528891e4e7bart return di->got_present ? di->got_size : 0; 423668347837b3d82e48f85daff33ec7ba528891e4e7bart} 423768347837b3d82e48f85daff33ec7ba528891e4e7bart 42381636d33c13958b9c0e7d3059cdd5005746418eb2florianconst HChar* VG_(DebugInfo_get_soname)(const DebugInfo* di) 4239eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->soname; 4241b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 4242eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 42431636d33c13958b9c0e7d3059cdd5005746418eb2florianconst HChar* VG_(DebugInfo_get_filename)(const DebugInfo* di) 4244b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 4245a5acac39bf3be7546222b1316faee5ee524be0d1sewardj return di->fsm.filename; 4246eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4247eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4248e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjPtrdiffT VG_(DebugInfo_get_text_bias)(const DebugInfo* di) 4249bbec7728efefaa650970dd1f0282b77040287133sewardj{ 4250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return di->text_present ? di->text_bias : 0; 4251bbec7728efefaa650970dd1f0282b77040287133sewardj} 4252bbec7728efefaa650970dd1f0282b77040287133sewardj 4253e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjInt VG_(DebugInfo_syms_howmany) ( const DebugInfo *si ) 4254eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4255eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj return si->symtab_used; 4256eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4257eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4258e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardjvoid VG_(DebugInfo_syms_getidx) ( const DebugInfo *si, 4259e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj Int idx, 42604cace66777ca9ee73ea156210c04e9d4cc178395philippe /*OUT*/SymAVMAs* avmas, 42614cace66777ca9ee73ea156210c04e9d4cc178395philippe /*OUT*/UInt* size, 42621ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian /*OUT*/const HChar** pri_name, 42631ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian /*OUT*/const HChar*** sec_names, 42644cace66777ca9ee73ea156210c04e9d4cc178395philippe /*OUT*/Bool* isText, 42654cace66777ca9ee73ea156210c04e9d4cc178395philippe /*OUT*/Bool* isIFunc ) 4266eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj{ 4267eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj vg_assert(idx >= 0 && idx < si->symtab_used); 42684cace66777ca9ee73ea156210c04e9d4cc178395philippe if (avmas) *avmas = si->symtab[idx].avmas; 4269a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (size) *size = si->symtab[idx].size; 4270a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (pri_name) *pri_name = si->symtab[idx].pri_name; 42711ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian if (sec_names) *sec_names = si->symtab[idx].sec_names; 4272a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (isText) *isText = si->symtab[idx].isText; 4273a5cace0c2a3e212931badbf6398a0cd98393121asewardj if (isIFunc) *isIFunc = si->symtab[idx].isIFunc; 4274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 4275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 4278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- SectKind query functions ---*/ 4279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/ 4280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Convert a VgSectKind to a string, which must be copied if you want 4282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj to change it. */ 4283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjconst HChar* VG_(pp_SectKind)( VgSectKind kind ) 4284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 4285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj switch (kind) { 4286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectUnknown: return "Unknown"; 4287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectText: return "Text"; 4288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectData: return "Data"; 4289b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectBSS: return "BSS"; 4290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectGOT: return "GOT"; 4291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectPLT: return "PLT"; 4292b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj case Vg_SectOPD: return "OPD"; 42935706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj case Vg_SectGOTPLT: return "GOTPLT"; 4294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj default: vg_assert(0); 4295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4296b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj} 4297b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Given an address 'a', make a guess of which section of which object 4299e08950b4ce5a3f5d75a7279548f975cd6207dc74florian it comes from. If name is non-NULL, then the object's name is put 4300e08950b4ce5a3f5d75a7279548f975cd6207dc74florian in *name. The returned name, if any, should be saved away, if there is 4301e08950b4ce5a3f5d75a7279548f975cd6207dc74florian a chance that a debug-info will be discarded and the name is being 4302e08950b4ce5a3f5d75a7279548f975cd6207dc74florian used later on. */ 4303e08950b4ce5a3f5d75a7279548f975cd6207dc74florianVgSectKind VG_(DebugInfo_sect_kind)( /*OUT*/const HChar** name, Addr a) 4304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{ 4305b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj DebugInfo* di; 4306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VgSectKind res = Vg_SectUnknown; 4307b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj for (di = debugInfo_list; di != NULL; di = di->next) { 4309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (0) 4311b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj VG_(printf)( 4312e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj "addr=%#lx di=%p %s got=%#lx,%ld plt=%#lx,%ld " 4313e3f1e5988a94af9230f67273ca9236c4d7e8b8dasewardj "data=%#lx,%ld bss=%#lx,%ld\n", 4314a5acac39bf3be7546222b1316faee5ee524be0d1sewardj a, di, di->fsm.filename, 4315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->got_avma, di->got_size, 4316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->plt_avma, di->plt_size, 4317b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->data_avma, di->data_size, 4318b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj di->bss_avma, di->bss_size); 4319b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4320b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->text_present 4321b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->text_size > 0 4322b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->text_avma && a < di->text_avma + di->text_size) { 4323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectText; 4324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4326b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->data_present 4327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->data_size > 0 4328b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->data_avma && a < di->data_avma + di->data_size) { 4329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectData; 4330b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->sdata_present 4333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->sdata_size > 0 4334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->sdata_avma && a < di->sdata_avma + di->sdata_size) { 4335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectData; 4336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->bss_present 4339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->bss_size > 0 4340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->bss_avma && a < di->bss_avma + di->bss_size) { 4341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectBSS; 4342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 43445706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj if (di->sbss_present 43455706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && di->sbss_size > 0 43465706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj && a >= di->sbss_avma && a < di->sbss_avma + di->sbss_size) { 43475706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj res = Vg_SectBSS; 43485706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj break; 43495706ca98d16b4ed5f455c71c01655fc12f6b9eb9sewardj } 4350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->plt_present 4351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->plt_size > 0 4352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->plt_avma && a < di->plt_avma + di->plt_size) { 4353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectPLT; 4354b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4356b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->got_present 4357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->got_size > 0 4358b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->got_avma && a < di->got_avma + di->got_size) { 4359b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectGOT; 4360b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4361b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4362092b6268cc4a38ae9ee41d1e3355937536ddc579bart if (di->gotplt_present 4363092b6268cc4a38ae9ee41d1e3355937536ddc579bart && di->gotplt_size > 0 4364092b6268cc4a38ae9ee41d1e3355937536ddc579bart && a >= di->gotplt_avma && a < di->gotplt_avma + di->gotplt_size) { 4365092b6268cc4a38ae9ee41d1e3355937536ddc579bart res = Vg_SectGOTPLT; 4366092b6268cc4a38ae9ee41d1e3355937536ddc579bart break; 4367092b6268cc4a38ae9ee41d1e3355937536ddc579bart } 4368b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (di->opd_present 4369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && di->opd_size > 0 4370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj && a >= di->opd_avma && a < di->opd_avma + di->opd_size) { 4371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj res = Vg_SectOPD; 4372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj break; 4373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj /* we could also check for .eh_frame, if anyone really cares */ 4375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj vg_assert( (di == NULL && res == Vg_SectUnknown) 4378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj || (di != NULL && res != Vg_SectUnknown) ); 4379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj if (name) { 4381a5acac39bf3be7546222b1316faee5ee524be0d1sewardj if (di && di->fsm.filename) { 4382e08950b4ce5a3f5d75a7279548f975cd6207dc74florian *name = di->fsm.filename; 4383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } else { 4384e08950b4ce5a3f5d75a7279548f975cd6207dc74florian *name = "???"; 4385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj } 4387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj return res; 4389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj 4390eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj} 4391eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj 4392eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 4393eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- end ---*/ 4394eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--------------------------------------------------------------------*/ 4395